diff --git a/bsp/nrf52832/Libraries/SConscript b/bsp/nrf52832/Libraries/SConscript deleted file mode 100644 index d24823f5f8e208552742714aa293e7ee003a7121..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/Libraries/SConscript +++ /dev/null @@ -1,27 +0,0 @@ -import rtconfig -Import('RTT_ROOT') -from building import * - -# get current directory -cwd = GetCurrentDir() - -# The set of source files associated with this SConscript file. -src = Split(""" -nrf52832/Source/templates/system_nrf52.c -""") - -#add for Startup script -if rtconfig.CROSS_TOOL == 'gcc': - src = src + ['nrf52832/Source/templates/arm/gcc_startup_nrf52.s'] -elif rtconfig.CROSS_TOOL == 'keil': - src = src + ['nrf52832/Source/templates/arm/arm_startup_nrf52.s'] -elif rtconfig.CROSS_TOOL == 'iar': - src = src + ['nrf52832/Source/templates/arm/iar_startup_nrf52.s'] - -path = [cwd + '/CMSIS/Include', - cwd + '/nrf52832/Include'] - -CPPDEFINES = ['USE_STDPERIPH_DRIVER', 'NRF52'] -group = DefineGroup('Startup Code', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) - -Return('group') diff --git a/bsp/nrf52832/Libraries/nrf52832/Include/nrf.h b/bsp/nrf52832/Libraries/nrf52832/Include/nrf.h deleted file mode 100644 index dfe7ceafd4c72221031c29cfcb30b8d9639b5b92..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/Libraries/nrf52832/Include/nrf.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2015, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * 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. - * - * * Neither the name of Nordic Semiconductor ASA 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. - * - */ - -#ifndef NRF_H -#define NRF_H - -#if defined(_WIN32) - /* Do not include nrf51 specific files when building for PC host */ -#elif defined(__unix) - /* Do not include nrf51 specific files when building for PC host */ -#elif defined(__APPLE__) - /* Do not include nrf51 specific files when building for PC host */ -#else - - /* Family selection for family includes. */ - #if defined (NRF51) - #include "nrf51.h" - #include "nrf51_bitfields.h" - #include "nrf51_deprecated.h" - #elif defined (NRF52) - #include "nrf52.h" - #include "nrf52_bitfields.h" - #include "nrf51_to_nrf52.h" - #else - #error "Device family must be defined. See nrf.h." - #endif /* NRF51, NRF52 */ - - #include "compiler_abstraction.h" - -#endif /* _WIN32 || __unix || __APPLE__ */ - -#endif /* NRF_H */ - diff --git a/bsp/nrf52832/Libraries/nrf52832/Include/nrf_gpio.h b/bsp/nrf52832/Libraries/nrf52832/Include/nrf_gpio.h deleted file mode 100644 index 097f9d1bb1dd9a65f7457a8a383b0bff9495696b..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/Libraries/nrf52832/Include/nrf_gpio.h +++ /dev/null @@ -1,604 +0,0 @@ -#ifndef NRF_GPIO_H__ -#define NRF_GPIO_H__ - -#include "nrf.h" -#include - -/** - * @defgroup nrf_gpio GPIO abstraction - * @{ - * @ingroup nrf_drivers - * @brief GPIO pin abstraction and port abstraction for reading and writing byte-wise to GPIO ports. - * - * Here, the GPIO ports are defined as follows: - * - Port 0 -> pin 0-7 - * - Port 1 -> pin 8-15 - * - Port 2 -> pin 16-23 - * - Port 3 -> pin 24-31 - */ - -#define NUMBER_OF_PINS 32 - -/** - * @brief Enumerator used for selecting between port 0 - 3. - */ -typedef enum -{ - NRF_GPIO_PORT_SELECT_PORT0 = 0, ///< Port 0 (GPIO pin 0-7) - NRF_GPIO_PORT_SELECT_PORT1, ///< Port 1 (GPIO pin 8-15) - NRF_GPIO_PORT_SELECT_PORT2, ///< Port 2 (GPIO pin 16-23) - NRF_GPIO_PORT_SELECT_PORT3, ///< Port 3 (GPIO pin 24-31) -} nrf_gpio_port_select_t; - -/** - * @brief Enumerator used for setting the direction of a GPIO port. - */ -typedef enum -{ - NRF_GPIO_PORT_DIR_OUTPUT, ///< Output - NRF_GPIO_PORT_DIR_INPUT ///< Input -} nrf_gpio_port_dir_t; - -/** - * @brief Pin direction definitions. - */ -typedef enum -{ - NRF_GPIO_PIN_DIR_INPUT = GPIO_PIN_CNF_DIR_Input, ///< Input - NRF_GPIO_PIN_DIR_OUTPUT = GPIO_PIN_CNF_DIR_Output ///< Output -} nrf_gpio_pin_dir_t; - -/** - * @brief Connection of input buffer - */ -typedef enum -{ - NRF_GPIO_PIN_INPUT_CONNECT = GPIO_PIN_CNF_INPUT_Connect, ///< Connect input buffer - NRF_GPIO_PIN_INPUT_DISCONNECT = GPIO_PIN_CNF_INPUT_Disconnect ///< Disconnect input buffer -} nrf_gpio_pin_input_t; - -/** - * @brief Enumerator used for selecting the pin to be pulled down or up at the time of pin configuration - */ -typedef enum -{ - NRF_GPIO_PIN_NOPULL = GPIO_PIN_CNF_PULL_Disabled, ///< Pin pullup resistor disabled - NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown, ///< Pin pulldown resistor enabled - NRF_GPIO_PIN_PULLUP = GPIO_PIN_CNF_PULL_Pullup, ///< Pin pullup resistor enabled -} nrf_gpio_pin_pull_t; - -/** - * @brief Enumerator used for selecting output drive mode - */ -typedef enum -{ - NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< !< Standard '0', standard '1' - NRF_GPIO_PIN_H0S1 = GPIO_PIN_CNF_DRIVE_H0S1, ///< !< High drive '0', standard '1' - NRF_GPIO_PIN_S0H1 = GPIO_PIN_CNF_DRIVE_S0H1, ///< !< Standard '0', high drive '1' - NRF_GPIO_PIN_H0H1 = GPIO_PIN_CNF_DRIVE_H0H1, ///< !< High drive '0', high 'drive '1'' - NRF_GPIO_PIN_D0S1 = GPIO_PIN_CNF_DRIVE_D0S1, ///< !< Disconnect '0' standard '1' - NRF_GPIO_PIN_D0H1 = GPIO_PIN_CNF_DRIVE_D0H1, ///< !< Disconnect '0', high drive '1' - NRF_GPIO_PIN_S0D1 = GPIO_PIN_CNF_DRIVE_S0D1, ///< !< Standard '0'. disconnect '1' - NRF_GPIO_PIN_H0D1 = GPIO_PIN_CNF_DRIVE_H0D1, ///< !< High drive '0', disconnect '1' -} nrf_gpio_pin_drive_t; - -/** - * @brief Enumerator used for selecting the pin to sense high or low level on the pin input. - */ -typedef enum -{ - NRF_GPIO_PIN_NOSENSE = GPIO_PIN_CNF_SENSE_Disabled, ///< Pin sense level disabled. - NRF_GPIO_PIN_SENSE_LOW = GPIO_PIN_CNF_SENSE_Low, ///< Pin sense low level. - NRF_GPIO_PIN_SENSE_HIGH = GPIO_PIN_CNF_SENSE_High, ///< Pin sense high level. -} nrf_gpio_pin_sense_t; - - -/** - * @brief Function for configuring the GPIO pin range as outputs with normal drive strength. - * This function can be used to configure pin range as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). - * - * @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30) - * - * @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30) - * - * @note For configuring only one pin as output use @ref nrf_gpio_cfg_output - * Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output. - */ -__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end); - -/** - * @brief Function for configuring the GPIO pin range as inputs with given initial value set, hiding inner details. - * This function can be used to configure pin range as simple input. - * - * @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30) - * - * @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30) - * - * @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high) - * - * @note For configuring only one pin as input use @ref nrf_gpio_cfg_input - * Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable - */ -__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config); - -/** - * @brief Pin configuration function - * - * The main pin configuration function. - * This function allows to set any aspect in PIN_CNF register. - * @param pin_number Specifies the pin number (allowed values 0-31). - * @param dir Pin direction - * @param input Connect or disconnect input buffer - * @param pull Pull configuration - * @param drive Drive configuration - * @param sense Pin sensing mechanism - */ -__STATIC_INLINE void nrf_gpio_cfg( - uint32_t pin_number, - nrf_gpio_pin_dir_t dir, - nrf_gpio_pin_input_t input, - nrf_gpio_pin_pull_t pull, - nrf_gpio_pin_drive_t drive, - nrf_gpio_pin_sense_t sense); - -/** - * @brief Function for configuring the given GPIO pin number as output with given initial value set, hiding inner details. - * This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). - * - * @param pin_number specifies the pin number (allowed values 0-31) - * - * @note Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output. - */ -__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number); - -/** - * @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details. - * This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). - * - * @param pin_number Specifies the pin number (allowed values 0-30). - * @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high). - * - * @note Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable - */ -__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config); - -/** - * @brief Function for reseting pin configuration to its default state. - * - * @param pin_number Specifies the pin number (allowed values 0-31). - */ -__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number); - -/** - * @brief Function for configuring the given GPIO pin number as a watcher. Only input is connected. - * - * @param pin_number Specifies the pin number (allowed values 0-31). - * - */ -__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number); - -/** - * @brief Function for disconnecting input for the given GPIO. - * - * @param pin_number Specifies the pin number (allowed values 0-31). - * - */ -__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number); - -/** - * @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details. - * This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). - * Sense capability on the pin is configurable, and input is connected to buffer so that the GPIO->IN register is readable. - * - * @param pin_number Specifies the pin number (allowed values 0-30). - * @param pull_config State of the pin pull resistor (no pull, pulled down or pulled high). - * @param sense_config Sense level of the pin (no sense, sense low or sense high). - */ -__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config); - -/** - * @brief Function for configuring sense level for the given GPIO. - * - * @param pin_number Specifies the pin number of gpio pin numbers to be configured (allowed values 0-30). - * @param sense_config Sense configuration. - * - */ -__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config); - -/** - * @brief Function for setting the direction for a GPIO pin. - * - * @param pin_number specifies the pin number [0:31] for which to - * set the direction. - * - * @param direction specifies the direction - */ -__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction); - -/** - * @brief Function for setting a GPIO pin. - * - * Note that the pin must be configured as an output for this - * function to have any effect. - * - * @param pin_number specifies the pin number [0:31] to - * set. - */ -__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number); - -/** - * @brief Function for clearing a GPIO pin. - * - * Note that the pin must be configured as an output for this - * function to have any effect. - * - * @param pin_number specifies the pin number [0:31] to - * clear. - */ -__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number); - -/** - * @brief Function for toggling a GPIO pin. - * - * Note that the pin must be configured as an output for this - * function to have any effect. - * - * @param pin_number specifies the pin number [0:31] to - * toggle. - */ -__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number); - -/** - * @brief Function for writing a value to a GPIO pin. - * - * Note that the pin must be configured as an output for this - * function to have any effect. - * - * @param pin_number specifies the pin number [0:31] to - * write. - * - * @param value specifies the value to be written to the pin. - * @arg 0 clears the pin - * @arg >=1 sets the pin. - */ -__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value); - -/** - * @brief Function for reading the input level of a GPIO pin. - * - * Note that the pin must have input connected for the value - * returned from this function to be valid. - * - * @param pin_number specifies the pin number [0:31] to - * read. - * - * @return - * @retval 0 if the pin input level is low. - * @retval 1 if the pin input level is high. - * @retval > 1 should never occur. - */ -__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number); - -/** - * @brief Function for reading the input level of all GPIO pins. - * - * Note that the pin must have input connected for the value - * returned from this function to be valid. - * - * @retval Status of input of all pins - */ -__STATIC_INLINE uint32_t nrf_gpio_pins_read(void); - -/** - * @brief Function for reading the sense configuration of a GPIO pin. - * - * @param pin_number specifies the pin number [0:31] to - * read. - * - * @retval Sense configuration - */ -__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number); - -/** - * @brief Generic function for writing a single byte of a 32 bit word at a given - * address. - * - * This function should not be called from outside the nrf_gpio - * abstraction layer. - * - * @param word_address is the address of the word to be written. - * - * @param byte_no is the word byte number (0-3) to be written. - * - * @param value is the value to be written to byte "byte_no" of word - * at address "word_address" - */ -__STATIC_INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value); - -/** - * @brief Generic function for reading a single byte of a 32 bit word at a given - * address. - * - * This function should not be called from outside the nrf_gpio - * abstraction layer. - * - * @param word_address is the address of the word to be read. - * - * @param byte_no is the byte number (0-3) of the word to be read. - * - * @return byte "byte_no" of word at address "word_address". - */ -__STATIC_INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no); - -/** - * @brief Function for setting the direction of a port. - * - * @param port is the port for which to set the direction. - * - * @param dir direction to be set for this port. - */ -__STATIC_INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir); - -/** - * @brief Function for reading a GPIO port. - * - * @param port is the port to read. - * - * @return the input value on this port. - */ -__STATIC_INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port); - -/** - * @brief Function for writing to a GPIO port. - * - * @param port is the port to write. - * - * @param value is the value to write to this port. - * - * @sa nrf_gpio_port_dir_set() - */ -__STATIC_INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value); - -/** - * @brief Function for setting individual pins on GPIO port. - * - * @param port is the port for which to set the pins. - * - * @param set_mask is a mask specifying which pins to set. A bit - * set to 1 indicates that the corresponding port pin shall be - * set. - * - * @sa nrf_gpio_port_dir_set() - */ -__STATIC_INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask); - -/** - * @brief Function for clearing individual pins on GPIO port. - * - * @param port is the port for which to clear the pins. - * - * @param clr_mask is a mask specifying which pins to clear. A bit - * set to 1 indicates that the corresponding port pin shall be - * cleared. - * - * @sa nrf_gpio_port_dir_set() - */ -__STATIC_INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask); - -#ifndef SUPPRESS_INLINE_IMPLEMENTATION -__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end) -{ - /*lint -e{845} // A zero has been given as right argument to operator '|'" */ - for (; pin_range_start <= pin_range_end; pin_range_start++) - { - nrf_gpio_cfg_output(pin_range_start); - } -} - -__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config) -{ - /*lint -e{845} // A zero has been given as right argument to operator '|'" */ - for (; pin_range_start <= pin_range_end; pin_range_start++) - { - nrf_gpio_cfg_input(pin_range_start, pull_config); - } -} - -__STATIC_INLINE void nrf_gpio_cfg( - uint32_t pin_number, - nrf_gpio_pin_dir_t dir, - nrf_gpio_pin_input_t input, - nrf_gpio_pin_pull_t pull, - nrf_gpio_pin_drive_t drive, - nrf_gpio_pin_sense_t sense) -{ - NRF_GPIO->PIN_CNF[pin_number] = ((uint32_t)dir << GPIO_PIN_CNF_DIR_Pos) - | ((uint32_t)input << GPIO_PIN_CNF_INPUT_Pos) - | ((uint32_t)pull << GPIO_PIN_CNF_PULL_Pos) - | ((uint32_t)drive << GPIO_PIN_CNF_DRIVE_Pos) - | ((uint32_t)sense << GPIO_PIN_CNF_SENSE_Pos); -} - -__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number) -{ - nrf_gpio_cfg( - pin_number, - NRF_GPIO_PIN_DIR_OUTPUT, - NRF_GPIO_PIN_INPUT_DISCONNECT, - NRF_GPIO_PIN_NOPULL, - NRF_GPIO_PIN_S0S1, - NRF_GPIO_PIN_NOSENSE); -} - -__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config) -{ - nrf_gpio_cfg( - pin_number, - NRF_GPIO_PIN_DIR_INPUT, - NRF_GPIO_PIN_INPUT_CONNECT, - pull_config, - NRF_GPIO_PIN_S0S1, - NRF_GPIO_PIN_NOSENSE); -} - -__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number) -{ - nrf_gpio_cfg( - pin_number, - NRF_GPIO_PIN_DIR_INPUT, - NRF_GPIO_PIN_INPUT_DISCONNECT, - NRF_GPIO_PIN_NOPULL, - NRF_GPIO_PIN_S0S1, - NRF_GPIO_PIN_NOSENSE); -} - -__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number) -{ - /*lint -e{845} // A zero has been given as right argument to operator '|'" */ - uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk; - NRF_GPIO->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); -} - -__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number) -{ - /*lint -e{845} // A zero has been given as right argument to operator '|'" */ - uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk; - NRF_GPIO->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); -} - -__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config) -{ - nrf_gpio_cfg( - pin_number, - NRF_GPIO_PIN_DIR_INPUT, - NRF_GPIO_PIN_INPUT_CONNECT, - pull_config, - NRF_GPIO_PIN_S0S1, - sense_config); -} - -__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config) -{ - /*lint -e{845} // A zero has been given as right argument to operator '|'" */ - //uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_SENSE_Msk; - NRF_GPIO->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_SENSE_Msk; - NRF_GPIO->PIN_CNF[pin_number] |= (sense_config << GPIO_PIN_CNF_SENSE_Pos); -} - -__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction) -{ - if(direction == NRF_GPIO_PIN_DIR_INPUT) - { - nrf_gpio_cfg( - pin_number, - NRF_GPIO_PIN_DIR_INPUT, - NRF_GPIO_PIN_INPUT_CONNECT, - NRF_GPIO_PIN_NOPULL, - NRF_GPIO_PIN_S0S1, - NRF_GPIO_PIN_NOSENSE); - } - else - { - NRF_GPIO->DIRSET = (1UL << pin_number); - } -} - -__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number) -{ - NRF_GPIO->OUTSET = (1UL << pin_number); -} - -__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number) -{ - NRF_GPIO->OUTCLR = (1UL << pin_number); -} - -__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number) -{ - const uint32_t pin_bit = 1UL << pin_number; - const uint32_t pin_state = ((NRF_GPIO->OUT >> pin_number) & 1UL); - - if (pin_state == 0) - { - // Current state low, set high. - NRF_GPIO->OUTSET = pin_bit; - } - else - { - // Current state high, set low. - NRF_GPIO->OUTCLR = pin_bit; - } -} - -__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value) -{ - if (value == 0) - { - nrf_gpio_pin_clear(pin_number); - } - else - { - nrf_gpio_pin_set(pin_number); - } -} - -__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number) -{ - return ((NRF_GPIO->IN >> pin_number) & 1UL); -} - -__STATIC_INLINE uint32_t nrf_gpio_pins_read(void) -{ - return NRF_GPIO->IN; -} - -__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number) -{ - return (nrf_gpio_pin_sense_t)((NRF_GPIO->PIN_CNF[pin_number] & GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos); -} - -__STATIC_INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value) -{ - *((volatile uint8_t*)(word_address) + byte_no) = value; -} - -__STATIC_INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no) -{ - return (*((const volatile uint8_t*)(word_address) + byte_no)); -} - -__STATIC_INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir) -{ - if (dir == NRF_GPIO_PORT_DIR_OUTPUT) - { - nrf_gpio_word_byte_write(&NRF_GPIO->DIRSET, port, 0xFF); - } - else - { - nrf_gpio_range_cfg_input(port*8, (port+1)*8-1, NRF_GPIO_PIN_NOPULL); - } -} - -__STATIC_INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port) -{ - return nrf_gpio_word_byte_read(&NRF_GPIO->IN, port); -} - -__STATIC_INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value) -{ - nrf_gpio_word_byte_write(&NRF_GPIO->OUT, port, value); -} - -__STATIC_INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask) -{ - nrf_gpio_word_byte_write(&NRF_GPIO->OUTSET, port, set_mask); -} - -__STATIC_INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask) -{ - nrf_gpio_word_byte_write(&NRF_GPIO->OUTCLR, port, clr_mask); -} -#endif //SUPPRESS_INLINE_IMPLEMENTATION -/** @} */ - -#endif diff --git a/bsp/nrf52832/Libraries/nrf52832/Include/system_nrf52.h b/bsp/nrf52832/Libraries/nrf52832/Include/system_nrf52.h deleted file mode 100644 index f0464c1577ccabb56cdaca5071c1f2c026dd442f..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/Libraries/nrf52832/Include/system_nrf52.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 2015, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * 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. - * - * * Neither the name of Nordic Semiconductor ASA 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. - * - */ - -#ifndef SYSTEM_NRF52_H -#define SYSTEM_NRF52_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - - -extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ - -/** - * Initialize the system - * - * @param none - * @return none - * - * @brief Setup the microcontroller system. - * Initialize the System and update the SystemCoreClock variable. - */ -extern void SystemInit (void); - -/** - * Update SystemCoreClock variable - * - * @param none - * @return none - * - * @brief Updates the SystemCoreClock with current core Clock - * retrieved from cpu registers. - */ -extern void SystemCoreClockUpdate (void); - -#ifdef __cplusplus -} -#endif - -#endif /* SYSTEM_NRF52_H */ diff --git a/bsp/nrf52832/Libraries/nrf52832/Source/templates/arm/gcc_startup_nrf52.s b/bsp/nrf52832/Libraries/nrf52832/Source/templates/arm/gcc_startup_nrf52.s deleted file mode 100644 index 0792af34dfd38843f81d7b14dd5edc7e319ad333..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/Libraries/nrf52832/Source/templates/arm/gcc_startup_nrf52.s +++ /dev/null @@ -1,490 +0,0 @@ -/* -Copyright (c) 2015, Nordic Semiconductor ASA -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* 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. - -* Neither the name of Nordic Semiconductor ASA 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. -*/ - -/* -NOTE: Template files (including this one) are application specific and therefore -expected to be copied into the application project folder prior to its use! -*/ - - .syntax unified - .arch armv6-m - - .section .stack - .align 3 -#ifdef __STACK_SIZE - .equ Stack_Size, __STACK_SIZE -#else - .equ Stack_Size, 8192 -#endif - .globl __StackTop - .globl __StackLimit -__StackLimit: - .space Stack_Size - .size __StackLimit, . - __StackLimit -__StackTop: - .size __StackTop, . - __StackTop - - .section .heap - .align 3 -#ifdef __HEAP_SIZE - .equ Heap_Size, __HEAP_SIZE -#else - .equ Heap_Size, 8192 -#endif - .globl __HeapBase - .globl __HeapLimit -__HeapBase: - .if Heap_Size - .space Heap_Size - .endif - .size __HeapBase, . - __HeapBase -__HeapLimit: - .size __HeapLimit, . - __HeapLimit - - .section .Vectors - .align 2 - .globl __Vectors -__Vectors: - .long __StackTop /* Top of Stack */ - .long Reset_Handler /* Reset Handler */ - .long NMI_Handler /* NMI Handler */ - .long HardFault_Handler /* Hard Fault Handler */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long SVC_Handler /* SVCall Handler */ - .long 0 /* Reserved */ - .long 0 /* Reserved */ - .long PendSV_Handler /* PendSV Handler */ - .long SysTick_Handler /* SysTick Handler */ - - /* External Interrupts */ - .long POWER_CLOCK_IRQHandler - .long RADIO_IRQHandler - .long UARTE0_UART0_IRQHandler - .long SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler - .long SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler - .long NFCT_IRQHandler - .long GPIOTE_IRQHandler - .long SAADC_IRQHandler - .long TIMER0_IRQHandler - .long TIMER1_IRQHandler - .long TIMER2_IRQHandler - .long RTC0_IRQHandler - .long TEMP_IRQHandler - .long RNG_IRQHandler - .long ECB_IRQHandler - .long CCM_AAR_IRQHandler - .long WDT_IRQHandler - .long RTC1_IRQHandler - .long QDEC_IRQHandler - .long COMP_LPCOMP_IRQHandler - .long SWI0_EGU0_IRQHandler - .long SWI1_EGU1_IRQHandler - .long SWI2_EGU2_IRQHandler - .long SWI3_EGU3_IRQHandler - .long SWI4_EGU4_IRQHandler - .long SWI5_EGU5_IRQHandler - .long TIMER3_IRQHandler - .long TIMER4_IRQHandler - .long PWM0_IRQHandler - .long PDM_IRQHandler - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long MWU_IRQHandler - .long PWM1_IRQHandler - .long PWM2_IRQHandler - .long SPIM2_SPIS2_SPI2_IRQHandler - .long RTC2_IRQHandler - .long I2S_IRQHandler - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - .long 0 /*Reserved */ - - .size __Vectors, . - __Vectors - -/* Reset Handler */ - - .text - .thumb - .thumb_func - .align 1 - .globl Reset_Handler - .type Reset_Handler, %function -Reset_Handler: - .fnstart - - -/* Loop to copy data from read only memory to RAM. The ranges - * of copy from/to are specified by following symbols evaluated in - * linker script. - * __etext: End of code section, i.e., begin of data sections to copy from. - * __data_start__/__data_end__: RAM address range that data should be - * copied to. Both must be aligned to 4 bytes boundary. */ - - ldr r1, =__etext - ldr r2, =__data_start__ - ldr r3, =__data_end__ - - subs r3, r2 - ble .LC0 - -.LC1: - subs r3, 4 - ldr r0, [r1,r3] - str r0, [r2,r3] - bgt .LC1 -.LC0: - - LDR R0, =SystemInit - BLX R0 - LDR R0, =_start - BX R0 - - .pool - .cantunwind - .fnend - .size Reset_Handler,.-Reset_Handler - - .section ".text" - - -/* Dummy Exception Handlers (infinite loops which can be modified) */ - - .weak NMI_Handler - .type NMI_Handler, %function -NMI_Handler: - B . - .size NMI_Handler, . - NMI_Handler - - - .weak HardFault_Handler - .type HardFault_Handler, %function -HardFault_Handler: - B . - .size HardFault_Handler, . - HardFault_Handler - - - .weak MemoryManagement_Handler - .type MemoryManagement_Handler, %function -MemoryManagement_Handler: - B . - .size MemoryManagement_Handler, . - MemoryManagement_Handler - - - .weak BusFault_Handler - .type BusFault_Handler, %function -BusFault_Handler: - B . - .size BusFault_Handler, . - BusFault_Handler - - - .weak UsageFault_Handler - .type UsageFault_Handler, %function -UsageFault_Handler: - B . - .size UsageFault_Handler, . - UsageFault_Handler - - - .weak SVC_Handler - .type SVC_Handler, %function -SVC_Handler: - B . - .size SVC_Handler, . - SVC_Handler - - - .weak PendSV_Handler - .type PendSV_Handler, %function -PendSV_Handler: - B . - .size PendSV_Handler, . - PendSV_Handler - - - .weak SysTick_Handler - .type SysTick_Handler, %function -SysTick_Handler: - B . - .size SysTick_Handler, . - SysTick_Handler - - -/* IRQ Handlers */ - - .globl Default_Handler - .type Default_Handler, %function -Default_Handler: - B . - .size Default_Handler, . - Default_Handler - - .macro IRQ handler - .weak \handler - .set \handler, Default_Handler - .endm - - IRQ POWER_CLOCK_IRQHandler - IRQ RADIO_IRQHandler - IRQ UARTE0_UART0_IRQHandler - IRQ SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler - IRQ SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler - IRQ NFCT_IRQHandler - IRQ GPIOTE_IRQHandler - IRQ SAADC_IRQHandler - IRQ TIMER0_IRQHandler - IRQ TIMER1_IRQHandler - IRQ TIMER2_IRQHandler - IRQ RTC0_IRQHandler - IRQ TEMP_IRQHandler - IRQ RNG_IRQHandler - IRQ ECB_IRQHandler - IRQ CCM_AAR_IRQHandler - IRQ WDT_IRQHandler - IRQ RTC1_IRQHandler - IRQ QDEC_IRQHandler - IRQ COMP_LPCOMP_IRQHandler - IRQ SWI0_EGU0_IRQHandler - IRQ SWI1_EGU1_IRQHandler - IRQ SWI2_EGU2_IRQHandler - IRQ SWI3_EGU3_IRQHandler - IRQ SWI4_EGU4_IRQHandler - IRQ SWI5_EGU5_IRQHandler - IRQ TIMER3_IRQHandler - IRQ TIMER4_IRQHandler - IRQ PWM0_IRQHandler - IRQ PDM_IRQHandler - IRQ MWU_IRQHandler - IRQ PWM1_IRQHandler - IRQ PWM2_IRQHandler - IRQ SPIM2_SPIS2_SPI2_IRQHandler - IRQ RTC2_IRQHandler - IRQ I2S_IRQHandler - - .end diff --git a/bsp/nrf52832/Libraries/nrf52832/Source/templates/arm/iar_startup_nrf52.s b/bsp/nrf52832/Libraries/nrf52832/Source/templates/arm/iar_startup_nrf52.s deleted file mode 100644 index ea06ac6b7a1b47f7bd71871c1d8c4eb5ea681915..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/Libraries/nrf52832/Source/templates/arm/iar_startup_nrf52.s +++ /dev/null @@ -1,525 +0,0 @@ -;; Copyright (c) 2015, Nordic Semiconductor ASA -;; All rights reserved. -;; -;; Redistribution and use in source and binary forms, with or without -;; modification, are permitted provided that the following conditions are met: -;; -;; * Redistributions of source code must retain the above copyright notice, this -;; list of conditions and the following disclaimer. -;; -;; * 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. -;; -;; * Neither the name of Nordic Semiconductor ASA 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. - - - -;; NOTE: Template files (including this one) are application specific and therefore -;; expected to be copied into the application project folder prior to its use! - -;; Description message - - MODULE ?cstartup - - ;; Stack size default : Defined in *.icf (linker file). Can be modified inside EW. - ;; Heap size default : Defined in *.icf (linker file). Can be modified inside EW. - - ;; Forward declaration of sections. - SECTION CSTACK:DATA:NOROOT(3) - - SECTION .intvec:CODE:NOROOT(2) - - EXTERN __iar_program_start - EXTERN SystemInit - PUBLIC __vector_table - PUBLIC __Vectors - PUBLIC __Vectors_End - PUBLIC __Vectors_Size - - DATA - -__vector_table - DCD sfe(CSTACK) - DCD Reset_Handler - DCD NMI_Handler - DCD HardFault_Handler - DCD 0 - DCD 0 - DCD 0 -;__vector_table_0x1c - DCD 0 - DCD 0 - DCD 0 - DCD 0 - DCD SVC_Handler - DCD 0 - DCD 0 - DCD PendSV_Handler - DCD SysTick_Handler - - ; External Interrupts - DCD POWER_CLOCK_IRQHandler - DCD RADIO_IRQHandler - DCD UARTE0_UART0_IRQHandler - DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler - DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler - DCD NFCT_IRQHandler - DCD GPIOTE_IRQHandler - DCD SAADC_IRQHandler - DCD TIMER0_IRQHandler - DCD TIMER1_IRQHandler - DCD TIMER2_IRQHandler - DCD RTC0_IRQHandler - DCD TEMP_IRQHandler - DCD RNG_IRQHandler - DCD ECB_IRQHandler - DCD CCM_AAR_IRQHandler - DCD WDT_IRQHandler - DCD RTC1_IRQHandler - DCD QDEC_IRQHandler - DCD COMP_LPCOMP_IRQHandler - DCD SWI0_EGU0_IRQHandler - DCD SWI1_EGU1_IRQHandler - DCD SWI2_EGU2_IRQHandler - DCD SWI3_EGU3_IRQHandler - DCD SWI4_EGU4_IRQHandler - DCD SWI5_EGU5_IRQHandler - DCD TIMER3_IRQHandler - DCD TIMER4_IRQHandler - DCD PWM0_IRQHandler - DCD PDM_IRQHandler - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD MWU_IRQHandler - DCD PWM1_IRQHandler - DCD PWM2_IRQHandler - DCD SPIM2_SPIS2_SPI2_IRQHandler - DCD RTC2_IRQHandler - DCD I2S_IRQHandler - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - -__Vectors_End -__Vectors EQU __vector_table -__Vectors_Size EQU __Vectors_End - __Vectors - -; Default handlers. - THUMB - - PUBWEAK Reset_Handler - SECTION .text:CODE:REORDER:NOROOT(2) -Reset_Handler - - LDR R0, =SystemInit - BLX R0 - LDR R0, =__iar_program_start - BX R0 - - ; Dummy exception handlers - - - PUBWEAK NMI_Handler - SECTION .text:CODE:REORDER:NOROOT(1) -NMI_Handler - B . - - PUBWEAK HardFault_Handler - SECTION .text:CODE:REORDER:NOROOT(1) -HardFault_Handler - B . - - PUBWEAK MemoryManagement_Handler - SECTION .text:CODE:REORDER:NOROOT(1) -MemoryManagement_Handler - B . - - PUBWEAK BusFault_Handler - SECTION .text:CODE:REORDER:NOROOT(1) -BusFault_Handler - B . - - PUBWEAK UsageFault_Handler - SECTION .text:CODE:REORDER:NOROOT(1) -UsageFault_Handler - B . - - PUBWEAK SVC_Handler - SECTION .text:CODE:REORDER:NOROOT(1) -SVC_Handler - B . - - PUBWEAK PendSV_Handler - SECTION .text:CODE:REORDER:NOROOT(1) -PendSV_Handler - B . - - PUBWEAK SysTick_Handler - SECTION .text:CODE:REORDER:NOROOT(1) -SysTick_Handler - B . - - - ; Dummy interrupt handlers - - PUBWEAK POWER_CLOCK_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -POWER_CLOCK_IRQHandler - B . - PUBWEAK RADIO_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -RADIO_IRQHandler - B . - PUBWEAK UARTE0_UART0_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -UARTE0_UART0_IRQHandler - B . - PUBWEAK SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler - B . - PUBWEAK SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler - B . - PUBWEAK NFCT_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -NFCT_IRQHandler - B . - PUBWEAK GPIOTE_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -GPIOTE_IRQHandler - B . - PUBWEAK SAADC_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -SAADC_IRQHandler - B . - PUBWEAK TIMER0_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -TIMER0_IRQHandler - B . - PUBWEAK TIMER1_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -TIMER1_IRQHandler - B . - PUBWEAK TIMER2_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -TIMER2_IRQHandler - B . - PUBWEAK RTC0_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -RTC0_IRQHandler - B . - PUBWEAK TEMP_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -TEMP_IRQHandler - B . - PUBWEAK RNG_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -RNG_IRQHandler - B . - PUBWEAK ECB_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -ECB_IRQHandler - B . - PUBWEAK CCM_AAR_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -CCM_AAR_IRQHandler - B . - PUBWEAK WDT_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -WDT_IRQHandler - B . - PUBWEAK RTC1_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -RTC1_IRQHandler - B . - PUBWEAK QDEC_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -QDEC_IRQHandler - B . - PUBWEAK COMP_LPCOMP_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -COMP_LPCOMP_IRQHandler - B . - PUBWEAK SWI0_EGU0_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -SWI0_EGU0_IRQHandler - B . - PUBWEAK SWI1_EGU1_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -SWI1_EGU1_IRQHandler - B . - PUBWEAK SWI2_EGU2_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -SWI2_EGU2_IRQHandler - B . - PUBWEAK SWI3_EGU3_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -SWI3_EGU3_IRQHandler - B . - PUBWEAK SWI4_EGU4_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -SWI4_EGU4_IRQHandler - B . - PUBWEAK SWI5_EGU5_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -SWI5_EGU5_IRQHandler - B . - PUBWEAK TIMER3_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -TIMER3_IRQHandler - B . - PUBWEAK TIMER4_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -TIMER4_IRQHandler - B . - PUBWEAK PWM0_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -PWM0_IRQHandler - B . - PUBWEAK PDM_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -PDM_IRQHandler - B . - PUBWEAK MWU_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -MWU_IRQHandler - B . - PUBWEAK PWM1_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -PWM1_IRQHandler - B . - PUBWEAK PWM2_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -PWM2_IRQHandler - B . - PUBWEAK SPIM2_SPIS2_SPI2_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -SPIM2_SPIS2_SPI2_IRQHandler - B . - PUBWEAK RTC2_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -RTC2_IRQHandler - B . - PUBWEAK I2S_IRQHandler - SECTION .text:CODE:REORDER:NOROOT(1) -I2S_IRQHandler - B . - - END - - diff --git a/bsp/nrf52832/Libraries/nrf52832/Source/templates/system_nrf52.c b/bsp/nrf52832/Libraries/nrf52832/Source/templates/system_nrf52.c deleted file mode 100644 index d7ca537781e3b1cdd38752db0896834af147db8e..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/Libraries/nrf52832/Source/templates/system_nrf52.c +++ /dev/null @@ -1,180 +0,0 @@ -/* Copyright (c) 2015, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * 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. - * - * * Neither the name of Nordic Semiconductor ASA 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. - * - */ - -#include -#include -#include "nrf.h" -#include "system_nrf52.h" - -/*lint ++flb "Enter library region" */ - -#define __SYSTEM_CLOCK_16M (16000000UL) -#define __SYSTEM_CLOCK_64M (64000000UL) - -static bool ftpan_32(void); -static bool ftpan_37(void); -static bool ftpan_36(void); - - -#if defined ( __CC_ARM ) - uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; -#elif defined ( __ICCARM__ ) - __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M; -#elif defined ( __GNUC__ ) - uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; -#endif - -void SystemCoreClockUpdate(void) -{ - SystemCoreClock = __SYSTEM_CLOCK_64M; -} - -void SystemInit(void) -{ - /* Workaround for FTPAN-32 "DIF: Debug session automatically enables TracePort pins" found at Product Anomaly document - for your device located at https://www.nordicsemi.com/ */ - if (ftpan_32()){ - CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; - } - - /* Workaround for FTPAN-37 "AMLI: EasyDMA is slow with Radio, ECB, AAR and CCM." found at Product Anomaly document - for your device located at https://www.nordicsemi.com/ */ - if (ftpan_37()){ - *(volatile uint32_t *)0x400005A0 = 0x3; - } - - /* Workaround for FTPAN-36 "CLOCK: Some registers are not reset when expected." found at Product Anomaly document - for your device located at https://www.nordicsemi.com/ */ - if (ftpan_36()){ - NRF_CLOCK->EVENTS_DONE = 0; - NRF_CLOCK->EVENTS_CTTO = 0; - } - - /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the - * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit - * operations are not used in your code. */ - #if (__FPU_USED == 1) - SCB->CPACR |= (3UL << 20) | (3UL << 22); - __DSB(); - __ISB(); - #endif - - /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined, - two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as - normal GPIOs. */ - #if defined (CONFIG_NFCT_PINS_AS_GPIOS) - if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){ - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} - NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} - NVIC_SystemReset(); - } - #endif - - /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not - defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be - reserved for PinReset and not available as normal GPIO. */ - #if defined (CONFIG_GPIO_AS_PINRESET) - if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) || - ((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){ - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} - NRF_UICR->PSELRESET[0] = 21; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} - NRF_UICR->PSELRESET[1] = 21; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} - NVIC_SystemReset(); - } - #endif - - /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product - Specification to see which one). */ - #if defined (ENABLE_SWO) - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos; - #endif - - /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product - Specification to see which ones). */ - #if defined (ENABLE_TRACE) - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos; - #endif - - SystemCoreClockUpdate(); -} - -static bool ftpan_32(void) -{ - if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) - { - if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) - { - return true; - } - } - - return false; -} - -static bool ftpan_37(void) -{ - if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) - { - if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) - { - return true; - } - } - - return false; -} - -static bool ftpan_36(void) -{ - if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) - { - if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) - { - return true; - } - } - - return false; -} - - - -/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/SConscript b/bsp/nrf52832/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..efebe406f7bbaafc74a38115ca90cfdde90a3718 --- /dev/null +++ b/bsp/nrf52832/SConscript @@ -0,0 +1,16 @@ +# for module compiling +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +objs = objs + SConscript(os.path.join(cwd, 'nRF5_SDK_13.0.0_04a0bfd/components/SConscript')) + +Return('objs') diff --git a/bsp/nrf52832/SConstruct b/bsp/nrf52832/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..78a2f594b5b01e697faf97fa7221e1c78372d422 --- /dev/null +++ b/bsp/nrf52832/SConstruct @@ -0,0 +1,34 @@ +import os +import sys +import rtconfig + +if os.getenv('RTT_ROOT'): + RTT_ROOT = os.getenv('RTT_ROOT') +else: + RTT_ROOT = os.path.normpath(os.getcwd() + '/../..') + +sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] +from building import * + +TARGET = 'rtthread_nrf52832.' + rtconfig.TARGET_EXT + +env = Environment(tools = ['mingw'], + AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, + CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS, + AR = rtconfig.AR, ARFLAGS = '-rc', + LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) +env.PrependENVPath('PATH', rtconfig.EXEC_PATH) + +if rtconfig.PLATFORM == 'iar': + env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES']) + env.Replace(ARFLAGS = ['']) + env.Replace(LINKCOM = ['$LINK $SOURCES $LINKFLAGS -o $TARGET --map project.map']) + +Export('RTT_ROOT') +Export('rtconfig') + +# prepare building environment +objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) + +# make a building +DoBuilding(TARGET, objs) diff --git a/bsp/nrf52832/applications/application.c b/bsp/nrf52832/applications/application.c index 5af6888bbb14c8e5cc835a757a23cde05491ff87..d23a11a3e0ff7fdd801351828690c64c2f4e5898 100644 --- a/bsp/nrf52832/applications/application.c +++ b/bsp/nrf52832/applications/application.c @@ -25,13 +25,20 @@ #include #endif +void rt_init_thread_entry(void* parameter) +{ + +} + int rt_application_init(void) { - /* Set finsh device */ -#ifdef RT_USING_FINSH - /* initialize finsh */ - finsh_system_init(); -#endif + rt_thread_t tid; + + tid = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 1024, + RT_THREAD_PRIORITY_MAX / 3, 20); + if (tid != RT_NULL) + rt_thread_startup(tid); + return 0; } diff --git a/bsp/nrf52832/applications/ble_nus_app.c b/bsp/nrf52832/applications/ble_nus_app.c new file mode 100644 index 0000000000000000000000000000000000000000..a8f95e9ee134b55839c47829cd92ab2030eb9030 --- /dev/null +++ b/bsp/nrf52832/applications/ble_nus_app.c @@ -0,0 +1,670 @@ +#include "nordic_common.h" +#include "nrf.h" +#include "ble_hci.h" +#include "ble_advdata.h" +#include "ble_advertising.h" +#include "ble_conn_params.h" +#include "softdevice_handler.h" +#include "nrf_ble_gatt.h" +#include "app_timer.h" +#include "ble_nus.h" +#include "app_util_platform.h" + +#include + +typedef rt_size_t (*BLE_NOTIFY_T)(rt_uint8_t *buf, rt_uint16_t size); + +#define STACK_EVT_MQ_NUM 10 + +#define FAST_ADV() \ + do { \ + uint32_t err_code; \ + err_code = ble_advertising_start(BLE_ADV_MODE_FAST); \ + APP_ERROR_CHECK(err_code); \ + } while(0) + +typedef enum +{ + STACK_EV_DISCON = 1, + STACK_EV_DISPATCH = 2, + STACK_EV_KEY = 4, +} STACK_EV_E; + +typedef struct +{ + rt_list_t node; + void* evt; +} evt_list_t; + +typedef enum +{ + STACK_STATE_IDLE = 0, + STACK_STATE_ADV = 1, + STACK_STATE_CON = 2, + STACK_STATE_DISC = 3 +} STACK_STATE_E; + +STACK_STATE_E stack_state = STACK_STATE_IDLE; + +rt_event_t stack_event; +rt_sem_t sd_evt_sem; +rt_mq_t stack_evt_mq; +rt_uint8_t *evt_sample; + +BLE_NOTIFY_T rx_notify = RT_NULL; + +// Low frequency clock source to be used by the SoftDevice +#define NRF_CLOCK_LFCLKSRC {.source = NRF_CLOCK_LF_SRC_XTAL, \ + .rc_ctiv = 0, \ + .rc_temp_ctiv = 0, \ + .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM} + + +#define CONN_CFG_TAG 1 /**< A tag that refers to the BLE stack configuration we set with @ref sd_ble_cfg_set. Default tag is @ref BLE_CONN_CFG_TAG_DEFAULT. */ + +#define APP_FEATURE_NOT_SUPPORTED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2 /**< Reply when unsupported features are requested. */ + +#define DEVICE_NAME "Nordic_UART" /**< Name of device. Will be included in the advertising data. */ +#define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */ + +#define APP_ADV_INTERVAL 64 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */ +#define APP_ADV_TIMEOUT_IN_SECONDS 30 /**< The advertising timeout (in units of seconds). */ + +#define MIN_CONN_INTERVAL MSEC_TO_UNITS(20, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */ +#define MAX_CONN_INTERVAL MSEC_TO_UNITS(75, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */ +#define SLAVE_LATENCY 0 /**< Slave latency. */ +#define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */ +#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */ +#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(30000) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */ +#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */ + +#define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */ + +#define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */ +#define UART_RX_BUF_SIZE 256 /**< UART RX buffer size. */ + +static ble_nus_t m_nus; /**< Structure to identify the Nordic UART Service. */ +static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */ + +static nrf_ble_gatt_t m_gatt; /**< GATT module instance. */ +static ble_uuid_t m_adv_uuids[] = {{BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}}; /**< Universally unique service identifier. */ +static uint16_t m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - 3; /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */ + +/**@brief Function for assert macro callback. + * + * @details This function will be called in case of an assert in the SoftDevice. + * + * @warning This handler is an example only and does not fit a final product. You need to analyse + * how your product is supposed to react in case of Assert. + * @warning On assert from the SoftDevice, the system can only recover on reset. + * + * @param[in] line_num Line number of the failing ASSERT call. + * @param[in] p_file_name File name of the failing ASSERT call. + */ +void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name) +{ + app_error_handler(DEAD_BEEF, line_num, p_file_name); +} + + +/**@brief Function for the GAP initialization. + * + * @details This function will set up all the necessary GAP (Generic Access Profile) parameters of + * the device. It also sets the permissions and appearance. + */ +static void gap_params_init(void) +{ + uint32_t err_code; + ble_gap_conn_params_t gap_conn_params; + ble_gap_conn_sec_mode_t sec_mode; + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); + + err_code = sd_ble_gap_device_name_set(&sec_mode, + (const uint8_t *) DEVICE_NAME, + strlen(DEVICE_NAME)); + APP_ERROR_CHECK(err_code); + + memset(&gap_conn_params, 0, sizeof(gap_conn_params)); + + gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; + gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; + gap_conn_params.slave_latency = SLAVE_LATENCY; + gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; + + err_code = sd_ble_gap_ppcp_set(&gap_conn_params); + APP_ERROR_CHECK(err_code); +} + + +/**@brief Function for handling the data from the Nordic UART Service. + * + * @details This function will process the data received from the Nordic UART BLE Service and send + * it to the UART module. + * + * @param[in] p_nus Nordic UART Service structure. + * @param[in] p_data Data to be send to UART module. + * @param[in] length Length of the data. + */ +/**@snippet [Handling the data received over BLE] */ +static void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length) +{ + rt_kprintf("Received data from BLE NUS. Writing data on UART.\r\n"); + + for (uint32_t i = 0; i < length; i++) + { + rt_kprintf("%02x ", p_data[i]); + } + + // ble_send(p_data, length); + + if (rx_notify != RT_NULL) + { + rx_notify(p_data, length); + } +} +/**@snippet [Handling the data received over BLE] */ + + +/**@brief Function for initializing services that will be used by the application. + */ +static void services_init(void) +{ + uint32_t err_code; + ble_nus_init_t nus_init; + + memset(&nus_init, 0, sizeof(nus_init)); + + nus_init.data_handler = nus_data_handler; + + err_code = ble_nus_init(&m_nus, &nus_init); + APP_ERROR_CHECK(err_code); +} + + +/**@brief Function for handling an event from the Connection Parameters Module. + * + * @details This function will be called for all events in the Connection Parameters Module + * which are passed to the application. + * + * @note All this function does is to disconnect. This could have been done by simply setting + * the disconnect_on_fail config parameter, but instead we use the event handler + * mechanism to demonstrate its use. + * + * @param[in] p_evt Event received from the Connection Parameters Module. + */ +static void on_conn_params_evt(ble_conn_params_evt_t * p_evt) +{ + uint32_t err_code; + + if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) + { + err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); + APP_ERROR_CHECK(err_code); + } +} + + +/**@brief Function for handling errors from the Connection Parameters module. + * + * @param[in] nrf_error Error code containing information about what went wrong. + */ +static void conn_params_error_handler(uint32_t nrf_error) +{ + APP_ERROR_HANDLER(nrf_error); +} + + +/**@brief Function for initializing the Connection Parameters module. + */ +static void conn_params_init(void) +{ + uint32_t err_code; + ble_conn_params_init_t cp_init; + + memset(&cp_init, 0, sizeof(cp_init)); + + cp_init.p_conn_params = NULL; + cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; + cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; + cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; + cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; + cp_init.disconnect_on_fail = false; + cp_init.evt_handler = on_conn_params_evt; + cp_init.error_handler = conn_params_error_handler; + + err_code = ble_conn_params_init(&cp_init); + APP_ERROR_CHECK(err_code); +} + +/**@brief Function for handling advertising events. + * + * @details This function will be called for advertising events which are passed to the application. + * + * @param[in] ble_adv_evt Advertising event. + */ +static void on_adv_evt(ble_adv_evt_t ble_adv_evt) +{ + // uint32_t err_code; + + switch (ble_adv_evt) + { + case BLE_ADV_EVT_FAST: + // err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING); + // APP_ERROR_CHECK(err_code); + stack_state = STACK_STATE_ADV; + rt_kprintf("fast advert\n"); + break; + case BLE_ADV_EVT_IDLE: + // sleep_mode_enter(); + stack_state = STACK_STATE_IDLE; + rt_kprintf("advert idle\n"); + break; + default: + break; + } +} + + +/**@brief Function for the application's SoftDevice event handler. + * + * @param[in] p_ble_evt SoftDevice event. + */ +static void on_ble_evt(ble_evt_t * p_ble_evt) +{ + uint32_t err_code; + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + // err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); + // APP_ERROR_CHECK(err_code); + m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + stack_state = STACK_STATE_CON; + rt_kprintf("Connected\r\n"); + break; // BLE_GAP_EVT_CONNECTED + + case BLE_GAP_EVT_DISCONNECTED: + // err_code = bsp_indication_set(BSP_INDICATE_IDLE); + // APP_ERROR_CHECK(err_code); + m_conn_handle = BLE_CONN_HANDLE_INVALID; + stack_state = STACK_STATE_DISC; + rt_kprintf("Disconnected\r\n"); + break; // BLE_GAP_EVT_DISCONNECTED + + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + // Pairing not supported + err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); + APP_ERROR_CHECK(err_code); + break; // BLE_GAP_EVT_SEC_PARAMS_REQUEST + + case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: + { + ble_gap_data_length_params_t dl_params; + + // Clearing the struct will effectivly set members to @ref BLE_GAP_DATA_LENGTH_AUTO + memset(&dl_params, 0, sizeof(ble_gap_data_length_params_t)); + err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, &dl_params, NULL); + APP_ERROR_CHECK(err_code); + } break; + + case BLE_GATTS_EVT_SYS_ATTR_MISSING: + // No system attributes have been stored. + err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); + APP_ERROR_CHECK(err_code); + break; // BLE_GATTS_EVT_SYS_ATTR_MISSING + + case BLE_GATTC_EVT_TIMEOUT: + // Disconnect on GATT Client timeout event. + err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, + BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + APP_ERROR_CHECK(err_code); + break; // BLE_GATTC_EVT_TIMEOUT + + case BLE_GATTS_EVT_TIMEOUT: + // Disconnect on GATT Server timeout event. + err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, + BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + APP_ERROR_CHECK(err_code); + break; // BLE_GATTS_EVT_TIMEOUT + + case BLE_EVT_USER_MEM_REQUEST: + err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gattc_evt.conn_handle, NULL); + APP_ERROR_CHECK(err_code); + break; // BLE_EVT_USER_MEM_REQUEST + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + { + ble_gatts_evt_rw_authorize_request_t req; + ble_gatts_rw_authorize_reply_params_t auth_reply; + + req = p_ble_evt->evt.gatts_evt.params.authorize_request; + + if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) + { + if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || + (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || + (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) + { + if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + } + else + { + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; + } + auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; + err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, + &auth_reply); + APP_ERROR_CHECK(err_code); + } + } + } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for dispatching a SoftDevice event to all modules with a SoftDevice + * event handler. + * + * @details This function is called from the SoftDevice event interrupt handler after a + * SoftDevice event has been received. + * + * @param[in] p_ble_evt SoftDevice event. + */ +static void ble_evt_dispatch(ble_evt_t * p_ble_evt) +{ + if (rt_mq_send(stack_evt_mq, p_ble_evt, p_ble_evt->header.evt_len) != RT_EOK) + { + rt_kprintf("dispatch malloc failure\n"); + } + else + { + rt_event_send(stack_event, STACK_EV_DISPATCH); + } +} + +static rt_err_t evt_dispatch_worker(void) +{ + ble_evt_t * p_ble_evt = (ble_evt_t *)evt_sample; + rt_err_t err; + + err = rt_mq_recv(stack_evt_mq, (void*)evt_sample, BLE_STACK_EVT_MSG_BUF_SIZE, RT_WAITING_NO); + + if (RT_EOK == err) + { + ble_conn_params_on_ble_evt(p_ble_evt); + nrf_ble_gatt_on_ble_evt(&m_gatt, p_ble_evt); + ble_nus_on_ble_evt(&m_nus, p_ble_evt); + on_ble_evt(p_ble_evt); + ble_advertising_on_ble_evt(p_ble_evt); + // bsp_btn_ble_on_ble_evt(p_ble_evt); + + rt_kprintf("ble evt dispatch\n"); + } + + return err; +} + +static uint32_t _softdevice_evt_schedule(void) +{ + rt_sem_release(sd_evt_sem); + + return NRF_SUCCESS; +} + +/**@brief Function for the SoftDevice initialization. + * + * @details This function initializes the SoftDevice and the BLE event interrupt. + */ +static void ble_stack_init(void) +{ + uint32_t err_code; + + nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC; + + // Initialize SoftDevice. + SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, _softdevice_evt_schedule); + + // Fetch the start address of the application RAM. + uint32_t ram_start = 0; + err_code = softdevice_app_ram_start_get(&ram_start); + APP_ERROR_CHECK(err_code); + + // Overwrite some of the default configurations for the BLE stack. + ble_cfg_t ble_cfg; + + // Configure the maximum number of connections. + memset(&ble_cfg, 0, sizeof(ble_cfg)); + ble_cfg.gap_cfg.role_count_cfg.periph_role_count = BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT; + ble_cfg.gap_cfg.role_count_cfg.central_role_count = 0; + ble_cfg.gap_cfg.role_count_cfg.central_sec_count = 0; + err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, ram_start); + APP_ERROR_CHECK(err_code); + + // Configure the maximum ATT MTU. + memset(&ble_cfg, 0x00, sizeof(ble_cfg)); + ble_cfg.conn_cfg.conn_cfg_tag = CONN_CFG_TAG; + ble_cfg.conn_cfg.params.gatt_conn_cfg.att_mtu = NRF_BLE_GATT_MAX_MTU_SIZE; + err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &ble_cfg, ram_start); + APP_ERROR_CHECK(err_code); + + // Configure the maximum event length. + memset(&ble_cfg, 0x00, sizeof(ble_cfg)); + ble_cfg.conn_cfg.conn_cfg_tag = CONN_CFG_TAG; + ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = 320; + ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count = BLE_GAP_CONN_COUNT_DEFAULT; + err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, ram_start); + APP_ERROR_CHECK(err_code); + + // Enable BLE stack. + err_code = softdevice_enable(&ram_start); + APP_ERROR_CHECK(err_code); + + // Subscribe for BLE events. + err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch); + APP_ERROR_CHECK(err_code); +} + +/**@brief Function for handling events from the GATT library. */ +static void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, const nrf_ble_gatt_evt_t * p_evt) +{ + if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)) + { + m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH; + rt_kprintf("Data len is set to 0x%X(%d)\r\n", m_ble_nus_max_data_len, m_ble_nus_max_data_len); + } + rt_kprintf("ATT MTU exchange completed. central 0x%x peripheral 0x%x\r\n", p_gatt->att_mtu_desired_central, p_gatt->att_mtu_desired_periph); +} + +/**@brief Function for initializing the GATT library. */ +static void gatt_init(void) +{ + ret_code_t err_code; + + err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler); + APP_ERROR_CHECK(err_code); + + err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, 64); + APP_ERROR_CHECK(err_code); +} + +/**@brief Function for initializing the Advertising functionality. + */ +static void advertising_init(void) +{ + uint32_t err_code; + ble_advdata_t advdata; + ble_advdata_t scanrsp; + ble_adv_modes_config_t options; + + // Build advertising data struct to pass into @ref ble_advertising_init. + memset(&advdata, 0, sizeof(advdata)); + advdata.name_type = BLE_ADVDATA_FULL_NAME; + advdata.include_appearance = false; + advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE; + + memset(&scanrsp, 0, sizeof(scanrsp)); + scanrsp.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]); + scanrsp.uuids_complete.p_uuids = m_adv_uuids; + + memset(&options, 0, sizeof(options)); + options.ble_adv_fast_enabled = true; + options.ble_adv_fast_interval = APP_ADV_INTERVAL; + options.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS; + + err_code = ble_advertising_init(&advdata, &scanrsp, &options, on_adv_evt, NULL); + APP_ERROR_CHECK(err_code); + + ble_advertising_conn_cfg_tag_set(CONN_CFG_TAG); +} + +/**@brief Function for handling app_uart events. + * + * @details This function will receive a single character from the app_uart module and append it to + * a string. The string will be be sent over BLE when the last character received was a + * 'new line' '\n' (hex 0x0A) or if the string has reached the maximum data length. + */ +/**@snippet [Handling the data received over UART] */ +void uart_event_handle(rt_device_t uart) +{ + uint8_t data_array[BLE_NUS_MAX_DATA_LEN]; + rt_size_t size = 0; + uint32_t err_code; + + size = rt_device_read(uart, 0, data_array, BLE_NUS_MAX_DATA_LEN); + + if (size <= 0) + { + return; + } + + do + { + err_code = ble_nus_string_send(&m_nus, data_array, size); + if ( (err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_BUSY) ) + { + APP_ERROR_CHECK(err_code); + } + } while (err_code == NRF_ERROR_BUSY); +} +/**@snippet [Handling the data received over UART] */ + +/**@brief Function for initializing the UART module. + */ +/**@snippet [UART Initialization] */ +static rt_bool_t _stack_init(void) +{ + uint32_t err_code; + + stack_event = rt_event_create("stackev", RT_IPC_FLAG_FIFO); + sd_evt_sem = rt_sem_create("sdsem", 0, RT_IPC_FLAG_FIFO); + stack_evt_mq = rt_mq_create("stackmq", BLE_STACK_EVT_MSG_BUF_SIZE, STACK_EVT_MQ_NUM, RT_IPC_FLAG_FIFO); + evt_sample = rt_malloc(BLE_STACK_EVT_MSG_BUF_SIZE); + + if (!stack_event || !sd_evt_sem || !stack_evt_mq || !evt_sample) + { + rt_kprintf("uart rx sem create failure\n"); + return RT_FALSE; + } + + // Initialize. + err_code = app_timer_init(); + APP_ERROR_CHECK(err_code); + + ble_stack_init(); + gap_params_init(); + gatt_init(); + services_init(); + advertising_init(); + conn_params_init(); + + return RT_TRUE; +} + +/**@brief Application main function. + */ +static void _stack_thread(void *parameter) +{ + rt_tick_t next_timeout = (rt_tick_t)RT_WAITING_FOREVER; + + FAST_ADV(); + // Enter main loop. + for (;;) + { + rt_uint32_t event = 0; + rt_tick_t dispatch_timeout = RT_WAITING_NO; + + rt_event_recv(stack_event, STACK_EV_DISCON | STACK_EV_DISPATCH | STACK_EV_KEY, + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, next_timeout, &event); + + if (evt_dispatch_worker() != RT_EOK) + { + dispatch_timeout = (rt_tick_t)RT_WAITING_FOREVER; + } + + if (event & STACK_EV_DISCON) + { + if (BLE_CONN_HANDLE_INVALID != m_conn_handle) + { + sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + } + } + + if (event & STACK_EV_KEY) + { + if (stack_state != STACK_STATE_CON && stack_state != STACK_STATE_ADV) + { + FAST_ADV(); + } + } + + next_timeout = (rt_tick_t)RT_WAITING_FOREVER; + + if (dispatch_timeout < next_timeout) + { + next_timeout = dispatch_timeout; + } + } +} + +static void _softdevice_thread(void* parameter) +{ + for (;;) + { + rt_sem_take(sd_evt_sem, RT_WAITING_FOREVER); + intern_softdevice_events_execute(); + } +} + +rt_err_t ble_init(void) +{ + rt_thread_t thread; + + _stack_init(); + + thread = rt_thread_create("sdth", _softdevice_thread, RT_NULL, 512, 0, 10); + + if (thread != RT_NULL) + { + rt_thread_startup(thread); + } + else + { + return RT_ERROR; + } + + thread = rt_thread_create("bleth", _stack_thread, RT_NULL, 2048, 1, 10); + + if (thread != RT_NULL) + { + return rt_thread_startup(thread); + } + + return RT_ERROR; +} diff --git a/bsp/nrf52832/applications/sdk_config.h b/bsp/nrf52832/applications/sdk_config.h new file mode 100644 index 0000000000000000000000000000000000000000..72abeeed7ca34d014b2a3e936460e9d6b65ae079 --- /dev/null +++ b/bsp/nrf52832/applications/sdk_config.h @@ -0,0 +1,3991 @@ + + +#ifndef SDK_CONFIG_H +#define SDK_CONFIG_H +// <<< Use Configuration Wizard in Context Menu >>>\n +#ifdef USE_APP_CONFIG +#include "app_config.h" +#endif +// nRF_BLE + +//========================================================== +// BLE_ADVERTISING_ENABLED - ble_advertising - Advertising module + + +#ifndef BLE_ADVERTISING_ENABLED +#define BLE_ADVERTISING_ENABLED 1 +#endif + +// BLE_DTM_ENABLED - ble_dtm - Module for testing RF/PHY using DTM commands + + +#ifndef BLE_DTM_ENABLED +#define BLE_DTM_ENABLED 0 +#endif + +// BLE_RACP_ENABLED - ble_racp - Record Access Control Point library + + +#ifndef BLE_RACP_ENABLED +#define BLE_RACP_ENABLED 0 +#endif + +// NRF_BLE_GATT_ENABLED - nrf_ble_gatt - GATT module +//========================================================== +#ifndef NRF_BLE_GATT_ENABLED +#define NRF_BLE_GATT_ENABLED 1 +#endif +#if NRF_BLE_GATT_ENABLED +// NRF_BLE_GATT_MAX_MTU_SIZE - Static maximum MTU size that is passed to the @ref sd_ble_enable function. +#ifndef NRF_BLE_GATT_MAX_MTU_SIZE +#define NRF_BLE_GATT_MAX_MTU_SIZE 158 +#endif + +#endif //NRF_BLE_GATT_ENABLED +// + +// NRF_BLE_QWR_ENABLED - nrf_ble_qwr - Queued writes support module (prepare/execute write) + + +#ifndef NRF_BLE_QWR_ENABLED +#define NRF_BLE_QWR_ENABLED 0 +#endif + +// PEER_MANAGER_ENABLED - peer_manager - Peer Manager + + +#ifndef PEER_MANAGER_ENABLED +#define PEER_MANAGER_ENABLED 0 +#endif + +// +//========================================================== + +// nRF_BLE_Services + +//========================================================== +// BLE_ANCS_C_ENABLED - ble_ancs_c - Apple Notification Service Client + + +#ifndef BLE_ANCS_C_ENABLED +#define BLE_ANCS_C_ENABLED 0 +#endif + +// BLE_ANS_C_ENABLED - ble_ans_c - Alert Notification Service Client + + +#ifndef BLE_ANS_C_ENABLED +#define BLE_ANS_C_ENABLED 0 +#endif + +// BLE_BAS_C_ENABLED - ble_bas_c - Battery Service Client + + +#ifndef BLE_BAS_C_ENABLED +#define BLE_BAS_C_ENABLED 0 +#endif + +// BLE_BAS_ENABLED - ble_bas - Battery Service + + +#ifndef BLE_BAS_ENABLED +#define BLE_BAS_ENABLED 0 +#endif + +// BLE_CSCS_ENABLED - ble_cscs - Cycling Speed and Cadence Service + + +#ifndef BLE_CSCS_ENABLED +#define BLE_CSCS_ENABLED 0 +#endif + +// BLE_CTS_C_ENABLED - ble_cts_c - Current Time Service Client + + +#ifndef BLE_CTS_C_ENABLED +#define BLE_CTS_C_ENABLED 0 +#endif + +// BLE_DIS_ENABLED - ble_dis - Device Information Service + + +#ifndef BLE_DIS_ENABLED +#define BLE_DIS_ENABLED 0 +#endif + +// BLE_GLS_ENABLED - ble_gls - Glucose Service + + +#ifndef BLE_GLS_ENABLED +#define BLE_GLS_ENABLED 0 +#endif + +// BLE_HIDS_ENABLED - ble_hids - Human Interface Device Service + + +#ifndef BLE_HIDS_ENABLED +#define BLE_HIDS_ENABLED 0 +#endif + +// BLE_HRS_C_ENABLED - ble_hrs_c - Heart Rate Service Client +//========================================================== +#ifndef BLE_HRS_C_ENABLED +#define BLE_HRS_C_ENABLED 0 +#endif +#if BLE_HRS_C_ENABLED +// BLE_HRS_C_RR_INTERVALS_MAX_CNT - Maximum number of RR_INTERVALS per notification to be decoded +#ifndef BLE_HRS_C_RR_INTERVALS_MAX_CNT +#define BLE_HRS_C_RR_INTERVALS_MAX_CNT 30 +#endif + +#endif //BLE_HRS_C_ENABLED +// + +// BLE_HRS_ENABLED - ble_hrs - Heart Rate Service + + +#ifndef BLE_HRS_ENABLED +#define BLE_HRS_ENABLED 0 +#endif + +// BLE_HTS_ENABLED - ble_hts - Health Thermometer Service + + +#ifndef BLE_HTS_ENABLED +#define BLE_HTS_ENABLED 0 +#endif + +// BLE_IAS_C_ENABLED - ble_ias_c - Immediate Alert Service Client + + +#ifndef BLE_IAS_C_ENABLED +#define BLE_IAS_C_ENABLED 0 +#endif + +// BLE_IAS_ENABLED - ble_ias - Immediate Alert Service + + +#ifndef BLE_IAS_ENABLED +#define BLE_IAS_ENABLED 0 +#endif + +// BLE_LBS_C_ENABLED - ble_lbs_c - Nordic LED Button Service Client + + +#ifndef BLE_LBS_C_ENABLED +#define BLE_LBS_C_ENABLED 0 +#endif + +// BLE_LBS_ENABLED - ble_lbs - LED Button Service + + +#ifndef BLE_LBS_ENABLED +#define BLE_LBS_ENABLED 0 +#endif + +// BLE_LLS_ENABLED - ble_lls - Link Loss Service + + +#ifndef BLE_LLS_ENABLED +#define BLE_LLS_ENABLED 0 +#endif + +// BLE_NUS_C_ENABLED - ble_nus_c - Nordic UART Central Service + + +#ifndef BLE_NUS_C_ENABLED +#define BLE_NUS_C_ENABLED 0 +#endif + +// BLE_NUS_ENABLED - ble_nus - Nordic UART Service + + +#ifndef BLE_NUS_ENABLED +#define BLE_NUS_ENABLED 1 +#endif + +// BLE_RSCS_C_ENABLED - ble_rscs_c - Running Speed and Cadence Client + + +#ifndef BLE_RSCS_C_ENABLED +#define BLE_RSCS_C_ENABLED 0 +#endif + +// BLE_RSCS_ENABLED - ble_rscs - Running Speed and Cadence Service + + +#ifndef BLE_RSCS_ENABLED +#define BLE_RSCS_ENABLED 0 +#endif + +// BLE_TPS_ENABLED - ble_tps - TX Power Service + + +#ifndef BLE_TPS_ENABLED +#define BLE_TPS_ENABLED 0 +#endif + +// +//========================================================== + +// nRF_Drivers + +//========================================================== +// APP_USBD_ENABLED - app_usbd - USB Device library +//========================================================== +#ifndef APP_USBD_ENABLED +#define APP_USBD_ENABLED 0 +#endif +#if APP_USBD_ENABLED +// APP_USBD_VID - Vendor ID <0x0000-0xFFFF> + + +// Vendor ID ordered from USB IF: http://www.usb.org/developers/vendor/ + +#ifndef APP_USBD_VID +#define APP_USBD_VID 0 +#endif + +// APP_USBD_PID - Product ID <0x0000-0xFFFF> + + +// Selected Product ID + +#ifndef APP_USBD_PID +#define APP_USBD_PID 0 +#endif + +// APP_USBD_DEVICE_VER_MAJOR - Device version, major part <0-99> + + +// Device version, will be converted automatically to BCD notation. Use just decimal values. + +#ifndef APP_USBD_DEVICE_VER_MAJOR +#define APP_USBD_DEVICE_VER_MAJOR 1 +#endif + +// APP_USBD_DEVICE_VER_MINOR - Device version, minor part <0-99> + + +// Device version, will be converted automatically to BCD notation. Use just decimal values. + +#ifndef APP_USBD_DEVICE_VER_MINOR +#define APP_USBD_DEVICE_VER_MINOR 0 +#endif + +#endif //APP_USBD_ENABLED +// + +// CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver +//========================================================== +#ifndef CLOCK_ENABLED +#define CLOCK_ENABLED 1 +#endif +#if CLOCK_ENABLED +// CLOCK_CONFIG_XTAL_FREQ - HF XTAL Frequency + +// <0=> Default (64 MHz) + +#ifndef CLOCK_CONFIG_XTAL_FREQ +#define CLOCK_CONFIG_XTAL_FREQ 0 +#endif + +// CLOCK_CONFIG_LF_SRC - LF Clock Source + +// <0=> RC +// <1=> XTAL +// <2=> Synth + +#ifndef CLOCK_CONFIG_LF_SRC +#define CLOCK_CONFIG_LF_SRC 1 +#endif + +// CLOCK_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef CLOCK_CONFIG_IRQ_PRIORITY +#define CLOCK_CONFIG_IRQ_PRIORITY 7 +#endif + +// CLOCK_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef CLOCK_CONFIG_LOG_ENABLED +#define CLOCK_CONFIG_LOG_ENABLED 0 +#endif +#if CLOCK_CONFIG_LOG_ENABLED +// CLOCK_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef CLOCK_CONFIG_LOG_LEVEL +#define CLOCK_CONFIG_LOG_LEVEL 3 +#endif + +// CLOCK_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef CLOCK_CONFIG_INFO_COLOR +#define CLOCK_CONFIG_INFO_COLOR 0 +#endif + +// CLOCK_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef CLOCK_CONFIG_DEBUG_COLOR +#define CLOCK_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //CLOCK_CONFIG_LOG_ENABLED +// + +#endif //CLOCK_ENABLED +// + +// COMP_ENABLED - nrf_drv_comp - COMP peripheral driver +//========================================================== +#ifndef COMP_ENABLED +#define COMP_ENABLED 0 +#endif +#if COMP_ENABLED +// COMP_CONFIG_REF - Reference voltage + +// <0=> Internal 1.2V +// <1=> Internal 1.8V +// <2=> Internal 2.4V +// <4=> VDD +// <7=> ARef + +#ifndef COMP_CONFIG_REF +#define COMP_CONFIG_REF 1 +#endif + +// COMP_CONFIG_MAIN_MODE - Main mode + +// <0=> Single ended +// <1=> Differential + +#ifndef COMP_CONFIG_MAIN_MODE +#define COMP_CONFIG_MAIN_MODE 0 +#endif + +// COMP_CONFIG_SPEED_MODE - Speed mode + +// <0=> Low power +// <1=> Normal +// <2=> High speed + +#ifndef COMP_CONFIG_SPEED_MODE +#define COMP_CONFIG_SPEED_MODE 2 +#endif + +// COMP_CONFIG_HYST - Hystheresis + +// <0=> No +// <1=> 50mV + +#ifndef COMP_CONFIG_HYST +#define COMP_CONFIG_HYST 0 +#endif + +// COMP_CONFIG_ISOURCE - Current Source + +// <0=> Off +// <1=> 2.5 uA +// <2=> 5 uA +// <3=> 10 uA + +#ifndef COMP_CONFIG_ISOURCE +#define COMP_CONFIG_ISOURCE 0 +#endif + +// COMP_CONFIG_INPUT - Analog input + +// <0=> 0 +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef COMP_CONFIG_INPUT +#define COMP_CONFIG_INPUT 0 +#endif + +// COMP_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef COMP_CONFIG_IRQ_PRIORITY +#define COMP_CONFIG_IRQ_PRIORITY 7 +#endif + +// COMP_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef COMP_CONFIG_LOG_ENABLED +#define COMP_CONFIG_LOG_ENABLED 0 +#endif +#if COMP_CONFIG_LOG_ENABLED +// COMP_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef COMP_CONFIG_LOG_LEVEL +#define COMP_CONFIG_LOG_LEVEL 3 +#endif + +// COMP_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef COMP_CONFIG_INFO_COLOR +#define COMP_CONFIG_INFO_COLOR 0 +#endif + +// COMP_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef COMP_CONFIG_DEBUG_COLOR +#define COMP_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //COMP_CONFIG_LOG_ENABLED +// + +#endif //COMP_ENABLED +// + +// EGU_ENABLED - nrf_drv_swi - SWI(EGU) peripheral driver +//========================================================== +#ifndef EGU_ENABLED +#define EGU_ENABLED 0 +#endif +#if EGU_ENABLED +// SWI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SWI_CONFIG_LOG_ENABLED +#define SWI_CONFIG_LOG_ENABLED 0 +#endif +#if SWI_CONFIG_LOG_ENABLED +// SWI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SWI_CONFIG_LOG_LEVEL +#define SWI_CONFIG_LOG_LEVEL 3 +#endif + +// SWI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SWI_CONFIG_INFO_COLOR +#define SWI_CONFIG_INFO_COLOR 0 +#endif + +// SWI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SWI_CONFIG_DEBUG_COLOR +#define SWI_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //SWI_CONFIG_LOG_ENABLED +// + +#endif //EGU_ENABLED +// + +// GPIOTE_ENABLED - nrf_drv_gpiote - GPIOTE peripheral driver +//========================================================== +#ifndef GPIOTE_ENABLED +#define GPIOTE_ENABLED 1 +#endif +#if GPIOTE_ENABLED +// GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins +#ifndef GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS +#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 4 +#endif + +// GPIOTE_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef GPIOTE_CONFIG_IRQ_PRIORITY +#define GPIOTE_CONFIG_IRQ_PRIORITY 7 +#endif + +// GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef GPIOTE_CONFIG_LOG_ENABLED +#define GPIOTE_CONFIG_LOG_ENABLED 0 +#endif +#if GPIOTE_CONFIG_LOG_ENABLED +// GPIOTE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef GPIOTE_CONFIG_LOG_LEVEL +#define GPIOTE_CONFIG_LOG_LEVEL 3 +#endif + +// GPIOTE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef GPIOTE_CONFIG_INFO_COLOR +#define GPIOTE_CONFIG_INFO_COLOR 0 +#endif + +// GPIOTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef GPIOTE_CONFIG_DEBUG_COLOR +#define GPIOTE_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //GPIOTE_CONFIG_LOG_ENABLED +// + +#endif //GPIOTE_ENABLED +// + +// I2S_ENABLED - nrf_drv_i2s - I2S peripheral driver +//========================================================== +#ifndef I2S_ENABLED +#define I2S_ENABLED 0 +#endif +#if I2S_ENABLED +// I2S_CONFIG_SCK_PIN - SCK pin <0-31> + + +#ifndef I2S_CONFIG_SCK_PIN +#define I2S_CONFIG_SCK_PIN 31 +#endif + +// I2S_CONFIG_LRCK_PIN - LRCK pin <1-31> + + +#ifndef I2S_CONFIG_LRCK_PIN +#define I2S_CONFIG_LRCK_PIN 30 +#endif + +// I2S_CONFIG_MCK_PIN - MCK pin +#ifndef I2S_CONFIG_MCK_PIN +#define I2S_CONFIG_MCK_PIN 255 +#endif + +// I2S_CONFIG_SDOUT_PIN - SDOUT pin <0-31> + + +#ifndef I2S_CONFIG_SDOUT_PIN +#define I2S_CONFIG_SDOUT_PIN 29 +#endif + +// I2S_CONFIG_SDIN_PIN - SDIN pin <0-31> + + +#ifndef I2S_CONFIG_SDIN_PIN +#define I2S_CONFIG_SDIN_PIN 28 +#endif + +// I2S_CONFIG_MASTER - Mode + +// <0=> Master +// <1=> Slave + +#ifndef I2S_CONFIG_MASTER +#define I2S_CONFIG_MASTER 0 +#endif + +// I2S_CONFIG_FORMAT - Format + +// <0=> I2S +// <1=> Aligned + +#ifndef I2S_CONFIG_FORMAT +#define I2S_CONFIG_FORMAT 0 +#endif + +// I2S_CONFIG_ALIGN - Alignment + +// <0=> Left +// <1=> Right + +#ifndef I2S_CONFIG_ALIGN +#define I2S_CONFIG_ALIGN 0 +#endif + +// I2S_CONFIG_SWIDTH - Sample width (bits) + +// <0=> 8 +// <1=> 16 +// <2=> 24 + +#ifndef I2S_CONFIG_SWIDTH +#define I2S_CONFIG_SWIDTH 1 +#endif + +// I2S_CONFIG_CHANNELS - Channels + +// <0=> Stereo +// <1=> Left +// <2=> Right + +#ifndef I2S_CONFIG_CHANNELS +#define I2S_CONFIG_CHANNELS 1 +#endif + +// I2S_CONFIG_MCK_SETUP - MCK behavior + +// <0=> Disabled +// <2147483648=> 32MHz/2 +// <1342177280=> 32MHz/3 +// <1073741824=> 32MHz/4 +// <805306368=> 32MHz/5 +// <671088640=> 32MHz/6 +// <536870912=> 32MHz/8 +// <402653184=> 32MHz/10 +// <369098752=> 32MHz/11 +// <285212672=> 32MHz/15 +// <268435456=> 32MHz/16 +// <201326592=> 32MHz/21 +// <184549376=> 32MHz/23 +// <142606336=> 32MHz/30 +// <138412032=> 32MHz/31 +// <134217728=> 32MHz/32 +// <100663296=> 32MHz/42 +// <68157440=> 32MHz/63 +// <34340864=> 32MHz/125 + +#ifndef I2S_CONFIG_MCK_SETUP +#define I2S_CONFIG_MCK_SETUP 536870912 +#endif + +// I2S_CONFIG_RATIO - MCK/LRCK ratio + +// <0=> 32x +// <1=> 48x +// <2=> 64x +// <3=> 96x +// <4=> 128x +// <5=> 192x +// <6=> 256x +// <7=> 384x +// <8=> 512x + +#ifndef I2S_CONFIG_RATIO +#define I2S_CONFIG_RATIO 2000 +#endif + +// I2S_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef I2S_CONFIG_IRQ_PRIORITY +#define I2S_CONFIG_IRQ_PRIORITY 7 +#endif + +// I2S_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef I2S_CONFIG_LOG_ENABLED +#define I2S_CONFIG_LOG_ENABLED 0 +#endif +#if I2S_CONFIG_LOG_ENABLED +// I2S_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef I2S_CONFIG_LOG_LEVEL +#define I2S_CONFIG_LOG_LEVEL 3 +#endif + +// I2S_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef I2S_CONFIG_INFO_COLOR +#define I2S_CONFIG_INFO_COLOR 0 +#endif + +// I2S_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef I2S_CONFIG_DEBUG_COLOR +#define I2S_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //I2S_CONFIG_LOG_ENABLED +// + +#endif //I2S_ENABLED +// + +// LPCOMP_ENABLED - nrf_drv_lpcomp - LPCOMP peripheral driver +//========================================================== +#ifndef LPCOMP_ENABLED +#define LPCOMP_ENABLED 0 +#endif +#if LPCOMP_ENABLED +// LPCOMP_CONFIG_REFERENCE - Reference voltage + +// <0=> Supply 1/8 +// <1=> Supply 2/8 +// <2=> Supply 3/8 +// <3=> Supply 4/8 +// <4=> Supply 5/8 +// <5=> Supply 6/8 +// <6=> Supply 7/8 +// <8=> Supply 1/16 (nRF52) +// <9=> Supply 3/16 (nRF52) +// <10=> Supply 5/16 (nRF52) +// <11=> Supply 7/16 (nRF52) +// <12=> Supply 9/16 (nRF52) +// <13=> Supply 11/16 (nRF52) +// <14=> Supply 13/16 (nRF52) +// <15=> Supply 15/16 (nRF52) +// <7=> External Ref 0 +// <65543=> External Ref 1 + +#ifndef LPCOMP_CONFIG_REFERENCE +#define LPCOMP_CONFIG_REFERENCE 3 +#endif + +// LPCOMP_CONFIG_DETECTION - Detection + +// <0=> Crossing +// <1=> Up +// <2=> Down + +#ifndef LPCOMP_CONFIG_DETECTION +#define LPCOMP_CONFIG_DETECTION 2 +#endif + +// LPCOMP_CONFIG_INPUT - Analog input + +// <0=> 0 +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef LPCOMP_CONFIG_INPUT +#define LPCOMP_CONFIG_INPUT 0 +#endif + +// LPCOMP_CONFIG_HYST - Hysteresis + + +#ifndef LPCOMP_CONFIG_HYST +#define LPCOMP_CONFIG_HYST 0 +#endif + +// LPCOMP_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef LPCOMP_CONFIG_IRQ_PRIORITY +#define LPCOMP_CONFIG_IRQ_PRIORITY 7 +#endif + +// LPCOMP_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef LPCOMP_CONFIG_LOG_ENABLED +#define LPCOMP_CONFIG_LOG_ENABLED 0 +#endif +#if LPCOMP_CONFIG_LOG_ENABLED +// LPCOMP_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef LPCOMP_CONFIG_LOG_LEVEL +#define LPCOMP_CONFIG_LOG_LEVEL 3 +#endif + +// LPCOMP_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef LPCOMP_CONFIG_INFO_COLOR +#define LPCOMP_CONFIG_INFO_COLOR 0 +#endif + +// LPCOMP_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef LPCOMP_CONFIG_DEBUG_COLOR +#define LPCOMP_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //LPCOMP_CONFIG_LOG_ENABLED +// + +#endif //LPCOMP_ENABLED +// + +// PDM_ENABLED - nrf_drv_pdm - PDM peripheral driver +//========================================================== +#ifndef PDM_ENABLED +#define PDM_ENABLED 0 +#endif +#if PDM_ENABLED +// PDM_CONFIG_MODE - Mode + +// <0=> Stereo +// <1=> Mono + +#ifndef PDM_CONFIG_MODE +#define PDM_CONFIG_MODE 1 +#endif + +// PDM_CONFIG_EDGE - Edge + +// <0=> Left falling +// <1=> Left rising + +#ifndef PDM_CONFIG_EDGE +#define PDM_CONFIG_EDGE 0 +#endif + +// PDM_CONFIG_CLOCK_FREQ - Clock frequency + +// <134217728=> 1000k +// <138412032=> 1032k (default) +// <142606336=> 1067k + +#ifndef PDM_CONFIG_CLOCK_FREQ +#define PDM_CONFIG_CLOCK_FREQ 138412032 +#endif + +// PDM_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef PDM_CONFIG_IRQ_PRIORITY +#define PDM_CONFIG_IRQ_PRIORITY 7 +#endif + +// PDM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef PDM_CONFIG_LOG_ENABLED +#define PDM_CONFIG_LOG_ENABLED 0 +#endif +#if PDM_CONFIG_LOG_ENABLED +// PDM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PDM_CONFIG_LOG_LEVEL +#define PDM_CONFIG_LOG_LEVEL 3 +#endif + +// PDM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PDM_CONFIG_INFO_COLOR +#define PDM_CONFIG_INFO_COLOR 0 +#endif + +// PDM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PDM_CONFIG_DEBUG_COLOR +#define PDM_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //PDM_CONFIG_LOG_ENABLED +// + +#endif //PDM_ENABLED +// + +// PERIPHERAL_RESOURCE_SHARING_ENABLED - nrf_drv_common - Peripheral drivers common module +//========================================================== +#ifndef PERIPHERAL_RESOURCE_SHARING_ENABLED +#define PERIPHERAL_RESOURCE_SHARING_ENABLED 0 +#endif +#if PERIPHERAL_RESOURCE_SHARING_ENABLED +// COMMON_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef COMMON_CONFIG_LOG_ENABLED +#define COMMON_CONFIG_LOG_ENABLED 0 +#endif +#if COMMON_CONFIG_LOG_ENABLED +// COMMON_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef COMMON_CONFIG_LOG_LEVEL +#define COMMON_CONFIG_LOG_LEVEL 3 +#endif + +// COMMON_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef COMMON_CONFIG_INFO_COLOR +#define COMMON_CONFIG_INFO_COLOR 0 +#endif + +// COMMON_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef COMMON_CONFIG_DEBUG_COLOR +#define COMMON_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //COMMON_CONFIG_LOG_ENABLED +// + +#endif //PERIPHERAL_RESOURCE_SHARING_ENABLED +// + +// POWER_ENABLED - nrf_drv_power - POWER peripheral driver +//========================================================== +#ifndef POWER_ENABLED +#define POWER_ENABLED 0 +#endif +#if POWER_ENABLED +// POWER_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef POWER_CONFIG_IRQ_PRIORITY +#define POWER_CONFIG_IRQ_PRIORITY 7 +#endif + +// POWER_CONFIG_DEFAULT_DCDCEN - The default configuration of main DCDC regulator + + +// This settings means only that components for DCDC regulator are installed and it can be enabled. + +#ifndef POWER_CONFIG_DEFAULT_DCDCEN +#define POWER_CONFIG_DEFAULT_DCDCEN 0 +#endif + +// POWER_CONFIG_DEFAULT_DCDCENHV - The default configuration of High Voltage DCDC regulator + + +// This settings means only that components for DCDC regulator are installed and it can be enabled. + +#ifndef POWER_CONFIG_DEFAULT_DCDCENHV +#define POWER_CONFIG_DEFAULT_DCDCENHV 0 +#endif + +#endif //POWER_ENABLED +// + +// PPI_ENABLED - nrf_drv_ppi - PPI peripheral driver +//========================================================== +#ifndef PPI_ENABLED +#define PPI_ENABLED 0 +#endif +#if PPI_ENABLED +// PPI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef PPI_CONFIG_LOG_ENABLED +#define PPI_CONFIG_LOG_ENABLED 0 +#endif +#if PPI_CONFIG_LOG_ENABLED +// PPI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PPI_CONFIG_LOG_LEVEL +#define PPI_CONFIG_LOG_LEVEL 3 +#endif + +// PPI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PPI_CONFIG_INFO_COLOR +#define PPI_CONFIG_INFO_COLOR 0 +#endif + +// PPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PPI_CONFIG_DEBUG_COLOR +#define PPI_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //PPI_CONFIG_LOG_ENABLED +// + +#endif //PPI_ENABLED +// + +// PWM_ENABLED - nrf_drv_pwm - PWM peripheral driver +//========================================================== +#ifndef PWM_ENABLED +#define PWM_ENABLED 1 +#endif +#if PWM_ENABLED +// PWM_DEFAULT_CONFIG_OUT0_PIN - Out0 pin <0-31> + + +#ifndef PWM_DEFAULT_CONFIG_OUT0_PIN +#define PWM_DEFAULT_CONFIG_OUT0_PIN 2 +#endif + +// PWM_DEFAULT_CONFIG_OUT1_PIN - Out1 pin <0-31> + + +#ifndef PWM_DEFAULT_CONFIG_OUT1_PIN +#define PWM_DEFAULT_CONFIG_OUT1_PIN 31 +#endif + +// PWM_DEFAULT_CONFIG_OUT2_PIN - Out2 pin <0-31> + + +#ifndef PWM_DEFAULT_CONFIG_OUT2_PIN +#define PWM_DEFAULT_CONFIG_OUT2_PIN 31 +#endif + +// PWM_DEFAULT_CONFIG_OUT3_PIN - Out3 pin <0-31> + + +#ifndef PWM_DEFAULT_CONFIG_OUT3_PIN +#define PWM_DEFAULT_CONFIG_OUT3_PIN 31 +#endif + +// PWM_DEFAULT_CONFIG_BASE_CLOCK - Base clock + +// <0=> 16 MHz +// <1=> 8 MHz +// <2=> 4 MHz +// <3=> 2 MHz +// <4=> 1 MHz +// <5=> 500 kHz +// <6=> 250 kHz +// <7=> 125 MHz + +#ifndef PWM_DEFAULT_CONFIG_BASE_CLOCK +#define PWM_DEFAULT_CONFIG_BASE_CLOCK 7 +#endif + +// PWM_DEFAULT_CONFIG_COUNT_MODE - Count mode + +// <0=> Up +// <1=> Up and Down + +#ifndef PWM_DEFAULT_CONFIG_COUNT_MODE +#define PWM_DEFAULT_CONFIG_COUNT_MODE 0 +#endif + +// PWM_DEFAULT_CONFIG_TOP_VALUE - Top value +#ifndef PWM_DEFAULT_CONFIG_TOP_VALUE +#define PWM_DEFAULT_CONFIG_TOP_VALUE 46 +#endif + +// PWM_DEFAULT_CONFIG_LOAD_MODE - Load mode + +// <0=> Common +// <1=> Grouped +// <2=> Individual +// <3=> Waveform + +#ifndef PWM_DEFAULT_CONFIG_LOAD_MODE +#define PWM_DEFAULT_CONFIG_LOAD_MODE 0 +#endif + +// PWM_DEFAULT_CONFIG_STEP_MODE - Step mode + +// <0=> Auto +// <1=> Triggered + +#ifndef PWM_DEFAULT_CONFIG_STEP_MODE +#define PWM_DEFAULT_CONFIG_STEP_MODE 0 +#endif + +// PWM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef PWM_DEFAULT_CONFIG_IRQ_PRIORITY +#define PWM_DEFAULT_CONFIG_IRQ_PRIORITY 7 +#endif + +// PWM0_ENABLED - Enable PWM0 instance + + +#ifndef PWM0_ENABLED +#define PWM0_ENABLED 1 +#endif + +// PWM1_ENABLED - Enable PWM1 instance + + +#ifndef PWM1_ENABLED +#define PWM1_ENABLED 0 +#endif + +// PWM2_ENABLED - Enable PWM2 instance + + +#ifndef PWM2_ENABLED +#define PWM2_ENABLED 0 +#endif + +// PWM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef PWM_CONFIG_LOG_ENABLED +#define PWM_CONFIG_LOG_ENABLED 0 +#endif +#if PWM_CONFIG_LOG_ENABLED +// PWM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PWM_CONFIG_LOG_LEVEL +#define PWM_CONFIG_LOG_LEVEL 3 +#endif + +// PWM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PWM_CONFIG_INFO_COLOR +#define PWM_CONFIG_INFO_COLOR 0 +#endif + +// PWM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PWM_CONFIG_DEBUG_COLOR +#define PWM_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //PWM_CONFIG_LOG_ENABLED +// + +// PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED - Enables nRF52 Anomaly 109 workaround for PWM. + +// The workaround uses interrupts to wake up the CPU and ensure +// it is active when PWM is about to start a DMA transfer. For +// initial transfer, done when a playback is started via PPI, +// a specific EGU instance is used to generate the interrupt. +// During the playback, the PWM interrupt triggered on SEQEND +// event of a preceding sequence is used to protect the transfer +// done for the next sequence to be played. +//========================================================== +#ifndef PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED +#define PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 0 +#endif +#if PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED +// PWM_NRF52_ANOMALY_109_EGU_INSTANCE - EGU instance used by the nRF52 Anomaly 109 workaround for PWM. + +// <0=> EGU0 +// <1=> EGU1 +// <2=> EGU2 +// <3=> EGU3 +// <4=> EGU4 +// <5=> EGU5 + +#ifndef PWM_NRF52_ANOMALY_109_EGU_INSTANCE +#define PWM_NRF52_ANOMALY_109_EGU_INSTANCE 5 +#endif + +#endif //PWM_NRF52_ANOMALY_109_WORKAROUND_ENABLED +// + +#endif //PWM_ENABLED +// + +// QDEC_ENABLED - nrf_drv_qdec - QDEC peripheral driver +//========================================================== +#ifndef QDEC_ENABLED +#define QDEC_ENABLED 0 +#endif +#if QDEC_ENABLED +// QDEC_CONFIG_REPORTPER - Report period + +// <0=> 10 Samples +// <1=> 40 Samples +// <2=> 80 Samples +// <3=> 120 Samples +// <4=> 160 Samples +// <5=> 200 Samples +// <6=> 240 Samples +// <7=> 280 Samples + +#ifndef QDEC_CONFIG_REPORTPER +#define QDEC_CONFIG_REPORTPER 0 +#endif + +// QDEC_CONFIG_SAMPLEPER - Sample period + +// <0=> 128 us +// <1=> 256 us +// <2=> 512 us +// <3=> 1024 us +// <4=> 2048 us +// <5=> 4096 us +// <6=> 8192 us +// <7=> 16384 us + +#ifndef QDEC_CONFIG_SAMPLEPER +#define QDEC_CONFIG_SAMPLEPER 7 +#endif + +// QDEC_CONFIG_PIO_A - A pin <0-31> + + +#ifndef QDEC_CONFIG_PIO_A +#define QDEC_CONFIG_PIO_A 31 +#endif + +// QDEC_CONFIG_PIO_B - B pin <0-31> + + +#ifndef QDEC_CONFIG_PIO_B +#define QDEC_CONFIG_PIO_B 31 +#endif + +// QDEC_CONFIG_PIO_LED - LED pin <0-31> + + +#ifndef QDEC_CONFIG_PIO_LED +#define QDEC_CONFIG_PIO_LED 31 +#endif + +// QDEC_CONFIG_LEDPRE - LED pre +#ifndef QDEC_CONFIG_LEDPRE +#define QDEC_CONFIG_LEDPRE 511 +#endif + +// QDEC_CONFIG_LEDPOL - LED polarity + +// <0=> Active low +// <1=> Active high + +#ifndef QDEC_CONFIG_LEDPOL +#define QDEC_CONFIG_LEDPOL 1 +#endif + +// QDEC_CONFIG_DBFEN - Debouncing enable + + +#ifndef QDEC_CONFIG_DBFEN +#define QDEC_CONFIG_DBFEN 0 +#endif + +// QDEC_CONFIG_SAMPLE_INTEN - Sample ready interrupt enable + + +#ifndef QDEC_CONFIG_SAMPLE_INTEN +#define QDEC_CONFIG_SAMPLE_INTEN 0 +#endif + +// QDEC_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef QDEC_CONFIG_IRQ_PRIORITY +#define QDEC_CONFIG_IRQ_PRIORITY 7 +#endif + +// QDEC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef QDEC_CONFIG_LOG_ENABLED +#define QDEC_CONFIG_LOG_ENABLED 0 +#endif +#if QDEC_CONFIG_LOG_ENABLED +// QDEC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef QDEC_CONFIG_LOG_LEVEL +#define QDEC_CONFIG_LOG_LEVEL 3 +#endif + +// QDEC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef QDEC_CONFIG_INFO_COLOR +#define QDEC_CONFIG_INFO_COLOR 0 +#endif + +// QDEC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef QDEC_CONFIG_DEBUG_COLOR +#define QDEC_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //QDEC_CONFIG_LOG_ENABLED +// + +#endif //QDEC_ENABLED +// + +// RNG_ENABLED - nrf_drv_rng - RNG peripheral driver +//========================================================== +#ifndef RNG_ENABLED +#define RNG_ENABLED 0 +#endif +#if RNG_ENABLED +// RNG_CONFIG_ERROR_CORRECTION - Error correction + + +#ifndef RNG_CONFIG_ERROR_CORRECTION +#define RNG_CONFIG_ERROR_CORRECTION 0 +#endif + +// RNG_CONFIG_POOL_SIZE - Pool size +#ifndef RNG_CONFIG_POOL_SIZE +#define RNG_CONFIG_POOL_SIZE 32 +#endif + +// RNG_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef RNG_CONFIG_IRQ_PRIORITY +#define RNG_CONFIG_IRQ_PRIORITY 7 +#endif + +// RNG_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef RNG_CONFIG_LOG_ENABLED +#define RNG_CONFIG_LOG_ENABLED 0 +#endif +#if RNG_CONFIG_LOG_ENABLED +// RNG_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef RNG_CONFIG_LOG_LEVEL +#define RNG_CONFIG_LOG_LEVEL 3 +#endif + +// RNG_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RNG_CONFIG_INFO_COLOR +#define RNG_CONFIG_INFO_COLOR 0 +#endif + +// RNG_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RNG_CONFIG_DEBUG_COLOR +#define RNG_CONFIG_DEBUG_COLOR 0 +#endif + +// RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED - Enables logging of random numbers. + + +#ifndef RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED +#define RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED 0 +#endif + +#endif //RNG_CONFIG_LOG_ENABLED +// + +#endif //RNG_ENABLED +// + +// RTC_ENABLED - nrf_drv_rtc - RTC peripheral driver +//========================================================== +#ifndef RTC_ENABLED +#define RTC_ENABLED 0 +#endif +#if RTC_ENABLED +// RTC_DEFAULT_CONFIG_FREQUENCY - Frequency <16-32768> + + +#ifndef RTC_DEFAULT_CONFIG_FREQUENCY +#define RTC_DEFAULT_CONFIG_FREQUENCY 32768 +#endif + +// RTC_DEFAULT_CONFIG_RELIABLE - Ensures safe compare event triggering + + +#ifndef RTC_DEFAULT_CONFIG_RELIABLE +#define RTC_DEFAULT_CONFIG_RELIABLE 0 +#endif + +// RTC_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef RTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define RTC_DEFAULT_CONFIG_IRQ_PRIORITY 7 +#endif + +// RTC0_ENABLED - Enable RTC0 instance + + +#ifndef RTC0_ENABLED +#define RTC0_ENABLED 0 +#endif + +// RTC1_ENABLED - Enable RTC1 instance + + +#ifndef RTC1_ENABLED +#define RTC1_ENABLED 0 +#endif + +// RTC2_ENABLED - Enable RTC2 instance + + +#ifndef RTC2_ENABLED +#define RTC2_ENABLED 0 +#endif + +// NRF_MAXIMUM_LATENCY_US - Maximum possible time[us] in highest priority interrupt +#ifndef NRF_MAXIMUM_LATENCY_US +#define NRF_MAXIMUM_LATENCY_US 2000 +#endif + +// RTC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef RTC_CONFIG_LOG_ENABLED +#define RTC_CONFIG_LOG_ENABLED 0 +#endif +#if RTC_CONFIG_LOG_ENABLED +// RTC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef RTC_CONFIG_LOG_LEVEL +#define RTC_CONFIG_LOG_LEVEL 3 +#endif + +// RTC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RTC_CONFIG_INFO_COLOR +#define RTC_CONFIG_INFO_COLOR 0 +#endif + +// RTC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RTC_CONFIG_DEBUG_COLOR +#define RTC_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //RTC_CONFIG_LOG_ENABLED +// + +#endif //RTC_ENABLED +// + +// SAADC_ENABLED - nrf_drv_saadc - SAADC peripheral driver +//========================================================== +#ifndef SAADC_ENABLED +#define SAADC_ENABLED 1 +#endif +#if SAADC_ENABLED +// SAADC_CONFIG_RESOLUTION - Resolution + +// <0=> 8 bit +// <1=> 10 bit +// <2=> 12 bit +// <3=> 14 bit + +#ifndef SAADC_CONFIG_RESOLUTION +#define SAADC_CONFIG_RESOLUTION 2 +#endif + +// SAADC_CONFIG_OVERSAMPLE - Sample period + +// <0=> Disabled +// <1=> 2x +// <2=> 4x +// <3=> 8x +// <4=> 16x +// <5=> 32x +// <6=> 64x +// <7=> 128x +// <8=> 256x + +#ifndef SAADC_CONFIG_OVERSAMPLE +#define SAADC_CONFIG_OVERSAMPLE 0 +#endif + +// SAADC_CONFIG_LP_MODE - Enabling low power mode + + +#ifndef SAADC_CONFIG_LP_MODE +#define SAADC_CONFIG_LP_MODE 0 +#endif + +// SAADC_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef SAADC_CONFIG_IRQ_PRIORITY +#define SAADC_CONFIG_IRQ_PRIORITY 7 +#endif + +// SAADC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SAADC_CONFIG_LOG_ENABLED +#define SAADC_CONFIG_LOG_ENABLED 0 +#endif +#if SAADC_CONFIG_LOG_ENABLED +// SAADC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SAADC_CONFIG_LOG_LEVEL +#define SAADC_CONFIG_LOG_LEVEL 3 +#endif + +// SAADC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SAADC_CONFIG_INFO_COLOR +#define SAADC_CONFIG_INFO_COLOR 0 +#endif + +// SAADC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SAADC_CONFIG_DEBUG_COLOR +#define SAADC_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //SAADC_CONFIG_LOG_ENABLED +// + +#endif //SAADC_ENABLED +// + +// SPIS_ENABLED - nrf_drv_spis - SPI Slave driver +//========================================================== +#ifndef SPIS_ENABLED +#define SPIS_ENABLED 0 +#endif +#if SPIS_ENABLED +// SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef SPIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define SPIS_DEFAULT_CONFIG_IRQ_PRIORITY 7 +#endif + +// SPIS_DEFAULT_MODE - Mode + +// <0=> MODE_0 +// <1=> MODE_1 +// <2=> MODE_2 +// <3=> MODE_3 + +#ifndef SPIS_DEFAULT_MODE +#define SPIS_DEFAULT_MODE 0 +#endif + +// SPIS_DEFAULT_BIT_ORDER - SPIS default bit order + +// <0=> MSB first +// <1=> LSB first + +#ifndef SPIS_DEFAULT_BIT_ORDER +#define SPIS_DEFAULT_BIT_ORDER 0 +#endif + +// SPIS_DEFAULT_DEF - SPIS default DEF character <0-255> + + +#ifndef SPIS_DEFAULT_DEF +#define SPIS_DEFAULT_DEF 255 +#endif + +// SPIS_DEFAULT_ORC - SPIS default ORC character <0-255> + + +#ifndef SPIS_DEFAULT_ORC +#define SPIS_DEFAULT_ORC 255 +#endif + +// SPIS0_ENABLED - Enable SPIS0 instance + + +#ifndef SPIS0_ENABLED +#define SPIS0_ENABLED 0 +#endif + +// SPIS1_ENABLED - Enable SPIS1 instance + + +#ifndef SPIS1_ENABLED +#define SPIS1_ENABLED 0 +#endif + +// SPIS2_ENABLED - Enable SPIS2 instance + + +#ifndef SPIS2_ENABLED +#define SPIS2_ENABLED 0 +#endif + +// SPIS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SPIS_CONFIG_LOG_ENABLED +#define SPIS_CONFIG_LOG_ENABLED 0 +#endif +#if SPIS_CONFIG_LOG_ENABLED +// SPIS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SPIS_CONFIG_LOG_LEVEL +#define SPIS_CONFIG_LOG_LEVEL 3 +#endif + +// SPIS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPIS_CONFIG_INFO_COLOR +#define SPIS_CONFIG_INFO_COLOR 0 +#endif + +// SPIS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPIS_CONFIG_DEBUG_COLOR +#define SPIS_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //SPIS_CONFIG_LOG_ENABLED +// + +// SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED - Enables nRF52 Anomaly 109 workaround for SPIS. + + +// The workaround uses a GPIOTE channel to generate interrupts +// on falling edges detected on the CSN line. This will make +// the CPU active for the moment when SPIS starts DMA transfers, +// and this way the transfers will be protected. +// This workaround uses GPIOTE driver, so this driver must be +// enabled as well. + +#ifndef SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED +#define SPIS_NRF52_ANOMALY_109_WORKAROUND_ENABLED 0 +#endif + +#endif //SPIS_ENABLED +// + +// SPI_ENABLED - nrf_drv_spi - SPI/SPIM peripheral driver +//========================================================== +#ifndef SPI_ENABLED +#define SPI_ENABLED 0 +#endif +#if SPI_ENABLED +// SPI_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef SPI_DEFAULT_CONFIG_IRQ_PRIORITY +#define SPI_DEFAULT_CONFIG_IRQ_PRIORITY 7 +#endif + +// SPI0_ENABLED - Enable SPI0 instance +//========================================================== +#ifndef SPI0_ENABLED +#define SPI0_ENABLED 0 +#endif +#if SPI0_ENABLED +// SPI0_USE_EASY_DMA - Use EasyDMA + + +#ifndef SPI0_USE_EASY_DMA +#define SPI0_USE_EASY_DMA 1 +#endif + +// SPI0_DEFAULT_FREQUENCY - SPI frequency + +// <33554432=> 125 kHz +// <67108864=> 250 kHz +// <134217728=> 500 kHz +// <268435456=> 1 MHz +// <536870912=> 2 MHz +// <1073741824=> 4 MHz +// <2147483648=> 8 MHz + +#ifndef SPI0_DEFAULT_FREQUENCY +#define SPI0_DEFAULT_FREQUENCY 1073741824 +#endif + +#endif //SPI0_ENABLED +// + +// SPI1_ENABLED - Enable SPI1 instance +//========================================================== +#ifndef SPI1_ENABLED +#define SPI1_ENABLED 0 +#endif +#if SPI1_ENABLED +// SPI1_USE_EASY_DMA - Use EasyDMA + + +#ifndef SPI1_USE_EASY_DMA +#define SPI1_USE_EASY_DMA 1 +#endif + +// SPI1_DEFAULT_FREQUENCY - SPI frequency + +// <33554432=> 125 kHz +// <67108864=> 250 kHz +// <134217728=> 500 kHz +// <268435456=> 1 MHz +// <536870912=> 2 MHz +// <1073741824=> 4 MHz +// <2147483648=> 8 MHz + +#ifndef SPI1_DEFAULT_FREQUENCY +#define SPI1_DEFAULT_FREQUENCY 1073741824 +#endif + +#endif //SPI1_ENABLED +// + +// SPI2_ENABLED - Enable SPI2 instance +//========================================================== +#ifndef SPI2_ENABLED +#define SPI2_ENABLED 0 +#endif +#if SPI2_ENABLED +// SPI2_USE_EASY_DMA - Use EasyDMA + + +#ifndef SPI2_USE_EASY_DMA +#define SPI2_USE_EASY_DMA 1 +#endif + +// SPI2_DEFAULT_FREQUENCY - Use EasyDMA + + +#ifndef SPI2_DEFAULT_FREQUENCY +#define SPI2_DEFAULT_FREQUENCY 1 +#endif + +#endif //SPI2_ENABLED +// + +// SPI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SPI_CONFIG_LOG_ENABLED +#define SPI_CONFIG_LOG_ENABLED 0 +#endif +#if SPI_CONFIG_LOG_ENABLED +// SPI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SPI_CONFIG_LOG_LEVEL +#define SPI_CONFIG_LOG_LEVEL 3 +#endif + +// SPI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPI_CONFIG_INFO_COLOR +#define SPI_CONFIG_INFO_COLOR 0 +#endif + +// SPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPI_CONFIG_DEBUG_COLOR +#define SPI_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //SPI_CONFIG_LOG_ENABLED +// + +// SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED - Enables nRF52 anomaly 109 workaround for SPIM. + + +// The workaround uses interrupts to wake up the CPU by catching +// a start event of zero-length transmission to start the clock. This +// ensures that the DMA transfer will be executed without issues and +// that the proper transfer will be started. See more in the Errata +// document or Anomaly 109 Addendum located at +// https://infocenter.nordicsemi.com/ + +#ifndef SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED +#define SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 0 +#endif + +#endif //SPI_ENABLED +// + +// TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver +//========================================================== +#ifndef TIMER_ENABLED +#define TIMER_ENABLED 0 +#endif +#if TIMER_ENABLED +// TIMER_DEFAULT_CONFIG_FREQUENCY - Timer frequency if in Timer mode + +// <0=> 16 MHz +// <1=> 8 MHz +// <2=> 4 MHz +// <3=> 2 MHz +// <4=> 1 MHz +// <5=> 500 kHz +// <6=> 250 kHz +// <7=> 125 kHz +// <8=> 62.5 kHz +// <9=> 31.25 kHz + +#ifndef TIMER_DEFAULT_CONFIG_FREQUENCY +#define TIMER_DEFAULT_CONFIG_FREQUENCY 0 +#endif + +// TIMER_DEFAULT_CONFIG_MODE - Timer mode or operation + +// <0=> Timer +// <1=> Counter + +#ifndef TIMER_DEFAULT_CONFIG_MODE +#define TIMER_DEFAULT_CONFIG_MODE 0 +#endif + +// TIMER_DEFAULT_CONFIG_BIT_WIDTH - Timer counter bit width + +// <0=> 16 bit +// <1=> 8 bit +// <2=> 24 bit +// <3=> 32 bit + +#ifndef TIMER_DEFAULT_CONFIG_BIT_WIDTH +#define TIMER_DEFAULT_CONFIG_BIT_WIDTH 0 +#endif + +// TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef TIMER_DEFAULT_CONFIG_IRQ_PRIORITY +#define TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 7 +#endif + +// TIMER0_ENABLED - Enable TIMER0 instance + + +#ifndef TIMER0_ENABLED +#define TIMER0_ENABLED 0 +#endif + +// TIMER1_ENABLED - Enable TIMER1 instance + + +#ifndef TIMER1_ENABLED +#define TIMER1_ENABLED 0 +#endif + +// TIMER2_ENABLED - Enable TIMER2 instance + + +#ifndef TIMER2_ENABLED +#define TIMER2_ENABLED 0 +#endif + +// TIMER3_ENABLED - Enable TIMER3 instance + + +#ifndef TIMER3_ENABLED +#define TIMER3_ENABLED 0 +#endif + +// TIMER4_ENABLED - Enable TIMER4 instance + + +#ifndef TIMER4_ENABLED +#define TIMER4_ENABLED 0 +#endif + +// TIMER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TIMER_CONFIG_LOG_ENABLED +#define TIMER_CONFIG_LOG_ENABLED 0 +#endif +#if TIMER_CONFIG_LOG_ENABLED +// TIMER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TIMER_CONFIG_LOG_LEVEL +#define TIMER_CONFIG_LOG_LEVEL 3 +#endif + +// TIMER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TIMER_CONFIG_INFO_COLOR +#define TIMER_CONFIG_INFO_COLOR 0 +#endif + +// TIMER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TIMER_CONFIG_DEBUG_COLOR +#define TIMER_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //TIMER_CONFIG_LOG_ENABLED +// + +#endif //TIMER_ENABLED +// + +// TWIS_ENABLED - nrf_drv_twis - TWIS peripheral driver +//========================================================== +#ifndef TWIS_ENABLED +#define TWIS_ENABLED 0 +#endif +#if TWIS_ENABLED +// TWIS_DEFAULT_CONFIG_ADDR0 - Address0 +#ifndef TWIS_DEFAULT_CONFIG_ADDR0 +#define TWIS_DEFAULT_CONFIG_ADDR0 0 +#endif + +// TWIS_DEFAULT_CONFIG_ADDR1 - Address1 +#ifndef TWIS_DEFAULT_CONFIG_ADDR1 +#define TWIS_DEFAULT_CONFIG_ADDR1 0 +#endif + +// TWIS_DEFAULT_CONFIG_SCL_PULL - SCL pin pull configuration + +// <0=> Disabled +// <1=> Pull down +// <3=> Pull up + +#ifndef TWIS_DEFAULT_CONFIG_SCL_PULL +#define TWIS_DEFAULT_CONFIG_SCL_PULL 0 +#endif + +// TWIS_DEFAULT_CONFIG_SDA_PULL - SDA pin pull configuration + +// <0=> Disabled +// <1=> Pull down +// <3=> Pull up + +#ifndef TWIS_DEFAULT_CONFIG_SDA_PULL +#define TWIS_DEFAULT_CONFIG_SDA_PULL 0 +#endif + +// TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef TWIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define TWIS_DEFAULT_CONFIG_IRQ_PRIORITY 7 +#endif + +// TWIS0_ENABLED - Enable TWIS0 instance + + +#ifndef TWIS0_ENABLED +#define TWIS0_ENABLED 0 +#endif + +// TWIS1_ENABLED - Enable TWIS1 instance + + +#ifndef TWIS1_ENABLED +#define TWIS1_ENABLED 0 +#endif + +// TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized only once + + +// Optimization flag. Registers used by TWIS are shared by other peripherals. Normally, during initialization driver tries to clear all registers to known state before doing the initialization itself. This gives initialization safe procedure, no matter when it would be called. If you activate TWIS only once and do never uninitialize it - set this flag to 1 what gives more optimal code. + +#ifndef TWIS_ASSUME_INIT_AFTER_RESET_ONLY +#define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +#endif + +// TWIS_NO_SYNC_MODE - Remove support for synchronous mode + + +// Synchronous mode would be used in specific situations. And it uses some additional code and data memory to safely process state machine by polling it in status functions. If this functionality is not required it may be disabled to free some resources. + +#ifndef TWIS_NO_SYNC_MODE +#define TWIS_NO_SYNC_MODE 0 +#endif + +// TWIS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TWIS_CONFIG_LOG_ENABLED +#define TWIS_CONFIG_LOG_ENABLED 0 +#endif +#if TWIS_CONFIG_LOG_ENABLED +// TWIS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TWIS_CONFIG_LOG_LEVEL +#define TWIS_CONFIG_LOG_LEVEL 3 +#endif + +// TWIS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWIS_CONFIG_INFO_COLOR +#define TWIS_CONFIG_INFO_COLOR 0 +#endif + +// TWIS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWIS_CONFIG_DEBUG_COLOR +#define TWIS_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //TWIS_CONFIG_LOG_ENABLED +// + +#endif //TWIS_ENABLED +// + +// TWI_ENABLED - nrf_drv_twi - TWI/TWIM peripheral driver +//========================================================== +#ifndef TWI_ENABLED +#define TWI_ENABLED 0 +#endif +#if TWI_ENABLED +// TWI_DEFAULT_CONFIG_FREQUENCY - Frequency + +// <26738688=> 100k +// <67108864=> 250k +// <104857600=> 400k + +#ifndef TWI_DEFAULT_CONFIG_FREQUENCY +#define TWI_DEFAULT_CONFIG_FREQUENCY 26738688 +#endif + +// TWI_DEFAULT_CONFIG_CLR_BUS_INIT - Enables bus clearing procedure during init + + +#ifndef TWI_DEFAULT_CONFIG_CLR_BUS_INIT +#define TWI_DEFAULT_CONFIG_CLR_BUS_INIT 0 +#endif + +// TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT - Enables bus holding after uninit + + +#ifndef TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT +#define TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0 +#endif + +// TWI_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef TWI_DEFAULT_CONFIG_IRQ_PRIORITY +#define TWI_DEFAULT_CONFIG_IRQ_PRIORITY 7 +#endif + +// TWI0_ENABLED - Enable TWI0 instance +//========================================================== +#ifndef TWI0_ENABLED +#define TWI0_ENABLED 0 +#endif +#if TWI0_ENABLED +// TWI0_USE_EASY_DMA - Use EasyDMA (if present) + + +#ifndef TWI0_USE_EASY_DMA +#define TWI0_USE_EASY_DMA 0 +#endif + +#endif //TWI0_ENABLED +// + +// TWI1_ENABLED - Enable TWI1 instance +//========================================================== +#ifndef TWI1_ENABLED +#define TWI1_ENABLED 0 +#endif +#if TWI1_ENABLED +// TWI1_USE_EASY_DMA - Use EasyDMA (if present) + + +#ifndef TWI1_USE_EASY_DMA +#define TWI1_USE_EASY_DMA 0 +#endif + +#endif //TWI1_ENABLED +// + +// TWI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TWI_CONFIG_LOG_ENABLED +#define TWI_CONFIG_LOG_ENABLED 0 +#endif +#if TWI_CONFIG_LOG_ENABLED +// TWI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TWI_CONFIG_LOG_LEVEL +#define TWI_CONFIG_LOG_LEVEL 3 +#endif + +// TWI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWI_CONFIG_INFO_COLOR +#define TWI_CONFIG_INFO_COLOR 0 +#endif + +// TWI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWI_CONFIG_DEBUG_COLOR +#define TWI_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //TWI_CONFIG_LOG_ENABLED +// + +// TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED - Enables nRF52 anomaly 109 workaround for TWIM. + + +// The workaround uses interrupts to wake up the CPU by catching +// the start event of zero-frequency transmission, clear the +// peripheral, set desired frequency, start the peripheral, and +// the proper transmission. See more in the Errata document or +// Anomaly 109 Addendum located at https://infocenter.nordicsemi.com/ + +#ifndef TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED +#define TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 0 +#endif + +#endif //TWI_ENABLED +// + +// UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver +//========================================================== +#ifndef UART_ENABLED +#define UART_ENABLED 1 +#endif +#if UART_ENABLED +// UART_DEFAULT_CONFIG_HWFC - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef UART_DEFAULT_CONFIG_HWFC +#define UART_DEFAULT_CONFIG_HWFC 0 +#endif + +// UART_DEFAULT_CONFIG_PARITY - Parity + +// <0=> Excluded +// <14=> Included + +#ifndef UART_DEFAULT_CONFIG_PARITY +#define UART_DEFAULT_CONFIG_PARITY 0 +#endif + +// UART_DEFAULT_CONFIG_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3862528=> 14400 baud +// <5152768=> 19200 baud +// <7716864=> 28800 baud +// <10289152=> 38400 baud +// <15400960=> 57600 baud +// <20615168=> 76800 baud +// <30801920=> 115200 baud +// <61865984=> 230400 baud +// <67108864=> 250000 baud +// <121634816=> 460800 baud +// <251658240=> 921600 baud +// <268435456=> 57600 baud + +#ifndef UART_DEFAULT_CONFIG_BAUDRATE +#define UART_DEFAULT_CONFIG_BAUDRATE 30801920 +#endif + +// UART_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY +#define UART_DEFAULT_CONFIG_IRQ_PRIORITY 7 +#endif + +// UART_EASY_DMA_SUPPORT - Driver supporting EasyDMA + + +#ifndef UART_EASY_DMA_SUPPORT +#define UART_EASY_DMA_SUPPORT 0 +#endif + +// UART_LEGACY_SUPPORT - Driver supporting Legacy mode + + +#ifndef UART_LEGACY_SUPPORT +#define UART_LEGACY_SUPPORT 1 +#endif + +// UART0_ENABLED - Enable UART0 instance +//========================================================== +#ifndef UART0_ENABLED +#define UART0_ENABLED 1 +#endif +#if UART0_ENABLED +// UART0_CONFIG_USE_EASY_DMA - Default setting for using EasyDMA + + +#ifndef UART0_CONFIG_USE_EASY_DMA +#define UART0_CONFIG_USE_EASY_DMA 0 +#endif + +#endif //UART0_ENABLED +// + +// UART_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef UART_CONFIG_LOG_ENABLED +#define UART_CONFIG_LOG_ENABLED 0 +#endif +#if UART_CONFIG_LOG_ENABLED +// UART_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef UART_CONFIG_LOG_LEVEL +#define UART_CONFIG_LOG_LEVEL 3 +#endif + +// UART_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef UART_CONFIG_INFO_COLOR +#define UART_CONFIG_INFO_COLOR 0 +#endif + +// UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef UART_CONFIG_DEBUG_COLOR +#define UART_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //UART_CONFIG_LOG_ENABLED +// + +#endif //UART_ENABLED +// + +// USBD_ENABLED - nrf_drv_usbd - USB driver +//========================================================== +#ifndef USBD_ENABLED +#define USBD_ENABLED 0 +#endif +#if USBD_ENABLED +// USBD_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef USBD_CONFIG_IRQ_PRIORITY +#define USBD_CONFIG_IRQ_PRIORITY 7 +#endif + +// NRF_DRV_USBD_DMASCHEDULER_MODE - USBD SMA scheduler working scheme + +// <0=> Prioritized access +// <1=> Round Robin + +#ifndef NRF_DRV_USBD_DMASCHEDULER_MODE +#define NRF_DRV_USBD_DMASCHEDULER_MODE 0 +#endif + +// NRF_USBD_DRV_LOG_ENABLED - Enable logging + + +#ifndef NRF_USBD_DRV_LOG_ENABLED +#define NRF_USBD_DRV_LOG_ENABLED 0 +#endif + +#endif //USBD_ENABLED +// + +// WDT_ENABLED - nrf_drv_wdt - WDT peripheral driver +//========================================================== +#ifndef WDT_ENABLED +#define WDT_ENABLED 0 +#endif +#if WDT_ENABLED +// WDT_CONFIG_BEHAVIOUR - WDT behavior in CPU SLEEP or HALT mode + +// <1=> Run in SLEEP, Pause in HALT +// <8=> Pause in SLEEP, Run in HALT +// <9=> Run in SLEEP and HALT +// <0=> Pause in SLEEP and HALT + +#ifndef WDT_CONFIG_BEHAVIOUR +#define WDT_CONFIG_BEHAVIOUR 1 +#endif + +// WDT_CONFIG_RELOAD_VALUE - Reload value <15-4294967295> + + +#ifndef WDT_CONFIG_RELOAD_VALUE +#define WDT_CONFIG_RELOAD_VALUE 2000 +#endif + +// WDT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef WDT_CONFIG_IRQ_PRIORITY +#define WDT_CONFIG_IRQ_PRIORITY 7 +#endif + +// WDT_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef WDT_CONFIG_LOG_ENABLED +#define WDT_CONFIG_LOG_ENABLED 0 +#endif +#if WDT_CONFIG_LOG_ENABLED +// WDT_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef WDT_CONFIG_LOG_LEVEL +#define WDT_CONFIG_LOG_LEVEL 3 +#endif + +// WDT_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef WDT_CONFIG_INFO_COLOR +#define WDT_CONFIG_INFO_COLOR 0 +#endif + +// WDT_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef WDT_CONFIG_DEBUG_COLOR +#define WDT_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //WDT_CONFIG_LOG_ENABLED +// + +#endif //WDT_ENABLED +// + +// +//========================================================== + +// nRF_Libraries + +//========================================================== +// APP_FIFO_ENABLED - app_fifo - Software FIFO implementation + + +#ifndef APP_FIFO_ENABLED +#define APP_FIFO_ENABLED 1 +#endif + +// APP_GPIOTE_ENABLED - app_gpiote - GPIOTE events dispatcher + + +#ifndef APP_GPIOTE_ENABLED +#define APP_GPIOTE_ENABLED 0 +#endif + +// APP_PWM_ENABLED - app_pwm - PWM functionality + + +#ifndef APP_PWM_ENABLED +#define APP_PWM_ENABLED 0 +#endif + +// APP_SCHEDULER_ENABLED - app_scheduler - Events scheduler +//========================================================== +#ifndef APP_SCHEDULER_ENABLED +#define APP_SCHEDULER_ENABLED 1 +#endif +#if APP_SCHEDULER_ENABLED +// APP_SCHEDULER_WITH_PAUSE - Enabling pause feature + + +#ifndef APP_SCHEDULER_WITH_PAUSE +#define APP_SCHEDULER_WITH_PAUSE 0 +#endif + +// APP_SCHEDULER_WITH_PROFILER - Enabling scheduler profiling + + +#ifndef APP_SCHEDULER_WITH_PROFILER +#define APP_SCHEDULER_WITH_PROFILER 0 +#endif + +#endif //APP_SCHEDULER_ENABLED +// + +// APP_TIMER_ENABLED - app_timer - Application timer functionality +//========================================================== +#ifndef APP_TIMER_ENABLED +#define APP_TIMER_ENABLED 1 +#endif +#if APP_TIMER_ENABLED +// APP_TIMER_CONFIG_RTC_FREQUENCY - Configure RTC prescaler. + +// <0=> 32768 Hz +// <1=> 16384 Hz +// <3=> 8192 Hz +// <7=> 4096 Hz +// <15=> 2048 Hz +// <31=> 1024 Hz + +#ifndef APP_TIMER_CONFIG_RTC_FREQUENCY +#define APP_TIMER_CONFIG_RTC_FREQUENCY 0 +#endif + +// APP_TIMER_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef APP_TIMER_CONFIG_IRQ_PRIORITY +#define APP_TIMER_CONFIG_IRQ_PRIORITY 7 +#endif + +// APP_TIMER_CONFIG_OP_QUEUE_SIZE - Capacity of timer requests queue. +// Size of the queue depends on how many timers are used +// in the system, how often timers are started and overall +// system latency. If queue size is too small app_timer calls +// will fail. + +#ifndef APP_TIMER_CONFIG_OP_QUEUE_SIZE +#define APP_TIMER_CONFIG_OP_QUEUE_SIZE 10 +#endif + +// APP_TIMER_CONFIG_USE_SCHEDULER - Enable scheduling app_timer events to app_scheduler + + +#ifndef APP_TIMER_CONFIG_USE_SCHEDULER +#define APP_TIMER_CONFIG_USE_SCHEDULER 0 +#endif + +// APP_TIMER_WITH_PROFILER - Enable app_timer profiling + + +#ifndef APP_TIMER_WITH_PROFILER +#define APP_TIMER_WITH_PROFILER 0 +#endif + +// APP_TIMER_KEEPS_RTC_ACTIVE - Enable RTC always on + + +// If option is enabled RTC is kept running even if there is no active timers. +// This option can be used when app_timer is used for timestamping. + +#ifndef APP_TIMER_KEEPS_RTC_ACTIVE +#define APP_TIMER_KEEPS_RTC_ACTIVE 0 +#endif + +// APP_TIMER_CONFIG_SWI_NUMBER - Configure SWI instance used. + +// <0=> 0 +// <1=> 1 + +#ifndef APP_TIMER_CONFIG_SWI_NUMBER +#define APP_TIMER_CONFIG_SWI_NUMBER 0 +#endif + +#endif //APP_TIMER_ENABLED +// + +// APP_TWI_ENABLED - app_twi - TWI transaction manager + + +#ifndef APP_TWI_ENABLED +#define APP_TWI_ENABLED 0 +#endif + +// APP_UART_ENABLED - app_uart - UART driver +//========================================================== +#ifndef APP_UART_ENABLED +#define APP_UART_ENABLED 1 +#endif +#if APP_UART_ENABLED +// APP_UART_DRIVER_INSTANCE - UART instance used + +// <0=> 0 + +#ifndef APP_UART_DRIVER_INSTANCE +#define APP_UART_DRIVER_INSTANCE 0 +#endif + +#endif //APP_UART_ENABLED +// + +// APP_USBD_CLASS_AUDIO_ENABLED - app_usbd_audio - USB AUDIO class + + +#ifndef APP_USBD_CLASS_AUDIO_ENABLED +#define APP_USBD_CLASS_AUDIO_ENABLED 0 +#endif + +// APP_USBD_CLASS_HID_ENABLED - app_usbd_hid - USB HID class + + +#ifndef APP_USBD_CLASS_HID_ENABLED +#define APP_USBD_CLASS_HID_ENABLED 0 +#endif + +// APP_USBD_HID_GENERIC_ENABLED - app_usbd_hid_generic - USB HID generic + + +#ifndef APP_USBD_HID_GENERIC_ENABLED +#define APP_USBD_HID_GENERIC_ENABLED 0 +#endif + +// APP_USBD_HID_KBD_ENABLED - app_usbd_hid_kbd - USB HID keyboard + + +#ifndef APP_USBD_HID_KBD_ENABLED +#define APP_USBD_HID_KBD_ENABLED 0 +#endif + +// APP_USBD_HID_MOUSE_ENABLED - app_usbd_hid_mouse - USB HID mouse + + +#ifndef APP_USBD_HID_MOUSE_ENABLED +#define APP_USBD_HID_MOUSE_ENABLED 0 +#endif + +// BUTTON_ENABLED - app_button - buttons handling module + + +#ifndef BUTTON_ENABLED +#define BUTTON_ENABLED 1 +#endif + +// CRC16_ENABLED - crc16 - CRC16 calculation routines + + +#ifndef CRC16_ENABLED +#define CRC16_ENABLED 0 +#endif + +// CRC32_ENABLED - crc32 - CRC32 calculation routines + + +#ifndef CRC32_ENABLED +#define CRC32_ENABLED 0 +#endif + +// ECC_ENABLED - ecc - Elliptic Curve Cryptography Library + + +#ifndef ECC_ENABLED +#define ECC_ENABLED 0 +#endif + +// FDS_ENABLED - fds - Flash data storage module +//========================================================== +#ifndef FDS_ENABLED +#define FDS_ENABLED 0 +#endif +#if FDS_ENABLED +// FDS_OP_QUEUE_SIZE - Size of the internal queue. +#ifndef FDS_OP_QUEUE_SIZE +#define FDS_OP_QUEUE_SIZE 4 +#endif + +// FDS_CHUNK_QUEUE_SIZE - Determines how many @ref fds_record_chunk_t structures can be buffered at any time. +#ifndef FDS_CHUNK_QUEUE_SIZE +#define FDS_CHUNK_QUEUE_SIZE 8 +#endif + +// FDS_MAX_USERS - Maximum number of callbacks that can be registered. +#ifndef FDS_MAX_USERS +#define FDS_MAX_USERS 8 +#endif + +// FDS_VIRTUAL_PAGES - Number of virtual flash pages to use. +// One of the virtual pages is reserved by the system for garbage collection. +// Therefore, the minimum is two virtual pages: one page to store data and +// one page to be used by the system for garbage collection. The total amount +// of flash memory that is used by FDS amounts to @ref FDS_VIRTUAL_PAGES +// @ref FDS_VIRTUAL_PAGE_SIZE * 4 bytes. + +#ifndef FDS_VIRTUAL_PAGES +#define FDS_VIRTUAL_PAGES 3 +#endif + +// FDS_VIRTUAL_PAGE_SIZE - The size of a virtual page of flash memory, expressed in number of 4-byte words. + + +// By default, a virtual page is the same size as a physical page. +// The size of a virtual page must be a multiple of the size of a physical page. +// <1024=> 1024 +// <2048=> 2048 + +#ifndef FDS_VIRTUAL_PAGE_SIZE +#define FDS_VIRTUAL_PAGE_SIZE 1024 +#endif + +#endif //FDS_ENABLED +// + +// FSTORAGE_ENABLED - fstorage - Flash storage module +//========================================================== +#ifndef FSTORAGE_ENABLED +#define FSTORAGE_ENABLED 1 +#endif +#if FSTORAGE_ENABLED +// FS_QUEUE_SIZE - Configures the size of the internal queue. +// Increase this if there are many users, or if it is likely that many +// operation will be queued at once without waiting for the previous operations +// to complete. In general, increase the queue size if you frequently receive +// @ref FS_ERR_QUEUE_FULL errors when calling @ref fs_store or @ref fs_erase. + +#ifndef FS_QUEUE_SIZE +#define FS_QUEUE_SIZE 4 +#endif + +// FS_OP_MAX_RETRIES - Number attempts to execute an operation if the SoftDevice fails. +// Increase this value if events return the @ref FS_ERR_OPERATION_TIMEOUT +// error often. The SoftDevice may fail to schedule flash access due to high BLE activity. + +#ifndef FS_OP_MAX_RETRIES +#define FS_OP_MAX_RETRIES 3 +#endif + +// FS_MAX_WRITE_SIZE_WORDS - Maximum number of words to be written to flash in a single operation. +// Tweaking this value can increase the chances of the SoftDevice being +// able to fit flash operations in between radio activity. This value is bound by the +// maximum number of words which the SoftDevice can write to flash in a single call to +// @ref sd_flash_write, which is 256 words for nRF51 ICs and 1024 words for nRF52 ICs. + +#ifndef FS_MAX_WRITE_SIZE_WORDS +#define FS_MAX_WRITE_SIZE_WORDS 1024 +#endif + +#endif //FSTORAGE_ENABLED +// + +// HARDFAULT_HANDLER_ENABLED - hardfault_default - HardFault default handler for debugging and release + + +#ifndef HARDFAULT_HANDLER_ENABLED +#define HARDFAULT_HANDLER_ENABLED 0 +#endif + +// HCI_MEM_POOL_ENABLED - hci_mem_pool - memory pool implementation used by HCI +//========================================================== +#ifndef HCI_MEM_POOL_ENABLED +#define HCI_MEM_POOL_ENABLED 0 +#endif +#if HCI_MEM_POOL_ENABLED +// HCI_TX_BUF_SIZE - TX buffer size in bytes. +#ifndef HCI_TX_BUF_SIZE +#define HCI_TX_BUF_SIZE 600 +#endif + +// HCI_RX_BUF_SIZE - RX buffer size in bytes. +#ifndef HCI_RX_BUF_SIZE +#define HCI_RX_BUF_SIZE 600 +#endif + +// HCI_RX_BUF_QUEUE_SIZE - RX buffer queue size. +#ifndef HCI_RX_BUF_QUEUE_SIZE +#define HCI_RX_BUF_QUEUE_SIZE 4 +#endif + +#endif //HCI_MEM_POOL_ENABLED +// + +// HCI_SLIP_ENABLED - hci_slip - SLIP protocol implementation used by HCI +//========================================================== +#ifndef HCI_SLIP_ENABLED +#define HCI_SLIP_ENABLED 0 +#endif +#if HCI_SLIP_ENABLED +// HCI_UART_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3862528=> 14400 baud +// <5152768=> 19200 baud +// <7716864=> 28800 baud +// <10289152=> 38400 baud +// <15400960=> 57600 baud +// <20615168=> 76800 baud +// <30801920=> 115200 baud +// <61865984=> 230400 baud +// <67108864=> 250000 baud +// <121634816=> 460800 baud +// <251658240=> 921600 baud +// <268435456=> 57600 baud + +#ifndef HCI_UART_BAUDRATE +#define HCI_UART_BAUDRATE 30801920 +#endif + +// HCI_UART_FLOW_CONTROL - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef HCI_UART_FLOW_CONTROL +#define HCI_UART_FLOW_CONTROL 0 +#endif + +// HCI_UART_RX_PIN - UART RX pin +#ifndef HCI_UART_RX_PIN +#define HCI_UART_RX_PIN 8 +#endif + +// HCI_UART_TX_PIN - UART TX pin +#ifndef HCI_UART_TX_PIN +#define HCI_UART_TX_PIN 6 +#endif + +// HCI_UART_RTS_PIN - UART RTS pin +#ifndef HCI_UART_RTS_PIN +#define HCI_UART_RTS_PIN 5 +#endif + +// HCI_UART_CTS_PIN - UART CTS pin +#ifndef HCI_UART_CTS_PIN +#define HCI_UART_CTS_PIN 7 +#endif + +#endif //HCI_SLIP_ENABLED +// + +// HCI_TRANSPORT_ENABLED - hci_transport - HCI transport +//========================================================== +#ifndef HCI_TRANSPORT_ENABLED +#define HCI_TRANSPORT_ENABLED 0 +#endif +#if HCI_TRANSPORT_ENABLED +// HCI_MAX_PACKET_SIZE_IN_BITS - Maximum size of a single application packet in bits. +#ifndef HCI_MAX_PACKET_SIZE_IN_BITS +#define HCI_MAX_PACKET_SIZE_IN_BITS 8000 +#endif + +#endif //HCI_TRANSPORT_ENABLED +// + +// LED_SOFTBLINK_ENABLED - led_softblink - led_softblink module + + +#ifndef LED_SOFTBLINK_ENABLED +#define LED_SOFTBLINK_ENABLED 0 +#endif + +// LOW_POWER_PWM_ENABLED - low_power_pwm - low_power_pwm module + + +#ifndef LOW_POWER_PWM_ENABLED +#define LOW_POWER_PWM_ENABLED 0 +#endif + +// MEM_MANAGER_ENABLED - mem_manager - Dynamic memory allocator +//========================================================== +#ifndef MEM_MANAGER_ENABLED +#define MEM_MANAGER_ENABLED 0 +#endif +#if MEM_MANAGER_ENABLED +// MEMORY_MANAGER_SMALL_BLOCK_COUNT - Size of each memory blocks identified as 'small' block. <0-255> + + +#ifndef MEMORY_MANAGER_SMALL_BLOCK_COUNT +#define MEMORY_MANAGER_SMALL_BLOCK_COUNT 1 +#endif + +// MEMORY_MANAGER_SMALL_BLOCK_SIZE - Size of each memory blocks identified as 'small' block. +// Size of each memory blocks identified as 'small' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_SMALL_BLOCK_SIZE +#define MEMORY_MANAGER_SMALL_BLOCK_SIZE 32 +#endif + +// MEMORY_MANAGER_MEDIUM_BLOCK_COUNT - Size of each memory blocks identified as 'medium' block. <0-255> + + +#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_COUNT +#define MEMORY_MANAGER_MEDIUM_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_MEDIUM_BLOCK_SIZE - Size of each memory blocks identified as 'medium' block. +// Size of each memory blocks identified as 'medium' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_SIZE +#define MEMORY_MANAGER_MEDIUM_BLOCK_SIZE 256 +#endif + +// MEMORY_MANAGER_LARGE_BLOCK_COUNT - Size of each memory blocks identified as 'large' block. <0-255> + + +#ifndef MEMORY_MANAGER_LARGE_BLOCK_COUNT +#define MEMORY_MANAGER_LARGE_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_LARGE_BLOCK_SIZE - Size of each memory blocks identified as 'large' block. +// Size of each memory blocks identified as 'large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_LARGE_BLOCK_SIZE +#define MEMORY_MANAGER_LARGE_BLOCK_SIZE 256 +#endif + +// MEMORY_MANAGER_XLARGE_BLOCK_COUNT - Size of each memory blocks identified as 'extra large' block. <0-255> + + +#ifndef MEMORY_MANAGER_XLARGE_BLOCK_COUNT +#define MEMORY_MANAGER_XLARGE_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_XLARGE_BLOCK_SIZE - Size of each memory blocks identified as 'extra large' block. +// Size of each memory blocks identified as 'extra large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_XLARGE_BLOCK_SIZE +#define MEMORY_MANAGER_XLARGE_BLOCK_SIZE 1320 +#endif + +// MEMORY_MANAGER_XXLARGE_BLOCK_COUNT - Size of each memory blocks identified as 'extra extra large' block. <0-255> + + +#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_COUNT +#define MEMORY_MANAGER_XXLARGE_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_XXLARGE_BLOCK_SIZE - Size of each memory blocks identified as 'extra extra large' block. +// Size of each memory blocks identified as 'extra extra large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_SIZE +#define MEMORY_MANAGER_XXLARGE_BLOCK_SIZE 3444 +#endif + +// MEMORY_MANAGER_XSMALL_BLOCK_COUNT - Size of each memory blocks identified as 'extra small' block. <0-255> + + +#ifndef MEMORY_MANAGER_XSMALL_BLOCK_COUNT +#define MEMORY_MANAGER_XSMALL_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_XSMALL_BLOCK_SIZE - Size of each memory blocks identified as 'extra small' block. +// Size of each memory blocks identified as 'extra large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_XSMALL_BLOCK_SIZE +#define MEMORY_MANAGER_XSMALL_BLOCK_SIZE 64 +#endif + +// MEMORY_MANAGER_XXSMALL_BLOCK_COUNT - Size of each memory blocks identified as 'extra extra small' block. <0-255> + + +#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_COUNT +#define MEMORY_MANAGER_XXSMALL_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_XXSMALL_BLOCK_SIZE - Size of each memory blocks identified as 'extra extra small' block. +// Size of each memory blocks identified as 'extra extra small' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_SIZE +#define MEMORY_MANAGER_XXSMALL_BLOCK_SIZE 32 +#endif + +// MEM_MANAGER_ENABLE_LOGS - Enable debug trace in the module. + + +#ifndef MEM_MANAGER_ENABLE_LOGS +#define MEM_MANAGER_ENABLE_LOGS 0 +#endif + +// MEM_MANAGER_DISABLE_API_PARAM_CHECK - Disable API parameter checks in the module. + + +#ifndef MEM_MANAGER_DISABLE_API_PARAM_CHECK +#define MEM_MANAGER_DISABLE_API_PARAM_CHECK 0 +#endif + +#endif //MEM_MANAGER_ENABLED +// + +// NRF_CSENSE_ENABLED - nrf_csense - Capacitive sensor module +//========================================================== +#ifndef NRF_CSENSE_ENABLED +#define NRF_CSENSE_ENABLED 0 +#endif +#if NRF_CSENSE_ENABLED +// NRF_CSENSE_PAD_HYSTERESIS - Minimum value of change required to determine that a pad was touched. +#ifndef NRF_CSENSE_PAD_HYSTERESIS +#define NRF_CSENSE_PAD_HYSTERESIS 15 +#endif + +// NRF_CSENSE_PAD_DEVIATION - Minimum value measured on a pad required to take it into account while calculating the step. +#ifndef NRF_CSENSE_PAD_DEVIATION +#define NRF_CSENSE_PAD_DEVIATION 70 +#endif + +// NRF_CSENSE_MIN_PAD_VALUE - Minimum normalized value on a pad required to take its value into account. +#ifndef NRF_CSENSE_MIN_PAD_VALUE +#define NRF_CSENSE_MIN_PAD_VALUE 20 +#endif + +// NRF_CSENSE_MAX_PADS_NUMBER - Maximum number of pads used for one instance. +#ifndef NRF_CSENSE_MAX_PADS_NUMBER +#define NRF_CSENSE_MAX_PADS_NUMBER 20 +#endif + +// NRF_CSENSE_MAX_VALUE - Maximum normalized value obtained from measurement. +#ifndef NRF_CSENSE_MAX_VALUE +#define NRF_CSENSE_MAX_VALUE 1000 +#endif + +// NRF_CSENSE_OUTPUT_PIN - Output pin used by the low-level module. +// This is used when capacitive sensor does not use COMP. + +#ifndef NRF_CSENSE_OUTPUT_PIN +#define NRF_CSENSE_OUTPUT_PIN 26 +#endif + +#endif //NRF_CSENSE_ENABLED +// + +// NRF_DRV_CSENSE_ENABLED - nrf_drv_csense - Capacitive sensor low-level module +//========================================================== +#ifndef NRF_DRV_CSENSE_ENABLED +#define NRF_DRV_CSENSE_ENABLED 0 +#endif +#if NRF_DRV_CSENSE_ENABLED +// USE_COMP - Use the comparator to implement the capacitive sensor driver. + +// Due to Anomaly 84, COMP I_SOURCE is not functional. It has too high a varation. +//========================================================== +#ifndef USE_COMP +#define USE_COMP 0 +#endif +#if USE_COMP +// TIMER0_FOR_CSENSE - First TIMER instance used by the driver (not used on nRF51). +#ifndef TIMER0_FOR_CSENSE +#define TIMER0_FOR_CSENSE 1 +#endif + +// TIMER1_FOR_CSENSE - Second TIMER instance used by the driver (not used on nRF51). +#ifndef TIMER1_FOR_CSENSE +#define TIMER1_FOR_CSENSE 2 +#endif + +// MEASUREMENT_PERIOD - Single measurement period. +// Time of a single measurement can be calculated as +// T = (1/2)*MEASUREMENT_PERIOD*(1/f_OSC) where f_OSC = I_SOURCE / (2C*(VUP-VDOWN) ). +// I_SOURCE, VUP, and VDOWN are values used to initialize COMP and C is the capacitance of the used pad. + +#ifndef MEASUREMENT_PERIOD +#define MEASUREMENT_PERIOD 20 +#endif + +#endif //USE_COMP +// + +#endif //NRF_DRV_CSENSE_ENABLED +// + +// NRF_QUEUE_ENABLED - nrf_queue - Queue module + + +#ifndef NRF_QUEUE_ENABLED +#define NRF_QUEUE_ENABLED 0 +#endif + +// NRF_STRERROR_ENABLED - nrf_strerror - Library for converting error code to string. + + +#ifndef NRF_STRERROR_ENABLED +#define NRF_STRERROR_ENABLED 1 +#endif + +// RETARGET_ENABLED - retarget - Retargeting stdio functions + + +#ifndef RETARGET_ENABLED +#define RETARGET_ENABLED 1 +#endif + +// SLIP_ENABLED - slip - SLIP encoding and decoding + + +#ifndef SLIP_ENABLED +#define SLIP_ENABLED 0 +#endif + +// app_usbd_cdc_acm - USB CDC ACM class + +//========================================================== +// APP_USBD_CLASS_CDC_ACM_ENABLED - Enabling USBD CDC ACM Class library + + +#ifndef APP_USBD_CLASS_CDC_ACM_ENABLED +#define APP_USBD_CLASS_CDC_ACM_ENABLED 0 +#endif + +// APP_USBD_CDC_ACM_LOG_ENABLED - Enables logging in the module. + + +#ifndef APP_USBD_CDC_ACM_LOG_ENABLED +#define APP_USBD_CDC_ACM_LOG_ENABLED 0 +#endif + +// +//========================================================== + +// app_usbd_msc - USB MSC class + +//========================================================== +// APP_USBD_CLASS_MSC_ENABLED - Enabling USBD MSC Class library + + +#ifndef APP_USBD_CLASS_MSC_ENABLED +#define APP_USBD_CLASS_MSC_ENABLED 0 +#endif + +// APP_USBD_MSC_CLASS_LOG_ENABLED - Enables logging in the module. + + +#ifndef APP_USBD_MSC_CLASS_LOG_ENABLED +#define APP_USBD_MSC_CLASS_LOG_ENABLED 0 +#endif + +// +//========================================================== + +// +//========================================================== + +// nRF_Log + +//========================================================== +// NRF_LOG_ENABLED - nrf_log - Logging +//========================================================== +#ifndef NRF_LOG_ENABLED +#define NRF_LOG_ENABLED 0 +#endif +#if NRF_LOG_ENABLED +// NRF_LOG_USES_COLORS - If enabled then ANSI escape code for colors is prefixed to every string +//========================================================== +#ifndef NRF_LOG_USES_COLORS +#define NRF_LOG_USES_COLORS 0 +#endif +#if NRF_LOG_USES_COLORS +// NRF_LOG_COLOR_DEFAULT - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LOG_COLOR_DEFAULT +#define NRF_LOG_COLOR_DEFAULT 0 +#endif + +// NRF_LOG_ERROR_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LOG_ERROR_COLOR +#define NRF_LOG_ERROR_COLOR 0 +#endif + +// NRF_LOG_WARNING_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LOG_WARNING_COLOR +#define NRF_LOG_WARNING_COLOR 0 +#endif + +#endif //NRF_LOG_USES_COLORS +// + +// NRF_LOG_DEFAULT_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_LOG_DEFAULT_LEVEL +#define NRF_LOG_DEFAULT_LEVEL 3 +#endif + +// NRF_LOG_DEFERRED - Enable deffered logger. + +// Log data is buffered and can be processed in idle. +//========================================================== +#ifndef NRF_LOG_DEFERRED +#define NRF_LOG_DEFERRED 0 +#endif +#if NRF_LOG_DEFERRED +// NRF_LOG_DEFERRED_BUFSIZE - Size of the buffer for logs in words. +// Must be power of 2 + +#ifndef NRF_LOG_DEFERRED_BUFSIZE +#define NRF_LOG_DEFERRED_BUFSIZE 256 +#endif + +#endif //NRF_LOG_DEFERRED +// + +// NRF_LOG_USES_TIMESTAMP - Enable timestamping + + +// Function for getting the timestamp is provided by the user + +#ifndef NRF_LOG_USES_TIMESTAMP +#define NRF_LOG_USES_TIMESTAMP 0 +#endif + +#endif //NRF_LOG_ENABLED +// + +// nrf_log_backend - Logging sink + +//========================================================== +// NRF_LOG_BACKEND_MAX_STRING_LENGTH - Buffer for storing single output string +// Logger backend RAM usage is determined by this value. + +#ifndef NRF_LOG_BACKEND_MAX_STRING_LENGTH +#define NRF_LOG_BACKEND_MAX_STRING_LENGTH 256 +#endif + +// NRF_LOG_TIMESTAMP_DIGITS - Number of digits for timestamp +// If higher resolution timestamp source is used it might be needed to increase that + +#ifndef NRF_LOG_TIMESTAMP_DIGITS +#define NRF_LOG_TIMESTAMP_DIGITS 8 +#endif + +// NRF_LOG_BACKEND_SERIAL_USES_UART - If enabled data is printed over UART +//========================================================== +#ifndef NRF_LOG_BACKEND_SERIAL_USES_UART +#define NRF_LOG_BACKEND_SERIAL_USES_UART 0 +#endif +#if NRF_LOG_BACKEND_SERIAL_USES_UART +// NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3862528=> 14400 baud +// <5152768=> 19200 baud +// <7716864=> 28800 baud +// <10289152=> 38400 baud +// <15400960=> 57600 baud +// <20615168=> 76800 baud +// <30801920=> 115200 baud +// <61865984=> 230400 baud +// <67108864=> 250000 baud +// <121634816=> 460800 baud +// <251658240=> 921600 baud +// <268435456=> 57600 baud + +#ifndef NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE +#define NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE 30801920 +#endif + +// NRF_LOG_BACKEND_SERIAL_UART_TX_PIN - UART TX pin +#ifndef NRF_LOG_BACKEND_SERIAL_UART_TX_PIN +#define NRF_LOG_BACKEND_SERIAL_UART_TX_PIN 4 +#endif + +// NRF_LOG_BACKEND_SERIAL_UART_RX_PIN - UART RX pin +#ifndef NRF_LOG_BACKEND_SERIAL_UART_RX_PIN +#define NRF_LOG_BACKEND_SERIAL_UART_RX_PIN 3 +#endif + +// NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN - UART RTS pin +#ifndef NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN +#define NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN 5 +#endif + +// NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN - UART CTS pin +#ifndef NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN +#define NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN 7 +#endif + +// NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL +#define NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL 0 +#endif + +// NRF_LOG_BACKEND_UART_INSTANCE - UART instance used + +// <0=> 0 + +#ifndef NRF_LOG_BACKEND_UART_INSTANCE +#define NRF_LOG_BACKEND_UART_INSTANCE 0 +#endif + +#endif //NRF_LOG_BACKEND_SERIAL_USES_UART +// + +// NRF_LOG_BACKEND_SERIAL_USES_RTT - If enabled data is printed using RTT +//========================================================== +#ifndef NRF_LOG_BACKEND_SERIAL_USES_RTT +#define NRF_LOG_BACKEND_SERIAL_USES_RTT 0 +#endif +#if NRF_LOG_BACKEND_SERIAL_USES_RTT +// NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE - RTT output buffer size. +// Should be equal or bigger than \ref NRF_LOG_BACKEND_MAX_STRING_LENGTH. +// This value is used in Segger RTT configuration to set the buffer size +// if it is bigger than default RTT buffer size. + +#ifndef NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE +#define NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE 512 +#endif + +#endif //NRF_LOG_BACKEND_SERIAL_USES_RTT +// + +// +//========================================================== + +// +//========================================================== + +// nRF_Segger_RTT + +//========================================================== +// segger_rtt - SEGGER RTT + +//========================================================== +// SEGGER_RTT_CONFIG_BUFFER_SIZE_UP - Size of upstream buffer. +// Note that either @ref NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE +// or this value is actually used. It depends on which one is bigger. + +#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP +#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 64 +#endif + +// SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS - Size of upstream buffer. +#ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS +#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2 +#endif + +// SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN - Size of upstream buffer. +#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN +#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16 +#endif + +// SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS - Size of upstream buffer. +#ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS +#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2 +#endif + +// SEGGER_RTT_CONFIG_DEFAULT_MODE - RTT behavior if the buffer is full. + + +// The following modes are supported: +// - SKIP - Do not block, output nothing. +// - TRIM - Do not block, output as much as fits. +// - BLOCK - Wait until there is space in the buffer. +// <0=> SKIP +// <1=> TRIM +// <2=> BLOCK_IF_FIFO_FULL + +#ifndef SEGGER_RTT_CONFIG_DEFAULT_MODE +#define SEGGER_RTT_CONFIG_DEFAULT_MODE 0 +#endif + +// +//========================================================== + +// +//========================================================== + +// <<< end of configuration section >>> +#endif //SDK_CONFIG_H + diff --git a/bsp/nrf52832/applications/startup.c b/bsp/nrf52832/applications/startup.c index 9dccb80589e6f4467e53da39b8a94aa38cd9ad8f..fe48118b344879a7002ead33ab3cd004d5021d83 100644 --- a/bsp/nrf52832/applications/startup.c +++ b/bsp/nrf52832/applications/startup.c @@ -58,7 +58,7 @@ void rtthread_startup(void) rt_system_timer_init(); #ifdef RT_USING_HEAP - rt_system_heap_init((void*)NRF_SRAM_BEGIN, (void*)NRF_SRAM_END); + rt_system_heap_init((void*)NRF_SRAM_BEGIN, (void*)CHIP_SRAM_END); #endif /* init scheduler system */ @@ -83,7 +83,7 @@ void rtthread_startup(void) int main(void) { /* disable interrupt first */ - rt_hw_interrupt_disable(); + // rt_hw_interrupt_disable(); /* startup RT-Thread RTOS */ rtthread_startup(); diff --git a/bsp/nrf52832/board/Sconscript b/bsp/nrf52832/board/Sconscript new file mode 100644 index 0000000000000000000000000000000000000000..aa1e87d860be5fa9ea9a9182fd169797b7380ae6 --- /dev/null +++ b/bsp/nrf52832/board/Sconscript @@ -0,0 +1,14 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + +#remove other no use files +#SrcRemove(src, '*.c') + +group = DefineGroup('Board', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') \ No newline at end of file diff --git a/bsp/nrf52832/board/board.c b/bsp/nrf52832/board/board.c new file mode 100644 index 0000000000000000000000000000000000000000..0a28a35593d441ce84df6c171d6b1a96d077c04b --- /dev/null +++ b/bsp/nrf52832/board/board.c @@ -0,0 +1,244 @@ +#include "board.h" +#include "uart.h" +#include "app_util_platform.h" +#include "nrf_drv_common.h" +#include "nrf_systick.h" +#include "nrf_rtc.h" +#include "nrf_drv_clock.h" +#include "softdevice_handler.h" +#include "nrf_drv_uart.h" +#include "nrf_gpio.h" + +#include + +static rt_bool_t osready = RT_FALSE; + +#if 0 + +/******************************************************************************* + * Function Name : SysTick_Configuration + * Description : Configures the SysTick for OS tick. + * Input : None + * Output : None + * Return : None + *******************************************************************************/ +void SysTick_Configuration(void) +{ + nrf_drv_common_irq_enable(SysTick_IRQn, APP_TIMER_CONFIG_IRQ_PRIORITY); + nrf_systick_load_set(SystemCoreClock / RT_TICK_PER_SECOND); + nrf_systick_val_clear(); + nrf_systick_csr_set(NRF_SYSTICK_CSR_CLKSOURCE_CPU | NRF_SYSTICK_CSR_TICKINT_ENABLE + | NRF_SYSTICK_CSR_ENABLE); +} + +/** + * This is the timer interrupt service routine. + * + */ + + +void SysTick_Handler(void) +{ + if (osready) + { + /* enter interrupt */ + rt_interrupt_enter(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); + } +} + +#else + +#define TICK_RATE_HZ RT_TICK_PER_SECOND +#define SYSTICK_CLOCK_HZ ( 32768UL ) + +#define NRF_RTC_REG NRF_RTC1 + /* IRQn used by the selected RTC */ +#define NRF_RTC_IRQn RTC1_IRQn + /* Constants required to manipulate the NVIC. */ +#define NRF_RTC_PRESCALER ( (uint32_t) (ROUNDED_DIV(SYSTICK_CLOCK_HZ, TICK_RATE_HZ) - 1) ) + /* Maximum RTC ticks */ +#define NRF_RTC_MAXTICKS ((1U<<24)-1U) + +static volatile uint32_t m_tick_overflow_count = 0; +#define NRF_RTC_BITWIDTH 24 +#define OSTick_Handler RTC1_IRQHandler +#define EXPECTED_IDLE_TIME_BEFORE_SLEEP 2 + +void SysTick_Configuration(void) +{ + nrf_drv_clock_lfclk_request(NULL); + + /* Configure SysTick to interrupt at the requested rate. */ + nrf_rtc_prescaler_set(NRF_RTC_REG, NRF_RTC_PRESCALER); + nrf_rtc_int_enable (NRF_RTC_REG, RTC_INTENSET_TICK_Msk); + nrf_rtc_task_trigger (NRF_RTC_REG, NRF_RTC_TASK_CLEAR); + nrf_rtc_task_trigger (NRF_RTC_REG, NRF_RTC_TASK_START); + nrf_rtc_event_enable(NRF_RTC_REG, RTC_EVTEN_OVRFLW_Msk); + + NVIC_SetPriority(NRF_RTC_IRQn, 0xF); + NVIC_EnableIRQ(NRF_RTC_IRQn); +} + +void OSTick_Handler( void ) +{ + nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0); + + uint32_t systick_counter = nrf_rtc_counter_get(NRF_RTC_REG); + nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_TICK); + + /* check for overflow in TICK counter */ + if(nrf_rtc_event_pending(NRF_RTC_REG, NRF_RTC_EVENT_OVERFLOW)) + { + nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_OVERFLOW); + m_tick_overflow_count++; + } + + { + uint32_t diff; + diff = ((m_tick_overflow_count << NRF_RTC_BITWIDTH) + systick_counter) - rt_tick_get(); + + while((diff--) > 0) + { + if (osready) + { + /* enter interrupt */ + rt_interrupt_enter(); + + rt_tick_increase(); + + /* leave interrupt */ + rt_interrupt_leave(); + } + } + } +} + +static void _sleep_ongo( uint32_t sleep_tick ) +{ + /* + * Implementation note: + * + * To help debugging the option configUSE_TICKLESS_IDLE_SIMPLE_DEBUG was presented. + * This option would make sure that even if program execution was stopped inside + * this function no more than expected number of ticks would be skipped. + * + * Normally RTC works all the time even if firmware execution was stopped + * and that may lead to skipping too much of ticks. + */ + uint32_t enterTime; + + uint32_t entry_tick; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if ( sleep_tick > NRF_RTC_MAXTICKS - EXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + sleep_tick = NRF_RTC_MAXTICKS - EXPECTED_IDLE_TIME_BEFORE_SLEEP; + } + + rt_enter_critical(); + + enterTime = nrf_rtc_counter_get(NRF_RTC_REG); + + // if ( eTaskConfirmSleepModeStatus() != eAbortSleep ) + { + uint32_t wakeupTime = (enterTime + sleep_tick) & NRF_RTC_MAXTICKS; + + /* Stop tick events */ + nrf_rtc_int_disable(NRF_RTC_REG, NRF_RTC_INT_TICK_MASK); + + /* Configure CTC interrupt */ + nrf_rtc_cc_set(NRF_RTC_REG, 0, wakeupTime); + nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0); + nrf_rtc_int_enable(NRF_RTC_REG, NRF_RTC_INT_COMPARE0_MASK); + + entry_tick = rt_tick_get(); + + __DSB(); + + if ( sleep_tick > 0 ) + { +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + uint32_t err_code = sd_app_evt_wait(); + APP_ERROR_CHECK(err_code); + } + else +#endif + { + /* No SD - we would just block interrupts globally. + * BASEPRI cannot be used for that because it would prevent WFE from wake up. + */ + do{ + __WFE(); + } while (0 == (NVIC->ISPR[0] | NVIC->ISPR[1])); + } + } + + nrf_rtc_int_disable(NRF_RTC_REG, NRF_RTC_INT_COMPARE0_MASK); + nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0); + + /* Correct the system ticks */ + { + + nrf_rtc_event_clear(NRF_RTC_REG, NRF_RTC_EVENT_TICK); + nrf_rtc_int_enable (NRF_RTC_REG, NRF_RTC_INT_TICK_MASK); + /* It is important that we clear pending here so that our corrections are latest and in sync with tick_interrupt handler */ + NVIC_ClearPendingIRQ(NRF_RTC_IRQn); + } + + rt_kprintf("entry tick:%u, expected:%u, current tick:%u\n", entry_tick, sleep_tick, rt_tick_get()); + } + + rt_exit_critical(); +} + +#endif + +void rt_os_ready(void) +{ + osready = 1; +} + +void rt_hw_system_powersave(void) +{ + uint32_t sleep_tick; + + sleep_tick = rt_timer_next_timeout_tick() - rt_tick_get(); + + if ( sleep_tick >= EXPECTED_IDLE_TIME_BEFORE_SLEEP) + { + // rt_kprintf("sleep entry:%u\n", rt_tick_get()); + _sleep_ongo( sleep_tick ); + } +} + +void rt_hw_board_init(void) +{ + // sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE); + /* Activate deep sleep mode */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + nrf_drv_clock_init(); + // nrf_drv_clock_hfclk_request(0); + + SysTick_Configuration(); + + rt_thread_idle_sethook(rt_hw_system_powersave); + + rt_hw_uart_init(); + +#ifdef RT_USING_CONSOLE + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif +} + diff --git a/bsp/nrf52832/board/board.h b/bsp/nrf52832/board/board.h new file mode 100644 index 0000000000000000000000000000000000000000..7f81fde4d0475ba2b3e8097008393f3d6ece2771 --- /dev/null +++ b/bsp/nrf52832/board/board.h @@ -0,0 +1,15 @@ +#ifndef _BOARD_H_ +#define _BOARD_H_ + +#include + +#include "nrf.h" + +#define CHIP_SRAM_END (0x20000000 + 64*1024) + +void rt_hw_board_init(void); + +void rt_os_ready(void); + +#endif + diff --git a/bsp/nrf52832/board/uart.c b/bsp/nrf52832/board/uart.c new file mode 100644 index 0000000000000000000000000000000000000000..837ef2dc26d73cd68fad86b4ae33fc7fd916027d --- /dev/null +++ b/bsp/nrf52832/board/uart.c @@ -0,0 +1,289 @@ +#include "board.h" +#include "uart.h" + +#include "nrf_drv_common.h" +#include "nrf_drv_uart.h" +#include "app_util_platform.h" +#include "nrf_gpio.h" + +#include + +static struct rt_serial_device _serial0_0; +#if USE_UART0_1 +static struct rt_serial_device _serial0_1; +#endif + +typedef struct +{ + struct rt_serial_device *serial; + nrf_drv_uart_t uart; + uint32_t rx_pin; + uint32_t tx_pin; +} UART_CFG_T; + +UART_CFG_T uart0 = { + .uart = NRF_DRV_UART_INSTANCE(0), +#ifdef RT_USING_CONSOLE + .rx_pin = 3, + .tx_pin = 4 +#else + .rx_pin = 19, + .tx_pin = 20 +#endif +}; + +#if USE_UART0_1 +UART_CFG_T uart1 = { + .uart = NRF_DRV_UART_INSTANCE(0), + .rx_pin = 3, + .tx_pin = 4 +}; +#endif + +UART_CFG_T *working_cfg = RT_NULL; + +void UART0_IRQHandler(void) +{ + if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_ERROR) + && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_ERROR)) + { + nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR); + } + + if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_RXDRDY) + && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXDRDY)) + { + rt_hw_serial_isr(working_cfg->serial, RT_SERIAL_EVENT_RX_IND); + } + + if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_TXDRDY) + && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY)) + { + rt_hw_serial_isr(working_cfg->serial, RT_SERIAL_EVENT_TX_DONE); + } + + if (nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXTO)) + { + rt_hw_serial_isr(working_cfg->serial, RT_SERIAL_EVENT_RX_TIMEOUT); + } +} + +static rt_err_t _uart_cfg(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG; + UART_CFG_T *instance = &uart0; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + if (serial->parent.user_data != RT_NULL) + { + instance = (UART_CFG_T*)serial->parent.user_data; + } + + nrf_uart_disable(instance->uart.reg.p_uart); + + switch (cfg->baud_rate) + { + case 115200: + config.baudrate = NRF_UART_BAUDRATE_115200; + break; + + case 9600: + config.baudrate = NRF_UART_BAUDRATE_9600; + break; + + default: + config.baudrate = NRF_UART_BAUDRATE_115200; + break; + } + + if (cfg->parity == PARITY_NONE) + { + config.parity = NRF_UART_PARITY_EXCLUDED; + } + else + { + config.parity = NRF_UART_PARITY_INCLUDED; + } + + config.hwfc = NRF_UART_HWFC_DISABLED; + config.interrupt_priority = APP_IRQ_PRIORITY_LOWEST; + config.pselcts = 0; + config.pselrts = 0; + config.pselrxd = instance->rx_pin; + config.pseltxd = instance->tx_pin; + + nrf_gpio_pin_set(config.pseltxd); + nrf_gpio_cfg_output(config.pseltxd); + nrf_gpio_pin_clear(config.pseltxd); + nrf_gpio_cfg_input(config.pselrxd, NRF_GPIO_PIN_NOPULL); + nrf_uart_baudrate_set(instance->uart.reg.p_uart, config.baudrate); + nrf_uart_configure(instance->uart.reg.p_uart, config.parity, config.hwfc); + nrf_uart_txrx_pins_set(instance->uart.reg.p_uart, config.pseltxd, config.pselrxd); + + if (config.hwfc == NRF_UART_HWFC_ENABLED) + { + nrf_uart_hwfc_pins_set(instance->uart.reg.p_uart, config.pselrts, config.pselcts); + } + + nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_TXDRDY); + nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_RXDRDY); + nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_RXTO); + nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_ERROR); + + nrf_uart_int_enable(instance->uart.reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_RXTO | NRF_UART_INT_MASK_ERROR); + nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)instance->uart.reg.p_uart), config.interrupt_priority); + nrf_uart_enable(instance->uart.reg.p_uart); + // nrf_uart_task_trigger(instance->uart.reg.p_uart, NRF_UART_TASK_STARTRX); + working_cfg = instance; + return RT_EOK; +} + +static rt_err_t _uart_ctrl(struct rt_serial_device *serial, int cmd, void *arg) +{ + UART_CFG_T *instance = working_cfg; + + RT_ASSERT(serial != RT_NULL); + + if (serial->parent.user_data != RT_NULL) + { + instance = (UART_CFG_T*)serial->parent.user_data; + } + + switch (cmd) + { + /* disable interrupt */ + case RT_DEVICE_CTRL_CLR_INT: + nrf_uart_task_trigger(instance->uart.reg.p_uart, NRF_UART_TASK_STOPRX); + nrf_uart_int_disable(instance->uart.reg.p_uart, NRF_UART_INT_MASK_RXDRDY + | NRF_UART_INT_MASK_RXTO + | NRF_UART_INT_MASK_ERROR); + nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)instance->uart.reg.p_uart)); + break; + + /* enable interrupt */ + case RT_DEVICE_CTRL_SET_INT: + nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_RXDRDY); + nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_RXTO); + nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_ERROR); + /* Enable RX interrupt. */ + nrf_uart_int_enable(instance->uart.reg.p_uart, NRF_UART_INT_MASK_RXDRDY + | NRF_UART_INT_MASK_RXTO + | NRF_UART_INT_MASK_ERROR); + nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)instance->uart.reg.p_uart), APP_IRQ_PRIORITY_LOWEST); + nrf_uart_task_trigger(instance->uart.reg.p_uart, NRF_UART_TASK_STARTRX); + break; + + case RT_DEVICE_CTRL_CUSTOM: + if ((rt_uint32_t)(arg) == UART_CONFIG_BAUD_RATE_9600) + { + instance->serial->config.baud_rate = 9600; + nrf_uart_baudrate_set(instance->uart.reg.p_uart, NRF_UART_BAUDRATE_9600); + } + else if ((rt_uint32_t)(arg) == UART_CONFIG_BAUD_RATE_115200) + { + instance->serial->config.baud_rate = 115200; + nrf_uart_baudrate_set(instance->uart.reg.p_uart, NRF_UART_BAUDRATE_115200); + } + + // _uart_cfg(instance->serial, &(instance->serial->config)); + // nrf_uart_task_trigger(instance->uart.reg.p_uart, NRF_UART_TASK_STARTRX); + break; + + case RT_DEVICE_CTRL_PIN: + if (working_cfg != instance) + { + _uart_cfg(instance->serial, &(instance->serial->config)); + } + break; + + case RT_DEVICE_POWERSAVE: + nrf_uart_disable(instance->uart.reg.p_uart); + nrf_uart_txrx_pins_disconnect(instance->uart.reg.p_uart); + nrf_gpio_pin_clear(instance->rx_pin); + nrf_gpio_cfg_output(instance->rx_pin); + nrf_gpio_pin_clear(instance->tx_pin); + nrf_gpio_cfg_output(instance->tx_pin); + break; + + case RT_DEVICE_WAKEUP: + _uart_cfg(instance->serial, &(instance->serial->config)); + break; + + default: + return RT_ERROR; + } + + return RT_EOK; +} + +static int _uart_putc(struct rt_serial_device *serial, char c) +{ + UART_CFG_T *instance = working_cfg; + + RT_ASSERT(serial != RT_NULL); + + if (serial->parent.user_data != RT_NULL) + { + instance = (UART_CFG_T*)serial->parent.user_data; + } + + nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_TXDRDY); + nrf_uart_task_trigger(instance->uart.reg.p_uart, NRF_UART_TASK_STARTTX); + nrf_uart_txd_set(instance->uart.reg.p_uart, (uint8_t)c); + while (!nrf_uart_event_check(instance->uart.reg.p_uart, NRF_UART_EVENT_TXDRDY)) + { + } + + return 1; +} + +static int _uart_getc(struct rt_serial_device *serial) +{ + int ch = -1; + UART_CFG_T *instance = working_cfg; + + RT_ASSERT(serial != RT_NULL); + + if (serial->parent.user_data != RT_NULL) + { + instance = (UART_CFG_T*)serial->parent.user_data; + } + + if (nrf_uart_event_check(instance->uart.reg.p_uart, NRF_UART_EVENT_RXDRDY)) + { + nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_RXDRDY); + ch = (int)(nrf_uart_rxd_get(instance->uart.reg.p_uart)); + } + + return ch; +} + +static struct rt_uart_ops _uart_ops = { + _uart_cfg, + _uart_ctrl, + _uart_putc, + _uart_getc +}; + +void rt_hw_uart_init(void) +{ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + + config.bufsz = RT_SERIAL_RB_BUFSZ; + _serial0_0.config = config; + _serial0_0.ops = &_uart_ops; + uart0.serial = &_serial0_0; + + rt_hw_serial_register(&_serial0_0, "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart0); + +#if USE_UART0_1 + config.bufsz = UART0_RB_SIZE; + _serial0_1.config = config; + _serial0_1.ops = &_uart_ops; + uart1.serial = &_serial0_1; + rt_hw_serial_register(&_serial0_1, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart1); +#endif +} + diff --git a/bsp/nrf52832/board/uart.h b/bsp/nrf52832/board/uart.h new file mode 100644 index 0000000000000000000000000000000000000000..da37eff016c0aa84708edb7cdd2c83bb7d3b598c --- /dev/null +++ b/bsp/nrf52832/board/uart.h @@ -0,0 +1,19 @@ +#ifndef _UART_H_ +#define _UART_H_ + +#define RT_DEVICE_CTRL_CUSTOM 0x20 +#define RT_DEVICE_CTRL_PIN 0x21 +#define RT_DEVICE_POWERSAVE 0x22 +#define RT_DEVICE_WAKEUP 0x23 + +#define UART_CONFIG_BAUD_RATE_9600 1 +#define UART_CONFIG_BAUD_RATE_115200 2 + +#define UART0_RB_SIZE 1024 + +// #define USE_UART0_1 0 + +void rt_hw_uart_init(void); + +#endif + diff --git a/bsp/nrf52832/drivers/SConscript b/bsp/nrf52832/drivers/SConscript deleted file mode 100644 index 638846d6564b73e6a6554e8791a062a2e13885ca..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/drivers/SConscript +++ /dev/null @@ -1,13 +0,0 @@ -Import('RTT_ROOT') -Import('rtconfig') -from building import * - -# get current directory -cwd = GetCurrentDir() - -src = Glob('*.c') -CPPPATH = [cwd] - -group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) - -Return('group') diff --git a/bsp/nrf52832/drivers/board.c b/bsp/nrf52832/drivers/board.c deleted file mode 100644 index 2bb937440181722d4b813fef8e1e28b069b91110..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/drivers/board.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * File : board.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2015 RT-Thread Develop Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2015-11-11 Xue Liu Initial for nRF52 - */ - -#include -#include - -#include -#include - -#include "board.h" -#include "uart.h" - -/** - * @addtogroup NRF52832 - */ - -/** @brief: Function for handling the Systick interrupts. - */ -void SysTick_Handler(void) -{ - /* enter interrupt */ - rt_interrupt_enter(); - - rt_tick_increase(); //This function will notify kernel there is one tick passed - - /* leave interrupt */ - rt_interrupt_leave(); -} - - -/** - * This function will initial NRF52832 board. - */ -void rt_hw_board_init() -{ - /* Configure the SysTick */ - SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND); - - /* Initial usart deriver, and set console device */ - rt_hw_uart_init(); - -#ifdef RT_USING_CONSOLE - rt_console_set_device(RT_CONSOLE_DEVICE_NAME); -#endif -} - -/*@}*/ diff --git a/bsp/nrf52832/drivers/board.h b/bsp/nrf52832/drivers/board.h deleted file mode 100644 index e19ceb246ec56cbef78ecf8572376da9450c006c..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/drivers/board.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * File : board.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2009, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - */ - -#ifndef __BOARD_H__ -#define __BOARD_H__ - - - -void rt_hw_board_init(void); - -#endif diff --git a/bsp/nrf52832/drivers/uart.c b/bsp/nrf52832/drivers/uart.c deleted file mode 100644 index a77ae021ef2083e028928c3a8431762050feb4c0..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/drivers/uart.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * File : uart.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2015 RT-Thread Develop Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - */ - -#include -#include -#include - -#include -#include - -#include "board.h" -#include "uart.h" - -#include - -#define UART_RX_BUFSZ 512 -rt_uint8_t rx_buffer[UART_RX_BUFSZ]; - -struct nrf52832_uart -{ - struct rt_device parent; - struct rt_ringbuffer rx_rb; -} uart_device; - -void UART0_IRQHandler(void) -{ - rt_ubase_t level; - struct nrf52832_uart* uart = &uart_device; - - level = rt_hw_interrupt_disable(); - - // Wait for RXD data to be received - while (NRF_UART0->EVENTS_RXDRDY != 1) ; - NRF_UART0->EVENTS_RXDRDY = 0; - - rt_hw_interrupt_enable(level); - /* [Handling the data received over UART] */ - rt_ringbuffer_putchar_force(&(uart->rx_rb), (rt_uint8_t)NRF_UART0->RXD); - - /* invoke callback */ - if(uart->parent.rx_indicate != RT_NULL) - { - uart->parent.rx_indicate(&uart->parent, rt_ringbuffer_data_len(&uart->rx_rb)); - } -} - - -static rt_err_t rt_uart_init (rt_device_t dev) -{ - /* UART Initialization and Enable */ - /** @snippet [Configure UART RX and TX pin] */ - nrf_gpio_cfg_output(TX_PIN_NUMBER); - nrf_gpio_cfg_input(RX_PIN_NUMBER, NRF_GPIO_PIN_NOPULL); - - NRF_UART0->PSELTXD = TX_PIN_NUMBER; - NRF_UART0->PSELRXD = RX_PIN_NUMBER; - /** @snippet [Configure UART RX and TX pin] */ - if (HWFC) - { - nrf_gpio_cfg_output(RTS_PIN_NUMBER); - nrf_gpio_cfg_input(CTS_PIN_NUMBER, NRF_GPIO_PIN_NOPULL); - NRF_UART0->PSELCTS = CTS_PIN_NUMBER; - NRF_UART0->PSELRTS = RTS_PIN_NUMBER; - NRF_UART0->CONFIG = (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); - } - - NRF_UART0->BAUDRATE = (UART_BAUDRATE_BAUDRATE_Baud38400 << UART_BAUDRATE_BAUDRATE_Pos); - NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos); - NRF_UART0->TASKS_STARTTX = 1; - NRF_UART0->TASKS_STARTRX = 1; - NRF_UART0->EVENTS_RXDRDY = 0; - - NRF_UART0->INTENSET = (UART_INTENSET_RXDRDY_Enabled << UART_INTENSET_RXDRDY_Pos); - - NVIC_EnableIRQ(UART0_IRQn); - - return RT_EOK; -} - -static rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag) -{ - RT_ASSERT(dev != RT_NULL); - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - /* Enable the UART Interrupt */ - NVIC_EnableIRQ(UART0_IRQn); - } - - return RT_EOK; -} - -static rt_err_t rt_uart_close(rt_device_t dev) -{ - RT_ASSERT(dev != RT_NULL); - if (dev->flag & RT_DEVICE_FLAG_INT_RX) - { - /* Disable the UART Interrupt */ - NVIC_DisableIRQ(UART0_IRQn); - } - - return RT_EOK; -} - -static rt_size_t rt_uart_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) -{ - rt_size_t length; - struct nrf52832_uart *uart = (struct nrf52832_uart*)dev; - /* interrupt receive */ - rt_base_t level; - - RT_ASSERT(uart != RT_NULL); - - /* disable interrupt */ - level = rt_hw_interrupt_disable(); - length = rt_ringbuffer_get(&(uart->rx_rb), buffer, size); - /* enable interrupt */ - rt_hw_interrupt_enable(level); - - return length; -} - -static rt_size_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) -{ - char *ptr; - ptr = (char*) buffer; - - if (dev->open_flag & RT_DEVICE_FLAG_STREAM) - { - /* stream mode */ - while (size) - { - if (*ptr == '\n') - { - NRF_UART0->TXD = (uint8_t)'\r'; - - // Wait for TXD data to be sent. - while (NRF_UART0->EVENTS_TXDRDY != 1) ; - - NRF_UART0->EVENTS_TXDRDY = 0; - } - - NRF_UART0->TXD = (uint8_t)(*ptr); - - // Wait for TXD data to be sent. - while (NRF_UART0->EVENTS_TXDRDY != 1) ; - - NRF_UART0->EVENTS_TXDRDY = 0; - - ptr ++; - size --; - } - } - else - { - while ( size != 0 ) - { - NRF_UART0->TXD = (uint8_t)(*ptr); - - // Wait for TXD data to be sent. - while (NRF_UART0->EVENTS_TXDRDY != 1) ; - - NRF_UART0->EVENTS_TXDRDY = 0; - - ptr++; - size--; - } - } - - return (rt_size_t) ptr - (rt_size_t) buffer; -} - -void rt_hw_uart_init(void) -{ - struct nrf52832_uart* uart; - - /* get uart device */ - uart = &uart_device; - - /* device initialization */ - uart->parent.type = RT_Device_Class_Char; - rt_ringbuffer_init(&(uart->rx_rb), rx_buffer, sizeof(rx_buffer)); - - /* device interface */ - uart->parent.init = rt_uart_init; - uart->parent.open = rt_uart_open; - uart->parent.close = rt_uart_close; - uart->parent.read = rt_uart_read; - uart->parent.write = rt_uart_write; - uart->parent.control = RT_NULL; - uart->parent.user_data = RT_NULL; - - rt_device_register(&uart->parent, "uart0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX); -} diff --git a/bsp/nrf52832/drivers/uart.h b/bsp/nrf52832/drivers/uart.h deleted file mode 100644 index ec620cac777568e31b17a1171ad25dedbbc44e7b..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/drivers/uart.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * File : uart.h - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2015, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - */ - -#ifndef __UART_H__ -#define __UART_H__ - - - -#define RX_PIN_NUMBER 8 -#define TX_PIN_NUMBER 6 -#define CTS_PIN_NUMBER 7 -#define RTS_PIN_NUMBER 5 -#define HWFC false - - -void rt_hw_uart_init(void); - -#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/Sconscript b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/Sconscript new file mode 100644 index 0000000000000000000000000000000000000000..52d864a76144614af4170d29caba6a36462728ae --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/Sconscript @@ -0,0 +1,34 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +# get current directory +cwd = GetCurrentDir() + +BLE_COMMON = Glob('./components/ble/common/*.c') +SrcRemove(BLE_COMMON, 'ble_conn_state.c') + +BLE_GATT = Glob('./components/ble/nrf_ble_gatt/*.c') +BLE_ADVERTISING = Glob('./components/ble/ble_advertising/*.c') + +BLE_SERVICE = Glob('./components/ble/ble_services/ble_nus/*.c') + +BLE_SRC = BLE_COMMON + BLE_GATT + BLE_SERVICE + BLE_ADVERTISING + +SOFTDEVICE = Glob('./components/softdevice/common/softdevice_handler/*.c') +SrcRemove(SOFTDEVICE, 'softdevice_handler_appsh.c') + +BLE_STACK_SRC = BLE_SRC + SOFTDEVICE + +path = [cwd + '/components'] +path += [cwd + '/components/softdevice/common/softdevice_handler'] +path += [cwd + '/components/softdevice/s132/headers'] +path += [cwd + '/components/softdevice/s132/headers/nrf52'] +path += [cwd + '/components/ble/common'] +path += [cwd + '/components/ble/nrf_ble_gatt'] +path += [cwd + '/components/ble/ble_advertising'] +path += [cwd + '/components/ble/ble_services/ble_nus'] + +CPPDEFINES = ['BLE_STACK_SUPPORT_REQD', 'NRF_SD_BLE_API_VERSION=4', 'S132', 'SOFTDEVICE_PRESENT'] +group = DefineGroup('BLE_STACK', BLE_STACK_SRC, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) +Return('group') diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/SConscript b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..a5f18ca9871f44ef0e6116acef50ba04710e68e8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/SConscript @@ -0,0 +1,52 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +# get current directory +cwd = GetCurrentDir() + +DriversDir = cwd + '/drivers_nrf/' +DeviceDrivers = [DriversDir + 'hal/nrf_saadc.c'] +DeviceDrivers += [DriversDir + 'common/nrf_drv_common.c'] +#DeviceDrivers += [DriversDir + 'uart/nrf_drv_uart.c'] +DeviceDrivers += [DriversDir + 'clock/nrf_drv_clock.c'] +DeviceDrivers += [DriversDir + 'gpiote/nrf_drv_gpiote.c'] +DeviceDrivers += [DriversDir + 'pwm/nrf_drv_pwm.c'] +DeviceDrivers += [DriversDir + 'saadc/nrf_drv_saadc.c'] + +Libraries_dir = cwd + '/libraries/' +Libraries_src = Glob(Libraries_dir + 'log/src/*.c') +Libraries_src += Glob(Libraries_dir + 'timer/app_timer_rtthread.c') +Libraries_src += Glob(Libraries_dir + 'util/*.c') +Libraries_src += Glob(Libraries_dir + 'fstorage/fstorage.c') +Libraries_src += Glob(Libraries_dir + 'strerror/nrf_strerror.c') + +src = DeviceDrivers + Libraries_src + +path = [cwd] +path += [cwd + '/device'] +path += [cwd + '/drivers_nrf/delay'] +path += [cwd + '/drivers_nrf/uart'] +path += [cwd + '/drivers_nrf/clock'] +path += [cwd + '/drivers_nrf/gpiote'] +path += [cwd + '/drivers_nrf/common'] +path += [cwd + '/drivers_nrf/hal'] +path += [cwd + '/drivers_nrf/pwm'] +path += [DriversDir + 'saadc'] + +path += [Libraries_dir + 'util'] +path += [Libraries_dir + 'timer'] +path += [Libraries_dir + 'fstorage'] +path += [Libraries_dir + 'experimental_section_vars'] +path += [Libraries_dir + 'log'] +path += [Libraries_dir + 'log/src'] +path += [Libraries_dir + 'strerror'] + +path += [cwd + '/toolchain/cmsis/include'] + +CPPDEFINES = ['RTTHREAD', 'SWI_DISABLE0', 'CONFIG_GPIO_AS_PINRESET', 'NRF52', 'NRF52832_XXAA'] +CPPDEFINES += ['NRF52_PAN_12', 'NRF52_PAN_15', 'NRF52_PAN_20', 'NRF52_PAN_31', 'NRF52_PAN_36'] +CPPDEFINES += ['NRF52_PAN_51', 'NRF52_PAN_54', 'NRF52_PAN_55', 'NRF52_PAN_58', 'NRF52_PAN_64', 'NRF52_PAN_74'] + +group = DefineGroup('NRF_DRIVERS', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) +Return('group') diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_channel_config/ant_channel_config.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_channel_config/ant_channel_config.c new file mode 100644 index 0000000000000000000000000000000000000000..f4ae6c8270a211d118ecf28ff87a46610e5be5d1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_channel_config/ant_channel_config.c @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_CHANNEL_CONFIG) +#include "nrf_error.h" +#include "ant_channel_config.h" +#include "ant_interface.h" +#include "ant_parameters.h" + +uint32_t ant_channel_init(ant_channel_config_t const * p_config) +{ + uint32_t err_code; + // Set Channel Number. + err_code = sd_ant_channel_assign(p_config->channel_number, + p_config->channel_type, + p_config->network_number, + p_config->ext_assign); + + VERIFY_SUCCESS(err_code); + + // Set Channel ID. + err_code = sd_ant_channel_id_set(p_config->channel_number, + p_config->device_number, + p_config->device_type, + p_config->transmission_type); + + VERIFY_SUCCESS(err_code); + + // Set Channel RF frequency. + err_code = sd_ant_channel_radio_freq_set(p_config->channel_number, p_config->rf_freq); + VERIFY_SUCCESS(err_code); + + // Set Channel period. + if (!(p_config->ext_assign & EXT_PARAM_ALWAYS_SEARCH) && (p_config->channel_period != 0)) + { + err_code = sd_ant_channel_period_set(p_config->channel_number, p_config->channel_period); + } + + +#if ANT_CONFIG_ENCRYPTED_CHANNELS > 0 + VERIFY_SUCCESS(err_code); + + err_code = ant_channel_encrypt_config(p_config->channel_type , p_config->channel_number, p_config->p_crypto_settings); +#endif + + return err_code; +} + +#endif // NRF_MODULE_ENABLED(ANT_CHANNEL_CONFIG) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_channel_config/ant_channel_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_channel_config/ant_channel_config.h new file mode 100644 index 0000000000000000000000000000000000000000..9a1f9c56ad6edd708c9e8cc78802ed1628a169ca --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_channel_config/ant_channel_config.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_CHANNEL_CONFIG_H__ +#define ANT_CHANNEL_CONFIG_H__ + +/** @file + * + * @defgroup ant_channel_config ANT channel configuration + * @{ + * @ingroup ant_sdk_utils + * @brief ANT channel configuration module. + */ + +#include +#include "sdk_config.h" + + +#ifndef ANT_CONFIG_ENCRYPTED_CHANNELS + #error Undefined ANT_CONFIG_ENCRYPTED_CHANNELS. It should be defined in sdk_config.h file. +#elif ANT_CONFIG_ENCRYPTED_CHANNELS > 0 + #include "ant_encrypt_config.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief ANT channel configuration structure. */ +typedef struct +{ + uint8_t channel_number; ///< Assigned channel number. + uint8_t channel_type; ///< Channel type (see Assign Channel Parameters in ant_parameters.h: @ref ant_parameters). + uint8_t ext_assign; ///< Extended assign (see Ext. Assign Channel Parameters in ant_parameters.h: @ref ant_parameters). + uint8_t rf_freq; ///< Radio frequency offset from 2400 MHz (for example, 2466 MHz, rf_freq = 66). + uint8_t transmission_type; ///< Transmission type. + uint8_t device_type; ///< Device type. + uint16_t device_number; ///< Device number. + uint16_t channel_period; ///< The period in 32 kHz counts. + uint8_t network_number; ///< Network number denoting the network key. + +#if ANT_CONFIG_ENCRYPTED_CHANNELS > 0 + ant_encrypt_channel_settings_t * p_crypto_settings; ///< Pointer to cryptographic settings, NULL if this configuration have to be omitted. +#endif + +} ant_channel_config_t; + +/**@brief Function for configuring the ANT channel. + * + * @param[in] p_config Pointer to the channel configuration structure. + * + * @retval NRF_SUCCESS If the channel was successfully configured. Otherwise, an error code is returned. + */ +uint32_t ant_channel_init(ant_channel_config_t const * p_config); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_CHANNEL_CONFIG_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_encryption/ant_encrypt_config.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_encryption/ant_encrypt_config.c new file mode 100644 index 0000000000000000000000000000000000000000..10f01ca30855d2dea1151e1644134faf82677d37 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_encryption/ant_encrypt_config.c @@ -0,0 +1,239 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_ENCRYPT_CONFIG) +#include +#include "ant_encrypt_config.h" +#include "ant_interface.h" +#include "ant_parameters.h" + +#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED + #include "ant_encrypt_negotiation_slave.h" +#endif + + /*lint -e551 -save*/ +/** Flag for checking if stack was configured for encryption. */ +static bool m_stack_encryption_configured = false; + /*lint -restore */ + + /** Pointer to handler of module's events. */ +static ant_encryp_user_handler_t m_ant_enc_evt_handler = NULL; + +static ret_code_t ant_enc_advance_burs_config_apply( + ant_encrypt_adv_burst_settings_t const * const p_adv_burst_set); + +ret_code_t ant_stack_encryption_config(ant_encrypt_stack_settings_t const * const p_crypto_set) +{ + ret_code_t err_code; + + for ( uint32_t i = 0; i < p_crypto_set->key_number; i++) + { + err_code = sd_ant_crypto_key_set(i, p_crypto_set->pp_key[i]); + VERIFY_SUCCESS(err_code); + } + + if (p_crypto_set->p_adv_burst_config != NULL) + { + err_code = ant_enc_advance_burs_config_apply(p_crypto_set->p_adv_burst_config); + VERIFY_SUCCESS(err_code); + } + + // subcomands LUT for @ref sd_ant_crypto_info_set calls + const uint8_t set_enc_info_param_lut[] = + { + ENCRYPTION_INFO_SET_CRYPTO_ID, + ENCRYPTION_INFO_SET_CUSTOM_USER_DATA, + ENCRYPTION_INFO_SET_RNG_SEED + }; + + for ( uint32_t i = 0; i < sizeof(set_enc_info_param_lut); i++) + { + if ( p_crypto_set->info.pp_array[i] != NULL) + { + err_code = sd_ant_crypto_info_set(set_enc_info_param_lut[i], + p_crypto_set->info.pp_array[i]); + + VERIFY_SUCCESS(err_code); + } + } + + #ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED + // all ANT channels have unsupported slave encryption tracking (even master's channel) + ant_channel_encryp_negotiation_slave_init(); + #endif + + m_ant_enc_evt_handler = NULL; + + m_stack_encryption_configured = true; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for configuring advanced burst settings according to encryption requirements. + * + * @param p_adv_burst_set Pointer to ANT advanced burst settings. + * + * @retval Value returned by @ref sd_ant_adv_burst_config_set. + */ +static ret_code_t ant_enc_advance_burs_config_apply( + ant_encrypt_adv_burst_settings_t const * const p_adv_burst_set) +{ + uint8_t adv_burst_conf_str[ADV_BURST_CFG_MIN_SIZE] = + { ADV_BURST_MODE_ENABLE, 0, 0, 0, 0, 0, 0, 0 }; + + adv_burst_conf_str[ADV_BURST_CFG_PACKET_SIZE_INDEX] = p_adv_burst_set->packet_length; + adv_burst_conf_str[ADV_BURST_CFG_REQUIRED_FEATURES] = p_adv_burst_set->required_feature; + adv_burst_conf_str[ADV_BURST_CFG_OPTIONAL_FEATURES] = p_adv_burst_set->optional_feature; + + return sd_ant_adv_burst_config_set(adv_burst_conf_str, sizeof(adv_burst_conf_str)); +} + + +ret_code_t ant_channel_encrypt_config_perform(uint8_t channel_number, + ant_encrypt_channel_settings_t * p_crypto_config) +{ + return sd_ant_crypto_channel_enable(channel_number, + p_crypto_config->mode, + p_crypto_config->key_index, + p_crypto_config->decimation_rate); +} + + +ret_code_t ant_channel_encrypt_config(uint8_t channel_type, + uint8_t channel_number, + ant_encrypt_channel_settings_t * p_crypto_config) +{ + ret_code_t err_code; + + if (p_crypto_config != NULL) + { + // encryption of the stack should be initialized previously + if (m_stack_encryption_configured == false) + { + return NRF_ERROR_MODULE_NOT_INITIALZED; + } + + switch (channel_type) + { + case CHANNEL_TYPE_MASTER: + err_code = ant_channel_encrypt_config_perform(channel_number, p_crypto_config); +#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED + ant_channel_encryp_tracking_state_set(channel_number, + ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED); +#endif + break; + +#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED + case CHANNEL_TYPE_SLAVE: + ant_slave_channel_encrypt_config(channel_number, p_crypto_config); + + if (p_crypto_config->mode == ENCRYPTION_DISABLED_MODE) + { + err_code = ant_channel_encrypt_config_perform(channel_number, p_crypto_config); + ant_channel_encryp_tracking_state_set(channel_number, + ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED); + } + else + { + ant_channel_encryp_tracking_state_set(channel_number, + ANT_ENC_CHANNEL_STAT_NOT_TRACKING); + err_code = NRF_SUCCESS; + } + break; +#endif + + default: + err_code = NRF_ERROR_INVALID_PARAM; + break; + } + } + else + { +#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED + ant_channel_encryp_tracking_state_set(channel_number, + ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED); +#endif + err_code = NRF_SUCCESS; + } + + return err_code; +} + +/** @brief Function for calling the handler of module events.*/ +static void ant_encrypt_user_handler_try_to_run(uint8_t ant_channel, ant_encrypt_user_evt_t event) +{ + if (m_ant_enc_evt_handler != NULL) + { + m_ant_enc_evt_handler(ant_channel, event); + } +} + +void ant_encrypt_event_handler(ant_evt_t * p_ant_evt) +{ + uint8_t const ant_channel = p_ant_evt->channel; + +#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED + ant_slave_encrypt_negotiation(p_ant_evt); +#endif + + switch (p_ant_evt->event) + { + case EVENT_RX_FAIL_GO_TO_SEARCH: + ant_encrypt_user_handler_try_to_run(ant_channel, ANT_ENC_EVT_CHANNEL_LOST); + break; + + case EVENT_ENCRYPT_NEGOTIATION_SUCCESS: + ant_encrypt_user_handler_try_to_run(ant_channel, ANT_ENC_EVT_NEGOTIATION_SUCCESS); + break; + + case EVENT_ENCRYPT_NEGOTIATION_FAIL: + ant_encrypt_user_handler_try_to_run(ant_channel, ANT_ENC_EVT_NEGOTIATION_FAIL); + break; + } +} + +void ant_enc_event_handler_register(ant_encryp_user_handler_t user_handler_func) +{ + m_ant_enc_evt_handler = user_handler_func; +} + +#endif // NRF_MODULE_ENABLED(ANT_ENCRYPT_CONFIG) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_encryption/ant_encrypt_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_encryption/ant_encrypt_config.h new file mode 100644 index 0000000000000000000000000000000000000000..c48d6800252630e1539a51d470fb5662dd926d25 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_encryption/ant_encrypt_config.h @@ -0,0 +1,255 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_ENCRYPT_CONFIG__ +#define ANT_ENCRYPT_CONFIG__ + +/**@file + * + * @defgroup ant_encrypt_config ANT encryption configuration + * @{ + * @ingroup ant_sdk_utils + * + * @brief Encryption configuration for the ANT stack and channels. + * + */ + +#include + +#include "sdk_errors.h" +#include "ant_stack_handler_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @name Advanced burst configuration for encryption modules + * @{ + */ +#define ADV_BURST_CFG_MIN_SIZE 8 ///< Minimum size of the advance burst configuration data. +#define ADV_BURST_CFG_PACKET_SIZE_INDEX 1 ///< Index of the packet size field in the configuration data. +#define ADV_BURST_CFG_REQUIRED_FEATURES 2 ///< Index of the required features field in the configuration data. +#define ADV_BURST_CFG_OPTIONAL_FEATURES 5 ///< Index of the optional features field in the configuration data. +/**@} */ + +/** @brief ANT channel cryptographic configuration. */ +typedef struct +{ + uint8_t mode; ///< Encryption mode. See the encrypted channel defines in ant_parameters.h. + uint8_t key_index; ///< Index of encryption key. + uint8_t decimation_rate; ///< Division of the master channel rate by the slave’s tracking channel rate. +} ant_encrypt_channel_settings_t; + +/** @brief ANT encryption information. */ +typedef union +{ + uint8_t * pp_array[3]; // For array access support. + struct + { + uint8_t * p_encryption_id; ///< Pointer to the encryption ID of the device (4 bytes). + uint8_t * p_user_info; ///< Pointer to the user information string (19 bytes). + uint8_t * p_random_num_seed; ///< Pointer to the random number seed (16 bytes). + } items; +} ant_encrypt_info_settings_t; + +/** @brief Advanced burst settings used by the encrypted channel. */ +typedef struct +{ + uint8_t packet_length; ///< RF payload size. See the advanced burst configuration defines in ant_parameters.h. + uint8_t required_feature; ///< Required advanced burst modes. See the advanced burst configuration defines in ant_parameters.h. + uint8_t optional_feature; ///< Optional advanced burst modes. See the advanced burst configuration defines in ant_parameters.h. +} ant_encrypt_adv_burst_settings_t; + +/**@brief ANT stack cryptographic configuration. */ +typedef struct +{ + ant_encrypt_info_settings_t info; ///< Pointer to the encryption information structure. + uint8_t * * pp_key; ///< Pointer to an array for pointers to encryption keys. Each key must have a length of 16 bytes. + uint8_t key_number; ///< Number of encryption keys. + ant_encrypt_adv_burst_settings_t * p_adv_burst_config; ///< Advanced burst configuration. If NULL, the advanced burst must be configured externally. +} ant_encrypt_stack_settings_t; + +/** + * @brief ANT encryption negotiation events. + */ +typedef enum +{ + ANT_ENC_EVT_NEGOTIATION_SUCCESS, ///< Negotiation success. + ANT_ENC_EVT_NEGOTIATION_FAIL, ///< Negotiation failure. + ANT_ENC_EVT_CHANNEL_LOST ///< Lost a channel. It's relevant only for slave channels. +} ant_encrypt_user_evt_t; + +/** + * @brief Event handler for ANT encryption user events. + */ +typedef void (* ant_encryp_user_handler_t)(uint8_t channel, ant_encrypt_user_evt_t event); + +/** + * @brief Macro for initializing an ANT encryption information structure. + * + * @param[in] P_ENC_ID Pointer to the encryption ID of the device (4 bytes). + * @param[in] P_USER_INFO Pointer to the user information string (19 bytes). + * @param[in] P_RAND_NUM_SEED Pointer to the random number seed (16 bytes). + */ +#define ANT_CRYPTO_INFO_SETTINGS_INIT(P_ENC_ID, P_USER_INFO, P_RAND_NUM_SEED) \ + { \ + .items = \ + { \ + .p_encryption_id = P_ENC_ID, \ + .p_user_info = P_USER_INFO, \ + .p_random_num_seed = P_RAND_NUM_SEED \ + } \ + } + +/** + * @brief Macro for declaring the basic cryptographic configuration for the ANT stack. + * + * This macro configures the following settings: + * - Cryptographic key + * - Encryption ID + * - Advanced burst mode with the maximum RF payload size + * + * Use @ref ANT_ENCRYPT_STACK_SETTINGS_BASE to access the created configuration instance. + * + * @param[in] NAME Name for the created data instance. + * @param[in] P_KEY Pointer to the cryptographic key (16 bytes). + * @param[in] P_ENC_ID Pointer to the encryption ID (4 bytes). + */ +#define ANT_ENCRYPT_STACK_SETTINGS_BASE_DEF(NAME, P_KEY, P_ENC_ID) \ + ant_encrypt_adv_burst_settings_t NAME##_ant_enc_adv_burst_set = \ + { \ + .packet_length = ADV_BURST_MODES_MAX_SIZE, \ + .required_feature = 0, \ + .optional_feature = 0 \ + }; \ + uint8_t * pp_##NAME##_key[1] = {P_KEY}; \ + ant_encrypt_stack_settings_t NAME ## _ant_crypto_settings = \ + { \ + .info = ANT_CRYPTO_INFO_SETTINGS_INIT(P_ENC_ID, NULL, NULL), \ + .pp_key = pp_##NAME##_key, \ + .key_number = 1, \ + .p_adv_burst_config = &NAME##_ant_enc_adv_burst_set \ + } + + +/** @brief Macro for accessing the configuration instance created + * by @ref ANT_ENCRYPT_STACK_SETTINGS_BASE_DEF. + * + * @param[in] NAME Name of the settings instance. + */ +#define ANT_ENCRYPT_STACK_SETTINGS_BASE(NAME) (NAME##_ant_crypto_settings) + +/** + * @brief Function for applying an encryption configuration to a slave channel. + * + * This function enables encryption on a channel. + * + * This function should be used by the @ref ant_encrypt_negotiation_slave module and this module. + * + * @param[in] channel_number ANT channel number. + * @param[in] p_crypto_config Pointer to the encryption configuration. + * + * @return Value returned by @ref sd_ant_crypto_channel_enable (for example, NRF_SUCCESS if + * the configuration was successful). + */ +ret_code_t ant_channel_encrypt_config_perform(uint8_t channel_number, + ant_encrypt_channel_settings_t * p_crypto_config); + +/** + * @brief Function for applying an encryption configuration to a master or slave channel. + * + * When called for a master channel, this function enables encryption + * for that channel. When called for a slave channel, it saves + * the encryption configuration for future use. + * + * This function should be used by the @ref ant_channel_config module. + * + * @param[in] channel_type ANT channel type: CHANNEL_TYPE_SLAVE or CHANNEL_TYPE_MASTER. + * @param[in] channel_num ANT channel number. + * @param[in] p_crypto_config Pointer to the encryption configuration. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_PARAM If the channel type is invalid. + * @retval NRF_ERROR_MODULE_NOT_INITIALZED If the stack is not configured for encryption. + * @retval Other Otherwise, the error value returned by the @ref + * ant_channel_encrypt_config_perform function is returned. + */ +ret_code_t ant_channel_encrypt_config(uint8_t channel_type, + uint8_t channel_num, + ant_encrypt_channel_settings_t * p_crypto_config); + +/** + * @brief Function for configuring the cryptographic settings of the ANT stack. + * + * @param[in] p_crypto_info_set Pointer to the settings. + */ +ret_code_t ant_stack_encryption_config(ant_encrypt_stack_settings_t const * const p_crypto_info_set); + + +/** + * @brief Function for handling ANT encryption events. + * + * This function should be used directly in the ANT event dispatching process. + * It serves the ANT encryption events to the registered event handler. + * If @ref ant_encrypt_negotiation_slave is used, this function is required. + * + * This function should be used by the @ref ant_encrypt_config module. + * + * @param[in] p_ant_evt Pointer to the ANT stack event message structure. + */ +void ant_encrypt_event_handler(ant_evt_t * p_ant_evt); + +/** + * @brief Function for registering an event handler for ANT encryption events. + * + * The event handler should support all of the events in @ref ant_encrypt_user_evt_t. + * + * @param[in] p_handler Pointer to a handler function. + */ +void ant_enc_event_handler_register(ant_encryp_user_handler_t p_handler); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif // ANT_ENCRYPT_CONFIG__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_encryption/ant_encrypt_negotiation_slave.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_encryption/ant_encrypt_negotiation_slave.c new file mode 100644 index 0000000000000000000000000000000000000000..39dcac33f9a39bec18bc59b8e640e11332651ea5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_encryption/ant_encrypt_negotiation_slave.c @@ -0,0 +1,189 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_ENCRYPT_NEGOTIATION_SLAVE) +#include +#include +#include "ant_encrypt_config.h" +#include "ant_interface.h" +#include "ant_parameters.h" +#include "nrf_error.h" +#include "app_error.h" + +#include "ant_encrypt_negotiation_slave.h" + +/** Number of supported channels. */ +#define NUMBER_OF_CHANNELS (ANT_CONFIG_TOTAL_CHANNELS_ALLOCATED) + +/** Flag to block other channels from attempting to enable encryption while + * another encryption is in the process. + */ +static volatile bool m_can_enable_crypto = true; + +/** Array to keep track of which channels are currently tracking. */ +static ant_encrypt_tracking_state_t m_encrypt_channel_states[NUMBER_OF_CHANNELS]; + +/** Array for the slave channels' encryption settings. */ +static ant_encrypt_channel_settings_t m_slave_channel_conf[MAX_ANT_CHANNELS]; + + + +void ant_channel_encryp_tracking_state_set(uint8_t channel_number, + ant_encrypt_tracking_state_t state) +{ + m_encrypt_channel_states[channel_number] = state; +} + + +void ant_channel_encryp_negotiation_slave_init(void) +{ + for (uint32_t channel = 0; channel < NUMBER_OF_CHANNELS; channel++) + { + ant_channel_encryp_tracking_state_set(channel, ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED); + } + + m_can_enable_crypto = true; +} + + +ant_encrypt_tracking_state_t ant_channel_encryp_tracking_state_get(uint8_t channel_number) +{ + return m_encrypt_channel_states[channel_number]; +} + + +void ant_slave_channel_encrypt_config(uint8_t channel_number, + ant_encrypt_channel_settings_t const * const p_crypto_config) +{ + memcpy(&m_slave_channel_conf[channel_number], p_crypto_config, + sizeof(ant_encrypt_channel_settings_t)); +} + + +/**@brief Function for handling ANT RX channel events. + * + * @param[in] p_event_message_buffer The ANT event message buffer. + */ +static void ant_slave_encrypt_try_enable(uint8_t ant_channel, + uint8_t ant_message_id) +{ + uint32_t err_code; + ant_encrypt_tracking_state_t track_stat; + + + switch (ant_message_id) + { + // Broadcast data received. + case MESG_BROADCAST_DATA_ID: + + track_stat = ant_channel_encryp_tracking_state_get(ant_channel); + // If the encryption has not yet been negotiated for this channel and another channel + // is not currently trying to enable encryption, enable encryption + if ((track_stat != ANT_ENC_CHANNEL_STAT_TRACKING_DECRYPTED) + && (track_stat != ANT_ENC_CHANNEL_STAT_NEGOTIATING) + && m_can_enable_crypto) + { + // Block other channels from trying to enable encryption until this channel + // is finished + m_can_enable_crypto = false; + ant_channel_encryp_tracking_state_set(ant_channel, + ANT_ENC_CHANNEL_STAT_NEGOTIATING); + + // Enable encryption on ant_channel + err_code = + ant_channel_encrypt_config_perform(ant_channel, + &m_slave_channel_conf[ant_channel]); + APP_ERROR_CHECK(err_code); + } + break; + + default: + break; + } +} + + +void ant_slave_encrypt_negotiation(ant_evt_t * p_ant_evt) +{ + + uint8_t const ant_channel = p_ant_evt->channel; + ANT_MESSAGE * p_ant_msg; + + ant_encrypt_tracking_state_t track_state = ant_channel_encryp_tracking_state_get(ant_channel); + + if (track_state == ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED) + return; + + switch (p_ant_evt->event) + { + case EVENT_RX_FAIL_GO_TO_SEARCH: + if (track_state == ANT_ENC_CHANNEL_STAT_NEGOTIATING) + { + m_can_enable_crypto = true; + } + + ant_channel_encryp_tracking_state_set(ant_channel, ANT_ENC_CHANNEL_STAT_NOT_TRACKING); + break; + + case EVENT_RX: + /*lint -e545 -save*/ + p_ant_msg = (ANT_MESSAGE *) &(p_ant_evt->msg.evt_buffer); + /*lint -restore*/ + ant_slave_encrypt_try_enable(ant_channel, p_ant_msg->ANT_MESSAGE_ucMesgID); + break; + + case EVENT_ENCRYPT_NEGOTIATION_SUCCESS: + m_can_enable_crypto = true; + ant_channel_encryp_tracking_state_set(ant_channel, + ANT_ENC_CHANNEL_STAT_TRACKING_DECRYPTED); + break; + + case EVENT_ENCRYPT_NEGOTIATION_FAIL: + m_can_enable_crypto = true; + ant_channel_encryp_tracking_state_set(ant_channel, + ANT_ENC_CHANNEL_STAT_TRACKING_ENCRYPTED); + break; + + default: + break; + } +} + +#endif // NRF_MODULE_ENABLED(ANT_ENCRYPT_NEGOTIATION_SLAVE) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_encryption/ant_encrypt_negotiation_slave.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_encryption/ant_encrypt_negotiation_slave.h new file mode 100644 index 0000000000000000000000000000000000000000..9bcf93530d997a8bf86d1f688d758bb7af9b894b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_encryption/ant_encrypt_negotiation_slave.h @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_ENCRYPT_NEGOTIATION_SLAVE_H__ +#define ANT_ENCRYPT_NEGOTIATION_SLAVE_H__ + +/**@file + * + * @defgroup ant_encrypt_negotiation_slave ANT encryption negotiation + * @{ + * @ingroup ant_sdk_utils + * + * @brief Encryption negotiation for encrypted ANT slave channels. + * + * After pairing, the slave starts negotiating the encryption with the master. After + * successful negotiation, the slave can decrypt messages from the master, and all + * future messages are sent encrypted. + * + */ + +#include +#include "ant_stack_handler_types.h" +#include "ant_encrypt_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Encryption negotiation states for a slave channel. */ +typedef enum +{ + ANT_ENC_CHANNEL_STAT_NOT_TRACKING, ///< Not tracking the master. + ANT_ENC_CHANNEL_STAT_TRACKING_ENCRYPTED, ///< Tracking the master, but cannot decrypt messages. + ANT_ENC_CHANNEL_STAT_NEGOTIATING, ///< Encryption has been enabled and negotiation is in progress. + ANT_ENC_CHANNEL_STAT_TRACKING_DECRYPTED, ///< Tracking the master and can decrypt messages. + ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED ///< Tracking unsupported on this channel. +} ant_encrypt_tracking_state_t; + + +/** + * @brief Function for setting the encryption negotiation state of a slave ANT channel. + * + * This function should be used by the @ref ant_encrypt_config module. + * + * @param[in] channel_number ANT channel number. + * @param[in] state State to set. + */ +void ant_channel_encryp_tracking_state_set(uint8_t channel_number, + ant_encrypt_tracking_state_t state); + +/** + * @brief Function for getting the encryption negotiation state of a slave ANT channel. + * + * @param[in] channel_number ANT channel number. + */ +ant_encrypt_tracking_state_t ant_channel_encryp_tracking_state_get(uint8_t channel_number); + +/** + * @brief Function for initializing the module. + * + * This function initializes internal states of the module. It should + * only be used by the @ref ant_encrypt_config module. + * + */ +void ant_channel_encryp_negotiation_slave_init(void); + +/** + * @brief Function for setting the configuration for the slave channel. + * + * This function saves the channel's encryption configuration to a lookup table (LUT) for + * future usage. The configuration can then be used to enable encryption. + * + * This function is intended to be used by the @ref ant_encrypt_config module. + * + * @param[in] channel_number ANT channel number. + * @param[in] p_crypto_config Pointer to the encryption configuration. + */ +void ant_slave_channel_encrypt_config(uint8_t channel_number, + ant_encrypt_channel_settings_t const * const p_crypto_config); + + +/** + * @brief Function for handling ANT encryption negotiation on slave nodes. + * + * This function should be used directly in the ANT event dispatching process. It + * tries to enable slave channel encryption for all slave channels that are declared + * as encrypted channels (if appropriate master channels are found). + * + * This function should be used by the @ref ant_encrypt_config module. + * + * @param[in] p_ant_evt Pointer to the ANT stack event message structure. + */ +void ant_slave_encrypt_negotiation(ant_evt_t * p_ant_evt); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif // ANT_ENCRYPT_NEGOTIATION_SLAVE_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/antfs.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/antfs.c new file mode 100644 index 0000000000000000000000000000000000000000..6c46f32093b58175abe0407f21bd97c1db155c5c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/antfs.c @@ -0,0 +1,2379 @@ +/** + * This software is subject to the ANT+ Shared Source License + * www.thisisant.com/swlicenses + * Copyright (c) Dynastream Innovations, Inc. 2012 + * 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 Dynastream nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * The following actions are prohibited: + * 1) Redistribution of source code containing the ANT+ Network + * Key. The ANT+ Network Key is available to ANT+ Adopters. + * Please refer to http://thisisant.com to become an ANT+ + * Adopter and access the key. + * + * 2) Reverse engineering, decompilation, and/or disassembly of + * software provided in binary form under this license. + * + * 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 HEREBY + * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW + * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE + * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANTFS) + +#include "antfs.h" +#include +#include "defines.h" +#include "app_error.h" +#include "app_timer.h" +#include "ant_error.h" +#include "ant_parameters.h" +#include "ant_interface.h" +#include "ant_key_manager.h" +#include "crc.h" + +#if ANTFS_CONFIG_DEBUG_LED_ENABLED + #include "bsp.h" +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED + +#define BURST_PACKET_SIZE 8u /**< The burst packet size. */ + +#define ANTFS_CONNECTION_TYPE_OFFSET 0x00u /**< The connection type offset within ANT-FS message. */ +#define ANTFS_COMMAND_OFFSET 0x01u /**< The command offset within ANT-FS message. */ +#define ANTFS_RESPONSE_OFFSET 0x01u /**< The response offset within ANT-FS message. */ + +#define ANTFS_CONTROL_OFFSET 0x02u /**< The control offset within ANT-FS message. */ +#define ANTFS_DATA_OFFSET 0x03u /**< The data offset within ANT-FS message. */ + +#define ANTFS_BEACON_ID 0x43u /**< The ANT-FS beacon ID. */ +#define ANTFS_COMMAND_ID 0x44u /**< The ANT-FS command ID. */ + +// Beacon definitions. +#define STATUS1_OFFSET 0x01u /**< The beacon status1 field offset. */ +#define STATUS2_OFFSET 0x02u /**< The beacon status2 field offset. */ + #define DEVICE_STATE_SHIFT 0x00u /**< Shift value for device state bitfield. */ + #define DEVICE_STATE_MASK (0x0Fu << DEVICE_STATE_SHIFT) /**< Device state bitmask. */ + #define DEVICE_STATE_LINK (0x00u << DEVICE_STATE_SHIFT) /**< Device is in link state. */ + #define DEVICE_STATE_AUTHENTICATE (0x01u << DEVICE_STATE_SHIFT) /**< Device is in authenticate state. */ + #define DEVICE_STATE_TRANSPORT (0x02u << DEVICE_STATE_SHIFT) /**< Device is in transport state. */ + #define DEVICE_STATE_BUSY (0x03u << DEVICE_STATE_SHIFT) /**< Device is in busy state. */ + +#define DEVICE_DESCRIPTOR_OFFSET_0 0x04u /**< Beacon ANT-FS device descriptor LSB position. */ +#define DEVICE_DESCRIPTOR_OFFSET_1 0x05u /**< Beacon ANT-FS device descriptor LSB + 1 position. */ +#define DEVICE_DESCRIPTOR_OFFSET_2 0x06u /**< Beacon ANT-FS device descriptor LSB + 2 position. */ +#define DEVICE_DESCRIPTOR_OFFSET_3 0x07u /**< Beacon ANT-FS device descriptor MSB position. */ + +// Commands. +#define ANTFS_CMD_NONE 0x00u /**< Used to identify that no ANT-FS command is in progress. */ +#define ANTFS_CMD_LINK_ID 0x02u /**< ANT-FS link command ID. */ +#define ANTFS_CMD_DISCONNECT_ID 0x03u /**< ANT-FS disconnect command ID. */ +#define ANTFS_CMD_AUTHENTICATE_ID 0x04u /**< ANT-FS authenticate command ID. */ +#define ANTFS_CMD_PING_ID 0x05u /**< ANT-FS ping command ID. */ +#define ANTFS_CMD_DOWNLOAD_ID 0x09u /**< ANT-FS download request command ID. */ +#define ANTFS_CMD_UPLOAD_REQUEST_ID 0x0Au /**< ANT-FS upload request command ID. */ +#define ANTFS_CMD_ERASE_ID 0x0Bu /**< ANT-FS erase request command ID. */ +#define ANTFS_CMD_UPLOAD_DATA_ID 0x0Cu /**< ANT-FS upload command ID. */ + +// Responses. +#define ANTFS_RSP_AUTHENTICATE_ID 0x84u /**< ANT-FS authenticate response command ID. */ +#define ANTFS_RSP_DOWNLOAD_ID 0x89u /**< ANT-FS download request response command ID. */ +#define ANTFS_RSP_UPLOAD_REQ_ID 0x8Au /**< ANT-FS upload request response command ID. */ +#define ANTFS_RSP_ERASE_ID 0x8Bu /**< ANT-FS erase response command ID. */ +#define ANTFS_RSP_UPLOAD_DATA_ID 0x8Cu /**< ANT-FS upload data response command ID. */ + +// Link command. +#define TRANSPORT_CHANNEL_FREQUENCY_OFFSET 0x02u /**< Channel frequency field offset within link command. */ +#define TRANSPORT_MESSAGE_PERIOD_OFFSET 0x03u /**< Channel period field offset within link command. */ +#define HOST_ID_OFFSET_0 0x04u /**< Host serial number period field LSB offset within link command. */ +#define HOST_ID_OFFSET_1 0x05u /**< Host serial number period field LSB + 1 offset within link command. */ +#define HOST_ID_OFFSET_2 0x06u /**< Host serial number period field LSB + 2 offset within link command. */ +#define HOST_ID_OFFSET_3 0x07u /**< Host serial number period field MSB offset within link command. */ + +// Authenticate command. +#define COMMAND_TYPE_OFFSET 0x02u /**< Command type field offset within authenticate command. */ + #define COMMAND_TYPE_PROCEED 0x00u /**< Command type proceed to transport in the authenticate command. */ + #define COMMAND_TYPE_REQUEST_SERIAL 0x01u /**< Command type request client device serial number in the authenticate command. */ + #define COMMAND_TYPE_REQUEST_PAIR 0x02u /**< Command type request pairing in the authenticate command. */ + #define COMMAND_TYPE_REQUEST_PASSKEY 0x03u /**< Command type request passkey exchange in the authenticate command. */ + +// Authenticate response. +#define RESPONSE_TYPE_OFFSET 0x02u /**< Command type field offset within authenticate response command. */ + #define AUTH_RESPONSE_N_A 0x00u /**< Command response type N/A (response for client serial number request). */ + #define AUTH_RESPONSE_ACCEPT 0x01u /**< Command response type accept. */ + #define AUTH_RESPONSE_REJECT 0x02u /**< Command response type reject. */ + +// Authenticate command/response. +#define AUTH_STRING_LENGTH_OFFSET 0x03u /**< Authenticate Command/Response authentication string length offset. */ +#define SERIAL_NUMBER_OFFSET_0 0x04u /**< Authenticate Command/Response client/host serial number LSB offset. */ +#define SERIAL_NUMBER_OFFSET_1 0x05u /**< Authenticate Command/Response client/host serial number LSB + 1 offset. */ +#define SERIAL_NUMBER_OFFSET_2 0x06u /**< Authenticate Command/Response client/host serial number LSB + 2 offset. */ +#define SERIAL_NUMBER_OFFSET_3 0x07u /**< Authenticate Command/Response client/host serial number MSB offset. */ + +// Download/Upload/Erase commands. +#define INITIAL_REQUEST_OFFSET 0x01u /**< Download/Upload/Erase command initial request command offset. */ +#define DATA_INDEX_OFFSET_LOW 0x02u /**< Download/Upload/Erase command offset index low. */ +#define DATA_INDEX_OFFSET_HIGH 0x03u /**< Download/Upload/Erase command offset index high. */ + +#define ADDRESS_PARAMETER_OFFSET_0 0x04u /**< Download/Upload command parameter LSB offset. */ +#define ADDRESS_PARAMETER_OFFSET_1 0x05u /**< Download/Upload command parameter LSB + 1 offset. */ +#define ADDRESS_PARAMETER_OFFSET_2 0x06u /**< Download/Upload command parameter LSB + 2 offset. */ +#define ADDRESS_PARAMETER_OFFSET_3 0x07u /**< Download/Upload command parameter MSB offset. */ +#define UPLOAD_CRC_OFFSET_LOW 0x06u /**< Upload data CRC offset low. */ +#define UPLOAD_CRC_OFFSET_HIGH 0x07u /**< Upload data CRC offset high. */ + +// Authentication type. The highest level of authentication available is included in the beacon. +#if ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED + #define AUTHENTICATION_TYPE COMMAND_TYPE_REQUEST_PASSKEY /**< Passkey and pairing only mode set as authentication type in beacon. */ +#elif ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED + #define AUTHENTICATION_TYPE COMMAND_TYPE_REQUEST_PAIR /**< Pairing only mode set as authentication type in beacon. */ +#elif ANTFS_CONFIG_AUTH_TYPE_PASSTHROUGH_ENABLED + #define AUTHENTICATION_TYPE COMMAND_TYPE_PROCEED /**< Pass-through mode set as authentication type in beacon. */ +#else + #error "No valid auth type defined" +#endif + +#define AUTHENTICATION_RETRIES 0x05u /**< Max number of retries for authentication responses */ + +#define ANTFS_EVENT_QUEUE_SIZE 0x04u /**< ANT-FS event queue size. */ +#define SAVE_DISTANCE 256u /**< Save distance required because of nRF buffer to line up data offset on retry. */ + +// Buffer Indices. +#define BUFFER_INDEX_MESG_SIZE 0x00u /**< ANT message buffer index length offset. */ +#define BUFFER_INDEX_MESG_ID 0x01u /**< ANT message buffer index ID offset. */ +#define BUFFER_INDEX_CHANNEL_NUM 0x02u /**< ANT message buffer index channel number offset. */ +#define BUFFER_INDEX_MESG_DATA 0x03u /**< ANT message buffer index begin of data offset. */ +#define BUFFER_INDEX_RESPONSE_CODE 0x04u /**< ANT message buffer index response code offset. */ + +typedef struct +{ + char friendly_name[ANTFS_FRIENDLY_NAME_MAX]; /**< Friendly Name. */ + bool is_name_set; /**< Is the name set. */ + uint32_t index; /**< Current index (for reading the friendly name). */ + uint32_t friendly_name_size; /**< Friendly name size. */ +} friendly_name_t; + +typedef union +{ + antfs_link_substate_t link_sub_state; /**< Sub-state (Link layer). */ + antfs_authenticate_substate_t auth_sub_state; /**< Sub-state (Authentication layer). */ + antfs_transport_substate_t trans_sub_state; /**< Sub-state (Transport layer). */ +} antfs_substate_t; + +typedef struct +{ + antfs_state_t state; /**< ANT-FS state. */ + antfs_substate_t sub_state; /**< ANT-FS sub-state. */ +} antfs_states_t; + +typedef struct +{ + antfs_event_return_t * p_queue; /**< ANT-FS event queue. */ + uint32_t head; /**< ANT-FS event queue head index. */ + uint32_t tail; /**< ANT-FS event queue tail index. */ +} antfs_event_queue_t; + +static antfs_params_t m_initial_parameters; /**< Initial parameters. */ +static antfs_beacon_status_byte1_t m_active_beacon_status1_field; /**< Status 1 field in beacon. */ +static uint32_t m_active_beacon_frequency; /**< Active beacon frequency. */ +static antfs_states_t m_current_state; /**< Current state. */ +static friendly_name_t m_friendly_name; /**< Host's friendly name. */ +static ulong_union_t m_link_host_serial_number; /**< Host's serial number. */ +static uint32_t m_link_command_in_progress; /**< ANT-FS command in progress. */ +static uint32_t m_authenticate_command_type; /**< Authenticate command type in progress. */ +static volatile uint8_t m_burst_wait; /**< Polling status flag for data unlock on burst handler input. */ +static uint8_t m_retry; /**< Retry counter */ +APP_TIMER_DEF(m_timer_id); /**< Timer ID used with the timer module. */ + +#if ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED + static uint32_t m_passkey_index; /**< Current location of Tx block (auth string). */ +#endif // ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED + +// Download/upload. +static bool m_is_data_request_pending; /**< Requested data pending. */ +static bool m_is_crc_pending; /**< CRC for data packets pending. */ +static ushort_union_t m_file_index; /**< File index of current upload/download. */ +static ulong_union_t m_file_size; /**< File size of current upload/download (bytes). */ +static ulong_union_t m_max_block_size; /**< Maximum number of bytes expected to be downloaded in a single burst block of data (set by host). */ +static ulong_union_t m_link_burst_index; /**< Current location of Tx block (bytes). */ +static ulong_union_t m_bytes_remaining; /**< Total remaining data length (bytes). */ +static ulong_union_t m_max_transfer_index; /**< Upper limit of the current Tx burst block (bytes). */ +static uint32_t m_bytes_to_write; /**< Number of bytes to write to file (upload). */ +static const uint8_t * mp_upload_data; /**< Address of begin of the buffer that holds data received from upload. */ +#if ANTFS_CONFIG_UPLOAD_ENABLED + static ulong_union_t m_block_size; /**< Number of bytes the client can receive in a single burst. */ +#endif // ANTFS_CONFIG_UPLOAD_ENABLED + +// CRC verification. +static uint32_t m_saved_crc_offset; /**< CRC data offset (bytes) saved at last CRC update (save point). */ +static uint32_t m_saved_buffer_crc_offset; /**< Data offset to track how much data has been buffered into nRF */ +static uint32_t m_temp_crc_offset; /**< Temporary CRC data offset used in CRC calculation. */ +static uint16_t m_compared_crc; /**< 16-bit CRC for all data packets in the block (provided by download request). */ +static uint16_t m_transfer_crc; /**< 16-bit CRC for all data packets in the block (calculated by client). */ +static uint16_t m_saved_transfer_crc; /**< 16-bit CRC saved at last CRC update (save point). */ +static uint16_t m_saved_buffer_crc; /**< 16-bit CRC saved at last CRC update (save point) for buffering the nRF */ + +// ANT-FS event handling. +static antfs_event_return_t m_event_queue_buffer[ANTFS_EVENT_QUEUE_SIZE]; /**< Event queue storage. */ +static antfs_event_queue_t m_event_queue; /**< Event queue. */ + +static antfs_burst_wait_handler_t m_burst_wait_handler = NULL; /**< Burst wait handler */ + + +const char * antfs_hostname_get(void) +{ + if (m_friendly_name.is_name_set) + { + return (m_friendly_name.friendly_name); + } + + return NULL; +} + + +/**@brief Function for waiting for the burst transmission request to complete. + */ +static void wait_burst_request_to_complete(void) +{ + while (m_burst_wait != 0) + { + if (m_burst_wait_handler != NULL) + { + m_burst_wait_handler(); + } + }; +} + + +/**@brief Function for stopping ANT-FS timeout, which is possibly currently running. + */ +static void timeout_disable(void) +{ + m_link_command_in_progress = ANTFS_CMD_NONE; + + const uint32_t err_code = app_timer_stop(m_timer_id); + APP_ERROR_CHECK(err_code); +} + + +/**@brief Function for transmitting a beacon. + * + * Transmits a beacon either using a broadcast or burst transmission mode. + * + * @param[in] message_type Defines the used transmission mode. + */ +static void beacon_transmit(uint32_t message_type) +{ + uint8_t beacon_status_byte2; + + // Set beacon status byte 2. + + if (m_link_command_in_progress == ANTFS_CMD_NONE) + { + switch (m_current_state.state) + { + case ANTFS_STATE_AUTH: + beacon_status_byte2 = DEVICE_STATE_AUTHENTICATE; + break; + + case ANTFS_STATE_TRANS: + beacon_status_byte2 = DEVICE_STATE_TRANSPORT; + break; + + default: + beacon_status_byte2 = DEVICE_STATE_LINK; + break; + } + } + else + { + beacon_status_byte2 = DEVICE_STATE_BUSY; + } + + // Set remaining beacon fields. + + uint8_t tx_buffer[BURST_PACKET_SIZE]; + + tx_buffer[0] = ANTFS_BEACON_ID; + tx_buffer[1] = m_active_beacon_status1_field.status; + tx_buffer[2] = beacon_status_byte2; + tx_buffer[3] = AUTHENTICATION_TYPE; + + if ((m_current_state.state == ANTFS_STATE_AUTH) || + (m_current_state.state == ANTFS_STATE_TRANS)) + { + tx_buffer[4] = m_link_host_serial_number.bytes.byte0; + tx_buffer[5] = m_link_host_serial_number.bytes.byte1; + tx_buffer[6] = m_link_host_serial_number.bytes.byte2; + tx_buffer[7] = m_link_host_serial_number.bytes.byte3; + } + else + { + tx_buffer[4] = m_initial_parameters.beacon_device_type; + tx_buffer[5] = (m_initial_parameters.beacon_device_type >> 8u); + tx_buffer[6] = m_initial_parameters.beacon_device_manufacturing_id; + tx_buffer[7] = (m_initial_parameters.beacon_device_manufacturing_id >> 8u); + } + + if (message_type == MESG_BROADCAST_DATA_ID) + { + if (sd_ant_broadcast_message_tx(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer) != NRF_SUCCESS) + { + // @note: No implementation needed, as it is a valid and accepted use case for this call + // to fail. This call can fail if we are in middle of bursting. + } + } + else if (message_type == MESG_BURST_DATA_ID) + { + // Send as the first packet of a burst. + const uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_START); + APP_ERROR_CHECK(err_code); + + wait_burst_request_to_complete(); + + // This is the first packet of a burst response, disable command timeout while bursting. + timeout_disable(); + } + else + { + // This should not happen. + APP_ERROR_HANDLER(message_type); + } +} + + +/**@brief Function for transmitting a authenticate response message. + * + * @param[in] response_type Authenticate response code. + * @param[in] password_length Length of authentication string. + * @param[in] p_password Authentication string transmitted. + */ +static void authenticate_response_transmit(uint8_t response_type, + uint32_t password_length, + const uint8_t * p_password) +{ + ulong_union_t serial_number; + + serial_number.data = m_initial_parameters.client_serial_number; + + // First packet is beacon. + beacon_transmit(MESG_BURST_DATA_ID); + + uint8_t tx_buffer[BURST_PACKET_SIZE]; + + tx_buffer[ANTFS_CONNECTION_TYPE_OFFSET] = ANTFS_COMMAND_ID; + tx_buffer[ANTFS_RESPONSE_OFFSET] = ANTFS_RSP_AUTHENTICATE_ID; + tx_buffer[RESPONSE_TYPE_OFFSET] = response_type; + tx_buffer[AUTH_STRING_LENGTH_OFFSET] = password_length; + tx_buffer[SERIAL_NUMBER_OFFSET_0] = serial_number.bytes.byte0; + tx_buffer[SERIAL_NUMBER_OFFSET_1] = serial_number.bytes.byte1; + tx_buffer[SERIAL_NUMBER_OFFSET_2] = serial_number.bytes.byte2; + tx_buffer[SERIAL_NUMBER_OFFSET_3] = serial_number.bytes.byte3; + + uint32_t err_code; + if ((m_current_state.state == ANTFS_STATE_AUTH) && + ( + (response_type != AUTH_RESPONSE_REJECT) && + password_length && + (password_length <= ANTFS_AUTH_STRING_MAX) + ) + ) + { + // Send second packet (auth response). + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_CONTINUE); + APP_ERROR_CHECK(err_code); + + wait_burst_request_to_complete(); + + // Round size to a multiple of 8 bytes. + uint8_t tx_buffer_authenticate[ANTFS_AUTH_STRING_MAX + 1u]; + + memset(tx_buffer_authenticate, 0, ANTFS_AUTH_STRING_MAX + 1u); + memcpy(tx_buffer_authenticate, p_password, password_length); + + // Round up total number bytes to a multiple of 8 to be sent to burst handler. + if (password_length & (BURST_PACKET_SIZE - 1u)) + { + password_length &= ~(BURST_PACKET_SIZE - 1u); + password_length += BURST_PACKET_SIZE; + } + + // Send auth string (last packets of the burst). + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + password_length, + tx_buffer_authenticate, + BURST_SEGMENT_END); + APP_ERROR_CHECK(err_code); + + wait_burst_request_to_complete(); + + m_link_command_in_progress = ANTFS_RSP_AUTHENTICATE_ID; + } + else + { + // If the authorization is rejected or there is no valid password, the auth response is the + // last packet. + + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_END); + APP_ERROR_CHECK(err_code); + + wait_burst_request_to_complete(); + } + + // Switch to appropiate state. + if (response_type == AUTH_RESPONSE_REJECT) + { + m_current_state.sub_state.auth_sub_state = ANTFS_AUTH_SUBSTATE_REJECT; + } + else if (response_type == AUTH_RESPONSE_ACCEPT) + { + m_current_state.sub_state.auth_sub_state = ANTFS_AUTH_SUBSTATE_ACCEPT; + } + else + { + // No implementation needed. + } +} + + +bool antfs_pairing_resp_transmit(bool accept) +{ +#if ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED + // This function should only be called when ANT-FS is in PAIRING mode. + if ((m_current_state.state != ANTFS_STATE_AUTH) || + (m_current_state.sub_state.auth_sub_state != ANTFS_AUTH_SUBSTATE_PAIR)) + { + return false; + } + + m_link_command_in_progress = ANTFS_CMD_AUTHENTICATE_ID; + + if (accept) + { + // Accept request and send passkey if authentication passed. + authenticate_response_transmit(AUTH_RESPONSE_ACCEPT, + ANTFS_PASSKEY_SIZE, + m_initial_parameters.p_pass_key); + } + else + { + // Reject authentication request. + authenticate_response_transmit(AUTH_RESPONSE_REJECT, 0, NULL); + } + + return true; +#else + return false; +#endif // ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED +} + + +/**@brief Function for adding an ANT-FS event to the event queue. + * + * @param[in] event_code The event to be added. + */ +static void event_queue_write(antfs_event_t event_code) +{ + antfs_event_return_t * p_event = NULL; +#if ANTFS_CONFIG_DEBUG_LED_ENABLED + uint32_t err_code; +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED + + // Check if there is room in the queue for a new event. + if (((m_event_queue.head + 1u) & (ANTFS_EVENT_QUEUE_SIZE - 1u)) != m_event_queue.tail) + { + p_event = &(m_event_queue.p_queue[m_event_queue.head]); + } + + if (p_event != NULL) + { + // Initialize event parameters. + p_event->event = event_code; + + // Set parameters depending on event type. + switch (event_code) + { + case ANTFS_EVENT_ERASE_REQUEST: + p_event->file_index = m_file_index.data; + p_event->offset = 0; + p_event->bytes = 0; + p_event->crc = 0; + break; + + case ANTFS_EVENT_DOWNLOAD_REQUEST: + p_event->file_index = m_file_index.data; + // Requested offset for the download. + p_event->offset = m_link_burst_index.data; + p_event->bytes = 0; + p_event->crc = 0; + break; + + case ANTFS_EVENT_DOWNLOAD_REQUEST_DATA: + p_event->file_index = m_file_index.data; + // Current offset. + p_event->offset = m_link_burst_index.data; + + if (m_bytes_remaining.data > (ANTFS_BURST_BLOCK_SIZE * BURST_PACKET_SIZE)) + { + // If remaining bytes > burst block size then grab one block at a time. + p_event->bytes = ANTFS_BURST_BLOCK_SIZE * BURST_PACKET_SIZE; + } + else + { + p_event->bytes = m_bytes_remaining.data; + } + + p_event->crc = 0; + break; + + case ANTFS_EVENT_UPLOAD_REQUEST: + p_event->file_index = m_file_index.data; + // Requested offset for the upload. + p_event->offset = m_link_burst_index.data; + // Upper limit of the download (offset + remaining bytes). + p_event->bytes = m_max_transfer_index.data; + // CRC Seed (from last save point if resuming). + p_event->crc = m_transfer_crc; + break; + + case ANTFS_EVENT_UPLOAD_DATA: + p_event->file_index = m_file_index.data; + // Current offset. + p_event->offset = m_link_burst_index.data; + // Current CRC. + p_event->crc = m_transfer_crc; + // Number of bytes to write. + p_event->bytes = m_bytes_to_write; + // Upload to appication data buffer. + memcpy(p_event->data, mp_upload_data, m_bytes_to_write); + break; + + case ANTFS_EVENT_PAIRING_REQUEST: +#if ANTFS_CONFIG_DEBUG_LED_ENABLED + err_code = bsp_indication_set(BSP_INDICATE_BONDING); + APP_ERROR_CHECK(err_code); +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED + break; + + default: + // No parameters need to be set. + + p_event->file_index = 0; + p_event->offset = 0; + p_event->bytes = 0; + p_event->crc = 0; + break; + } + + // Put the event in the queue. + m_event_queue.head = ((m_event_queue.head + 1u) & (ANTFS_EVENT_QUEUE_SIZE - 1u)); + } + else + { + // No free space left in the queue. + APP_ERROR_HANDLER(0); + } +} + + +/**@brief Function for transmitting download request response message. + * + * @param[in] response Download response code. + */ +static void download_request_response_transmit(uint8_t response) +{ + // First burst packet is beacon. + beacon_transmit(MESG_BURST_DATA_ID); + + uint8_t tx_buffer[BURST_PACKET_SIZE]; + + // Next send the first part of the download response. + tx_buffer[0] = ANTFS_COMMAND_ID; + tx_buffer[1] = ANTFS_RSP_DOWNLOAD_ID; + tx_buffer[2] = response; + tx_buffer[3] = 0; + // Total number of bytes remaining in the data block. + tx_buffer[4] = m_bytes_remaining.bytes.byte0; + tx_buffer[5] = m_bytes_remaining.bytes.byte1; + tx_buffer[6] = m_bytes_remaining.bytes.byte2; + tx_buffer[7] = m_bytes_remaining.bytes.byte3; + + uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_CONTINUE); + APP_ERROR_CHECK(err_code); + + wait_burst_request_to_complete(); + + // Second part of the download response. + + // The offset the data will start from in this block. + tx_buffer[0] = m_link_burst_index.bytes.byte0; + tx_buffer[1] = m_link_burst_index.bytes.byte1; + tx_buffer[2] = m_link_burst_index.bytes.byte2; + tx_buffer[3] = m_link_burst_index.bytes.byte3; + // The file size in the client device. + tx_buffer[4] = m_file_size.bytes.byte0; + tx_buffer[5] = m_file_size.bytes.byte1; + tx_buffer[6] = m_file_size.bytes.byte2; + tx_buffer[7] = m_file_size.bytes.byte3; + + if (response || (m_bytes_remaining.data == 0)) + { + // If the download was rejected or there is no data to send. + + // Set response to end since we're not downloading any data. + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_END); + APP_ERROR_CHECK(err_code); + + wait_burst_request_to_complete(); + } + else + { + // Response will continue (data packets + CRC footer to follow). + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_CONTINUE); + APP_ERROR_CHECK(err_code); + + wait_burst_request_to_complete(); + } + + m_link_command_in_progress = ANTFS_CMD_DOWNLOAD_ID; + + if (response == 0) + { + // If we are going to download (response OK), enter the downloading substate. + m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_DOWNLOADING; + event_queue_write(ANTFS_EVENT_DOWNLOAD_START); + } + else + { + // Download rejected. + event_queue_write(ANTFS_EVENT_DOWNLOAD_FAIL); + } +} + + +void antfs_download_req_resp_prepare(uint8_t response, + const antfs_request_info_t * const p_request_info) +{ + // This function should only be called after receiving a download request. + APP_ERROR_CHECK_BOOL((m_current_state.state == ANTFS_STATE_TRANS) && + (m_link_command_in_progress == ANTFS_CMD_DOWNLOAD_ID)); + + if (response == 0) + { + // Download request OK. + + // File size of the requested download. + m_file_size.data = p_request_info->file_size.data; + + if (m_link_burst_index.data > m_file_size.data) + { + // Offset should not exceed file size. + m_link_burst_index.data = m_file_size.data; + } + + // If the host is not limiting download size or the file size does not exceed the host's + // download size limit. + if ((m_max_block_size.data == 0) || (m_file_size.data < m_max_block_size.data)) + { + // Number of bytes remaining to be downloaded in this block is the file size. + m_bytes_remaining.data = m_file_size.data; + } + + if ((m_file_size.data - m_link_burst_index.data) < m_bytes_remaining.data) + { + // Calculate number of remaining bytes in this block based on the offset. + m_bytes_remaining.data = m_file_size.data - m_link_burst_index.data; + } + + // If the application is limiting the Tx block size. + if (m_bytes_remaining.data > p_request_info->max_burst_block_size.data) + { + // Number of remaining bytes in this block is the application defined block size. + m_bytes_remaining.data = p_request_info->max_burst_block_size.data; + } + + // Find upper limit of the burst Tx. + m_max_transfer_index.data = m_link_burst_index.data + m_bytes_remaining.data; + + if (m_saved_crc_offset == ANTFS_MAX_FILE_SIZE) + { + // CRC checking was set as invalid. An invalid download was requested, so reject it. + response = RESPONSE_INVALID_OPERATION; + } + } + + if ((response != 0) || (m_file_size.data == 0)) + { + // Send the response right away if the download request was rejected or there is no data to + // send. + download_request_response_transmit(response); + } + else + { + // Proceed to download data. + if (m_link_burst_index.data != m_saved_crc_offset) + { + uint32_t temp; + + // If requesting to resume exactly where we left off, we can start from the same block. + if (m_link_burst_index.data == m_temp_crc_offset) + { + // Move last save point to end of last block sent. + m_saved_crc_offset = m_link_burst_index.data; + m_saved_transfer_crc = m_transfer_crc; + } + + // To resume the download, request a block of data starting from the last save point. + // Update the remaining number of bytes per the last save point. + m_bytes_remaining.data += (m_link_burst_index.data - m_saved_crc_offset); + + // Swap the current burst Tx index with the saved CRC index, to make sure we do not + // start updating the CRC until we get to the requested index. + temp = m_link_burst_index.data; + m_link_burst_index.data = m_saved_crc_offset; + m_saved_crc_offset = temp; + + // Set CRC to previous save point, to check the CRC provided by the host. + m_transfer_crc = m_saved_transfer_crc; + } + + m_temp_crc_offset = m_saved_crc_offset; + + m_is_data_request_pending = true; + + // Request data from application. + event_queue_write(ANTFS_EVENT_DOWNLOAD_REQUEST_DATA); + + m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_VERIFY_CRC; + } +} + + +uint32_t antfs_input_data_download(uint16_t index, + uint32_t offset, + uint32_t num_bytes, + const uint8_t * const p_message) +{ + // Verify that this is the requested data. + APP_ERROR_CHECK_BOOL((offset == m_link_burst_index.data) && (index == m_file_index.data)); + + // If file offset is greater than the upper limit, this is not data we need. + APP_ERROR_CHECK_BOOL(offset <= m_max_transfer_index.data); + + if ((m_current_state.state == ANTFS_STATE_TRANS) && + ( + (m_current_state.sub_state.trans_sub_state == ANTFS_TRANS_SUBSTATE_VERIFY_CRC) || + // Only send data if we were processing a download request. + (m_current_state.sub_state.trans_sub_state == ANTFS_TRANS_SUBSTATE_DOWNLOADING) + ) + ) + { + uint32_t block_offset = 0; + + if (m_current_state.sub_state.trans_sub_state == ANTFS_TRANS_SUBSTATE_VERIFY_CRC) + { + // Make sure download_request_response_transmit defaults to RESPONSE_INVALID_CRC. + uint32_t response = RESPONSE_MESSAGE_OK; + + // Check CRC. + if (m_link_burst_index.data == m_saved_crc_offset) + { + // If indexes match, we can compare CRC directly. + if (m_transfer_crc != m_compared_crc) + { + response = RESPONSE_INVALID_CRC; + } + else + { + // Set up the save point + m_temp_crc_offset = m_link_burst_index.data; // Reset save point counter + m_saved_crc_offset = m_link_burst_index.data; + m_saved_buffer_crc_offset = m_link_burst_index.data; + + // Set up the CRC save points + m_saved_transfer_crc = m_compared_crc; + m_saved_buffer_crc = m_compared_crc; + m_is_crc_pending = true; + } + // Start bursting beacon and the download response (3 burst packets). + download_request_response_transmit(response); + } + // If the data is in this block, advance to the requested offset + else if ((m_link_burst_index.data < m_saved_crc_offset) && + ((m_saved_crc_offset - m_link_burst_index.data) < num_bytes)) + { + // Update the offset within this block for the requested transmission. + block_offset = m_saved_crc_offset - m_link_burst_index.data; + // Update the number of bytes that will actually be transmitted. + num_bytes -= block_offset; + + // Update CRC calculation up to requested index. + m_transfer_crc = crc_crc16_update(m_transfer_crc, p_message, block_offset); + // Update the remaining number of bytes. + m_bytes_remaining.data -= block_offset; + + // Check CRC + if (m_transfer_crc != m_compared_crc) + { + response = RESPONSE_INVALID_CRC; + } + else + { + // Move index back to point where transmission will resume. + m_link_burst_index.data = m_saved_crc_offset; + + // Set up the save point + m_temp_crc_offset = m_link_burst_index.data; // Reset save point counter + m_saved_buffer_crc_offset = m_link_burst_index.data; + + // Set up the CRC save points + m_saved_transfer_crc = m_compared_crc; + m_saved_buffer_crc = m_compared_crc; + + m_is_crc_pending = true; + } + download_request_response_transmit(response); + } + // Data index has gone too far and it is not possible to check CRC, fail and let host retry + else if (m_link_burst_index.data > m_saved_crc_offset) + { + response = RESPONSE_INVALID_CRC; + download_request_response_transmit(response); + } + // Keep getting data and recalculate the CRC until the indexes match + else + { + m_is_data_request_pending = false; + + // Update the current burst index and bytes remaining + m_link_burst_index.data += num_bytes; + m_bytes_remaining.data -= num_bytes; + + // Update CRC + m_transfer_crc = crc_crc16_update(m_transfer_crc, p_message, num_bytes); + + // Request more data. + event_queue_write(ANTFS_EVENT_DOWNLOAD_REQUEST_DATA); + } + } + + // Append data. + if (m_current_state.sub_state.trans_sub_state == ANTFS_TRANS_SUBSTATE_DOWNLOADING) + { + uint32_t num_of_bytes_to_burst = num_bytes; + + if (num_of_bytes_to_burst & (BURST_PACKET_SIZE - 1u)) + { + // Round up total number bytes to a multiple of BURST_PACKET_SIZE to be sent to + // burst handler. + num_of_bytes_to_burst &= ~(BURST_PACKET_SIZE - 1u); + num_of_bytes_to_burst += BURST_PACKET_SIZE; + } + + uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + num_of_bytes_to_burst, + (uint8_t*)&(p_message[block_offset]), + BURST_SEGMENT_CONTINUE); + if (err_code != NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR) + { + // If burst failed before we are able to catch it, we will get a TRANSFER_SEQUENCE_NUMBER_ERROR + // The message processing will send client back to correct state + APP_ERROR_CHECK(err_code); + } + + wait_burst_request_to_complete(); + + // Update current burst index. + m_link_burst_index.data += num_bytes; + // Update remaining bytes. + m_bytes_remaining.data -= num_bytes; + + m_is_data_request_pending = false; + + m_transfer_crc = crc_crc16_update(m_transfer_crc, + &(p_message[block_offset]), + num_bytes); + + if ((m_link_burst_index.data - m_temp_crc_offset) > SAVE_DISTANCE) + { + // Set CRC save point + m_saved_transfer_crc = m_saved_buffer_crc; // Set CRC at buffer save point (will always be one behind to account for buffering) + m_saved_buffer_crc = m_transfer_crc; // Set CRC at save point + + // Set offset save point + m_saved_crc_offset = m_saved_buffer_crc_offset; // Set offset at buffer save point (will always be one behind to account for buffering) + m_saved_buffer_crc_offset = m_link_burst_index.data; // Set buffer offset to current data offset + + // Reset save counter offset + m_temp_crc_offset = m_link_burst_index.data; // Set to current location; next save point will take place after SAVE_DISTANCE bytes + } + + if (!m_is_data_request_pending && (m_link_burst_index.data < m_max_transfer_index.data)) + { + // If we have not finished the download. + + // Request more data. + event_queue_write(ANTFS_EVENT_DOWNLOAD_REQUEST_DATA); + + m_is_data_request_pending = true; + } + else if (m_link_burst_index.data >= m_max_transfer_index.data && m_is_crc_pending) + { + // We are done, send CRC footer. + + uint8_t tx_buffer[BURST_PACKET_SIZE]; + + tx_buffer[0] = 0; + tx_buffer[1] = 0; + tx_buffer[2] = 0; + tx_buffer[3] = 0; + tx_buffer[4] = 0; + tx_buffer[5] = 0; + tx_buffer[6] = (uint8_t)m_transfer_crc; + tx_buffer[7] = (uint8_t)(m_transfer_crc >> 8u); + + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_END); + if (err_code != NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR) + { + // If burst failed before we are able to catch it, we will get a TRANSFER_SEQUENCE_NUMBER_ERROR + // The message processing will send client back to correct state + APP_ERROR_CHECK(err_code); + } + + wait_burst_request_to_complete(); + + m_is_crc_pending = false; + m_max_transfer_index.data = 0; + } + + // Return the number of bytes we accepted. + return num_bytes; + } + } + + // No bytes were accepted. + return 0; +} + + +bool antfs_upload_req_resp_transmit(uint8_t response, + const antfs_request_info_t * const p_request_info) +{ +#if ANTFS_CONFIG_UPLOAD_ENABLED + if (m_current_state.state != ANTFS_STATE_TRANS || + // Only send the response if we were processing an upload request. + (m_link_command_in_progress != ANTFS_CMD_UPLOAD_REQUEST_ID)) + { + return false; + } + + // If the application is sending a response for a different file than requested, the upload + // will fail. + if (p_request_info->file_index.data != m_file_index.data) + { + event_queue_write(ANTFS_EVENT_UPLOAD_FAIL); + + return false; + } + + ulong_union_t max_mem_size; + // Set maximum number of bytes that can be written to the file. + max_mem_size.data = p_request_info->max_file_size; + + if (p_request_info->max_burst_block_size.data != 0) + { + // If the client is limiting the block size set the block size requested by the client. + m_block_size.data = p_request_info->max_burst_block_size.data; + } + else + { + // Try to get the entire file in a single block. + m_block_size.data = max_mem_size.data; + } + + if (response == 0) + { + if (m_max_transfer_index.data > max_mem_size.data) + { + // Not enough space to write file, reject download. + response = RESPONSE_MESSAGE_NOT_ENOUGH_SPACE; + } + } + + // Get last valid CRC and last valid offset. + m_transfer_crc = p_request_info->file_crc; + m_link_burst_index.data = p_request_info->file_size.data; + + // First packet to transmit is the beacon. + beacon_transmit(MESG_BURST_DATA_ID); + + // Second packet. + + uint8_t tx_buffer[BURST_PACKET_SIZE]; + + tx_buffer[0] = ANTFS_COMMAND_ID; + tx_buffer[1] = ANTFS_RSP_UPLOAD_REQ_ID; + tx_buffer[2] = response; + tx_buffer[3] = 0; + // Last valid data offset written to the file. + tx_buffer[4] = m_link_burst_index.bytes.byte0; + tx_buffer[5] = m_link_burst_index.bytes.byte1; + tx_buffer[6] = m_link_burst_index.bytes.byte2; + tx_buffer[7] = m_link_burst_index.bytes.byte3; + + + uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_CONTINUE); + APP_ERROR_CHECK(err_code); + + wait_burst_request_to_complete(); + + // Third packet. + + // Maximum number of bytes that can be written to the file. + tx_buffer[0] = max_mem_size.bytes.byte0; + tx_buffer[1] = max_mem_size.bytes.byte1; + tx_buffer[2] = max_mem_size.bytes.byte2; + tx_buffer[3] = max_mem_size.bytes.byte3; + // Maximum upload block size. + tx_buffer[4] = m_block_size.bytes.byte0; + tx_buffer[5] = m_block_size.bytes.byte1; + tx_buffer[6] = m_block_size.bytes.byte2; + tx_buffer[7] = m_block_size.bytes.byte3; + + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_CONTINUE); + APP_ERROR_CHECK(err_code); + + wait_burst_request_to_complete(); + + // Fourth packet. + + tx_buffer[0] = 0; + tx_buffer[1] = 0; + tx_buffer[2] = 0; + tx_buffer[3] = 0; + tx_buffer[4] = 0; + tx_buffer[5] = 0; + // Value of CRC at last data offset. + tx_buffer[6] = (uint8_t) m_transfer_crc; + tx_buffer[7] = (uint8_t)(m_transfer_crc >> 8); + + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_END); + APP_ERROR_CHECK(err_code); + + wait_burst_request_to_complete(); + + m_link_command_in_progress = ANTFS_CMD_UPLOAD_REQUEST_ID; + + if (response != 0) + { + // Failed upload request. Reset max transfer index to 0 (do not accept any data if the host + // sends it anyway). + m_max_transfer_index.data = 0; + } + else + { + // Wait for upload data request. + m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_UPLOAD_WAIT_FOR_DATA; + } + + return true; +#else + return false; +#endif // ANTFS_CONFIG_UPLOAD_ENABLED +} + + +bool antfs_upload_data_resp_transmit(bool data_upload_success) +{ +#if ANTFS_CONFIG_UPLOAD_ENABLED + // Should be in TRANSPORT layer to send this response. + if (m_current_state.state != ANTFS_STATE_TRANS) + { + return false; + } + + uint8_t tx_buffer[BURST_PACKET_SIZE]; + + // Response. + tx_buffer[0] = ANTFS_COMMAND_ID; + tx_buffer[1] = ANTFS_RSP_UPLOAD_DATA_ID; + tx_buffer[2] = (data_upload_success) ? RESPONSE_MESSAGE_OK : RESPONSE_MESSAGE_FAIL; + tx_buffer[3] = 0; + tx_buffer[4] = 0; + tx_buffer[5] = 0; + tx_buffer[6] = 0; + tx_buffer[7] = 0; + + // First packet is beacon. + beacon_transmit(MESG_BURST_DATA_ID); + + // Send last packet. + uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_END); + APP_ERROR_CHECK(err_code); + + wait_burst_request_to_complete(); + + m_link_command_in_progress = ANTFS_CMD_UPLOAD_REQUEST_ID; + + // Reset maximum index. + m_max_transfer_index.data = 0; + + return true; +#else + return false; +#endif // ANTFS_CONFIG_UPLOAD_ENABLED +} + + +void antfs_erase_req_resp_transmit(uint8_t response) +{ + // This function should only be called after receiving an erase request. + APP_ERROR_CHECK_BOOL((m_current_state.state == ANTFS_STATE_TRANS) && + (m_link_command_in_progress == ANTFS_CMD_ERASE_ID)); + + beacon_transmit(MESG_BURST_DATA_ID); + + uint8_t tx_buffer[BURST_PACKET_SIZE]; + + // Erase response. + tx_buffer[0] = ANTFS_COMMAND_ID; + tx_buffer[1] = ANTFS_RSP_ERASE_ID; + tx_buffer[2] = response; + tx_buffer[3] = 0; + tx_buffer[4] = 0; + tx_buffer[5] = 0; + tx_buffer[6] = 0; + tx_buffer[7] = 0; + + uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_END); + APP_ERROR_CHECK(err_code); + + wait_burst_request_to_complete(); +} + + +bool antfs_event_extract(antfs_event_return_t * const p_event) +{ + bool return_value = false; + + if (m_event_queue.head != m_event_queue.tail) + { + // Pending events exist. Copy event parameters into return event. + p_event->event = m_event_queue.p_queue[m_event_queue.tail].event; + p_event->file_index = m_event_queue.p_queue[m_event_queue.tail].file_index; + p_event->offset = m_event_queue.p_queue[m_event_queue.tail].offset; + p_event->bytes = m_event_queue.p_queue[m_event_queue.tail].bytes; + p_event->crc = m_event_queue.p_queue[m_event_queue.tail].crc; + memcpy(p_event->data, + m_event_queue.p_queue[m_event_queue.tail].data, + sizeof(p_event->data)); + + // Release the event queue. + m_event_queue.tail = ((m_event_queue.tail + 1u) & (ANTFS_EVENT_QUEUE_SIZE - 1u)); + + return_value = true; + } + + return return_value; +} + + +/**@brief Function for setting the channel period. + * + * Sets the channel period. The only allowed frequencies are 0.5, 1, 2, 4 and 8 Hz. + * + * @param[in] link_period Link period for the beacon transmission. + */ +static void channel_period_set(uint32_t link_period) +{ + uint32_t period; + + switch (link_period) + { + default: + // Shouldn't happen, but just in case default to 0,5Hz. + case BEACON_PERIOD_0_5_HZ: + period = 65535u; + break; + + case BEACON_PERIOD_1_HZ: + period = 32768u; + break; + + case BEACON_PERIOD_2_HZ: + period = 16384u; + break; + + case BEACON_PERIOD_4_HZ: + period = 8192u; + break; + + case BEACON_PERIOD_8_HZ: + period = 4096u; + break; + } + + const uint32_t err_code = sd_ant_channel_period_set(ANTFS_CONFIG_CHANNEL_NUMBER, period); + APP_ERROR_CHECK(err_code); +} + + +/**@brief Function for starting ANT-FS timeout. + * + * @param[in] timeout_in_secs Timeout requested in unit of seconds. + */ +static void timeout_start(uint32_t timeout_in_secs) +{ + uint32_t err_code = app_timer_stop(m_timer_id); + APP_ERROR_CHECK(err_code); + + err_code = app_timer_start(m_timer_id, + APP_TIMER_TICKS((uint32_t)(timeout_in_secs * 1000u)), + NULL); + APP_ERROR_CHECK(err_code); +} + + +/**@brief Function for switching to authentication layer. + */ +static void authenticate_layer_transit(void) +{ + if (m_current_state.state != ANTFS_STATE_OFF) + { + m_current_state.state = ANTFS_STATE_AUTH; + m_current_state.sub_state.auth_sub_state = ANTFS_AUTH_SUBSTATE_NONE; + m_link_command_in_progress = ANTFS_CMD_NONE; + + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); + + uint32_t err_code = sd_ant_channel_radio_freq_set(ANTFS_CONFIG_CHANNEL_NUMBER, m_active_beacon_frequency); + APP_ERROR_CHECK(err_code); + + event_queue_write(ANTFS_EVENT_AUTH); + } +} + + +/**@brief Function for decoding an ANT-FS command received at the link layer. + * + * @param[in] p_command_buffer The ANT-FS command buffer. + */ +static void link_layer_cmd_decode(const uint8_t * p_command_buffer) +{ + if (p_command_buffer[ANTFS_CONNECTION_TYPE_OFFSET] != ANTFS_COMMAND_ID) + { + return; + } + + switch (p_command_buffer[ANTFS_COMMAND_OFFSET]) + { + case ANTFS_CMD_LINK_ID: + // Channel frequency. + m_active_beacon_frequency = + p_command_buffer[TRANSPORT_CHANNEL_FREQUENCY_OFFSET]; + // Channel message period. + m_active_beacon_status1_field.parameters.link_period = + p_command_buffer[TRANSPORT_MESSAGE_PERIOD_OFFSET]; + // Host serial Number. + m_link_host_serial_number.bytes.byte0 = + p_command_buffer[HOST_ID_OFFSET_0]; + m_link_host_serial_number.bytes.byte1 = + p_command_buffer[HOST_ID_OFFSET_1]; + m_link_host_serial_number.bytes.byte2 = + p_command_buffer[HOST_ID_OFFSET_2]; + m_link_host_serial_number.bytes.byte3 = + p_command_buffer[HOST_ID_OFFSET_3]; + + // Move to the channel period issued by the host. + channel_period_set(m_active_beacon_status1_field.parameters.link_period); + + authenticate_layer_transit(); + break; + + default: + break; + } +} + + +/**@brief Function for switching to link layer. + */ +static void link_layer_transit(void) +{ + if (m_current_state.state != ANTFS_STATE_OFF) + { + uint32_t err_code; +#if ANTFS_CONFIG_DEBUG_LED_ENABLED + err_code = bsp_indication_set(BSP_INDICATE_IDLE); + APP_ERROR_CHECK(err_code); +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED + + m_current_state.state = ANTFS_STATE_LINK; + m_current_state.sub_state.link_sub_state = ANTFS_LINK_SUBSTATE_NONE; + m_link_command_in_progress = ANTFS_CMD_NONE; + m_active_beacon_status1_field = m_initial_parameters.beacon_status_byte1; + m_active_beacon_frequency = m_initial_parameters.beacon_frequency; + + timeout_disable(); + + err_code = sd_ant_channel_radio_freq_set(ANTFS_CONFIG_CHANNEL_NUMBER, m_active_beacon_frequency); + APP_ERROR_CHECK(err_code); + + event_queue_write(ANTFS_EVENT_LINK); + } +} + + +/**@brief Function for decoding an ANT-FS command received at the authenticate layer. + * + * @param[in] control_byte The command control byte. + * @param[in] p_command_buffer The ANT-FS command buffer. + */ +static void authenticate_layer_cmd_decode(uint8_t control_byte, + const uint8_t * p_command_buffer) +{ + // @note: Response variable must have a static storage allocation as it keeps track of the + // passkey authentication progress between multiple burst packets. +#if ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED + static uint32_t response; +#endif // ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED + + if ((control_byte & ~SEQUENCE_LAST_MESSAGE) == 0 && m_link_command_in_progress != ANTFS_CMD_NONE) + { + // This is something new, and we're busy processing something already, so don't respond + return; + } + + if (p_command_buffer[ANTFS_CONNECTION_TYPE_OFFSET] == ANTFS_COMMAND_ID && + m_link_command_in_progress == ANTFS_CMD_NONE) + { + if (p_command_buffer[ANTFS_COMMAND_OFFSET] == ANTFS_CMD_AUTHENTICATE_ID) + { + // Make sure it is the correct host + if (m_link_host_serial_number.bytes.byte0 != p_command_buffer[HOST_ID_OFFSET_0] || + m_link_host_serial_number.bytes.byte1 != p_command_buffer[HOST_ID_OFFSET_1] || + m_link_host_serial_number.bytes.byte2 != p_command_buffer[HOST_ID_OFFSET_2] || + m_link_host_serial_number.bytes.byte3 != p_command_buffer[HOST_ID_OFFSET_3]) + return; + + m_link_command_in_progress = ANTFS_CMD_AUTHENTICATE_ID; + m_authenticate_command_type = p_command_buffer[COMMAND_TYPE_OFFSET]; + m_retry = AUTHENTICATION_RETRIES; + } + } + + if (m_link_command_in_progress == ANTFS_CMD_AUTHENTICATE_ID) + { + switch (m_authenticate_command_type) + { + case COMMAND_TYPE_REQUEST_SERIAL: + if (control_byte & SEQUENCE_LAST_MESSAGE) + { + // Don't do anything before the burst completes (last burst message received). + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); + authenticate_response_transmit(AUTH_RESPONSE_N_A, + ANTFS_REMOTE_FRIENDLY_NAME_MAX, + // Send device friendly name if it exists. + m_initial_parameters.p_remote_friendly_name); + } + break; + +#if ANTFS_CONFIG_AUTH_TYPE_PASSTHROUGH_ENABLED + case COMMAND_TYPE_PROCEED: + if (control_byte & SEQUENCE_LAST_MESSAGE) + { + // Don't do anything before the burst completes (last burst message received). + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); + // Proceed directly to transport layer (no authentication required). + authenticate_response_transmit(AUTH_RESPONSE_ACCEPT, 0, NULL); + } + break; + +#endif // ANTFS_CONFIG_AUTH_TYPE_PASSTHROUGH_ENABLED +#if ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED + case COMMAND_TYPE_REQUEST_PAIR: + if ((control_byte & SEQUENCE_NUMBER_ROLLOVER) == 0) + { + // First burst packet. + + // Friendly name length. + m_friendly_name.friendly_name_size = + p_command_buffer[AUTH_STRING_LENGTH_OFFSET]; + + if (m_friendly_name.friendly_name_size > 0) + { + if (m_friendly_name.friendly_name_size > ANTFS_FRIENDLY_NAME_MAX) + { + m_friendly_name.friendly_name_size = ANTFS_FRIENDLY_NAME_MAX; + } + + m_friendly_name.index = 0; + } + } + else + { + // Next burst packets: read host friendly name. + + if (m_friendly_name.index < ANTFS_FRIENDLY_NAME_MAX) + { + uint32_t num_of_bytes = ANTFS_FRIENDLY_NAME_MAX - m_friendly_name.index; + if (num_of_bytes > 8u) + { + num_of_bytes = 8u; + } + memcpy((uint8_t*)&m_friendly_name.friendly_name[m_friendly_name.index], + p_command_buffer, + num_of_bytes); + m_friendly_name.index += num_of_bytes; + } + } + + if (control_byte & SEQUENCE_LAST_MESSAGE) + { + // Last burst packet. + + timeout_start(ANTFS_CONFIG_PAIRING_TIMEOUT); + if (m_friendly_name.friendly_name_size > 0) + { + m_friendly_name.is_name_set = true; + } + + m_current_state.sub_state.auth_sub_state = ANTFS_AUTH_SUBSTATE_PAIR; + // If pairing is supported, send request to UI. + event_queue_write(ANTFS_EVENT_PAIRING_REQUEST); + } + break; + +#endif // ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED +#if ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED + case COMMAND_TYPE_REQUEST_PASSKEY: + if ((control_byte & SEQUENCE_NUMBER_ROLLOVER) == 0) + { + // First burst packet. + + // Passkey length. + const uint32_t passkey_size = p_command_buffer[AUTH_STRING_LENGTH_OFFSET]; + + // Default the algorithm to accept. + response = AUTH_RESPONSE_ACCEPT; + + // Check if the passkey length is valid. + if (passkey_size == ANTFS_PASSKEY_SIZE) + { + m_passkey_index = 0; + } + else + { + // Invalid lenght supplied - the authentication will be rejected. + response = AUTH_RESPONSE_REJECT; + } + } + else + { + // Next burst packets: read host friendly name. + + if ((response == AUTH_RESPONSE_ACCEPT) && + // Prevent buffer overrun. + (m_passkey_index != ANTFS_PASSKEY_SIZE)) + { + // Passkey length was valid and the host supplied key matches so far. + uint32_t idx = 0; + + // Check the current received burst packet for passkey match. + do + { + if (m_initial_parameters.p_pass_key[m_passkey_index++] != + p_command_buffer[idx]) + { + // Reject the authentication request and further processing of + // passkey matching if a mismatch is found. + response = AUTH_RESPONSE_REJECT; + break; + } + + ++idx; + } + while (idx < BURST_PACKET_SIZE); + } + } + + if (control_byte & SEQUENCE_LAST_MESSAGE) + { + // Last burst packet. + + if (m_passkey_index < ANTFS_PASSKEY_SIZE) + { + // We did not get the complete passkey, reject authentication request. + response = AUTH_RESPONSE_REJECT; + } + + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); + m_current_state.sub_state.auth_sub_state = ANTFS_AUTH_SUBSTATE_PASSKEY; + authenticate_response_transmit(response, 0, NULL); + } + break; + +#endif // ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED + default: + break; + } + } + else if (p_command_buffer[ANTFS_COMMAND_OFFSET] == ANTFS_CMD_DISCONNECT_ID) + { + if (control_byte & SEQUENCE_LAST_MESSAGE) + { + // Don't do anything before the burst completes (last burst message received). + link_layer_transit(); + } + } + else if (p_command_buffer[ANTFS_COMMAND_OFFSET] == ANTFS_CMD_PING_ID) + { + // Reset timeout. + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); + m_link_command_in_progress = ANTFS_CMD_NONE; + } + else + { + // No implementation needed. + } +} + + +/**@brief Function for decoding an ANT-FS command received at the transport layer. + * + * @param[in] control_byte The command control byte. + * @param[in] p_command_buffer The ANT-FS command buffer. + */ +static void transport_layer_cmd_decode(uint8_t control_byte, const uint8_t * p_command_buffer) +{ + ulong_union_t host_serial_number = {0}; + + if (p_command_buffer[ANTFS_CONNECTION_TYPE_OFFSET] == ANTFS_COMMAND_ID) + { + m_link_command_in_progress = p_command_buffer[ANTFS_COMMAND_OFFSET]; + } + + switch (m_link_command_in_progress) + { + case ANTFS_CMD_PING_ID: + // Reset timeout. + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); + m_link_command_in_progress = ANTFS_CMD_NONE; + break; + + case ANTFS_CMD_DISCONNECT_ID: + if (control_byte & SEQUENCE_LAST_MESSAGE) + { + // Don't do anything before the burst completes (last burst message received). + link_layer_transit(); + } + break; + + case ANTFS_CMD_ERASE_ID: + if (control_byte & SEQUENCE_LAST_MESSAGE) + { + // Don't do anything before the burst completes (last burst message received). + + // Requested index. + m_file_index.bytes.low = p_command_buffer[DATA_INDEX_OFFSET_LOW]; + m_file_index.bytes.high = p_command_buffer[DATA_INDEX_OFFSET_HIGH]; + + // Send erase request to the application. + event_queue_write(ANTFS_EVENT_ERASE_REQUEST); + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); + m_link_command_in_progress = ANTFS_CMD_ERASE_ID; + } + break; + + case ANTFS_CMD_DOWNLOAD_ID: + if (m_current_state.sub_state.trans_sub_state != ANTFS_TRANS_SUBSTATE_NONE) + { + // Ignore the command if we are busy. + break; + } + + if ((control_byte & ~SEQUENCE_LAST_MESSAGE) == 0x00) + { + // First burst packet. + + if ((m_file_index.bytes.low != p_command_buffer[DATA_INDEX_OFFSET_LOW]) || + (m_file_index.bytes.high != p_command_buffer[DATA_INDEX_OFFSET_HIGH])) + { + // This is a new index, so we can not check the CRC against the previous saved + // CRC. + + // CRC seed checking is made invalid by setting the last saved offset to the + // maximum file size. + m_saved_crc_offset = ANTFS_MAX_FILE_SIZE; + } + + // Requested data file index. + m_file_index.bytes.low = p_command_buffer[DATA_INDEX_OFFSET_LOW]; + m_file_index.bytes.high = p_command_buffer[DATA_INDEX_OFFSET_HIGH]; + + // Initialize current position in the TX burst to the requested offset. + m_link_burst_index.bytes.byte0 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_0]; + m_link_burst_index.bytes.byte1 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_1]; + m_link_burst_index.bytes.byte2 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_2]; + m_link_burst_index.bytes.byte3 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_3]; + } + else if (control_byte & SEQUENCE_LAST_MESSAGE) + { + // Last burst packet (download command should be two packets long). + + // Get CRC seed from host. + m_compared_crc = (uint16_t)p_command_buffer[DATA_INDEX_OFFSET_LOW]; + m_compared_crc |= ((uint16_t)p_command_buffer[DATA_INDEX_OFFSET_HIGH] << 8u); + + // Maximum block size allowed by host. + m_max_block_size.bytes.byte0 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_0]; + m_max_block_size.bytes.byte1 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_1]; + m_max_block_size.bytes.byte2 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_2]; + m_max_block_size.bytes.byte3 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_3]; + + // Initialize number of remaining bytes for this block to the maximum block size. + m_bytes_remaining.data = m_max_block_size.data; + + if (p_command_buffer[INITIAL_REQUEST_OFFSET]) + { + // This request is the start of a new transfer. + + // Initialize data offset for CRC calculation to the requested data offset. + m_saved_crc_offset = m_link_burst_index.data; + m_saved_buffer_crc_offset = m_link_burst_index.data; + + // Use CRC seed provided by host for CRC checking of the data. + m_transfer_crc = m_compared_crc; + m_saved_transfer_crc = m_compared_crc; + m_saved_buffer_crc = m_compared_crc; + m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_VERIFY_CRC; + } + else + { + // This is a request to resume a partially completed transfer. + + if (m_saved_crc_offset > m_link_burst_index.data) + { + // We can not check the received CRC seed as the requested offset is before + // our last save point. + + // Set CRC checking as invalid. + m_saved_crc_offset = ANTFS_MAX_FILE_SIZE; + } + else + { + m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_VERIFY_CRC; + } + } + + m_is_data_request_pending = false; + + // Send download request to the application for further handling. + event_queue_write(ANTFS_EVENT_DOWNLOAD_REQUEST); + + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); + m_link_command_in_progress = ANTFS_CMD_DOWNLOAD_ID; + } + break; + + case ANTFS_CMD_UPLOAD_REQUEST_ID: +#if ANTFS_CONFIG_UPLOAD_ENABLED + if ((control_byte & ~SEQUENCE_LAST_MESSAGE) == 0x00) + { + // First burst packet. + + if ((m_file_index.bytes.low != p_command_buffer[DATA_INDEX_OFFSET_LOW]) || + ( + (m_file_index.bytes.high != p_command_buffer[DATA_INDEX_OFFSET_HIGH]) || + (m_current_state.sub_state.trans_sub_state == ANTFS_TRANS_SUBSTATE_NONE) + ) + ) + { + // If it is a new index or we completed the last upload. + + // Get the file index. + m_file_index.bytes.low = p_command_buffer[DATA_INDEX_OFFSET_LOW]; + m_file_index.bytes.high = p_command_buffer[DATA_INDEX_OFFSET_HIGH]; + + // As this is a new upload, reset save point to the beginning of the file. + + // Set CRC to zero. + m_saved_crc_offset = 0; + m_saved_transfer_crc = 0; + } + + // Get the upper limit of upload from request message. + m_max_transfer_index.bytes.byte0 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_0]; + m_max_transfer_index.bytes.byte1 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_1]; + m_max_transfer_index.bytes.byte2 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_2]; + m_max_transfer_index.bytes.byte3 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_3]; + } + else if (control_byte & SEQUENCE_LAST_MESSAGE) + { + // Last burst (second) packet. + + // Get data offset the requested upload will start at. + m_link_burst_index.bytes.byte0 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_0]; + m_link_burst_index.bytes.byte1 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_1]; + m_link_burst_index.bytes.byte2 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_2]; + m_link_burst_index.bytes.byte3 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_3]; + + if (m_link_burst_index.data != ANTFS_MAX_FILE_SIZE) + { + // If this is a new upload. + + // The data offset specified in the upload request will be used. + m_saved_crc_offset = m_link_burst_index.data; + + m_saved_transfer_crc = 0; + } + + m_transfer_crc = m_saved_transfer_crc; + + // Send upload request to the application for further handling. + event_queue_write(ANTFS_EVENT_UPLOAD_REQUEST); + + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); + m_link_command_in_progress = ANTFS_CMD_UPLOAD_REQUEST_ID; + } +#endif // ANTFS_CONFIG_UPLOAD_ENABLED + break; + + case ANTFS_CMD_UPLOAD_DATA_ID: +#if ANTFS_CONFIG_UPLOAD_ENABLED + if ((control_byte & ~SEQUENCE_LAST_MESSAGE) == 0x00) + { + // First burst packet. + + if (m_current_state.sub_state.trans_sub_state == + ANTFS_TRANS_SUBSTATE_UPLOAD_WAIT_FOR_DATA) + { + antfs_event_t event; + + // Get CRC Seed from host. + m_compared_crc = (uint16_t)p_command_buffer[DATA_INDEX_OFFSET_LOW]; + m_compared_crc |= ((uint16_t)p_command_buffer[DATA_INDEX_OFFSET_HIGH] << 8u); + + // Set download offset. + m_link_burst_index.bytes.byte0 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_0]; + m_link_burst_index.bytes.byte1 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_1]; + m_link_burst_index.bytes.byte2 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_2]; + m_link_burst_index.bytes.byte3 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_3]; + + if ((m_link_burst_index.data + m_block_size.data) < m_max_transfer_index.data) + { + // Adjust block size as set by client. + m_max_transfer_index.data = m_link_burst_index.data + m_block_size.data; + } + + if (m_compared_crc != m_transfer_crc) + { + // Check that the request matches the CRC sent on the upload response. + + // Do not accept any data. + m_max_transfer_index.data = 0; + + // Failure will be reported when upload is done. + event = (antfs_event_t)0; + } + + // Set ready to receive a file. + m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_UPLOADING; + + event = ANTFS_EVENT_UPLOAD_START; + m_transfer_crc = m_compared_crc; + + if (m_link_burst_index.data > m_max_transfer_index.data) + { + // If the requested offset is too high. + + // Clear the max transfer index, so we'll report fail when the transfer + // finishes. + m_max_transfer_index.data = 0; + // Clear the event because we normally would not send an event at this point + // in this case. + event = (antfs_event_t)0; + } + + if (control_byte & SEQUENCE_LAST_MESSAGE) + { + // If this upload contains no data. + + // Leave the upload state. + m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_NONE; + + // if it was a valid index, report it as a successful upload, otherwise + // report it as a failure. + if (event == 0) + { + event = ANTFS_EVENT_UPLOAD_FAIL; + } + else + { + event = ANTFS_EVENT_UPLOAD_COMPLETE; + } + } + + if (event != 0) + { + event_queue_write(event); + } + } + } +#endif // ANTFS_CONFIG_UPLOAD_ENABLED + break; + + case ANTFS_CMD_LINK_ID: + host_serial_number.bytes.byte0 = p_command_buffer[HOST_ID_OFFSET_0]; + host_serial_number.bytes.byte1 = p_command_buffer[HOST_ID_OFFSET_1]; + host_serial_number.bytes.byte2 = p_command_buffer[HOST_ID_OFFSET_2]; + host_serial_number.bytes.byte3 = p_command_buffer[HOST_ID_OFFSET_3]; + + if (m_link_host_serial_number.data == host_serial_number.data) + { + m_active_beacon_frequency = p_command_buffer[TRANSPORT_CHANNEL_FREQUENCY_OFFSET]; + m_active_beacon_status1_field.parameters.link_period = + p_command_buffer[TRANSPORT_MESSAGE_PERIOD_OFFSET]; + + const uint32_t err_code = sd_ant_channel_radio_freq_set(ANTFS_CONFIG_CHANNEL_NUMBER, + m_active_beacon_frequency); + APP_ERROR_CHECK(err_code); + + channel_period_set(m_active_beacon_status1_field.parameters.link_period); + } + + m_link_command_in_progress = 0; + break; + + default: + // Don't do anything, this is an invalid message. + m_link_command_in_progress = 0; + break; + } +} + + +/**@brief Function for handling data upload. + * + * @param[in] control_byte The command control byte. + * @param[in] p_buffer The data buffer. + */ +static void upload_data_process(uint8_t control_byte, const uint8_t * p_buffer) +{ +#if ANTFS_CONFIG_UPLOAD_ENABLED + if (control_byte & SEQUENCE_LAST_MESSAGE) + { + // Last burst packet: upload complete. + + m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_NONE; + + // CRC for data packets contained in this upload block. + m_compared_crc = p_buffer[UPLOAD_CRC_OFFSET_LOW ]; + m_compared_crc |= (p_buffer[UPLOAD_CRC_OFFSET_HIGH] << 8u); + + if (m_max_transfer_index.data && (m_compared_crc == m_transfer_crc)) + { + // CRC OK, upload was completed successfully. + event_queue_write(ANTFS_EVENT_UPLOAD_COMPLETE); + } + else + { + // CRC mismatch, upload failed. + event_queue_write(ANTFS_EVENT_UPLOAD_FAIL); + } + + m_max_transfer_index.data = 0; + } + else + { + // Not the last burst packet: upload not complete. + + // Set initial number of bytes to 8 (size of burst packet). + m_bytes_to_write = BURST_PACKET_SIZE; + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); + + if (m_link_burst_index.data > m_max_transfer_index.data) + { + // We are past the main index, we do not need to write any more data. + m_bytes_to_write = 0; + } + else + { + if ((m_bytes_to_write + m_link_burst_index.data) > m_max_transfer_index.data) + { + // if we're less than 8 bytes away from the end, adjust the number of bytes to write + // in this block. + m_bytes_to_write = m_max_transfer_index.data - m_link_burst_index.data; + } + } + + if (m_bytes_to_write != 0) + { + APP_ERROR_CHECK_BOOL(m_bytes_to_write <= BURST_PACKET_SIZE); + + // Store begin of upload data. + mp_upload_data = p_buffer; + + m_transfer_crc = crc_crc16_update(m_transfer_crc, p_buffer, m_bytes_to_write); + + // Send data to application. + event_queue_write(ANTFS_EVENT_UPLOAD_DATA); + + // Update current offset. + m_link_burst_index.data += m_bytes_to_write; + + // Store save point. + m_saved_crc_offset = m_link_burst_index.data; + m_saved_transfer_crc = m_transfer_crc; + } + } +#endif // ANTFS_CONFIG_UPLOAD_ENABLED +} + + +/**@brief Function for switching to transport layer. + */ +static void transport_layer_transit(void) +{ + if (m_current_state.state != ANTFS_STATE_OFF) + { +#if ANTFS_CONFIG_DEBUG_LED_ENABLED + uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE); + APP_ERROR_CHECK(err_code); +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED + m_current_state.state = ANTFS_STATE_TRANS; + m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_NONE; + + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); + + beacon_transmit(MESG_BROADCAST_DATA_ID); + + event_queue_write(ANTFS_EVENT_TRANS); + } +} + + +void antfs_message_process(uint8_t * p_message) +{ +#if ANTFS_CONFIG_DEBUG_LED_ENABLED + uint32_t err_code; +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED + + if (p_message != NULL) + { + if ((p_message[BUFFER_INDEX_CHANNEL_NUM] & CHANNEL_NUMBER_MASK) != ANTFS_CONFIG_CHANNEL_NUMBER) + { + // Only process messages corresponding to the ANT-FS channel here. + return; + } + + if ((m_current_state.state == ANTFS_STATE_OFF) && + ( + !( + (p_message[BUFFER_INDEX_MESG_ID] == MESG_RESPONSE_EVENT_ID) && + (p_message[BUFFER_INDEX_RESPONSE_CODE] == NO_EVENT) + ) + ) + ) + { + return; + } + + switch (p_message[BUFFER_INDEX_MESG_ID]) + { + case MESG_BROADCAST_DATA_ID: + // We are not going to process broadcast messages or pass them to the app to handle. + break; + + case MESG_ACKNOWLEDGED_DATA_ID: + // Mark it as being the last message if it's an ack message. + p_message[ANTFS_CONTROL_OFFSET] |= SEQUENCE_LAST_MESSAGE; + + /* fall-through */ + case MESG_BURST_DATA_ID: + switch (m_current_state.state) + { + case ANTFS_STATE_LINK: + link_layer_cmd_decode(&p_message[ANTFS_DATA_OFFSET]); + break; + + case ANTFS_STATE_AUTH: + authenticate_layer_cmd_decode(p_message[ANTFS_CONTROL_OFFSET], + &p_message[ANTFS_DATA_OFFSET]); + break; + + case ANTFS_STATE_TRANS: + if (m_current_state.sub_state.trans_sub_state != + ANTFS_TRANS_SUBSTATE_UPLOADING) + { + transport_layer_cmd_decode(p_message[ANTFS_CONTROL_OFFSET], + &p_message[ANTFS_DATA_OFFSET]); + } + else + { + upload_data_process(p_message[ANTFS_CONTROL_OFFSET], + &p_message[ANTFS_DATA_OFFSET]); + } + break; + + default: + // If in any other state or sub-state, do nothing. + break; + } + break; + + case MESG_RESPONSE_EVENT_ID: + // Branch on event ID. + switch (p_message[BUFFER_INDEX_RESPONSE_CODE]) + { + case EVENT_TRANSFER_TX_FAILED: + m_link_command_in_progress = ANTFS_CMD_NONE; + // Switch into the appropriate state after the failure. Must be ready for + // the host to do a retry. + switch (m_current_state.state) + { + case ANTFS_STATE_LINK: + link_layer_transit(); + break; + + case ANTFS_STATE_AUTH: + // Burst failed, retry sending the response + if (!m_retry) + { + authenticate_layer_transit(); // Reload beacon + } + else + { + if (m_current_state.sub_state.auth_sub_state == ANTFS_AUTH_SUBSTATE_ACCEPT) + { + if (m_authenticate_command_type == COMMAND_TYPE_REQUEST_PAIR) + { + authenticate_response_transmit(AUTH_RESPONSE_ACCEPT, ANTFS_PASSKEY_SIZE, + m_initial_parameters.p_pass_key); + } + else + { + authenticate_response_transmit(AUTH_RESPONSE_ACCEPT, 0, NULL); + } + } + else if (m_current_state.sub_state.auth_sub_state == ANTFS_AUTH_SUBSTATE_REJECT) + { + authenticate_response_transmit(AUTH_RESPONSE_REJECT, 0, NULL); + } + else if (m_authenticate_command_type == COMMAND_TYPE_REQUEST_SERIAL) + { + authenticate_response_transmit(AUTH_RESPONSE_N_A, + ANTFS_REMOTE_FRIENDLY_NAME_MAX, + // Send device friendly name if it exists. + m_initial_parameters.p_remote_friendly_name); + } + else + { + // No implementation needed + } + + m_retry--; + } + + break; + + case ANTFS_STATE_TRANS: + if (m_current_state.sub_state.trans_sub_state == + ANTFS_TRANS_SUBSTATE_DOWNLOADING) + { + event_queue_write(ANTFS_EVENT_DOWNLOAD_FAIL); + } + transport_layer_transit(); + break; + + default: + // No implementation needed. + break; + } + break; + + case EVENT_TRANSFER_RX_FAILED: + m_link_command_in_progress = ANTFS_CMD_NONE; + + if (m_current_state.sub_state.trans_sub_state == + ANTFS_TRANS_SUBSTATE_UPLOADING) + { + event_queue_write(ANTFS_EVENT_UPLOAD_FAIL); + + m_current_state.sub_state.trans_sub_state = + ANTFS_TRANS_SUBSTATE_UPLOAD_RESUME; + } + else + { + // No implementation needed + } + + break; + + case EVENT_TRANSFER_TX_COMPLETED: + m_link_command_in_progress = ANTFS_CMD_NONE; + + // Switch into appropiate state after successful command. + switch (m_current_state.state) + { + case ANTFS_STATE_AUTH: + if (m_current_state.sub_state.auth_sub_state == + ANTFS_AUTH_SUBSTATE_ACCEPT) + { + // We passed authentication, so go to transport state. + transport_layer_transit(); + } + else if (m_current_state.sub_state.auth_sub_state == + ANTFS_AUTH_SUBSTATE_REJECT) + { + // We failed authentication, so go to link state. + link_layer_transit(); + } + else + { + // Reload beacon. + authenticate_layer_transit(); + } + break; + + case ANTFS_STATE_TRANS: + if (m_current_state.sub_state.trans_sub_state == + ANTFS_TRANS_SUBSTATE_DOWNLOADING) + { + event_queue_write(ANTFS_EVENT_DOWNLOAD_COMPLETE); + } + if (m_current_state.sub_state.trans_sub_state != + ANTFS_TRANS_SUBSTATE_UPLOAD_WAIT_FOR_DATA) + { + transport_layer_transit(); // Reload beacon. + } + break; + + default: + link_layer_transit(); // Reload beacon. + break; + } + break; + + case EVENT_TX: +#if ANTFS_CONFIG_DEBUG_LED_ENABLED + err_code = bsp_indication_set(BSP_INDICATE_SENT_OK); + APP_ERROR_CHECK(err_code); +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED + // Load beacon. + beacon_transmit(MESG_BROADCAST_DATA_ID); + break; + + case EVENT_CHANNEL_CLOSED: + event_queue_write(ANTFS_EVENT_CLOSE_COMPLETE); + break; + + case NO_EVENT: + // This shouldn't happen... command responses should not occur. + APP_ERROR_HANDLER(p_message[BUFFER_INDEX_RESPONSE_CODE]); + break; + + default: + // No implementation needed. + return; + } + break; + + default: + // No implementation needed. + return; + } + } +} + + +void antfs_channel_setup(void) +{ + // Start channel configuration. + uint32_t err_code = ant_fs_key_set(ANTFS_CONFIG_NETWORK_NUMBER); + APP_ERROR_CHECK(err_code); + + err_code = sd_ant_channel_assign(ANTFS_CONFIG_CHANNEL_NUMBER, + ANTFS_CHANNEL_TYPE, + ANTFS_CONFIG_NETWORK_NUMBER, + 0); + APP_ERROR_CHECK(err_code); + + // Use the lower 2 bytes of the ESN for device number. + uint16_t device_number = (uint16_t)(m_initial_parameters.client_serial_number & 0x0000FFFFu); + if (device_number == 0) + { + // Device number of 0 is not allowed. + device_number = 2; + } + + err_code = sd_ant_channel_id_set(ANTFS_CONFIG_CHANNEL_NUMBER, + device_number, + ANTFS_CONFIG_DEVICE_TYPE, + ANTFS_CONFIG_TRANS_TYPE); + APP_ERROR_CHECK(err_code); + + // Remain in initialization state until channel is open. + m_current_state.state = ANTFS_STATE_INIT; + // @note: Channel frequency is set by function below. + link_layer_transit(); + m_current_state.state = ANTFS_STATE_INIT; + + channel_period_set(m_active_beacon_status1_field.parameters.link_period); + + err_code = sd_ant_channel_open(ANTFS_CONFIG_CHANNEL_NUMBER); + APP_ERROR_CHECK(err_code); + + err_code = sd_ant_channel_radio_tx_power_set(ANTFS_CONFIG_CHANNEL_NUMBER, + ANTFS_CONFIG_TRANSMIT_POWER, + ANTFS_CONFIG_CUSTOM_TRANSMIT_POWER); + APP_ERROR_CHECK(err_code); + + m_current_state.state = ANTFS_STATE_LINK; + m_current_state.sub_state.link_sub_state = ANTFS_LINK_SUBSTATE_NONE; + + event_queue_write(ANTFS_EVENT_OPEN_COMPLETE); + + // Start beacon broadcast. + beacon_transmit(MESG_BROADCAST_DATA_ID); +} + + +/**@brief Function for resetting the ANT-FS state machine. + */ +static void state_machine_reset(void) +{ + m_current_state.state = ANTFS_STATE_OFF; + m_link_command_in_progress = ANTFS_CMD_NONE; + + timeout_disable(); + + // Reset the ANT-FS event queue. + m_event_queue.p_queue = m_event_queue_buffer; + m_event_queue.head = 0; + m_event_queue.tail = 0; + + // Set as invalid. + m_authenticate_command_type = 0xFFu; + m_retry = 0; + + m_saved_crc_offset = 0xFFFFFFFFu; + m_max_transfer_index.data = 0; + m_is_crc_pending = false; + m_is_data_request_pending = false; + + m_friendly_name.is_name_set = false; + m_friendly_name.index = 0; + + memset(m_friendly_name.friendly_name, 0, ANTFS_FRIENDLY_NAME_MAX); +} + + +/**@brief Function for ANT-FS timer event. + * + * Handles pairing and command timeouts. + * + * @param[in] p_context The callback context. + */ +static void timeout_handle(void * p_context) +{ + if (m_current_state.state == ANTFS_STATE_OFF) + { + return; + } + + if ((m_current_state.state == ANTFS_STATE_AUTH) && + // Pairing timeout. + (m_current_state.sub_state.auth_sub_state == ANTFS_AUTH_SUBSTATE_PAIR)) + { + // Reject authentication request and send pairing timeout event. + authenticate_response_transmit(AUTH_RESPONSE_REJECT, 0, NULL); + event_queue_write(ANTFS_EVENT_PAIRING_TIMEOUT); + } + + // Fall back to link layer when an ANT-FS event times out. + link_layer_transit(); +} + + +void antfs_init(const antfs_params_t * const p_params, + antfs_burst_wait_handler_t burst_wait_handler) +{ + m_initial_parameters = *p_params; + m_burst_wait_handler = burst_wait_handler; + m_active_beacon_status1_field = m_initial_parameters.beacon_status_byte1; + + uint32_t err_code = app_timer_create(&m_timer_id, APP_TIMER_MODE_SINGLE_SHOT, timeout_handle); + APP_ERROR_CHECK(err_code); + + state_machine_reset(); + + err_code = sd_ant_burst_handler_wait_flag_enable((uint8_t *)(&m_burst_wait)); + APP_ERROR_CHECK(err_code); +} +#endif // NRF_MODULE_ENABLED(ANTFS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/antfs.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/antfs.h new file mode 100644 index 0000000000000000000000000000000000000000..27511246e27248de634d0c11030baaa296e41d26 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/antfs.h @@ -0,0 +1,396 @@ +/** + * This software is subject to the ANT+ Shared Source License + * www.thisisant.com/swlicenses + * Copyright (c) Dynastream Innovations, Inc. 2012 + * 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 Dynastream nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * The following actions are prohibited: + * 1) Redistribution of source code containing the ANT+ Network + * Key. The ANT+ Network Key is available to ANT+ Adopters. + * Please refer to http://thisisant.com to become an ANT+ + * Adopter and access the key. + * + * 2) Reverse engineering, decompilation, and/or disassembly of + * software provided in binary form under this license. + * + * 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 HEREBY + * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW + * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE + * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. + * + */ +/**@file + * @brief The ANT-FS client protocol interface. + * This file is based on implementation originally made by Dynastream Innovations Inc. - August 2012 + * @defgroup ant_fs ANT-FS client device simulator + * @{ + * @ingroup ant_sdk_utils + * + * @brief The ANT-FS client device simulator. + * + * @note The ANT-FS Network Key is available for ANT+ Adopters. Please refer to http://thisisant.com to become an ANT+ Adopter and access the key. + */ + +#ifndef ANTFS_H__ +#define ANTFS_H__ + +#include +#include +#include "defines.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ANTFS_VERSION_MAJOR 1u /**< Version major number. */ +#define ANTFS_VERSION_MINOR 0 /**< Version minor number. */ +#define ANTFS_VERSION_ITERATION 0 /**< Version iteration. */ +#define ANTFS_VERSION_TYPE 'R' /**< Version type is release. */ +#define ANTFS_VERSION_SPEC '0.AK' /**< Version of the ANT-FS Technology Specification. */ +#define ANTFS_DIR_STRUCT_VERSION 1u /**< Version of the directory file structure. */ +#define ANTFS_VERSION_DATE 20090522u /**< Version date. */ + +// ANT-FS options. +#define ANTFS_LINK_FREQ 50u /**< RF Frequency (+2400MHz). */ +#define ANTFS_CHANNEL_TYPE CHANNEL_TYPE_MASTER /**< ANT-FS Client Channel Type. */ +#define ANTFS_AUTH_STRING_MAX 255u /**< Maximum size of authentication strings (passkey/friendly name). */ +#define ANTFS_PASSKEY_SIZE 16u /**< Passkey size. */ +#define ANTFS_FRIENDLY_NAME_MAX 16u /**< Maximum size of friendly name received from host. */ +#define ANTFS_REMOTE_FRIENDLY_NAME_MAX 16u /**< Maximum size of client's friendly name. */ + +// Beacon definitions. +#define BEACON_PERIOD_SHIFT 0x00 /**< Shift value for masking out beacon period. */ +#define BEACON_PERIOD_MASK (0x07u << BEACON_PERIOD_SHIFT) /**< Beacon period bitmask. */ +#define BEACON_PERIOD_0_5_HZ (0x00 << BEACON_PERIOD_SHIFT) /**< Value for 0,5Hz beacon period. */ +#define BEACON_PERIOD_1_HZ (0x01u << BEACON_PERIOD_SHIFT) /**< Value for 1Hz beacon period. */ +#define BEACON_PERIOD_2_HZ (0x02u << BEACON_PERIOD_SHIFT) /**< Value for 2Hz beacon period. */ +#define BEACON_PERIOD_4_HZ (0x03u << BEACON_PERIOD_SHIFT) /**< Value for 4Hz beacon period. */ +#define BEACON_PERIOD_8_HZ (0x04u << BEACON_PERIOD_SHIFT) /**< Value for 8Hz beacon period. */ +#define PAIRING_AVAILABLE_FLAG_SHIFT 0x03u /**< Shift value for masking out pairing enabled bit. */ +#define PAIRING_AVAILABLE_FLAG_MASK (0x01u << PAIRING_AVAILABLE_FLAG_SHIFT) /**< Pairing enabled bitmask. */ +#define UPLOAD_ENABLED_FLAG_SHIFT 0x04u /**< Shift value for masking out upload enabled bit. */ +#define UPLOAD_ENABLED_FLAG_MASK (0x01u << UPLOAD_ENABLED_FLAG_SHIFT) /**< Upload enabled bitmask. */ +#define DATA_AVAILABLE_FLAG_SHIFT 0x05u /**< Shift value for masking out data available bit. */ +#define DATA_AVAILABLE_FLAG_MASK (0x01u << DATA_AVAILABLE_FLAG_SHIFT) /**< Data available bitmask. */ + +#if ANTFS_ENABLED +// Build the default beacon settings. +#if ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED + #define ANTFS_PAIRING_BIT PAIRING_AVAILABLE_FLAG_MASK /**< Build pairing enabled default beacon setting. */ +#else + #define ANTFS_PAIRING_BIT 0x00u /**< Build pairing disabled default beacon setting. */ +#endif // ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED +#if ANTFS_CONFIG_UPLOAD_ENABLED + #define ANTFS_UPLOAD_BIT UPLOAD_ENABLED_FLAG_MASK /**< Build upload enabled default beacon setting. */ +#else + #define ANTFS_UPLOAD_BIT 0x00u /**< Build upload disabled default beacon setting. */ +#endif // ANTFS_CONFIG_UPLOAD_ENABLED + +#define ANTFS_DEFAULT_BEACON (ANTFS_CONFIG_BEACON_STATUS_PERIOD | ANTFS_UPLOAD_BIT | ANTFS_PAIRING_BIT | DATA_AVAILABLE_FLAG_MASK) /**< Define the default beacon setting. */ +#endif // ANTFS_ENABLED + +// Download/Upload responses. +#define RESPONSE_MESSAGE_OK 0x00u /**< Download request ok. */ +#define RESPONSE_MESSAGE_NOT_EXIST 0x01u /**< File does not exist. */ +#define RESPONSE_MESSAGE_NOT_AVAILABLE 0x02u /**< File can not be read/written to (download/upload respectively). */ +#define RESPONSE_INVALID_OPERATION 0x04u /**< Request invalid. */ +// Download responses. +#define RESPONSE_MESSAGE_NOT_READY 0x03u /**< Not ready to download. */ +#define RESPONSE_INVALID_CRC 0x05u /**< CRC incorrect. */ +// Upload responses. +#define RESPONSE_MESSAGE_NOT_ENOUGH_SPACE 0x03u /**< Not enough space to to complete write. */ +#define RESPONSE_MESSAGE_UPLOAD_NOT_READY 0x05u /**< Not ready to upload */ +// Upload/Erase responses. +#define RESPONSE_MESSAGE_FAIL 0x01u /**< Data File Index does not exist / Erase failed. */ + +// Directory general file flags. +#define ANTFS_DIR_READ_MASK 0x80u /**< Read (can download). */ +#define ANTFS_DIR_WRITE_MASK 0x40u /**< Write (can upload). */ +#define ANTFS_DIR_ERASE_MASK 0x20u /**< Erase (can erase). */ +#define ANTFS_DIR_ARCHIVE_MASK 0x10u /**< Archive (has been downloaded). */ +#define ANTFS_DIR_APPEND_MASK 0x08u /**< Append (can append to file only). */ + +#define ANTFS_MAX_FILE_SIZE 0xFFFFFFFFu /**< Maximum file size, as specified by directory structure. */ +#define ANTFS_BURST_BLOCK_SIZE 16u /**< Size of each block of burst data that the client attempts to send when it processes a data request event. */ + +/**@brief ANT-FS beacon status. */ +typedef union +{ + uint32_t status; /**< Beacon status byte 1. */ + + struct + { + uint32_t link_period : 3; /**< Beacon period (0.5 - 8 Hz). */ + bool is_pairing_enabled : 1; /**< Pairing is enabled/disabled. */ + bool is_upload_enabled : 1; /**< Upload is enabled/disabled. */ + bool is_data_available : 1; /**< Data is available for download / no data available. */ + bool reserved : 2; /**< Reserved. */ + } parameters; +} antfs_beacon_status_byte1_t; + +// ANT-FS states. +typedef enum +{ + ANTFS_STATE_OFF, /**< Off state. */ + ANTFS_STATE_INIT, /**< Init state. */ + ANTFS_STATE_LINK, /**< Link state. */ + ANTFS_STATE_AUTH, /**< Authenticate state. */ + ANTFS_STATE_TRANS /**< Transport state. */ +} antfs_state_t; + +// ANT-FS link layer substates. +typedef enum +{ + ANTFS_LINK_SUBSTATE_NONE /**< None state. */ +} antfs_link_substate_t; + +// ANT-FS authenticate layer substates. */ +typedef enum +{ + ANTFS_AUTH_SUBSTATE_NONE, /**< None state. */ + ANTFS_AUTH_SUBSTATE_PAIR, /**< Pairing state. */ + ANTFS_AUTH_SUBSTATE_PASSKEY, /**< Passkey state. */ + ANTFS_AUTH_SUBSTATE_ACCEPT, /**< Authenticate accept state. */ + ANTFS_AUTH_SUBSTATE_REJECT /**< Authenticate reject state. */ +} antfs_authenticate_substate_t; + +// ANT-FS transport layer substates. */ +typedef enum +{ + ANTFS_TRANS_SUBSTATE_NONE, /**< None state. */ + ANTFS_TRANS_SUBSTATE_VERIFY_CRC, /**< Verify CRC state. */ + ANTFS_TRANS_SUBSTATE_DOWNLOADING, /**< Downloading state. */ + ANTFS_TRANS_SUBSTATE_UPLOAD_WAIT_FOR_DATA, /**< Wait for upload data request state. */ + ANTFS_TRANS_SUBSTATE_UPLOADING, /**< Ready / receiving upload data state. */ + ANTFS_TRANS_SUBSTATE_UPLOAD_RESUME /**< RX failure upon receiving upload data state. */ +} antfs_transport_substate_t; + +// ANT-FS Events. +typedef enum +{ + ANTFS_EVENT_PAIRING_REQUEST = 0xB0, /**< Pairing request event. */ + ANTFS_EVENT_PAIRING_TIMEOUT = 0xB1, /**< Pairing timeout event. */ + ANTFS_EVENT_OPEN_COMPLETE = 0xB2, /**< Channel setup complete event. */ + ANTFS_EVENT_CLOSE_COMPLETE = 0xB4, /**< Channel closed event. */ + ANTFS_EVENT_LINK = 0xB6, /**< Enter link layer event. */ + ANTFS_EVENT_AUTH = 0xB7, /**< Enter authenticate layer event. */ + ANTFS_EVENT_TRANS = 0xB8, /**< Enter transport layer event. */ + ANTFS_EVENT_DOWNLOAD_REQUEST = 0xB9, /**< Download request event. */ + ANTFS_EVENT_DOWNLOAD_REQUEST_DATA = 0xBA, /**< Download request data event. */ + ANTFS_EVENT_DOWNLOAD_START = 0xBB, /**< Download started event. */ + ANTFS_EVENT_DOWNLOAD_COMPLETE = 0xBC, /**< Download completed event. */ + ANTFS_EVENT_DOWNLOAD_FAIL = 0xBD, /**< Download failed event. */ + ANTFS_EVENT_UPLOAD_REQUEST = 0xBE, /**< Upload request event. */ + ANTFS_EVENT_UPLOAD_DATA = 0xBF, /**< Upload data available for read event. */ + ANTFS_EVENT_UPLOAD_START = 0xC0, /**< Upload begin event. */ + ANTFS_EVENT_UPLOAD_COMPLETE = 0xC1, /**< Upload completed event. */ + ANTFS_EVENT_UPLOAD_FAIL = 0xC2, /**< Upload process failed event. */ + ANTFS_EVENT_ERASE_REQUEST = 0xC3 /**< Erase request event. */ +} antfs_event_t; + +/**@brief ANT-FS <-> application event communication object. */ +typedef struct +{ + antfs_event_t event; /**< ANT-FS event. */ + uint16_t file_index; /**< File index (download/upload/erase). */ + uint32_t offset; /**< Current offset (download/upload). */ + uint32_t bytes; /**< Number of bytes in block (download/upload). */ + uint16_t crc; /**< Current CRC (upload). */ + uint8_t data[8]; /**< Block of data (upload). */ +} antfs_event_return_t; + +/**@brief ANT-FS parameters. */ +typedef struct +{ + uint32_t client_serial_number; /**< Client serial number. */ + uint16_t beacon_device_type; /**< Client device type. */ + uint16_t beacon_device_manufacturing_id; /**< Client manufacturing ID. */ + uint8_t beacon_frequency; /**< Beacon RF Frequency. */ + antfs_beacon_status_byte1_t beacon_status_byte1; /**< Beacon status byte 1. */ + const uint8_t * p_pass_key; /**< Pass Key. */ + const uint8_t * p_remote_friendly_name; /**< Friendly Name. */ +} antfs_params_t; + +/**@brief ANT-FS directory header. */ +typedef struct +{ + uint8_t version; /**< Version of the directory file structure. */ + uint8_t length; /**< Length of each structure, in bytes. */ + uint8_t time_format; /**< Defines how system keeps track of date/time stamps. */ + uint8_t reserved01; + uint8_t reserved02; + uint8_t reserved03; + uint8_t reserved04; + uint8_t reserved05; + uint32_t system_time; /**< Number of seconds elapsed since system power up. */ + uint32_t date; /**< Number of seconds elapsed since 00:00 hrs Dec 31, 1989. If system time is unknown, used as counter. */ +} antfs_dir_header_t; + +/**@brief ANT-FS directory entry. */ +typedef struct +{ + uint16_t data_file_index; /**< Data file index. */ + uint8_t file_data_type; /**< File data type. */ + uint8_t user_defined1; /**< Identifier, first byte (structure defined by data type). */ + uint16_t user_defined2; /**< Identifier, last two bytes (structure defined by data type). */ + uint8_t user_flags; /**< File data type specific flags (bits defined by data type). */ + uint8_t general_flags; /**< Bit mapped flags of flag permissions. */ + uint32_t file_size_in_bytes; /**< File size, in bytes. */ + uint32_t date; /**< Number of seconds elapsed since 00:00 hrs Dec 31, 1980, if supported. */ +} antfs_dir_struct_t; + +/**@brief ANT-FS download/upload request context. */ +typedef struct +{ + ulong_union_t file_size; /**< Size of a file to download when reading, or the size of a partially completed upload when writing. */ + uint32_t max_file_size; /**< The maximum size of the file specified, this is the file size when reading, and the maximum allowed file size when writing. */ + ulong_union_t max_burst_block_size; /**< Maximum burst block size. */ + ushort_union_t file_index; /**< File index. */ + uint16_t file_crc; /**< CRC (uploads). */ +} antfs_request_info_t; + +/**@brief The burst wait handler can be configured by the application to customize the code that is + * executed while waiting for the burst busy flag. */ +typedef void(*antfs_burst_wait_handler_t)(void); + +/**@brief Function for setting initial ANT-FS configuration parameters. + * + * @param[in] p_params The initial ANT-FS configuration parameters. + * @param[in] burst_wait_handler Burst wait handler. + */ +void antfs_init(const antfs_params_t * const p_params, + antfs_burst_wait_handler_t burst_wait_handler); + +/**@brief Function for getting host name if received. + * + * @return Pointer to host name buffer if a host name was recieved, NULL otherwise. + */ +const char * antfs_hostname_get(void); + +/**@brief Function for transmitting a response to a pairing request issued by ANT-FS host. + * + * @param[in] accept The pairing response, true if pairing accepted. + * + * @retval true Operation success. Response to a pairing request was transmitted. + * @retval false Operation failure. Not in pairing mode or pairing not supported by the + * implementation. + */ +bool antfs_pairing_resp_transmit(bool accept); + +/**@brief Function for doing calculations prior downloading the data to the ANT-FS host. + * + * Function does the necessary pre processing calculations, which are required prior downloading the + * data, and also transmits the download request response right away in case of the download request + * was rejected or there is no data to send. + * + * @param[in] response The download request response code. + * @param[in] p_request_info ANT-FS request info structure. + */ +void antfs_download_req_resp_prepare(uint8_t response, + const antfs_request_info_t * const p_request_info); + +/**@brief Function for downloading requested data. + * + * @param[in] index Index of the current file downloaded. + * @param[in] offset Offset specified by client. + * @param[in] num_bytes Number of bytes requested to be transmitted from the buffer. + * @param[in] p_message Data buffer to be transmitted. + * + * @return Number of data bytes transmitted. + */ +uint32_t antfs_input_data_download(uint16_t index, + uint32_t offset, + uint32_t num_bytes, + const uint8_t * const p_message); + +/**@brief Function for transmitting upload request response to a upload request command by ANT-FS + * host. + * + * @param[in] response The upload response code. + * @param[in] p_request_info ANT-FS request info structure. + * + * @retval true Operation success. Response to upload request command was transmitted. + * @retval false Operation failure. Upload not supported by the implementation or not in correct + * state or application is sending a response for a different file + * than requested. + */ +bool antfs_upload_req_resp_transmit(uint8_t response, + const antfs_request_info_t * const p_request_info); + +/**@brief Function for transmitting upload data response to a upload data command by ANT-FS host. + * + * @param[in] data_upload_success The upload response code, true for success. + * + * @retval true Operation success. Response to upload data command was transmitted. + * @retval false Operation failure. Upload not supported by the implementation or not in correct + * state. + */ +bool antfs_upload_data_resp_transmit(bool data_upload_success); + +/**@brief Function for transmitting erase response to a erase request. + * + * @param[in] response The erase response code. + */ +void antfs_erase_req_resp_transmit(uint8_t response); + +/**@brief Function for extracting possible pending ANT-FS event. + * + * @param[out] p_event The output event structure. + * + * @retval true Operation success. Pending ANT-FS event available and it was copied to the output + * event structure. + * @retval false Operation failure. No pending ANT-FS event available. + */ +bool antfs_event_extract(antfs_event_return_t * const p_event); + +/**@brief Function for processing ANT events and data received from the ANT-FS channel. + * + * @param[in] p_message The message buffer containing the message received from the ANT-FS + * channel. + */ +void antfs_message_process(uint8_t * p_message); + +/**@brief Function for setting up the ANT-FS channel. + */ +void antfs_channel_setup(void); + + +#ifdef __cplusplus +} +#endif + +#endif // ANTFS_H__ + +/** + *@} + **/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/crc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/crc.c new file mode 100644 index 0000000000000000000000000000000000000000..ee26d885a2a5faf85f586ec18fa7bcb1b4feedb1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/crc.c @@ -0,0 +1,98 @@ +/** + * This software is subject to the ANT+ Shared Source License + * www.thisisant.com/swlicenses + * Copyright (c) Dynastream Innovations, Inc. 2012 + * 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 Dynastream nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * The following actions are prohibited: + * 1) Redistribution of source code containing the ANT+ Network + * Key. The ANT+ Network Key is available to ANT+ Adopters. + * Please refer to http://thisisant.com to become an ANT+ + * Adopter and access the key. + * + * 2) Reverse engineering, decompilation, and/or disassembly of + * software provided in binary form under this license. + * + * 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 HEREBY + * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW + * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE + * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. + * + */ +#include "crc.h" +#include "compiler_abstraction.h" + + +/**@brief Function for updating the current CRC-16 value for a single byte input. + * + * @param[in] current_crc The current calculated CRC-16 value. + * @param[in] byte The input data byte for the computation. + * + * @return The updated CRC-16 value, based on the input supplied. + */ +static __INLINE uint16_t crc16_get(uint16_t current_crc, uint8_t byte) +{ + static const uint16_t crc16_table[16] = + { + 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, + 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 + }; + + uint16_t temp; + + // Compute checksum of lower four bits of a byte. + temp = crc16_table[current_crc & 0xF]; + current_crc = (current_crc >> 4u) & 0x0FFFu; + current_crc = current_crc ^ temp ^ crc16_table[byte & 0xF]; + + // Now compute checksum of upper four bits of a byte. + temp = crc16_table[current_crc & 0xF]; + current_crc = (current_crc >> 4u) & 0x0FFFu; + current_crc = current_crc ^ temp ^ crc16_table[(byte >> 4u) & 0xF]; + + return current_crc; +} + + +uint16_t crc_crc16_update(uint16_t current_crc, const volatile void * p_data, uint32_t size) +{ + uint8_t * p_block = (uint8_t *)p_data; + + while (size != 0) + { + current_crc = crc16_get(current_crc, *p_block); + p_block++; + size--; + } + + return current_crc; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/crc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/crc.h new file mode 100644 index 0000000000000000000000000000000000000000..dffa5ada23e4bec990d9dae73cc66d5b72527366 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/crc.h @@ -0,0 +1,94 @@ +/** + * This software is subject to the ANT+ Shared Source License + * www.thisisant.com/swlicenses + * Copyright (c) Dynastream Innovations, Inc. 2012 + * 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 Dynastream nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * The following actions are prohibited: + * 1) Redistribution of source code containing the ANT+ Network + * Key. The ANT+ Network Key is available to ANT+ Adopters. + * Please refer to http://thisisant.com to become an ANT+ + * Adopter and access the key. + * + * 2) Reverse engineering, decompilation, and/or disassembly of + * software provided in binary form under this license. + * + * 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 HEREBY + * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW + * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE + * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. + * + */ +/** @file + * @brief The CRC-16 interface. + * This file is based on implementation originally made by Dynastream Innovations Inc. - August 2012 + * @defgroup ant_fs_client_main ANT-FS client device simulator + * @{ + * @ingroup ant_fs + * + * @brief The ANT-FS client device simulator. + * + */ + +#ifndef CRC_H__ +#define CRC_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Function for calculating CRC-16 in blocks. + * + * Feed each consecutive data block into this function, along with the current value of current_crc + * as returned by the previous call of this function. The first call of this function should pass + * the initial value (usually 0) of the crc in current_crc. + + * @param[in] current_crc The current calculated CRC-16 value. + * @param[in] p_data The input data block for computation. + * @param[in] size The size of the input data block in bytes. + * + * @return The updated CRC-16 value, based on the input supplied. + */ +uint16_t crc_crc16_update(uint16_t current_crc, const volatile void * p_data, uint32_t size); + + +#ifdef __cplusplus +} +#endif + +#endif // CRC_H__ + +/** + *@} + **/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/defines.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/defines.h new file mode 100644 index 0000000000000000000000000000000000000000..266de5c706b8f521a07f7039793fab4709014c0e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_fs/defines.h @@ -0,0 +1,109 @@ +/** + * This software is subject to the ANT+ Shared Source License + * www.thisisant.com/swlicenses + * Copyright (c) Dynastream Innovations, Inc. 2012 + * 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 Dynastream nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * The following actions are prohibited: + * 1) Redistribution of source code containing the ANT+ Network + * Key. The ANT+ Network Key is available to ANT+ Adopters. + * Please refer to http://thisisant.com to become an ANT+ + * Adopter and access the key. + * + * 2) Reverse engineering, decompilation, and/or disassembly of + * software provided in binary form under this license. + * + * 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 HEREBY + * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW + * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE + * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. + * + */ +/**@file + * @brief Definitions. + * This file is based on implementation originally made by Dynastream Innovations Inc. - August 2012 + * @defgroup ant_fs_client_main ANT-FS client device simulator + * @{ + * @ingroup nrf_ant_fs_client + * + * @brief The ANT-FS client device simulator. + * + */ + +#ifndef DEFINES_H__ +#define DEFINES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_ULONG 0xFFFFFFFFu /**< The Max value for the type. */ + +/**@brief uint16_t type presentation as an union. */ +typedef union +{ + uint16_t data; /**< The data content. */ + + struct + { + uint8_t low; /**< The low byte of the data content. */ + uint8_t high; /**< The high byte of the data content. */ + } bytes; +} ushort_union_t; + +/**@brief uint32_t type presentation as an union. */ +typedef union +{ + uint32_t data; /**< The data content as a single variable. */ + uint8_t data_bytes[sizeof(uint32_t)]; /**< The data content as a byte array. */ + + struct + { + // The least significant byte of the uint32_t in this structure is referenced by byte0. + uint8_t byte0; /**< Byte 0 of the data content. */ + uint8_t byte1; /**< Byte 1 of the data content. */ + uint8_t byte2; /**< Byte 2 of the data content. */ + uint8_t byte3; /**< Byte 3 of the data content. */ + } bytes; +} ulong_union_t; + +#ifdef __cplusplus +} +#endif + +#endif // DEFINES_H__ + +/** + *@} + **/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_key_manager/ant_key_manager.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_key_manager/ant_key_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..6dd254b0886ec3803a9be8e1f24775309f804cf8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_key_manager/ant_key_manager.c @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_KEY_MANAGER) +#include +#include "ant_key_manager.h" +#include "ant_key_manager_config.h" +#include "ant_interface.h" +#include "nrf_assert.h" + +static uint8_t m_ant_plus_network_key[] = ANT_PLUS_NETWORK_KEY; +static uint8_t m_ant_fs_network_key[] = ANT_FS_NETWORK_KEY; + +uint32_t ant_custom_key_set(uint8_t network_number, uint8_t * network_key) +{ + ASSERT(network_key != NULL); + return sd_ant_network_address_set(network_number, network_key); +} + +uint32_t ant_plus_key_set(uint8_t network_number) +{ + return sd_ant_network_address_set(network_number, m_ant_plus_network_key); +} + +uint32_t ant_fs_key_set(uint8_t network_number) +{ + return sd_ant_network_address_set(network_number, m_ant_fs_network_key); +} + +#endif // NRF_MODULE_ENABLED(ANT_KEY_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_key_manager/ant_key_manager.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_key_manager/ant_key_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..b763425d06f0180d3884dec05a62868c25666953 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_key_manager/ant_key_manager.h @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_KEY_MANAGER_H__ +#define ANT_KEY_MANAGER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + */ +/** + * @defgroup ant_key_manager ANT key manager + * @{ + * @ingroup ant_sdk_utils + * @brief Module for registering common and custom ANT network keys. + */ + +/**@brief Function for registering a custom network key. + * + * @param[in] network_number Network key number. + * @param[in] p_network_key Pointer to the custom ANT network key. + * + * @return A SoftDevice error code. + */ +uint32_t ant_custom_key_set(uint8_t network_number, uint8_t * p_network_key); + +/**@brief Function for registering an ANT+ network key. + * + * The key must be defined by @ref ANT_PLUS_NETWORK_KEY. + * + * @note The ANT+ Network Key is available for ANT+ Adopters. Go to http://thisisant.com + * to become an ANT+ Adopter and access the key. + * + * @param[in] network_number Network key number. + * + * @return A SoftDevice error code. + */ +uint32_t ant_plus_key_set(uint8_t network_number); + +/**@brief Function for registering an ANT-FS network key. + * + * The key must be defined by @ref ANT_FS_NETWORK_KEY. + * + * @note The ANT+ Network Key is available for ANT+ Adopters. Go to http://thisisant.com + * to become an ANT+ Adopter and access the key. + * + * @param[in] network_number Network key number. + * + * @return A SoftDevice error code. + */ +uint32_t ant_fs_key_set(uint8_t network_number); + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_KEY_MANAGER_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_key_manager/config/ant_key_manager_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_key_manager/config/ant_key_manager_config.h new file mode 100644 index 0000000000000000000000000000000000000000..0f7a0d5a91f2d873a25a039d0ec05a6612a4e5b7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_key_manager/config/ant_key_manager_config.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_KEY_MANAGER_CONFIG_H__ +#define ANT_KEY_MANAGER_CONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup ant_key_manager + * @{ + */ + +#ifndef ANT_PLUS_NETWORK_KEY + #define ANT_PLUS_NETWORK_KEY {0, 0, 0, 0, 0, 0, 0, 0} /**< The ANT+ network key. */ +#endif //ANT_PLUS_NETWORK_KEY + +#ifndef ANT_FS_NETWORK_KEY + #define ANT_FS_NETWORK_KEY {0, 0, 0, 0, 0, 0, 0, 0} /**< The ANT-FS network key. */ +#endif // ANT_FS_NETWORK_KEY + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_KEY_MANAGER_CONFIG_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/ant_bpwr.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/ant_bpwr.c new file mode 100644 index 0000000000000000000000000000000000000000..d4b956db138c8c11c03437c1dd6623ecd4ae6a94 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/ant_bpwr.c @@ -0,0 +1,491 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + +#include "nrf_assert.h" +#include "app_error.h" +#include "ant_interface.h" +#include "ant_bpwr.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR" +#if ANT_BPWR_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_INFO_COLOR +#else // ANT_BPWR_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_LOG_ENABLED +#include "nrf_log.h" + +#define BPWR_CALIB_INT_TIMEOUT ((ANT_CLOCK_FREQUENCY * BPWR_CALIBRATION_TIMOUT_S) / BPWR_MSG_PERIOD) // calibration timeout in ant message period's unit + +// for torque sensor Minimum: Interleave every 9th message +#define BPWR_PAGE_16_INTERVAL 5 // Preferred: Interleave every 5th message +#define BPWR_PAGE_16_INTERVAL_OFS 2 // Permissible offset +#define COMMON_PAGE_80_INTERVAL 119 // Minimum: Interleave every 121 messages +#define COMMON_PAGE_81_INTERVAL 120 // Minimum: Interleave every 121 messages +#define AUTO_ZERO_SUPPORT_INTERVAL 120 // Minimum: Interleave every 121 messages + +/**@brief Bicycle power message data layout structure. */ +typedef struct +{ + uint8_t page_number; + uint8_t page_payload[7]; +} ant_bpwr_message_layout_t; + + +/**@brief Function for initializing the ANT Bicycle Power Profile instance. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_channel_config Pointer to the ANT channel configuration structure. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. + */ +static ret_code_t ant_bpwr_init(ant_bpwr_profile_t * p_profile, + ant_channel_config_t const * p_channel_config) +{ + p_profile->channel_number = p_channel_config->channel_number; + + p_profile->page_1 = DEFAULT_ANT_BPWR_PAGE1(); + p_profile->page_16 = DEFAULT_ANT_BPWR_PAGE16(); + p_profile->page_17 = DEFAULT_ANT_BPWR_PAGE17(); + p_profile->page_18 = DEFAULT_ANT_BPWR_PAGE18(); + p_profile->page_80 = DEFAULT_ANT_COMMON_page80(); + p_profile->page_81 = DEFAULT_ANT_COMMON_page81(); + + NRF_LOG_INFO("ANT B-PWR channel %u init\r\n", p_profile->channel_number); + return ant_channel_init(p_channel_config); +} + + +ret_code_t ant_bpwr_disp_init(ant_bpwr_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_bpwr_disp_config_t const * p_disp_config) +{ + ASSERT(p_profile != NULL); + ASSERT(p_channel_config != NULL); + ASSERT(p_disp_config != NULL); + ASSERT(p_disp_config->evt_handler != NULL); + ASSERT(p_disp_config->p_cb != NULL); + + p_profile->evt_handler = p_disp_config->evt_handler; + p_profile->_cb.p_disp_cb = p_disp_config->p_cb; + + p_profile->_cb.p_disp_cb ->calib_timeout = 0; + p_profile->_cb.p_disp_cb ->calib_stat = BPWR_DISP_CALIB_NONE; + + return ant_bpwr_init(p_profile, p_channel_config); +} + + +ret_code_t ant_bpwr_sens_init(ant_bpwr_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_bpwr_sens_config_t const * p_sens_config) +{ + ASSERT(p_profile != NULL); + ASSERT(p_channel_config != NULL); + ASSERT(p_sens_config != NULL); + ASSERT(p_sens_config->p_cb != NULL); + ASSERT(p_sens_config->evt_handler != NULL); + ASSERT(p_sens_config->calib_handler != NULL); + + p_profile->evt_handler = p_sens_config->evt_handler; + p_profile->_cb.p_sens_cb = p_sens_config->p_cb; + + p_profile->_cb.p_sens_cb->torque_use = p_sens_config->torque_use; + p_profile->_cb.p_sens_cb->calib_handler = p_sens_config->calib_handler; + p_profile->_cb.p_sens_cb->calib_stat = BPWR_SENS_CALIB_NONE; + p_profile->_cb.p_sens_cb->message_counter = 0; + + return ant_bpwr_init(p_profile, p_channel_config); +} + + + +/**@brief Function for getting next page number to send. + * + * @param[in] p_profile Pointer to the profile instance. + * + * @return Next page number. + */ +static ant_bpwr_page_t next_page_number_get(ant_bpwr_profile_t * p_profile) +{ + ant_bpwr_sens_cb_t * p_bpwr_cb = p_profile->_cb.p_sens_cb; + ant_bpwr_page_t page_number; + + if (p_bpwr_cb->calib_stat == BPWR_SENS_CALIB_READY) + { + page_number = ANT_BPWR_PAGE_1; + p_bpwr_cb->calib_stat = BPWR_SENS_CALIB_NONE; // mark event as processed + } + else if ((p_profile->BPWR_PROFILE_auto_zero_status != ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED) + && (p_bpwr_cb->message_counter == AUTO_ZERO_SUPPORT_INTERVAL)) + { + page_number = ANT_BPWR_PAGE_1; + p_profile->BPWR_PROFILE_calibration_id = ANT_BPWR_CALIB_ID_AUTO_SUPPORT; + p_bpwr_cb->message_counter++; + } + else if (p_bpwr_cb->message_counter >= COMMON_PAGE_81_INTERVAL) + { + page_number = ANT_BPWR_PAGE_81; + p_bpwr_cb->message_counter = 0; + } + else + { + if (p_bpwr_cb->message_counter == COMMON_PAGE_80_INTERVAL) + { + page_number = ANT_BPWR_PAGE_80; + } + else + { + if ( p_bpwr_cb->torque_use == TORQUE_NONE) + { + page_number = ANT_BPWR_PAGE_16; + } + else if ((p_bpwr_cb->message_counter % BPWR_PAGE_16_INTERVAL) + == BPWR_PAGE_16_INTERVAL_OFS) + { + page_number = ANT_BPWR_PAGE_16; + } + else if ( p_bpwr_cb->torque_use == TORQUE_WHEEL) + { + page_number = ANT_BPWR_PAGE_17; + } + else // assumed TORQUE_CRANK + { + page_number = ANT_BPWR_PAGE_18; + } + } + p_bpwr_cb->message_counter++; + } + + return page_number; +} + + +/**@brief Function for encoding Bicycle Power Sensor message. + * + * @note Assume to be call each time when Tx window will occur. + */ +static void sens_message_encode(ant_bpwr_profile_t * p_profile, uint8_t * p_message_payload) +{ + ant_bpwr_message_layout_t * p_bpwr_message_payload = + (ant_bpwr_message_layout_t *)p_message_payload; + + p_bpwr_message_payload->page_number = next_page_number_get(p_profile); + + NRF_LOG_INFO("B-PWR tx page: %u\r\n", p_bpwr_message_payload->page_number); + + switch (p_bpwr_message_payload->page_number) + { + case ANT_BPWR_PAGE_1: + ant_bpwr_page_1_encode(p_bpwr_message_payload->page_payload, &(p_profile->page_1)); + break; + + case ANT_BPWR_PAGE_16: + ant_bpwr_page_16_encode(p_bpwr_message_payload->page_payload, &(p_profile->page_16)); + ant_bpwr_cadence_encode(p_bpwr_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_BPWR_PAGE_17: + ant_bpwr_page_17_encode(p_bpwr_message_payload->page_payload, &(p_profile->page_17)); + ant_bpwr_cadence_encode(p_bpwr_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_BPWR_PAGE_18: + ant_bpwr_page_18_encode(p_bpwr_message_payload->page_payload, &(p_profile->page_18)); + ant_bpwr_cadence_encode(p_bpwr_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_COMMON_PAGE_80: + ant_common_page_80_encode(p_bpwr_message_payload->page_payload, &(p_profile->page_80)); + break; + + case ANT_COMMON_PAGE_81: + ant_common_page_81_encode(p_bpwr_message_payload->page_payload, &(p_profile->page_81)); + break; + + default: + return; + } + + p_profile->evt_handler(p_profile, (ant_bpwr_evt_t)p_bpwr_message_payload->page_number); + +} + + +/**@brief Function for decoding messages received by Bicycle Power sensor message. + * + * @note Assume to be call each time when Rx window will occur. + */ +static void sens_message_decode(ant_bpwr_profile_t * p_profile, uint8_t * p_message_payload) +{ + const ant_bpwr_message_layout_t * p_bpwr_message_payload = + (ant_bpwr_message_layout_t *)p_message_payload; + ant_bpwr_page1_data_t page1; + + switch (p_bpwr_message_payload->page_number) + { + case ANT_BPWR_PAGE_1: + ant_bpwr_page_1_decode(p_bpwr_message_payload->page_payload, &page1); + p_profile->_cb.p_sens_cb->calib_stat = BPWR_SENS_CALIB_REQUESTED; + p_profile->_cb.p_sens_cb->calib_handler(p_profile, &page1); + break; + + default: + break; + } +} + + +/**@brief Function for decoding messages received by Bicycle Power display message. + * + * @note Assume to be call each time when Rx window will occur. + */ +static void disp_message_decode(ant_bpwr_profile_t * p_profile, uint8_t * p_message_payload) +{ + const ant_bpwr_message_layout_t * p_bpwr_message_payload = + (ant_bpwr_message_layout_t *)p_message_payload; + + NRF_LOG_INFO("B-PWR rx page: %u\r\n", p_bpwr_message_payload->page_number); + + switch (p_bpwr_message_payload->page_number) + { + case ANT_BPWR_PAGE_1: + ant_bpwr_page_1_decode(p_bpwr_message_payload->page_payload, &(p_profile->page_1)); + p_profile->_cb.p_disp_cb->calib_stat = BPWR_DISP_CALIB_NONE; + break; + + case ANT_BPWR_PAGE_16: + ant_bpwr_page_16_decode(p_bpwr_message_payload->page_payload, &(p_profile->page_16)); + ant_bpwr_cadence_decode(p_bpwr_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_BPWR_PAGE_17: + ant_bpwr_page_17_decode(p_bpwr_message_payload->page_payload, &(p_profile->page_17)); + ant_bpwr_cadence_decode(p_bpwr_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_BPWR_PAGE_18: + ant_bpwr_page_18_decode(p_bpwr_message_payload->page_payload, &(p_profile->page_18)); + ant_bpwr_cadence_decode(p_bpwr_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_COMMON_PAGE_80: + ant_common_page_80_decode(p_bpwr_message_payload->page_payload, &(p_profile->page_80)); + break; + + case ANT_COMMON_PAGE_81: + ant_common_page_81_decode(p_bpwr_message_payload->page_payload, &(p_profile->page_81)); + break; + + default: + return; + } + + p_profile->evt_handler(p_profile, (ant_bpwr_evt_t)p_bpwr_message_payload->page_number); +} + + +ret_code_t ant_bpwr_calib_request(ant_bpwr_profile_t * p_profile, ant_bpwr_page1_data_t * p_page_1) +{ + ant_bpwr_message_layout_t bpwr_message_payload; + + if (p_profile->_cb.p_disp_cb->calib_stat == BPWR_DISP_CALIB_REQUESTED) + { + return NRF_SUCCESS; // calibration in progress, so omit this request + } + + bpwr_message_payload.page_number = ANT_BPWR_PAGE_1; + ant_bpwr_page_1_encode(bpwr_message_payload.page_payload, p_page_1); + + uint32_t err_code = sd_ant_acknowledge_message_tx(p_profile->channel_number, + sizeof (bpwr_message_payload), + (uint8_t *) &bpwr_message_payload); + + if (err_code == NRF_SUCCESS) + { + p_profile->_cb.p_disp_cb->calib_timeout = BPWR_CALIB_INT_TIMEOUT; // initialize watch on calibration's time-out + p_profile->_cb.p_disp_cb->calib_stat = BPWR_DISP_CALIB_REQUESTED; + NRF_LOG_INFO("Start calibration process\r\n"); + } + return err_code; +} + + +void ant_bpwr_calib_response(ant_bpwr_profile_t * p_profile) +{ + if (p_profile->_cb.p_sens_cb->calib_stat != BPWR_SENS_CALIB_READY) // abort if callback request is in progress + { + p_profile->_cb.p_sens_cb->calib_stat = BPWR_SENS_CALIB_READY; // calibration respond + } +} + + +/**@brief Function for hangling calibration events. + */ +static void service_calib(ant_bpwr_profile_t * p_profile, uint8_t event) +{ + ant_bpwr_evt_t bpwr_event; + + if (p_profile->_cb.p_disp_cb->calib_stat == BPWR_DISP_CALIB_REQUESTED) + { + switch (event) + { + case EVENT_RX: + /* fall through */ + case EVENT_RX_FAIL: + + if (p_profile->_cb.p_disp_cb->calib_timeout-- == 0) + { + bpwr_event = ANT_BPWR_CALIB_TIMEOUT; + break; + } + else + { + return; + } + + case EVENT_TRANSFER_TX_FAILED: + bpwr_event = ANT_BPWR_CALIB_REQUEST_TX_FAILED; + break; + + case EVENT_RX_SEARCH_TIMEOUT: + bpwr_event = ANT_BPWR_CALIB_TIMEOUT; + break; + + default: + return; + } + + NRF_LOG_INFO("End calibration process\r\n"); + p_profile->_cb.p_disp_cb->calib_stat = BPWR_DISP_CALIB_NONE; + + p_profile->evt_handler(p_profile, bpwr_event); + } +} + + +static void ant_message_send(ant_bpwr_profile_t * p_profile) +{ + uint32_t err_code; + uint8_t p_message_payload[ANT_STANDARD_DATA_PAYLOAD_SIZE]; + + sens_message_encode(p_profile, p_message_payload); + err_code = + sd_ant_broadcast_message_tx(p_profile->channel_number, + sizeof (p_message_payload), + p_message_payload); + APP_ERROR_CHECK(err_code); +} + + +ret_code_t ant_bpwr_disp_open(ant_bpwr_profile_t * p_profile) +{ + NRF_LOG_INFO("ANT B-PWR %u open\r\n", p_profile->channel_number); + return sd_ant_channel_open(p_profile->channel_number); +} + + +ret_code_t ant_bpwr_sens_open(ant_bpwr_profile_t * p_profile) +{ + // Fill tx buffer for the first frame + ant_message_send(p_profile); + + NRF_LOG_INFO("ANT B-PWR %u open\r\n", p_profile->channel_number); + return sd_ant_channel_open(p_profile->channel_number); +} + + +void ant_bpwr_sens_evt_handler(ant_bpwr_profile_t * p_profile, ant_evt_t * p_ant_event) +{ + if (p_ant_event->channel == p_profile->channel_number) + { + ANT_MESSAGE * p_message; + + switch (p_ant_event->event) + { + case EVENT_TX: + ant_message_send(p_profile); + break; + + case EVENT_RX: + p_message = (ANT_MESSAGE *)p_ant_event->msg.evt_buffer; + + if (p_message->ANT_MESSAGE_ucMesgID == MESG_ACKNOWLEDGED_DATA_ID) + { + sens_message_decode(p_profile, p_message->ANT_MESSAGE_aucPayload); + } + break; + + default: + // No implementation needed + break; + } + } +} + + +void ant_bpwr_disp_evt_handler(ant_bpwr_profile_t * p_profile, ant_evt_t * p_ant_event) +{ + if (p_ant_event->channel == p_profile->channel_number) + { + ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->msg.evt_buffer; + + switch (p_ant_event->event) + { + case EVENT_RX: + + if (p_message->ANT_MESSAGE_ucMesgID == MESG_BROADCAST_DATA_ID + || p_message->ANT_MESSAGE_ucMesgID == MESG_ACKNOWLEDGED_DATA_ID + || p_message->ANT_MESSAGE_ucMesgID == MESG_BURST_DATA_ID) + { + disp_message_decode(p_profile, p_message->ANT_MESSAGE_aucPayload); + } + break; + + default: + break; + } + service_calib(p_profile, p_ant_event->event); + } +} + +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/ant_bpwr.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/ant_bpwr.h new file mode 100644 index 0000000000000000000000000000000000000000..791cc31bb78a89ba4e7c843f23bdf5d02137c292 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/ant_bpwr.h @@ -0,0 +1,374 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @defgroup ant_bpwr Bicycle Power profile + * @{ + * @ingroup ant_sdk_profiles + * @brief This module implements the Bicycle Power profile. + * + */ + + #ifndef ANT_BICYCLE_POWER_H__ + #define ANT_BICYCLE_POWER_H__ + +#include +#include +#include "ant_parameters.h" +#include "ant_stack_handler_types.h" +#include "ant_channel_config.h" +#include "ant_bpwr_pages.h" +#include "sdk_errors.h" + +#define BPWR_DEVICE_TYPE 0x0Bu ///< Device type reserved for ANT+ Bicycle Power. +#define BPWR_ANTPLUS_RF_FREQ 0x39u ///< Frequency, decimal 57 (2457 MHz). +#define BPWR_MSG_PERIOD 8182u ///< Message period, decimal 8182 (4.0049 Hz). + +#define BPWR_EXT_ASSIGN 0x00 ///< ANT ext assign (see Ext. Assign Channel Parameters in ant_parameters.h: @ref ant_parameters). +#define BPWR_DISP_CHANNEL_TYPE CHANNEL_TYPE_SLAVE ///< Display Bicycle Power channel type. +#define BPWR_SENS_CHANNEL_TYPE CHANNEL_TYPE_MASTER ///< Sensor Bicycle Power channel type. + +#define BPWR_CALIBRATION_TIMOUT_S 5u ///< Time-out for responding to calibration callback (s). + +/**@brief Initialize an ANT channel configuration structure for the Bicycle Power profile (Display). + * + * @param[in] NAME Name of related instance. + * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance. + * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance. + * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance. + * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance. + */ +#define BPWR_DISP_CHANNEL_CONFIG_DEF(NAME, \ + CHANNEL_NUMBER, \ + TRANSMISSION_TYPE, \ + DEVICE_NUMBER, \ + NETWORK_NUMBER) \ +static const ant_channel_config_t NAME##_channel_bpwr_disp_config = \ + { \ + .channel_number = (CHANNEL_NUMBER), \ + .channel_type = BPWR_DISP_CHANNEL_TYPE, \ + .ext_assign = BPWR_EXT_ASSIGN, \ + .rf_freq = BPWR_ANTPLUS_RF_FREQ, \ + .transmission_type = (TRANSMISSION_TYPE), \ + .device_type = BPWR_DEVICE_TYPE, \ + .device_number = (DEVICE_NUMBER), \ + .channel_period = BPWR_MSG_PERIOD, \ + .network_number = (NETWORK_NUMBER), \ + } +#define BPWR_DISP_CHANNEL_CONFIG(NAME) &NAME##_channel_bpwr_disp_config + +/**@brief Initialize an ANT channel configuration structure for the Bicycle Power profile (Sensor). + * + * @param[in] NAME Name of related instance. + * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance. + * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance. + * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance. + * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance. + */ +#define BPWR_SENS_CHANNEL_CONFIG_DEF(NAME, \ + CHANNEL_NUMBER, \ + TRANSMISSION_TYPE, \ + DEVICE_NUMBER, \ + NETWORK_NUMBER) \ +static const ant_channel_config_t NAME##_channel_bpwr_sens_config = \ + { \ + .channel_number = (CHANNEL_NUMBER), \ + .channel_type = BPWR_SENS_CHANNEL_TYPE, \ + .ext_assign = BPWR_EXT_ASSIGN, \ + .rf_freq = BPWR_ANTPLUS_RF_FREQ, \ + .transmission_type = (TRANSMISSION_TYPE), \ + .device_type = BPWR_DEVICE_TYPE, \ + .device_number = (DEVICE_NUMBER), \ + .channel_period = BPWR_MSG_PERIOD, \ + .network_number = (NETWORK_NUMBER), \ + } +#define BPWR_SENS_CHANNEL_CONFIG(NAME) &NAME##_channel_bpwr_sens_config + +/**@brief Initialize an ANT profile configuration structure for the BPWR profile (Display). + * + * @param[in] NAME Name of related instance. + * @param[in] EVT_HANDLER Event handler to be called for handling events in the BPWR profile. + */ +#define BPWR_DISP_PROFILE_CONFIG_DEF(NAME, \ + EVT_HANDLER) \ +static ant_bpwr_disp_cb_t NAME##_bpwr_disp_cb; \ +static const ant_bpwr_disp_config_t NAME##_profile_bpwr_disp_config = \ + { \ + .p_cb = &NAME##_bpwr_disp_cb, \ + .evt_handler = (EVT_HANDLER), \ + } +#define BPWR_DISP_PROFILE_CONFIG(NAME) &NAME##_profile_bpwr_disp_config + +/**@brief Initialize an ANT profile configuration structure for the BPWR profile (Sensor). + * + * @param[in] NAME Name of related instance. + * @param[in] TORQUE_USED Determines whether the torque page is included. + * @param[in] CALIB_HANDLER Event handler to be called for handling calibration requests. + * @param[in] EVT_HANDLER Event handler to be called for handling events in the BPWR profile. + */ +#define BPWR_SENS_PROFILE_CONFIG_DEF(NAME, \ + TORQUE_USED, \ + CALIB_HANDLER, \ + EVT_HANDLER) \ +static ant_bpwr_sens_cb_t NAME##_bpwr_sens_cb; \ +static const ant_bpwr_sens_config_t NAME##_profile_bpwr_sens_config = \ + { \ + .torque_use = (TORQUE_USED), \ + .calib_handler = (CALIB_HANDLER), \ + .p_cb = &NAME##_bpwr_sens_cb, \ + .evt_handler = (EVT_HANDLER), \ + } +#define BPWR_SENS_PROFILE_CONFIG(NAME) &NAME##_profile_bpwr_sens_config + +/**@brief Configuration values for the Bicycle Power torque page. */ +typedef enum +{ + TORQUE_NONE = 0, + TORQUE_WHEEL = 1, + TORQUE_CRANK = 2, +} ant_bpwr_torque_t; + +/**@brief Bicycle Power page number type. */ +typedef enum +{ + ANT_BPWR_PAGE_1 = 1, ///< Calibration data page. + ANT_BPWR_PAGE_16 = 16, ///< Standard power-only main data page. + ANT_BPWR_PAGE_17 = 17, ///< Standard wheel torque main data page. + ANT_BPWR_PAGE_18 = 18, ///< Standard crank torque main data page. + ANT_BPWR_PAGE_80 = ANT_COMMON_PAGE_80, + ANT_BPWR_PAGE_81 = ANT_COMMON_PAGE_81 +} ant_bpwr_page_t; + +/**@brief BPWR profile event type. */ +typedef enum +{ + ANT_BPWR_PAGE_1_UPDATED = ANT_BPWR_PAGE_1, ///< Data page 1 and speed have been updated (Display) or sent (Sensor). + ANT_BPWR_PAGE_16_UPDATED = ANT_BPWR_PAGE_16, ///< Data page 16 and speed have been updated (Display) or sent (Sensor). + ANT_BPWR_PAGE_17_UPDATED = ANT_BPWR_PAGE_17, ///< Data page 17 and speed have been updated (Display) or sent (Sensor). + ANT_BPWR_PAGE_18_UPDATED = ANT_BPWR_PAGE_18, ///< Data page 18 has been updated (Display) or sent (Sensor). + ANT_BPWR_PAGE_80_UPDATED = ANT_BPWR_PAGE_80, ///< Data page 80 has been updated (Display) or sent (Sensor). + ANT_BPWR_PAGE_81_UPDATED = ANT_BPWR_PAGE_81, ///< Data page 81 has been updated (Display) or sent (Sensor). + ANT_BPWR_CALIB_TIMEOUT, ///< Request of calibration time-out occurred (Display). + ANT_BPWR_CALIB_REQUEST_TX_FAILED, ///< Calibration request did not reach the destination (Display). +} ant_bpwr_evt_t; + +// Forward declaration of the ant_bpwr_profile_t type. +typedef struct ant_bpwr_profile_s ant_bpwr_profile_t; + +/**@brief BPWR event handler type. */ +typedef void (* ant_bpwr_evt_handler_t) (ant_bpwr_profile_t *, ant_bpwr_evt_t); + +/**@brief BPWR Sensor calibration request handler type. */ +typedef void (* ant_bpwr_calib_handler_t) (ant_bpwr_profile_t *, ant_bpwr_page1_data_t *); + +#include "ant_bpwr_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Bicycle Power Sensor configuration structure. */ +typedef struct +{ + ant_bpwr_torque_t torque_use; ///< Determines whether the torque page is included. + ant_bpwr_sens_cb_t * p_cb; ///< Pointer to the data buffer for internal use. + ant_bpwr_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the BPWR profile. + ant_bpwr_calib_handler_t calib_handler; ///< Event handler to be called for handling calibration requests. +} ant_bpwr_sens_config_t; + +/**@brief Bicycle Power Display configuration structure. */ +typedef struct +{ + ant_bpwr_disp_cb_t * p_cb; ///< Pointer to the data buffer for internal use. + ant_bpwr_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the BPWR profile. +} ant_bpwr_disp_config_t; + +/**@brief Bicycle Power profile structure. */ +struct ant_bpwr_profile_s +{ + uint8_t channel_number; ///< Channel number assigned to the profile. + union { + ant_bpwr_disp_cb_t * p_disp_cb; + ant_bpwr_sens_cb_t * p_sens_cb; + } _cb; ///< Pointer to internal control block. + ant_bpwr_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the BPWR profile. + ant_bpwr_page1_data_t page_1; ///< Page 1. + ant_bpwr_page16_data_t page_16; ///< Page 16. + ant_bpwr_page17_data_t page_17; ///< Page 17. + ant_bpwr_page18_data_t page_18; ///< Page 18. + ant_common_page80_data_t page_80; ///< Page 80. + ant_common_page81_data_t page_81; ///< Page 81. + ant_bpwr_common_data_t common; ///< BPWR common data. +}; + +/** @name Defines for accessing ant_bpwr_profile_t member variables + @{ */ +#define BPWR_PROFILE_calibration_id page_1.calibration_id +#define BPWR_PROFILE_auto_zero_status page_1.auto_zero_status +#define BPWR_PROFILE_general_calib_data page_1.data.general_calib +#define BPWR_PROFILE_custom_calib_data page_1.data.custom_calib +#define BPWR_PROFILE_instantaneous_cadence common.instantaneous_cadence +#define BPWR_PROFILE_pedal_power page_16.pedal_power.items +#define BPWR_PROFILE_power_update_event_count page_16.update_event_count +#define BPWR_PROFILE_accumulated_power page_16.accumulated_power +#define BPWR_PROFILE_instantaneous_power page_16.instantaneous_power +#define BPWR_PROFILE_wheel_update_event_count page_17.update_event_count +#define BPWR_PROFILE_wheel_tick page_17.tick +#define BPWR_PROFILE_wheel_period page_17.period +#define BPWR_PROFILE_wheel_accumulated_torque page_17.accumulated_torque +#define BPWR_PROFILE_crank_update_event_count page_18.update_event_count +#define BPWR_PROFILE_crank_tick page_18.tick +#define BPWR_PROFILE_crank_period page_18.period +#define BPWR_PROFILE_crank_accumulated_torque page_18.accumulated_torque +#define BPWR_PROFILE_manuf_id page_80.manuf_id +#define BPWR_PROFILE_hw_revision page_80.hw_revision +#define BPWR_PROFILE_manufacturer_id page_80.manufacturer_id +#define BPWR_PROFILE_model_number page_80.model_number +#define BPWR_PROFILE_sw_revision_minor page_81.sw_revision_minor +#define BPWR_PROFILE_sw_revision_major page_81.sw_revision_major +#define BPWR_PROFILE_serial_number page_81.serial_number +/** @} */ + +/**@brief Function for initializing the ANT Bicycle Power Display profile instance. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_channel_config Pointer to the ANT channel configuration structure. + * @param[in] p_disp_config Pointer to the Bicycle Power Display configuration structure. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. + */ +ret_code_t ant_bpwr_disp_init(ant_bpwr_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_bpwr_disp_config_t const * p_disp_config); + +/**@brief Function for initializing the ANT Bicycle Power Sensor profile instance. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_channel_config Pointer to the ANT channel configuration structure. + * @param[in] p_sens_config Pointer to the Bicycle Power Sensor configuration structure. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. + */ +ret_code_t ant_bpwr_sens_init(ant_bpwr_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_bpwr_sens_config_t const * p_sens_config); + +/**@brief Function for opening the profile instance channel for ANT BPWR Display. + * + * Before calling this function, pages should be configured. + * + * @param[in] p_profile Pointer to the profile instance. + * + * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned. + */ +ret_code_t ant_bpwr_disp_open(ant_bpwr_profile_t * p_profile); + +/**@brief Function for opening the profile instance channel for ANT BPWR Sensor. + * + * Before calling this function, pages should be configured. + * + * @param[in] p_profile Pointer to the profile instance. + * + * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned. + */ +ret_code_t ant_bpwr_sens_open(ant_bpwr_profile_t * p_profile); + +/** @name Functions: Sensor calibration API + * @{ + */ + +/** @brief Function for initializing the response for a calibration request. + * + * This function should be used to signal the status of the calibration procedure to the ANT profile layer . + * + * @param[in] p_profile Pointer to the profile instance. + */ +void ant_bpwr_calib_response(ant_bpwr_profile_t * p_profile); +/** @} */ + + +/**@brief Function for handling the Sensor ANT events. + * + * @details This function handles all events from the ANT stack that are of interest to the Bicycle Power Display profile. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_ant_event Event received from the ANT stack. + */ +void ant_bpwr_sens_evt_handler(ant_bpwr_profile_t * p_profile, ant_evt_t * p_ant_event); + +/**@brief Function for handling the Display ANT events. + * + * @details This function handles all events from the ANT stack that are of interest to the Bicycle Power Display profile. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_ant_event Event received from the ANT stack. + */ +void ant_bpwr_disp_evt_handler(ant_bpwr_profile_t * p_profile, ant_evt_t * p_ant_event); + +/** @name Functions: Display calibration API + * @{ + */ + +/**@brief Function for initializing the calibration request process from the Bicycle Power Display side. + * + * @details This function requests a transfer to the Sensor and starts watching for the calibration response. + * If a calibration response has already been requested, the function ignores the new request and returns NRF_SUCCESS. + * + * @param [in] p_profile Pointer to the profile instance. + * @param [in] p_page_1 Pointer to the prepared page 1. + * + * @return Values returned by the @ref sd_ant_acknowledge_message_tx SVC callback. + */ +uint32_t ant_bpwr_calib_request(ant_bpwr_profile_t * p_profile, ant_bpwr_page1_data_t * p_page_1); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BICYCLE_POWER_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/ant_bpwr_local.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/ant_bpwr_local.h new file mode 100644 index 0000000000000000000000000000000000000000..1a7aab19b9ee75cb95d496b9739bc6a133b52330 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/ant_bpwr_local.h @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BPWR_LOCAL_H__ +#define ANT_BPWR_LOCAL_H__ + +#include +#include +#include "ant_bpwr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup ant_bpwr + * @{ + */ + +/** @brief Bicycle Power Sensor control block. */ +typedef struct +{ + uint8_t message_counter; + ant_bpwr_torque_t torque_use; + enum + { + BPWR_SENS_CALIB_NONE, ///< Idle state. + BPWR_SENS_CALIB_REQUESTED, ///< Received request for general calibration result message by the sensor. + BPWR_SENS_CALIB_READY, ///< Calibration response message is ready to be transmitted. + } calib_stat; + ant_bpwr_calib_handler_t calib_handler; +} ant_bpwr_sens_cb_t; + +/**@brief Bicycle Power Sensor RX control block. */ +typedef struct +{ + uint8_t calib_timeout; + enum + { + BPWR_DISP_CALIB_NONE, ///< Idle state. + BPWR_DISP_CALIB_REQUESTED, ///< Calibration requested. + } calib_stat; +} ant_bpwr_disp_cb_t; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BPWR_LOCAL_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.c new file mode 100644 index 0000000000000000000000000000000000000000..a279bddf9581ce8bf13a693978863be9fba9c22c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.c @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + +#include "ant_bpwr_common_data.h" +#include "ant_bpwr_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR_COMMON" +#if ANT_BPWR_COMMON_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_COMMON_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_COMMON_INFO_COLOR +#else // ANT_BPWR_COMMON_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_COMMON_LOG_ENABLED +#include "nrf_log.h" + +/**@brief BPWR common page data layout structure. */ +typedef struct +{ + uint8_t reserved0[2]; + uint8_t instantaneous_cadence; + uint8_t reserved1[4]; +}ant_bpwr_cadence_data_layout_t; + +/**@brief Function for tracing common data. + * + * @param[in] p_common_data Pointer to the common data. + */ +static void cadence_data_log(ant_bpwr_common_data_t const * p_common_data) +{ + if (p_common_data->instantaneous_cadence == 0xFF) + { + NRF_LOG_INFO("instantaneous cadence: -- rpm\r\n\n"); + } + else + { + NRF_LOG_INFO("instantaneous cadence: %u rpm\r\n\n", + p_common_data->instantaneous_cadence); + } +} + +void ant_bpwr_cadence_encode(uint8_t * p_page_buffer, + ant_bpwr_common_data_t const * p_common_data) +{ + ant_bpwr_cadence_data_layout_t * p_outcoming_data = (ant_bpwr_cadence_data_layout_t *)p_page_buffer; + p_outcoming_data->instantaneous_cadence = p_common_data->instantaneous_cadence; + + cadence_data_log(p_common_data); +} + +void ant_bpwr_cadence_decode(uint8_t const * p_page_buffer, + ant_bpwr_common_data_t * p_common_data) +{ + ant_bpwr_cadence_data_layout_t const * p_incoming_data = (ant_bpwr_cadence_data_layout_t *)p_page_buffer; + p_common_data->instantaneous_cadence = p_incoming_data->instantaneous_cadence; + + cadence_data_log(p_common_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.h new file mode 100644 index 0000000000000000000000000000000000000000..0372fb4df7ea4cfe9abc7814da2d997796ff1b0c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.h @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BPWR_COMMON_DATA_H__ +#define ANT_BPWR_COMMON_DATA_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bpwr_common_data_page Stride Based Speed and Distance Monitor profile common data + * @{ + * @ingroup ant_sdk_profiles_bpwr_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for BPWR common data. + * + * @details This structure stores data that is not associated with a particular page. + */ +typedef struct +{ + uint8_t instantaneous_cadence; ///< Crank cadence (rpm, 0 - 254, 255-> invalid). +} ant_bpwr_common_data_t; + +/**@brief Initialize common data. + */ +#define DEFAULT_ANT_BPWR_COMMON_DATA() \ + (ant_bpwr_common_data_t) \ + { \ + .instantaneous_cadence = 0, \ + } + +/**@brief Function for encoding speed. + * + * This function can be used for pages 16, 17, and 18. + * + * @param[in] p_common_data Pointer to the common data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bpwr_cadence_encode(uint8_t * p_page_buffer, + ant_bpwr_common_data_t const * p_common_data); + +/**@brief Function for decoding speed. + * + * This function can be used for pages 16, 17, and 18. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_common_data Pointer to the common data. + */ +void ant_bpwr_cadence_decode(uint8_t const * p_page_buffer, + ant_bpwr_common_data_t * p_common_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BPWR_COMMON_DATA_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.c new file mode 100644 index 0000000000000000000000000000000000000000..364f210bd7549e390ab133f201043ed8779660ad --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.c @@ -0,0 +1,285 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + +#include +#include "ant_bpwr_page_1.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR_PAGE_1" +#if ANT_BPWR_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_PAGE_1_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_1_INFO_COLOR +#else // ANT_BPWR_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_PAGE_1_LOG_ENABLED +#include "nrf_log.h" + +/**@brief bicycle power page 1 data layout structure. */ +typedef struct +{ + uint8_t calibration_id; ///< Calibration request type + union + { + struct + { + uint8_t reserved[6]; ///< Unused, fill by 0xFF. + } general_calib_request; + struct + { + uint8_t auto_zero_status; ///< Status of automatic zero feature of power sensor. + uint8_t reserved[5]; ///< Unused, fill by 0xFF. + } auto_zero_config; + struct + { + uint8_t auto_zero_status; ///< Status of automatic zero feature of power sensor. + uint8_t reserved[3]; ///< Unused, fill by 0xFF. + uint8_t data[2]; ///< Calibration Data. + } general_calib_response; + struct + { + uint8_t enable : 1; + uint8_t status : 1; + uint8_t reserved0 : 6; ///< Unused, fill by 0x00. + uint8_t reserved1[5]; ///< Unused, fill by 0xFF. + } auto_zero_support; + struct + { + uint8_t manufac_spec[6]; ///< Manufacture Specyfic Data. + } custom_calib; + } data; +} ant_bpwr_page1_data_layout_t; + + +static void page1_data_log(ant_bpwr_page1_data_t const * p_page_data) +{ + NRF_LOG_INFO("Calibration id: %u\r\n", p_page_data->calibration_id); + + switch (p_page_data->calibration_id) + { + case ANT_BPWR_CALIB_ID_MANUAL: + // No implementation needed + break; + + case ANT_BPWR_CALIB_ID_MANUAL_SUCCESS: + /* fall through */ + case ANT_BPWR_CALIB_ID_FAILED: + NRF_LOG_INFO("General calibration data: %u\r\n", + p_page_data->data.general_calib); + /* fall through */ + case ANT_BPWR_CALIB_ID_AUTO: + /* fall through */ + case ANT_BPWR_CALIB_ID_AUTO_SUPPORT: + + switch (p_page_data->auto_zero_status) + { + case ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED: + NRF_LOG_INFO("Auto zero not supported\r\n\n"); + break; + + case ANT_BPWR_AUTO_ZERO_OFF: + NRF_LOG_INFO("Auto zero off\r\n\n"); + break; + + case ANT_BPWR_AUTO_ZERO_ON: + NRF_LOG_INFO("Auto zero on\r\n\n"); + break; + } + break; + + case ANT_BPWR_CALIB_ID_CTF: + NRF_LOG_INFO("Not supported\r\n\n"); + break; + + case ANT_BPWR_CALIB_ID_CUSTOM_REQ: + /* fall through */ + case ANT_BPWR_CALIB_ID_CUSTOM_REQ_SUCCESS: + /* fall through */ + case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE: + /* fall through */ + case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE_SUCCESS: + NRF_LOG_INFO("Manufacture specyfic: "); + NRF_LOG_HEXDUMP_INFO((uint8_t*)p_page_data->data.custom_calib, + sizeof (p_page_data->data.custom_calib)); + break; + + default: // shouldn't occur + NRF_LOG_INFO("Unsupported calibration ID\r\n\n"); + break; + } +} + + +void ant_bpwr_page_1_encode(uint8_t * p_page_buffer, + ant_bpwr_page1_data_t const * p_page_data) +{ + ant_bpwr_page1_data_layout_t * p_outcoming_data = (ant_bpwr_page1_data_layout_t *)p_page_buffer; + + page1_data_log(p_page_data); + + p_outcoming_data->calibration_id = p_page_data->calibration_id; + + switch (p_page_data->calibration_id) + { + case ANT_BPWR_CALIB_ID_MANUAL: + memset(p_outcoming_data->data.general_calib_request.reserved, 0xFF, + sizeof (p_outcoming_data->data.general_calib_request.reserved)); + break; + + case ANT_BPWR_CALIB_ID_AUTO: + memset(p_outcoming_data->data.auto_zero_config.reserved, 0xFF, + sizeof (p_outcoming_data->data.auto_zero_config.reserved)); + p_outcoming_data->data.auto_zero_config.auto_zero_status = + p_page_data->auto_zero_status; + break; + + case ANT_BPWR_CALIB_ID_MANUAL_SUCCESS: + /* fall through */ + case ANT_BPWR_CALIB_ID_FAILED: + memset(p_outcoming_data->data.general_calib_response.reserved, 0xFF, + sizeof (p_outcoming_data->data.general_calib_response.reserved)); + p_outcoming_data->data.general_calib_response.auto_zero_status = + p_page_data->auto_zero_status; + UNUSED_PARAMETER(uint16_encode(p_page_data->data.general_calib, + p_outcoming_data->data.general_calib_response.data)); + break; + + case ANT_BPWR_CALIB_ID_CTF: + NRF_LOG_INFO("Not supported\r\n"); + break; + + case ANT_BPWR_CALIB_ID_AUTO_SUPPORT: + memset(p_outcoming_data->data.auto_zero_support.reserved1, 0xFF, + sizeof (p_outcoming_data->data.auto_zero_support.reserved1)); + p_outcoming_data->data.auto_zero_support.reserved0 = 0x00; + p_outcoming_data->data.auto_zero_support.enable = + (p_page_data->auto_zero_status == ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED) ? false : true; + p_outcoming_data->data.auto_zero_support.status = + (p_page_data->auto_zero_status == ANT_BPWR_AUTO_ZERO_ON) ? true : false; + break; + + case ANT_BPWR_CALIB_ID_CUSTOM_REQ: + /* fall through */ + case ANT_BPWR_CALIB_ID_CUSTOM_REQ_SUCCESS: + /* fall through */ + case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE: + /* fall through */ + case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE_SUCCESS: + memcpy(p_outcoming_data->data.custom_calib.manufac_spec, + (void *)p_page_data->data.custom_calib, + sizeof (p_page_data->data.custom_calib)); + break; + + default: // shouldn't occur + break; + } +} + + +void ant_bpwr_page_1_decode(uint8_t const * p_page_buffer, + ant_bpwr_page1_data_t * p_page_data) +{ + ant_bpwr_page1_data_layout_t const * p_incoming_data = + (ant_bpwr_page1_data_layout_t *)p_page_buffer; + + p_page_data->calibration_id = (ant_bpwr_calib_id_t)p_incoming_data->calibration_id; + + switch (p_incoming_data->calibration_id) + { + case ANT_BPWR_CALIB_ID_MANUAL: + // No implementation needed + break; + + case ANT_BPWR_CALIB_ID_AUTO: + /* fall through */ + p_page_data->auto_zero_status = + (ant_bpwr_auto_zero_status_t)p_incoming_data->data.auto_zero_config.auto_zero_status; + break; + + case ANT_BPWR_CALIB_ID_MANUAL_SUCCESS: + /* fall through */ + case ANT_BPWR_CALIB_ID_FAILED: + p_page_data->auto_zero_status = + (ant_bpwr_auto_zero_status_t)p_incoming_data->data.general_calib_response. + auto_zero_status; + p_page_data->data.general_calib = uint16_decode( + p_incoming_data->data.general_calib_response.data); + break; + + case ANT_BPWR_CALIB_ID_CTF: + NRF_LOG_INFO("Not supported\r\n"); + break; + + case ANT_BPWR_CALIB_ID_AUTO_SUPPORT: + + if (p_incoming_data->data.auto_zero_support.enable == false) + { + p_page_data->auto_zero_status = ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED; + } + else if (p_incoming_data->data.auto_zero_support.status) + { + p_page_data->auto_zero_status = ANT_BPWR_AUTO_ZERO_ON; + } + else + { + p_page_data->auto_zero_status = ANT_BPWR_AUTO_ZERO_OFF; + } + break; + + case ANT_BPWR_CALIB_ID_CUSTOM_REQ: + /* fall through */ + case ANT_BPWR_CALIB_ID_CUSTOM_REQ_SUCCESS: + /* fall through */ + case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE: + /* fall through */ + case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE_SUCCESS: + memcpy((void *)p_page_data->data.custom_calib, + p_incoming_data->data.custom_calib.manufac_spec, + sizeof (p_page_data->data.custom_calib)); + break; + + default: // shouldn't occur + break; + } + + page1_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.h new file mode 100644 index 0000000000000000000000000000000000000000..ff42b69ecb36ae8fbeff8a6126df9279b47ea14f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.h @@ -0,0 +1,136 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BPWR_PAGE_1_H__ +#define ANT_BPWR_PAGE_1_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bpwr_page1 Bicycle Power profile page 1 + * @{ + * @ingroup ant_sdk_profiles_bpwr_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief BPWR Calibration ID. + */ +typedef enum +{ + ANT_BPWR_CALIB_ID_NONE = 0x00, + ANT_BPWR_CALIB_ID_MANUAL = 0xAA, ///< Calibration Request: Manual Zero. + ANT_BPWR_CALIB_ID_AUTO = 0xAB, ///< Calibration Request: Auto Zero Configuration. + ANT_BPWR_CALIB_ID_MANUAL_SUCCESS = 0xAC, ///< Calibration Response: Manual Zero Successful. + ANT_BPWR_CALIB_ID_FAILED = 0xAF, ///< Calibration Response: Failed. + ANT_BPWR_CALIB_ID_CTF = 0x10, ///< Crank Torque Frequency (CTF) Power sensor Defined Message. + ANT_BPWR_CALIB_ID_AUTO_SUPPORT = 0x12, ///< Auto Zero Support. + ANT_BPWR_CALIB_ID_CUSTOM_REQ = 0xBA, ///< Custom Calibration Parameter Request. + ANT_BPWR_CALIB_ID_CUSTOM_REQ_SUCCESS = 0xBB, ///< Custom Calibration Parameter Response. + ANT_BPWR_CALIB_ID_CUSTOM_UPDATE = 0xBC, ///< Custom Calibration Parameter Update. + ANT_BPWR_CALIB_ID_CUSTOM_UPDATE_SUCCESS = 0xBD, ///< Custom Calibration Parameter Update Response. +} ant_bpwr_calib_id_t; + +/**@brief BPWR Calibration Auto Zero Status. + */ +typedef enum +{ + ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED = 0xFF, ///< Auto Zero Not Supported. + ANT_BPWR_AUTO_ZERO_OFF = 0x00, ///< Auto Zero OFF. + ANT_BPWR_AUTO_ZERO_ON = 0x01, ///< Auto Zero ON. +} ant_bpwr_auto_zero_status_t; + +/**@brief Data structure for Bicycle Power data page 1. + */ +typedef struct +{ + ant_bpwr_calib_id_t calibration_id; ///< Calibration request type. + ant_bpwr_auto_zero_status_t auto_zero_status; ///< Status of automatic zero feature of power sensor. + union + { + int16_t general_calib; + uint8_t custom_calib[6]; + } data; +} ant_bpwr_page1_data_t; + +/**@brief Initialize page 1. + */ +#define DEFAULT_ANT_BPWR_PAGE1() \ + (ant_bpwr_page1_data_t) \ + { \ + .calibration_id = ANT_BPWR_CALIB_ID_NONE, \ + .auto_zero_status = ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED, \ + .data.general_calib = 0x00, \ + } + +/**@brief Initialize page 1 with the general request. + */ +#define ANT_BPWR_GENERAL_CALIB_REQUEST() \ + (ant_bpwr_page1_data_t) \ + { \ + .calibration_id = ANT_BPWR_CALIB_ID_MANUAL, \ + } + +/**@brief Function for encoding page 1. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bpwr_page_1_encode(uint8_t * p_page_buffer, + ant_bpwr_page1_data_t const * p_page_data); + +/**@brief Function for decoding page 1. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_bpwr_page_1_decode(uint8_t const * p_page_buffer, + ant_bpwr_page1_data_t * p_page_data); + + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BPWR_PAGE_1_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.c new file mode 100644 index 0000000000000000000000000000000000000000..f1353c7220c671c0ef4ff319183e6ef9f01117e5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.c @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + +#include "ant_bpwr_page_16.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR_PAGE_16" +#if ANT_BPWR_PAGE_16_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_PAGE_16_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_16_INFO_COLOR +#else // ANT_BPWR_PAGE_16_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_PAGE_16_LOG_ENABLED +#include "nrf_log.h" + +/**@brief bicycle power page 16 data layout structure. */ +typedef struct +{ + uint8_t update_event_count; + uint8_t pedal_power; + uint8_t reserved; + uint8_t accumulated_power[2]; + uint8_t instantaneous_power[2]; +}ant_bpwr_page16_data_layout_t; + + +static void page16_data_log(ant_bpwr_page16_data_t const * p_page_data) +{ + NRF_LOG_INFO("event count: %u\r\n", p_page_data->update_event_count); + + if (p_page_data->pedal_power.byte != 0xFF) + { + NRF_LOG_INFO("pedal power: %u %%\r\n", + p_page_data->pedal_power.items.distribution); + } + else + { + NRF_LOG_INFO("pedal power: --\r\n"); + } + + NRF_LOG_INFO("accumulated power: %u W\r\n", p_page_data->accumulated_power); + NRF_LOG_INFO("instantaneous power: %u W\r\n", p_page_data->instantaneous_power); +} + + +void ant_bpwr_page_16_encode(uint8_t * p_page_buffer, + ant_bpwr_page16_data_t const * p_page_data) +{ + ant_bpwr_page16_data_layout_t * p_outcoming_data = + (ant_bpwr_page16_data_layout_t *)p_page_buffer; + + p_outcoming_data->update_event_count = p_page_data->update_event_count; + p_outcoming_data->pedal_power = p_page_data->pedal_power.byte; + + UNUSED_PARAMETER(uint16_encode(p_page_data->accumulated_power, + p_outcoming_data->accumulated_power)); + UNUSED_PARAMETER(uint16_encode(p_page_data->instantaneous_power, + p_outcoming_data->instantaneous_power)); + + page16_data_log(p_page_data); +} + + +void ant_bpwr_page_16_decode(uint8_t const * p_page_buffer, + ant_bpwr_page16_data_t * p_page_data) +{ + ant_bpwr_page16_data_layout_t const * p_incoming_data = + (ant_bpwr_page16_data_layout_t *)p_page_buffer; + + p_page_data->update_event_count = p_incoming_data->update_event_count; + p_page_data->pedal_power.byte = p_incoming_data->pedal_power; + p_page_data->accumulated_power = uint16_decode(p_incoming_data->accumulated_power); + p_page_data->instantaneous_power = uint16_decode(p_incoming_data->instantaneous_power); + + page16_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.h new file mode 100644 index 0000000000000000000000000000000000000000..04382bdf36a00efd6648d46e1534fe679c85214c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.h @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BPWR_PAGE_16_H__ +#define ANT_BPWR_PAGE_16_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bpwr_page16 Bicycle Power profile page 16 + * @{ + * @ingroup ant_sdk_profiles_bpwr_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for Bicycle Power data page 16. + * + * @note This structure implements only page 16 specific data. + */ +typedef struct +{ + union + { + struct + { + uint8_t distribution : 7; ///< Pedal power distribution (%). + uint8_t differentiation : 1; ///< Pedal differentiation: 1 -> right, 0 -> unknown. + } items; + uint8_t byte; + } pedal_power; + + uint8_t update_event_count; ///< Power event count. + uint16_t accumulated_power; ///< Accumulated power (W). + uint16_t instantaneous_power; ///< Instantaneous power (W). +} ant_bpwr_page16_data_t; + +/**@brief Initialize page 16. + */ +#define DEFAULT_ANT_BPWR_PAGE16() \ + (ant_bpwr_page16_data_t) \ + { \ + .update_event_count = 0, \ + .pedal_power.items.distribution = 0, \ + .pedal_power.items.differentiation = 0, \ + .accumulated_power = 0, \ + .instantaneous_power = 0, \ + } + +/**@brief Function for encoding page 16. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bpwr_page_16_encode(uint8_t * p_page_buffer, + ant_bpwr_page16_data_t const * p_page_data); + +/**@brief Function for decoding page 16. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_bpwr_page_16_decode(uint8_t const * p_page_buffer, + ant_bpwr_page16_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BPWR_PAGE_16_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.c new file mode 100644 index 0000000000000000000000000000000000000000..1684f2fd94b90bb9d090d9e50c22d3002f6ea63c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + +#include "ant_bpwr_page_17.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR_PAGE_17" +#if ANT_BPWR_PAGE_17_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_PAGE_17_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_17_INFO_COLOR +#else // ANT_BPWR_PAGE_17_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_PAGE_17_LOG_ENABLED +#include "nrf_log.h" + +static void page17_data_log(ant_bpwr_page17_data_t const * p_page_data) +{ + NRF_LOG_INFO("Wheel:\r\n"); + ant_bpwr_page_torque_log((ant_bpwr_page_torque_data_t *) p_page_data); +} + + +void ant_bpwr_page_17_encode(uint8_t * p_page_buffer, + ant_bpwr_page17_data_t const * p_page_data) +{ + ant_bpwr_page_torque_encode(p_page_buffer, (ant_bpwr_page_torque_data_t *)p_page_data); + page17_data_log(p_page_data); +} + + +void ant_bpwr_page_17_decode(uint8_t const * p_page_buffer, + ant_bpwr_page17_data_t * p_page_data) +{ + ant_bpwr_page_torque_decode(p_page_buffer, (ant_bpwr_page_torque_data_t *) p_page_data); + page17_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.h new file mode 100644 index 0000000000000000000000000000000000000000..d212367832911709da2fab557650e8c711004106 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.h @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BPWR_PAGE_17_H__ +#define ANT_BPWR_PAGE_17_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bpwr_page17 Bicycle Power profile page 17 + * @{ + * @ingroup ant_sdk_profiles_bpwr_pages + */ + +#include +#include "ant_bpwr_page_torque.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for Bicycle Power data page 17. + * + * @note This structure implements only page 17 specific data. + */ +typedef ant_bpwr_page_torque_data_t ant_bpwr_page17_data_t; + +/**@brief Initialize page 17. + */ +#define DEFAULT_ANT_BPWR_PAGE17() (ant_bpwr_page17_data_t) DEFAULT_ANT_BPWR_PAGE_TORQUE(0, 0, 0, 0) + +/**@brief Function for encoding page 17. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bpwr_page_17_encode(uint8_t * p_page_buffer, + ant_bpwr_page17_data_t const * p_page_data); + +/**@brief Function for decoding page 17. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_bpwr_page_17_decode(uint8_t const * p_page_buffer, + ant_bpwr_page17_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BPWR_PAGE_17_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.c new file mode 100644 index 0000000000000000000000000000000000000000..3d754bb37f1f3930981f42509170bbdac89a5b22 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + +#include "ant_bpwr_page_18.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR_PAGE_18" +#if ANT_BPWR_PAGE_18_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_PAGE_18_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_18_INFO_COLOR +#else // ANT_BPWR_PAGE_18_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_PAGE_18_LOG_ENABLED +#include "nrf_log.h" + +static void page18_data_log(ant_bpwr_page18_data_t const * p_page_data) +{ + NRF_LOG_INFO("Crank:\r\n"); + ant_bpwr_page_torque_log((ant_bpwr_page_torque_data_t *) p_page_data); +} + + +void ant_bpwr_page_18_encode(uint8_t * p_page_buffer, + ant_bpwr_page18_data_t const * p_page_data) +{ + ant_bpwr_page_torque_encode(p_page_buffer, (ant_bpwr_page_torque_data_t *)p_page_data); + page18_data_log(p_page_data); +} + + +void ant_bpwr_page_18_decode(uint8_t const * p_page_buffer, + ant_bpwr_page18_data_t * p_page_data) +{ + ant_bpwr_page_torque_decode(p_page_buffer, (ant_bpwr_page_torque_data_t *) p_page_data); + page18_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.h new file mode 100644 index 0000000000000000000000000000000000000000..4252abcba9a2da45b32da30a5a3fe9acd968c1a9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.h @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BPWR_PAGE_18_H__ +#define ANT_BPWR_PAGE_18_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bpwr_page18 Bicycle Power profile page 18 + * @{ + * @ingroup ant_sdk_profiles_bpwr_pages + */ + +#include +#include "ant_bpwr_page_torque.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for Bicycle Power data page 18. + * + * @note This structure implements only page 18 specific data. + */ +typedef ant_bpwr_page_torque_data_t ant_bpwr_page18_data_t; + +/**@brief Initialize page 18. + */ +#define DEFAULT_ANT_BPWR_PAGE18() (ant_bpwr_page18_data_t) DEFAULT_ANT_BPWR_PAGE_TORQUE(0, 0, 0, 0) + +/**@brief Function for encoding page 18. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bpwr_page_18_encode(uint8_t * p_page_buffer, + ant_bpwr_page18_data_t const * p_page_data); + +/**@brief Function for decoding page 18. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_bpwr_page_18_decode(uint8_t const * p_page_buffer, + ant_bpwr_page18_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BPWR_PAGE_18_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.c new file mode 100644 index 0000000000000000000000000000000000000000..a307b0f331828cce387c69b2c1a9d09450f353d1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.c @@ -0,0 +1,112 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + +#include +#include "ant_bpwr_page_torque.h" +#include "ant_bpwr_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR_PAGE_TORQUE" +#if ANT_BPWR_PAGE_TORQUE_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_PAGE_TORQUE_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_TORQUE_INFO_COLOR +#else // ANT_BPWR_PAGE_TORQUE_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_PAGE_TORQUE_LOG_ENABLED +#include "nrf_log.h" + +/**@brief bicycle power page torque data layout structure. */ +typedef struct +{ + uint8_t update_event_count; + uint8_t tick; + uint8_t reserved; + uint8_t period[2]; + uint8_t accumulated_torque[2]; +}ant_bpwr_page_torque_data_layout_t; + +STATIC_ASSERT(ANT_BPWR_TORQUE_PERIOD_DISP_PRECISION == 1000); ///< Display format need to be updated +STATIC_ASSERT(ANT_BPWR_ACC_TORQUE_DISP_PRECISION == 10); ///< Display format need to be updated + +void ant_bpwr_page_torque_log(ant_bpwr_page_torque_data_t const * p_page_data) +{ + uint16_t period = ANT_BPWR_TORQUE_PERIOD_RESCALE(p_page_data->period); + uint32_t acc_torque = ANT_BPWR_ACC_TORQUE_RESCALE(p_page_data->accumulated_torque); + + NRF_LOG_INFO("event count: %u\r\n", p_page_data->update_event_count); + NRF_LOG_INFO("tick: %u\r\n", p_page_data->tick); + NRF_LOG_INFO("period: %u.%03us\r\n", + (unsigned int)(period / ANT_BPWR_TORQUE_PERIOD_DISP_PRECISION), + (unsigned int)(period % ANT_BPWR_TORQUE_PERIOD_DISP_PRECISION)); + NRF_LOG_INFO("accumulated torque: %u.%01uNm\r\n", + (unsigned int)(acc_torque / ANT_BPWR_ACC_TORQUE_DISP_PRECISION), + (unsigned int)(acc_torque % ANT_BPWR_ACC_TORQUE_DISP_PRECISION)); +} + + +void ant_bpwr_page_torque_encode(uint8_t * p_page_buffer, + ant_bpwr_page_torque_data_t const * p_page_data) +{ + ant_bpwr_page_torque_data_layout_t * p_outcoming_data = + (ant_bpwr_page_torque_data_layout_t *)p_page_buffer; + + p_outcoming_data->update_event_count = p_page_data->update_event_count; + p_outcoming_data->tick = p_page_data->tick; + + UNUSED_PARAMETER(uint16_encode(p_page_data->period, p_outcoming_data->period)); + UNUSED_PARAMETER(uint16_encode(p_page_data->accumulated_torque, + p_outcoming_data->accumulated_torque)); +} + + +void ant_bpwr_page_torque_decode(uint8_t const * p_page_buffer, + ant_bpwr_page_torque_data_t * p_page_data) +{ + ant_bpwr_page_torque_data_layout_t const * p_incoming_data = + (ant_bpwr_page_torque_data_layout_t *)p_page_buffer; + + p_page_data->update_event_count = p_incoming_data->update_event_count; + p_page_data->tick = p_incoming_data->tick; + p_page_data->period = uint16_decode(p_incoming_data->period); + p_page_data->accumulated_torque = uint16_decode(p_incoming_data->accumulated_torque); +} + +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.h new file mode 100644 index 0000000000000000000000000000000000000000..7873692164c00755f26d895571e81a9121adf14e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.h @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BPWR_PAGE_TORQUE_COMMON_H__ +#define ANT_BPWR_PAGE_TORQUE_COMMON_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bicycle_p_page_torque Bicycle Power profile pages 17, 18 (commons) + * @{ + * @ingroup ant_sdk_profiles_bpwr_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Common data structure for Bicycle Power data pages 17, 18. + * + * @note This structure implements specific data that is common for pages 17, 18. + */ +typedef struct +{ + uint8_t update_event_count; ///< Power event count. + uint8_t tick; ///< Wheel/crank revolutions counter. + uint16_t period; ///< Accumulated wheel/crank period (1/2048 s). + uint16_t accumulated_torque; ///< Accumulated wheel/torque (1/32 Nm). +} ant_bpwr_page_torque_data_t; + +/**@brief Initialize page torque. + */ +#define DEFAULT_ANT_BPWR_PAGE_TORQUE(up_evt_cnt, def_tick, def_period, acc_torque) \ + { \ + .update_event_count = (up_evt_cnt), \ + .tick = (def_tick), \ + .period = (def_period), \ + .accumulated_torque = (acc_torque) \ + } + +/**@brief Function for encoding pages 17, 18. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bpwr_page_torque_encode(uint8_t * p_page_buffer, + ant_bpwr_page_torque_data_t const * p_page_data); + +/**@brief Function for decoding pages 17, 18. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_bpwr_page_torque_decode(uint8_t const * p_page_buffer, + ant_bpwr_page_torque_data_t * p_page_data); + +/**@brief Function for logging pages 17, 18. + * + * @param[in] p_page_data Pointer to the page data. + */ +void ant_bpwr_page_torque_log(ant_bpwr_page_torque_data_t const * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BPWR_PAGE_TORQUE_COMMON_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_pages.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_pages.h new file mode 100644 index 0000000000000000000000000000000000000000..38badee2f0c7b43c6bf6be3ec3cc8b885f88984f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_pages.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BPWR_PAGES_H__ +#define ANT_BPWR_PAGES_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bpwr_pages Bicycle Power profile pages + * @{ + * @ingroup ant_bpwr + * @brief This module implements functions for the BPWR data pages. + */ + +#include "ant_bpwr_page_1.h" // Calibration message main data page. +#include "ant_bpwr_page_16.h" // Standard power-only page. +#include "ant_bpwr_page_17.h" // Wheel Torque main data page. +#include "ant_bpwr_page_18.h" // Crank Torque main data page. +#include "ant_bpwr_common_data.h" // Instantaneous cadence data. +#include "ant_common_page_80.h" // Manufacturer's information data page. +#include "ant_common_page_81.h" // Product information data page. + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BPWR_PAGES_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.c new file mode 100644 index 0000000000000000000000000000000000000000..75563b402a673b265fef7442a0dd1e7a1135122c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.c @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ant_bpwr_simulator.h" +#include "app_util.h" +#include "nordic_common.h" + +#define POWER_MIN 0 +#define POWER_MAX 2000 +#define POWER_INCR 10 + +#define CADENCE_MIN 0 +#define CADENCE_MAX (UINT8_MAX - 1) +#define CADENCE_INCR 1 + +#define PEDAL_MIN 0 +#define PEDAL_MAX 100 +#define PEDAL_INCR 1 + +#define TORQUE_PERIOD 774 +#define SIMULATOR_TIME_INCREMENT BPWR_MSG_PERIOD + +#define TORQUE_INCR 10 + + +void ant_bpwr_simulator_init(ant_bpwr_simulator_t * p_simulator, + ant_bpwr_simulator_cfg_t const * p_config, + bool auto_change) +{ + p_simulator->p_profile = p_config->p_profile; + p_simulator->_cb.auto_change = auto_change; + p_simulator->_cb.tick_incr = 0; + + p_simulator->_cb.power_sensorsim_cfg.min = POWER_MIN; + p_simulator->_cb.power_sensorsim_cfg.max = POWER_MAX; + p_simulator->_cb.power_sensorsim_cfg.incr = POWER_INCR; + p_simulator->_cb.power_sensorsim_cfg.start_at_max = false; + + p_simulator->_cb.cadence_sensorsim_cfg.min = CADENCE_MIN; + p_simulator->_cb.cadence_sensorsim_cfg.max = CADENCE_MAX; + p_simulator->_cb.cadence_sensorsim_cfg.incr = CADENCE_INCR; + p_simulator->_cb.cadence_sensorsim_cfg.start_at_max = false; + + p_simulator->_cb.pedal_sensorsim_cfg.min = PEDAL_MIN; + p_simulator->_cb.pedal_sensorsim_cfg.max = PEDAL_MAX; + p_simulator->_cb.pedal_sensorsim_cfg.incr = PEDAL_INCR; + p_simulator->_cb.pedal_sensorsim_cfg.start_at_max = false; + + p_simulator->p_profile->BPWR_PROFILE_pedal_power.differentiation = 0x01; // right + + sensorsim_init(&(p_simulator->_cb.power_sensorsim_state), + &(p_simulator->_cb.power_sensorsim_cfg)); + sensorsim_init(&(p_simulator->_cb.cadence_sensorsim_state), + &(p_simulator->_cb.cadence_sensorsim_cfg)); + sensorsim_init(&(p_simulator->_cb.pedal_sensorsim_state), + &(p_simulator->_cb.pedal_sensorsim_cfg)); +} + + +void ant_bpwr_simulator_one_iteration(ant_bpwr_simulator_t * p_simulator, ant_bpwr_evt_t event) +{ + switch (event) + { + case ANT_BPWR_PAGE_16_UPDATED: + + if (p_simulator->_cb.auto_change) + { + UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.power_sensorsim_state), + &(p_simulator->_cb.power_sensorsim_cfg))); + UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.cadence_sensorsim_state), + &(p_simulator->_cb.cadence_sensorsim_cfg))); + UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.pedal_sensorsim_state), + &(p_simulator->_cb.pedal_sensorsim_cfg))); + } + + p_simulator->p_profile->BPWR_PROFILE_instantaneous_power = + p_simulator->_cb.power_sensorsim_state.current_val; + p_simulator->p_profile->BPWR_PROFILE_accumulated_power += + p_simulator->_cb.power_sensorsim_state.current_val; + + if (p_simulator->p_profile->BPWR_PROFILE_accumulated_power == UINT16_MAX) + { + p_simulator->p_profile->BPWR_PROFILE_accumulated_power = 0; + } + p_simulator->p_profile->BPWR_PROFILE_instantaneous_cadence = + p_simulator->_cb.cadence_sensorsim_state.current_val; + p_simulator->p_profile->BPWR_PROFILE_pedal_power.distribution = + p_simulator->_cb.pedal_sensorsim_state.current_val; + p_simulator->p_profile->BPWR_PROFILE_power_update_event_count++; + break; + + case ANT_BPWR_PAGE_17_UPDATED: + + if (p_simulator->_cb.auto_change) + { + UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.cadence_sensorsim_state), + &(p_simulator->_cb.cadence_sensorsim_cfg))); + } + p_simulator->p_profile->BPWR_PROFILE_instantaneous_cadence = + p_simulator->_cb.cadence_sensorsim_state.current_val; + p_simulator->p_profile->BPWR_PROFILE_wheel_period += TORQUE_PERIOD; + p_simulator->_cb.tick_incr += + SIMULATOR_TIME_INCREMENT; + p_simulator->p_profile->BPWR_PROFILE_wheel_tick += + p_simulator->_cb.tick_incr / (TORQUE_PERIOD * 16); + p_simulator->_cb.tick_incr = + p_simulator->_cb.tick_incr % (TORQUE_PERIOD * 16); + p_simulator->p_profile->BPWR_PROFILE_wheel_accumulated_torque += TORQUE_INCR; + p_simulator->p_profile->BPWR_PROFILE_wheel_update_event_count++; + break; + + case ANT_BPWR_PAGE_18_UPDATED: + + if (p_simulator->_cb.auto_change) + { + UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.cadence_sensorsim_state), + &(p_simulator->_cb.cadence_sensorsim_cfg))); + } + p_simulator->p_profile->BPWR_PROFILE_instantaneous_cadence = + p_simulator->_cb.cadence_sensorsim_state.current_val; + p_simulator->p_profile->BPWR_PROFILE_crank_period = TORQUE_PERIOD; + p_simulator->_cb.tick_incr += + SIMULATOR_TIME_INCREMENT; + p_simulator->p_profile->BPWR_PROFILE_crank_tick += + p_simulator->_cb.tick_incr / (TORQUE_PERIOD * 16); + p_simulator->_cb.tick_incr = + p_simulator->_cb.tick_incr % (TORQUE_PERIOD * 16); + p_simulator->p_profile->BPWR_PROFILE_crank_accumulated_torque += TORQUE_INCR; + p_simulator->p_profile->BPWR_PROFILE_crank_update_event_count++; + break; + + default: + break; + } +} + + +void ant_bpwr_simulator_increment(ant_bpwr_simulator_t * p_simulator) +{ + if (!p_simulator->_cb.auto_change) + { + sensorsim_increment(&(p_simulator->_cb.power_sensorsim_state), + &(p_simulator->_cb.power_sensorsim_cfg)); + sensorsim_increment(&(p_simulator->_cb.cadence_sensorsim_state), + &(p_simulator->_cb.cadence_sensorsim_cfg)); + sensorsim_increment(&(p_simulator->_cb.pedal_sensorsim_state), + &(p_simulator->_cb.pedal_sensorsim_cfg)); + } +} + + +void ant_bpwr_simulator_decrement(ant_bpwr_simulator_t * p_simulator) +{ + if (!p_simulator->_cb.auto_change) + { + sensorsim_decrement(&(p_simulator->_cb.power_sensorsim_state), + &(p_simulator->_cb.power_sensorsim_cfg)); + sensorsim_decrement(&(p_simulator->_cb.cadence_sensorsim_state), + &(p_simulator->_cb.cadence_sensorsim_cfg)); + sensorsim_decrement(&(p_simulator->_cb.pedal_sensorsim_state), + &(p_simulator->_cb.pedal_sensorsim_cfg)); + } +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.h new file mode 100644 index 0000000000000000000000000000000000000000..42054fb7ebad0a81359e99d740b3cc857636907d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.h @@ -0,0 +1,123 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BPWR_SIMULATOR_H__ +#define ANT_BPWR_SIMULATOR_H__ + +/** @file + * + * @defgroup ant_sdk_simulators ANT simulators + * @ingroup ant_sdk_utils + * @brief Modules that simulate sensors. + * + * @defgroup ant_sdk_bpwr_simulator ANT BPWR simulator + * @{ + * @ingroup ant_sdk_simulators + * @brief ANT BPWR simulator module. + * + * @details This module simulates power for the ANT BPWR profile. The module calculates + * abstract values, which are handled by the BPWR pages data model to ensure that they are + * compatible. It provides a handler for changing the power value manually and functionality + * for changing the power automatically. + * + */ + +#include +#include +#include "bsp.h" +#include "ant_bpwr.h" +#include "sensorsim.h" +#include "ant_bpwr_simulator_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief BPWR simulator configuration structure. */ +typedef struct +{ + ant_bpwr_profile_t * p_profile; ///< Related profile. + ant_bpwr_torque_t sensor_type; ///< Type of related sensor. +} ant_bpwr_simulator_cfg_t; + +/**@brief BPWR simulator structure. */ +typedef struct +{ + ant_bpwr_profile_t * p_profile; ///< Related profile. + ant_bpwr_simulator_cb_t _cb; ///< Internal control block. +} ant_bpwr_simulator_t; + + +/**@brief Function for initializing the ANT BPWR simulator instance. + * + * @param[in] p_simulator Pointer to the simulator instance. + * @param[in] p_config Pointer to the simulator configuration structure. + * @param[in] auto_change Enable or disable automatic changes of the power. + */ +void ant_bpwr_simulator_init(ant_bpwr_simulator_t * p_simulator, + ant_bpwr_simulator_cfg_t const * p_config, + bool auto_change); + +/**@brief Function for simulating a device event. + * + * @details Based on this event, the transmitter data is simulated. + * + * This function should be called in the BPWR TX event handler. + */ +void ant_bpwr_simulator_one_iteration(ant_bpwr_simulator_t * p_simulator, ant_bpwr_evt_t event); + +/**@brief Function for incrementing the power value. + * + * @param[in] p_simulator Pointer to the simulator instance. + */ +void ant_bpwr_simulator_increment(ant_bpwr_simulator_t * p_simulator); + +/**@brief Function for decrementing the power value. + * + * @param[in] p_simulator Pointer to the simulator instance. + */ +void ant_bpwr_simulator_decrement(ant_bpwr_simulator_t * p_simulator); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BPWR_SIMULATOR_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator_local.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator_local.h new file mode 100644 index 0000000000000000000000000000000000000000..a454584ac8a1b5da2198ed95673ba69852164c36 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator_local.h @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BPWR_SIMULATOR_LOCAL_H__ +#define ANT_BPWR_SIMULATOR_LOCAL_H__ + +#include +#include +#include "bsp.h" +#include "ant_bpwr.h" +#include "sensorsim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup ant_sdk_bpwr_simulator + * @brief BPWR simulator control block structure. */ +typedef struct +{ + bool auto_change; ///< Power will change automatically (if auto_change is set) or manually. + uint32_t tick_incr; ///< Fractional part of tick increment. + sensorsim_state_t power_sensorsim_state; ///< Power state of the simulated sensor. + sensorsim_cfg_t power_sensorsim_cfg; ///< Power configuration of the simulated sensor. + sensorsim_state_t cadence_sensorsim_state; ///< Cadence stated of the simulated sensor. + sensorsim_cfg_t cadence_sensorsim_cfg; ///< Cadence configuration of the simulated sensor. + sensorsim_state_t pedal_sensorsim_state; ///< Pedal state of the simulated sensor. + sensorsim_cfg_t pedal_sensorsim_cfg; ///< Pedal configuration of the simulated sensor. +}ant_bpwr_simulator_cb_t; + + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BPWR_SIMULATOR_LOCAL_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/utils/ant_bpwr_utils.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/utils/ant_bpwr_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..bdf91e3f204000f6424fcba9ef488196427702b2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bpwr/utils/ant_bpwr_utils.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BPWR_UTILS_H__ +#define ANT_BPWR_UTILS_H__ + +#include "app_util.h" +#include "nrf_assert.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + * + * @defgroup ant_sdk_profiles_bpwr_utils Bicycle Power profile utilities + * @{ + * @ingroup ant_bpwr + * @brief This module implements utilities for the Bicycle Power profile. + * + */ + +/*@brief A reversal of torque period unit. + * + * @details According to the ANT BPWR specification, the torque period unit is 1/2048 of a second. + */ +#define ANT_BPWR_TORQUE_PERIOD_UNIT_REVERSAL 2048 +#define ANT_BPWR_TORQUE_PERIOD_DISP_PRECISION 1000 +#define ANT_BPWR_TORQUE_PERIOD_RESCALE(VALUE) value_rescale((VALUE), ANT_BPWR_TORQUE_PERIOD_UNIT_REVERSAL, \ + ANT_BPWR_TORQUE_PERIOD_DISP_PRECISION) + +/*@brief A reversal of accumulated torque unit. + * + * @details According to the ANT BPWR specification, the accumulated torque unit is 1/32 of a Nm. + */ +#define ANT_BPWR_ACC_TORQUE_UNIT_REVERSAL 32 +#define ANT_BPWR_ACC_TORQUE_DISP_PRECISION 10 +#define ANT_BPWR_ACC_TORQUE_RESCALE(VALUE) value_rescale((VALUE), ANT_BPWR_ACC_TORQUE_UNIT_REVERSAL, \ + ANT_BPWR_ACC_TORQUE_DISP_PRECISION) + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BPWR_UTILS_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/ant_bsc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/ant_bsc.c new file mode 100644 index 0000000000000000000000000000000000000000..128e7c943d08b0a3ce63ec488214c54c033e4be5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/ant_bsc.c @@ -0,0 +1,420 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + +#include "nrf_assert.h" +#include "nrf_error.h" +#include "app_error.h" +#include "ant_interface.h" +#include "ant_bsc.h" +#include "ant_bsc_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_BSC" +#if ANT_BSC_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_INFO_COLOR +#else // ANT_BSC_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_LOG_ENABLED +#include "nrf_log.h" + +#define MAIN_DATA_INTERVAL 4 /**< The number of background data pages sent between main data pages.*/ +#define BACKGROUND_DATA_INTERVAL 64 /**< The number of main data pages sent between background data page. + Background data page is sent every 65th message. */ +#define TX_TOGGLE_DIVISOR 4 /**< The number of messages between changing state of toggle bit. */ + +/**@brief BSC message data layout structure. */ +typedef struct +{ + ant_bsc_page_t page_number : 7; + uint8_t toggle_bit : 1; + uint8_t page_payload[7]; +}ant_bsc_single_message_layout_t; + +typedef struct +{ + uint8_t page_payload[8]; +}ant_bsc_combined_message_layout_t; + +typedef union +{ + ant_bsc_single_message_layout_t speed_or_cadence; + ant_bsc_combined_message_layout_t combined; +}ant_bsc_message_layout_t; + + +/**@brief Function for initializing the ANT BSC profile instance. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_channel_config Pointer to the ANT channel configuration structure. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. + */ +static ret_code_t ant_bsc_init(ant_bsc_profile_t * p_profile, + ant_channel_config_t const * p_channel_config) +{ + p_profile->channel_number = p_channel_config->channel_number; + + p_profile->page_0 = DEFAULT_ANT_BSC_PAGE0(); + p_profile->page_1 = DEFAULT_ANT_BSC_PAGE1(); + p_profile->page_2 = DEFAULT_ANT_BSC_PAGE2(); + p_profile->page_3 = DEFAULT_ANT_BSC_PAGE3(); + p_profile->page_4 = DEFAULT_ANT_BSC_PAGE4(); + p_profile->page_5 = DEFAULT_ANT_BSC_PAGE5(); + p_profile->page_comb_0 = DEFAULT_ANT_BSC_COMBINED_PAGE0(); + + NRF_LOG_INFO("ANT BSC channel %u init\r\n", p_profile->channel_number); + return ant_channel_init(p_channel_config); +} + +ret_code_t ant_bsc_disp_init(ant_bsc_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_bsc_disp_config_t const * p_disp_config) +{ + ASSERT(p_profile != NULL); + ASSERT(p_channel_config != NULL); + ASSERT(p_disp_config->evt_handler != NULL); + + p_profile->evt_handler = p_disp_config->evt_handler; + p_profile->_cb.p_disp_cb = p_disp_config->p_cb; + + p_profile->_cb.p_disp_cb->device_type = p_channel_config->device_type; + + return ant_bsc_init(p_profile, p_channel_config); +} + +ret_code_t ant_bsc_sens_init(ant_bsc_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_bsc_sens_config_t const * p_sens_config) +{ + ASSERT(p_profile != NULL); + ASSERT(p_channel_config != NULL); + ASSERT(p_sens_config != NULL); + ASSERT(p_sens_config->p_cb != NULL); + ASSERT(p_sens_config->evt_handler != NULL); + + ASSERT((p_sens_config->main_page_number == ANT_BSC_PAGE_0) + || (p_sens_config->main_page_number == ANT_BSC_PAGE_5) + || (p_sens_config->main_page_number == ANT_BSC_COMB_PAGE_0)); + + p_profile->evt_handler = p_sens_config->evt_handler; + p_profile->_cb.p_sens_cb = p_sens_config->p_cb; + + p_profile->_cb.p_sens_cb->page_1_present = p_sens_config->page_1_present; + p_profile->_cb.p_sens_cb->page_4_present = p_sens_config->page_4_present; + p_profile->_cb.p_sens_cb->main_page_number = p_sens_config->main_page_number; + p_profile->_cb.p_sens_cb->bkgd_page_number = + p_sens_config->page_1_present ? ANT_BSC_PAGE_1 : ANT_BSC_PAGE_2; + p_profile->_cb.p_sens_cb->message_counter = 0; + p_profile->_cb.p_sens_cb->toggle_bit = true; + p_profile->_cb.p_sens_cb->device_type = p_channel_config->device_type; /* Device type is set up in channel config */ + + return ant_bsc_init(p_profile, p_channel_config); +} + +/**@brief Function for setting the next background page number. + * + * @param[in] p_profile Pointer to the profile instance. + * + */ +__STATIC_INLINE void next_bkgd_page_number_set(ant_bsc_profile_t * p_profile) +{ + /* Determine the last background page*/ + ant_bsc_page_t last_bkgd_page = + p_profile->_cb.p_sens_cb->page_4_present ? ANT_BSC_PAGE_4 : ANT_BSC_PAGE_3; + + /* Switch the background page according to user settings */ + ++(p_profile->_cb.p_sens_cb->bkgd_page_number); + if (p_profile->_cb.p_sens_cb->bkgd_page_number > last_bkgd_page) + { + p_profile->_cb.p_sens_cb->bkgd_page_number = + p_profile->_cb.p_sens_cb->page_1_present ? ANT_BSC_PAGE_1 : ANT_BSC_PAGE_2; + } +} + +/**@brief Function for getting next page number to send. + * + * @param[in] p_profile Pointer to the profile instance. + * + * @return Next page number. + */ +static ant_bsc_page_t next_page_number_get(ant_bsc_profile_t * p_profile) +{ + ant_bsc_page_t page_number; + + /* This is a single speed or cadence sensor - switch data page */ + if (p_profile->_cb.p_sens_cb->message_counter < (BACKGROUND_DATA_INTERVAL)) + { + /* Return main page */ + page_number = p_profile->_cb.p_sens_cb->main_page_number; + } + else + { + /* Return background page */ + page_number = p_profile->_cb.p_sens_cb->bkgd_page_number; + } + + /* Set page toggle bit */ + if ((p_profile->_cb.p_sens_cb->message_counter % TX_TOGGLE_DIVISOR) == 0) + { + p_profile->_cb.p_sens_cb->toggle_bit ^= 1; + } + + /* Update message counter, wrap when counter equals 64 + 4 */ + ++(p_profile->_cb.p_sens_cb->message_counter); + if (p_profile->_cb.p_sens_cb->message_counter == (BACKGROUND_DATA_INTERVAL + MAIN_DATA_INTERVAL)) + { + p_profile->_cb.p_sens_cb->message_counter = 0; + /* Set new background data page number */ + next_bkgd_page_number_set(p_profile); + } + + return page_number; +} + +/**@brief Function for encoding BSC message. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[out] p_message_payload Pointer to the message payload structure. + * + * @note Assume to be called each time when Tx window will occur. + */ +static void sens_message_encode(ant_bsc_profile_t * p_profile, uint8_t * p_message_payload) +{ + ant_bsc_message_layout_t * p_bsc_message_payload = (ant_bsc_message_layout_t *)p_message_payload; + ant_bsc_evt_t bsc_sens_event; + + if (p_profile->_cb.p_sens_cb->device_type == BSC_COMBINED_DEVICE_TYPE) + { + NRF_LOG_INFO("BSC TX Page: \"Combined Speed & Cadence Page\"\r\n"); + ant_bsc_combined_page_0_encode(p_bsc_message_payload->combined.page_payload, + &(p_profile->page_comb_0)); + bsc_sens_event = (ant_bsc_evt_t) ANT_BSC_COMB_PAGE_0_UPDATED; + } + else + { + p_bsc_message_payload->speed_or_cadence.page_number = next_page_number_get(p_profile); + p_bsc_message_payload->speed_or_cadence.toggle_bit = p_profile->_cb.p_sens_cb->toggle_bit; + NRF_LOG_INFO("BSC TX Page number: %u\r\n", + p_bsc_message_payload->speed_or_cadence.page_number); + + ant_bsc_page_0_encode(p_bsc_message_payload->speed_or_cadence.page_payload, + &(p_profile->page_0)); + bsc_sens_event = (ant_bsc_evt_t) p_bsc_message_payload->speed_or_cadence.page_number; + + switch (p_bsc_message_payload->speed_or_cadence.page_number) + { + case ANT_BSC_PAGE_0: + // No implementation needed + break; + case ANT_BSC_PAGE_1: + ant_bsc_page_1_encode(p_bsc_message_payload->speed_or_cadence.page_payload, + &(p_profile->page_1)); + break; + case ANT_BSC_PAGE_2: + ant_bsc_page_2_encode(p_bsc_message_payload->speed_or_cadence.page_payload, + &(p_profile->page_2)); + break; + case ANT_BSC_PAGE_3: + ant_bsc_page_3_encode(p_bsc_message_payload->speed_or_cadence.page_payload, + &(p_profile->page_3)); + break; + case ANT_BSC_PAGE_4: + ant_bsc_page_4_encode(p_bsc_message_payload->speed_or_cadence.page_payload, + &(p_profile->page_4)); + break; + case ANT_BSC_PAGE_5: + ant_bsc_page_5_encode(p_bsc_message_payload->speed_or_cadence.page_payload, + &(p_profile->page_5)); + break; + default: + // No implementation needed + break; + } + } + + p_profile->evt_handler(p_profile, bsc_sens_event); +} + +/**@brief Function for setting payload for ANT message and sending it. + * + * @param[in] p_profile Pointer to the profile instance. + */ +static void ant_message_send(ant_bsc_profile_t * p_profile) +{ + uint8_t p_message_payload[ANT_STANDARD_DATA_PAYLOAD_SIZE]; + uint32_t err_code; + + sens_message_encode(p_profile, p_message_payload); + err_code = sd_ant_broadcast_message_tx(p_profile->channel_number, + sizeof(p_message_payload), + p_message_payload); + APP_ERROR_CHECK(err_code); +} + +void ant_bsc_sens_evt_handler(ant_bsc_profile_t * p_profile, + ant_evt_t * p_ant_event) +{ + if (p_ant_event->channel == p_profile->channel_number) + { + switch (p_ant_event->event) + { + case EVENT_TX: + ant_message_send(p_profile); + break; + + default: + break; + } + } +} + +ret_code_t ant_bsc_disp_open(ant_bsc_profile_t * p_profile) +{ + ASSERT(p_profile != NULL); + + NRF_LOG_INFO("ANT BSC channel %u open\r\n", p_profile->channel_number); + return sd_ant_channel_open(p_profile->channel_number); +} + +ret_code_t ant_bsc_sens_open(ant_bsc_profile_t * p_profile) +{ + ASSERT(p_profile != NULL); + + // Fill tx buffer for the first frame + ant_message_send(p_profile); + + NRF_LOG_INFO("ANT BSC channel %u open\r\n", p_profile->channel_number); + return sd_ant_channel_open(p_profile->channel_number); +} + +/**@brief Function for decoding BSC message. + * + * @param[in,out] p_profile Pointer to the profile instance. + * @param[in] p_message_payload Pointer to the message payload structure. + * + * @note Assume to be call each time when Rx window will occur. + */ +static void disp_message_decode(ant_bsc_profile_t * p_profile, uint8_t * p_message_payload) +{ + const ant_bsc_message_layout_t * p_bsc_message_payload = + (ant_bsc_message_layout_t *)p_message_payload; + ant_bsc_evt_t bsc_disp_event; + + if (p_profile->_cb.p_disp_cb->device_type == BSC_COMBINED_DEVICE_TYPE) + { + NRF_LOG_INFO("BSC RX Page Number: \"Combined Speed & Cadence Page\"\r\n"); + ant_bsc_combined_page_0_decode(p_bsc_message_payload->combined.page_payload, + &(p_profile->page_comb_0)); + bsc_disp_event = (ant_bsc_evt_t) ANT_BSC_COMB_PAGE_0_UPDATED; + } + else + { + NRF_LOG_INFO("BSC RX Page Number: %u\r\n", + p_bsc_message_payload->speed_or_cadence.page_number); + ant_bsc_page_0_decode(p_bsc_message_payload->speed_or_cadence.page_payload, + &(p_profile->page_0)); // Page 0 is present in each message + bsc_disp_event = (ant_bsc_evt_t) p_bsc_message_payload->speed_or_cadence.page_number; + + switch (p_bsc_message_payload->speed_or_cadence.page_number) + { + case ANT_BSC_PAGE_0: + // No implementation needed + break; + + case ANT_BSC_PAGE_1: + ant_bsc_page_1_decode(p_bsc_message_payload->speed_or_cadence.page_payload, + &(p_profile->page_1)); + break; + + case ANT_BSC_PAGE_2: + ant_bsc_page_2_decode(p_bsc_message_payload->speed_or_cadence.page_payload, + &(p_profile->page_2)); + break; + + case ANT_BSC_PAGE_3: + ant_bsc_page_3_decode(p_bsc_message_payload->speed_or_cadence.page_payload, + &(p_profile->page_3)); + break; + + case ANT_BSC_PAGE_4: + ant_bsc_page_4_decode(p_bsc_message_payload->speed_or_cadence.page_payload, + &(p_profile->page_4)); + break; + + case ANT_BSC_PAGE_5: + ant_bsc_page_5_decode(p_bsc_message_payload->speed_or_cadence.page_payload, + &(p_profile->page_5)); + break; + + default: + // No implementation needed + break; + } + } + + p_profile->evt_handler(p_profile, bsc_disp_event); +} + +void ant_bsc_disp_evt_handler(ant_bsc_profile_t * p_profile, + ant_evt_t * p_ant_event) +{ + if (p_ant_event->channel == p_profile->channel_number) + { + ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->msg.evt_buffer; + switch (p_ant_event->event) + { + case EVENT_RX: + + if (p_message->ANT_MESSAGE_ucMesgID == MESG_BROADCAST_DATA_ID + || p_message->ANT_MESSAGE_ucMesgID == MESG_ACKNOWLEDGED_DATA_ID + || p_message->ANT_MESSAGE_ucMesgID == MESG_BURST_DATA_ID) + { + disp_message_decode(p_profile, p_message->ANT_MESSAGE_aucPayload); + } + break; + default: + break; + } + } +} + +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/ant_bsc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/ant_bsc.h new file mode 100644 index 0000000000000000000000000000000000000000..9cf8d537a6de288ca465b29c6a54c15e671b338a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/ant_bsc.h @@ -0,0 +1,361 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ant_bsc Bicycle Speed and Cadence profile + * @{ + * @ingroup ant_sdk_profiles + * @brief This module implements the Bicycle Speed and Cadence profile. + * + */ + +#ifndef ANT_BSC_H__ +#define ANT_BSC_H__ + +#include +#include +#include "sdk_errors.h" +#include "ant_parameters.h" +#include "ant_stack_handler_types.h" +#include "ant_channel_config.h" +#include "ant_bsc_pages.h" + +#define BSC_ANTPLUS_RF_FREQ 0x39u ///< Frequency, decimal 57 (2457 MHz). + +#define BSC_SPEED_DEVICE_TYPE 0x7B ///< Device type reserved for ANT+ bike speed sensor. +#define BSC_CADENCE_DEVICE_TYPE 0x7A ///< Device type reserved for ANT+ bike cadence sensor. +#define BSC_COMBINED_DEVICE_TYPE 0x79 ///< Device type reserved for ANT+ bike combined speed and cadence sensor. + +#define BSC_MSG_PERIOD_4Hz 1u ///< Message period, 4 Hz (in basic period counts, where basic period time = 0.25 s). +#define BSC_MSG_PERIOD_2Hz 2u ///< Message period, 2 Hz (in basic period counts). +#define BSC_MSG_PERIOD_1Hz 4u ///< Message period, 1 Hz (in basic period counts). +#define BSC_MSG_PERIOD_SPEED 0x1FB6u ///< Message period in ticks, decimal 8118 (4.04 Hz). +#define BSC_MSG_PERIOD_CADENCE 0x1FA6u ///< Message period in ticks, decimal 8102 (4.04 Hz). +#define BSC_MSG_PERIOD_COMBINED 0x1F96u ///< Message period in ticks, decimal 8086 (4.05 Hz). + + +#define BSC_EXT_ASSIGN 0x00 ///< ANT ext assign (see Ext. Assign Channel Parameters in ant_parameters.h: @ref ant_parameters). +#define BSC_DISP_CHANNEL_TYPE CHANNEL_TYPE_SLAVE_RX_ONLY ///< Display BSC channel type. +#define BSC_SENS_CHANNEL_TYPE CHANNEL_TYPE_MASTER ///< Sensor BSC channel type. + + +/**@brief Select the basic ANT channel period (in ticks) for the BSC profile depending on the device type. + * + * @param[in] DEVICE_TYPE Type of device. Supported types: @ref BSC_SPEED_DEVICE_TYPE, @ref BSC_CADENCE_DEVICE_TYPE, + * @ref BSC_COMBINED_DEVICE_TYPE. + */ +#define BSC_DEVICE_TICKS(DEVICE_TYPE) \ + ((DEVICE_TYPE) == (BSC_SPEED_DEVICE_TYPE) ? (BSC_MSG_PERIOD_SPEED) : \ + ((DEVICE_TYPE) == (BSC_CADENCE_DEVICE_TYPE) ? (BSC_MSG_PERIOD_CADENCE) : \ + ((DEVICE_TYPE) == (BSC_COMBINED_DEVICE_TYPE) ? (BSC_MSG_PERIOD_COMBINED) : 0u))) + +/**@brief Calculate the channel period (in ticks) depending on the device type and the chosen message frequency. + * + * @param[in] DEVICE_TYPE Type of device. Supported types: @ref BSC_SPEED_DEVICE_TYPE, @ref BSC_CADENCE_DEVICE_TYPE, + * @ref BSC_COMBINED_DEVICE_TYPE. + * @param[in] BSC_MSG_PERIOD Channel data period. The BSC profile supports only the following periods: + * @ref BSC_MSG_PERIOD_4Hz, @ref BSC_MSG_PERIOD_2Hz, @ref BSC_MSG_PERIOD_1Hz. + */ +#define BSC_PERIOD_TICKS(DEVICE_TYPE, BSC_MSG_PERIOD) \ + ((BSC_DEVICE_TICKS(DEVICE_TYPE)) * (BSC_MSG_PERIOD)) + +/**@brief Initialize an ANT channel configuration structure for the BSC profile (Display). + * + * @param[in] NAME Name of related instance. + * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance. + * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance. + * @param[in] DEVICE_TYPE Type of device. Supported types: @ref BSC_SPEED_DEVICE_TYPE, @ref BSC_CADENCE_DEVICE_TYPE, + * @ref BSC_COMBINED_DEVICE_TYPE. + * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance. + * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance. + * @param[in] BSC_MSG_PERIOD Channel data frequency in Hz. The BSC profile supports only the following frequencies: + * @ref BSC_MSG_PERIOD_4Hz, @ref BSC_MSG_PERIOD_2Hz, @ref BSC_MSG_PERIOD_1Hz. + */ +#define BSC_DISP_CHANNEL_CONFIG_DEF(NAME, \ + CHANNEL_NUMBER, \ + TRANSMISSION_TYPE, \ + DEVICE_TYPE, \ + DEVICE_NUMBER, \ + NETWORK_NUMBER, \ + BSC_MSG_PERIOD) \ +static const ant_channel_config_t NAME##_channel_bsc_disp_config = \ + { \ + .channel_number = (CHANNEL_NUMBER), \ + .channel_type = BSC_DISP_CHANNEL_TYPE, \ + .ext_assign = BSC_EXT_ASSIGN, \ + .rf_freq = BSC_ANTPLUS_RF_FREQ, \ + .transmission_type = (TRANSMISSION_TYPE), \ + .device_type = (DEVICE_TYPE), \ + .device_number = (DEVICE_NUMBER), \ + .channel_period = BSC_PERIOD_TICKS(DEVICE_TYPE, BSC_MSG_PERIOD), \ + .network_number = (NETWORK_NUMBER), \ + } +#define BSC_DISP_CHANNEL_CONFIG(NAME) &NAME##_channel_bsc_disp_config + +/**@brief Initialize an ANT channel configuration structure for the BSC profile (Transmitter). + * + * @param[in] NAME Name of related instance. + * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance. + * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance. + * @param[in] DEVICE_TYPE Type of device. Supported types: @ref BSC_SPEED_DEVICE_TYPE, @ref BSC_CADENCE_DEVICE_TYPE, + * @ref BSC_COMBINED_DEVICE_TYPE. + * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance. + * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance. + */ +#define BSC_SENS_CHANNEL_CONFIG_DEF(NAME, \ + CHANNEL_NUMBER, \ + TRANSMISSION_TYPE, \ + DEVICE_TYPE, \ + DEVICE_NUMBER, \ + NETWORK_NUMBER) \ +static const ant_channel_config_t NAME##_channel_bsc_sens_config = \ + { \ + .channel_number = (CHANNEL_NUMBER), \ + .channel_type = BSC_SENS_CHANNEL_TYPE, \ + .ext_assign = BSC_EXT_ASSIGN, \ + .rf_freq = BSC_ANTPLUS_RF_FREQ, \ + .transmission_type = (TRANSMISSION_TYPE), \ + .device_type = (DEVICE_TYPE), \ + .device_number = (DEVICE_NUMBER), \ + .channel_period = BSC_PERIOD_TICKS(DEVICE_TYPE, BSC_MSG_PERIOD_4Hz), \ + .network_number = (NETWORK_NUMBER), \ + } +#define BSC_SENS_CHANNEL_CONFIG(NAME) &NAME##_channel_bsc_sens_config + +/**@brief Initialize an ANT profile configuration structure for the BSC profile (Display). + * + * @param[in] NAME Name of related instance. + * @param[in] EVT_HANDLER Event handler to be called for handling events in the BSC profile. + */ +#define BSC_DISP_PROFILE_CONFIG_DEF(NAME, \ + EVT_HANDLER) \ +static ant_bsc_disp_cb_t NAME##_bsc_disp_cb; \ +static const ant_bsc_disp_config_t NAME##_profile_bsc_disp_config = \ + { \ + .p_cb = &NAME##_bsc_disp_cb, \ + .evt_handler = (EVT_HANDLER), \ + } +#define BSC_DISP_PROFILE_CONFIG(NAME) &NAME##_profile_bsc_disp_config + +/**@brief Initialize an ANT profile configuration structure for the BSC profile (Sensor). + * + * @param[in] NAME Name of related instance. + * @param[in] PAGE_1_PRESENT Determines whether page 1 is included. + * @param[in] PAGE_4_PRESENT Determines whether page 4 is included. + * @param[in] MAIN_PAGE_NUMBER Determines the main data page (@ref ANT_BSC_PAGE_0 or @ref ANT_BSC_PAGE_5 or @ref ANT_BSC_COMB_PAGE_0). + * @param[in] EVT_HANDLER Event handler to be called for handling events in the BSC profile. + */ +#define BSC_SENS_PROFILE_CONFIG_DEF(NAME, \ + PAGE_1_PRESENT, \ + PAGE_4_PRESENT, \ + MAIN_PAGE_NUMBER, \ + EVT_HANDLER) \ +static ant_bsc_sens_cb_t NAME##_bsc_sens_cb; \ +static const ant_bsc_sens_config_t NAME##_profile_bsc_sens_config = \ + { \ + .page_1_present = (PAGE_1_PRESENT), \ + .page_4_present = (PAGE_4_PRESENT), \ + .main_page_number = (MAIN_PAGE_NUMBER), \ + .p_cb = &NAME##_bsc_sens_cb, \ + .evt_handler = (EVT_HANDLER), \ + } +#define BSC_SENS_PROFILE_CONFIG(NAME) &NAME##_profile_bsc_sens_config + +/**@brief BSC page number type. */ +typedef enum{ + ANT_BSC_PAGE_0, ///< Main data page number 0. + ANT_BSC_PAGE_1, ///< Background data page number 1. This page is optional. + ANT_BSC_PAGE_2, ///< Background data page number 2. + ANT_BSC_PAGE_3, ///< Background data page number 3. + ANT_BSC_PAGE_4, ///< Background data page number 4. This page is optional. + ANT_BSC_PAGE_5, ///< Main data page number 5. This page is optional. + ANT_BSC_COMB_PAGE_0 ///< Main data page number 0 for combined speed and cadence sensor. +} ant_bsc_page_t; + +/**@brief BSC profile event type. */ +typedef enum{ + ANT_BSC_PAGE_0_UPDATED = ANT_BSC_PAGE_0, ///< Data page 0 has been updated (Display) or sent (Sensor). + ANT_BSC_PAGE_1_UPDATED = ANT_BSC_PAGE_1, ///< Data page 0 and page 1 have been updated (Display) or sent (Sensor). + ANT_BSC_PAGE_2_UPDATED = ANT_BSC_PAGE_2, ///< Data page 0 and page 2 have been updated (Display) or sent (Sensor). + ANT_BSC_PAGE_3_UPDATED = ANT_BSC_PAGE_3, ///< Data page 0 and page 3 have been updated (Display) or sent (Sensor). + ANT_BSC_PAGE_4_UPDATED = ANT_BSC_PAGE_4, ///< Data page 0 and page 4 have been updated (Display) or sent (Sensor). + ANT_BSC_PAGE_5_UPDATED = ANT_BSC_PAGE_5, ///< Data page 0 and page 5 have been updated (Display) or sent (Sensor). + ANT_BSC_COMB_PAGE_0_UPDATED = ANT_BSC_COMB_PAGE_0, ///< Combined Speed and cadence data page has been updated (Display) or sent (Sensor). +} ant_bsc_evt_t; + +// Forward declaration of the ant_bsc_profile_t type. +typedef struct ant_bsc_profile_s ant_bsc_profile_t; + +/**@brief BSC event handler type. */ +typedef void (* ant_bsc_evt_handler_t) (ant_bsc_profile_t *, ant_bsc_evt_t); + +#include "ant_bsc_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief BSC Display configuration structure. */ +typedef struct +{ + ant_bsc_disp_cb_t * p_cb; ///< Pointer to the data buffer for internal use. + ant_bsc_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the BSC profile. +} ant_bsc_disp_config_t; + +/**@brief BSC Sensor configuration structure. */ +typedef struct +{ + bool page_1_present; ///< Determines whether page 1 is included. + bool page_4_present; ///< Determines whether page 4 is included. + ant_bsc_page_t main_page_number; ///< Determines the main data page (@ref ANT_BSC_PAGE_0 or @ref ANT_BSC_PAGE_5 or @ref ANT_BSC_COMB_PAGE_0). + ant_bsc_sens_cb_t * p_cb; ///< Pointer to the data buffer for internal use. + ant_bsc_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the BSC profile. +} ant_bsc_sens_config_t; + +/**@brief BSC profile structure. */ +struct ant_bsc_profile_s +{ + uint8_t channel_number; ///< Channel number assigned to the profile. + union { + ant_bsc_disp_cb_t * p_disp_cb; + ant_bsc_sens_cb_t * p_sens_cb; + } _cb; ///< Pointer to internal control block. + ant_bsc_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the BSC profile. + ant_bsc_page0_data_t page_0; ///< Page 0. + ant_bsc_page1_data_t page_1; ///< Page 1. + ant_bsc_page2_data_t page_2; ///< Page 2. + ant_bsc_page3_data_t page_3; ///< Page 3. + ant_bsc_page4_data_t page_4; ///< Page 4. + ant_bsc_page5_data_t page_5; ///< Page 5. + ant_bsc_combined_page0_data_t page_comb_0; ///< Page 0 for combined speed and cadence sensor. +}; + +/** @name Defines for accessing ant_bsc_profile_t member variables +@{ */ +#define BSC_PROFILE_event_time page_0.event_time +#define BSC_PROFILE_rev_count page_0.rev_count +#define BSC_PROFILE_operating_time page_1.operating_time +#define BSC_PROFILE_manuf_id page_2.manuf_id +#define BSC_PROFILE_serial_num page_2.serial_num +#define BSC_PROFILE_hw_version page_3.hw_version +#define BSC_PROFILE_sw_version page_3.sw_version +#define BSC_PROFILE_model_num page_3.model_num +#define BSC_PROFILE_fract_bat_volt page_4.fract_bat_volt +#define BSC_PROFILE_coarse_bat_volt page_4.coarse_bat_volt +#define BSC_PROFILE_bat_status page_4.bat_status +#define BSC_PROFILE_stop_indicator page_5.stop_indicator +#define BSC_PROFILE_cadence_event_time page_comb_0.cadence_event_time +#define BSC_PROFILE_cadence_rev_count page_comb_0.cadence_rev_count +#define BSC_PROFILE_speed_event_time page_comb_0.speed_event_time +#define BSC_PROFILE_speed_rev_count page_comb_0.speed_rev_count +/** @} */ + +/**@brief Function for initializing the ANT BSC profile instance. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_channel_config Pointer to the ANT channel configuration structure. + * @param[in] p_disp_config Pointer to the BSC display configuration structure. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. + */ +ret_code_t ant_bsc_disp_init(ant_bsc_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_bsc_disp_config_t const * p_disp_config); + +/**@brief Function for initializing the ANT BSC profile instance. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_channel_config Pointer to the ANT channel configuration structure. + * @param[in] p_sens_config Pointer to the BSC sensor configuration structure. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. + */ +ret_code_t ant_bsc_sens_init(ant_bsc_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_bsc_sens_config_t const * p_sens_config); + +/**@brief Function for opening the profile instance channel for the ANT BSC Display. + * + * Before calling this function, pages should be configured. + * + * @param[in] p_profile Pointer to the profile instance. + * + * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned. + */ +ret_code_t ant_bsc_disp_open(ant_bsc_profile_t * p_profile); + +/**@brief Function for opening the profile instance channel for the ANT BSC Sensor. + * + * Before calling this function, pages should be configured. + * + * @param[in] p_profile Pointer to the profile instance. + * + * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned. + */ +ret_code_t ant_bsc_sens_open(ant_bsc_profile_t * p_profile); + +/**@brief Function for handling the Sensor ANT events. + * + * @details This function handles all events from the ANT stack that are of interest to the Bicycle Speed and Cadence Sensor profile. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_ant_event Event received from the ANT stack. + */ +void ant_bsc_sens_evt_handler(ant_bsc_profile_t * p_profile, + ant_evt_t * p_ant_event); + +/**@brief Function for handling the Display ANT events. + * + * @details This function handles all events from the ANT stack that are of interest to the Bicycle Speed and Cadence Display profile. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_ant_event Event received from the ANT stack. + */ +void ant_bsc_disp_evt_handler(ant_bsc_profile_t * p_profile, + ant_evt_t * p_ant_event); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BSC_H__ +/** @} */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/ant_bsc_local.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/ant_bsc_local.h new file mode 100644 index 0000000000000000000000000000000000000000..2d56cac03450f4811c7e4814f9dbc6bf7434a6ff --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/ant_bsc_local.h @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BSC_LOCAL_H__ +#define ANT_BSC_LOCAL_H__ + +#include +#include +#include "ant_bsc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup ant_bsc + * @{ + */ + +/**@brief BSC Sensor control block. */ +typedef struct +{ + uint8_t device_type; + uint8_t toggle_bit : 1; + ant_bsc_page_t main_page_number : 7; + uint8_t page_1_present : 1; + uint8_t page_4_present : 1; + ant_bsc_page_t bkgd_page_number : 6; + uint8_t message_counter; +}ant_bsc_sens_cb_t; + +/**@brief BSC Display control block. */ +typedef struct +{ + uint8_t device_type; +}ant_bsc_disp_cb_t; + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BSC_LOCAL_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.c new file mode 100644 index 0000000000000000000000000000000000000000..1f2937919f78b836fd1c6ff3239b5d1c2f5f645f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.c @@ -0,0 +1,128 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + +#include "ant_bsc_combined_page_0.h" +#include "ant_bsc_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_BCS_COMBINED_PAGE_0" +#if ANT_BSC_COMBINED_PAGE_0_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_COMBINED_PAGE_0_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_COMBINED_PAGE_0_INFO_COLOR +#else // ANT_BSC_COMBINED_PAGE_0_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_COMBINED_PAGE_0_LOG_ENABLED +#include "nrf_log.h" + +/**@brief BSC page 0 data layout structure. */ +typedef struct +{ + uint8_t cadence_evt_time_LSB; + uint8_t cadence_evt_time_MSB; + uint8_t cadence_rev_count_LSB; + uint8_t cadence_rev_count_MSB; + uint8_t speed_evt_time_LSB; + uint8_t speed_evt_time_MSB; + uint8_t speed_rev_count_LSB; + uint8_t speed_rev_count_MSB; +}ant_bsc_combined_page0_data_layout_t; + +/**@brief Function for printing combined speed and cadence page0 data. */ +static void comb_page0_data_log(ant_bsc_combined_page0_data_t const * p_page_data) +{ + NRF_LOG_INFO("Cadence Revolution count: %u\r\n", + (unsigned int)p_page_data->cadence_rev_count); + + NRF_LOG_INFO("Cadence event time: %u.%03us\r\n", + (unsigned int)ANT_BSC_EVENT_TIME_SEC(p_page_data->cadence_event_time), + (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->cadence_event_time)); + + NRF_LOG_INFO("Speed Revolution count: %u\r\n", + (unsigned int)p_page_data->speed_rev_count); + + NRF_LOG_INFO("Speed event time: %u.%03us\r\n\n", + (unsigned int)ANT_BSC_EVENT_TIME_SEC(p_page_data->speed_event_time), + (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->speed_event_time)); +} + +void ant_bsc_combined_page_0_encode(uint8_t * p_page_buffer, ant_bsc_combined_page0_data_t const * p_page_data) +{ + ant_bsc_combined_page0_data_layout_t * p_outcoming_data = (ant_bsc_combined_page0_data_layout_t *) p_page_buffer; + + uint16_t cadence_event_time = p_page_data->cadence_event_time; + uint16_t cadence_rev_count = p_page_data->cadence_rev_count; + uint16_t speed_event_time = p_page_data->speed_event_time; + uint16_t speed_rev_count = p_page_data->speed_rev_count; + + p_outcoming_data->cadence_evt_time_LSB = (uint8_t)(cadence_event_time & UINT8_MAX); + p_outcoming_data->cadence_evt_time_MSB = (uint8_t)((cadence_event_time >> 8) & UINT8_MAX); + p_outcoming_data->cadence_rev_count_LSB = (uint8_t)(cadence_rev_count & UINT8_MAX); + p_outcoming_data->cadence_rev_count_MSB = (uint8_t)((cadence_rev_count >> 8) & UINT8_MAX); + p_outcoming_data->speed_evt_time_LSB = (uint8_t)(speed_event_time & UINT8_MAX); + p_outcoming_data->speed_evt_time_MSB = (uint8_t)((speed_event_time >> 8) & UINT8_MAX); + p_outcoming_data->speed_rev_count_LSB = (uint8_t)(speed_rev_count & UINT8_MAX); + p_outcoming_data->speed_rev_count_MSB = (uint8_t)((speed_rev_count >> 8) & UINT8_MAX); + + comb_page0_data_log(p_page_data); +} + +void ant_bsc_combined_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_combined_page0_data_t * p_page_data) +{ + ant_bsc_combined_page0_data_layout_t const * p_incoming_data = (ant_bsc_combined_page0_data_layout_t *)p_page_buffer; + + uint16_t cadence_event_time = (uint16_t)((p_incoming_data->cadence_evt_time_MSB << 8) + + p_incoming_data->cadence_evt_time_LSB); + uint16_t cadence_revolution_count = (uint16_t) ((p_incoming_data->cadence_rev_count_MSB << 8) + + p_incoming_data->cadence_rev_count_LSB); + uint16_t speed_event_time = (uint16_t)((p_incoming_data->speed_evt_time_MSB << 8) + + p_incoming_data->speed_evt_time_LSB); + uint16_t speed_revolution_count = (uint16_t) ((p_incoming_data->speed_rev_count_MSB << 8) + + p_incoming_data->speed_rev_count_LSB); + + p_page_data->cadence_event_time = cadence_event_time; + p_page_data->cadence_rev_count = cadence_revolution_count; + p_page_data->speed_event_time = speed_event_time; + p_page_data->speed_rev_count = speed_revolution_count; + + comb_page0_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.h new file mode 100644 index 0000000000000000000000000000000000000000..b6e68347cf0d2bf3ff3eef55cafb66ca40ab3c82 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.h @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BSC_COMBINED_PAGE_0_H__ +#define ANT_BSC_COMBINED_PAGE_0_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bsc_combined_page0 BSC profile page 0 (combined speed & cadence) + * @{ + * @ingroup ant_sdk_profiles_bsc_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for Bicycle Combined Speed and Cadence data page 0. + * + * This structure is used as a common page. + */ +typedef struct +{ + uint16_t cadence_event_time; ///< Cadence event time. + uint16_t cadence_rev_count; ///< Cadence revolution count. + uint16_t speed_event_time; ///< Speed event time. + uint16_t speed_rev_count; ///< Speed revolution count. +} ant_bsc_combined_page0_data_t; + +/**@brief Initialize page 0. + */ +#define DEFAULT_ANT_BSC_COMBINED_PAGE0() \ + (ant_bsc_combined_page0_data_t) \ + { \ + .cadence_event_time = 0, \ + .cadence_rev_count = 0, \ + .speed_event_time = 0, \ + .speed_rev_count = 0, \ + } + +/**@brief Function for encoding page 0. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bsc_combined_page_0_encode(uint8_t * p_page_buffer, ant_bsc_combined_page0_data_t const * p_page_data); + +/**@brief Function for decoding page 0. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_bsc_combined_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_combined_page0_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BSC_COMBINED_PAGE_0_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.c new file mode 100644 index 0000000000000000000000000000000000000000..ab56d6b73448176112eab809ceaab8a83ef5bb8b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.c @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + +#include "ant_bsc_page_0.h" +#include "ant_bsc_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_BCS_PAGE_0" +#if ANT_BSC_PAGE_0_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_PAGE_0_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_0_INFO_COLOR +#else // ANT_BSC_PAGE_0_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_PAGE_0_LOG_ENABLED +#include "nrf_log.h" + +/**@brief BSC page 0 data layout structure. */ +typedef struct +{ + uint8_t reserved[3]; + uint8_t bsc_evt_time_LSB; + uint8_t bsc_evt_time_MSB; + uint8_t bsc_rev_count_LSB; + uint8_t bsc_rev_count_MSB; +}ant_bsc_page0_data_layout_t; + +/**@brief Function for printing speed or cadence page0 data. */ +static void page0_data_log(ant_bsc_page0_data_t const * p_page_data) +{ + NRF_LOG_INFO("Revolution count: %u\r\n", (unsigned int)p_page_data->rev_count); + + NRF_LOG_INFO("BSC event time: %u.%03us\r\n", + (unsigned int)ANT_BSC_EVENT_TIME_SEC(p_page_data->event_time), + (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->event_time)); + +// NRF_LOG_INFO("%03us\r\n", (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->event_time)); +} + +void ant_bsc_page_0_encode(uint8_t * p_page_buffer, ant_bsc_page0_data_t const * p_page_data) +{ + ant_bsc_page0_data_layout_t * p_outcoming_data = (ant_bsc_page0_data_layout_t *) p_page_buffer; + uint16_t event_time = p_page_data->event_time; + uint16_t rev_count = p_page_data->rev_count; + + p_outcoming_data->reserved[0] = UINT8_MAX; + p_outcoming_data->reserved[1] = UINT8_MAX; + p_outcoming_data->reserved[2] = UINT8_MAX; + p_outcoming_data->bsc_evt_time_LSB = (uint8_t)(event_time & UINT8_MAX); + p_outcoming_data->bsc_evt_time_MSB = (uint8_t)((event_time >> 8) & UINT8_MAX); + p_outcoming_data->bsc_rev_count_LSB = (uint8_t)(rev_count & UINT8_MAX); + p_outcoming_data->bsc_rev_count_MSB = (uint8_t)((rev_count >> 8) & UINT8_MAX); + + page0_data_log(p_page_data); +} + +void ant_bsc_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_page0_data_t * p_page_data) +{ + ant_bsc_page0_data_layout_t const * p_incoming_data = (ant_bsc_page0_data_layout_t *)p_page_buffer; + + uint16_t event_time = (uint16_t)((p_incoming_data->bsc_evt_time_MSB << 8) + + p_incoming_data->bsc_evt_time_LSB); + + uint16_t revolution_count = (uint16_t) ((p_incoming_data->bsc_rev_count_MSB << 8) + + p_incoming_data->bsc_rev_count_LSB); + + p_page_data->event_time = event_time; + p_page_data->rev_count = revolution_count; + + page0_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.h new file mode 100644 index 0000000000000000000000000000000000000000..d3362c14367d75eb3b19fc0e52411234b919864a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.h @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BSC_PAGE_0_H__ +#define ANT_BSC_PAGE_0_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bsc_page0 BSC profile page 0 + * @{ + * @ingroup ant_sdk_profiles_bsc_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for BSC data page 0. + * + * This structure is used as a common page. + */ +typedef struct +{ + uint16_t event_time; ///< Speed or cadence event time. + uint16_t rev_count; ///< Speed or cadence revolution count. +} ant_bsc_page0_data_t; + +/**@brief Initialize page 0. + */ +#define DEFAULT_ANT_BSC_PAGE0() \ + (ant_bsc_page0_data_t) \ + { \ + .event_time = 0, \ + .rev_count = 0 \ + } + +/**@brief Function for encoding page 0. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bsc_page_0_encode(uint8_t * p_page_buffer, ant_bsc_page0_data_t const * p_page_data); + +/**@brief Function for decoding page 0. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_bsc_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_page0_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BSC_PAGE_0_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.c new file mode 100644 index 0000000000000000000000000000000000000000..7961f9ff5e7f96f4c4dcdd6f719c46b4ae9b240c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.c @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + +#include "ant_bsc_page_1.h" +#include "ant_bsc_utils.h" +#include "app_util.h" +#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "ANT_BCS_PAGE_1" +#if ANT_BSC_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_PAGE_1_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_1_INFO_COLOR +#else // ANT_BSC_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_PAGE_1_LOG_ENABLED +#include "nrf_log.h" + +/**@brief BSC page 1 data layout structure. */ +typedef struct +{ + uint8_t cumulative_operating_time[3]; + uint8_t reserved[4]; +}ant_bsc_page1_data_layout_t; + +/**@brief Function for printing speed or cadence page1 data. */ +static void page1_data_log(ant_bsc_page1_data_t const * p_page_data) +{ + NRF_LOG_INFO("Cumulative operating time: %ud %uh %um %us\r\n", + (unsigned int)ANT_BSC_OPERATING_DAYS(p_page_data->operating_time), + (unsigned int)ANT_BSC_OPERATING_HOURS(p_page_data->operating_time), + (unsigned int)ANT_BSC_OPERATING_MINUTES(p_page_data->operating_time), + (unsigned int)ANT_BSC_OPERATING_SECONDS(p_page_data->operating_time)); +} + +void ant_bsc_page_1_encode(uint8_t * p_page_buffer, ant_bsc_page1_data_t const * p_page_data) +{ + ant_bsc_page1_data_layout_t * p_outcoming_data = (ant_bsc_page1_data_layout_t *)p_page_buffer; + + UNUSED_PARAMETER(uint24_encode(p_page_data->operating_time, + p_outcoming_data->cumulative_operating_time)); + page1_data_log( p_page_data); +} + +void ant_bsc_page_1_decode(uint8_t const * p_page_buffer, ant_bsc_page1_data_t * p_page_data) +{ + ant_bsc_page1_data_layout_t const * p_incoming_data = (ant_bsc_page1_data_layout_t *)p_page_buffer; + + p_page_data->operating_time = uint24_decode(p_incoming_data->cumulative_operating_time); + + page1_data_log( p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_BSC) + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.h new file mode 100644 index 0000000000000000000000000000000000000000..4cb6bc4d4f2efdc6805fd2d7896ab150f761ab00 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.h @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BSC_PAGE_1_H__ +#define ANT_BSC_PAGE_1_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bsc_page1 BSC profile page 1 + * @{ + * @ingroup ant_sdk_profiles_bsc_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for BSC data page 1. + * + * This structure implements only page 1 specific data. + */ +typedef struct +{ + uint32_t operating_time; ///< Operating time. +} ant_bsc_page1_data_t; + +/**@brief Initialize page 1. + */ +#define DEFAULT_ANT_BSC_PAGE1() \ + (ant_bsc_page1_data_t) \ + { \ + .operating_time = 0, \ + } + +/**@brief Function for encoding page 1. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bsc_page_1_encode(uint8_t * p_page_buffer, ant_bsc_page1_data_t const * p_page_data); + +/**@brief Function for decoding page 1. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_bsc_page_1_decode(uint8_t const * p_page_buffer, ant_bsc_page1_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BSC_PAGE_1_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.c new file mode 100644 index 0000000000000000000000000000000000000000..a3a301583756d0e053967aa43097bdda11910c23 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.c @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + +#include "ant_bsc_page_2.h" + +#define NRF_LOG_MODULE_NAME "ANT_BCS_PAGE_2" +#if ANT_BSC_PAGE_2_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_PAGE_2_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_2_INFO_COLOR +#else // ANT_BSC_PAGE_2_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_PAGE_2_LOG_ENABLED +#include "nrf_log.h" + +/**@brief BSC page 2 data layout structure. */ +typedef struct +{ + uint8_t manuf_id; + uint8_t serial_num_LSB; + uint8_t serial_num_MSB; + uint8_t reserved[4]; +}ant_bsc_page2_data_layout_t; + +/**@brief Function for printing speed or cadence page2 data. */ +static void page2_data_log(ant_bsc_page2_data_t const * p_page_data) +{ + NRF_LOG_INFO("Manufacturer ID: %u\r\n", (unsigned int)p_page_data->manuf_id); + NRF_LOG_INFO("Serial No (upper 16-bits): 0x%X\r\n", + (unsigned int)p_page_data->serial_num); +} + +void ant_bsc_page_2_encode(uint8_t * p_page_buffer, ant_bsc_page2_data_t const * p_page_data) +{ + ant_bsc_page2_data_layout_t * p_outcoming_data = (ant_bsc_page2_data_layout_t *)p_page_buffer; + uint32_t serial_num = p_page_data->serial_num; + + p_outcoming_data->manuf_id = (uint8_t)p_page_data->manuf_id; + p_outcoming_data->serial_num_LSB = (uint8_t)(serial_num & UINT8_MAX); + p_outcoming_data->serial_num_MSB = (uint8_t)((serial_num >> 8) & UINT8_MAX); + + page2_data_log( p_page_data); +} + +void ant_bsc_page_2_decode(uint8_t const * p_page_buffer, ant_bsc_page2_data_t * p_page_data) +{ + ant_bsc_page2_data_layout_t const * p_incoming_data = (ant_bsc_page2_data_layout_t *)p_page_buffer; + uint32_t serial_num = (uint32_t)((p_incoming_data->serial_num_MSB << 8) + + p_incoming_data->serial_num_LSB); + + p_page_data->manuf_id = (uint32_t)p_incoming_data->manuf_id; + p_page_data->serial_num = serial_num; + + page2_data_log( p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.h new file mode 100644 index 0000000000000000000000000000000000000000..c116ca9f7315cad67dc14041aeecb16048c0fe0a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.h @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BSC_PAGE_2_H__ +#define ANT_BSC_PAGE_2_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bsc_page2 BSC profile page 2 + * @{ + * @ingroup ant_sdk_profiles_bsc_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for BSC data page 2. + * + * This structure implements only page 2 specific data. + */ +typedef struct +{ + uint8_t manuf_id; ///< Manufacturer ID. + uint16_t serial_num; ///< Serial number. +} ant_bsc_page2_data_t; + +/**@brief Initialize page 2. + */ +#define DEFAULT_ANT_BSC_PAGE2() \ + (ant_bsc_page2_data_t) \ + { \ + .manuf_id = 0, \ + .serial_num = 0, \ + } + +/**@brief Function for encoding page 2. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bsc_page_2_encode(uint8_t * p_page_buffer, ant_bsc_page2_data_t const * p_page_data); + +/**@brief Function for decoding page 2. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_bsc_page_2_decode(uint8_t const * p_page_buffer, ant_bsc_page2_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BSC_PAGE_2_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.c new file mode 100644 index 0000000000000000000000000000000000000000..1fc1082b53bb27bd7d722c828ea8298f7ab80c8b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.c @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + +#include "ant_bsc_page_3.h" + +#define NRF_LOG_MODULE_NAME "ANT_BCS_PAGE_3" +#if ANT_BSC_PAGE_3_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_PAGE_3_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_3_INFO_COLOR +#else // ANT_BSC_PAGE_3_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_PAGE_3_LOG_ENABLED +#include "nrf_log.h" + +/**@brief BSC page 3 data layout structure. */ +typedef struct +{ + uint8_t hw_version; + uint8_t sw_version; + uint8_t model_num; + uint8_t reserved[4]; +}ant_bsc_page3_data_layout_t; + +/**@brief Function for printing speed or cadence page3 data. */ +static void page3_data_log(ant_bsc_page3_data_t const * p_page_data) +{ + NRF_LOG_INFO("Hardware Rev ID: %u\r\n", (unsigned int)p_page_data->hw_version); + NRF_LOG_INFO("Model Number: %u\r\n", (unsigned int)p_page_data->model_num); + NRF_LOG_INFO("Software Ver ID: %u\r\n", (unsigned int)p_page_data->sw_version); +} + +void ant_bsc_page_3_encode(uint8_t * p_page_buffer, ant_bsc_page3_data_t const * p_page_data) +{ + ant_bsc_page3_data_layout_t * p_outcoming_data = (ant_bsc_page3_data_layout_t *)p_page_buffer; + + p_outcoming_data->hw_version = (uint8_t)p_page_data->hw_version; + p_outcoming_data->sw_version = (uint8_t)p_page_data->sw_version; + p_outcoming_data->model_num = (uint8_t)p_page_data->model_num; + + page3_data_log( p_page_data); +} + +void ant_bsc_page_3_decode(uint8_t const * p_page_buffer, ant_bsc_page3_data_t * p_page_data) +{ + ant_bsc_page3_data_layout_t const * p_incoming_data = (ant_bsc_page3_data_layout_t *)p_page_buffer; + + p_page_data->hw_version = (uint32_t)p_incoming_data->hw_version; + p_page_data->sw_version = (uint32_t)p_incoming_data->sw_version; + p_page_data->model_num = (uint32_t)p_incoming_data->model_num; + + page3_data_log( p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.h new file mode 100644 index 0000000000000000000000000000000000000000..a16e2bff90b892a72cd18ccd3f6b42d8bef86d2d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.h @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BSC_PAGE_3_H__ +#define ANT_BSC_PAGE_3_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bsc_page3 BSC profile page 3 + * @{ + * @ingroup ant_sdk_profiles_bsc_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for BSC data page 3. + * + * This structure implements only page 3 specific data. + */ +typedef struct +{ + uint8_t hw_version; ///< Hardware version. + uint8_t sw_version; ///< Software version. + uint8_t model_num; ///< Model number. +} ant_bsc_page3_data_t; + +/**@brief Initialize page 3. + */ +#define DEFAULT_ANT_BSC_PAGE3() \ + (ant_bsc_page3_data_t) \ + { \ + .hw_version = 0, \ + .sw_version = 0, \ + .model_num = 0, \ + } + +/**@brief Function for encoding page 3. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bsc_page_3_encode(uint8_t * p_page_buffer, ant_bsc_page3_data_t const * p_page_data); + +/**@brief Function for decoding page 3. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_bsc_page_3_decode(uint8_t const * p_page_buffer, ant_bsc_page3_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BSC_PAGE_3_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.c new file mode 100644 index 0000000000000000000000000000000000000000..07ec0529cab62cae3bdd8a612fa62e65c5d4b412 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.c @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + +#include "ant_bsc_page_4.h" +#include "ant_bsc_utils.h" +#include "app_util.h" + +#define NRF_LOG_MODULE_NAME "ANT_BCS_PAGE_4" +#if ANT_BSC_PAGE_4_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_PAGE_4_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_4_INFO_COLOR +#else // ANT_BSC_PAGE_4_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_PAGE_4_LOG_ENABLED +#include "nrf_log.h" + +/**@brief BSC page 4 data layout structure. */ +typedef struct +{ + uint8_t reserved_byte; + uint8_t fract_bat_volt; + uint8_t coarse_bat_volt : 4; + uint8_t bat_status : 3; + uint8_t bitfield_reserved : 1; + uint8_t reserved[4]; +}ant_bsc_page4_data_layout_t; + +/* Display precission must be updated. */ +STATIC_ASSERT(ANT_BSC_BAT_VOLTAGE_PRECISION == 1000); + +/**@brief Function for printing speed or cadence page4 data. */ +static void page4_data_log( ant_bsc_page4_data_t const * p_page_data) +{ + NRF_LOG_INFO("Battery voltage: %u.%03uV\r\n", + (unsigned int)p_page_data->coarse_bat_volt, + (unsigned int)ANT_BSC_BAT_VOLTAGE_FRACTION_MV(p_page_data->fract_bat_volt)); + NRF_LOG_INFO("Battery status: %u\r\n", (unsigned int)p_page_data->bat_status); +} + +void ant_bsc_page_4_encode(uint8_t * p_page_buffer, ant_bsc_page4_data_t const * p_page_data) +{ + ant_bsc_page4_data_layout_t * p_outcoming_data = (ant_bsc_page4_data_layout_t *)p_page_buffer; + + p_outcoming_data->reserved_byte = UINT8_MAX; + p_outcoming_data->fract_bat_volt = p_page_data->fract_bat_volt; + p_outcoming_data->coarse_bat_volt = p_page_data->coarse_bat_volt; + p_outcoming_data->bat_status = p_page_data->bat_status; + p_outcoming_data->bitfield_reserved = 0; + + page4_data_log( p_page_data); +} + +void ant_bsc_page_4_decode(uint8_t const * p_page_buffer, ant_bsc_page4_data_t * p_page_data) +{ + ant_bsc_page4_data_layout_t const * p_incoming_data = (ant_bsc_page4_data_layout_t *)p_page_buffer; + + p_page_data->fract_bat_volt = p_incoming_data->fract_bat_volt; + p_page_data->coarse_bat_volt = p_incoming_data->coarse_bat_volt; + p_page_data->bat_status = p_incoming_data->bat_status; + + page4_data_log( p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.h new file mode 100644 index 0000000000000000000000000000000000000000..7af4919dc6b3ef71144e28792e82093aa9f9b043 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.h @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BSC_PAGE_4_H__ +#define ANT_BSC_PAGE_4_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bsc_page4 BSC profile page 4 + * @{ + * @ingroup ant_sdk_profiles_bsc_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief BSC profile battery status. + * + * This enum represents possible battery status values for the ANT BSC profile. + */ +typedef enum +{ + RESERVED0 = 0, ///< Reserved. + BSC_BAT_STATUS_NEW = 1, ///< Battery status: new. + BSC_BAT_STATUS_GOOD = 2, ///< Battery status: good. + BSC_BAT_STATUS_OK = 3, ///< Battery status: ok. + BSC_BAT_STATUS_LOW = 4, ///< Battery status: low. + BSC_BAT_STATUS_CRITICAL = 5, ///< Battery status: critical. + RESERVED1 = 6, ///< Reserved. + BSC_BAT_STATUS_INVALID = 7 ///< Invalid battery status. +} ant_bsc_bat_status_t; + +/**@brief Data structure for BSC data page 4. + * + * This structure implements only page 4 specific data. + */ +typedef struct +{ + uint8_t fract_bat_volt; ///< Fractional battery voltage. + uint8_t coarse_bat_volt : 4; ///< Coarse battery voltage. + uint8_t bat_status : 3; ///< Battery status. +} ant_bsc_page4_data_t; + +/**@brief Initialize page 4. + */ +#define DEFAULT_ANT_BSC_PAGE4() \ + (ant_bsc_page4_data_t) \ + { \ + .fract_bat_volt = 0, \ + .coarse_bat_volt = 0, \ + .bat_status = BSC_BAT_STATUS_INVALID \ + } + +/**@brief Function for encoding page 4. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bsc_page_4_encode(uint8_t * p_page_buffer, ant_bsc_page4_data_t const * p_page_data); + +/**@brief Function for decoding page 4. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_bsc_page_4_decode(uint8_t const * p_page_buffer, ant_bsc_page4_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BSC_PAGE_4_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.c new file mode 100644 index 0000000000000000000000000000000000000000..cacd866c07933183a3f906befad24e130b1d3588 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.c @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + +#include "ant_bsc_page_5.h" +#include "ant_bsc_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_BCS_PAGE_5" +#if ANT_BSC_PAGE_5_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_PAGE_5_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_5_INFO_COLOR +#else // ANT_BSC_PAGE_5_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_PAGE_5_LOG_ENABLED +#include "nrf_log.h" + +/**@brief BSC profile page 5 bitfields definitions. */ +#define ANT_BSC_STOP_IND_MASK 0x01 + +/**@brief BSC page 5 data layout structure. */ +typedef struct +{ + uint8_t flags; + uint8_t reserved[6]; +}ant_bsc_page5_data_layout_t; + +/**@brief Function for printing speed or cadence page5 data. */ +static void page5_data_log(ant_bsc_page5_data_t const * p_page_data) +{ + if (p_page_data->stop_indicator) + { + NRF_LOG_INFO("Bicycle stopped.\r\n"); + } + else + { + NRF_LOG_INFO("Bicycle moving.\r\n"); + } +} + +void ant_bsc_page_5_encode(uint8_t * p_page_buffer, ant_bsc_page5_data_t const * p_page_data) +{ + ant_bsc_page5_data_layout_t * p_outcoming_data = (ant_bsc_page5_data_layout_t *)p_page_buffer; + + p_outcoming_data->flags = (uint8_t)p_page_data->stop_indicator; + + page5_data_log( p_page_data); +} + +void ant_bsc_page_5_decode(uint8_t const * p_page_buffer, ant_bsc_page5_data_t * p_page_data) +{ + ant_bsc_page5_data_layout_t const * p_incoming_data = (ant_bsc_page5_data_layout_t *)p_page_buffer; + + p_page_data->stop_indicator = (p_incoming_data->flags) & ANT_BSC_STOP_IND_MASK; + + page5_data_log( p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.h new file mode 100644 index 0000000000000000000000000000000000000000..22b250d7e6779db172ade8480cdaa5c46fe84ba4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.h @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BSC_PAGE_5_H__ +#define ANT_BSC_PAGE_5_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_bsc_page5 BSC profile page 5 + * @{ + * @ingroup ant_sdk_profiles_bsc_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for BSC data page 5. + * + * This structure implements only page 5 specific data. + */ +typedef struct +{ + uint8_t stop_indicator:1; ///< Stop indication bit. + uint8_t reserved:7; ///< Reserved. +} ant_bsc_page5_data_t; + +/**@brief Initialize page 5. + */ +#define DEFAULT_ANT_BSC_PAGE5() \ + (ant_bsc_page5_data_t) \ + { \ + .stop_indicator = 0, \ + .reserved = 0, \ + } + +/**@brief Function for encoding page 5. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_bsc_page_5_encode(uint8_t * p_page_buffer, ant_bsc_page5_data_t const * p_page_data); + +/**@brief Function for decoding page 5. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_bsc_page_5_decode(uint8_t const * p_page_buffer, ant_bsc_page5_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BSC_PAGE_5_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_pages.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_pages.h new file mode 100644 index 0000000000000000000000000000000000000000..392678c35d0277065a2883f46cad6d859ebf5cf6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_pages.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef __ANT_BSC_PAGES_H +#define __ANT_BSC_PAGES_H + +/** @file + * + * @defgroup ant_sdk_profiles_bsc_pages Bicycle Speed and Cadence profile pages + * @{ + * @ingroup ant_bsc + * @brief This module implements functions for the BSC data pages. + */ + +#include "ant_bsc_page_0.h" +#include "ant_bsc_page_1.h" +#include "ant_bsc_page_2.h" +#include "ant_bsc_page_3.h" +#include "ant_bsc_page_4.h" +#include "ant_bsc_page_5.h" +#include "ant_bsc_combined_page_0.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif // __ANT_BSC_PAGES_H +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.c new file mode 100644 index 0000000000000000000000000000000000000000..de090a0a7bb6aeaa29622320b13d7da3ffd1e608 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.c @@ -0,0 +1,280 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ant_bsc_simulator.h" +#include "ant_bsc_utils.h" +#include "app_util.h" + +#define ITERATION_ANT_CYCLES(DEVICE_TYPE) \ + (BSC_PERIOD_TICKS(DEVICE_TYPE, BSC_MSG_PERIOD_4Hz)) ///< period of calculation [1/32678 s], defined in ANT device profile + // use the same DEVICE TYPE as in profile definition +#define ITERATION_PERIOD(DEVICE_TYPE) \ + ((ITERATION_ANT_CYCLES(DEVICE_TYPE)) * 1024 / ANT_CLOCK_FREQUENCY) ///< integer part of calculation's period [1/1024 s] +#define ITERATION_FRACTION(DEVICE_TYPE) \ + ((ITERATION_ANT_CYCLES(DEVICE_TYPE)) * 1024 % ANT_CLOCK_FREQUENCY) ///< fractional part of calculation's period [1/32678 s] + +#define SPEED_SIM_MIN_VAL 0u ///< speed simulation minimum value [m/s] +#define SPEED_SIM_MAX_VAL 16u ///< speed simulation maximum value [m/s] +#define SPEED_SIM_INCREMENT 1u ///< speed simulation value increment [m/s] +#define CADENCE_SIM_MIN_VAL 70u ///< cadence simulation minimum value [rpm] +#define CADENCE_SIM_MAX_VAL 120u ///< cadence simulation maximum value [rpm] +#define CADENCE_SIM_INCREMENT 1u ///< cadence simulation value increment [rpm] +#define WHEEL_CIRCUMFERENCE 1766u ///< bike wheel circumference [mm] +#define MM_TO_METERS(MM_VAL) ((MM_VAL) / 1000u) +#define TWO_SEC_TO_TICKS 2048 ///< number of [1/1024s] ticks in 2 sec period +#define CUMULATIVE_TIME_UNIT 2 ///< cumulative time unit + +void ant_bsc_simulator_init(ant_bsc_simulator_t * p_simulator, + ant_bsc_simulator_cfg_t const * p_config, + bool auto_change) +{ + p_simulator->p_profile = p_config->p_profile; + p_simulator->_cb.auto_change = auto_change; + p_simulator->_cb.speed_sim_val = SPEED_SIM_MIN_VAL; + p_simulator->_cb.cadence_sim_val = CADENCE_SIM_MIN_VAL; + p_simulator->_cb.time_since_last_s_evt = 0; + p_simulator->_cb.fraction_since_last_s_evt = 0; + p_simulator->_cb.time_since_last_c_evt = 0; + p_simulator->_cb.fraction_since_last_c_evt = 0; + p_simulator->_cb.device_type = p_config->device_type; + + p_simulator->_cb.sensorsim_s_cfg.min = SPEED_SIM_MIN_VAL; + p_simulator->_cb.sensorsim_s_cfg.max = SPEED_SIM_MAX_VAL; + p_simulator->_cb.sensorsim_s_cfg.incr = SPEED_SIM_INCREMENT; + p_simulator->_cb.sensorsim_s_cfg.start_at_max = false; + sensorsim_init(&(p_simulator->_cb.sensorsim_s_state), + &(p_simulator->_cb.sensorsim_s_cfg)); + p_simulator->_cb.sensorsim_c_cfg.min = CADENCE_SIM_MIN_VAL; + p_simulator->_cb.sensorsim_c_cfg.max = CADENCE_SIM_MAX_VAL; + p_simulator->_cb.sensorsim_c_cfg.incr = CADENCE_SIM_INCREMENT; + p_simulator->_cb.sensorsim_c_cfg.start_at_max = false; + p_simulator->_cb.stop_cnt = 0; + sensorsim_init(&(p_simulator->_cb.sensorsim_c_state), + &(p_simulator->_cb.sensorsim_c_cfg)); +} + + +void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator) +{ + + // Set constant battery voltage + p_simulator->p_profile->BSC_PROFILE_coarse_bat_volt = 2; + p_simulator->p_profile->BSC_PROFILE_fract_bat_volt = 200; + p_simulator->p_profile->BSC_PROFILE_bat_status = BSC_BAT_STATUS_GOOD; + + // Calculate speed and cadence values + if (p_simulator->_cb.auto_change) + { + p_simulator->_cb.speed_sim_val = sensorsim_measure(&(p_simulator->_cb.sensorsim_s_state), + &(p_simulator->_cb.sensorsim_s_cfg)); + p_simulator->_cb.cadence_sim_val = sensorsim_measure(&(p_simulator->_cb.sensorsim_c_state), + &(p_simulator->_cb.sensorsim_c_cfg)); + } + else + { + p_simulator->_cb.speed_sim_val = p_simulator->_cb.sensorsim_s_state.current_val; + p_simulator->_cb.cadence_sim_val = p_simulator->_cb.sensorsim_c_state.current_val; + } + + // Simulate bicycle stopped for around 10s and go for around 5s only in auto-simulation + if (p_simulator->_cb.auto_change) + { + if ((p_simulator->p_profile->_cb.p_sens_cb->main_page_number == ANT_BSC_PAGE_5) && + (p_simulator->_cb.stop_cnt++ < 40)) + { + p_simulator->_cb.speed_sim_val = 0; + p_simulator->_cb.cadence_sim_val = 0; + } + else + { + if (p_simulator->_cb.stop_cnt == 60) + { + p_simulator->_cb.stop_cnt = 0; + } + } + } + if (p_simulator->_cb.speed_sim_val == 0) + { + p_simulator->p_profile->BSC_PROFILE_stop_indicator = 1; + } + else + { + p_simulator->p_profile->BSC_PROFILE_stop_indicator = 0; + } + + // @note: Take a local copy within scope in order to assist the compiler in variable register + // allocation. + const uint32_t computed_speed = p_simulator->_cb.speed_sim_val; + const uint32_t computed_cadence = p_simulator->_cb.cadence_sim_val; + + // @note: This implementation assumes that the current instantaneous speed/cadence can vary and this + // function is called with static frequency. + // value and the speed/cadence pulse interval is derived from it. The computation is based on 60 + // seconds in a minute and the used time base is 1/1024 seconds. + const uint32_t current_speed_pulse_interval = + MM_TO_METERS((WHEEL_CIRCUMFERENCE * 1024u) / computed_speed); + const uint32_t current_cadence_pulse_interval = (60u * 1024u) / computed_cadence; + + //update time from last evt detected + p_simulator->_cb.time_since_last_s_evt += ITERATION_PERIOD(p_simulator->_cb.device_type); + p_simulator->_cb.time_since_last_c_evt += ITERATION_PERIOD(p_simulator->_cb.device_type); + + // extended calculation by fraction make calculating accurate in long time perspective + p_simulator->_cb.fraction_since_last_s_evt += ITERATION_FRACTION(p_simulator->_cb.device_type); + p_simulator->_cb.fraction_since_last_c_evt += ITERATION_FRACTION(p_simulator->_cb.device_type); + + uint32_t add_period = p_simulator->_cb.fraction_since_last_s_evt / ANT_CLOCK_FREQUENCY; + if (add_period > 0) + { + p_simulator->_cb.time_since_last_s_evt++; + p_simulator->_cb.fraction_since_last_s_evt %= ANT_CLOCK_FREQUENCY; + } + + add_period = p_simulator->_cb.fraction_since_last_c_evt / ANT_CLOCK_FREQUENCY; + if (add_period > 0) + { + p_simulator->_cb.time_since_last_c_evt++; + p_simulator->_cb.fraction_since_last_c_evt %= ANT_CLOCK_FREQUENCY; + } + + // Calculate cumulative time based on time since last event (from profile data) in [1/1024] ticks + int16_t diff = p_simulator->p_profile->BSC_PROFILE_event_time - + p_simulator->_cb.prev_time_since_evt; + p_simulator->_cb.prev_time_since_evt = p_simulator->p_profile->BSC_PROFILE_event_time; + + if (diff >= 0) // Check for time count overflow + { + // No overflow + p_simulator->_cb.cumulative_time += diff / TWO_SEC_TO_TICKS; + p_simulator->_cb.cumulative_time_frac += diff % TWO_SEC_TO_TICKS; + } + else + { + p_simulator->_cb.cumulative_time += (UINT16_MAX + diff) / TWO_SEC_TO_TICKS; + p_simulator->_cb.cumulative_time_frac += (UINT16_MAX + diff) % TWO_SEC_TO_TICKS; + } + // Check fraction + if ((p_simulator->_cb.cumulative_time_frac / TWO_SEC_TO_TICKS) > 0) + { + p_simulator->_cb.cumulative_time += p_simulator->_cb.cumulative_time_frac / TWO_SEC_TO_TICKS; + p_simulator->_cb.cumulative_time_frac %= TWO_SEC_TO_TICKS; + } + // Update page data if necessary + if (p_simulator->_cb.cumulative_time != p_simulator->p_profile->BSC_PROFILE_operating_time) + { + p_simulator->p_profile->BSC_PROFILE_operating_time = p_simulator->_cb.cumulative_time; + } + + //calc number of events as will fill + uint32_t new_s_events = p_simulator->_cb.time_since_last_s_evt / + current_speed_pulse_interval; + uint32_t add_speed_event_time = new_s_events * current_speed_pulse_interval; + if ((new_s_events > 0) && ((p_simulator->_cb.device_type == BSC_SPEED_DEVICE_TYPE) || + (p_simulator->_cb.device_type == BSC_COMBINED_DEVICE_TYPE))) + { + p_simulator->p_profile->BSC_PROFILE_rev_count += new_s_events; + p_simulator->p_profile->BSC_PROFILE_speed_rev_count += new_s_events; + + // Current speed event time is the previous event time plus the current speed + // pulse interval. + uint32_t current_speed_event_time = p_simulator->p_profile->BSC_PROFILE_event_time + + add_speed_event_time; + // Set current event time. + p_simulator->p_profile->BSC_PROFILE_event_time = current_speed_event_time; // <- B<4,5> <- + + current_speed_event_time = p_simulator->p_profile->BSC_PROFILE_speed_event_time + + add_speed_event_time; + // Set current event time for combined device. + p_simulator->p_profile->BSC_PROFILE_speed_event_time = current_speed_event_time; + + p_simulator->_cb.time_since_last_s_evt -= add_speed_event_time; + } + + uint32_t new_c_events = p_simulator->_cb.time_since_last_c_evt / + current_cadence_pulse_interval; + uint32_t add_cadence_event_time = new_c_events * current_cadence_pulse_interval; + if ((new_c_events > 0) && ((p_simulator->_cb.device_type == BSC_CADENCE_DEVICE_TYPE) || + (p_simulator->_cb.device_type == BSC_COMBINED_DEVICE_TYPE))) + { + p_simulator->p_profile->BSC_PROFILE_rev_count += new_c_events; + p_simulator->p_profile->BSC_PROFILE_cadence_rev_count += new_c_events; + + // Current speed event time is the previous event time plus the current speed + // pulse interval. + uint32_t current_cadence_event_time = p_simulator->p_profile->BSC_PROFILE_event_time + + add_cadence_event_time; + // Set current event time. + p_simulator->p_profile->BSC_PROFILE_event_time = current_cadence_event_time; //<- B<4,5> <- + + current_cadence_event_time = p_simulator->p_profile->BSC_PROFILE_cadence_event_time + + add_cadence_event_time; + // Set current event time for combined device. + p_simulator->p_profile->BSC_PROFILE_cadence_event_time = current_cadence_event_time; + + p_simulator->_cb.time_since_last_c_evt -= add_cadence_event_time; + } +} + + +void ant_bsc_simulator_increment(ant_bsc_simulator_t * p_simulator) +{ + if (!p_simulator->_cb.auto_change) + { + // Speed + sensorsim_increment(&(p_simulator->_cb.sensorsim_s_state), + &(p_simulator->_cb.sensorsim_s_cfg)); + // Cadence + sensorsim_increment(&(p_simulator->_cb.sensorsim_c_state), + &(p_simulator->_cb.sensorsim_c_cfg)); + } +} + + +void ant_bsc_simulator_decrement(ant_bsc_simulator_t * p_simulator) +{ + if (!p_simulator->_cb.auto_change) + { + // Speed + sensorsim_decrement(&(p_simulator->_cb.sensorsim_s_state), + &(p_simulator->_cb.sensorsim_s_cfg)); + // Cadence + sensorsim_decrement(&(p_simulator->_cb.sensorsim_c_state), + &(p_simulator->_cb.sensorsim_c_cfg)); + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.h new file mode 100644 index 0000000000000000000000000000000000000000..1a283074678227ac3fb5aac1cce7a7770852a601 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.h @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BSC_SIMULATOR_H__ +#define ANT_BSC_SIMULATOR_H__ + +/** @file + * + * @defgroup ant_sdk_bsc_simulator ANT BSC simulator + * @{ + * @ingroup ant_sdk_simulators + * @brief ANT BSC simulator module. + * + * @details This module simulates a pulse for the ANT Bicycle Speed and Cadence profile. The module + * calculates abstract values, which are handled by the BSC pages data model to ensure that + * they are compatible. It provides a handler for changing the cadence and speed values manually + * as well as functionality to change the values automatically. + * + */ + +#include +#include +#include "ant_bsc.h" +#include "ant_bsc_utils.h" +#include "sensorsim.h" +#include "ant_bsc_simulator_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief BSC simulator configuration structure. */ +typedef struct +{ + ant_bsc_profile_t * p_profile; ///< Related profile. + uint8_t device_type; ///< BSC device type (must be consistent with the type chosen for the profile). Supported types: + // @ref BSC_SPEED_DEVICE_TYPE, @ref BSC_CADENCE_DEVICE_TYPE, @ref BSC_COMBINED_DEVICE_TYPE. +} ant_bsc_simulator_cfg_t; + +/**@brief BSC simulator structure. */ +typedef struct +{ + ant_bsc_profile_t * p_profile; ///< Related profile. + ant_bsc_simulator_cb_t _cb; ///< Internal control block. +} ant_bsc_simulator_t; + + +/**@brief Function for initializing the ANT BSC simulator instance. + * + * @param[in] p_simulator Pointer to the simulator instance. + * @param[in] p_config Pointer to the simulator configuration structure. + * @param[in] auto_change Enable or disable automatic changes of speed or cadence. + */ +void ant_bsc_simulator_init(ant_bsc_simulator_t * p_simulator, + ant_bsc_simulator_cfg_t const * p_config, + bool auto_change); + +/**@brief Function for simulating a device event. + * + * @details Based on this event, the transmitter data is simulated. + * + * This function should be called in the BSC Sensor event handler. + */ +void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator); + +/**@brief Function for incrementing the cadence value. + * + * @param[in] p_simulator Pointer to the simulator instance. + */ +void ant_bsc_simulator_increment(ant_bsc_simulator_t * p_simulator); + +/**@brief Function for decrementing the cadence value. + * + * @param[in] p_simulator Pointer to the simulator instance. + */ +void ant_bsc_simulator_decrement(ant_bsc_simulator_t * p_simulator); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BSC_SIMULATOR_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator_local.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator_local.h new file mode 100644 index 0000000000000000000000000000000000000000..256813bb0f522d9a57745d7e8489400ccdae6648 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator_local.h @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BSC_SIMULATOR_LOCAL_H__ +#define ANT_BSC_SIMULATOR_LOCAL_H__ + +#include +#include +#include "ant_bsc.h" +#include "sensorsim.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief BSC simulator control block structure. */ +typedef struct +{ + uint8_t device_type; + bool auto_change; ///< Cadence will change automatically (if auto_change is set) or manually. + uint16_t speed_sim_val; ///< Instantaneous speed value. + uint16_t cadence_sim_val; ///< Instantaneous cadence value. + uint32_t time_since_last_s_evt; ///< Time since last speed event occurred (integer part). + uint64_t fraction_since_last_s_evt; ///< Time since last speed event occurred (fractional part). + uint32_t time_since_last_c_evt; ///< Time since last cadence event occurred (integer part). + uint64_t fraction_since_last_c_evt; ///< Time since last cadence event occurred (fractional part). + sensorsim_state_t sensorsim_s_state; ///< State of the simulated speed sensor. + sensorsim_cfg_t sensorsim_s_cfg; ///< Configuration of the simulated speed sensor. + sensorsim_state_t sensorsim_c_state; ///< State of the simulated cadence sensor. + sensorsim_cfg_t sensorsim_c_cfg; ///< Configuration of the simulated cadence sensor. + uint16_t prev_time_since_evt; ///< Previous value of time since the last event. + uint32_t cumulative_time; ///< Cumulative time in 2 s ticks used for updating the cumulative time. + uint32_t cumulative_time_frac; ///< Cumulative time in 2 s ticks (fractional part), used for updating the cumulative time. + uint8_t stop_cnt; ///< Counter used for simulating bicycle stopped state. +} ant_bsc_simulator_cb_t; + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BSC_SIMULATOR_LOCAL_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/utils/ant_bsc_utils.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/utils/ant_bsc_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..964f53da778a112daf8e3b11852d37387b605101 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_bsc/utils/ant_bsc_utils.h @@ -0,0 +1,128 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_BSC_UTILS_H__ +#define ANT_BSC_UTILS_H__ + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + * + * @defgroup ant_sdk_profiles_bsc_utils Bicycle Speed and Cadence profile utilities + * @{ + * @ingroup ant_bsc + * @brief This module implements utilities for the Bicycle Speed and Cadence profile. + * + */ + +/**@brief Unit for BSC operating time. + * + * @details According to the ANT BSC specification, the operating time unit is 2 seconds. + */ +#define ANT_BSC_OPERATING_TIME_UNIT 2u + +/**@brief This macro should be used to get the seconds part of the operating time. + */ +#define ANT_BSC_OPERATING_SECONDS(OPERATING_TIME) (((OPERATING_TIME) * ANT_BSC_OPERATING_TIME_UNIT) % 60) + +/**@brief This macro should be used to get the minutes part of the operating time. + */ +#define ANT_BSC_OPERATING_MINUTES(OPERATING_TIME) ((((OPERATING_TIME) * ANT_BSC_OPERATING_TIME_UNIT) / 60) % 60) + +/**@brief This macro should be used to get the hours part of the operating time. + */ +#define ANT_BSC_OPERATING_HOURS(OPERATING_TIME) ((((OPERATING_TIME) * ANT_BSC_OPERATING_TIME_UNIT) / (60 * 60)) % 24) + +/**@brief This macro should be used to get the days part of the operating time. + */ +#define ANT_BSC_OPERATING_DAYS(OPERATING_TIME) ((((OPERATING_TIME) * ANT_BSC_OPERATING_TIME_UNIT) / (60 * 60)) / 24) + +/**@brief Number of Bicycle Speed or Cadence event time counts per second. + * + * @details According to the ANT BSC specification, the speed or cadence event time unit is 1/1024 of a second. + */ +#define ANT_BSC_EVENT_TIME_COUNTS_PER_SEC 1024u + +/**@brief BSC event time display required precision. + * + * @details This value is used to decode the number of milliseconds. + */ +#define ANT_BSC_EVENT_TIME_PRECISION 1000u + +/**@brief This macro should be used to get the seconds part of the BSC event time. + */ +#define ANT_BSC_EVENT_TIME_SEC(EVENT_TIME) ((EVENT_TIME) / ANT_BSC_EVENT_TIME_COUNTS_PER_SEC) + +/**@brief This macro should be used to get the milliseconds part of the BSC event time. + */ +#define ANT_BSC_EVENT_TIME_MSEC(EVENT_TIME) (((((EVENT_TIME) % ANT_BSC_EVENT_TIME_COUNTS_PER_SEC) * ANT_BSC_EVENT_TIME_PRECISION) \ + + ANT_BSC_EVENT_TIME_COUNTS_PER_SEC / 2) \ + / ANT_BSC_EVENT_TIME_COUNTS_PER_SEC) + +/**@brief Battery voltage display required precision. + * + * @details This value is used to decode the number of mV. + */ +#define ANT_BSC_BAT_VOLTAGE_PRECISION 1000u + +/**@brief Bike Speed and Cadence profile, unit divisor of the fractional part of the battery voltage. + * + * @details According to the ANT BSC specification, the battery voltage fraction unit is (1/256) V. + */ +#define ANT_BSC_BAT_VOLTAGE_FRACTION_PER_VOLT 256u + +/**@brief This macro should be used to get the mV part of the BSC battery voltage. + */ +#define ANT_BSC_BAT_VOLTAGE_FRACTION_MV(VOLT_FRACT) ((((VOLT_FRACT) * ANT_BSC_BAT_VOLTAGE_PRECISION) \ + + ANT_BSC_BAT_VOLTAGE_FRACTION_PER_VOLT / 2) \ + / ANT_BSC_BAT_VOLTAGE_FRACTION_PER_VOLT) + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_BSC_UTILS_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.c new file mode 100644 index 0000000000000000000000000000000000000000..cf6a117f584b9c5de7a8109e7336bf3113ee9e80 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.c @@ -0,0 +1,225 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_REQUEST_CONTROLLER) +#include "ant_request_controller.h" +#include "ant_interface.h" +#include "ant_parameters.h" +#include "app_error.h" +#include "nrf_assert.h" +#include "nrf.h" + +/**@brief Common message data layout structure. */ +typedef struct +{ + uint8_t page_number; ///< Page number. + uint8_t page_payload[7]; ///< Page payload. +}ant_common_message_layout_t; + + +void ant_request_controller_init(ant_request_controller_t * p_controller) +{ + ASSERT(p_controller != NULL); + + p_controller->state = ANT_REQUEST_CONTROLLER_IDLE; + p_controller->page_70 = DEFAULT_ANT_COMMON_PAGE70(); +} + + +uint32_t ant_request_controller_request(ant_request_controller_t * p_controller, + uint8_t channel_number, + ant_common_page70_data_t * p_page_70) +{ + ASSERT(p_controller != NULL); + ASSERT(p_page_70 != NULL); + + ant_common_message_layout_t message; + message.page_number = ANT_COMMON_PAGE_70; + + ant_common_page_70_encode(message.page_payload, p_page_70); + + p_controller->state = ANT_REQUEST_CONTROLLER_SENDED; + + return sd_ant_acknowledge_message_tx(channel_number, sizeof (message), (uint8_t *)&message); +} + + +bool ant_request_controller_pending_get(ant_request_controller_t * p_controller, + uint8_t * p_page_number) +{ + ASSERT(p_controller != NULL); + ASSERT(p_page_number != NULL); + + if ((p_controller->state == ANT_REQUEST_CONTROLLER_ACK_UNTIL_SUCCESS_REQUESTED) + || (p_controller->state == ANT_REQUEST_CONTROLLER_ACK_REQUESTED) + || (p_controller->state == ANT_REQUEST_CONTROLLER_BROADCAST_REQUESTED)) + { + *p_page_number = p_controller->page_70.page_number; + return true; + } + return false; +} + + +bool ant_request_controller_ack_needed(ant_request_controller_t * p_controller) +{ + ASSERT(p_controller != NULL); + return ((p_controller->state == ANT_REQUEST_CONTROLLER_ACK_UNTIL_SUCCESS_REQUESTED) + || (p_controller->state == ANT_REQUEST_CONTROLLER_ACK_REQUESTED)); +} + + +ant_request_controller_evt_t ant_request_controller_disp_evt_handler( + ant_request_controller_t * p_controller, + ant_evt_t * p_ant_event) +{ + ASSERT(p_controller != NULL); + ASSERT(p_ant_event != NULL); + + if ( p_controller->state == ANT_REQUEST_CONTROLLER_SENDED) + { + switch (p_ant_event->event) + { + case EVENT_TRANSFER_TX_FAILED: + p_controller->state = ANT_REQUEST_CONTROLLER_IDLE; + return ANT_REQUEST_CONTROLLER_FAILED; + + case EVENT_TRANSFER_TX_COMPLETED: + p_controller->state = ANT_REQUEST_CONTROLLER_IDLE; + return ANT_REQUEST_CONTROLLER_SUCCESS; + + default: + break; + } + } + + return ANT_REQUEST_CONTROLLER_NONE; +} + + +/**@brief Function for confirmation of page sending. + * + * @param[in] p_controller Pointer to the controller instance. + */ +__STATIC_INLINE void page_sended(ant_request_controller_t * p_controller) +{ + if (!((p_controller->page_70.transmission_response.items.transmit_count)--)) + { + p_controller->state = ANT_REQUEST_CONTROLLER_IDLE; + } +} + + +/**@brief Function for handling page request. + * + * @param[in] p_controller Pointer to the controller instance. + * @param[in] p_message_payload Pointer to the message payload. + */ +__STATIC_INLINE void page_requested(ant_request_controller_t * p_controller, + ant_common_message_layout_t * p_message_payload) +{ + ant_common_page_70_decode(p_message_payload->page_payload, &(p_controller->page_70)); + + if ((p_controller->page_70.command_type == ANT_PAGE70_COMMAND_PAGE_DATA_REQUEST) + && (p_controller->page_70.transmission_response.specyfic != ANT_PAGE70_RESPONSE_INVALID)) + { + if (p_controller->page_70.transmission_response.items.ack_resposne) + { + if (p_controller->page_70.transmission_response.specyfic == + ANT_PAGE70_RESPONSE_TRANSMIT_UNTIL_SUCCESS) + { + p_controller->state = ANT_REQUEST_CONTROLLER_ACK_UNTIL_SUCCESS_REQUESTED; + } + else + { + p_controller->state = ANT_REQUEST_CONTROLLER_ACK_REQUESTED; + } + } + else + { + p_controller->state = ANT_REQUEST_CONTROLLER_BROADCAST_REQUESTED; + } + } +} + + +void ant_request_controller_sens_evt_handler(ant_request_controller_t * p_controller, + ant_evt_t * p_ant_event) +{ + ASSERT(p_controller != NULL); + ASSERT(p_ant_event != NULL); + + ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->msg.evt_buffer; + ant_common_message_layout_t * p_message_payload = + (ant_common_message_layout_t *)p_message->ANT_MESSAGE_aucPayload; + + switch (p_ant_event->event) + { + case EVENT_RX: + + if (p_message_payload->page_number == ANT_COMMON_PAGE_70) + { + page_requested(p_controller, p_message_payload); + } + break; + + case EVENT_TRANSFER_TX_COMPLETED: + + if (p_controller->state == ANT_REQUEST_CONTROLLER_ACK_UNTIL_SUCCESS_REQUESTED) + { + p_controller->state = ANT_REQUEST_CONTROLLER_IDLE; + } + /* fall through */ + + case EVENT_TX: + + if (p_controller->state == ANT_REQUEST_CONTROLLER_BROADCAST_REQUESTED + || p_controller->state == ANT_REQUEST_CONTROLLER_ACK_REQUESTED) + { + page_sended(p_controller); + } + break; + + default: + break; + } +} + +#endif // NRF_MODULE_ENABLED(ANT_REQUEST_CONTROLLER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.h new file mode 100644 index 0000000000000000000000000000000000000000..2654d9234e5b0f6b976baa72c5ba7e212b1e744a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.h @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ant_request_controller ANT request controller + * @{ + * @ingroup ant_sdk_utils + * + * @brief Module for handling page requests related to page 70. + */ + +#ifndef ANT_REQUEST_CONTROLLER_H__ +#define ANT_REQUEST_CONTROLLER_H__ +#include +#include "ant_common_page_70.h" +#include "ant_stack_handler_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Request controller events types. */ +typedef enum +{ + ANT_REQUEST_CONTROLLER_NONE, ///< No event. + ANT_REQUEST_CONTROLLER_SUCCESS, ///< Page request successful. + ANT_REQUEST_CONTROLLER_FAILED, ///< Page request failed. +} ant_request_controller_evt_t; + +/**@brief Request controller states. */ +typedef enum +{ + ANT_REQUEST_CONTROLLER_IDLE, ///< Module is in idle state. + ANT_REQUEST_CONTROLLER_SENDED, ///< Module waits for acknowledgment of its request. + ANT_REQUEST_CONTROLLER_BROADCAST_REQUESTED, ///< Module is requested to send page n times using broadcast. + ANT_REQUEST_CONTROLLER_ACK_REQUESTED, ///< Module is requested to send page n times using acknowledgment. + ANT_REQUEST_CONTROLLER_ACK_UNTIL_SUCCESS_REQUESTED, ///< Module is requested to send page until success using acknowledgment. +} ant_request_controller_state_t; + +/**@brief ANT request controller structure. */ +typedef struct +{ + ant_request_controller_state_t state; ///< Actual module state. + ant_common_page70_data_t page_70; ///< Page 70. +} ant_request_controller_t; + +/**@brief Function for initializing the ANT request controller instance. + * + * @param[in] p_controller Pointer to the controller instance. + */ +void ant_request_controller_init(ant_request_controller_t * p_controller); + +/**@brief Function for sending a request. + * + * @param[in] p_controller Pointer to the controller instance. + * @param[in] channel_number Channel number. + * @param[in] p_page_70 Pointer to the prepared page 70. + * + * @return Error code returned by @ref sd_ant_acknowledge_message_tx(). + */ +uint32_t ant_request_controller_request(ant_request_controller_t * p_controller, + uint8_t channel_number, + ant_common_page70_data_t * p_page_70); + +/**@brief Function for getting pending page number. + * + * @details This function checks whether a page number was requested. + * + * @param[in] p_controller Pointer to the controller instance. + * @param[out] p_page_number Pending page number (valid if true was returned). + * + * @retval TRUE If there was a pending page. + * @retval FALSE If no page was pending. + */ +bool ant_request_controller_pending_get(ant_request_controller_t * p_controller, + uint8_t * p_page_number); + +/**@brief Function for checking whether the next page must be sent with acknowledgment. + * + * @param[in] p_controller Pointer to the controller instance. + * + * @retval TRUE If the next transmission needs acknowledgment. + * @retval FALSE If the next transmission does not need acknowledgment. + */ +bool ant_request_controller_ack_needed(ant_request_controller_t * p_controller); + +/** + * @brief Function for handling ANT events on display side. + * + * @details All events from the ANT stack that are related to the appropriate channel number + * should be propagated. + * + * @param[in] p_controller Pointer to the controller instance. + * @param[in] p_ant_event Event received from the ANT stack. + */ +ant_request_controller_evt_t ant_request_controller_disp_evt_handler( + ant_request_controller_t * p_controller, + ant_evt_t * p_ant_event); + +/** + * @brief Function for handling ANT events on sensor side. + * + * @details All events from the ANT stack that are related to the appropriate channel number + * should be propagated. + * + * @param[in] p_controller Pointer to the controller instance. + * @param[in] p_ant_event Event received from the ANT stack. + * @retval TRUE If there was a pending page. + */ +void ant_request_controller_sens_evt_handler(ant_request_controller_t * p_controller, + ant_evt_t * p_ant_event); + + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_REQUEST_CONTROLLER_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.c new file mode 100644 index 0000000000000000000000000000000000000000..6c8a55b6c08eb5e5131f91ba51cbc60f92781ddc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.c @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_COMMON_PAGE_70) + +#include +#include "ant_common_page_70.h" + +#define NRF_LOG_MODULE_NAME "ANT_COMMON_PAGE_70" +#if ANT_COMMON_PAGE_70_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_COMMON_PAGE_70_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_COMMON_PAGE_70_INFO_COLOR +#else // ANT_COMMON_PAGE_70_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_COMMON_PAGE_70_LOG_ENABLED +#include "nrf_log.h" + +/**@brief ANT+ common page 70 data layout structure. */ +typedef struct +{ + uint8_t reserved[2]; + uint8_t descriptor[2]; + uint8_t req_trans_response; + uint8_t req_page_number; + uint8_t command_type; +}ant_common_page70_data_layout_t; + +/**@brief Function for tracing page 70 data. + * + * @param[in] p_page_data Pointer to the page 70 data. + */ +static void page70_data_log(volatile ant_common_page70_data_t const * p_page_data) +{ + NRF_LOG_INFO("Page %d request\r\n", p_page_data->page_number); + + switch (p_page_data->transmission_response.specyfic) + { + case ANT_PAGE70_RESPONSE_TRANSMIT_UNTIL_SUCCESS: + NRF_LOG_INFO("Try to send until ACK\r\n"); + break; + + case ANT_PAGE70_RESPONSE_INVALID: + NRF_LOG_INFO("Invalid requested transmission response\r\n"); + break; + + default: + + if (p_page_data->transmission_response.items.ack_resposne) + { + NRF_LOG_INFO("Answer with acknowledged messages\r\n"); + } + NRF_LOG_INFO("Requested number of transmissions: %d\r\n", + p_page_data->transmission_response.items.transmit_count); + } + + switch (p_page_data->command_type) + { + case ANT_PAGE70_COMMAND_PAGE_DATA_REQUEST: + NRF_LOG_INFO("Request Data Page\r\n"); + break; + + case ANT_PAGE70_COMMAND_ANT_FS_SESSION_REQUEST: + NRF_LOG_INFO("Request ANT-FS Session\r\n"); + break; + + default: + NRF_LOG_INFO("Invalid request\r\n"); + } + NRF_LOG_INFO("Descriptor %x\r\n\n", p_page_data->descriptor); +} + + +void ant_common_page_70_encode(uint8_t * p_page_buffer, + volatile ant_common_page70_data_t const * p_page_data) +{ + ant_common_page70_data_layout_t * p_outcoming_data = + (ant_common_page70_data_layout_t *)p_page_buffer; + + memset(p_outcoming_data->reserved, UINT8_MAX, sizeof (p_outcoming_data->reserved)); + UNUSED_PARAMETER(uint16_encode(p_page_data->descriptor, p_outcoming_data->descriptor)); + p_outcoming_data->req_trans_response = p_page_data->transmission_response.byte; + p_outcoming_data->req_page_number = p_page_data->page_number; + p_outcoming_data->command_type = p_page_data->command_type; + + page70_data_log(p_page_data); +} + + +void ant_common_page_70_decode(uint8_t const * p_page_buffer, + volatile ant_common_page70_data_t * p_page_data) +{ + ant_common_page70_data_layout_t const * p_incoming_data = + (ant_common_page70_data_layout_t *)p_page_buffer; + + p_page_data->descriptor = uint16_decode(p_incoming_data->descriptor); + p_page_data->transmission_response.byte = p_incoming_data->req_trans_response; + p_page_data->page_number = p_incoming_data->req_page_number; + p_page_data->command_type = (ant_page70_command_t)p_incoming_data->command_type; + + page70_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_COMMON_PAGE_70) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.h new file mode 100644 index 0000000000000000000000000000000000000000..e63f565e00f600b428bfa311e43203590f8eea74 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.h @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_COMMON_PAGE_70_H__ +#define ANT_COMMON_PAGE_70_H__ + +/** @file + * + * @defgroup ant_common_page_70 ANT+ common page 70 + * @{ + * @ingroup ant_sdk_common_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ANT_COMMON_PAGE_70 (70) ///< @brief ID value of common page 70. +#define ANT_PAGE70_INVALID_DESCRIPTOR UINT16_MAX ///< Invalid descriptor. + +/**@brief Command type. + */ +typedef enum +{ + ANT_PAGE70_COMMAND_PAGE_DATA_REQUEST = 0x01, ///< Page request. + ANT_PAGE70_COMMAND_ANT_FS_SESSION_REQUEST = 0x02, ///< ANT FS session request. +} ant_page70_command_t; + + +/**@brief Data structure for ANT+ common data page 70. + */ +typedef struct +{ + uint8_t page_number; ///< Requested page number. + uint16_t descriptor; ///< Descriptor. + ant_page70_command_t command_type; ///< Command type. + union + { + enum + { + ANT_PAGE70_RESPONSE_INVALID = 0x00, ///< Invalid response type. + ANT_PAGE70_RESPONSE_TRANSMIT_UNTIL_SUCCESS = 0x80, ///< Transmit until a successful acknowledge is received. + } specyfic; + struct + { + uint8_t transmit_count :7; ///< Number of re-transmissions. + uint8_t ack_resposne :1; ///< Acknowledge transmission is required. + } items; + uint8_t byte; + } transmission_response; +} ant_common_page70_data_t; + +/**@brief Initialize page 70 with default values. + */ +#define DEFAULT_ANT_COMMON_PAGE70() \ + (ant_common_page70_data_t) \ + { \ + .page_number = 0x00, \ + .command_type = (ant_page70_command_t)0x00, \ + .transmission_response.specyfic = ANT_PAGE70_RESPONSE_INVALID, \ + .descriptor = ANT_PAGE70_INVALID_DESCRIPTOR, \ + } + +/**@brief Initialize page 70 with the page request. + */ +#define ANT_COMMON_PAGE_DATA_REQUEST(PAGE_NUMBER) \ + (ant_common_page70_data_t) \ + { \ + .page_number = (PAGE_NUMBER), \ + .command_type = ANT_PAGE70_COMMAND_PAGE_DATA_REQUEST, \ + .transmission_response.specyfic = ANT_PAGE70_RESPONSE_TRANSMIT_UNTIL_SUCCESS, \ + .descriptor = ANT_PAGE70_INVALID_DESCRIPTOR, \ + } + +/**@brief Function for encoding page 70. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_common_page_70_encode(uint8_t * p_page_buffer, + volatile ant_common_page70_data_t const * p_page_data); + +/**@brief Function for decoding page 70. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_common_page_70_decode(uint8_t const * p_page_buffer, + volatile ant_common_page70_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_COMMON_PAGE_70_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.c new file mode 100644 index 0000000000000000000000000000000000000000..b54bf2abc0c8800435572c83de29e0c513944f93 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.c @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_COMMON_PAGE_80) + +#include +#include "ant_common_page_80.h" + +#define NRF_LOG_MODULE_NAME "ANT_COMMON_PAGE_80" +#if ANT_COMMON_PAGE_80_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_COMMON_PAGE_80_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_COMMON_PAGE_80_INFO_COLOR +#else // ANT_COMMON_PAGE_80_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_COMMON_PAGE_80_LOG_ENABLED +#include "nrf_log.h" + +/**@brief ant+ common page 80 data layout structure. */ +typedef struct +{ + uint8_t reserved[2]; ///< unused, fill by 0xFF + uint8_t hw_revision; + uint8_t manufacturer_id[2]; + uint8_t model_number[2]; +}ant_common_page80_data_layout_t; + + +/**@brief Function for tracing page 80 data. + * + * @param[in] p_page_data Pointer to the page 80 data. + */ +static void page80_data_log(volatile ant_common_page80_data_t const * p_page_data) +{ + NRF_LOG_INFO("hw revision: %u\r\n", p_page_data->hw_revision); + NRF_LOG_INFO("manufacturer id: %u\r\n", p_page_data->manufacturer_id); + NRF_LOG_INFO("model number: %u\r\n\n", p_page_data->model_number); +} + + +void ant_common_page_80_encode(uint8_t * p_page_buffer, + volatile ant_common_page80_data_t const * p_page_data) +{ + ant_common_page80_data_layout_t * p_outcoming_data = + (ant_common_page80_data_layout_t *)p_page_buffer; + + memset(p_page_buffer, UINT8_MAX, sizeof (p_outcoming_data->reserved)); + + p_outcoming_data->hw_revision = p_page_data->hw_revision; + + UNUSED_PARAMETER(uint16_encode(p_page_data->manufacturer_id, + p_outcoming_data->manufacturer_id)); + UNUSED_PARAMETER(uint16_encode(p_page_data->model_number, p_outcoming_data->model_number)); + + page80_data_log(p_page_data); +} + + +void ant_common_page_80_decode(uint8_t const * p_page_buffer, + volatile ant_common_page80_data_t * p_page_data) +{ + ant_common_page80_data_layout_t const * p_incoming_data = + (ant_common_page80_data_layout_t *)p_page_buffer; + + p_page_data->hw_revision = p_incoming_data->hw_revision; + + p_page_data->manufacturer_id = uint16_decode(p_incoming_data->manufacturer_id); + p_page_data->model_number = uint16_decode(p_incoming_data->model_number); + + page80_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_COMMON_PAGE_80) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.h new file mode 100644 index 0000000000000000000000000000000000000000..0d13d215445c6179f14bfe99c5a1a8ed74aab777 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.h @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_COMMON_PAGE_80_H__ +#define ANT_COMMON_PAGE_80_H__ + +/** @file + * + * @defgroup ant_sdk_common_pages ANT+ common pages + * @{ + * @ingroup ant_sdk_profiles + * @brief This module implements functions for the ANT+ common pages. + * @details ANT+ common data pages define common data formats that can be used by any device on any ANT network. The ability to send and receive these common pages is defined by the transmission type of the ANT channel parameter. + * + * Note that all unused pages in this section are not defined and therefore cannot be used. + * @} + * + * @defgroup ant_common_page_80 ANT+ common page 80 + * @{ + * @ingroup ant_sdk_common_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ANT_COMMON_PAGE_80 (80) ///< @brief ID value of common page 80. + +/**@brief Data structure for ANT+ common data page 80. + * + * @note This structure implements only page 80 specific data. + */ +typedef struct +{ + uint8_t hw_revision; ///< Hardware revision. + uint16_t manufacturer_id; ///< Manufacturer ID. + uint16_t model_number; ///< Model number. +} ant_common_page80_data_t; + +/**@brief Initialize page 80. + */ +#define DEFAULT_ANT_COMMON_page80() \ + (ant_common_page80_data_t) \ + { \ + .hw_revision = 0x00, \ + .manufacturer_id = UINT8_MAX, \ + .model_number = 0x00, \ + } + +/**@brief Initialize page 80. + */ +#define ANT_COMMON_page80(hw_rev, man_id, mod_num) \ + (ant_common_page80_data_t) \ + { \ + .hw_revision = (hw_rev), \ + .manufacturer_id = (man_id), \ + .model_number = (mod_num), \ + } + +/**@brief Function for encoding page 80. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_common_page_80_encode(uint8_t * p_page_buffer, + volatile ant_common_page80_data_t const * p_page_data); + +/**@brief Function for decoding page 80. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_common_page_80_decode(uint8_t const * p_page_buffer, + volatile ant_common_page80_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_COMMON_PAGE_80_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.c new file mode 100644 index 0000000000000000000000000000000000000000..5f36bdf9904277a32a2f8151b575f577ad0d3d01 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.c @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_COMMON_PAGE_81) + +#include "ant_common_page_81.h" + +#define NRF_LOG_MODULE_NAME "ANT_COMMON_PAGE_81" +#if ANT_COMMON_PAGE_81_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_COMMON_PAGE_81_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_COMMON_PAGE_81_INFO_COLOR +#else // ANT_COMMON_PAGE_81_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_COMMON_PAGE_81_LOG_ENABLED +#include "nrf_log.h" + +/**@brief ant+ common page 81 data layout structure. */ +typedef struct +{ + uint8_t reserved; ///< unused, fill by 0xFF + uint8_t sw_revision_minor; + uint8_t sw_revision_major; + uint8_t serial_number[4]; +}ant_common_page81_data_layout_t; + + +/**@brief Function for tracing page 80 data. + * + * @param[in] p_page_data Pointer to the page 80 data. + */ +static void page81_data_log(volatile ant_common_page81_data_t const * p_page_data) +{ + if (p_page_data->sw_revision_minor != UINT8_MAX) + { + NRF_LOG_INFO("sw revision: %u.%u\r\n", + ((ant_common_page81_data_t const *) p_page_data)->sw_revision_major, + ((ant_common_page81_data_t const *) p_page_data)->sw_revision_minor); + } + else + { + NRF_LOG_INFO("sw revision: %u\r\n", p_page_data->sw_revision_major); + } + + NRF_LOG_INFO("serial number: %u\r\n\n", (unsigned int) p_page_data->serial_number); +} + + +void ant_common_page_81_encode(uint8_t * p_page_buffer, + volatile ant_common_page81_data_t const * p_page_data) +{ + ant_common_page81_data_layout_t * p_outcoming_data = + (ant_common_page81_data_layout_t *)p_page_buffer; + + p_outcoming_data->reserved = UINT8_MAX; + + p_outcoming_data->sw_revision_minor = p_page_data->sw_revision_minor; + p_outcoming_data->sw_revision_major = p_page_data->sw_revision_major; + + UNUSED_PARAMETER(uint32_encode(p_page_data->serial_number, p_outcoming_data->serial_number)); + + page81_data_log(p_page_data); +} + + +void ant_common_page_81_decode(uint8_t const * p_page_buffer, + volatile ant_common_page81_data_t * p_page_data) +{ + ant_common_page81_data_layout_t const * p_incoming_data = + (ant_common_page81_data_layout_t *)p_page_buffer; + + p_page_data->sw_revision_minor = p_incoming_data->sw_revision_minor; + p_page_data->sw_revision_major = p_incoming_data->sw_revision_major; + + p_page_data->serial_number = uint32_decode(p_incoming_data->serial_number); + + page81_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_COMMON_PAGE_81) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.h new file mode 100644 index 0000000000000000000000000000000000000000..fae7d660307a6d2dd220b8a713214c97e725ed41 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.h @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_COMMON_PAGE_81_H__ +#define ANT_COMMON_PAGE_81_H__ + +/** @file + * + * @defgroup ant_common_page_81 ANT+ common page 81 + * @{ + * @ingroup ant_sdk_common_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ANT_COMMON_PAGE_81 (81) ///< @brief ID value of common page 81. + +/**@brief Data structure for ANT+ common data page 81. + * + * @note This structure implements only page 81 specific data. + */ +typedef struct +{ + uint8_t sw_revision_minor; ///< Supplemental, fill by 0xFF if unused. + uint8_t sw_revision_major; ///< Main software version. + uint32_t serial_number; ///< Lowest 32 b of serial number, fill by 0xFFFFFFFFF if unused. +} ant_common_page81_data_t; + +/**@brief Initialize page 81. + */ +#define DEFAULT_ANT_COMMON_page81() \ + (ant_common_page81_data_t) \ + { \ + .sw_revision_minor = UINT8_MAX, \ + .sw_revision_major = UINT8_MAX, \ + .serial_number = UINT32_MAX, \ + } + +/**@brief Initialize page 81. + */ +#define ANT_COMMON_page81(sw_major_rev, sw_minor_rev, seril_no) \ + (ant_common_page81_data_t) \ + { \ + .sw_revision_minor = (sw_minor_rev), \ + .sw_revision_major = (sw_major_rev), \ + .serial_number = (seril_no), \ + } + +/**@brief Function for encoding page 81. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_common_page_81_encode(uint8_t * p_page_buffer, + volatile ant_common_page81_data_t const * p_page_data); + +/**@brief Function for decoding page 81. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_common_page_81_decode(uint8_t const * p_page_buffer, + volatile ant_common_page81_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_COMMON_PAGE_81_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/ant_hrm.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/ant_hrm.c new file mode 100644 index 0000000000000000000000000000000000000000..e765f7184b571b33825e7ce00f12f3d2c7c66ff2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/ant_hrm.c @@ -0,0 +1,346 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if ANT_HRM_ENABLED + +#include "nrf_assert.h" +#include "app_error.h" +#include "ant_interface.h" +#include "app_util.h" +#include "ant_hrm.h" +#include "ant_hrm_utils.h" +#include "app_error.h" + +#define NRF_LOG_MODULE_NAME "ANT_HRM" +#if ANT_HRM_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_HRM_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_HRM_INFO_COLOR +#else // ANT_HRM_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_HRM_LOG_ENABLED +#include "nrf_log.h" + +#define BACKGROUND_DATA_INTERVAL 64 /**< The number of main data pages sent between background data page. + Background data page is sent every 65th message. */ +#define TX_TOGGLE_DIVISOR 4 /**< The number of messages between changing state of toggle bit. */ + +/**@brief HRM message data layout structure. */ +typedef struct +{ + ant_hrm_page_t page_number : 7; + uint8_t toggle_bit : 1; + uint8_t page_payload[7]; +} ant_hrm_message_layout_t; + +/**@brief Function for initializing the ANT HRM profile instance. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_channel_config Pointer to the ANT channel configuration structure. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. + */ +static ret_code_t ant_hrm_init(ant_hrm_profile_t * p_profile, + ant_channel_config_t const * p_channel_config) +{ + p_profile->channel_number = p_channel_config->channel_number; + + p_profile->page_0 = DEFAULT_ANT_HRM_PAGE0(); + p_profile->page_1 = DEFAULT_ANT_HRM_PAGE1(); + p_profile->page_2 = DEFAULT_ANT_HRM_PAGE2(); + p_profile->page_3 = DEFAULT_ANT_HRM_PAGE3(); + p_profile->page_4 = DEFAULT_ANT_HRM_PAGE4(); + + NRF_LOG_INFO("ANT HRM channel %u init\r\n", p_profile->channel_number); + return ant_channel_init(p_channel_config); +} + + +ret_code_t ant_hrm_disp_init(ant_hrm_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_hrm_evt_handler_t evt_handler) +{ + ASSERT(p_profile != NULL); + ASSERT(p_channel_config != NULL); + ASSERT(evt_handler != NULL); + + p_profile->evt_handler = evt_handler; + + return ant_hrm_init(p_profile, p_channel_config); +} + + +ret_code_t ant_hrm_sens_init(ant_hrm_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_hrm_sens_config_t const * p_sens_config) +{ + ASSERT(p_profile != NULL); + ASSERT(p_channel_config != NULL); + ASSERT(p_sens_config != NULL); + ASSERT(p_sens_config->p_cb != NULL); + ASSERT(p_sens_config->evt_handler != NULL); + + ASSERT((p_sens_config->main_page_number == ANT_HRM_PAGE_0) + || (p_sens_config->main_page_number == ANT_HRM_PAGE_4)); + + p_profile->evt_handler = p_sens_config->evt_handler; + p_profile->_cb.p_sens_cb = p_sens_config->p_cb; + + ant_hrm_sens_cb_t * p_hrm_cb = p_profile->_cb.p_sens_cb; + p_hrm_cb->page_1_present = p_sens_config->page_1_present; + p_hrm_cb->main_page_number = p_sens_config->main_page_number; + p_hrm_cb->ext_page_number = p_hrm_cb->page_1_present ? ANT_HRM_PAGE_1 : ANT_HRM_PAGE_2; + p_hrm_cb->message_counter = 0; + p_hrm_cb->toggle_bit = true; + + return ant_hrm_init(p_profile, p_channel_config); +} + + +/**@brief Function for getting next page number to send. + * + * @param[in] p_profile Pointer to the profile instance. + * + * @return Next page number. + */ +static ant_hrm_page_t next_page_number_get(ant_hrm_profile_t * p_profile) +{ + ant_hrm_sens_cb_t * p_hrm_cb = p_profile->_cb.p_sens_cb; + ant_hrm_page_t page_number; + + if (p_hrm_cb->message_counter == (BACKGROUND_DATA_INTERVAL)) + { + page_number = p_hrm_cb->ext_page_number; + + p_hrm_cb->message_counter = 0; + + p_hrm_cb->ext_page_number++; + + if (p_hrm_cb->ext_page_number > ANT_HRM_PAGE_3) + { + p_hrm_cb->ext_page_number = p_hrm_cb->page_1_present ? ANT_HRM_PAGE_1 : ANT_HRM_PAGE_2; + } + } + else + { + page_number = p_hrm_cb->main_page_number; + } + + if (p_hrm_cb->message_counter % TX_TOGGLE_DIVISOR == 0) + { + p_hrm_cb->toggle_bit ^= 1; + } + + p_hrm_cb->message_counter++; + + return page_number; +} + + +/**@brief Function for encoding HRM message. + * + * @note Assume to be call each time when Tx window will occur. + */ +static void sens_message_encode(ant_hrm_profile_t * p_profile, uint8_t * p_message_payload) +{ + ant_hrm_message_layout_t * p_hrm_message_payload = + (ant_hrm_message_layout_t *)p_message_payload; + ant_hrm_sens_cb_t * p_hrm_cb = p_profile->_cb.p_sens_cb; + + p_hrm_message_payload->page_number = next_page_number_get(p_profile); + p_hrm_message_payload->toggle_bit = p_hrm_cb->toggle_bit; + + NRF_LOG_INFO("HRM TX Page number: %u\r\n", p_hrm_message_payload->page_number); + + ant_hrm_page_0_encode(p_hrm_message_payload->page_payload, &(p_profile->page_0)); // Page 0 is present in each message + + switch (p_hrm_message_payload->page_number) + { + case ANT_HRM_PAGE_0: + // No implementation needed + break; + + case ANT_HRM_PAGE_1: + ant_hrm_page_1_encode(p_hrm_message_payload->page_payload, &(p_profile->page_1)); + break; + + case ANT_HRM_PAGE_2: + ant_hrm_page_2_encode(p_hrm_message_payload->page_payload, &(p_profile->page_2)); + break; + + case ANT_HRM_PAGE_3: + ant_hrm_page_3_encode(p_hrm_message_payload->page_payload, &(p_profile->page_3)); + break; + + case ANT_HRM_PAGE_4: + ant_hrm_page_4_encode(p_hrm_message_payload->page_payload, &(p_profile->page_4)); + break; + + default: + return; + } + + p_profile->evt_handler(p_profile, (ant_hrm_evt_t)p_hrm_message_payload->page_number); +} + + +/**@brief Function for setting payload for ANT message and sending it. + * + * @param[in] p_profile Pointer to the profile instance. + */ +static void ant_message_send(ant_hrm_profile_t * p_profile) +{ + uint32_t err_code; + uint8_t p_message_payload[ANT_STANDARD_DATA_PAYLOAD_SIZE]; + + sens_message_encode(p_profile, p_message_payload); + err_code = + sd_ant_broadcast_message_tx(p_profile->channel_number, + sizeof (p_message_payload), + p_message_payload); + APP_ERROR_CHECK(err_code); +} + + +void ant_hrm_sens_evt_handler(ant_hrm_profile_t * p_profile, ant_evt_t * p_ant_event) +{ + if (p_ant_event->channel == p_profile->channel_number) + { + switch (p_ant_event->event) + { + case EVENT_TX: + ant_message_send(p_profile); + break; + + default: + break; + } + } +} + + +ret_code_t ant_hrm_disp_open(ant_hrm_profile_t * p_profile) +{ + ASSERT(p_profile != NULL); + + NRF_LOG_INFO("ANT HRM channel %u open\r\n", p_profile->channel_number); + return sd_ant_channel_open(p_profile->channel_number); +} + + +ret_code_t ant_hrm_sens_open(ant_hrm_profile_t * p_profile) +{ + ASSERT(p_profile != NULL); + + // Fill tx buffer for the first frame + ant_message_send(p_profile); + + NRF_LOG_INFO("ANT HRM channel %u open\r\n", p_profile->channel_number); + return sd_ant_channel_open(p_profile->channel_number); +} + + +/**@brief Function for decoding HRM message. + * + * @note Assume to be call each time when Rx window will occur. + */ +static void disp_message_decode(ant_hrm_profile_t * p_profile, uint8_t * p_message_payload) +{ + const ant_hrm_message_layout_t * p_hrm_message_payload = + (ant_hrm_message_layout_t *)p_message_payload; + + NRF_LOG_INFO("HRM RX Page Number: %u\r\n", p_hrm_message_payload->page_number); + + ant_hrm_page_0_decode(p_hrm_message_payload->page_payload, &(p_profile->page_0)); // Page 0 is present in each message + + switch (p_hrm_message_payload->page_number) + { + case ANT_HRM_PAGE_0: + // No implementation needed + break; + + case ANT_HRM_PAGE_1: + ant_hrm_page_1_decode(p_hrm_message_payload->page_payload, &(p_profile->page_1)); + break; + + case ANT_HRM_PAGE_2: + ant_hrm_page_2_decode(p_hrm_message_payload->page_payload, &(p_profile->page_2)); + break; + + case ANT_HRM_PAGE_3: + ant_hrm_page_3_decode(p_hrm_message_payload->page_payload, &(p_profile->page_3)); + break; + + case ANT_HRM_PAGE_4: + ant_hrm_page_4_decode(p_hrm_message_payload->page_payload, &(p_profile->page_4)); + break; + + default: + return; + } + + p_profile->evt_handler(p_profile, (ant_hrm_evt_t)p_hrm_message_payload->page_number); +} + + +void ant_hrm_disp_evt_handler(ant_hrm_profile_t * p_profile, ant_evt_t * p_ant_event) +{ + if (p_ant_event->channel == p_profile->channel_number) + { + ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->msg.evt_buffer; + + switch (p_ant_event->event) + { + case EVENT_RX: + + if (p_message->ANT_MESSAGE_ucMesgID == MESG_BROADCAST_DATA_ID + || p_message->ANT_MESSAGE_ucMesgID == MESG_ACKNOWLEDGED_DATA_ID + || p_message->ANT_MESSAGE_ucMesgID == MESG_BURST_DATA_ID) + { + disp_message_decode(p_profile, p_message->ANT_MESSAGE_aucPayload); + } + break; + + default: + break; + } + } +} + +#endif // ANT_HRM_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/ant_hrm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/ant_hrm.h new file mode 100644 index 0000000000000000000000000000000000000000..1c1772fa94bbd5e54fbdbed3179d5bca7e417f4b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/ant_hrm.h @@ -0,0 +1,290 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ant_hrm Heart Rate Monitor profile + * @{ + * @ingroup ant_sdk_profiles + * @brief This module implements the Heart Rate Monitor profile. + * + */ + +#ifndef ANT_HRM_H__ +#define ANT_HRM_H__ + +#include +#include +#include "app_util.h" +#include "ant_parameters.h" +#include "ant_stack_handler_types.h" +#include "ant_channel_config.h" +#include "ant_hrm_pages.h" +#include "sdk_errors.h" + +#define HRM_DEVICE_TYPE 0x78u ///< Device type reserved for ANT+ heart rate monitor. +#define HRM_ANTPLUS_RF_FREQ 0x39u ///< Frequency, decimal 57 (2457 MHz). + +#define HRM_MSG_PERIOD_4Hz 0x1F86u ///< Message period, decimal 8070 (4.06 Hz). +#define HRM_MSG_PERIOD_2Hz 0x3F0Cu ///< Message period, decimal 16140 (2.03 Hz). +#define HRM_MSG_PERIOD_1Hz 0x7E18u ///< Message period, decimal 32280 (1.02 Hz). + +#define HRM_EXT_ASSIGN 0x00 ///< ANT ext assign. +#define HRM_DISP_CHANNEL_TYPE CHANNEL_TYPE_SLAVE_RX_ONLY ///< Display HRM channel type. +#define HRM_SENS_CHANNEL_TYPE CHANNEL_TYPE_MASTER ///< Sensor HRM channel type. + +/**@brief Initialize an ANT channel configuration structure for the HRM profile (Display). + * + * @param[in] NAME Name of related instance. + * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance. + * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance. + * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance. + * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance. + * @param[in] HRM_MSG_PERIOD Channel period in 32 kHz counts. The HRM profile supports only the following periods: + * @ref HRM_MSG_PERIOD_4Hz, @ref HRM_MSG_PERIOD_2Hz, @ref HRM_MSG_PERIOD_1Hz. + */ +#define HRM_DISP_CHANNEL_CONFIG_DEF(NAME, \ + CHANNEL_NUMBER, \ + TRANSMISSION_TYPE, \ + DEVICE_NUMBER, \ + NETWORK_NUMBER, \ + HRM_MSG_PERIOD) \ +static const ant_channel_config_t NAME##_channel_hrm_disp_config = \ + { \ + .channel_number = (CHANNEL_NUMBER), \ + .channel_type = HRM_DISP_CHANNEL_TYPE, \ + .ext_assign = HRM_EXT_ASSIGN, \ + .rf_freq = HRM_ANTPLUS_RF_FREQ, \ + .transmission_type = (TRANSMISSION_TYPE), \ + .device_type = HRM_DEVICE_TYPE, \ + .device_number = (DEVICE_NUMBER), \ + .channel_period = (HRM_MSG_PERIOD), \ + .network_number = (NETWORK_NUMBER), \ + } +#define HRM_DISP_CHANNEL_CONFIG(NAME) &NAME##_channel_hrm_disp_config + +/**@brief Initialize an ANT channel configuration structure for the HRM profile (Sensor). + * + * @param[in] NAME Name of related instance. + * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance. + * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance. + * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance. + * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance. + */ +#define HRM_SENS_CHANNEL_CONFIG_DEF(NAME, \ + CHANNEL_NUMBER, \ + TRANSMISSION_TYPE, \ + DEVICE_NUMBER, \ + NETWORK_NUMBER) \ +static const ant_channel_config_t NAME##_channel_hrm_sens_config = \ + { \ + .channel_number = (CHANNEL_NUMBER), \ + .channel_type = HRM_SENS_CHANNEL_TYPE, \ + .ext_assign = HRM_EXT_ASSIGN, \ + .rf_freq = HRM_ANTPLUS_RF_FREQ, \ + .transmission_type = (TRANSMISSION_TYPE), \ + .device_type = HRM_DEVICE_TYPE, \ + .device_number = (DEVICE_NUMBER), \ + .channel_period = HRM_MSG_PERIOD_4Hz, \ + .network_number = (NETWORK_NUMBER), \ + } +#define HRM_SENS_CHANNEL_CONFIG(NAME) &NAME##_channel_hrm_sens_config + +/**@brief Initialize an ANT profile configuration structure for the HRM profile (Sensor). + * + * @param[in] NAME Name of related instance. + * @param[in] PAGE_1_PRESENT Determines whether page 1 is included. + * @param[in] MAIN_PAGE_NUMBER Determines the main data page (@ref ANT_HRM_PAGE_0 or @ref ANT_HRM_PAGE_4). + * @param[in] EVT_HANDLER Event handler to be called for handling events in the HRM profile. + */ +#define HRM_SENS_PROFILE_CONFIG_DEF(NAME, \ + PAGE_1_PRESENT, \ + MAIN_PAGE_NUMBER, \ + EVT_HANDLER) \ +static ant_hrm_sens_cb_t NAME##_hrm_sens_cb; \ +static const ant_hrm_sens_config_t NAME##_profile_hrm_sens_config = \ + { \ + .page_1_present = (PAGE_1_PRESENT), \ + .main_page_number = (MAIN_PAGE_NUMBER), \ + .p_cb = &NAME##_hrm_sens_cb, \ + .evt_handler = (EVT_HANDLER), \ + } +#define HRM_SENS_PROFILE_CONFIG(NAME) &NAME##_profile_hrm_sens_config + +/**@brief HRM page number type. */ +typedef enum +{ + ANT_HRM_PAGE_0, ///< Main data page number 0. + ANT_HRM_PAGE_1, ///< Background data page number 1. This page is optional. + ANT_HRM_PAGE_2, ///< Background data page number 2. + ANT_HRM_PAGE_3, ///< Background data page number 3. + ANT_HRM_PAGE_4 ///< Main data page number 4. +} ant_hrm_page_t; + +/**@brief HRM profile event type. */ +typedef enum +{ + ANT_HRM_PAGE_0_UPDATED = ANT_HRM_PAGE_0, ///< Data page 0 has been updated (Display) or sent (Sensor). + ANT_HRM_PAGE_1_UPDATED = ANT_HRM_PAGE_1, ///< Data page 0 and page 1 have been updated (Display) or sent (Sensor). + ANT_HRM_PAGE_2_UPDATED = ANT_HRM_PAGE_2, ///< Data page 0 and page 2 have been updated (Display) or sent (Sensor). + ANT_HRM_PAGE_3_UPDATED = ANT_HRM_PAGE_3, ///< Data page 0 and page 3 have been updated (Display) or sent (Sensor). + ANT_HRM_PAGE_4_UPDATED = ANT_HRM_PAGE_4, ///< Data page 0 and page 4 have been updated (Display) or sent (Sensor). +} ant_hrm_evt_t; + +// Forward declaration of the ant_hrm_profile_t type. +typedef struct ant_hrm_profile_s ant_hrm_profile_t; + +/**@brief HRM event handler type. */ +typedef void (* ant_hrm_evt_handler_t) (ant_hrm_profile_t *, ant_hrm_evt_t); + +#include "ant_hrm_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief HRM sensor configuration structure. */ +typedef struct +{ + bool page_1_present; ///< Determines whether page 1 is included. + ant_hrm_page_t main_page_number; ///< Determines the main data page (@ref ANT_HRM_PAGE_0 or @ref ANT_HRM_PAGE_4). + ant_hrm_sens_cb_t * p_cb; ///< Pointer to the data buffer for internal use. + ant_hrm_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the HRM profile. +} ant_hrm_sens_config_t; + +/**@brief HRM profile structure. */ +struct ant_hrm_profile_s +{ + uint8_t channel_number; ///< Channel number assigned to the profile. + union { + void * p_none; + ant_hrm_sens_cb_t * p_sens_cb; + } _cb; ///< Pointer to internal control block. + ant_hrm_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the HRM profile. + ant_hrm_page0_data_t page_0; ///< Page 0. + ant_hrm_page1_data_t page_1; ///< Page 1. + ant_hrm_page2_data_t page_2; ///< Page 2. + ant_hrm_page3_data_t page_3; ///< Page 3. + ant_hrm_page4_data_t page_4; ///< Page 4. +}; + +/** @name Defines for accessing ant_hrm_profile_t member variables + @{ */ +#define HRM_PROFILE_beat_count page_0.beat_count +#define HRM_PROFILE_computed_heart_rate page_0.computed_heart_rate +#define HRM_PROFILE_beat_time page_0.beat_time +#define HRM_PROFILE_operating_time page_1.operating_time +#define HRM_PROFILE_manuf_id page_2.manuf_id +#define HRM_PROFILE_serial_num page_2.serial_num +#define HRM_PROFILE_hw_version page_3.hw_version +#define HRM_PROFILE_sw_version page_3.sw_version +#define HRM_PROFILE_model_num page_3.model_num +#define HRM_PROFILE_manuf_spec page_4.manuf_spec +#define HRM_PROFILE_prev_beat page_4.prev_beat +/** @} */ + +/**@brief Function for initializing the ANT HRM Display profile instance. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_channel_config Pointer to the ANT channel configuration structure. + * @param[in] evt_handler Event handler to be called for handling events in the HRM profile. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. + */ +ret_code_t ant_hrm_disp_init(ant_hrm_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_hrm_evt_handler_t evt_handler); + +/**@brief Function for initializing the ANT HRM Sensor profile instance. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_channel_config Pointer to the ANT channel configuration structure. + * @param[in] p_sens_config Pointer to the HRM sensor configuration structure. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. + */ +ret_code_t ant_hrm_sens_init(ant_hrm_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_hrm_sens_config_t const * p_sens_config); + +/**@brief Function for opening the profile instance channel for ANT HRM Display. + * + * Before calling this function, pages should be configured. + * + * @param[in] p_profile Pointer to the profile instance. + * + * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned. + */ +ret_code_t ant_hrm_disp_open(ant_hrm_profile_t * p_profile); + +/**@brief Function for opening the profile instance channel for ANT HRM Sensor. + * + * Before calling this function, pages should be configured. + * + * @param[in] p_profile Pointer to the profile instance. + * + * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned. + */ +ret_code_t ant_hrm_sens_open(ant_hrm_profile_t * p_profile); + +/**@brief Function for handling the sensor ANT events. + * + * @details This function handles all events from the ANT stack that are of interest to the Heart Rate Monitor Sensor profile. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_ant_event Event received from the ANT stack. + */ +void ant_hrm_sens_evt_handler(ant_hrm_profile_t * p_profile, ant_evt_t * p_ant_event); + +/**@brief Function for handling the display ANT events. + * + * @details This function handles all events from the ANT stack that are of interest to the Heart Rate Monitor Display profile. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_ant_event Event received from the ANT stack. + */ +void ant_hrm_disp_evt_handler(ant_hrm_profile_t * p_profile, ant_evt_t * p_ant_event); + +#ifdef __cplusplus +} +#endif + +#endif // ANT_HRM_H__ +/** @} */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/ant_hrm_local.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/ant_hrm_local.h new file mode 100644 index 0000000000000000000000000000000000000000..4f4ca69d745a6f210f2f2874fbfa56ffd5bf5fa4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/ant_hrm_local.h @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_HRM_LOCAL_H__ +#define ANT_HRM_LOCAL_H__ + +#include +#include +#include "ant_hrm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup ant_hrm + * @{ + */ + +/** @brief HRM Sensor control block. */ +typedef struct +{ + uint8_t toggle_bit; + ant_hrm_page_t main_page_number; + uint8_t page_1_present; + ant_hrm_page_t ext_page_number; + uint8_t message_counter; +} ant_hrm_sens_cb_t; + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_HRM_LOCAL_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.c new file mode 100644 index 0000000000000000000000000000000000000000..e39eb55e722d1032f6baa182eb282b69e8b5f298 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.c @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_HRM) + +#include "ant_hrm_page_0.h" +#include "ant_hrm_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_HRM_PAGE_0" +#if ANT_HRM_PAGE_0_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_HRM_PAGE_0_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_0_INFO_COLOR +#else // ANT_HRM_PAGE_0_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_HRM_PAGE_0_LOG_ENABLED +#include "nrf_log.h" + +/**@brief HRM page 0 data layout structure. */ +typedef struct +{ + uint8_t reserved[3]; + uint8_t heart_beat_evt_time_LSB; + uint8_t heart_beat_evt_time_MSB; + uint8_t heart_beat_count; + uint8_t computed_heart_rate; +}ant_hrm_page0_data_layout_t; + +/**@brief Function for tracing page 0 and common data. + * + * @param[in] p_common_data Pointer to the common data. + * @param[in] p_page_data Pointer to the page 0 data. + */ +static void page0_data_log(ant_hrm_page0_data_t const * p_page_data) +{ + NRF_LOG_INFO("Heart beat count: %u\r\n", (unsigned int)p_page_data->beat_count); + NRF_LOG_INFO("Computed heart rate: %u\r\n", + (unsigned int) p_page_data->computed_heart_rate); + NRF_LOG_INFO("Heart beat event time: %u.%03us\r\n\n", + (unsigned int) ANT_HRM_BEAT_TIME_SEC(p_page_data->beat_time), + (unsigned int) ANT_HRM_BEAT_TIME_MSEC(p_page_data->beat_time)); +} + + +void ant_hrm_page_0_encode(uint8_t * p_page_buffer, + ant_hrm_page0_data_t const * p_page_data) +{ + ant_hrm_page0_data_layout_t * p_outcoming_data = (ant_hrm_page0_data_layout_t *)p_page_buffer; + uint32_t beat_time = p_page_data->beat_time; + + p_outcoming_data->reserved[0] = UINT8_MAX; + p_outcoming_data->reserved[1] = UINT8_MAX; + p_outcoming_data->reserved[2] = UINT8_MAX; + p_outcoming_data->heart_beat_evt_time_LSB = (uint8_t)(beat_time & UINT8_MAX); + p_outcoming_data->heart_beat_evt_time_MSB = (uint8_t)((beat_time >> 8) & UINT8_MAX); + p_outcoming_data->heart_beat_count = (uint8_t)p_page_data->beat_count; + p_outcoming_data->computed_heart_rate = (uint8_t)p_page_data->computed_heart_rate; + + page0_data_log(p_page_data); +} + + +void ant_hrm_page_0_decode(uint8_t const * p_page_buffer, + ant_hrm_page0_data_t * p_page_data) +{ + ant_hrm_page0_data_layout_t const * p_incoming_data = + (ant_hrm_page0_data_layout_t *)p_page_buffer; + + uint32_t beat_time = (uint32_t)((p_incoming_data->heart_beat_evt_time_MSB << 8) + + p_incoming_data->heart_beat_evt_time_LSB); + + p_page_data->beat_count = (uint32_t)p_incoming_data->heart_beat_count; + p_page_data->computed_heart_rate = (uint32_t)p_incoming_data->computed_heart_rate; + p_page_data->beat_time = beat_time; + + page0_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_HRM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.h new file mode 100644 index 0000000000000000000000000000000000000000..60061832c4e7ab02e6390f927fab2b7250e42302 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.h @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_HRM_PAGE_0_H__ +#define ANT_HRM_PAGE_0_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_hrm_page0 HRM profile page 0 + * @{ + * @ingroup ant_sdk_profiles_hrm_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for HRM data page 0. + * + * This structure is used as a common page. + */ +typedef struct +{ + uint8_t beat_count; ///< Beat count. + uint8_t computed_heart_rate; ///< Computed heart rate. + uint16_t beat_time; ///< Beat time. +} ant_hrm_page0_data_t; + +/**@brief Initialize page 0. + */ +#define DEFAULT_ANT_HRM_PAGE0() \ + (ant_hrm_page0_data_t) \ + { \ + .beat_count = 0, \ + .computed_heart_rate = 0, \ + .beat_time = 0, \ + } + +/**@brief Function for encoding page 0. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_hrm_page_0_encode(uint8_t * p_page_buffer, + ant_hrm_page0_data_t const * p_page_data); + +/**@brief Function for decoding page 0. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_hrm_page_0_decode(uint8_t const * p_page_buffer, + ant_hrm_page0_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_HRM_PAGE_0_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.c new file mode 100644 index 0000000000000000000000000000000000000000..df9eb3272865e1ff184cd894b3301b982d11e44d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.c @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_HRM) + +#include "ant_hrm_page_1.h" +#include "ant_hrm_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_HRM_PAGE_1" +#if ANT_HRM_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_HRM_PAGE_1_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_1_INFO_COLOR +#else // ANT_HRM_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_HRM_PAGE_1_LOG_ENABLED +#include "nrf_log.h" + +/**@brief HRM page 1 data layout structure. */ +typedef struct +{ + uint8_t cumulative_operating_time[3]; + uint8_t reserved[4]; +}ant_hrm_page1_data_layout_t; + +/**@brief Function for tracing page 1 and common data. + * + * @param[in] p_common_data Pointer to the common data. + * @param[in] p_page_data Pointer to the page 1 data. + */ +static void page1_data_log(ant_hrm_page1_data_t const * p_page_data) +{ + NRF_LOG_INFO("Cumulative operating time: %ud %uh %um %us\r\n\n", + (unsigned int) ANT_HRM_OPERATING_DAYS(p_page_data->operating_time), + (unsigned int) ANT_HRM_OPERATING_HOURS(p_page_data->operating_time), + (unsigned int) ANT_HRM_OPERATING_MINUTES(p_page_data->operating_time), + (unsigned int) ANT_HRM_OPERATING_SECONDS(p_page_data->operating_time)); +} + + +void ant_hrm_page_1_encode(uint8_t * p_page_buffer, + ant_hrm_page1_data_t const * p_page_data) +{ + ant_hrm_page1_data_layout_t * p_outcoming_data = (ant_hrm_page1_data_layout_t *)p_page_buffer; + uint32_t operating_time = p_page_data->operating_time; + + UNUSED_PARAMETER(uint24_encode(operating_time, p_outcoming_data->cumulative_operating_time)); + page1_data_log(p_page_data); +} + + +void ant_hrm_page_1_decode(uint8_t const * p_page_buffer, + ant_hrm_page1_data_t * p_page_data) +{ + ant_hrm_page1_data_layout_t const * p_incoming_data = + (ant_hrm_page1_data_layout_t *)p_page_buffer; + + uint32_t operating_time = uint24_decode(p_incoming_data->cumulative_operating_time); + + p_page_data->operating_time = operating_time; + + page1_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_HRM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.h new file mode 100644 index 0000000000000000000000000000000000000000..b79c28e58b080223b8dcf78c23c34bcd04002006 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.h @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_HRM_PAGE_1_H__ +#define ANT_HRM_PAGE_1_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_hrm_page1 HRM profile page 1 + * @{ + * @ingroup ant_sdk_profiles_hrm_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for HRM data page 1. + * + * This structure implements only page 1 specific data. + */ +typedef struct +{ + uint32_t operating_time; ///< Operating time. +} ant_hrm_page1_data_t; + +/**@brief Initialize page 1. + */ +#define DEFAULT_ANT_HRM_PAGE1() \ + (ant_hrm_page1_data_t) \ + { \ + .operating_time = 0, \ + } + +/**@brief Function for encoding page 1. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_hrm_page_1_encode(uint8_t * p_page_buffer, + ant_hrm_page1_data_t const * p_page_data); + +/**@brief Function for decoding page 1. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_hrm_page_1_decode(uint8_t const * p_page_buffer, + ant_hrm_page1_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_HRM_PAGE_1_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.c new file mode 100644 index 0000000000000000000000000000000000000000..4b2f9a77262c56b6f0480515ec293b60c2b1661c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.c @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_HRM) + +#include "ant_hrm_page_2.h" + +#define NRF_LOG_MODULE_NAME "ANT_HRM_PAGE_2" +#if ANT_HRM_PAGE_2_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_HRM_PAGE_2_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_2_INFO_COLOR +#else // ANT_HRM_PAGE_2_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_HRM_PAGE_2_LOG_ENABLED +#include "nrf_log.h" + +/**@brief HRM page 2 data layout structure. */ +typedef struct +{ + uint8_t manuf_id; + uint8_t serial_num_LSB; + uint8_t serial_num_MSB; + uint8_t reserved[4]; +}ant_hrm_page2_data_layout_t; + +/**@brief Function for tracing page 2 and common data. + * + * @param[in] p_common_data Pointer to the common data. + * @param[in] p_page_data Pointer to the page 2 data. + */ +static void page2_data_log(ant_hrm_page2_data_t const * p_page_data) +{ + NRF_LOG_INFO("Manufacturer ID: %u\r\n", (unsigned int)p_page_data->manuf_id); + NRF_LOG_INFO("Serial No (upper 16-bits): 0x%X\r\n\n", (unsigned int)p_page_data->serial_num); +} + + +void ant_hrm_page_2_encode(uint8_t * p_page_buffer, + ant_hrm_page2_data_t const * p_page_data) +{ + ant_hrm_page2_data_layout_t * p_outcoming_data = (ant_hrm_page2_data_layout_t *)p_page_buffer; + uint32_t serial_num = p_page_data->serial_num; + + p_outcoming_data->manuf_id = (uint8_t)p_page_data->manuf_id; + p_outcoming_data->serial_num_LSB = (uint8_t)(serial_num & UINT8_MAX); + p_outcoming_data->serial_num_MSB = (uint8_t)((serial_num >> 8) & UINT8_MAX); + + page2_data_log(p_page_data); +} + + +void ant_hrm_page_2_decode(uint8_t const * p_page_buffer, + ant_hrm_page2_data_t * p_page_data) +{ + ant_hrm_page2_data_layout_t const * p_incoming_data = + (ant_hrm_page2_data_layout_t *)p_page_buffer; + uint32_t serial_num = + (uint32_t)((p_incoming_data->serial_num_MSB << 8) + + p_incoming_data-> + serial_num_LSB); + + p_page_data->manuf_id = (uint32_t)p_incoming_data->manuf_id; + p_page_data->serial_num = serial_num; + + page2_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_HRM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.h new file mode 100644 index 0000000000000000000000000000000000000000..6d426e73a7f48aac07651843c6774fecbcd64fb3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.h @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_HRM_PAGE_2_H__ +#define ANT_HRM_PAGE_2_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_hrm_page2 HRM profile page 2 + * @{ + * @ingroup ant_sdk_profiles_hrm_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for HRM data page 2. + * + * This structure implements only page 2 specific data. + */ +typedef struct +{ + uint8_t manuf_id; ///< Manufacturer ID. + uint16_t serial_num; ///< Serial number. +} ant_hrm_page2_data_t; + +/**@brief Initialize page 2. + */ +#define DEFAULT_ANT_HRM_PAGE2() \ + (ant_hrm_page2_data_t) \ + { \ + .manuf_id = 0, \ + .serial_num = 0, \ + } + +/**@brief Function for encoding page 2. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_hrm_page_2_encode(uint8_t * p_page_buffer, + ant_hrm_page2_data_t const * p_page_data); + +/**@brief Function for decoding page 2. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_hrm_page_2_decode(uint8_t const * p_page_buffer, + ant_hrm_page2_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_HRM_PAGE_2_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.c new file mode 100644 index 0000000000000000000000000000000000000000..55f0fbf8bad19a76af81229721858295f2baf022 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.c @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_HRM) + +#include "ant_hrm_page_3.h" + +#define NRF_LOG_MODULE_NAME "ANT_HRM_PAGE_3" +#if ANT_HRM_PAGE_3_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_HRM_PAGE_3_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_3_INFO_COLOR +#else // ANT_HRM_PAGE_3_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_HRM_PAGE_3_LOG_ENABLED +#include "nrf_log.h" + +/**@brief HRM page 3 data layout structure. */ +typedef struct +{ + uint8_t hw_version; + uint8_t sw_version; + uint8_t model_num; + uint8_t reserved[4]; +}ant_hrm_page3_data_layout_t; + +/**@brief Function for tracing page 3 and common data. + * + * @param[in] p_common_data Pointer to the common data. + * @param[in] p_page_data Pointer to the page 3 data. + */ +static void page3_data_log(ant_hrm_page3_data_t const * p_page_data) +{ + NRF_LOG_INFO("Hardware Rev ID %u\r\n", (unsigned int)p_page_data->hw_version); + NRF_LOG_INFO("Model %u\r\n", (unsigned int)p_page_data->model_num); + NRF_LOG_INFO("Software Ver ID %u\r\n\n", (unsigned int)p_page_data->sw_version); +} + + +void ant_hrm_page_3_encode(uint8_t * p_page_buffer, + ant_hrm_page3_data_t const * p_page_data) +{ + ant_hrm_page3_data_layout_t * p_outcoming_data = (ant_hrm_page3_data_layout_t *)p_page_buffer; + + p_outcoming_data->hw_version = (uint8_t)p_page_data->hw_version; + p_outcoming_data->sw_version = (uint8_t)p_page_data->sw_version; + p_outcoming_data->model_num = (uint8_t)p_page_data->model_num; + + page3_data_log(p_page_data); +} + + +void ant_hrm_page_3_decode(uint8_t const * p_page_buffer, + ant_hrm_page3_data_t * p_page_data) +{ + ant_hrm_page3_data_layout_t const * p_incoming_data = + (ant_hrm_page3_data_layout_t *)p_page_buffer; + + p_page_data->hw_version = (uint32_t)p_incoming_data->hw_version; + p_page_data->sw_version = (uint32_t)p_incoming_data->sw_version; + p_page_data->model_num = (uint32_t)p_incoming_data->model_num; + + page3_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_HRM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.h new file mode 100644 index 0000000000000000000000000000000000000000..8f04b37856edd25a2e5120b91c0d70ce6c45c0dd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.h @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_HRM_PAGE_3_H__ +#define ANT_HRM_PAGE_3_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_hrm_page3 HRM profile page 3 + * @{ + * @ingroup ant_sdk_profiles_hrm_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for HRM data page 3. + * + * This structure implements only page 3 specific data. + */ +typedef struct +{ + uint8_t hw_version; ///< Hardware version. + uint8_t sw_version; ///< Software version. + uint8_t model_num; ///< Model number. +} ant_hrm_page3_data_t; + +/**@brief Initialize page 3. + */ +#define DEFAULT_ANT_HRM_PAGE3() \ + (ant_hrm_page3_data_t) \ + { \ + .hw_version = 0, \ + .sw_version = 0, \ + .model_num = 0, \ + } + +/**@brief Function for encoding page 3. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_hrm_page_3_encode(uint8_t * p_page_buffer, + ant_hrm_page3_data_t const * p_page_data); + +/**@brief Function for decoding page 3. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_hrm_page_3_decode(uint8_t const * p_page_buffer, + ant_hrm_page3_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_HRM_PAGE_3_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.c new file mode 100644 index 0000000000000000000000000000000000000000..9ee44256ff9fb0d2c9e0bf4b3241953526de0271 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.c @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_HRM) + +#include "ant_hrm_page_4.h" +#include "ant_hrm_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_HRM_PAGE_4" +#if ANT_HRM_PAGE_4_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_HRM_PAGE_4_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_4_INFO_COLOR +#else // ANT_HRM_PAGE_4_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_HRM_PAGE_4_LOG_ENABLED +#include "nrf_log.h" + +/**@brief HRM page 4 data layout structure. */ +typedef struct +{ + uint8_t manuf_spec; + uint8_t prev_beat_LSB; + uint8_t prev_beat_MSB; + uint8_t reserved[4]; +}ant_hrm_page4_data_layout_t; + +/**@brief Function for tracing page 4 and common data. + * + * @param[in] p_common_data Pointer to the common data. + * @param[in] p_page_data Pointer to the page 4 data. + */ +static void page4_data_log(ant_hrm_page4_data_t const * p_page_data) +{ + NRF_LOG_INFO("Previous heart beat event time: %u.%03us\r\n\n", + (unsigned int)ANT_HRM_BEAT_TIME_SEC(p_page_data->prev_beat), + (unsigned int)ANT_HRM_BEAT_TIME_MSEC(p_page_data->prev_beat)); +} + + +void ant_hrm_page_4_encode(uint8_t * p_page_buffer, + ant_hrm_page4_data_t const * p_page_data) +{ + ant_hrm_page4_data_layout_t * p_outcoming_data = (ant_hrm_page4_data_layout_t *)p_page_buffer; + uint32_t prev_beat = p_page_data->prev_beat; + + p_outcoming_data->manuf_spec = p_page_data->manuf_spec; + p_outcoming_data->prev_beat_LSB = (uint8_t)(prev_beat & UINT8_MAX); + p_outcoming_data->prev_beat_MSB = (uint8_t)((prev_beat >> 8) & UINT8_MAX); + + page4_data_log(p_page_data); +} + + +void ant_hrm_page_4_decode(uint8_t const * p_page_buffer, + ant_hrm_page4_data_t * p_page_data) +{ + ant_hrm_page4_data_layout_t const * p_incoming_data = + (ant_hrm_page4_data_layout_t *)p_page_buffer; + + uint32_t prev_beat = (uint32_t)((p_incoming_data->prev_beat_MSB << 8) + + p_incoming_data->prev_beat_LSB); + + p_page_data->manuf_spec = p_incoming_data->manuf_spec; + p_page_data->prev_beat = prev_beat; + + page4_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_HRM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.h new file mode 100644 index 0000000000000000000000000000000000000000..a73e80cce1e42dd544ce5d499a1157bfbe11a421 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.h @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_HRM_PAGE_4_H__ +#define ANT_HRM_PAGE_4_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_hrm_page4 HRM profile page 4 + * @{ + * @ingroup ant_sdk_profiles_hrm_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for HRM data page 4. + * + * This structure implements only page 4 specific data. + */ +typedef struct +{ + uint8_t manuf_spec; ///< Manufacturer specific byte. + uint16_t prev_beat; ///< Previous beat. +} ant_hrm_page4_data_t; + +/**@brief Initialize page 4. + */ +#define DEFAULT_ANT_HRM_PAGE4() \ + (ant_hrm_page4_data_t) \ + { \ + .manuf_spec = 0, \ + .prev_beat = 0, \ + } + +/**@brief Function for encoding page 4. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_hrm_page_4_encode(uint8_t * p_page_buffer, + ant_hrm_page4_data_t const * p_page_data); + +/**@brief Function for decoding page 4. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_hrm_page_4_decode(uint8_t const * p_page_buffer, + ant_hrm_page4_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_HRM_PAGE_3_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_pages.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_pages.h new file mode 100644 index 0000000000000000000000000000000000000000..ae82ba91576b9a5a6e19a7ac70b1cdfd6950841b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_pages.h @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef __ANT_HRM_PAGES_H +#define __ANT_HRM_PAGES_H + +/** @file + * + * @defgroup ant_sdk_profiles_hrm_pages Heart Rate Monitor profile pages + * @{ + * @ingroup ant_hrm + * @brief This module implements functions for the HRM data pages. + */ + +#include "ant_hrm_page_0.h" +#include "ant_hrm_page_1.h" +#include "ant_hrm_page_2.h" +#include "ant_hrm_page_3.h" +#include "ant_hrm_page_4.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif // __ANT_HRM_PAGES_H +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.c new file mode 100644 index 0000000000000000000000000000000000000000..786de567edca80f95cd9c184a9aa641841aa1a35 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.c @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if ANT_HRM_ENABLED + +#include "ant_hrm_simulator.h" +#include "ant_hrm_utils.h" +#include "nordic_common.h" + +#define ITERATION_ANT_CYCLES HRM_MSG_PERIOD_4Hz ///< period of calculation [1/32678 s], defined in ANT device profile +#define ITERATION_PERIOD (ITERATION_ANT_CYCLES * 1024 / ANT_CLOCK_FREQUENCY) ///< integer part of calculation's period [1/1024 s] +#define ITERATION_FRACTION (ITERATION_ANT_CYCLES * 1024 % ANT_CLOCK_FREQUENCY) ///< fractional part of calculation's period [1/32678 s] + +void ant_hrm_simulator_init(ant_hrm_simulator_t * p_simulator, + ant_hrm_simulator_cfg_t const * p_config, + bool auto_change) +{ + + p_simulator->p_profile = p_config->p_profile; + p_simulator->_cb.sensorsim_cfg = p_config->sensorsim_cfg; + p_simulator->_cb.auto_change = auto_change; + p_simulator->_cb.sensorsim_state.current_val = p_simulator->_cb.sensorsim_cfg.min; + p_simulator->_cb.time_since_last_hb = 0; + p_simulator->_cb.fraction_since_last_hb = 0; + + sensorsim_init(&(p_simulator->_cb.sensorsim_state), &(p_simulator->_cb.sensorsim_cfg)); +} + + +void ant_hrm_simulator_one_iteration(ant_hrm_simulator_t * p_simulator) +{ + + if (p_simulator->_cb.auto_change) + { + UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.sensorsim_state), + &(p_simulator->_cb.sensorsim_cfg))); + } + + // @note: Take a local copy within scope in order to assist the compiler in variable register + // allocation. + const uint32_t computed_heart_rate_value = p_simulator->_cb.sensorsim_state.current_val; + + // @note: This implementation assumes that the current instantaneous heart can vary and this + // function is called with static frequency. + // value and the heart rate pulse interval is derived from it. The computation is based on 60 + // seconds in a minute and the used time base is 1/1024 seconds. + const uint32_t current_hb_pulse_interval = (60u * 1024u) / computed_heart_rate_value; + + // update time from last hb detected + p_simulator->_cb.time_since_last_hb += ITERATION_PERIOD; + + // extended celculadion by fraction make calculating accurat in long time perspective + p_simulator->_cb.fraction_since_last_hb += ITERATION_FRACTION; + uint32_t add_period = p_simulator->_cb.fraction_since_last_hb / ANT_CLOCK_FREQUENCY; + + if (add_period > 0) + { + p_simulator->_cb.time_since_last_hb++; + p_simulator->_cb.fraction_since_last_hb %= ANT_CLOCK_FREQUENCY; + } + + // calc number of hb as will fill + uint32_t new_beats = p_simulator->_cb.time_since_last_hb / current_hb_pulse_interval; + uint32_t add_event_time = new_beats * current_hb_pulse_interval; + + if (new_beats > 0) + { + p_simulator->p_profile->HRM_PROFILE_computed_heart_rate = + (uint8_t)computed_heart_rate_value; + + // Current heart beat event time is the previous event time added with the current heart rate + // pulse interval. + uint32_t current_heart_beat_event_time = p_simulator->p_profile->HRM_PROFILE_beat_time + + add_event_time; + + // Set current event time. + p_simulator->p_profile->HRM_PROFILE_beat_time = current_heart_beat_event_time; // <- B<4,5> <- + + // Set previous event time. // p4.B<2,3> <- B<4,5> + p_simulator->p_profile->HRM_PROFILE_prev_beat = + p_simulator->p_profile->HRM_PROFILE_beat_time - current_hb_pulse_interval; + + // Event count. + p_simulator->p_profile->HRM_PROFILE_beat_count += new_beats; // B<6> + + p_simulator->_cb.time_since_last_hb -= add_event_time; + } +} + + +void ant_hrm_simulator_increment(ant_hrm_simulator_t * p_simulator) +{ + if (!p_simulator->_cb.auto_change) + { + sensorsim_increment(&(p_simulator->_cb.sensorsim_state), + &(p_simulator->_cb.sensorsim_cfg)); + } +} + + +void ant_hrm_simulator_decrement(ant_hrm_simulator_t * p_simulator) +{ + if (!p_simulator->_cb.auto_change) + { + sensorsim_decrement(&(p_simulator->_cb.sensorsim_state), + &(p_simulator->_cb.sensorsim_cfg)); + } +} + + +#endif // ANT_HRM_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.h new file mode 100644 index 0000000000000000000000000000000000000000..5671ad42c91973c8af3eddf644702783f8621c5f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.h @@ -0,0 +1,130 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_HRM_SIMULATOR_H__ +#define ANT_HRM_SIMULATOR_H__ + +/** @file + * + * @defgroup ant_sdk_hrm_simulator ANT HRM simulator + * @{ + * @ingroup ant_sdk_simulators + * @brief ANT HRM simulator module. + * + * @details This module simulates a pulse for the ANT HRM profile. The module calculates abstract values, which are handled + * by the HRM pages data model to ensure that they are compatible. It provides a handler for changing the heart rate + * value manually and functionality to change the heart rate value automatically. + * + */ + +#include +#include +#include "ant_hrm.h" +#include "ant_hrm_utils.h" +#include "sensorsim.h" +#include "ant_hrm_simulator_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief HRM simulator configuration structure. */ +typedef struct +{ + ant_hrm_profile_t * p_profile; ///< Related profile. + sensorsim_cfg_t sensorsim_cfg; ///< Sensorsim configuration. +} ant_hrm_simulator_cfg_t; + +/**@brief Initialize @ref ant_hrm_simulator_cfg_t. + */ +#define DEFAULT_ANT_HRM_SIMULATOR_CFG(P_PROFILE, MIN_HEART_RATE, MAX_HEART_RATE, INCREMENT) \ + { \ + .p_profile = (P_PROFILE), \ + .sensorsim_cfg.min = (MIN_HEART_RATE), \ + .sensorsim_cfg.max = (MAX_HEART_RATE), \ + .sensorsim_cfg.incr = (INCREMENT), \ + .sensorsim_cfg.start_at_max = false, \ + } + +/**@brief HRM simulator structure. */ +typedef struct +{ + ant_hrm_profile_t * p_profile; ///< Related profile. + ant_hrm_simulator_cb_t _cb; ///< Internal control block. +} ant_hrm_simulator_t; + + +/**@brief Function for initializing the ANT HRM simulator instance. + * + * @param[in] p_simulator Pointer to the simulator instance. + * @param[in] p_config Pointer to the simulator configuration structure. + * @param[in] auto_change Enable or disable automatic changes of the cadence. + */ +void ant_hrm_simulator_init(ant_hrm_simulator_t * p_simulator, + ant_hrm_simulator_cfg_t const * p_config, + bool auto_change); + +/**@brief Function for simulating a device event. + * + * @details Based on this event, the transmitter data is simulated. + * + * This function should be called in the HRM TX event handler. + */ +void ant_hrm_simulator_one_iteration(ant_hrm_simulator_t * p_simulator); + +/**@brief Function for incrementing the cadence value. + * + * @param[in] p_simulator Pointer to the simulator instance. + */ +void ant_hrm_simulator_increment(ant_hrm_simulator_t * p_simulator); + +/**@brief Function for decrementing the cadence value. + * + * @param[in] p_simulator Pointer to the simulator instance. + */ +void ant_hrm_simulator_decrement(ant_hrm_simulator_t * p_simulator); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_HRM_SIMULATOR_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator_local.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator_local.h new file mode 100644 index 0000000000000000000000000000000000000000..a1b7018abc9bea8bcb517754664e45e68cfd52f6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator_local.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_HRM_SIMULATOR_LOCAL_H__ +#define ANT_HRM_SIMULATOR_LOCAL_H__ + +#include +#include +#include "ant_hrm.h" +#include "sensorsim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup ant_sdk_hrm_simulator + * @brief HRM simulator control block structure. */ +typedef struct +{ + bool auto_change; ///< Cadence will change automatically (if auto_change is set) or manually. + uint32_t time_since_last_hb; ///< Time since last heart beat occurred (integer part). + uint64_t fraction_since_last_hb; ///< Time since last heart beat occurred (fractional part). + sensorsim_state_t sensorsim_state; ///< State of the simulated sensor. + sensorsim_cfg_t sensorsim_cfg; ///< Configuration of the simulated sensor. +} ant_hrm_simulator_cb_t; + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_HRM_SIMULATOR_LOCAL_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/utils/ant_hrm_utils.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/utils/ant_hrm_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..f8e35d9ec872ad89efe1c49e7902a5eda1dfddd4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_hrm/utils/ant_hrm_utils.h @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_HRM_UTILS_H__ +#define ANT_HRM_UTILS_H__ + +#include "app_util.h" +#include "nrf_assert.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + * + * @defgroup ant_sdk_profiles_hrm_utils Heart Rate Monitor profile utilities + * @{ + * @ingroup ant_hrm + * @brief This module implements utilities for the Heart Rate Monitor profile. + * + */ + +/**@brief Unit for HRM operating time. + * + * @details According to the ANT HRM specification, the operating time unit is 2 seconds. + */ +#define ANT_HRM_OPERATING_TIME_UNIT 2u + +/**@brief This macro should be used to get the seconds part of the operating time. + */ +#define ANT_HRM_OPERATING_SECONDS(OPERATING_TIME) (((OPERATING_TIME) * ANT_HRM_OPERATING_TIME_UNIT) % 60) + +/**@brief This macro should be used to get the minutes part of the operating time. + */ +#define ANT_HRM_OPERATING_MINUTES(OPERATING_TIME) ((((OPERATING_TIME) * ANT_HRM_OPERATING_TIME_UNIT) / 60) % 60) + +/**@brief This macro should be used to get the hours part of the operating time. + */ +#define ANT_HRM_OPERATING_HOURS(OPERATING_TIME) ((((OPERATING_TIME) * ANT_HRM_OPERATING_TIME_UNIT) / (60 * 60)) % 24) + +/**@brief This macro should be used to get the days part of the operating time. + */ +#define ANT_HRM_OPERATING_DAYS(OPERATING_TIME) ((((OPERATING_TIME) * ANT_HRM_OPERATING_TIME_UNIT) / (60 * 60)) / 24) + +/**@brief Number of HRM beat time counts per second. + * + * @details According to the ANT HRM specification, the beat time unit is 1/1024 of a second. + */ +#define ANT_HRM_BEAT_TIME_COUNTS_PER_SEC 1024u + +/**@brief Beat time display required precision. + * + * @details This value is used to decode the number of milliseconds. + */ +#define ANT_HRM_BEAT_TIME_PRECISION 1000u + +/**@brief This macro should be used to get the seconds part of the HRM beat time. + */ +#define ANT_HRM_BEAT_TIME_SEC(BEAT_TIME) ((BEAT_TIME) / ANT_HRM_BEAT_TIME_COUNTS_PER_SEC) + +/**@brief This macro should be used to get the milliseconds part of the HRM beat time. + */ +#define ANT_HRM_BEAT_TIME_MSEC(BEAT_TIME) (((((BEAT_TIME) % ANT_HRM_BEAT_TIME_COUNTS_PER_SEC) * ANT_HRM_BEAT_TIME_PRECISION) \ + + (ANT_HRM_BEAT_TIME_COUNTS_PER_SEC / 2)) \ + / ANT_HRM_BEAT_TIME_COUNTS_PER_SEC) +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_HRM_UTILS_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/ant_sdm.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/ant_sdm.c new file mode 100644 index 0000000000000000000000000000000000000000..a2acd9aaba9d76a9d58fcd55b3c16a566279936e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/ant_sdm.c @@ -0,0 +1,399 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + +#include "nrf_assert.h" +#include "app_error.h" +#include "ant_interface.h" +#include "ant_sdm.h" +#include "app_error.h" +#include "ant_sdm_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM" +#if ANT_SDM_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_INFO_COLOR +#else // ANT_SDM_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_LOG_ENABLED +#include "nrf_log.h" + +#define COMMON_DATA_INTERVAL 64 /**< Common data page is sent every 65th message. */ + +/**@brief SDM message data layout structure. */ +typedef struct +{ + ant_sdm_page_t page_number; + uint8_t page_payload[7]; +}ant_sdm_message_layout_t; + +/**@brief Function for initializing the ANT SDM profile instance. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_channel_config Pointer to the ANT channel configuration structure. + * + * @retval NRF_SUCCESS Successful initialization. + * Error code when initialization failed. + */ +static ret_code_t ant_sdm_init(ant_sdm_profile_t * p_profile, + ant_channel_config_t const * p_channel_config) +{ + p_profile->channel_number = p_channel_config->channel_number; + + p_profile->page_1 = DEFAULT_ANT_SDM_PAGE1(); + p_profile->page_2 = DEFAULT_ANT_SDM_PAGE2(); + p_profile->page_3 = DEFAULT_ANT_SDM_PAGE3(); + p_profile->page_22 = DEFAULT_ANT_SDM_PAGE22(); + p_profile->common = DEFAULT_ANT_SDM_COMMON_DATA(); + p_profile->page_80 = DEFAULT_ANT_COMMON_page80(); + p_profile->page_81 = DEFAULT_ANT_COMMON_page81(); + + NRF_LOG_INFO("ANT SDM channel %u init\r\n", p_profile->channel_number); + return ant_channel_init(p_channel_config); +} + +ret_code_t ant_sdm_disp_init(ant_sdm_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_sdm_disp_config_t const * p_disp_config) +{ + ASSERT(p_profile != NULL); + ASSERT(p_channel_config != NULL); + ASSERT(p_disp_config != NULL); + ASSERT(p_disp_config->p_cb != NULL); + ASSERT(p_disp_config->evt_handler != NULL); + + p_profile->evt_handler = p_disp_config->evt_handler; + p_profile->_cb.p_disp_cb = p_disp_config->p_cb; + ant_request_controller_init(&(p_profile->_cb.p_disp_cb->req_controller)); + + return ant_sdm_init(p_profile, p_channel_config); +} + +ret_code_t ant_sdm_sens_init(ant_sdm_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_sdm_sens_config_t const * p_sens_config) +{ + ASSERT(p_profile != NULL); + ASSERT(p_channel_config != NULL); + ASSERT(p_sens_config != NULL); + ASSERT(p_sens_config->p_cb != NULL); + ASSERT(p_sens_config->evt_handler != NULL); + ASSERT(p_sens_config->supplementary_page_number == ANT_SDM_PAGE_1 + || p_sens_config->supplementary_page_number == ANT_SDM_PAGE_2 + || p_sens_config->supplementary_page_number == ANT_SDM_PAGE_3); + + p_profile->evt_handler = p_sens_config->evt_handler; + p_profile->_cb.p_sens_cb = p_sens_config->p_cb; + ant_request_controller_init(&(p_profile->_cb.p_sens_cb->req_controller)); + + p_profile->_cb.p_sens_cb->message_counter = 0; + p_profile->_cb.p_sens_cb->supp_page_control = 0; + p_profile->_cb.p_sens_cb->supp_page_number = p_sens_config->supplementary_page_number; + p_profile->_cb.p_sens_cb->common_page_number = ANT_SDM_PAGE_80; + + return ant_sdm_init(p_profile, p_channel_config); +} + +ret_code_t ant_sdm_page_request(ant_sdm_profile_t * p_profile, ant_common_page70_data_t * p_page_70) +{ + ASSERT(p_profile != NULL); + ASSERT(p_page_70 != NULL); + + uint32_t err_code = ant_request_controller_request(&(p_profile->_cb.p_disp_cb->req_controller), + p_profile->channel_number, p_page_70); + NRF_LOG_INFO("\r\n"); + + return err_code; +} + +/**@brief Function for getting next page number to send. + * + * @param[in] p_profile Pointer to the profile instance. + * + * @return Next page number. + */ +static ant_sdm_page_t next_page_number_get(ant_sdm_profile_t * p_profile) +{ + ant_sdm_sens_cb_t * p_sdm_cb = p_profile->_cb.p_sens_cb; + ant_sdm_page_t page_number; + + if (ant_request_controller_pending_get(&(p_sdm_cb->req_controller), (uint8_t *)&page_number)) + { + // No implementation needed + } + else if (p_sdm_cb->message_counter == (COMMON_DATA_INTERVAL)) + { + page_number = p_sdm_cb->common_page_number; + p_sdm_cb->message_counter++; + } + else if (p_sdm_cb->message_counter == (COMMON_DATA_INTERVAL + 1)) + { + page_number = p_sdm_cb->common_page_number; + p_sdm_cb->common_page_number = (p_sdm_cb->common_page_number == ANT_SDM_PAGE_80) + ? ANT_SDM_PAGE_81 : ANT_SDM_PAGE_80; + p_sdm_cb->message_counter = 0; + } + else + { + if (p_sdm_cb->supp_page_control) + { + page_number = p_sdm_cb->supp_page_number; + } + else + { + page_number = ANT_SDM_PAGE_1; + } + + if ((p_sdm_cb->message_counter % 2) == 1) + { + p_sdm_cb->supp_page_control = !p_sdm_cb->supp_page_control; + } + p_sdm_cb->message_counter++; + } + return page_number; +} + +/**@brief Function for encoding SDM message. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_message_payload Pointer to the message payload. + * + * @note Assume to be call each time when Tx window will occur. + */ +static void sens_message_encode(ant_sdm_profile_t * p_profile, uint8_t * p_message_payload) +{ + ant_sdm_message_layout_t * p_sdm_message_payload = (ant_sdm_message_layout_t *)p_message_payload; + + p_sdm_message_payload->page_number = next_page_number_get(p_profile); + + NRF_LOG_INFO("SDM Page number: %u\r\n", p_sdm_message_payload->page_number); + + switch (p_sdm_message_payload->page_number) + { + case ANT_SDM_PAGE_1: + ant_sdm_page_1_encode(p_sdm_message_payload->page_payload, &(p_profile->page_1), + &(p_profile->common)); + ant_sdm_speed_encode(p_sdm_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_SDM_PAGE_2: + ant_sdm_page_2_encode(p_sdm_message_payload->page_payload, &(p_profile->page_2)); + ant_sdm_speed_encode(p_sdm_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_SDM_PAGE_3: + ant_sdm_page_2_encode(p_sdm_message_payload->page_payload, &(p_profile->page_2)); + ant_sdm_page_3_encode(p_sdm_message_payload->page_payload, &(p_profile->page_3)); + ant_sdm_speed_encode(p_sdm_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_SDM_PAGE_16: + ant_sdm_page_16_encode(p_sdm_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_SDM_PAGE_22: + ant_sdm_page_22_encode(p_sdm_message_payload->page_payload, &(p_profile->page_22)); + break; + + case ANT_SDM_PAGE_80: + ant_common_page_80_encode(p_sdm_message_payload->page_payload, &(p_profile->page_80)); + break; + + case ANT_SDM_PAGE_81: + ant_common_page_81_encode(p_sdm_message_payload->page_payload, &(p_profile->page_81)); + break; + + default: + return; + } + + p_profile->evt_handler(p_profile, (ant_sdm_evt_t)p_sdm_message_payload->page_number); +} + +void ant_sdm_sens_evt_handler(ant_sdm_profile_t * p_profile, ant_evt_t * p_ant_event) +{ + ASSERT(p_profile != NULL); + ASSERT(p_ant_event != NULL); + + if (p_ant_event->channel == p_profile->channel_number) + { + uint32_t err_code; + uint8_t p_message_payload[ANT_STANDARD_DATA_PAYLOAD_SIZE]; + ant_sdm_sens_cb_t * p_sdm_cb = p_profile->_cb.p_sens_cb; + ant_request_controller_sens_evt_handler(&(p_sdm_cb->req_controller), p_ant_event); + + switch (p_ant_event->event) + { + case EVENT_TX: + case EVENT_TRANSFER_TX_FAILED: + case EVENT_TRANSFER_TX_COMPLETED: + sens_message_encode(p_profile, p_message_payload); + if (ant_request_controller_ack_needed(&(p_sdm_cb->req_controller))) + { + err_code = sd_ant_acknowledge_message_tx(p_profile->channel_number, sizeof(p_message_payload), p_message_payload); + } + else + { + err_code = sd_ant_broadcast_message_tx(p_profile->channel_number, sizeof(p_message_payload), p_message_payload); + } + APP_ERROR_CHECK(err_code); + break; + default: + break; + } + } +} + +ret_code_t ant_sdm_disp_open(ant_sdm_profile_t * p_profile) +{ + ASSERT(p_profile != NULL); + + NRF_LOG_INFO("ANT SDM channel %u open\r\n", p_profile->channel_number); + return sd_ant_channel_open(p_profile->channel_number); +} + +ret_code_t ant_sdm_sens_open(ant_sdm_profile_t * p_profile) +{ + ASSERT(p_profile != NULL); + + // Fill tx buffer for the first frame + uint32_t err_code; + uint8_t p_message_payload[ANT_STANDARD_DATA_PAYLOAD_SIZE]; + + sens_message_encode(p_profile, p_message_payload); + err_code = + sd_ant_broadcast_message_tx(p_profile->channel_number, + sizeof (p_message_payload), + p_message_payload); + APP_ERROR_CHECK(err_code); + + NRF_LOG_INFO("ANT SDM channel %u open\r\n", p_profile->channel_number); + return sd_ant_channel_open(p_profile->channel_number); +} + + +/**@brief Function for decoding SDM message. + * + * @note Assume to be call each time when Rx window will occur. + */ +static void disp_message_decode(ant_sdm_profile_t * p_profile, uint8_t * p_message_payload) +{ + const ant_sdm_message_layout_t * p_sdm_message_payload = (ant_sdm_message_layout_t *)p_message_payload; + + NRF_LOG_INFO("SDM Page number: %u\r\n", p_sdm_message_payload->page_number); + + switch (p_sdm_message_payload->page_number) + { + case ANT_SDM_PAGE_1: + ant_sdm_page_1_decode(p_sdm_message_payload->page_payload, &(p_profile->page_1), &(p_profile->common)); + ant_sdm_speed_decode(p_sdm_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_SDM_PAGE_3: + ant_sdm_page_3_decode(p_sdm_message_payload->page_payload, &(p_profile->page_3)); + /* fall through */ + case ANT_SDM_PAGE_2: + ant_sdm_page_2_decode(p_sdm_message_payload->page_payload, &(p_profile->page_2)); + ant_sdm_speed_decode(p_sdm_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_SDM_PAGE_16: + ant_sdm_page_16_decode(p_sdm_message_payload->page_payload, &(p_profile->common)); + break; + + case ANT_SDM_PAGE_22: + ant_sdm_page_22_decode(p_sdm_message_payload->page_payload, &(p_profile->page_22)); + break; + + case ANT_SDM_PAGE_80: + ant_common_page_80_decode(p_sdm_message_payload->page_payload, &(p_profile->page_80)); + break; + + case ANT_SDM_PAGE_81: + ant_common_page_81_decode(p_sdm_message_payload->page_payload, &(p_profile->page_81)); + break; + + default: + return; + } + + p_profile->evt_handler(p_profile, (ant_sdm_evt_t)p_sdm_message_payload->page_number); +} + +void ant_sdm_disp_evt_handler(ant_sdm_profile_t * p_profile, ant_evt_t * p_ant_event) +{ + ASSERT(p_profile != NULL); + ASSERT(p_ant_event != NULL); + + if (p_ant_event->channel == p_profile->channel_number) + { + ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->msg.evt_buffer; + ant_sdm_disp_cb_t * p_sdm_cb = p_profile->_cb.p_disp_cb; + + switch (ant_request_controller_disp_evt_handler(&(p_sdm_cb->req_controller), p_ant_event)) + { + case ANT_REQUEST_CONTROLLER_SUCCESS: + p_profile->evt_handler(p_profile, ANT_SDM_PAGE_REQUEST_SUCCESS); + break; + case ANT_REQUEST_CONTROLLER_FAILED: + p_profile->evt_handler(p_profile, ANT_SDM_PAGE_REQUEST_FAILED); + break; + default: + break; + } + + switch (p_ant_event->event) + { + case EVENT_RX: + if (p_message->ANT_MESSAGE_ucMesgID == MESG_BROADCAST_DATA_ID + || p_message->ANT_MESSAGE_ucMesgID == MESG_ACKNOWLEDGED_DATA_ID + || p_message->ANT_MESSAGE_ucMesgID == MESG_BURST_DATA_ID) + { + disp_message_decode(p_profile, p_message->ANT_MESSAGE_aucPayload); + } + break; + default: + break; + } + } +} + +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/ant_sdm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/ant_sdm.h new file mode 100644 index 0000000000000000000000000000000000000000..dceef0507fed971cbd79e95ed9b2916509594048 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/ant_sdm.h @@ -0,0 +1,330 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ant_sdm Stride Based Speed and Distance Monitor profile + * @{ + * @ingroup ant_sdk_profiles + * @brief This module implements the Stride Based Speed and Distance Monitor profile. + * + */ + +#ifndef ANT_SDM_H__ +#define ANT_SDM_H__ + +#include +#include +#include "ant_parameters.h" +#include "ant_stack_handler_types.h" +#include "ant_channel_config.h" +#include "ant_request_controller.h" +#include "ant_sdm_pages.h" +#include "sdk_errors.h" + +#define SDM_DEVICE_TYPE 0x7Cu ///< Device type reserved for ANT+ SDM. +#define SDM_ANTPLUS_RF_FREQ 0x39u ///< Frequency, decimal 57 (2457 MHz). + +#define SDM_MSG_PERIOD_4Hz 0x1FC6u ///< Message period, decimal 8134 (4.03 Hz). +#define SDM_MSG_PERIOD_2Hz 0x3F8Cu ///< Message period, decimal 16268 (2.01 Hz). + +#define SDM_EXT_ASSIGN 0x00 ///< ANT ext assign (see Ext. Assign Channel Parameters in ant_parameters.h: @ref ant_parameters). +#define SDM_DISP_CHANNEL_TYPE CHANNEL_TYPE_SLAVE ///< RX SDM channel type. +#define SDM_SENS_CHANNEL_TYPE CHANNEL_TYPE_MASTER ///< TX SDM channel type. + +/**@brief Initialize an ANT channel configuration structure for the SDM profile (Display). + * + * @param[in] NAME Name of related instance. + * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance. + * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance. + * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance. + * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance. + * @param[in] SDM_MSG_PERIOD Channel period in 32 kHz counts. The SDM profile supports only the following periods: + * @ref SDM_MSG_PERIOD_4Hz, @ref SDM_MSG_PERIOD_2Hz. + */ +#define SDM_DISP_CHANNEL_CONFIG_DEF(NAME, \ + CHANNEL_NUMBER, \ + TRANSMISSION_TYPE, \ + DEVICE_NUMBER, \ + NETWORK_NUMBER, \ + SDM_MSG_PERIOD) \ +static const ant_channel_config_t NAME##_channel_sdm_disp_config = \ + { \ + .channel_number = (CHANNEL_NUMBER), \ + .channel_type = SDM_DISP_CHANNEL_TYPE, \ + .ext_assign = SDM_EXT_ASSIGN, \ + .rf_freq = SDM_ANTPLUS_RF_FREQ, \ + .transmission_type = (TRANSMISSION_TYPE), \ + .device_type = SDM_DEVICE_TYPE, \ + .device_number = (DEVICE_NUMBER), \ + .channel_period = (SDM_MSG_PERIOD), \ + .network_number = (NETWORK_NUMBER), \ + } +#define SDM_DISP_CHANNEL_CONFIG(NAME) &NAME##_channel_sdm_disp_config + +/**@brief Initialize an ANT channel configuration structure for the SDM profile (Sensor). + * + * @param[in] NAME Name of related instance. + * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance. + * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance. + * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance. + * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance. + */ +#define SDM_SENS_CHANNEL_CONFIG_DEF(NAME, \ + CHANNEL_NUMBER, \ + TRANSMISSION_TYPE, \ + DEVICE_NUMBER, \ + NETWORK_NUMBER) \ +static const ant_channel_config_t NAME##_channel_sdm_sens_config = \ + { \ + .channel_number = (CHANNEL_NUMBER), \ + .channel_type = SDM_SENS_CHANNEL_TYPE, \ + .ext_assign = SDM_EXT_ASSIGN, \ + .rf_freq = SDM_ANTPLUS_RF_FREQ, \ + .transmission_type = (TRANSMISSION_TYPE), \ + .device_type = SDM_DEVICE_TYPE, \ + .device_number = (DEVICE_NUMBER), \ + .channel_period = SDM_MSG_PERIOD_4Hz, \ + .network_number = (NETWORK_NUMBER), \ + } +#define SDM_SENS_CHANNEL_CONFIG(NAME) &NAME##_channel_sdm_sens_config + +/**@brief Initialize an ANT profile configuration structure for the SDM profile (Display). + * + * @param[in] NAME Name of related instance. + * @param[in] EVT_HANDLER Event handler to be called for handling events in the SDM profile. + */ +#define SDM_DISP_PROFILE_CONFIG_DEF(NAME, \ + EVT_HANDLER) \ +static ant_sdm_disp_cb_t NAME##_sdm_disp_cb; \ +static const ant_sdm_disp_config_t NAME##_profile_sdm_disp_config = \ + { \ + .p_cb = &NAME##_sdm_disp_cb, \ + .evt_handler = (EVT_HANDLER), \ + } +#define SDM_DISP_PROFILE_CONFIG(NAME) &NAME##_profile_sdm_disp_config + +/**@brief Initialize an ANT profile configuration structure for the SDM profile (Sensor). + * + * @param[in] NAME Name of related instance. + * @param[in] SUPPLEMENTARY_PAGE_NUMBER Supplementary data page (ANT_SDM_PAGE_2 or ANT_SDM_PAGE_3). Use ANT_SDM_PAGE_1 to disable. + * @param[in] EVT_HANDLER Event handler to be called for handling events in the SDM profile. + */ +#define SDM_SENS_PROFILE_CONFIG_DEF(NAME, \ + SUPPLEMENTARY_PAGE_NUMBER, \ + EVT_HANDLER) \ +static ant_sdm_sens_cb_t NAME##_sdm_sens_cb; \ +static const ant_sdm_sens_config_t NAME##_profile_sdm_sens_config = \ + { \ + .supplementary_page_number = (SUPPLEMENTARY_PAGE_NUMBER), \ + .p_cb = &NAME##_sdm_sens_cb, \ + .evt_handler = (EVT_HANDLER), \ + } +#define SDM_SENS_PROFILE_CONFIG(NAME) &NAME##_profile_sdm_sens_config + + +/**@brief SDM page number type. */ +typedef enum{ + ANT_SDM_PAGE_1 = 1, ///< Required data page 1. + ANT_SDM_PAGE_2 = 2, ///< Supplementary data page 2. + ANT_SDM_PAGE_3 = 3, ///< Supplementary data page 3. + ANT_SDM_PAGE_16 = 16, ///< Page 16 (sent on request). + ANT_SDM_PAGE_22 = 22, ///< Page 22 (sent on request). + ANT_SDM_PAGE_70 = ANT_COMMON_PAGE_70, + ANT_SDM_PAGE_80 = ANT_COMMON_PAGE_80, + ANT_SDM_PAGE_81 = ANT_COMMON_PAGE_81, +} ant_sdm_page_t; + +/**@brief SDM profile event type. */ +typedef enum{ + ANT_SDM_PAGE_1_UPDATED = ANT_SDM_PAGE_1, ///< Data page 1 and speed have been updated (Display) or sent (Sensor). + ANT_SDM_PAGE_2_UPDATED = ANT_SDM_PAGE_2, ///< Data page 2 and speed have been updated (Display) or sent (Sensor). + ANT_SDM_PAGE_3_UPDATED = ANT_SDM_PAGE_3, ///< Data page 3 and speed have been updated (Display) or sent (Sensor). + ANT_SDM_PAGE_16_UPDATED = ANT_SDM_PAGE_16, ///< Data page 16 has been updated (Display) or sent (Sensor). + ANT_SDM_PAGE_22_UPDATED = ANT_SDM_PAGE_22, ///< Data page 22 has been updated (Display) or sent (Sensor). + ANT_SDM_PAGE_80_UPDATED = ANT_SDM_PAGE_80, ///< Data page 80 has been updated (Display) or sent (Sensor). + ANT_SDM_PAGE_81_UPDATED = ANT_SDM_PAGE_81, ///< Data page 81 has been updated (Display) or sent (Sensor). + ANT_SDM_PAGE_REQUEST_SUCCESS, ///< Data page request reached the destination. + ANT_SDM_PAGE_REQUEST_FAILED, ///< Data page request did not reach the destination. +} ant_sdm_evt_t; + +// Forward declaration of the ant_sdm_profile_t type. +typedef struct ant_sdm_profile_s ant_sdm_profile_t; + +/**@brief SDM event handler type. */ +typedef void (* ant_sdm_evt_handler_t) (ant_sdm_profile_t *, ant_sdm_evt_t); + +#include "ant_sdm_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief SDM Sensor configuration structure. */ +typedef struct +{ + ant_sdm_page_t supplementary_page_number; ///< Supplementary data page (ANT_SDM_PAGE_2 or ANT_SDM_PAGE_3). Use ANT_SDM_PAGE_1 to disable. + ant_sdm_sens_cb_t * p_cb; ///< Pointer to the data buffer for internal use. + ant_sdm_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the SDM profile. +} ant_sdm_sens_config_t; + +/**@brief SDM Display configuration structure. */ +typedef struct +{ + ant_sdm_disp_cb_t * p_cb; ///< Pointer to the data buffer for internal use. + ant_sdm_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the SDM profile. +} ant_sdm_disp_config_t; + +/**@brief SDM profile structure. */ +struct ant_sdm_profile_s +{ + uint8_t channel_number; ///< Channel number assigned to the profile. + union { + ant_sdm_disp_cb_t * p_disp_cb; + ant_sdm_sens_cb_t * p_sens_cb; + } _cb; ///< Pointer to internal control block. + ant_sdm_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the SDM profile. + ant_sdm_page1_data_t page_1; ///< Page 1. + ant_sdm_page2_data_t page_2; ///< Page 2. + ant_sdm_page3_data_t page_3; ///< Page 3. + ant_sdm_page22_data_t page_22; ///< Page 22. + ant_common_page80_data_t page_80; ///< Page 80. + ant_common_page81_data_t page_81; ///< Page 81. + ant_sdm_common_data_t common; ///< SDM common data. +}; + +/** @name Defines for accessing ant_sdm_profile_t members variables +@{ */ +#define SDM_PROFILE_update_latency page_1.update_latency +#define SDM_PROFILE_time page_1.time +#define SDM_PROFILE_status page_2.status.items +#define SDM_PROFILE_cadence page_2.cadence +#define SDM_PROFILE_calories page_3.calories +#define SDM_PROFILE_capabilities page_22.capabilities.items +#define SDM_PROFILE_speed common.speed +#define SDM_PROFILE_distance common.distance +#define SDM_PROFILE_strides common.strides +#define SDM_PROFILE_hw_revision page_80.hw_revision +#define SDM_PROFILE_manufacturer_id page_80.manufacturer_id +#define SDM_PROFILE_model_number page_80.model_number +#define SDM_PROFILE_sw_revision_minor page_81.sw_revision_minor +#define SDM_PROFILE_sw_revision_major page_81.sw_revision_major +#define SDM_PROFILE_serial_number page_81.serial_number +/** @} */ + +/**@brief Function for initializing the ANT SDM RX profile instance. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_channel_config Pointer to the ANT channel configuration structure. + * @param[in] p_disp_config Pointer to the SDM Display configuration structure. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. + */ +ret_code_t ant_sdm_disp_init(ant_sdm_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_sdm_disp_config_t const * p_disp_config); + +/**@brief Function for initializing the ANT SDM TX profile instance. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_channel_config Pointer to the ANT channel configuration structure. + * @param[in] p_sens_config Pointer to the SDM Sensor configuration structure. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. + */ +ret_code_t ant_sdm_sens_init(ant_sdm_profile_t * p_profile, + ant_channel_config_t const * p_channel_config, + ant_sdm_sens_config_t const * p_sens_config); + +/**@brief Function for opening the profile instance channel for ANT SDM Display. + * + * Before calling this function, pages should be configured. + * + * @param[in] p_profile Pointer to the profile instance. + * + * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned. + */ +ret_code_t ant_sdm_disp_open(ant_sdm_profile_t * p_profile); + +/**@brief Function for opening the profile instance channel for ANT SDM Sensor. + * + * Before calling this function, pages should be configured. + * + * @param[in] p_profile Pointer to the profile instance. + * + * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned. + */ +ret_code_t ant_sdm_sens_open(ant_sdm_profile_t * p_profile); + +/**@brief Function for sending a data page request. + * + * This function can be called only on the display side. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_page_70 Pointer to the prepared page 70. + * + * @retval NRF_SUCCESS If the request has been sent. Otherwise, an error code is returned. + */ +ret_code_t ant_sdm_page_request(ant_sdm_profile_t * p_profile, ant_common_page70_data_t * p_page_70); + +/**@brief Function for handling the Sensor ANT events. + * + * @details This function handles all events from the ANT stack that are of interest to the SDM Sensor profile. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_ant_event Event received from the ANT stack. + */ +void ant_sdm_sens_evt_handler(ant_sdm_profile_t * p_profile, ant_evt_t * p_ant_event); + +/**@brief Function for handling the Display ANT events. + * + * @details This function handles all events from the ANT stack that are of interest to the SDM Display profile. + * + * @param[in] p_profile Pointer to the profile instance. + * @param[in] p_ant_event Event received from the ANT stack. + */ +void ant_sdm_disp_evt_handler(ant_sdm_profile_t * p_profile, ant_evt_t * p_ant_event); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_SDM_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/ant_sdm_local.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/ant_sdm_local.h new file mode 100644 index 0000000000000000000000000000000000000000..37cf894be7a726346794c421be7f7d8e7d6a3f62 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/ant_sdm_local.h @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_SDM_LOCAL_H__ +#define ANT_SDM_LOCAL_H__ + +#include +#include +#include "ant_sdm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup ant_sdm + * @{ + */ + +/** @brief SDM Display control block. */ +typedef struct +{ + ant_request_controller_t req_controller; +}ant_sdm_disp_cb_t; + +/**@brief SDM Sensor control block. */ +typedef struct +{ + uint8_t supp_page_control; + ant_sdm_page_t supp_page_number; + ant_sdm_page_t common_page_number; + uint8_t message_counter; + ant_request_controller_t req_controller; +}ant_sdm_sens_cb_t; + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_SDM_LOCAL_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.c new file mode 100644 index 0000000000000000000000000000000000000000..4e4ee6b3f849c16a49fcd7f47b75a3994795cf01 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.c @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + +#include "ant_sdm_common_data.h" +#include "ant_sdm_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM" +#if ANT_SDM_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_INFO_COLOR +#else // ANT_SDM_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_LOG_ENABLED +#include "nrf_log.h" + +/**@brief SDM common page data layout structure. */ +typedef struct +{ + uint8_t reserved0[3]; + uint8_t speed_integer :4; + uint8_t reserved1 :4; + uint8_t speed_fractional; + uint8_t reserved2[2]; +}ant_sdm_speed_data_layout_t; + +/**@brief Function for tracing common data. + * + * @param[in] p_common_data Pointer to the common data. + */ +static void speed_data_log(ant_sdm_common_data_t const * p_common_data) +{ + uint32_t speed = ANT_SDM_SPEED_RESCALE(p_common_data->speed); + UNUSED_VARIABLE(speed); + + NRF_LOG_INFO("Speed %u.%02u m/s\r\n\n", + (unsigned int)(speed / ANT_SDM_SPEED_DISP_PRECISION), + (unsigned int)(speed % ANT_SDM_SPEED_DISP_PRECISION)); +} + +void ant_sdm_speed_encode(uint8_t * p_page_buffer, + ant_sdm_common_data_t const * p_common_data) +{ + ant_sdm_speed_data_layout_t * p_outcoming_data = (ant_sdm_speed_data_layout_t *)p_page_buffer; + uint16_t speed = p_common_data->speed; + + p_outcoming_data->speed_integer = speed / ANT_SDM_SPEED_UNIT_REVERSAL; + p_outcoming_data->speed_fractional = speed % ANT_SDM_SPEED_UNIT_REVERSAL; + + speed_data_log(p_common_data); +} + +void ant_sdm_speed_decode(uint8_t const * p_page_buffer, + ant_sdm_common_data_t * p_common_data) +{ + ant_sdm_speed_data_layout_t const * p_incoming_data = (ant_sdm_speed_data_layout_t *)p_page_buffer; + uint16_t speed = (p_incoming_data->speed_integer + * ANT_SDM_SPEED_UNIT_REVERSAL) + + p_incoming_data->speed_fractional; + + p_common_data->speed = speed; + + speed_data_log(p_common_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.h new file mode 100644 index 0000000000000000000000000000000000000000..2ebb0c0eeef8c6a77c97927dfe29d7f5875b3b68 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.h @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_SDM_COMMON_DATA_H__ +#define ANT_SDM_COMMON_DATA_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_sdm_common_data_page Stride Based Speed and Distance Monitor profile common data + * @{ + * @ingroup ant_sdk_profiles_sdm_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for SDM common data. + * + * @details This structure stores data that is not associated with a particular page. + */ +typedef struct +{ + uint16_t speed; ///< Actual speed. + uint32_t distance; ///< Accumulated distance. + uint32_t strides; ///< Accumulated strides. +} ant_sdm_common_data_t; + +/**@brief Initialize common data. + */ +#define DEFAULT_ANT_SDM_COMMON_DATA() \ + (ant_sdm_common_data_t) \ + { \ + .speed = 0, \ + .distance = 0, \ + .strides = 0, \ + } + +/**@brief Function for encoding speed. + * + * This function can be used for pages 2 and 3. + * + * @param[in] p_common_data Pointer to the common data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_sdm_speed_encode(uint8_t * p_page_buffer, + ant_sdm_common_data_t const * p_common_data); + +/**@brief Function for decoding speed. + * + * This function can be used for pages 2 and 3. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_common_data Pointer to the common data. + */ +void ant_sdm_speed_decode(uint8_t const * p_page_buffer, + ant_sdm_common_data_t * p_common_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_SDM_COMMON_DATA_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.c new file mode 100644 index 0000000000000000000000000000000000000000..2762cfee9f0cd681e00af3880ee74de79f24b54a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.c @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + +#include "ant_sdm_page_1.h" +#include "ant_sdm_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM_PAGE_1" +#if ANT_SDM_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_PAGE_1_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_PAGE_1_INFO_COLOR +#else // ANT_SDM_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_PAGE_1_LOG_ENABLED +#include "nrf_log.h" + +/**@brief SDM page 1 data layout structure. */ +typedef struct +{ + uint8_t time_fractional; + uint8_t time_integer; + uint8_t distance_integer; + uint8_t reserved0 : 4; + uint8_t distance_fractional : 4; + uint8_t reserved1; + uint8_t strides; + uint8_t update_latency; +}ant_sdm_page1_data_layout_t; + +STATIC_ASSERT(ANT_SDM_UPDATE_LATENCY_DISP_PRECISION == 1000); ///< Display format need to be updated +STATIC_ASSERT(ANT_SDM_TIME_DISP_PRECISION == 1000); ///< Display format need to be updated +STATIC_ASSERT(ANT_SDM_DISTANCE_DISP_PRECISION == 10); ///< Display format need to be updated + +/**@brief Function for tracing page 1 and common data. + * + * @param[in] p_common_data Pointer to the common data. + * @param[in] p_page_data Pointer to the page 1 data. + */ +static void page_1_data_log(ant_sdm_page1_data_t const * p_page_data, + ant_sdm_common_data_t const * p_common_data) +{ + uint32_t strides = p_common_data->strides; + uint64_t distance = ANT_SDM_DISTANCE_RESCALE(p_common_data->distance); + uint16_t update_latency = ANT_SDM_UPDATE_LATENCY_RESCALE(p_page_data->update_latency); + uint32_t time = ANT_SDM_TIME_RESCALE(p_page_data->time); + + NRF_LOG_INFO("Update latency %u.%03u s\r\n", + update_latency / ANT_SDM_UPDATE_LATENCY_DISP_PRECISION, + update_latency % ANT_SDM_UPDATE_LATENCY_DISP_PRECISION); + NRF_LOG_INFO("Time %u.%03u s\r\n", + (unsigned int)(time / ANT_SDM_TIME_DISP_PRECISION), + (unsigned int)(time % ANT_SDM_TIME_DISP_PRECISION)); + NRF_LOG_INFO("Distance %u.%01um \r\n", + (unsigned int)(distance / ANT_SDM_DISTANCE_DISP_PRECISION), + (unsigned int)(distance % ANT_SDM_DISTANCE_DISP_PRECISION)); + NRF_LOG_INFO("Strides %u\r\n", (unsigned int)strides); +} + + +void ant_sdm_page_1_encode(uint8_t * p_page_buffer, + ant_sdm_page1_data_t const * p_page_data, + ant_sdm_common_data_t const * p_common_data) +{ + ant_sdm_page1_data_layout_t * p_outcoming_data = (ant_sdm_page1_data_layout_t *)p_page_buffer; + uint32_t distance = p_common_data->distance; + uint16_t time = p_page_data->time; + + p_outcoming_data->time_fractional = time % ANT_SDM_TIME_UNIT_REVERSAL; + p_outcoming_data->time_integer = time / ANT_SDM_TIME_UNIT_REVERSAL; + p_outcoming_data->distance_integer = + (UINT8_MAX & (distance / ANT_SDM_DISTANCE_UNIT_REVERSAL)); // Only LSB + p_outcoming_data->distance_fractional = distance % ANT_SDM_DISTANCE_UNIT_REVERSAL; + p_outcoming_data->strides = (UINT8_MAX & p_common_data->strides); // Only LSB + p_outcoming_data->update_latency = p_page_data->update_latency; + + page_1_data_log(p_page_data, p_common_data); +} + + +void ant_sdm_page_1_decode(uint8_t const * p_page_buffer, + ant_sdm_page1_data_t * p_page_data, + ant_sdm_common_data_t * p_common_data) +{ + ant_sdm_page1_data_layout_t const * p_incoming_data = + (ant_sdm_page1_data_layout_t *)p_page_buffer; + + uint16_t distance = p_incoming_data->distance_integer * ANT_SDM_DISTANCE_UNIT_REVERSAL + + p_incoming_data->distance_fractional; + uint16_t time = p_incoming_data->time_integer * ANT_SDM_TIME_UNIT_REVERSAL + + p_incoming_data->time_fractional; + + uint8_t prev_strides = p_common_data->strides; + + p_common_data->strides += ((p_incoming_data->strides - prev_strides) & UINT8_MAX); + + uint16_t prev_distance = p_common_data->distance; + p_common_data->distance += ((distance - prev_distance) & 0xFFF); + + p_page_data->update_latency = p_incoming_data->update_latency; + p_page_data->time = time; + p_page_data->strides = p_incoming_data->strides; + + page_1_data_log(p_page_data, p_common_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.h new file mode 100644 index 0000000000000000000000000000000000000000..6e998d6aa7b7c0103aae3359eb5cc86830131ec4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.h @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_SDM_PAGE_1_H__ +#define ANT_SDM_PAGE_1_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_sdm_page1 Stride Based Speed and Distance Monitor profile page 1 + * @{ + * @ingroup ant_sdk_profiles_sdm_pages + */ + +#include +#include "ant_sdm_common_data.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for SDM data page 1. + */ +typedef struct +{ + uint8_t update_latency; ///< Update latency. + uint8_t strides; ///< Strides (writing to this field has no effect). + uint16_t time; ///< Time. +} ant_sdm_page1_data_t; + +/**@brief Initialize page 1. + */ +#define DEFAULT_ANT_SDM_PAGE1() \ + (ant_sdm_page1_data_t) \ + { \ + .update_latency = 0, \ + .time = 0, \ + } + +/**@brief Function for encoding page 1. + * + * @param[in] p_page_data Pointer to the page data. + * @param[in] p_common_data Pointer to the common data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_sdm_page_1_encode(uint8_t * p_page_buffer, + ant_sdm_page1_data_t const * p_page_data, + ant_sdm_common_data_t const * p_common_data); + +/**@brief Function for decoding page 1. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + * @param[out] p_common_data Pointer to the common data. + */ +void ant_sdm_page_1_decode(uint8_t const * p_page_buffer, + ant_sdm_page1_data_t * p_page_data, + ant_sdm_common_data_t * p_common_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_SDM_PAGE_1_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.c new file mode 100644 index 0000000000000000000000000000000000000000..cda7521b5e9a359aeb4a3907d77377b5b1cd26f6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.c @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + +#include "ant_sdm_page_16.h" +#include "ant_sdm_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM_PAGE_16" +#if ANT_SDM_PAGE_16_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_PAGE_16_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_PAGE_16_INFO_COLOR +#else // ANT_SDM_PAGE_16_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_PAGE_16_LOG_ENABLED +#include "nrf_log.h" + + +/**@brief SDM page 16 data layout structure. */ +typedef struct +{ + uint8_t strides[3]; + uint8_t distance[4]; +}ant_sdm_page16_data_layout_t; + +STATIC_ASSERT(ANT_SDM_DISTANCE_DISP_PRECISION == 10); ///< Display format need to be updated + +/**@brief Function for tracing common data. + * + * @param[in] p_common_data Pointer to the common data. + */ +static void page_16_data_log(ant_sdm_common_data_t const * p_common_data) +{ + uint64_t distance = ANT_SDM_DISTANCE_RESCALE(p_common_data->distance); + + NRF_LOG_INFO("Distance %u.%01u m\r\n", + (unsigned int)(distance / ANT_SDM_DISTANCE_DISP_PRECISION), + (unsigned int)(distance % ANT_SDM_DISTANCE_DISP_PRECISION)); + NRF_LOG_INFO("Strides %u\r\n\n", + (unsigned int)p_common_data->strides); +} + + +void ant_sdm_page_16_encode(uint8_t * p_page_buffer, + ant_sdm_common_data_t const * p_common_data) +{ + ant_sdm_page16_data_layout_t * p_outcoming_data = (ant_sdm_page16_data_layout_t *)p_page_buffer; + + UNUSED_PARAMETER(uint24_encode(p_common_data->strides, p_outcoming_data->strides)); + UNUSED_PARAMETER(uint32_encode(p_common_data->distance << 4, p_outcoming_data->distance)); + + page_16_data_log(p_common_data); +} + + +void ant_sdm_page_16_decode(uint8_t const * p_page_buffer, + ant_sdm_common_data_t * p_common_data) +{ + ant_sdm_page16_data_layout_t const * p_incoming_data = + (ant_sdm_page16_data_layout_t *)p_page_buffer; + + p_common_data->strides = uint24_decode(p_incoming_data->strides); + p_common_data->distance = uint32_decode(p_incoming_data->distance) >> 4; + + page_16_data_log(p_common_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.h new file mode 100644 index 0000000000000000000000000000000000000000..744f9a7024ca823b1b5d154dce04554ebe91f20b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.h @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_SDM_PAGE_16_H__ +#define ANT_SDM_PAGE_16_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_sdm_page16 Stride Based Speed and Distance Monitor profile page 16 + * @{ + * @ingroup ant_sdk_profiles_sdm_pages + */ + +#include +#include "ant_sdm_common_data.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Function for encoding page 16. + * + * @param[in] p_common_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_sdm_page_16_encode(uint8_t * p_page_buffer, + ant_sdm_common_data_t const * p_common_data); + +/**@brief Function for decoding page 16. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_common_data Pointer to the page data. + */ +void ant_sdm_page_16_decode(uint8_t const * p_page_buffer, + ant_sdm_common_data_t * p_common_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_SDM_PAGE_16_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.c new file mode 100644 index 0000000000000000000000000000000000000000..8761bb58e036b1284121a4d8bed87804c57ae706 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.c @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + +#include "ant_sdm_page_2.h" +#include "ant_sdm_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM_PAGE_2" +#if ANT_SDM_PAGE_2_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_PAGE_2_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_PAGE_2_INFO_COLOR +#else // ANT_SDM_PAGE_2_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_PAGE_2_LOG_ENABLED +#include "nrf_log.h" + + +/**@brief SDM page 2 data layout structure. */ +typedef struct +{ + uint8_t reserved0[2]; + uint8_t cadence_integer; + uint8_t reserved1 : 4; + uint8_t cadence_fractional : 4; + uint8_t reserved2; + uint8_t reserved3; + uint8_t status; +}ant_sdm_page2_data_layout_t; + +/**@brief Function for page 2 data. + * + * @param[in] p_common_data Pointer to the page 2 data. + */ +static void page_2_data_log(ant_sdm_page2_data_t const * p_page_data) +{ + static const char * p_location[4] = {"Laces", "Midsole", "Other", "Ankle"}; + static const char * p_battery[4] = {"New", "Good", "OK", "Low"}; + static const char * p_health[4] = {"OK", "Error", "Warning", ""}; + static const char * p_state[4] = {"Inactive", "Active", "", ""}; + + uint16_t cadence = ANT_SDM_CADENCE_RESCALE(p_page_data->cadence); + + NRF_LOG_INFO("Status:\r\n"); + NRF_LOG_INFO("state: %s\r\n", + (uint32_t)p_state[p_page_data->status.items.state]); + NRF_LOG_INFO("health: %s\r\n", + (uint32_t)p_health[p_page_data->status.items.health]); + NRF_LOG_INFO("battery: %s\r\n", + (uint32_t)p_battery[p_page_data->status.items.battery]); + NRF_LOG_INFO("location: %s\r\n", + (uint32_t)p_location[p_page_data->status.items.location]); + NRF_LOG_INFO("Cadence %u.%01u strides/min\r\n", + cadence / ANT_SDM_CADENCE_DISP_PRECISION, + cadence % ANT_SDM_CADENCE_DISP_PRECISION); +} + + +void ant_sdm_page_2_encode(uint8_t * p_page_buffer, + ant_sdm_page2_data_t const * p_page_data) +{ + ant_sdm_page2_data_layout_t * p_outcoming_data = (ant_sdm_page2_data_layout_t *)p_page_buffer; + uint8_t status = p_page_data->status.byte; + uint16_t cadence = p_page_data->cadence; + + p_outcoming_data->reserved0[0] = UINT8_MAX; + p_outcoming_data->reserved0[1] = UINT8_MAX; + p_outcoming_data->cadence_integer = cadence / ANT_SDM_CADENCE_UNIT_REVERSAL; + p_outcoming_data->cadence_fractional = cadence % ANT_SDM_CADENCE_UNIT_REVERSAL; + p_outcoming_data->reserved3 = UINT8_MAX; + p_outcoming_data->status = status; + page_2_data_log(p_page_data); +} + + +void ant_sdm_page_2_decode(uint8_t const * p_page_buffer, + ant_sdm_page2_data_t * p_page_data) +{ + ant_sdm_page2_data_layout_t const * p_incoming_data = + (ant_sdm_page2_data_layout_t *)p_page_buffer; + + uint8_t status = p_incoming_data->status; + uint16_t cadence = p_incoming_data->cadence_integer * ANT_SDM_CADENCE_UNIT_REVERSAL + + p_incoming_data->cadence_fractional; + + p_page_data->cadence = cadence; + p_page_data->status.byte = status; + + page_2_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.h new file mode 100644 index 0000000000000000000000000000000000000000..011904d23010ad672db1643977c74cacc86c539f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.h @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_SDM_PAGE_2_H__ +#define ANT_SDM_PAGE_2_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_sdm_page2 Stride Based Speed and Distance Monitor profile page 2 + * @{ + * @ingroup ant_sdk_profiles_sdm_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for SDM data page 2. + */ +typedef struct +{ + union + { + struct + { + enum + { + ANT_SDM_USE_STATE_INACTIVE = 0x00, + ANT_SDM_USE_STATE_ACTIVE = 0x01, + ANT_SDM_STATE_RESERVED0 = 0x02, + ANT_SDM_STATE_RESERVED1 = 0x03, + } state : 2; ///< Use state. + enum + { + ANT_SDM_HEALTH_OK = 0x00, + ANT_SDM_HEALTH_ERROR = 0x01, + ANT_SDM_HEALTH_WARNING = 0x02, + ANT_SDM_HEALTH_RESERVED = 0x03, + } health : 2; ///< SDM health. + enum + { + ANT_SDM_BATTERY_STATUS_NEW = 0x00, + ANT_SDM_BATTERY_STATUS_GOOD = 0x01, + ANT_SDM_BATTERY_STATUS_OK = 0x02, + ANT_SDM_BATTERY_STATUS_LOW = 0x03, + } battery : 2; ///< Battery status. + enum + { + ANT_SDM_LOCATION_LACES = 0x00, + ANT_SDM_LOCATION_MIDSOLE = 0x01, + ANT_SDM_LOCATION_OTHER = 0x02, + ANT_SDM_LOCATION_ANKLE = 0x03, + } location : 2; ///< Location of the SDM sensor. + } items; + uint8_t byte; + } status; ///< Actual status. + uint16_t cadence; ///< Actual cadence. +} ant_sdm_page2_data_t; + +/**@brief Initialize page 2. + */ +#define DEFAULT_ANT_SDM_PAGE2() \ + (ant_sdm_page2_data_t) \ + { \ + .status.byte = 0, \ + .cadence = 0, \ + } + +/**@brief Function for encoding page 2. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_sdm_page_2_encode(uint8_t * p_page_buffer, + ant_sdm_page2_data_t const * p_page_data); + +/**@brief Function for decoding page 2. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_sdm_page_2_decode(uint8_t const * p_page_buffer, + ant_sdm_page2_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_SDM_PAGE_2_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.c new file mode 100644 index 0000000000000000000000000000000000000000..f5bae799ecb11a67b08fbe12e7dc220b4f5839be --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.c @@ -0,0 +1,128 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + +#include +#include "ant_sdm_page_22.h" +#include "ant_sdm_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM_PAGE_22" +#if ANT_SDM_PAGE_22_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_PAGE_22_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_PAGE_22_INFO_COLOR +#else // ANT_SDM_PAGE_22_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_PAGE_22_LOG_ENABLED +#include "nrf_log.h" + + +/**@brief SDM page 22 data layout structure. */ +typedef struct +{ + uint8_t capabilities; + uint8_t reserved[6]; +}ant_sdm_page22_data_layout_t; + +/**@brief Function for tracing page 22 data. + * + * @param[in] p_page_data Pointer to the page 22 data. + */ +static void page_22_data_log(ant_sdm_page22_data_t const * p_page_data) +{ + NRF_LOG_INFO("Capabilities: "); + + if (p_page_data->capabilities.items.time_is_valid) + { + NRF_LOG_RAW_INFO(" time"); + } + + if (p_page_data->capabilities.items.distance_is_valid) + { + NRF_LOG_RAW_INFO(" distance"); + } + + if (p_page_data->capabilities.items.speed_is_valid) + { + NRF_LOG_RAW_INFO(" speed"); + } + + if (p_page_data->capabilities.items.latency_is_valid) + { + NRF_LOG_RAW_INFO(" latency"); + } + + if (p_page_data->capabilities.items.cadency_is_valid) + { + NRF_LOG_RAW_INFO(" cadence"); + } + + if (p_page_data->capabilities.items.calorie_is_valid) + { + NRF_LOG_RAW_INFO(" calories"); + } + NRF_LOG_RAW_INFO("\r\n\n"); +} + + +void ant_sdm_page_22_encode(uint8_t * p_page_buffer, + ant_sdm_page22_data_t const * p_page_data) +{ + ant_sdm_page22_data_layout_t * p_outcoming_data = (ant_sdm_page22_data_layout_t *)p_page_buffer; + + p_outcoming_data->capabilities = p_page_data->capabilities.byte; + memset(p_outcoming_data->reserved, UINT8_MAX, sizeof (p_outcoming_data->reserved)); + + page_22_data_log(p_page_data); +} + + +void ant_sdm_page_22_decode(uint8_t const * p_page_buffer, + ant_sdm_page22_data_t * p_page_data) +{ + ant_sdm_page22_data_layout_t const * p_incoming_data = + (ant_sdm_page22_data_layout_t *)p_page_buffer; + + p_page_data->capabilities.byte = p_incoming_data->capabilities; + + page_22_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.h new file mode 100644 index 0000000000000000000000000000000000000000..1d8e6a128617bc5be12ae408aeffa0972b29082e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.h @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_SDM_PAGE_22_H__ +#define ANT_SDM_PAGE_22_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_sdm_page22 Stride Based Speed and Distance Monitor profile page 22 + * @{ + * @ingroup ant_sdk_profiles_sdm_pages + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for SDM data page 22. + */ +typedef struct +{ + union + { + struct + { + bool time_is_valid : 1; ///< Transmitted time is valid. + bool distance_is_valid : 1; ///< Transmitted distance is valid. + bool speed_is_valid : 1; ///< Transmitted speed is valid. + bool latency_is_valid : 1; ///< Transmitted latency is valid. + bool cadency_is_valid : 1; ///< Transmitted cadency is valid. + bool calorie_is_valid : 1; ///< Transmitted calorie is valid. + } items; + uint8_t byte; + } capabilities; +} ant_sdm_page22_data_t; + +/**@brief Initialize page 2. + */ +#define DEFAULT_ANT_SDM_PAGE22() \ + (ant_sdm_page22_data_t) \ + { \ + .capabilities.byte = 0, \ + } + +/**@brief Function for encoding page 22. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_sdm_page_22_encode(uint8_t * p_page_buffer, + ant_sdm_page22_data_t const * p_page_data); + +/**@brief Function for decoding page 22. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_sdm_page_22_decode(uint8_t const * p_page_buffer, + ant_sdm_page22_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_SDM_PAGE_22_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.c new file mode 100644 index 0000000000000000000000000000000000000000..b17a27c0e097a980c21195804eab40a3d85e1d24 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.c @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + +#include "ant_sdm_page_3.h" +#include "ant_sdm_utils.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM_PAGE_3" +#if ANT_SDM_PAGE_3_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_PAGE_3_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_PAGE_3_INFO_COLOR +#else // ANT_SDM_PAGE_3_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_PAGE_3_LOG_ENABLED +#include "nrf_log.h" + + +/**@brief SDM page 3 data layout structure. */ +typedef struct +{ + uint8_t reserved0[5]; + uint8_t calories; + uint8_t reserved1; +}ant_sdm_page3_data_layout_t; + +static void page_3_data_log(ant_sdm_page3_data_t const * p_page_data) +{ + NRF_LOG_INFO("Calories: %u\r\n\n", p_page_data->calories); +} + + +void ant_sdm_page_3_encode(uint8_t * p_page_buffer, + ant_sdm_page3_data_t const * p_page_data) +{ + ant_sdm_page3_data_layout_t * p_outcoming_data = (ant_sdm_page3_data_layout_t *)p_page_buffer; + + p_outcoming_data->calories = p_page_data->calories; + page_3_data_log(p_page_data); +} + + +void ant_sdm_page_3_decode(uint8_t const * p_page_buffer, + ant_sdm_page3_data_t * p_page_data) +{ + ant_sdm_page3_data_layout_t const * p_incoming_data = + (ant_sdm_page3_data_layout_t *)p_page_buffer; + + uint8_t prev_calories = (uint8_t) p_page_data->calories; + + p_page_data->calories += ((p_incoming_data->calories - prev_calories) & UINT8_MAX); + + page_3_data_log(p_page_data); +} + +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.h new file mode 100644 index 0000000000000000000000000000000000000000..075268eb6c1a35cee193ae33363ee02a47335705 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.h @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_SDM_PAGE_3_H__ +#define ANT_SDM_PAGE_3_H__ + +/** @file + * + * @defgroup ant_sdk_profiles_sdm_page3 Stride Based Speed and Distance Monitor profile page 3 + * @{ + * @ingroup ant_sdk_profiles_sdm_pages + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Data structure for SDM data page 3. + */ +typedef struct +{ + uint32_t calories; ///< Calories. +} ant_sdm_page3_data_t; + +/**@brief Initialize page 3. + */ +#define DEFAULT_ANT_SDM_PAGE3() \ + (ant_sdm_page3_data_t) \ + { \ + .calories = 0, \ + } + +/**@brief Function for encoding page 3. + * + * @param[in] p_page_data Pointer to the page data. + * @param[out] p_page_buffer Pointer to the data buffer. + */ +void ant_sdm_page_3_encode(uint8_t * p_page_buffer, + ant_sdm_page3_data_t const * p_page_data); + +/**@brief Function for decoding page 3. + * + * @param[in] p_page_buffer Pointer to the data buffer. + * @param[out] p_page_data Pointer to the page data. + */ +void ant_sdm_page_3_decode(uint8_t const * p_page_buffer, + ant_sdm_page3_data_t * p_page_data); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_SDM_PAGE_3_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_pages.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_pages.h new file mode 100644 index 0000000000000000000000000000000000000000..e3e24ac8026379a489602080bc3bb0a4b5d22806 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_pages.h @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef __ANT_SDM_PAGES_H +#define __ANT_SDM_PAGES_H + +/** @file + * + * @defgroup ant_sdk_profiles_sdm_pages Stride Based Speed and Distance Monitor profile pages + * @{ + * @ingroup ant_sdm + * @brief This module implements functions for the SDM data pages. + */ + +#include "ant_sdm_page_1.h" +#include "ant_sdm_page_2.h" +#include "ant_sdm_page_3.h" +#include "ant_sdm_page_16.h" +#include "ant_sdm_page_22.h" +#include "ant_sdm_common_data.h" +#include "ant_common_page_70.h" +#include "ant_common_page_80.h" +#include "ant_common_page_81.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif // __ANT_SDM_PAGES_H +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.c new file mode 100644 index 0000000000000000000000000000000000000000..7afdae0c6e8b8bd0b3fa1ef1a63a4996b3e82b78 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.c @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + +#include "ant_sdm_simulator.h" +#include "ant_sdm_utils.h" + +#define SIMULATOR_STRIDE_LENGTH_UNIT_REVERSAL 100 ///< Stride length unit is cm. +#define SIMULATOR_BURN_RATE_UNIT 1000 ///< Burn rate uinit is kcal per km. +#define SIMULATOR_TIME_INCREMENT SDM_MSG_PERIOD_4Hz ///< Ticks between two cycles. +#define SIMULATOR_TIME_UNIT_REVERSAL ANT_CLOCK_FREQUENCY ///< Simulation time frequency. +#define SEC_PER_MIN 60 ///< Number of seconds per minute. +#define SIMULATOR_STRIDE_UNIT_REVERSAL (SIMULATOR_TIME_UNIT_REVERSAL * \ + ANT_SDM_CADENCE_UNIT_REVERSAL * SEC_PER_MIN) + + +void ant_sdm_simulator_init(ant_sdm_simulator_t * p_simulator, + ant_sdm_simulator_cfg_t const * p_config, + bool auto_change) +{ + p_simulator->p_profile = p_config->p_profile; + p_simulator->_cb.stride_length = p_config->stride_length; + p_simulator->_cb.burn_rate = p_config->burn_rate; + p_simulator->_cb.sensorsim_cfg = p_config->sensorsim_cfg; + p_simulator->_cb.auto_change = auto_change; + p_simulator->_cb.sensorsim_state.current_val = p_simulator->_cb.sensorsim_cfg.min; + p_simulator->_cb.stride_incr = 0; + p_simulator->_cb.time = 0; + + + sensorsim_init(&(p_simulator->_cb.sensorsim_state), &(p_simulator->_cb.sensorsim_cfg)); +} + + +void ant_sdm_simulator_one_iteration(ant_sdm_simulator_t * p_simulator) +{ + if (p_simulator->_cb.auto_change) + { + UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.sensorsim_state), + &(p_simulator->_cb.sensorsim_cfg))); + } + + p_simulator->_cb.time += SIMULATOR_TIME_INCREMENT; + + p_simulator->_cb.stride_incr += p_simulator->_cb.sensorsim_state.current_val * + SIMULATOR_TIME_INCREMENT; + p_simulator->p_profile->SDM_PROFILE_strides += p_simulator->_cb.stride_incr / + SIMULATOR_STRIDE_UNIT_REVERSAL; + p_simulator->_cb.stride_incr = p_simulator->_cb.stride_incr % + SIMULATOR_STRIDE_UNIT_REVERSAL; + + + uint32_t distance = value_rescale( + p_simulator->p_profile->SDM_PROFILE_strides * p_simulator->_cb.stride_length, + SIMULATOR_STRIDE_LENGTH_UNIT_REVERSAL, + ANT_SDM_DISTANCE_UNIT_REVERSAL); + + if (p_simulator->p_profile->SDM_PROFILE_capabilities.cadency_is_valid) + { + p_simulator->p_profile->SDM_PROFILE_cadence = p_simulator->_cb.sensorsim_state.current_val; + } + + if (p_simulator->p_profile->SDM_PROFILE_capabilities.speed_is_valid) + { + p_simulator->p_profile->SDM_PROFILE_speed = value_rescale( + p_simulator->_cb.sensorsim_state.current_val * p_simulator->_cb.stride_length, + ANT_SDM_CADENCE_UNIT_REVERSAL * SIMULATOR_STRIDE_LENGTH_UNIT_REVERSAL * SEC_PER_MIN, + ANT_SDM_SPEED_UNIT_REVERSAL); + } + + if (p_simulator->p_profile->SDM_PROFILE_capabilities.distance_is_valid) + { + p_simulator->p_profile->SDM_PROFILE_distance = distance; + } + + if (p_simulator->p_profile->SDM_PROFILE_capabilities.calorie_is_valid) + { + p_simulator->p_profile->SDM_PROFILE_calories = value_rescale(distance, + SIMULATOR_BURN_RATE_UNIT + * ANT_SDM_DISTANCE_UNIT_REVERSAL, + p_simulator->_cb.burn_rate); + } + + if (p_simulator->p_profile->SDM_PROFILE_capabilities.time_is_valid) + { + p_simulator->p_profile->SDM_PROFILE_time = value_rescale(p_simulator->_cb.time, + SIMULATOR_TIME_UNIT_REVERSAL, + ANT_SDM_TIME_UNIT_REVERSAL); + } + + if (p_simulator->p_profile->SDM_PROFILE_capabilities.latency_is_valid) + { + p_simulator->p_profile->SDM_PROFILE_update_latency = + ROUNDED_DIV(((uint64_t)p_simulator->_cb.stride_incr * + ANT_SDM_UPDATE_LATENCY_UNIT_REVERSAL), + (uint64_t)SIMULATOR_TIME_UNIT_REVERSAL * + p_simulator->_cb.sensorsim_state.current_val); + } +} + + +void ant_sdm_simulator_increment(ant_sdm_simulator_t * p_simulator) +{ + if (!p_simulator->_cb.auto_change) + { + sensorsim_increment(&(p_simulator->_cb.sensorsim_state), + &(p_simulator->_cb.sensorsim_cfg)); + } +} + + +void ant_sdm_simulator_decrement(ant_sdm_simulator_t * p_simulator) +{ + if (!p_simulator->_cb.auto_change) + { + sensorsim_decrement(&(p_simulator->_cb.sensorsim_state), + &(p_simulator->_cb.sensorsim_cfg)); + } +} + +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.h new file mode 100644 index 0000000000000000000000000000000000000000..a078c7589607cdcfa08a1f4bbb2d1d89983dd729 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.h @@ -0,0 +1,139 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_SDM_SIMULATOR_H__ +#define ANT_SDM_SIMULATOR_H__ + +/** @file + * + * @defgroup ant_sdk_sdm_simulator ANT SDM simulator + * @{ + * @ingroup ant_sdk_simulators + * @brief ANT SDM simulator module. + * + * @details This module simulates strides for the ANT SDM profile. The module calculates + * abstract values, which are handled by the SDM pages data model to ensure that they are + * compatible. It provides a handler for changing the cadence value manually and functionality + * for changing the cadence automatically. + * + */ + +#include +#include +#include "ant_sdm.h" +#include "ant_sdm_utils.h" +#include "sensorsim.h" +#include "ant_sdm_simulator_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief SDM simulator configuration structure. */ +typedef struct +{ + ant_sdm_profile_t * p_profile; ///< Related profile. + uint32_t stride_length; ///< Length of a stride in cm. + uint32_t burn_rate; ///< Kcal per kilometer. + sensorsim_cfg_t sensorsim_cfg; ///< Sensorsim configuration. +} ant_sdm_simulator_cfg_t; + +/**@brief Initialize @ref ant_sdm_simulator_cfg_t. + */ +#define DEFAULT_ANT_SDM_SIMULATOR_CFG(P_PROFILE, \ + STRIDE_LEN, \ + BURN_RATE, \ + MIN_CADENCE, \ + MAX_CADENCE, \ + INCREMENT) \ + { \ + .p_profile = (P_PROFILE), \ + .stride_length = (STRIDE_LEN), \ + .burn_rate = (BURN_RATE), \ + .sensorsim_cfg.min = (MIN_CADENCE) *(ANT_SDM_CADENCE_UNIT_REVERSAL), \ + .sensorsim_cfg.max = (MAX_CADENCE) *(ANT_SDM_CADENCE_UNIT_REVERSAL), \ + .sensorsim_cfg.incr = (INCREMENT) *(ANT_SDM_CADENCE_UNIT_REVERSAL), \ + .sensorsim_cfg.start_at_max = false, \ + } + +/**@brief SDM simulator structure. */ +typedef struct +{ + ant_sdm_profile_t * p_profile; ///< Related profile. + ant_sdm_simulator_cb_t _cb; ///< Internal control block. +} ant_sdm_simulator_t; + + +/**@brief Function for initializing the ANT SDM simulator instance. + * + * @param[in] p_simulator Pointer to the simulator instance. + * @param[in] p_config Pointer to the simulator configuration structure. + * @param[in] auto_change Enable or disable automatic changes of the cadence. + */ +void ant_sdm_simulator_init(ant_sdm_simulator_t * p_simulator, + ant_sdm_simulator_cfg_t const * p_config, + bool auto_change); + +/**@brief Function for simulating a device event. + * + * @details Based on this event, the transmitter data is simulated. + * + * This function should be called in the SDM TX event handler. + */ +void ant_sdm_simulator_one_iteration(ant_sdm_simulator_t * p_simulator); + +/**@brief Function for incrementing the cadence value. + * + * @param[in] p_simulator Pointer to the simulator instance. + */ +void ant_sdm_simulator_increment(ant_sdm_simulator_t * p_simulator); + +/**@brief Function for decrementing the cadence value. + * + * @param[in] p_simulator Pointer to the simulator instance. + */ +void ant_sdm_simulator_decrement(ant_sdm_simulator_t * p_simulator); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_SDM_SIMULATOR_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator_local.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator_local.h new file mode 100644 index 0000000000000000000000000000000000000000..6777717689c70c412bfeee264c7be668bc22be01 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator_local.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_SDM_SIMULATOR_LOCAL_H__ +#define ANT_SDM_SIMULATOR_LOCAL_H__ + +#include +#include +#include "ant_sdm.h" +#include "sensorsim.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @ingroup ant_sdk_sdm_simulator + * @brief SDM simulator control block structure. */ +typedef struct +{ + bool auto_change; ///< Cadence will change automatically (if auto_change is set) or manually. + uint8_t stride_length; ///< Length of a stride (in cm). + uint8_t burn_rate; ///< Kcal per kilometer. + uint32_t stride_incr; ///< Fractional part of stride increment. + uint64_t time; ///< Simulation time. + sensorsim_state_t sensorsim_state; ///< State of the simulated sensor. + sensorsim_cfg_t sensorsim_cfg; ///< Configuration of the simulated sensor. +}ant_sdm_simulator_cb_t; + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_SDM_SIMULATOR_LOCAL_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/utils/ant_sdm_utils.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/utils/ant_sdm_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..045a3225eea101197516be2e7110b3d25c88d984 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_profiles/ant_sdm/utils/ant_sdm_utils.h @@ -0,0 +1,112 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_SDM_UTILS_H__ +#define ANT_SDM_UTILS_H__ + +#include "nrf_assert.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + * + * @defgroup ant_sdk_profiles_sdm_utils Stride Based Speed and Distance Monitor profile utilities + * @{ + * @ingroup ant_sdm + * @brief This module implements utilities for the Stride Based Speed and Distance Monitor profile. + * + */ + +/*@brief A reversal of time unit. + * + * @details According to the ANT SDM specification, the time unit (fractional part) is 1/200 of a second. + */ +#define ANT_SDM_TIME_UNIT_REVERSAL 200 +#define ANT_SDM_TIME_DISP_PRECISION 1000 +#define ANT_SDM_TIME_RESCALE(VALUE) value_rescale((VALUE), ANT_SDM_TIME_UNIT_REVERSAL, \ + ANT_SDM_TIME_DISP_PRECISION) + +/*@brief A reversal of distance unit. + * + * @details According to the ANT SDM specification, the distance unit (page 1 - fractional part) is 1/16 of a meter. + */ +#define ANT_SDM_DISTANCE_UNIT_REVERSAL 16 +#define ANT_SDM_DISTANCE_DISP_PRECISION 10 +#define ANT_SDM_DISTANCE_RESCALE(VALUE) value_rescale((VALUE), ANT_SDM_DISTANCE_UNIT_REVERSAL, \ + ANT_SDM_DISTANCE_DISP_PRECISION) + +/*@brief A reversal of speed unit. + * + * @details According to the ANT SDM specification, the speed unit (fractional part) is 1/256 of m/s. + */ +#define ANT_SDM_SPEED_UNIT_REVERSAL 256 +#define ANT_SDM_SPEED_DISP_PRECISION 100 +#define ANT_SDM_SPEED_RESCALE(VALUE) value_rescale((VALUE), ANT_SDM_SPEED_UNIT_REVERSAL, \ + ANT_SDM_SPEED_DISP_PRECISION) + +/*@brief A reversal of update latency unit. + * + * @details According to the ANT SDM specification, the update latency unit (fractional part) is 1/32 of a second. + */ +#define ANT_SDM_UPDATE_LATENCY_UNIT_REVERSAL 32 +#define ANT_SDM_UPDATE_LATENCY_DISP_PRECISION 1000 +#define ANT_SDM_UPDATE_LATENCY_RESCALE(VALUE) value_rescale((VALUE), ANT_SDM_UPDATE_LATENCY_UNIT_REVERSAL, \ + ANT_SDM_UPDATE_LATENCY_DISP_PRECISION) + +/*@brief A reversal of cadence unit. + * + * @details According to the ANT SDM specification, the cadence unit (fractional part) is 1/16 of strides/minute. + */ +#define ANT_SDM_CADENCE_UNIT_REVERSAL 16 +#define ANT_SDM_CADENCE_DISP_PRECISION 10 +#define ANT_SDM_CADENCE_RESCALE(VALUE) value_rescale((VALUE), ANT_SDM_CADENCE_UNIT_REVERSAL, \ + ANT_SDM_CADENCE_DISP_PRECISION) + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_SDM_UTILS_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_search_config/ant_search_config.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_search_config/ant_search_config.c new file mode 100644 index 0000000000000000000000000000000000000000..0a38f1478fc1fddb96e22930b7c0f388a525763d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_search_config/ant_search_config.c @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SEARCH_CONFIG) + +#include "ant_search_config.h" +#include "ant_interface.h" + +uint32_t ant_search_init(ant_search_config_t const * p_config) +{ + uint32_t err_code; + + if (p_config->low_priority_timeout == ANT_LOW_PRIORITY_SEARCH_DISABLE + && p_config->high_priority_timeout == ANT_HIGH_PRIORITY_SEARCH_DISABLE) + { + return NRF_ERROR_INVALID_PARAM; + } + + err_code = sd_ant_search_channel_priority_set(p_config->channel_number, + p_config->search_priority); + VERIFY_SUCCESS(err_code); + + err_code = sd_ant_search_waveform_set(p_config->channel_number, + p_config->waveform); + VERIFY_SUCCESS(err_code); + + err_code = sd_ant_channel_rx_search_timeout_set(p_config->channel_number, + p_config->high_priority_timeout); + VERIFY_SUCCESS(err_code); + + err_code = sd_ant_channel_low_priority_rx_search_timeout_set(p_config->channel_number, + p_config->low_priority_timeout); + VERIFY_SUCCESS(err_code); + + err_code = sd_ant_active_search_sharing_cycles_set(p_config->channel_number, + p_config->search_sharing_cycles); + return err_code; +} + +#endif // NRF_MODULE_ENABLED(ANT_SEARCH_CONFIG) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_search_config/ant_search_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_search_config/ant_search_config.h new file mode 100644 index 0000000000000000000000000000000000000000..4dd2cf7e260b95982e064406106003884e0d014b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_search_config/ant_search_config.h @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_SEARCH_CONFIG_H__ +#define ANT_SEARCH_CONFIG_H__ + +/** @file + * + * @defgroup ant_search_config ANT search configuration + * @{ + * @ingroup ant_sdk_utils + * @brief ANT channel search configuration module. + */ + +#include +#include "ant_parameters.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ANT_SEARCH_SHARING_CYCLES_DISABLE 0x00 ///< Disable search sharing. + +#define ANT_LOW_PRIORITY_SEARCH_DISABLE 0x00 ///< Disable low priority search. +#define ANT_LOW_PRIORITY_TIMEOUT_DISABLE 0xFF ///< Disable low priority search time-out. + +#define ANT_HIGH_PRIORITY_SEARCH_DISABLE 0x00 ///< Disable high priority search. +#define ANT_HIGH_PRIORITY_TIMEOUT_DISABLE 0xFF ///< Disable high priority search time-out. + +/**@brief Search priority. */ +typedef enum +{ + ANT_SEARCH_PRIORITY_DEFAULT = 0, ///< Default search priority level. + ANT_SEARCH_PRIORITY_LOWEST = ANT_SEARCH_PRIORITY_DEFAULT, ///< Lowest search priority level. + ANT_SEARCH_PRIORITY_0 = ANT_SEARCH_PRIORITY_LOWEST, + ANT_SEARCH_PRIORITY_1 = 1, + ANT_SEARCH_PRIORITY_2 = 2, + ANT_SEARCH_PRIORITY_3 = 3, + ANT_SEARCH_PRIORITY_4 = 4, + ANT_SEARCH_PRIORITY_5 = 5, + ANT_SEARCH_PRIORITY_6 = 6, + ANT_SEARCH_PRIORITY_7 = 7, + ANT_SEARCH_PRIORITY_HIGHEST = ANT_SEARCH_PRIORITY_7, ///< Highest search priority level. +} ant_search_priority_t; + +/**@brief ANT search waveform. */ +typedef enum +{ + ANT_WAVEFORM_DEFAULT = 316, ///< Standard search waveform value. + ANT_WAVEFORM_FAST = 97, ///< Accelerated search waveform value. +} ant_waveform_t; + +/**@brief ANT search configuration structure. */ +typedef struct +{ + uint8_t channel_number; ///< Assigned channel number. + uint8_t low_priority_timeout; ///< Low priority time-out (in 2.5 second increments). + uint8_t high_priority_timeout; ///< High priority time-out (in 2.5 second increments). + uint8_t search_sharing_cycles; ///< Number of search cycles to run before alternating searches. Search sharing can be disabled by @ref ANT_SEARCH_SHARING_CYCLES_DISABLE. + ant_search_priority_t search_priority; ///< Search priority. + ant_waveform_t waveform; ///< Search waveform. Do not use custom values. +} ant_search_config_t; + +/**@brief Initializes the default ANT search configuration structure. + * + * @param[in] CHANNEL_NUMBER Number of the channel. + */ +#define DEFAULT_ANT_SEARCH_CONFIG(CHANNEL_NUMBER) \ +{ \ + .channel_number = CHANNEL_NUMBER, \ + .low_priority_timeout = ANT_DEFAULT_LOW_PRIORITY_TIMEOUT, \ + .high_priority_timeout = ANT_DEFAULT_HIGH_PRIORITY_TIMEOUT, \ + .search_sharing_cycles = ANT_SEARCH_SHARING_CYCLES_DISABLE, \ + .search_priority = ANT_SEARCH_PRIORITY_DEFAULT, \ + .waveform = ANT_WAVEFORM_DEFAULT, \ +} + +/**@brief Function for configuring the ANT channel search. + * + * @param[in] p_config Pointer to the search configuration structure. + * + * @retval NRF_SUCCESS If the channel was successfully configured. Otherwise, an error code is returned. + */ +uint32_t ant_search_init(ant_search_config_t const * p_config); + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_SEARCH_CONFIG_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_stack_config/ant_stack_config.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_stack_config/ant_stack_config.c new file mode 100644 index 0000000000000000000000000000000000000000..e8b02f972cf735bdc9e58ff0b908f62cf19ae279 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_stack_config/ant_stack_config.c @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_STACK_CONFIG) +#include "nrf_assert.h" +#include "ant_stack_config.h" +#include "ant_interface.h" +#include "ant_parameters.h" + +#define ANT_BUFFER_SIZE_FOR_SD ANT_ENABLE_GET_REQUIRED_SPACE(ANT_CONFIG_TOTAL_CHANNELS_ALLOCATED, \ + ANT_CONFIG_ENCRYPTED_CHANNELS, \ + ANT_CONFIG_BURST_QUEUE_SIZE, \ + ANT_CONFIG_EVENT_QUEUE_SIZE) + +static union +{ + uint8_t u8[ANT_BUFFER_SIZE_FOR_SD]; + uint32_t u32[1]; // force allign to uint32_t +}ant_stack_buffer; /*!< Memory buffer provided in order to support channel configuration */ + +uint32_t ant_stack_static_config(void) +{ + ASSERT(ANT_CONFIG_TOTAL_CHANNELS_ALLOCATED <= MAX_ANT_CHANNELS); + ASSERT(ANT_CONFIG_ENCRYPTED_CHANNELS <= ANT_CONFIG_TOTAL_CHANNELS_ALLOCATED); + + ANT_ENABLE m_ant_enable_cfg = + { + .ucTotalNumberOfChannels = ANT_CONFIG_TOTAL_CHANNELS_ALLOCATED, + .ucNumberOfEncryptedChannels = ANT_CONFIG_ENCRYPTED_CHANNELS, + .usNumberOfEvents = ANT_CONFIG_EVENT_QUEUE_SIZE, + .pucMemoryBlockStartLocation = ant_stack_buffer.u8, + .usMemoryBlockByteSize = ANT_BUFFER_SIZE_FOR_SD + }; + + return sd_ant_enable(&m_ant_enable_cfg); +} + +#endif // NRF_MODULE_ENABLED(ANT_STACK_CONFIG) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_stack_config/ant_stack_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_stack_config/ant_stack_config.h new file mode 100644 index 0000000000000000000000000000000000000000..79d2c44d2f94cdef64f67056b90ab71c14855ae9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_stack_config/ant_stack_config.h @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_STACK_CONFIG_H__ +#define ANT_STACK_CONFIG_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + */ + +/** + * @defgroup ant_stack_config ANT stack configuration + * @{ + * @ingroup ant_sdk_utils + * @brief Configuration of resources used in the ANT stack. + * + * This module initializes the stack according to the configuration of the ANT channels. + */ + +/** + * @brief Function for configuring and enabling the ANT stack. + * @details The function sets the channel configuration for the stack using the parameters provided + * in the sdk_config.h file. It also assigns a correspondingly large buffer + * as static resource. + * + * @return A SoftDevice error code. + */ +uint32_t ant_stack_static_config(void); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_STACK_CONFIG_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_stack_config/config/ant_stack_config_defs.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_stack_config/config/ant_stack_config_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..643393e815f606144c72caca680de2161b928431 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_stack_config/config/ant_stack_config_defs.h @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_STACK_CONFIG_DEFS_H__ +#define ANT_STACK_CONFIG_DEFS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ANT_CONFIG_TOTAL_CHANNELS_ALLOCATED 0 +#define ANT_CONFIG_ENCRYPTED_CHANNELS 0 +#define ANT_CONFIG_BURST_QUEUE_SIZE 128 +#define ANT_CONFIG_EVENT_QUEUE_SIZE 32 + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_STACK_CONFIG_DEFS_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_state_indicator/ant_state_indicator.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_state_indicator/ant_state_indicator.c new file mode 100644 index 0000000000000000000000000000000000000000..e42cef470b3e3eacd4b27bdd1c40ba235b4d38e2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_state_indicator/ant_state_indicator.c @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_STATE_INDICATOR) +#include "ant_parameters.h" +#include "bsp.h" +#include "ant_state_indicator.h" +#include "app_error.h" +#include "bsp_btn_ant.h" +#include "nrf_soc.h" + +/** + * @addtogroup ant_sdk_state_indicator ANT channel state indicator module. + * @{ + */ + +static uint8_t m_related_channel; ///< ANT channel number linked to indication +static uint8_t m_channel_type; ///< type of linked ANT channel + + +void ant_state_indicator_init( uint8_t channel, uint8_t channel_type) +{ + m_related_channel = channel; + m_channel_type = channel_type; + + uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE); + APP_ERROR_CHECK(err_code); +} + + +uint32_t ant_state_indicator_channel_opened(void) +{ + uint32_t err_code = NRF_SUCCESS; + + switch (m_channel_type) + { + case CHANNEL_TYPE_SLAVE: + err_code = bsp_indication_set(BSP_INDICATE_SCANNING); + break; + + case CHANNEL_TYPE_SLAVE_RX_ONLY: + err_code = bsp_indication_set(BSP_INDICATE_SCANNING); + break; + + case CHANNEL_TYPE_MASTER: + err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING); + break; + } + + return err_code; +} + + +void ant_state_indicator_evt_handler(ant_evt_t * p_ant_evt) +{ + uint32_t err_code = NRF_SUCCESS; + + if (m_related_channel != p_ant_evt->channel) + return; + + switch (m_channel_type) + { + case CHANNEL_TYPE_SLAVE: + case CHANNEL_TYPE_SLAVE_RX_ONLY: + switch (p_ant_evt->event) + { + case EVENT_RX: + err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); + break; + + case EVENT_RX_FAIL: + err_code = bsp_indication_set(BSP_INDICATE_RCV_ERROR); + break; + + case EVENT_RX_FAIL_GO_TO_SEARCH: + err_code = bsp_indication_set(BSP_INDICATE_SCANNING); + break; + + case EVENT_CHANNEL_CLOSED: + err_code = bsp_indication_set(BSP_INDICATE_IDLE); + ant_state_indicator_sleep_mode_enter(); + break; + + case EVENT_RX_SEARCH_TIMEOUT: + err_code = bsp_indication_set(BSP_INDICATE_IDLE); + break; + } + break; + + case CHANNEL_TYPE_MASTER: + switch (p_ant_evt->event) + { + case EVENT_TX: + break; + } + break; + } + APP_ERROR_CHECK(err_code); +} + + +void ant_state_indicator_sleep_mode_enter(void) +{ + uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE); + APP_ERROR_CHECK(err_code); + + // Prepare wakeup buttons. + err_code = bsp_btn_ant_sleep_mode_prepare(); + APP_ERROR_CHECK(err_code); + + // Go to system-off mode (this function will not return; wakeup will cause a reset). + err_code = sd_power_system_off(); + for (;;) + { + // Infinite loop after sd_power_system_off for emulated System OFF. + } +} + +/** + *@} + */ + +#endif // NRF_MODULE_ENABLED(ANT_STATE_INDICATOR) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_state_indicator/ant_state_indicator.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_state_indicator/ant_state_indicator.h new file mode 100644 index 0000000000000000000000000000000000000000..7fb94519cca7ef7bbdc6c748bee1225379015b75 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ant/ant_state_indicator/ant_state_indicator.h @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef __ANT_STATE_INDICATOR_H +#define __ANT_STATE_INDICATOR_H + +/** @file + * + * @defgroup ant_state_indicator ANT channel state indicator + * @{ + * @ingroup ant_sdk_utils + * @brief ANT channel state indicator module. + * + * @details This module provides functionality for indicating the ANT channel state. + */ + +#include +#include "ant_stack_handler_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Function for initializing the ANT channel state indicator. + * + * @details This function links the signaling procedure with a specific ANT channel. + * + * Before calling this function, you must initiate the @ref lib_bsp to be able to use the LEDs. + * + * @param[in] channel ANT channel number. + * @param[in] channel_type ANT channel type (see Assign Channel Parameters in ant_parameters.h: @ref ant_parameters). + */ +void ant_state_indicator_init( uint8_t channel, uint8_t channel_type); + + +/** + * @brief Function for handling ANT events. + * + * @details This function handles all events from the ANT stack that are of interest to the channel state indicator. + * This function should always be called when an ANT event occurs. + * + * @param[in] p_ant_evt Event received from the ANT stack. + */ +void ant_state_indicator_evt_handler(ant_evt_t * p_ant_evt); + + +/** + * @brief Function for indicating the channel opening. + * + * @details This function should be called after the opening of the channel. + * + * @retval NRF_SUCCESS If the state was successfully indicated. + * @retval NRF_ERROR_NO_MEM If the internal timer operations queue was full. + * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized + * or the internal timer has not been created. + */ +uint32_t ant_state_indicator_channel_opened(void); + + +/**@brief Function for putting the chip into sleep mode. + * + * @details This function sets up a wakeup button and puts the chip into deep sleep mode. + * + * @note This function will not return. + */ +void ant_state_indicator_sleep_mode_enter(void); + + + +#ifdef __cplusplus +} +#endif + +#endif +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_advertising/ble_advertising.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_advertising/ble_advertising.c new file mode 100644 index 0000000000000000000000000000000000000000..902a8c4900b782ddd3aa9fba530229f6ad75926c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_advertising/ble_advertising.c @@ -0,0 +1,727 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_ADVERTISING) +#include "ble_advdata.h" +#include "ble_advertising.h" +#include "nrf_soc.h" +#include "nrf_log.h" +#include "fstorage.h" +#include "sdk_errors.h" + + +// Total number of possible advertising modes. +#define BLE_ADV_MODES (5) + + +static bool m_initialized; +static bool m_advertising_start_pending; /**< Flag to keep track of ongoing operations in flash. */ + +static ble_adv_evt_t m_adv_evt; /**< Advertising event propogated to the main application. The event is either a transaction to a new advertising mode, or a request for whitelist or peer address. */ + +static ble_adv_mode_t m_adv_mode_current; /**< Variable to keep track of the current advertising mode. */ +static ble_adv_modes_config_t m_adv_modes_config; /**< Struct to keep track of disabled and enabled advertising modes, as well as time-outs and intervals.*/ +static uint8_t m_conn_cfg_tag; /**< Variable to keep track of what connection settings will be used if the advertising results in a connection. */ + +static ble_gap_addr_t m_peer_address; /**< Address of the most recently connected peer, used for direct advertising. */ +static bool m_peer_addr_reply_expected; /**< Flag to verify that peer address is only set when requested. */ + +static ble_advdata_t m_advdata; /**< Used by the initialization function to set name, appearance, and UUIDs and advertising flags visible to peer devices. */ +static ble_advdata_manuf_data_t m_manuf_specific_data; /**< Manufacturer specific data structure*/ +static uint8_t m_manuf_data_array[BLE_GAP_ADV_MAX_SIZE]; /**< Array to store the Manufacturer specific data*/ +static ble_advdata_service_data_t m_service_data; /**< Service data structure. */ +static uint8_t m_service_data_array[BLE_GAP_ADV_MAX_SIZE]; /**< Array to store the service data. */ +static ble_advdata_conn_int_t m_slave_conn_int; /**< Connection interval range structure.*/ +static uint16_t m_current_slave_link_conn_handle; /**< Connection handle for the active link. */ + +static ble_advertising_evt_handler_t m_evt_handler; /**< Handler for the advertising events. Can be initialized as NULL if no handling is implemented on in the main application. */ +static ble_advertising_error_handler_t m_error_handler; /**< Handler for the advertising error events. */ + +static bool m_whitelist_temporarily_disabled; /**< Flag to keep track of temporary disabling of the whitelist. */ +static bool m_whitelist_reply_expected; + +#if (NRF_SD_BLE_API_VERSION <= 2) + + // For SoftDevices v 2.x, this module caches a whitelist which is retrieved from the + // application using an event, and which is passed as a parameter when calling + // sd_ble_gap_adv_start(). + + static ble_gap_addr_t * m_p_whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + static ble_gap_irk_t * m_p_whitelist_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; + static ble_gap_addr_t m_whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + static ble_gap_irk_t m_whitelist_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; + + static ble_gap_whitelist_t m_whitelist = + { + .pp_addrs = m_p_whitelist_addrs, + .pp_irks = m_p_whitelist_irks + }; + +#else + + // For SoftDevices v 3.x, this module does not need to cache a whitelist, but it needs to + // be aware of whether or not a whitelist has been set (e.g. using the Peer Manager) + // in order to start advertising with the proper advertising params (filter policy). + + static bool m_whitelist_in_use; + +#endif + + +#if (NRF_SD_BLE_API_VERSION <= 2) + + static bool whitelist_has_entries() + { + return ((m_whitelist.addr_count != 0) || (m_whitelist.irk_count != 0)); + } + +#else + + static bool whitelist_has_entries() + { + return m_whitelist_in_use; + } + +#endif + + + +/**@brief Function for checking if an address is valid. + */ +static bool addr_is_valid(uint8_t const * const addr) +{ + for (uint32_t i = 0; i < BLE_GAP_ADDR_LEN; i++) + { + if (addr[i] != 0) + { + return true; + } + } + return false; +} + + +static ble_adv_mode_t adv_mode_next_get(ble_adv_mode_t adv_mode) +{ + return (ble_adv_mode_t)((adv_mode + 1) % BLE_ADV_MODES); +} + + +/**@brief Function for handling the Connected event. + * + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connected(ble_evt_t const * p_ble_evt) +{ + if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH) + { + m_current_slave_link_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + } +} + + +/**@brief Function for handling the Disconnected event. + * + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnected(ble_evt_t const * p_ble_evt) +{ + uint32_t ret; + + m_whitelist_temporarily_disabled = false; + + if (p_ble_evt->evt.gap_evt.conn_handle == m_current_slave_link_conn_handle) + { + ret = ble_advertising_start(BLE_ADV_MODE_DIRECTED); + if ((ret != NRF_SUCCESS) && (m_error_handler != NULL)) + { + m_error_handler(ret); + } + } +} + + +/**@brief Function for handling the Timeout event. + * + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_timeout(ble_evt_t const * p_ble_evt) +{ + ret_code_t ret; + + if (p_ble_evt->evt.gap_evt.params.timeout.src != BLE_GAP_TIMEOUT_SRC_ADVERTISING) + { + // Nothing to do. + return; + } + + // Start advertising in the next mode. + ret = ble_advertising_start(adv_mode_next_get(m_adv_mode_current)); + + if ((ret != NRF_SUCCESS) && (m_error_handler != NULL)) + { + m_error_handler(ret); + } +} + + +/** @brief Function to determine if a flash write operation in in progress. + * + * @return true if a flash operation is in progress, false if not. + */ +static bool flash_access_in_progress() +{ + uint32_t count; + + (void)fs_queued_op_count_get(&count); + + return (count != 0); +} + + +/**@brief Get the next available advertising mode. + * + * @param[in] adv_mode Requested advertising mode. + * + * @returns adv_mode if possible, or the best available mode if not. + */ +static ble_adv_mode_t adv_mode_next_avail_get(ble_adv_mode_t adv_mode) +{ + bool peer_addr_is_valid = addr_is_valid(m_peer_address.addr); + + // If a mode is disabled, continue to the next mode. + + switch (adv_mode) + { + case BLE_ADV_MODE_DIRECTED: + if ((m_adv_modes_config.ble_adv_directed_enabled) && peer_addr_is_valid) + { + return BLE_ADV_MODE_DIRECTED; + } + // Fallthrough. + + case BLE_ADV_MODE_DIRECTED_SLOW: + if ((m_adv_modes_config.ble_adv_directed_slow_enabled) && peer_addr_is_valid) + { + return BLE_ADV_MODE_DIRECTED_SLOW; + } + // Fallthrough. + + case BLE_ADV_MODE_FAST: + if (m_adv_modes_config.ble_adv_fast_enabled) + { + return BLE_ADV_MODE_FAST; + } + // Fallthrough. + + case BLE_ADV_MODE_SLOW: + if (m_adv_modes_config.ble_adv_slow_enabled) + { + return BLE_ADV_MODE_SLOW; + } + // Fallthrough. + + default: + return BLE_ADV_MODE_IDLE; + } +} + + +/**@brief Function for starting directed advertising. + * + * @param[out] p_adv_params Advertising parameters. + * + * @return NRF_SUCCESS + */ +static ret_code_t set_adv_mode_directed(ble_gap_adv_params_t * p_adv_params) +{ + m_adv_evt = BLE_ADV_EVT_DIRECTED; + + p_adv_params->p_peer_addr = &m_peer_address; + p_adv_params->type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND; + p_adv_params->timeout = 0; + p_adv_params->interval = 0; + + return NRF_SUCCESS; +} + + +/**@brief Function for starting directed slow advertising. + * + * @param[out] p_adv_params Advertising parameters. + * + * @return NRF_SUCCESS + */ +static ret_code_t set_adv_mode_directed_slow(ble_gap_adv_params_t * p_adv_params) +{ + m_adv_evt = BLE_ADV_EVT_DIRECTED_SLOW; + + p_adv_params->p_peer_addr = &m_peer_address; + p_adv_params->type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND; + p_adv_params->timeout = m_adv_modes_config.ble_adv_directed_slow_timeout; + p_adv_params->interval = m_adv_modes_config.ble_adv_directed_slow_interval; + + return NRF_SUCCESS; +} + + +/**@brief Function for starting fast advertising. + * + * @param[out] p_adv_params Advertising parameters. + * + * @return NRF_SUCCESS or an error from @ref ble_advdata_set(). + */ +static ret_code_t set_adv_mode_fast(ble_gap_adv_params_t * p_adv_params) +{ + ret_code_t ret; + + p_adv_params->interval = m_adv_modes_config.ble_adv_fast_interval; + p_adv_params->timeout = m_adv_modes_config.ble_adv_fast_timeout; + + if ((m_adv_modes_config.ble_adv_whitelist_enabled) && + (!m_whitelist_temporarily_disabled) && + (whitelist_has_entries())) + { + #if (NRF_SD_BLE_API_VERSION <= 2) + p_adv_params->p_whitelist = &m_whitelist; + #endif + + p_adv_params->fp = BLE_GAP_ADV_FP_FILTER_CONNREQ; + m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; + + ret = ble_advdata_set(&m_advdata, NULL); + if (ret != NRF_SUCCESS) + { + return ret; + } + + m_adv_evt = BLE_ADV_EVT_FAST_WHITELIST; + } + else + { + m_adv_evt = BLE_ADV_EVT_FAST; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for starting slow advertising. + * + * @param[out] p_adv_params Advertising parameters. + * + * @return NRF_SUCCESS or an error from @ref ble_advdata_set(). + */ +static ret_code_t set_adv_mode_slow(ble_gap_adv_params_t * p_adv_params) +{ + ret_code_t ret; + + p_adv_params->interval = m_adv_modes_config.ble_adv_slow_interval; + p_adv_params->timeout = m_adv_modes_config.ble_adv_slow_timeout; + + if ((m_adv_modes_config.ble_adv_whitelist_enabled) && + (!m_whitelist_temporarily_disabled) && + (whitelist_has_entries())) + { + #if (NRF_SD_BLE_API_VERSION <= 2) + { + p_adv_params->p_whitelist = &m_whitelist; + } + #endif + + p_adv_params->fp = BLE_GAP_ADV_FP_FILTER_CONNREQ; + m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; + + ret = ble_advdata_set(&m_advdata, NULL); + if (ret != NRF_SUCCESS) + { + return ret; + } + + m_adv_evt = BLE_ADV_EVT_SLOW_WHITELIST; + } + else + { + m_adv_evt = BLE_ADV_EVT_SLOW; + } + + return NRF_SUCCESS; +} + + +void ble_advertising_conn_cfg_tag_set(uint8_t ble_cfg_tag) +{ + m_conn_cfg_tag = ble_cfg_tag; +} + + +uint32_t ble_advertising_init(ble_advdata_t const * p_advdata, + ble_advdata_t const * p_srdata, + ble_adv_modes_config_t const * p_config, + ble_advertising_evt_handler_t const evt_handler, + ble_advertising_error_handler_t const error_handler) +{ + uint32_t ret; + + if ((p_advdata == NULL) || (p_config == NULL)) + { + return NRF_ERROR_NULL; + } + + m_initialized = true; + m_adv_mode_current = BLE_ADV_MODE_IDLE; + m_adv_modes_config = *p_config; + m_conn_cfg_tag = BLE_CONN_CFG_TAG_DEFAULT; + m_evt_handler = evt_handler; + m_error_handler = error_handler; + m_current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID; + + memset(&m_peer_address, 0, sizeof(m_peer_address)); + memset(&m_advdata, 0, sizeof(m_advdata)); + + // Copy advertising data. + m_advdata.name_type = p_advdata->name_type; + m_advdata.include_appearance = p_advdata->include_appearance; + m_advdata.flags = p_advdata->flags; + m_advdata.short_name_len = p_advdata->short_name_len; + + m_advdata.uuids_complete = p_advdata->uuids_complete; + m_advdata.uuids_more_available = p_advdata->uuids_more_available; + m_advdata.uuids_solicited = p_advdata->uuids_solicited; + + if (p_advdata->p_manuf_specific_data != NULL) + { + m_advdata.p_manuf_specific_data = &m_manuf_specific_data; + m_manuf_specific_data.data.p_data = m_manuf_data_array; + m_advdata.p_manuf_specific_data->company_identifier = + p_advdata->p_manuf_specific_data->company_identifier; + m_advdata.p_manuf_specific_data->data.size = p_advdata->p_manuf_specific_data->data.size; + + for (uint32_t i = 0; i < m_advdata.p_manuf_specific_data->data.size; i++) + { + m_manuf_data_array[i] = p_advdata->p_manuf_specific_data->data.p_data[i]; + } + } + + if (p_advdata->p_service_data_array != NULL) + { + m_service_data.data.p_data = m_service_data_array; + m_advdata.p_service_data_array = &m_service_data; + m_advdata.p_service_data_array->data.p_data = m_service_data_array; + m_advdata.p_service_data_array->data.size = p_advdata->p_service_data_array->data.size; + m_advdata.p_service_data_array->service_uuid = p_advdata->p_service_data_array->service_uuid; + + for (uint32_t i = 0; i < m_advdata.p_service_data_array->data.size; i++) + { + m_service_data_array[i] = p_advdata->p_service_data_array->data.p_data[i]; + } + + m_advdata.service_data_count = p_advdata->service_data_count; + } + + if (p_advdata->p_slave_conn_int != NULL) + { + m_advdata.p_slave_conn_int = &m_slave_conn_int; + m_advdata.p_slave_conn_int->max_conn_interval = p_advdata->p_slave_conn_int->max_conn_interval; + m_advdata.p_slave_conn_int->min_conn_interval = p_advdata->p_slave_conn_int->min_conn_interval; + } + + if (p_advdata->p_tx_power_level != NULL) + { + m_advdata.p_tx_power_level = p_advdata->p_tx_power_level; + } + +#if (NRF_SD_BLE_API_VERSION <= 2) + for (int i = 0; i = 3) + m_whitelist_in_use = false; + #endif + m_whitelist_reply_expected = true; + m_evt_handler(BLE_ADV_EVT_WHITELIST_REQUEST); + } + else + { + m_whitelist_reply_expected = false; + } + + // Initialize advertising parameters with default values. + memset(&adv_params, 0, sizeof(adv_params)); + + adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; + adv_params.fp = BLE_GAP_ADV_FP_ANY; + + // Set advertising parameters and events according to selected advertising mode. + switch (m_adv_mode_current) + { + case BLE_ADV_MODE_DIRECTED: + ret = set_adv_mode_directed(&adv_params); + break; + + case BLE_ADV_MODE_DIRECTED_SLOW: + ret = set_adv_mode_directed_slow(&adv_params); + break; + + case BLE_ADV_MODE_FAST: + ret = set_adv_mode_fast(&adv_params); + break; + + case BLE_ADV_MODE_SLOW: + ret = set_adv_mode_slow(&adv_params); + break; + + case BLE_ADV_MODE_IDLE: + m_adv_evt = BLE_ADV_EVT_IDLE; + break; + + default: + break; + } + + if (m_adv_mode_current != BLE_ADV_MODE_IDLE) + { + ret = sd_ble_gap_adv_start(&adv_params, m_conn_cfg_tag); + if (ret != NRF_SUCCESS) + { + return ret; + } + } + + if (m_evt_handler != NULL) + { + m_evt_handler(m_adv_evt); + } + + return NRF_SUCCESS; +} + + +void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connected(p_ble_evt); + break; + + // Upon disconnection, whitelist will be activated and direct advertising is started. + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_ble_evt); + break; + + // Upon time-out, the next advertising mode is started. + case BLE_GAP_EVT_TIMEOUT: + on_timeout(p_ble_evt); + break; + + default: + break; + } +} + + +void ble_advertising_on_sys_evt(uint32_t sys_evt) +{ + uint32_t ret; + + switch (sys_evt) + { + //When a flash operation finishes, re-attempt to start advertising operations. + case NRF_EVT_FLASH_OPERATION_SUCCESS: + case NRF_EVT_FLASH_OPERATION_ERROR: + if (m_advertising_start_pending) + { + m_advertising_start_pending = false; + ret = ble_advertising_start(m_adv_mode_current); + if ((ret != NRF_SUCCESS) && (m_error_handler != NULL)) + { + m_error_handler(ret); + } + } + break; + + default: + // No implementation needed. + break; + } +} + + +uint32_t ble_advertising_peer_addr_reply(ble_gap_addr_t * p_peer_address) +{ + if (!m_peer_addr_reply_expected) + { + return NRF_ERROR_INVALID_STATE; + } + + m_peer_addr_reply_expected = false; + + memcpy(&m_peer_address, p_peer_address, sizeof(m_peer_address)); + + return NRF_SUCCESS; +} + + +uint32_t ble_advertising_whitelist_reply(ble_gap_addr_t const * p_gap_addrs, + uint32_t addr_cnt, + ble_gap_irk_t const * p_gap_irks, + uint32_t irk_cnt) +{ + if (!m_whitelist_reply_expected) + { + return NRF_ERROR_INVALID_STATE; + } + + m_whitelist_reply_expected = false; + + #if (NRF_SD_BLE_API_VERSION <= 2) + + m_whitelist.addr_count = addr_cnt; + m_whitelist.irk_count = irk_cnt; + + for (uint32_t i = 0; i < addr_cnt; i++) + { + *m_whitelist.pp_addrs[i] = p_gap_addrs[i]; + } + + for (uint32_t i = 0; i < irk_cnt; i++) + { + *m_whitelist.pp_irks[i] = p_gap_irks[i]; + } + + #else + + m_whitelist_in_use = ((addr_cnt > 0) || (irk_cnt > 0)); + + #endif + + return NRF_SUCCESS; +} + + +uint32_t ble_advertising_restart_without_whitelist(void) +{ + uint32_t ret; + + (void) sd_ble_gap_adv_stop(); + + m_whitelist_temporarily_disabled = true; + + #if (NRF_SD_BLE_API_VERSION >= 3) + m_whitelist_in_use = false; + #endif + + m_advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; + + ret = ble_advdata_set(&m_advdata, NULL); + if (ret != NRF_SUCCESS) + { + return ret; + } + + ret = ble_advertising_start(m_adv_mode_current); + if ((ret != NRF_SUCCESS) && (m_error_handler != NULL)) + { + m_error_handler(ret); + } + + return NRF_SUCCESS; +} + +#endif // NRF_MODULE_ENABLED(BLE_ADVERTISING) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_advertising/ble_advertising.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_advertising/ble_advertising.h new file mode 100644 index 0000000000000000000000000000000000000000..76c9ca280314f38be79efcad98753f85e876fbb4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_advertising/ble_advertising.h @@ -0,0 +1,270 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ble_advertising Advertising Module + * @{ + * @ingroup ble_sdk_lib + * @brief Module for handling connectable BLE advertising. + * + * @details The Advertising Module handles connectable advertising for your application. It can + * be configured with advertising modes to suit most typical use cases. + * Your main application can react to changes in advertising modes + * if an event handler is provided. + * + * @note The Advertising Module supports only applications with a single peripheral link. + * + * The application must propagate BLE stack events to this module by calling + * @ref ble_advertising_on_ble_evt() and system events by calling + * @ref ble_advertising_on_sys_evt(). + * + */ + +#ifndef BLE_ADVERTISING_H__ +#define BLE_ADVERTISING_H__ + +#include +#include "nrf_error.h" +#include "ble.h" +#include "ble_gattc.h" +#include "ble_advdata.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Advertising modes. +*/ +typedef enum +{ + BLE_ADV_MODE_IDLE, /**< Idle; no connectable advertising is ongoing. */ + BLE_ADV_MODE_DIRECTED, /**< Directed advertising attempts to connect to the most recently disconnected peer. */ + BLE_ADV_MODE_DIRECTED_SLOW, /**< Directed advertising (low duty cycle) attempts to connect to the most recently disconnected peer. */ + BLE_ADV_MODE_FAST, /**< Fast advertising will connect to any peer device, or filter with a whitelist if one exists. */ + BLE_ADV_MODE_SLOW, /**< Slow advertising is similar to fast advertising. By default, it uses a longer advertising interval and time-out than fast advertising. However, these options are defined by the user. */ +} ble_adv_mode_t; + +/**@brief Advertising events. + * + * @details These events are propagated to the main application if a handler was provided during + * initialization of the Advertising Module. Events for modes that are not used can be + * ignored. Similarly, BLE_ADV_EVT_WHITELIST_REQUEST and BLE_ADV_EVT_PEER_ADDR_REQUEST + * can be ignored if whitelist and direct advertising is not used. + */ +typedef enum +{ + BLE_ADV_EVT_IDLE, /**< Idle; no connectable advertising is ongoing.*/ + BLE_ADV_EVT_DIRECTED, /**< Direct advertising mode has started. */ + BLE_ADV_EVT_DIRECTED_SLOW, /**< Directed advertising (low duty cycle) has started. */ + BLE_ADV_EVT_FAST, /**< Fast advertising mode has started. */ + BLE_ADV_EVT_SLOW, /**< Slow advertising mode has started. */ + BLE_ADV_EVT_FAST_WHITELIST, /**< Fast advertising mode using the whitelist has started. */ + BLE_ADV_EVT_SLOW_WHITELIST, /**< Slow advertising mode using the whitelist has started. */ + BLE_ADV_EVT_WHITELIST_REQUEST, /**< Request a whitelist from the main application. For whitelist advertising to work, the whitelist must be set when this event occurs. */ + BLE_ADV_EVT_PEER_ADDR_REQUEST /**< Request a peer address from the main application. For directed advertising to work, the peer address must be set when this event occurs. */ +} ble_adv_evt_t; + + +/**@brief Options for the different advertisement modes. + * + * @details This structure is used to enable or disable advertising modes and to configure time-out + * periods and advertising intervals. + */ +typedef struct +{ + bool ble_adv_whitelist_enabled; /**< Enable or disable use of the whitelist. */ + bool ble_adv_directed_enabled; /**< Enable or disable direct advertising mode. */ + bool ble_adv_directed_slow_enabled; /**< Enable or disable direct advertising mode. */ + bool ble_adv_fast_enabled; /**< Enable or disable fast advertising mode. */ + bool ble_adv_slow_enabled; /**< Enable or disable slow advertising mode. */ + uint32_t ble_adv_directed_slow_interval; /**< Advertising interval for directed advertising. */ + uint32_t ble_adv_directed_slow_timeout; /**< Time-out (number of tries) for direct advertising. */ + uint32_t ble_adv_fast_interval; /**< Advertising interval for fast advertising. */ + uint32_t ble_adv_fast_timeout; /**< Time-out (in seconds) for fast advertising. */ + uint32_t ble_adv_slow_interval; /**< Advertising interval for slow advertising. */ + uint32_t ble_adv_slow_timeout; /**< Time-out (in seconds) for slow advertising. */ +} ble_adv_modes_config_t; + + +typedef struct +{ + uint32_t interval; + uint32_t timeout; + bool enabled; +} ble_adv_mode_config_t; + + +/**@brief BLE advertising event handler type. */ +typedef void (*ble_advertising_evt_handler_t) (ble_adv_evt_t const adv_evt); + +/**@brief BLE advertising error handler type. */ +typedef void (*ble_advertising_error_handler_t) (uint32_t nrf_error); + +/**@brief Initialization parameters for the Advertising Module. + * @details This structure is used to pass advertising options, advertising data, and an event handler to the Advertising Module during initialization. */ +typedef struct +{ + ble_adv_modes_config_t options; /**< Parameters for advertising modes.*/ + ble_advdata_t advdata; /**< Advertising data. */ + ble_advertising_evt_handler_t evt_handler; /**< Event handler. */ +} ble_adv_init_t; + + +/**@brief Function for handling BLE events. + * + * @details This function must be called from the BLE stack event dispatcher for + * the module to handle BLE events that are relevant for the Advertising Module. + * + * @param[in] p_ble_evt BLE stack event. + */ +void ble_advertising_on_ble_evt(const ble_evt_t * const p_ble_evt); + + +/**@brief Function for handling system events. + * + * @details This function must be called to handle system events that are relevant + * for the Advertising Module. Specifically, the advertising module can not use the + * softdevice as long as there are pending writes to the flash memory. This + * event handler is designed to delay advertising until there is no flash operation. + * + * @param[in] sys_evt System event. + */ +void ble_advertising_on_sys_evt(uint32_t sys_evt); + + +/**@brief Function for initializing the Advertising Module. + * + * @details Encodes the required advertising data and passes it to the stack. + * Also builds a structure to be passed to the stack when starting advertising. + * The supplied advertising data is copied to a local structure and is manipulated + * depending on what advertising modes are started in @ref ble_advertising_start. + * + * @param[in] p_advdata Advertising data: name, appearance, discovery flags, and more. + * @param[in] p_srdata Scan response data: Supplement to advertising data. + * @param[in] p_config Select which advertising modes and intervals will be utilized. + * @param[in] evt_handler Event handler that will be called upon advertising events. + * @param[in] error_handler Error handler that will propogate internal errors to the main applications. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. + */ +uint32_t ble_advertising_init(ble_advdata_t const * p_advdata, + ble_advdata_t const * p_srdata, + ble_adv_modes_config_t const * p_config, + ble_advertising_evt_handler_t const evt_handler, + ble_advertising_error_handler_t const error_handler); + + + /**@brief Function for changing the connection settings tag that will be used for upcoming connections. + * + * @details See @ref sd_ble_cfg_set for more details about changing connection settings. If this + * function is never called, @ref BLE_CONN_CFG_TAG_DEFAULT will be used. + * + * @param[in] ble_cfg_tag Configuration for the connection settings (see @ref sd_ble_cfg_set). + */ +void ble_advertising_conn_cfg_tag_set(uint8_t ble_cfg_tag); + +/**@brief Function for starting advertising. + * + * @details You can start advertising in any of the advertising modes that you enabled + * during initialization. + * + * @param[in] advertising_mode Advertising mode. + * + * @retval @ref NRF_SUCCESS On success, else an error code indicating reason for failure. + * @retval @ref NRF_ERROR_INVALID_STATE If the module is not initialized. + */ +uint32_t ble_advertising_start(ble_adv_mode_t advertising_mode); + + +/**@brief Function for setting the peer address. + * + * @details The peer address must be set by the application upon receiving a + * @ref BLE_ADV_EVT_PEER_ADDR_REQUEST event. Without the peer address, the directed + * advertising mode will not be run. + * + * @param[in] p_peer_addr Pointer to a peer address. + * + * @retval @ref NRF_SUCCESS Successfully stored the peer address pointer in the advertising module. + * @retval @ref NRF_ERROR_INVALID_STATE If a reply was not expected. + */ +uint32_t ble_advertising_peer_addr_reply(ble_gap_addr_t * p_peer_addr); + + +/**@brief Function for setting a whitelist. + * + * @details The whitelist must be set by the application upon receiving a + * @ref BLE_ADV_EVT_WHITELIST_REQUEST event. Without the whitelist, the whitelist + * advertising for fast and slow modes will not be run. + * + * @param[in] p_gap_addrs The list of GAP addresses to whitelist. + * @param[in] addr_cnt The number of GAP addresses to whitelist. + * @param[in] p_gap_irks The list of peer IRK to whitelist. + * @param[in] irk_cnt The number of peer IRK to whitelist. + * + * @retval @ref NRF_SUCCESS If the operation was successful. + * @retval @ref NRF_ERROR_INVALID_STATE If a call to this function was made without a + * BLE_ADV_EVT_WHITELIST_REQUEST event being received. + */ +uint32_t ble_advertising_whitelist_reply(ble_gap_addr_t const * p_gap_addrs, + uint32_t addr_cnt, + ble_gap_irk_t const * p_gap_irks, + uint32_t irk_cnt); + + +/**@brief Function for disabling whitelist advertising. + * + * @details This function temporarily disables whitelist advertising. + * Calling this function resets the current time-out countdown. + * + * @retval @ref NRF_SUCCESS On success, else an error message propogated from the Softdevice. + */ +uint32_t ble_advertising_restart_without_whitelist(void); + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_ADVERTISING_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_db_discovery/ble_db_discovery.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_db_discovery/ble_db_discovery.c new file mode 100644 index 0000000000000000000000000000000000000000..2f78c1d8f9e23b40eb2c8e280d03cac55b2e67ee --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_db_discovery/ble_db_discovery.c @@ -0,0 +1,958 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_DB_DISCOVERY) +#include "ble_db_discovery.h" +#include +#include "ble.h" +#include "ble_srv_common.h" +#define NRF_LOG_MODULE_NAME "BLE_DB_DISC" +#include "nrf_log.h" + +#define SRV_DISC_START_HANDLE 0x0001 /**< The start handle value used during service discovery. */ +#define DB_DISCOVERY_MAX_USERS BLE_DB_DISCOVERY_MAX_SRV /**< The maximum number of users/registrations allowed by this module. */ +#define MODULE_INITIALIZED (m_initialized == true) /**< Macro designating whether the module has been initialized properly. */ + + +/**@brief Array of structures containing information about the registered application modules. */ +static ble_uuid_t m_registered_handlers[DB_DISCOVERY_MAX_USERS]; + + +/**@brief Array of structures containing pending events to be sent to the application modules. + * + * @details Whenever a discovery related event is to be raised to a user module, it will be stored + * in this array first. When all services needed to be discovered have been + * discovered, all pending events will be sent to the corresponding user modules. + **/ +static struct +{ + ble_db_discovery_evt_t evt; /**< The pending event. */ + ble_db_discovery_evt_handler_t evt_handler; /**< The event handler which should be called to raise this event. */ +} m_pending_user_evts[DB_DISCOVERY_MAX_USERS]; + +static ble_db_discovery_evt_handler_t m_evt_handler; +static uint32_t m_pending_usr_evt_index; /**< The index to the pending user event array, pointing to the last added pending user event. */ +static uint32_t m_num_of_handlers_reg; /**< The number of handlers registered with the DB Discovery module. */ +static bool m_initialized = false; /**< This variable Indicates if the module is initialized or not. */ + +/**@brief Function for fetching the event handler provided by a registered application module. + * + * @param[in] srv_uuid UUID of the service. + * + * @retval evt_handler Event handler of the module, registered for the given service UUID. + * @retval NULL If no event handler is found. + */ +static ble_db_discovery_evt_handler_t registered_handler_get(ble_uuid_t const * p_srv_uuid) +{ + for (uint32_t i = 0; i < m_num_of_handlers_reg; i++) + { + if (BLE_UUID_EQ(&(m_registered_handlers[i]), p_srv_uuid)) + { + return (m_evt_handler); + } + } + + return NULL; +} + + +/**@brief Function for storing the event handler provided by a registered application module. + * + * @param[in] p_srv_uuid The UUID of the service. + * @param[in] p_evt_handler The event handler provided by the application. + * + * @retval NRF_SUCCESS If the handler was stored or already present in the list. + * @retval NRF_ERROR_NO_MEM If there is no space left to store the handler. + */ +static uint32_t registered_handler_set(ble_uuid_t const * p_srv_uuid, + ble_db_discovery_evt_handler_t p_evt_handler) +{ + if (registered_handler_get(p_srv_uuid) != NULL) + { + return NRF_SUCCESS; + } + + if (m_num_of_handlers_reg < DB_DISCOVERY_MAX_USERS) + { + m_registered_handlers[m_num_of_handlers_reg] = *p_srv_uuid; + m_num_of_handlers_reg++; + + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_NO_MEM; + } +} + + +/**@brief Function for sending all pending discovery events to the corresponding user modules. + */ +static void pending_user_evts_send(void) +{ + for (uint32_t i = 0; i < m_num_of_handlers_reg; i++) + { + // Pass the event to the corresponding event handler. + m_pending_user_evts[i].evt_handler(&(m_pending_user_evts[i].evt)); + } + + m_pending_usr_evt_index = 0; +} + + +/**@brief Function for indicating error to the application. + * + * @details This function will fetch the event handler based on the UUID of the service being + * discovered. (The event handler is registered by the application beforehand). + * The error code is added to the pending events together with the event handler. + * If no event handler was found, then this function will do nothing. + * + * @param[in] p_db_discovery Pointer to the DB discovery structure. + * @param[in] err_code Error code that should be provided to the application. + * @param[in] conn_handle Connection Handle. + * + */ +static void discovery_error_evt_trigger(ble_db_discovery_t * p_db_discovery, + uint32_t err_code, + uint16_t conn_handle) +{ + ble_db_discovery_evt_handler_t p_evt_handler; + ble_gatt_db_srv_t * p_srv_being_discovered; + + p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); + + p_evt_handler = registered_handler_get(&(p_srv_being_discovered->srv_uuid)); + + if (p_evt_handler != NULL) + { + ble_db_discovery_evt_t evt; + + evt.conn_handle = conn_handle; + evt.evt_type = BLE_DB_DISCOVERY_ERROR; + evt.params.err_code = err_code; + + p_evt_handler(&evt); + } +} + + +/**@brief Function for triggering a Discovery Complete or Service Not Found event to the + * application. + * + * @details This function will fetch the event handler based on the UUID of the service being + * discovered. (The event handler is registered by the application beforehand). + * It then triggers an event indicating the completion of the service discovery. + * If no event handler was found, then this function will do nothing. + * + * @param[in] p_db_discovery Pointer to the DB discovery structure. + * @param[in] is_srv_found Variable to indicate if the service was found at the peer. + * @param[in] conn_handle Connection Handle. + */ +static void discovery_complete_evt_trigger(ble_db_discovery_t * p_db_discovery, + bool is_srv_found, + uint16_t conn_handle) +{ + ble_db_discovery_evt_handler_t p_evt_handler; + ble_gatt_db_srv_t * p_srv_being_discovered; + + p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); + + p_evt_handler = registered_handler_get(&(p_srv_being_discovered->srv_uuid)); + + if (p_evt_handler != NULL) + { + if (m_pending_usr_evt_index < DB_DISCOVERY_MAX_USERS) + { + // Insert an event into the pending event list. + m_pending_user_evts[m_pending_usr_evt_index].evt.conn_handle = conn_handle; + m_pending_user_evts[m_pending_usr_evt_index].evt.params.discovered_db = + *p_srv_being_discovered; + + if (is_srv_found) + { + m_pending_user_evts[m_pending_usr_evt_index].evt.evt_type = + BLE_DB_DISCOVERY_COMPLETE; + } + else + { + m_pending_user_evts[m_pending_usr_evt_index].evt.evt_type = + BLE_DB_DISCOVERY_SRV_NOT_FOUND; + } + + m_pending_user_evts[m_pending_usr_evt_index].evt_handler = p_evt_handler; + m_pending_usr_evt_index++; + + if (m_pending_usr_evt_index == m_num_of_handlers_reg) + { + // All registered modules have pending events. Send all pending events to the user + // modules. + pending_user_evts_send(); + } + else + { + // Too many events pending. Do nothing. (Ideally this should not happen.) + } + } + } +} + + +/**@brief Function for handling service discovery completion. + * + * @details This function will be used to determine if there are more services to be discovered, + * and if so, initiate the discovery of the next service. + * + * @param[in] p_db_discovery Pointer to the DB Discovery Structure. + * @param[in] conn_handle Connection Handle. + */ +static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery, + uint16_t conn_handle) +{ + p_db_discovery->discoveries_count++; + + // Check if more services need to be discovered. + if (p_db_discovery->discoveries_count < m_num_of_handlers_reg) + { + // Reset the current characteristic index since a new service discovery is about to start. + p_db_discovery->curr_char_ind = 0; + + // Initiate discovery of the next service. + p_db_discovery->curr_srv_ind++; + + ble_gatt_db_srv_t * p_srv_being_discovered; + + p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); + + p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind]; + + // Reset the characteristic count in the current service to zero since a new service + // discovery is about to start. + p_srv_being_discovered->char_count = 0; + + NRF_LOG_DEBUG("Starting discovery of service with UUID 0x%x on connection handle 0x%x.\r\n", + p_srv_being_discovered->srv_uuid.uuid, conn_handle); + + uint32_t err_code; + + err_code = sd_ble_gattc_primary_services_discover(conn_handle, + SRV_DISC_START_HANDLE, + &(p_srv_being_discovered->srv_uuid)); + + if (err_code != NRF_SUCCESS) + { + p_db_discovery->discovery_in_progress = false; + + // Error with discovering the service. + // Indicate the error to the registered user application. + discovery_error_evt_trigger(p_db_discovery, err_code, conn_handle); + + m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; + m_pending_user_evts[0].evt.conn_handle = conn_handle; + + return; + } + } + else + { + // No more service discovery is needed. + p_db_discovery->discovery_in_progress = false; + m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; + m_pending_user_evts[0].evt.conn_handle = conn_handle; + } +} + + +/**@brief Function for finding out if a characteristic discovery should be performed after the + * last discovered characteristic. + * + * @details This function is used during the time of database discovery to find out if there is + * a need to do more characteristic discoveries. The value handles of the + * last discovered characteristic is compared with the end handle of the service. + * If the service handle is greater than one of the former characteristic handles, + * it means that a characteristic discovery is required. + * + * @param[in] p_db_discovery The pointer to the DB Discovery structure. + * @param[in] p_after_char The pointer to the last discovered characteristic. + * + * @retval True if a characteristic discovery is required. + * @retval False if a characteristic discovery is NOT required. + */ +static bool is_char_discovery_reqd(ble_db_discovery_t * p_db_discovery, + ble_gattc_char_t * p_after_char) +{ + if (p_after_char->handle_value < + p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle) + { + // Handle value of the characteristic being discovered is less than the end handle of + // the service being discovered. There is a possibility of more characteristics being + // present. Hence a characteristic discovery is required. + return true; + } + + return false; +} + + +/**@brief Function to find out if a descriptor discovery is required. + * + * @details This function finds out if there is a possibility of existence of descriptors between + * current characteristic and the next characteristic. If so, this function will compute + * the handle range on which the descriptors may be present and will return it. + * If the current characteristic is the last known characteristic, then this function + * will use the service end handle to find out if the current characteristic can have + * descriptors. + * + * @param[in] p_db_discovery Pointer to the DB Discovery structure. + * @param[in] p_curr_char Pointer to the current characteristic. + * @param[in] p_next_char Pointer to the next characteristic. This should be NULL if the + * caller knows that there is no characteristic after the current + * characteristic at the peer. + * @param[out] p_handle_range Pointer to the handle range in which descriptors may exist at the + * the peer. + * + * @retval True If a descriptor discovery is required. + * @retval False If a descriptor discovery is NOT required. + */ +static bool is_desc_discovery_reqd(ble_db_discovery_t * p_db_discovery, + ble_gatt_db_char_t * p_curr_char, + ble_gatt_db_char_t * p_next_char, + ble_gattc_handle_range_t * p_handle_range) +{ + if (p_next_char == NULL) + { + // Current characteristic is the last characteristic in the service. Check if the value + // handle of the current characteristic is equal to the service end handle. + if ( + p_curr_char->characteristic.handle_value == + p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle + ) + { + // No descriptors can be present for the current characteristic. p_curr_char is the last + // characteristic with no descriptors. + return false; + } + + p_handle_range->start_handle = p_curr_char->characteristic.handle_value + 1; + + // Since the current characteristic is the last characteristic in the service, the end + // handle should be the end handle of the service. + p_handle_range->end_handle = + p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle; + + return true; + } + + // p_next_char != NULL. Check for existence of descriptors between the current and the next + // characteristic. + if ((p_curr_char->characteristic.handle_value + 1) == p_next_char->characteristic.handle_decl) + { + // No descriptors can exist between the two characteristic. + return false; + } + + p_handle_range->start_handle = p_curr_char->characteristic.handle_value + 1; + p_handle_range->end_handle = p_next_char->characteristic.handle_decl - 1; + + return true; +} + + +/**@brief Function for performing characteristic discovery. + * + * @param[in] p_db_discovery Pointer to the DB Discovery structure. + * @param[in] conn_handle Connection Handle. + * + * @return NRF_SUCCESS if the SoftDevice was successfully requested to perform the characteristic + * discovery. Otherwise an error code. This function returns the error code returned + * by the SoftDevice API @ref sd_ble_gattc_characteristics_discover. + */ +static uint32_t characteristics_discover(ble_db_discovery_t * p_db_discovery, + uint16_t conn_handle) +{ + ble_gatt_db_srv_t * p_srv_being_discovered; + ble_gattc_handle_range_t handle_range; + + p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); + + if (p_db_discovery->curr_char_ind != 0) + { + // This is not the first characteristic being discovered. Hence the 'start handle' to be + // used must be computed using the handle_value of the previous characteristic. + ble_gattc_char_t * p_prev_char; + uint8_t prev_char_ind = p_db_discovery->curr_char_ind - 1; + + p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); + + p_prev_char = &(p_srv_being_discovered->charateristics[prev_char_ind].characteristic); + + handle_range.start_handle = p_prev_char->handle_value + 1; + } + else + { + // This is the first characteristic of this service being discovered. + handle_range.start_handle = p_srv_being_discovered->handle_range.start_handle; + } + + handle_range.end_handle = p_srv_being_discovered->handle_range.end_handle; + + return sd_ble_gattc_characteristics_discover(conn_handle, &handle_range); +} + + +/**@brief Function for performing descriptor discovery, if required. + * + * @details This function will check if descriptor discovery is required and then perform it if + * needed. If no more descriptor discovery is required for the service, then the output + * parameter p_raise_discov_complete is set to true, indicating to the caller that a + * discovery complete event can be triggered to the application. + * + * @param[in] p_db_discovery Pointer to the DB Discovery structure. + * @param[out] p_raise_discov_complete The value pointed to by this pointer will be set to true if + * the Discovery Complete event can be triggered to the + * application. + * @param[in] conn_handle Connection Handle. + * + * @return NRF_SUCCESS if the SoftDevice was successfully requested to perform the descriptor + * discovery, or if no more descriptor discovery is required. Otherwise an error code. + * This function returns the error code returned by the SoftDevice API @ref + * sd_ble_gattc_descriptors_discover. + */ +static uint32_t descriptors_discover(ble_db_discovery_t * p_db_discovery, + bool * p_raise_discov_complete, + uint16_t conn_handle) +{ + ble_gattc_handle_range_t handle_range; + ble_gatt_db_char_t * p_curr_char_being_discovered; + ble_gatt_db_srv_t * p_srv_being_discovered; + bool is_discovery_reqd = false; + + p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); + + p_curr_char_being_discovered = + &(p_srv_being_discovered->charateristics[p_db_discovery->curr_char_ind]); + + if ((p_db_discovery->curr_char_ind + 1) == p_srv_being_discovered->char_count) + { + // This is the last characteristic of this service. + is_discovery_reqd = is_desc_discovery_reqd(p_db_discovery, + p_curr_char_being_discovered, + NULL, + &handle_range); + } + else + { + uint8_t i; + ble_gatt_db_char_t * p_next_char; + + for (i = p_db_discovery->curr_char_ind; i < p_srv_being_discovered->char_count; i++) + { + if (i == (p_srv_being_discovered->char_count - 1)) + { + // The current characteristic is the last characteristic in the service. + p_next_char = NULL; + } + else + { + p_next_char = &(p_srv_being_discovered->charateristics[i + 1]); + } + + // Check if it is possible for the current characteristic to have a descriptor. + if (is_desc_discovery_reqd(p_db_discovery, + p_curr_char_being_discovered, + p_next_char, + &handle_range)) + { + is_discovery_reqd = true; + break; + } + else + { + // No descriptors can exist. + p_curr_char_being_discovered = p_next_char; + p_db_discovery->curr_char_ind++; + } + } + } + + if (!is_discovery_reqd) + { + // No more descriptor discovery required. Discovery is complete. + // This informs the caller that a discovery complete event can be triggered. + *p_raise_discov_complete = true; + + return NRF_SUCCESS; + } + + *p_raise_discov_complete = false; + + return sd_ble_gattc_descriptors_discover(conn_handle, &handle_range); +} + + +/**@brief Function for handling primary service discovery response. + * + * @details This function will handle the primary service discovery response and start the + * discovery of characteristics within that service. + * + * @param[in] p_db_discovery Pointer to the DB Discovery structure. + * @param[in] p_ble_gattc_evt Pointer to the GATT Client event. + */ +static void on_primary_srv_discovery_rsp(ble_db_discovery_t * p_db_discovery, + ble_gattc_evt_t const * p_ble_gattc_evt) +{ + ble_gatt_db_srv_t * p_srv_being_discovered; + + p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); + + if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle) + { + return; + } + + if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS) + { + uint32_t err_code; + ble_gattc_evt_prim_srvc_disc_rsp_t const * p_prim_srvc_disc_rsp_evt; + + NRF_LOG_DEBUG("Found service UUID 0x%x.\r\n", p_srv_being_discovered->srv_uuid.uuid); + + p_prim_srvc_disc_rsp_evt = &(p_ble_gattc_evt->params.prim_srvc_disc_rsp); + + p_srv_being_discovered->srv_uuid = p_prim_srvc_disc_rsp_evt->services[0].uuid; + p_srv_being_discovered->handle_range = p_prim_srvc_disc_rsp_evt->services[0].handle_range; + + err_code = characteristics_discover(p_db_discovery, p_ble_gattc_evt->conn_handle); + + if (err_code != NRF_SUCCESS) + { + p_db_discovery->discovery_in_progress = false; + + // Error with discovering the service. + // Indicate the error to the registered user application. + discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle); + + m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; + m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle; + } + } + else + { + NRF_LOG_DEBUG("Service UUID 0x%x not found.\r\n", p_srv_being_discovered->srv_uuid.uuid); + // Trigger Service Not Found event to the application. + discovery_complete_evt_trigger(p_db_discovery, false, p_ble_gattc_evt->conn_handle); + on_srv_disc_completion(p_db_discovery, p_ble_gattc_evt->conn_handle); + } +} + + +/**@brief Function for handling characteristic discovery response. + * + * @param[in] p_db_discovery Pointer to the DB Discovery structure. + * @param[in] p_ble_gattc_evt Pointer to the GATT Client event. + */ +static void on_characteristic_discovery_rsp(ble_db_discovery_t * p_db_discovery, + ble_gattc_evt_t const * p_ble_gattc_evt) +{ + uint32_t err_code; + ble_gatt_db_srv_t * p_srv_being_discovered; + bool perform_desc_discov = false; + + if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle) + { + return; + } + + p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); + + if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS) + { + ble_gattc_evt_char_disc_rsp_t const * p_char_disc_rsp_evt; + + p_char_disc_rsp_evt = &(p_ble_gattc_evt->params.char_disc_rsp); + + // Find out the number of characteristics that were previously discovered (in earlier + // characteristic discovery responses, if any). + uint8_t num_chars_prev_disc = p_srv_being_discovered->char_count; + + // Find out the number of characteristics that are currently discovered (in the + // characteristic discovery response being handled). + uint8_t num_chars_curr_disc = p_char_disc_rsp_evt->count; + + // Check if the total number of discovered characteristics are supported by this module. + if ((num_chars_prev_disc + num_chars_curr_disc) <= BLE_GATT_DB_MAX_CHARS) + { + // Update the characteristics count. + p_srv_being_discovered->char_count += num_chars_curr_disc; + } + else + { + // The number of characteristics discovered at the peer is more than the supported + // maximum. This module will store only the characteristics found up to this point. + p_srv_being_discovered->char_count = BLE_GATT_DB_MAX_CHARS; + } + + uint32_t i; + uint32_t j; + + for (i = num_chars_prev_disc, j = 0; i < p_srv_being_discovered->char_count; i++, j++) + { + p_srv_being_discovered->charateristics[i].characteristic = + p_char_disc_rsp_evt->chars[j]; + + p_srv_being_discovered->charateristics[i].cccd_handle = BLE_GATT_HANDLE_INVALID; + p_srv_being_discovered->charateristics[i].ext_prop_handle = BLE_GATT_HANDLE_INVALID; + p_srv_being_discovered->charateristics[i].user_desc_handle = BLE_GATT_HANDLE_INVALID; + p_srv_being_discovered->charateristics[i].report_ref_handle = BLE_GATT_HANDLE_INVALID; + } + + ble_gattc_char_t * p_last_known_char; + + p_last_known_char = &(p_srv_being_discovered->charateristics[i - 1].characteristic); + + // If no more characteristic discovery is required, or if the maximum number of supported + // characteristic per service has been reached, descriptor discovery will be performed. + if ( !is_char_discovery_reqd(p_db_discovery, p_last_known_char) + || (p_srv_being_discovered->char_count == BLE_GATT_DB_MAX_CHARS)) + { + perform_desc_discov = true; + } + else + { + // Update the current characteristic index. + p_db_discovery->curr_char_ind = p_srv_being_discovered->char_count; + + // Perform another round of characteristic discovery. + err_code = characteristics_discover(p_db_discovery, p_ble_gattc_evt->conn_handle); + + if (err_code != NRF_SUCCESS) + { + p_db_discovery->discovery_in_progress = false; + + discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle); + + m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; + m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle; + //m_evt_handler(&m_pending_user_evts[0].evt); + + return; + } + } + } + else + { + // The previous characteristic discovery resulted in no characteristics. + // descriptor discovery should be performed. + perform_desc_discov = true; + } + + if (perform_desc_discov) + { + bool raise_discov_complete; + + p_db_discovery->curr_char_ind = 0; + + err_code = descriptors_discover(p_db_discovery, + &raise_discov_complete, + p_ble_gattc_evt->conn_handle); + + if (err_code != NRF_SUCCESS) + { + p_db_discovery->discovery_in_progress = false; + + discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle); + + m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; + m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle; + //m_evt_handler(&m_pending_user_evts[0].evt); + + return; + } + if (raise_discov_complete) + { + // No more characteristics and descriptors need to be discovered. Discovery is complete. + // Send a discovery complete event to the user application. + NRF_LOG_DEBUG("Discovery of service with UUID 0x%x completed with success" + " on connection handle 0x%x.\r\n", + p_srv_being_discovered->srv_uuid.uuid, + p_ble_gattc_evt->conn_handle); + + discovery_complete_evt_trigger(p_db_discovery, true, p_ble_gattc_evt->conn_handle); + on_srv_disc_completion(p_db_discovery, p_ble_gattc_evt->conn_handle); + } + } +} + + +/**@brief Function for handling descriptor discovery response. + * + * @param[in] p_db_discovery Pointer to the DB Discovery structure. + * @param[in] p_ble_gattc_evt Pointer to the GATT Client event. + */ +static void on_descriptor_discovery_rsp(ble_db_discovery_t * const p_db_discovery, + const ble_gattc_evt_t * const p_ble_gattc_evt) +{ + const ble_gattc_evt_desc_disc_rsp_t * p_desc_disc_rsp_evt; + ble_gatt_db_srv_t * p_srv_being_discovered; + + if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle) + { + return; + } + + p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); + + p_desc_disc_rsp_evt = &(p_ble_gattc_evt->params.desc_disc_rsp); + + ble_gatt_db_char_t * p_char_being_discovered = + &(p_srv_being_discovered->charateristics[p_db_discovery->curr_char_ind]); + + if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS) + { + // The descriptor was found at the peer. + // Iterate through and collect CCCD, Extended Properties, + // User Description & Report Reference descriptor handles. + for (uint32_t i = 0; i < p_desc_disc_rsp_evt->count; i++) + { + switch (p_desc_disc_rsp_evt->descs[i].uuid.uuid) + { + case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG: + p_char_being_discovered->cccd_handle = + p_desc_disc_rsp_evt->descs[i].handle; + break; + + case BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP: + p_char_being_discovered->ext_prop_handle = + p_desc_disc_rsp_evt->descs[i].handle; + break; + + case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC: + p_char_being_discovered->user_desc_handle = + p_desc_disc_rsp_evt->descs[i].handle; + break; + + case BLE_UUID_REPORT_REF_DESCR: + p_char_being_discovered->report_ref_handle = + p_desc_disc_rsp_evt->descs[i].handle; + break; + } + + /* Break if we've found all the descriptors we are looking for. */ + if (p_char_being_discovered->cccd_handle != BLE_GATT_HANDLE_INVALID && + p_char_being_discovered->ext_prop_handle != BLE_GATT_HANDLE_INVALID && + p_char_being_discovered->user_desc_handle != BLE_GATT_HANDLE_INVALID && + p_char_being_discovered->report_ref_handle != BLE_GATT_HANDLE_INVALID) + { + break; + } + } + } + + bool raise_discov_complete = false; + + if ((p_db_discovery->curr_char_ind + 1) == p_srv_being_discovered->char_count) + { + // No more characteristics and descriptors need to be discovered. Discovery is complete. + // Send a discovery complete event to the user application. + + raise_discov_complete = true; + } + else + { + // Begin discovery of descriptors for the next characteristic. + uint32_t err_code; + + p_db_discovery->curr_char_ind++; + + err_code = descriptors_discover(p_db_discovery, + &raise_discov_complete, + p_ble_gattc_evt->conn_handle); + + if (err_code != NRF_SUCCESS) + { + p_db_discovery->discovery_in_progress = false; + + // Error with discovering the service. + // Indicate the error to the registered user application. + discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle); + + m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; + m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle; + + return; + } + } + + if (raise_discov_complete) + { + NRF_LOG_DEBUG("Discovery of service with UUID 0x%x completed with success" + " on connection handle 0x%x.\r\n", + p_srv_being_discovered->srv_uuid.uuid, + p_ble_gattc_evt->conn_handle); + + discovery_complete_evt_trigger(p_db_discovery, true, p_ble_gattc_evt->conn_handle); + on_srv_disc_completion(p_db_discovery, p_ble_gattc_evt->conn_handle); + } +} + + +uint32_t ble_db_discovery_init(const ble_db_discovery_evt_handler_t evt_handler) +{ + uint32_t err_code = NRF_SUCCESS; + VERIFY_PARAM_NOT_NULL(evt_handler); + + m_num_of_handlers_reg = 0; + m_initialized = true; + m_pending_usr_evt_index = 0; + m_evt_handler = evt_handler; + + return err_code; + +} + + +uint32_t ble_db_discovery_close() +{ + m_num_of_handlers_reg = 0; + m_initialized = false; + m_pending_usr_evt_index = 0; + + return NRF_SUCCESS; +} + + +uint32_t ble_db_discovery_evt_register(ble_uuid_t const * p_uuid) +{ + VERIFY_PARAM_NOT_NULL(p_uuid); + VERIFY_MODULE_INITIALIZED(); + + return registered_handler_set(p_uuid, m_evt_handler); +} + + +uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, + uint16_t conn_handle) +{ + VERIFY_PARAM_NOT_NULL(p_db_discovery); + VERIFY_MODULE_INITIALIZED(); + + if (m_num_of_handlers_reg == 0) + { + // No user modules were registered. There are no services to discover. + return NRF_ERROR_INVALID_STATE; + } + + if (p_db_discovery->discovery_in_progress) + { + return NRF_ERROR_BUSY; + } + + p_db_discovery->conn_handle = conn_handle; + ble_gatt_db_srv_t * p_srv_being_discovered; + + m_pending_usr_evt_index = 0; + + p_db_discovery->discoveries_count = 0; + p_db_discovery->curr_srv_ind = 0; + p_db_discovery->curr_char_ind = 0; + + p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); + + p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind]; + + NRF_LOG_DEBUG("Starting discovery of service with UUID 0x%x on connection handle 0x%x.\r\n", + p_srv_being_discovered->srv_uuid.uuid, conn_handle); + + uint32_t err_code; + + err_code = sd_ble_gattc_primary_services_discover(conn_handle, + SRV_DISC_START_HANDLE, + &(p_srv_being_discovered->srv_uuid)); + VERIFY_SUCCESS(err_code); + p_db_discovery->discovery_in_progress = true; + + return NRF_SUCCESS; +} + + +/**@brief Function for handling disconnected event. + * + * @param[in] p_db_discovery Pointer to the DB Discovery structure. + * @param[in] p_ble_gattc_evt Pointer to the GAP event. + */ +static void on_disconnected(ble_db_discovery_t * p_db_discovery, + ble_gap_evt_t const * p_evt) +{ + if (p_evt->conn_handle == p_db_discovery->conn_handle) + { + p_db_discovery->discovery_in_progress = false; + } +} + + +void ble_db_discovery_on_ble_evt(ble_db_discovery_t * p_db_discovery, + ble_evt_t const * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_db_discovery); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + VERIFY_MODULE_INITIALIZED_VOID(); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: + on_primary_srv_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt)); + break; + + case BLE_GATTC_EVT_CHAR_DISC_RSP: + on_characteristic_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt)); + break; + + case BLE_GATTC_EVT_DESC_DISC_RSP: + on_descriptor_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt)); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_db_discovery, &(p_ble_evt->evt.gap_evt)); + break; + + default: + break; + } +} +#endif // NRF_MODULE_ENABLED(BLE_DB_DISCOVERY) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_db_discovery/ble_db_discovery.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_db_discovery/ble_db_discovery.h new file mode 100644 index 0000000000000000000000000000000000000000..01f5032e310fbd8b540ad75b2d147b9e77a05d23 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_db_discovery/ble_db_discovery.h @@ -0,0 +1,216 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ble_db_discovery Database Discovery + * @{ + * @ingroup ble_sdk_lib + * @brief Database discovery module. + * + * @details This module contains the APIs and types exposed by the DB Discovery module. These APIs + * and types can be used by the application to perform discovery of a service and its + * characteristics at the peer server. This module can also be used to discover the + * desired services in multiple remote devices. + * + * @warning The maximum number of characteristics per service that can be discovered by this module + * is determined by the number of characteristics in the service structure defined in + * db_disc_config.h. If the peer has more than the supported number of characteristics, then + * the first found will be discovered and any further characteristics will be ignored. Only the + * following descriptors will be searched for at the peer: Client Characteristic Configuration, + * Characteristic Extended Properties, Characteristic User Description, and Report Reference. + * + * @note Presently only one instance of a Primary Service can be discovered by this module. If + * there are multiple instances of the service at the peer, only the first instance + * of it at the peer is fetched and returned to the application. + * + * @note The application must propagate BLE stack events to this module by calling + * ble_db_discovery_on_ble_evt(). + * + */ + +#ifndef BLE_DB_DISCOVERY_H__ +#define BLE_DB_DISCOVERY_H__ + +#include +#include "nrf_error.h" +#include "ble.h" +#include "ble_gattc.h" +#include "ble_srv_common.h" +#include "ble_gatt_db.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define BLE_DB_DISCOVERY_MAX_SRV 6 /**< Maximum number of services supported by this module. This also indicates the maximum number of users allowed to be registered to this module. (one user per service). */ + + +/**@brief Type of the DB Discovery event. + */ +typedef enum +{ + BLE_DB_DISCOVERY_COMPLETE, /**< Event indicating that the GATT Database discovery is complete. */ + BLE_DB_DISCOVERY_ERROR, /**< Event indicating that an internal error has occurred in the DB Discovery module. This could typically be because of the SoftDevice API returning an error code during the DB discover.*/ + BLE_DB_DISCOVERY_SRV_NOT_FOUND, /**< Event indicating that the service was not found at the peer.*/ + BLE_DB_DISCOVERY_AVAILABLE /**< Event indicating that the DB discovery module is available.*/ +} ble_db_discovery_evt_type_t; + + + +/**@brief Structure for holding the information related to the GATT database at the server. + * + * @details This module identifies a remote database. Use one instance of this structure per + * connection. + * + * @warning This structure must be zero-initialized. + */ +typedef struct +{ + ble_gatt_db_srv_t services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered. This is intended for internal use during service discovery.*/ + uint8_t srv_count; /**< Number of services at the peers GATT database.*/ + uint8_t curr_char_ind; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/ + uint8_t curr_srv_ind; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/ + bool discovery_in_progress; /**< Variable to indicate if there is a service discovery in progress. */ + uint8_t discoveries_count; /**< Number of service discoveries made, both successful and unsuccessful. */ + uint16_t conn_handle; /**< Connection handle on which the discovery is started*/ +} ble_db_discovery_t; + + +/**@brief Structure containing the event from the DB discovery module to the application. + */ +typedef struct +{ + ble_db_discovery_evt_type_t evt_type; /**< Type of event. */ + uint16_t conn_handle; /**< Handle of the connection for which this event has occurred. */ + union + { + ble_gatt_db_srv_t discovered_db; /**< Structure containing the information about the GATT Database at the server. This will be filled when the event type is @ref BLE_DB_DISCOVERY_COMPLETE.*/ + uint32_t err_code; /**< nRF Error code indicating the type of error which occurred in the DB Discovery module. This will be filled when the event type is @ref BLE_DB_DISCOVERY_ERROR. */ + } params; +} ble_db_discovery_evt_t; + + +/**@brief DB Discovery event handler type. */ +typedef void (* ble_db_discovery_evt_handler_t)(ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for initializing the DB Discovery module. + * + * @param[in] evt_handler Event handler to be called by the DB discovery module when any event + * related to discovery of the registered service occurs. + * + * @retval NRF_SUCCESS On successful initialization. + * @retval NRF_ERROR_NULL If the handler was NULL. + */ +uint32_t ble_db_discovery_init(ble_db_discovery_evt_handler_t evt_handler); + + +/**@brief Function for closing the DB Discovery module. + * + * @details This function will clear up any internal variables and states maintained by the + * module. To re-use the module after calling this function, the function @ref + * ble_db_discovery_init must be called again. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t ble_db_discovery_close(void); + + +/**@brief Function for registering with the DB Discovery module. + * + * @details The application can use this function to inform which service it is interested in + * discovering at the server. + * + * @param[in] p_uuid Pointer to the UUID of the service to be discovered at the server. + * + * @note The total number of services that can be discovered by this module is @ref + * BLE_DB_DISCOVERY_MAX_SRV. This effectively means that the maximum number of + * registrations possible is equal to the @ref BLE_DB_DISCOVERY_MAX_SRV. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL When a NULL pointer is passed as input. + * @retval NRF_ERROR_INVALID_STATE If this function is called without calling the + * @ref ble_db_discovery_init. + * @retval NRF_ERROR_NO_MEM The maximum number of registrations allowed by this module + * has been reached. + */ +uint32_t ble_db_discovery_evt_register(const ble_uuid_t * const p_uuid); + + +/**@brief Function for starting the discovery of the GATT database at the server. + * + * @warning p_db_discovery structure must be zero-initialized. + * + * @param[out] p_db_discovery Pointer to the DB Discovery structure. + * @param[in] conn_handle The handle of the connection for which the discovery should be + * started. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL When a NULL pointer is passed as input. + * @retval NRF_ERROR_INVALID_STATE If this function is called without calling the + * @ref ble_db_discovery_init, or without calling + * @ref ble_db_discovery_evt_register. + * @retval NRF_ERROR_BUSY If a discovery is already in progress for the current + * connection. + * + * @return This API propagates the error code returned by the + * SoftDevice API @ref sd_ble_gattc_primary_services_discover. + */ +uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, + uint16_t conn_handle); + + +/**@brief Function for handling the Application's BLE Stack events. + * + * @param[in,out] p_db_discovery Pointer to the DB Discovery structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +void ble_db_discovery_on_ble_evt(ble_db_discovery_t * const p_db_discovery, + const ble_evt_t * const p_ble_evt); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_DB_DISCOVERY_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm.c new file mode 100644 index 0000000000000000000000000000000000000000..6e9f2725a67d2a90fdb0857aaf21728d5b8340b3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm.c @@ -0,0 +1,663 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_DTM) +#include "ble_dtm.h" +#include "ble_dtm_hw.h" +#include +#include +#include "nrf.h" + +#define DTM_HEADER_OFFSET 0 /**< Index where the header of the pdu is located. */ +#define DTM_HEADER_SIZE 2 /**< Size of PDU header. */ +#define DTM_PAYLOAD_MAX_SIZE 255 /**< Maximum payload size allowed during dtm execution. */ +#define DTM_LENGTH_OFFSET (DTM_HEADER_OFFSET + 1) /**< Index where the length of the payload is encoded. */ +#define DTM_PDU_MAX_MEMORY_SIZE (DTM_HEADER_SIZE + DTM_PAYLOAD_MAX_SIZE) /**< Maximum PDU size allowed during dtm execution. */ +#define DTM_ON_AIR_OVERHEAD_SIZE 10 /**< Size of the packet on air without the payload (preamble + sync word + type + RFU + length + CRC). */ + +#define RX_MODE true /**< Constant defining RX mode for radio during dtm test. */ +#define TX_MODE false /**< Constant defining TX mode for radio during dtm test. */ + +#define PHYS_CH_MAX 39 /**< Maximum number of valid channels in BLE. */ + +// Values that for now are "constants" - they could be configured by a function setting them, +// but most of these are set by the BLE DTM standard, so changing them is not relevant. +#define RFPHY_TEST_0X0F_REF_PATTERN 0x0f /**< RF-PHY test packet patterns, for the repeated octet packets. */ +#define RFPHY_TEST_0X55_REF_PATTERN 0x55 /**< RF-PHY test packet patterns, for the repeated octet packets. */ + +#define PRBS9_CONTENT {0xFF, 0xC1, 0xFB, 0xE8, 0x4C, 0x90, 0x72, 0x8B, \ + 0xE7, 0xB3, 0x51, 0x89, 0x63, 0xAB, 0x23, 0x23, \ + 0x02, 0x84, 0x18, 0x72, 0xAA, 0x61, 0x2F, 0x3B, \ + 0x51, 0xA8, 0xE5, 0x37, 0x49, 0xFB, 0xC9, 0xCA, \ + 0x0C, 0x18, 0x53, 0x2C, 0xFD, 0x45, 0xE3, 0x9A, \ + 0xE6, 0xF1, 0x5D, 0xB0, 0xB6, 0x1B, 0xB4, 0xBE, \ + 0x2A, 0x50, 0xEA, 0xE9, 0x0E, 0x9C, 0x4B, 0x5E, \ + 0x57, 0x24, 0xCC, 0xA1, 0xB7, 0x59, 0xB8, 0x87, \ + 0xFF, 0xE0, 0x7D, 0x74, 0x26, 0x48, 0xB9, 0xC5, \ + 0xF3, 0xD9, 0xA8, 0xC4, 0xB1, 0xD5, 0x91, 0x11, \ + 0x01, 0x42, 0x0C, 0x39, 0xD5, 0xB0, 0x97, 0x9D, \ + 0x28, 0xD4, 0xF2, 0x9B, 0xA4, 0xFD, 0x64, 0x65, \ + 0x06, 0x8C, 0x29, 0x96, 0xFE, 0xA2, 0x71, 0x4D, \ + 0xF3, 0xF8, 0x2E, 0x58, 0xDB, 0x0D, 0x5A, 0x5F, \ + 0x15, 0x28, 0xF5, 0x74, 0x07, 0xCE, 0x25, 0xAF, \ + 0x2B, 0x12, 0xE6, 0xD0, 0xDB, 0x2C, 0xDC, 0xC3, \ + 0x7F, 0xF0, 0x3E, 0x3A, 0x13, 0xA4, 0xDC, 0xE2, \ + 0xF9, 0x6C, 0x54, 0xE2, 0xD8, 0xEA, 0xC8, 0x88, \ + 0x00, 0x21, 0x86, 0x9C, 0x6A, 0xD8, 0xCB, 0x4E, \ + 0x14, 0x6A, 0xF9, 0x4D, 0xD2, 0x7E, 0xB2, 0x32, \ + 0x03, 0xC6, 0x14, 0x4B, 0x7F, 0xD1, 0xB8, 0xA6, \ + 0x79, 0x7C, 0x17, 0xAC, 0xED, 0x06, 0xAD, 0xAF, \ + 0x0A, 0x94, 0x7A, 0xBA, 0x03, 0xE7, 0x92, 0xD7, \ + 0x15, 0x09, 0x73, 0xE8, 0x6D, 0x16, 0xEE, 0xE1, \ + 0x3F, 0x78, 0x1F, 0x9D, 0x09, 0x52, 0x6E, 0xF1, \ + 0x7C, 0x36, 0x2A, 0x71, 0x6C, 0x75, 0x64, 0x44, \ + 0x80, 0x10, 0x43, 0x4E, 0x35, 0xEC, 0x65, 0x27, \ + 0x0A, 0xB5, 0xFC, 0x26, 0x69, 0x3F, 0x59, 0x99, \ + 0x01, 0x63, 0x8A, 0xA5, 0xBF, 0x68, 0x5C, 0xD3, \ + 0x3C, 0xBE, 0x0B, 0xD6, 0x76, 0x83, 0xD6, 0x57, \ + 0x05, 0x4A, 0x3D, 0xDD, 0x81, 0x73, 0xC9, 0xEB, \ + 0x8A, 0x84, 0x39, 0xF4, 0x36, 0x0B, 0xF7} /**< The PRBS9 sequence used as packet payload. + The bytes in the sequence is in the right order, but the bits of each byte in the array is reverse. + of that found by running the PRBS9 algorithm. This is because of the endianess of the nRF5 radio. */ + +/**@brief Structure holding the PDU used for transmitting/receiving a PDU. + */ +typedef struct +{ + uint8_t content[DTM_HEADER_SIZE + DTM_PAYLOAD_MAX_SIZE]; /**< PDU packet content. */ +} pdu_type_t; + +/**@brief States used for the DTM test implementation. + */ +typedef enum +{ + STATE_UNINITIALIZED, /**< The DTM is uninitialized. */ + STATE_IDLE, /**< State when system has just initialized, or current test has completed. */ + STATE_TRANSMITTER_TEST, /**< State used when a DTM Transmission test is running. */ + STATE_CARRIER_TEST, /**< State used when a DTM Carrier test is running (Vendor specific test). */ + STATE_RECEIVER_TEST /**< State used when a DTM Receive test is running. */ +} state_t; + +// Internal variables set as side effects of commands or events. +static state_t m_state = STATE_UNINITIALIZED; /**< Current machine state. */ +static uint16_t m_rx_pkt_count; /**< Number of valid packets received. */ +static pdu_type_t m_pdu; /**< PDU to be sent. */ +static uint16_t m_event; /**< current command status - initially "ok", may be set if error detected, or to packet count. */ +static bool m_new_event; /**< Command has been processed - number of not yet reported event bytes. */ +static uint32_t m_packet_length; /**< Payload length of transmitted PDU, bits 2:7 of 16-bit dtm command. */ +static dtm_pkt_type_t m_packet_type; /**< Bits 0..1 of 16-bit transmit command, or 0xFFFFFFFF. */ +static dtm_freq_t m_phys_ch; /**< 0..39 physical channel number (base 2402 MHz, Interval 2 MHz), bits 8:13 of 16-bit dtm command. */ +static uint32_t m_current_time = 0; /**< Counter for interrupts from timer to ensure that the 2 bytes forming a DTM command are received within the time window. */ + +// Nordic specific configuration values (not defined by BLE standard). +// Definition of initial values found in ble_dtm.h +static int32_t m_tx_power = DEFAULT_TX_POWER; /**< TX power for transmission test, default to maximum value (+4 dBm). */ +static NRF_TIMER_Type * mp_timer = DEFAULT_TIMER; /**< Timer to be used. */ +static IRQn_Type m_timer_irq = DEFAULT_TIMER_IRQn; /**< which interrupt line to clear on every timeout */ + +static uint8_t const m_prbs_content[] = PRBS9_CONTENT; /**< Pseudo-random bit sequence defined by the BLE standard. */ +static uint8_t m_packetHeaderLFlen = 8; /**< Length of length field in packet Header (in bits). */ +static uint8_t m_packetHeaderS0len = 1; /**< Length of S0 field in packet Header (in bytes). */ +static uint8_t m_packetHeaderS1len = 0; /**< Length of S1 field in packet Header (in bits). */ +static uint8_t m_crcConfSkipAddr = 1; /**< Leave packet address field out of CRC calculation. */ +static uint8_t m_static_length = 0; /**< Number of bytes sent in addition to the var.length payload. */ +static uint32_t m_balen = 3; /**< Base address length in bytes. */ +static uint32_t m_endian = RADIO_PCNF1_ENDIAN_Little; /**< On air endianess of packet, this applies to the S0, LENGTH, S1 and the PAYLOAD fields. */ +static uint32_t m_whitening = RADIO_PCNF1_WHITEEN_Disabled; /**< Whitening disabled. */ +static uint8_t m_crcLength = RADIO_CRCCNF_LEN_Three; /**< CRC Length (in bytes). */ +static uint32_t m_address = 0x71764129; /**< Address. */ +static uint32_t m_crc_poly = 0x0000065B; /**< CRC polynomial. */ +static uint32_t m_crc_init = 0x00555555; /**< Initial value for CRC calculation. */ +static uint8_t m_radio_mode = RADIO_MODE_MODE_Ble_1Mbit; /**< nRF51 specific radio mode value. */ +static uint32_t m_txIntervaluS = 2500; /**< Time between start of Tx packets (in uS). */ + + +/**@brief Function for verifying that a received PDU has the expected structure and content. + */ +static bool check_pdu(void) +{ + uint8_t k; // Byte pointer for running through PDU payload + uint8_t pattern; // Repeating octet value in payload + dtm_pkt_type_t pdu_packet_type; // Note: PDU packet type is a 4-bit field in HCI, but 2 bits in BLE DTM + uint32_t length = 0; + + pdu_packet_type = (dtm_pkt_type_t)(m_pdu.content[DTM_HEADER_OFFSET] & 0x0F); + length = m_pdu.content[DTM_LENGTH_OFFSET]; + + if ((pdu_packet_type > (dtm_pkt_type_t)PACKET_TYPE_MAX) || (length > DTM_PAYLOAD_MAX_SIZE)) + { + return false; + } + + if (pdu_packet_type == DTM_PKT_PRBS9) + { + // Payload does not consist of one repeated octet; must compare ir with entire block into + return (memcmp(m_pdu.content + DTM_HEADER_SIZE, m_prbs_content, length) == 0); + } + + if (pdu_packet_type == DTM_PKT_0X0F) + { + pattern = RFPHY_TEST_0X0F_REF_PATTERN; + } + else + { + pattern = RFPHY_TEST_0X55_REF_PATTERN; + } + + for (k = 0; k < length; k++) + { + // Check repeated pattern filling the PDU payload + if (m_pdu.content[k + 2] != pattern) + { + return false; + } + } + return true; +} + + +/**@brief Function for turning off the radio after a test. + * Also called after test done, to be ready for next test. + */ +static void radio_reset(void) +{ + NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Msk | PPI_CHENCLR_CH1_Msk; + + NRF_RADIO->SHORTS = 0; + NRF_RADIO->EVENTS_DISABLED = 0; + NRF_RADIO->TASKS_DISABLE = 1; + + while (NRF_RADIO->EVENTS_DISABLED == 0) + { + // Do nothing + } + + NRF_RADIO->EVENTS_DISABLED = 0; + NRF_RADIO->TASKS_RXEN = 0; + NRF_RADIO->TASKS_TXEN = 0; + + m_rx_pkt_count = 0; +} + + +/**@brief Function for initializing the radio for DTM. + */ +static uint32_t radio_init(void) +{ + if(dtm_radio_validate(m_tx_power, m_radio_mode) != DTM_SUCCESS) + { + return DTM_ERROR_ILLEGAL_CONFIGURATION; + } + + // Turn off radio before configuring it + radio_reset(); + + NRF_RADIO->TXPOWER = m_tx_power; + NRF_RADIO->MODE = m_radio_mode << RADIO_MODE_MODE_Pos; + + // Set the access address, address0/prefix0 used for both Rx and Tx address + NRF_RADIO->PREFIX0 &= ~RADIO_PREFIX0_AP0_Msk; + NRF_RADIO->PREFIX0 |= (m_address >> 24) & RADIO_PREFIX0_AP0_Msk; + NRF_RADIO->BASE0 = m_address << 8; + NRF_RADIO->RXADDRESSES = RADIO_RXADDRESSES_ADDR0_Enabled << RADIO_RXADDRESSES_ADDR0_Pos; + NRF_RADIO->TXADDRESS = (0x00 << RADIO_TXADDRESS_TXADDRESS_Pos) & RADIO_TXADDRESS_TXADDRESS_Msk; + + // Configure CRC calculation + NRF_RADIO->CRCCNF = (m_crcConfSkipAddr << RADIO_CRCCNF_SKIP_ADDR_Pos) | + (m_crcLength << RADIO_CRCCNF_LEN_Pos); + + NRF_RADIO->PCNF0 = (m_packetHeaderS1len << RADIO_PCNF0_S1LEN_Pos) | + (m_packetHeaderS0len << RADIO_PCNF0_S0LEN_Pos) | + (m_packetHeaderLFlen << RADIO_PCNF0_LFLEN_Pos); + + NRF_RADIO->PCNF1 = (m_whitening << RADIO_PCNF1_WHITEEN_Pos) | + (m_endian << RADIO_PCNF1_ENDIAN_Pos) | + (m_balen << RADIO_PCNF1_BALEN_Pos) | + (m_static_length << RADIO_PCNF1_STATLEN_Pos) | + (DTM_PAYLOAD_MAX_SIZE << RADIO_PCNF1_MAXLEN_Pos); + + return DTM_SUCCESS; +} + + +/**@brief Function for preparing the radio. At start of each test: Turn off RF, clear interrupt flags of RF, initialize the radio + * at given RF channel. + * + *@param[in] rx boolean indicating if radio should be prepared in rx mode (true) or tx mode. + */ +static void radio_prepare(bool rx) +{ + dtm_turn_off_test(); + NRF_RADIO->CRCPOLY = m_crc_poly; + NRF_RADIO->CRCINIT = m_crc_init; + NRF_RADIO->FREQUENCY = (m_phys_ch << 1) + 2; // Actual frequency (MHz): 2400 + register value + NRF_RADIO->PACKETPTR = (uint32_t)&m_pdu; // Setting packet pointer will start the radio + NRF_RADIO->EVENTS_READY = 0; + NRF_RADIO->SHORTS = (1 << RADIO_SHORTS_READY_START_Pos) | // Shortcut between READY event and START task + (1 << RADIO_SHORTS_END_DISABLE_Pos); // Shortcut between END event and DISABLE task + + if (rx) + { + NRF_RADIO->EVENTS_END = 0; + NRF_RADIO->TASKS_RXEN = 1; // shorts will start radio in RX mode when it is ready + } + else // tx + { + NRF_RADIO->TXPOWER = m_tx_power; + } +} + + +/**@brief Function for terminating the ongoing test (if any) and closing down the radio. + */ +static void dtm_test_done(void) +{ + dtm_turn_off_test(); + NRF_PPI->CHENCLR = 0x01; + NRF_PPI->CH[0].EEP = 0; // Break connection from timer to radio to stop transmit loop + NRF_PPI->CH[0].TEP = 0; + + radio_reset(); + m_state = STATE_IDLE; +} + + +/**@brief Function for configuring the timer for 625us cycle time. + */ +static uint32_t timer_init(void) +{ + // Use 16MHz from external crystal + // This could be customized for RC/Xtal, or even to use a 32 kHz crystal + NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; + NRF_CLOCK->TASKS_HFCLKSTART = 1; + + while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) + { + // Do nothing while waiting for the clock to start + } + + mp_timer->TASKS_STOP = 1; // Stop timer, if it was running + mp_timer->TASKS_CLEAR = 1; + mp_timer->MODE = TIMER_MODE_MODE_Timer; // Timer mode (not counter) + mp_timer->EVENTS_COMPARE[0] = 0; // clean up possible old events + mp_timer->EVENTS_COMPARE[1] = 0; + mp_timer->EVENTS_COMPARE[2] = 0; + mp_timer->EVENTS_COMPARE[3] = 0; + + // Timer is polled, but enable the compare0 interrupt in order to wakeup from CPU sleep + mp_timer->INTENSET = TIMER_INTENSET_COMPARE0_Msk; + mp_timer->SHORTS = 1 << TIMER_SHORTS_COMPARE0_CLEAR_Pos; // Clear the count every time timer reaches the CCREG0 count + mp_timer->PRESCALER = 4; // Input clock is 16MHz, timer clock = 2 ^ prescale -> interval 1us + mp_timer->CC[0] = m_txIntervaluS; // 625uS with 1MHz clock to the timer + mp_timer->CC[1] = UART_POLL_CYCLE; // Depends on the baud rate of the UART. Default baud rate of 19200 will result in a 260uS time with 1MHz clock to the timer + mp_timer->TASKS_START = 1; // Start the timer - it will be running continuously + m_current_time = 0; + return DTM_SUCCESS; +} + + +/**@brief Function for handling vendor specific commands. + * Used when packet type is set to Vendor specific. + * The length field is used for encoding vendor specific command. + * The frequency field is used for encoding vendor specific options to the command. + * + * @param[in] vendor_cmd Vendor specific command to be executed. + * @param[in] vendor_option Vendor specific option to the vendor command. + * + * @return DTM_SUCCESS or one of the DTM_ERROR_ values + */ +static uint32_t dtm_vendor_specific_pkt(uint32_t vendor_cmd, dtm_freq_t vendor_option) +{ + switch (vendor_cmd) + { + // nRFgo Studio uses CARRIER_TEST_STUDIO to indicate a continuous carrier without + // a modulated signal. + case CARRIER_TEST: + case CARRIER_TEST_STUDIO: + // Not a packet type, but used to indicate that a continuous carrier signal + // should be transmitted by the radio. + radio_prepare(TX_MODE); + + dtm_constant_carrier(); + + // Shortcut between READY event and START task + NRF_RADIO->SHORTS = 1 << RADIO_SHORTS_READY_START_Pos; + + // Shortcut will start radio in Tx mode when it is ready + NRF_RADIO->TASKS_TXEN = 1; + m_state = STATE_CARRIER_TEST; + break; + + case SET_TX_POWER: + if (!dtm_set_txpower(vendor_option)) + { + return DTM_ERROR_ILLEGAL_CONFIGURATION; + } + break; + + case SELECT_TIMER: + if (!dtm_set_timer(vendor_option)) + { + return DTM_ERROR_ILLEGAL_CONFIGURATION; + } + break; + } + // Event code is unchanged, successful + return DTM_SUCCESS; +} + + +uint32_t dtm_init(void) +{ + if ((timer_init() != DTM_SUCCESS) || (radio_init() != DTM_SUCCESS)) + { + return DTM_ERROR_ILLEGAL_CONFIGURATION; + } + m_new_event = false; + m_state = STATE_IDLE; + m_packet_length = 0; + + // Enable wake-up on event + SCB->SCR |= SCB_SCR_SEVONPEND_Msk; + + return DTM_SUCCESS; +} + + +uint32_t dtm_wait(void) +{ + // Enable wake-up on event + SCB->SCR |= SCB_SCR_SEVONPEND_Msk; + + for (;;) + { + // Event may be the reception of a packet - + // handle radio first, to give it highest priority: + if (NRF_RADIO->EVENTS_END != 0) + { + NRF_RADIO->EVENTS_END = 0; + NVIC_ClearPendingIRQ(RADIO_IRQn); + + if (m_state == STATE_RECEIVER_TEST) + { + NRF_RADIO->TASKS_RXEN = 1; + if ((NRF_RADIO->CRCSTATUS == 1) && check_pdu()) + { + // Count the number of successfully received packets + m_rx_pkt_count++; + } + // Note that failing packets are simply ignored (CRC or contents error). + + // Zero fill all pdu fields to avoid stray data + memset(&m_pdu, 0, DTM_PDU_MAX_MEMORY_SIZE); + } + // If no RECEIVER_TEST is running, ignore incoming packets (but do clear IRQ!) + } + + // Check for timeouts: + if (mp_timer->EVENTS_COMPARE[0] != 0) + { + mp_timer->EVENTS_COMPARE[0] = 0; + } + else if (mp_timer->EVENTS_COMPARE[1] != 0) + { + // Reset timeout event flag for next iteration. + mp_timer->EVENTS_COMPARE[1] = 0; + NVIC_ClearPendingIRQ(m_timer_irq); + return ++m_current_time; + } + + // Other events: No processing + } +} + + +uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t payload) +{ + // Save specified packet in static variable for tx/rx functions to use. + // Note that BLE conformance testers always use full length packets. + m_packet_length = (m_packet_length & 0xC0) | ((uint8_t)length & 0x3F); + m_packet_type = payload; + m_phys_ch = freq; + + // Clean out any non-retrieved event that might linger from an earlier test + m_new_event = true; + + // Set default event; any error will set it to LE_TEST_STATUS_EVENT_ERROR + m_event = LE_TEST_STATUS_EVENT_SUCCESS; + + if (m_state == STATE_UNINITIALIZED) + { + // Application has not explicitly initialized DTM, + return DTM_ERROR_UNINITIALIZED; + } + + if (cmd == LE_RESET) + { + // Note that timer will continue running after a reset + dtm_test_done(); + if (freq == 0x01) + { + m_packet_length = length << 6; + } + else + { + m_packet_length = 0; + } + return DTM_SUCCESS; + } + + if (cmd == LE_TEST_END) + { + if (m_state == STATE_IDLE) + { + // Sequencing error - only rx or tx test may be ended! + m_event = LE_TEST_STATUS_EVENT_ERROR; + return DTM_ERROR_INVALID_STATE; + } + m_event = LE_PACKET_REPORTING_EVENT | m_rx_pkt_count; + dtm_test_done(); + return DTM_SUCCESS; + } + + if (m_state != STATE_IDLE) + { + // Sequencing error - only TEST_END/RESET are legal while test is running + // Note: State is unchanged; ongoing test not affected + m_event = LE_TEST_STATUS_EVENT_ERROR; + return DTM_ERROR_INVALID_STATE; + } + + // Check for illegal values of m_phys_ch. Skip the check if the packet is vendor spesific. + if (payload != DTM_PKT_VENDORSPECIFIC && m_phys_ch > PHYS_CH_MAX) + { + // Parameter error + // Note: State is unchanged; ongoing test not affected + m_event = LE_TEST_STATUS_EVENT_ERROR; + return DTM_ERROR_ILLEGAL_CHANNEL; + } + + m_rx_pkt_count = 0; + + if (cmd == LE_RECEIVER_TEST) + { + // Zero fill all pdu fields to avoid stray data from earlier test run + memset(&m_pdu, 0, DTM_PDU_MAX_MEMORY_SIZE); + radio_prepare(RX_MODE); // Reinitialize "everything"; RF interrupts OFF + m_state = STATE_RECEIVER_TEST; + return DTM_SUCCESS; + } + + if (cmd == LE_TRANSMITTER_TEST) + { + // Check for illegal values of m_packet_length. Skip the check if the packet is vendor spesific. + if (payload != DTM_PKT_VENDORSPECIFIC && m_packet_length > DTM_PAYLOAD_MAX_SIZE) + { + // Parameter error + m_event = LE_TEST_STATUS_EVENT_ERROR; + return DTM_ERROR_ILLEGAL_LENGTH; + } + + // Note that PDU uses 4 bits even though BLE DTM uses only 2 (the HCI SDU uses all 4) + m_pdu.content[DTM_HEADER_OFFSET] = ((uint8_t)m_packet_type & 0x0F); + m_pdu.content[DTM_LENGTH_OFFSET] = m_packet_length; + + switch (m_packet_type) + { + case DTM_PKT_PRBS9: + // Non-repeated, must copy entire pattern to PDU + memcpy(m_pdu.content + DTM_HEADER_SIZE, m_prbs_content, m_packet_length); + break; + + case DTM_PKT_0X0F: + // Bit pattern 00001111 repeated + memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0X0F_REF_PATTERN, m_packet_length); + break; + + case DTM_PKT_0X55: + // Bit pattern 01010101 repeated + memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0X55_REF_PATTERN, m_packet_length); + break; + + case DTM_PKT_VENDORSPECIFIC: + // The length field is for indicating the vendor specific command to execute. + // The frequency field is used for vendor specific options to the command. + return dtm_vendor_specific_pkt(length, freq); + + default: + // Parameter error + m_event = LE_TEST_STATUS_EVENT_ERROR; + return DTM_ERROR_ILLEGAL_CONFIGURATION; + } + + // Initialize CRC value, set channel: + radio_prepare(TX_MODE); + // Set the timer to the correct period. The delay between each packet is described in the + // Bluetooth Core Spsification version 4.2 Vol. 6 Part F Section 4.1.6. + if ((m_packet_length + DTM_ON_AIR_OVERHEAD_SIZE ) * 8 <= 376) + { + mp_timer->CC[0] = 625; // 625uS with 1MHz clock to the timer + } + else if ((m_packet_length + DTM_ON_AIR_OVERHEAD_SIZE ) * 8 <= 1000) + { + mp_timer->CC[0] = 1250; // 625uS with 1MHz clock to the timer + } + else if ((m_packet_length + DTM_ON_AIR_OVERHEAD_SIZE ) * 8 <= 1624) + { + mp_timer->CC[0] = 1875; // 625uS with 1MHz clock to the timer + } + else + { + mp_timer->CC[0] = 2500; // 625uS with 1MHz clock to the timer + } + + // Configure PPI so that timer will activate radio every 625 us + NRF_PPI->CH[0].EEP = (uint32_t)&mp_timer->EVENTS_COMPARE[0]; + NRF_PPI->CH[0].TEP = (uint32_t)&NRF_RADIO->TASKS_TXEN; + NRF_PPI->CHENSET = 0x01; + m_state = STATE_TRANSMITTER_TEST; + } + return DTM_SUCCESS; +} + + +bool dtm_event_get(dtm_event_t *p_dtm_event) +{ + bool was_new = m_new_event; + // mark the current event as retrieved + m_new_event = false; + *p_dtm_event = m_event; + // return value indicates whether this value was already retrieved. + return was_new; +} + + +// ================================================================================================= +// Configuration functions (only for parameters not definitely determined by the BLE DTM standard). +// These functions return true if successful, false if value could not be set + + +/**@brief Function for configuring the output power for transmitter test. + This function may be called directly, or through dtm_cmd() specifying + DTM_PKT_VENDORSPECIFIC as payload, SET_TX_POWER as length, and the dBm value as frequency. + */ +bool dtm_set_txpower(uint32_t new_tx_power) +{ + // radio->TXPOWER register is 32 bits, low octet a signed value, upper 24 bits zeroed + int8_t new_power8 = (int8_t)(new_tx_power & 0xFF); + + // The two most significant bits are not sent in the 6 bit field of the DTM command. + // These two bits are 1's if and only if the tx_power is a negative number. + // All valid negative values have the fourth most significant bit as 1. + // All valid positive values have the fourth most significant bit as 0. + // By checking this bit, the two most significant bits can be determined. + new_power8 = (new_power8 & 0x30) != 0 ? (new_power8 | 0xC0) : new_power8; + + if (m_state > STATE_IDLE) + { + // radio must be idle to change the tx power + return false; + } + + m_tx_power = new_power8; + + return true; +} + + +/**@brief Function for selecting a timer resource. + * This function may be called directly, or through dtm_cmd() specifying + * DTM_PKT_VENDORSPECIFIC as payload, SELECT_TIMER as length, and the timer as freq + * + * @param[in] new_timer Timer id for the timer to use: 0, 1, or 2. + * + * @return true if the timer was successfully changed, false otherwise. + */ +bool dtm_set_timer(uint32_t new_timer) +{ + if (m_state > STATE_IDLE) + { + return false; + } + return dtm_hw_set_timer(&mp_timer, &m_timer_irq, new_timer); +} + +/// @} +#endif // NRF_MODULE_ENABLED(BLE_DTM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm.h new file mode 100644 index 0000000000000000000000000000000000000000..8cadb95d378cc6cdcbfb553a8cdfdf51fdd002cb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm.h @@ -0,0 +1,216 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_dtm DTM - Direct Test Mode + * @{ + * @ingroup ble_sdk_lib + * @brief Module for testing RF/PHY using DTM commands. + */ + +#ifndef BLE_DTM_H__ +#define BLE_DTM_H__ + +#include +#include +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Configuration parameters. */ +#define DTM_BITRATE UART_BAUDRATE_BAUDRATE_Baud19200/**< Serial bitrate on the UART */ +#define DEFAULT_TX_POWER RADIO_TXPOWER_TXPOWER_0dBm /**< Default Transmission power using in the DTM module. */ +#define DEFAULT_TIMER NRF_TIMER0 /**< Default timer used for timing. */ +#define DEFAULT_TIMER_IRQn TIMER0_IRQn /**< IRQ used for timer. NOTE: MUST correspond to DEFAULT_TIMER. */ + +/**@brief BLE DTM command codes. */ +typedef uint32_t dtm_cmd_t; /**< DTM command type. */ + +#define LE_RESET 0 /**< DTM command: Reset device. */ +#define LE_RECEIVER_TEST 1 /**< DTM command: Start receive test. */ +#define LE_TRANSMITTER_TEST 2 /**< DTM command: Start transmission test. */ +#define LE_TEST_END 3 /**< DTM command: End test and send packet report. */ + +// Configuration options used as parameter 2 +// when cmd == LE_TRANSMITTER_TEST and payload == DTM_PKT_VENDORSPECIFIC +// Configuration value, if any, is supplied in parameter 3 + +#define CARRIER_TEST 0 /**< Length=0 indicates a constant, unmodulated carrier until LE_TEST_END or LE_RESET */ +#define CARRIER_TEST_STUDIO 1 /**< nRFgo Studio uses value 1 in length field, to indicate a constant, unmodulated carrier until LE_TEST_END or LE_RESET */ +#define SET_TX_POWER 2 /**< Set transmission power, value -40..+4 dBm in steps of 4 */ +#define SELECT_TIMER 3 /**< Select on of the 16 MHz timers 0, 1 or 2 */ + +#define LE_PACKET_REPORTING_EVENT 0x8000 /**< DTM Packet reporting event, returned by the device to the tester. */ +#define LE_TEST_STATUS_EVENT_SUCCESS 0x0000 /**< DTM Status event, indicating success. */ +#define LE_TEST_STATUS_EVENT_ERROR 0x0001 /**< DTM Status event, indicating an error. */ + +#define DTM_PKT_PRBS9 0x00 /**< Bit pattern PRBS9. */ +#define DTM_PKT_0X0F 0x01 /**< Bit pattern 11110000 (LSB is the leftmost bit). */ +#define DTM_PKT_0X55 0x02 /**< Bit pattern 10101010 (LSB is the leftmost bit). */ +#define DTM_PKT_VENDORSPECIFIC 0xFFFFFFFF /**< Vendor specific. Nordic: Continuous carrier test, or configuration. */ + +/**@brief Return codes from dtm_cmd(). */ +#define DTM_SUCCESS 0x00 /**< Indicate that the DTM function completed with success. */ +#define DTM_ERROR_ILLEGAL_CHANNEL 0x01 /**< Physical channel number must be in the range 0..39. */ +#define DTM_ERROR_INVALID_STATE 0x02 /**< Sequencing error: Command is not valid now. */ +#define DTM_ERROR_ILLEGAL_LENGTH 0x03 /**< Payload size must be in the range 0..37. */ +#define DTM_ERROR_ILLEGAL_CONFIGURATION 0x04 /**< Parameter out of range (legal range is function dependent). */ +#define DTM_ERROR_UNINITIALIZED 0x05 /**< DTM module has not been initialized by the application. */ + +/**@details The UART poll cycle in micro seconds. + * A baud rate of e.g. 19200 bits / second, and 8 data bits, 1 start/stop bit, no flow control, + * give the time to transmit a byte: 10 bits * 1/19200 = approx: 520 us. + * To ensure no loss of bytes, the UART should be polled every 260 us. + */ +#if DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud9600 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/9600/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud14400 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/14400/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud19200 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/19200/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud28800 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/28800/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud38400 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/38400/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud57600 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/57600/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud76800 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/768000/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud115200 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/115200/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud230400 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/230400/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud250000 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/250000/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud460800 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/460800/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud921600 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/921600/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud1M +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/1e6/2)) +#else +// It is possible to find values that work for other baud rates, but the formula above is not +// guaranteed to work for all values. Suitable values may have to be found by trial and error. +#error "Unsupported baud rate set." +#endif + +// Note: DTM_PKT_VENDORSPECIFIC, is not a packet type +#define PACKET_TYPE_MAX DTM_PKT_0X55 /**< Highest value allowed as DTM Packet type. */ + +/** @brief BLE DTM event type. */ +typedef uint32_t dtm_event_t; /**< Type for handling DTM event. */ + +/** @brief BLE DTM frequency type. */ +typedef uint32_t dtm_freq_t; /**< Physical channel, valid range: 0..39. */ + +/**@brief BLE DTM packet types. */ +typedef uint32_t dtm_pkt_type_t; /**< Type for holding the requested DTM payload type.*/ + + +/**@brief Function for initializing or re-initializing DTM module + * + * @return DTM_SUCCESS on successful initialization of the DTM module. +*/ +uint32_t dtm_init(void); + + +/**@brief Function for giving control to dtmlib for handling timer and radio events. + * Will return to caller at 625us intervals or whenever another event than radio occurs + * (such as UART input). Function will put MCU to sleep between events. + * + * @return Time counter, incremented every 625 us. + */ +uint32_t dtm_wait(void); + + +/**@brief Function for calling when a complete command has been prepared by the Tester. + * + * @param[in] cmd One of the DTM_CMD values (bits 14:15 in the 16-bit UART format). + * @param[in] freq Phys. channel no - actual frequency = (2402 + freq * 2) MHz (bits 8:13 in + * the 16-bit UART format). + * @param[in] length Payload length, 0..37 (bits 2:7 in the 16-bit UART format). + * @param[in] payload One of the DTM_PKT values (bits 0:1 in the 16-bit UART format). + * + * @return DTM_SUCCESS or one of the DTM_ERROR_ values + */ +uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t payload); + + +/**@brief Function for reading the result of a DTM command + * + * @param[out] p_dtm_event Pointer to buffer for 16 bit event code according to DTM standard. + * + * @return true: new event, false: no event since last call, this event has been read earlier + */ +bool dtm_event_get(dtm_event_t * p_dtm_event); + + +/**@brief Function for configuring the timer to use. + * + * @note Must be called when no DTM test is running. + * + * @param[in] new_timer Index (0..2) of timer to be used by the DTM library + * + * @return true: success, new timer was selected, false: parameter error + */ +bool dtm_set_timer(uint32_t new_timer); + + +/**@brief Function for configuring the transmit power. + * + * @note Must be called when no DTM test is running. + * + * @param[in] new_tx_power New output level, +4..-40, in steps of 4. + * + * @return true: tx power setting changed, false: parameter error + */ +bool dtm_set_txpower(uint32_t new_tx_power); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_DTM_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm_hw.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm_hw.h new file mode 100644 index 0000000000000000000000000000000000000000..c63d155cc865baef99d1541bb405a1b4106a5e84 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm_hw.h @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_dtm_hw Direct Test Mode HW + * @{ + * @ingroup ble_sdk_lib + * @brief Module contains hardware related function for testing RF/PHY using DTM commands. + */ + +#ifndef BLE_DTM_HW_H__ +#define BLE_DTM_HW_H__ + +#include +#include +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Function for selecting a timer resource. + * This function may be called directly, or through dtm_cmd() specifying + * DTM_PKT_VENDORSPECIFIC as payload, SELECT_TIMER as length, and the timer as freq + * + * @param[out] mp_timer Pointer to timer instance used in dtm source file. + * @param[out] m_timer_irq Pointer to timer interrupt related to mp_timer. + * @param[in] new_timer Timer id for the timer to use. + * + * @retval true if the timer was successfully changed. + * @retval false if the error occurs. + */ + +bool dtm_hw_set_timer(NRF_TIMER_Type ** mp_timer, IRQn_Type * m_timer_irq, uint32_t new_timer); + + +/**@brief Function for turning off radio test. + * This function is platform depending. For now only nRF51 requieres this special function. + */ +void dtm_turn_off_test(void); + + +/**@brief Function for setting constant carrier in radio settings. + * This function is used to handle vendor specific command testing continous carrier without + * a modulated signal. + */ +void dtm_constant_carrier(void); + + +/**@brief Function for validating tx power and radio move settings. + * @param[in] m_tx_power TX power for transmission test. + * @param[in] m_radio_mode Radio mode value. + * + * @retval DTM_SUCCESS if input parameters values are correct. + * @retval DTM_ERROR_ILLEGAL_CONFIGURATION if input parameters values are not correct. + */ +uint32_t dtm_radio_validate(int32_t m_tx_power, uint8_t m_radio_mode); + +#ifdef __cplusplus +} +#endif + +#endif // BLE_DTM_HW_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm_hw_nrf51.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm_hw_nrf51.c new file mode 100644 index 0000000000000000000000000000000000000000..f0e238e4daa812e58eca187ca30474fca54f71c0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm_hw_nrf51.c @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_dtm_hw.h" +#include "ble_dtm.h" +#include +#include +#include "nrf.h" + + +void dtm_turn_off_test() +{ + NRF_RADIO->TEST = 0; +} + + +void dtm_constant_carrier() +{ + NRF_RADIO->TEST = (RADIO_TEST_PLL_LOCK_Enabled << RADIO_TEST_PLL_LOCK_Pos) | + (RADIO_TEST_CONST_CARRIER_Enabled << RADIO_TEST_CONST_CARRIER_Pos); +} + + +uint32_t dtm_radio_validate(int32_t m_tx_power, uint8_t m_radio_mode) +{ + // Handle BLE Radio tuning parameters from production for DTM if required. + // Only needed for DTM without SoftDevice, as the SoftDevice normally handles this. + // PCN-083. + if ( ((NRF_FICR->OVERRIDEEN) & FICR_OVERRIDEEN_BLE_1MBIT_Msk) == FICR_OVERRIDEEN_BLE_1MBIT_Override) + { + NRF_RADIO->OVERRIDE0 = NRF_FICR->BLE_1MBIT[0]; + NRF_RADIO->OVERRIDE1 = NRF_FICR->BLE_1MBIT[1]; + NRF_RADIO->OVERRIDE2 = NRF_FICR->BLE_1MBIT[2]; + NRF_RADIO->OVERRIDE3 = NRF_FICR->BLE_1MBIT[3]; + NRF_RADIO->OVERRIDE4 = NRF_FICR->BLE_1MBIT[4]; + } + + // Initializing code below is quite generic - for BLE, the values are fixed, and expressions + // are constant. Non-constant values are essentially set in radio_prepare(). + if (!(m_tx_power == RADIO_TXPOWER_TXPOWER_0dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Pos4dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg30dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg20dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg16dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg12dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg8dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg4dBm + ) || + (m_radio_mode > RADIO_MODE_MODE_Ble_1Mbit) // Values 0 - 2: Proprietary mode, 3 (last valid): BLE + ) + { + return DTM_ERROR_ILLEGAL_CONFIGURATION; + } + + return DTM_SUCCESS; +} + + +bool dtm_hw_set_timer(NRF_TIMER_Type ** mp_timer, IRQn_Type * m_timer_irq, uint32_t new_timer) +{ + if (new_timer == 0) + { + *mp_timer = NRF_TIMER0; + *m_timer_irq = TIMER0_IRQn; + } + else if (new_timer == 1) + { + *mp_timer = NRF_TIMER1; + *m_timer_irq = TIMER1_IRQn; + } + else if (new_timer == 2) + { + *mp_timer = NRF_TIMER2; + *m_timer_irq = TIMER2_IRQn; + } + else + { + // Parameter error: Only TIMER 0, 1, 2 provided by nRF51 + return false; + } + // New timer has been selected: + return true; +} + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm_hw_nrf52.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm_hw_nrf52.c new file mode 100644 index 0000000000000000000000000000000000000000..d204d05f31d68fdeeba1b40ba7b20ad8a052f366 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_dtm/ble_dtm_hw_nrf52.c @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_dtm_hw.h" +#include "ble_dtm.h" +#include +#include +#include "nrf.h" + + +void dtm_turn_off_test() +{ +} + + +void dtm_constant_carrier() +{ +NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_RU_Default << RADIO_MODECNF0_RU_Pos) | + (RADIO_MODECNF0_DTX_Center << RADIO_MODECNF0_DTX_Pos); +} + + +uint32_t dtm_radio_validate(int32_t m_tx_power, uint8_t m_radio_mode) +{ + // Initializing code below is quite generic - for BLE, the values are fixed, and expressions + // are constant. Non-constant values are essentially set in radio_prepare(). + if (!(m_tx_power == RADIO_TXPOWER_TXPOWER_0dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Pos4dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg30dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg20dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg16dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg12dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg8dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg4dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Pos3dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg40dBm + ) || + (m_radio_mode > RADIO_MODE_MODE_Ble_1Mbit) // Values 0 - 2: Proprietary mode, 3 (last valid): BLE + ) + { + return DTM_ERROR_ILLEGAL_CONFIGURATION; + } + + return DTM_SUCCESS; +} + + +bool dtm_hw_set_timer(NRF_TIMER_Type ** mp_timer, IRQn_Type * m_timer_irq, uint32_t new_timer) +{ + if (new_timer == 0) + { + *mp_timer = NRF_TIMER0; + *m_timer_irq = TIMER0_IRQn; + } + else if (new_timer == 1) + { + *mp_timer = NRF_TIMER1; + *m_timer_irq = TIMER1_IRQn; + } + else if (new_timer == 2) + { + *mp_timer = NRF_TIMER2; + *m_timer_irq = TIMER2_IRQn; + } + else if (new_timer == 3) + { + *mp_timer = NRF_TIMER3; + *m_timer_irq = TIMER3_IRQn; + } + else if (new_timer == 4) + { + *mp_timer = NRF_TIMER4; + *m_timer_irq = TIMER4_IRQn; + } + else + { + // Parameter error: Only TIMER 0, 1, 2, 3 and 4 provided by nRF52 + return false; + } + // New timer has been selected: + return true; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_racp/ble_racp.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_racp/ble_racp.c new file mode 100644 index 0000000000000000000000000000000000000000..dbb9d46a326ff9df908c3a25cace2205d5f17c4e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_racp/ble_racp.c @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_RACP) +#include "ble_racp.h" +#include + + +void ble_racp_decode(uint8_t data_len, uint8_t * p_data, ble_racp_value_t * p_racp_val) +{ + p_racp_val->opcode = 0xFF; + p_racp_val->operator = 0xFF; + p_racp_val->operand_len = 0; + p_racp_val->p_operand = NULL; + + if (data_len > 0) + { + p_racp_val->opcode = p_data[0]; + } + if (data_len > 1) + { + p_racp_val->operator = p_data[1]; //lint !e415 + } + if (data_len > 2) + { + p_racp_val->operand_len = data_len - 2; + p_racp_val->p_operand = &p_data[2]; //lint !e416 + } +} + + +uint8_t ble_racp_encode(const ble_racp_value_t * p_racp_val, uint8_t * p_data) +{ + uint8_t len = 0; + int i; + + if (p_data != NULL) + { + p_data[len++] = p_racp_val->opcode; + p_data[len++] = p_racp_val->operator; + + for (i = 0; i < p_racp_val->operand_len; i++) + { + p_data[len++] = p_racp_val->p_operand[i]; + } + } + + return len; +} +#endif // NRF_MODULE_ENABLED(BLE_RACP) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_racp/ble_racp.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_racp/ble_racp.h new file mode 100644 index 0000000000000000000000000000000000000000..2756441c727c3b4cd36e9c52de8d7cd0632e6be5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_racp/ble_racp.h @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_racp Record Access Control Point + * @{ + * @ingroup ble_sdk_lib + * @brief Record Access Control Point library. + */ + +#ifndef BLE_RACP_H__ +#define BLE_RACP_H__ + +#include +#include +#include "ble.h" +#include "ble_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Record Access Control Point opcodes. */ +#define RACP_OPCODE_RESERVED 0 /**< Record Access Control Point opcode - Reserved for future use. */ +#define RACP_OPCODE_REPORT_RECS 1 /**< Record Access Control Point opcode - Report stored records. */ +#define RACP_OPCODE_DELETE_RECS 2 /**< Record Access Control Point opcode - Delete stored records. */ +#define RACP_OPCODE_ABORT_OPERATION 3 /**< Record Access Control Point opcode - Abort operation. */ +#define RACP_OPCODE_REPORT_NUM_RECS 4 /**< Record Access Control Point opcode - Report number of stored records. */ +#define RACP_OPCODE_NUM_RECS_RESPONSE 5 /**< Record Access Control Point opcode - Number of stored records response. */ +#define RACP_OPCODE_RESPONSE_CODE 6 /**< Record Access Control Point opcode - Response code. */ + +/**@brief Record Access Control Point operators. */ +#define RACP_OPERATOR_NULL 0 /**< Record Access Control Point operator - Null. */ +#define RACP_OPERATOR_ALL 1 /**< Record Access Control Point operator - All records. */ +#define RACP_OPERATOR_LESS_OR_EQUAL 2 /**< Record Access Control Point operator - Less than or equal to. */ +#define RACP_OPERATOR_GREATER_OR_EQUAL 3 /**< Record Access Control Point operator - Greater than or equal to. */ +#define RACP_OPERATOR_RANGE 4 /**< Record Access Control Point operator - Within range of (inclusive). */ +#define RACP_OPERATOR_FIRST 5 /**< Record Access Control Point operator - First record (i.e. oldest record). */ +#define RACP_OPERATOR_LAST 6 /**< Record Access Control Point operator - Last record (i.e. most recent record). */ +#define RACP_OPERATOR_RFU_START 7 /**< Record Access Control Point operator - Start of Reserved for Future Use area. */ + +/**@brief Record Access Control Point Operand Filter Type Value. */ +#define RACP_OPERAND_FILTER_TYPE_TIME_OFFSET 1 /**< Record Access Control Point Operand Filter Type Value - Time Offset- */ + +/**@brief Record Access Control Point response codes. */ +#define RACP_RESPONSE_RESERVED 0 /**< Record Access Control Point response code - Reserved for future use. */ +#define RACP_RESPONSE_SUCCESS 1 /**< Record Access Control Point response code - Successful operation. */ +#define RACP_RESPONSE_OPCODE_UNSUPPORTED 2 /**< Record Access Control Point response code - Unsupported op code received. */ +#define RACP_RESPONSE_INVALID_OPERATOR 3 /**< Record Access Control Point response code - Operator not valid for service. */ +#define RACP_RESPONSE_OPERATOR_UNSUPPORTED 4 /**< Record Access Control Point response code - Unsupported operator. */ +#define RACP_RESPONSE_INVALID_OPERAND 5 /**< Record Access Control Point response code - Operand not valid for service. */ +#define RACP_RESPONSE_NO_RECORDS_FOUND 6 /**< Record Access Control Point response code - No matching records found. */ +#define RACP_RESPONSE_ABORT_FAILED 7 /**< Record Access Control Point response code - Abort could not be completed. */ +#define RACP_RESPONSE_PROCEDURE_NOT_DONE 8 /**< Record Access Control Point response code - Procedure could not be completed. */ +#define RACP_RESPONSE_OPERAND_UNSUPPORTED 9 /**< Record Access Control Point response code - Unsupported operand. */ + +/**@brief Record Access Control Point value structure. */ +typedef struct +{ + uint8_t opcode; /**< Op Code. */ + uint8_t operator; /**< Operator. */ + uint8_t operand_len; /**< Length of the operand. */ + uint8_t * p_operand; /**< Pointer to the operand. */ +} ble_racp_value_t; + +/**@brief Function for decoding a Record Access Control Point write. + * + * @details This call decodes a write to the Record Access Control Point. + * + * @param[in] data_len Length of data in received write. + * @param[in] p_data Pointer to received data. + * @param[out] p_racp_val Pointer to decoded Record Access Control Point write. + * @note This does not do a data copy. It assumes the data pointed to by + * p_data is persistant until no longer needed. + */ +void ble_racp_decode(uint8_t data_len, uint8_t * p_data, ble_racp_value_t * p_racp_val); + +/**@brief Function for encoding a Record Access Control Point response. + * + * @details This call encodes a response from the Record Access Control Point response. + * + * @param[in] p_racp_val Pointer to Record Access Control Point to encode. + * @param[out] p_data Pointer to where encoded data is written. + * NOTE! It is calling routines respsonsibility to make sure. + * + * @return Length of encoded data. + */ +uint8_t ble_racp_encode(const ble_racp_value_t * p_racp_val, uint8_t * p_data); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_RACP_H__ + +/** @} */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_radio_notification/ble_radio_notification.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_radio_notification/ble_radio_notification.c new file mode 100644 index 0000000000000000000000000000000000000000..ffdfdaa31a3c82344e0280a84c0a94557f6bf2c4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_radio_notification/ble_radio_notification.c @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_radio_notification.h" +#include + + +static bool m_radio_active = false; /**< Current radio state. */ +static ble_radio_notification_evt_handler_t m_evt_handler = NULL; /**< Application event handler for handling Radio Notification events. */ + + +void SWI1_IRQHandler(void) +{ + m_radio_active = !m_radio_active; + if (m_evt_handler != NULL) + { + m_evt_handler(m_radio_active); + } +} + + +uint32_t ble_radio_notification_init(uint32_t irq_priority, + uint8_t distance, + ble_radio_notification_evt_handler_t evt_handler) +{ + uint32_t err_code; + + m_evt_handler = evt_handler; + + // Initialize Radio Notification software interrupt + err_code = sd_nvic_ClearPendingIRQ(SWI1_IRQn); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = sd_nvic_SetPriority(SWI1_IRQn, irq_priority); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = sd_nvic_EnableIRQ(SWI1_IRQn); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Configure the event + return sd_radio_notification_cfg_set(NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, distance); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_radio_notification/ble_radio_notification.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_radio_notification/ble_radio_notification.h new file mode 100644 index 0000000000000000000000000000000000000000..43e7946f3eb5d439d9ed29591c8542b0d98f3c56 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_radio_notification/ble_radio_notification.h @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_radio_notification Radio Notification Event Handler + * @{ + * @ingroup ble_sdk_lib + * @brief Module for propagating Radio Notification events to the application. + */ + +#ifndef BLE_RADIO_NOTIFICATION_H__ +#define BLE_RADIO_NOTIFICATION_H__ + +#include +#include +#include "nrf_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Application radio notification event handler type. */ +typedef void (*ble_radio_notification_evt_handler_t) (bool radio_active); + +/**@brief Function for initializing the Radio Notification module. + * + * @param[in] irq_priority Interrupt priority for the Radio Notification interrupt handler. + * @param[in] distance The time from an Active event until the radio is activated. + * @param[in] evt_handler Handler to be executed when a radio notification event has been + * received. + * + * @return NRF_SUCCESS on successful initialization, otherwise an error code. + */ +uint32_t ble_radio_notification_init(uint32_t irq_priority, + uint8_t distance, + ble_radio_notification_evt_handler_t evt_handler); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_RADIO_NOTIFICATION_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c new file mode 100644 index 0000000000000000000000000000000000000000..f8a14d67bd1ef1ee0a3e67339ff4255301ffedde --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c @@ -0,0 +1,367 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA. + * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working. + */ + +#include "ancs_app_attr_get.h" +#include "nrf_ble_ancs_c.h" +#include "ancs_tx_buffer.h" +#include "sdk_macros.h" +#include "nrf_log.h" +#include "string.h" + +#define GATTC_OPCODE_SIZE 1 /**< Size of the GATTC OPCODE. */ +#define GATTC_ATTR_HANDLE_SIZE 4 /**< Size of the Attribute handle Size. */ + + +#define ANCS_GATTC_WRITE_PAYLOAD_LEN_MAX (BLE_GATT_ATT_MTU_DEFAULT - GATTC_OPCODE_SIZE - GATTC_ATTR_HANDLE_SIZE) /**< Maximum Length of the data we can send in one write. */ + + +/**@brief Enum to keep track of the state based encoding while requesting App attributes. */ +typedef enum +{ + APP_ATTR_COMMAND_ID, /**< Currently encoding the Command ID. */ + APP_ATTR_APP_ID, /**< Currently encoding the App ID. */ + APP_ATTR_ATTR_ID, /**< Currently encoding the Attribute ID. */ + APP_ATTR_DONE /**< Encoding done. */ +}encode_app_attr_t; + + +/**@brief Function for determening if an attribute is desired to get. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * + * @return True If it is requested + * @return False If it is not be requested. +*/ +static bool app_attr_is_requested(ble_ancs_c_t * p_ancs, uint32_t attr_id) +{ + if(p_ancs->ancs_app_attr_list[attr_id].get == true) + { + return true; + } + return false; +} + +/**@brief Function for counting the number of attributes that will be requested upon a Get App Attribute. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * + * @return Number of attributes that will be requested upon a Get App Attribute. +*/ +static uint32_t app_attr_nb_to_get(ble_ancs_c_t * p_ancs) +{ + uint32_t attr_nb_to_get = 0; + for(uint32_t i = 0; i < (sizeof(p_ancs->ancs_app_attr_list)/sizeof(ble_ancs_c_attr_list_t)); i++) + { + if(app_attr_is_requested(p_ancs,i)) + { + attr_nb_to_get++; + } + } + return attr_nb_to_get; +} + + +/**@brief Function for encoding the Command ID as part of assembling a "Get App Attributes" command. + * + * @param[in] conn_handle Connection handle for where the prepared write will be executed. + * @param[in] handle_value The handle that will receive the execute command. + * @param[in] p_offset Pointer to the offset for the write. + * @param[in] p_index Pointer to the length encoded so far for the current write. + * @param[in,out] p_msg Pointer to the tx message that has been filled out and will be added to + * tx queue in this function. + */ +static void queued_write_tx_message(uint16_t conn_handle, + uint16_t handle_value, + uint16_t * p_offset, + uint32_t * p_index, + tx_message_t * p_msg) +{ + NRF_LOG_DEBUG("Starting new TX message.\r\n"); + + p_msg->conn_handle = conn_handle; + p_msg->type = WRITE_REQ; + p_msg->req.write_req.gattc_params.len = *p_index; + p_msg->req.write_req.gattc_params.handle = handle_value; + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + + p_msg->req.write_req.gattc_params.offset = *p_offset; + + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_PREP_WRITE_REQ; + + tx_buffer_insert(p_msg); +} + + +/**@brief Function for encoding the Command ID as part of assembling a "Get App Attributes" command. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] p_index Pointer to the length encoded so far for the current write. + * @param[in] p_offset Pointer to the accumulated offset for the next write. + * @param[in,out] p_msg Pointer to the tx message that will be filled out in this function. + */ +static encode_app_attr_t app_attr_encode_cmd_id(ble_ancs_c_t * p_ancs, + uint32_t * index, + tx_message_t * p_msg) +{ + NRF_LOG_DEBUG("Encoding Command ID\r\n"); + + // Encode Command ID. + p_msg->req.write_req.gattc_value[(*index)++] = BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES; + return APP_ATTR_APP_ID; +} + +/**@brief Function for encoding the App Identifier as part of assembling a "Get App Attributes" command. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] p_app_id The App ID for the App which we will request App Attributes for. + * @param[in] app_id_len Length of the App ID. + * @param[in] p_index Pointer to the length encoded so far for the current write. + * @param[in] p_offset Pointer to the accumulated offset for the next write. + * @param[in] p_app_id_bytes_encoded_count Variable to keep count of the encoded APP ID bytes. + * As long as it is lower than the length of the App ID, + * parsing will continue. + */ +static encode_app_attr_t app_attr_encode_app_id(ble_ancs_c_t * p_ancs, + uint32_t * p_index, + uint16_t * p_offset, + tx_message_t * p_msg, + const uint8_t * p_app_id, + const uint32_t app_id_len, + uint32_t * p_app_id_bytes_encoded_count) +{ + NRF_LOG_DEBUG("Encoding APP ID\r\n"); + if(*p_index >= ANCS_GATTC_WRITE_PAYLOAD_LEN_MAX) + { + queued_write_tx_message(p_ancs->conn_handle, p_ancs->service.control_point_char.handle_value, p_offset, p_index, p_msg); + *(p_offset) += *p_index; + *p_index = 0; + } + + //Encode App Identifier. + if(*p_app_id_bytes_encoded_count == app_id_len) + { + p_msg->req.write_req.gattc_value[(*p_index)++] = '\0'; + (*p_app_id_bytes_encoded_count)++; + } + NRF_LOG_DEBUG("%c\r\n", p_app_id[(*p_app_id_bytes_encoded_count)]); + if(*p_app_id_bytes_encoded_count < app_id_len) + { + p_msg->req.write_req.gattc_value[(*p_index)++] = p_app_id[(*p_app_id_bytes_encoded_count)++]; + } + if(*p_app_id_bytes_encoded_count > app_id_len) + { + return APP_ATTR_ATTR_ID; + } + return APP_ATTR_APP_ID; +} + +/**@brief Function for encoding the Attribute ID as part of assembling a "Get App Attributes" command. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * + * @param[in] p_index Pointer to the length encoded so far for the current write. + * @param[in] p_offset Pointer to the accumulated offset for the next write. + * @param[in,out] p_msg Pointer to the tx message that will be filled out in this function. + * @param[in] p_attr_count Pointer to a variable that iterates the possible App Attributes. + */ +static encode_app_attr_t app_attr_encode_attr_id(ble_ancs_c_t * p_ancs, + uint32_t * p_index, + uint16_t * p_offset, + tx_message_t * p_msg, + uint32_t * p_attr_count, + uint32_t * attr_get_total_nb) +{ + NRF_LOG_DEBUG("Encoding Attribute ID\r\n"); + if((*p_index) >= ANCS_GATTC_WRITE_PAYLOAD_LEN_MAX) + { + queued_write_tx_message(p_ancs->conn_handle, + p_ancs->service.control_point_char.handle_value, + p_offset, p_index, p_msg); + *(p_offset) += *p_index; + *p_index = 0; + } + //Encode Attribute ID. + if (*p_attr_count < BLE_ANCS_NB_OF_APP_ATTR) + { + if (app_attr_is_requested(p_ancs, *p_attr_count)) + { + p_msg->req.write_req.gattc_value[(*p_index)] = *p_attr_count; + p_ancs->number_of_requested_attr++; + (*p_index)++; + NRF_LOG_DEBUG("offset %i\r\n", *p_offset); + } + (*p_attr_count)++; + } + if (*p_attr_count == BLE_ANCS_NB_OF_APP_ATTR) + { + return APP_ATTR_DONE; + } + return APP_ATTR_APP_ID; +} + +/**@brief Function for writing the execute write command to a handle for a given connection. + * + * @param[in] conn_handle Connection handle for where the prepared write will be executed. + * @param[in] handle_value The handle that will receive the execute command. + * @param[in] p_msg Pointer to the message that will be filled out in this function and then + * added to the tx queue. + */ +static void app_attr_execute_write(uint16_t conn_handle, uint16_t handle_value, tx_message_t * p_msg) +{ + NRF_LOG_DEBUG("Sending Execute Write.\r\n"); + memset(p_msg,0,sizeof(tx_message_t)); + + p_msg->req.write_req.gattc_params.handle = handle_value; + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + p_msg->req.write_req.gattc_params.offset = 0; + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_EXEC_WRITE_REQ; + p_msg->req.write_req.gattc_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE; + + p_msg->req.write_req.gattc_params.len = 0; + p_msg->conn_handle = conn_handle; + p_msg->type = WRITE_REQ; + + tx_buffer_insert(p_msg); +} + + +/**@brief Function for sending a get App Attributes request. + * + * @details Since the APP id may not fit in a single write, we use long write + * with a state machine to encode the Get App Attribute request. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] p_app_id The App ID for the App which we will request App Attributes for. + * @param[in] app_id_len Length of the App ID. + * +*/ +static uint32_t app_attr_get(ble_ancs_c_t * p_ancs, + const uint8_t * p_app_id, + uint32_t app_id_len) +{ + uint32_t index = 0; + uint32_t attr_bytes_encoded_count = 0; + uint16_t offset = 0; + uint32_t app_id_bytes_encoded_count = 0; + encode_app_attr_t state = APP_ATTR_COMMAND_ID; + p_ancs->number_of_requested_attr = 0; + + uint32_t attr_get_total_nb = app_attr_nb_to_get(p_ancs); + tx_message_t p_msg; + + memset(&p_msg, 0, sizeof(tx_message_t)); + + while(state != APP_ATTR_DONE) + { + switch(state) + { + case APP_ATTR_COMMAND_ID: + state = app_attr_encode_cmd_id(p_ancs, + &index, + &p_msg); + break; + case APP_ATTR_APP_ID: + state = app_attr_encode_app_id(p_ancs, + &index, + &offset, + &p_msg, + p_app_id, + app_id_len, + &app_id_bytes_encoded_count); + break; + case APP_ATTR_ATTR_ID: + state = app_attr_encode_attr_id(p_ancs, + &index, + &offset, + &p_msg, + &attr_bytes_encoded_count, + &attr_get_total_nb); + break; + case APP_ATTR_DONE: + break; + default: + break; + } + } + queued_write_tx_message(p_ancs->conn_handle, + p_ancs->service.control_point_char.handle_value, + &offset, + &index, + &p_msg); + + app_attr_execute_write(p_ancs->conn_handle, + p_ancs->service.control_point_char.handle_value, + &p_msg); + + p_ancs->parse_info.expected_number_of_attrs = p_ancs->number_of_requested_attr; + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +uint32_t ancs_c_app_attr_request(ble_ancs_c_t * p_ancs, + const uint8_t * p_app_id, + uint32_t len) +{ + uint32_t err_code; + + if(len == 0) + { + return NRF_ERROR_DATA_SIZE; + } + if(p_app_id[len] != '\0') // App id to be requestes must be NULL terminated + { + return NRF_ERROR_INVALID_PARAM; + } + + p_ancs->parse_info.parse_state = COMMAND_ID; + err_code = app_attr_get(p_ancs, p_app_id, len); + VERIFY_SUCCESS(err_code); + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h new file mode 100644 index 0000000000000000000000000000000000000000..708d29574adc8768a08f32ad9a40d8443e200801 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANCS_APP_ATTR_GET_H__ +#define ANCS_APP_ATTR_GET_H__ + +#include "nrf_ble_ancs_c.h" +/** @file + * + * @addtogroup ble_ancs_c + * @{ + */ + +/**@brief Function for requesting attributes for an app. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] app_id App identifier of the app for which to request app attributes. + * @param[in] len Length of the app identifier. + * + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +uint32_t ancs_c_app_attr_request(ble_ancs_c_t * p_ancs, + const uint8_t * app_id, + uint32_t len); + +/** @} */ + +#endif // ANCS_APP_ATTR_GET_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c new file mode 100644 index 0000000000000000000000000000000000000000..322e764f3d9907627ee10566658f18689a0d8f59 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c @@ -0,0 +1,392 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA. + * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working. + */ + + #include "nrf_ble_ancs_c.h" + #include "ancs_attr_parser.h" + #include "nrf_log.h" + + +static bool all_req_attrs_parsed(ble_ancs_c_t * p_ancs) +{ + if (p_ancs->parse_info.expected_number_of_attrs == 0) + { + return true; + } + return false; +} + +static bool attr_is_requested(ble_ancs_c_t * p_ancs, ble_ancs_c_attr_t attr) +{ + if(p_ancs->parse_info.p_attr_list[attr.attr_id].get == true) + { + return true; + } + return false; +} + + +/**@brief Function for parsing command id and notification id. + * Used in the @ref parse_get_notif_attrs_response state machine. + * + * @details UID and command ID will be received only once at the beginning of the first + * GATTC notification of a new attribute request for a given iOS notification. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed. + * + * @return The next parse state. + */ +static ble_ancs_c_parse_state_t command_id_parse(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + uint32_t * index) +{ + ble_ancs_c_parse_state_t parse_state; + + p_ancs->parse_info.command_id = (ble_ancs_c_cmd_id_val_t) p_data_src[(*index)++]; + + switch (p_ancs->parse_info.command_id) + { + case BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES: + p_ancs->evt.evt_type = BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE; + p_ancs->parse_info.p_attr_list = p_ancs->ancs_notif_attr_list; + p_ancs->parse_info.nb_of_attr = BLE_ANCS_NB_OF_NOTIF_ATTR; + parse_state = NOTIF_UID; + break; + + case BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES: + p_ancs->evt.evt_type = BLE_ANCS_C_EVT_APP_ATTRIBUTE; + p_ancs->parse_info.p_attr_list = p_ancs->ancs_app_attr_list; + p_ancs->parse_info.nb_of_attr = BLE_ANCS_NB_OF_APP_ATTR; + parse_state = APP_ID; + break; + + default: + //no valid command_id, abort the rest of the parsing procedure. + NRF_LOG_DEBUG("Invalid Command ID"); + parse_state = DONE; + break; + } + return parse_state; +} + + +static ble_ancs_c_parse_state_t notif_uid_parse(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + uint32_t * index) +{ + p_ancs->evt.notif_uid = uint32_decode(&p_data_src[*index]); + *index += sizeof(uint32_t); + return ATTR_ID; +} + +static ble_ancs_c_parse_state_t app_id_parse(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + uint32_t * index) +{ + p_ancs->evt.app_id[p_ancs->parse_info.current_app_id_index] = p_data_src[(*index)++]; + + if(p_ancs->evt.app_id[p_ancs->parse_info.current_app_id_index] != '\0') + { + p_ancs->parse_info.current_app_id_index++; + return APP_ID; + } + else + { + return ATTR_ID; + } +} + +/**@brief Function for parsing the id of an iOS attribute. + * Used in the @ref parse_get_notif_attrs_response state machine. + * + * @details We only request attributes that are registered with @ref ble_ancs_c_attr_add + * once they have been reveiced we stop parsing. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed. + * + * @return The next parse state. + */ +static ble_ancs_c_parse_state_t attr_id_parse(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + uint32_t * index) +{ + p_ancs->evt.attr.attr_id = p_data_src[(*index)++]; + + if (p_ancs->evt.attr.attr_id >= p_ancs->parse_info.nb_of_attr) + { + NRF_LOG_DEBUG("Attribute ID Invalid.\r\n"); + return DONE; + } + p_ancs->evt.attr.p_attr_data = p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].p_attr_data; + + if (all_req_attrs_parsed(p_ancs)) + { + NRF_LOG_DEBUG("All requested attributes received. \r\n"); + return DONE; + } + else + { + if (attr_is_requested(p_ancs, p_ancs->evt.attr)) + { + p_ancs->parse_info.expected_number_of_attrs--; + } + NRF_LOG_DEBUG("Attribute ID %i \r\n", p_ancs->evt.attr.attr_id); + return ATTR_LEN1; + } +} + + +/**@brief Function for parsing the length of an iOS attribute. + * Used in the @ref parse_get_notif_attrs_response state machine. + * + * @details The Length is 2 bytes. Since there is a chance we reveice the bytes in two different + * GATTC notifications, we parse only the first byte here and then set the state machine + * ready to parse the next byte. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed. + * + * @return The next parse state. + */ +static ble_ancs_c_parse_state_t attr_len1_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index) +{ + p_ancs->evt.attr.attr_len = p_data_src[(*index)++]; + return ATTR_LEN2; +} + +/**@brief Function for parsing the length of an iOS attribute. + * Used in the @ref parse_get_notif_attrs_response state machine. + * + * @details Second byte of the length field. If the length is zero, it means that the attribute is not + * present and the state machine is set to parse the next attribute. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed. + * + * @return The next parse state. + */ +static ble_ancs_c_parse_state_t attr_len2_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index) +{ + p_ancs->evt.attr.attr_len |= (p_data_src[(*index)++] << 8); + p_ancs->parse_info.current_attr_index = 0; + + if (p_ancs->evt.attr.attr_len != 0) + { + //If the attribute has a length but there is no allocated space for this attribute + if((p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].attr_len == 0) || + (p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].p_attr_data == NULL)) + { + return ATTR_SKIP; + } + else + { + return ATTR_DATA; + } + } + else + { + + NRF_LOG_DEBUG("Attribute LEN %i \r\n", p_ancs->evt.attr.attr_len); + if(attr_is_requested(p_ancs, p_ancs->evt.attr)) + { + p_ancs->evt_handler(&p_ancs->evt); + } + if(all_req_attrs_parsed(p_ancs)) + { + return DONE; + } + else + { + return ATTR_ID; + } + } +} + + +/**@brief Function for parsing the data of an iOS attribute. + * Used in the @ref parse_get_notif_attrs_response state machine. + * + * @details Read the data of the attribute into our local buffer. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed. + * + * @return The next parse state. + */ +static ble_ancs_c_parse_state_t attr_data_parse(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + uint32_t * index) +{ + // We have not reached the end of the attribute, nor our max allocated internal size. + // Proceed with copying data over to our buffer. + if ( (p_ancs->parse_info.current_attr_index < p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].attr_len) + && (p_ancs->parse_info.current_attr_index < p_ancs->evt.attr.attr_len)) + { + //NRF_LOG_DEBUG("Byte copied to buffer: %c\r\n", p_data_src[(*index)]); // Un-comment this line to see every byte of an attribute as it is parsed. Commented out by default since it can overflow the uart buffer. + p_ancs->evt.attr.p_attr_data[p_ancs->parse_info.current_attr_index++] = p_data_src[(*index)++]; + } + + // We have reached the end of the attribute, or our max allocated internal size. + // Stop copying data over to our buffer. NUL-terminate at the current index. + if ( (p_ancs->parse_info.current_attr_index == p_ancs->evt.attr.attr_len) || + (p_ancs->parse_info.current_attr_index == p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].attr_len - 1)) + { + if (attr_is_requested(p_ancs, p_ancs->evt.attr)) + { + p_ancs->evt.attr.p_attr_data[p_ancs->parse_info.current_attr_index] = '\0'; + } + + // If our max buffer size is smaller than the remaining attribute data, we must + // increase index to skip the data until the start of the next attribute. + if (p_ancs->parse_info.current_attr_index < p_ancs->evt.attr.attr_len) + { + return ATTR_SKIP; + } + NRF_LOG_DEBUG("Attribute finished!\r\n"); + if(attr_is_requested(p_ancs, p_ancs->evt.attr)) + { + p_ancs->evt_handler(&p_ancs->evt); + } + if(all_req_attrs_parsed(p_ancs)) + { + return DONE; + } + else + { + return ATTR_ID; + } + } + return ATTR_DATA; +} + + +static ble_ancs_c_parse_state_t attr_skip(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index) +{ + // We have not reached the end of the attribute, nor our max allocated internal size. + // Proceed with copying data over to our buffer. + if (p_ancs->parse_info.current_attr_index < p_ancs->evt.attr.attr_len) + { + p_ancs->parse_info.current_attr_index++; + (*index)++; + } + // At the end of the attribute, determine if it should be passed to event handler and + // continue parsing the next attribute ID if we are not done with all the attributes. + if (p_ancs->parse_info.current_attr_index == p_ancs->evt.attr.attr_len) + { + if(attr_is_requested(p_ancs, p_ancs->evt.attr)) + { + p_ancs->evt_handler(&p_ancs->evt); + } + if(all_req_attrs_parsed(p_ancs)) + { + return DONE; + } + else + { + return ATTR_ID; + } + } + return ATTR_SKIP; +} + + +void ancs_parse_get_attrs_response(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + const uint16_t hvx_data_len) +{ + uint32_t index; + + for (index = 0; index < hvx_data_len;) + { + switch (p_ancs->parse_info.parse_state) + { + case COMMAND_ID: + p_ancs->parse_info.parse_state = command_id_parse(p_ancs, p_data_src, &index); + break; + + case NOTIF_UID: + p_ancs->parse_info.parse_state = notif_uid_parse(p_ancs, p_data_src, &index); + break; + + case APP_ID: + p_ancs->parse_info.parse_state = app_id_parse(p_ancs, p_data_src, &index); + break; + + case ATTR_ID: + p_ancs->parse_info.parse_state = attr_id_parse(p_ancs, p_data_src, &index); + break; + + case ATTR_LEN1: + p_ancs->parse_info.parse_state = attr_len1_parse(p_ancs, p_data_src, &index); + break; + + case ATTR_LEN2: + p_ancs->parse_info.parse_state = attr_len2_parse(p_ancs, p_data_src, &index); + break; + + case ATTR_DATA: + p_ancs->parse_info.parse_state = attr_data_parse(p_ancs, p_data_src, &index); + break; + + case ATTR_SKIP: + p_ancs->parse_info.parse_state = attr_skip(p_ancs, p_data_src, &index); + break; + + case DONE: + NRF_LOG_DEBUG("Parse state: Done \r\n"); + index = hvx_data_len; + break; + + default: + // Default case will never trigger intentionally. Go to the DONE state to minimize the consequences. + p_ancs->parse_info.parse_state = DONE; + break; + } + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..32c69d77f0cbd4dce88a3598b3f542e8b4f51911 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_ANCS_ATTR_PARSER_H__ +#define BLE_ANCS_ATTR_PARSER_H__ + +#include "nrf_ble_ancs_c.h" + +/** @file + * + * @addtogroup ble_ancs_c + * @{ + */ + +/**@brief Function for parsing notification or app attribute response data. + * + * @details The data that comes from the Notification Provider can be much longer than what + * would fit in a single GATTC notification. Therefore, this function relies on a + * state-oriented switch case. + * UID and command ID will be received only once at the beginning of the first + * GATTC notification of a new attribute request for a given iOS notification. + * After this, we can loop several ATTR_ID > LENGTH > DATA > ATTR_ID > LENGTH > DATA until + * we have received all attributes we wanted as a Notification Consumer. + * The Notification Provider can also simply stop sending attributes. + * + * 1 byte | 4 bytes |1 byte |2 bytes |... X bytes ... |1 bytes| 2 bytes| ... X bytes ... + * --------|-------------|-------|--------|----------------|-------|--------|---------------- + * CMD_ID | NOTIF_UID |ATTR_ID| LENGTH | DATA |ATTR_ID| LENGTH | DATA + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] hvx_data_len Length of the data that was received from the Notification Provider. + */ +void ancs_parse_get_attrs_response(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + const uint16_t hvx_data_len); + +/** @} */ + +#endif // BLE_ANCS_ATTR_PARSER_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c new file mode 100644 index 0000000000000000000000000000000000000000..52905210910ee31de6e19c0991982c2330fab8a1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA. + * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working. + */ + + #include "nrf_ble_ancs_c.h" + #include "ancs_tx_buffer.h" + #include "sdk_macros.h" + #include "nrf_log.h" + #include "string.h" + + +static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the Notification Provider. */ +static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */ +static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */ + + +void tx_buffer_init(void) +{ + memset(m_tx_buffer, 0, sizeof(m_tx_buffer)); +} + + +void tx_buffer_insert(tx_message_t * p_msg) +{ + + memset(&(m_tx_buffer[m_tx_insert_index]), 0, sizeof(m_tx_buffer)/sizeof(tx_message_t)); + + m_tx_buffer[m_tx_insert_index].conn_handle = p_msg->conn_handle; + m_tx_buffer[m_tx_insert_index].type = p_msg->type; + + m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.handle = p_msg->req.write_req.gattc_params.handle; + m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.len = p_msg->req.write_req.gattc_params.len; + m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.write_op = p_msg->req.write_req.gattc_params.write_op; + m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.flags = p_msg->req.write_req.gattc_params.flags; + m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.p_value = m_tx_buffer[m_tx_insert_index].req.write_req.gattc_value; + m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.offset = p_msg->req.write_req.gattc_params.offset; + + if(p_msg->type == WRITE_REQ) + { + memcpy(m_tx_buffer[m_tx_insert_index].req.write_req.gattc_value, + p_msg->req.write_req.gattc_value, + WRITE_MESSAGE_LENGTH); + } + + m_tx_insert_index++; + m_tx_insert_index &= TX_BUFFER_MASK; +} + + + +void tx_buffer_process(void) +{ + if (m_tx_index != m_tx_insert_index) + { + uint32_t err_code; + + if (m_tx_buffer[m_tx_index].type == READ_REQ) + { + err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle, + m_tx_buffer[m_tx_index].req.read_handle, + 0); + } + else + { + err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle, + &m_tx_buffer[m_tx_index].req.write_req.gattc_params); + } + if (err_code == NRF_SUCCESS) + { + ++m_tx_index; + m_tx_index &= TX_BUFFER_MASK; + } + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..89363d492158f1755e565275ccfc9d78c523c4d1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANCS_TX_BUFFER_H__ +#define ANCS_TX_BUFFER_H__ + +#include "nrf_ble_ancs_c.h" + +/** @file + * + * @addtogroup ble_ancs_c + * @{ + */ + +#define TX_BUFFER_MASK 0x07 //!< TX buffer mask. Must be a mask of contiguous zeroes followed by a contiguous sequence of ones: 000...111. +#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) //!< Size of the send buffer, which is 1 bigger than the mask. +#define WRITE_MESSAGE_LENGTH 20 //!< Length of the write message for the CCCD/control point. + +/**@brief ANCS request types. + */ +typedef enum +{ + READ_REQ = 1, /**< Type identifying that this TX message is a read request. */ + WRITE_REQ /**< Type identifying that this TX message is a write request. */ +} tx_request_t; + + +/**@brief Structure for writing a message to the central, thus the Control Point or CCCD. + */ +typedef struct +{ + uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; //!< The message to write. + ble_gattc_write_params_t gattc_params; //!< GATTC parameters for this message. +} write_params_t; + + +/**@brief Data to be transmitted to the connected master. + */ +typedef struct +{ + uint16_t conn_handle; //!< Connection handle to be used when transmitting this message. + tx_request_t type; //!< Type of this message (read or write message). + union + { + uint16_t read_handle; //!< Read request message. + write_params_t write_req; //!< Write request message. + } req; +} tx_message_t; + +/**@brief Function for clearing the TX buffer. + * + * @details Always call this function before using the TX buffer. +*/ +void tx_buffer_init(void); + +/**@brief Function for moving the pointer of the ring buffer to the next element. +*/ +void tx_buffer_insert(tx_message_t * p_msg); + +/**@brief Function for passing any pending request from the buffer to the stack. +*/ +void tx_buffer_process(void); + +/** @} */ + +#endif // ANCS_TX_BUFFER_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c new file mode 100644 index 0000000000000000000000000000000000000000..3e87f72c420404a53d0f2a32ea65140e2393adf4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c @@ -0,0 +1,658 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA. + * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working. + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_ANCS_C) +#include "nrf_ble_ancs_c.h" +#include "ancs_tx_buffer.h" +#include "ancs_attr_parser.h" +#include "ancs_app_attr_get.h" +#include "ble_err.h" +#include "ble_srv_common.h" +#include "nrf_assert.h" +#include "ble_db_discovery.h" +#include "app_error.h" +#define NRF_LOG_MODULE_NAME "BLE_ANCS_C" +#include "nrf_log.h" + +#define BLE_ANCS_NOTIF_EVT_ID_INDEX 0 /**< Index of the Event ID field when parsing notifications. */ +#define BLE_ANCS_NOTIF_FLAGS_INDEX 1 /**< Index of the Flags field when parsing notifications. */ +#define BLE_ANCS_NOTIF_CATEGORY_ID_INDEX 2 /**< Index of the Category ID field when parsing notifications. */ +#define BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX 3 /**< Index of the Category Count field when parsing notifications. */ +#define BLE_ANCS_NOTIF_NOTIF_UID 4 /**< Index of the Notification UID field when patsin notifications. */ + +#define BLE_CCCD_NOTIFY_BIT_MASK 0x0001 /**< Enable notification bit. */ + +#define TIME_STRING_LEN 15 /**< Unicode Technical Standard (UTS) #35 date format pattern "yyyyMMdd'T'HHmmSS" + "'\0'". */ + + +/**@brief 128-bit service UUID for the Apple Notification Center Service. + */ +const ble_uuid128_t ble_ancs_base_uuid128 = +{ + { + // 7905F431-B5CE-4E99-A40F-4B1E122D00D0 + 0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4, + 0x99, 0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79 + } +}; + + +/**@brief 128-bit control point UUID. + */ +const ble_uuid128_t ble_ancs_cp_base_uuid128 = +{ + { + // 69d1d8f3-45e1-49a8-9821-9BBDFDAAD9D9 + 0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98, + 0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69 + } +}; + +/**@brief 128-bit notification source UUID. +*/ +const ble_uuid128_t ble_ancs_ns_base_uuid128 = +{ + { + // 9FBF120D-6301-42D9-8C58-25E699A21DBD + 0xbd, 0x1d, 0xa2, 0x99, 0xe6, 0x25, 0x58, 0x8c, + 0xd9, 0x42, 0x01, 0x63, 0x0d, 0x12, 0xbf, 0x9f + + } +}; + +/**@brief 128-bit data source UUID. +*/ +const ble_uuid128_t ble_ancs_ds_base_uuid128 = +{ + { + // 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB + 0xfb, 0x7b, 0x7c, 0xce, 0x6a, 0xb3, 0x44, 0xbe, + 0xb5, 0x4b, 0xd6, 0x24, 0xe9, 0xc6, 0xea, 0x22 + } +}; + + +/**@brief Function for handling Disconnected event received from the SoftDevice. + * + * @details This function check if the disconnect event is happening on the link + * associated with the current instance of the module, if so it will set its + * conn_handle to invalid. + * + * @param[in] p_ancs Pointer to the ANCS client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_disconnected(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt) +{ + if (p_ancs->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_ancs->conn_handle = BLE_CONN_HANDLE_INVALID; + } +} + + +void ble_ancs_c_on_db_disc_evt(ble_ancs_c_t * p_ancs, ble_db_discovery_evt_t * p_evt) +{ + NRF_LOG_INFO("Database Discovery handler called with event 0x%x\r\n", p_evt->evt_type); + + ble_ancs_c_evt_t evt; + ble_gatt_db_char_t * p_chars; + + p_chars = p_evt->params.discovered_db.charateristics; + + // Check if the ANCS Service was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && + p_evt->params.discovered_db.srv_uuid.uuid == ANCS_UUID_SERVICE && + p_evt->params.discovered_db.srv_uuid.type == p_ancs->service.service.uuid.type) + { + // Find the handles of the ANCS characteristic. + uint32_t i; + + for (i = 0; i < p_evt->params.discovered_db.char_count; i++) + { + switch (p_chars[i].characteristic.uuid.uuid) + { + case ANCS_UUID_CHAR_CONTROL_POINT: + NRF_LOG_INFO("Control Point Characteristic found.\r\n"); + memcpy(&evt.service.control_point_char, + &p_chars[i].characteristic, + sizeof(ble_gattc_char_t)); + break; + + case ANCS_UUID_CHAR_DATA_SOURCE: + NRF_LOG_INFO("Data Source Characteristic found.\r\n"); + memcpy(&evt.service.data_source_char, + &p_chars[i].characteristic, + sizeof(ble_gattc_char_t)); + evt.service.data_source_cccd.handle = p_chars[i].cccd_handle; + break; + + case ANCS_UUID_CHAR_NOTIFICATION_SOURCE: + NRF_LOG_INFO("Notification point Characteristic found.\r\n"); + memcpy(&evt.service.notif_source_char, + &p_chars[i].characteristic, + sizeof(ble_gattc_char_t)); + evt.service.notif_source_cccd.handle = p_chars[i].cccd_handle; + break; + + default: + break; + } + } + evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_COMPLETE; + evt.conn_handle = p_evt->conn_handle; + p_ancs->evt_handler(&evt); + } + else + { + evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_FAILED; + p_ancs->evt_handler(&evt); + } +} + + +/**@brief Function for checking if data in an iOS notification is out of bounds. + * + * @param[in] notif An iOS notification. + * + * @retval NRF_SUCCESS If the notification is within bounds. + * @retval NRF_ERROR_INVALID_PARAM If the notification is out of bounds. + */ +static uint32_t ble_ancs_verify_notification_format(const ble_ancs_c_evt_notif_t * notif) +{ + if( (notif->evt_id >= BLE_ANCS_NB_OF_EVT_ID) + || (notif->category_id >= BLE_ANCS_NB_OF_CATEGORY_ID)) + { + return NRF_ERROR_INVALID_PARAM; + } + return NRF_SUCCESS; +} + +/**@brief Function for receiving and validating notifications received from the Notification Provider. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] hvx_len Length of the data that was received by the Notification Provider. + */ +static void parse_notif(const ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + const uint16_t hvx_data_len) +{ + ble_ancs_c_evt_t ancs_evt; + uint32_t err_code; + if (hvx_data_len != BLE_ANCS_NOTIFICATION_DATA_LENGTH) + { + ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF; + p_ancs->evt_handler(&ancs_evt); + } + + /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */ + ancs_evt.notif.evt_id = + (ble_ancs_c_evt_id_values_t) p_data_src[BLE_ANCS_NOTIF_EVT_ID_INDEX]; + + ancs_evt.notif.evt_flags.silent = + (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_SILENT) & 0x01; + + ancs_evt.notif.evt_flags.important = + (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_IMPORTANT) & 0x01; + + ancs_evt.notif.evt_flags.pre_existing = + (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_PREEXISTING) & 0x01; + + ancs_evt.notif.evt_flags.positive_action = + (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION) & 0x01; + + ancs_evt.notif.evt_flags.negative_action = + (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION) & 0x01; + + ancs_evt.notif.category_id = + (ble_ancs_c_category_id_val_t) p_data_src[BLE_ANCS_NOTIF_CATEGORY_ID_INDEX]; + + ancs_evt.notif.category_count = p_data_src[BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX]; + ancs_evt.notif.notif_uid = uint32_decode(&p_data_src[BLE_ANCS_NOTIF_NOTIF_UID]); + /*lint -restore*/ + + err_code = ble_ancs_verify_notification_format(&ancs_evt.notif); + if (err_code == NRF_SUCCESS) + { + ancs_evt.evt_type = BLE_ANCS_C_EVT_NOTIF; + } + else + { + ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF; + } + + p_ancs->evt_handler(&ancs_evt); +} + + +ret_code_t nrf_ble_ancs_c_app_attr_request(ble_ancs_c_t * p_ancs, + const uint8_t * p_app_id, + uint32_t len) +{ + return ancs_c_app_attr_request(p_ancs, p_app_id, len); +} + + +/**@brief Function for receiving and validating notifications received from the Notification Provider. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_ble_evt Bluetooth stack event. + */ +static void on_evt_gattc_notif(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt) +{ + const ble_gattc_evt_hvx_t * p_notif = &p_ble_evt->evt.gattc_evt.params.hvx; + + if(p_ble_evt->evt.gattc_evt.conn_handle != p_ancs->conn_handle) + { + return; + } + + if (p_notif->handle == p_ancs->service.notif_source_char.handle_value) + { + parse_notif(p_ancs, p_notif->data, p_notif->len); + } + else if (p_notif->handle == p_ancs->service.data_source_char.handle_value) + { + ancs_parse_get_attrs_response(p_ancs, p_notif->data, p_notif->len); + } + else + { + // No applicable action. + } +} + +/**@brief Function for handling error response events. + * + * @param[in] p_ancs_c Pointer to the Battery Service Client Structure. + * @param[in] p_ble_evt Pointer to the SoftDevice event. + */ +static void on_ctrlpt_error_rsp(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt) +{ + ble_ancs_c_evt_t ancs_evt; + + ancs_evt.evt_type = BLE_ANCS_C_EVT_NP_ERROR; + ancs_evt.err_code_np = p_ble_evt->evt.gattc_evt.gatt_status; + + p_ancs->evt_handler(&ancs_evt); +} + +/**@brief Function for handling write response events. + * + * @param[in] p_ancs_c Pointer to the Battery Service Client Structure. + * @param[in] p_ble_evt Pointer to the SoftDevice event. + */ +static void on_write_rsp(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt) +{ + // Check if the event if on the link for this instance + if (p_ancs->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + if ((p_ble_evt->evt.gattc_evt.error_handle != BLE_GATT_HANDLE_INVALID) + && (p_ble_evt->evt.gattc_evt.error_handle == p_ancs->service.control_point_char.handle_value)) + { + on_ctrlpt_error_rsp(p_ancs,p_ble_evt); + } + // Check if there is any message to be sent across to the peer and send it. + tx_buffer_process(); +} + + +void ble_ancs_c_on_ble_evt(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt) +{ + uint16_t evt = p_ble_evt->header.evt_id; + + switch (evt) + { + case BLE_GATTC_EVT_WRITE_RSP: + on_write_rsp(p_ancs, p_ble_evt); + break; + + case BLE_GATTC_EVT_HVX: + on_evt_gattc_notif(p_ancs, p_ble_evt); + break; + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_ancs, p_ble_evt); + break; + default: + break; + } +} + + +ret_code_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, const ble_ancs_c_init_t * p_ancs_init) +{ + uint32_t err_code; + + //Verify that the parameters needed for to initialize this instance of ANCS are not NULL. + VERIFY_PARAM_NOT_NULL(p_ancs); + VERIFY_PARAM_NOT_NULL(p_ancs_init); + VERIFY_PARAM_NOT_NULL(p_ancs_init->evt_handler); + + //Initialize state for the attribute parsing state machine. + p_ancs->parse_info.parse_state = COMMAND_ID; + p_ancs->parse_info.p_data_dest = NULL; + p_ancs->parse_info.current_attr_index = 0; + p_ancs->parse_info.current_app_id_index = 0; + + p_ancs->evt_handler = p_ancs_init->evt_handler; + p_ancs->error_handler = p_ancs_init->error_handler; + p_ancs->conn_handle = BLE_CONN_HANDLE_INVALID; + + p_ancs->service.data_source_cccd.uuid.uuid = BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG; + p_ancs->service.notif_source_cccd.uuid.uuid = BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG; + + // Make sure instance of service is clear. GATT handles inside the service and characteristics are set to @ref BLE_GATT_HANDLE_INVALID. + memset(&p_ancs->service, 0, sizeof(ble_ancs_c_service_t)); + tx_buffer_init(); + + // Assign UUID types. + err_code = sd_ble_uuid_vs_add(&ble_ancs_base_uuid128, &p_ancs->service.service.uuid.type); + VERIFY_SUCCESS(err_code); + + err_code = sd_ble_uuid_vs_add(&ble_ancs_cp_base_uuid128, &p_ancs->service.control_point_char.uuid.type); + VERIFY_SUCCESS(err_code); + + err_code = sd_ble_uuid_vs_add(&ble_ancs_ns_base_uuid128, &p_ancs->service.notif_source_char.uuid.type); + VERIFY_SUCCESS(err_code); + + err_code = sd_ble_uuid_vs_add(&ble_ancs_ds_base_uuid128, &p_ancs->service.data_source_char.uuid.type); + VERIFY_SUCCESS(err_code); + + // Assign UUID to the service. + p_ancs->service.service.uuid.uuid = ANCS_UUID_SERVICE; + p_ancs->service.service.uuid.type = p_ancs->service.service.uuid.type; + + return ble_db_discovery_evt_register(&p_ancs->service.service.uuid); +} + + +/**@brief Function for creating a TX message for writing a CCCD. + * + * @param[in] conn_handle Connection handle on which to perform the configuration. + * @param[in] handle_cccd Handle of the CCCD. + * @param[in] enable Enable or disable GATTC notifications. + * + * @retval NRF_SUCCESS If the message was created successfully. + * @retval NRF_ERROR_INVALID_PARAM If one of the input parameters was invalid. + */ +static uint32_t cccd_configure(const uint16_t conn_handle, const uint16_t handle_cccd, bool enable) +{ + tx_message_t p_msg; + memset(&p_msg, 0, sizeof(tx_message_t)); + uint16_t cccd_val = enable ? BLE_CCCD_NOTIFY_BIT_MASK : 0; + + p_msg.req.write_req.gattc_params.handle = handle_cccd; + p_msg.req.write_req.gattc_params.len = 2; + p_msg.req.write_req.gattc_params.p_value = p_msg.req.write_req.gattc_value; + p_msg.req.write_req.gattc_params.offset = 0; + p_msg.req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + p_msg.req.write_req.gattc_value[0] = LSB_16(cccd_val); + p_msg.req.write_req.gattc_value[1] = MSB_16(cccd_val); + p_msg.conn_handle = conn_handle; + p_msg.type = WRITE_REQ; + + tx_buffer_insert(&p_msg); + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +ret_code_t ble_ancs_c_notif_source_notif_enable(const ble_ancs_c_t * p_ancs) +{ + NRF_LOG_INFO("Enable Notification Source notifications. writing to handle: %i \r\n", + p_ancs->service.notif_source_cccd.handle); + return cccd_configure(p_ancs->conn_handle, p_ancs->service.notif_source_cccd.handle, true); +} + + +ret_code_t ble_ancs_c_notif_source_notif_disable(const ble_ancs_c_t * p_ancs) +{ + return cccd_configure(p_ancs->conn_handle, p_ancs->service.notif_source_cccd.handle, false); +} + + +ret_code_t ble_ancs_c_data_source_notif_enable(const ble_ancs_c_t * p_ancs) +{ + NRF_LOG_INFO("Enable Data Source notifications. Writing to handle: %i \r\n", + p_ancs->service.data_source_cccd.handle); + return cccd_configure(p_ancs->conn_handle, p_ancs->service.data_source_cccd.handle, true); +} + + +ret_code_t ble_ancs_c_data_source_notif_disable(const ble_ancs_c_t * p_ancs) +{ + return cccd_configure(p_ancs->conn_handle, p_ancs->service.data_source_cccd.handle, false); +} + + +uint32_t ble_ancs_get_notif_attrs(ble_ancs_c_t * p_ancs, + const uint32_t p_uid) +{ + tx_message_t p_msg; + memset(&p_msg, 0, sizeof(tx_message_t)); + + uint32_t index = 0; + p_ancs->number_of_requested_attr = 0; + + + p_msg.req.write_req.gattc_params.handle = p_ancs->service.control_point_char.handle_value; + p_msg.req.write_req.gattc_params.p_value = p_msg.req.write_req.gattc_value; + p_msg.req.write_req.gattc_params.offset = 0; + p_msg.req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + + //Encode Command ID. + p_msg.req.write_req.gattc_value[index++] = BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES; + + //Encode Notification UID. + index += uint32_encode(p_uid, &(p_msg.req.write_req.gattc_value[index])); + + //Encode Attribute ID. + for (uint32_t attr = 0; attr < BLE_ANCS_NB_OF_NOTIF_ATTR; attr++) + { + if (p_ancs->ancs_notif_attr_list[attr].get == true) + { + p_msg.req.write_req.gattc_value[index++] = attr; + if ((attr == BLE_ANCS_NOTIF_ATTR_ID_TITLE) || + (attr == BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE) || + (attr == BLE_ANCS_NOTIF_ATTR_ID_MESSAGE)) + { + //Encode Length field, only applicable for Title, Subtitle and Message + index += uint16_encode(p_ancs->ancs_notif_attr_list[attr].attr_len, + &(p_msg.req.write_req.gattc_value[index])); + } + p_ancs->number_of_requested_attr++; + } + } + p_msg.req.write_req.gattc_params.len = index; + p_msg.conn_handle = p_ancs->conn_handle; + p_msg.type = WRITE_REQ; + p_ancs->parse_info.expected_number_of_attrs = p_ancs->number_of_requested_attr; + + tx_buffer_insert(&p_msg); + tx_buffer_process(); + + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_ancs_c_attr_add(ble_ancs_c_t * p_ancs, + const ble_ancs_c_notif_attr_id_val_t id, + uint8_t * p_data, + const uint16_t len) +{ + VERIFY_PARAM_NOT_NULL(p_data); + + if((len == 0) || (len > BLE_ANCS_ATTR_DATA_MAX)) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_ancs->ancs_notif_attr_list[id].get = true; + p_ancs->ancs_notif_attr_list[id].attr_len = len; + p_ancs->ancs_notif_attr_list[id].p_attr_data = p_data; + + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_ancs_c_app_attr_add(ble_ancs_c_t * p_ancs, + const ble_ancs_c_app_attr_id_val_t id, + uint8_t * p_data, + const uint16_t len) +{ + VERIFY_PARAM_NOT_NULL(p_ancs); + VERIFY_PARAM_NOT_NULL(p_data); + + if((len == 0) || (len > BLE_ANCS_ATTR_DATA_MAX)) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_ancs->ancs_app_attr_list[id].get = true; + p_ancs->ancs_app_attr_list[id].attr_len = len; + p_ancs->ancs_app_attr_list[id].p_attr_data = p_data; + + return NRF_SUCCESS; +} + +ret_code_t ble_ancs_c_app_attr_remove(ble_ancs_c_t * p_ancs, + const ble_ancs_c_app_attr_id_val_t id) +{ + p_ancs->ancs_app_attr_list[id].get = false; + p_ancs->ancs_app_attr_list[id].attr_len = 0; + p_ancs->ancs_app_attr_list[id].p_attr_data = NULL; + return NRF_SUCCESS; +} + +ret_code_t ble_ancs_c_notif_attr_remove(ble_ancs_c_t * p_ancs, + const ble_ancs_c_notif_attr_id_val_t id) +{ + p_ancs->ancs_notif_attr_list[id].get = false; + p_ancs->ancs_notif_attr_list[id].attr_len = 0; + p_ancs->ancs_notif_attr_list[id].p_attr_data = NULL; + return NRF_SUCCESS; +} + +ret_code_t nrf_ble_ancs_c_attr_req_clear_all(ble_ancs_c_t * p_ancs) +{ + memset(p_ancs->ancs_notif_attr_list, 0 , sizeof(p_ancs->ancs_notif_attr_list)); + memset(p_ancs->ancs_app_attr_list, 0 , sizeof(p_ancs->ancs_app_attr_list)); + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_ancs_c_request_attrs(ble_ancs_c_t * p_ancs, + const ble_ancs_c_evt_notif_t * p_notif) +{ + uint32_t err_code; + err_code = ble_ancs_verify_notification_format(p_notif); + VERIFY_SUCCESS(err_code); + + err_code = ble_ancs_get_notif_attrs(p_ancs, p_notif->notif_uid); + p_ancs->parse_info.parse_state = COMMAND_ID; + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} + +static uint16_t encode_notif_action(uint8_t * p_encoded_data, uint32_t uid, ble_ancs_c_action_id_values_t action_id) +{ + uint8_t index = 0; + + p_encoded_data[index++] = BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION; + index += uint32_encode(uid, &p_encoded_data[index]); + p_encoded_data[index++] = (uint8_t)action_id; + + return index; +} + +ret_code_t nrf_ancs_perform_notif_action(ble_ancs_c_t * p_ancs, uint32_t uid, ble_ancs_c_action_id_values_t action_id) +{ + VERIFY_PARAM_NOT_NULL(p_ancs); + + tx_message_t msg; + memset(&msg, 0, sizeof(tx_message_t)); + + uint16_t len = 0; + + len = encode_notif_action(msg.req.write_req.gattc_value, uid, action_id); + + msg.req.write_req.gattc_params.handle = p_ancs->service.control_point_char.handle_value; + msg.req.write_req.gattc_params.p_value = msg.req.write_req.gattc_value; + msg.req.write_req.gattc_params.offset = 0; + msg.req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + + msg.req.write_req.gattc_params.len = len; + msg.conn_handle = p_ancs->conn_handle; + msg.type = WRITE_REQ; + + tx_buffer_insert(&msg); + tx_buffer_process(); + + return NRF_SUCCESS; +} + +ret_code_t nrf_ble_ancs_c_handles_assign(ble_ancs_c_t * p_ancs, + const uint16_t conn_handle, + const ble_ancs_c_service_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ancs); + + p_ancs->conn_handle = conn_handle; + + if(p_peer_handles != NULL) + { + p_ancs->service.control_point_char.handle_value = p_peer_handles->control_point_char.handle_value; + p_ancs->service.data_source_cccd.handle = p_peer_handles->data_source_cccd.handle; + p_ancs->service.data_source_char.handle_value = p_peer_handles->data_source_char.handle_value; + p_ancs->service.notif_source_cccd.handle = p_peer_handles->notif_source_cccd.handle; + p_ancs->service.notif_source_char.handle_value = p_peer_handles->notif_source_char.handle_value; + } + + return NRF_SUCCESS; +} + +#endif// NRF_MODULE_ENABLED(BLE_ANCS_C) + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h new file mode 100644 index 0000000000000000000000000000000000000000..1a59445a9028326c3d01107e1595187a0a74e5d8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h @@ -0,0 +1,581 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_ancs_c Apple Notification Service client + * @{ + * @ingroup ble_sdk_srv + * + * @brief Apple Notification Center Service Client Module. + * + * @details Disclaimer: This client implementation of the Apple Notification Center Service can + * be changed at any time by Nordic Semiconductor ASA. Server implementations such as the + * ones found in iOS can be changed at any time by Apple and may cause this client + * implementation to stop working. + * + * This module implements the Apple Notification Center Service (ANCS) client. + * This client can be used as a Notification Consumer (NC) that receives data + * notifications from a Notification Provider (NP). The NP is typically an iOS + * device acting as a server. For terminology and up-to-date specs, see + * http://developer.apple.com. + * + * The term "notification" is used in two different meanings: + * - An iOS notification is the data received from the Notification Provider. + * - A GATTC notification is a way to transfer data with Bluetooth Smart. + * In this module, we receive iOS notifications using GATTC notifications. + * We use the full term (iOS notification or GATTC notification) where required to avoid confusion. + * + * Upon initializing the module, you must add the different iOS notification attributes you + * would like to receive for iOS notifications (see @ref nrf_ble_ancs_c_attr_add). + * + * Once a connection is established with a central device, the module does a service discovery to + * discover the ANCS server handles. If this succeeds (@ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE), + * the handles for the ANCS server are part of the @ref ble_ancs_c_evt_t structure and must be + * assigned to an ANCS_C instance using the @ref nrf_ble_ancs_c_handles_assign function. For more + * information about service discovery, see the @ref lib_ble_db_discovery documentation. + * + * The application can now subscribe to iOS notifications using + * @ref ble_ancs_c_notif_source_notif_enable. They arrive in the @ref BLE_ANCS_C_EVT_NOTIF event. + * @ref nrf_ble_ancs_c_request_attrs can be used to request attributes for the notifications. They + * arrive in the @ref BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE event. + * @ref nrf_ble_ancs_c_app_attr_request can be used to request attributes of the app that issued + * the notifications. They arrive in the @ref BLE_ANCS_C_EVT_APP_ATTRIBUTE event. + * @ref nrf_ancs_perform_notif_action can be used to make the Notification Provider perform an + * action based on the provided notification. + * + * @msc + * hscale = "1.5"; + * Application, ANCS_C; + * |||; + * Application=>ANCS_C [label = "ble_ancs_c_attr_add(attribute)"]; + * Application=>ANCS_C [label = "ble_ancs_c_init(ancs_instance, event_handler)"]; + * ...; + * Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_DISCOVERY_COMPLETE"]; + * Application=>ANCS_C [label = "ble_ancs_c_handles_assign(ancs_instance, conn_handle, service_handles)"]; + * Application=>ANCS_C [label = "ble_ancs_c_notif_source_notif_enable(ancs_instance)"]; + * Application=>ANCS_C [label = "ble_ancs_c_data_source_notif_enable(ancs_instance)"]; + * |||; + * ...; + * |||; + * Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_NOTIF"]; + * |||; + * ...; + * |||; + * Application=>ANCS_C [label = "ble_ancs_c_request_attrs(attr_id, buffer)"]; + * Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE"]; + * |||; + * @endmsc + * + * @note The application must propagate BLE stack events to this module + * by calling ble_ancs_c_on_ble_evt() from the @ref softdevice_handler callback. + */ +#ifndef BLE_ANCS_C_H__ +#define BLE_ANCS_C_H__ + +#include "ble_types.h" +#include "ble_srv_common.h" +#include "sdk_errors.h" +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif +#define BLE_ANCS_ATTR_DATA_MAX 32 //!< Maximum data length of an iOS notification attribute. +#define BLE_ANCS_NB_OF_CATEGORY_ID 12 //!< Number of iOS notification categories: Other, Incoming Call, Missed Call, Voice Mail, Social, Schedule, Email, News, Health And Fitness, Business And Finance, Location, Entertainment. +#define BLE_ANCS_NB_OF_NOTIF_ATTR 8 //!< Number of iOS notification attributes: AppIdentifier, Title, Subtitle, Message, MessageSize, Date, PositiveActionLabel, NegativeActionLabel. +#define BLE_ANCS_NB_OF_APP_ATTR 1 //!< Number of iOS application attributes: DisplayName. +#define BLE_ANCS_NB_OF_EVT_ID 3 //!< Number of iOS notification events: Added, Modified, Removed. + +/** @brief Length of the iOS notification data. + * + * @details 8 bytes: + * Event ID |Event flags |Category ID |Category count|Notification UID + * ---------|------------|------------|--------------|---------------- + * 1 byte | 1 byte | 1 byte | 1 byte | 4 bytes + */ +#define BLE_ANCS_NOTIFICATION_DATA_LENGTH 8 + +#define ANCS_UUID_SERVICE 0xF431 //!< 16-bit service UUID for the Apple Notification Center Service. +#define ANCS_UUID_CHAR_CONTROL_POINT 0xD8F3 //!< 16-bit control point UUID. +#define ANCS_UUID_CHAR_DATA_SOURCE 0xC6E9 //!< 16-bit data source UUID. +#define ANCS_UUID_CHAR_NOTIFICATION_SOURCE 0x120D //!< 16-bit notification source UUID. + +#define BLE_ANCS_EVENT_FLAG_SILENT 0 //!< 0b.......1 Silent: First (LSB) bit is set. All flags can be active at the same time. +#define BLE_ANCS_EVENT_FLAG_IMPORTANT 1 //!< 0b......1. Important: Second (LSB) bit is set. All flags can be active at the same time. +#define BLE_ANCS_EVENT_FLAG_PREEXISTING 2 //!< 0b.....1.. Pre-existing: Third (LSB) bit is set. All flags can be active at the same time. +#define BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION 3 //!< 0b....1... Positive action: Fourth (LSB) bit is set. All flags can be active at the same time. +#define BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION 4 //!< 0b...1.... Negative action: Fifth (LSB) bit is set. All flags can be active at the same time. + +/** @defgroup BLE_ANCS_NP_ERROR_CODES Notification Provider (iOS) Error Codes + * @{ */ +#define BLE_ANCS_NP_UNKNOWN_COMMAND 0x01A0 //!< The command ID is unknown to the NP. +#define BLE_ANCS_NP_INVALID_COMMAND 0x01A1 //!< The command format is invalid. +#define BLE_ANCS_NP_INVALID_PARAMETER 0x01A2 //!< One or more parameters does not exist in the NP. +#define BLE_ANCS_NP_ACTION_FAILED 0x01A3 //!< The action failed to be performed by the NP. +/** @} */ + +/**@brief Event types that are passed from client to application on an event. */ +typedef enum +{ + BLE_ANCS_C_EVT_DISCOVERY_COMPLETE, /**< A successful connection has been established and the service was found on the connected peer. */ + BLE_ANCS_C_EVT_DISCOVERY_FAILED, /**< It was not possible to discover the service or characteristics of the connected peer. */ + BLE_ANCS_C_EVT_NOTIF, /**< An iOS notification was received on the notification source control point. */ + BLE_ANCS_C_EVT_INVALID_NOTIF, /**< An iOS notification was received on the notification source control point, but the format is invalid. */ + BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE, /**< A received iOS notification attribute has been parsed. */ + BLE_ANCS_C_EVT_APP_ATTRIBUTE, /**< An iOS app attribute has been parsed. */ + BLE_ANCS_C_EVT_NP_ERROR, /**< An error has been sent on the ANCS Control Point from the iOS Notification Provider. */ +} ble_ancs_c_evt_type_t; + +/**@brief Category IDs for iOS notifications. */ +typedef enum +{ + BLE_ANCS_CATEGORY_ID_OTHER, /**< The iOS notification belongs to the "other" category. */ + BLE_ANCS_CATEGORY_ID_INCOMING_CALL, /**< The iOS notification belongs to the "Incoming Call" category. */ + BLE_ANCS_CATEGORY_ID_MISSED_CALL, /**< The iOS notification belongs to the "Missed Call" category. */ + BLE_ANCS_CATEGORY_ID_VOICE_MAIL, /**< The iOS notification belongs to the "Voice Mail" category. */ + BLE_ANCS_CATEGORY_ID_SOCIAL, /**< The iOS notification belongs to the "Social" category. */ + BLE_ANCS_CATEGORY_ID_SCHEDULE, /**< The iOS notification belongs to the "Schedule" category. */ + BLE_ANCS_CATEGORY_ID_EMAIL, /**< The iOS notification belongs to the "E-mail" category. */ + BLE_ANCS_CATEGORY_ID_NEWS, /**< The iOS notification belongs to the "News" category. */ + BLE_ANCS_CATEGORY_ID_HEALTH_AND_FITNESS, /**< The iOS notification belongs to the "Health and Fitness" category. */ + BLE_ANCS_CATEGORY_ID_BUSINESS_AND_FINANCE, /**< The iOS notification belongs to the "Buisness and Finance" category. */ + BLE_ANCS_CATEGORY_ID_LOCATION, /**< The iOS notification belongs to the "Location" category. */ + BLE_ANCS_CATEGORY_ID_ENTERTAINMENT /**< The iOS notification belongs to the "Entertainment" category. */ +} ble_ancs_c_category_id_val_t; + +/**@brief Event IDs for iOS notifications. */ +typedef enum +{ + BLE_ANCS_EVENT_ID_NOTIFICATION_ADDED, /**< The iOS notification was added. */ + BLE_ANCS_EVENT_ID_NOTIFICATION_MODIFIED, /**< The iOS notification was modified. */ + BLE_ANCS_EVENT_ID_NOTIFICATION_REMOVED /**< The iOS notification was removed. */ +} ble_ancs_c_evt_id_values_t; + +/**@brief Control point command IDs that the Notification Consumer can send to the Notification Provider. */ +typedef enum +{ + BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given notification. */ + BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given iOS app. */ + BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION, /**< Requests an action to be performed on a given notification, for example, dismiss an alarm. */ +} ble_ancs_c_cmd_id_val_t; + +/**@brief IDs for actions that can be performed for iOS notifications. */ +typedef enum +{ + ACTION_ID_POSITIVE = 0, /**< Positive action. */ + ACTION_ID_NEGATIVE /**< Negative action. */ +} ble_ancs_c_action_id_values_t; + +/**@brief App attribute ID values. + * @details Currently, only one value is defined. However, the number of app + * attributes might increase. Therefore, they are stored in an enumeration. + */ +typedef enum +{ + BLE_ANCS_APP_ATTR_ID_DISPLAY_NAME = 0 /**< Command used to get the display name for an app identifier. */ +} ble_ancs_c_app_attr_id_val_t; + +/**@brief IDs for iOS notification attributes. */ +typedef enum +{ + BLE_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER = 0, /**< Identifies that the attribute data is of an "App Identifier" type. */ + BLE_ANCS_NOTIF_ATTR_ID_TITLE, /**< Identifies that the attribute data is a "Title". */ + BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE, /**< Identifies that the attribute data is a "Subtitle". */ + BLE_ANCS_NOTIF_ATTR_ID_MESSAGE, /**< Identifies that the attribute data is a "Message". */ + BLE_ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE, /**< Identifies that the attribute data is a "Message Size". */ + BLE_ANCS_NOTIF_ATTR_ID_DATE, /**< Identifies that the attribute data is a "Date". */ + BLE_ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL, /**< The notification has a "Positive action" that can be executed associated with it. */ + BLE_ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL, /**< The notification has a "Negative action" that can be executed associated with it. */ +} ble_ancs_c_notif_attr_id_val_t; + + +/**@brief Flags for iOS notifications. */ +typedef struct +{ + uint8_t silent : 1; //!< If this flag is set, the notification has a low priority. + uint8_t important : 1; //!< If this flag is set, the notification has a high priority. + uint8_t pre_existing : 1; //!< If this flag is set, the notification is pre-existing. + uint8_t positive_action : 1; //!< If this flag is set, the notification has a positive action that can be taken. + uint8_t negative_action : 1; //!< If this flag is set, the notification has a negative action that can be taken. +} ble_ancs_c_notif_flags_t; + + +/**@brief Parsing states for received iOS notification and app attributes. + */ +typedef enum +{ + COMMAND_ID, /**< Parsing the command ID. */ + NOTIF_UID, /**< Parsing the notification UID. */ + APP_ID, /**< Parsing app ID. */ + ATTR_ID, /**< Parsing attribute ID. */ + ATTR_LEN1, /**< Parsing the LSB of the attribute length. */ + ATTR_LEN2, /**< Parsing the MSB of the attribute length. */ + ATTR_DATA, /**< Parsing the attribute data. */ + ATTR_SKIP, /**< Parsing is skipped for the rest (or entire) of an attribute. */ + DONE, /**< Parsing for one attribute is done. */ +} ble_ancs_c_parse_state_t; + + +/**@brief iOS notification structure. */ +typedef struct +{ + uint32_t notif_uid; //!< Notification UID. + ble_ancs_c_evt_id_values_t evt_id; //!< Whether the notification was added, removed, or modified. + ble_ancs_c_notif_flags_t evt_flags; //!< Bitmask to signal if a special condition applies to the notification, for example, "Silent" or "Important". + ble_ancs_c_category_id_val_t category_id; //!< Classification of the notification type, for example, email or location. + uint8_t category_count; //!< Current number of active notifications for this category ID. +} ble_ancs_c_evt_notif_t; + + +/**@brief iOS attribute structure. This type is used for both notification attributes and app attributes. */ +typedef struct +{ + uint16_t attr_len; //!< Length of the received attribute data. + uint32_t attr_id; //!< Classification of the attribute type, for example, title or date. + uint8_t * p_attr_data; //!< Pointer to where the memory is allocated for storing incoming attributes. +} ble_ancs_c_attr_t; + +/**@brief iOS notification attribute structure for incoming attributes. */ +typedef struct +{ + uint32_t notif_uid; //!< UID of the notification that the attribute belongs to. + ble_ancs_c_attr_t attrs; //!< A received attribute. +} ble_ancs_c_evt_attr_t; + +typedef struct +{ + uint16_t attr_len; //!< Length of the received attribute data. + uint32_t attr_id; //!< Classification of the attribute type, for example, title or date. + uint8_t * p_attr_data; //!< Pointer to where the memory is allocated for storing incoming attributes. +} ble_ancs_c_evt_app_attr_t; + +/**@brief iOS notification attribute content wanted by our application. */ +typedef struct +{ + bool get; //!< Boolean to determine if this attribute will be requested from the Notification Provider. + uint32_t attr_id; //!< Attribute ID: AppIdentifier(0), Title(1), Subtitle(2), Message(3), MessageSize(4), Date(5), PositiveActionLabel(6), NegativeActionLabel(7). + uint16_t attr_len; //!< Length of the attribute. If more data is received from the Notification Provider, all data beyond this length is discarded. + uint8_t * p_attr_data; //!< Pointer to where the memory is allocated for storing incoming attributes. +} ble_ancs_c_attr_list_t; + + +/**@brief Structure used for holding the Apple Notification Center Service found during the + discovery process. + */ +typedef struct +{ + ble_gattc_service_t service; //!< The GATT Service holding the discovered Apple Notification Center Service. (0xF431). + ble_gattc_char_t control_point_char; //!< ANCS Control Point Characteristic. Allows interaction with the peer (0xD8F3). + ble_gattc_char_t notif_source_char; //!< ANCS Notification Source Characteristic. Keeps track of arrival, modification, and removal of notifications (0x120D). + ble_gattc_desc_t notif_source_cccd; //!< ANCS Notification Source Characteristic Descriptor. Enables or disables GATT notifications. + ble_gattc_char_t data_source_char; //!< ANCS Data Source Characteristic, where attribute data for the notifications is received from peer (0xC6E9). + ble_gattc_desc_t data_source_cccd; //!< ANCS Data Source Characteristic Descriptor. Enables or disables GATT notifications. +} ble_ancs_c_service_t; + + +/**@brief ANCS client module event structure. + * + * @details The structure contains the event that should be handled by the main application. + */ +typedef struct +{ + ble_ancs_c_evt_type_t evt_type; //!< Type of event. + uint16_t conn_handle; //!< Connection handle on which the ANCS service was discovered on the peer device. This field will be filled if the @p evt_type is @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE. + ble_ancs_c_evt_notif_t notif; //!< iOS notification. This field will be filled if @p evt_type is @ref BLE_ANCS_C_EVT_NOTIF. + uint16_t err_code_np; //!< An error coming from the Notification Provider. This field will be filled with @ref BLE_ANCS_NP_ERROR_CODES if @p evt_type is @ref BLE_ANCS_C_EVT_NP_ERROR. + ble_ancs_c_attr_t attr; //!< iOS notification attribute or app attribute, depending on the event type. + uint32_t notif_uid; //!< Notification UID. + uint8_t app_id[BLE_ANCS_ATTR_DATA_MAX]; //!< App identifier. + ble_ancs_c_service_t service; //!< Information on the discovered Alert Notification Service. This field will be filled if the @p evt_type is @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE. +} ble_ancs_c_evt_t; + + +/**@brief iOS notification event handler type. */ +typedef void (*ble_ancs_c_evt_handler_t) (ble_ancs_c_evt_t * p_evt); + + +typedef struct +{ + ble_ancs_c_attr_list_t * p_attr_list; //!< The current list of attributes being parsed. This field will point to either @ref ble_ancs_c_t::ancs_notif_attr_list or @ref ble_ancs_c_t::ancs_app_attr_list. + uint32_t nb_of_attr; //!< Number of possible attributes. When parsing begins, it is set to either @ref BLE_ANCS_NB_OF_NOTIF_ATTR or @ref BLE_ANCS_NB_OF_APP_ATTR. + uint32_t expected_number_of_attrs; //!< The number of attributes expected upon receiving attributes. Keeps track of when to stop reading incoming attributes. + ble_ancs_c_parse_state_t parse_state; //!< ANCS notification attribute parsing state. + ble_ancs_c_cmd_id_val_t command_id; //!< Variable to keep track of what command type we are currently parsing ( @ref BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES or @ref BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES. + uint8_t * p_data_dest; //!< Attribute that the parsed data will be copied into. + uint16_t current_attr_index; //!< Variable to keep track of how much (for a given attribute) we are done parsing. + uint32_t current_app_id_index; //!< Variable to keep track of how much (for a given app identifier) we are done parsing. +} ble_ancs_parse_sm_t; + + +/**@brief iOS notification structure, which contains various status information for the client. */ +typedef struct +{ + ble_ancs_c_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Apple Notification client application. + ble_srv_error_handler_t error_handler; //!< Function to be called in case of an error. + uint16_t conn_handle; //!< Handle of the current connection. Set with @ref nrf_ble_ancs_c_handles_assign when connected. + ble_ancs_c_service_t service; //!< Structure to store the different handles and UUIDs related to the service. + ble_ancs_c_attr_list_t ancs_notif_attr_list[BLE_ANCS_NB_OF_NOTIF_ATTR]; //!< For all attributes; contains whether they should be requested upon attribute request and the length and buffer of where to store attribute data. + ble_ancs_c_attr_list_t ancs_app_attr_list[BLE_ANCS_NB_OF_APP_ATTR]; //!< For all app attributes; contains whether they should be requested upon attribute request and the length and buffer of where to store attribute data. + uint32_t number_of_requested_attr; //!< The number of attributes that will be requested when an iOS notification attribute request is made. + ble_ancs_parse_sm_t parse_info; //!< Structure containing different information used to parse incoming attributes (from data_source characteristic) correctly. + ble_ancs_c_evt_t evt; //!< The event is filled with several iterations of the @ref ancs_parse_get_attrs_response function when requesting iOS notification attributes. So we must allocate memory for it here. +} ble_ancs_c_t; + + +/**@brief Apple Notification client init structure, which contains all options and data needed for + * initialization of the client. */ +typedef struct +{ + ble_ancs_c_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Battery Service. + ble_srv_error_handler_t error_handler; //!< Function to be called in case of an error. +} ble_ancs_c_init_t; + + + +/**@brief Apple Notification Center Service UUIDs. */ +extern const ble_uuid128_t ble_ancs_base_uuid128; //!< Service UUID. +extern const ble_uuid128_t ble_ancs_cp_base_uuid128; //!< Control point UUID. +extern const ble_uuid128_t ble_ancs_ns_base_uuid128; //!< Notification source UUID. +extern const ble_uuid128_t ble_ancs_ds_base_uuid128; //!< Data source UUID. + + +/**@brief Function for handling the application's BLE stack events. + * + * @details Handles all events from the BLE stack that are of interest to the ANCS client. + * + * @param[in] p_ancs ANCS client structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_ancs_c_on_ble_evt(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt); + + +/**@brief Function for handling events from the database discovery module. + * + * @details This function will handle an event from the database discovery module and determine + * if it relates to the discovery of ANCS at the peer. If so, it will + * call the application's event handler indicating that ANCS has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param[in] p_ancs Pointer to the ANCS client structure. + * @param[in] p_evt Pointer to the event received from the database discovery module. + */ + void ble_ancs_c_on_db_disc_evt(ble_ancs_c_t * p_ancs, ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for initializing the ANCS client. + * + * @param[out] p_ancs ANCS client structure. This structure must be + * supplied by the application. It is initialized by this function + * and will later be used to identify this particular client instance. + * @param[in] p_ancs_init Information needed to initialize the client. + * + * @retval NRF_SUCCESS If the client was initialized successfully. Otherwise, an error code is returned. + */ +ret_code_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, const ble_ancs_c_init_t * p_ancs_init); + + +/**@brief Function for writing to the CCCD to enable notifications from the Apple Notification Service. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * + * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned. + */ +ret_code_t ble_ancs_c_notif_source_notif_enable(const ble_ancs_c_t * p_ancs); + + +/**@brief Function for writing to the CCCD to enable data source notifications from the ANCS. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * + * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned. + */ +ret_code_t ble_ancs_c_data_source_notif_enable(const ble_ancs_c_t * p_ancs); + + +/**@brief Function for writing to the CCCD to disable notifications from the ANCS. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * + * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned. + */ +ret_code_t ble_ancs_c_notif_source_notif_disable(const ble_ancs_c_t * p_ancs); + + +/**@brief Function for writing to the CCCD to disable data source notifications from the ANCS. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * + * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned. + */ +ret_code_t ble_ancs_c_data_source_notif_disable(const ble_ancs_c_t * p_ancs); + + +/**@brief Function for registering attributes that will be requested when @ref nrf_ble_ancs_c_request_attrs + * is called. + * + * @param[in] p_ancs ANCS client instance on which the attribute will be registered. + * @param[in] id ID of the attribute that will be added. + * @param[in] p_data Pointer to a buffer where the data of the attribute can be stored. + * @param[in] len Length of the buffer where the data of the attribute can be stored. + + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_ancs_c_attr_add(ble_ancs_c_t * p_ancs, + const ble_ancs_c_notif_attr_id_val_t id, + uint8_t * p_data, + const uint16_t len); + + +/**@brief Function for removing attributes so that they will no longer be requested when + * @ref nrf_ble_ancs_c_request_attrs is called. + * + * @param[in] p_ancs ANCS client instance on which the attribute will be removed. + * @param[in] id ID of the attribute that will be removed. + * + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_ancs_c_attr_remove(ble_ancs_c_t * p_ancs, + const ble_ancs_c_notif_attr_id_val_t id); + +/**@brief Function for removing attributes so that they will no longer be requested when + * @ref nrf_ble_ancs_c_app_attr_request is called. + * + * @param[in] p_ancs ANCS client instance on which the attribute will be removed. + * @param[in] id ID of the attribute that will be removed. + * + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_ancs_c_app_attr_remove(ble_ancs_c_t * p_ancs, + const ble_ancs_c_app_attr_id_val_t id); + + +/**@brief Function for registering attributes that will be requested when @ref nrf_ble_ancs_c_app_attr_request + * is called. + * + * @param[in] p_ancs ANCS client instance on which the attribute will be registered. + * @param[in] id ID of the attribute that will be added. + * @param[in] p_data Pointer to a buffer where the data of the attribute can be stored. + * @param[in] len Length of the buffer where the data of the attribute can be stored. + * + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_ancs_c_app_attr_add(ble_ancs_c_t * p_ancs, + const ble_ancs_c_app_attr_id_val_t id, + uint8_t * p_data, + const uint16_t len); + +/**@brief Function for clearing the list of notification attributes and app attributes that + * would be requested from NP. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. +**/ +ret_code_t nrf_ble_ancs_c_attr_req_clear_all(ble_ancs_c_t * p_ancs); + +/**@brief Function for requesting attributes for a notification. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] p_notif Pointer to the notification whose attributes will be requested from + * the Notification Provider. + * + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_ancs_c_request_attrs(ble_ancs_c_t * p_ancs, + const ble_ancs_c_evt_notif_t * p_notif); + +/**@brief Function for requesting attributes for a given app. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] p_app_id App identifier of the app for which the app attributes are requested. + * @param[in] len Length of the app identifier. + * + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_ancs_c_app_attr_request(ble_ancs_c_t * p_ancs, + const uint8_t * p_app_id, + uint32_t len); + + +/**@brief Function for performing a notification action. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] uuid The UUID of the notification for which to perform the action. + * @param[in] action_id Perform a positive or negative action. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If @p p_ancs was a NULL pointer. + */ +ret_code_t nrf_ancs_perform_notif_action(ble_ancs_c_t * p_ancs, + uint32_t uuid, + ble_ancs_c_action_id_values_t action_id); + +/**@brief Function for assigning a handle to this instance of ancs_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to this instance of the module. This makes it + * possible to handle several link and associate each link to a particular + * instance of this module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ancs Pointer to the ANCS client structure instance to associate with these + * handles. + * @param[in] conn_handle Connection handle to associate with the given ANCS instance. + * @param[in] p_service Attribute handles on the ANCS server that you want this ANCS client to + * interact with. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If @p p_ancs was a NULL pointer. + */ +ret_code_t nrf_ble_ancs_c_handles_assign(ble_ancs_c_t * p_ancs, + const uint16_t conn_handle, + const ble_ancs_c_service_t * p_service); + +#endif // BLE_ANCS_C_H__ + +/** @} */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ans_c/ble_ans_c.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ans_c/ble_ans_c.c new file mode 100644 index 0000000000000000000000000000000000000000..83f4b0af43089f8d475c1630e39a0235e772a515 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ans_c/ble_ans_c.c @@ -0,0 +1,574 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_ANS_C) +#include "ble_ans_c.h" +#include +#include +#include "ble_err.h" +#include "ble_srv_common.h" +#include "nrf_assert.h" +#include "ble_db_discovery.h" +#define NRF_LOG_MODULE_NAME "BLE_ANS_C" +#include "nrf_log.h" + +#define NOTIFICATION_DATA_LENGTH 2 /**< The mandatory length of notification data. After the mandatory data, the optional message is located. */ +#define READ_DATA_LENGTH_MIN 1 /**< Minimum data length in a valid Alert Notification Read Response message. */ + +#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of contiguous zeroes, followed by contiguous sequence of ones: 000...111. */ +#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */ +#define WRITE_MESSAGE_LENGTH 2 /**< Length of the write message for CCCD/control point. */ + + +typedef enum +{ + READ_REQ = 1, /**< Type identifying that this tx_message is a read request. */ + WRITE_REQ /**< Type identifying that this tx_message is a write request. */ +} ans_tx_request_t; + + +/**@brief Structure for writing a message to the central, i.e. Control Point or CCCD. + */ +typedef struct +{ + uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */ + ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */ +} ans_write_params_t; + +/**@brief Structure for holding data to be transmitted to the connected central. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */ + ans_tx_request_t type; /**< Type of this message, i.e. read or write message. */ + union + { + uint16_t read_handle; /**< Read request message. */ + ans_write_params_t write_req; /**< Write request message. */ + } req; +} ans_tx_message_t; + +static ans_tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */ +static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where next message should be inserted. */ +static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */ + + +/**@brief Function for passing any pending request from the buffer to the stack. + */ +static void tx_buffer_process(void) +{ + if (m_tx_index != m_tx_insert_index) + { + uint32_t err_code; + + if (m_tx_buffer[m_tx_index].type == READ_REQ) + { + err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle, + m_tx_buffer[m_tx_index].req.read_handle, + 0); + } + else + { + err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle, + &m_tx_buffer[m_tx_index].req.write_req.gattc_params); + } + if (err_code == NRF_SUCCESS) + { + ++m_tx_index; + m_tx_index &= TX_BUFFER_MASK; + } + } +} + + +/** @brief Function for copying a characteristic. + */ +static void char_set(ble_gattc_char_t * p_dest_char, const ble_gattc_char_t * p_source_char) +{ + memcpy(p_dest_char, p_source_char, sizeof(ble_gattc_char_t)); +} + +static void char_cccd_set(ble_gattc_desc_t * p_cccd, const uint16_t cccd_handle) +{ + p_cccd->handle = cccd_handle; +} + +/** @brief Function to check that all handles required by the client to use the server are present. + */ +static bool is_valid_ans_srv_discovered(const ble_ans_c_service_t * p_srv) +{ + if ((p_srv->alert_notif_ctrl_point.handle_value == BLE_GATT_HANDLE_INVALID) || + (p_srv->suported_new_alert_cat.handle_value == BLE_GATT_HANDLE_INVALID) || + (p_srv->suported_unread_alert_cat.handle_value == BLE_GATT_HANDLE_INVALID) || + (p_srv->new_alert.handle_value == BLE_GATT_HANDLE_INVALID) || + (p_srv->unread_alert_status.handle_value == BLE_GATT_HANDLE_INVALID) || + (p_srv->new_alert_cccd.handle == BLE_GATT_HANDLE_INVALID) || + (p_srv->unread_alert_cccd.handle == BLE_GATT_HANDLE_INVALID) + ) + { + // At least one required characteristic is missing on the server side. + return false; + } + return true; +} + + +void ble_ans_c_on_db_disc_evt(ble_ans_c_t * p_ans, const ble_db_discovery_evt_t * p_evt) +{ + ble_ans_c_evt_t evt; + + memset(&evt, 0, sizeof(ble_ans_c_evt_t)); + evt.conn_handle = p_evt->conn_handle; + evt.evt_type = BLE_ANS_C_EVT_DISCOVERY_FAILED; + + // Check if the Alert Notification Service was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE + && + p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_ALERT_NOTIFICATION_SERVICE + && + p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) + { + // Find the characteristics inside the service. + for (uint8_t i = 0; i < p_evt->params.discovered_db.char_count; i++) + { + const ble_gatt_db_char_t * p_char = &(p_evt->params.discovered_db.charateristics[i]); + + switch (p_char->characteristic.uuid.uuid) + { + case BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR: + NRF_LOG_DEBUG("Found Ctrlpt \r\n\r"); + char_set(&evt.data.service.alert_notif_ctrl_point, &p_char->characteristic); + break; + + case BLE_UUID_UNREAD_ALERT_CHAR: + NRF_LOG_DEBUG("Found Unread Alert \r\n\r"); + char_set(&evt.data.service.unread_alert_status, &p_char->characteristic); + char_cccd_set(&evt.data.service.unread_alert_cccd, + p_char->cccd_handle); + break; + + case BLE_UUID_NEW_ALERT_CHAR: + NRF_LOG_DEBUG("Found New Alert \r\n\r"); + char_set(&evt.data.service.new_alert, &p_char->characteristic); + char_cccd_set(&evt.data.service.new_alert_cccd, + p_char->cccd_handle); + break; + + case BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR: + NRF_LOG_DEBUG("Found supported unread alert category \r\n\r"); + char_set(&evt.data.service.suported_unread_alert_cat, &p_char->characteristic); + break; + + case BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR: + NRF_LOG_DEBUG("Found supported new alert category \r\n\r"); + char_set(&evt.data.service.suported_new_alert_cat, &p_char->characteristic); + break; + + default: + // No implementation needed. + break; + } + } + if (is_valid_ans_srv_discovered(&evt.data.service)) + { + evt.evt_type = BLE_ANS_C_EVT_DISCOVERY_COMPLETE; + } + } + p_ans->evt_handler(&evt); +} + + +/**@brief Function for receiving and validating notifications received from the central. + */ +static void event_notify(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) +{ + uint32_t message_length; + ble_ans_c_evt_t event; + ble_ans_alert_notification_t * p_alert = &event.data.alert; + const ble_gattc_evt_hvx_t * p_notification = &p_ble_evt->evt.gattc_evt.params.hvx; + + // Message is not valid -> ignore. + event.evt_type = BLE_ANS_C_EVT_NOTIFICATION; + if (p_notification->len < NOTIFICATION_DATA_LENGTH) + { + return; + } + message_length = p_notification->len - NOTIFICATION_DATA_LENGTH; + + if (p_notification->handle == p_ans->service.new_alert.handle_value) + { + BLE_UUID_COPY_INST(event.uuid, p_ans->service.new_alert.uuid); + } + else if (p_notification->handle == p_ans->service.unread_alert_status.handle_value) + { + BLE_UUID_COPY_INST(event.uuid, p_ans->service.unread_alert_status.uuid); + } + else + { + // Nothing to process. + return; + } + + p_alert->alert_category = p_notification->data[0]; + p_alert->alert_category_count = p_notification->data[1]; //lint !e415 + p_alert->alert_msg_length = (message_length > p_ans->message_buffer_size) + ? p_ans->message_buffer_size + : message_length; + p_alert->p_alert_msg_buf = p_ans->p_message_buffer; + + memcpy(p_alert->p_alert_msg_buf, + &p_notification->data[NOTIFICATION_DATA_LENGTH], + p_alert->alert_msg_length); //lint !e416 + + p_ans->evt_handler(&event); +} + + +/**@brief Function for handling write response events. + */ +static void event_write_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) +{ + tx_buffer_process(); +} + + +/**@brief Function for validating and passing the response to the application, + * when a read response is received. + */ +static void event_read_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) +{ + ble_ans_c_evt_t event; + const ble_gattc_evt_read_rsp_t * p_response; + + p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp; + event.evt_type = BLE_ANS_C_EVT_READ_RESP; + + if (p_response->len < READ_DATA_LENGTH_MIN) + { + tx_buffer_process(); + return; + } + + if (p_response->handle == p_ans->service.suported_new_alert_cat.handle_value) + { + BLE_UUID_COPY_INST(event.uuid, p_ans->service.suported_new_alert_cat.uuid); + } + else if (p_response->handle == p_ans->service.suported_unread_alert_cat.handle_value) + { + BLE_UUID_COPY_INST(event.uuid, p_ans->service.suported_unread_alert_cat.uuid); + } + else + { + // Bad response, ignore. + tx_buffer_process(); + return; + } + + event.data.settings = *(ble_ans_alert_settings_t *)(p_response->data); + + if (p_response->len == READ_DATA_LENGTH_MIN) + { + // Those must default to 0, if they are not returned by central. + event.data.settings.ans_high_prioritized_alert_support = 0; + event.data.settings.ans_instant_message_support = 0; + } + + p_ans->evt_handler(&event); + + tx_buffer_process(); +} + + +/**@brief Function for disconnecting and cleaning the current service. + */ +static void event_disconnect(ble_ans_c_t * p_ans, ble_evt_t const * p_ble_evt) +{ + if (p_ans->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_ans->conn_handle = BLE_CONN_HANDLE_INVALID; + + // Clearing all data for the service will also set all handle values to @ref BLE_GATT_HANDLE_INVALID + memset(&p_ans->service, 0, sizeof(ble_ans_c_service_t)); + + // There was a valid instance of IAS on the peer. Send an event to the + // application, so that it can do any clean up related to this module. + ble_ans_c_evt_t evt; + + evt.evt_type = BLE_ANS_C_EVT_DISCONN_COMPLETE; + p_ans->evt_handler(&evt); + } +} + + +/**@brief Function for handling of BLE stack events. + */ +void ble_ans_c_on_ble_evt(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTC_EVT_HVX: + event_notify(p_ans, p_ble_evt); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + event_write_rsp(p_ans, p_ble_evt); + break; + + case BLE_GATTC_EVT_READ_RSP: + event_read_rsp(p_ans, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + event_disconnect(p_ans, p_ble_evt); + break; + } +} + + +uint32_t ble_ans_c_init(ble_ans_c_t * p_ans, const ble_ans_c_init_t * p_ans_init) +{ + VERIFY_PARAM_NOT_NULL(p_ans); + VERIFY_PARAM_NOT_NULL(p_ans_init); + VERIFY_PARAM_NOT_NULL(p_ans_init->evt_handler); + + // clear all handles + memset(p_ans, 0, sizeof(ble_ans_c_t)); + memset(m_tx_buffer, 0, TX_BUFFER_SIZE); + p_ans->conn_handle = BLE_CONN_HANDLE_INVALID; + + p_ans->evt_handler = p_ans_init->evt_handler; + p_ans->error_handler = p_ans_init->error_handler; + p_ans->message_buffer_size = p_ans_init->message_buffer_size; + p_ans->p_message_buffer = p_ans_init->p_message_buffer; + + BLE_UUID_BLE_ASSIGN(p_ans->service.service.uuid, BLE_UUID_ALERT_NOTIFICATION_SERVICE); + BLE_UUID_BLE_ASSIGN(p_ans->service.new_alert.uuid, BLE_UUID_NEW_ALERT_CHAR); + BLE_UUID_BLE_ASSIGN(p_ans->service.alert_notif_ctrl_point.uuid, + BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR); + BLE_UUID_BLE_ASSIGN(p_ans->service.unread_alert_status.uuid, BLE_UUID_UNREAD_ALERT_CHAR); + BLE_UUID_BLE_ASSIGN(p_ans->service.suported_new_alert_cat.uuid, + BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR); + BLE_UUID_BLE_ASSIGN(p_ans->service.suported_unread_alert_cat.uuid, + BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR); + + BLE_UUID_BLE_ASSIGN(p_ans->service.new_alert_cccd.uuid, BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG); + BLE_UUID_BLE_ASSIGN(p_ans->service.unread_alert_cccd.uuid, + BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG); + + return ble_db_discovery_evt_register(&p_ans->service.service.uuid); +} + + +/**@brief Function for creating a TX message for writing a CCCD. + */ +static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable) +{ + ans_tx_message_t * p_msg; + uint16_t cccd_val = enable ? BLE_GATT_HVX_NOTIFICATION : 0; + + p_msg = &m_tx_buffer[m_tx_insert_index++]; + m_tx_insert_index &= TX_BUFFER_MASK; + + p_msg->req.write_req.gattc_params.handle = handle_cccd; + p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH; + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + p_msg->req.write_req.gattc_params.offset = 0; + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val); + p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val); + p_msg->conn_handle = conn_handle; + p_msg->type = WRITE_REQ; + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +uint32_t ble_ans_c_enable_notif_new_alert(const ble_ans_c_t * p_ans) +{ + if (p_ans->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + else + { + return cccd_configure(p_ans->conn_handle, + p_ans->service.new_alert_cccd.handle, + true); + } +} + + +uint32_t ble_ans_c_disable_notif_new_alert(const ble_ans_c_t * p_ans) +{ + return cccd_configure(p_ans->conn_handle, + p_ans->service.new_alert_cccd.handle, + false); +} + + +uint32_t ble_ans_c_enable_notif_unread_alert(const ble_ans_c_t * p_ans) +{ + if ( p_ans->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + return cccd_configure(p_ans->conn_handle, + p_ans->service.unread_alert_cccd.handle, + true); +} + + +uint32_t ble_ans_c_disable_notif_unread_alert(const ble_ans_c_t * p_ans) +{ + return cccd_configure(p_ans->conn_handle, + p_ans->service.unread_alert_cccd.handle, + false); +} + + +uint32_t ble_ans_c_control_point_write(const ble_ans_c_t * p_ans, + const ble_ans_control_point_t * p_control_point) +{ + ans_tx_message_t * p_msg; + + p_msg = &m_tx_buffer[m_tx_insert_index++]; + m_tx_insert_index &= TX_BUFFER_MASK; + + p_msg->req.write_req.gattc_params.handle = p_ans->service.alert_notif_ctrl_point.handle_value; + p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH; + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + p_msg->req.write_req.gattc_params.offset = 0; + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + p_msg->req.write_req.gattc_value[0] = p_control_point->command; + p_msg->req.write_req.gattc_value[1] = p_control_point->category; + p_msg->conn_handle = p_ans->conn_handle; + p_msg->type = WRITE_REQ; + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +uint32_t ble_ans_c_new_alert_read(const ble_ans_c_t * p_ans) +{ + ans_tx_message_t * msg; + + msg = &m_tx_buffer[m_tx_insert_index++]; + m_tx_insert_index &= TX_BUFFER_MASK; + + msg->req.read_handle = p_ans->service.suported_new_alert_cat.handle_value; + msg->conn_handle = p_ans->conn_handle; + msg->type = READ_REQ; + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +uint32_t ble_ans_c_unread_alert_read(const ble_ans_c_t * p_ans) +{ + ans_tx_message_t * msg; + + msg = &m_tx_buffer[m_tx_insert_index++]; + m_tx_insert_index &= TX_BUFFER_MASK; + + msg->req.read_handle = p_ans->service.suported_unread_alert_cat.handle_value; + msg->conn_handle = p_ans->conn_handle; + msg->type = READ_REQ; + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +uint32_t ble_ans_c_new_alert_notify(const ble_ans_c_t * p_ans, ble_ans_category_id_t category_id) +{ + ble_ans_control_point_t control_point; + + control_point.command = ANS_NOTIFY_NEW_INCOMING_ALERT_IMMEDIATELY; + control_point.category = category_id; + + return ble_ans_c_control_point_write(p_ans, &control_point); +} + + +uint32_t ble_ans_c_unread_alert_notify(const ble_ans_c_t * p_ans, ble_ans_category_id_t category_id) +{ + ble_ans_control_point_t control_point; + + control_point.command = ANS_NOTIFY_UNREAD_CATEGORY_STATUS_IMMEDIATELY; + control_point.category = category_id; + + return ble_ans_c_control_point_write(p_ans, &control_point); +} + + +uint32_t ble_ans_c_handles_assign(ble_ans_c_t * p_ans, + const uint16_t conn_handle, + const ble_ans_c_service_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ans); + + if (!is_valid_ans_srv_discovered(p_peer_handles)) + { + return NRF_ERROR_INVALID_PARAM; + } + p_ans->conn_handle = conn_handle; + + if (p_peer_handles != NULL) + { + // Copy the handles from the discovered characteristics over to the provided client instance. + char_set(&p_ans->service.alert_notif_ctrl_point, &p_peer_handles->alert_notif_ctrl_point); + char_set(&p_ans->service.suported_new_alert_cat, &p_peer_handles->suported_new_alert_cat); + char_set(&p_ans->service.suported_unread_alert_cat, &p_peer_handles->suported_unread_alert_cat); + char_set(&p_ans->service.new_alert, &p_peer_handles->new_alert); + char_cccd_set(&p_ans->service.new_alert_cccd, p_peer_handles->new_alert_cccd.handle); + char_set(&p_ans->service.unread_alert_status, &p_peer_handles->unread_alert_status); + char_cccd_set(&p_ans->service.unread_alert_cccd, p_peer_handles->unread_alert_cccd.handle); + } + + return NRF_SUCCESS; +} +#endif // NRF_MODULE_ENABLED(BLE_ANS_C) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ans_c/ble_ans_c.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ans_c/ble_ans_c.h new file mode 100644 index 0000000000000000000000000000000000000000..25fe2ec9bd37dea1c81c98edd8245f9d553f95ed --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ans_c/ble_ans_c.h @@ -0,0 +1,385 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_ans_c Alert Notification Service Client + * @{ + * @ingroup ble_sdk_srv + * @brief Alert Notification module. + * + * @details This module implements the Alert Notification Client according to the + * Alert Notification Profile. + * + * @note The application must propagate BLE stack events to the Alert Notification Client module + * by calling ble_ans_c_on_ble_evt() from the @ref softdevice_handler callback. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ +#ifndef BLE_ANS_C_H__ +#define BLE_ANS_C_H__ + +#include "ble.h" +#include "ble_gatts.h" +#include "ble_types.h" +#include "sdk_common.h" +#include "ble_srv_common.h" +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +// Forward declaration of the ble_ans_c_t type. +typedef struct ble_ans_c_s ble_ans_c_t; + +/** Alerts types as defined in the alert category id; UUID: 0x2A43. */ +typedef enum +{ + ANS_TYPE_SIMPLE_ALERT = 0, /**< General text alert or non-text alert.*/ + ANS_TYPE_EMAIL = 1, /**< Alert when email messages arrives.*/ + ANS_TYPE_NEWS = 2, /**< News feeds such as RSS, Atom.*/ + ANS_TYPE_NOTIFICATION_CALL = 3, /**< Incoming call.*/ + ANS_TYPE_MISSED_CALL = 4, /**< Missed call.*/ + ANS_TYPE_SMS_MMS = 5, /**< SMS/MMS message arrives.*/ + ANS_TYPE_VOICE_MAIL = 6, /**< Voice mail.*/ + ANS_TYPE_SCHEDULE = 7, /**< Alert occurred on calendar, planner.*/ + ANS_TYPE_HIGH_PRIORITIZED_ALERT = 8, /**< Alert that should be handled as high priority.*/ + ANS_TYPE_INSTANT_MESSAGE = 9, /**< Alert for incoming instant messages.*/ + ANS_TYPE_ALL_ALERTS = 0xFF /**< Identifies All Alerts. */ +} ble_ans_category_id_t; + +/** Alerts notification control point commands as defined in the Alert Notification Specification; + * UUID: 0x2A44. + */ +typedef enum +{ + ANS_ENABLE_NEW_INCOMING_ALERT_NOTIFICATION = 0, /**< Enable New Incoming Alert Notification.*/ + ANS_ENABLE_UNREAD_CATEGORY_STATUS_NOTIFICATION = 1, /**< Enable Unread Category Status Notification.*/ + ANS_DISABLE_NEW_INCOMING_ALERT_NOTIFICATION = 2, /**< Disable New Incoming Alert Notification.*/ + ANS_DISABLE_UNREAD_CATEGORY_STATUS_NOTIFICATION = 3, /**< Disable Unread Category Status Notification.*/ + ANS_NOTIFY_NEW_INCOMING_ALERT_IMMEDIATELY = 4, /**< Notify New Incoming Alert immediately.*/ + ANS_NOTIFY_UNREAD_CATEGORY_STATUS_IMMEDIATELY = 5, /**< Notify Unread Category Status immediately.*/ +} ble_ans_command_id_t; + +/**@brief Alert Notification Event types that are passed from client to application on an event. */ +typedef enum +{ + BLE_ANS_C_EVT_DISCOVERY_COMPLETE, /**< A successful connection has been established and the characteristics of the server has been fetched. */ + BLE_ANS_C_EVT_DISCOVERY_FAILED, /**< It was not possible to discover service or characteristics of the connected peer. */ + BLE_ANS_C_EVT_DISCONN_COMPLETE, /**< The connection has been taken down. */ + BLE_ANS_C_EVT_NOTIFICATION, /**< A valid Alert Notification has been received from the server.*/ + BLE_ANS_C_EVT_READ_RESP, /**< A read response has been received from the server.*/ + BLE_ANS_C_EVT_WRITE_RESP /**< A write response has been received from the server.*/ +} ble_ans_c_evt_type_t; + +/**@brief Alert Notification Control Point structure. */ +typedef struct +{ + ble_ans_command_id_t command; /**< The command to be written to the control point, see @ref ble_ans_command_id_t. */ + ble_ans_category_id_t category; /**< The category for the control point for which the command applies, see @ref ble_ans_category_id_t. */ +} ble_ans_control_point_t; + +/**@brief Alert Notification Setting structure containing the supported alerts in the service. + * + *@details + * The structure contains bit fields describing which alerts that are supported: + * 0 = Unsupported + * 1 = Supported + */ +typedef struct +{ + uint8_t ans_simple_alert_support : 1; /**< Support for General text alert or non-text alert.*/ + uint8_t ans_email_support : 1; /**< Support for Alert when email messages arrives.*/ + uint8_t ans_news_support : 1; /**< Support for News feeds such as RSS, Atom.*/ + uint8_t ans_notification_call_support : 1; /**< Support for Incoming call.*/ + uint8_t ans_missed_call_support : 1; /**< Support for Missed call.*/ + uint8_t ans_sms_mms_support : 1; /**< Support for SMS/MMS message arrives.*/ + uint8_t ans_voice_mail_support : 1; /**< Support for Voice mail.*/ + uint8_t ans_schedule_support : 1; /**< Support for Alert occurred on calendar, planner.*/ + uint8_t ans_high_prioritized_alert_support : 1; /**< Support for Alert that should be handled as high priority.*/ + uint8_t ans_instant_message_support : 1; /**< Support for Alert for incoming instant messages.*/ + uint8_t reserved : 6; /**< Reserved for future use. */ +} ble_ans_alert_settings_t; + +/**@brief Alert Notification structure + */ +typedef struct +{ + uint8_t alert_category; /**< Alert category to which this alert belongs.*/ + uint8_t alert_category_count; /**< Number of alerts in the category. */ + uint32_t alert_msg_length; /**< Length of optional text message send by the server. */ + uint8_t * p_alert_msg_buf; /**< Pointer to buffer containing the optional text message. */ +} ble_ans_alert_notification_t; + + +/**@brief Struct to hold information on the Alert Notification Service if found on the server. +*/ +typedef struct +{ + ble_gattc_service_t service; /**< The GATT service holding the discovered Alert Notification Service. */ + ble_gattc_char_t alert_notif_ctrl_point; /**< Characteristic for the Alert Notification Control Point. @ref BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR */ + ble_gattc_char_t suported_new_alert_cat; /**< Characteristic for the Supported New Alert category. @ref BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR */ + ble_gattc_char_t suported_unread_alert_cat; /**< Characteristic for the Unread Alert category. @ref BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR */ + ble_gattc_char_t new_alert; /**< Characteristic for the New Alert Notification. @ref BLE_UUID_NEW_ALERT_CHAR */ + ble_gattc_desc_t new_alert_cccd; /**< Characteristic Descriptor for New Alert Category. Enables or Disables GATT notifications */ + ble_gattc_char_t unread_alert_status; /**< Characteristic for the Unread Alert Notification. @ref BLE_UUID_UNREAD_ALERT_CHAR */ + ble_gattc_desc_t unread_alert_cccd; /**< Characteristic Descriptor for Unread Alert Category. Enables or Disables GATT notifications */ +} ble_ans_c_service_t; + + +/**@brief Alert Notification Event structure + * + * @details The structure contains the event that should be handled, as well as + * additional information. + */ +typedef struct +{ + ble_ans_c_evt_type_t evt_type; /**< Type of event. */ + uint16_t conn_handle; /**< Connection handle on which the ANS service was discovered on the peer device. This will be filled if the evt_type is @ref BLE_ANS_C_EVT_DISCOVERY_COMPLETE.*/ + ble_uuid_t uuid; /**< UUID of the event in case of an alert or notification. */ + union + { + ble_ans_alert_settings_t settings; /**< Setting returned from server on read request. */ + ble_ans_alert_notification_t alert; /**< Alert Notification data sent by the server. */ + uint32_t error_code; /**< Additional status/error code if the event was caused by a stack error or gatt status, e.g. during service discovery. */ + ble_ans_c_service_t service; /**< Info on the discovered Alert Notification Service discovered. This will be filled if the evt_type is @ref BLE_ANS_C_EVT_DISCOVERY_COMPLETE.*/ + } data; +} ble_ans_c_evt_t; + +/**@brief Alert Notification event handler type. */ +typedef void (*ble_ans_c_evt_handler_t) (ble_ans_c_evt_t * p_evt); + + +/**@brief Alert Notification structure. This contains various status information for the client. */ +struct ble_ans_c_s +{ + ble_ans_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Alert Notification Client Application. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ + uint8_t central_handle; /**< Handle for the currently connected central if peer is bonded. */ + uint8_t service_handle; /**< Handle to the service in the database to use for this instance. */ + uint32_t message_buffer_size; /**< Size of message buffer to hold the additional text messages received on notifications. */ + uint8_t * p_message_buffer; /**< Pointer to the buffer to be used for additional text message handling. */ + ble_ans_c_service_t service; /**< Struct to store the different handles and UUIDs related to the service. */ +}; + +/**@brief Alert Notification init structure. This contains all options and data needed for + * initialization of the client.*/ +typedef struct +{ + ble_ans_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + uint32_t message_buffer_size; /**< Size of buffer to handle messages. */ + uint8_t * p_message_buffer; /**< Pointer to buffer for passing messages. */ +} ble_ans_c_init_t; + + +/**@brief Function for handling events from the database discovery module. + * + * @details Call this function when getting a callback event from the DB discovery modue. + * This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of heart rate service at the peer. If so, it will + * call the application's event handler indicating that the heart rate service has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param[in] p_ans Pointer to the Alert Notification client structure instance that will handle + * the discovery. + * @param[in] p_evt Pointer to the event received from the database discovery module. + */ +void ble_ans_c_on_db_disc_evt(ble_ans_c_t * p_ans, const ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the Alert Notification Client. + * + * @param[in] p_ans Alert Notification Client structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_ans_c_on_ble_evt(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt); + + +/**@brief Function for initializing the Alert Notification Client. + * + * @param[out] p_ans Alert Notification Client structure. This structure will have to be + * supplied by the application. It will be initialized by this function, + * and will later be used to identify this particular client instance. + * @param[in] p_ans_init Information needed to initialize the client. + * + * @return NRF_SUCCESS on successful initialization of client, otherwise an error code. + */ +uint32_t ble_ans_c_init(ble_ans_c_t * p_ans, const ble_ans_c_init_t * p_ans_init); + + +/**@brief Function for writing the to CCCD to enable new alert notifications from the Alert Notification Service. + * + * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by + * the application. It identifies the particular client instance to use. + * + * @return NRF_SUCCESS on successful writing of the CCCD, otherwise an error code. + */ +uint32_t ble_ans_c_enable_notif_new_alert(const ble_ans_c_t * p_ans); + + +/**@brief Function for writing to the CCCD to enable unread alert notifications from the Alert Notification Service. + * + * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by + * the application. It identifies the particular client instance to use. + * + * @return NRF_SUCCESS on successful writing of the CCCD, otherwise an error code. + */ +uint32_t ble_ans_c_enable_notif_unread_alert(const ble_ans_c_t * p_ans); + + +/**@brief Function for writing to the CCCD to disable new alert notifications from the Alert Notification Service. + * + * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by + * the application. It identifies the particular client instance to use. + * + * @return NRF_SUCCESS on successful writing of the CCCD, otherwise an error code. + */ +uint32_t ble_ans_c_disable_notif_new_alert(const ble_ans_c_t * p_ans); + + +/**@brief Function for writing to the CCCD to disable unread alert notifications from the Alert Notification Service. + * + * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by + * the application. It identifies the particular client instance to use. + * + * @return NRF_SUCCESS on successful writing of the CCCD, otherwise an error code. + */ +uint32_t ble_ans_c_disable_notif_unread_alert(const ble_ans_c_t * p_ans); + + +/**@brief Function for writing to the Alert Notification Control Point to specify alert notification behavior in the + * Alert Notification Service on the Central. + * + * @param[in] p_ans Alert Notification structure. This structure will have to be + * supplied by the application. It identifies the particular client + * instance to use. + * @param[in] p_control_point Alert Notification Control Point structure. This structure + * specifies the values to write to the Alert Notification Control + * Point, UUID 0x2A44. + * + * @return NRF_SUCCESS on successful writing of the Control Point, otherwise an error code. + */ +uint32_t ble_ans_c_control_point_write(const ble_ans_c_t * p_ans, + const ble_ans_control_point_t * p_control_point); + + +/**@brief Function for reading the Supported New Alert characteristic value of the service. + * The value describes the alerts supported in the central. + * + * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by + * the application. It identifies the particular client instance to use. + * + * @return NRF_SUCCESS on successful transmission of the read request, otherwise an error code. + */ +uint32_t ble_ans_c_new_alert_read(const ble_ans_c_t * p_ans); + + +/**@brief Function for reading the Supported Unread Alert characteristic value of the service. + * The value describes the alerts supported in the central. + * + * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by + * the application. It identifies the particular client instance to use. + * + * @return NRF_SUCCESS on successful transmission of the read request, otherwise an error code. + */ +uint32_t ble_ans_c_unread_alert_read(const ble_ans_c_t * p_ans); + + +/**@brief Function for requesting the peer to notify the New Alert characteristics immediately. + * + * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] category The category ID for which the peer should notify the client. + * + * @return NRF_SUCCESS on successful transmission of the read request, otherwise an error code. + */ +uint32_t ble_ans_c_new_alert_notify(const ble_ans_c_t * p_ans, ble_ans_category_id_t category); + + +/**@brief Function for requesting the peer to notify the Unread Alert characteristics immediately. + * + * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] category The category ID for which the peer should notify the client. + * + * @return NRF_SUCCESS on successful transmission of the read request, otherwise an error code. + */ +uint32_t ble_ans_c_unread_alert_notify(const ble_ans_c_t * p_ans, ble_ans_category_id_t category); + + +/**@brief Function for assigning a handles to a an instance of ans_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to an instance of the module. This makes it + * possible to handle several link and associate each link to a particular + * instance of the ans_c module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_ANS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ans Pointer to the Alert Notification client structure instance to + * associate with the handles. + * @param[in] conn_handle Connection handle to associated with the given Alert Notification Client + * Instance. + * @param[in] p_peer_handles Attribute handles on the ANS server that you want this ANS client to + * interact with. + * + */ +uint32_t ble_ans_c_handles_assign(ble_ans_c_t * p_ans, + const uint16_t conn_handle, + const ble_ans_c_service_t * p_peer_handles); + + + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_ANS_C_H__ + +/** @} */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bas/ble_bas.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bas/ble_bas.c new file mode 100644 index 0000000000000000000000000000000000000000..a80799962180126fd3310082a333507292e030af --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bas/ble_bas.c @@ -0,0 +1,343 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_BAS) +#include "ble_bas.h" +#include +#include "ble_srv_common.h" + + +#define INVALID_BATTERY_LEVEL 255 + + +/**@brief Function for handling the Connect event. + * + * @param[in] p_bas Battery Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_bas_t * p_bas, ble_evt_t * p_ble_evt) +{ + p_bas->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; +} + + +/**@brief Function for handling the Disconnect event. + * + * @param[in] p_bas Battery Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_bas_t * p_bas, ble_evt_t * p_ble_evt) +{ + UNUSED_PARAMETER(p_ble_evt); + p_bas->conn_handle = BLE_CONN_HANDLE_INVALID; +} + + +/**@brief Function for handling the Write event. + * + * @param[in] p_bas Battery Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_bas_t * p_bas, ble_evt_t * p_ble_evt) +{ + if (p_bas->is_notification_supported) + { + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if ( + (p_evt_write->handle == p_bas->battery_level_handles.cccd_handle) + && + (p_evt_write->len == 2) + ) + { + // CCCD written, call application event handler + if (p_bas->evt_handler != NULL) + { + ble_bas_evt_t evt; + + if (ble_srv_is_notification_enabled(p_evt_write->data)) + { + evt.evt_type = BLE_BAS_EVT_NOTIFICATION_ENABLED; + } + else + { + evt.evt_type = BLE_BAS_EVT_NOTIFICATION_DISABLED; + } + + p_bas->evt_handler(p_bas, &evt); + } + } + } +} + + +void ble_bas_on_ble_evt(ble_bas_t * p_bas, ble_evt_t * p_ble_evt) +{ + if (p_bas == NULL || p_ble_evt == NULL) + { + return; + } + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_bas, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_bas, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_bas, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for adding the Battery Level characteristic. + * + * @param[in] p_bas Battery Service structure. + * @param[in] p_bas_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t battery_level_char_add(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init) +{ + uint32_t err_code; + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t initial_battery_level; + uint8_t encoded_report_ref[BLE_SRV_ENCODED_REPORT_REF_LEN]; + uint8_t init_len; + + // Add Battery Level characteristic + if (p_bas->is_notification_supported) + { + memset(&cccd_md, 0, sizeof(cccd_md)); + + // According to BAS_SPEC_V10, the read operation on cccd should be possible without + // authentication. + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + cccd_md.write_perm = p_bas_init->battery_level_char_attr_md.cccd_write_perm; + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + } + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.char_props.notify = (p_bas->is_notification_supported) ? 1 : 0; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = (p_bas->is_notification_supported) ? &cccd_md : NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BATTERY_LEVEL_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_bas_init->battery_level_char_attr_md.read_perm; + attr_md.write_perm = p_bas_init->battery_level_char_attr_md.write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + initial_battery_level = p_bas_init->initial_batt_level; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof(uint8_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = sizeof(uint8_t); + attr_char_value.p_value = &initial_battery_level; + + err_code = sd_ble_gatts_characteristic_add(p_bas->service_handle, &char_md, + &attr_char_value, + &p_bas->battery_level_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (p_bas_init->p_report_ref != NULL) + { + // Add Report Reference descriptor + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_REF_DESCR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_bas_init->battery_level_report_read_perm; + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + init_len = ble_srv_report_ref_encode(encoded_report_ref, p_bas_init->p_report_ref); + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = init_len; + attr_char_value.init_offs = 0; + attr_char_value.max_len = attr_char_value.init_len; + attr_char_value.p_value = encoded_report_ref; + + err_code = sd_ble_gatts_descriptor_add(p_bas->battery_level_handles.value_handle, + &attr_char_value, + &p_bas->report_ref_handle); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else + { + p_bas->report_ref_handle = BLE_GATT_HANDLE_INVALID; + } + + return NRF_SUCCESS; +} + + +uint32_t ble_bas_init(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init) +{ + if (p_bas == NULL || p_bas_init == NULL) + { + return NRF_ERROR_NULL; + } + + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Initialize service structure + p_bas->evt_handler = p_bas_init->evt_handler; + p_bas->conn_handle = BLE_CONN_HANDLE_INVALID; + p_bas->is_notification_supported = p_bas_init->support_notification; + p_bas->battery_level_last = INVALID_BATTERY_LEVEL; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BATTERY_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_bas->service_handle); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add battery level characteristic + return battery_level_char_add(p_bas, p_bas_init); +} + + +uint32_t ble_bas_battery_level_update(ble_bas_t * p_bas, uint8_t battery_level) +{ + if (p_bas == NULL) + { + return NRF_ERROR_NULL; + } + + uint32_t err_code = NRF_SUCCESS; + ble_gatts_value_t gatts_value; + + if (battery_level != p_bas->battery_level_last) + { + // Initialize value struct. + memset(&gatts_value, 0, sizeof(gatts_value)); + + gatts_value.len = sizeof(uint8_t); + gatts_value.offset = 0; + gatts_value.p_value = &battery_level; + + // Update database. + err_code = sd_ble_gatts_value_set(p_bas->conn_handle, + p_bas->battery_level_handles.value_handle, + &gatts_value); + if (err_code == NRF_SUCCESS) + { + // Save new battery value. + p_bas->battery_level_last = battery_level; + } + else + { + return err_code; + } + + // Send value if connected and notifying. + if ((p_bas->conn_handle != BLE_CONN_HANDLE_INVALID) && p_bas->is_notification_supported) + { + ble_gatts_hvx_params_t hvx_params; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_bas->battery_level_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = gatts_value.offset; + hvx_params.p_len = &gatts_value.len; + hvx_params.p_data = gatts_value.p_value; + + err_code = sd_ble_gatts_hvx(p_bas->conn_handle, &hvx_params); + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + } + + return err_code; +} +#endif // NRF_MODULE_ENABLED(BLE_BAS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bas/ble_bas.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bas/ble_bas.h new file mode 100644 index 0000000000000000000000000000000000000000..65cdde5a4e036feadf3cad1d6da1187de9c4c97c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bas/ble_bas.h @@ -0,0 +1,169 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_bas Battery Service + * @{ + * @ingroup ble_sdk_srv + * @brief Battery Service module. + * + * @details This module implements the Battery Service with the Battery Level characteristic. + * During initialization it adds the Battery Service and Battery Level characteristic + * to the BLE stack database. Optionally it can also add a Report Reference descriptor + * to the Battery Level characteristic (used when including the Battery Service in + * the HID service). + * + * If specified, the module will support notification of the Battery Level characteristic + * through the ble_bas_battery_level_update() function. + * If an event handler is supplied by the application, the Battery Service will + * generate Battery Service events to the application. + * + * @note The application must propagate BLE stack events to the Battery Service module by calling + * ble_bas_on_ble_evt() from the @ref softdevice_handler callback. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#ifndef BLE_BAS_H__ +#define BLE_BAS_H__ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Battery Service event type. */ +typedef enum +{ + BLE_BAS_EVT_NOTIFICATION_ENABLED, /**< Battery value notification enabled event. */ + BLE_BAS_EVT_NOTIFICATION_DISABLED /**< Battery value notification disabled event. */ +} ble_bas_evt_type_t; + +/**@brief Battery Service event. */ +typedef struct +{ + ble_bas_evt_type_t evt_type; /**< Type of event. */ +} ble_bas_evt_t; + +// Forward declaration of the ble_bas_t type. +typedef struct ble_bas_s ble_bas_t; + +/**@brief Battery Service event handler type. */ +typedef void (*ble_bas_evt_handler_t) (ble_bas_t * p_bas, ble_bas_evt_t * p_evt); + +/**@brief Battery Service init structure. This contains all options and data needed for + * initialization of the service.*/ +typedef struct +{ + ble_bas_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */ + bool support_notification; /**< TRUE if notification of Battery Level measurement is supported. */ + ble_srv_report_ref_t * p_report_ref; /**< If not NULL, a Report Reference descriptor with the specified value will be added to the Battery Level characteristic */ + uint8_t initial_batt_level; /**< Initial battery level */ + ble_srv_cccd_security_mode_t battery_level_char_attr_md; /**< Initial security level for battery characteristics attribute */ + ble_gap_conn_sec_mode_t battery_level_report_read_perm; /**< Initial security level for battery report read attribute */ +} ble_bas_init_t; + +/**@brief Battery Service structure. This contains various status information for the service. */ +struct ble_bas_s +{ + ble_bas_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */ + uint16_t service_handle; /**< Handle of Battery Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t battery_level_handles; /**< Handles related to the Battery Level characteristic. */ + uint16_t report_ref_handle; /**< Handle of the Report Reference descriptor. */ + uint8_t battery_level_last; /**< Last Battery Level measurement passed to the Battery Service. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ + bool is_notification_supported; /**< TRUE if notification of Battery Level is supported. */ +}; + +/**@brief Function for initializing the Battery Service. + * + * @param[out] p_bas Battery Service structure. This structure will have to be supplied by + * the application. It will be initialized by this function, and will later + * be used to identify this particular service instance. + * @param[in] p_bas_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +uint32_t ble_bas_init(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init); + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the Battery Service. + * + * @note For the requirements in the BAS specification to be fulfilled, + * ble_bas_battery_level_update() must be called upon reconnection if the + * battery level has changed while the service has been disconnected from a bonded + * client. + * + * @param[in] p_bas Battery Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_bas_on_ble_evt(ble_bas_t * p_bas, ble_evt_t * p_ble_evt); + +/**@brief Function for updating the battery level. + * + * @details The application calls this function after having performed a battery measurement. If + * notification has been enabled, the battery level characteristic is sent to the client. + * + * @note For the requirements in the BAS specification to be fulfilled, + * this function must be called upon reconnection if the battery level has changed + * while the service has been disconnected from a bonded client. + * + * @param[in] p_bas Battery Service structure. + * @param[in] battery_level New battery measurement value (in percent of full capacity). + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_bas_battery_level_update(ble_bas_t * p_bas, uint8_t battery_level); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_BAS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bas_c/ble_bas_c.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bas_c/ble_bas_c.c new file mode 100644 index 0000000000000000000000000000000000000000..3bcceb9134c05023229fb434847b64a19fe7be67 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bas_c/ble_bas_c.c @@ -0,0 +1,402 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_BAS_C) +#include "ble_bas_c.h" +#include "ble_db_discovery.h" +#include "ble_types.h" +#include "ble_srv_common.h" +#include "ble_gattc.h" +#define NRF_LOG_MODULE_NAME "BLE_BAS_C" +#include "nrf_log.h" + +#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of contiguous zeroes, followed by contiguous sequence of ones: 000...111. */ +#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of the send buffer, which is 1 higher than the mask. */ +#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */ + +typedef enum +{ + READ_REQ, /**< Type identifying that this tx_message is a read request. */ + WRITE_REQ /**< Type identifying that this tx_message is a write request. */ +} tx_request_t; + +/**@brief Structure for writing a message to the peer, i.e. CCCD. + */ +typedef struct +{ + uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */ + ble_gattc_write_params_t gattc_params; /**< The GATTC parameters for this message. */ +} write_params_t; + +/**@brief Structure for holding the data that will be transmitted to the connected central. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */ + tx_request_t type; /**< Type of message. (read or write). */ + union + { + uint16_t read_handle; /**< Read request handle. */ + write_params_t write_req; /**< Write request message. */ + } req; +} tx_message_t; + + +static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for the messages that will be transmitted to the central. */ +static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */ +static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer containing the next message to be transmitted. */ + +/**@brief Function for passing any pending request from the buffer to the stack. + */ +static void tx_buffer_process(void) +{ + if (m_tx_index != m_tx_insert_index) + { + uint32_t err_code; + + if (m_tx_buffer[m_tx_index].type == READ_REQ) + { + err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle, + m_tx_buffer[m_tx_index].req.read_handle, + 0); + } + else + { + err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle, + &m_tx_buffer[m_tx_index].req.write_req.gattc_params); + } + if (err_code == NRF_SUCCESS) + { + NRF_LOG_DEBUG("SD Read/Write API returns Success..\r\n"); + m_tx_index++; + m_tx_index &= TX_BUFFER_MASK; + } + else + { + NRF_LOG_DEBUG("SD Read/Write API returns error. This message sending will be " + "attempted again..\r\n"); + } + } +} + + +/**@brief Function for handling write response events. + * + * @param[in] p_bas_c Pointer to the Battery Service Client Structure. + * @param[in] p_ble_evt Pointer to the SoftDevice event. + */ +static void on_write_rsp(ble_bas_c_t * p_bas_c, const ble_evt_t * p_ble_evt) +{ + // Check if the event if on the link for this instance + if (p_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + // Check if there is any message to be sent across to the peer and send it. + tx_buffer_process(); +} + + +/**@brief Function for handling read response events. + * + * @details This function will validate the read response and raise the appropriate + * event to the application. + * + * @param[in] p_bas_c Pointer to the Battery Service Client Structure. + * @param[in] p_ble_evt Pointer to the SoftDevice event. + */ +static void on_read_rsp(ble_bas_c_t * p_bas_c, const ble_evt_t * p_ble_evt) +{ + const ble_gattc_evt_read_rsp_t * p_response; + + // Check if the event if on the link for this instance + if (p_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + + p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp; + + if (p_response->handle == p_bas_c->peer_bas_db.bl_handle) + { + ble_bas_c_evt_t evt; + + evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle; + evt.evt_type = BLE_BAS_C_EVT_BATT_READ_RESP; + + evt.params.battery_level = p_response->data[0]; + + p_bas_c->evt_handler(p_bas_c, &evt); + } + // Check if there is any buffered transmissions and send them. + tx_buffer_process(); +} + + +/**@brief Function for handling Handle Value Notification received from the SoftDevice. + * + * @details This function will handle the Handle Value Notification received from the SoftDevice + * and checks if it is a notification of the Battery Level measurement from the peer. If + * so, this function will decode the battery level measurement and send it to the + * application. + * + * @param[in] p_ble_bas_c Pointer to the Battery Service Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_hvx(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt) +{ + // Check if the event if on the link for this instance + if (p_ble_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + // Check if this notification is a battery level notification. + if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_bas_c->peer_bas_db.bl_handle) + { + if (p_ble_evt->evt.gattc_evt.params.hvx.len == 1) + { + ble_bas_c_evt_t ble_bas_c_evt; + ble_bas_c_evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle; + ble_bas_c_evt.evt_type = BLE_BAS_C_EVT_BATT_NOTIFICATION; + + ble_bas_c_evt.params.battery_level = p_ble_evt->evt.gattc_evt.params.hvx.data[0]; + + p_ble_bas_c->evt_handler(p_ble_bas_c, &ble_bas_c_evt); + } + } +} + + +void ble_bas_on_db_disc_evt(ble_bas_c_t * p_ble_bas_c, const ble_db_discovery_evt_t * p_evt) +{ + // Check if the Battery Service was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE + && + p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_BATTERY_SERVICE + && + p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) + { + // Find the CCCD Handle of the Battery Level characteristic. + uint8_t i; + + ble_bas_c_evt_t evt; + evt.evt_type = BLE_BAS_C_EVT_DISCOVERY_COMPLETE; + evt.conn_handle = p_evt->conn_handle; + for (i = 0; i < p_evt->params.discovered_db.char_count; i++) + { + if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid == + BLE_UUID_BATTERY_LEVEL_CHAR) + { + // Found Battery Level characteristic. Store CCCD handle and break. + evt.params.bas_db.bl_cccd_handle = + p_evt->params.discovered_db.charateristics[i].cccd_handle; + evt.params.bas_db.bl_handle = + p_evt->params.discovered_db.charateristics[i].characteristic.handle_value; + break; + } + } + + NRF_LOG_DEBUG("Battery Service discovered at peer.\r\n"); + + //If the instance has been assigned prior to db_discovery, assign the db_handles + if (p_ble_bas_c->conn_handle != BLE_CONN_HANDLE_INVALID) + { + if ((p_ble_bas_c->peer_bas_db.bl_cccd_handle == BLE_GATT_HANDLE_INVALID)&& + (p_ble_bas_c->peer_bas_db.bl_handle == BLE_GATT_HANDLE_INVALID)) + { + p_ble_bas_c->peer_bas_db = evt.params.bas_db; + } + } + p_ble_bas_c->evt_handler(p_ble_bas_c, &evt); + } + else + { + NRF_LOG_DEBUG("Battery Service discovery failure at peer. \r\n"); + } +} + + +/**@brief Function for creating a message for writing to the CCCD. + */ +static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool notification_enable) +{ + NRF_LOG_DEBUG("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d\r\n", + handle_cccd,conn_handle); + + tx_message_t * p_msg; + uint16_t cccd_val = notification_enable ? BLE_GATT_HVX_NOTIFICATION : 0; + + p_msg = &m_tx_buffer[m_tx_insert_index++]; + m_tx_insert_index &= TX_BUFFER_MASK; + + p_msg->req.write_req.gattc_params.handle = handle_cccd; + p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH; + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + p_msg->req.write_req.gattc_params.offset = 0; + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val); + p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val); + p_msg->conn_handle = conn_handle; + p_msg->type = WRITE_REQ; + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +uint32_t ble_bas_c_init(ble_bas_c_t * p_ble_bas_c, ble_bas_c_init_t * p_ble_bas_c_init) +{ + VERIFY_PARAM_NOT_NULL(p_ble_bas_c); + VERIFY_PARAM_NOT_NULL(p_ble_bas_c_init); + + ble_uuid_t bas_uuid; + + bas_uuid.type = BLE_UUID_TYPE_BLE; + bas_uuid.uuid = BLE_UUID_BATTERY_SERVICE; + + p_ble_bas_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_bas_c->peer_bas_db.bl_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_bas_c->peer_bas_db.bl_handle = BLE_GATT_HANDLE_INVALID; + p_ble_bas_c->evt_handler = p_ble_bas_c_init->evt_handler; + + return ble_db_discovery_evt_register(&bas_uuid); +} + + +/**@brief Function for handling Disconnected event received from the SoftDevice. + * + * @details This function check if the disconnect event is happening on the link + * associated with the current instance of the module, if so it will set its + * conn_handle to invalid. + * + * @param[in] p_ble_bas_c Pointer to the Battery Service Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_disconnected(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt) +{ + if (p_ble_bas_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_ble_bas_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_bas_c->peer_bas_db.bl_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_bas_c->peer_bas_db.bl_handle = BLE_GATT_HANDLE_INVALID; + } +} + + +void ble_bas_c_on_ble_evt(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt) +{ + if ((p_ble_bas_c == NULL) || (p_ble_evt == NULL)) + { + return; + } + + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTC_EVT_HVX: + on_hvx(p_ble_bas_c, p_ble_evt); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + on_write_rsp(p_ble_bas_c, p_ble_evt); + break; + + case BLE_GATTC_EVT_READ_RSP: + on_read_rsp(p_ble_bas_c, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_ble_bas_c, p_ble_evt); + break; + + default: + break; + } +} + + +uint32_t ble_bas_c_bl_notif_enable(ble_bas_c_t * p_ble_bas_c) +{ + VERIFY_PARAM_NOT_NULL(p_ble_bas_c); + + if (p_ble_bas_c->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + + return cccd_configure(p_ble_bas_c->conn_handle, p_ble_bas_c->peer_bas_db.bl_cccd_handle, true); +} + + +uint32_t ble_bas_c_bl_read(ble_bas_c_t * p_ble_bas_c) +{ + VERIFY_PARAM_NOT_NULL(p_ble_bas_c); + if (p_ble_bas_c->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + + tx_message_t * msg; + + msg = &m_tx_buffer[m_tx_insert_index++]; + m_tx_insert_index &= TX_BUFFER_MASK; + + msg->req.read_handle = p_ble_bas_c->peer_bas_db.bl_handle; + msg->conn_handle = p_ble_bas_c->conn_handle; + msg->type = READ_REQ; + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +uint32_t ble_bas_c_handles_assign(ble_bas_c_t * p_ble_bas_c, + uint16_t conn_handle, + ble_bas_c_db_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ble_bas_c); + + p_ble_bas_c->conn_handle = conn_handle; + if (p_peer_handles != NULL) + { + p_ble_bas_c->peer_bas_db = *p_peer_handles; + } + return NRF_SUCCESS; +} +#endif // NRF_MODULE_ENABLED(BLE_BAS_C) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bas_c/ble_bas_c.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bas_c/ble_bas_c.h new file mode 100644 index 0000000000000000000000000000000000000000..b7fa7433543ba0eb539452f6888298c5e261f0f3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bas_c/ble_bas_c.h @@ -0,0 +1,251 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ble_bas_c Battery Service Client + * @{ + * @ingroup ble_sdk_srv + * @brief Battery Service Client module. + * + * @details This module contains APIs to read and interact with the Battery Service of a remote + * device. + * + * @note The application must propagate BLE stack events to this module by calling + * ble_hrs_c_on_ble_evt(). + * + */ + +#ifndef BLE_BAS_C_H__ +#define BLE_BAS_C_H__ + +#include +#include "ble.h" +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup bas_c_enums Enumerations + * @{ + */ + +/**@brief Battery Service Client event type. */ +typedef enum +{ + BLE_BAS_C_EVT_DISCOVERY_COMPLETE, /**< Event indicating that the Battery Service has been discovered at the peer. */ + BLE_BAS_C_EVT_BATT_NOTIFICATION, /**< Event indicating that a notification of the Battery Level characteristic has been received from the peer. */ + BLE_BAS_C_EVT_BATT_READ_RESP /**< Event indicating that a read response on Battery Level characteristic has been received from peer. */ +} ble_bas_c_evt_type_t; + +/** @} */ + +/** + * @defgroup bas_c_structs Structures + * @{ + */ + + +/**@brief Structure containing the handles related to the Battery Service found on the peer. */ +typedef struct +{ + uint16_t bl_cccd_handle; /**< Handle of the CCCD of the Battery Level characteristic. */ + uint16_t bl_handle; /**< Handle of the Battery Level characteristic as provided by the SoftDevice. */ +} ble_bas_c_db_t; + +/**@brief Battery Service Client Event structure. */ +typedef struct +{ + ble_bas_c_evt_type_t evt_type; /**< Event Type. */ + uint16_t conn_handle; /**< Connection handle relevent to this event.*/ + union + { + ble_bas_c_db_t bas_db; /**< Battery Service related handles found on the peer device. This will be filled if the evt_type is @ref BLE_BAS_C_EVT_DISCOVERY_COMPLETE.*/ + uint8_t battery_level; /**< Battery level received from peer. This field will be used for the events @ref BLE_BAS_C_EVT_BATT_NOTIFICATION and @ref BLE_BAS_C_EVT_BATT_READ_RESP.*/ + } params; +} ble_bas_c_evt_t; + +/** @} */ + +/** + * @defgroup bas_c_types Types + * @{ + */ + +// Forward declaration of the ble_bas_t type. +typedef struct ble_bas_c_s ble_bas_c_t; + +/**@brief Event handler type. + * + * @details This is the type of the event handler that should be provided by the application + * of this module in order to receive events. + */ +typedef void (* ble_bas_c_evt_handler_t) (ble_bas_c_t * p_bas_bas_c, ble_bas_c_evt_t * p_evt); + +/** @} */ + +/** + * @addtogroup bas_c_structs + * @{ + */ + +/**@brief Battery Service Client structure. + + */ +struct ble_bas_c_s +{ + uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */ + ble_bas_c_db_t peer_bas_db; /**< Handles related to BAS on the peer*/ + ble_bas_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the Battery service. */ +}; + +/**@brief Battery Service Client initialization structure. + */ +typedef struct +{ + ble_bas_c_evt_handler_t evt_handler; /**< Event handler to be called by the Battery Service Client module whenever there is an event related to the Battery Service. */ +} ble_bas_c_init_t; + +/** @} */ + +/** + * @defgroup bas_c_functions Functions + * @{ + */ + +/**@brief Function for initializing the Battery Service Client module. + * + * @details This function will initialize the module and set up Database Discovery to discover + * the Battery Service. After calling this function, call @ref ble_db_discovery_start + * to start discovery once a link with a peer has been established. + * + * @param[out] p_ble_bas_c Pointer to the Battery Service client structure. + * @param[in] p_ble_bas_c_init Pointer to the Battery Service initialization structure containing + * the initialization information. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL A parameter is NULL. + * Otherwise, an error code returned by @ref ble_db_discovery_evt_register. + */ +uint32_t ble_bas_c_init(ble_bas_c_t * p_ble_bas_c, ble_bas_c_init_t * p_ble_bas_c_init); + + +/**@brief Function for handling BLE events from the SoftDevice. + * + * @details This function will handle the BLE events received from the SoftDevice. If the BLE + * event is relevant for the Battery Service Client module, then it is used to update + * interval variables and, if necessary, send events to the application. + * + * @note This function must be called by the application. + * + * @param[in] p_ble_bas_c Pointer to the Battery Service client structure. + * @param[in] p_ble_evt Pointer to the BLE event. + */ +void ble_bas_c_on_ble_evt(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt); + + +/**@brief Function for enabling notifications on the Battery Level characteristic. + * + * @details This function will enable to notification of the Battery Level characteristic at the + * peer by writing to the CCCD of the Battery Level Characteristic. + * + * @param p_ble_bas_c Pointer to the Battery Service client structure. + * + * @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer. + * NRF_ERROR_NULL Parameter is NULL. + * Otherwise, an error code returned by the SoftDevice API @ref + * sd_ble_gattc_write. + */ +uint32_t ble_bas_c_bl_notif_enable(ble_bas_c_t * p_ble_bas_c); + + +/**@brief Function for reading the Battery Level characteristic. + * + * @param p_ble_bas_c Pointer to the Battery Service client structure. + * + * @retval NRF_SUCCESS If the read request was successfully queued to be sent to peer. + */ +uint32_t ble_bas_c_bl_read(ble_bas_c_t * p_ble_bas_c); + + +/**@brief Function for handling events from the database discovery module. + * + * @details Call this function when getting a callback event from the DB discovery modue. + * This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of Battery service at the peer. If so, it will + * call the application's event handler indicating that the Battery service has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param p_ble_bas_c Pointer to the Battery Service client structure. + * @param[in] p_evt Pointer to the event received from the database discovery module. + * + */ +void ble_bas_on_db_disc_evt(ble_bas_c_t * p_ble_bas_c, const ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for assigning handles to a this instance of bas_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to this instance of the module. This makes it + * possible to handle several link and associate each link to a particular + * instance of this module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_BAS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ble_bas_c Pointer to the Battery client structure instance to associate. + * @param[in] conn_handle Connection handle to associated with the given Battery Client Instance. + * @param[in] p_peer_handles Attribute handles on the BAS server you want this BAS client to + * interact with. + */ +uint32_t ble_bas_c_handles_assign(ble_bas_c_t * p_ble_bas_c, + uint16_t conn_handle, + ble_bas_c_db_t * p_peer_handles); + +/** @} */ // End tag for Function group. + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_BAS_C_H__ + +/** @} */ // End tag for the file. diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bps/ble_bps.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bps/ble_bps.c new file mode 100644 index 0000000000000000000000000000000000000000..72f7f391db21eabab44df9f0413f8bcdff9fb30a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bps/ble_bps.c @@ -0,0 +1,473 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_BPS) +#include "ble_bps.h" +#include +#include "nordic_common.h" +#include "ble_l2cap.h" +#include "ble_srv_common.h" + + +#define OPCODE_LENGTH 1 /**< Length of opcode inside Blood Pressure Measurement packet. */ +#define HANDLE_LENGTH 2 /**< Length of handle inside Blood Pressure Measurement packet. */ +#define MAX_BPM_LEN (BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Blood Pressure Measurement. */ + +// Blood Pressure Measurement Flags bits +#define BPS_MEAS_BLOOD_PRESSURE_UNITS_FLAG_BIT (0x01 << 0) /**< Blood Pressure Units Flag bit. */ +#define BPS_MEAS_TIME_STAMP_FLAG_BIT (0x01 << 1) /**< Time Stamp Flag bit. */ +#define BPS_MEAS_PULSE_RATE_FLAG_BIT (0x01 << 2) /**< Pulse Rate Flag bit. */ +#define BPS_MEAS_USER_ID_FLAG_BIT (0x01 << 3) /**< User ID Flag bit. */ +#define BPS_MEAS_MEASUREMENT_STATUS_FLAG_BIT (0x01 << 4) /**< Measurement Status Flag bit. */ + + +/**@brief Function for handling the Connect event. + * + * @param[in] p_bps Blood Pressure Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_bps_t * p_bps, ble_evt_t * p_ble_evt) +{ + p_bps->conn_handle = p_ble_evt->evt.gatts_evt.conn_handle; +} + + +/**@brief Function for handling the Disconnect event. + * + * @param[in] p_bps Blood Pressure Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_bps_t * p_bps, ble_evt_t * p_ble_evt) +{ + UNUSED_PARAMETER(p_ble_evt); + p_bps->conn_handle = BLE_CONN_HANDLE_INVALID; +} + + +/**@brief Function for handling the write events to the Blood Pressure Measurement characteristic. + * + * @param[in] p_bps Blood Pressure Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_cccd_write(ble_bps_t * p_bps, ble_gatts_evt_write_t * p_evt_write) +{ + if (p_evt_write->len == 2) + { + // CCCD written, update indication state + if (p_bps->evt_handler != NULL) + { + ble_bps_evt_t evt; + + if (ble_srv_is_indication_enabled(p_evt_write->data)) + { + evt.evt_type = BLE_BPS_EVT_INDICATION_ENABLED; + } + else + { + evt.evt_type = BLE_BPS_EVT_INDICATION_DISABLED; + } + + p_bps->evt_handler(p_bps, &evt); + } + } +} + + +/**@brief Function for handling the Write event. + * + * @param[in] p_bps Blood Pressure Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_bps_t * p_bps, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if (p_evt_write->handle == p_bps->meas_handles.cccd_handle) + { + on_cccd_write(p_bps, p_evt_write); + } +} + + +/**@brief Function for handling the HVC event. + * + * @details Handles HVC events from the BLE stack. + * + * @param[in] p_bps Blood Pressure Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_hvc(ble_bps_t * p_bps, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_hvc_t * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc; + + if (p_hvc->handle == p_bps->meas_handles.value_handle) + { + ble_bps_evt_t evt; + + evt.evt_type = BLE_BPS_EVT_INDICATION_CONFIRMED; + p_bps->evt_handler(p_bps, &evt); + } +} + + +void ble_bps_on_ble_evt(ble_bps_t * p_bps, ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_bps, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_bps, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_bps, p_ble_evt); + break; + + case BLE_GATTS_EVT_HVC: + on_hvc(p_bps, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for encoding a Blood Pressure Measurement. + * + * @param[in] p_bps Blood Pressure Service structure. + * @param[in] p_bps_meas Measurement to be encoded. + * @param[out] p_encoded_buffer Buffer where the encoded data will be written. + * + * @return Size of encoded data. + */ +static uint8_t bps_measurement_encode(ble_bps_t * p_bps, + ble_bps_meas_t * p_bps_meas, + uint8_t * p_encoded_buffer) +{ + uint8_t flags = 0; + uint8_t len = 1; + uint16_t encoded_sfloat; + + // Set measurement units flag + if (p_bps_meas->blood_pressure_units_in_kpa) + { + flags |= BPS_MEAS_BLOOD_PRESSURE_UNITS_FLAG_BIT; + } + + // Blood Pressure Measurement - Systolic + encoded_sfloat = ((p_bps_meas->blood_pressure_systolic.exponent << 12) & 0xF000) | + ((p_bps_meas->blood_pressure_systolic.mantissa << 0) & 0x0FFF); + len += uint16_encode(encoded_sfloat, &p_encoded_buffer[len]); + + // Blood Pressure Measurement - Diastolic + encoded_sfloat = ((p_bps_meas->blood_pressure_diastolic.exponent << 12) & 0xF000) | + ((p_bps_meas->blood_pressure_diastolic.mantissa << 0) & 0x0FFF); + len += uint16_encode(encoded_sfloat, &p_encoded_buffer[len]); + + // Blood Pressure Measurement - Mean Arterial Pressure + encoded_sfloat = ((p_bps_meas->mean_arterial_pressure.exponent << 12) & 0xF000) | + ((p_bps_meas->mean_arterial_pressure.mantissa << 0) & 0x0FFF); + len += uint16_encode(encoded_sfloat, &p_encoded_buffer[len]); + + // Time Stamp field + if (p_bps_meas->time_stamp_present) + { + flags |= BPS_MEAS_TIME_STAMP_FLAG_BIT; + len += ble_date_time_encode(&p_bps_meas->time_stamp, &p_encoded_buffer[len]); + } + + // Pulse Rate + if (p_bps_meas->pulse_rate_present) + { + flags |= BPS_MEAS_PULSE_RATE_FLAG_BIT; + + encoded_sfloat = ((p_bps_meas->pulse_rate.exponent << 12) & 0xF000) | + ((p_bps_meas->pulse_rate.mantissa << 0) & 0x0FFF); + len += uint16_encode(encoded_sfloat, &p_encoded_buffer[len]); + } + + // User ID + if (p_bps_meas->user_id_present) + { + flags |= BPS_MEAS_USER_ID_FLAG_BIT; + p_encoded_buffer[len++] = p_bps_meas->user_id; + } + + // Measurement Status + if (p_bps_meas->measurement_status_present) + { + flags |= BPS_MEAS_MEASUREMENT_STATUS_FLAG_BIT; + len += uint16_encode(p_bps_meas->measurement_status, &p_encoded_buffer[len]); + } + + // Flags field + p_encoded_buffer[0] = flags; + + return len; +} + + +/**@brief Function for adding Blood Pressure Measurement characteristics. + * + * @param[in] p_bps Blood Pressure Service structure. + * @param[in] p_bps_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t bps_measurement_char_add(ble_bps_t * p_bps, const ble_bps_init_t * p_bps_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + ble_bps_meas_t initial_bpm; + uint8_t encoded_bpm[MAX_BPM_LEN]; + + memset(&cccd_md, 0, sizeof(cccd_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + cccd_md.write_perm = p_bps_init->bps_meas_attr_md.cccd_write_perm; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.indicate = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.read_perm = p_bps_init->bps_meas_attr_md.read_perm; + attr_md.write_perm = p_bps_init->bps_meas_attr_md.write_perm; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 1; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + memset(&initial_bpm, 0, sizeof(initial_bpm)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = bps_measurement_encode(p_bps, &initial_bpm, encoded_bpm); + attr_char_value.init_offs = 0; + attr_char_value.max_len = MAX_BPM_LEN; + attr_char_value.p_value = encoded_bpm; + + return sd_ble_gatts_characteristic_add(p_bps->service_handle, + &char_md, + &attr_char_value, + &p_bps->meas_handles); +} + + +/**@brief Function for adding Blood Pressure Feature characteristics. + * + * @param[in] p_bps Blood Pressure Service structure. + * @param[in] p_bps_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t bps_feature_char_add(ble_bps_t * p_bps, const ble_bps_init_t * p_bps_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t init_value_encoded[2]; + uint8_t init_value_len; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BLOOD_PRESSURE_FEATURE_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.read_perm = p_bps_init->bps_feature_attr_md.read_perm; + attr_md.write_perm = p_bps_init->bps_feature_attr_md.write_perm; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + init_value_len = uint16_encode(p_bps_init->feature, init_value_encoded); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = init_value_len; + attr_char_value.init_offs = 0; + attr_char_value.max_len = init_value_len; + attr_char_value.p_value = init_value_encoded; + + return sd_ble_gatts_characteristic_add(p_bps->service_handle, + &char_md, + &attr_char_value, + &p_bps->feature_handles); +} + + +uint32_t ble_bps_init(ble_bps_t * p_bps, const ble_bps_init_t * p_bps_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Initialize service structure + p_bps->evt_handler = p_bps_init->evt_handler; + p_bps->conn_handle = BLE_CONN_HANDLE_INVALID; + p_bps->feature = p_bps_init->feature; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BLOOD_PRESSURE_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_bps->service_handle); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add measurement characteristic + err_code = bps_measurement_char_add(p_bps, p_bps_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add feature characteristic + err_code = bps_feature_char_add(p_bps, p_bps_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + return NRF_SUCCESS; +} + + +uint32_t ble_bps_measurement_send(ble_bps_t * p_bps, ble_bps_meas_t * p_bps_meas) +{ + uint32_t err_code; + + // Send value if connected + if (p_bps->conn_handle != BLE_CONN_HANDLE_INVALID) + { + uint8_t encoded_bps_meas[MAX_BPM_LEN]; + uint16_t len; + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + + len = bps_measurement_encode(p_bps, p_bps_meas, encoded_bps_meas); + hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_bps->meas_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_INDICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_bps_meas; + + err_code = sd_ble_gatts_hvx(p_bps->conn_handle, &hvx_params); + if ((err_code == NRF_SUCCESS) && (hvx_len != len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + + return err_code; +} + + +uint32_t ble_bps_is_indication_enabled(ble_bps_t * p_bps, bool * p_indication_enabled) +{ + uint32_t err_code; + uint8_t cccd_value_buf[BLE_CCCD_VALUE_LEN]; + ble_gatts_value_t gatts_value; + + // Initialize value struct. + memset(&gatts_value, 0, sizeof(gatts_value)); + + gatts_value.len = BLE_CCCD_VALUE_LEN; + gatts_value.offset = 0; + gatts_value.p_value = cccd_value_buf; + + err_code = sd_ble_gatts_value_get(p_bps->conn_handle, + p_bps->meas_handles.cccd_handle, + &gatts_value); + + if (err_code == NRF_SUCCESS) + { + *p_indication_enabled = ble_srv_is_indication_enabled(cccd_value_buf); + } + if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) + { + *p_indication_enabled = false; + return NRF_SUCCESS; + } + return err_code; +} +#endif // NRF_MODULE_ENABLED(BLE_BPS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bps/ble_bps.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bps/ble_bps.h new file mode 100644 index 0000000000000000000000000000000000000000..6fe27bf16c4e74ecaf031d822c04bcbbef227385 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_bps/ble_bps.h @@ -0,0 +1,198 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_bps Blood Pressure Service + * @{ + * @ingroup ble_sdk_srv + * @brief Blood Pressure Service module. + * + * @details This module implements the Blood Pressure Service. + * + * If an event handler is supplied by the application, the Blood Pressure + * Service will generate Blood Pressure Service events to the application. + * + * @note The application must propagate BLE stack events to the Blood Pressure Service + * module by calling ble_bps_on_ble_evt() from the @ref softdevice_handler function. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#ifndef BLE_BPS_H__ +#define BLE_BPS_H__ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "ble_date_time.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Blood Pressure Feature bits +#define BLE_BPS_FEATURE_BODY_MOVEMENT_BIT (0x01 << 0) /**< Body Movement Detection Support bit. */ +#define BLE_BPS_FEATURE_CUFF_FIT_BIT (0x01 << 1) /**< Cuff Fit Detection Support bit. */ +#define BLE_BPS_FEATURE_IRREGULAR_PULSE_BIT (0x01 << 2) /**< Irregular Pulse Detection Support bit. */ +#define BLE_BPS_FEATURE_PULSE_RATE_RANGE_BIT (0x01 << 3) /**< Pulse Rate Range Detection Support bit. */ +#define BLE_BPS_FEATURE_MEASUREMENT_POSITION_BIT (0x01 << 4) /**< Measurement Position Detection Support bit. */ +#define BLE_BPS_FEATURE_MULTIPLE_BOND_BIT (0x01 << 5) /**< Multiple Bond Support bit. */ + +/**@brief Blood Pressure Service event type. */ +typedef enum +{ + BLE_BPS_EVT_INDICATION_ENABLED, /**< Blood Pressure value indication enabled event. */ + BLE_BPS_EVT_INDICATION_DISABLED, /**< Blood Pressure value indication disabled event. */ + BLE_BPS_EVT_INDICATION_CONFIRMED /**< Confirmation of a blood pressure measurement indication has been received. */ +} ble_bps_evt_type_t; + +/**@brief Blood Pressure Service event. */ +typedef struct +{ + ble_bps_evt_type_t evt_type; /**< Type of event. */ +} ble_bps_evt_t; + +// Forward declaration of the ble_bps_t type. +typedef struct ble_bps_s ble_bps_t; + +/**@brief Blood Pressure Service event handler type. */ +typedef void (*ble_bps_evt_handler_t) (ble_bps_t * p_bps, ble_bps_evt_t * p_evt); + +/**@brief SFLOAT format (IEEE-11073 16-bit FLOAT, defined as a 16-bit vlue with 12-bit mantissa and + * 4-bit exponent. */ +typedef struct +{ + int8_t exponent; /**< Base 10 exponent, only 4 bits */ + int16_t mantissa; /**< Mantissa, only 12 bits */ +} ieee_float16_t; + +/**@brief Blood Pressure Service init structure. This contains all options and data + * needed for initialization of the service. */ +typedef struct +{ + ble_bps_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Blood Pressure Service. */ + ble_srv_cccd_security_mode_t bps_meas_attr_md; /**< Initial security level for blood pressure measurement attribute */ + ble_srv_security_mode_t bps_feature_attr_md; /**< Initial security level for blood pressure feature attribute */ + uint16_t feature; /**< Initial value for blood pressure feature */ +} ble_bps_init_t; + +/**@brief Blood Pressure Service structure. This contains various status information for + * the service. */ +struct ble_bps_s +{ + ble_bps_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Blood Pressure Service. */ + uint16_t service_handle; /**< Handle of Blood Pressure Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t meas_handles; /**< Handles related to the Blood Pressure Measurement characteristic. */ + ble_gatts_char_handles_t feature_handles; /**< Handles related to the Blood Pressure Feature characteristic. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ + uint16_t feature; /**< Value of Blood Pressure feature. */ +}; + +/**@brief Blood Pressure Service measurement structure. This contains a Blood Pressure + * measurement. */ +typedef struct ble_bps_meas_s +{ + bool blood_pressure_units_in_kpa; /**< Blood Pressure Units Flag, 0=mmHg, 1=kPa */ + bool time_stamp_present; /**< Time Stamp Flag, 0=not present, 1=present. */ + bool pulse_rate_present; /**< Pulse Rate Flag, 0=not present, 1=present. */ + bool user_id_present; /**< User ID Flag, 0=not present, 1=present. */ + bool measurement_status_present; /**< Measurement Status Flag, 0=not present, 1=present. */ + ieee_float16_t blood_pressure_systolic; /**< Blood Pressure Measurement Compound Value - Systolic. */ + ieee_float16_t blood_pressure_diastolic; /**< Blood Pressure Measurement Compound Value - Diastolic . */ + ieee_float16_t mean_arterial_pressure; /**< Blood Pressure Measurement Compound Value - Mean Arterial Pressure. */ + ble_date_time_t time_stamp; /**< Time Stamp. */ + ieee_float16_t pulse_rate; /**< Pulse Rate. */ + uint8_t user_id; /**< User ID. */ + uint16_t measurement_status; /**< Measurement Status. */ +} ble_bps_meas_t; + +/**@brief Function for initializing the Blood Pressure Service. + * + * @param[out] p_bps Blood Pressure Service structure. This structure will have to + * be supplied by the application. It will be initialized by this function, + * and will later be used to identify this particular service instance. + * @param[in] p_bps_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +uint32_t ble_bps_init(ble_bps_t * p_bps, const ble_bps_init_t * p_bps_init); + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the Blood Pressure Service. + * + * @param[in] p_bps Blood Pressure Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_bps_on_ble_evt(ble_bps_t * p_bps, ble_evt_t * p_ble_evt); + +/**@brief Function for sending blood pressure measurement if indication has been enabled. + * + * @details The application calls this function after having performed a Blood Pressure + * measurement. If indication has been enabled, the measurement data is encoded and + * sent to the client. + * + * @param[in] p_bps Blood Pressure Service structure. + * @param[in] p_bps_meas Pointer to new blood pressure measurement. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_bps_measurement_send(ble_bps_t * p_bps, ble_bps_meas_t * p_bps_meas); + +/**@brief Function for checking if indication of Blood Pressure Measurement is currently enabled. + * + * @param[in] p_bps Blood Pressure Service structure. + * @param[out] p_indication_enabled TRUE if indication is enabled, FALSE otherwise. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_bps_is_indication_enabled(ble_bps_t * p_bps, bool * p_indication_enabled); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_BPS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cscs/ble_cscs.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cscs/ble_cscs.c new file mode 100644 index 0000000000000000000000000000000000000000..e6cac855967fe7bbae3cc39998b90bd181947a33 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cscs/ble_cscs.c @@ -0,0 +1,470 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ + +#include "ble_cscs.h" +#include +#include "nordic_common.h" +#include "ble.h" +#include "ble_srv_common.h" +#include "app_util.h" + +#define OPCODE_LENGTH 1 /**< Length of opcode inside Cycling Speed and Cadence Measurement packet. */ +#define HANDLE_LENGTH 2 /**< Length of handle inside Cycling Speed and Cadence Measurement packet. */ +#define MAX_CSCM_LEN (BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Cycling Speed and Cadence Measurement. */ + +// Cycling Speed and Cadence Measurement flag bits +#define CSC_MEAS_FLAG_MASK_WHEEL_REV_DATA_PRESENT (0x01 << 0) /**< Wheel revolution data present flag bit. */ +#define CSC_MEAS_FLAG_MASK_CRANK_REV_DATA_PRESENT (0x01 << 1) /**< Crank revolution data present flag bit. */ + + +/**@brief Function for handling the Connect event. + * + * @param[in] p_cscs Cycling Speed and Cadence Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_cscs_t * p_cscs, ble_evt_t * p_ble_evt) +{ + p_cscs->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; +} + + +/**@brief Function for handling the Disconnect event. + * + * @param[in] p_cscs Cycling Speed and Cadence Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_cscs_t * p_cscs, ble_evt_t * p_ble_evt) +{ + UNUSED_PARAMETER(p_ble_evt); + p_cscs->conn_handle = BLE_CONN_HANDLE_INVALID; +} + + +/**@brief Function for handling write events to the CSCS Measurement characteristic. + * + * @param[in] p_cscs Cycling Speed and Cadence Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_meas_cccd_write(ble_cscs_t * p_cscs, ble_gatts_evt_write_t * p_evt_write) +{ + if (p_evt_write->len == 2) + { + // CCCD written, update notification state + if (p_cscs->evt_handler != NULL) + { + ble_cscs_evt_t evt; + + if (ble_srv_is_notification_enabled(p_evt_write->data)) + { + evt.evt_type = BLE_CSCS_EVT_NOTIFICATION_ENABLED; + } + else + { + evt.evt_type = BLE_CSCS_EVT_NOTIFICATION_DISABLED; + } + + p_cscs->evt_handler(p_cscs, &evt); + } + } +} + + +/**@brief Function for handling the Write event. + * + * @param[in] p_cscs Cycling Speed and Cadence Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_cscs_t * p_cscs, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if (p_evt_write->handle == p_cscs->meas_handles.cccd_handle) + { + on_meas_cccd_write(p_cscs, p_evt_write); + } +} + + +void ble_cscs_on_ble_evt(ble_cscs_t * p_cscs, ble_evt_t * p_ble_evt) +{ + ble_sc_ctrlpt_on_ble_evt(&(p_cscs->ctrl_pt), p_ble_evt); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_cscs, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_cscs, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_cscs, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for encoding a CSCS Measurement. + * + * @param[in] p_cscs Cycling Speed and Cadence Service structure. + * @param[in] p_csc_measurement Measurement to be encoded. + * @param[out] p_encoded_buffer Buffer where the encoded data will be written. + * + * @return Size of encoded data. + */ +static uint8_t csc_measurement_encode(ble_cscs_t * p_cscs, + ble_cscs_meas_t * p_csc_measurement, + uint8_t * p_encoded_buffer) +{ + uint8_t flags = 0; + uint8_t len = 1; + + // Cumulative Wheel Revolutions and Last Wheel Event Time Fields + if (p_cscs->feature & BLE_CSCS_FEATURE_WHEEL_REV_BIT) + { + if (p_csc_measurement->is_wheel_rev_data_present) + { + flags |= CSC_MEAS_FLAG_MASK_WHEEL_REV_DATA_PRESENT; + len += uint32_encode(p_csc_measurement->cumulative_wheel_revs, &p_encoded_buffer[len]); + len += uint16_encode(p_csc_measurement->last_wheel_event_time, &p_encoded_buffer[len]); + } + } + + // Cumulative Crank Revolutions and Last Crank Event Time Fields + if (p_cscs->feature & BLE_CSCS_FEATURE_CRANK_REV_BIT) + { + if (p_csc_measurement->is_crank_rev_data_present) + { + flags |= CSC_MEAS_FLAG_MASK_CRANK_REV_DATA_PRESENT; + len += uint16_encode(p_csc_measurement->cumulative_crank_revs, &p_encoded_buffer[len]); + len += uint16_encode(p_csc_measurement->last_crank_event_time, &p_encoded_buffer[len]); + } + } + + // Flags Field + p_encoded_buffer[0] = flags; + + return len; +} + + +/**@brief Function for adding CSC Measurement characteristics. + * + * @param[in] p_cscs Cycling Speed and Cadence Service structure. + * @param[in] p_cscs_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t csc_measurement_char_add(ble_cscs_t * p_cscs, const ble_cscs_init_t * p_cscs_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + ble_cscs_meas_t initial_scm; + uint8_t encoded_scm[MAX_CSCM_LEN]; + memset(&cccd_md, 0, sizeof(cccd_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + cccd_md.write_perm = p_cscs_init->csc_meas_attr_md.cccd_write_perm; + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.notify = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CSC_MEASUREMENT_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm ); + + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm); + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 1; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = csc_measurement_encode(p_cscs, &initial_scm, encoded_scm); + attr_char_value.init_offs = 0; + attr_char_value.max_len = MAX_CSCM_LEN; + attr_char_value.p_value = encoded_scm; + + return sd_ble_gatts_characteristic_add(p_cscs->service_handle, + &char_md, + &attr_char_value, + &p_cscs->meas_handles); +} + + +/**@brief Function for adding CSC Feature characteristics. + * + * @param[in] p_cscs Cycling Speed and Cadence Service structure. + * @param[in] p_cscs_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t csc_feature_char_add(ble_cscs_t * p_cscs, const ble_cscs_init_t * p_cscs_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t init_value_encoded[2]; + uint8_t init_value_len; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CSC_FEATURE_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_cscs_init->csc_feature_attr_md.read_perm; + + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm); + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + init_value_len = uint16_encode(p_cscs_init->feature, &init_value_encoded[0]); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = init_value_len; + attr_char_value.init_offs = 0; + attr_char_value.max_len = init_value_len; + attr_char_value.p_value = init_value_encoded; + + return sd_ble_gatts_characteristic_add(p_cscs->service_handle, + &char_md, + &attr_char_value, + &p_cscs->feature_handles); +} + + +/**@brief Function for adding CSC Sensor Location characteristic. + * + * @param[in] p_cscs Cycling Speed and Cadence Service structure. + * @param[in] p_cscs_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t csc_sensor_loc_char_add(ble_cscs_t * p_cscs, const ble_cscs_init_t * p_cscs_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t init_value_len; + uint8_t encoded_init_value[1]; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_SENSOR_LOCATION_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_cscs_init->csc_sensor_loc_attr_md.read_perm; + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm); + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + init_value_len = sizeof(uint8_t); + if (p_cscs_init->sensor_location != NULL) + { + encoded_init_value[0] = *p_cscs_init->sensor_location; + } + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = init_value_len; + attr_char_value.init_offs = 0; + attr_char_value.max_len = init_value_len; + attr_char_value.p_value = encoded_init_value; + + return sd_ble_gatts_characteristic_add(p_cscs->service_handle, + &char_md, + &attr_char_value, + &p_cscs->sensor_loc_handles); +} + + +uint32_t ble_cscs_init(ble_cscs_t * p_cscs, const ble_cscs_init_t * p_cscs_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + ble_cs_ctrlpt_init_t sc_ctrlpt_init; + + // Initialize service structure + p_cscs->evt_handler = p_cscs_init->evt_handler; + p_cscs->conn_handle = BLE_CONN_HANDLE_INVALID; + p_cscs->feature = p_cscs_init->feature; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CYCLING_SPEED_AND_CADENCE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_cscs->service_handle); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add cycling speed and cadence measurement characteristic + err_code = csc_measurement_char_add(p_cscs, p_cscs_init); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add cycling speed and cadence feature characteristic + err_code = csc_feature_char_add(p_cscs, p_cscs_init); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add Sensor Location characteristic (optional) + if (p_cscs_init->sensor_location != NULL) + { + err_code = csc_sensor_loc_char_add(p_cscs, p_cscs_init); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + + // Add speed and cadence control point characteristic + sc_ctrlpt_init.error_handler = p_cscs_init->error_handler; + sc_ctrlpt_init.size_list_supported_locations = p_cscs_init->size_list_supported_locations; + sc_ctrlpt_init.supported_functions = p_cscs_init->ctrplt_supported_functions; + sc_ctrlpt_init.evt_handler = p_cscs_init->ctrlpt_evt_handler; + sc_ctrlpt_init.list_supported_locations = p_cscs_init->list_supported_locations; + sc_ctrlpt_init.sc_ctrlpt_attr_md = p_cscs_init->csc_ctrlpt_attr_md; + sc_ctrlpt_init.sensor_location_handle = p_cscs->sensor_loc_handles.value_handle; + sc_ctrlpt_init.service_handle = p_cscs->service_handle; + + return ble_sc_ctrlpt_init(&p_cscs->ctrl_pt, &sc_ctrlpt_init); +} + + +uint32_t ble_cscs_measurement_send(ble_cscs_t * p_cscs, ble_cscs_meas_t * p_measurement) +{ + uint32_t err_code; + + // Send value if connected and notifying + if (p_cscs->conn_handle != BLE_CONN_HANDLE_INVALID) + { + uint8_t encoded_csc_meas[MAX_CSCM_LEN]; + uint16_t len; + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + + len = csc_measurement_encode(p_cscs, p_measurement, encoded_csc_meas); + hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_cscs->meas_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_csc_meas; + + err_code = sd_ble_gatts_hvx(p_cscs->conn_handle, &hvx_params); + if ((err_code == NRF_SUCCESS) && (hvx_len != len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cscs/ble_cscs.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cscs/ble_cscs.h new file mode 100644 index 0000000000000000000000000000000000000000..cccc36335a32233ccbac9aca9b5d33c4d1982add --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cscs/ble_cscs.h @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_cscs Cycling Speed and Cadence Service + * @{ + * @ingroup ble_sdk_srv + * @brief Cycling Speed and Cadence Service module. + * + * @details This module implements the Cycling Speed and Cadence Service. If enabled, notification + * of the Cycling Speead and Candence Measurement is performed when the application + * calls ble_cscs_measurement_send(). + * + * To use this service, you need to provide the the supported features (@ref BLE_CSCS_FEATURES). + * If you choose to support Wheel revolution data (feature bit @ref BLE_CSCS_FEATURE_WHEEL_REV_BIT), + * you then need to support the 'setting of cumulative value' operation by the supporting the + * Speed and Cadence Control Point (@ref ble_sdk_srv_sc_ctrlpt) by setting the @ref BLE_SRV_SC_CTRLPT_CUM_VAL_OP_SUPPORTED + * bit of the ctrplt_supported_functions in the @ref ble_cscs_init_t structure. + * If you want to support the 'start autocalibration' control point feature, you need, after the @ref BLE_SC_CTRLPT_EVT_START_CALIBRATION + * has been received and the auto calibration is finished, to call the @ref ble_sc_ctrlpt_rsp_send to indicate that the operation is finished + * and thus be able to receive new control point operations. + * If you want to support the 'sensor location' related operation, you need to provide a list of supported location in the + * @ref ble_cscs_init_t structure. + * + * + * @note The application or the service using this module must propagate BLE stack events to the + * Cycling Speead and Candence Service module by calling ble_cscs_on_ble_evt() from the + * from the @ref softdevice_handler function. This service will forward the event to the @ref ble_sdk_srv_sc_ctrlpt module. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#ifndef BLE_CSCS_H__ +#define BLE_CSCS_H__ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "ble_sc_ctrlpt.h" +#include "ble_sensor_location.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup BLE_CSCS_FEATURES Cycling Speed and Cadence Service feature bits + * @{ */ +#define BLE_CSCS_FEATURE_WHEEL_REV_BIT (0x01 << 0) /**< Wheel Revolution Data Supported bit. */ +#define BLE_CSCS_FEATURE_CRANK_REV_BIT (0x01 << 1) /**< Crank Revolution Data Supported bit. */ +#define BLE_CSCS_FEATURE_MULTIPLE_SENSORS_BIT (0x01 << 2) /**< Multiple Sensor Locations Supported bit. */ +/** @} */ + +/**@brief Cycling Speed and Cadence Service event type. */ +typedef enum +{ + BLE_CSCS_EVT_NOTIFICATION_ENABLED, /**< Cycling Speed and Cadence value notification enabled event. */ + BLE_CSCS_EVT_NOTIFICATION_DISABLED /**< Cycling Speed and Cadence value notification disabled event. */ +} ble_cscs_evt_type_t; + +/**@brief Cycling Speed and Cadence Service event. */ +typedef struct +{ + ble_cscs_evt_type_t evt_type; /**< Type of event. */ +} ble_cscs_evt_t; + +// Forward declaration of the ble_csc_t type. +typedef struct ble_cscs_s ble_cscs_t; + +/**@brief Cycling Speed and Cadence Service event handler type. */ +typedef void (*ble_cscs_evt_handler_t) (ble_cscs_t * p_cscs, ble_cscs_evt_t * p_evt); + +/**@brief Cycling Speed and Cadence Service init structure. This contains all options and data +* needed for initialization of the service. */ +typedef struct +{ + ble_cscs_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Cycling Speed and Cadence Service. */ + ble_srv_cccd_security_mode_t csc_meas_attr_md; /**< Initial security level for cycling speed and cadence measurement attribute */ + ble_srv_cccd_security_mode_t csc_ctrlpt_attr_md; /**< Initial security level for cycling speed and cadence control point attribute */ + ble_srv_security_mode_t csc_feature_attr_md; /**< Initial security level for feature attribute */ + uint16_t feature; /**< Initial value for features of sensor @ref BLE_CSCS_FEATURES. */ + uint8_t ctrplt_supported_functions; /**< Supported control point functionalities see @ref BLE_SRV_SC_CTRLPT_SUPP_FUNC. */ + ble_sc_ctrlpt_evt_handler_t ctrlpt_evt_handler; /**< Event handler */ + ble_sensor_location_t *list_supported_locations; /**< List of supported sensor locations.*/ + uint8_t size_list_supported_locations; /**< Number of supported sensor locations in the list.*/ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + ble_sensor_location_t *sensor_location; /**< Initial Sensor Location, if NULL, sensor_location characteristic is not added*/ + ble_srv_cccd_security_mode_t csc_sensor_loc_attr_md; /**< Initial security level for sensor location attribute */ +} ble_cscs_init_t; + +/**@brief Cycling Speed and Cadence Service structure. This contains various status information for + * the service. */ +struct ble_cscs_s +{ + ble_cscs_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Cycling Speed and Cadence Service. */ + uint16_t service_handle; /**< Handle of Cycling Speed and Cadence Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t meas_handles; /**< Handles related to the Cycling Speed and Cadence Measurement characteristic. */ + ble_gatts_char_handles_t feature_handles; /**< Handles related to the Cycling Speed and Cadence feature characteristic. */ + ble_gatts_char_handles_t sensor_loc_handles; /**< Handles related to the Cycling Speed and Cadence Sensor Location characteristic. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ + uint16_t feature; /**< Bit mask of features available on sensor. */ + ble_sc_ctrlpt_t ctrl_pt; /**< data for speed and cadence control point */ +}; + +/**@brief Cycling Speed and Cadence Service measurement structure. This contains a Cycling Speed and + * Cadence Service measurement. */ +typedef struct ble_cscs_meas_s +{ + bool is_wheel_rev_data_present; /**< True if Wheel Revolution Data is present in the measurement. */ + bool is_crank_rev_data_present; /**< True if Crank Revolution Data is present in the measurement. */ + uint32_t cumulative_wheel_revs; /**< Cumulative Wheel Revolutions. */ + uint16_t last_wheel_event_time; /**< Last Wheel Event Time. */ + uint16_t cumulative_crank_revs; /**< Cumulative Crank Revolutions. */ + uint16_t last_crank_event_time; /**< Last Crank Event Time. */ +} ble_cscs_meas_t; + +/**@brief Function for initializing the Cycling Speed and Cadence Service. + * + * @param[out] p_cscs Cycling Speed and Cadence Service structure. This structure will have to + * be supplied by the application. It will be initialized by this function, + * and will later be used to identify this particular service instance. + * @param[in] p_cscs_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +uint32_t ble_cscs_init(ble_cscs_t * p_cscs, const ble_cscs_init_t * p_cscs_init); + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the Cycling Speed and Cadence + * Service. + * + * @param[in] p_cscs Cycling Speed and Cadence Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_cscs_on_ble_evt(ble_cscs_t * p_cscs, ble_evt_t * p_ble_evt); + +/**@brief Function for sending cycling speed and cadence measurement if notification has been enabled. + * + * @details The application calls this function after having performed a Cycling Speed and Cadence + * Service measurement. If notification has been enabled, the measurement data is encoded + * and sent to the client. + * + * @param[in] p_cscs Cycling Speed and Cadence Service structure. + * @param[in] p_measurement Pointer to new cycling speed and cadence measurement. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_cscs_measurement_send(ble_cscs_t * p_cscs, ble_cscs_meas_t * p_measurement); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_CSCS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.c new file mode 100644 index 0000000000000000000000000000000000000000..ee3510769d90f50e1fd2ef02bc7f4ebfa72898b4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.c @@ -0,0 +1,665 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! + * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#include "ble_sc_ctrlpt.h" +#include +#include "nordic_common.h" +#include "ble.h" +#include "ble_srv_common.h" +#include "app_util.h" + +#define SC_CTRLPT_NACK_PROC_ALREADY_IN_PROGRESS (BLE_GATT_STATUS_ATTERR_APP_BEGIN + 0) +#define SC_CTRLPT_NACK_CCCD_IMPROPERLY_CONFIGURED (BLE_GATT_STATUS_ATTERR_APP_BEGIN + 1) + +uint32_t ble_sc_ctrlpt_init(ble_sc_ctrlpt_t * p_sc_ctrlpt, + const ble_cs_ctrlpt_init_t * p_sc_ctrlpt_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + p_sc_ctrlpt->conn_handle = BLE_CONN_HANDLE_INVALID; + p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS; + + p_sc_ctrlpt->size_list_supported_locations = p_sc_ctrlpt_init->size_list_supported_locations; + + if ((p_sc_ctrlpt_init->size_list_supported_locations != 0) && + (p_sc_ctrlpt_init->list_supported_locations != NULL)) + { + memcpy(p_sc_ctrlpt->list_supported_locations, + p_sc_ctrlpt_init->list_supported_locations, + p_sc_ctrlpt->size_list_supported_locations * sizeof(ble_sensor_location_t)); + } + + p_sc_ctrlpt->service_handle = p_sc_ctrlpt_init->service_handle; + p_sc_ctrlpt->evt_handler = p_sc_ctrlpt_init->evt_handler; + p_sc_ctrlpt->supported_functions = p_sc_ctrlpt_init->supported_functions; + p_sc_ctrlpt->sensor_location_handle = p_sc_ctrlpt_init->sensor_location_handle; + p_sc_ctrlpt->error_handler = p_sc_ctrlpt_init->error_handler; + + memset(&cccd_md, 0, sizeof(cccd_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + cccd_md.write_perm = p_sc_ctrlpt_init->sc_ctrlpt_attr_md.cccd_write_perm; + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.indicate = 1; + char_md.char_props.write = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_SC_CTRLPT_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm); + attr_md.write_perm = p_sc_ctrlpt_init->sc_ctrlpt_attr_md.write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 1; + attr_md.vlen = 1; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = 0; + attr_char_value.init_offs = 0; + attr_char_value.max_len = BLE_SC_CTRLPT_MAX_LEN; + attr_char_value.p_value = 0; + + return sd_ble_gatts_characteristic_add(p_sc_ctrlpt->service_handle, + &char_md, + &attr_char_value, + &p_sc_ctrlpt->sc_ctrlpt_handles); +} + + +/**@brief Decode an incoming control point write. + * + * @param[in] rcvd_val received write value + * @param[in] len value length + * @param[out] decoded_ctrlpt decoded control point structure + */ +static uint32_t sc_ctrlpt_decode(uint8_t * p_rcvd_val, + uint8_t len, + ble_sc_ctrlpt_val_t * p_write_val) +{ + int pos = 0; + + if (len < BLE_SC_CTRLPT_MIN_LEN) + { + return NRF_ERROR_INVALID_PARAM; + } + + p_write_val->opcode = (ble_scpt_operator_t) p_rcvd_val[pos++]; + + switch (p_write_val->opcode) + { + case BLE_SCPT_REQUEST_SUPPORTED_SENSOR_LOCATIONS: + break; + + case BLE_SCPT_START_AUTOMATIC_CALIBRATION: + break; + + case BLE_SCPT_UPDATE_SENSOR_LOCATION: + p_write_val->location = (ble_sensor_location_t)p_rcvd_val[pos]; + break; + + case BLE_SCPT_SET_CUMULATIVE_VALUE: + p_write_val->cumulative_value = uint32_decode(&(p_rcvd_val[pos])); + break; + + default: + return NRF_ERROR_INVALID_PARAM; + } + return NRF_SUCCESS; +} + + +/**@brief encode a control point response indication. + * + * @param[in] p_sc_ctrlpt SC Ctrlpt structure. + * @param[in] p_ctrlpt_rsp structure containing response data to be encoded + * @param[out] p_data pointer where data needs to be written + * @return size of encoded data + */ +static int ctrlpt_rsp_encode(ble_sc_ctrlpt_t * p_sc_ctrlpt, + ble_sc_ctrlpt_rsp_t * p_ctrlpt_rsp, + uint8_t * p_data) +{ + int len = 0; + + p_data[len++] = BLE_SCPT_RESPONSE_CODE; + p_data[len++] = p_ctrlpt_rsp->opcode; + p_data[len++] = p_ctrlpt_rsp->status; + + if (p_ctrlpt_rsp->status == BLE_SCPT_SUCCESS) + { + switch (p_ctrlpt_rsp->opcode) + { + case BLE_SCPT_REQUEST_SUPPORTED_SENSOR_LOCATIONS: + { + int i; + for (i = 0; i < p_sc_ctrlpt->size_list_supported_locations; i++) + { + p_data[len++] = p_sc_ctrlpt->list_supported_locations[i]; + } + break; + } + + default: + // No implementation needed. + break; + } + } + return len; +} + + +/**@brief check if a given sensor location is supported or not. + * + * @param[in] p_sc_ctrlpt SC Ctrlpt structure. + * @param[in] location sensor location to check. + * @return true if the given location is found in the list of supported locations, false otherwise. + */ +static bool is_location_supported(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_sensor_location_t location) +{ + int i; + + for (i = 0; i < p_sc_ctrlpt->size_list_supported_locations; i++) + { + if (p_sc_ctrlpt->list_supported_locations[i] == location) + { + return true; + } + } + return false; +} + + +/**@brief check if the cccd is configured + * + * @param[in] p_sc_ctrlpt SC Ctrlpt structure. + * @return true if the sc_control point's cccd is correctly configured, false otherwise. + */ +static bool is_cccd_configured(ble_sc_ctrlpt_t * p_sc_ctrlpt) +{ + uint32_t err_code; + uint8_t cccd_value_buf[BLE_CCCD_VALUE_LEN]; + bool is_sccp_indic_enabled = false; + ble_gatts_value_t gatts_value; + + // Initialize value struct. + memset(&gatts_value, 0, sizeof(gatts_value)); + + gatts_value.len = BLE_CCCD_VALUE_LEN; + gatts_value.offset = 0; + gatts_value.p_value = cccd_value_buf; + + err_code = sd_ble_gatts_value_get(p_sc_ctrlpt->conn_handle, + p_sc_ctrlpt->sc_ctrlpt_handles.cccd_handle, + &gatts_value); + if (err_code != NRF_SUCCESS) + { + // Report error to application + if (p_sc_ctrlpt->error_handler != NULL) + { + p_sc_ctrlpt->error_handler(err_code); + } + } + + is_sccp_indic_enabled = ble_srv_is_indication_enabled(cccd_value_buf); + + return is_sccp_indic_enabled; +} + + +/**@brief sends a control point indication. + * + * @param[in] p_sc_ctrlpt SC Ctrlpt structure. + */ +static void sc_ctrlpt_resp_send(ble_sc_ctrlpt_t * p_sc_ctrlpt) +{ + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + uint32_t err_code; + + if ((p_sc_ctrlpt->procedure_status == BLE_SCPT_INDICATION_PENDING)) + { + hvx_len = p_sc_ctrlpt->response.len; + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_sc_ctrlpt->sc_ctrlpt_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_INDICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = p_sc_ctrlpt->response.encoded_ctrl_rsp; + + err_code = sd_ble_gatts_hvx(p_sc_ctrlpt->conn_handle, &hvx_params); + + // Error handling + if ((err_code == NRF_SUCCESS) && (hvx_len != p_sc_ctrlpt->response.len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + + switch (err_code) + { + case NRF_SUCCESS: + p_sc_ctrlpt->procedure_status = BLE_SCPT_IND_CONFIRM_PENDING; + // Wait for HVC event + break; + + case NRF_ERROR_RESOURCES: + // Wait for TX_COMPLETE event to retry transmission. + p_sc_ctrlpt->procedure_status = BLE_SCPT_INDICATION_PENDING; + break; + + default: + // Report error to application. + p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS; + if (p_sc_ctrlpt->error_handler != NULL) + { + p_sc_ctrlpt->error_handler(err_code); + } + break; + } + } +} + + +/**@brief Handle a write event to the Speed and Cadence Control Point. + * + * @param[in] p_sc_ctrlpt SC Ctrlpt structure. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_ctrlpt_write(ble_sc_ctrlpt_t * p_sc_ctrlpt, + ble_gatts_evt_write_t * p_evt_write) +{ + ble_sc_ctrlpt_val_t rcvd_ctrlpt = + { BLE_SCPT_RESPONSE_CODE , 0, BLE_SENSOR_LOCATION_OTHER }; + + ble_sc_ctrlpt_rsp_t rsp; + uint32_t err_code; + ble_gatts_rw_authorize_reply_params_t auth_reply; + ble_sc_ctrlpt_evt_t evt; + + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.params.write.offset = 0; + auth_reply.params.write.len = 0; + auth_reply.params.write.p_data = NULL; + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; + + if (is_cccd_configured(p_sc_ctrlpt)) + { + if (p_sc_ctrlpt->procedure_status == BLE_SCPT_NO_PROC_IN_PROGRESS) + { + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + } + else + { + auth_reply.params.write.gatt_status = SC_CTRLPT_NACK_PROC_ALREADY_IN_PROGRESS; + } + } + else + { + auth_reply.params.write.gatt_status = SC_CTRLPT_NACK_CCCD_IMPROPERLY_CONFIGURED; + } + + err_code = sd_ble_gatts_rw_authorize_reply(p_sc_ctrlpt->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + // Report error to application. + if (p_sc_ctrlpt->error_handler != NULL) + { + p_sc_ctrlpt->error_handler(err_code); + } + } + + if (auth_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS) + { + return; + } + + p_sc_ctrlpt->procedure_status = BLE_SCPT_INDICATION_PENDING; + rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED; + + err_code = sc_ctrlpt_decode(p_evt_write->data, p_evt_write->len, &rcvd_ctrlpt); + if (err_code != NRF_SUCCESS) + { + rsp.opcode = rcvd_ctrlpt.opcode; + rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED; + } + else + { + rsp.opcode = rcvd_ctrlpt.opcode; + + switch (rcvd_ctrlpt.opcode) + { + case BLE_SCPT_REQUEST_SUPPORTED_SENSOR_LOCATIONS: + if ((p_sc_ctrlpt->supported_functions & + BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED) == + BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED) + { + rsp.status = BLE_SCPT_SUCCESS; + } + else + { + rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED; + } + break; + + case BLE_SCPT_UPDATE_SENSOR_LOCATION: + if ((p_sc_ctrlpt->supported_functions & + BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED) == + BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED) + { + if (is_location_supported(p_sc_ctrlpt, rcvd_ctrlpt.location)) + { + ble_gatts_value_t gatts_value; + uint8_t rcvd_location = (uint8_t)rcvd_ctrlpt.location; + rsp.status = BLE_SCPT_SUCCESS; + + // Initialize value struct. + memset(&gatts_value, 0, sizeof(gatts_value)); + + gatts_value.len = sizeof(uint8_t); + gatts_value.offset = 0; + gatts_value.p_value = &rcvd_location; + + evt.evt_type = BLE_SC_CTRLPT_EVT_UPDATE_LOCATION; + evt.params.update_location = rcvd_ctrlpt.location; + if (p_sc_ctrlpt->evt_handler != NULL) + { + rsp.status = p_sc_ctrlpt->evt_handler(p_sc_ctrlpt, &evt); + } + if (rsp.status == BLE_SCPT_SUCCESS) + { + err_code = sd_ble_gatts_value_set(p_sc_ctrlpt->conn_handle, + p_sc_ctrlpt->sensor_location_handle, + &gatts_value); + if (err_code != NRF_SUCCESS) + { + // Report error to application + if (p_sc_ctrlpt->error_handler != NULL) + { + p_sc_ctrlpt->error_handler(err_code); + } + rsp.status = BLE_SCPT_OPERATION_FAILED; + } + } + } + else + { + rsp.status = BLE_SCPT_INVALID_PARAMETER; + } + } + else + { + rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED; + } + break; + + case BLE_SCPT_SET_CUMULATIVE_VALUE: + if ((p_sc_ctrlpt->supported_functions & + BLE_SRV_SC_CTRLPT_CUM_VAL_OP_SUPPORTED) == + BLE_SRV_SC_CTRLPT_CUM_VAL_OP_SUPPORTED) + { + rsp.status = BLE_SCPT_SUCCESS; + + evt.evt_type = BLE_SC_CTRLPT_EVT_SET_CUMUL_VALUE; + evt.params.cumulative_value = rcvd_ctrlpt.cumulative_value; + if (p_sc_ctrlpt->evt_handler != NULL) + { + rsp.status = p_sc_ctrlpt->evt_handler(p_sc_ctrlpt, &evt); + } + } + else + { + rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED; + } + break; + + case BLE_SCPT_START_AUTOMATIC_CALIBRATION: + if ((p_sc_ctrlpt->supported_functions & + BLE_SRV_SC_CTRLPT_START_CALIB_OP_SUPPORTED) == + BLE_SRV_SC_CTRLPT_START_CALIB_OP_SUPPORTED) + { + p_sc_ctrlpt->procedure_status = BLE_SCPT_AUTOMATIC_CALIB_IN_PROGRESS; + evt.evt_type = BLE_SC_CTRLPT_EVT_START_CALIBRATION; + if (p_sc_ctrlpt->evt_handler != NULL) + { + rsp.status = p_sc_ctrlpt->evt_handler(p_sc_ctrlpt, &evt); + if (rsp.status != BLE_SCPT_SUCCESS) + { + p_sc_ctrlpt->procedure_status = BLE_SCPT_INDICATION_PENDING; // If the application returns an error, the response is to be sent right away and the calibration is considered as not started. + } + } + } + else + { + rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED; + } + break; + + default: + rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED; + break; + } + + } + + p_sc_ctrlpt->response.len = ctrlpt_rsp_encode(p_sc_ctrlpt, &rsp, + p_sc_ctrlpt->response.encoded_ctrl_rsp); + + + if (p_sc_ctrlpt->procedure_status == BLE_SCPT_INDICATION_PENDING) + { + sc_ctrlpt_resp_send(p_sc_ctrlpt); + } +} + + +/**@brief Authorize WRITE request event handler. + * + * @details Handles WRITE events from the BLE stack. + * + * @param[in] p_sc_ctrlpt SC Ctrlpt structure. + * @param[in] p_gatts_evt GATTS Event received from the BLE stack. + * + */ +static void on_rw_authorize_request(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_gatts_evt_t * p_gatts_evt) +{ + ble_gatts_evt_rw_authorize_request_t * p_auth_req = &p_gatts_evt->params.authorize_request; + if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + if ( (p_gatts_evt->params.authorize_request.request.write.op + != BLE_GATTS_OP_PREP_WRITE_REQ) + && (p_gatts_evt->params.authorize_request.request.write.op + != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + && (p_gatts_evt->params.authorize_request.request.write.op + != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL) + ) + { + if (p_auth_req->request.write.handle == p_sc_ctrlpt->sc_ctrlpt_handles.value_handle) + { + on_ctrlpt_write(p_sc_ctrlpt, &p_auth_req->request.write); + } + } + } +} + + +/**@brief Tx Complete event handler. + * + * @details Tx Complete event handler. + * Handles WRITE events from the BLE stack and if an indication was pending try sending it + * again. + * + * @param[in] p_sc_ctrlpt SC Ctrlpt structure. + * + */ +static void on_tx_complete(ble_sc_ctrlpt_t * p_sc_ctrlpt) +{ + if (p_sc_ctrlpt->procedure_status == BLE_SCPT_INDICATION_PENDING) + { + sc_ctrlpt_resp_send(p_sc_ctrlpt); + } +} + + +/**@brief Function for handling the Connect event. + * + * @param[in] p_sc_ctrlpt SC Ctrlpt structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_evt_t * p_ble_evt) +{ + p_sc_ctrlpt->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS; +} + + +/**@brief Function for handling the Disconnect event. + * + * @param[in] p_sc_ctrlpt SC Ctrlpt structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_evt_t * p_ble_evt) +{ + UNUSED_PARAMETER(p_ble_evt); + p_sc_ctrlpt->conn_handle = BLE_CONN_HANDLE_INVALID; + p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS; +} + + +/**@brief Function for handling the BLE_GATTS_EVT_HVC event. + * + * @param[in] p_sc_ctrlpt SC Ctrlpt structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_sc_hvc_confirm(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_evt_t * p_ble_evt) +{ + if (p_ble_evt->evt.gatts_evt.params.hvc.handle == p_sc_ctrlpt->sc_ctrlpt_handles.value_handle) + { + if (p_sc_ctrlpt->procedure_status == BLE_SCPT_IND_CONFIRM_PENDING) + { + p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS; + } + } +} + + +void ble_sc_ctrlpt_on_ble_evt(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_sc_ctrlpt, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_sc_ctrlpt, p_ble_evt); + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + on_rw_authorize_request(p_sc_ctrlpt, &p_ble_evt->evt.gatts_evt); + break; + + case BLE_GATTS_EVT_HVC: + on_sc_hvc_confirm(p_sc_ctrlpt, p_ble_evt); + break; + + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + on_tx_complete(p_sc_ctrlpt); + break; + + default: + break; + } +} + + +uint32_t ble_sc_ctrlpt_rsp_send(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_scpt_response_t response_status) +{ + uint32_t err_code = NRF_SUCCESS; + ble_sc_ctrlpt_rsp_t rsp; + uint8_t encoded_ctrl_rsp[BLE_SC_CTRLPT_MAX_LEN]; + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + + if (p_sc_ctrlpt->procedure_status != BLE_SCPT_AUTOMATIC_CALIB_IN_PROGRESS) + { + return NRF_ERROR_INVALID_STATE; + } + rsp.status = response_status; + rsp.opcode = BLE_SCPT_START_AUTOMATIC_CALIBRATION; + hvx_len = ctrlpt_rsp_encode(p_sc_ctrlpt, &rsp, encoded_ctrl_rsp); + + // Send indication + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_sc_ctrlpt->sc_ctrlpt_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_INDICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_ctrl_rsp; + + err_code = sd_ble_gatts_hvx(p_sc_ctrlpt->conn_handle, &hvx_params); + + if (err_code == NRF_SUCCESS) + { + p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS; + } + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.h new file mode 100644 index 0000000000000000000000000000000000000000..b9f9f3fd372abbf0268b661a17c2d0fda9dd724a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.h @@ -0,0 +1,247 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_srv_sc_ctrlpt Speed and Cadence Control Point + * @{ + * @ingroup ble_sdk_srv + * @brief Speed and Cadence Control Point module. + * + * @details This module implements the Speed and Cadence control point behavior. It is used + * by the @ref ble_cscs module and the ble_sdk_srv_rsc module for control point + * mechanisms like setting a cumulative value, Start an automatic calibration, + * Update the sensor location or request the supported locations. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#ifndef BLE_SC_CTRLPT_H__ +#define BLE_SC_CTRLPT_H__ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "ble_sensor_location.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_SC_CTRLPT_MAX_LEN 19 /**< maximum lenght for Speed and cadence control point characteristic value. */ +#define BLE_SC_CTRLPT_MIN_LEN 1 /**< minimum length for Speed and cadence control point characteristic value. */ + +// Forward declaration of the ble_sc_ctrlpt_t type. +typedef struct ble_sc_ctrlpt_s ble_sc_ctrlpt_t; + + +/**@brief Speed and Cadence Control Point event type. */ +typedef enum +{ + BLE_SC_CTRLPT_EVT_UPDATE_LOCATION, /**< rcvd update location opcode (the control point handles the change of location automatically, the event just informs the application in case it needs to adjust its algorithm). */ + BLE_SC_CTRLPT_EVT_SET_CUMUL_VALUE, /**< rcvd set cumulative value opcode, it is then up to the application to use the new cumulative value. */ + BLE_SC_CTRLPT_EVT_START_CALIBRATION, /**< rcvd start calibration opcode, the application needs, at the end ot the calibration to call ble_sc_ctrlpt_send_rsp. */ +} ble_sc_ctrlpt_evt_type_t; + + +/**@brief Speed and Cadence Control point event. */ +typedef struct +{ + ble_sc_ctrlpt_evt_type_t evt_type; /**< Type of event. */ + union + { + ble_sensor_location_t update_location; + uint32_t cumulative_value; + }params; +} ble_sc_ctrlpt_evt_t; + + +/** Speed and Cadence Control Point operator code (see RSC service specification)*/ +typedef enum { + BLE_SCPT_SET_CUMULATIVE_VALUE = 0x01, /**< Operator to set a given cumulative value. */ + BLE_SCPT_START_AUTOMATIC_CALIBRATION = 0x02, /**< Operator to start automatic calibration. */ + BLE_SCPT_UPDATE_SENSOR_LOCATION = 0x03, /**< Operator to update the sensor location. */ + BLE_SCPT_REQUEST_SUPPORTED_SENSOR_LOCATIONS = 0x04, /**< Operator to request the supported sensor locations. */ + BLE_SCPT_RESPONSE_CODE = 0x10, /**< Response Code. */ +} ble_scpt_operator_t; + + +/** Speed and Cadence Control Point response parameter (see RSC service specification)*/ +typedef enum { + BLE_SCPT_SUCCESS = 0x01, /**< Sucess Response. */ + BLE_SCPT_OP_CODE_NOT_SUPPORTED = 0x02, /**< Error Response received opcode not supported. */ + BLE_SCPT_INVALID_PARAMETER = 0x03, /**< Error Response received parameter invalid. */ + BLE_SCPT_OPERATION_FAILED = 0x04, /**< Error Response operation failed. */ +} ble_scpt_response_t; + + +/** Speed and Cadence Control Point procedure status (indicates is a procedure is in progress or not and which procedure is in progress*/ +typedef enum { + BLE_SCPT_NO_PROC_IN_PROGRESS = 0x00, /**< No procedure in progress. */ + BLE_SCPT_AUTOMATIC_CALIB_IN_PROGRESS = 0x01, /**< Automatic Calibration is in progress. */ + BLE_SCPT_INDICATION_PENDING = 0x02, /**< Control Point Indication is pending. */ + BLE_SCPT_IND_CONFIRM_PENDING = 0x03, /**< Waiting for the indication confirmation. */ +}ble_scpt_procedure_status_t; + +/**@brief Speed and Cadence Control point event handler type. */ +typedef ble_scpt_response_t (*ble_sc_ctrlpt_evt_handler_t) (ble_sc_ctrlpt_t * p_sc_ctrlpt, + ble_sc_ctrlpt_evt_t * p_evt); + + +typedef struct{ + ble_scpt_operator_t opcode; + uint32_t cumulative_value; + ble_sensor_location_t location; +}ble_sc_ctrlpt_val_t; + + +typedef struct{ + ble_scpt_operator_t opcode; + ble_scpt_response_t status; + ble_sensor_location_t location_list[BLE_NB_MAX_SENSOR_LOCATIONS]; +}ble_sc_ctrlpt_rsp_t; + + +/** + * \defgroup BLE_SRV_SC_CTRLPT_SUPP_FUNC Control point functionalities. + *@{ + */ +#define BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED 0x01 /**< Support for sensor location related operations */ +#define BLE_SRV_SC_CTRLPT_CUM_VAL_OP_SUPPORTED 0x02 /**< Support for setting cumulative value related operations */ +#define BLE_SRV_SC_CTRLPT_START_CALIB_OP_SUPPORTED 0x04 /**< Support for starting calibration related operations */ +/** + *@} + */ + +/**@brief Speed and Cadence Control Point init structure. This contains all options and data +* needed for initialization of the Speed and Cadence Control Point module. */ +typedef struct +{ + ble_srv_cccd_security_mode_t sc_ctrlpt_attr_md; /**< Initial security level for cycling speed and cadence control point attribute */ + uint8_t supported_functions; /**< supported control point functionalities see @ref BLE_SRV_SC_CTRLPT_SUPP_FUNC. */ + uint16_t service_handle; /**< Handle of the parent service (as provided by the BLE stack). */ + ble_sc_ctrlpt_evt_handler_t evt_handler; /**< event handler */ + ble_sensor_location_t *list_supported_locations; /**< list of supported sensor locations.*/ + uint8_t size_list_supported_locations; /**< number of supported sensor locations in the list.*/ + uint16_t sensor_location_handle; /**< handle for the sensor location characteristic (if sensor_location related operation are supported).*/ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ +} ble_cs_ctrlpt_init_t; + + +/**@brief Speed and Cadence Control Point response indication structure. */ +typedef struct +{ + ble_scpt_response_t status; /**< control point response status .*/ + uint8_t len; /**< control point response length .*/ + uint8_t encoded_ctrl_rsp[BLE_SC_CTRLPT_MAX_LEN]; /**< control point encoded response.*/ +}ble_sc_ctrlpt_resp_t; + + +/**@brief Speed and Cadence Control Point structure. This contains various status information for + * the Speed and Cadence Control Point behavior. */ +struct ble_sc_ctrlpt_s +{ + uint8_t supported_functions; /**< supported control point functionalities see @ref BLE_SRV_SC_CTRLPT_SUPP_FUNC. */ + uint16_t service_handle; /**< Handle of the parent service (as provided by the BLE stack). */ + ble_gatts_char_handles_t sc_ctrlpt_handles; /**< Handles related to the Speed and Cadence Control Point characteristic. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ + ble_sensor_location_t list_supported_locations[BLE_NB_MAX_SENSOR_LOCATIONS]; /**< list of supported sensor locations.*/ + uint8_t size_list_supported_locations; /**< number of supported sensor locations in the list.*/ + ble_sc_ctrlpt_evt_handler_t evt_handler; /**< Handle of the parent service (as provided by the BLE stack). */ + uint16_t sensor_location_handle; /**< handle for the sensor location characteristic (if sensor_location related operation are supported).*/ + ble_scpt_procedure_status_t procedure_status; /**< status of possible procedure*/ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + ble_sc_ctrlpt_resp_t response; /**< pending response data.*/ +}; + +#define SCPT_OPCODE_POS 0 /**< Request opcode position. */ +#define SCPT_PARAMETER_POS 1 /**< Request parameter position. */ + +#define SCPT_RESPONSE_REQUEST_OPCODE_POS 1 /**< Response position of requested opcode. */ +#define SCPT_RESPONSE_CODE_POS 2 /**< Response position of response code. */ +#define SCPT_RESPONSE_PARAMETER 3 /**< Response position of response parameter. */ + +#define SCPT_MIN_RESPONSE_SIZE 3 /**< Minimum size for control point response. */ +#define SCPT_MAX_RESPONSE_SIZE (SCPT_MIN_RESPONSE_SIZE + NB_MAX_SENSOR_LOCATIONS) /**< Maximum size for control point response. */ + + +/**@brief Function for Initializing the Speed and Cadence Control Point. + * + * @details Function for Initializing the Speed and Cadence Control Point. + * @param[in] p_sc_ctrlpt Speed and Cadence Control Point structure. + * @param[in] p_sc_ctrlpt_init Information needed to initialize the control point behavior. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +uint32_t ble_sc_ctrlpt_init(ble_sc_ctrlpt_t * p_sc_ctrlpt, + const ble_cs_ctrlpt_init_t * p_sc_ctrlpt_init); + + +/**@brief Function for sending a control point response. + * + * @details Function for sending a control point response when the control point received was + * BLE_SCPT_START_AUTOMATIC_CALIBRATION. To be called after the calibration procedure is finished. + * + * @param[in] p_sc_ctrlpt Speed and Cadence Control Point structure. + * @param[in] response_status status to include in the control point response. + */ +uint32_t ble_sc_ctrlpt_rsp_send(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_scpt_response_t response_status); + + +/**@brief Speed and Cadence Control Point BLE stack event handler. + * + * @details Handles all events from the BLE stack of interest to the Speed and Cadence Control Point. + * + * @param[in] p_sc_ctrlpt Speed and Cadence Control Point structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_sc_ctrlpt_on_ble_evt(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_evt_t * p_ble_evt); + + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_SC_CTRLPT_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cts_c/ble_cts_c.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cts_c/ble_cts_c.c new file mode 100644 index 0000000000000000000000000000000000000000..ac64bd2dc2ceff201b983d95bbea36ab4f43e067 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cts_c/ble_cts_c.c @@ -0,0 +1,359 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_CTS_C) +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "ble_gattc.h" +#include "ble_cts_c.h" +#include "ble_date_time.h" +#include "ble_db_discovery.h" +#define NRF_LOG_MODULE_NAME "BLE_CTS_C" +#include "nrf_log.h" + +#define CTS_YEAR_MIN 1582 /**< The lowest valid Current Time year is the year when the western calendar was introduced. */ +#define CTS_YEAR_MAX 9999 /**< The highest possible Current Time. */ + +#define CTS_C_CURRENT_TIME_EXPECTED_LENGTH 10 /**< | Year |Month |Day |Hours |Minutes |Seconds |Weekday |Fraction|Reason | + | 2 bytes |1 byte |1 byte |1 byte |1 byte |1 byte |1 byte |1 byte |1 byte | = 10 bytes. */ + + +/**@brief Function for handling events from the database discovery module. + * + * @details This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of Current Time Service at the peer. If so, it will + * call the application's event handler indicating that the Current Time Service has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param[in] p_evt Pointer to the event received from the database discovery module. + * + */ +void ble_cts_c_on_db_disc_evt(ble_cts_c_t * p_cts, ble_db_discovery_evt_t * p_evt) +{ + NRF_LOG_DEBUG("Database Discovery handler called with event 0x%x\r\n", p_evt->evt_type); + + ble_cts_c_evt_t evt; + const ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics; + + evt.evt_type = BLE_CTS_C_EVT_DISCOVERY_FAILED; + evt.conn_handle = p_evt->conn_handle; + + // Check if the Current Time Service was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && + p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_CURRENT_TIME_SERVICE && + p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) + { + + // Find the handles of the Current Time characteristic. + uint32_t i; + + for (i = 0; i < p_evt->params.discovered_db.char_count; i++) + { + if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid == + BLE_UUID_CURRENT_TIME_CHAR) + { + // Found Current Time characteristic. Store CCCD and value handle and break. + evt.params.char_handles.cts_handle = p_chars->characteristic.handle_value; + evt.params.char_handles.cts_cccd_handle = p_chars->cccd_handle; + break; + } + } + + NRF_LOG_INFO("Current Time Service discovered at peer.\r\n"); + + evt.evt_type = BLE_CTS_C_EVT_DISCOVERY_COMPLETE; + } + p_cts->evt_handler(p_cts, &evt); +} + + +uint32_t ble_cts_c_init(ble_cts_c_t * p_cts, ble_cts_c_init_t const * p_cts_init) +{ + //Verify that the parameters needed for to initialize this instance of CTS are not NULL. + VERIFY_PARAM_NOT_NULL(p_cts); + VERIFY_PARAM_NOT_NULL(p_cts_init); + VERIFY_PARAM_NOT_NULL(p_cts_init->error_handler); + VERIFY_PARAM_NOT_NULL(p_cts_init->evt_handler); + + static ble_uuid_t cts_uuid; + + BLE_UUID_BLE_ASSIGN(cts_uuid, BLE_UUID_CURRENT_TIME_SERVICE); + + p_cts->evt_handler = p_cts_init->evt_handler; + p_cts->error_handler = p_cts_init->error_handler; + p_cts->conn_handle = BLE_CONN_HANDLE_INVALID; + p_cts->char_handles.cts_handle = BLE_GATT_HANDLE_INVALID; + p_cts->char_handles.cts_cccd_handle = BLE_GATT_HANDLE_INVALID; + + return ble_db_discovery_evt_register(&cts_uuid); +} + + +/**@brief Function for decoding a read from the current time characteristic. + * + * @param[in] p_time Current Time structure. + * @param[in] p_data Pointer to the buffer containing the current time. + * @param[in] length length of the buffer containing the current time. + * + * @return NRF_SUCCESS if the time struct is valid. + * @return NRF_ERROR_DATA_SIZE if length does not match the expected size of the data. + */ +static uint32_t current_time_decode(current_time_char_t * p_time, + const uint8_t * p_data, + const uint32_t length) +{ + //lint -save -e415 -e416 "Access of out of bounds pointer" "Creation of out of bounds pointer" + + if (length != CTS_C_CURRENT_TIME_EXPECTED_LENGTH) + { + // Return to prevent accessing out of bounds data. + return NRF_ERROR_DATA_SIZE; + } + + NRF_LOG_DEBUG("Current Time read response data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG(p_data, 10); + + uint32_t index = 0; + + // Date. + index += ble_date_time_decode(&p_time->exact_time_256.day_date_time.date_time, p_data); + + // Day of week. + p_time->exact_time_256.day_date_time.day_of_week = p_data[index++]; + + // Fractions of a second. + p_time->exact_time_256.fractions256 = p_data[index++]; + + // Reason for updating the time. + p_time->adjust_reason.manual_time_update = (p_data[index] >> 0) & 0x01; + p_time->adjust_reason.external_reference_time_update = (p_data[index] >> 1) & 0x01; + p_time->adjust_reason.change_of_time_zone = (p_data[index] >> 2) & 0x01; + p_time->adjust_reason.change_of_daylight_savings_time = (p_data[index] >> 3) & 0x01; + + + //lint -restore + return NRF_SUCCESS; +} + + +/**@brief Function for decoding a read from the current time characteristic. + * + * @param[in] p_time Current Time struct. + * + * @return NRF_SUCCESS if the time struct is valid. + * @return NRF_ERROR_INVALID_DATA if the time is out of bounds. + */ +static uint32_t current_time_validate(current_time_char_t * p_time) +{ + // Year. + if ( (p_time->exact_time_256.day_date_time.date_time.year > CTS_YEAR_MAX) + || ((p_time->exact_time_256.day_date_time.date_time.year < CTS_YEAR_MIN) + && (p_time->exact_time_256.day_date_time.date_time.year != 0))) + { + return NRF_ERROR_INVALID_DATA; + } + + // Month. + if (p_time->exact_time_256.day_date_time.date_time.month > 12) + { + return NRF_ERROR_INVALID_DATA; + } + + // Day. + if (p_time->exact_time_256.day_date_time.date_time.day > 31) + { + return NRF_ERROR_INVALID_DATA; + } + + // Hours. + if (p_time->exact_time_256.day_date_time.date_time.hours > 23) + { + return NRF_ERROR_INVALID_DATA; + } + + // Minutes. + if (p_time->exact_time_256.day_date_time.date_time.minutes > 59) + { + return NRF_ERROR_INVALID_DATA; + } + + // Seconds. + if (p_time->exact_time_256.day_date_time.date_time.seconds > 59) + { + return NRF_ERROR_INVALID_DATA; + } + + // Day of week. + if (p_time->exact_time_256.day_date_time.day_of_week > 7) + { + return NRF_ERROR_INVALID_DATA; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for reading the current time. The time is decoded, then it is validated. + * Depending on the outcome the cts event handler will be called with + * the current time event or an invalid time event. + * + * @param[in] p_cts Current Time Service client structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void current_time_read(ble_cts_c_t * p_cts, const ble_evt_t * p_ble_evt) +{ + ble_cts_c_evt_t evt; + uint32_t err_code = NRF_SUCCESS; + + // Check if the event is on the same connection as this cts instance + if (p_cts->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + + if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_SUCCESS) + { + err_code = current_time_decode(&evt.params.current_time, + p_ble_evt->evt.gattc_evt.params.read_rsp.data, + p_ble_evt->evt.gattc_evt.params.read_rsp.len); + + if (err_code != NRF_SUCCESS) + { + // The data length was invalid, decoding was not completed. + evt.evt_type = BLE_CTS_C_EVT_INVALID_TIME; + } + else + { + // Verify That the time is valid. + err_code = current_time_validate(&evt.params.current_time); + + if (err_code != NRF_SUCCESS) + { + // Invalid time received. + evt.evt_type = BLE_CTS_C_EVT_INVALID_TIME; + } + else + { + // Valid time reveiced. + evt.evt_type = BLE_CTS_C_EVT_CURRENT_TIME; + } + } + p_cts->evt_handler(p_cts, &evt); + } +} + + +/**@brief Function for handling the Disconnect event. + * + * @param[in] p_cts Current Time Service client structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_cts_c_t * p_cts, ble_evt_t const * p_ble_evt) +{ + if (p_cts->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_cts->conn_handle = BLE_CONN_HANDLE_INVALID; + } + + if (ble_cts_c_is_cts_discovered(p_cts)) + { + // There was a valid instance of cts on the peer. Send an event to the + // application, so that it can do any clean up related to this module. + ble_cts_c_evt_t evt; + + evt.evt_type = BLE_CTS_C_EVT_DISCONN_COMPLETE; + + p_cts->evt_handler(p_cts, &evt); + p_cts->char_handles.cts_handle = BLE_GATT_HANDLE_INVALID; + p_cts->char_handles.cts_cccd_handle = BLE_GATT_HANDLE_INVALID; + } +} + + +void ble_cts_c_on_ble_evt(ble_cts_c_t * p_cts, ble_evt_t const * p_ble_evt) +{ + NRF_LOG_DEBUG("BLE event handler called with event 0x%x\r\n", p_ble_evt->header.evt_id); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTC_EVT_READ_RSP: + current_time_read(p_cts, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_cts, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +uint32_t ble_cts_c_current_time_read(ble_cts_c_t const * p_cts) +{ + if (!ble_cts_c_is_cts_discovered(p_cts)) + { + return NRF_ERROR_NOT_FOUND; + } + + return sd_ble_gattc_read(p_cts->conn_handle, p_cts->char_handles.cts_handle, 0); +} + + +uint32_t ble_cts_c_handles_assign(ble_cts_c_t * p_cts, + const uint16_t conn_handle, + const ble_cts_c_handles_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_cts); + + p_cts->conn_handle = conn_handle; + if (p_peer_handles != NULL) + { + p_cts->char_handles.cts_cccd_handle = p_peer_handles->cts_cccd_handle; + p_cts->char_handles.cts_handle = p_peer_handles->cts_handle; + } + + return NRF_SUCCESS; +} +#endif // NRF_MODULE_ENABLED(BLE_CTS_C) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cts_c/ble_cts_c.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cts_c/ble_cts_c.h new file mode 100644 index 0000000000000000000000000000000000000000..3886f790a46b98c83ed6a8dc82ab2ea07527c75d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_cts_c/ble_cts_c.h @@ -0,0 +1,255 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_cts_c Current Time Service client + * @{ + * @ingroup ble_sdk_srv + * @brief Current Time Service client module. + * + * @details This module implements the Current Time Service (CTS) client-peripheral role of + * the Time Profile. After security is established, the module tries to discover the + * Current Time Service and Characteristic on the central side. If this succeeds, + * the application can trigger a read of the current time from the connected server. + * + * The module informs the application about a successful discovery using the + * @ref BLE_CTS_C_EVT_DISCOVERY_COMPLETE event. The handles for the CTS server is now + * available in the @ref ble_cts_c_evt_t structure. These handles must be assigned to an + * instance of CTS_C, using @ref ble_cts_c_handles_assign. For more information about + * service discovery, see the ble_discovery module documentation @ref lib_ble_db_discovery. + * + * The application can then use the function @ref ble_cts_c_current_time_read to read the + * current time. If the read succeeds, it will trigger either a + * @ref BLE_CTS_C_EVT_CURRENT_TIME event or a @ref BLE_CTS_C_EVT_INVALID_TIME event + * (depending on if the data that was read was actually a valid time), which is then sent + * to the application. The current time is then available in the params field of the + * passed @ref ble_cts_c_evt_t structure. + * + * @note The application must propagate BLE stack events to this module by calling + * ble_cts_c_on_ble_evt() from the @ref softdevice_handler callback function. + */ + +#ifndef BLE_CTS_C_H__ +#define BLE_CTS_C_H__ + +#include "ble_srv_common.h" +#include "ble_gattc.h" +#include "ble.h" +#include "ble_date_time.h" +#include "ble_db_discovery.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief "Day Date Time" field of the "Exact Time 256" field of the Current Time Characteristic. */ +typedef struct +{ + ble_date_time_t date_time; + uint8_t day_of_week; +} day_date_time_t; + +/**@brief "Exact Time 256" field of the Current Time Characteristic. */ +typedef struct +{ + day_date_time_t day_date_time; + uint8_t fractions256; +} exact_time_256_t; + +/**@brief "Adjust Reason" field of the Current Time Characteristic. */ +typedef struct +{ + uint8_t manual_time_update : 1; + uint8_t external_reference_time_update : 1; + uint8_t change_of_time_zone : 1; + uint8_t change_of_daylight_savings_time : 1; +} adjust_reason_t; + +/**@brief Data structure for the Current Time Characteristic. */ +typedef struct +{ + exact_time_256_t exact_time_256; + adjust_reason_t adjust_reason; +} current_time_char_t; + +// Forward declaration of the ble_cts_c_t type. +typedef struct ble_cts_c_s ble_cts_c_t; + +/**@brief Current Time Service client event type. */ +typedef enum +{ + BLE_CTS_C_EVT_DISCOVERY_COMPLETE, /**< The Current Time Service was found at the peer. */ + BLE_CTS_C_EVT_DISCOVERY_FAILED, /**< The Current Time Service was not found at the peer. */ + BLE_CTS_C_EVT_DISCONN_COMPLETE, /**< Event indicating that the Current Time Service client module has finished processing the BLE_GAP_EVT_DISCONNECTED event. This event is raised only if a valid instance of the Current Time Service was found at the server. The event can be used by the application to do clean up related to the Current Time Service client.*/ + BLE_CTS_C_EVT_CURRENT_TIME, /**< A new current time reading has been received. */ + BLE_CTS_C_EVT_INVALID_TIME /**< The current time value received from the peer is invalid.*/ +} ble_cts_c_evt_type_t; + +/**@brief Structure containing the handles related to the Heart Rate Service found on the peer. */ +typedef struct +{ + uint16_t cts_handle; /**< Handle of the Current Time characteristic as provided by the SoftDevice. */ + uint16_t cts_cccd_handle; /**< Handle of the CCCD of the Current Time characteristic. */ +} ble_cts_c_handles_t; + +/**@brief Current Time Service client event. */ +typedef struct +{ + ble_cts_c_evt_type_t evt_type; /**< Type of event. */ + uint16_t conn_handle; /**< Connection handle on which the CTS service was discovered on the peer device. This will be filled if the evt_type is @ref BLE_CTS_C_EVT_DISCOVERY_COMPLETE.*/ + union + { + current_time_char_t current_time; /**< Current Time Characteristic data. This will be filled when the evt_type is @ref BLE_CTS_C_EVT_CURRENT_TIME. */ + ble_cts_c_handles_t char_handles; /**< Current Time related handles found on the peer device. This will be filled when the evt_type is @ref BLE_HRS_C_EVT_DISCOVERY_COMPLETE.*/ + } params; +} ble_cts_c_evt_t; + +/**@brief Current Time Service client event handler type. */ +typedef void (* ble_cts_c_evt_handler_t) (ble_cts_c_t * p_cts, ble_cts_c_evt_t * p_evt); + + +/**@brief Current Time Service client structure. This structure contains status information for the client. */ +struct ble_cts_c_s +{ + ble_cts_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events from the Current Time Service client. */ + ble_srv_error_handler_t error_handler; /**< Function to be called if an error occurs. */ + ble_cts_c_handles_t char_handles; /**< Handles of Current Time Characteristic at the peer (handles are provided by the BLE stack through the DB Discovery module). */ + uint16_t conn_handle; /**< Handle of the current connection. BLE_CONN_HANDLE_INVALID if not in a connection. */ +}; + +/**@brief Current Time Service client init structure. This structure contains all options and data needed for initialization of the client.*/ +typedef struct +{ + ble_cts_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events from the Current Time Service client. */ + ble_srv_error_handler_t error_handler; /**< Function to be called if an error occurs. */ +} ble_cts_c_init_t; + + +/**@brief Function for initializing the Current Time Service client. + * + * @details This function must be used by the application to initialize the Current Time Service client. + * + * @param[out] p_cts Current Time Service client structure. This structure must + * be supplied by the application. It is initialized by this + * function and can later be used to identify this particular client + * instance. + * @param[in] p_cts_init Information needed to initialize the Current Time Service client. + * + * @retval NRF_SUCCESS If the service was initialized successfully. + */ +uint32_t ble_cts_c_init(ble_cts_c_t * p_cts, const ble_cts_c_init_t * p_cts_init); + + +/**@brief Function for handling events from the database discovery module. + * + * @details This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of CTS at the peer. If so, it will + * call the application's event handler indicating that CTS has been + * discovered. It also populates the event with the service related + * information before providing it to the application. + * + * @param[in] p_cts Pointer to the CTS client structure. + * @param[in] p_evt Pointer to the event received from the database discovery module. + */ + void ble_cts_c_on_db_disc_evt(ble_cts_c_t * p_cts, ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for handling the application's BLE stack events. + * + * @details This function handles all events from the BLE stack that are of interest to the + * Current Time Service client. This is a callback function that must be dispatched + * from main application context. + * + * @param[in] p_cts Current Time Service client structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_cts_c_on_ble_evt(ble_cts_c_t * p_cts, const ble_evt_t * p_ble_evt); + + +/**@brief Function for checking whether the peer's Current Time Service instance and the Current Time + * Characteristic have been discovered. + * + * @param[in] p_cts Current Time Service client structure. + */ +static __INLINE bool ble_cts_c_is_cts_discovered(const ble_cts_c_t * p_cts) +{ + return (p_cts->char_handles.cts_handle != BLE_GATT_HANDLE_INVALID); +} + + +/**@brief Function for reading the peer's Current Time Service Current Time Characteristic. + * + * @param[in] p_cts Current Time Service client structure. + * + * @retval NRF_SUCCESS If the operation is successful. Otherwise, an error code is returned. + */ +uint32_t ble_cts_c_current_time_read(ble_cts_c_t const * p_cts); + + +/**@brief Function for assigning handles to a this instance of cts_c. + * + * @details Call this function when a link has been established with a peer to + * associate the link to this instance of the module. This makes it + * possible to handle several links and associate each link to a particular + * instance of this module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_CTS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_cts Pointer to the CTS client structure instance to associate. + * @param[in] conn_handle Connection handle to associated with the given CTS instance. + * @param[in] p_peer_handles Attribute handles for the CTS server you want this CTS client to + * interact with. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If a p_cts was a NULL pointer. + */ +uint32_t ble_cts_c_handles_assign(ble_cts_c_t * p_cts, + const uint16_t conn_handle, + const ble_cts_c_handles_t * p_peer_handles); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_CTS_C_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_dfu/ble_dfu.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_dfu/ble_dfu.c new file mode 100644 index 0000000000000000000000000000000000000000..76bd847c12ebaab2fe39c335b520d3628b4b4198 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_dfu/ble_dfu.c @@ -0,0 +1,457 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ + +#include "ble_dfu.h" +#include "nrf_log.h" +#include +#include "ble_hci.h" +#include "sdk_macros.h" +#include "ble_srv_common.h" +#include "nrf_nvic.h" +#include "nrf_sdm.h" +#include "nrf_soc.h" +#include "nrf_log.h" + +#define MAX_CTRL_POINT_RESP_PARAM_LEN 3 +#define IRQ_ENABLED 0x01 /**< Field that identifies if an interrupt is enabled. */ +#define MAX_NUMBER_INTERRUPTS 32 /**< Maximum number of interrupts available. */ +#define BOOTLOADER_DFU_START 0xB1 + +#define BLE_DFU_SERVICE_UUID 0xFE59 //!< The 16-bit UUID of the Secure DFU Service. + +/**@brief Function for disabling all interrupts before jumping from bootloader to application. + */ +static void interrupts_disable(void) +{ + uint32_t interrupt_setting_mask; + uint32_t irq; + + // Fetch the current interrupt settings. + interrupt_setting_mask = NVIC->ISER[0]; + + // Loop from interrupt 0 for disabling of all interrupts. + for (irq = 0; irq < MAX_NUMBER_INTERRUPTS; irq++) + { + if (interrupt_setting_mask & (IRQ_ENABLED << irq)) + { + // The interrupt was enabled, hence disable it. + NVIC_DisableIRQ((IRQn_Type)irq); + } + } +} + +/**@brief Function for preparing the reset, disabling SoftDevice, and jumping to the bootloader. + * + */ +static uint32_t bootloader_start(void) +{ + uint32_t err_code; + + err_code = sd_power_gpregret_clr(0, 0xffffffff); + VERIFY_SUCCESS(err_code); + + err_code = sd_power_gpregret_set(0, BOOTLOADER_DFU_START); + VERIFY_SUCCESS(err_code); + + err_code = sd_softdevice_disable(); + VERIFY_SUCCESS(err_code); + + err_code = sd_softdevice_vector_table_base_set(NRF_UICR->NRFFW[0]); + VERIFY_SUCCESS(err_code); + + NVIC_ClearPendingIRQ(SWI2_IRQn); + interrupts_disable(); + + NVIC_SystemReset(); + return NRF_SUCCESS; +} + +static void enter_bootloader(ble_dfu_t * p_dfu) +{ + if (p_dfu->evt_handler != NULL) + { + ble_dfu_evt_t evt; + + evt.type = BLE_DFU_EVT_ENTERING_BOOTLOADER; + + p_dfu->evt_handler(p_dfu, &evt); + } + + // Set the flag to indicate that the device will be reset when we have + // received hvc confirmation on indication + p_dfu->is_waiting_for_reset = true; +} + + +/**@brief Function for adding RX characteristic. + * + * @param[in] p_dfu Nordic DFU Service structure. + * @param[in] p_dfu_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t buttonless_char_pt_add(ble_dfu_t * p_dfu, const ble_dfu_init_t * p_dfu_init) +{ + ble_gatts_char_md_t char_md = {{0}}; + ble_gatts_attr_md_t cccd_md = {{0}}; + ble_gatts_attr_t attr_char_value = {0}; + ble_gatts_attr_md_t attr_md = {{0}}; + ble_uuid_t char_uuid; + + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); + + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + + char_md.char_props.indicate = 1; + char_md.char_props.write = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = NULL; + + char_uuid.type = p_dfu->uuid_type; + char_uuid.uuid = BLE_DFU_BUTTONLESS_CHAR_UUID; + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 1; + attr_md.vlen = 1; + + attr_char_value.p_uuid = &char_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = 0; + attr_char_value.init_offs = 0; + attr_char_value.max_len = BLE_GATT_ATT_MTU_DEFAULT; + attr_char_value.p_value = 0; + + return sd_ble_gatts_characteristic_add(p_dfu->service_handle, + &char_md, + &attr_char_value, + &p_dfu->control_point_char); +} + + + +uint32_t ble_dfu_init(ble_dfu_t * p_dfu, const ble_dfu_init_t * p_dfu_init) +{ + uint32_t err_code; + ble_uuid_t service_uuid; + ble_uuid128_t nordic_base_uuid = BLE_NORDIC_VENDOR_BASE_UUID; + + VERIFY_PARAM_NOT_NULL(p_dfu); + VERIFY_PARAM_NOT_NULL(p_dfu_init); + + // Initialize the service structure. + p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID; + p_dfu->evt_handler = p_dfu_init->evt_handler; + p_dfu->is_waiting_for_reset = false; + p_dfu->is_ctrlpt_indication_enabled = false; + + + BLE_UUID_BLE_ASSIGN(service_uuid, BLE_DFU_SERVICE_UUID); + + // Add proprietary service + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &service_uuid, + &(p_dfu->service_handle)); + + VERIFY_SUCCESS(err_code); + + // Add vendor specific UUID to use with the Buttonless DFU characteristic + err_code = sd_ble_uuid_vs_add(&nordic_base_uuid, &p_dfu->uuid_type); + VERIFY_SUCCESS(err_code); + + // Add the Buttonless DFU Characteristic. + err_code = buttonless_char_pt_add(p_dfu, p_dfu_init); + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} + +static void resp_send(ble_dfu_t * p_dfu, ble_dfu_buttonless_op_code_t op_code, ble_dfu_rsp_code_t rsp_code) +{ + // Send notification + uint16_t hvx_len; + uint8_t hvx_data[MAX_CTRL_POINT_RESP_PARAM_LEN]; + ble_gatts_hvx_params_t hvx_params; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_len = 3; + hvx_data[0] = DFU_OP_RESPONSE_CODE; + hvx_data[1] = (uint8_t)op_code; + hvx_data[2] = (uint8_t)rsp_code; + + hvx_params.handle = p_dfu->control_point_char.value_handle; + hvx_params.type = BLE_GATT_HVX_INDICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = hvx_data; + + (void)sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params); +} + + + +/**@brief Handle write events to the Location and Navigation Service Control Point characteristic. + * + * @param[in] p_dfu DFU Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_ctrlpt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t const * p_evt_write) +{ + uint32_t err_code; + ble_dfu_rsp_code_t rsp_code = DFU_RSP_OPERATION_FAILED; + + ble_gatts_rw_authorize_reply_params_t write_authorize_reply; + memset(&write_authorize_reply, 0, sizeof(write_authorize_reply)); + + write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + + if (p_dfu->is_ctrlpt_indication_enabled) + { + write_authorize_reply.params.write.update = 1; + write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + } + else + { + write_authorize_reply.params.write.gatt_status = DFU_RSP_CCCD_CONFIG_IMPROPER; + } + + // reply to the write authorization + do { + err_code = sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply); + } while (err_code == NRF_ERROR_BUSY); + + + if (write_authorize_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS) + { + return; + } + + // Start executing the control point write action + NRF_LOG_INFO("on_ctrlpt_write: execute enter\r\n"); + switch (p_evt_write->data[0]) + { + case BLE_DFU_ENTER_BOOTLOADER: + NRF_LOG_DEBUG("on_ctrlpt_write: execuing!!\r\n"); + rsp_code = DFU_RSP_SUCCESS; + break; + + // Unrecognized Op Code + default: + rsp_code = DFU_RSP_OP_CODE_NOT_SUPPORTED; + break; + } + + resp_send(p_dfu, (ble_dfu_buttonless_op_code_t)p_evt_write->data[0], rsp_code); + + if (rsp_code == DFU_RSP_SUCCESS + && p_evt_write->data[0] == BLE_DFU_ENTER_BOOTLOADER) + { + enter_bootloader(p_dfu); + } +} + + +/**@brief Write authorization request event handler. + * + * @details The write authorization request event handler is called when writing to the control point. + * + * @param[in] p_dfu DFU structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_rw_authorize_req(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt) +{ + if (p_ble_evt->evt.gatts_evt.conn_handle != p_dfu->conn_handle) + { + return; + } + + const ble_gatts_evt_rw_authorize_request_t * p_auth_req = + &p_ble_evt->evt.gatts_evt.params.authorize_request; + + if ( + (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + && + (p_auth_req->request.write.handle == p_dfu->control_point_char.value_handle) + && + (p_auth_req->request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ) + && + (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + && + (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL) + ) + { + on_ctrlpt_write(p_dfu, &p_auth_req->request.write); + } +} + +/**@brief Connect event handler. + * + * @param[in] p_dfu DFU Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt) +{ + p_dfu->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; +} + + +/**@brief Disconnect event handler. + * + * @param[in] p_dfu DFU Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt) +{ + if (p_dfu->conn_handle != p_ble_evt->evt.gatts_evt.conn_handle) + { + return; + } + + p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID; +} + +/**@brief Write event handler. + * + * @param[in] p_dfu DFU Service structure. + * @param[in] p_ble_evt Event received from the BLE stack.rtt + */ +static void on_write(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt) +{ + const ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if (p_evt_write->handle != p_dfu->control_point_char.cccd_handle) + { + return; + } + + if (p_evt_write->len == BLE_CCCD_VALUE_LEN) + { + // CCCD written, update indications state + p_dfu->is_ctrlpt_indication_enabled = ble_srv_is_indication_enabled(p_evt_write->data); + + NRF_LOG_INFO("Received indication state %d, notification state %d\r\n", p_dfu->is_ctrlpt_indication_enabled, ble_srv_is_notification_enabled(p_evt_write->data)); + + if (p_dfu->evt_handler != NULL) + { + ble_dfu_evt_t evt; + + if (p_dfu->is_ctrlpt_indication_enabled) + { + evt.type = BLE_DFU_EVT_INDICATION_ENABLED; + } + else + { + evt.type = BLE_DFU_EVT_INDICATION_DISABLED; + } + + p_dfu->evt_handler(p_dfu, &evt); + } + } +} + + +/**@brief Function for handling the HVC event. + * + * @details Handles HVC events from the BLE stack. + * + * @param[in] p_dfu DFU Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_hvc(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_hvc_t * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc; + + if (p_hvc->handle == p_dfu->control_point_char.value_handle) + { + // Enter bootloader if we were waiting for reset after hvc indication confimation. + if (p_dfu->is_waiting_for_reset) + { + (void)bootloader_start(); + } + } +} + + +void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_dfu); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_dfu, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_dfu, p_ble_evt); + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + on_rw_authorize_req(p_dfu, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_dfu, p_ble_evt); + break; + + case BLE_GATTS_EVT_HVC: + on_hvc(p_dfu, p_ble_evt); + break; + + default: + // no implementation + break; + } + +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_dfu/ble_dfu.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_dfu/ble_dfu.h new file mode 100644 index 0000000000000000000000000000000000000000..85a353fab5fec39a97d85ee70d5bd58eee176d83 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_dfu/ble_dfu.h @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_dfu Buttonless DFU Service + * @{ + * @ingroup ble_sdk_srv + * @brief Buttonless DFU Service module. + * + * @details + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#ifndef BLE_DFU_H__ +#define BLE_DFU_H__ + +#include +#include "ble_srv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_DFU_BUTTONLESS_CHAR_UUID 0x0003 + +/**< Nordic vendor specific base UUID. */ +#define BLE_NORDIC_VENDOR_BASE_UUID \ +{{ \ + 0x50, 0xEA, 0xDA, 0x30, 0x88, 0x83, 0xB8, 0x9F, \ + 0x60, 0x4F, 0x15, 0xF3, 0x00, 0x00, 0xC9, 0x8E \ +}} + +#define BLE_DFU_ENTER_BOOTLOADER 0x01 + +typedef enum { + BLE_DFU_EVT_ENTERING_BOOTLOADER, /**< Event indicating that the bootloader will be entered after return of this event.*/ + BLE_DFU_EVT_INDICATION_ENABLED, /**< Indication that the control point is enabled.*/ + BLE_DFU_EVT_INDICATION_DISABLED /**< Indication that the control point is disabled.*/ +} ble_dfu_evt_type_t; + +typedef struct { + ble_dfu_evt_type_t type; +} ble_dfu_evt_t; + +/* Forward declaration of the ble_dfu_type type. */ +typedef struct ble_dfu_s ble_dfu_t; + +/**@brief Nordic Buttonless DFU Service event handler type. */ +typedef void (*ble_dfu_evt_handler_t) (ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt); + + + +// Control Point response values +typedef enum +{ + DFU_RSP_RESERVED = 0x00, /**< Reserved for future use. */ + DFU_RSP_SUCCESS = 0x01, /**< Success. */ + DFU_RSP_OP_CODE_NOT_SUPPORTED = 0x02, /**< Op Code not supported. */ + DFU_RSP_OPERATION_FAILED = 0x04, /**< Operation Failed. */ + DFU_RSP_CCCD_CONFIG_IMPROPER = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR /**< CCCD is improperly configured. */ +} ble_dfu_rsp_code_t; + +// Control Point Op Code values +typedef enum +{ + DFU_OP_RESERVED = 0x00, /**< Reserved for future use. */ + DFU_OP_ENTER_BOOTLOADER = 0x01, /**< Enter bootloader. */ + DFU_OP_RESPONSE_CODE = 0x20 /**< Response code. */ +} ble_dfu_buttonless_op_code_t; + + + +struct ble_dfu_s { + uint8_t uuid_type; /**< UUID type for DFU UUID. */ + uint16_t service_handle; /**< Handle of DFU (as provided by the SoftDevice). */ + uint16_t conn_handle; + ble_gatts_char_handles_t control_point_char; /**< Handles related to the DFU Control Point characteristic. */ + bool is_ctrlpt_indication_enabled; + + ble_dfu_evt_handler_t evt_handler; /**< Event handler which is called right before. */ + + bool is_waiting_for_reset; /**< Flag indicating that the device will enter bootloader. */ +}; + +typedef struct { + ble_dfu_evt_handler_t evt_handler; /**< Event handler which is called right before. */ + security_req_t ctrl_point_security_req_write_perm; /**< Read security level of the LN Control Point characteristic. */ + security_req_t ctrl_point_security_req_cccd_write_perm; /**< CCCD write security level of the LN Control Point characteristic. */ +} ble_dfu_init_t; + + +/**@brief Function for initializing the Device Firmware Update module + * + * + * @param[in] p_dfu DFU Service structure. + * @param[in] p_dfu_init The structure containing the values of characteristics needed by the + * service. + * + * @return NRF_SUCCESS on successful initialization of service. + */ +uint32_t ble_dfu_init(ble_dfu_t * p_dfu, const ble_dfu_init_t * p_dfu_init); + + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the Battery Service. + * + * @param[in] p_dfu DFU Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_DIS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_dis/ble_dis.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_dis/ble_dis.c new file mode 100644 index 0000000000000000000000000000000000000000..645b034b91ca25440c5d2eff4772d6b5bce101c8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_dis/ble_dis.c @@ -0,0 +1,304 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_DIS) +#include "ble_dis.h" + +#include +#include +#include "app_error.h" +#include "ble_gatts.h" +#include "ble_srv_common.h" + + +#define BLE_DIS_SYS_ID_LEN 8 /**< Length of System ID Characteristic Value. */ +#define BLE_DIS_PNP_ID_LEN 7 /**< Length of Pnp ID Characteristic Value. */ + +static uint16_t service_handle; +static ble_gatts_char_handles_t manufact_name_handles; +static ble_gatts_char_handles_t model_num_handles; +static ble_gatts_char_handles_t serial_num_handles; +static ble_gatts_char_handles_t hw_rev_handles; +static ble_gatts_char_handles_t fw_rev_handles; +static ble_gatts_char_handles_t sw_rev_handles; +static ble_gatts_char_handles_t sys_id_handles; +static ble_gatts_char_handles_t reg_cert_data_list_handles; +static ble_gatts_char_handles_t pnp_id_handles; + + +/**@brief Function for encoding a System ID. + * + * @param[out] p_encoded_buffer Buffer where the encoded data will be written. + * @param[in] p_sys_id System ID to be encoded. + */ +static void sys_id_encode(uint8_t * p_encoded_buffer, const ble_dis_sys_id_t * p_sys_id) +{ + APP_ERROR_CHECK_BOOL(p_sys_id != NULL); + APP_ERROR_CHECK_BOOL(p_encoded_buffer != NULL); + + p_encoded_buffer[0] = (p_sys_id->manufacturer_id & 0x00000000FF); + p_encoded_buffer[1] = (p_sys_id->manufacturer_id & 0x000000FF00) >> 8; + p_encoded_buffer[2] = (p_sys_id->manufacturer_id & 0x0000FF0000) >> 16; + p_encoded_buffer[3] = (p_sys_id->manufacturer_id & 0x00FF000000) >> 24; + p_encoded_buffer[4] = (p_sys_id->manufacturer_id & 0xFF00000000) >> 32; + + p_encoded_buffer[5] = (p_sys_id->organizationally_unique_id & 0x0000FF); + p_encoded_buffer[6] = (p_sys_id->organizationally_unique_id & 0x00FF00) >> 8; + p_encoded_buffer[7] = (p_sys_id->organizationally_unique_id & 0xFF0000) >> 16; +} + + +/**@brief Function for encoding a PnP ID. + * + * @param[out] p_encoded_buffer Buffer where the encoded data will be written. + * @param[in] p_pnp_id PnP ID to be encoded. + */ +static void pnp_id_encode(uint8_t * p_encoded_buffer, const ble_dis_pnp_id_t * p_pnp_id) +{ + uint8_t len = 0; + + APP_ERROR_CHECK_BOOL(p_pnp_id != NULL); + APP_ERROR_CHECK_BOOL(p_encoded_buffer != NULL); + + p_encoded_buffer[len++] = p_pnp_id->vendor_id_source; + + len += uint16_encode(p_pnp_id->vendor_id, &p_encoded_buffer[len]); + len += uint16_encode(p_pnp_id->product_id, &p_encoded_buffer[len]); + len += uint16_encode(p_pnp_id->product_version, &p_encoded_buffer[len]); + + APP_ERROR_CHECK_BOOL(len == BLE_DIS_PNP_ID_LEN); +} + + +/**@brief Function for adding the Characteristic. + * + * @param[in] uuid UUID of characteristic to be added. + * @param[in] p_char_value Initial value of characteristic to be added. + * @param[in] char_len Length of initial value. This will also be the maximum value. + * @param[in] dis_attr_md Security settings of characteristic to be added. + * @param[out] p_handles Handles of new characteristic. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t char_add(uint16_t uuid, + uint8_t * p_char_value, + uint16_t char_len, + const ble_srv_security_mode_t * dis_attr_md, + ble_gatts_char_handles_t * p_handles) +{ + ble_uuid_t ble_uuid; + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_gatts_attr_md_t attr_md; + + APP_ERROR_CHECK_BOOL(p_char_value != NULL); + APP_ERROR_CHECK_BOOL(char_len > 0); + + // The ble_gatts_char_md_t structure uses bit fields. So we reset the memory to zero. + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, uuid); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = dis_attr_md->read_perm; + attr_md.write_perm = dis_attr_md->write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = char_len; + attr_char_value.init_offs = 0; + attr_char_value.max_len = char_len; + attr_char_value.p_value = p_char_value; + + return sd_ble_gatts_characteristic_add(service_handle, &char_md, &attr_char_value, p_handles); +} + + +uint32_t ble_dis_init(const ble_dis_init_t * p_dis_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_DEVICE_INFORMATION_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &service_handle); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add characteristics + if (p_dis_init->manufact_name_str.length > 0) + { + err_code = char_add(BLE_UUID_MANUFACTURER_NAME_STRING_CHAR, + p_dis_init->manufact_name_str.p_str, + p_dis_init->manufact_name_str.length, + &p_dis_init->dis_attr_md, + &manufact_name_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + if (p_dis_init->model_num_str.length > 0) + { + err_code = char_add(BLE_UUID_MODEL_NUMBER_STRING_CHAR, + p_dis_init->model_num_str.p_str, + p_dis_init->model_num_str.length, + &p_dis_init->dis_attr_md, + &model_num_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + if (p_dis_init->serial_num_str.length > 0) + { + err_code = char_add(BLE_UUID_SERIAL_NUMBER_STRING_CHAR, + p_dis_init->serial_num_str.p_str, + p_dis_init->serial_num_str.length, + &p_dis_init->dis_attr_md, + &serial_num_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + if (p_dis_init->hw_rev_str.length > 0) + { + err_code = char_add(BLE_UUID_HARDWARE_REVISION_STRING_CHAR, + p_dis_init->hw_rev_str.p_str, + p_dis_init->hw_rev_str.length, + &p_dis_init->dis_attr_md, + &hw_rev_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + if (p_dis_init->fw_rev_str.length > 0) + { + err_code = char_add(BLE_UUID_FIRMWARE_REVISION_STRING_CHAR, + p_dis_init->fw_rev_str.p_str, + p_dis_init->fw_rev_str.length, + &p_dis_init->dis_attr_md, + &fw_rev_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + if (p_dis_init->sw_rev_str.length > 0) + { + err_code = char_add(BLE_UUID_SOFTWARE_REVISION_STRING_CHAR, + p_dis_init->sw_rev_str.p_str, + p_dis_init->sw_rev_str.length, + &p_dis_init->dis_attr_md, + &sw_rev_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + if (p_dis_init->p_sys_id != NULL) + { + uint8_t encoded_sys_id[BLE_DIS_SYS_ID_LEN]; + + sys_id_encode(encoded_sys_id, p_dis_init->p_sys_id); + err_code = char_add(BLE_UUID_SYSTEM_ID_CHAR, + encoded_sys_id, + BLE_DIS_SYS_ID_LEN, + &p_dis_init->dis_attr_md, + &sys_id_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + if (p_dis_init->p_reg_cert_data_list != NULL) + { + err_code = char_add(BLE_UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR, + p_dis_init->p_reg_cert_data_list->p_list, + p_dis_init->p_reg_cert_data_list->list_len, + &p_dis_init->dis_attr_md, + ®_cert_data_list_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + if (p_dis_init->p_pnp_id != NULL) + { + uint8_t encoded_pnp_id[BLE_DIS_PNP_ID_LEN]; + + pnp_id_encode(encoded_pnp_id, p_dis_init->p_pnp_id); + err_code = char_add(BLE_UUID_PNP_ID_CHAR, + encoded_pnp_id, + BLE_DIS_PNP_ID_LEN, + &p_dis_init->dis_attr_md, + &pnp_id_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} +#endif // NRF_MODULE_ENABLED(BLE_DIS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_dis/ble_dis.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_dis/ble_dis.h new file mode 100644 index 0000000000000000000000000000000000000000..c4cc6177e956b0e547e571580e6cb8d99520a688 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_dis/ble_dis.h @@ -0,0 +1,134 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_dis Device Information Service + * @{ + * @ingroup ble_sdk_srv + * @brief Device Information Service module. + * + * @details This module implements the Device Information Service. + * During initialization it adds the Device Information Service to the BLE stack database. + * It then encodes the supplied information, and adds the corresponding characteristics. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#ifndef BLE_DIS_H__ +#define BLE_DIS_H__ + +#include +#include "ble_srv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup DIS_VENDOR_ID_SRC_VALUES Vendor ID Source values + * @{ + */ +#define BLE_DIS_VENDOR_ID_SRC_BLUETOOTH_SIG 1 /**< Vendor ID assigned by Bluetooth SIG. */ +#define BLE_DIS_VENDOR_ID_SRC_USB_IMPL_FORUM 2 /**< Vendor ID assigned by USB Implementer's Forum. */ +/** @} */ + +/**@brief System ID parameters */ +typedef struct +{ + uint64_t manufacturer_id; /**< Manufacturer ID. Only 5 LSOs shall be used. */ + uint32_t organizationally_unique_id; /**< Organizationally unique ID. Only 3 LSOs shall be used. */ +} ble_dis_sys_id_t; + +/**@brief IEEE 11073-20601 Regulatory Certification Data List Structure */ +typedef struct +{ + uint8_t * p_list; /**< Pointer the byte array containing the encoded opaque structure based on IEEE 11073-20601 specification. */ + uint8_t list_len; /**< Length of the byte array. */ +} ble_dis_reg_cert_data_list_t; + +/**@brief PnP ID parameters */ +typedef struct +{ + uint8_t vendor_id_source; /**< Vendor ID Source. see @ref DIS_VENDOR_ID_SRC_VALUES. */ + uint16_t vendor_id; /**< Vendor ID. */ + uint16_t product_id; /**< Product ID. */ + uint16_t product_version; /**< Product Version. */ +} ble_dis_pnp_id_t; + +/**@brief Device Information Service init structure. This contains all possible characteristics + * needed for initialization of the service. + */ +typedef struct +{ + ble_srv_utf8_str_t manufact_name_str; /**< Manufacturer Name String. */ + ble_srv_utf8_str_t model_num_str; /**< Model Number String. */ + ble_srv_utf8_str_t serial_num_str; /**< Serial Number String. */ + ble_srv_utf8_str_t hw_rev_str; /**< Hardware Revision String. */ + ble_srv_utf8_str_t fw_rev_str; /**< Firmware Revision String. */ + ble_srv_utf8_str_t sw_rev_str; /**< Software Revision String. */ + ble_dis_sys_id_t * p_sys_id; /**< System ID. */ + ble_dis_reg_cert_data_list_t * p_reg_cert_data_list; /**< IEEE 11073-20601 Regulatory Certification Data List. */ + ble_dis_pnp_id_t * p_pnp_id; /**< PnP ID. */ + ble_srv_security_mode_t dis_attr_md; /**< Initial Security Setting for Device Information Characteristics. */ +} ble_dis_init_t; + +/**@brief Function for initializing the Device Information Service. + * + * @details This call allows the application to initialize the device information service. + * It adds the DIS service and DIS characteristics to the database, using the initial + * values supplied through the p_dis_init parameter. Characteristics which are not to be + * added, shall be set to NULL in p_dis_init. + * + * @param[in] p_dis_init The structure containing the values of characteristics needed by the + * service. + * + * @return NRF_SUCCESS on successful initialization of service. + */ +uint32_t ble_dis_init(const ble_dis_init_t * p_dis_init); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_DIS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_escs/escs_defs.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_escs/escs_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..3a00f27f948963795b6b97964187ad86e4101ade --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_escs/escs_defs.h @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ESCS_DEFS_H__ +#define ESCS_DEFS_H__ + +#include "es.h" + +/*@file Contains definitions specific to the Eddystone Configuration Service */ + +#define ESCS_LOCK_STATE_NEW_LOCK_CODE_WRITE_LENGTH 17 + +#define ESCS_UID_READ_LENGTH (ES_UID_LENGTH) +#define ESCS_UID_WRITE_LENGTH (ES_UID_NAMESPACE_LENGTH + \ + ES_UID_INSTANCE_LENGTH + ES_FRAME_TYPE_LENGTH) + +#define ESCS_TLM_READ_LENGTH (ESCS_TLM_READ_LENGTH) +#define ESCS_TLM_WRITE_LENGTH (ES_FRAME_TYPE_LENGTH) + +#define ESCS_EID_READ_LENGTH (14) +#define ESCS_EID_WRITE_ECDH_LENGTH (34) +#define ESCS_EID_WRITE_PUB_KEY_INDEX (1) +#define ESCS_EID_WRITE_ENC_ID_KEY_INDEX (1) +#define ESCS_EID_WRITE_IDK_LENGTH (18) + +#define ESCS_URL_MIN_WRITE_LENGTH (4) +#define ESCS_URL_WRITE_LENGTH (19) + +#ifdef NRF52 +#define ESCS_NUM_OF_SUPPORTED_TX_POWER (9) +/**@brief TX power levels, based on nRF52 specifications. */ +#define ESCS_SUPPORTED_TX_POWER {-40, -20, -16, -12, -8, -4, 0, 3, 4} +#elif NRF51 +/**@brief TX power levels, based on nRF51 specifications. */ +#define ESCS_NUM_OF_SUPPORTED_TX_POWER (8) +#define ESCS_SUPPORTED_TX_POWER {-30, -20, -16, -12, -8, -4, 0, 4} +#else +#error MISSING TX POWER +#endif + +// Defined in Eddystone Specifications +#define ESCS_AES_KEY_SIZE (16) +#define ESCS_ECDH_KEY_SIZE (32) + +#define ESCS_ADV_SLOT_CHAR_LENGTH_MAX (34) // Corresponds to when the slots is configured as an EID slot + +// Characteristic: Broadcast Capabilities + +// Field: nrf_ble_escs_init_params_t.broadcast_cap.cap_bitfield +#define ESCS_BROADCAST_VAR_ADV_SUPPORTED_Yes (1) // Set if the beacon supports individual per-slot adv intervals +#define ESCS_BROADCAST_VAR_ADV_SUPPORTED_No (0) +#define ESCS_BROADCAST_VAR_ADV_SUPPORTED_Pos (0) +#define ESCS_BROADCAST_VAR_ADV_SUPPORTED_Msk (1 << ESCS_BROADCAST_VAR_ADV_SUPPORTED_Pos) +#define ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Yes (1) // Set if the beacon supports individual per-slot TX intervals +#define ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_No (0) +#define ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Pos (1) +#define ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Msk (1 << ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Pos) +#define ESCS_BROADCAST_VAR_RFU_MASK (0x03) // AND Mask to guarantee that bits 0x04 to 0x80 (RFU) are cleared + +// Field: nrf_ble_escs_init_params_t.broadcast_cap.supp_frame_types +#define ESCS_FRAME_TYPE_UID_SUPPORTED_Yes (1) +#define ESCS_FRAME_TYPE_UID_SUPPORTED_No (0) +#define ESCS_FRAME_TYPE_UID_SUPPORTED_Pos (0) +#define ESCS_FRAME_TYPE_UID_SUPPORTED_Msk (1 << ESCS_FRAME_TYPE_UID_SUPPORTED_Pos) + +#define ESCS_FRAME_TYPE_URL_SUPPORTED_Yes (1) +#define ESCS_FRAME_TYPE_URL_SUPPORTED_No (0) +#define ESCS_FRAME_TYPE_URL_SUPPORTED_Pos (1) +#define ESCS_FRAME_TYPE_URL_SUPPORTED_Msk (1 << ESCS_FRAME_TYPE_URL_SUPPORTED_Pos) + +#define ESCS_FRAME_TYPE_TLM_SUPPORTED_Yes (1) +#define ESCS_FRAME_TYPE_TLM_SUPPORTED_No (0) +#define ESCS_FRAME_TYPE_TLM_SUPPORTED_Pos (2) +#define ESCS_FRAME_TYPE_TLM_SUPPORTED_Msk (1 << ESCS_FRAME_TYPE_TLM_SUPPORTED_Pos) + +#define ESCS_FRAME_TYPE_EID_SUPPORTED_Yes (1) +#define ESCS_FRAME_TYPE_EID_SUPPORTED_No (0) +#define ESCS_FRAME_TYPE_EID_SUPPORTED_Pos (3) +#define ESCS_FRAME_TYPE_EID_SUPPORTED_Msk (1 << ESCS_FRAME_TYPE_EID_SUPPORTED_Pos) + +#define ESCS_FRAME_TYPE_RFU_MASK (0x000F) // AND Mask to guarantee that bits 0x0010 to 0x8000 (RFU) are cleared + +// Characteristic: Lock State: Lock State (READ) +#define ESCS_LOCK_STATE_LOCKED (0x00) +#define ESCS_LOCK_STATE_UNLOCKED (0x01) +#define ESCS_LOCK_STATE_UNLOCKED_AUTO_RELOCK_DISABLED (0x02) + +// Characteristic: Lock State: Lock Byte (WRITE) +#define ESCS_LOCK_BYTE_LOCK (0x00) +#define ESCS_LOCK_BYTE_DISABLE_AUTO_RELOCK (0x02) + + +// Charcteristic: Remain Connectable +#define ESCS_FUNCT_REMAIN_CONNECTABLE_SUPPORTED_Yes (0x01) +#define ESCS_FUNCT_REMAIN_CONNECTABLE_SUPPORTED_No (0x00) + +#endif // ESCS_DEFS_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_escs/nrf_ble_escs.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_escs/nrf_ble_escs.c new file mode 100644 index 0000000000000000000000000000000000000000..c0decc672c9af0431ac44b3aa45e8697f6ca4326 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_escs/nrf_ble_escs.c @@ -0,0 +1,660 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_ble_escs.h" +#include +#include "es_app_config.h" + +#ifdef BLE_HANDLER_DEBUG + #include "SEGGER_RTT.h" + #define DEBUG_PRINTF SEGGER_RTT_printf +#else + #define DEBUG_PRINTF(...) +#endif + +#define EID_BUFF_SIZE 64 + +typedef struct +{ + uint16_t uuid; + uint8_t read:1; + uint8_t write:1; + uint8_t rd_auth:1; + uint8_t wr_auth:1; + uint8_t vlen:1; + uint8_t vloc:2; + uint8_t init_len; + uint8_t max_len; +} char_init_t; + +typedef struct +{ + uint16_t val_handle; + uint16_t uuid; +} val_handle_to_uuid_t; + +static const char_init_t BROADCAST_CAP_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_BROADCAST_CAP_CHAR, + .read = 1, + .write = 0, + .rd_auth = 1, + .wr_auth = 0, + .vlen = 1, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = NRF_BLE_ESCS_BROADCAST_CAP_LEN, + .max_len = NRF_BLE_ESCS_BROADCAST_CAP_LEN +}; + +static const char_init_t ACTIVE_SLOT_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_ACTIVE_SLOT_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_USER, + .init_len = sizeof(nrf_ble_escs_active_slot_t), + .max_len = sizeof(nrf_ble_escs_active_slot_t) +}; + +static const char_init_t ADV_INTERVAL_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_ADV_INTERVAL_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = sizeof(nrf_ble_escs_adv_interval_t), + .max_len = sizeof(nrf_ble_escs_adv_interval_t) +}; + +static const char_init_t RADIO_TX_PWR_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_RADIO_TX_PWR_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = sizeof(nrf_ble_escs_radio_tx_pwr_t), + .max_len = sizeof(nrf_ble_escs_radio_tx_pwr_t) +}; + +static const char_init_t ADV_TX_PWR_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_ADV_TX_PWR_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = sizeof(nrf_ble_escs_adv_tx_pwr_t), + .max_len = sizeof(nrf_ble_escs_adv_tx_pwr_t) +}; + +static const char_init_t LOCK_STATE_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_LOCK_STATE_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 1, + .vloc = BLE_GATTS_VLOC_USER, + .init_len = 1, + .max_len = 17 +}; + +static const char_init_t UNLOCK_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_UNLOCK_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = 1, + .max_len = ESCS_AES_KEY_SIZE +}; + +static const char_init_t PUBLIC_ECDH_KEY_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_PUBLIC_ECDH_KEY_CHAR, + .read = 1, + .write = 0, + .rd_auth = 1, + .wr_auth = 0, + .vlen = 1, + .init_len = 1, + .vloc = BLE_GATTS_VLOC_STACK, + .max_len = ESCS_ECDH_KEY_SIZE +}; + +static const char_init_t EID_ID_KEY_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_EID_ID_KEY_CHAR, + .read = 1, + .write = 0, + .rd_auth = 1, + .wr_auth = 0, + .vlen = 1, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = 1, + .max_len = ESCS_AES_KEY_SIZE +}; + +static const char_init_t RW_ADV_SLOT_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_RW_ADV_SLOT_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 1, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = 0, + .max_len = ESCS_ADV_SLOT_CHAR_LENGTH_MAX +}; + +static const char_init_t FACTORY_RESET_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_FACTORY_RESET_CHAR, + .read = 0, + .write = 1, + .rd_auth = 0, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = sizeof(nrf_ble_escs_factory_reset_t), + .max_len = sizeof(nrf_ble_escs_factory_reset_t) +}; + +static const char_init_t REMAIN_CONNECTABLE_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = 1, + .max_len = 1 +}; + +static val_handle_to_uuid_t m_handle_to_uuid_map[BLE_ESCS_NUMBER_OF_CHARACTERISTICS]; //!< Map from handle to UUID. +static uint8_t m_handle_to_uuid_map_idx = 0; //!< Index of map from handle to UUID. +static uint8_t m_eid_mem[EID_BUFF_SIZE] = {0}; //!< Memory buffer used for EID writes. +static ble_user_mem_block_t m_eid_mem_block = +{ + .p_mem = m_eid_mem, + .len = EID_BUFF_SIZE +}; //!< Memory block used for EID writes. + + + +/**@brief Function for adding characteristic to Eddystone service. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_escs_init Information needed to initialize the service. + * @param[in] p_char_init Information needed to initialize the characteristic. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t char_add(const char_init_t * p_char_init, + nrf_ble_escs_t * p_escs, + void * p_value, + ble_gatts_char_handles_t * p_handles) +{ + uint32_t err_code; + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + VERIFY_PARAM_NOT_NULL(p_char_init); + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_value); + VERIFY_PARAM_NOT_NULL(p_handles); + + memset(&char_md, 0, sizeof(char_md)); + memset(&attr_char_value, 0, sizeof(attr_char_value)); + memset(&ble_uuid, 0, sizeof(ble_uuid)); + memset(&attr_md, 0, sizeof(attr_md)); + + if(p_char_init->read) + { + char_md.char_props.read = 1; + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + } + + else + { + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm); + } + + if(p_char_init->write) + { + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + char_md.char_props.write = 1; + } + + else + { + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm); + } + + ble_uuid.type = p_escs->uuid_type; + ble_uuid.uuid = p_char_init->uuid; + + attr_md.vloc = p_char_init->vloc; + attr_md.rd_auth = p_char_init->rd_auth; + attr_md.wr_auth = p_char_init->wr_auth; + attr_md.vlen = p_char_init->vlen; + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = p_char_init->init_len; + attr_char_value.p_value = p_value; + attr_char_value.max_len = p_char_init->max_len; + + err_code = sd_ble_gatts_characteristic_add(p_escs->service_handle, + &char_md, + &attr_char_value, + p_handles); + + if(err_code == NRF_SUCCESS) + { + ASSERT(m_handle_to_uuid_map_idx < BLE_ESCS_NUMBER_OF_CHARACTERISTICS); + m_handle_to_uuid_map[m_handle_to_uuid_map_idx].val_handle = p_handles->value_handle; + m_handle_to_uuid_map[m_handle_to_uuid_map_idx].uuid = p_char_init->uuid; + m_handle_to_uuid_map_idx++; + } + + return err_code; +} + + +/**@brief Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the SoftDevice. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_connect(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_escs); + p_escs->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; +} + + +/**@brief Function for handling the @ref BLE_GAP_EVT_DISCONNECTED event from the SoftDevice. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_disconnect(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_escs); + UNUSED_PARAMETER(p_ble_evt); + p_escs->conn_handle = BLE_CONN_HANDLE_INVALID; +} + + +static uint32_t get_evt_type_for_handle(uint16_t handle, uint16_t * p_uuid) +{ + VERIFY_PARAM_NOT_NULL(p_uuid); + + for(uint8_t i = 0; i < BLE_ESCS_NUMBER_OF_CHARACTERISTICS; ++i) + { + if(m_handle_to_uuid_map[i].val_handle == handle) + { + *p_uuid = m_handle_to_uuid_map[i].uuid; + return NRF_SUCCESS; + } + } + + return NRF_ERROR_NOT_FOUND; +} + +/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: BLE_GATTS_AUTHORIZE_TYPE_WRITE event from the SoftDevice. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static ret_code_t on_write(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + uint32_t err_code; + uint16_t write_evt_uuid = 0; + + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_ble_evt); + + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.authorize_request.request.write; + + err_code = get_evt_type_for_handle(p_evt_write->handle, &write_evt_uuid); + RETURN_IF_ERROR(err_code); + + p_escs->write_evt_handler(p_escs, + write_evt_uuid, + p_evt_write->handle, + p_evt_write->data, + p_evt_write->len); + + return NRF_SUCCESS; +} + + +/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: BLE_GATTS_AUTHORIZE_TYPE_WRITE: event from the SoftDevice. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_long_write(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + static uint16_t write_evt_uuid; + static bool write_evt_uuid_set = false; + uint32_t err_code; + + VERIFY_PARAM_NOT_NULL_VOID(p_escs); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + + ble_gatts_evt_write_t * p_evt_write = + &p_ble_evt->evt.gatts_evt.params.authorize_request.request.write; + ble_gatts_rw_authorize_reply_params_t reply = {0}; + + if (p_evt_write->op == BLE_GATTS_OP_PREP_WRITE_REQ) + { + err_code = get_evt_type_for_handle(p_evt_write->handle, &write_evt_uuid); + APP_ERROR_CHECK(err_code); + + write_evt_uuid_set = true; + + reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + reply.params.write.update = 0; + reply.params.write.offset = 0; + reply.params.write.len = p_evt_write->len; + reply.params.write.p_data = NULL; + + err_code = sd_ble_gatts_rw_authorize_reply(p_escs->conn_handle, &reply); + APP_ERROR_CHECK(err_code); + } + + else if (p_evt_write->op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + { + uint8_t value_buffer[ESCS_ADV_SLOT_CHAR_LENGTH_MAX] = {0}; + ble_gatts_value_t value = + { + .len = sizeof(value_buffer), + .offset = 0, + .p_value = &(value_buffer[0]) + }; + + ASSERT(write_evt_uuid_set); + write_evt_uuid_set = false; + + reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + reply.params.write.update = 0; + reply.params.write.offset = 0; + reply.params.write.len = p_evt_write->len; + reply.params.write.p_data = NULL; + + err_code = sd_ble_gatts_rw_authorize_reply(p_escs->conn_handle, &reply); + APP_ERROR_CHECK(err_code); + + // Now that the value has been accepted using 'sd_ble_gatts_rw_authorize_reply', it can be found in the database. + err_code = sd_ble_gatts_value_get( p_escs->conn_handle, + p_escs->rw_adv_slot_handles.value_handle, + &value); + APP_ERROR_CHECK(err_code); + + p_escs->write_evt_handler(p_escs, + write_evt_uuid, + p_evt_write->handle, + value.p_value, + value.len); + } + else + { + } +} + + +/**@brief Function for handling events from the SoftDevice related to long writes. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static ret_code_t on_read(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_ble_evt); + ret_code_t err_code; + uint16_t read_evt_uuid = 0; + uint16_t val_handle = p_ble_evt->evt.gatts_evt.params.authorize_request.request.read.handle; + err_code = get_evt_type_for_handle(val_handle, &read_evt_uuid); + RETURN_IF_ERROR(err_code); + + p_escs->read_evt_handler(p_escs, read_evt_uuid, val_handle); + + return NRF_SUCCESS; +} + + +static ret_code_t on_rw_authorize_req(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + ret_code_t err_code; + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_ble_evt); + + ble_gatts_evt_rw_authorize_request_t *ar = &p_ble_evt->evt.gatts_evt.params.authorize_request; + if (ar->type == BLE_GATTS_AUTHORIZE_TYPE_READ) + { + err_code = on_read(p_escs, p_ble_evt); + RETURN_IF_ERROR(err_code); + } + else if (ar->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + if (ar->request.write.op == BLE_GATTS_OP_WRITE_REQ + || ar->request.write.op == BLE_GATTS_OP_WRITE_CMD) + { + err_code = on_write(p_escs, p_ble_evt); + RETURN_IF_ERROR(err_code); + } + + else if(ar->request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ + || ar->request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + { + on_long_write(p_escs, p_ble_evt); + } + else + { + } + } + else + { + return NRF_ERROR_INVALID_STATE; + } + + return NRF_SUCCESS; +} + + + +ret_code_t nrf_ble_escs_on_ble_evt(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + ret_code_t err_code; + + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_ble_evt); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_escs, p_ble_evt); + + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_escs, p_ble_evt); + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + err_code = on_rw_authorize_req(p_escs, p_ble_evt); + VERIFY_SUCCESS(err_code); + break; + + // BLE_EVT_USER_MEM_REQUEST & BLE_EVT_USER_MEM_RELEASE are for long writes to the RW ADV slot characteristic + case BLE_EVT_USER_MEM_REQUEST: + err_code = sd_ble_user_mem_reply(p_escs->conn_handle, &m_eid_mem_block); + VERIFY_SUCCESS(err_code); + break; + + case BLE_EVT_USER_MEM_RELEASE: + break; + + default: + // No implementation needed. + break; + } + + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_escs_init(nrf_ble_escs_t * p_escs, const nrf_ble_escs_init_t * p_escs_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + ble_uuid128_t ecs_base_uuid = ESCS_BASE_UUID; + uint8_t zero_val = 0; + + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_escs_init); + + // Initialize the service structure. + p_escs->conn_handle = BLE_CONN_HANDLE_INVALID; + p_escs->write_evt_handler = p_escs_init->write_evt_handler; + p_escs->read_evt_handler = p_escs_init->read_evt_handler; + + // Add a custom base UUID. + err_code = sd_ble_uuid_vs_add(&ecs_base_uuid, &p_escs->uuid_type); + VERIFY_SUCCESS(err_code); + + ble_uuid.type = p_escs->uuid_type; + ble_uuid.uuid = BLE_UUID_ESCS_SERVICE; + + // Add the service. + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_escs->service_handle); + VERIFY_SUCCESS(err_code); + + m_handle_to_uuid_map_idx = 0; + + // Set up initial values for characteristics + + // Eddystone spec requires big endian + nrf_ble_escs_broadcast_cap_t temp = p_escs_init->p_init_vals->broadcast_cap; + temp.supp_frame_types = BYTES_SWAP_16BIT(temp.supp_frame_types); + + nrf_ble_escs_adv_interval_t temp_interval = p_escs_init->p_init_vals->adv_interval; + temp_interval = BYTES_SWAP_16BIT(temp_interval); + + // Adding chracteristics + + err_code = char_add(&BROADCAST_CAP_CHAR_INIT, p_escs, + &temp, &p_escs->broadcast_cap_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&ACTIVE_SLOT_CHAR_INIT, p_escs, + p_escs->p_active_slot, &p_escs->active_slot_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&ADV_INTERVAL_CHAR_INIT, p_escs, + &temp_interval, &p_escs->adv_interval_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&RADIO_TX_PWR_CHAR_INIT, p_escs, + &(p_escs_init->p_init_vals->radio_tx_pwr), &p_escs->radio_tx_pwr_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&ADV_TX_PWR_CHAR_INIT, p_escs, + &(p_escs_init->p_init_vals->adv_tx_pwr), &p_escs->adv_tx_pwr_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&LOCK_STATE_CHAR_INIT, p_escs, + p_escs->p_lock_state, &p_escs->lock_state_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&UNLOCK_CHAR_INIT, p_escs, + &zero_val, &p_escs->unlock_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&PUBLIC_ECDH_KEY_CHAR_INIT, p_escs, + &zero_val, &p_escs->pub_ecdh_key_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&EID_ID_KEY_CHAR_INIT, p_escs, + &zero_val, &p_escs->eid_id_key_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&RW_ADV_SLOT_CHAR_INIT, p_escs, + &zero_val, &p_escs->rw_adv_slot_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&FACTORY_RESET_CHAR_INIT, p_escs, + &(p_escs_init->p_init_vals->factory_reset), &p_escs->factory_reset_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&REMAIN_CONNECTABLE_CHAR_INIT, p_escs, + &(p_escs_init->p_init_vals->remain_connectable.r_is_non_connectable_supported), + &p_escs->remain_connectable_handles); + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_escs/nrf_ble_escs.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_escs/nrf_ble_escs.h new file mode 100644 index 0000000000000000000000000000000000000000..b07b10d574936d429c79f07df9e8475a71cf0fb0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_escs/nrf_ble_escs.h @@ -0,0 +1,261 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_BLE_ESCS_H__ +#define NRF_BLE_ESCS_H__ + +#include "ble.h" +#include "ble_srv_common.h" +#include "app_util_platform.h" +#include "sdk_common.h" +#include "escs_defs.h" +#include +#include + + +/** + * @file + * @defgroup nrf_ble_escs Eddystone Configuration Service + * @brief Eddystone Configuration Service module. + * @ingroup ble_sdk_srv + * @{ + */ + +#define BLE_ESCS_NUMBER_OF_CHARACTERISTICS 13 //!< Number of characteristics contained in the Eddystone Configuration Service. + +#define BLE_UUID_ESCS_SERVICE 0x7500 //!< UUID of the Eddystone Configuration Service. + +// ECS UUIDs +#define BLE_UUID_ESCS_BROADCAST_CAP_CHAR 0x7501 +#define BLE_UUID_ESCS_ACTIVE_SLOT_CHAR 0x7502 +#define BLE_UUID_ESCS_ADV_INTERVAL_CHAR 0x7503 +#define BLE_UUID_ESCS_RADIO_TX_PWR_CHAR 0x7504 +#define BLE_UUID_ESCS_ADV_TX_PWR_CHAR 0x7505 +#define BLE_UUID_ESCS_LOCK_STATE_CHAR 0x7506 +#define BLE_UUID_ESCS_UNLOCK_CHAR 0x7507 +#define BLE_UUID_ESCS_PUBLIC_ECDH_KEY_CHAR 0x7508 +#define BLE_UUID_ESCS_EID_ID_KEY_CHAR 0x7509 +#define BLE_UUID_ESCS_RW_ADV_SLOT_CHAR 0x750A +#define BLE_UUID_ESCS_FACTORY_RESET_CHAR 0x750B +#define BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR 0x750C + +#define ESCS_BASE_UUID \ + {{0x95, 0xE2, 0xED, 0xEB, 0x1B, 0xA0, 0x39, 0x8A, 0xDF, 0x4B, 0xD3, 0x8E, 0x00, 0x00, 0xC8, \ + 0xA3}} +// A3C8XXXX-8ED3-4BDF-8A39-A01BEBEDE295 + +#define NRF_BLE_ESCS_BROADCAST_CAP_LEN (ESCS_NUM_OF_SUPPORTED_TX_POWER + 6) // According to the eddystone spec, there are 6 bytes of data in addition to the supported_radio_tx_power array + + +/**@brief Data fields in the Broadcast Capabilities characteristic. + * @note This is a packed structure. Therefore, you should not change it. + */ +typedef PACKED_STRUCT +{ + int8_t vers_byte; + int8_t max_supp_total_slots; + int8_t max_supp_eid_slots; + int8_t cap_bitfield; + int16_t supp_frame_types; + int8_t supp_radio_tx_power[ESCS_NUM_OF_SUPPORTED_TX_POWER]; +} nrf_ble_escs_broadcast_cap_t; + +typedef uint8_t nrf_ble_escs_active_slot_t; +typedef uint16_t nrf_ble_escs_adv_interval_t; +typedef int8_t nrf_ble_escs_radio_tx_pwr_t; +typedef int8_t nrf_ble_escs_adv_tx_pwr_t; + +/**@brief Read states of the Lock State characteristic. */ +typedef enum +{ + NRF_BLE_ESCS_LOCK_STATE_LOCKED = ESCS_LOCK_STATE_LOCKED, + NRF_BLE_ESCS_LOCK_STATE_UNLOCKED = ESCS_LOCK_STATE_UNLOCKED, + NRF_BLE_ESCS_LOCK_STATE_UNLOCKED_AUTO_RELOCK_DISABLED = + ESCS_LOCK_STATE_UNLOCKED_AUTO_RELOCK_DISABLED +} nrf_ble_escs_lock_state_read_t; + +/**@brief Write bytes of the Lock State characteristic. */ +typedef enum +{ + NRF_BLE_ESCS_LOCK_BYTE_LOCK = ESCS_LOCK_BYTE_LOCK, + NRF_BLE_ESCS_LOCK_BYTE_DISABLE_AUTO_RELOCK = ESCS_LOCK_BYTE_DISABLE_AUTO_RELOCK +} nrf_ble_escs_lock_byte_t; + +/**@brief Write data fields of the Lock State characteristic. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + nrf_ble_escs_lock_byte_t lock_byte; + int8_t encrypted_key[ESCS_AES_KEY_SIZE]; +} nrf_ble_escs_lock_state_write_t; + +/**@brief Lock State characteristic. */ +typedef union +{ + nrf_ble_escs_lock_state_read_t read; + nrf_ble_escs_lock_state_write_t write; +} nrf_ble_escs_lock_state_t; + +/**@brief Unlock characteristic (read/write). */ +typedef union +{ + int8_t r_challenge[ESCS_AES_KEY_SIZE]; + int8_t w_unlock_token[ESCS_AES_KEY_SIZE]; +} nrf_ble_escs_unlock_t; + +/**@brief Public ECDH Key characteristic. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + int8_t key[ESCS_ECDH_KEY_SIZE]; +} nrf_ble_escs_public_ecdh_key_t; + +/**@brief EID Identity Key characteristic. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + int8_t key[ESCS_AES_KEY_SIZE]; +} nrf_ble_escs_eid_id_key_t; + + +typedef uint8_t nrf_ble_escs_factory_reset_t; + +/**@brief Unlock characteristic (read/write). */ +typedef union +{ + uint8_t r_is_non_connectable_supported; + uint8_t w_remain_connectable_boolean; +} nrf_ble_escs_remain_conntbl_t; + +/**@brief Eddystone Configuration Service initialization parameters (corresponding to required characteristics). */ +typedef struct +{ + nrf_ble_escs_broadcast_cap_t broadcast_cap; + nrf_ble_escs_adv_interval_t adv_interval; + nrf_ble_escs_radio_tx_pwr_t radio_tx_pwr; + nrf_ble_escs_adv_tx_pwr_t adv_tx_pwr; + nrf_ble_escs_factory_reset_t factory_reset; + nrf_ble_escs_remain_conntbl_t remain_connectable; + + +} nrf_ble_escs_init_params_t; + +// Forward Declaration of nrf_ble_escs_t type. +typedef struct nrf_ble_escs_s nrf_ble_escs_t; + +typedef void (*nrf_ble_escs_write_evt_handler_t)(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t value_handle, + uint8_t * p_data, + uint16_t length); + +typedef void (*nrf_ble_escs_read_evt_handler_t)(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t value_handle + ); + +/**@brief Eddystone Configuration Service initialization structure. + * + * @details This structure contains the initialization information for the service. The application + * must fill this structure and pass it to the service using the @ref nrf_ble_escs_init + * function. + */ +typedef struct +{ + nrf_ble_escs_init_params_t * p_init_vals; //!< Initialization parameters for the service. + nrf_ble_escs_write_evt_handler_t write_evt_handler; //!< Event handler to be called for authorizing write requests. + nrf_ble_escs_read_evt_handler_t read_evt_handler; //!< Event handler to be called for authorizing read requests. +} nrf_ble_escs_init_t; + +struct nrf_ble_escs_s +{ + uint8_t uuid_type; //!< UUID type for the Eddystone Configuration Service Base UUID. + uint16_t service_handle; //!< Handle of the Eddystone Configuration Service (as provided by the SoftDevice). + ble_gatts_char_handles_t broadcast_cap_handles; //!< Handles related to the Capabilities characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t active_slot_handles; //!< Handles related to the Active Slot characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t adv_interval_handles; //!< Handles related to the Advertising Interval characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t radio_tx_pwr_handles; //!< Handles related to the Radio Tx Power characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t adv_tx_pwr_handles; //!< Handles related to the (Advanced) Advertised Tx Power characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t lock_state_handles; //!< Handles related to the Lock State characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t unlock_handles; //!< Handles related to the Unlock characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t pub_ecdh_key_handles; //!< Handles related to the Public ECDH Key characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t eid_id_key_handles; //!< Handles related to the EID Identity Key characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t rw_adv_slot_handles; //!< Handles related to the ADV Slot Data characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t factory_reset_handles; //!< Handles related to the (Advanced) Factory reset characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t remain_connectable_handles; //!< Handles related to the (Advanced) Remain Connectable characteristic (as provided by the SoftDevice). + uint16_t conn_handle; //!< Handle of the current connection (as provided by the SoftDevice). @ref BLE_CONN_HANDLE_INVALID if not in a connection. + nrf_ble_escs_write_evt_handler_t write_evt_handler; //!< Event handler to be called for handling write attempts. + nrf_ble_escs_read_evt_handler_t read_evt_handler; //!< Event handler to be called for handling read attempts. + uint8_t * p_active_slot; + nrf_ble_escs_lock_state_read_t * p_lock_state; +}; + +/**@brief Function for initializing the Eddystone Configuration Service. + * + * @param[out] p_escs Eddystone Configuration Service structure. This structure must be supplied + * by the application. It is initialized by this function and will + * later be used to identify this particular service instance. + * @param[in] p_ecs_init Information needed to initialize the service. + * + * @retval NRF_SUCCESS If the service was successfully initialized. Otherwise, an error code is returned. + * @retval NRF_ERROR_NULL If either of the pointers @p p_escs or @p p_ecs_init is NULL. + */ +ret_code_t nrf_ble_escs_init(nrf_ble_escs_t * p_escs, const nrf_ble_escs_init_t * p_ecs_init); + +/**@brief Function for handling the Eddystone Configuration Service's BLE events. + * + * @details The Eddystone Configuration Service expects the application to call this function each time an + * event is received from the SoftDevice. This function processes the event if it + * is relevant and calls the Eddystone Configuration Service event handler of the + * application if necessary. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_ble_evt Event received from the SoftDevice. + * + * @retval NRF_ERROR_NULL If any of the arguments given are NULL. + * @retval NRF_SUCCESS otherwise. + */ +ret_code_t nrf_ble_escs_on_ble_evt(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt); + +/** @} */ + +#endif // NRF_BLE_ESCS_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_gls/ble_gls.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_gls/ble_gls.c new file mode 100644 index 0000000000000000000000000000000000000000..3dfdb3205f0e03720367b203fae7e7655921740b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_gls/ble_gls.c @@ -0,0 +1,1306 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ + +#include "sdk_common.h" + +#if NRF_MODULE_ENABLED(BLE_GLS) + +#include "ble_gls.h" +#include +#include "ble_gls_db.h" +#include "ble_racp.h" +#include "ble_srv_common.h" + + +#define OPERAND_FILTER_TYPE_SEQ_NUM 0x01 /**< Filter data using Sequence Number criteria. */ +#define OPERAND_FILTER_TYPE_FACING_TIME 0x02 /**< Filter data using User Facing Time criteria. */ +#define OPERAND_FILTER_TYPE_RFU_START 0x07 /**< Start of filter types reserved For Future Use range */ +#define OPERAND_FILTER_TYPE_RFU_END 0xFF /**< End of filter types reserved For Future Use range */ + +#define OPCODE_LENGTH 1 /**< Length of opcode inside Glucose Measurement packet. */ +#define HANDLE_LENGTH 2 /**< Length of handle inside Glucose Measurement packet. */ +#define MAX_GLM_LEN (BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Glucose Measurement. */ + +#define GLS_NACK_PROC_ALREADY_IN_PROGRESS BLE_GATT_STATUS_ATTERR_APP_BEGIN + 0 /**< Reply when a requested procedure is already in progress. */ +#define GLS_NACK_CCCD_IMPROPERLY_CONFIGURED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 1 /**< Reply when the a s CCCD is improperly configured. */ + +/**@brief Glucose Service communication state. */ +typedef enum +{ + STATE_NO_COMM, /**< The service is not in a communicating state. */ + STATE_RACP_PROC_ACTIVE, /**< Processing requested data. */ + STATE_RACP_RESPONSE_PENDING, /**< There is a RACP indication waiting to be sent. */ + STATE_RACP_RESPONSE_IND_VERIF /**< Waiting for a verification of a RACP indication. */ +} gls_state_t; + +static gls_state_t m_gls_state; /**< Current communication state. */ +static uint16_t m_next_seq_num; /**< Sequence number of the next database record. */ +static uint8_t m_racp_proc_operator; /**< Operator of current request. */ +static uint16_t m_racp_proc_seq_num; /**< Sequence number of current request. */ +static uint8_t m_racp_proc_record_ndx; /**< Current record index. */ +static uint8_t m_racp_proc_records_reported; /**< Number of reported records. */ +static uint8_t m_racp_proc_records_reported_since_txcomplete; /**< Number of reported records since last TX_COMPLETE event. */ +static ble_racp_value_t m_pending_racp_response; /**< RACP response to be sent. */ +static uint8_t m_pending_racp_response_operand[2]; /**< Operand of RACP response to be sent. */ + + +/**@brief Function for setting the GLS communication state. + * + * @param[in] new_state New communication state. + */ +static void state_set(gls_state_t new_state) +{ + m_gls_state = new_state; +} + + +/**@brief Function for setting the next sequence number by reading the last record in the data base. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +static uint32_t next_sequence_number_set(void) +{ + uint16_t num_records; + ble_gls_rec_t rec; + + num_records = ble_gls_db_num_records_get(); + if (num_records > 0) + { + // Get last record + uint32_t err_code = ble_gls_db_record_get(num_records - 1, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + m_next_seq_num = rec.meas.sequence_number + 1; + } + else + { + m_next_seq_num = 0; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for encoding a Glucose measurement. + * + * @param[in] p_meas Measurement to be encoded. + * @param[out] p_encoded_buffer Pointer to buffer where the encoded measurement is to be stored. + * + * @return Size of encoded measurement. + */ +static uint8_t gls_meas_encode(const ble_gls_meas_t * p_meas, uint8_t * p_encoded_buffer) +{ + uint8_t len = 0; + + p_encoded_buffer[len++] = p_meas->flags; + + len += uint16_encode(p_meas->sequence_number, &p_encoded_buffer[len]); + len += ble_date_time_encode(&p_meas->base_time, &p_encoded_buffer[len]); + + if (p_meas->flags & BLE_GLS_MEAS_FLAG_TIME_OFFSET) + { + len += uint16_encode(p_meas->time_offset, &p_encoded_buffer[len]); + } + + if (p_meas->flags & BLE_GLS_MEAS_FLAG_CONC_TYPE_LOC) + { + uint16_t encoded_concentration; + + encoded_concentration = ((p_meas->glucose_concentration.exponent << 12) & 0xF000) | + ((p_meas->glucose_concentration.mantissa << 0) & 0x0FFF); + + p_encoded_buffer[len++] = (uint8_t)(encoded_concentration); + p_encoded_buffer[len++] = (uint8_t)(encoded_concentration >> 8); + p_encoded_buffer[len++] = (p_meas->sample_location << 4) | (p_meas->type & 0x0F); + } + + if (p_meas->flags & BLE_GLS_MEAS_FLAG_SENSOR_STATUS) + { + len += uint16_encode(p_meas->sensor_status_annunciation, &p_encoded_buffer[len]); + } + + return len; +} + + +/**@brief Function for adding the characteristic for a glucose measurement. + * + * @param[in] p_gls Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +static uint32_t glucose_measurement_char_add(ble_gls_t * p_gls) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + ble_gls_rec_t initial_gls_rec_value; + uint8_t encoded_gls_meas[MAX_GLM_LEN]; + uint8_t num_recs; + memset(&cccd_md, 0, sizeof(cccd_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm); + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.notify = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_GLUCOSE_MEASUREMENT_CHAR); + memset(&attr_md, 0, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 1; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + memset(&initial_gls_rec_value, 0, sizeof(initial_gls_rec_value)); + + num_recs = ble_gls_db_num_records_get(); + if (num_recs > 0) + { + uint32_t err_code = ble_gls_db_record_get(num_recs - 1, &initial_gls_rec_value); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = gls_meas_encode(&initial_gls_rec_value.meas, encoded_gls_meas); + attr_char_value.init_offs = 0; + attr_char_value.max_len = MAX_GLM_LEN; + attr_char_value.p_value = encoded_gls_meas; + + return sd_ble_gatts_characteristic_add(p_gls->service_handle, + &char_md, + &attr_char_value, + &p_gls->glm_handles); +} + + +/**@brief Function for adding the characteristic for a glucose feature. + * + * @param[in] p_gls Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +static uint32_t glucose_feature_char_add(ble_gls_t * p_gls) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t encoded_initial_feature[2]; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_GLUCOSE_FEATURE_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + encoded_initial_feature[0] = (uint8_t)(p_gls->feature); + encoded_initial_feature[1] = (uint8_t)((p_gls->feature) >> 8); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof (uint16_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = sizeof (uint16_t); + attr_char_value.p_value = encoded_initial_feature; + + return sd_ble_gatts_characteristic_add(p_gls->service_handle, + &char_md, + &attr_char_value, + &p_gls->glf_handles); +} + + +/**@brief Function for adding the characteristic for a record access control point. + * + * @param[in] p_gls Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +static uint32_t record_access_control_point_char_add(ble_gls_t * p_gls) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&cccd_md, 0, sizeof(cccd_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm); + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.indicate = 1; + char_md.char_props.write = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_RECORD_ACCESS_CONTROL_POINT_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 1; + attr_md.vlen = 1; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = 0; + attr_char_value.init_offs = 0; + attr_char_value.max_len = BLE_GATT_ATT_MTU_DEFAULT; + attr_char_value.p_value = 0; + + return sd_ble_gatts_characteristic_add(p_gls->service_handle, + &char_md, + &attr_char_value, + &p_gls->racp_handles); +} + + +uint32_t ble_gls_init(ble_gls_t * p_gls, const ble_gls_init_t * p_gls_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Initialize data base + err_code = ble_gls_db_init(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = next_sequence_number_set(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Initialize service structure + p_gls->evt_handler = p_gls_init->evt_handler; + p_gls->error_handler = p_gls_init->error_handler; + p_gls->feature = p_gls_init->feature; + p_gls->is_context_supported = p_gls_init->is_context_supported; + p_gls->conn_handle = BLE_CONN_HANDLE_INVALID; + + + // Initialize global variables + state_set(STATE_NO_COMM); + m_racp_proc_records_reported_since_txcomplete = 0; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_GLUCOSE_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_gls->service_handle); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add glucose measurement characteristic + err_code = glucose_measurement_char_add(p_gls); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add glucose measurement feature characteristic + err_code = glucose_feature_char_add(p_gls); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add record control access point characteristic + err_code = record_access_control_point_char_add(p_gls); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for sending a response from the Record Access Control Point. + * + * @param[in] p_gls Service instance. + * @param[in] p_racp_val RACP value to be sent. + */ +static void racp_send(ble_gls_t * p_gls, ble_racp_value_t * p_racp_val) +{ + uint32_t err_code; + uint8_t encoded_resp[25]; + uint8_t len; + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + + if ( + (m_gls_state != STATE_RACP_RESPONSE_PENDING) + && + (m_racp_proc_records_reported_since_txcomplete > 0) + ) + { + state_set(STATE_RACP_RESPONSE_PENDING); + return; + } + + // Send indication + len = ble_racp_encode(p_racp_val, encoded_resp); + hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_gls->racp_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_INDICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_resp; + + err_code = sd_ble_gatts_hvx(p_gls->conn_handle, &hvx_params); + + // Error handling + if ((err_code == NRF_SUCCESS) && (hvx_len != len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + switch (err_code) + { + case NRF_SUCCESS: + // Wait for HVC event + state_set(STATE_RACP_RESPONSE_IND_VERIF); + break; + + case NRF_ERROR_RESOURCES: + // Wait for TX_COMPLETE event to retry transmission + state_set(STATE_RACP_RESPONSE_PENDING); + break; + + case NRF_ERROR_INVALID_STATE: + // Make sure state machine returns to the default state + state_set(STATE_NO_COMM); + break; + + default: + // Report error to application + if (p_gls->error_handler != NULL) + { + p_gls->error_handler(err_code); + } + + // Make sure state machine returns to the default state + state_set(STATE_NO_COMM); + break; + } +} + + +/**@brief Function for sending a RACP response containing a Response Code Op Code and a Response Code Value. + * + * @param[in] p_gls Service instance. + * @param[in] opcode RACP Op Code. + * @param[in] value RACP Response Code Value. + */ +static void racp_response_code_send(ble_gls_t * p_gls, uint8_t opcode, uint8_t value) +{ + m_pending_racp_response.opcode = RACP_OPCODE_RESPONSE_CODE; + m_pending_racp_response.operator = RACP_OPERATOR_NULL; + m_pending_racp_response.operand_len = 2; + m_pending_racp_response.p_operand = m_pending_racp_response_operand; + + m_pending_racp_response_operand[0] = opcode; + m_pending_racp_response_operand[1] = value; + + racp_send(p_gls, &m_pending_racp_response); +} + + +/**@brief Function for sending a glucose measurement/context. + * + * @param[in] p_gls Service instance. + * @param[in] p_rec Measurement to be sent. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t glucose_meas_send(ble_gls_t * p_gls, ble_gls_rec_t * p_rec) +{ + uint32_t err_code; + uint8_t encoded_glm[MAX_GLM_LEN]; + uint16_t len; + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + + len = gls_meas_encode(&p_rec->meas, encoded_glm); + hvx_len = len; + + memset(&hvx_params, 0, sizeof (hvx_params)); + + hvx_params.handle = p_gls->glm_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_glm; + + err_code = sd_ble_gatts_hvx(p_gls->conn_handle, &hvx_params); + if (err_code == NRF_SUCCESS) + { + if (hvx_len != len) + { + err_code = NRF_ERROR_DATA_SIZE; + } + else + { + // Measurement successfully sent + m_racp_proc_records_reported++; + m_racp_proc_records_reported_since_txcomplete++; + } + } + + return err_code; +} + + +/**@brief Function for responding to the ALL operation. + * + * @param[in] p_gls Service instance. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t racp_report_records_all(ble_gls_t * p_gls) +{ + uint16_t total_records = ble_gls_db_num_records_get(); + + if (m_racp_proc_record_ndx >= total_records) + { + state_set(STATE_NO_COMM); + } + else + { + uint32_t err_code; + ble_gls_rec_t rec; + + err_code = ble_gls_db_record_get(m_racp_proc_record_ndx, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = glucose_meas_send(p_gls, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +/**@brief Function for responding to the FIRST or the LAST operation. + * + * @param[in] p_gls Service instance. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t racp_report_records_first_last(ble_gls_t * p_gls) +{ + uint32_t err_code; + ble_gls_rec_t rec; + uint16_t total_records; + + total_records = ble_gls_db_num_records_get(); + + if ((m_racp_proc_records_reported != 0) || (total_records == 0)) + { + state_set(STATE_NO_COMM); + } + else + { + if (m_racp_proc_operator == RACP_OPERATOR_FIRST) + { + err_code = ble_gls_db_record_get(0, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else if (m_racp_proc_operator == RACP_OPERATOR_LAST) + { + err_code = ble_gls_db_record_get(total_records - 1, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + err_code = glucose_meas_send(p_gls, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +/**@brief Function for responding to the GREATER_OR_EQUAL operation. + * + * @param[in] p_gls Service instance. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t racp_report_records_greater_or_equal(ble_gls_t * p_gls) +{ + uint16_t total_records = ble_gls_db_num_records_get(); + + while (m_racp_proc_record_ndx < total_records) + { + uint32_t err_code; + ble_gls_rec_t rec; + + err_code = ble_gls_db_record_get(m_racp_proc_record_ndx, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (rec.meas.sequence_number >= m_racp_proc_seq_num) + { + err_code = glucose_meas_send(p_gls, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + break; + } + m_racp_proc_record_ndx++; + } + if (m_racp_proc_record_ndx == total_records) + { + state_set(STATE_NO_COMM); + } + + return NRF_SUCCESS; +} + + +/**@brief Function for informing that the REPORT RECORDS procedure is completed. + * + * @param[in] p_gls Service instance. + */ +static void racp_report_records_completed(ble_gls_t * p_gls) +{ + uint8_t resp_code_value; + + if (m_racp_proc_records_reported > 0) + { + resp_code_value = RACP_RESPONSE_SUCCESS; + } + else + { + resp_code_value = RACP_RESPONSE_NO_RECORDS_FOUND; + } + + racp_response_code_send(p_gls, RACP_OPCODE_REPORT_RECS, resp_code_value); +} + + +/**@brief Function for the RACP report records procedure. + * + * @param[in] p_gls Service instance. + */ +static void racp_report_records_procedure(ble_gls_t * p_gls) +{ + uint32_t err_code; + + while (m_gls_state == STATE_RACP_PROC_ACTIVE) + { + // Execute requested procedure + switch (m_racp_proc_operator) + { + case RACP_OPERATOR_ALL: + err_code = racp_report_records_all(p_gls); + break; + + case RACP_OPERATOR_FIRST: + case RACP_OPERATOR_LAST: + err_code = racp_report_records_first_last(p_gls); + break; + + case RACP_OPERATOR_GREATER_OR_EQUAL: + err_code = racp_report_records_greater_or_equal(p_gls); + break; + + default: + // Report error to application + if (p_gls->error_handler != NULL) + { + p_gls->error_handler(NRF_ERROR_INTERNAL); + } + + // Make sure state machine returns to the default state + state_set(STATE_NO_COMM); + return; + } + + // Error handling + switch (err_code) + { + case NRF_SUCCESS: + if (m_gls_state == STATE_RACP_PROC_ACTIVE) + { + m_racp_proc_record_ndx++; + } + else + { + racp_report_records_completed(p_gls); + } + break; + + case NRF_ERROR_RESOURCES: + // Wait for TX_COMPLETE event to resume transmission + return; + + case NRF_ERROR_INVALID_STATE: + // Notification is probably not enabled. Ignore request. + state_set(STATE_NO_COMM); + return; + + default: + // Report error to application + if (p_gls->error_handler != NULL) + { + p_gls->error_handler(err_code); + } + + // Make sure state machine returns to the default state + state_set(STATE_NO_COMM); + return; + } + } +} + + +/**@brief Function for testing if the received request is to be executed. + * + * @param[in] p_racp_request Request to be checked. + * @param[out] p_response_code Response code to be sent in case the request is rejected. + * RACP_RESPONSE_RESERVED is returned if the received message is + * to be rejected without sending a response. + * + * @return TRUE if the request is to be executed, FALSE if it is to be rejected. + * If it is to be rejected, p_response_code will contain the response code to be + * returned to the central. + */ +static bool is_request_to_be_executed(const ble_racp_value_t * p_racp_request, + uint8_t * p_response_code) +{ + *p_response_code = RACP_RESPONSE_RESERVED; + + if (p_racp_request->opcode == RACP_OPCODE_ABORT_OPERATION) + { + if (m_gls_state == STATE_RACP_PROC_ACTIVE) + { + if (p_racp_request->operator != RACP_OPERATOR_NULL) + { + *p_response_code = RACP_RESPONSE_INVALID_OPERATOR; + } + else if (p_racp_request->operand_len != 0) + { + *p_response_code = RACP_RESPONSE_INVALID_OPERAND; + } + else + { + *p_response_code = RACP_RESPONSE_SUCCESS; + } + } + else + { + *p_response_code = RACP_RESPONSE_ABORT_FAILED; + } + } + else if (m_gls_state != STATE_NO_COMM) + { + return false; + } + // Supported opcodes. + else if ((p_racp_request->opcode == RACP_OPCODE_REPORT_RECS) || + (p_racp_request->opcode == RACP_OPCODE_REPORT_NUM_RECS)) + { + switch (p_racp_request->operator) + { + // Operators WITHOUT a filter. + case RACP_OPERATOR_ALL: + case RACP_OPERATOR_FIRST: + case RACP_OPERATOR_LAST: + if (p_racp_request->operand_len != 0) + { + *p_response_code = RACP_RESPONSE_INVALID_OPERAND; + } + break; + + // Operators WITH a filter. + case RACP_OPERATOR_GREATER_OR_EQUAL: + if (p_racp_request->p_operand[0] == OPERAND_FILTER_TYPE_SEQ_NUM) + { + if (p_racp_request->operand_len != 3) + { + *p_response_code = RACP_RESPONSE_INVALID_OPERAND; + } + } + else if (p_racp_request->p_operand[0] == OPERAND_FILTER_TYPE_FACING_TIME) + { + *p_response_code = RACP_RESPONSE_OPERAND_UNSUPPORTED; + } + else if (p_racp_request->p_operand[0] >= OPERAND_FILTER_TYPE_RFU_START) + { + *p_response_code = RACP_RESPONSE_OPERAND_UNSUPPORTED; + } + else + { + *p_response_code = RACP_RESPONSE_INVALID_OPERAND; + } + break; + + // Unsupported operators. + case RACP_OPERATOR_LESS_OR_EQUAL: + case RACP_OPERATOR_RANGE: + *p_response_code = RACP_RESPONSE_OPERATOR_UNSUPPORTED; + break; + + // Invalid operators. + case RACP_OPERATOR_NULL: + default: + if (p_racp_request->operator >= RACP_OPERATOR_RFU_START) + { + *p_response_code = RACP_RESPONSE_OPERATOR_UNSUPPORTED; + } + else + { + *p_response_code = RACP_RESPONSE_INVALID_OPERATOR; + } + break; + } + } + // Unsupported opcodes, + else if (p_racp_request->opcode == RACP_OPCODE_DELETE_RECS) + { + *p_response_code = RACP_RESPONSE_OPCODE_UNSUPPORTED; + } + // Unknown opcodes. + else + { + *p_response_code = RACP_RESPONSE_OPCODE_UNSUPPORTED; + } + + // NOTE: The computation of the return value will change slightly when deferred write has been + // implemented in the stack. + return (*p_response_code == RACP_RESPONSE_RESERVED); +} + + +/**@brief Function for processing a REPORT RECORDS request. + * + * @param[in] p_gls Service instance. + * @param[in] p_racp_request Request to be executed. + */ +static void report_records_request_execute(ble_gls_t * p_gls, ble_racp_value_t * p_racp_request) +{ + uint16_t seq_num = (p_racp_request->p_operand[2] << 8) | p_racp_request->p_operand[1]; + + state_set(STATE_RACP_PROC_ACTIVE); + + m_racp_proc_record_ndx = 0; + m_racp_proc_operator = p_racp_request->operator; + m_racp_proc_records_reported = 0; + m_racp_proc_seq_num = seq_num; + + racp_report_records_procedure(p_gls); +} + + +/**@brief Function for processing a REPORT NUM RECORDS request. + * + * @param[in] p_gls Service instance. + * @param[in] p_racp_request Request to be executed. + */ +static void report_num_records_request_execute(ble_gls_t * p_gls, ble_racp_value_t * p_racp_request) +{ + uint16_t total_records; + uint16_t num_records; + + total_records = ble_gls_db_num_records_get(); + num_records = 0; + + if (p_racp_request->operator == RACP_OPERATOR_ALL) + { + num_records = total_records; + } + else if (p_racp_request->operator == RACP_OPERATOR_GREATER_OR_EQUAL) + { + uint16_t seq_num; + uint16_t i; + + seq_num = (p_racp_request->p_operand[2] << 8) | p_racp_request->p_operand[1]; + + for (i = 0; i < total_records; i++) + { + uint32_t err_code; + ble_gls_rec_t rec; + + err_code = ble_gls_db_record_get(i, &rec); + if (err_code != NRF_SUCCESS) + { + if (p_gls->error_handler != NULL) + { + p_gls->error_handler(err_code); + } + return; + } + + if (rec.meas.sequence_number >= seq_num) + { + num_records++; + } + } + } + else if ((p_racp_request->operator == RACP_OPERATOR_FIRST) || + (p_racp_request->operator == RACP_OPERATOR_LAST)) + { + if (total_records > 0) + { + num_records = 1; + } + } + + m_pending_racp_response.opcode = RACP_OPCODE_NUM_RECS_RESPONSE; + m_pending_racp_response.operator = RACP_OPERATOR_NULL; + m_pending_racp_response.operand_len = sizeof(uint16_t); + m_pending_racp_response.p_operand = m_pending_racp_response_operand; + + m_pending_racp_response_operand[0] = num_records & 0xFF; + m_pending_racp_response_operand[1] = num_records >> 8; + + racp_send(p_gls, &m_pending_racp_response); +} + + +/**@brief Function for checking if the CCCDs are configured. + * + * @param[in] p_gls Service instance. + * @param[in] p_are_cccd_configured boolean indicating if both cccds are configured + */ +uint32_t ble_gls_are_cccd_configured(ble_gls_t * p_gls, bool * p_are_cccd_configured) +{ + uint32_t err_code; + uint8_t cccd_value_buf[BLE_CCCD_VALUE_LEN]; + bool is_glm_notif_enabled = false; + bool is_racp_indic_enabled = false; + ble_gatts_value_t gatts_value; + + // Initialize value struct. + memset(&gatts_value, 0, sizeof(gatts_value)); + + gatts_value.len = BLE_CCCD_VALUE_LEN; + gatts_value.offset = 0; + gatts_value.p_value = cccd_value_buf; + + err_code = sd_ble_gatts_value_get(p_gls->conn_handle, + p_gls->glm_handles.cccd_handle, + &gatts_value); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + is_glm_notif_enabled = ble_srv_is_notification_enabled(cccd_value_buf); + + err_code = sd_ble_gatts_value_get(p_gls->conn_handle, + p_gls->racp_handles.cccd_handle, + &gatts_value); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + is_racp_indic_enabled = ble_srv_is_indication_enabled(cccd_value_buf); + if (is_racp_indic_enabled & is_glm_notif_enabled) + { + *p_are_cccd_configured = true; + } + else + { + *p_are_cccd_configured = false; + } + return NRF_SUCCESS; +} + + +/**@brief Function for handling a write event to the Record Access Control Point. + * + * @param[in] p_gls Service instance. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_racp_value_write(ble_gls_t * p_gls, ble_gatts_evt_write_t * p_evt_write) +{ + ble_racp_value_t racp_request; + uint8_t response_code; + ble_gatts_rw_authorize_reply_params_t auth_reply; + bool are_cccd_configured; + uint32_t err_code; + + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.params.write.offset = 0; + auth_reply.params.write.len = 0; + auth_reply.params.write.p_data = NULL; + + err_code = ble_gls_are_cccd_configured(p_gls, &are_cccd_configured); + if (err_code != NRF_SUCCESS) + { + if (p_gls->error_handler != NULL) + { + p_gls->error_handler(err_code); + } + return; + } + + if (!are_cccd_configured) + { + auth_reply.params.write.gatt_status = GLS_NACK_CCCD_IMPROPERLY_CONFIGURED; + err_code = sd_ble_gatts_rw_authorize_reply(p_gls->conn_handle, + &auth_reply); + + if (err_code != NRF_SUCCESS) + { + if (p_gls->error_handler != NULL) + { + p_gls->error_handler(err_code); + } + } + return; + } + + // Decode request. + ble_racp_decode(p_evt_write->len, p_evt_write->data, &racp_request); + + // Check if request is to be executed. + if (is_request_to_be_executed(&racp_request, &response_code)) + { + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; + + err_code = sd_ble_gatts_rw_authorize_reply(p_gls->conn_handle, + &auth_reply); + + if (err_code != NRF_SUCCESS) + { + if (p_gls->error_handler != NULL) + { + p_gls->error_handler(err_code); + } + return; + } + // Execute request. + if (racp_request.opcode == RACP_OPCODE_REPORT_RECS) + { + report_records_request_execute(p_gls, &racp_request); + } + else if (racp_request.opcode == RACP_OPCODE_REPORT_NUM_RECS) + { + report_num_records_request_execute(p_gls, &racp_request); + } + } + else if (response_code != RACP_RESPONSE_RESERVED) + { + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; + err_code = sd_ble_gatts_rw_authorize_reply(p_gls->conn_handle, + &auth_reply); + + if (err_code != NRF_SUCCESS) + { + if (p_gls->error_handler != NULL) + { + p_gls->error_handler(err_code); + } + return; + } + + // Abort any running procedure. + state_set(STATE_NO_COMM); + + // Respond with error code. + racp_response_code_send(p_gls, racp_request.opcode, response_code); + } + else + { + auth_reply.params.write.gatt_status = GLS_NACK_PROC_ALREADY_IN_PROGRESS; + err_code = sd_ble_gatts_rw_authorize_reply(p_gls->conn_handle, + &auth_reply); + + if (err_code != NRF_SUCCESS) + { + if (p_gls->error_handler != NULL) + { + p_gls->error_handler(err_code); + } + return; + } + } +} + + +/**@brief Function for handling the Glucose measurement CCCD write event. + * + * @param[in] p_gls Service instance. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_glm_cccd_write(ble_gls_t * p_gls, ble_gatts_evt_write_t * p_evt_write) +{ + if (p_evt_write->len == 2) + { + // CCCD written, update notification state + ble_gls_evt_t evt; + + if (ble_srv_is_notification_enabled(p_evt_write->data)) + { + evt.evt_type = BLE_GLS_EVT_NOTIFICATION_ENABLED; + } + else + { + evt.evt_type = BLE_GLS_EVT_NOTIFICATION_DISABLED; + } + + if (p_gls->evt_handler != NULL) + { + p_gls->evt_handler(p_gls, &evt); + } + } +} + + +/**@brief Function for handling the WRITE event. + * + * @details Handles WRITE events from the BLE stack. + * + * @param[in] p_gls Glucose Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_gls_t * p_gls, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if (p_evt_write->handle == p_gls->glm_handles.cccd_handle) + { + on_glm_cccd_write(p_gls, p_evt_write); + } + else if (p_evt_write->handle == p_gls->racp_handles.value_handle) + { + on_racp_value_write(p_gls, p_evt_write); + } +} + + +/**@brief Function for handling the TX_COMPLETE event. + * + * @details Handles TX_COMPLETE events from the BLE stack. + * + * @param[in] p_gls Glucose Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_tx_complete(ble_gls_t * p_gls, ble_evt_t * p_ble_evt) +{ + m_racp_proc_records_reported_since_txcomplete = 0; + + if (m_gls_state == STATE_RACP_RESPONSE_PENDING) + { + racp_send(p_gls, &m_pending_racp_response); + } + else if (m_gls_state == STATE_RACP_PROC_ACTIVE) + { + racp_report_records_procedure(p_gls); + } +} + + +/**@brief Function for handling the HVC event. + * + * @details Handles HVC events from the BLE stack. + * + * @param[in] p_gls Glucose Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_hvc(ble_gls_t * p_gls, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_hvc_t * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc; + + if (p_hvc->handle == p_gls->racp_handles.value_handle) + { + if (m_gls_state == STATE_RACP_RESPONSE_IND_VERIF) + { + // Indication has been acknowledged. Return to default state. + state_set(STATE_NO_COMM); + } + else + { + // We did not expect this event in this state. Report error to application. + if (p_gls->error_handler != NULL) + { + p_gls->error_handler(NRF_ERROR_INVALID_STATE); + } + } + } +} + + +static void on_rw_authorize_request(ble_gls_t * p_gls, ble_gatts_evt_t * p_gatts_evt) +{ + ble_gatts_evt_rw_authorize_request_t * p_auth_req = &p_gatts_evt->params.authorize_request; + if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + if ( (p_gatts_evt->params.authorize_request.request.write.op + != BLE_GATTS_OP_PREP_WRITE_REQ) + && (p_gatts_evt->params.authorize_request.request.write.op + != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + && (p_gatts_evt->params.authorize_request.request.write.op + != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL) + ) + { + if (p_auth_req->request.write.handle == p_gls->racp_handles.value_handle) + { + on_racp_value_write(p_gls, &p_auth_req->request.write); + } + } + } +} + +void ble_gls_on_ble_evt(ble_gls_t * p_gls, ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + p_gls->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + state_set(STATE_NO_COMM); + break; + + case BLE_GAP_EVT_DISCONNECTED: + p_gls->conn_handle = BLE_CONN_HANDLE_INVALID; + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_gls, p_ble_evt); + break; + + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + on_tx_complete(p_gls, p_ble_evt); + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + on_rw_authorize_request(p_gls, &p_ble_evt->evt.gatts_evt); + break; + + case BLE_GATTS_EVT_HVC: + on_hvc(p_gls, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +uint32_t ble_gls_glucose_new_meas(ble_gls_t * p_gls, ble_gls_rec_t * p_rec) +{ + p_rec->meas.sequence_number = m_next_seq_num++; + return ble_gls_db_record_add(p_rec); +} +#endif // NRF_MODULE_ENABLED(BLE_GLS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_gls/ble_gls.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_gls/ble_gls.h new file mode 100644 index 0000000000000000000000000000000000000000..2b2be7800062bfd4460aac83201b9a87f56c5c39 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_gls/ble_gls.h @@ -0,0 +1,301 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_gls Glucose Service + * @{ + * @ingroup ble_sdk_srv + * @brief Glucose Service module. + * + * @details This module implements the Glucose Service. + * + * @note The application must propagate BLE stack events to the Glucose Service module by calling + * ble_gls_on_ble_evt() from the @ref softdevice_handler callback. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#ifndef BLE_GLS_H__ +#define BLE_GLS_H__ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "ble_date_time.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Glucose feature */ +#define BLE_GLS_FEATURE_LOW_BATT 0x0001 /**< Low Battery Detection During Measurement Supported */ +#define BLE_GLS_FEATURE_MALFUNC 0x0002 /**< Sensor Malfunction Detection Supported */ +#define BLE_GLS_FEATURE_SAMPLE_SIZE 0x0004 /**< Sensor Sample Size Supported */ +#define BLE_GLS_FEATURE_INSERT_ERR 0x0008 /**< Sensor Strip Insertion Error Detection Supported */ +#define BLE_GLS_FEATURE_TYPE_ERR 0x0010 /**< Sensor Strip Type Error Detection Supported */ +#define BLE_GLS_FEATURE_RES_HIGH_LOW 0x0020 /**< Sensor Result High-Low Detection Supported */ +#define BLE_GLS_FEATURE_TEMP_HIGH_LOW 0x0040 /**< Sensor Temperature High-Low Detection Supported */ +#define BLE_GLS_FEATURE_READ_INT 0x0080 /**< Sensor Read Interrupt Detection Supported */ +#define BLE_GLS_FEATURE_GENERAL_FAULT 0x0100 /**< General Device Fault Supported */ +#define BLE_GLS_FEATURE_TIME_FAULT 0x0200 /**< Time Fault Supported */ +#define BLE_GLS_FEATURE_MULTI_BOND 0x0400 /**< Multiple Bond Supported */ + +/**@brief Glucose measurement flags */ +#define BLE_GLS_MEAS_FLAG_TIME_OFFSET 0x01 /**< Time Offset Present */ +#define BLE_GLS_MEAS_FLAG_CONC_TYPE_LOC 0x02 /**< Glucose Concentration, Type, and Sample Location Present */ +#define BLE_GLS_MEAS_FLAG_UNITS_KG_L 0x00 /**< Glucose Concentration Units kg/L */ +#define BLE_GLS_MEAS_FLAG_UNITS_MOL_L 0x04 /**< Glucose Concentration Units mol/L */ +#define BLE_GLS_MEAS_FLAG_SENSOR_STATUS 0x08 /**< Sensor Status Annunciation Present */ +#define BLE_GLS_MEAS_FLAG_CONTEXT_INFO 0x10 /**< Context Information Follows */ + +/**@brief Glucose measurement type */ +#define BLE_GLS_MEAS_TYPE_CAP_BLOOD 1 /**< Capillary whole blood */ +#define BLE_GLS_MEAS_TYPE_CAP_PLASMA 2 /**< Capillary plasma */ +#define BLE_GLS_MEAS_TYPE_VEN_BLOOD 3 /**< Venous whole blood */ +#define BLE_GLS_MEAS_TYPE_VEN_PLASMA 4 /**< Venous plasma */ +#define BLE_GLS_MEAS_TYPE_ART_BLOOD 5 /**< Arterial whole blood */ +#define BLE_GLS_MEAS_TYPE_ART_PLASMA 6 /**< Arterial plasma */ +#define BLE_GLS_MEAS_TYPE_UNDET_BLOOD 7 /**< Undetermined whole blood */ +#define BLE_GLS_MEAS_TYPE_UNDET_PLASMA 8 /**< Undetermined plasma */ +#define BLE_GLS_MEAS_TYPE_FLUID 9 /**< Interstitial fluid (ISF) */ +#define BLE_GLS_MEAS_TYPE_CONTROL 10 /**< Control solution */ + +/**@brief Glucose measurement location */ +#define BLE_GLS_MEAS_LOC_FINGER 1 /**< Finger */ +#define BLE_GLS_MEAS_LOC_AST 2 /**< Alternate Site Test (AST) */ +#define BLE_GLS_MEAS_LOC_EAR 3 /**< Earlobe */ +#define BLE_GLS_MEAS_LOC_CONTROL 4 /**< Control solution */ +#define BLE_GLS_MEAS_LOC_NOT_AVAIL 15 /**< Sample Location value not available */ + +/**@brief Glucose sensor status annunciation */ +#define BLE_GLS_MEAS_STATUS_BATT_LOW 0x0001 /**< Device battery low at time of measurement */ +#define BLE_GLS_MEAS_STATUS_SENSOR_FAULT 0x0002 /**< Sensor malfunction or faulting at time of measurement */ +#define BLE_GLS_MEAS_STATUS_SAMPLE_SIZE 0x0004 /**< Sample size for blood or control solution insufficient at time of measurement */ +#define BLE_GLS_MEAS_STATUS_STRIP_INSERT 0x0008 /**< Strip insertion error */ +#define BLE_GLS_MEAS_STATUS_STRIP_TYPE 0x0010 /**< Strip type incorrect for device */ +#define BLE_GLS_MEAS_STATUS_RESULT_HIGH 0x0020 /**< Sensor result higher than the device can process */ +#define BLE_GLS_MEAS_STATUS_RESULT_LOW 0x0040 /**< Sensor result lower than the device can process */ +#define BLE_GLS_MEAS_STATUS_TEMP_HIGH 0x0080 /**< Sensor temperature too high for valid test/result at time of measurement */ +#define BLE_GLS_MEAS_STATUS_TEMP_LOW 0x0100 /**< Sensor temperature too low for valid test/result at time of measurement */ +#define BLE_GLS_MEAS_STATUS_STRIP_PULL 0x0200 /**< Sensor read interrupted because strip was pulled too soon at time of measurement */ +#define BLE_GLS_MEAS_STATUS_GENERAL_FAULT 0x0400 /**< General device fault has occurred in the sensor */ +#define BLE_GLS_MEAS_STATUS_TIME_FAULT 0x0800 /**< Time fault has occurred in the sensor and time may be inaccurate */ + +/**@brief Glucose measurement context flags */ +#define BLE_GLS_CONTEXT_FLAG_CARB 0x01 /**< Carbohydrate id and carbohydrate present */ +#define BLE_GLS_CONTEXT_FLAG_MEAL 0x02 /**< Meal present */ +#define BLE_GLS_CONTEXT_FLAG_TESTER 0x04 /**< Tester-health present */ +#define BLE_GLS_CONTEXT_FLAG_EXERCISE 0x08 /**< Exercise duration and exercise intensity present */ +#define BLE_GLS_CONTEXT_FLAG_MED 0x10 /**< Medication ID and medication present */ +#define BLE_GLS_CONTEXT_FLAG_MED_KG 0x00 /**< Medication value units, kilograms */ +#define BLE_GLS_CONTEXT_FLAG_MED_L 0x20 /**< Medication value units, liters */ +#define BLE_GLS_CONTEXT_FLAG_HBA1C 0x40 /**< Hba1c present */ +#define BLE_GLS_CONTEXT_FLAG_EXT 0x80 /**< Extended flags present */ + +/**@brief Glucose measurement context carbohydrate ID */ +#define BLE_GLS_CONTEXT_CARB_BREAKFAST 1 /**< Breakfast */ +#define BLE_GLS_CONTEXT_CARB_LUNCH 2 /**< Lunch */ +#define BLE_GLS_CONTEXT_CARB_DINNER 3 /**< Dinner */ +#define BLE_GLS_CONTEXT_CARB_SNACK 4 /**< Snack */ +#define BLE_GLS_CONTEXT_CARB_DRINK 5 /**< Drink */ +#define BLE_GLS_CONTEXT_CARB_SUPPER 6 /**< Supper */ +#define BLE_GLS_CONTEXT_CARB_BRUNCH 7 /**< Brunch */ + +/**@brief Glucose measurement context meal */ +#define BLE_GLS_CONTEXT_MEAL_PREPRANDIAL 1 /**< Preprandial (before meal) */ +#define BLE_GLS_CONTEXT_MEAL_POSTPRANDIAL 2 /**< Postprandial (after meal) */ +#define BLE_GLS_CONTEXT_MEAL_FASTING 3 /**< Fasting */ +#define BLE_GLS_CONTEXT_MEAL_CASUAL 4 /**< Casual (snacks, drinks, etc.) */ +#define BLE_GLS_CONTEXT_MEAL_BEDTIME 5 /**< Bedtime */ + +/**@brief Glucose measurement context tester */ +#define BLE_GLS_CONTEXT_TESTER_SELF 1 /**< Self */ +#define BLE_GLS_CONTEXT_TESTER_PRO 2 /**< Health care professional */ +#define BLE_GLS_CONTEXT_TESTER_LAB 3 /**< Lab test */ +#define BLE_GLS_CONTEXT_TESTER_NOT_AVAIL 15 /**< Tester value not available */ + +/**@brief Glucose measurement context health */ +#define BLE_GLS_CONTEXT_HEALTH_MINOR 1 /**< Minor health issues */ +#define BLE_GLS_CONTEXT_HEALTH_MAJOR 2 /**< Major health issues */ +#define BLE_GLS_CONTEXT_HEALTH_MENSES 3 /**< During menses */ +#define BLE_GLS_CONTEXT_HEALTH_STRESS 4 /**< Under stress */ +#define BLE_GLS_CONTEXT_HEALTH_NONE 5 /**< No health issues */ +#define BLE_GLS_CONTEXT_HEALTH_NOT_AVAIL 15 /**< Health value not available */ + +/**@brief Glucose measurement context medication ID */ +#define BLE_GLS_CONTEXT_MED_RAPID 1 /**< Rapid acting insulin */ +#define BLE_GLS_CONTEXT_MED_SHORT 2 /**< Short acting insulin */ +#define BLE_GLS_CONTEXT_MED_INTERMED 3 /**< Intermediate acting insulin */ +#define BLE_GLS_CONTEXT_MED_LONG 4 /**< Long acting insulin */ +#define BLE_GLS_CONTEXT_MED_PREMIX 5 /**< Pre-mixed insulin */ + +/**@brief SFLOAT format (IEEE-11073 16-bit FLOAT, meaning 4 bits for exponent (base 10) and 12 bits mantissa) */ +typedef struct +{ + int8_t exponent; /**< Base 10 exponent, should be using only 4 bits */ + int16_t mantissa; /**< Mantissa, should be using only 12 bits */ +} sfloat_t; + +/**@brief Glucose Service event type. */ +typedef enum +{ + BLE_GLS_EVT_NOTIFICATION_ENABLED, /**< Glucose value notification enabled event. */ + BLE_GLS_EVT_NOTIFICATION_DISABLED /**< Glucose value notification disabled event. */ +} ble_gls_evt_type_t; + +/**@brief Glucose Service event. */ +typedef struct +{ + ble_gls_evt_type_t evt_type; /**< Type of event. */ +} ble_gls_evt_t; + +// Forward declaration of the ble_gls_t type. +typedef struct ble_gls_s ble_gls_t; + +/**@brief Glucose Service event handler type. */ +typedef void (*ble_gls_evt_handler_t) (ble_gls_t * p_gls, ble_gls_evt_t * p_evt); + +/**@brief Glucose Measurement structure. This contains glucose measurement value. */ +typedef struct +{ + uint8_t flags; /**< Flags */ + uint16_t sequence_number; /**< Sequence number */ + ble_date_time_t base_time; /**< Time stamp */ + int16_t time_offset; /**< Time offset */ + sfloat_t glucose_concentration; /**< Glucose concentration */ + uint8_t type; /**< Type */ + uint8_t sample_location; /**< Sample location */ + uint16_t sensor_status_annunciation; /**< Sensor status annunciation */ +} ble_gls_meas_t; + +/**@brief Glucose measurement context structure */ +typedef struct +{ + uint8_t flags; /**< Flags */ + uint8_t extended_flags; /**< Extended Flags */ + uint8_t carbohydrate_id; /**< Carbohydrate ID */ + sfloat_t carbohydrate; /**< Carbohydrate */ + uint8_t meal; /**< Meal */ + uint8_t tester_and_health; /**< Tester and health */ + uint16_t exercise_duration; /**< Exercise Duration */ + uint8_t exercise_intensity; /**< Exercise Intensity */ + uint8_t medication_id; /**< Medication ID */ + sfloat_t medication; /**< Medication */ + uint16_t hba1c; /**< HbA1c */ +} ble_gls_meas_context_t; + +/**@brief Glucose measurement record */ +typedef struct +{ + ble_gls_meas_t meas; /**< Glucose measurement */ + ble_gls_meas_context_t context; /**< Glucose measurement context */ +} ble_gls_rec_t; + +/**@brief Glucose Service init structure. This contains all options and data needed for + * initialization of the service. */ +typedef struct +{ + ble_gls_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Glucose Service. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + uint16_t feature; /**< Glucose Feature value indicating supported features. */ + bool is_context_supported; /**< Determines if optional Glucose Measurement Context is to be supported. */ +} ble_gls_init_t; + +/**@brief Glucose Service structure. This contains various status information for the service. */ +struct ble_gls_s +{ + ble_gls_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Glucose Service. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + uint16_t service_handle; /**< Handle of Glucose Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t glm_handles; /**< Handles related to the Glucose Measurement characteristic. */ + ble_gatts_char_handles_t glm_context_handles; /**< Handles related to the Glucose Measurement Context characteristic. */ + ble_gatts_char_handles_t glf_handles; /**< Handles related to the Glucose Feature characteristic. */ + ble_gatts_char_handles_t racp_handles; /**< Handles related to the Record Access Control Point characteristic. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ + uint16_t feature; + bool is_context_supported; +}; + +/**@brief Function for initializing the Glucose Service. + * + * @details This call allows the application to initialize the Glucose Service. + * + * @param[out] p_gls Glucose Service structure. This structure will have to be supplied by + * the application. It will be initialized by this function, and will later + * be used to identify this particular service instance. + * @param[in] p_gls_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +uint32_t ble_gls_init(ble_gls_t * p_gls, const ble_gls_init_t * p_gls_init); + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the Glucose Service. + * + * @param[in] p_gls Glucose Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_gls_on_ble_evt(ble_gls_t * p_gls, ble_evt_t * p_ble_evt); + +/**@brief Function for reporting a new glucose measurement to the glucose service module. + * + * @details The application calls this function after having performed a new glucose measurement. + * The new measurement is recorded in the RACP database. + * + * @param[in] p_gls Glucose Service structure. + * @param[in] p_rec Pointer to glucose record (measurement plus context). + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_gls_glucose_new_meas(ble_gls_t * p_gls, ble_gls_rec_t * p_rec); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_GLS_H__ + +/** @} */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_gls/ble_gls_db.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_gls/ble_gls_db.c new file mode 100644 index 0000000000000000000000000000000000000000..c1bbe8b3fbb256bbd3f7df8096eb20efde305a69 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_gls/ble_gls_db.c @@ -0,0 +1,143 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_GLS) +#include "ble_gls_db.h" + + +typedef struct +{ + bool in_use_flag; + ble_gls_rec_t record; +} database_entry_t; + +static database_entry_t m_database[BLE_GLS_DB_MAX_RECORDS]; +static uint8_t m_database_crossref[BLE_GLS_DB_MAX_RECORDS]; +static uint16_t m_num_records; + + +uint32_t ble_gls_db_init(void) +{ + int i; + + for (i = 0; i < BLE_GLS_DB_MAX_RECORDS; i++) + { + m_database[i].in_use_flag = false; + m_database_crossref[i] = 0xFF; + } + + m_num_records = 0; + + return NRF_SUCCESS; +} + + +uint16_t ble_gls_db_num_records_get(void) +{ + return m_num_records; +} + + +uint32_t ble_gls_db_record_get(uint8_t rec_ndx, ble_gls_rec_t * p_rec) +{ + if (rec_ndx >= m_num_records) + { + return NRF_ERROR_INVALID_PARAM; + } + + // copy record to the specified memory + *p_rec = m_database[m_database_crossref[rec_ndx]].record; + + return NRF_SUCCESS; +} + + +uint32_t ble_gls_db_record_add(ble_gls_rec_t * p_rec) +{ + int i; + + if (m_num_records == BLE_GLS_DB_MAX_RECORDS) + { + return NRF_ERROR_NO_MEM; + } + + // find next available database entry + for (i = 0; i < BLE_GLS_DB_MAX_RECORDS; i++) + { + if (!m_database[i].in_use_flag) + { + m_database[i].in_use_flag = true; + m_database[i].record = *p_rec; + + m_database_crossref[m_num_records] = i; + m_num_records++; + + return NRF_SUCCESS; + } + } + + return NRF_ERROR_NO_MEM; +} + + +uint32_t ble_gls_db_record_delete(uint8_t rec_ndx) +{ + int i; + + if (rec_ndx >= m_num_records) + { + return NRF_ERROR_NOT_FOUND; + } + + // free entry + m_database[m_database_crossref[rec_ndx]].in_use_flag = false; + + // decrease number of records + m_num_records--; + + // remove cross reference index + for (i = rec_ndx; i < m_num_records; i++) + { + m_database_crossref[i] = m_database_crossref[i + 1]; + } + + return NRF_SUCCESS; +} +#endif // NRF_MODULE_ENABLED(BLE_GLS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_gls/ble_gls_db.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_gls/ble_gls_db.h new file mode 100644 index 0000000000000000000000000000000000000000..ffc928d87f40f0329ef00a5dec4825fcec1a128e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_gls/ble_gls_db.h @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_srv_gls_db Glucose Database Service + * @{ + * @ingroup ble_sdk_srv + * @brief Glucose Service module. + * + * @details This module implements at database of stored glucose measurement values. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, These APIs must not be modified. However, the corresponding + * functions' implementations can be modified. + */ + +#ifndef BLE_GLS_DB_H__ +#define BLE_GLS_DB_H__ + +#include +#include "ble_gls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_GLS_DB_MAX_RECORDS 20 + +/**@brief Function for initializing the glucose record database. + * + * @details This call initializes the database holding glucose records. + * + * @return NRF_SUCCESS on success. + */ +uint32_t ble_gls_db_init(void); + +/**@brief Function for getting the number of records in the database. + * + * @details This call returns the number of records in the database. + * + * @return Number of records in the database. + */ +uint16_t ble_gls_db_num_records_get(void); + +/**@brief Function for getting a record from the database. + * + * @details This call returns a specified record from the database. + * + * @param[in] record_num Index of the record to retrieve. + * @param[out] p_rec Pointer to record structure where retrieved record is copied to. + * + * @return NRF_SUCCESS on success. + */ +uint32_t ble_gls_db_record_get(uint8_t record_num, ble_gls_rec_t * p_rec); + +/**@brief Function for adding a record at the end of the database. + * + * @details This call adds a record as the last record in the database. + * + * @param[in] p_rec Pointer to record to add to database. + * + * @return NRF_SUCCESS on success. + */ +uint32_t ble_gls_db_record_add(ble_gls_rec_t * p_rec); + +/**@brief Function for deleting a database entry. + * + * @details This call deletes an record from the database. + * + * @param[in] record_num Index of record to delete. + * + * @return NRF_SUCCESS on success. + */ +uint32_t ble_gls_db_record_delete(uint8_t record_num); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_GLS_DB_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hids/ble_hids.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hids/ble_hids.c new file mode 100644 index 0000000000000000000000000000000000000000..23f27b418c6cc9ac3039508ba54a866dac02856e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hids/ble_hids.c @@ -0,0 +1,1407 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_HIDS) +#include "ble_hids.h" +#include +#include "app_error.h" +#include "ble_srv_common.h" + + +// Protocol Mode values +#define PROTOCOL_MODE_BOOT 0x00 /**< Boot Protocol Mode. */ +#define PROTOCOL_MODE_REPORT 0x01 /**< Report Protocol Mode. */ + +// HID Control Point values +#define HIDS_CONTROL_POINT_SUSPEND 0 /**< Suspend command. */ +#define HIDS_CONTROL_POINT_EXIT_SUSPEND 1 /**< Exit Suspend command. */ + +#define DEFAULT_PROTOCOL_MODE PROTOCOL_MODE_REPORT /**< Default value for the Protocol Mode characteristic. */ +#define INITIAL_VALUE_HID_CONTROL_POINT HIDS_CONTROL_POINT_SUSPEND /**< Initial value for the HID Control Point characteristic. */ + +#define ENCODED_HID_INFORMATION_LEN 4 /**< Maximum size of an encoded HID Information characteristic. */ + +#define BOOT_KB_INPUT_REPORT_MAX_SIZE 8 /**< Maximum size of a Boot Keyboard Input Report (as per Appendix B in Device Class Definition for Human Interface Devices (HID), Version 1.11). */ +#define BOOT_KB_OUTPUT_REPORT_MAX_SIZE 1 /**< Maximum size of a Boot Keyboard Output Report (as per Appendix B in Device Class Definition for Human Interface Devices (HID), Version 1.11). */ +#define BOOT_MOUSE_INPUT_REPORT_MIN_SIZE 3 /**< Minimum size of a Boot Mouse Input Report (as per Appendix B in Device Class Definition for Human Interface Devices (HID), Version 1.11). */ +#define BOOT_MOUSE_INPUT_REPORT_MAX_SIZE 8 /**< Maximum size of a Boot Mouse Input Report (as per Appendix B in Device Class Definition for Human Interface Devices (HID), Version 1.11). */ + + +/**@brief Function for making a HID Service characteristic id. + * + * @param[in] uuid UUID of characteristic. + * @param[in] rep_type Type of report. + * @param[in] rep_index Index of the characteristic. + * + * @return HID Service characteristic id structure. + */ +static ble_hids_char_id_t make_char_id(uint16_t uuid, uint8_t rep_type, uint8_t rep_index) +{ + ble_hids_char_id_t char_id = {0}; + + char_id.uuid = uuid; + char_id.rep_type = rep_type; + char_id.rep_index = rep_index; + + return char_id; +} + + +/**@brief Function for handling the Connect event. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_hids_t * p_hids, ble_evt_t * p_ble_evt) +{ + uint32_t err_code; + uint8_t default_protocol_mode; + ble_gatts_value_t gatts_value; + + p_hids->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + + if (p_hids->protocol_mode_handles.value_handle) + { + // Set Protocol Mode characteristic value to default value + default_protocol_mode = DEFAULT_PROTOCOL_MODE; + + // Initialize value struct. + memset(&gatts_value, 0, sizeof(gatts_value)); + + gatts_value.len = sizeof(uint8_t); + gatts_value.offset = 0; + gatts_value.p_value = &default_protocol_mode; + + err_code = sd_ble_gatts_value_set(p_hids->conn_handle, + p_hids->protocol_mode_handles.value_handle, + &gatts_value); + if ((err_code != NRF_SUCCESS) && (p_hids->error_handler != NULL)) + { + p_hids->error_handler(err_code); + } + } +} + + +/**@brief Function for handling the Disconnect event. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_hids_t * p_hids, ble_evt_t * p_ble_evt) +{ + UNUSED_PARAMETER(p_ble_evt); + p_hids->conn_handle = BLE_CONN_HANDLE_INVALID; +} + + +/**@brief Function for handling write events to the HID Control Point value. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_control_point_write(ble_hids_t * p_hids, ble_gatts_evt_write_t * p_evt_write) +{ + if ((p_evt_write->len == 1) && (p_hids->evt_handler != NULL)) + { + ble_hids_evt_t evt; + + // HID Control Point written, propagate event to application + switch (p_evt_write->data[0]) + { + case HIDS_CONTROL_POINT_SUSPEND: + evt.evt_type = BLE_HIDS_EVT_HOST_SUSP; + break; + + case HIDS_CONTROL_POINT_EXIT_SUSPEND: + evt.evt_type = BLE_HIDS_EVT_HOST_EXIT_SUSP; + break; + + default: + // Illegal Control Point value, ignore + return; + } + + p_hids->evt_handler(p_hids, &evt); + } +} + + +/**@brief Function for handling write events to the Protocol Mode value. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_protocol_mode_write(ble_hids_t * p_hids, ble_gatts_evt_write_t * p_evt_write) +{ + if ((p_evt_write->len == 1) && (p_hids->evt_handler != NULL)) + { + ble_hids_evt_t evt; + + // HID Protocol Mode written, propagate event to application + switch (p_evt_write->data[0]) + { + case PROTOCOL_MODE_BOOT: + evt.evt_type = BLE_HIDS_EVT_BOOT_MODE_ENTERED; + break; + + case PROTOCOL_MODE_REPORT: + evt.evt_type = BLE_HIDS_EVT_REPORT_MODE_ENTERED; + break; + + default: + // Illegal Protocol Mode value, ignore + return; + } + + p_hids->evt_handler(p_hids, &evt); + } +} + + +/**@brief Function for handling write events to a report CCCD. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_char_id Id of report characteristic. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_report_cccd_write(ble_hids_t * p_hids, + ble_hids_char_id_t * p_char_id, + ble_gatts_evt_write_t * p_evt_write) +{ + if (p_evt_write->len == 2) + { + // CCCD written, update notification state + if (p_hids->evt_handler != NULL) + { + ble_hids_evt_t evt; + + if (ble_srv_is_notification_enabled(p_evt_write->data)) + { + evt.evt_type = BLE_HIDS_EVT_NOTIF_ENABLED; + } + else + { + evt.evt_type = BLE_HIDS_EVT_NOTIF_DISABLED; + } + evt.params.notification.char_id = *p_char_id; + + p_hids->evt_handler(p_hids, &evt); + } + } +} + + +/**@brief Function for handling write events to a report value. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_char_id Id of report characteristic. + */ +static void on_report_value_write(ble_hids_t * p_hids, + ble_evt_t * p_ble_evt, + ble_hids_char_id_t * p_char_id) +{ + if (p_hids->evt_handler != NULL) + { + ble_hids_evt_t evt; + + evt.evt_type = BLE_HIDS_EVT_REP_CHAR_WRITE; + evt.params.char_write.char_id = *p_char_id; + evt.params.char_write.offset = p_ble_evt->evt.gatts_evt.params.write.offset; + evt.params.char_write.len = p_ble_evt->evt.gatts_evt.params.write.len; + evt.params.char_write.data = p_ble_evt->evt.gatts_evt.params.write.data; + + p_hids->evt_handler(p_hids, &evt); + } +} + +/**@brief Handle authorize read events to a report value. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_char_id Id of report characteristic. + */ +static void on_report_value_read_auth(ble_hids_t * p_hids, + ble_hids_char_id_t * p_char_id, + ble_evt_t * p_ble_evt) +{ + if (p_hids->evt_handler != NULL) + { + ble_hids_evt_t evt; + + evt.evt_type = BLE_HIDS_EVT_REPORT_READ; + evt.params.char_auth_read.char_id = *p_char_id; + evt.p_ble_evt = p_ble_evt; + + p_hids->evt_handler(p_hids, &evt); + } +} + +/**@brief Function for finding the Characteristic Id of a characteristic corresponding to a CCCD handle. + * + * @param[in] p_hids HID Service structure. + * @param[in] handle Handle to search for. + * @param[out] p_char_id Id of report characteristic. + * + * @return TRUE if CCCD handle was found, FALSE otherwise. + */ +static bool inp_rep_cccd_identify(ble_hids_t * p_hids, + uint16_t handle, + ble_hids_char_id_t * p_char_id) +{ + uint8_t i; + + for (i = 0; i < p_hids->inp_rep_count; i++) + { + if (handle == p_hids->inp_rep_array[i].char_handles.cccd_handle) + { + *p_char_id = make_char_id(BLE_UUID_REPORT_CHAR, BLE_HIDS_REP_TYPE_INPUT, i); + return true; + } + } + + return false; +} + + +/**@brief Function for finding the Characteristic Id of a characteristic corresponding to a value handle. + * + * @param[in] p_hids HID Service structure. + * @param[in] handle Handle to search for. + * @param[out] p_char_id Id of report characteristic. + * + * @return TRUE if value handle was found, FALSE otherwise. + */ +static bool rep_value_identify(ble_hids_t * p_hids, + uint16_t handle, + ble_hids_char_id_t * p_char_id) +{ + uint8_t i; + + for (i = 0; i < p_hids->inp_rep_count; i++) + { + if (handle == p_hids->inp_rep_array[i].char_handles.value_handle) + { + *p_char_id = make_char_id(BLE_UUID_REPORT_CHAR, BLE_HIDS_REP_TYPE_INPUT, i); + return true; + } + } + + for (i = 0; i < p_hids->outp_rep_count; i++) + { + if (handle == p_hids->outp_rep_array[i].char_handles.value_handle) + { + *p_char_id = make_char_id(BLE_UUID_REPORT_CHAR, BLE_HIDS_REP_TYPE_OUTPUT, i); + return true; + } + } + + for (i = 0; i < p_hids->feature_rep_count; i++) + { + if (handle == p_hids->feature_rep_array[i].char_handles.value_handle) + { + *p_char_id = make_char_id(BLE_UUID_REPORT_CHAR, BLE_HIDS_REP_TYPE_FEATURE, i); + return true; + } + } + + return false; +} + + +/**@brief Function for handling the Write event. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_hids_t * p_hids, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + ble_hids_char_id_t char_id; + + if (p_evt_write->handle == p_hids->hid_control_point_handles.value_handle) + { + on_control_point_write(p_hids, p_evt_write); + } + else if (p_evt_write->handle == p_hids->protocol_mode_handles.value_handle) + { + on_protocol_mode_write(p_hids, p_evt_write); + } + else if (p_evt_write->handle == p_hids->boot_kb_inp_rep_handles.cccd_handle) + { + char_id = make_char_id(BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR, 0, 0); + on_report_cccd_write(p_hids, &char_id, p_evt_write); + } + else if (p_evt_write->handle == p_hids->boot_kb_inp_rep_handles.value_handle) + { + char_id = make_char_id(BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR, 0, 0); + on_report_value_write(p_hids, p_ble_evt, &char_id); + } + else if (p_evt_write->handle == p_hids->boot_mouse_inp_rep_handles.cccd_handle) + { + char_id = make_char_id(BLE_UUID_BOOT_MOUSE_INPUT_REPORT_CHAR, 0, 0); + on_report_cccd_write(p_hids, &char_id, p_evt_write); + } + else if (p_evt_write->handle == p_hids->boot_mouse_inp_rep_handles.value_handle) + { + char_id = make_char_id(BLE_UUID_BOOT_MOUSE_INPUT_REPORT_CHAR, 0, 0); + on_report_value_write(p_hids, p_ble_evt, &char_id); + } + else if (inp_rep_cccd_identify(p_hids, p_evt_write->handle, &char_id)) + { + on_report_cccd_write(p_hids, &char_id, p_evt_write); + } + else if (rep_value_identify(p_hids, p_evt_write->handle, &char_id)) + { + on_report_value_write(p_hids, p_ble_evt, &char_id); + } + else + { + // No implementation needed. + } +} + +/**@brief Read/write authorize request event handler. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_rw_authorize_request(ble_hids_t * p_hids, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_rw_authorize_request_t * evt_rw_auth = &p_ble_evt->evt.gatts_evt.params.authorize_request; + ble_hids_char_id_t char_id; + + if (evt_rw_auth->type != BLE_GATTS_AUTHORIZE_TYPE_READ) + { + // Unexpected operation + return; + } + + if (rep_value_identify(p_hids, evt_rw_auth->request.read.handle, &char_id)) + { + on_report_value_read_auth(p_hids, &char_id, p_ble_evt); + } +} + +void ble_hids_on_ble_evt(ble_hids_t * p_hids, ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_hids, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_hids, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_hids, p_ble_evt); + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + on_rw_authorize_request(p_hids, p_ble_evt); + break; + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for adding Protocol Mode characteristics. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_sec_mode Characteristic security settings. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t protocol_mode_char_add(ble_hids_t * p_hids, + const ble_srv_security_mode_t * p_sec_mode) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t initial_protocol_mode; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.char_props.write_wo_resp = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_PROTOCOL_MODE_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_sec_mode->read_perm; + attr_md.write_perm = p_sec_mode->write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + initial_protocol_mode = DEFAULT_PROTOCOL_MODE; + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof(uint8_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = sizeof(uint8_t); + attr_char_value.p_value = &initial_protocol_mode; + + return sd_ble_gatts_characteristic_add(p_hids->service_handle, + &char_md, + &attr_char_value, + &p_hids->protocol_mode_handles); +} + + +/**@brief Function for adding report characteristics. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_properties Report characteristic properties. + * @param[in] max_len Maximum length of report value. + * @param[in] p_rep_ref Report Reference descriptor. + * @param[in] p_rep_ref_attr_md Characteristic security settings. + * @param[in] is_read_resp Characteristic read authorization. + * @param[out] p_rep_char Handles of new characteristic. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t rep_char_add(ble_hids_t * p_hids, + ble_gatt_char_props_t * p_properties, + uint16_t max_len, + ble_srv_report_ref_t * p_rep_ref, + ble_srv_cccd_security_mode_t * p_rep_ref_attr_md, + bool is_read_resp, + ble_hids_rep_char_t * p_rep_char) +{ + uint32_t err_code; + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t encoded_rep_ref[BLE_SRV_ENCODED_REPORT_REF_LEN]; + + // Add Report characteristic + if (p_properties->notify) + { + memset(&cccd_md, 0, sizeof(cccd_md)); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + cccd_md.write_perm = p_rep_ref_attr_md->cccd_write_perm; + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + } + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props = *p_properties; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = (p_properties->notify) ? &cccd_md : NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_rep_ref_attr_md->read_perm; + attr_md.write_perm = p_rep_ref_attr_md->write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = is_read_resp ? 1 : 0; + attr_md.wr_auth = 0; + attr_md.vlen = 1; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = 0; + attr_char_value.init_offs = 0; + attr_char_value.max_len = max_len; + attr_char_value.p_value = NULL; + + err_code = sd_ble_gatts_characteristic_add(p_hids->service_handle, + &char_md, + &attr_char_value, + &p_rep_char->char_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add Report Reference descriptor + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_REF_DESCR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_rep_ref_attr_md->read_perm; + attr_md.write_perm = p_rep_ref_attr_md->write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = ble_srv_report_ref_encode(encoded_rep_ref, p_rep_ref); + attr_char_value.init_offs = 0; + attr_char_value.max_len = attr_char_value.init_len; + attr_char_value.p_value = encoded_rep_ref; + + return sd_ble_gatts_descriptor_add(p_rep_char->char_handles.value_handle, + &attr_char_value, + &p_rep_char->ref_handle); +} + + +/**@brief Function for adding Report Map characteristics. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_hids_init Service initialization structure. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t rep_map_char_add(ble_hids_t * p_hids, const ble_hids_init_t * p_hids_init) +{ + uint32_t err_code; + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + // Add Report Map characteristic + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_MAP_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_hids_init->rep_map.security_mode.read_perm; + attr_md.write_perm = p_hids_init->rep_map.security_mode.write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 1; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = p_hids_init->rep_map.data_len; + attr_char_value.init_offs = 0; + attr_char_value.max_len = p_hids_init->rep_map.data_len; + attr_char_value.p_value = p_hids_init->rep_map.p_data; + + err_code = sd_ble_gatts_characteristic_add(p_hids->service_handle, + &char_md, + &attr_char_value, + &p_hids->rep_map_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (p_hids_init->rep_map.ext_rep_ref_num != 0 && p_hids_init->rep_map.p_ext_rep_ref == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + for (int i = 0; i < p_hids_init->rep_map.ext_rep_ref_num; ++i) + { + uint8_t encoded_rep_ref[sizeof(ble_uuid128_t)]; + uint8_t encoded_rep_ref_len; + + // Add External Report Reference descriptor + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_EXTERNAL_REPORT_REF_DESCR); + + memset(&attr_md, 0, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + err_code = sd_ble_uuid_encode(&p_hids_init->rep_map.p_ext_rep_ref[i], + &encoded_rep_ref_len, + encoded_rep_ref); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = encoded_rep_ref_len; + attr_char_value.init_offs = 0; + attr_char_value.max_len = attr_char_value.init_len; + attr_char_value.p_value = encoded_rep_ref; + + err_code = sd_ble_gatts_descriptor_add(p_hids->rep_map_handles.value_handle, + &attr_char_value, + &p_hids->rep_map_ext_rep_ref_handle); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +/**@brief Function for adding Input Report characteristics. + * + * @param[in] p_hids HID Service structure. + * @param[in] uuid UUID of report characteristic to be added. + * @param[in] max_data_len Maximum length of report value. + * @param[in] p_sec_mode Characteristic security settings. + * @param[out] p_char_handles Handles of new characteristic. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t boot_inp_rep_char_add(ble_hids_t * p_hids, + uint16_t uuid, + uint16_t max_data_len, + const ble_srv_cccd_security_mode_t * p_sec_mode, + ble_gatts_char_handles_t * p_char_handles) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&cccd_md, 0, sizeof(cccd_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + cccd_md.write_perm = p_sec_mode->cccd_write_perm; + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.char_props.write = (p_sec_mode->write_perm.sm) ? 1 : 0; + char_md.char_props.notify = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, uuid); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_sec_mode->read_perm; + attr_md.write_perm = p_sec_mode->write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = 0; + attr_char_value.init_offs = 0; + attr_char_value.max_len = max_data_len; + attr_char_value.p_value = NULL; + + return sd_ble_gatts_characteristic_add(p_hids->service_handle, + &char_md, + &attr_char_value, + p_char_handles); +} + + +/**@brief Function for adding Boot Keyboard Output Report characteristics. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_hids_init Service initialization structure. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t boot_kb_outp_rep_char_add(ble_hids_t * p_hids, const ble_hids_init_t * p_hids_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.char_props.write = 1; + char_md.char_props.write_wo_resp = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_hids_init->security_mode_boot_kb_outp_rep.read_perm; + attr_md.write_perm = p_hids_init->security_mode_boot_kb_outp_rep.write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = 0; + attr_char_value.init_offs = 0; + attr_char_value.max_len = BOOT_KB_OUTPUT_REPORT_MAX_SIZE; + attr_char_value.p_value = NULL; + + return sd_ble_gatts_characteristic_add(p_hids->service_handle, &char_md, &attr_char_value, + &p_hids->boot_kb_outp_rep_handles); +} + + +/**@brief Function for encoding a HID Information characteristic value. + * + * @param[out] p_encoded_buffer Buffer where the encoded data will be written. + * @param[in] p_hid_information Measurement to be encoded. + * + * @return Size of encoded data. + */ +static uint8_t encode_hid_information(uint8_t * p_encoded_buffer, + const ble_hids_hid_information_t * p_hid_information) +{ + uint8_t len = uint16_encode(p_hid_information->bcd_hid, p_encoded_buffer); + + p_encoded_buffer[len++] = p_hid_information->b_country_code; + p_encoded_buffer[len++] = p_hid_information->flags; + + APP_ERROR_CHECK_BOOL(len == ENCODED_HID_INFORMATION_LEN); + + return len; +} + + +/**@brief Function for adding HID Information characteristics. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_hids_init Service initialization structure. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t hid_information_char_add(ble_hids_t * p_hids, const ble_hids_init_t * p_hids_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t encoded_hid_information[ENCODED_HID_INFORMATION_LEN]; + uint8_t hid_info_len; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HID_INFORMATION_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_hids_init->hid_information.security_mode.read_perm; + attr_md.write_perm = p_hids_init->hid_information.security_mode.write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + hid_info_len = encode_hid_information(encoded_hid_information, &p_hids_init->hid_information); + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = hid_info_len; + attr_char_value.init_offs = 0; + attr_char_value.max_len = attr_char_value.init_len; + attr_char_value.p_value = encoded_hid_information; + + return sd_ble_gatts_characteristic_add(p_hids->service_handle, &char_md, + &attr_char_value, + &p_hids->hid_information_handles); +} + + +/**@brief Function for adding HID Control Point characteristics. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_sec_mode Characteristic security settings. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t hid_control_point_char_add(ble_hids_t * p_hids, + const ble_srv_security_mode_t * p_sec_mode) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t initial_hid_control_point; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.write_wo_resp = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HID_CONTROL_POINT_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_sec_mode->read_perm; + attr_md.write_perm = p_sec_mode->write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + initial_hid_control_point = INITIAL_VALUE_HID_CONTROL_POINT; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof(uint8_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = sizeof(uint8_t); + attr_char_value.p_value = &initial_hid_control_point; + + return sd_ble_gatts_characteristic_add(p_hids->service_handle, &char_md, + &attr_char_value, + &p_hids->hid_control_point_handles); +} + + +/**@brief Function for adding input report characteristics. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_hids_init Service initialization structure. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t inp_rep_characteristics_add(ble_hids_t * p_hids, + const ble_hids_init_t * p_hids_init) +{ + if ((p_hids_init->inp_rep_count != 0) && (p_hids_init->p_inp_rep_array != NULL)) + { + uint8_t i; + + for (i = 0; i < p_hids_init->inp_rep_count; i++) + { + uint32_t err_code; + ble_hids_inp_rep_init_t * p_rep_init = &p_hids_init->p_inp_rep_array[i]; + ble_gatt_char_props_t properties; + + memset(&properties, 0, sizeof(properties)); + + properties.read = true; + properties.write = p_rep_init->security_mode.write_perm.sm ? 1 : 0; + properties.notify = true; + + err_code = rep_char_add(p_hids, + &properties, + p_rep_init->max_len, + &p_rep_init->rep_ref, + &p_rep_init->security_mode, + p_rep_init->read_resp, + &p_hids->inp_rep_array[i]); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + } + + return NRF_SUCCESS; +} + + +/**@brief Function for adding output report characteristics. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_hids_init Service initialization structure. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t outp_rep_characteristics_add(ble_hids_t * p_hids, + const ble_hids_init_t * p_hids_init) +{ + if ((p_hids_init->outp_rep_count != 0) && (p_hids_init->p_outp_rep_array != NULL)) + { + uint8_t i; + + for (i = 0; i < p_hids_init->outp_rep_count; i++) + { + uint32_t err_code; + ble_hids_outp_rep_init_t * p_rep_init = &p_hids_init->p_outp_rep_array[i]; + ble_gatt_char_props_t properties; + + memset(&properties, 0, sizeof(properties)); + + properties.read = true; + properties.write = true; + properties.write_wo_resp = true; + + err_code = rep_char_add(p_hids, + &properties, + p_rep_init->max_len, + &p_rep_init->rep_ref, + &p_rep_init->security_mode, + p_rep_init->read_resp, + &p_hids->outp_rep_array[i]); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + } + + return NRF_SUCCESS; +} + + +/**@brief Function for adding feature report characteristics. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_hids_init Service initialization structure. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t feature_rep_characteristics_add(ble_hids_t * p_hids, + const ble_hids_init_t * p_hids_init) +{ + if ((p_hids_init->feature_rep_count != 0) && (p_hids_init->p_feature_rep_array != NULL)) + { + uint8_t i; + + for (i = 0; i < p_hids_init->feature_rep_count; i++) + { + uint32_t err_code; + ble_hids_feature_rep_init_t * p_rep_init = &p_hids_init->p_feature_rep_array[i]; + ble_gatt_char_props_t properties; + + memset(&properties, 0, sizeof(properties)); + + properties.read = true; + properties.write = true; + + err_code = rep_char_add(p_hids, + &properties, + p_rep_init->max_len, + &p_rep_init->rep_ref, + &p_rep_init->security_mode, + p_rep_init->read_resp, + &p_hids->feature_rep_array[i]); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + } + + return NRF_SUCCESS; +} + + +/**@brief Function for adding included services. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_hids_init Service initialization structure. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t includes_add(ble_hids_t * p_hids, const ble_hids_init_t * p_hids_init) +{ + uint32_t err_code; + uint8_t i; + uint16_t unused_include_handle; + + for (i = 0; i < p_hids_init->included_services_count; i++) + { + err_code = sd_ble_gatts_include_add(p_hids->service_handle, + p_hids_init->p_included_services_array[i], + &unused_include_handle); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +uint32_t ble_hids_init(ble_hids_t * p_hids, const ble_hids_init_t * p_hids_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + + if ((p_hids_init->inp_rep_count > BLE_HIDS_MAX_INPUT_REP) || + (p_hids_init->outp_rep_count > BLE_HIDS_MAX_OUTPUT_REP) || + (p_hids_init->feature_rep_count > BLE_HIDS_MAX_FEATURE_REP) + ) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Initialize service structure. + p_hids->evt_handler = p_hids_init->evt_handler; + p_hids->error_handler = p_hids_init->error_handler; + p_hids->inp_rep_count = p_hids_init->inp_rep_count; + p_hids->outp_rep_count = p_hids_init->outp_rep_count; + p_hids->feature_rep_count = p_hids_init->feature_rep_count; + p_hids->conn_handle = BLE_CONN_HANDLE_INVALID; + + // Add service. + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HUMAN_INTERFACE_DEVICE_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_hids->service_handle); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add includes. + err_code = includes_add(p_hids, p_hids_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (p_hids_init->is_kb || p_hids_init->is_mouse) + { + // Add Protocol Mode characteristic. + err_code = protocol_mode_char_add(p_hids, &p_hids_init->security_mode_protocol); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + // Add Input Report characteristics (if any). + err_code = inp_rep_characteristics_add(p_hids, p_hids_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add Output Report characteristics (if any). + err_code = outp_rep_characteristics_add(p_hids, p_hids_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add Feature Report characteristic (if any). + err_code = feature_rep_characteristics_add(p_hids, p_hids_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add Report Map characteristic. + err_code = rep_map_char_add(p_hids, p_hids_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (p_hids_init->is_kb) + { + // Add Boot Keyboard Input Report characteristic. + err_code = boot_inp_rep_char_add(p_hids, + BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR, + BOOT_KB_INPUT_REPORT_MAX_SIZE, + &p_hids_init->security_mode_boot_kb_inp_rep, + &p_hids->boot_kb_inp_rep_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add Boot Keyboard Output Report characteristic. + err_code = boot_kb_outp_rep_char_add(p_hids, p_hids_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + if (p_hids_init->is_mouse) + { + // Add Boot Mouse Input Report characteristic. + err_code = boot_inp_rep_char_add(p_hids, + BLE_UUID_BOOT_MOUSE_INPUT_REPORT_CHAR, + BOOT_MOUSE_INPUT_REPORT_MAX_SIZE, + &p_hids_init->security_mode_boot_mouse_inp_rep, + &p_hids->boot_mouse_inp_rep_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + // Add HID Information characteristic. + err_code = hid_information_char_add(p_hids, p_hids_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add HID Control Point characteristic. + err_code = hid_control_point_char_add(p_hids, &p_hids_init->security_mode_ctrl_point); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + return NRF_SUCCESS; +} + + +uint32_t ble_hids_inp_rep_send(ble_hids_t * p_hids, + uint8_t rep_index, + uint16_t len, + uint8_t * p_data) +{ + uint32_t err_code; + + if (rep_index < p_hids->inp_rep_count) + { + ble_hids_rep_char_t * p_rep_char = &p_hids->inp_rep_array[rep_index]; + + if (p_hids->conn_handle != BLE_CONN_HANDLE_INVALID) + { + ble_gatts_hvx_params_t hvx_params; + uint16_t hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_rep_char->char_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = p_data; + + err_code = sd_ble_gatts_hvx(p_hids->conn_handle, &hvx_params); + if ((err_code == NRF_SUCCESS) && (hvx_len != len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + } + else + { + err_code = NRF_ERROR_INVALID_PARAM; + } + + return err_code; +} + + +uint32_t ble_hids_boot_kb_inp_rep_send(ble_hids_t * p_hids, uint16_t len, uint8_t * p_data) +{ + uint32_t err_code; + + if (p_hids->conn_handle != BLE_CONN_HANDLE_INVALID) + { + ble_gatts_hvx_params_t hvx_params; + uint16_t hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_hids->boot_kb_inp_rep_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = p_data; + + err_code = sd_ble_gatts_hvx(p_hids->conn_handle, &hvx_params); + if ((err_code == NRF_SUCCESS) && (hvx_len != len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + + return err_code; +} + + +uint32_t ble_hids_boot_mouse_inp_rep_send(ble_hids_t * p_hids, + uint8_t buttons, + int8_t x_delta, + int8_t y_delta, + uint16_t optional_data_len, + uint8_t * p_optional_data) +{ + uint32_t err_code; + + if (p_hids->conn_handle != BLE_CONN_HANDLE_INVALID) + { + uint16_t hvx_len = BOOT_MOUSE_INPUT_REPORT_MIN_SIZE + optional_data_len; + + if (hvx_len <= BOOT_MOUSE_INPUT_REPORT_MAX_SIZE) + { + uint8_t buffer[BOOT_MOUSE_INPUT_REPORT_MAX_SIZE]; + ble_gatts_hvx_params_t hvx_params; + + APP_ERROR_CHECK_BOOL(BOOT_MOUSE_INPUT_REPORT_MIN_SIZE == 3); + + // Build buffer + buffer[0] = buttons; + buffer[1] = (uint8_t)x_delta; + buffer[2] = (uint8_t)y_delta; + + if (optional_data_len > 0) + { + memcpy(&buffer[3], p_optional_data, optional_data_len); + } + + // Pass buffer to stack + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_hids->boot_mouse_inp_rep_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = buffer; + + err_code = sd_ble_gatts_hvx(p_hids->conn_handle, &hvx_params); + if ((err_code == NRF_SUCCESS) && + (hvx_len != BOOT_MOUSE_INPUT_REPORT_MIN_SIZE + optional_data_len) + ) + { + err_code = NRF_ERROR_DATA_SIZE; + } + } + else + { + err_code = NRF_ERROR_DATA_SIZE; + } + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + + return err_code; +} + + +uint32_t ble_hids_outp_rep_get(ble_hids_t * p_hids, + uint8_t rep_index, + uint16_t len, + uint8_t offset, + uint8_t * p_outp_rep) +{ + ble_gatts_value_t gatts_value; + + // Initialize value struct. + memset(&gatts_value, 0, sizeof(gatts_value)); + + gatts_value.len = len; + gatts_value.offset = offset; + gatts_value.p_value = p_outp_rep; + + return sd_ble_gatts_value_get(p_hids->conn_handle, + p_hids->outp_rep_array[rep_index].char_handles.value_handle, + &gatts_value); +} + +/** + @} +*/ +#endif // NRF_MODULE_ENABLED(BLE_HIDS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hids/ble_hids.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hids/ble_hids.h new file mode 100644 index 0000000000000000000000000000000000000000..233b48c9f55308a2e33f53d98f5913d29496e7ea --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hids/ble_hids.h @@ -0,0 +1,350 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_hids Human Interface Device Service + * @{ + * @ingroup ble_sdk_srv + * @brief Human Interface Device Service module. + * + * @details This module implements the Human Interface Device Service with the corresponding set of + * characteristics. During initialization it adds the Human Interface Device Service and + * a set of characteristics as per the Human Interface Device Service specification and + * the user requirements to the BLE stack database. + * + * If enabled, notification of Input Report characteristics is performed when the + * application calls the corresponding ble_hids_xx_input_report_send() function. + * + * If an event handler is supplied by the application, the Human Interface Device Service + * will generate Human Interface Device Service events to the application. + * + * @note The application must propagate BLE stack events to the Human Interface Device Service + * module by calling ble_hids_on_ble_evt() from the @ref softdevice_handler callback. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#ifndef BLE_HIDS_H__ +#define BLE_HIDS_H__ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @name Report Type values + * @anchor BLE_HIDS_REPORT_TYPE @{ + */ +// Report Type values +#define BLE_HIDS_REP_TYPE_INPUT 1 +#define BLE_HIDS_REP_TYPE_OUTPUT 2 +#define BLE_HIDS_REP_TYPE_FEATURE 3 +/** @} */ + +// Maximum number of the various Report Types +#define BLE_HIDS_MAX_INPUT_REP 10 +#define BLE_HIDS_MAX_OUTPUT_REP 10 +#define BLE_HIDS_MAX_FEATURE_REP 10 + +// Information Flags +#define HID_INFO_FLAG_REMOTE_WAKE_MSK 0x01 +#define HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK 0x02 + +/**@brief HID Service characteristic id. */ +typedef struct +{ + uint16_t uuid; /**< UUID of characteristic. */ + uint8_t rep_type; /**< Type of report (only used for BLE_UUID_REPORT_CHAR, see @ref BLE_HIDS_REPORT_TYPE). */ + uint8_t rep_index; /**< Index of the characteristic (only used for BLE_UUID_REPORT_CHAR). */ +} ble_hids_char_id_t; + +/**@brief HID Service event type. */ +typedef enum +{ + BLE_HIDS_EVT_HOST_SUSP, /**< Suspend command received. */ + BLE_HIDS_EVT_HOST_EXIT_SUSP, /**< Exit suspend command received. */ + BLE_HIDS_EVT_NOTIF_ENABLED, /**< Notification enabled event. */ + BLE_HIDS_EVT_NOTIF_DISABLED, /**< Notification disabled event. */ + BLE_HIDS_EVT_REP_CHAR_WRITE, /**< A new value has been written to an Report characteristic. */ + BLE_HIDS_EVT_BOOT_MODE_ENTERED, /**< Boot mode entered. */ + BLE_HIDS_EVT_REPORT_MODE_ENTERED, /**< Report mode entered. */ + BLE_HIDS_EVT_REPORT_READ /**< Read with response */ +} ble_hids_evt_type_t; + +/**@brief HID Service event. */ +typedef struct +{ + ble_hids_evt_type_t evt_type; /**< Type of event. */ + union + { + struct + { + ble_hids_char_id_t char_id; /**< Id of characteristic for which notification has been started. */ + } notification; + struct + { + ble_hids_char_id_t char_id; /**< Id of characteristic having been written. */ + uint16_t offset; /**< Offset for the write operation. */ + uint16_t len; /**< Length of the incoming data. */ + uint8_t* data; /**< Incoming data, variable length */ + } char_write; + struct + { + ble_hids_char_id_t char_id; /**< Id of characteristic being read. */ + } char_auth_read; + } params; + ble_evt_t * p_ble_evt; /**< corresponding received ble event, NULL if not relevant */ +} ble_hids_evt_t; + +// Forward declaration of the ble_hids_t type. +typedef struct ble_hids_s ble_hids_t; + +/**@brief HID Service event handler type. */ +typedef void (*ble_hids_evt_handler_t) (ble_hids_t * p_hids, ble_hids_evt_t * p_evt); + +/**@brief HID Information characteristic value. */ +typedef struct +{ + uint16_t bcd_hid; /**< 16-bit unsigned integer representing version number of base USB HID Specification implemented by HID Device */ + uint8_t b_country_code; /**< Identifies which country the hardware is localized for. Most hardware is not localized and thus this value would be zero (0). */ + uint8_t flags; /**< See http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.hid_information.xml */ + ble_srv_security_mode_t security_mode; /**< Security mode for the HID Information characteristic. */ +} ble_hids_hid_information_t; + +/**@brief HID Service Input Report characteristic init structure. This contains all options and + * data needed for initialization of one Input Report characteristic. */ +typedef struct +{ + uint16_t max_len; /**< Maximum length of characteristic value. */ + ble_srv_report_ref_t rep_ref; /**< Value of the Report Reference descriptor. */ + ble_srv_cccd_security_mode_t security_mode; /**< Security mode for the HID Input Report characteristic, including cccd. */ + uint8_t read_resp : 1; /**< Should application generate a response to read requests. */ +} ble_hids_inp_rep_init_t; + +/**@brief HID Service Output Report characteristic init structure. This contains all options and + * data needed for initialization of one Output Report characteristic. */ +typedef struct +{ + uint16_t max_len; /**< Maximum length of characteristic value. */ + ble_srv_report_ref_t rep_ref; /**< Value of the Report Reference descriptor. */ + ble_srv_cccd_security_mode_t security_mode; /**< Security mode for the HID Output Report characteristic, including cccd. */ + uint8_t read_resp : 1; /**< Should application generate a response to read requests. */ +} ble_hids_outp_rep_init_t; + +/**@brief HID Service Feature Report characteristic init structure. This contains all options and + * data needed for initialization of one Feature Report characteristic. */ +typedef struct +{ + uint16_t max_len; /**< Maximum length of characteristic value. */ + ble_srv_report_ref_t rep_ref; /**< Value of the Report Reference descriptor. */ + ble_srv_cccd_security_mode_t security_mode; /**< Security mode for the HID Service Feature Report characteristic, including cccd. */ + uint8_t read_resp : 1; /**< Should application generate a response to read requests. */ +} ble_hids_feature_rep_init_t; + +/**@brief HID Service Report Map characteristic init structure. This contains all options and data + * needed for initialization of the Report Map characteristic. */ +typedef struct +{ + uint8_t * p_data; /**< Report map data. */ + uint16_t data_len; /**< Length of report map data. */ + uint8_t ext_rep_ref_num; /**< Number of Optional External Report Reference descriptors. */ + ble_uuid_t * p_ext_rep_ref; /**< Optional External Report Reference descriptor (will be added if != NULL). */ + ble_srv_security_mode_t security_mode; /**< Security mode for the HID Service Report Map characteristic. */ +} ble_hids_rep_map_init_t; + +/**@brief HID Report characteristic structure. */ +typedef struct +{ + ble_gatts_char_handles_t char_handles; /**< Handles related to the Report characteristic. */ + uint16_t ref_handle; /**< Handle of the Report Reference descriptor. */ +} ble_hids_rep_char_t; + +/**@brief HID Service init structure. This contains all options and data needed for initialization + * of the service. */ +typedef struct +{ + ble_hids_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the HID Service. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + bool is_kb; /**< TRUE if device is operating as a keyboard, FALSE if it is not. */ + bool is_mouse; /**< TRUE if device is operating as a mouse, FALSE if it is not. */ + uint8_t inp_rep_count; /**< Number of Input Report characteristics. */ + ble_hids_inp_rep_init_t * p_inp_rep_array; /**< Information about the Input Report characteristics. */ + uint8_t outp_rep_count; /**< Number of Output Report characteristics. */ + ble_hids_outp_rep_init_t * p_outp_rep_array; /**< Information about the Output Report characteristics. */ + uint8_t feature_rep_count; /**< Number of Feature Report characteristics. */ + ble_hids_feature_rep_init_t * p_feature_rep_array; /**< Information about the Feature Report characteristics. */ + ble_hids_rep_map_init_t rep_map; /**< Information nedeed for initialization of the Report Map characteristic. */ + ble_hids_hid_information_t hid_information; /**< Value of the HID Information characteristic. */ + uint8_t included_services_count; /**< Number of services to include in HID service. */ + uint16_t * p_included_services_array; /**< Array of services to include in HID service. */ + ble_srv_security_mode_t security_mode_protocol; /**< Security settings for HID service protocol attribute */ + ble_srv_security_mode_t security_mode_ctrl_point; /**< Security settings for HID service Control Point attribute */ + ble_srv_cccd_security_mode_t security_mode_boot_mouse_inp_rep; /**< Security settings for HID service Mouse input report attribute */ + ble_srv_cccd_security_mode_t security_mode_boot_kb_inp_rep; /**< Security settings for HID service Keyboard input report attribute */ + ble_srv_security_mode_t security_mode_boot_kb_outp_rep; /**< Security settings for HID service Keyboard output report attribute */ +} ble_hids_init_t; + +/**@brief HID Service structure. This contains various status information for the service. */ +struct ble_hids_s +{ + ble_hids_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the HID Service. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + uint16_t service_handle; /**< Handle of HID Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t protocol_mode_handles; /**< Handles related to the Protocol Mode characteristic (will only be created if ble_hids_init_t.is_kb or ble_hids_init_t.is_mouse is set). */ + uint8_t inp_rep_count; /**< Number of Input Report characteristics. */ + ble_hids_rep_char_t inp_rep_array[BLE_HIDS_MAX_INPUT_REP]; /**< Information about the Input Report characteristics. */ + uint8_t outp_rep_count; /**< Number of Output Report characteristics. */ + ble_hids_rep_char_t outp_rep_array[BLE_HIDS_MAX_OUTPUT_REP]; /**< Information about the Output Report characteristics. */ + uint8_t feature_rep_count; /**< Number of Feature Report characteristics. */ + ble_hids_rep_char_t feature_rep_array[BLE_HIDS_MAX_FEATURE_REP]; /**< Information about the Feature Report characteristics. */ + ble_gatts_char_handles_t rep_map_handles; /**< Handles related to the Report Map characteristic. */ + uint16_t rep_map_ext_rep_ref_handle; /**< Handle of the Report Map External Report Reference descriptor. */ + ble_gatts_char_handles_t boot_kb_inp_rep_handles; /**< Handles related to the Boot Keyboard Input Report characteristic (will only be created if ble_hids_init_t.is_kb is set). */ + ble_gatts_char_handles_t boot_kb_outp_rep_handles; /**< Handles related to the Boot Keyboard Output Report characteristic (will only be created if ble_hids_init_t.is_kb is set). */ + ble_gatts_char_handles_t boot_mouse_inp_rep_handles; /**< Handles related to the Boot Mouse Input Report characteristic (will only be created if ble_hids_init_t.is_mouse is set). */ + ble_gatts_char_handles_t hid_information_handles; /**< Handles related to the Report Map characteristic. */ + ble_gatts_char_handles_t hid_control_point_handles; /**< Handles related to the Report Map characteristic. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ +}; + +/**@brief Function for initializing the HID Service. + * + * @param[out] p_hids HID Service structure. This structure will have to be supplied by the + * application. It will be initialized by this function, and will later be + * used to identify this particular service instance. + * @param[in] p_hids_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +uint32_t ble_hids_init(ble_hids_t * p_hids, const ble_hids_init_t * p_hids_init); + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the HID Service. + * + * @param[in] p_hids HID Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_hids_on_ble_evt(ble_hids_t * p_hids, ble_evt_t * p_ble_evt); + +/**@brief Function for sending Input Report. + * + * @details Sends data on an Input Report characteristic. + * + * @param[in] p_hids HID Service structure. + * @param[in] rep_index Index of the characteristic (corresponding to the index in + * ble_hids_t.inp_rep_array as passed to ble_hids_init()). + * @param[in] len Length of data to be sent. + * @param[in] p_data Pointer to data to be sent. + * + * @return NRF_SUCCESS on successful sending of input report, otherwise an error code. + */ +uint32_t ble_hids_inp_rep_send(ble_hids_t * p_hids, + uint8_t rep_index, + uint16_t len, + uint8_t * p_data); + +/**@brief Function for sending Boot Keyboard Input Report. + * + * @details Sends data on an Boot Keyboard Input Report characteristic. + * + * @param[in] p_hids HID Service structure. + * @param[in] len Length of data to be sent. + * @param[in] p_data Pointer to data to be sent. + * + * @return NRF_SUCCESS on successful sending of the report, otherwise an error code. + */ +uint32_t ble_hids_boot_kb_inp_rep_send(ble_hids_t * p_hids, + uint16_t len, + uint8_t * p_data); + +/**@brief Function for sending Boot Mouse Input Report. + * + * @details Sends data on an Boot Mouse Input Report characteristic. + * + * @param[in] p_hids HID Service structure. + * @param[in] buttons State of mouse buttons. + * @param[in] x_delta Horizontal movement. + * @param[in] y_delta Vertical movement. + * @param[in] optional_data_len Length of optional part of Boot Mouse Input Report. + * @param[in] p_optional_data Optional part of Boot Mouse Input Report. + * + * @return NRF_SUCCESS on successful sending of the report, otherwise an error code. + */ +uint32_t ble_hids_boot_mouse_inp_rep_send(ble_hids_t * p_hids, + uint8_t buttons, + int8_t x_delta, + int8_t y_delta, + uint16_t optional_data_len, + uint8_t * p_optional_data); + +/**@brief Function for getting the current value of Output Report from the stack. + * + * @details Fetches the current value of the output report characteristic from the stack. + * + * @param[in] p_hids HID Service structure. + * @param[in] rep_index Index of the characteristic (corresponding to the index in + * ble_hids_t.outp_rep_array as passed to ble_hids_init()). + * @param[in] len Length of output report needed. + * @param[in] offset Offset in bytes to read from. + * @param[out] p_outp_rep Pointer to the output report. + * + * @return NRF_SUCCESS on successful read of the report, otherwise an error code. + */ +uint32_t ble_hids_outp_rep_get(ble_hids_t * p_hids, + uint8_t rep_index, + uint16_t len, + uint8_t offset, + uint8_t * p_outp_rep); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_HIDS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hrs/ble_hrs.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hrs/ble_hrs.c new file mode 100644 index 0000000000000000000000000000000000000000..b02aae93a15490f6800d82d11bfd56f36c9fae0c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hrs/ble_hrs.c @@ -0,0 +1,478 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_HRS) +#include "ble_hrs.h" +#include +#include "ble_l2cap.h" +#include "ble_srv_common.h" + + +#define OPCODE_LENGTH 1 /**< Length of opcode inside Heart Rate Measurement packet. */ +#define HANDLE_LENGTH 2 /**< Length of handle inside Heart Rate Measurement packet. */ +#define MAX_HRM_LEN (NRF_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Heart Rate Measurement. */ + +#define INITIAL_VALUE_HRM 0 /**< Initial Heart Rate Measurement value. */ + +// Heart Rate Measurement flag bits +#define HRM_FLAG_MASK_HR_VALUE_16BIT (0x01 << 0) /**< Heart Rate Value Format bit. */ +#define HRM_FLAG_MASK_SENSOR_CONTACT_DETECTED (0x01 << 1) /**< Sensor Contact Detected bit. */ +#define HRM_FLAG_MASK_SENSOR_CONTACT_SUPPORTED (0x01 << 2) /**< Sensor Contact Supported bit. */ +#define HRM_FLAG_MASK_EXPENDED_ENERGY_INCLUDED (0x01 << 3) /**< Energy Expended Status bit. Feature Not Supported */ +#define HRM_FLAG_MASK_RR_INTERVAL_INCLUDED (0x01 << 4) /**< RR-Interval bit. */ + + +/**@brief Function for handling the Connect event. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_hrs_t * p_hrs, ble_evt_t * p_ble_evt) +{ + p_hrs->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; +} + + +/**@brief Function for handling the Disconnect event. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_hrs_t * p_hrs, ble_evt_t * p_ble_evt) +{ + UNUSED_PARAMETER(p_ble_evt); + p_hrs->conn_handle = BLE_CONN_HANDLE_INVALID; +} + + +/**@brief Function for handling write events to the Heart Rate Measurement characteristic. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_hrm_cccd_write(ble_hrs_t * p_hrs, ble_gatts_evt_write_t * p_evt_write) +{ + if (p_evt_write->len == 2) + { + // CCCD written, update notification state + if (p_hrs->evt_handler != NULL) + { + ble_hrs_evt_t evt; + + if (ble_srv_is_notification_enabled(p_evt_write->data)) + { + evt.evt_type = BLE_HRS_EVT_NOTIFICATION_ENABLED; + } + else + { + evt.evt_type = BLE_HRS_EVT_NOTIFICATION_DISABLED; + } + + p_hrs->evt_handler(p_hrs, &evt); + } + } +} + + +/**@brief Function for handling the Write event. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_hrs_t * p_hrs, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if (p_evt_write->handle == p_hrs->hrm_handles.cccd_handle) + { + on_hrm_cccd_write(p_hrs, p_evt_write); + } +} + + +void ble_hrs_on_ble_evt(ble_hrs_t * p_hrs, ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_hrs, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_hrs, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_hrs, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for encoding a Heart Rate Measurement. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] heart_rate Measurement to be encoded. + * @param[out] p_encoded_buffer Buffer where the encoded data will be written. + * + * @return Size of encoded data. + */ +static uint8_t hrm_encode(ble_hrs_t * p_hrs, uint16_t heart_rate, uint8_t * p_encoded_buffer) +{ + uint8_t flags = 0; + uint8_t len = 1; + int i; + + // Set sensor contact related flags + if (p_hrs->is_sensor_contact_supported) + { + flags |= HRM_FLAG_MASK_SENSOR_CONTACT_SUPPORTED; + } + if (p_hrs->is_sensor_contact_detected) + { + flags |= HRM_FLAG_MASK_SENSOR_CONTACT_DETECTED; + } + + // Encode heart rate measurement + if (heart_rate > 0xff) + { + flags |= HRM_FLAG_MASK_HR_VALUE_16BIT; + len += uint16_encode(heart_rate, &p_encoded_buffer[len]); + } + else + { + p_encoded_buffer[len++] = (uint8_t)heart_rate; + } + + // Encode rr_interval values + if (p_hrs->rr_interval_count > 0) + { + flags |= HRM_FLAG_MASK_RR_INTERVAL_INCLUDED; + } + for (i = 0; i < p_hrs->rr_interval_count; i++) + { + if (len + sizeof(uint16_t) > p_hrs->max_hrm_len) + { + // Not all stored rr_interval values can fit into the encoded hrm, + // move the remaining values to the start of the buffer. + memmove(&p_hrs->rr_interval[0], + &p_hrs->rr_interval[i], + (p_hrs->rr_interval_count - i) * sizeof(uint16_t)); + break; + } + len += uint16_encode(p_hrs->rr_interval[i], &p_encoded_buffer[len]); + } + p_hrs->rr_interval_count -= i; + + // Add flags + p_encoded_buffer[0] = flags; + + return len; +} + + +/**@brief Function for adding the Heart Rate Measurement characteristic. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] p_hrs_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t heart_rate_measurement_char_add(ble_hrs_t * p_hrs, + const ble_hrs_init_t * p_hrs_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t encoded_initial_hrm[MAX_HRM_LEN]; + + memset(&cccd_md, 0, sizeof(cccd_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + cccd_md.write_perm = p_hrs_init->hrs_hrm_attr_md.cccd_write_perm; + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.notify = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HEART_RATE_MEASUREMENT_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_hrs_init->hrs_hrm_attr_md.read_perm; + attr_md.write_perm = p_hrs_init->hrs_hrm_attr_md.write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 1; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = hrm_encode(p_hrs, INITIAL_VALUE_HRM, encoded_initial_hrm); + attr_char_value.init_offs = 0; + attr_char_value.max_len = MAX_HRM_LEN; + attr_char_value.p_value = encoded_initial_hrm; + + return sd_ble_gatts_characteristic_add(p_hrs->service_handle, + &char_md, + &attr_char_value, + &p_hrs->hrm_handles); +} + + +/**@brief Function for adding the Body Sensor Location characteristic. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] p_hrs_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t body_sensor_location_char_add(ble_hrs_t * p_hrs, const ble_hrs_init_t * p_hrs_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BODY_SENSOR_LOCATION_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_hrs_init->hrs_bsl_attr_md.read_perm; + attr_md.write_perm = p_hrs_init->hrs_bsl_attr_md.write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof (uint8_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = sizeof (uint8_t); + attr_char_value.p_value = p_hrs_init->p_body_sensor_location; + + return sd_ble_gatts_characteristic_add(p_hrs->service_handle, + &char_md, + &attr_char_value, + &p_hrs->bsl_handles); +} + + +uint32_t ble_hrs_init(ble_hrs_t * p_hrs, const ble_hrs_init_t * p_hrs_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Initialize service structure + p_hrs->evt_handler = p_hrs_init->evt_handler; + p_hrs->is_sensor_contact_supported = p_hrs_init->is_sensor_contact_supported; + p_hrs->conn_handle = BLE_CONN_HANDLE_INVALID; + p_hrs->is_sensor_contact_detected = false; + p_hrs->rr_interval_count = 0; + p_hrs->max_hrm_len = MAX_HRM_LEN; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HEART_RATE_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_hrs->service_handle); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add heart rate measurement characteristic + err_code = heart_rate_measurement_char_add(p_hrs, p_hrs_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (p_hrs_init->p_body_sensor_location != NULL) + { + // Add body sensor location characteristic + err_code = body_sensor_location_char_add(p_hrs, p_hrs_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +uint32_t ble_hrs_heart_rate_measurement_send(ble_hrs_t * p_hrs, uint16_t heart_rate) +{ + uint32_t err_code; + + // Send value if connected and notifying + if (p_hrs->conn_handle != BLE_CONN_HANDLE_INVALID) + { + uint8_t encoded_hrm[MAX_HRM_LEN]; + uint16_t len; + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + + len = hrm_encode(p_hrs, heart_rate, encoded_hrm); + hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_hrs->hrm_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_hrm; + + err_code = sd_ble_gatts_hvx(p_hrs->conn_handle, &hvx_params); + if ((err_code == NRF_SUCCESS) && (hvx_len != len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + + return err_code; +} + + +void ble_hrs_rr_interval_add(ble_hrs_t * p_hrs, uint16_t rr_interval) +{ + if (p_hrs->rr_interval_count == BLE_HRS_MAX_BUFFERED_RR_INTERVALS) + { + // The rr_interval buffer is full, delete the oldest value + memmove(&p_hrs->rr_interval[0], + &p_hrs->rr_interval[1], + (BLE_HRS_MAX_BUFFERED_RR_INTERVALS - 1) * sizeof(uint16_t)); + p_hrs->rr_interval_count--; + } + + // Add new value + p_hrs->rr_interval[p_hrs->rr_interval_count++] = rr_interval; +} + + +bool ble_hrs_rr_interval_buffer_is_full(ble_hrs_t * p_hrs) +{ + return (p_hrs->rr_interval_count == BLE_HRS_MAX_BUFFERED_RR_INTERVALS); +} + + +uint32_t ble_hrs_sensor_contact_supported_set(ble_hrs_t * p_hrs, bool is_sensor_contact_supported) +{ + // Check if we are connected to peer + if (p_hrs->conn_handle == BLE_CONN_HANDLE_INVALID) + { + p_hrs->is_sensor_contact_supported = is_sensor_contact_supported; + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INVALID_STATE; + } +} + + +void ble_hrs_sensor_contact_detected_update(ble_hrs_t * p_hrs, bool is_sensor_contact_detected) +{ + p_hrs->is_sensor_contact_detected = is_sensor_contact_detected; +} + + +uint32_t ble_hrs_body_sensor_location_set(ble_hrs_t * p_hrs, uint8_t body_sensor_location) +{ + ble_gatts_value_t gatts_value; + + // Initialize value struct. + memset(&gatts_value, 0, sizeof(gatts_value)); + + gatts_value.len = sizeof(uint8_t); + gatts_value.offset = 0; + gatts_value.p_value = &body_sensor_location; + + return sd_ble_gatts_value_set(p_hrs->conn_handle, p_hrs->bsl_handles.value_handle, &gatts_value); +} + + +void ble_hrs_on_gatt_evt(ble_hrs_t * p_hrs, nrf_ble_gatt_evt_t const * p_gatt_evt) +{ + if ( (p_hrs->conn_handle == p_gatt_evt->conn_handle) + && (p_gatt_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)) + { + p_hrs->max_hrm_len = p_gatt_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH; + } +} +#endif // NRF_MODULE_ENABLED(BLE_HRS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hrs/ble_hrs.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hrs/ble_hrs.h new file mode 100644 index 0000000000000000000000000000000000000000..46c9a2b1c1d6a2043e0bbfce228c88b860dfade3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hrs/ble_hrs.h @@ -0,0 +1,241 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_hrs Heart Rate Service + * @{ + * @ingroup ble_sdk_srv + * @brief Heart Rate Service module. + * + * @details This module implements the Heart Rate Service with the Heart Rate Measurement, + * Body Sensor Location and Heart Rate Control Point characteristics. + * During initialization it adds the Heart Rate Service and Heart Rate Measurement + * characteristic to the BLE stack database. Optionally it also adds the + * Body Sensor Location and Heart Rate Control Point characteristics. + * + * If enabled, notification of the Heart Rate Measurement characteristic is performed + * when the application calls ble_hrs_heart_rate_measurement_send(). + * + * The Heart Rate Service also provides a set of functions for manipulating the + * various fields in the Heart Rate Measurement characteristic, as well as setting + * the Body Sensor Location characteristic value. + * + * If an event handler is supplied by the application, the Heart Rate Service will + * generate Heart Rate Service events to the application. + * + * @note The application must propagate BLE stack events to the Heart Rate Service module by calling + * ble_hrs_on_ble_evt() from the @ref softdevice_handler callback. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#ifndef BLE_HRS_H__ +#define BLE_HRS_H__ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "nrf_ble_gatt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Body Sensor Location values +#define BLE_HRS_BODY_SENSOR_LOCATION_OTHER 0 +#define BLE_HRS_BODY_SENSOR_LOCATION_CHEST 1 +#define BLE_HRS_BODY_SENSOR_LOCATION_WRIST 2 +#define BLE_HRS_BODY_SENSOR_LOCATION_FINGER 3 +#define BLE_HRS_BODY_SENSOR_LOCATION_HAND 4 +#define BLE_HRS_BODY_SENSOR_LOCATION_EAR_LOBE 5 +#define BLE_HRS_BODY_SENSOR_LOCATION_FOOT 6 + +#define BLE_HRS_MAX_BUFFERED_RR_INTERVALS 20 /**< Size of RR Interval buffer inside service. */ + +/**@brief Heart Rate Service event type. */ +typedef enum +{ + BLE_HRS_EVT_NOTIFICATION_ENABLED, /**< Heart Rate value notification enabled event. */ + BLE_HRS_EVT_NOTIFICATION_DISABLED /**< Heart Rate value notification disabled event. */ +} ble_hrs_evt_type_t; + +/**@brief Heart Rate Service event. */ +typedef struct +{ + ble_hrs_evt_type_t evt_type; /**< Type of event. */ +} ble_hrs_evt_t; + +// Forward declaration of the ble_hrs_t type. +typedef struct ble_hrs_s ble_hrs_t; + +/**@brief Heart Rate Service event handler type. */ +typedef void (*ble_hrs_evt_handler_t) (ble_hrs_t * p_hrs, ble_hrs_evt_t * p_evt); + +/**@brief Heart Rate Service init structure. This contains all options and data needed for + * initialization of the service. */ +typedef struct +{ + ble_hrs_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Heart Rate Service. */ + bool is_sensor_contact_supported; /**< Determines if sensor contact detection is to be supported. */ + uint8_t * p_body_sensor_location; /**< If not NULL, initial value of the Body Sensor Location characteristic. */ + ble_srv_cccd_security_mode_t hrs_hrm_attr_md; /**< Initial security level for heart rate service measurement attribute */ + ble_srv_security_mode_t hrs_bsl_attr_md; /**< Initial security level for body sensor location attribute */ +} ble_hrs_init_t; + +/**@brief Heart Rate Service structure. This contains various status information for the service. */ +struct ble_hrs_s +{ + ble_hrs_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Heart Rate Service. */ + bool is_expended_energy_supported; /**< TRUE if Expended Energy measurement is supported. */ + bool is_sensor_contact_supported; /**< TRUE if sensor contact detection is supported. */ + uint16_t service_handle; /**< Handle of Heart Rate Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t hrm_handles; /**< Handles related to the Heart Rate Measurement characteristic. */ + ble_gatts_char_handles_t bsl_handles; /**< Handles related to the Body Sensor Location characteristic. */ + ble_gatts_char_handles_t hrcp_handles; /**< Handles related to the Heart Rate Control Point characteristic. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ + bool is_sensor_contact_detected; /**< TRUE if sensor contact has been detected. */ + uint16_t rr_interval[BLE_HRS_MAX_BUFFERED_RR_INTERVALS]; /**< Set of RR Interval measurements since the last Heart Rate Measurement transmission. */ + uint16_t rr_interval_count; /**< Number of RR Interval measurements since the last Heart Rate Measurement transmission. */ + uint8_t max_hrm_len; /**< Current maximum HR measurement length, adjusted according to the current ATT MTU. */ +}; + +/**@brief Function for initializing the Heart Rate Service. + * + * @param[out] p_hrs Heart Rate Service structure. This structure will have to be supplied by + * the application. It will be initialized by this function, and will later + * be used to identify this particular service instance. + * @param[in] p_hrs_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +uint32_t ble_hrs_init(ble_hrs_t * p_hrs, const ble_hrs_init_t * p_hrs_init); + + +/**@brief Function for handling the GATT module's events. + * + * @details Handles all events from the GATT module of interest to the Heart Rate Service. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] p_gatt_evt Event received from the GATT module. + */ +void ble_hrs_on_gatt_evt(ble_hrs_t * p_hrs, const nrf_ble_gatt_evt_t * p_gatt_evt); + + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the Heart Rate Service. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_hrs_on_ble_evt(ble_hrs_t * p_hrs, ble_evt_t * p_ble_evt); + +/**@brief Function for sending heart rate measurement if notification has been enabled. + * + * @details The application calls this function after having performed a heart rate measurement. + * If notification has been enabled, the heart rate measurement data is encoded and sent to + * the client. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] heart_rate New heart rate measurement. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_hrs_heart_rate_measurement_send(ble_hrs_t * p_hrs, uint16_t heart_rate); + +/**@brief Function for adding a RR Interval measurement to the RR Interval buffer. + * + * @details All buffered RR Interval measurements will be included in the next heart rate + * measurement message, up to the maximum number of measurements that will fit into the + * message. If the buffer is full, the oldest measurement in the buffer will be deleted. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] rr_interval New RR Interval measurement (will be buffered until the next + * transmission of Heart Rate Measurement). + */ +void ble_hrs_rr_interval_add(ble_hrs_t * p_hrs, uint16_t rr_interval); + +/**@brief Function for checking if RR Interval buffer is full. + * + * @param[in] p_hrs Heart Rate Service structure. + * + * @return true if RR Interval buffer is full, false otherwise. + */ +bool ble_hrs_rr_interval_buffer_is_full(ble_hrs_t * p_hrs); + +/**@brief Function for setting the state of the Sensor Contact Supported bit. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] is_sensor_contact_supported New state of the Sensor Contact Supported bit. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_hrs_sensor_contact_supported_set(ble_hrs_t * p_hrs, bool is_sensor_contact_supported); + +/**@brief Function for setting the state of the Sensor Contact Detected bit. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] is_sensor_contact_detected TRUE if sensor contact is detected, FALSE otherwise. + */ +void ble_hrs_sensor_contact_detected_update(ble_hrs_t * p_hrs, bool is_sensor_contact_detected); + +/**@brief Function for setting the Body Sensor Location. + * + * @details Sets a new value of the Body Sensor Location characteristic. The new value will be sent + * to the client the next time the client reads the Body Sensor Location characteristic. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] body_sensor_location New Body Sensor Location. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_hrs_body_sensor_location_set(ble_hrs_t * p_hrs, uint8_t body_sensor_location); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_HRS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hrs_c/ble_hrs_c.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hrs_c/ble_hrs_c.c new file mode 100644 index 0000000000000000000000000000000000000000..bf14f48d56c06c5fb92b8accb097be2709ea86f1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hrs_c/ble_hrs_c.c @@ -0,0 +1,382 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@cond To Make Doxygen skip documentation generation for this file. + * @{ + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_HRS_C) +#include "ble_hrs_c.h" +#include "ble_db_discovery.h" +#include "ble_types.h" +#include "ble_srv_common.h" +#include "ble_gattc.h" + +#define NRF_LOG_MODULE_NAME "BLE_HRS_C" +#include "nrf_log.h" + +#define HRM_FLAG_MASK_HR_16BIT (0x01 << 0) /**< Bit mask used to extract the type of heart rate value. This is used to find if the received heart rate is a 16 bit value or an 8 bit value. */ +#define HRM_FLAG_MASK_HR_RR_INT (0x01 << 4) /**< Bit mask used to extract the presence of RR_INTERVALS. This is used to find if the received measurement includes RR_INTERVALS. */ + +#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of continuous zeroes, followed by continuous sequence of ones: 000...111. */ +#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */ + +#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */ +#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */ + +typedef enum +{ + READ_REQ, /**< Type identifying that this tx_message is a read request. */ + WRITE_REQ /**< Type identifying that this tx_message is a write request. */ +} tx_request_t; + +/**@brief Structure for writing a message to the peer, i.e. CCCD. + */ +typedef struct +{ + uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */ + ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */ +} write_params_t; + +/**@brief Structure for holding data to be transmitted to the connected central. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */ + tx_request_t type; /**< Type of this message, i.e. read or write message. */ + union + { + uint16_t read_handle; /**< Read request message. */ + write_params_t write_req; /**< Write request message. */ + } req; +} tx_message_t; + + +static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */ +static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */ +static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */ + + +/**@brief Function for passing any pending request from the buffer to the stack. + */ +static void tx_buffer_process(void) +{ + if (m_tx_index != m_tx_insert_index) + { + uint32_t err_code; + + if (m_tx_buffer[m_tx_index].type == READ_REQ) + { + err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle, + m_tx_buffer[m_tx_index].req.read_handle, + 0); + } + else + { + err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle, + &m_tx_buffer[m_tx_index].req.write_req.gattc_params); + } + if (err_code == NRF_SUCCESS) + { + m_tx_index++; + m_tx_index &= TX_BUFFER_MASK; + } + else + { + NRF_LOG_DEBUG("SD Read/Write API returns error. This message sending will be " + "attempted again..\r\n"); + } + } +} + + +/**@brief Function for handling write response events. + * + * @param[in] p_ble_hrs_c Pointer to the Heart Rate Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_write_rsp(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt) +{ + // Check if the event if on the link for this instance + if (p_ble_hrs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + // Check if there is any message to be sent across to the peer and send it. + tx_buffer_process(); +} + + +/**@brief Function for handling Handle Value Notification received from the SoftDevice. + * + * @details This function will uses the Handle Value Notification received from the SoftDevice + * and checks if it is a notification of the heart rate measurement from the peer. If + * it is, this function will decode the heart rate measurement and send it to the + * application. + * + * @param[in] p_ble_hrs_c Pointer to the Heart Rate Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_hvx(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt) +{ + // Check if the event is on the link for this instance + if (p_ble_hrs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + NRF_LOG_DEBUG("Received HVX on link 0x%x, not associated to this instance, ignore\r\n", + p_ble_evt->evt.gattc_evt.conn_handle); + return; + } + + NRF_LOG_DEBUG("Received HVX on link 0x%x, hrm_handle 0x%x\r\n", + p_ble_evt->evt.gattc_evt.params.hvx.handle, + p_ble_hrs_c->peer_hrs_db.hrm_handle); + + // Check if this is a heart rate notification. + if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_hrs_c->peer_hrs_db.hrm_handle) + { + ble_hrs_c_evt_t ble_hrs_c_evt; + uint32_t index = 0; + + ble_hrs_c_evt.evt_type = BLE_HRS_C_EVT_HRM_NOTIFICATION; + ble_hrs_c_evt.conn_handle = p_ble_hrs_c->conn_handle; + ble_hrs_c_evt.params.hrm.rr_intervals_cnt = 0; + + if (!(p_ble_evt->evt.gattc_evt.params.hvx.data[index++] & HRM_FLAG_MASK_HR_16BIT)) + { + // 8 Bit heart rate value received. + ble_hrs_c_evt.params.hrm.hr_value = p_ble_evt->evt.gattc_evt.params.hvx.data[index++]; //lint !e415 suppress Lint Warning 415: Likely access out of bond + } + else + { + // 16 bit heart rate value received. + ble_hrs_c_evt.params.hrm.hr_value = + uint16_decode(&(p_ble_evt->evt.gattc_evt.params.hvx.data[index])); + index += sizeof(uint16_t); + } + + if ((p_ble_evt->evt.gattc_evt.params.hvx.data[0] & HRM_FLAG_MASK_HR_RR_INT)) + { + uint32_t i; + /*lint --e{415} --e{416} --e{662} --e{661} -save suppress Warning 415: possible access out of bond */ + for (i = 0; i < BLE_HRS_C_RR_INTERVALS_MAX_CNT; i ++) + { + if (index >= p_ble_evt->evt.gattc_evt.params.hvx.len) + { + break; + } + ble_hrs_c_evt.params.hrm.rr_intervals[i] = + uint16_decode(&(p_ble_evt->evt.gattc_evt.params.hvx.data[index])); + index += sizeof(uint16_t); + } + /*lint -restore*/ + ble_hrs_c_evt.params.hrm.rr_intervals_cnt = (uint8_t)i; + } + p_ble_hrs_c->evt_handler(p_ble_hrs_c, &ble_hrs_c_evt); + } +} + + +/**@brief Function for handling Disconnected event received from the SoftDevice. + * + * @details This function check if the disconnect event is happening on the link + * associated with the current instance of the module, if so it will set its + * conn_handle to invalid. + * + * @param[in] p_ble_hrs_c Pointer to the Heart Rate Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_disconnected(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt) +{ + if (p_ble_hrs_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_ble_hrs_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_hrs_c->peer_hrs_db.hrm_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_hrs_c->peer_hrs_db.hrm_handle = BLE_GATT_HANDLE_INVALID; + } +} + + +void ble_hrs_on_db_disc_evt(ble_hrs_c_t * p_ble_hrs_c, const ble_db_discovery_evt_t * p_evt) +{ + // Check if the Heart Rate Service was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && + p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_HEART_RATE_SERVICE && + p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) + { + // Find the CCCD Handle of the Heart Rate Measurement characteristic. + uint32_t i; + + ble_hrs_c_evt_t evt; + + evt.evt_type = BLE_HRS_C_EVT_DISCOVERY_COMPLETE; + evt.conn_handle = p_evt->conn_handle; + + for (i = 0; i < p_evt->params.discovered_db.char_count; i++) + { + if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid == + BLE_UUID_HEART_RATE_MEASUREMENT_CHAR) + { + // Found Heart Rate characteristic. Store CCCD handle and break. + evt.params.peer_db.hrm_cccd_handle = + p_evt->params.discovered_db.charateristics[i].cccd_handle; + evt.params.peer_db.hrm_handle = + p_evt->params.discovered_db.charateristics[i].characteristic.handle_value; + break; + } + } + + NRF_LOG_DEBUG("Heart Rate Service discovered at peer.\r\n"); + //If the instance has been assigned prior to db_discovery, assign the db_handles + if (p_ble_hrs_c->conn_handle != BLE_CONN_HANDLE_INVALID) + { + if ((p_ble_hrs_c->peer_hrs_db.hrm_cccd_handle == BLE_GATT_HANDLE_INVALID)&& + (p_ble_hrs_c->peer_hrs_db.hrm_handle == BLE_GATT_HANDLE_INVALID)) + { + p_ble_hrs_c->peer_hrs_db = evt.params.peer_db; + } + } + + + p_ble_hrs_c->evt_handler(p_ble_hrs_c, &evt); + } +} + + +uint32_t ble_hrs_c_init(ble_hrs_c_t * p_ble_hrs_c, ble_hrs_c_init_t * p_ble_hrs_c_init) +{ + VERIFY_PARAM_NOT_NULL(p_ble_hrs_c); + VERIFY_PARAM_NOT_NULL(p_ble_hrs_c_init); + + ble_uuid_t hrs_uuid; + + hrs_uuid.type = BLE_UUID_TYPE_BLE; + hrs_uuid.uuid = BLE_UUID_HEART_RATE_SERVICE; + + + p_ble_hrs_c->evt_handler = p_ble_hrs_c_init->evt_handler; + p_ble_hrs_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_hrs_c->peer_hrs_db.hrm_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_hrs_c->peer_hrs_db.hrm_handle = BLE_GATT_HANDLE_INVALID; + + return ble_db_discovery_evt_register(&hrs_uuid); +} + + +void ble_hrs_c_on_ble_evt(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt) +{ + if ((p_ble_hrs_c == NULL) || (p_ble_evt == NULL)) + { + return; + } + + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTC_EVT_HVX: + on_hvx(p_ble_hrs_c, p_ble_evt); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + on_write_rsp(p_ble_hrs_c, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_ble_hrs_c, p_ble_evt); + break; + + default: + break; + } +} + + +/**@brief Function for creating a message for writing to the CCCD. + */ +static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable) +{ + NRF_LOG_DEBUG("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d\r\n", + handle_cccd,conn_handle); + + tx_message_t * p_msg; + uint16_t cccd_val = enable ? BLE_GATT_HVX_NOTIFICATION : 0; + + p_msg = &m_tx_buffer[m_tx_insert_index++]; + m_tx_insert_index &= TX_BUFFER_MASK; + + p_msg->req.write_req.gattc_params.handle = handle_cccd; + p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH; + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + p_msg->req.write_req.gattc_params.offset = 0; + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val); + p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val); + p_msg->conn_handle = conn_handle; + p_msg->type = WRITE_REQ; + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +uint32_t ble_hrs_c_hrm_notif_enable(ble_hrs_c_t * p_ble_hrs_c) +{ + VERIFY_PARAM_NOT_NULL(p_ble_hrs_c); + + return cccd_configure(p_ble_hrs_c->conn_handle, + p_ble_hrs_c->peer_hrs_db.hrm_cccd_handle, + true); +} + + +uint32_t ble_hrs_c_handles_assign(ble_hrs_c_t * p_ble_hrs_c, + uint16_t conn_handle, + const hrs_db_t * p_peer_hrs_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ble_hrs_c); + + p_ble_hrs_c->conn_handle = conn_handle; + if (p_peer_hrs_handles != NULL) + { + p_ble_hrs_c->peer_hrs_db = *p_peer_hrs_handles; + } + return NRF_SUCCESS; +} +/** @} + * @endcond + */ +#endif // NRF_MODULE_ENABLED(BLE_HRS_C) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hrs_c/ble_hrs_c.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hrs_c/ble_hrs_c.h new file mode 100644 index 0000000000000000000000000000000000000000..f5faaaec1e7944b55ba09ce95e6276b3cfd4f3a8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hrs_c/ble_hrs_c.h @@ -0,0 +1,267 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ble_hrs_c Heart Rate Service Client + * @{ + * @ingroup ble_sdk_srv + * @brief Heart Rate Service Client module. + * + * @details This module contains the APIs and types exposed by the Heart Rate Service Client + * module. These APIs and types can be used by the application to perform discovery of + * Heart Rate Service at the peer and interact with it. + * + * @warning Currently this module only has support for Heart Rate Measurement characteristic. This + * means that it will be able to enable notification of the characteristic at the peer and + * be able to receive Heart Rate Measurement notifications from the peer. It does not + * support the Body Sensor Location and the Heart Rate Control Point characteristics. + * When a Heart Rate Measurement is received, this module will decode only the + * Heart Rate Measurement Value (both 8 bit and 16 bit) field from it and provide it to + * the application. + * + * @note The application must propagate BLE stack events to this module by calling + * ble_hrs_c_on_ble_evt(). + * + */ + +#ifndef BLE_HRS_C_H__ +#define BLE_HRS_C_H__ + +#include +#include "ble.h" +#include "ble_db_discovery.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Maximum number of RR intervals to be decoded for each HRM notifications (any extra RR intervals will be ignored). + * + * This define should be defined in the sdk_config.h file to override the default. + */ +#ifndef BLE_HRS_C_RR_INTERVALS_MAX_CNT +#define BLE_HRS_C_RR_INTERVALS_MAX_CNT 20 +#endif + + +/** + * @defgroup hrs_c_enums Enumerations + * @{ + */ + +/**@brief HRS Client event type. */ +typedef enum +{ + BLE_HRS_C_EVT_DISCOVERY_COMPLETE = 1, /**< Event indicating that the Heart Rate Service has been discovered at the peer. */ + BLE_HRS_C_EVT_HRM_NOTIFICATION /**< Event indicating that a notification of the Heart Rate Measurement characteristic has been received from the peer. */ +} ble_hrs_c_evt_type_t; + +/** @} */ + +/** + * @defgroup hrs_c_structs Structures + * @{ + */ + +/**@brief Structure containing the heart rate measurement received from the peer. */ +typedef struct +{ + uint16_t hr_value; /**< Heart Rate Value. */ + uint8_t rr_intervals_cnt; /**< Number of RR intervals. */ + uint16_t rr_intervals[BLE_HRS_C_RR_INTERVALS_MAX_CNT]; /**< RR intervals. */ +} ble_hrm_t; + + +/**@brief Structure containing the handles related to the Heart Rate Service found on the peer. */ +typedef struct +{ + uint16_t hrm_cccd_handle; /**< Handle of the CCCD of the Heart Rate Measurement characteristic. */ + uint16_t hrm_handle; /**< Handle of the Heart Rate Measurement characteristic as provided by the SoftDevice. */ +} hrs_db_t; + + +/**@brief Heart Rate Event structure. */ +typedef struct +{ + ble_hrs_c_evt_type_t evt_type; /**< Type of the event. */ + uint16_t conn_handle; /**< Connection handle on which the Heart Rate service was discovered on the peer device..*/ + union + { + hrs_db_t peer_db; /**< Heart Rate related handles found on the peer device.. This will be filled if the evt_type is @ref BLE_HRS_C_EVT_DISCOVERY_COMPLETE.*/ + ble_hrm_t hrm; /**< Heart rate measurement received. This will be filled if the evt_type is @ref BLE_HRS_C_EVT_HRM_NOTIFICATION. */ + } params; +} ble_hrs_c_evt_t; + +/** @} */ + +/** + * @defgroup hrs_c_types Types + * @{ + */ + +// Forward declaration of the ble_bas_t type. +typedef struct ble_hrs_c_s ble_hrs_c_t; + +/**@brief Event handler type. + * + * @details This is the type of the event handler that should be provided by the application + * of this module in order to receive events. + */ +typedef void (* ble_hrs_c_evt_handler_t) (ble_hrs_c_t * p_ble_hrs_c, ble_hrs_c_evt_t * p_evt); + +/** @} */ + +/** + * @addtogroup hrs_c_structs + * @{ + */ + +/**@brief Heart Rate Client structure. + */ +struct ble_hrs_c_s +{ + uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */ + hrs_db_t peer_hrs_db; /**< Handles related to HRS on the peer*/ + ble_hrs_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the heart rate service. */ +}; + +/**@brief Heart Rate Client initialization structure. + */ +typedef struct +{ + ble_hrs_c_evt_handler_t evt_handler; /**< Event handler to be called by the Heart Rate Client module whenever there is an event related to the Heart Rate Service. */ +} ble_hrs_c_init_t; + +/** @} */ + +/** + * @defgroup hrs_c_functions Functions + * @{ + */ + +/**@brief Function for initializing the heart rate client module. + * + * @details This function will register with the DB Discovery module. There it + * registers for the Heart Rate Service. Doing so will make the DB Discovery + * module look for the presence of a Heart Rate Service instance at the peer when a + * discovery is started. + * + * @param[in] p_ble_hrs_c Pointer to the heart rate client structure. + * @param[in] p_ble_hrs_c_init Pointer to the heart rate initialization structure containing the + * initialization information. + * + * @retval NRF_SUCCESS On successful initialization. Otherwise an error code. This function + * propagates the error code returned by the Database Discovery module API + * @ref ble_db_discovery_evt_register. + */ +uint32_t ble_hrs_c_init(ble_hrs_c_t * p_ble_hrs_c, ble_hrs_c_init_t * p_ble_hrs_c_init); + +/**@brief Function for handling BLE events from the SoftDevice. + * + * @details This function will handle the BLE events received from the SoftDevice. If a BLE + * event is relevant to the Heart Rate Client module, then it uses it to update + * interval variables and, if necessary, send events to the application. + * + * @param[in] p_ble_hrs_c Pointer to the heart rate client structure. + * @param[in] p_ble_evt Pointer to the BLE event. + */ +void ble_hrs_c_on_ble_evt(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt); + + +/**@brief Function for requesting the peer to start sending notification of Heart Rate + * Measurement. + * + * @details This function will enable to notification of the Heart Rate Measurement at the peer + * by writing to the CCCD of the Heart Rate Measurement Characteristic. + * + * @param p_ble_hrs_c Pointer to the heart rate client structure. + * + * @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer. + * Otherwise, an error code. This function propagates the error code returned + * by the SoftDevice API @ref sd_ble_gattc_write. + */ +uint32_t ble_hrs_c_hrm_notif_enable(ble_hrs_c_t * p_ble_hrs_c); + + +/**@brief Function for handling events from the database discovery module. + * + * @details Call this function when getting a callback event from the DB discovery modue. + * This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of heart rate service at the peer. If so, it will + * call the application's event handler indicating that the heart rate service has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param[in] p_ble_hrs_c Pointer to the heart rate client structure instance to associate. + * @param[in] p_evt Pointer to the event received from the database discovery module. + * + */ +void ble_hrs_on_db_disc_evt(ble_hrs_c_t * p_ble_hrs_c, const ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for assigning a handles to a this instance of hrs_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to this instance of the module. This makes it + * possible to handle several link and associate each link to a particular + * instance of this module.The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_HRS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ble_hrs_c Pointer to the heart rate client structure instance to associate. + * @param[in] conn_handle Connection handle to associated with the given Heart Rate Client Instance. + * @param[in] p_peer_hrs_handles Attribute handles for the HRS server you want this HRS_C client to + * interact with. + */ +uint32_t ble_hrs_c_handles_assign(ble_hrs_c_t * p_ble_hrs_c, + uint16_t conn_handle, + const hrs_db_t * p_peer_hrs_handles); + +/** @} */ // End tag for Function group. + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_HRS_C_H__ + +/** @} */ // End tag for the file. diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hts/ble_hts.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hts/ble_hts.c new file mode 100644 index 0000000000000000000000000000000000000000..0b7fa532525795df2547bb06fbfbcf9571012ae8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hts/ble_hts.c @@ -0,0 +1,460 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_HTS) +#include "ble_hts.h" +#include +#include "ble_l2cap.h" +#include "ble_srv_common.h" + + +#define OPCODE_LENGTH 1 /**< Length of opcode inside Health Thermometer Measurement packet. */ +#define HANDLE_LENGTH 2 /**< Length of handle inside Health Thermometer Measurement packet. */ +#define MAX_HTM_LEN (BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Health Thermometer Measurement. */ + +// Health Thermometer Measurement flag bits +#define HTS_MEAS_FLAG_TEMP_UNITS_BIT (0x01 << 0) /**< Temperature Units flag. */ +#define HTS_MEAS_FLAG_TIME_STAMP_BIT (0x01 << 1) /**< Time Stamp flag. */ +#define HTS_MEAS_FLAG_TEMP_TYPE_BIT (0x01 << 2) /**< Temperature Type flag. */ + + +/**@brief Function for handling the Connect event. + * + * @param[in] p_hts Health Thermometer Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_hts_t * p_hts, ble_evt_t * p_ble_evt) +{ + p_hts->conn_handle = p_ble_evt->evt.gatts_evt.conn_handle; +} + + +/**@brief Function for handling the Disconnect event. + * + * @param[in] p_hts Health Thermometer Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_hts_t * p_hts, ble_evt_t * p_ble_evt) +{ + UNUSED_PARAMETER(p_ble_evt); + p_hts->conn_handle = BLE_CONN_HANDLE_INVALID; +} + + +/**@brief Function for handling write events to the Blood Pressure Measurement characteristic. + * + * @param[in] p_hts Health Thermometer Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_cccd_write(ble_hts_t * p_hts, ble_gatts_evt_write_t * p_evt_write) +{ + if (p_evt_write->len == 2) + { + // CCCD written, update indication state + if (p_hts->evt_handler != NULL) + { + ble_hts_evt_t evt; + + if (ble_srv_is_indication_enabled(p_evt_write->data)) + { + evt.evt_type = BLE_HTS_EVT_INDICATION_ENABLED; + } + else + { + evt.evt_type = BLE_HTS_EVT_INDICATION_DISABLED; + } + + p_hts->evt_handler(p_hts, &evt); + } + } +} + + +/**@brief Function for handling the Write event. + * + * @param[in] p_hts Health Thermometer Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_hts_t * p_hts, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if (p_evt_write->handle == p_hts->meas_handles.cccd_handle) + { + on_cccd_write(p_hts, p_evt_write); + } +} + + +/**@brief Function for handling the HVC event. + * + * @details Handles HVC events from the BLE stack. + * + * @param[in] p_hts Health Thermometer Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_hvc(ble_hts_t * p_hts, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_hvc_t * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc; + + if (p_hvc->handle == p_hts->meas_handles.value_handle) + { + ble_hts_evt_t evt; + + evt.evt_type = BLE_HTS_EVT_INDICATION_CONFIRMED; + p_hts->evt_handler(p_hts, &evt); + } +} + + +void ble_hts_on_ble_evt(ble_hts_t * p_hts, ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_hts, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_hts, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_hts, p_ble_evt); + break; + + case BLE_GATTS_EVT_HVC: + on_hvc(p_hts, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for encoding a Health Thermometer Measurement. + * + * @param[in] p_hts Health Thermometer Service structure. + * @param[in] p_hts_meas Measurement to be encoded. + * @param[out] p_encoded_buffer Buffer where the encoded data will be written. + * + * @return Size of encoded data. + */ +static uint8_t hts_measurement_encode(ble_hts_t * p_hts, + ble_hts_meas_t * p_hts_meas, + uint8_t * p_encoded_buffer) +{ + uint8_t flags = 0; + uint8_t len = 1; + uint32_t encoded_temp; + + // Flags field + if (p_hts_meas->temp_in_fahr_units) + { + flags |= HTS_MEAS_FLAG_TEMP_UNITS_BIT; + } + if (p_hts_meas->time_stamp_present) + { + flags |= HTS_MEAS_FLAG_TIME_STAMP_BIT; + } + + // Temperature Measurement Value field + if (p_hts_meas->temp_in_fahr_units) + { + flags |= HTS_MEAS_FLAG_TEMP_UNITS_BIT; + + encoded_temp = ((p_hts_meas->temp_in_fahr.exponent << 24) & 0xFF000000) | + ((p_hts_meas->temp_in_fahr.mantissa << 0) & 0x00FFFFFF); + } + else + { + encoded_temp = ((p_hts_meas->temp_in_celcius.exponent << 24) & 0xFF000000) | + ((p_hts_meas->temp_in_celcius.mantissa << 0) & 0x00FFFFFF); + } + len += uint32_encode(encoded_temp, &p_encoded_buffer[len]); + + // Time Stamp field + if (p_hts_meas->time_stamp_present) + { + flags |= HTS_MEAS_FLAG_TIME_STAMP_BIT; + len += ble_date_time_encode(&p_hts_meas->time_stamp, &p_encoded_buffer[len]); + } + + // Temperature Type field + if (p_hts_meas->temp_type_present) + { + flags |= HTS_MEAS_FLAG_TEMP_TYPE_BIT; + p_encoded_buffer[len++] = p_hts_meas->temp_type; + } + + // Flags field + p_encoded_buffer[0] = flags; + + return len; +} + + +/**@brief Function for adding Health Thermometer Measurement characteristics. + * + * @param[in] p_hts Health Thermometer Service structure. + * @param[in] p_hts_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t hts_measurement_char_add(ble_hts_t * p_hts, const ble_hts_init_t * p_hts_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + ble_hts_meas_t initial_htm; + uint8_t encoded_htm[MAX_HTM_LEN]; + + memset(&cccd_md, 0, sizeof(cccd_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + cccd_md.write_perm = p_hts_init->hts_meas_attr_md.cccd_write_perm; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.indicate = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_TEMPERATURE_MEASUREMENT_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.read_perm = p_hts_init->hts_meas_attr_md.read_perm; + attr_md.write_perm = p_hts_init->hts_meas_attr_md.write_perm; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 1; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + memset(&initial_htm, 0, sizeof(initial_htm)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = hts_measurement_encode(p_hts, &initial_htm, encoded_htm); + attr_char_value.init_offs = 0; + attr_char_value.max_len = MAX_HTM_LEN; + attr_char_value.p_value = encoded_htm; + + return sd_ble_gatts_characteristic_add(p_hts->service_handle, + &char_md, + &attr_char_value, + &p_hts->meas_handles); +} + + +/**@brief Function for adding Temperature Type characteristics. + * + * @param[in] p_hts Health Thermometer Service structure. + * @param[in] p_hts_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t hts_temp_type_char_add(ble_hts_t * p_hts, const ble_hts_init_t * p_hts_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t init_value_temp_type; + uint8_t init_value_encoded[1]; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_TEMPERATURE_TYPE_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.read_perm = p_hts_init->hts_temp_type_attr_md.read_perm; + attr_md.write_perm = p_hts_init->hts_temp_type_attr_md.write_perm; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + init_value_temp_type = p_hts_init->temp_type; + init_value_encoded[0] = init_value_temp_type; + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof (uint8_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = sizeof (uint8_t); + attr_char_value.p_value = init_value_encoded; + + return sd_ble_gatts_characteristic_add(p_hts->service_handle, + &char_md, + &attr_char_value, + &p_hts->temp_type_handles); +} + + +uint32_t ble_hts_init(ble_hts_t * p_hts, const ble_hts_init_t * p_hts_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Initialize service structure + p_hts->evt_handler = p_hts_init->evt_handler; + p_hts->conn_handle = BLE_CONN_HANDLE_INVALID; + p_hts->temp_type = p_hts_init->temp_type; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HEALTH_THERMOMETER_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_hts->service_handle); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add measurement characteristic + err_code = hts_measurement_char_add(p_hts, p_hts_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add temperature type characteristic + if (p_hts_init->temp_type_as_characteristic) + { + err_code = hts_temp_type_char_add(p_hts, p_hts_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +uint32_t ble_hts_measurement_send(ble_hts_t * p_hts, ble_hts_meas_t * p_hts_meas) +{ + uint32_t err_code; + + // Send value if connected + if (p_hts->conn_handle != BLE_CONN_HANDLE_INVALID) + { + uint8_t encoded_hts_meas[MAX_HTM_LEN]; + uint16_t len; + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + + len = hts_measurement_encode(p_hts, p_hts_meas, encoded_hts_meas); + hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_hts->meas_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_INDICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_hts_meas; + + err_code = sd_ble_gatts_hvx(p_hts->conn_handle, &hvx_params); + if ((err_code == NRF_SUCCESS) && (hvx_len != len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + + return err_code; +} + + +uint32_t ble_hts_is_indication_enabled(ble_hts_t * p_hts, bool * p_indication_enabled) +{ + uint32_t err_code; + uint8_t cccd_value_buf[BLE_CCCD_VALUE_LEN]; + ble_gatts_value_t gatts_value; + + // Initialize value struct. + memset(&gatts_value, 0, sizeof(gatts_value)); + + gatts_value.len = BLE_CCCD_VALUE_LEN; + gatts_value.offset = 0; + gatts_value.p_value = cccd_value_buf; + + err_code = sd_ble_gatts_value_get(p_hts->conn_handle, + p_hts->meas_handles.cccd_handle, + &gatts_value); + if (err_code == NRF_SUCCESS) + { + *p_indication_enabled = ble_srv_is_indication_enabled(cccd_value_buf); + } + if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) + { + *p_indication_enabled = false; + return NRF_SUCCESS; + } + return err_code; +} +#endif // NRF_MODULE_ENABLED(BLE_HTS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hts/ble_hts.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hts/ble_hts.h new file mode 100644 index 0000000000000000000000000000000000000000..e8322476680c9ad36d363edc6d54c716b052d3a1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_hts/ble_hts.h @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_hts Health Thermometer Service + * @{ + * @ingroup ble_sdk_srv + * @brief Health Thermometer Service module. + * + * @details This module implements the Health Thermometer Service. + * + * If an event handler is supplied by the application, the Health Thermometer + * Service will generate Health Thermometer Service events to the application. + * + * @note The application must propagate BLE stack events to the Health Thermometer Service + * module by calling ble_hts_on_ble_evt() from the @ref softdevice_handler function. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#ifndef BLE_HTS_H__ +#define BLE_HTS_H__ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "ble_date_time.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Temperature Type measurement locations +#define BLE_HTS_TEMP_TYPE_ARMPIT 1 +#define BLE_HTS_TEMP_TYPE_BODY 2 +#define BLE_HTS_TEMP_TYPE_EAR 3 +#define BLE_HTS_TEMP_TYPE_FINGER 4 +#define BLE_HTS_TEMP_TYPE_GI_TRACT 5 +#define BLE_HTS_TEMP_TYPE_MOUTH 6 +#define BLE_HTS_TEMP_TYPE_RECTUM 7 +#define BLE_HTS_TEMP_TYPE_TOE 8 +#define BLE_HTS_TEMP_TYPE_EAR_DRUM 9 + +/**@brief Health Thermometer Service event type. */ +typedef enum +{ + BLE_HTS_EVT_INDICATION_ENABLED, /**< Health Thermometer value indication enabled event. */ + BLE_HTS_EVT_INDICATION_DISABLED, /**< Health Thermometer value indication disabled event. */ + BLE_HTS_EVT_INDICATION_CONFIRMED /**< Confirmation of a temperature measurement indication has been received. */ +} ble_hts_evt_type_t; + +/**@brief Health Thermometer Service event. */ +typedef struct +{ + ble_hts_evt_type_t evt_type; /**< Type of event. */ +} ble_hts_evt_t; + +// Forward declaration of the ble_hts_t type. +typedef struct ble_hts_s ble_hts_t; + +/**@brief Health Thermometer Service event handler type. */ +typedef void (*ble_hts_evt_handler_t) (ble_hts_t * p_hts, ble_hts_evt_t * p_evt); + +/**@brief FLOAT format (IEEE-11073 32-bit FLOAT, defined as a 32-bit value with a 24-bit mantissa + * and an 8-bit exponent. */ +typedef struct +{ + int8_t exponent; /**< Base 10 exponent */ + int32_t mantissa; /**< Mantissa, should be using only 24 bits */ +} ieee_float32_t; + +/**@brief Health Thermometer Service init structure. This contains all options and data + * needed for initialization of the service. */ +typedef struct +{ + ble_hts_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Health Thermometer Service. */ + ble_srv_cccd_security_mode_t hts_meas_attr_md; /**< Initial security level for health thermometer measurement attribute */ + ble_srv_security_mode_t hts_temp_type_attr_md; /**< Initial security level for health thermometer tempearture type attribute */ + uint8_t temp_type_as_characteristic; /**< Set non-zero if temp type given as characteristic */ + uint8_t temp_type; /**< Temperature type if temperature characteristic is used */ +} ble_hts_init_t; + +/**@brief Health Thermometer Service structure. This contains various status information for + * the service. */ +struct ble_hts_s +{ + ble_hts_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Health Thermometer Service. */ + uint16_t service_handle; /**< Handle of Health Thermometer Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t meas_handles; /**< Handles related to the Health Thermometer Measurement characteristic. */ + ble_gatts_char_handles_t temp_type_handles; /**< Handles related to the Health Thermometer Temperature Type characteristic. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ + uint8_t temp_type; /**< Temperature type indicates where the measurement was taken. */ +}; + +/**@brief Health Thermometer Service measurement structure. This contains a Health Thermometer + * measurement. */ +typedef struct ble_hts_meas_s +{ + bool temp_in_fahr_units; /**< True if Temperature is in Fahrenheit units, Celcius otherwise. */ + bool time_stamp_present; /**< True if Time Stamp is present. */ + bool temp_type_present; /**< True if Temperature Type is present. */ + ieee_float32_t temp_in_celcius; /**< Temperature Measurement Value (Celcius). */ + ieee_float32_t temp_in_fahr; /**< Temperature Measurement Value (Fahrenheit). */ + ble_date_time_t time_stamp; /**< Time Stamp. */ + uint8_t temp_type; /**< Temperature Type. */ +} ble_hts_meas_t; + +/**@brief Function for initializing the Health Thermometer Service. + * + * @param[out] p_hts Health Thermometer Service structure. This structure will have to + * be supplied by the application. It will be initialized by this function, + * and will later be used to identify this particular service instance. + * @param[in] p_hts_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +uint32_t ble_hts_init(ble_hts_t * p_hts, const ble_hts_init_t * p_hts_init); + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the Health Thermometer Service. + * + * @param[in] p_hts Health Thermometer Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_hts_on_ble_evt(ble_hts_t * p_hts, ble_evt_t * p_ble_evt); + +/**@brief Function for sending health thermometer measurement if indication has been enabled. + * + * @details The application calls this function after having performed a Health Thermometer + * measurement. If indication has been enabled, the measurement data is encoded and + * sent to the client. + * + * @param[in] p_hts Health Thermometer Service structure. + * @param[in] p_hts_meas Pointer to new health thermometer measurement. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_hts_measurement_send(ble_hts_t * p_hts, ble_hts_meas_t * p_hts_meas); + +/**@brief Function for checking if indication of Temperature Measurement is currently enabled. + * + * @param[in] p_hts Health Thermometer Service structure. + * @param[out] p_indication_enabled TRUE if indication is enabled, FALSE otherwise. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_hts_is_indication_enabled(ble_hts_t * p_hts, bool * p_indication_enabled); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_HTS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ias/ble_ias.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ias/ble_ias.c new file mode 100644 index 0000000000000000000000000000000000000000..e02467e8378b449c6519da84abf82463683427aa --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ias/ble_ias.c @@ -0,0 +1,202 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_IAS) +#include "ble_ias.h" +#include +#include "ble_srv_common.h" + + +#define INITIAL_ALERT_LEVEL BLE_CHAR_ALERT_LEVEL_NO_ALERT + + +/**@brief Function for handling the Connect event. + * + * @param[in] p_ias Immediate Alert Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_ias_t * p_ias, ble_evt_t * p_ble_evt) +{ + p_ias->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; +} + +/**@brief Function for handling the Write event. + * + * @param[in] p_ias Immediate Alert Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_ias_t * p_ias, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if ((p_evt_write->handle == p_ias->alert_level_handles.value_handle) && (p_evt_write->len == 1)) + { + // Alert level written, call application event handler + ble_ias_evt_t evt; + + evt.evt_type = BLE_IAS_EVT_ALERT_LEVEL_UPDATED; + evt.params.alert_level = p_evt_write->data[0]; + + p_ias->evt_handler(p_ias, &evt); + } +} + + +void ble_ias_on_ble_evt(ble_ias_t * p_ias, ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_ias, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_ias, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for adding Alert Level characteristics. + * + * @param[in] p_ias Immediate Alert Service structure. + * @param[in] p_ias_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t alert_level_char_add(ble_ias_t * p_ias) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t initial_alert_level; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.write_wo_resp = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_ALERT_LEVEL_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + initial_alert_level = INITIAL_ALERT_LEVEL; + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof (uint8_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = sizeof (uint8_t); + attr_char_value.p_value = &initial_alert_level; + + return sd_ble_gatts_characteristic_add(p_ias->service_handle, + &char_md, + &attr_char_value, + &p_ias->alert_level_handles); +} + + +uint32_t ble_ias_init(ble_ias_t * p_ias, const ble_ias_init_t * p_ias_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Initialize service structure + if (p_ias_init->evt_handler == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + p_ias->evt_handler = p_ias_init->evt_handler; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_IMMEDIATE_ALERT_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_ias->service_handle); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add alert level characteristic + return alert_level_char_add(p_ias); +} + + +uint32_t ble_ias_alert_level_get(ble_ias_t * p_ias, uint8_t * p_alert_level) +{ + ble_gatts_value_t gatts_value; + + // Initialize value struct. + memset(&gatts_value, 0, sizeof(gatts_value)); + + gatts_value.len = sizeof(uint8_t); + gatts_value.offset = 0; + gatts_value.p_value = p_alert_level; + + return sd_ble_gatts_value_get(p_ias->conn_handle, + p_ias->alert_level_handles.value_handle, + &gatts_value); +} +#endif // NRF_MODULE_ENABLED(BLE_IAS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ias/ble_ias.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ias/ble_ias.h new file mode 100644 index 0000000000000000000000000000000000000000..421055bb2c224ba2b7964f1ca7b83a5776c5c861 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ias/ble_ias.h @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_ias Immediate Alert Service + * @{ + * @ingroup ble_sdk_srv + * @brief Immediate Alert Service module. + * + * @details This module implements the Immediate Alert Service with the Alert Level characteristic. + * During initialization it adds the Immediate Alert Service and Alert Level characteristic + * to the BLE stack database. + * + * The application must supply an event handler for receiving Immediate Alert Service + * events. Using this handler, the service will notify the application when the + * Alert Level characteristic value changes. + * + * The service also provides a function for letting the application poll the current + * value of the Alert Level characteristic. + * + * @note The application must propagate BLE stack events to the Immediate Alert Service + * module by calling ble_ias_on_ble_evt() from the @ref softdevice_handler callback. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. +*/ + +#ifndef BLE_IAS_H__ +#define BLE_IAS_H__ + +#include +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Immediate Alert Service event type. */ +typedef enum +{ + BLE_IAS_EVT_ALERT_LEVEL_UPDATED /**< Alert Level Updated event. */ +} ble_ias_evt_type_t; + +/**@brief Immediate Alert Service event. */ +typedef struct +{ + ble_ias_evt_type_t evt_type; /**< Type of event. */ + union + { + uint8_t alert_level; /**< New Alert Level value. */ + } params; +} ble_ias_evt_t; + +// Forward declaration of the ble_ias_t type. +typedef struct ble_ias_s ble_ias_t; + +/**@brief Immediate Alert Service event handler type. */ +typedef void (*ble_ias_evt_handler_t) (ble_ias_t * p_ias, ble_ias_evt_t * p_evt); + +/**@brief Immediate Alert Service init structure. This contains all options and data needed for + * initialization of the service. */ +typedef struct +{ + ble_ias_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Immediate Alert Service. */ +} ble_ias_init_t; + +/**@brief Immediate Alert Service structure. This contains various status information for the + * service. */ +struct ble_ias_s +{ + ble_ias_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Immediate Alert Service. */ + uint16_t service_handle; /**< Handle of Immediate Alert Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t alert_level_handles; /**< Handles related to the Alert Level characteristic. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ +}; + +/**@brief Function for initializing the Immediate Alert Service. + * + * @param[out] p_ias Immediate Alert Service structure. This structure will have to be + * supplied by the application. It will be initialized by this function, + * and will later be used to identify this particular service instance. + * @param[in] p_ias_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +uint32_t ble_ias_init(ble_ias_t * p_ias, const ble_ias_init_t * p_ias_init); + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the Immediate Alert Service. + * + * @param[in] p_ias Immediate Alert Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_ias_on_ble_evt(ble_ias_t * p_ias, ble_evt_t * p_ble_evt); + +/**@brief Function for getting current value of the Alert Level characteristic. + * + * @param[in] p_ias Immediate Alert Service structure. + * @param[out] p_alert_level Current Alert Level value. + */ +uint32_t ble_ias_alert_level_get(ble_ias_t * p_ias, uint8_t * p_alert_level); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_IAS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ias_c/ble_ias_c.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ias_c/ble_ias_c.c new file mode 100644 index 0000000000000000000000000000000000000000..6ce851b681299d56b42521690a249cbdc70e19aa --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ias_c/ble_ias_c.c @@ -0,0 +1,218 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_IAS_C) +#include "ble_ias_c.h" + +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "ble_gattc.h" +#include "ble_db_discovery.h" + + +void ble_ias_c_on_db_disc_evt(ble_ias_c_t * p_ias_c, const ble_db_discovery_evt_t * p_evt) +{ + ble_ias_c_evt_t evt; + + memset(&evt, 0, sizeof(ble_ias_c_evt_t)); + evt.evt_type = BLE_IAS_C_EVT_DISCOVERY_FAILED; + evt.conn_handle = p_evt->conn_handle; + + const ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics; + + // Check if the Immediate Alert Service was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE + && + p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_IMMEDIATE_ALERT_SERVICE + && + p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) + { + + uint32_t i; + + for (i = 0; i < p_evt->params.discovered_db.char_count; i++) + { + // The Alert Level characteristic in the Immediate Alert Service instance is found + // on peer. Check if it has the correct property 'Write without response'. + switch (p_chars[i].characteristic.uuid.uuid) + { + case BLE_UUID_ALERT_LEVEL_CHAR: + if (p_chars[i].characteristic.char_props.write_wo_resp) + { + // Found Alert Level characteristic inside the Immediate Alert Service. + memcpy(&evt.alert_level, + &p_chars[i].characteristic, + sizeof(ble_gattc_char_t)); + } + break; + + default: + break; + } + } + } + if (evt.alert_level.handle_value != BLE_GATT_HANDLE_INVALID) + { + evt.evt_type = BLE_IAS_C_EVT_DISCOVERY_COMPLETE; + } + + p_ias_c->evt_handler(p_ias_c, &evt); +} + + +uint32_t ble_ias_c_init(ble_ias_c_t * p_ias_c, ble_ias_c_init_t const * p_ias_c_init) +{ + VERIFY_PARAM_NOT_NULL(p_ias_c); + VERIFY_PARAM_NOT_NULL(p_ias_c_init->evt_handler); + VERIFY_PARAM_NOT_NULL(p_ias_c_init); + + p_ias_c->evt_handler = p_ias_c_init->evt_handler; + p_ias_c->error_handler = p_ias_c_init->error_handler; + p_ias_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ias_c->alert_level_char.handle_value = BLE_GATT_HANDLE_INVALID; + + BLE_UUID_BLE_ASSIGN(p_ias_c->alert_level_char.uuid, BLE_UUID_ALERT_LEVEL_CHAR); + BLE_UUID_BLE_ASSIGN(p_ias_c->service_uuid, BLE_UUID_IMMEDIATE_ALERT_SERVICE); + + return ble_db_discovery_evt_register(&p_ias_c->service_uuid); +} + + + +/**@brief Function for handling the Disconnect event. + * + * @param[in] p_ias_c Immediate Alert Service client structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_ias_c_t * p_ias_c, ble_evt_t const * p_ble_evt) +{ + // The following values will be re-initialized when a new connection is made. + p_ias_c->conn_handle = BLE_CONN_HANDLE_INVALID; + + if (ble_ias_c_is_discovered(p_ias_c)) + { + // There was a valid instance of IAS on the peer. Send an event to the + // application, so that it can do any clean up related to this module. + ble_ias_c_evt_t evt; + + evt.evt_type = BLE_IAS_C_EVT_DISCONN_COMPLETE; + + p_ias_c->evt_handler(p_ias_c, &evt); + p_ias_c->alert_level_char.handle_value = BLE_GATT_HANDLE_INVALID; + } +} + + +void ble_ias_c_on_ble_evt(ble_ias_c_t * p_ias_c, ble_evt_t const * p_ble_evt) +{ + uint32_t err_code = NRF_SUCCESS; + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_ias_c, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } + + if (err_code != NRF_SUCCESS && p_ias_c->error_handler != 0) + { + p_ias_c->error_handler(err_code); + } +} + + +/**@brief Function for performing a Write procedure. + * + * @param[in] conn_handle Handle of the connection on which to perform the write operation. + * @param[in] write_handle Handle of the attribute to be written. + * @param[in] length Length of data to be written. + * @param[in] p_value Data to be written. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t write_characteristic_value(uint16_t conn_handle, + uint16_t write_handle, + uint16_t length, + uint8_t * p_value) +{ + ble_gattc_write_params_t write_params; + + memset(&write_params, 0, sizeof(write_params)); + + write_params.handle = write_handle; + write_params.write_op = BLE_GATT_OP_WRITE_CMD; + write_params.offset = 0; + write_params.len = length; + write_params.p_value = p_value; + + return sd_ble_gattc_write(conn_handle, &write_params); +} + + +uint32_t ble_ias_c_send_alert_level(ble_ias_c_t const * p_ias_c, uint8_t alert_level) +{ + if (!ble_ias_c_is_discovered(p_ias_c)) + { + return NRF_ERROR_NOT_FOUND; + } + + return write_characteristic_value(p_ias_c->conn_handle, + p_ias_c->alert_level_char.handle_value, + sizeof(uint8_t), + &alert_level); +} + + +uint32_t ble_ias_c_handles_assign(ble_ias_c_t * p_ias_c, + const uint16_t conn_handle, + const uint16_t alert_level_handle) +{ + VERIFY_PARAM_NOT_NULL(p_ias_c); + + p_ias_c->conn_handle = conn_handle; + p_ias_c->alert_level_char.handle_value = alert_level_handle; + return NRF_SUCCESS; +} +#endif //NRF_MODULE_ENABLED(BLE_IAS_C) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ias_c/ble_ias_c.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ias_c/ble_ias_c.h new file mode 100644 index 0000000000000000000000000000000000000000..27b27afc9d626ca437f3227264d85bd18a83efce --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_ias_c/ble_ias_c.h @@ -0,0 +1,204 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_ias_c Immediate Alert Service Client + * @{ + * @ingroup ble_sdk_srv + * @brief Immediate Alert Service Client module + * + * @details This module implements the Immediate Alert Service client - locator role of the Find Me + * profile. On @ref BLE_GAP_EVT_CONNECTED event, this module starts discovery of the + * Immediate Alert Service with Alert Level characteristic at the peer. This module will + * indicate the application about a successful service & characteristic discovery using + * @ref BLE_IAS_C_EVT_DISCOVERY_COMPLETE event. The application can use @ref + * ble_ias_c_send_alert_level function to signal alerts to the peer. + * + * @note The application must propagate BLE stack events to this module by calling + * ble_ias_c_on_ble_evt() from the @ref softdevice_handler callback function. + */ + +#ifndef BLE_IAS_C_H__ +#define BLE_IAS_C_H__ + +#include +#include "ble_srv_common.h" +#include "ble_gattc.h" +#include "ble.h" +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Forward declaration of the ble_ias_c_t type. +typedef struct ble_ias_c_s ble_ias_c_t; + +/**@brief Immediate Alert Service client event type. */ +typedef enum +{ + BLE_IAS_C_EVT_DISCOVERY_COMPLETE, /**< Event indicating that the Immediate Alert Service is found at the peer. */ + BLE_IAS_C_EVT_DISCOVERY_FAILED, /**< Event indicating that the Immediate Alert Service is not found at the peer. */ + BLE_IAS_C_EVT_DISCONN_COMPLETE /**< Event indicating that the Immediate Alert Service client module has completed the processing of BLE_GAP_EVT_DISCONNECTED event. This event is raised only if a valid instance of IAS was found at the peer during the discovery phase. This event can be used the application to do clean up related to the IAS Client.*/ +} ble_ias_c_evt_type_t; + +/**@brief Immediate Alert Service client event. */ +typedef struct +{ + ble_ias_c_evt_type_t evt_type; /**< Type of event. */ + uint16_t conn_handle; /**< Connection handle on which the IAS service was discovered on the peer device. This will be filled if the evt_type is @ref BLE_IAS_C_EVT_DISCOVERY_COMPLETE.*/ + ble_gattc_char_t alert_level; /**< Info on the discovered Alert Level characteristic discovered. This will be filled if the evt_type is @ref BLE_IAS_C_EVT_DISCOVERY_COMPLETE.*/ +} ble_ias_c_evt_t; + +/**@brief Immediate Alert Service client event handler type. */ +typedef void (*ble_ias_c_evt_handler_t) (ble_ias_c_t * p_ias_c, ble_ias_c_evt_t * p_evt); + +/**@brief IAS Client structure. This contains various status information for the client. */ +struct ble_ias_c_s +{ + ble_ias_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Immediate Alert Service client. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + uint16_t conn_handle; /**< Handle of the current connection. Set with @ref ble_ias_c_handles_assign when connected. */ + ble_uuid_t service_uuid; /**< The GATT Service holding the discovered Immediate Service. */ + ble_gattc_char_t alert_level_char; /**< IAS Alert Level Characteristic. Stores data about the alert characteristic found on the peer. */ +}; + +/**@brief IAS Client init structure. This contains all options and data needed for initialization of + * the client.*/ +typedef struct +{ + ble_ias_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events from the Immediate Alert Service client. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ +} ble_ias_c_init_t; + +/**@brief Function for initializing the Immediate Alert Service client. + * + * @details This call allows the application to initialize the Immediate Alert Service client. + * + * @param[out] p_ias_c Immediate Alert Service client structure. This structure will have to + * be supplied by the application. It will be initialized by this + * function, and will later be used to identify this particular client + * instance. + * @param[in] p_ias_c_init Information needed to initialize the Immediate Alert Service client. + * + * @return NRF_SUCCESS on successful initialization of service. + */ +uint32_t ble_ias_c_init(ble_ias_c_t * p_ias_c, const ble_ias_c_init_t * p_ias_c_init); + +/**@brief Function for sending alert level to the peer. + * + * @details This function allows the application to send an alert to the peer. + * + * @param[in] p_ias_c Immediate Alert Service client structure. + * @param[in] alert_level Required alert level to be sent to the peer. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_ias_c_send_alert_level(const ble_ias_c_t * p_ias_c, uint8_t alert_level); + +/**@brief Function for handling the Application's BLE Stack events for Immediate Alert Service client. + * + * @details Handles all events from the BLE stack of interest to the Immediate Alert Service client. + * + * @param[in] p_ias_c Immediate Alert Service client structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_ias_c_on_ble_evt(ble_ias_c_t * p_ias_c, const ble_evt_t * p_ble_evt); + +/**@brief Function for checking whether the peer's Immediate Alert Service instance and the alert level + * characteristic have been discovered. + * + * @param[in] p_ias_c Immediate Alert Service client structure. + * + * @return TRUE if a handle has been assigned to alert_level_handle, meaning it must have been + * discovered. FALSE if the handle is invalid. + */ +static __INLINE bool ble_ias_c_is_discovered(const ble_ias_c_t * p_ias_c) +{ + return (p_ias_c->alert_level_char.handle_value != BLE_GATT_HANDLE_INVALID); +} + + +/**@brief Function for handling events from the database discovery module. + * + * @details Call this function when getting a callback event from the DB discovery modue. + * This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of heart rate service at the peer. If so, it will + * call the application's event handler indicating that the heart rate service has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param[in] p_ias_c Pointer to the immediate alert client structure instance that will handle + * the discovery. + * @param[in] p_evt Pointer to the event received from the database discovery module. + * + */ +void ble_ias_c_on_db_disc_evt(ble_ias_c_t * p_ias_c, const ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for assigning handles to an instance of ias_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to this instance of the module. This makes it + * possible to handle several links and associate each link to a particular + * instance of this module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_IAS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ias_c Pointer to the IAS client structure instance to associate. + * @param[in] conn_handle Connection handle to associated with the given IAS Instance. + * @param[in] alert_level_handle Attribute handle on the IAS server that you want this IAS_C client to + * interact with. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If a p_ias_c was a NULL pointer. + */ +uint32_t ble_ias_c_handles_assign(ble_ias_c_t * p_ias_c, + uint16_t conn_handle, + uint16_t alert_level_handle); + + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_IAS_C_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lbs/ble_lbs.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lbs/ble_lbs.c new file mode 100644 index 0000000000000000000000000000000000000000..501c19187f00b2bcacf1c7c260f5e3f76b72f133 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lbs/ble_lbs.c @@ -0,0 +1,231 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_LBS) +#include "ble_lbs.h" +#include "ble_srv_common.h" + + +/**@brief Function for handling the Write event. + * + * @param[in] p_lbs LED Button Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_lbs_t * p_lbs, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if ((p_evt_write->handle == p_lbs->led_char_handles.value_handle) && + (p_evt_write->len == 1) && + (p_lbs->led_write_handler != NULL)) + { + p_lbs->led_write_handler(p_ble_evt->evt.gap_evt.conn_handle, p_lbs, p_evt_write->data[0]); + } +} + + +void ble_lbs_on_ble_evt(ble_lbs_t * p_lbs, ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTS_EVT_WRITE: + on_write(p_lbs, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for adding the LED Characteristic. + * + * @param[in] p_lbs LED Button Service structure. + * @param[in] p_lbs_init LED Button Service initialization structure. + * + * @retval NRF_SUCCESS on success, else an error value from the SoftDevice + */ +static uint32_t led_char_add(ble_lbs_t * p_lbs, const ble_lbs_init_t * p_lbs_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.char_props.write = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + ble_uuid.type = p_lbs->uuid_type; + ble_uuid.uuid = LBS_UUID_LED_CHAR; + + memset(&attr_md, 0, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof(uint8_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = sizeof(uint8_t); + attr_char_value.p_value = NULL; + + return sd_ble_gatts_characteristic_add(p_lbs->service_handle, + &char_md, + &attr_char_value, + &p_lbs->led_char_handles); +} + + +/**@brief Function for adding the Button Characteristic. + * + * @param[in] p_lbs LED Button Service structure. + * @param[in] p_lbs_init LED Button Service initialization structure. + * + * @retval NRF_SUCCESS on success, else an error value from the SoftDevice + */ +static uint32_t button_char_add(ble_lbs_t * p_lbs, const ble_lbs_init_t * p_lbs_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&cccd_md, 0, sizeof(cccd_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.char_props.notify = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = NULL; + + ble_uuid.type = p_lbs->uuid_type; + ble_uuid.uuid = LBS_UUID_BUTTON_CHAR; + + memset(&attr_md, 0, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm); + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof(uint8_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = sizeof(uint8_t); + attr_char_value.p_value = NULL; + + return sd_ble_gatts_characteristic_add(p_lbs->service_handle, + &char_md, + &attr_char_value, + &p_lbs->button_char_handles); +} + +uint32_t ble_lbs_init(ble_lbs_t * p_lbs, const ble_lbs_init_t * p_lbs_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Initialize service structure. + p_lbs->led_write_handler = p_lbs_init->led_write_handler; + + // Add service. + ble_uuid128_t base_uuid = {LBS_UUID_BASE}; + err_code = sd_ble_uuid_vs_add(&base_uuid, &p_lbs->uuid_type); + VERIFY_SUCCESS(err_code); + + ble_uuid.type = p_lbs->uuid_type; + ble_uuid.uuid = LBS_UUID_SERVICE; + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_lbs->service_handle); + VERIFY_SUCCESS(err_code); + + // Add characteristics. + err_code = button_char_add(p_lbs, p_lbs_init); + VERIFY_SUCCESS(err_code); + + err_code = led_char_add(p_lbs, p_lbs_init); + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} + +uint32_t ble_lbs_on_button_change(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t button_state) +{ + ble_gatts_hvx_params_t params; + uint16_t len = sizeof(button_state); + + memset(¶ms, 0, sizeof(params)); + params.type = BLE_GATT_HVX_NOTIFICATION; + params.handle = p_lbs->button_char_handles.value_handle; + params.p_data = &button_state; + params.p_len = &len; + + return sd_ble_gatts_hvx(conn_handle, ¶ms); +} +#endif // NRF_MODULE_ENABLED(BLE_LBS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lbs/ble_lbs.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lbs/ble_lbs.h new file mode 100644 index 0000000000000000000000000000000000000000..2d5731bad1b06d76062f477ef0b4b50475547b73 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lbs/ble_lbs.h @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_lbs LED Button Service Server + * @{ + * @ingroup ble_sdk_srv + * + * @brief LED Button Service Server module. + * + * @details This module implements a custom LED Button Service with an LED and Button Characteristics. + * During initialization, the module adds the LED Button Service and Characteristics + * to the BLE stack database. + * + * The application must supply an event handler for receiving LED Button Service + * events. Using this handler, the service notifies the application when the + * LED value changes. + * + * The service also provides a function for letting the application notify + * the state of the Button Characteristic to connected peers. + * + * @note The application must propagate BLE stack events to the LED Button Service + * module by calling ble_lbs_on_ble_evt() from the @ref softdevice_handler callback. +*/ + +#ifndef BLE_LBS_H__ +#define BLE_LBS_H__ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LBS_UUID_BASE {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, \ + 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00} +#define LBS_UUID_SERVICE 0x1523 +#define LBS_UUID_BUTTON_CHAR 0x1524 +#define LBS_UUID_LED_CHAR 0x1525 + +// Forward declaration of the ble_lbs_t type. +typedef struct ble_lbs_s ble_lbs_t; + +typedef void (*ble_lbs_led_write_handler_t) (uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t new_state); + +/** @brief LED Button Service init structure. This structure contains all options and data needed for + * initialization of the service.*/ +typedef struct +{ + ble_lbs_led_write_handler_t led_write_handler; /**< Event handler to be called when the LED Characteristic is written. */ +} ble_lbs_init_t; + +/**@brief LED Button Service structure. This structure contains various status information for the service. */ +struct ble_lbs_s +{ + uint16_t service_handle; /**< Handle of LED Button Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t led_char_handles; /**< Handles related to the LED Characteristic. */ + ble_gatts_char_handles_t button_char_handles; /**< Handles related to the Button Characteristic. */ + uint8_t uuid_type; /**< UUID type for the LED Button Service. */ + ble_lbs_led_write_handler_t led_write_handler; /**< Event handler to be called when the LED Characteristic is written. */ +}; + +/**@brief Function for initializing the LED Button Service. + * + * @param[out] p_lbs LED Button Service structure. This structure must be supplied by + * the application. It is initialized by this function and will later + * be used to identify this particular service instance. + * @param[in] p_lbs_init Information needed to initialize the service. + * + * @retval NRF_SUCCESS If the service was initialized successfully. Otherwise, an error code is returned. + */ +uint32_t ble_lbs_init(ble_lbs_t * p_lbs, const ble_lbs_init_t * p_lbs_init); + +/**@brief Function for handling the application's BLE stack events. + * + * @details This function handles all events from the BLE stack that are of interest to the LED Button Service. + * + * @param[in] p_lbs LED Button Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_lbs_on_ble_evt(ble_lbs_t * p_lbs, ble_evt_t * p_ble_evt); + +/**@brief Function for sending a button state notification. + * + ' @param[in] conn_handle Handle of the peripheral connection to which the button state notification will be sent. + * @param[in] p_lbs LED Button Service structure. + * @param[in] button_state New button state. + * + * @retval NRF_SUCCESS If the notification was sent successfully. Otherwise, an error code is returned. + */ +uint32_t ble_lbs_on_button_change(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t button_state); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_LBS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lbs_c/ble_lbs_c.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lbs_c/ble_lbs_c.c new file mode 100644 index 0000000000000000000000000000000000000000..b2db52032a3abb3738e09d2aa582b5792b5f0307 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lbs_c/ble_lbs_c.c @@ -0,0 +1,392 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_LBS_C) + +#include "ble_lbs_c.h" +#include "ble_db_discovery.h" +#include "ble_types.h" +#include "ble_srv_common.h" +#include "ble_gattc.h" +#define NRF_LOG_MODULE_NAME "BLE_LBS_C" +#include "nrf_log.h" + +#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of continuous zeroes, followed by continuous sequence of ones: 000...111. */ +#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */ + +#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */ +#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */ + +typedef enum +{ + READ_REQ, /**< Type identifying that this tx_message is a read request. */ + WRITE_REQ /**< Type identifying that this tx_message is a write request. */ +} tx_request_t; + +/**@brief Structure for writing a message to the peer, i.e. CCCD. + */ +typedef struct +{ + uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */ + ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */ +} write_params_t; + +/**@brief Structure for holding data to be transmitted to the connected central. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */ + tx_request_t type; /**< Type of this message, i.e. read or write message. */ + union + { + uint16_t read_handle; /**< Read request message. */ + write_params_t write_req; /**< Write request message. */ + } req; +} tx_message_t; + + +static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */ +static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */ +static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */ + + +/**@brief Function for passing any pending request from the buffer to the stack. + */ +static void tx_buffer_process(void) +{ + if (m_tx_index != m_tx_insert_index) + { + uint32_t err_code; + + if (m_tx_buffer[m_tx_index].type == READ_REQ) + { + err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle, + m_tx_buffer[m_tx_index].req.read_handle, + 0); + } + else + { + err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle, + &m_tx_buffer[m_tx_index].req.write_req.gattc_params); + } + if (err_code == NRF_SUCCESS) + { + NRF_LOG_DEBUG("SD Read/Write API returns Success..\r\n"); + m_tx_index++; + m_tx_index &= TX_BUFFER_MASK; + } + else + { + NRF_LOG_DEBUG("SD Read/Write API returns error. This message sending will be " + "attempted again..\r\n"); + } + } +} + + +/**@brief Function for handling write response events. + * + * @param[in] p_ble_lbs_c Pointer to the Led Button Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_write_rsp(ble_lbs_c_t * p_ble_lbs_c, const ble_evt_t * p_ble_evt) +{ + // Check if the event if on the link for this instance + if (p_ble_lbs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + // Check if there is any message to be sent across to the peer and send it. + tx_buffer_process(); +} + + +/**@brief Function for handling Handle Value Notification received from the SoftDevice. + * + * @details This function will uses the Handle Value Notification received from the SoftDevice + * and checks if it is a notification of Button state from the peer. If + * it is, this function will decode the state of the button and send it to the + * application. + * + * @param[in] p_ble_lbs_c Pointer to the Led Button Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_hvx(ble_lbs_c_t * p_ble_lbs_c, const ble_evt_t * p_ble_evt) +{ + // Check if the event is on the link for this instance + if (p_ble_lbs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + // Check if this is a Button notification. + if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_lbs_c->peer_lbs_db.button_handle) + { + if (p_ble_evt->evt.gattc_evt.params.hvx.len == 1) + { + ble_lbs_c_evt_t ble_lbs_c_evt; + + ble_lbs_c_evt.evt_type = BLE_LBS_C_EVT_BUTTON_NOTIFICATION; + ble_lbs_c_evt.conn_handle = p_ble_lbs_c->conn_handle; + ble_lbs_c_evt.params.button.button_state = p_ble_evt->evt.gattc_evt.params.hvx.data[0]; + p_ble_lbs_c->evt_handler(p_ble_lbs_c, &ble_lbs_c_evt); + } + } +} + + +/**@brief Function for handling Disconnected event received from the SoftDevice. + * + * @details This function check if the disconnect event is happening on the link + * associated with the current instance of the module, if so it will set its + * conn_handle to invalid. + * + * @param[in] p_ble_lbs_c Pointer to the Led Button Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_disconnected(ble_lbs_c_t * p_ble_lbs_c, const ble_evt_t * p_ble_evt) +{ + if (p_ble_lbs_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_ble_lbs_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_lbs_c->peer_lbs_db.button_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_lbs_c->peer_lbs_db.button_handle = BLE_GATT_HANDLE_INVALID; + p_ble_lbs_c->peer_lbs_db.led_handle = BLE_GATT_HANDLE_INVALID; + } +} + + +void ble_lbs_on_db_disc_evt(ble_lbs_c_t * p_ble_lbs_c, const ble_db_discovery_evt_t * p_evt) +{ + // Check if the Led Button Service was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && + p_evt->params.discovered_db.srv_uuid.uuid == LBS_UUID_SERVICE && + p_evt->params.discovered_db.srv_uuid.type == p_ble_lbs_c->uuid_type) + { + ble_lbs_c_evt_t evt; + + evt.evt_type = BLE_LBS_C_EVT_DISCOVERY_COMPLETE; + evt.conn_handle = p_evt->conn_handle; + + uint32_t i; + for (i = 0; i < p_evt->params.discovered_db.char_count; i++) + { + const ble_gatt_db_char_t * p_char = &(p_evt->params.discovered_db.charateristics[i]); + switch (p_char->characteristic.uuid.uuid) + { + case LBS_UUID_LED_CHAR: + evt.params.peer_db.led_handle = p_char->characteristic.handle_value; + break; + case LBS_UUID_BUTTON_CHAR: + evt.params.peer_db.button_handle = p_char->characteristic.handle_value; + evt.params.peer_db.button_cccd_handle = p_char->cccd_handle; + break; + + default: + break; + } + } + + NRF_LOG_DEBUG("Led Button Service discovered at peer.\r\n"); + //If the instance has been assigned prior to db_discovery, assign the db_handles + if (p_ble_lbs_c->conn_handle != BLE_CONN_HANDLE_INVALID) + { + if ((p_ble_lbs_c->peer_lbs_db.led_handle == BLE_GATT_HANDLE_INVALID)&& + (p_ble_lbs_c->peer_lbs_db.button_handle == BLE_GATT_HANDLE_INVALID)&& + (p_ble_lbs_c->peer_lbs_db.button_cccd_handle == BLE_GATT_HANDLE_INVALID)) + { + p_ble_lbs_c->peer_lbs_db = evt.params.peer_db; + } + } + + p_ble_lbs_c->evt_handler(p_ble_lbs_c, &evt); + + } +} + + +uint32_t ble_lbs_c_init(ble_lbs_c_t * p_ble_lbs_c, ble_lbs_c_init_t * p_ble_lbs_c_init) +{ + uint32_t err_code; + ble_uuid_t lbs_uuid; + ble_uuid128_t lbs_base_uuid = {LBS_UUID_BASE}; + + VERIFY_PARAM_NOT_NULL(p_ble_lbs_c); + VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init); + VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init->evt_handler); + + p_ble_lbs_c->peer_lbs_db.button_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_lbs_c->peer_lbs_db.button_handle = BLE_GATT_HANDLE_INVALID; + p_ble_lbs_c->peer_lbs_db.led_handle = BLE_GATT_HANDLE_INVALID; + p_ble_lbs_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_lbs_c->evt_handler = p_ble_lbs_c_init->evt_handler; + + err_code = sd_ble_uuid_vs_add(&lbs_base_uuid, &p_ble_lbs_c->uuid_type); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + VERIFY_SUCCESS(err_code); + + lbs_uuid.type = p_ble_lbs_c->uuid_type; + lbs_uuid.uuid = LBS_UUID_SERVICE; + + return ble_db_discovery_evt_register(&lbs_uuid); +} + +void ble_lbs_c_on_ble_evt(ble_lbs_c_t * p_ble_lbs_c, const ble_evt_t * p_ble_evt) +{ + if ((p_ble_lbs_c == NULL) || (p_ble_evt == NULL)) + { + return; + } + + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTC_EVT_HVX: + on_hvx(p_ble_lbs_c, p_ble_evt); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + on_write_rsp(p_ble_lbs_c, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_ble_lbs_c, p_ble_evt); + break; + + default: + break; + } +} + + +/**@brief Function for configuring the CCCD. + * + * @param[in] conn_handle The connection handle on which to configure the CCCD. + * @param[in] handle_cccd The handle of the CCCD to be configured. + * @param[in] enable Whether to enable or disable the CCCD. + * + * @return NRF_SUCCESS if the CCCD configure was successfully sent to the peer. + */ +static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable) +{ + NRF_LOG_DEBUG("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d\r\n", + handle_cccd,conn_handle); + + tx_message_t * p_msg; + uint16_t cccd_val = enable ? BLE_GATT_HVX_NOTIFICATION : 0; + + p_msg = &m_tx_buffer[m_tx_insert_index++]; + m_tx_insert_index &= TX_BUFFER_MASK; + + p_msg->req.write_req.gattc_params.handle = handle_cccd; + p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH; + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + p_msg->req.write_req.gattc_params.offset = 0; + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val); + p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val); + p_msg->conn_handle = conn_handle; + p_msg->type = WRITE_REQ; + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +uint32_t ble_lbs_c_button_notif_enable(ble_lbs_c_t * p_ble_lbs_c) +{ + VERIFY_PARAM_NOT_NULL(p_ble_lbs_c); + + if (p_ble_lbs_c->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + + return cccd_configure(p_ble_lbs_c->conn_handle, + p_ble_lbs_c->peer_lbs_db.button_cccd_handle, + true); +} + + +uint32_t ble_lbs_led_status_send(ble_lbs_c_t * p_ble_lbs_c, uint8_t status) +{ + VERIFY_PARAM_NOT_NULL(p_ble_lbs_c); + + if (p_ble_lbs_c->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + + NRF_LOG_DEBUG("writing LED status 0x%x\r\n", status); + + tx_message_t * p_msg; + + p_msg = &m_tx_buffer[m_tx_insert_index++]; + m_tx_insert_index &= TX_BUFFER_MASK; + + p_msg->req.write_req.gattc_params.handle = p_ble_lbs_c->peer_lbs_db.led_handle; + p_msg->req.write_req.gattc_params.len = sizeof(status); + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + p_msg->req.write_req.gattc_params.offset = 0; + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_CMD; + p_msg->req.write_req.gattc_value[0] = status; + p_msg->conn_handle = p_ble_lbs_c->conn_handle; + p_msg->type = WRITE_REQ; + + tx_buffer_process(); + return NRF_SUCCESS; +} + +uint32_t ble_lbs_c_handles_assign(ble_lbs_c_t * p_ble_lbs_c, + uint16_t conn_handle, + const lbs_db_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ble_lbs_c); + + p_ble_lbs_c->conn_handle = conn_handle; + if (p_peer_handles != NULL) + { + p_ble_lbs_c->peer_lbs_db = *p_peer_handles; + } + return NRF_SUCCESS; +} + +#endif // NRF_MODULE_ENABLED(BLE_LBS_C) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lbs_c/ble_lbs_c.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lbs_c/ble_lbs_c.h new file mode 100644 index 0000000000000000000000000000000000000000..9885e7d4b67181d10aa6d598037fb8c161f20077 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lbs_c/ble_lbs_c.h @@ -0,0 +1,230 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ble_lbs_c LED Button Service Client + * @{ + * @ingroup ble_sdk_srv + * @brief The LED Button Service client can be used to set a LED, and read a button state on a + * LED button service server. + * + * @details This module contains the APIs and types exposed by the LED Button Service Client + * module. These APIs and types can be used by the application to perform discovery of + * LED Button Service at the peer and interact with it. + * + * @note The application must propagate BLE stack events to this module by calling + * ble_lbs_c_on_ble_evt(). + * + */ + +#ifndef BLE_LBS_C_H__ +#define BLE_LBS_C_H__ + +#include +#include "ble.h" +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LBS_UUID_BASE {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, \ + 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00} +#define LBS_UUID_SERVICE 0x1523 +#define LBS_UUID_BUTTON_CHAR 0x1524 +#define LBS_UUID_LED_CHAR 0x1525 + +/**@brief LBS Client event type. */ +typedef enum +{ + BLE_LBS_C_EVT_DISCOVERY_COMPLETE = 1, /**< Event indicating that the LED Button Service has been discovered at the peer. */ + BLE_LBS_C_EVT_BUTTON_NOTIFICATION /**< Event indicating that a notification of the LED Button Button characteristic has been received from the peer. */ +} ble_lbs_c_evt_type_t; + + +/**@brief Structure containing the Button value received from the peer. */ +typedef struct +{ + uint8_t button_state; /**< Button Value. */ +} ble_button_t; + + +/**@brief Structure containing the handles related to the LED Button Service found on the peer. */ +typedef struct +{ + uint16_t button_cccd_handle; /**< Handle of the CCCD of the Button characteristic. */ + uint16_t button_handle; /**< Handle of the Button characteristic as provided by the SoftDevice. */ + uint16_t led_handle; /**< Handle of the LED characteristic as provided by the SoftDevice. */ +} lbs_db_t; + + +/**@brief LED Button Event structure. */ +typedef struct +{ + ble_lbs_c_evt_type_t evt_type; /**< Type of the event. */ + uint16_t conn_handle; /**< Connection handle on which the event occured.*/ + union + { + ble_button_t button; /**< Button Value received. This will be filled if the evt_type is @ref BLE_LBS_C_EVT_BUTTON_NOTIFICATION. */ + lbs_db_t peer_db; /**< LED Button Service related handles found on the peer device. This will be filled if the evt_type is @ref BLE_LBS_C_EVT_DISCOVERY_COMPLETE.*/ + } params; +} ble_lbs_c_evt_t; + + +// Forward declaration of the ble_lbs_c_t type. +typedef struct ble_lbs_c_s ble_lbs_c_t; + +/**@brief Event handler type. + * + * @details This is the type of the event handler that should be provided by the application + * of this module in order to receive events. + */ +typedef void (* ble_lbs_c_evt_handler_t) (ble_lbs_c_t * p_ble_lbs_c, ble_lbs_c_evt_t * p_evt); + + +/**@brief LED Button Client structure. */ +struct ble_lbs_c_s +{ + uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */ + lbs_db_t peer_lbs_db; /**< Handles related to LBS on the peer*/ + ble_lbs_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the LED Button service. */ + uint8_t uuid_type; /**< UUID type. */ +}; + +/**@brief LED Button Client initialization structure. */ +typedef struct +{ + ble_lbs_c_evt_handler_t evt_handler; /**< Event handler to be called by the LED Button Client module whenever there is an event related to the LED Button Service. */ +} ble_lbs_c_init_t; + + +/**@brief Function for initializing the LED Button client module. + * + * @details This function will register with the DB Discovery module. There it registers for the + * LED Button Service. Doing so will make the DB Discovery module look for the presence + * of a LED Button Service instance at the peer when a discovery is started. + * + * @param[in] p_ble_lbs_c Pointer to the LED Button client structure. + * @param[in] p_ble_lbs_c_init Pointer to the LED Button initialization structure containing the + * initialization information. + * + * @retval NRF_SUCCESS On successful initialization. Otherwise an error code. This function + * propagates the error code returned by the Database Discovery module API + * @ref ble_db_discovery_evt_register. + */ +uint32_t ble_lbs_c_init(ble_lbs_c_t * p_ble_lbs_c, ble_lbs_c_init_t * p_ble_lbs_c_init); + +/**@brief Function for handling BLE events from the SoftDevice. + * + * @details This function will handle the BLE events received from the SoftDevice. If a BLE event + * is relevant to the LED Button Client module, then it uses it to update interval + * variables and, if necessary, send events to the application. + * + * @param[in] p_ble_lbs_c Pointer to the LED button client structure. + * @param[in] p_ble_evt Pointer to the BLE event. + */ +void ble_lbs_c_on_ble_evt(ble_lbs_c_t * p_ble_lbs_c, const ble_evt_t * p_ble_evt); + + +/**@brief Function for requesting the peer to start sending notification of the Button + * Characteristic. + * + * @details This function will enable to notification of the Button at the peer + * by writing to the CCCD of the Button Characteristic. + * + * @param[in] p_ble_lbs_c Pointer to the LED Button Client structure. + * + * @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer. + * Otherwise, an error code. This function propagates the error code returned + * by the SoftDevice API @ref sd_ble_gattc_write. + * NRF_ERROR_INVALID_STATE if no connection handle has been assigned (@ref ble_lbs_c_handles_assign) + * NRF_ERROR_NULL if the given parameter is NULL + */ +uint32_t ble_lbs_c_button_notif_enable(ble_lbs_c_t * p_ble_lbs_c); + + +/**@brief Function for handling events from the database discovery module. + * + * @details Call this function when getting a callback event from the DB discovery module. This + * function will handle an event from the database discovery module, and determine if it + * relates to the discovery of LED Button service at the peer. If so, it will call the + * application's event handler indicating that the LED Button service has been discovered + * at the peer. It also populates the event with the service related information before + * providing it to the application. + * + * @param[in] p_ble_lbs_c Pointer to the LED Button client structure. + * @param[in] p_evt Pointer to the event received from the database discovery module. + */ +void ble_lbs_on_db_disc_evt(ble_lbs_c_t * p_ble_lbs_c, const ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for assigning a Handles to this instance of lbs_c. + * + * @details Call this function when a link has been established with a peer to associate this link + * to this instance of the module. This makes it possible to handle several links and + * associate each link to a particular instance of this module. + * + * @param[in] p_ble_lbs_c Pointer to the LED Button client structure instance to associate. + * @param[in] conn_handle Connection handle to associate with the given LED Button Client Instance. + * @param[in] p_peer_handles LED Button Service handles found on the peer (from @ref BLE_LBS_C_EVT_DISCOVERY_COMPLETE event). + * + */ +uint32_t ble_lbs_c_handles_assign(ble_lbs_c_t * p_ble_lbs_c, + uint16_t conn_handle, + const lbs_db_t * p_peer_handles); + + +/**@brief Function for writing the LED status to the connected server. + * + * @param[in] p_ble_lbs_c Pointer to the LED Button client structure. + * @param[in] status LED status to send. + * + * @retval NRF_SUCCESS If the staus was sent successfully. Otherwise, an error code is returned. + */ +uint32_t ble_lbs_led_status_send(ble_lbs_c_t * p_ble_lbs_c, uint8_t status); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_LBS_C_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lls/ble_lls.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lls/ble_lls.c new file mode 100644 index 0000000000000000000000000000000000000000..3306f9ce8879d824ce06c743389b7abb16186f01 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lls/ble_lls.c @@ -0,0 +1,243 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_LLS) +#include "ble_lls.h" +#include +#include "ble_hci.h" +#include "ble_srv_common.h" + + +/**@brief Function for handling the Connect event. + * + * @param[in] p_lls Link Loss Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_lls_t * p_lls, ble_evt_t * p_ble_evt) +{ + // Link reconnected, notify application with a no_alert event + ble_lls_evt_t evt; + + p_lls->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + + evt.evt_type = BLE_LLS_EVT_LINK_LOSS_ALERT; + evt.params.alert_level = BLE_CHAR_ALERT_LEVEL_NO_ALERT; + p_lls->evt_handler(p_lls, &evt); +} + + +/**@brief Function for handling the Disconnect event. + * + * @param[in] p_lls Link Loss Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_lls_t * p_lls, ble_evt_t * p_ble_evt) +{ + uint8_t reason = p_ble_evt->evt.gap_evt.params.disconnected.reason; + + if (reason == BLE_HCI_CONNECTION_TIMEOUT) + { + // Link loss detected, notify application + uint32_t err_code; + ble_lls_evt_t evt; + + evt.evt_type = BLE_LLS_EVT_LINK_LOSS_ALERT; + + err_code = ble_lls_alert_level_get(p_lls, &evt.params.alert_level); + if (err_code == NRF_SUCCESS) + { + p_lls->evt_handler(p_lls, &evt); + } + else + { + if (p_lls->error_handler != NULL) + { + p_lls->error_handler(err_code); + } + } + } +} + + +/**@brief Function for handling the Authentication Status event. + * + * @param[in] p_lls Link Loss Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_auth_status(ble_lls_t * p_lls, ble_evt_t * p_ble_evt) +{ + if (p_ble_evt->evt.gap_evt.params.auth_status.auth_status == BLE_GAP_SEC_STATUS_SUCCESS) + { + ble_lls_evt_t evt; + + evt.evt_type = BLE_LLS_EVT_LINK_LOSS_ALERT; + evt.params.alert_level = BLE_CHAR_ALERT_LEVEL_NO_ALERT; + + p_lls->evt_handler(p_lls, &evt); + } +} + + +void ble_lls_on_ble_evt(ble_lls_t * p_lls, ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_lls, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_lls, p_ble_evt); + break; + + case BLE_GAP_EVT_AUTH_STATUS: + on_auth_status(p_lls, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for adding Alert Level characteristics. + * + * @param[in] p_lls Link Loss Service structure. + * @param[in] p_lls_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t alert_level_char_add(ble_lls_t * p_lls, const ble_lls_init_t * p_lls_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t initial_alert_level; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.char_props.write = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_ALERT_LEVEL_CHAR); + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_lls_init->lls_attr_md.read_perm; + attr_md.write_perm = p_lls_init->lls_attr_md.write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + initial_alert_level = p_lls_init->initial_alert_level; + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof (uint8_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = sizeof (uint8_t); + attr_char_value.p_value = &initial_alert_level; + + return sd_ble_gatts_characteristic_add(p_lls->service_handle, + &char_md, + &attr_char_value, + &p_lls->alert_level_handles); +} + + +uint32_t ble_lls_init(ble_lls_t * p_lls, const ble_lls_init_t * p_lls_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Initialize service structure + if (p_lls_init->evt_handler == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + p_lls->evt_handler = p_lls_init->evt_handler; + p_lls->error_handler = p_lls_init->error_handler; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_LINK_LOSS_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_lls->service_handle); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add alert level characteristic + return alert_level_char_add(p_lls, p_lls_init); +} + + +uint32_t ble_lls_alert_level_get(ble_lls_t * p_lls, uint8_t * p_alert_level) +{ + ble_gatts_value_t gatts_value; + + // Initialize value struct. + memset(&gatts_value, 0, sizeof(gatts_value)); + + gatts_value.len = sizeof(uint8_t); + gatts_value.offset = 0; + gatts_value.p_value = p_alert_level; + + return sd_ble_gatts_value_get(p_lls->conn_handle, + p_lls->alert_level_handles.value_handle, + &gatts_value); +} +#endif // NRF_MODULE_ENABLED(BLE_LLS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lls/ble_lls.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lls/ble_lls.h new file mode 100644 index 0000000000000000000000000000000000000000..bfb042a1d24b5c4b29039e531ae593ad167d4563 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_lls/ble_lls.h @@ -0,0 +1,152 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_lls Link Loss Service + * @{ + * @ingroup ble_sdk_srv + * @brief Link Loss Service module. + * + * @details This module implements the Link Loss Service with the Alert Level characteristic. + * During initialization it adds the Link Loss Service and Alert Level characteristic + * to the BLE stack database. + * + * The application must supply an event handler for receiving Link Loss Service + * events. Using this handler, the service will notify the application when the + * link has been lost, and which Alert Level has been set. + * + * The service also provides a function for letting the application poll the current + * value of the Alert Level characteristic. + * + * @note The application must propagate BLE stack events to the Link Loss Service + * module by calling ble_lls_on_ble_evt() from the @ref softdevice_handler callback. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. +*/ + +#ifndef BLE_LLS_H__ +#define BLE_LLS_H__ + +#include +#include "ble.h" +#include "ble_srv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Link Loss Service event type. */ +typedef enum +{ + BLE_LLS_EVT_LINK_LOSS_ALERT /**< Alert Level Updated event. */ +} ble_lls_evt_type_t; + +/**@brief Link Loss Service event. */ +typedef struct +{ + ble_lls_evt_type_t evt_type; /**< Type of event. */ + union + { + uint8_t alert_level; /**< New Alert Level value. */ + } params; +} ble_lls_evt_t; + +// Forward declaration of the ble_lls_t type. +typedef struct ble_lls_s ble_lls_t; + +/**@brief Link Loss Service event handler type. */ +typedef void (*ble_lls_evt_handler_t) (ble_lls_t * p_lls, ble_lls_evt_t * p_evt); + +/**@brief Link Loss Service init structure. This contains all options and data needed for initialization of the service. */ +typedef struct +{ + ble_lls_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Link Loss Service. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + uint8_t initial_alert_level; /**< Initial value of the Alert Level characteristic. */ + ble_srv_security_mode_t lls_attr_md; /**< Initial Security Setting for Link Loss Service Characteristics. */ +} ble_lls_init_t; + +/**@brief Link Loss Service structure. This contains various status information for the service. */ +struct ble_lls_s +{ + ble_lls_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Link Loss Service. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + uint16_t service_handle; /**< Handle of Link Loss Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t alert_level_handles; /**< Handles related to the Alert Level characteristic. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ +}; + +/**@brief Function for initializing the Link Loss Service. + * + * @param[out] p_lls Link Loss Service structure. This structure will have to be supplied by + * the application. It will be initialized by this function, and will later + * be used to identify this particular service instance. + * @param[in] p_lls_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +uint32_t ble_lls_init(ble_lls_t * p_lls, const ble_lls_init_t * p_lls_init); + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the Link Loss Service. + * + * @param[in] p_lls Link Loss Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_lls_on_ble_evt(ble_lls_t * p_lls, ble_evt_t * p_ble_evt); + +/**@brief Function for getting current value of the Alert Level characteristic. + * + * @param[in] p_lls Link Loss Service structure. + * @param[out] p_alert_level Current Alert Level value. + */ +uint32_t ble_lls_alert_level_get(ble_lls_t * p_lls, uint8_t * p_alert_level); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_LLS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_nus/ble_nus.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_nus/ble_nus.c new file mode 100644 index 0000000000000000000000000000000000000000..9bc85decc0b197d218e01c21b1fa1518c626ae2e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_nus/ble_nus.c @@ -0,0 +1,327 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_NUS) +#include "ble_nus.h" +#include "ble_srv_common.h" +#include "ble.h" + +#define BLE_UUID_NUS_TX_CHARACTERISTIC 0x0003 /**< The UUID of the TX Characteristic. */ +#define BLE_UUID_NUS_RX_CHARACTERISTIC 0x0002 /**< The UUID of the RX Characteristic. */ + +#define BLE_NUS_MAX_RX_CHAR_LEN BLE_NUS_MAX_DATA_LEN /**< Maximum length of the RX Characteristic (in bytes). */ +#define BLE_NUS_MAX_TX_CHAR_LEN BLE_NUS_MAX_DATA_LEN /**< Maximum length of the TX Characteristic (in bytes). */ + +#define NUS_BASE_UUID {{0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}} /**< Used vendor specific UUID. */ + +#include "nrf_log.h" + + +/**@brief Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the S110 SoftDevice. + * + * @param[in] p_nus Nordic UART Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_connect(ble_nus_t * p_nus, ble_evt_t * p_ble_evt) +{ + p_nus->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; +} + + +/**@brief Function for handling the @ref BLE_GAP_EVT_DISCONNECTED event from the S110 SoftDevice. + * + * @param[in] p_nus Nordic UART Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_disconnect(ble_nus_t * p_nus, ble_evt_t * p_ble_evt) +{ + UNUSED_PARAMETER(p_ble_evt); + p_nus->conn_handle = BLE_CONN_HANDLE_INVALID; +} + + +/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the S110 SoftDevice. + * + * @param[in] p_nus Nordic UART Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_write(ble_nus_t * p_nus, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if ( + (p_evt_write->handle == p_nus->tx_handles.cccd_handle) + && + (p_evt_write->len == 2) + ) + { + if (ble_srv_is_notification_enabled(p_evt_write->data)) + { + p_nus->is_notification_enabled = true; + } + else + { + p_nus->is_notification_enabled = false; + } + } + else if ( + (p_evt_write->handle == p_nus->rx_handles.value_handle) + && + (p_nus->data_handler != NULL) + ) + { + p_nus->data_handler(p_nus, p_evt_write->data, p_evt_write->len); + } + else + { + // Do Nothing. This event is not relevant for this service. + } +} + + +/**@brief Function for adding TX characteristic. + * + * @param[in] p_nus Nordic UART Service structure. + * @param[in] p_nus_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t tx_char_add(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init) +{ + /**@snippet [Adding proprietary characteristic to S110 SoftDevice] */ + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&cccd_md, 0, sizeof(cccd_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); + + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.notify = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = NULL; + + ble_uuid.type = p_nus->uuid_type; + ble_uuid.uuid = BLE_UUID_NUS_TX_CHARACTERISTIC; + + memset(&attr_md, 0, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 1; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof(uint8_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = BLE_NUS_MAX_TX_CHAR_LEN; + + return sd_ble_gatts_characteristic_add(p_nus->service_handle, + &char_md, + &attr_char_value, + &p_nus->tx_handles); + /**@snippet [Adding proprietary characteristic to S110 SoftDevice] */ +} + + +/**@brief Function for adding RX characteristic. + * + * @param[in] p_nus Nordic UART Service structure. + * @param[in] p_nus_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t rx_char_add(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.write = 1; + char_md.char_props.write_wo_resp = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + ble_uuid.type = p_nus->uuid_type; + ble_uuid.uuid = BLE_UUID_NUS_RX_CHARACTERISTIC; + + memset(&attr_md, 0, sizeof(attr_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 1; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = 1; + attr_char_value.init_offs = 0; + attr_char_value.max_len = BLE_NUS_MAX_RX_CHAR_LEN; + + return sd_ble_gatts_characteristic_add(p_nus->service_handle, + &char_md, + &attr_char_value, + &p_nus->rx_handles); +} + + +void ble_nus_on_ble_evt(ble_nus_t * p_nus, ble_evt_t * p_ble_evt) +{ + if ((p_nus == NULL) || (p_ble_evt == NULL)) + { + return; + } + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_nus, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_nus, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_nus, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +uint32_t ble_nus_init(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + ble_uuid128_t nus_base_uuid = NUS_BASE_UUID; + + VERIFY_PARAM_NOT_NULL(p_nus); + VERIFY_PARAM_NOT_NULL(p_nus_init); + + // Initialize the service structure. + p_nus->conn_handle = BLE_CONN_HANDLE_INVALID; + p_nus->data_handler = p_nus_init->data_handler; + p_nus->is_notification_enabled = false; + + /**@snippet [Adding proprietary Service to S110 SoftDevice] */ + // Add a custom base UUID. + err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_nus->uuid_type); + VERIFY_SUCCESS(err_code); + + ble_uuid.type = p_nus->uuid_type; + ble_uuid.uuid = BLE_UUID_NUS_SERVICE; + + // Add the service. + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_nus->service_handle); + /**@snippet [Adding proprietary Service to S110 SoftDevice] */ + VERIFY_SUCCESS(err_code); + + // Add the RX Characteristic. + err_code = rx_char_add(p_nus, p_nus_init); + VERIFY_SUCCESS(err_code); + + // Add the TX Characteristic. + err_code = tx_char_add(p_nus, p_nus_init); + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} + + +uint32_t ble_nus_string_send(ble_nus_t * p_nus, uint8_t * p_string, uint16_t length) +{ + ble_gatts_hvx_params_t hvx_params; + + VERIFY_PARAM_NOT_NULL(p_nus); + + if ((p_nus->conn_handle == BLE_CONN_HANDLE_INVALID) || (!p_nus->is_notification_enabled)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (length > BLE_NUS_MAX_DATA_LEN) + { + return NRF_ERROR_INVALID_PARAM; + } + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_nus->tx_handles.value_handle; + hvx_params.p_data = p_string; + hvx_params.p_len = &length; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + + return sd_ble_gatts_hvx(p_nus->conn_handle, &hvx_params); +} + +#endif // NRF_MODULE_ENABLED(BLE_NUS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_nus/ble_nus.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_nus/ble_nus.h new file mode 100644 index 0000000000000000000000000000000000000000..f9e187c3e4fc70c3cb8879febd0723829e40a62d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_nus/ble_nus.h @@ -0,0 +1,163 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ble_nus Nordic UART Service + * @{ + * @ingroup ble_sdk_srv + * @brief Nordic UART Service implementation. + * + * @details The Nordic UART Service is a simple GATT-based service with TX and RX characteristics. + * Data received from the peer is passed to the application, and the data received + * from the application of this service is sent to the peer as Handle Value + * Notifications. This module demonstrates how to implement a custom GATT-based + * service and characteristics using the SoftDevice. The service + * is used by the application to send and receive ASCII text strings to and from the + * peer. + * + * @note The application must propagate SoftDevice events to the Nordic UART Service module + * by calling the ble_nus_on_ble_evt() function from the ble_stack_handler callback. + */ + +#ifndef BLE_NUS_H__ +#define BLE_NUS_H__ + +#include "sdk_config.h" +#include "ble_stack_handler_types.h" + +#include "ble.h" +#include "ble_srv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */ + +#define OPCODE_LENGTH 1 +#define HANDLE_LENGTH 2 + +#if defined(NRF_BLE_GATT_MAX_MTU_SIZE) && (NRF_BLE_GATT_MAX_MTU_SIZE != 0) + #define BLE_NUS_MAX_DATA_LEN (NRF_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */ +#else + #define BLE_NUS_MAX_DATA_LEN (BLE_GATT_MTU_SIZE_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */ + #warning NRF_BLE_GATT_MAX_MTU_SIZE is not defined. +#endif + + + + +/* Forward declaration of the ble_nus_t type. */ +typedef struct ble_nus_s ble_nus_t; + +/**@brief Nordic UART Service event handler type. */ +typedef void (*ble_nus_data_handler_t) (ble_nus_t * p_nus, uint8_t * p_data, uint16_t length); + +/**@brief Nordic UART Service initialization structure. + * + * @details This structure contains the initialization information for the service. The application + * must fill this structure and pass it to the service using the @ref ble_nus_init + * function. + */ +typedef struct +{ + ble_nus_data_handler_t data_handler; /**< Event handler to be called for handling received data. */ +} ble_nus_init_t; + +/**@brief Nordic UART Service structure. + * + * @details This structure contains status information related to the service. + */ +struct ble_nus_s +{ + uint8_t uuid_type; /**< UUID type for Nordic UART Service Base UUID. */ + uint16_t service_handle; /**< Handle of Nordic UART Service (as provided by the SoftDevice). */ + ble_gatts_char_handles_t tx_handles; /**< Handles related to the TX characteristic (as provided by the SoftDevice). */ + ble_gatts_char_handles_t rx_handles; /**< Handles related to the RX characteristic (as provided by the SoftDevice). */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the SoftDevice). BLE_CONN_HANDLE_INVALID if not in a connection. */ + bool is_notification_enabled; /**< Variable to indicate if the peer has enabled notification of the RX characteristic.*/ + ble_nus_data_handler_t data_handler; /**< Event handler to be called for handling received data. */ +}; + +/**@brief Function for initializing the Nordic UART Service. + * + * @param[out] p_nus Nordic UART Service structure. This structure must be supplied + * by the application. It is initialized by this function and will + * later be used to identify this particular service instance. + * @param[in] p_nus_init Information needed to initialize the service. + * + * @retval NRF_SUCCESS If the service was successfully initialized. Otherwise, an error code is returned. + * @retval NRF_ERROR_NULL If either of the pointers p_nus or p_nus_init is NULL. + */ +uint32_t ble_nus_init(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init); + +/**@brief Function for handling the Nordic UART Service's BLE events. + * + * @details The Nordic UART Service expects the application to call this function each time an + * event is received from the SoftDevice. This function processes the event if it + * is relevant and calls the Nordic UART Service event handler of the + * application if necessary. + * + * @param[in] p_nus Nordic UART Service structure. + * @param[in] p_ble_evt Event received from the SoftDevice. + */ +void ble_nus_on_ble_evt(ble_nus_t * p_nus, ble_evt_t * p_ble_evt); + +/**@brief Function for sending a string to the peer. + * + * @details This function sends the input string as an RX characteristic notification to the + * peer. + * + * @param[in] p_nus Pointer to the Nordic UART Service structure. + * @param[in] p_string String to be sent. + * @param[in] length Length of the string. + * + * @retval NRF_SUCCESS If the string was sent successfully. Otherwise, an error code is returned. + */ +uint32_t ble_nus_string_send(ble_nus_t * p_nus, uint8_t * p_string, uint16_t length); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_NUS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_nus_c/ble_nus_c.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_nus_c/ble_nus_c.c new file mode 100644 index 0000000000000000000000000000000000000000..d00bfc5994e8db2e161609af4152a4636574244d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_nus_c/ble_nus_c.c @@ -0,0 +1,263 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_NUS_C) +#include // definition of NULL + +#include "ble.h" +#include "ble_nus_c.h" +#include "ble_gattc.h" +#include "ble_srv_common.h" +#include "app_error.h" + +#define NRF_LOG_MODULE_NAME "BLE_NUS" +#include "nrf_log.h" + +void ble_nus_c_on_db_disc_evt(ble_nus_c_t * p_ble_nus_c, ble_db_discovery_evt_t * p_evt) +{ + ble_nus_c_evt_t nus_c_evt; + memset(&nus_c_evt,0,sizeof(ble_nus_c_evt_t)); + + ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics; + + // Check if the NUS was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && + p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_NUS_SERVICE && + p_evt->params.discovered_db.srv_uuid.type == p_ble_nus_c->uuid_type) + { + + uint32_t i; + + for (i = 0; i < p_evt->params.discovered_db.char_count; i++) + { + switch (p_chars[i].characteristic.uuid.uuid) + { + case BLE_UUID_NUS_RX_CHARACTERISTIC: + nus_c_evt.handles.nus_rx_handle = p_chars[i].characteristic.handle_value; + break; + + case BLE_UUID_NUS_TX_CHARACTERISTIC: + nus_c_evt.handles.nus_tx_handle = p_chars[i].characteristic.handle_value; + nus_c_evt.handles.nus_tx_cccd_handle = p_chars[i].cccd_handle; + break; + + default: + break; + } + } + if (p_ble_nus_c->evt_handler != NULL) + { + nus_c_evt.conn_handle = p_evt->conn_handle; + nus_c_evt.evt_type = BLE_NUS_C_EVT_DISCOVERY_COMPLETE; + p_ble_nus_c->evt_handler(p_ble_nus_c, &nus_c_evt); + } + } +} + +/**@brief Function for handling Handle Value Notification received from the SoftDevice. + * + * @details This function will uses the Handle Value Notification received from the SoftDevice + * and checks if it is a notification of the NUS TX characteristic from the peer. If + * it is, this function will decode the data and send it to the + * application. + * + * @param[in] p_ble_nus_c Pointer to the NUS Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_hvx(ble_nus_c_t * p_ble_nus_c, const ble_evt_t * p_ble_evt) +{ + // HVX can only occur from client sending. + if ((p_ble_nus_c->handles.nus_tx_handle != BLE_GATT_HANDLE_INVALID) + && (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_nus_c->handles.nus_tx_handle) + && (p_ble_nus_c->evt_handler != NULL) + ) + { + ble_nus_c_evt_t ble_nus_c_evt; + + ble_nus_c_evt.evt_type = BLE_NUS_C_EVT_NUS_TX_EVT; + ble_nus_c_evt.p_data = (uint8_t *)p_ble_evt->evt.gattc_evt.params.hvx.data; + ble_nus_c_evt.data_len = p_ble_evt->evt.gattc_evt.params.hvx.len; + + p_ble_nus_c->evt_handler(p_ble_nus_c, &ble_nus_c_evt); + NRF_LOG_DEBUG("Client sending data.\r\n"); + } +} + +uint32_t ble_nus_c_init(ble_nus_c_t * p_ble_nus_c, ble_nus_c_init_t * p_ble_nus_c_init) +{ + uint32_t err_code; + ble_uuid_t uart_uuid; + ble_uuid128_t nus_base_uuid = NUS_BASE_UUID; + + VERIFY_PARAM_NOT_NULL(p_ble_nus_c); + VERIFY_PARAM_NOT_NULL(p_ble_nus_c_init); + + err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_ble_nus_c->uuid_type); + VERIFY_SUCCESS(err_code); + + uart_uuid.type = p_ble_nus_c->uuid_type; + uart_uuid.uuid = BLE_UUID_NUS_SERVICE; + + p_ble_nus_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_nus_c->evt_handler = p_ble_nus_c_init->evt_handler; + p_ble_nus_c->handles.nus_tx_handle = BLE_GATT_HANDLE_INVALID; + p_ble_nus_c->handles.nus_rx_handle = BLE_GATT_HANDLE_INVALID; + + return ble_db_discovery_evt_register(&uart_uuid); +} + +void ble_nus_c_on_ble_evt(ble_nus_c_t * p_ble_nus_c, const ble_evt_t * p_ble_evt) +{ + if ((p_ble_nus_c == NULL) || (p_ble_evt == NULL)) + { + return; + } + + if ( (p_ble_nus_c->conn_handle != BLE_CONN_HANDLE_INVALID) + &&(p_ble_nus_c->conn_handle != p_ble_evt->evt.gap_evt.conn_handle) + ) + { + return; + } + + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTC_EVT_HVX: + on_hvx(p_ble_nus_c, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + if (p_ble_evt->evt.gap_evt.conn_handle == p_ble_nus_c->conn_handle + && p_ble_nus_c->evt_handler != NULL) + { + ble_nus_c_evt_t nus_c_evt; + + nus_c_evt.evt_type = BLE_NUS_C_EVT_DISCONNECTED; + + p_ble_nus_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_nus_c->evt_handler(p_ble_nus_c, &nus_c_evt); + } + break; + + default: + // No implementation needed. + break; + } +} + +/**@brief Function for creating a message for writing to the CCCD. + */ +static uint32_t cccd_configure(uint16_t conn_handle, uint16_t cccd_handle, bool enable) +{ + uint8_t buf[BLE_CCCD_VALUE_LEN]; + + buf[0] = enable ? BLE_GATT_HVX_NOTIFICATION : 0; + buf[1] = 0; + + const ble_gattc_write_params_t write_params = { + .write_op = BLE_GATT_OP_WRITE_REQ, + .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE, + .handle = cccd_handle, + .offset = 0, + .len = sizeof(buf), + .p_value = buf + }; + + return sd_ble_gattc_write(conn_handle, &write_params); +} + +uint32_t ble_nus_c_tx_notif_enable(ble_nus_c_t * p_ble_nus_c) +{ + VERIFY_PARAM_NOT_NULL(p_ble_nus_c); + + if ( (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID) + ||(p_ble_nus_c->handles.nus_tx_cccd_handle == BLE_GATT_HANDLE_INVALID) + ) + { + return NRF_ERROR_INVALID_STATE; + } + return cccd_configure(p_ble_nus_c->conn_handle,p_ble_nus_c->handles.nus_tx_cccd_handle, true); +} + +uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length) +{ + VERIFY_PARAM_NOT_NULL(p_ble_nus_c); + + if (length > BLE_NUS_MAX_DATA_LEN) + { + NRF_LOG_WARNING("Content too long.\r\n"); + return NRF_ERROR_INVALID_PARAM; + } + if (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID) + { + NRF_LOG_WARNING("Connection handle invalid.\r\n"); + return NRF_ERROR_INVALID_STATE; + } + + ble_gattc_write_params_t const write_params = { + .write_op = BLE_GATT_OP_WRITE_CMD, + .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE, + .handle = p_ble_nus_c->handles.nus_rx_handle, + .offset = 0, + .len = length, + .p_value = p_string + }; + + return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params); +} + + +uint32_t ble_nus_c_handles_assign(ble_nus_c_t * p_ble_nus, + const uint16_t conn_handle, + const ble_nus_c_handles_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ble_nus); + + p_ble_nus->conn_handle = conn_handle; + if (p_peer_handles != NULL) + { + p_ble_nus->handles.nus_tx_cccd_handle = p_peer_handles->nus_tx_cccd_handle; + p_ble_nus->handles.nus_tx_handle = p_peer_handles->nus_tx_handle; + p_ble_nus->handles.nus_rx_handle = p_peer_handles->nus_rx_handle; + } + return NRF_SUCCESS; +} +#endif // NRF_MODULE_ENABLED(BLE_NUS_C) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_nus_c/ble_nus_c.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_nus_c/ble_nus_c.h new file mode 100644 index 0000000000000000000000000000000000000000..64d90baf3bcf71402b4b3d0fcd067b6ccbe0ac88 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_nus_c/ble_nus_c.h @@ -0,0 +1,237 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ble_nus_c Nordic UART Service Client + * @{ + * @ingroup ble_sdk_srv + * @brief Nordic UART Service Client module. + * + * @details This module contains the APIs and types exposed by the Nordic UART Service Client + * module. These APIs and types can be used by the application to perform discovery of + * the Nordic UART Service at the peer and interact with it. + * + * @note The application must propagate BLE stack events to this module by calling + * ble_nus_c_on_ble_evt(). + * + */ + + +#ifndef BLE_NUS_C_H__ +#define BLE_NUS_C_H__ + +#include +#include +#include "ble.h" +#include "ble_gatt.h" +#include "ble_db_discovery.h" + +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NUS_BASE_UUID {{0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}} /**< Used vendor specific UUID. */ + +#define BLE_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */ +#define BLE_UUID_NUS_RX_CHARACTERISTIC 0x0002 /**< The UUID of the RX Characteristic. */ +#define BLE_UUID_NUS_TX_CHARACTERISTIC 0x0003 /**< The UUID of the TX Characteristic. */ + +#define OPCODE_LENGTH 1 +#define HANDLE_LENGTH 2 + +#if defined(NRF_BLE_GATT_MAX_MTU_SIZE) && (NRF_BLE_GATT_MAX_MTU_SIZE != 0) + #define BLE_NUS_MAX_DATA_LEN (NRF_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */ +#else + #define BLE_NUS_MAX_DATA_LEN (BLE_GATT_MTU_SIZE_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */ + #warning NRF_BLE_GATT_MAX_MTU_SIZE is not defined. +#endif + + +/**@brief NUS Client event type. */ +typedef enum +{ + BLE_NUS_C_EVT_DISCOVERY_COMPLETE = 1, /**< Event indicating that the NUS service and its characteristics was found. */ + BLE_NUS_C_EVT_NUS_TX_EVT, /**< Event indicating that the central has received something from a peer. */ + BLE_NUS_C_EVT_DISCONNECTED /**< Event indicating that the NUS server has disconnected. */ +} ble_nus_c_evt_type_t; + +/**@brief Handles on the connected peer device needed to interact with it. */ +typedef struct { + uint16_t nus_tx_handle; /**< Handle of the NUS TX characteristic as provided by a discovery. */ + uint16_t nus_tx_cccd_handle; /**< Handle of the CCCD of the NUS TX characteristic as provided by a discovery. */ + uint16_t nus_rx_handle; /**< Handle of the NUS RX characteristic as provided by a discovery. */ +} ble_nus_c_handles_t; + +/**@brief Structure containing the NUS event data received from the peer. */ +typedef struct { + ble_nus_c_evt_type_t evt_type; + uint16_t conn_handle; + uint16_t max_data_len; + uint8_t * p_data; + uint8_t data_len; + ble_nus_c_handles_t handles; /**< Handles on which the Nordic Uart service characteristics was discovered on the peer device. This will be filled if the evt_type is @ref BLE_NUS_C_EVT_DISCOVERY_COMPLETE.*/ +} ble_nus_c_evt_t; + +// Forward declaration of the ble_nus_t type. +typedef struct ble_nus_c_s ble_nus_c_t; + +/**@brief Event handler type. + * + * @details This is the type of the event handler that should be provided by the application + * of this module to receive events. + */ +typedef void (* ble_nus_c_evt_handler_t)(ble_nus_c_t * p_ble_nus_c, const ble_nus_c_evt_t * p_evt); + +/**@brief NUS Client structure. */ +struct ble_nus_c_s +{ + uint8_t uuid_type; /**< UUID type. */ + uint16_t conn_handle; /**< Handle of the current connection. Set with @ref ble_nus_c_handles_assign when connected. */ + ble_nus_c_handles_t handles; /**< Handles on the connected peer device needed to interact with it. */ + ble_nus_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the NUS. */ +}; + +/**@brief NUS Client initialization structure. */ +typedef struct +{ + ble_nus_c_evt_handler_t evt_handler; +} ble_nus_c_init_t; + + +/**@brief Function for initializing the Nordic UART client module. + * + * @details This function registers with the Database Discovery module + * for the NUS. Doing so will make the Database Discovery + * module look for the presence of a NUS instance at the peer when a + * discovery is started. + * + * @param[in] p_ble_nus_c Pointer to the NUS client structure. + * @param[in] p_ble_nus_c_init Pointer to the NUS initialization structure containing the + * initialization information. + * + * @retval NRF_SUCCESS If the module was initialized successfully. Otherwise, an error + * code is returned. This function + * propagates the error code returned by the Database Discovery module API + * @ref ble_db_discovery_evt_register. + */ +uint32_t ble_nus_c_init(ble_nus_c_t * p_ble_nus_c, ble_nus_c_init_t * p_ble_nus_c_init); + + +/**@brief Function for handling events from the database discovery module. + * + * @details This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of NUS at the peer. If so, it will + * call the application's event handler indicating that NUS has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param[in] p_ble_nus_c Pointer to the NUS client structure. + * @param[in] p_evt Pointer to the event received from the database discovery module. + */ + void ble_nus_c_on_db_disc_evt(ble_nus_c_t * p_ble_nus_c, ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for handling BLE events from the SoftDevice. + * + * @details This function handles the BLE events received from the SoftDevice. If a BLE + * event is relevant to the NUS module, it is used to update + * internal variables and, if necessary, send events to the application. + * + * @param[in] p_ble_nus_c Pointer to the NUS client structure. + * @param[in] p_ble_evt Pointer to the BLE event. + */ +void ble_nus_c_on_ble_evt(ble_nus_c_t * p_ble_nus_c, const ble_evt_t * p_ble_evt); + +/**@brief Function for requesting the peer to start sending notification of TX characteristic. + * + * @details This function enables notifications of the NUS TX characteristic at the peer + * by writing to the CCCD of the NUS TX characteristic. + * + * @param p_ble_nus_c Pointer to the NUS client structure. + * + * @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer. + * Otherwise, an error code is returned. This function propagates the error + * code returned by the SoftDevice API @ref sd_ble_gattc_write. + */ +uint32_t ble_nus_c_tx_notif_enable(ble_nus_c_t * p_ble_nus_c); + +/**@brief Function for sending a string to the server. + * + * @details This function writes the RX characteristic of the server. + * + * @param[in] p_ble_nus_c Pointer to the NUS client structure. + * @param[in] p_string String to be sent. + * @param[in] length Length of the string. + * + * @retval NRF_SUCCESS If the string was sent successfully. Otherwise, an error code is returned. + */ +uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length); + + +/**@brief Function for assigning handles to a this instance of nus_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to this instance of the module. This makes it + * possible to handle several link and associate each link to a particular + * instance of this module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_NUS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ble_nus_c Pointer to the NUS client structure instance to associate with these + * handles. + * @param[in] conn_handle Connection handle to associated with the given NUS Instance. + * @param[in] p_peer_handles Attribute handles on the NUS server that you want this NUS client to + * interact with. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If a p_nus was a NULL pointer. + */ +uint32_t ble_nus_c_handles_assign(ble_nus_c_t * p_ble_nus_c, const uint16_t conn_handle, const ble_nus_c_handles_t * p_peer_handles); + + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_NUS_C_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_rscs/ble_rscs.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_rscs/ble_rscs.c new file mode 100644 index 0000000000000000000000000000000000000000..b3e7dae4b8188a37c2b4b91256c8d85dbd052223 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_rscs/ble_rscs.c @@ -0,0 +1,415 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ + +#include "sdk_common.h" + +#if NRF_MODULE_ENABLED(BLE_RSCS) + +#include "ble_rscs.h" +#include +#include "ble.h" +#include "ble_srv_common.h" + +#define OPCODE_LENGTH 1 /**< Length of opcode inside Running Speed and Cadence Measurement packet. */ +#define HANDLE_LENGTH 2 /**< Length of handle inside Running Speed and Cadence Measurement packet. */ +#define MAX_RSCM_LEN (BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Running Speed and Cadence Measurement. */ + +// Running Speed and Cadence Measurement flag bits +#define RSC_MEAS_FLAG_INSTANT_STRIDE_LEN_PRESENT (0x01 << 0) /**< Instantaneous Stride Length Present flag bit. */ +#define RSC_MEAS_FLAG_TOTAL_DISTANCE_PRESENT (0x01 << 1) /**< Total Distance Present flag bit. */ +#define RSC_MEAS_FLAG_WALKING_OR_RUNNING_BIT (0x01 << 2) /**< Walking or Running Status flag bit. */ + + +/**@brief Function for handling the Connect event. + * + * @param[in] p_rscs Running Speed and Cadence Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_rscs_t * p_rscs, ble_evt_t * p_ble_evt) +{ + p_rscs->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; +} + + +/**@brief Function for handling the Disconnect event. + * + * @param[in] p_rscs Running Speed and Cadence Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_rscs_t * p_rscs, ble_evt_t * p_ble_evt) +{ + UNUSED_PARAMETER(p_ble_evt); + p_rscs->conn_handle = BLE_CONN_HANDLE_INVALID; +} + + +/**@brief Function for handling the write events to the RSCS Measurement characteristic. + * + * @param[in] p_rscs Running Speed and Cadence Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_meas_cccd_write(ble_rscs_t * p_rscs, ble_gatts_evt_write_t * p_evt_write) +{ + if (p_evt_write->len == 2) + { + // CCCD written, update notification state + if (p_rscs->evt_handler != NULL) + { + ble_rscs_evt_t evt; + + if (ble_srv_is_notification_enabled(p_evt_write->data)) + { + evt.evt_type = BLE_RSCS_EVT_NOTIFICATION_ENABLED; + } + else + { + evt.evt_type = BLE_RSCS_EVT_NOTIFICATION_DISABLED; + } + + p_rscs->evt_handler(p_rscs, &evt); + } + } +} + + +/**@brief Function for handling the Write event. + * + * @param[in] p_rscs Running Speed and Cadence Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_rscs_t * p_rscs, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if (p_evt_write->handle == p_rscs->meas_handles.cccd_handle) + { + on_meas_cccd_write(p_rscs, p_evt_write); + } +} + + +void ble_rscs_on_ble_evt(ble_rscs_t * p_rscs, ble_evt_t * p_ble_evt) +{ + if (p_rscs == NULL || p_ble_evt == NULL) + { + return; + } + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_rscs, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_rscs, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_rscs, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for encoding a RSCS Measurement. + * + * @param[in] p_rscs Running Speed and Cadence Service structure. + * @param[in] p_rsc_measurement Measurement to be encoded. + * @param[out] p_encoded_buffer Buffer where the encoded data will be written. + * + * @return Size of encoded data. + */ +static uint8_t rsc_measurement_encode(const ble_rscs_t * p_rscs, + const ble_rscs_meas_t * p_rsc_measurement, + uint8_t * p_encoded_buffer) +{ + uint8_t flags = 0; + uint8_t len = 1; + + // Instantaneous speed field + len += uint16_encode(p_rsc_measurement->inst_speed, &p_encoded_buffer[len]); + + // Instantaneous cadence field + p_encoded_buffer[len++] = p_rsc_measurement->inst_cadence; + + // Instantaneous stride length field + if (p_rscs->feature & BLE_RSCS_FEATURE_INSTANT_STRIDE_LEN_BIT) + { + if (p_rsc_measurement->is_inst_stride_len_present) + { + flags |= RSC_MEAS_FLAG_INSTANT_STRIDE_LEN_PRESENT; + len += uint16_encode(p_rsc_measurement->inst_stride_length, + &p_encoded_buffer[len]); + } + } + + // Total distance field + if (p_rscs->feature & BLE_RSCS_FEATURE_TOTAL_DISTANCE_BIT) + { + if (p_rsc_measurement->is_total_distance_present) + { + flags |= RSC_MEAS_FLAG_TOTAL_DISTANCE_PRESENT; + len += uint32_encode(p_rsc_measurement->total_distance, &p_encoded_buffer[len]); + } + } + + // Flags field + if (p_rscs->feature & BLE_RSCS_FEATURE_WALKING_OR_RUNNING_STATUS_BIT) + { + if (p_rsc_measurement->is_running) + { + flags |= RSC_MEAS_FLAG_WALKING_OR_RUNNING_BIT; + } + } + p_encoded_buffer[0] = flags; + + return len; +} + + +/**@brief Function for adding RSC Measurement characteristics. + * + * @param[in] p_rscs Running Speed and Cadence Service structure. + * @param[in] p_rscs_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t rsc_measurement_char_add(ble_rscs_t * p_rscs, const ble_rscs_init_t * p_rscs_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint8_t encoded_rcm[MAX_RSCM_LEN]; + + memset(&cccd_md, 0, sizeof(cccd_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + cccd_md.write_perm = p_rscs_init->rsc_meas_attr_md.cccd_write_perm; + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.notify = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_RSC_MEASUREMENT_CHAR); + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_rscs_init->rsc_meas_attr_md.read_perm; + attr_md.write_perm = p_rscs_init->rsc_meas_attr_md.write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 1; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = rsc_measurement_encode(p_rscs, &p_rscs_init->initial_rcm, encoded_rcm); + attr_char_value.init_offs = 0; + attr_char_value.max_len = MAX_RSCM_LEN; + attr_char_value.p_value = encoded_rcm; + + return sd_ble_gatts_characteristic_add(p_rscs->service_handle, + &char_md, + &attr_char_value, + &p_rscs->meas_handles); +} + + +/**@brief Function for adding RSC Feature characteristics. + * + * @param[in] p_rscs Running Speed and Cadence Service structure. + * @param[in] p_rscs_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t rsc_feature_char_add(ble_rscs_t * p_rscs, const ble_rscs_init_t * p_rscs_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + uint16_t init_value_feature; + uint8_t init_value_encoded[2]; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_RSC_FEATURE_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_rscs_init->rsc_feature_attr_md.read_perm; + attr_md.write_perm = p_rscs_init->rsc_feature_attr_md.write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + init_value_feature = p_rscs_init->feature; + init_value_encoded[0] = init_value_feature & 0xFF; + init_value_encoded[1] = (init_value_feature >> 8) & 0xFF; + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof (uint16_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = sizeof (uint16_t); + attr_char_value.p_value = init_value_encoded; + + return sd_ble_gatts_characteristic_add(p_rscs->service_handle, + &char_md, + &attr_char_value, + &p_rscs->feature_handles); +} + + +uint32_t ble_rscs_init(ble_rscs_t * p_rscs, const ble_rscs_init_t * p_rscs_init) +{ + if (p_rscs == NULL || p_rscs_init == NULL) + { + return NRF_ERROR_NULL; + } + + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Initialize service structure + p_rscs->evt_handler = p_rscs_init->evt_handler; + p_rscs->conn_handle = BLE_CONN_HANDLE_INVALID; + p_rscs->feature = p_rscs_init->feature; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_RUNNING_SPEED_AND_CADENCE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_rscs->service_handle); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add measurement characteristic + err_code = rsc_measurement_char_add(p_rscs, p_rscs_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add feature characteristic + err_code = rsc_feature_char_add(p_rscs, p_rscs_init); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + return NRF_SUCCESS; +} + + +uint32_t ble_rscs_measurement_send(ble_rscs_t * p_rscs, ble_rscs_meas_t * p_measurement) +{ + if (p_rscs == NULL || p_measurement == NULL) + { + return NRF_ERROR_NULL; + } + + uint32_t err_code; + + // Send value if connected and notifying + if (p_rscs->conn_handle != BLE_CONN_HANDLE_INVALID) + { + uint8_t encoded_rsc_meas[MAX_RSCM_LEN]; + uint16_t len; + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + + len = rsc_measurement_encode(p_rscs, p_measurement, encoded_rsc_meas); + hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_rscs->meas_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_rsc_meas; + + err_code = sd_ble_gatts_hvx(p_rscs->conn_handle, &hvx_params); + if ((err_code == NRF_SUCCESS) && (hvx_len != len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + + return err_code; +} +#endif // NRF_MODULE_ENABLED(BLE_RSCS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_rscs/ble_rscs.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_rscs/ble_rscs.h new file mode 100644 index 0000000000000000000000000000000000000000..6dc1d2e1f56996011701b873d370e0084aa3d99a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_rscs/ble_rscs.h @@ -0,0 +1,179 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_rscs Running Speed and Cadence Service + * @{ + * @ingroup ble_sdk_srv + * @brief Running Speed and Cadence Service module. + * + * @details This module implements the Running Speed and Cadence Service. If enabled, notification + * of the Running Speead and Candence Measurement is performed when the application + * calls ble_rscs_measurement_send(). + * + * If an event handler is supplied by the application, the Running Speed and Cadence + * Service will generate Running Speed and Cadence Service events to the application. + * + * @note The application must propagate BLE stack events to the Running Speead and Candence Service + * module by calling ble_rscs_on_ble_evt() from the @ref softdevice_handler function. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#ifndef BLE_RSCS_H__ +#define BLE_RSCS_H__ + +#include +#include +#include "ble_srv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Running Speed and Cadence Service feature bits. */ +#define BLE_RSCS_FEATURE_INSTANT_STRIDE_LEN_BIT (0x01 << 0) /**< Instantaneous Stride Length Measurement Supported bit. */ +#define BLE_RSCS_FEATURE_TOTAL_DISTANCE_BIT (0x01 << 1) /**< Total Distance Measurement Supported bit. */ +#define BLE_RSCS_FEATURE_WALKING_OR_RUNNING_STATUS_BIT (0x01 << 2) /**< Walking or Running Status Supported bit. */ +#define BLE_RSCS_FEATURE_CALIBRATION_PROCEDURE_BIT (0x01 << 3) /**< Calibration Procedure Supported bit. */ +#define BLE_RSCS_FEATURE_MULTIPLE_SENSORS_BIT (0x01 << 4) /**< Multiple Sensor Locations Supported bit. */ + +/**@brief Running Speed and Cadence Service event type. */ +typedef enum +{ + BLE_RSCS_EVT_NOTIFICATION_ENABLED, /**< Running Speed and Cadence value notification enabled event. */ + BLE_RSCS_EVT_NOTIFICATION_DISABLED /**< Running Speed and Cadence value notification disabled event. */ +} ble_rscs_evt_type_t; + +/**@brief Running Speed and Cadence Service event. */ +typedef struct +{ + ble_rscs_evt_type_t evt_type; /**< Type of event. */ +} ble_rscs_evt_t; + +// Forward declaration of the ble_rsc types. +typedef struct ble_rscs_s ble_rscs_t; +typedef struct ble_rscs_meas_s ble_rscs_meas_t; + +/**@brief Running Speed and Cadence Service event handler type. */ +typedef void (*ble_rscs_evt_handler_t) (ble_rscs_t * p_rscs, ble_rscs_evt_t * p_evt); + +/**@brief Running Speed and Cadence Service measurement structure. This contains a Running Speed and + * Cadence measurement. */ +struct ble_rscs_meas_s +{ + bool is_inst_stride_len_present; /**< True if Instantaneous Stride Length is present in the measurement. */ + bool is_total_distance_present; /**< True if Total Distance is present in the measurement. */ + bool is_running; /**< True if running, False if walking. */ + uint16_t inst_speed; /**< Instantaneous Speed. */ + uint8_t inst_cadence; /**< Instantaneous Cadence. */ + uint16_t inst_stride_length; /**< Instantaneous Stride Length. */ + uint32_t total_distance; /**< Total Distance. */ +}; + +/**@brief Running Speed and Cadence Service init structure. This contains all options and data + * needed for initialization of the service. */ +typedef struct +{ + ble_rscs_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Running Speed and Cadence Service. */ + ble_srv_cccd_security_mode_t rsc_meas_attr_md; /**< Initial security level for running speed and cadence measurement attribute */ + ble_srv_security_mode_t rsc_feature_attr_md; /**< Initial security level for feature attribute */ + uint16_t feature; /**< Initial value for features of sensor. */ + ble_rscs_meas_t initial_rcm; /**< Initial Running Speed Cadence Measurement.*/ +} ble_rscs_init_t; + +/**@brief Running Speed and Cadence Service structure. This contains various status information for + * the service. */ +struct ble_rscs_s +{ + ble_rscs_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Running Speed and Cadence Service. */ + uint16_t service_handle; /**< Handle of Running Speed and Cadence Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t meas_handles; /**< Handles related to the Running Speed and Cadence Measurement characteristic. */ + ble_gatts_char_handles_t feature_handles; /**< Handles related to the Running Speed and Cadence feature characteristic. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ + uint16_t feature; /**< Bit mask of features available on sensor. */ +}; + + + +/**@brief Function for initializing the Running Speed and Cadence Service. + * + * @param[out] p_rscs Running Speed and Cadence Service structure. This structure will have to + * be supplied by the application. It will be initialized by this function, + * and will later be used to identify this particular service instance. + * @param[in] p_rscs_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +uint32_t ble_rscs_init(ble_rscs_t * p_rscs, const ble_rscs_init_t * p_rscs_init); + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the Running Speed and Cadence + * Service. + * + * @param[in] p_rscs Running Speed and Cadence Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_rscs_on_ble_evt(ble_rscs_t * p_rscs, ble_evt_t * p_ble_evt); + +/**@brief Function for sending running speed and cadence measurement if notification has been enabled. + * + * @details The application calls this function after having performed a Running Speed and Cadence + * measurement. If notification has been enabled, the measurement data is encoded and sent + * to the client. + * + * @param[in] p_rscs Running Speed and Cadence Service structure. + * @param[in] p_measurement Pointer to new running speed and cadence measurement. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_rscs_measurement_send(ble_rscs_t * p_rscs, ble_rscs_meas_t * p_measurement); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_RSCS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_rscs_c/ble_rscs_c.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_rscs_c/ble_rscs_c.c new file mode 100644 index 0000000000000000000000000000000000000000..3f451bee0b32f13a1c7b94994705d0d1f9797fa1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_rscs_c/ble_rscs_c.c @@ -0,0 +1,390 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@cond To Make Doxygen skip documentation generation for this file. + * @{ + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_RSCS_C) +#include "ble_rscs_c.h" +#include "ble_db_discovery.h" +#include "ble_types.h" +#include "ble_srv_common.h" +#include "ble_gattc.h" + +#define NRF_LOG_MODULE_NAME "BLE_RSCS_C" +#include "nrf_log.h" + +#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of continuous zeroes, followed by continuous sequence of ones: 000...111. */ +#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */ + +#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */ + +typedef enum +{ + READ_REQ, /**< Type identifying that this tx_message is a read request. */ + WRITE_REQ /**< Type identifying that this tx_message is a write request. */ +} tx_request_t; + +/**@brief Structure for writing a message to the peer, i.e. CCCD. + */ +typedef struct +{ + uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */ + ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */ +} write_params_t; + +/**@brief Structure for holding data to be transmitted to the connected central. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */ + tx_request_t type; /**< Type of this message, i.e. read or write message. */ + union + { + uint16_t read_handle; /**< Read request message. */ + write_params_t write_req; /**< Write request message. */ + } req; +} tx_message_t; + + +static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */ +static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */ +static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */ + + +/**@brief Function for passing any pending request from the buffer to the stack. + */ +static void tx_buffer_process(void) +{ + if (m_tx_index != m_tx_insert_index) + { + uint32_t err_code; + + if (m_tx_buffer[m_tx_index].type == READ_REQ) + { + err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle, + m_tx_buffer[m_tx_index].req.read_handle, + 0); + } + else + { + err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle, + &m_tx_buffer[m_tx_index].req.write_req.gattc_params); + } + if (err_code == NRF_SUCCESS) + { + NRF_LOG_INFO("SD Read/Write API returns Success.\r\n"); + m_tx_index++; + m_tx_index &= TX_BUFFER_MASK; + } + else + { + NRF_LOG_INFO("SD Read/Write API returns error. This message sending will be " + "attempted again..\r\n"); + } + } +} + + +/**@brief Function for handling write response events. + * + * @param[in] p_ble_rscs_c Pointer to the Running Speed and Cadence Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_write_rsp(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt) +{ + // Check if the event if on the link for this instance + if (p_ble_rscs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + // Check if there is any message to be sent across to the peer and send it. + tx_buffer_process(); +} + + +/**@brief Function for handling Handle Value Notification received from the SoftDevice. + * + * @details This function will uses the Handle Value Notification received from the SoftDevice + * and checks if it is a notification of the Running Speed and Cadence measurement from + * the peer. If it is, this function will decode the Running Speed measurement and send it + * to the application. + * + * @param[in] p_ble_rscs_c Pointer to the Running Speed and Cadence Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_hvx(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt) +{ + const ble_gattc_evt_hvx_t * p_notif = &p_ble_evt->evt.gattc_evt.params.hvx; + + // Check if the event if on the link for this instance + if (p_ble_rscs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + + // Check if this is a Running Speed and Cadence notification. + if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_rscs_c->peer_db.rsc_handle) + { + uint32_t index = 0; + ble_rscs_c_evt_t ble_rscs_c_evt; + ble_rscs_c_evt.evt_type = BLE_RSCS_C_EVT_RSC_NOTIFICATION; + ble_rscs_c_evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle; + + //lint -save -e415 -e416 -e662 "Access of out of bounds pointer" "Creation of out of bounds pointer" + + // Flags field + ble_rscs_c_evt.params.rsc.is_inst_stride_len_present = p_notif->data[index] >> BLE_RSCS_INSTANT_STRIDE_LEN_PRESENT & 0x01; + ble_rscs_c_evt.params.rsc.is_total_distance_present = p_notif->data[index] >> BLE_RSCS_TOTAL_DISTANCE_PRESENT & 0x01; + ble_rscs_c_evt.params.rsc.is_running = p_notif->data[index] >> BLE_RSCS_WALKING_OR_RUNNING_STATUS_BIT & 0x01; + index++; + + // Instantaneous Speed + ble_rscs_c_evt.params.rsc.inst_speed = uint16_decode(&p_notif->data[index]); + index += sizeof(uint16_t); + + // Instantaneous Cadence + ble_rscs_c_evt.params.rsc.inst_cadence = p_notif->data[index]; + index++; + + // Instantaneous Stride Length + if (ble_rscs_c_evt.params.rsc.is_inst_stride_len_present == true) + { + ble_rscs_c_evt.params.rsc.inst_stride_length = uint16_decode(&p_notif->data[index]); + index += sizeof(uint16_t); + } + + // Total distance field + if (ble_rscs_c_evt.params.rsc.is_total_distance_present == true) + { + ble_rscs_c_evt.params.rsc.total_distance = uint32_decode(&p_notif->data[index]); + //index += sizeof(uint32_t); + } + + p_ble_rscs_c->evt_handler(p_ble_rscs_c, &ble_rscs_c_evt); + + //lint -restore + } +} + + +/**@brief Function for handling events from the database discovery module. + * + * @details This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of heart rate service at the peer. If so, it will + * call the application's event handler indicating that the Running Speed and Cadence + * service has been discovered at the peer. It also populates the event with the service + * related information before providing it to the application. + * + * @param[in] p_evt Pointer to the event received from the database discovery module. + * + */ +void ble_rscs_on_db_disc_evt(ble_rscs_c_t * p_ble_rscs_c, const ble_db_discovery_evt_t * p_evt) +{ + // Check if the Heart Rate Service was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && + p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_RUNNING_SPEED_AND_CADENCE && + p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) + { + + ble_rscs_c_evt_t evt; + evt.conn_handle = p_evt->conn_handle; + + // Find the CCCD Handle of the Running Speed and Cadence characteristic. + uint32_t i; + + for (i = 0; i < p_evt->params.discovered_db.char_count; i++) + { + if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid == + BLE_UUID_RSC_MEASUREMENT_CHAR) + { + // Found Running Speed and Cadence characteristic. Store CCCD handle and break. + evt.params.rscs_db.rsc_cccd_handle = + p_evt->params.discovered_db.charateristics[i].cccd_handle; + evt.params.rscs_db.rsc_handle = + p_evt->params.discovered_db.charateristics[i].characteristic.handle_value; + break; + } + } + + NRF_LOG_INFO("Running Speed and Cadence Service discovered at peer.\r\n"); + + //If the instance has been assigned prior to db_discovery, assign the db_handles + if (p_ble_rscs_c->conn_handle != BLE_CONN_HANDLE_INVALID) + { + if ((p_ble_rscs_c->peer_db.rsc_cccd_handle == BLE_GATT_HANDLE_INVALID)&& + (p_ble_rscs_c->peer_db.rsc_handle == BLE_GATT_HANDLE_INVALID)) + { + p_ble_rscs_c->peer_db = evt.params.rscs_db; + } + } + + evt.evt_type = BLE_RSCS_C_EVT_DISCOVERY_COMPLETE; + + p_ble_rscs_c->evt_handler(p_ble_rscs_c, &evt); + } +} + + +uint32_t ble_rscs_c_init(ble_rscs_c_t * p_ble_rscs_c, ble_rscs_c_init_t * p_ble_rscs_c_init) +{ + VERIFY_PARAM_NOT_NULL(p_ble_rscs_c); + VERIFY_PARAM_NOT_NULL(p_ble_rscs_c_init); + + ble_uuid_t rscs_uuid; + + rscs_uuid.type = BLE_UUID_TYPE_BLE; + rscs_uuid.uuid = BLE_UUID_RUNNING_SPEED_AND_CADENCE; + + p_ble_rscs_c->evt_handler = p_ble_rscs_c_init->evt_handler; + p_ble_rscs_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_rscs_c->peer_db.rsc_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_rscs_c->peer_db.rsc_handle = BLE_GATT_HANDLE_INVALID; + + return ble_db_discovery_evt_register(&rscs_uuid); +} + + +uint32_t ble_rscs_c_handles_assign(ble_rscs_c_t * p_ble_rscs_c, + uint16_t conn_handle, + ble_rscs_c_db_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ble_rscs_c); + p_ble_rscs_c->conn_handle = conn_handle; + if (p_peer_handles != NULL) + { + p_ble_rscs_c->peer_db = *p_peer_handles; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for handling Disconnected event received from the SoftDevice. + * + * @details This function check if the disconnect event is happening on the link + * associated with the current instance of the module, if so it will set its + * conn_handle to invalid. + * + * @param[in] p_ble_rscs_c Pointer to the RSC Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_disconnected(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt) +{ + if (p_ble_rscs_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_ble_rscs_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_rscs_c->peer_db.rsc_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_rscs_c->peer_db.rsc_handle = BLE_GATT_HANDLE_INVALID; + } +} + + +void ble_rscs_c_on_ble_evt(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt) +{ + if ((p_ble_rscs_c == NULL) || (p_ble_evt == NULL)) + { + return; + } + + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTC_EVT_HVX: + on_hvx(p_ble_rscs_c, p_ble_evt); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + on_write_rsp(p_ble_rscs_c, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_ble_rscs_c, p_ble_evt); + break; + + default: + break; + } +} + + +/**@brief Function for creating a message for writing to the CCCD. + */ +static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable) +{ + NRF_LOG_INFO("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d\r\n", + handle_cccd, conn_handle); + + tx_message_t * p_msg; + uint16_t cccd_val = enable ? BLE_GATT_HVX_NOTIFICATION : 0; + + p_msg = &m_tx_buffer[m_tx_insert_index++]; + m_tx_insert_index &= TX_BUFFER_MASK; + + p_msg->req.write_req.gattc_params.handle = handle_cccd; + p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH; + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + p_msg->req.write_req.gattc_params.offset = 0; + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val); + p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val); + p_msg->conn_handle = conn_handle; + p_msg->type = WRITE_REQ; + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +uint32_t ble_rscs_c_rsc_notif_enable(ble_rscs_c_t * p_ble_rscs_c) +{ + VERIFY_PARAM_NOT_NULL(p_ble_rscs_c); + + if (p_ble_rscs_c->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + + return cccd_configure(p_ble_rscs_c->conn_handle, p_ble_rscs_c->peer_db.rsc_cccd_handle, true); +} + +/** @} + * @endcond + */ +#endif // NRF_MODULE_ENABLED(BLE_RSCS_C) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_rscs_c/ble_rscs_c.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_rscs_c/ble_rscs_c.h new file mode 100644 index 0000000000000000000000000000000000000000..801adb5ac476d0736a6aacf20333f3851734ad49 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_rscs_c/ble_rscs_c.h @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_RSCS_C_H__ +#define BLE_RSCS_C_H__ + +#include +#include +#include "ble.h" +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup ble_rscs_c Running Speed and Cadence Service Client + * @{ + * @ingroup ble_sdk_srv + * + * @details This module contains the APIs and types exposed by the Running Speed and Cadence + * Service Client module. These APIs and types can be used by the application to perform + * discovery of Running Speed and Cadence Service at the peer and interact with it. + * + * @note The application must propagate BLE stack events to this module by calling + * ble_rscs_c_on_ble_evt(). + */ + + +/**@brief Structure containing the handles related to the Running Speed and Cadence Service found on the peer. */ +typedef struct +{ + uint16_t rsc_cccd_handle; /**< Handle of the CCCD of the Running Speed and Cadence characteristic. */ + uint16_t rsc_handle; /**< Handle of the Running Speed and Cadence characteristic as provided by the SoftDevice. */ +} ble_rscs_c_db_t; + +/**@brief RSCS Client event type. */ +typedef enum +{ + BLE_RSCS_C_EVT_DISCOVERY_COMPLETE = 1, /**< Event indicating that the Running Speed and Cadence Service has been discovered at the peer. */ + BLE_RSCS_C_EVT_RSC_NOTIFICATION /**< Event indicating that a notification of the Running Speed and Cadence measurement characteristic has been received from the peer. */ +} ble_rscs_c_evt_type_t; + +#define BLE_RSCS_INSTANT_STRIDE_LEN_PRESENT 0x00 /**< Instantaneous Stride Length Measurement Supported bit. */ +#define BLE_RSCS_TOTAL_DISTANCE_PRESENT 0x01 /**< Total Distance Measurement Supported bit. */ +#define BLE_RSCS_WALKING_OR_RUNNING_STATUS_BIT 0x02 /**< Walking or Running Status Supported bit. */ + +/**@brief Structure containing the Running Speed and Cadence measurement received from the peer. */ +typedef struct +{ + bool is_inst_stride_len_present; /**< True if Instantaneous Stride Length is present in the measurement. */ + bool is_total_distance_present; /**< True if Total Distance is present in the measurement. */ + bool is_running; /**< True if running, False if walking. */ + uint16_t inst_speed; /**< Instantaneous Speed. */ + uint8_t inst_cadence; /**< Instantaneous Cadence. */ + uint16_t inst_stride_length; /**< Instantaneous Stride Length. */ + uint32_t total_distance; /**< Total Distance. */ +} ble_rsc_t; + +/**@brief Running Speed and Cadence Event structure. */ +typedef struct +{ + ble_rscs_c_evt_type_t evt_type; /**< Type of the event. */ + uint16_t conn_handle; /**< Connection handle on which the rscs_c event occured.*/ + union + { + ble_rscs_c_db_t rscs_db; /**< Running Speed and Cadence Service related handles found on the peer device. This will be filled if the evt_type is @ref BLE_RSCS_C_EVT_DISCOVERY_COMPLETE.*/ + ble_rsc_t rsc; /**< Running Speed and Cadence measurement received. This will be filled if the evt_type is @ref BLE_RSCS_C_EVT_RSC_NOTIFICATION. */ + } params; +} ble_rscs_c_evt_t; + +// Forward declaration of the ble_rscs_c_t type. +typedef struct ble_rscs_c_s ble_rscs_c_t; + + +/**@brief Event handler type. + * + * @details This is the type of the event handler that should be provided by the application + * of this module in order to receive events. + */ +typedef void (* ble_rscs_c_evt_handler_t) (ble_rscs_c_t * p_ble_rscs_c, ble_rscs_c_evt_t * p_evt); + +/**@brief Running Speed and Cadence client structure. + */ +struct ble_rscs_c_s +{ + uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */ + ble_rscs_c_db_t peer_db; /**< Handles related to RSCS on the peer*/ + ble_rscs_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the Running Speed and Cadence service. */ +}; + +/**@brief Running Speed and Cadence client initialization structure. + */ +typedef struct +{ + ble_rscs_c_evt_handler_t evt_handler; /**< Event handler to be called by the Running Speed and Cadence Client module whenever there is an event related to the Running Speed and Cadence Service. */ +} ble_rscs_c_init_t; + + +/**@brief Function for initializing the Running Speed and Cadence Service Client module. + * + * @details This function will initialize the module and set up Database Discovery to discover + * the Running Speed and Cadence Service. After calling this function, call @ref ble_db_discovery_start + * to start discovery once a link with a peer has been established. + * + * @param[out] p_ble_rscs_c Pointer to the RSC Service client structure. + * @param[in] p_ble_rscs_c_init Pointer to the RSC Service initialization structure containing + * the initialization information. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL A parameter is NULL. + * Otherwise, an error code returned by @ref ble_db_discovery_evt_register. + */ +uint32_t ble_rscs_c_init(ble_rscs_c_t * p_ble_rscs_c, ble_rscs_c_init_t * p_ble_rscs_c_init); + +void ble_rscs_c_on_ble_evt(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt); + +uint32_t ble_rscs_c_rsc_notif_enable(ble_rscs_c_t * p_ble_rscs_c); + + +/**@brief Function for handling events from the database discovery module. + * + * @details Call this function when getting a callback event from the DB discovery modue. + * This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of Running Speed and Cadence service at the peer. If so, it will + * call the application's event handler indicating that the RSC service has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param p_ble_rscs_c Pointer to the Runnind Speed and Cadence Service client structure. + * @param[in] p_evt Pointer to the event received from the database discovery module. + * + */ +void ble_rscs_on_db_disc_evt(ble_rscs_c_t * p_ble_rscs_c, const ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for assigning handles to a this instance of rscs_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to this instance of the module. This makes it + * possible to handle several link and associate each link to a particular + * instance of this module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_RSCS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ble_rscs_c Pointer to the RSC client structure instance to associate. + * @param[in] conn_handle Connection handle to associated with the given RSCS Client Instance. + * @param[in] p_peer_handles Attribute handles on the RSCS server that you want this RSCS client to + * interact with. + */ +uint32_t ble_rscs_c_handles_assign(ble_rscs_c_t * p_ble_rscs_c, + uint16_t conn_handle, + ble_rscs_c_db_t * p_peer_handles); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_RSCS_C_H__ + +/** @} */ // End tag for the file. diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_tps/ble_tps.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_tps/ble_tps.c new file mode 100644 index 0000000000000000000000000000000000000000..e849721a341184852f2c2ceb688b86e0422e837f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_tps/ble_tps.c @@ -0,0 +1,168 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_TPS) +#include "ble_tps.h" +#include +#include "ble_srv_common.h" + + +/**@brief Function for handling the Connect event. + * + * @param[in] p_tps TX Power Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_tps_t * p_tps, ble_evt_t * p_ble_evt) +{ + p_tps->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; +} + + +void ble_tps_on_ble_evt(ble_tps_t * p_tps, ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_tps, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for adding TX Power Level characteristics. + * + * @param[in] p_tps TX Power Service structure. + * @param[in] p_tps_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t tx_power_level_char_add(ble_tps_t * p_tps, + const ble_tps_init_t * p_tps_init) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&char_md, 0, sizeof(char_md)); + + char_md.char_props.read = 1; + char_md.p_char_user_desc = NULL; + char_md.p_char_pf = NULL; + char_md.p_user_desc_md = NULL; + char_md.p_cccd_md = NULL; + char_md.p_sccd_md = NULL; + + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_TX_POWER_LEVEL_CHAR); + + memset(&attr_md, 0, sizeof(attr_md)); + + attr_md.read_perm = p_tps_init->tps_attr_md.read_perm; + attr_md.write_perm = p_tps_init->tps_attr_md.write_perm; + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.rd_auth = 0; + attr_md.wr_auth = 0; + attr_md.vlen = 0; + + memset(&attr_char_value, 0, sizeof(attr_char_value)); + + memset(&attr_char_value, 0, sizeof (attr_char_value)); + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof (int8_t); + attr_char_value.init_offs = 0; + attr_char_value.max_len = sizeof (uint8_t); + attr_char_value.p_value = (uint8_t*)&p_tps_init->initial_tx_power_level; + + return sd_ble_gatts_characteristic_add(p_tps->service_handle, + &char_md, + &attr_char_value, + &p_tps->tx_power_level_handles); +} + + +uint32_t ble_tps_init(ble_tps_t * p_tps, const ble_tps_init_t * p_tps_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_TX_POWER_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_tps->service_handle); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add TX Power Level characteristic + return tx_power_level_char_add(p_tps, p_tps_init); +} + + +uint32_t ble_tps_tx_power_level_set(ble_tps_t * p_tps, int8_t tx_power_level) +{ + ble_gatts_value_t gatts_value; + + // Initialize value struct. + memset(&gatts_value, 0, sizeof(gatts_value)); + + gatts_value.len = sizeof(uint8_t); + gatts_value.offset = 0; + gatts_value.p_value = (uint8_t*)&tx_power_level; + + // Update database + return sd_ble_gatts_value_set(p_tps->conn_handle, + p_tps->tx_power_level_handles.value_handle, + &gatts_value); +} +#endif // NRF_MODULE_ENABLED(BLE_TPS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_tps/ble_tps.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_tps/ble_tps.h new file mode 100644 index 0000000000000000000000000000000000000000..f10ee856d48d3adf5818ac88b88ebb217cf183dc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/ble_tps/ble_tps.h @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_tps TX Power Service + * @{ + * @ingroup ble_sdk_srv + * @brief TX Power Service module. + * + * @details This module implements the TX Power Service with the TX Power Level characteristic. + * During initialization it adds the TX Power Service and TX Power Level characteristic + * with the specified initial value to the BLE stack database. + * + * It provides a function for letting the application update the TX Power Level + * characteristic. + * + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. + */ + +#ifndef BLE_TPS_H__ +#define BLE_TPS_H__ + +#include +#include "ble.h" +#include "ble_srv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief TX Power Service init structure. This contains all options and data needed for + * initialization of the service. */ +typedef struct +{ + int8_t initial_tx_power_level; /**< Initial value of the TX Power Level characteristic (in dBm). */ + ble_srv_security_mode_t tps_attr_md; /**< Initial Security Setting for TX Power Service Characteristics. */ +} ble_tps_init_t; + +/**@brief TX Power Service structure. This contains various status information for the service. */ +typedef struct +{ + uint16_t service_handle; /**< Handle of TX Power Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t tx_power_level_handles; /**< Handles related to the TX Power Level characteristic. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ +} ble_tps_t; + +/**@brief Function for initializing the TX Power Service. + * + * @param[out] p_hrs TX Power Service structure. This structure will have to be supplied by + * the application. It will be initialized by this function, and will later + * be used to identify this particular service instance. + * @param[in] p_tps_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +uint32_t ble_tps_init(ble_tps_t * p_hrs, const ble_tps_init_t * p_tps_init); + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack of interest to the TX Power Service. + * + * @param[in] p_tps TX Power Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_tps_on_ble_evt(ble_tps_t * p_tps, ble_evt_t * p_ble_evt); + +/**@brief Function for setting the state of the Sensor Contact Detected bit. + * + * @param[in] p_tps TX Power Service structure. + * @param[in] tx_power_level New TX Power Level (unit dBm, range -100 to 20). + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t ble_tps_tx_power_level_set(ble_tps_t * p_tps, int8_t tx_power_level); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_TPS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_common.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_common.h new file mode 100644 index 0000000000000000000000000000000000000000..cc1152eae9be8691f75e9ae5bc8182b08efbaaca --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_common.h @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_srv_ln_common Location and Navigation common defines + * @{ + * @ingroup ble_sdk_srv + * @brief Location and Navigation common defines + * + * @details This module contains define values common to LNS and LNCP + */ + +#ifndef BLE_LNS_COMMON_H__ +#define BLE_LNS_COMMON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_LNS_INVALID_ROUTE 0xFFFF +#define BLE_LNS_NO_FIX 0xFF + +#define BLE_LNS_MAX_NUM_ROUTES 10 /**< The maximum number of routes. This affects memory usage only. */ +#define BLE_LNS_MAX_ROUTE_NAME_LEN BLE_GATT_ATT_MTU_DEFAULT - 5 /**< The maximum length of length of a route name. */ +#define MAX_CTRL_POINT_RESP_PARAM_LEN BLE_LNS_MAX_ROUTE_NAME_LEN + 3 /**< Maximum length of a control point response. */ + +// Location and Navigation Service feature bits +#define BLE_LNS_FEATURE_INSTANT_SPEED_SUPPORTED (0x01 << 0) /**< Instaneous Speed Supported bit. */ +#define BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED (0x01 << 1) /**< Total Distance Supported bit. */ +#define BLE_LNS_FEATURE_LOCATION_SUPPORTED (0x01 << 2) /**< Location Supported bit. */ +#define BLE_LNS_FEATURE_ELEVATION_SUPPORTED (0x01 << 3) /**< Elevation Supported bit. */ +#define BLE_LNS_FEATURE_HEADING_SUPPORTED (0x01 << 4) /**< Heading Supported bit. */ +#define BLE_LNS_FEATURE_ROLLING_TIME_SUPPORTED (0x01 << 5) /**< Rolling Time Supported bit. */ +#define BLE_LNS_FEATURE_UTC_TIME_SUPPORTED (0x01 << 6) /**< UTC Time Supported bit. */ +#define BLE_LNS_FEATURE_REMAINING_DISTANCE_SUPPORTED (0x01 << 7) /**< Remaining Distance Supported bit. */ +#define BLE_LNS_FEATURE_REMAINING_VERT_DISTANCE_SUPPORTED (0x01 << 8) /**< Remaining Vertical Distance Supported bit. */ +#define BLE_LNS_FEATURE_EST_TIME_OF_ARRIVAL_SUPPORTED (0x01 << 9) /**< Estimated Time of Arrival Supported bit. */ +#define BLE_LNS_FEATURE_NUM_SATS_IN_SOLUTION_SUPPORTED (0x01 << 10) /**< Number of Satellites in Solution Supported bit. */ +#define BLE_LNS_FEATURE_NUM_SATS_IN_VIEW_SUPPORTED (0x01 << 11) /**< Number of Satellites in View Supported bit. */ +#define BLE_LNS_FEATURE_TIME_TO_FIRST_FIX_SUPPORTED (0x01 << 12) /**< Time to First Fix Supported bit. */ +#define BLE_LNS_FEATURE_EST_HORZ_POS_ERROR_SUPPORTED (0x01 << 13) /**< Estimated Horizontal Position Error Supported bit. */ +#define BLE_LNS_FEATURE_EST_VERT_POS_ERROR_SUPPORTED (0x01 << 14) /**< Estimated Vertical Position Error Supported bit. */ +#define BLE_LNS_FEATURE_HORZ_DILUTION_OF_PRECISION_SUPPORTED (0x01 << 15) /**< Horizontal Dilution of Precision Supported bit. */ +#define BLE_LNS_FEATURE_VERT_DILUTION_OF_PRECISION_SUPPORTED (0x01 << 16) /**< Vertical Dilution of Precision Supported bit. */ +#define BLE_LNS_FEATURE_LOC_AND_SPEED_CONTENT_MASKING_SUPPORTED (0x01 << 17) /**< Location and Speed Characteristic Content Masking Supported bit. */ +#define BLE_LNS_FEATURE_FIX_RATE_SETTING_SUPPORTED (0x01 << 18) /**< Fix Rate Setting Supported bit. */ +#define BLE_LNS_FEATURE_ELEVATION_SETTING_SUPPORTED (0x01 << 19) /**< Elevation Setting Supported bit. */ +#define BLE_LNS_FEATURE_POSITION_STATUS_SUPPORTED (0x01 << 20) /**< Position Status Supported bit. */ + + +#ifdef __cplusplus +} +#endif + +#endif /* BLE_LNS_COMMON_H__ */ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.c new file mode 100644 index 0000000000000000000000000000000000000000..46c019740d5d351c54378edf1b162a10d320ebc9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.c @@ -0,0 +1,820 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_ln_cp.h" +#include "ble_ln_db.h" +#include "ble_ln_common.h" +#include "sdk_common.h" + +#define NRF_LOG_MODULE_NAME "BLE_LN_CP" +#include "nrf_log.h" + +// Feature Mask bits +#define FEATURE_MASK_INSTANTANEOUS_SPEED (0x01 << 0) /**< Instantaneous Speed mask bit. */ +#define FEATURE_MASK_TOTAL_DISTANCE (0x01 << 1) /**< Total Distance mask bit. */ +#define FEATURE_MASK_LOCATION (0x01 << 2) /**< Location mask bit. */ +#define FEATURE_MASK_ELEVATION (0x01 << 3) /**< Elevation mask bit. */ +#define FEATURE_MASK_HEADING (0x01 << 4) /**< Heading mask bit. */ +#define FEATURE_MASK_ROLLING_TIME (0x01 << 5) /**< Rolling Time mask bit. */ +#define FEATURE_MASK_UTC_TIME (0x01 << 6) /**< UTC Time mask bit. */ + +// Data Control point parameter type lengths. +#define INT8_LEN 1 +#define INT16_LEN 2 +#define INT24_LEN 3 +#define INT32_LEN 4 + +#define OPCODE_LENGTH 1 /**< Length of opcode inside Location and Navigation Measurement packet. */ +#define HANDLE_LENGTH 2 /**< Length of handle inside Location and Navigation Measurement packet. */ + +static ble_lncp_rsp_code_t notify_app(ble_lncp_t const * p_lncp, ble_lncp_evt_t const * p_evt) +{ + ble_lncp_rsp_code_t rsp = LNCP_RSP_SUCCESS; + + if (p_lncp->evt_handler != NULL) + { + rsp = p_lncp->evt_handler(p_lncp, p_evt); + } + + return rsp; +} + + +static void resp_send(ble_lncp_t * p_lncp) +{ + // Send indication + uint16_t hvx_len; + uint8_t hvx_data[MAX_CTRL_POINT_RESP_PARAM_LEN]; + ble_gatts_hvx_params_t hvx_params; + uint32_t err_code; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_len = 3 + p_lncp->pending_rsp.rsp_param_len; + hvx_data[0] = LNCP_OP_RESPONSE_CODE; + hvx_data[1] = p_lncp->pending_rsp.op_code; + hvx_data[2] = p_lncp->pending_rsp.rsp_code; + + memcpy(&hvx_data[3], &p_lncp->pending_rsp.rsp_param[0], p_lncp->pending_rsp.rsp_param_len); + + hvx_params.handle = p_lncp->ctrlpt_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_INDICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = hvx_data; + + err_code = sd_ble_gatts_hvx(p_lncp->conn_handle, &hvx_params); + + // Error handling + if ((err_code == NRF_SUCCESS) && (hvx_len != p_lncp->pending_rsp.rsp_param_len + 3)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + + switch (err_code) + { + case NRF_SUCCESS: + p_lncp->procedure_status = LNCP_STATE_CONFIRMATION_PENDING; + // Wait for HVC event + break; + + case NRF_ERROR_RESOURCES: + // Wait for TX_COMPLETE event to retry transmission + p_lncp->procedure_status = LNCP_STATE_INDICATION_PENDING; + break; + + default: + p_lncp->procedure_status = LNCP_STATE_INDICATION_PENDING; + // error + if (p_lncp->error_handler != NULL) + { + p_lncp->error_handler(err_code); + } + break; + } +} + + +static void on_connect(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt) +{ + memset(&p_lncp->mask, 0, sizeof(ble_lncp_mask_t)); + p_lncp->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS; +} + + +static void on_disconnect(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt) +{ + UNUSED_PARAMETER(p_ble_evt); + p_lncp->conn_handle = BLE_CONN_HANDLE_INVALID; + p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS; +} + + +static void on_hvc_confirm(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt) +{ + if (p_ble_evt->evt.gatts_evt.params.hvc.handle == p_lncp->ctrlpt_handles.value_handle) + { + if (p_lncp->procedure_status == LNCP_STATE_CONFIRMATION_PENDING) + { + p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS; + } + else + { + if (p_lncp->error_handler != NULL) + { + p_lncp->error_handler(NRF_ERROR_INVALID_STATE); + } + } + } +} + + +static void on_tx_complete(ble_lncp_t * p_lncp) +{ + if (p_lncp->procedure_status == LNCP_STATE_INDICATION_PENDING) + { + resp_send(p_lncp); + } +} + + +/**@brief Handle write events to the control point cccd. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_lncp_cccd_write(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + if (p_evt_write->len == BLE_CCCD_VALUE_LEN) + { + // CCCD written, update indications state + p_lncp->is_ctrlpt_indication_enabled = ble_srv_is_indication_enabled(p_evt_write->data); + } +} + + +/**@brief Handle write events to the navigation cccd. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_nav_cccd_write(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + if (p_evt_write->len == BLE_CCCD_VALUE_LEN) + { + // CCCD written, update notification state + p_lncp->is_nav_notification_enabled = ble_srv_is_notification_enabled(p_evt_write->data); + } +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_set_cumulative_value(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + if ( !(p_lncp->available_features & BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH + INT24_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const uint32_t total_distance = uint24_decode(&p_evt_write->data[1]); + + const ble_lncp_evt_t evt = { + .evt_type = LNCP_EVT_TOTAL_DISTANCE_SET, + .params.total_distance = total_distance + }; + p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt); + + if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS) + { + p_lncp->total_distance = total_distance; + } + +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_mask_loc_speed_content(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + if ( !(p_lncp->available_features & BLE_LNS_FEATURE_LOC_AND_SPEED_CONTENT_MASKING_SUPPORTED) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + uint16_t rcvd_mask = uint16_decode(&p_evt_write->data[1]); + + if (rcvd_mask > 0x7F) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const ble_lncp_evt_t evt = { + .evt_type = LNCP_EVT_MASK_SET, + .params.mask.flags = rcvd_mask + }; + p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt); + + if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS) + { + p_lncp->mask.flags = rcvd_mask; + } +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_nav_control(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + if ( !(p_lncp->is_navigation_present) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != LNCP_NAV_CMD_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */ + const uint8_t data_buf = p_evt_write->data[1]; + /*lint -restore*/ + + if (data_buf > LNCP_NAV_CMD_MAX) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const ble_lncp_nav_cmd_t cmd = (ble_lncp_nav_cmd_t) data_buf; + + if (cmd == LNCP_CMD_NAV_START || cmd == LNCP_CMD_NAV_CONTINUE || cmd == LNCP_CMD_NAV_NEAREST) + { + p_lncp->is_navigation_running = true; + } + else if (cmd == LNCP_CMD_NAV_STOP || cmd == LNCP_CMD_NAV_PAUSE) + { + p_lncp->is_navigation_running = false; + } + + const ble_lncp_evt_t evt = { + .evt_type = LNCP_EVT_NAV_COMMAND, + .params.nav_cmd = cmd + }; + p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt); +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_req_num_routes(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS; + + if ( !(p_lncp->is_navigation_present) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const uint8_t num_records = ble_ln_db_num_records_get(); + p_lncp->pending_rsp.rsp_param_len = uint16_encode(num_records, &p_lncp->pending_rsp.rsp_param[0]); +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_req_name_of_route(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + uint8_t * p_name; + uint32_t err_code; + + p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS; + + if ( !(p_lncp->is_navigation_present) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */ + const uint16_t route_num = uint16_decode(&p_evt_write->data[1]); + /*lint -restore*/ + + err_code = ble_ln_db_record_name_get(route_num, &p_name); + if (err_code != NRF_SUCCESS) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OPERATION_FAILED; + return; + } + memcpy(&p_lncp->pending_rsp.rsp_param[0], p_name, BLE_LNS_MAX_ROUTE_NAME_LEN); + + p_lncp->pending_rsp.rsp_param_len = BLE_LNS_MAX_ROUTE_NAME_LEN; +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_select_route(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + if ( !(p_lncp->is_navigation_present)) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const uint16_t route_num = uint16_decode(&p_evt_write->data[1]); + const uint16_t stored_num = ble_ln_db_num_records_get(); + + if (route_num >= stored_num) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const ble_lncp_evt_t evt = { + .evt_type = LNCP_EVT_ROUTE_SELECTED, + .params.selected_route = route_num + }; + p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt); + + if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS) + { + p_lncp->selected_route = route_num; + } +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_set_fix_rate(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS; + + if ( !(p_lncp->available_features & BLE_LNS_FEATURE_FIX_RATE_SETTING_SUPPORTED) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH + INT8_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */ + const uint8_t fix_rate = p_evt_write->data[1]; + /*lint -restore*/ + + const ble_lncp_evt_t evt = { + .evt_type = LNCP_EVT_FIX_RATE_SET, + .params.fix_rate = fix_rate + }; + p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt); + + if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS) + { + p_lncp->fix_rate = fix_rate; + } +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_set_elevation(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS; + + if ( !(p_lncp->available_features & BLE_LNS_FEATURE_ELEVATION_SETTING_SUPPORTED) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH + INT24_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const uint32_t elevation = uint24_decode(&p_evt_write->data[1]); + ble_lncp_evt_t evt = { + .evt_type = LNCP_EVT_ELEVATION_SET, + .params.elevation = elevation + }; + p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt); + + if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS) + { + p_lncp->elevation = elevation; + } +} + + +/**@brief Handle write events to the Location and Navigation Service Control Point characteristic. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_ctrlpt_write(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + uint32_t err_code; + + p_lncp->pending_rsp.rsp_param_len = 0; + + ble_gatts_rw_authorize_reply_params_t write_authorize_reply; + memset(&write_authorize_reply, 0, sizeof(write_authorize_reply)); + + write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + + if (p_lncp->is_ctrlpt_indication_enabled) + { + if (p_lncp->procedure_status == LNCP_STATE_NO_PROC_IN_PROGRESS) + { + write_authorize_reply.params.write.update = 1; + write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + + // if the op code is navigation control, its cccd must be checked + if (p_evt_write->len > 0 && p_lncp->is_navigation_present) + { + if ( p_evt_write->data[0] == LNCP_OP_NAV_CONTROL + || p_evt_write->data[0] == LNCP_OP_REQ_NAME_OF_ROUTE + || p_evt_write->data[0] == LNCP_OP_REQ_NUM_ROUTES) + { + if (!p_lncp->is_nav_notification_enabled) + { + write_authorize_reply.params.write.gatt_status = LNCP_RSP_CCCD_CONFIG_IMPROPER; + } + } + } + } + else + { + write_authorize_reply.params.write.gatt_status = LNCP_RSP_PROC_ALR_IN_PROG; + } + } + else + { + write_authorize_reply.params.write.gatt_status = LNCP_RSP_CCCD_CONFIG_IMPROPER; + } + + // reply to the write authorization + do { + err_code = sd_ble_gatts_rw_authorize_reply(p_lncp->conn_handle, &write_authorize_reply); + if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_BUSY) + { + if (p_lncp->error_handler != NULL) + { + p_lncp->error_handler(err_code); + } + } + } while (err_code == NRF_ERROR_BUSY); + + + if (write_authorize_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS) + { + return; + } + + // Start executing the control point write action + p_lncp->procedure_status = LNCP_STATE_INDICATION_PENDING; + if (p_evt_write->len > 0) + { + p_lncp->pending_rsp.op_code = (ble_lncp_op_code_t) p_evt_write->data[0]; + switch (p_lncp->pending_rsp.op_code) + { + case LNCP_OP_SET_CUMULATIVE_VALUE: + on_set_cumulative_value(p_lncp, p_evt_write); + break; + + case LNCP_OP_MASK_LOC_SPEED_CONTENT: + on_mask_loc_speed_content(p_lncp, p_evt_write); + break; + + case LNCP_OP_NAV_CONTROL: + on_nav_control(p_lncp, p_evt_write); + break; + + case LNCP_OP_REQ_NUM_ROUTES: + on_req_num_routes(p_lncp, p_evt_write); + break; + + case LNCP_OP_REQ_NAME_OF_ROUTE: + on_req_name_of_route(p_lncp, p_evt_write); + break; + + case LNCP_OP_SELECT_ROUTE: + on_select_route(p_lncp, p_evt_write); + break; + + case LNCP_OP_SET_FIX_RATE: + on_set_fix_rate(p_lncp, p_evt_write); + break; + + case LNCP_OP_SET_ELEVATION: + on_set_elevation(p_lncp, p_evt_write); + break; + + // Unrecognized Op Code + default: + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + break; + } + + resp_send(p_lncp); + } + else + { + p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS; + } +} + + +/**@brief Write authorization request event handler. + * + * @details The write authorization request event handler is only called when writing to the control point. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_rw_authorize_req(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt) +{ + const ble_gatts_evt_rw_authorize_request_t * p_auth_req = + &p_ble_evt->evt.gatts_evt.params.authorize_request; + + if ( + (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + && + (p_auth_req->request.write.handle == p_lncp->ctrlpt_handles.value_handle) + && + (p_auth_req->request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ) + && + (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + && + (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL) + ) + { + on_ctrlpt_write(p_lncp, &p_auth_req->request.write); + } + +} + + +/**@brief Write event handler. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt) +{ + const ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if (p_evt_write->handle == p_lncp->ctrlpt_handles.cccd_handle) + { + on_lncp_cccd_write(p_lncp, p_evt_write); + } + else if (p_evt_write->handle == p_lncp->navigation_handles.cccd_handle) + { + on_nav_cccd_write(p_lncp, p_evt_write); + } +} + + +void ble_lncp_on_ble_evt(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_lncp); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_lncp, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + if (p_ble_evt->evt.gap_evt.conn_handle == p_lncp->conn_handle) + { + on_disconnect(p_lncp, p_ble_evt); + } + break; + + case BLE_GATTS_EVT_WRITE: + if (p_ble_evt->evt.gatts_evt.conn_handle == p_lncp->conn_handle) + { + on_write(p_lncp, p_ble_evt); + } + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + if (p_ble_evt->evt.gatts_evt.conn_handle == p_lncp->conn_handle) + { + on_rw_authorize_req(p_lncp, p_ble_evt); + } + break; + + case BLE_GATTS_EVT_HVC: + if (p_ble_evt->evt.gatts_evt.conn_handle == p_lncp->conn_handle) + { + on_hvc_confirm(p_lncp, p_ble_evt); + } + break; + + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + on_tx_complete(p_lncp); + break; + + default: + // no implementation + break; + } +} + + +uint32_t ble_lncp_total_distance_get(ble_lncp_t const * p_lncp) +{ + if (p_lncp == NULL) + { + return 0; + } + + return p_lncp->total_distance; +} + + +uint32_t ble_lncp_elevation_get(ble_lncp_t const * p_lncp) +{ + if (p_lncp == NULL) + { + return 0; + } + + return p_lncp->elevation; +} + + +ble_lncp_mask_t ble_lncp_mask_get(ble_lncp_t const * p_lncp) +{ + if (p_lncp == NULL) + { + const ble_lncp_mask_t empty_mask = {0}; + return empty_mask; + } + + return p_lncp->mask; +} + + +bool ble_lncp_is_navigation_running(ble_lncp_t const * p_lncp) +{ + if (p_lncp == NULL) + { + return false; + } + + return p_lncp->is_navigation_running; +} + + +ret_code_t ble_lncp_init(ble_lncp_t * p_lncp, ble_lncp_init_t const * p_lncp_init) +{ + VERIFY_PARAM_NOT_NULL(p_lncp); + VERIFY_PARAM_NOT_NULL(p_lncp_init); + + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + p_lncp->service_handle = p_lncp_init->service_handle; + p_lncp->evt_handler = p_lncp_init->evt_handler; + p_lncp->error_handler = p_lncp_init->error_handler; + p_lncp->available_features = p_lncp_init->available_features; + p_lncp->is_position_quality_present = p_lncp_init->is_position_quality_present; + p_lncp->is_navigation_present = p_lncp_init->is_navigation_present; + p_lncp->total_distance = p_lncp_init->total_distance; + p_lncp->elevation = p_lncp_init->elevation; + p_lncp->navigation_handles = p_lncp_init->navigation_handles; + + p_lncp->fix_rate = BLE_LNS_NO_FIX; + p_lncp->selected_route = BLE_LNS_INVALID_ROUTE; + + p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS; + p_lncp->conn_handle = BLE_CONN_HANDLE_INVALID; + p_lncp->is_navigation_running = false; + p_lncp->is_nav_notification_enabled = false; + p_lncp->is_ctrlpt_indication_enabled = false; + + memset(&p_lncp->mask, 0, sizeof(ble_lncp_mask_t)); + + add_char_params.uuid = BLE_UUID_LN_CONTROL_POINT_CHAR; + add_char_params.max_len = 0; + add_char_params.char_props.indicate = true; + add_char_params.char_props.write = true; + add_char_params.is_defered_write = true; + add_char_params.is_var_len = true; + add_char_params.max_len = BLE_GATT_ATT_MTU_DEFAULT; + add_char_params.write_access = p_lncp_init->write_perm; + add_char_params.cccd_write_access = p_lncp_init->cccd_write_perm; + + NRF_LOG_DEBUG("Initialized\r\n"); + + return characteristic_add(p_lncp->service_handle, + &add_char_params, + &p_lncp->ctrlpt_handles); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.h new file mode 100644 index 0000000000000000000000000000000000000000..6987da1ced11b831a9cb716725cabaafcc175468 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.h @@ -0,0 +1,255 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_srv_lncp Location and Navigation Service Control Point + * @{ + * @ingroup ble_sdk_srv + * @brief Location and Navigation Service Control Point module + * + * @details This module implements the Location and Navigation Service Control Point behavior. + */ + +#ifndef BLE_LN_CTRLPT_H__ +#define BLE_LN_CTRLPT_H__ + +#include "ble_srv_common.h" +#include "sdk_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_LNS_MAX_ROUTE_NAME_LEN BLE_GATT_ATT_MTU_DEFAULT - 5 /**< The maximum length of length of a route name. */ +#define MAX_CTRL_POINT_RESP_PARAM_LEN BLE_LNS_MAX_ROUTE_NAME_LEN + 3 /**< Maximum length of a control point response. */ + +typedef struct ble_lncp_s ble_lncp_t; + +/** @brief Location and Navigation event type. This list defines the possible events types from the Location and Navigation Service. */ +typedef enum +{ + LNCP_EVT_ELEVATION_SET, /**< Location and Navigation elevation was set. */ + LNCP_EVT_FIX_RATE_SET, /**< Fix rate was set. */ + LNCP_EVT_ROUTE_SELECTED, /**< A route was selected. */ + LNCP_EVT_NAV_COMMAND, /**< A navigation command was issued. */ + LNCP_EVT_MASK_SET, /**< Location and Speed feature mask was set. */ + LNCP_EVT_TOTAL_DISTANCE_SET /**< Location and Navigation total distance was set. */ +} ble_lncp_evt_type_t; + + +/** @brief Navigation commands. These commands can be sent to the control point and returned by an event callback. */ +typedef enum +{ + LNCP_CMD_NAV_STOP = 0x00, /**< When received, is_navigation_running in @ref ble_lns_s will be set to false. */ + LNCP_CMD_NAV_START = 0x01, /**< When received, is_navigation_running in @ref ble_lns_s will be set to true. */ + LNCP_CMD_NAV_PAUSE = 0x02, /**< When received, is_navigation_running in @ref ble_lns_s will be set to false. */ + LNCP_CMD_NAV_CONTINUE = 0x03, /**< When received, is_navigation_running in @ref ble_lns_s will be set to true. */ + LNCP_CMD_NAV_SKIP_WAYPOINT = 0x04, /**< When received, is_navigation_running in @ref ble_lns_s will not be affected. */ + LNCP_CMD_NAV_NEAREST = 0x05, /**< When received, is_navigation_running in @ref ble_lns_s will be set to true. */ +} ble_lncp_nav_cmd_t; +#define LNCP_NAV_CMD_MAX 0x05 +#define LNCP_NAV_CMD_LEN (OPCODE_LENGTH + 1) + + +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#endif + +/** @brief A mask can be used to temporarily enable and disable features of the Location and Speed characteristic.*/ +typedef union +{ + uint8_t flags; + struct + { + uint8_t instantaneous_speed :1; + uint8_t total_distance :1; + uint8_t location :1; + uint8_t elevation :1; + uint8_t heading :1; + uint8_t rolling_time :1; + uint8_t utc_time :1; + }; +} ble_lncp_mask_t; + +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + /* leave anonymous unions enabled */ +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#endif + +typedef struct +{ + ble_lncp_evt_type_t evt_type; + union + { + ble_lncp_mask_t mask; + ble_lncp_nav_cmd_t nav_cmd; + uint32_t total_distance; + uint8_t fix_rate; + uint16_t selected_route; + uint32_t elevation; + } params; +} ble_lncp_evt_t; + + +// Location and Navigation Control Point response values +typedef enum +{ + LNCP_RSP_RESERVED = 0x00, /**< Reserved for future use. */ + LNCP_RSP_SUCCESS = 0x01, /**< Success. */ + LNCP_RSP_OP_CODE_NOT_SUPPORTED = 0x02, /**< Op Code not supported. */ + LNCP_RSP_INVALID_PARAMETER = 0x03, /**< Invalid Parameter. */ + LNCP_RSP_OPERATION_FAILED = 0x04, /**< Operation Failed. */ + LNCP_RSP_PROC_ALR_IN_PROG = BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG, /**< Control point procedure is already in progress. */ + LNCP_RSP_CCCD_CONFIG_IMPROPER = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR /**< CCCD is improperly configured. */ +} ble_lncp_rsp_code_t; + + +typedef ble_lncp_rsp_code_t (*ble_lncp_evt_handler_t) (ble_lncp_t const * p_lncp, ble_lncp_evt_t const * p_evt); + +// Location and Navigation Control Point Op Code values +typedef enum +{ + LNCP_OP_RESERVED = 0x00, /**< Reserved for future use. */ + LNCP_OP_SET_CUMULATIVE_VALUE = 0x01, /**< Set Cumulative Value. */ + LNCP_OP_MASK_LOC_SPEED_CONTENT = 0x02, /**< Mask Location and Speed Characteristic Content. */ + LNCP_OP_NAV_CONTROL = 0x03, /**< Navigation Control. */ + LNCP_OP_REQ_NUM_ROUTES = 0x04, /**< Request Number of Routes. */ + LNCP_OP_REQ_NAME_OF_ROUTE = 0x05, /**< Request Name of Route. */ + LNCP_OP_SELECT_ROUTE = 0x06, /**< Select Route. */ + LNCP_OP_SET_FIX_RATE = 0x07, /**< Set Fix Rate. */ + LNCP_OP_SET_ELEVATION = 0x08, /**< Set Elevation. */ + LNCP_OP_RESPONSE_CODE = 0x20 /**< Response code. */ +} ble_lncp_op_code_t; + + +/** @brief Location and Navigation Control Point procedure status */ +typedef enum +{ + LNCP_STATE_NO_PROC_IN_PROGRESS, /**< No procedure in progress. */ + LNCP_STATE_INDICATION_PENDING, /**< Control Point indication is pending. */ + LNCP_STATE_CONFIRMATION_PENDING, /**< Waiting for the indication confirmation. */ +} ble_lncp_procedure_status_t; + + +/** @brief Information included in a control point write response indication. */ +typedef struct +{ + ble_lncp_op_code_t op_code; /**< Opcode of the control point write action. */ + ble_lncp_rsp_code_t rsp_code; /**< Response code of the control point write action. */ + uint8_t rsp_param_len; + uint8_t rsp_param[MAX_CTRL_POINT_RESP_PARAM_LEN]; +} ble_lncp_rsp_t; + + +typedef struct +{ + uint16_t service_handle; + ble_lncp_evt_handler_t evt_handler; + ble_srv_error_handler_t error_handler; + + uint32_t available_features; /**< Value of the LN feature. */ + bool is_position_quality_present; /**< If set to true, the position quality characteristic will be added. Else not. */ + bool is_control_point_present; /**< If set to true, the control point characteristic will be added. Else not. */ + bool is_navigation_present; /**< If set to true, the navigation characteristic will be added. Else not. */ + ble_gatts_char_handles_t navigation_handles; + + uint32_t total_distance; + uint32_t elevation; + + security_req_t write_perm; + security_req_t cccd_write_perm; +} ble_lncp_init_t; + + +struct ble_lncp_s +{ + uint16_t conn_handle; + uint16_t service_handle; + ble_gatts_char_handles_t ctrlpt_handles; + ble_gatts_char_handles_t navigation_handles; + ble_lncp_evt_handler_t evt_handler; + ble_srv_error_handler_t error_handler; + ble_lncp_procedure_status_t procedure_status; + ble_lncp_rsp_t pending_rsp; + + ble_lncp_mask_t mask; + uint32_t total_distance; + uint32_t elevation; + uint8_t fix_rate; + uint16_t selected_route; + uint32_t available_features; /**< Value of the LN feature. */ + bool is_position_quality_present; /**< If set to true, the position quality characteristic will be added. Else not. */ + bool is_control_point_present; /**< If set to true, the control point characteristic will be added. Else not. */ + bool is_navigation_present; /**< If set to true, the navigation characteristic will be added. Else not. */ + bool is_navigation_running; /**< This variable can be set using the control point. Must be true to be able to send navigation updates. */ + + bool is_ctrlpt_indication_enabled; /**< True if indication is enabled on the Control Point characteristic. */ + bool is_nav_notification_enabled; /**< True if notification is enabled on the Navigation characteristic. */ +}; + + +void ble_lncp_on_ble_evt(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt); + +uint32_t ble_lncp_total_distance_get(ble_lncp_t const * p_lncp); + +uint32_t ble_lncp_elevation_get(ble_lncp_t const * p_lncp); + +ble_lncp_mask_t ble_lncp_mask_get(ble_lncp_t const * p_lncp); + +bool ble_lncp_is_navigation_running(ble_lncp_t const * p_lncp); + +ret_code_t ble_lncp_init(ble_lncp_t * p_lncp, ble_lncp_init_t const * p_lncp_init); + + +#ifdef __cplusplus +} +#endif + +#endif //BLE_LN_CTRLPT_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_db.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_db.c new file mode 100644 index 0000000000000000000000000000000000000000..c4ea62a947188372537e4ccb3d9373f524ca8ddf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_db.c @@ -0,0 +1,151 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_ln_db.h" +#include "ble_ln_common.h" + +typedef struct +{ + bool in_use_flag; + ble_lns_route_t record; +} database_entry_t; + +static database_entry_t m_database[BLE_LNS_MAX_NUM_ROUTES]; +static uint8_t m_database_crossref[BLE_LNS_MAX_NUM_ROUTES]; +static uint16_t m_num_records; + +void ble_ln_db_init(void) +{ + int i; + + for (i = 0; i < BLE_LNS_MAX_NUM_ROUTES; i++) + { + m_database[i].in_use_flag = false; + m_database_crossref[i] = 0xFF; + } + + m_num_records = 0; +} + + +uint16_t ble_ln_db_num_records_get(void) +{ + return m_num_records; +} + + +ret_code_t ble_ln_db_record_get(uint8_t rec_ndx, ble_lns_route_t * p_rec) +{ + if (rec_ndx >= m_num_records) + { + return NRF_ERROR_INVALID_PARAM; + } + + // copy record to the specified memory + *p_rec = m_database[m_database_crossref[rec_ndx]].record; + + return NRF_SUCCESS; +} + + +ret_code_t ble_ln_db_record_name_get(uint8_t rec_ndx, uint8_t ** p_buf) +{ + if (rec_ndx >= m_num_records) + { + return NRF_ERROR_INVALID_PARAM; + } + + // copy record to the specified memory + *p_buf = m_database[m_database_crossref[rec_ndx]].record.route_name; + + return NRF_SUCCESS; +} + + +ret_code_t ble_ln_db_record_add(ble_lns_route_t * p_rec) +{ + int i; + + if (m_num_records == BLE_LNS_MAX_NUM_ROUTES) + { + return NRF_ERROR_NO_MEM; + } + + // find next available database entry + for (i = 0; i < BLE_LNS_MAX_NUM_ROUTES; i++) + { + if (!m_database[i].in_use_flag) + { + m_database[i].in_use_flag = true; + m_database[i].record = *p_rec; + m_database[i].record.route_id = i; + m_database_crossref[m_num_records] = i; + p_rec->route_id = i; + m_num_records++; + return NRF_SUCCESS; + } + } + + return NRF_ERROR_NO_MEM; +} + + +ret_code_t ble_ln_db_record_delete(uint8_t rec_ndx) +{ + int i; + + if (rec_ndx >= m_num_records) + { + return NRF_ERROR_NOT_FOUND; + } + + // free entry + m_database[m_database_crossref[rec_ndx]].in_use_flag = false; + + // decrease number of records + m_num_records--; + + // remove cross reference index + for (i = rec_ndx; i < m_num_records; i++) + { + m_database_crossref[i] = m_database_crossref[i + 1]; + } + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_db.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_db.h new file mode 100644 index 0000000000000000000000000000000000000000..a3604cba5e6dc5e2f9aa129edfcd58b4501e135b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_ln_db.h @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_srv_ln_db Location and Navigation database + * @{ + * @ingroup ble_sdk_srv + * @brief Location and Navigation route database + */ + +#ifndef BLE_LN_DB__ +#define BLE_LN_DB__ + +#include "ble_lns.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Function for initializing the route database. + * + * @details This call initializes the database holding route records. + * + * @return NRF_SUCCESS on success. + */ +void ble_ln_db_init(void); + +/**@brief Function for getting the number of records in the database. + * + * @details This call returns the number of records in the database. + * + * @return Number of records in the database. + */ +uint16_t ble_ln_db_num_records_get(void); + +/**@brief Function for getting a record from the database. + * + * @details This call returns a specified record from the database. + * + * @param[in] record_num Index of the record to retrieve. + * @param[out] p_rec Pointer to record structure where retrieved record is copied to. + * + * @return NRF_SUCCESS on success. + */ +ret_code_t ble_ln_db_record_get(uint8_t record_num, ble_lns_route_t * p_rec); + +/**@brief Function for getting a record name from the database. + * + * @details This call returns a specified record name from the database. + * + * @param[in] rec_ndx Index of the record to retrieve. + * @param[out] p_buf Pointer to array where retrieved record name is copied to. + * + * @return NRF_SUCCESS on success. + */ +ret_code_t ble_ln_db_record_name_get(uint8_t rec_ndx, uint8_t ** p_buf); + +/**@brief Function for adding a record at the end of the database. + * + * @details This call adds a record as the last record in the database. + * + * @param[in] p_rec Pointer to record to add to database. + * + * @return NRF_SUCCESS on success. + */ +ret_code_t ble_ln_db_record_add(ble_lns_route_t * p_rec); + +/**@brief Function for deleting a database entry. + * + * @details This call deletes an record from the database. + * + * @param[in] record_num Index of record to delete. + * + * @return NRF_SUCCESS on success. + */ +ret_code_t ble_ln_db_record_delete(uint8_t record_num); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_LN_DB_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_lns.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_lns.c new file mode 100644 index 0000000000000000000000000000000000000000..aa8b253e6a5cf23381268f9534e8f43ccf617fbf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_lns.c @@ -0,0 +1,1015 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_lns.h" +#include "ble_ln_db.h" +#include "ble_ln_common.h" +#include "sdk_common.h" + +#define NRF_LOG_MODULE_NAME "BLE_LNS" +#include "nrf_log.h" + +// Location and Speed flag bits +#define LOC_SPEED_FLAG_INSTANT_SPEED_PRESENT (0x01 << 0) /**< Instantaneous Speed Present bit. */ +#define LOC_SPEED_FLAG_TOTAL_DISTANCE_PRESENT (0x01 << 1) /**< Total Distance Present bit. */ +#define LOC_SPEED_FLAG_LOCATION_PRESENT (0x01 << 2) /**< Location Present bit. */ +#define LOC_SPEED_FLAG_ELEVATION_PRESENT (0x01 << 3) /**< Elevation Present bit. */ +#define LOC_SPEED_FLAG_HEADING_PRESENT (0x01 << 4) /**< Heading Present bit. */ +#define LOC_SPEED_FLAG_ROLLING_TIME_PRESENT (0x01 << 5) /**< Rolling Time Present bit. */ +#define LOC_SPEED_FLAG_UTC_TIME_PRESENT (0x01 << 6) /**< UTC Time Present bit. */ +#define LOC_SPEED_FLAG_POSITION_STATUS (0x03 << 7) /**< Position Status bits(2). */ +#define LOC_SPEED_FLAG_SPEED_AND_DIST_FORMAT (0x01 << 9) /**< Speed and Distance Format. */ +#define LOC_SPEED_FLAG_ELEVATION_SOURCE (0x03 << 10) /**< Elevation Source bits(2). */ +#define LOC_SPEED_FLAG_HEADING_SOURCE (0x01 << 12) /**< Heading Source. */ + +// Position Quality flag bits +#define POS_QUAL_FLAG_NUM_SATS_IN_SOLUTION_PRESENT (0x01 << 0) /**< Number of Satellites in Solution Present bit. */ +#define POS_QUAL_FLAG_NUM_SATS_IN_VIEW_PRESENT (0x01 << 1) /**< Number of Satellites in View Present bit. */ +#define POS_QUAL_FLAG_TIME_TO_FIRST_FIX_PRESESNT (0x01 << 2) /**< Time to First Fix Present bit. */ +#define POS_QUAL_FLAG_EHPE_PRESENT (0x01 << 3) /**< EHPE Present bit. */ +#define POS_QUAL_FLAG_EVPE_PRESENT (0x01 << 4) /**< EVPE Present bit. */ +#define POS_QUAL_FLAG_HDOP_PRESENT (0x01 << 5) /**< HDOP Present bit. */ +#define POS_QUAL_FLAG_VDOP_PRESENT (0x01 << 6) /**< VDOP Present bit. */ +#define POS_QUAL_FLAG_POSITION_STATUS (0x03 << 7) /**< Position Status bits(2). */ + +// Navigation flag bits +#define NAV_FLAG_REMAINING_DIST_PRESENT (0x01 << 0) /**< Remaining Distance Present bit. */ +#define NAV_FLAG_REAMINGING_VERT_DIST_PRESESNT (0x01 << 1) /**< Remaining Vertical Distance Present bit . */ +#define NAV_FLAG_ETA_PRESENT (0x01 << 2) /**< Estimated Time of Arrival Present bit. */ +#define NAV_FLAG_POSITION_STATUS (0x03 << 3) /**< Position Status bits(2). */ +#define NAV_FLAG_HEADING_SOURCE (0x01 << 5) /**< Heading Source bit. */ +#define NAV_FLAG_NAVIGATION_INDICATOR_TYPE (0x01 << 6) /**< Navigation Indicator Type bit. */ +#define NAV_FLAG_WAYPOINT_REACHED (0x01 << 7) /**< Waypoint Reached bit. */ +#define NAV_FLAG_DESTINATION_REACHED (0x01 << 8) /**< Destination Reached bit. */ + +#define BLE_LNS_NAV_MAX_LEN 19 /**< The length of a navigation notification when all features are enabled. See @ref ble_lns_navigation_t to see what this represents, or check https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.navigation.xml. */ + + +static void notification_buffer_process(ble_lns_t * p_lns) +{ + notification_t * p_notification; + + // See if a notification is pending + if (p_lns->pending_loc_speed_notifications[0].is_pending == true) + { + p_notification = &p_lns->pending_loc_speed_notifications[0]; + } + else if (p_lns->pending_loc_speed_notifications[1].is_pending == true) + { + p_notification = &p_lns->pending_loc_speed_notifications[1]; + } + else if (p_lns->pending_navigation_notification.is_pending == true) + { + p_notification = &p_lns->pending_navigation_notification; + } + else + { + p_notification = NULL; + } + + // send the notification if necessary + if (p_notification != NULL) + { + uint32_t err_code; + ble_gatts_hvx_params_t hvx_params; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + uint16_t hvx_len = p_notification->len; + + hvx_params.handle = p_notification->handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = &p_notification->data[0]; + + err_code = sd_ble_gatts_hvx(p_lns->conn_handle, &hvx_params); + + if ((err_code == NRF_SUCCESS) && (hvx_len == p_notification->len)) + { + p_notification->is_pending = false; + } + } +} + + +/**@brief Connect event handler. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connect(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt) +{ + p_lns->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + + // clear pending notifications + p_lns->pending_loc_speed_notifications[0].is_pending = false; + p_lns->pending_loc_speed_notifications[1].is_pending = false; + p_lns->pending_navigation_notification.is_pending = false; +} + + +/**@brief Disconnect event handler. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_disconnect(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt) +{ + if (p_lns->conn_handle != p_ble_evt->evt.gatts_evt.conn_handle) + { + return; + } + + p_lns->conn_handle = BLE_CONN_HANDLE_INVALID; +} + + +/**@brief Handle write events to the control point cccd. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_ctrl_pt_cccd_write(ble_lns_t * p_lns, ble_gatts_evt_write_t const * p_evt_write) +{ + if (p_evt_write->len == BLE_CCCD_VALUE_LEN) + { + if (p_lns->evt_handler != NULL) + { + ble_lns_evt_t evt; + + if (ble_srv_is_indication_enabled(p_evt_write->data)) + { + evt.evt_type = BLE_LNS_CTRLPT_EVT_INDICATION_ENABLED; + } + else + { + evt.evt_type = BLE_LNS_CTRLPT_EVT_INDICATION_DISABLED; + } + + p_lns->evt_handler(p_lns, &evt); + } + } +} + + +/**@brief Handle write events to the Location and Speed cccd. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_loc_speed_cccd_write(ble_lns_t * p_lns, + ble_gatts_evt_write_t const * p_evt_write) +{ + if (p_evt_write->len == BLE_CCCD_VALUE_LEN) + { + // CCCD written, update notification state + p_lns->is_loc_speed_notification_enabled = ble_srv_is_notification_enabled(p_evt_write->data); + if (p_lns->evt_handler != NULL) + { + ble_lns_evt_t evt; + + if (p_lns->is_loc_speed_notification_enabled) + { + evt.evt_type = BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_ENABLED; + } + else + { + evt.evt_type = BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_DISABLED; + } + + p_lns->evt_handler(p_lns, &evt); + } + } +} + + +/**@brief Handle write events to the navigation cccd. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_nav_cccd_write(ble_lns_t * p_lns, + ble_gatts_evt_write_t const * p_evt_write) +{ + if (p_evt_write->len == BLE_CCCD_VALUE_LEN) + { + p_lns->is_nav_notification_enabled = ble_srv_is_notification_enabled(p_evt_write->data); + if (p_lns->evt_handler != NULL) + { + ble_lns_evt_t evt; + + if (p_lns->is_nav_notification_enabled) + { + evt.evt_type = BLE_LNS_NAVIGATION_EVT_NOTIFICATION_ENABLED; + } + else + { + evt.evt_type = BLE_LNS_NAVIGATION_EVT_NOTIFICATION_DISABLED; + } + + p_lns->evt_handler(p_lns, &evt); + } + } +} + + +/**@brief Write event handler. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt) +{ + if (p_lns->conn_handle != p_ble_evt->evt.gatts_evt.conn_handle) + { + return; + } + + const ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if (p_evt_write->handle == p_lns->ctrlpt_handles.cccd_handle) + { + on_ctrl_pt_cccd_write(p_lns, p_evt_write); + } + else if (p_evt_write->handle == p_lns->loc_speed_handles.cccd_handle) + { + on_loc_speed_cccd_write(p_lns, p_evt_write); + } + else if (p_evt_write->handle == p_lns->navigation_handles.cccd_handle) + { + on_nav_cccd_write(p_lns, p_evt_write); + } +} + + +/**@brief Tx Complete event handler. This is used to retry sending a packet. + * + * @details Tx Complete event handler. + * Handles WRITE events from the BLE stack and if an indication was pending try sending it + * again. + * + * @param[in] p_lns Location navigation structure. + */ +static void on_tx_complete(ble_lns_t * p_lns) +{ + notification_buffer_process(p_lns); +} + + +/**@brief Encode position quality. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_pos_qual Position quality data to be encoded. + * @param[out] p_encoded_buffer Buffer where the encoded data will be written. + * + * @return Size of encoded data. + */ +static uint8_t pos_qual_encode(ble_lns_t const * p_lns, + ble_lns_pos_quality_t const * p_pos_qual, + uint8_t * p_encoded_buffer) +{ + uint16_t flags = 0; + uint8_t len = 2; // flags are added at last + + flags |= ((uint16_t)p_pos_qual->position_status << 7) & POS_QUAL_FLAG_POSITION_STATUS; + + if (p_pos_qual->number_of_satellites_in_solution_present) + { + flags |= POS_QUAL_FLAG_NUM_SATS_IN_SOLUTION_PRESENT; + p_encoded_buffer[len++] = p_pos_qual->number_of_satellites_in_solution; + } + + if (p_pos_qual->number_of_satellites_in_view_present) + { + flags |= POS_QUAL_FLAG_NUM_SATS_IN_VIEW_PRESENT; + p_encoded_buffer[len++] = p_pos_qual->number_of_satellites_in_view; + } + + if (p_pos_qual->time_to_first_fix_present) + { + flags |= POS_QUAL_FLAG_TIME_TO_FIRST_FIX_PRESESNT; + len += uint16_encode(p_pos_qual->time_to_first_fix, &p_encoded_buffer[len]); + } + + if (p_pos_qual->ehpe_present) + { + flags |= POS_QUAL_FLAG_EHPE_PRESENT; + len += uint32_encode(p_pos_qual->ehpe, &p_encoded_buffer[len]); + } + + if (p_pos_qual->evpe_present) + { + flags |= POS_QUAL_FLAG_EVPE_PRESENT; + len += uint32_encode(p_pos_qual->evpe, &p_encoded_buffer[len]); + } + + if (p_pos_qual->hdop_present) + { + flags |= POS_QUAL_FLAG_HDOP_PRESENT; + p_encoded_buffer[len++] = p_pos_qual->hdop; + } + + if (p_pos_qual->vdop_present) + { + flags |= POS_QUAL_FLAG_VDOP_PRESENT; + p_encoded_buffer[len++] = p_pos_qual->vdop; + } + + // Flags field + uint16_encode(flags, &p_encoded_buffer[0]); //lint !e534 "Ignoring return value of function" + + return len; +} + + +/**@brief Encode Location and Speed data packet 1 + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_loc_speed Location and Speed data to be encoded. + * @param[out] p_encoded_buffer Pointer to buffer buffer where encoded data will be written. + * + * @return Size of encoded data. + * + */ +static uint8_t loc_speed_encode_packet1(ble_lns_t const * p_lns, + ble_lns_loc_speed_t const * p_loc_speed, + uint8_t * p_encoded_buffer) +{ + uint16_t flags = 0; + uint8_t len = 2; + + const ble_lncp_mask_t mask = ble_lncp_mask_get(&p_lns->ctrl_pt); + + // Instantaneous Speed + if (p_lns->available_features & BLE_LNS_FEATURE_INSTANT_SPEED_SUPPORTED) + { + if (p_loc_speed->instant_speed_present && !mask.instantaneous_speed) + { + flags |= LOC_SPEED_FLAG_INSTANT_SPEED_PRESENT; + flags |= ((uint16_t)p_loc_speed->data_format<<9) & LOC_SPEED_FLAG_SPEED_AND_DIST_FORMAT; + len += uint16_encode(p_loc_speed->instant_speed, &p_encoded_buffer[len]); + } + } + + // Total Distance + if (p_lns->available_features & BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED) + { + if (p_loc_speed->total_distance_present && !mask.total_distance) + { + const uint32_t total_distance = ble_lncp_total_distance_get(&p_lns->ctrl_pt); + flags |= LOC_SPEED_FLAG_TOTAL_DISTANCE_PRESENT; + len += uint24_encode(total_distance, &p_encoded_buffer[len]); + } + } + + // Location + if (p_lns->available_features & BLE_LNS_FEATURE_LOCATION_SUPPORTED) + { + if (p_loc_speed->location_present && !mask.location) + { + flags |= LOC_SPEED_FLAG_LOCATION_PRESENT; + flags |= ((uint16_t)p_loc_speed->position_status <<7) & LOC_SPEED_FLAG_POSITION_STATUS; + len += uint32_encode(p_loc_speed->latitude, &p_encoded_buffer[len]); + len += uint32_encode(p_loc_speed->longitude, &p_encoded_buffer[len]); + } + } + + // Flags field + uint16_encode(flags, &p_encoded_buffer[0]); //lint !e534 "Ignoring return value of function" + + return len; +} + + +/**@brief Encode Location and Speed data packet 2 + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_loc_speed Location and Speed data to be encoded. + * @param[out] p_encoded_buffer Pointer to buffer buffer where encoded data will be written. + * + * @return Size of encoded data. + * + */ +static uint8_t loc_speed_encode_packet2(ble_lns_t const * p_lns, + ble_lns_loc_speed_t const * p_loc_speed, + uint8_t * p_encoded_buffer) +{ + uint16_t flags = 0; + uint8_t len = 2; + + const ble_lncp_mask_t mask = ble_lncp_mask_get(&p_lns->ctrl_pt); + + flags = 0; + len = 2; + + // Elevation + if (p_lns->available_features & BLE_LNS_FEATURE_ELEVATION_SUPPORTED) + { + if (p_loc_speed->elevation_present && !mask.elevation) + { + const uint32_t elevation = ble_lncp_elevation_get(&p_lns->ctrl_pt); + + flags |= LOC_SPEED_FLAG_ELEVATION_PRESENT; + flags |= ((uint16_t) p_loc_speed->elevation_source << 10) & LOC_SPEED_FLAG_ELEVATION_SOURCE; + len += uint24_encode(elevation, &p_encoded_buffer[len]); + } + } + + // Heading + if (p_lns->available_features & BLE_LNS_FEATURE_HEADING_SUPPORTED) + { + if (p_loc_speed->heading_present && !mask.heading) + { + flags |= LOC_SPEED_FLAG_HEADING_PRESENT; + flags |= ((uint16_t) p_loc_speed->heading_source << 12) & LOC_SPEED_FLAG_HEADING_SOURCE; + len += uint16_encode(p_loc_speed->heading, &p_encoded_buffer[len]); + } + } + + // Rolling Time + if (p_lns->available_features & BLE_LNS_FEATURE_ROLLING_TIME_SUPPORTED) + { + if ((p_loc_speed->rolling_time_present && !mask.rolling_time)) + { + flags |= LOC_SPEED_FLAG_ROLLING_TIME_PRESENT; + p_encoded_buffer[len++] = p_loc_speed->rolling_time; + } + } + + // UTC Time + if (p_lns->available_features & BLE_LNS_FEATURE_UTC_TIME_SUPPORTED) + { + if ((p_loc_speed->utc_time_time_present && !mask.utc_time)) + { + flags |= LOC_SPEED_FLAG_UTC_TIME_PRESENT; + len += ble_date_time_encode(&p_loc_speed->utc_time, &p_encoded_buffer[len]); + } + } + // Flags field + uint16_encode(flags, &p_encoded_buffer[0]); //lint !e534 "Ignoring return value of function" + + return len; +} + + +/**@brief Encode Navigation data. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_navigation Navigation data to be encoded. + * @param[out] p_encoded_buffer Buffer where the encoded data will be written. + * + * @return Size of encoded data. + */ +static uint8_t navigation_encode(ble_lns_t const * p_lns, + ble_lns_navigation_t const * p_navigation, + uint8_t * p_encoded_buffer) +{ + uint16_t flags = 0; + uint8_t len = 2; + + // Bearing + len += uint16_encode(p_navigation->bearing, &p_encoded_buffer[len]); + + // Heading + len += uint16_encode(p_navigation->heading, &p_encoded_buffer[len]); + + // Remaining Distance + if (p_lns->available_features & BLE_LNS_FEATURE_REMAINING_DISTANCE_SUPPORTED) + { + if (p_navigation->remaining_dist_present) + { + flags |= NAV_FLAG_REMAINING_DIST_PRESENT; + p_encoded_buffer[len++] = ((p_navigation->remaining_distance >> 0) & 0xFF); + p_encoded_buffer[len++] = ((p_navigation->remaining_distance >> 8) & 0xFF); + p_encoded_buffer[len++] = ((p_navigation->remaining_distance >> 16) & 0xFF); + } + } + + // Remaining Vertical Distance + if (p_lns->available_features & BLE_LNS_FEATURE_REMAINING_VERT_DISTANCE_SUPPORTED) + { + if (p_navigation->remaining_vert_dist_present) + { + flags |= NAV_FLAG_REAMINGING_VERT_DIST_PRESESNT; + p_encoded_buffer[len++] = ((p_navigation->remaining_vert_distance >> 0) & 0xFF); + p_encoded_buffer[len++] = ((p_navigation->remaining_vert_distance >> 8) & 0xFF); + p_encoded_buffer[len++] = ((p_navigation->remaining_vert_distance >> 16) & 0xFF); + } + } + + // Estimated Time of Arrival + if (p_lns->available_features & BLE_LNS_FEATURE_EST_TIME_OF_ARRIVAL_SUPPORTED) + { + if (p_navigation->eta_present) + { + flags |= NAV_FLAG_ETA_PRESENT; + len += ble_date_time_encode(&p_navigation->eta, &p_encoded_buffer[len]); + } + } + + flags |= ((uint16_t)p_navigation->position_status <<3) & NAV_FLAG_POSITION_STATUS; + flags |= ((uint16_t)p_navigation->heading_source <<5) & NAV_FLAG_HEADING_SOURCE; + flags |= ((uint16_t)p_navigation->navigation_indicator_type<<6)& NAV_FLAG_NAVIGATION_INDICATOR_TYPE; + flags |= ((uint16_t)p_navigation->waypoint_reached <<7)& NAV_FLAG_WAYPOINT_REACHED; + flags |= ((uint16_t)p_navigation->destination_reached <<8)& NAV_FLAG_DESTINATION_REACHED; + + // Flags field + uint16_encode(flags, &p_encoded_buffer[0]); //lint !e534 "Ignoring return value of function" + + return len; +} + + +/**@brief Add Location and Navigation Feature characteristic. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_lns_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static ret_code_t loc_and_nav_feature_char_add(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init) +{ + uint8_t init_value_encoded[sizeof(uint32_t)]; + uint8_t len; + ble_add_char_params_t add_char_params; + + len = uint32_encode(p_lns_init->available_features, init_value_encoded); + + memset(&add_char_params, 0, sizeof(add_char_params)); + + add_char_params.uuid = BLE_UUID_LN_FEATURE_CHAR; + add_char_params.max_len = len; + add_char_params.init_len = len; + add_char_params.p_init_value = &init_value_encoded[0]; + add_char_params.char_props.read = true; + add_char_params.read_access = p_lns_init->loc_nav_feature_security_req_read_perm; + + return characteristic_add(p_lns->service_handle, + &add_char_params, + &p_lns->feature_handles); +} + + +/**@brief Add Location and Speed characteristic. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_lns_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static ret_code_t loc_speed_char_add(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init) +{ + uint8_t encoded_initial_loc_speed1[BLE_GATT_ATT_MTU_DEFAULT]; + uint8_t len; + ble_add_char_params_t add_char_params; + + len = loc_speed_encode_packet1(p_lns, p_lns_init->p_location_speed, &encoded_initial_loc_speed1[0]); + + memset(&add_char_params, 0, sizeof(add_char_params)); + + add_char_params.uuid = BLE_UUID_LN_LOCATION_AND_SPEED_CHAR; + add_char_params.max_len = BLE_GATT_ATT_MTU_DEFAULT ; + add_char_params.init_len = len; + add_char_params.p_init_value = &encoded_initial_loc_speed1[0]; + add_char_params.is_var_len = true; + add_char_params.char_props.notify = true; + add_char_params.cccd_write_access = p_lns_init->loc_speed_security_req_cccd_write_perm; + + return characteristic_add(p_lns->service_handle, + &add_char_params, + &p_lns->loc_speed_handles); +} + + +/**@brief Add Location and Navigation position quality characteristic. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_lns_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static ret_code_t pos_quality_char_add(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init) +{ + uint8_t len; + uint8_t init_value_encoded[BLE_GATT_ATT_MTU_DEFAULT]; + ble_add_char_params_t add_char_params; + + len = pos_qual_encode(p_lns, p_lns_init->p_position_quality, init_value_encoded); + + memset(&add_char_params, 0, sizeof(add_char_params)); + + add_char_params.uuid = BLE_UUID_LN_POSITION_QUALITY_CHAR; + add_char_params.max_len = BLE_GATT_ATT_MTU_DEFAULT ; + add_char_params.init_len = len; + add_char_params.p_init_value = init_value_encoded; + add_char_params.char_props.read = true; + add_char_params.read_access = p_lns_init->position_quality_security_req_read_perm; + + return characteristic_add(p_lns->service_handle, + &add_char_params, + &p_lns->pos_qual_handles); +} + + +/**@brief Add Navigation characteristic. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_lns_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static ret_code_t navigation_char_add(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init) +{ + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + add_char_params.uuid = BLE_UUID_LN_NAVIGATION_CHAR; + add_char_params.max_len = BLE_LNS_NAV_MAX_LEN; + add_char_params.init_len = 0; + add_char_params.p_init_value = NULL; + add_char_params.char_props.notify = true; + add_char_params.cccd_write_access = p_lns_init->navigation_security_req_cccd_write_perm; + + return characteristic_add(p_lns->service_handle, + &add_char_params, + &p_lns->navigation_handles); +} + + +/** @brief Check if there is a mismatch in initialization parameters. + * + * @details It is possible to give an input which has an internal mismatch. Such a mismatch can arise in two different ways. + * One possibility is a mismatch between the characteristic present indicators and the available features specified. + * The other mismatch arises when no pointer to the characteristic data structure is specified. + * + * @param[in] p_lns_init The init structure which will be checked + * + * @return false if there is no mismatch. true if there is a mismatch + */ +static bool init_param_mismatch_present(ble_lns_init_t const * p_lns_init) +{ + if (p_lns_init->is_position_quality_present == false) + { + if (p_lns_init->available_features & + (BLE_LNS_FEATURE_NUM_SATS_IN_SOLUTION_SUPPORTED | + BLE_LNS_FEATURE_NUM_SATS_IN_VIEW_SUPPORTED | + BLE_LNS_FEATURE_TIME_TO_FIRST_FIX_SUPPORTED | + BLE_LNS_FEATURE_EST_HORZ_POS_ERROR_SUPPORTED | + BLE_LNS_FEATURE_EST_VERT_POS_ERROR_SUPPORTED | + BLE_LNS_FEATURE_HORZ_DILUTION_OF_PRECISION_SUPPORTED | + BLE_LNS_FEATURE_VERT_DILUTION_OF_PRECISION_SUPPORTED) + ) + { + return true; + } + if (p_lns_init->p_position_quality != NULL) + { + return true; + } + } + else if (p_lns_init->is_position_quality_present == true) + { + if (p_lns_init->p_position_quality == NULL) + { + return true; + } + } + + if (p_lns_init->is_control_point_present == false) + { + if (p_lns_init->available_features & + (BLE_LNS_FEATURE_LOC_AND_SPEED_CONTENT_MASKING_SUPPORTED | + BLE_LNS_FEATURE_FIX_RATE_SETTING_SUPPORTED | + BLE_LNS_FEATURE_ELEVATION_SETTING_SUPPORTED) + ) + { + return true; + } + } + + if (p_lns_init->is_navigation_present == false) + { + if (p_lns_init->available_features & + (BLE_LNS_FEATURE_REMAINING_DISTANCE_SUPPORTED | + BLE_LNS_FEATURE_REMAINING_VERT_DISTANCE_SUPPORTED | + BLE_LNS_FEATURE_EST_TIME_OF_ARRIVAL_SUPPORTED) + ) + { + return true; + } + if (p_lns_init->p_navigation != NULL) + { + return true; + } + } + else if (p_lns_init->is_navigation_present == true) + { + if (p_lns_init->p_navigation == NULL) + { + return true; + } + } + + // location and speed must always be specified + if (p_lns_init->p_location_speed == NULL) + { + return true; + } + + return false; +} + + +void ble_lns_on_ble_evt(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_lns); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + + ble_lncp_on_ble_evt(&p_lns->ctrl_pt, p_ble_evt); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_lns, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_lns, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_lns, p_ble_evt); + break; + + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + on_tx_complete(p_lns); + break; + + default: + // no implementation + break; + } +} + + +ret_code_t ble_lns_init(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init) +{ + VERIFY_PARAM_NOT_NULL(p_lns); + VERIFY_PARAM_NOT_NULL(p_lns_init); + + if (init_param_mismatch_present(p_lns_init) == true) + { + return NRF_ERROR_INVALID_PARAM; + } + + uint32_t err_code; + ble_uuid_t service_uuid; + ble_lncp_init_t lncp_init; + + // Initialize service structure + p_lns->evt_handler = p_lns_init->evt_handler; + p_lns->error_handler = p_lns_init->error_handler; + p_lns->conn_handle = BLE_CONN_HANDLE_INVALID; + p_lns->available_features = p_lns_init->available_features; + p_lns->is_navigation_present = p_lns_init->is_navigation_present; + + // clear pending notifications + p_lns->pending_loc_speed_notifications[0].is_pending = false; + p_lns->pending_loc_speed_notifications[1].is_pending = false; + p_lns->pending_navigation_notification.is_pending = false; + + p_lns->p_location_speed = p_lns_init->p_location_speed; + p_lns->p_position_quality = p_lns_init->p_position_quality; + p_lns->p_navigation = p_lns_init->p_navigation; + + p_lns->is_loc_speed_notification_enabled = false; + p_lns->is_nav_notification_enabled = false; + + ble_ln_db_init(); + + // Add service + BLE_UUID_BLE_ASSIGN(service_uuid, BLE_UUID_LOCATION_AND_NAVIGATION_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &service_uuid, &p_lns->service_handle); + VERIFY_SUCCESS(err_code); + + // Add location and navigation feature characteristic + err_code = loc_and_nav_feature_char_add(p_lns, p_lns_init); + VERIFY_SUCCESS(err_code); + + // Add location and speed characteristic + err_code = loc_speed_char_add(p_lns, p_lns_init); + VERIFY_SUCCESS(err_code); + + if (p_lns_init->is_position_quality_present) + { + // Add Position quality characteristic + err_code = pos_quality_char_add(p_lns, p_lns_init); + VERIFY_SUCCESS(err_code); + } + else + { + p_lns->pos_qual_handles.cccd_handle = BLE_GATT_HANDLE_INVALID; + p_lns->pos_qual_handles.sccd_handle = BLE_GATT_HANDLE_INVALID; + p_lns->pos_qual_handles.user_desc_handle = BLE_GATT_HANDLE_INVALID; + p_lns->pos_qual_handles.value_handle = BLE_GATT_HANDLE_INVALID; + } + + if (p_lns_init->is_navigation_present) + { + // Add navigation characteristic + err_code = navigation_char_add(p_lns, p_lns_init); + VERIFY_SUCCESS(err_code); + } + else + { + p_lns->navigation_handles.cccd_handle = BLE_GATT_HANDLE_INVALID; + p_lns->navigation_handles.sccd_handle = BLE_GATT_HANDLE_INVALID; + p_lns->navigation_handles.user_desc_handle = BLE_GATT_HANDLE_INVALID; + p_lns->navigation_handles.value_handle = BLE_GATT_HANDLE_INVALID; + } + + if (p_lns_init->is_control_point_present) + { + lncp_init.error_handler = p_lns_init->error_handler; + lncp_init.evt_handler = p_lns_init->lncp_evt_handler; + lncp_init.write_perm = p_lns_init->ctrl_point_security_req_write_perm; + lncp_init.cccd_write_perm = p_lns_init->ctrl_point_security_req_cccd_write_perm; + lncp_init.available_features = p_lns_init->available_features; + lncp_init.is_position_quality_present = p_lns_init->is_position_quality_present; + lncp_init.is_navigation_present = p_lns_init->is_navigation_present; + + lncp_init.total_distance = p_lns_init->p_location_speed->total_distance; + lncp_init.elevation = p_lns_init->p_location_speed->elevation; + + lncp_init.service_handle = p_lns->service_handle; + lncp_init.navigation_handles = p_lns->navigation_handles; + + // Add control pointer characteristic + err_code = ble_lncp_init(&p_lns->ctrl_pt, &lncp_init); + VERIFY_SUCCESS(err_code); + + memcpy(&p_lns->ctrlpt_handles, &p_lns->ctrl_pt.ctrlpt_handles, sizeof(ble_gatts_char_handles_t)); + } + + NRF_LOG_DEBUG("Initialized\r\n"); + + return NRF_SUCCESS; +} + + +ret_code_t ble_lns_loc_speed_send(ble_lns_t * p_lns) +{ + VERIFY_PARAM_NOT_NULL(p_lns); + + if (p_lns->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + + if (!p_lns->is_loc_speed_notification_enabled) + { + return NRF_ERROR_INVALID_STATE; + } + + notification_t * notif1 = &p_lns->pending_loc_speed_notifications[0]; + notification_t * notif2 = &p_lns->pending_loc_speed_notifications[1]; + + // clear previous unsent data. Previous data is invalid. + notif1->is_pending = false; + notif2->is_pending = false; + + // check if it is necessary to send packet 1 + if (p_lns->available_features & (BLE_LNS_FEATURE_INSTANT_SPEED_SUPPORTED + | BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED + | BLE_LNS_FEATURE_LOCATION_SUPPORTED)) + { + // encode + notif1->len = loc_speed_encode_packet1(p_lns, p_lns->p_location_speed, ¬if1->data[0]); + notif1->handle = p_lns->loc_speed_handles.value_handle; + notif1->is_pending = true; + + // send + notification_buffer_process(p_lns); + } + + // check if it is necessary to send packet 2 + if (p_lns->available_features & (BLE_LNS_FEATURE_ELEVATION_SUPPORTED + | BLE_LNS_FEATURE_HEADING_SUPPORTED + | BLE_LNS_FEATURE_ROLLING_TIME_SUPPORTED + | BLE_LNS_FEATURE_UTC_TIME_SUPPORTED)) + { + notif2->len = loc_speed_encode_packet2(p_lns, p_lns->p_location_speed, ¬if2->data[0]); + notif2->handle = p_lns->loc_speed_handles.value_handle; + notif2->is_pending = true; + + // send + notification_buffer_process(p_lns); + } + + return NRF_SUCCESS; +} + + +ret_code_t ble_lns_navigation_send(ble_lns_t * p_lns) +{ + VERIFY_PARAM_NOT_NULL(p_lns); + + if (p_lns->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + + notification_t * notif = &p_lns->pending_navigation_notification; + + // clear previous unsent data. Previous data is invalid. + notif->is_pending = false; + + if (!p_lns->is_navigation_present) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if (!p_lns->is_nav_notification_enabled) + { + return NRF_ERROR_INVALID_STATE; + } + + if (!ble_lncp_is_navigation_running(&p_lns->ctrl_pt)) + { + return NRF_ERROR_INVALID_STATE; + } + + notif->len = navigation_encode(p_lns, p_lns->p_navigation, ¬if->data[0]); + notif->handle = p_lns->navigation_handles.value_handle; + notif->is_pending = true; + + notification_buffer_process(p_lns); + + return NRF_SUCCESS; +} + + +ret_code_t ble_lns_add_route(ble_lns_t * p_lns, ble_lns_route_t * p_route) +{ + VERIFY_PARAM_NOT_NULL(p_lns); + VERIFY_PARAM_NOT_NULL(p_route); + + if (p_lns->is_navigation_present == false) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return ble_ln_db_record_add(p_route); +} + + +ret_code_t ble_lns_remove_route(ble_lns_t * p_lns, uint16_t route_id) +{ + VERIFY_PARAM_NOT_NULL(p_lns); + + if (p_lns->is_navigation_present == false) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return ble_ln_db_record_delete(route_id); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_lns.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_lns.h new file mode 100644 index 0000000000000000000000000000000000000000..958883702e7604fe8a94d348583087074af7d67a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_ble_lns/ble_lns.h @@ -0,0 +1,368 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_lns Location and Navigation Service + * @{ + * @ingroup ble_sdk_srv + * @brief Location and Navigation Service module. + * + * @details This module implements the Location and Navigation Service with the Location and Speed, Position + * Quality, Feature, Control Point, and Navigation characteristics. + * + * If an event handler is supplied by the application, the Location and Navigation Service will + * generate Location and Navigation Service events to the application. + * + * @note The application must propagate BLE stack events to the Location and Navigation Service module by calling + * @ref ble_lns_on_ble_evt() from the from the ble_stack_handler callback. + */ + +#ifndef BLE_LNS_H__ +#define BLE_LNS_H__ + +#include "ble_srv_common.h" +#include "ble_date_time.h" +#include "ble_ln_common.h" +#include "ble_ln_cp.h" +#include "sdk_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Location and Navigation event type. This list defines the possible events types from the Location and Navigation Service. */ +typedef enum { + BLE_LNS_CTRLPT_EVT_INDICATION_ENABLED, /**< Control Point value indication was enabled. */ + BLE_LNS_CTRLPT_EVT_INDICATION_DISABLED, /**< Control Point value indication was disabled. */ + BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_ENABLED, /**< Location and Speed value notification was enabled. */ + BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_DISABLED, /**< Location and Speed value notification was disabled. */ + BLE_LNS_NAVIGATION_EVT_NOTIFICATION_ENABLED, /**< Navigation value notification was enabled. */ + BLE_LNS_NAVIGATION_EVT_NOTIFICATION_DISABLED, /**< Navigation value notification was disabled. */ +} ble_lns_evt_type_t; + +/** @brief Location and Navigation event structure. When an event occurs, the data structures of the module are automatically updated. */ +typedef struct { + ble_lns_evt_type_t evt_type; +} ble_lns_evt_t; + +// Forward declarations of the ble_lns types. +typedef struct ble_lns_init_s ble_lns_init_t; +typedef struct ble_lns_s ble_lns_t; +typedef struct ble_lns_loc_speed_s ble_lns_loc_speed_t; +typedef struct ble_lns_pos_quality_s ble_lns_pos_quality_t; +typedef struct ble_lns_navigation_s ble_lns_navigation_t; + + +typedef struct { + bool is_pending; + uint16_t handle; + uint16_t len; +#if (NRF_SD_BLE_API_VERSION <= 3) + uint8_t data[GATT_MTU_SIZE_DEFAULT]; +#else + uint8_t data[BLE_GATT_ATT_MTU_DEFAULT]; +#endif +} notification_t; + + +/**@brief Location and Navigation Service event handler type. */ +typedef void (*ble_lns_evt_handler_t) (ble_lns_t const * p_lns, ble_lns_evt_t const * p_evt); + + +/**@brief Location and Navigation Service init structure. This structure contains all options and data needed to + * initialize the service. */ +struct ble_lns_init_s +{ + ble_lns_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Location and Navigation Service. */ + ble_lncp_evt_handler_t lncp_evt_handler; + ble_srv_error_handler_t error_handler; /**< Errors will be sent back to this function. */ + + bool is_position_quality_present; /**< If set to true, the position quality characteristic will be added. Else not. */ + bool is_control_point_present; /**< If set to true, the control point characteristic will be added. Else not. */ + bool is_navigation_present; /**< If set to true, the navigation characteristic will be added. Else not. */ + + security_req_t loc_nav_feature_security_req_read_perm; /**< Read security level of the LN Feature characteristic. */ + security_req_t loc_speed_security_req_cccd_write_perm; /**< CCCD write security level of the Write Location and Speed characteristic. */ + security_req_t position_quality_security_req_read_perm; /**< Read security level of the Position Quality characteristic. */ + security_req_t navigation_security_req_cccd_write_perm; /**< CCCD write security level of the Navigation characteristic. */ + security_req_t ctrl_point_security_req_write_perm; /**< Read security level of the LN Control Point characteristic. */ + security_req_t ctrl_point_security_req_cccd_write_perm; /**< CCCD write security level of the LN Control Point characteristic. */ + + uint32_t available_features; /**< Value of the LN feature. */ + ble_lns_loc_speed_t * p_location_speed; /**< Initial Location and Speed. */ + ble_lns_pos_quality_t * p_position_quality; /**< Initial Position Quality. */ + ble_lns_navigation_t * p_navigation; /**< Initial Navigation data structure. */ +}; + + +/**@brief Definition of a navigation route.*/ +typedef struct +{ + uint16_t route_id; + uint8_t route_name[BLE_LNS_MAX_ROUTE_NAME_LEN]; +} ble_lns_route_t; + + +/**@brief Location and Navigation Service structure. This structure contains various status information for the service. */ +struct ble_lns_s +{ + ble_lns_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Location and Navigation Service. */ + ble_srv_error_handler_t error_handler; /**< Error handler. */ + + bool is_navigation_present; /**< If set to true, the navigation characteristic is present. Else not. */ + + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack; BLE_CONN_HANDLE_INVALID if not in a connection). */ + uint16_t service_handle; /**< Handle of Location and Navigation Service (as provided by the BLE stack). */ + ble_gatts_char_handles_t loc_speed_handles; /**< Handles related to the Location and Speed characteristic. */ + ble_gatts_char_handles_t feature_handles; /**< Handles related to the Location and Navigation Feature characteristic. */ + ble_gatts_char_handles_t navigation_handles; /**< Handles related to the Navigation characteristic. */ + ble_gatts_char_handles_t pos_qual_handles; /**< Handles related to the Position Quality characteristic. */ + ble_gatts_char_handles_t ctrlpt_handles; + uint32_t available_features; /**< Value of Location and Navigation feature. */ + + bool is_loc_speed_notification_enabled; /**< True if notification is enabled on the Location and Speed characteristic. */ + bool is_nav_notification_enabled; /**< True if notification is enabled on the Navigation characteristic. */ + + notification_t pending_loc_speed_notifications[2]; /**< This buffer holds location and speed notifications. */ + notification_t pending_navigation_notification; /**< This buffer holds navigation notifications. */ + ble_lns_loc_speed_t * p_location_speed; /**< Location and Speed. */ + ble_lns_pos_quality_t * p_position_quality; /**< Position measurement quality. */ + ble_lns_navigation_t * p_navigation; /**< Navigation data structure. */ + ble_lncp_t ctrl_pt; +}; + + +/** @brief Position status. This enumeration defines how to interpret the position data. */ +typedef enum +{ + BLE_LNS_NO_POSITION = 0, + BLE_LNS_POSITION_OK = 1, + BLE_LNS_ESTIMATED = 2, + BLE_LNS_LAST_KNOWN_POSITION = 3 +} ble_lns_pos_status_type_t; + + +/** @brief The format of the position and speed measurements. */ +typedef enum +{ + BLE_LNS_SPEED_DISTANCE_FORMAT_2D = 0, + BLE_LNS_SPEED_DISTANCE_FORMAT_3D = 1 +} ble_lns_speed_distance_format_t; + + +/** @brief Elevation source. */ +typedef enum +{ + BLE_LNS_ELEV_SOURCE_POSITIONING_SYSTEM = 0, + BLE_LNS_ELEV_SOURCE_BAROMETRIC = 1, + BLE_LNS_ELEV_SOURCE_DATABASE_SERVICE = 2, + BLE_LNS_ELEV_SOURCE_OTHER = 3 +} ble_lns_elevation_source_t; + + +/** @brief Heading source. */ +typedef enum +{ + BLE_LNS_HEADING_SOURCE_MOVEMENT = 0, + BLE_LNS_HEADING_SOURCE_COMPASS = 1 +} ble_lns_heading_source_t; + + +/**@brief Location and Speed data structure. */ +struct ble_lns_loc_speed_s +{ + bool instant_speed_present; /**< Instantaneous Speed present (0=not present, 1=present). */ + bool total_distance_present; /**< Total Distance present (0=not present, 1=present). */ + bool location_present; /**< Location present (0=not present, 1=present). */ + bool elevation_present; /**< Elevation present (0=not present, 1=present). */ + bool heading_present; /**< Heading present (0=not present, 1=present). */ + bool rolling_time_present; /**< Rolling Time present (0=not present, 1=present). */ + bool utc_time_time_present; /**< UTC Time present (0=not present, 1=present). */ + ble_lns_pos_status_type_t position_status; /**< Status of current position */ + ble_lns_speed_distance_format_t data_format; /**< Format of data (either 2D or 3D). */ + ble_lns_elevation_source_t elevation_source; /**< Source of the elevation measurement. */ + ble_lns_heading_source_t heading_source; /**< Source of the heading measurement. */ + uint16_t instant_speed; /**< Instantaneous Speed (1/10 meter per sec). */ + uint32_t total_distance; /**< Total Distance (meters), size=24 bits. */ + int32_t latitude; /**< Latitude (10e-7 degrees). */ + int32_t longitude; /**< Longitude (10e-7 degrees). */ + int32_t elevation; /**< Elevation (1/100 meters), size=24 bits. */ + uint16_t heading; /**< Heading (1/100 degrees). */ + uint8_t rolling_time; /**< Rolling Time (seconds). */ + ble_date_time_t utc_time; /**< UTC Time. */ +}; + + +/** @brief Position quality structure. */ +struct ble_lns_pos_quality_s +{ + bool number_of_satellites_in_solution_present; /**< The number of satellites present in solution (0=not present, 1=present). */ + bool number_of_satellites_in_view_present; /**< The number of satellites present in solution (0=not present, 1=present). */ + bool time_to_first_fix_present; /**< Time to the first position fix present (0=not present, 1=present). */ + bool ehpe_present; /**< Error in horizontal position estimate present (0=not present, 1=present). */ + bool evpe_present; /**< Error in vertical position estimate present (0=not present, 1=present). */ + bool hdop_present; /**< Horizontal dilution of precision present (0=not present, 1=present). */ + bool vdop_present; /**< Vertical dilution of precision present (0=not present, 1=present). */ + ble_lns_pos_status_type_t position_status; /**< Status of last measured position. */ + uint8_t number_of_satellites_in_solution; /**< The number of satellites in solution (unitless, with a resolution of 1). */ + uint8_t number_of_satellites_in_view; /**< The number of satellites in view (unitless, with a resolution of 1). */ + uint16_t time_to_first_fix; /**< Time to the first position fix (seconds, with a resolution of 1/10). */ + uint32_t ehpe; /**< Error in horizontal position estimate (meters, with a resolution of 1/100). */ + uint32_t evpe; /**< Error in vertical position estimate (meters, with a resolution of 1/100). */ + uint8_t hdop; /**< Horizontal dilution of precision (unitless, with a resolution of 2/10). */ + uint8_t vdop; /**< Vertical dilution of precision (unitless, with a resolution of 2/10). */ +}; + + +/** @brief Navigation indicator type. */ +typedef enum +{ + BLE_LNS_NAV_TO_WAYPOINT = 0, + BLE_LNS_NAV_TO_DESTINATION = 1 +} ble_lns_nav_indicator_type_t; + + +/**@brief Navigation data structure. */ +struct ble_lns_navigation_s +{ + bool remaining_dist_present; /**< Remaining Distance present (0=not present, 1=present). */ + bool remaining_vert_dist_present; /**< Remaining Vertical Distance present (0=not present, 1=present). */ + bool eta_present; /**< Estimated Time of Arrival present (0=not present, 1=present). */ + ble_lns_pos_status_type_t position_status; /**< Status of last measured position. */ + ble_lns_heading_source_t heading_source; /**< Source of the heading measurement. */ + ble_lns_nav_indicator_type_t navigation_indicator_type; /**< Navigation indicator type. */ + bool waypoint_reached; /**< Waypoint Reached (0=not reached, 1=reached). */ + bool destination_reached; /**< Destination Reached (0=not reached, 1=reached). */ + uint16_t bearing; /**< Bearing (1/100 degrees).*/ + uint16_t heading; /**< Heading (1/100 degrees), size=24 bit. */ + uint32_t remaining_distance; /**< Remaining Distance (1/10 meters), size=24 bit. */ + int32_t remaining_vert_distance; /**< Remaining Vertical Distance (1/100 meters), size=24 bit. */ + ble_date_time_t eta; /**< Estimated Time of Arrival. */ +}; + + +/**@brief Function for initializing the Location and Navigation Service. + * + * @param[out] p_lns Location and Navigation Service structure. This structure must be supplied by + * the application. It is initialized by this function, and will later + * be used to identify this particular service instance. + * @param[in] p_lns_init Information needed to initialize the service. + * + * @retval NRF_SUCCESS If the service was initialized successfully. + * @retval NRF_ERROR_NULL If a NULL parameter was provided. + * @retval NRF_INVALID_PARAMS If there is an inconsistency in the initialization structure. + * @return Otherwise, an error code from either sd_ble_gatts_service_add() or sd_ble_gatts_characteristic_add() is returned. + */ +ret_code_t ble_lns_init(ble_lns_t * p_lns, const ble_lns_init_t * p_lns_init); + +/**@brief Function for handling Location and Navigation Service BLE stack events. + * + * @details This function handles all events from the BLE stack that are of interest to the Location and Navigation Service. + * + * @note The function returns when a NULL parameter is provided. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + * + */ +void ble_lns_on_ble_evt(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt); + +/**@brief Function for sending location and speed data if notification has been enabled. + * + * @details The application calls this function after having performed a location and speed determination. + * If notification has been enabled, the location and speed data is encoded and sent to + * the client. + * + * @param[in] p_lns Location and Navigation Service structure holding the location and speed data. + * + * @retval NRF_SUCCESS If the data was sent successfully. + * @retval NRF_ERROR_NULL If a NULL parameter was provided. + * @retval NRF_ERROR_INVALID_STATE If notification is disabled. + */ +ret_code_t ble_lns_loc_speed_send(ble_lns_t * p_lns); + +/**@brief Function for sending navigation data if notification has been enabled. + * + * @details The application calls this function after having performed a navigation determination. + * If notification has been enabled, the navigation data is encoded and sent to + * the client. + * + * @param[in] p_lns Location and Navigation Service structure holding the navigation data. + * + * @retval NRF_SUCCESS If the data was sent successfully. + * @retval NRF_ERROR_NULL If a NULL parameter was provided. + * @retval NRF_ERROR_NOT_SUPPORTED If the navigation characteristic is absent. + * @retval NRF_ERROR_INVALID_STATE If navigation is not running or notification is disabled. + */ +ret_code_t ble_lns_navigation_send(ble_lns_t * p_lns); + +/**@brief Function for adding a route to the Location and Navigation Service. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in,out] p_route The new route to be added. The route ID is updated. + * + * @retval NRF_SUCCESS If the route was added successfully. + * @retval NRF_ERROR_NULL If a NULL parameter was provided. + * @retval NRF_ERROR_NOT_SUPPORTED If the navigation characteristic is absent. + * @retval NRF_ERROR_NO_MEM If there is no memory left. + * @retval NRF_ERROR_INTERNAL If there is an inconsistency in the routes table. + */ +ret_code_t ble_lns_add_route(ble_lns_t * p_lns, ble_lns_route_t * p_route); + +/**@brief Function for removing a route from the Location and Navigation Service. + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] route_id The ID of the route to be removed. + * + * @retval NRF_SUCCESS If the route was removed successfully. + * @retval NRF_ERROR_NULL If a NULL parameter was provided. + * @retval NRF_ERROR_NOT_SUPPORTED If the navigation characteristic is absent. + * @retval NRF_INVALID_PARAM If the route ID does not exist. + */ +ret_code_t ble_lns_remove_route(ble_lns_t * p_lns, uint16_t route_id); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_LNS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.c new file mode 100644 index 0000000000000000000000000000000000000000..c974bc7ffe896090333a3d929d089f942178f52a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.c @@ -0,0 +1,615 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include + +#include "nrf_ble_bms.h" +#include "ble_srv_common.h" + +#define NRF_LOG_MODULE_NAME "BLE_BMS" +#include "nrf_log.h" + +/*@brief Check if a returned error code is NRF_SUCCESS, and call the error handler if not. + * + * @param[in] err_code Error code that should be checked. + * @param[in] err_handler Error handler that should be called. + */ +static void error_check(ret_code_t err_code, ble_srv_error_handler_t err_handler) +{ + if (err_code != NRF_SUCCESS) + { + err_handler(err_code); + } +} + + +/**@brief Function for adding the Bond Management Control Point characteristic. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_bms_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code returned by @ref characteristic_add. + */ +static ret_code_t ctrlpt_char_add(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t const * p_bms_init) +{ + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + add_char_params.uuid = BLE_UUID_BMS_CTRLPT; + add_char_params.char_props.write = 1; + add_char_params.is_defered_write = true; + add_char_params.is_var_len = true; + add_char_params.max_len = NRF_BLE_BMS_CTRLPT_MAX_LEN; + add_char_params.read_access = SEC_NO_ACCESS; + add_char_params.write_access = p_bms_init->bms_ctrlpt_sec_req; + + if (p_bms_init->p_qwr != NULL) + { + add_char_params.char_ext_props.reliable_wr = 1; + } + + return characteristic_add(p_bms->service_handle, &add_char_params, &p_bms->ctrlpt_handles); +} + + +/**@brief Forward an authorization request to the application, if necessary. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_ctrlpt Pointer to the received Control Point value. + */ +static void ctrlpt_auth(nrf_ble_bms_t * p_bms, nrf_ble_bms_ctrlpt_t * p_ctrlpt) +{ + nrf_ble_bms_features_t * p_feature = &p_bms->feature; + + p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_ALLOWED; + + /* Check if the authorization feature is enabled for this op code. */ + if (( + (p_ctrlpt->op_code == NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY) && + (p_feature->delete_requesting_auth) + ) || + ( + (p_ctrlpt->op_code == NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY) && + (p_feature->delete_all_auth) + ) || + ( + (p_ctrlpt->op_code == NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY) && + (p_feature->delete_all_but_requesting_auth) + ) + ) + { + if (p_bms->evt_handler != NULL) + { + nrf_ble_bms_evt_t bms_evt; + + memset(&bms_evt, 0, sizeof(bms_evt)); + bms_evt.evt_type = NRF_BLE_BMS_EVT_AUTH; + bms_evt.auth_code.len = p_ctrlpt->auth_code.len; + memcpy(bms_evt.auth_code.code, p_ctrlpt->auth_code.code, p_ctrlpt->auth_code.len); + + p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_PENDING; + + p_bms->evt_handler(p_bms, &bms_evt); + } + else + { + p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_DENIED; + } + } +} + + +/**@brief Decode an incoming Control Point write. + * + * @param[in] p_rcvd_val Received write value. + * @param[in] len Value length. + * @param[out] p_ctrlpt Decoded control point structure. + * + * @retval NRF_ERROR_INVALID_LENGTH The supplied value length is invalid. + * @retval NRF_ERROR_NOT_SUPPORTED The supplied op code is not supported. + * @retval NRF_SUCCESS Operation successful. + */ +static ret_code_t ctrlpt_decode(uint8_t * p_rcvd_val, uint16_t len, nrf_ble_bms_ctrlpt_t * p_ctrlpt) +{ + uint16_t pos = 0; + + VERIFY_TRUE(len >= NRF_BLE_BMS_CTRLPT_MIN_LEN, NRF_ERROR_INVALID_LENGTH); + VERIFY_TRUE(len <= NRF_BLE_BMS_CTRLPT_MAX_LEN, NRF_ERROR_INVALID_LENGTH); + + p_ctrlpt->op_code = (nrf_ble_bms_op_t) p_rcvd_val[pos++]; + p_ctrlpt->auth_code.len = (len - pos); + memcpy(p_ctrlpt->auth_code.code, &(p_rcvd_val[pos]), p_ctrlpt->auth_code.len); + + return NRF_SUCCESS; +} + + +/**@brief Function for performing an operation requested through the Control Point. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] op_code Op code to execute. + */ +static void ctrlpt_execute(nrf_ble_bms_t * p_bms, nrf_ble_bms_op_t op_code) +{ + switch (op_code) + { + case NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY: + /* Delete single bond */ + p_bms->bond_callbacks.delete_requesting(p_bms); + break; // NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY + + case NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY: + /* Delete all bonds */ + p_bms->bond_callbacks.delete_all(p_bms); + break; // NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY + + case NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY: + /* Delete all but current bond */ + p_bms->bond_callbacks.delete_all_except_requesting(p_bms); + break; // NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY + + default: + /* No implemementation needed. */ + break; + } +} + + +/*@brief Validate an incoming Control Point write. + * + * @param[in] op_code Received op code. + * @param[in] p_feature Supported features. + * + * @returns True if the op code is supported, or false. + */ +static bool ctrlpt_validate(nrf_ble_bms_ctrlpt_t * p_ctrlpt, nrf_ble_bms_features_t * p_feature) +{ + switch (p_ctrlpt->op_code) + { + case NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY: + if (p_feature->delete_requesting || p_feature->delete_requesting_auth) + { + return true; + } + break; + + case NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY: + if (p_feature->delete_all || p_feature->delete_all_auth) + { + return true; + } + break; + + case NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY: + if (p_feature->delete_all_but_requesting || p_feature->delete_all_but_requesting_auth) + { + return true; + } + break; + + default: + /* No implementation needed. */ + break; + } + + return false; +} + + +/**@brief Function for processing a write to the Control Point. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_rcvd_val Received write value. + * @param[in] len Value length. + * @param[out] p_ctrlpt Decoded control point structure. + */ +static uint16_t ctrlpt_process(nrf_ble_bms_t * p_bms, + uint8_t * p_rcvd_val, + uint16_t len, + nrf_ble_bms_ctrlpt_t * p_ctrlpt) +{ + ret_code_t err_code; + + /* Decode operation */ + err_code = ctrlpt_decode(p_rcvd_val, len, p_ctrlpt); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Control point write: Operation failed.\r\n"); + return NRF_BLE_BMS_OPERATION_FAILED; + } + + /* Verify that the operation is allowed. */ + if (!ctrlpt_validate(p_ctrlpt, &p_bms->feature)) + { + NRF_LOG_ERROR("Control point write: Invalid op code.\r\n"); + return NRF_BLE_BMS_OPCODE_NOT_SUPPORTED; + } + + /* Request authorization */ + ctrlpt_auth(p_bms, p_ctrlpt); + if (p_bms->auth_status != NRF_BLE_BMS_AUTH_STATUS_ALLOWED) + { + NRF_LOG_ERROR("Control point long write: Invalid auth.\r\n"); + return BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION; + } + + return BLE_GATT_STATUS_SUCCESS; +} + + +/**@brief Function for encoding the Bond Management Feature characteristic. + * + * @param[in] p_bms Bond Management Service structure. + * @param[out] p_encoded_feature Encoded features. + * + * @return Size of the encoded feature. + */ +static uint8_t feature_encode(nrf_ble_bms_features_t const * p_feature, uint8_t * p_encoded_feature) +{ + uint32_t data = 0; + + if (p_feature->delete_all_auth) + { + data |= NRF_BLE_BMS_ALL_BONDS_LE_AUTH_CODE; + } + if (p_feature->delete_all_but_requesting_auth) + { + data |= NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE_AUTH_CODE; + } + if (p_feature->delete_all_but_requesting) + { + data |= NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE; + } + if (p_feature->delete_all) + { + data |= NRF_BLE_BMS_ALL_BONDS_LE; + } + if (p_feature->delete_requesting_auth) + { + data |= NRF_BLE_BMS_REQUESTING_DEVICE_LE_AUTH_CODE; + } + if (p_feature->delete_requesting) + { + data |= NRF_BLE_BMS_REQUESTING_DEVICE_LE; + } + + return (uint24_encode(data, p_encoded_feature)); +} + + +/**@brief Function for adding the Bond Management Feature characteristic. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_bms_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code returned by @ref characteristic_add. + */ +static ret_code_t feature_char_add(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t const * p_bms_init) +{ + uint8_t encoded_feature[NRF_BLE_BMS_FEATURE_LEN]; + uint8_t init_value_len; + ble_add_char_params_t add_char_params; + nrf_ble_bms_features_t * p_feature = &p_bms->feature; + + if ((p_feature->delete_all_auth) || + (p_feature->delete_all_but_requesting_auth) || + (p_feature->delete_requesting_auth)) + { + VERIFY_PARAM_NOT_NULL(p_bms_init->evt_handler); + } + + if ((p_feature->delete_requesting_auth) || + (p_feature->delete_requesting)) + { + VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_requesting); + } + + if ((p_feature->delete_all) || + (p_feature->delete_all_auth)) + { + VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_all); + } + + if ((p_feature->delete_all_but_requesting) || + (p_feature->delete_all_but_requesting_auth)) + { + VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_all_except_requesting); + } + + init_value_len = feature_encode(&p_bms->feature, encoded_feature); + + memset(&add_char_params, 0, sizeof(add_char_params)); + add_char_params.uuid = BLE_UUID_BMS_FEATURE; + add_char_params.char_props.read = true; + add_char_params.max_len = init_value_len; + add_char_params.p_init_value = encoded_feature; + add_char_params.init_len = init_value_len; + add_char_params.read_access = p_bms_init->bms_feature_sec_req; + add_char_params.write_access = SEC_NO_ACCESS; + + return characteristic_add(p_bms->service_handle, &add_char_params, &p_bms->feature_handles); +} + + +/**@brief Handle a write event to the Bond Management Service Control Point. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_ctrlpt_write(nrf_ble_bms_t * p_bms, + ble_gatts_evt_write_t * p_evt_write, + ble_gatts_authorize_params_t * p_auth_params) +{ + ret_code_t err_code; + nrf_ble_bms_ctrlpt_t ctrlpt; + + err_code = ctrlpt_process(p_bms, p_evt_write->data, p_evt_write->len, &ctrlpt); + if (err_code != NRF_SUCCESS) + { + p_auth_params->gatt_status = err_code; + p_auth_params->update = 0; + + return; + } + + p_auth_params->gatt_status = BLE_GATT_STATUS_SUCCESS; + p_auth_params->update = 1; + + NRF_LOG_INFO("Control point write: Success\r\n"); + + /* Execute the requested operation. */ + ctrlpt_execute(p_bms, ctrlpt.op_code); +} + + +/**@brief Authorize WRITE request event handler. + * + * @details Handles WRITE events from the BLE stack. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_gatts_evt GATTS Event received from the BLE stack. + * + */ +static void on_rw_auth_req(nrf_ble_bms_t * p_bms, ble_gatts_evt_t * p_gatts_evt) +{ + ble_gatts_evt_rw_authorize_request_t * p_auth_req = &p_gatts_evt->params.authorize_request; + ble_gatts_rw_authorize_reply_params_t auth_reply; + ret_code_t err_code; + + memset(&auth_reply, 0, sizeof(auth_reply)); + + if ((p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && + (p_auth_req->request.write.op == BLE_GATTS_OP_WRITE_REQ) && + (p_auth_req->request.write.handle == p_bms->ctrlpt_handles.value_handle)) + { + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + on_ctrlpt_write(p_bms, &p_auth_req->request.write, &auth_reply.params.write); + + /* Send authorization reply */ + err_code = sd_ble_gatts_rw_authorize_reply(p_bms->conn_handle, &auth_reply); + error_check(err_code, p_bms->error_handler); + } + +} + + +/**@brief Handle authorization request events from the Queued Write module. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_qwr Queued Write Structure. + * @param[in] p_evt Event received from the Queued Writes module. + * + * @retval BLE_GATT_STATUS_SUCCESS If the received event is accepted. + * @retval BLE_BMS_OPCODE_OPERATION_FAILED If the received event is not relevant for any of this module's attributes. + * @retval BLE_BMS_OPCODE_NOT_SUPPORTED If the received opcode is not supported. + * @retval BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION If the application handler returns that the authorization code is not valid. + */ +uint16_t on_qwr_auth_req(nrf_ble_bms_t * p_bms, nrf_ble_qwr_t * p_qwr, nrf_ble_qwr_evt_t * p_evt) +{ + ret_code_t err_code; + uint16_t len = NRF_BLE_BMS_CTRLPT_MAX_LEN; + uint8_t mem_buffer[NRF_BLE_BMS_CTRLPT_MAX_LEN]; + nrf_ble_bms_ctrlpt_t ctrlpt; + + err_code = nrf_ble_qwr_value_get(p_qwr, p_evt->attr_handle, mem_buffer, &len); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Control point write: Operation failed.\r\n"); + return NRF_BLE_BMS_OPERATION_FAILED; + } + + return ctrlpt_process(p_bms, mem_buffer, len, &ctrlpt); +} + + +/**@brief Handle execute write events to from the Queued Write module. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_qwr Queued Write Structure. + * @param[in] p_evt Event received from the Queued Writes module. + * + * @retval BLE_GATT_STATUS_SUCCESS If the received event is accepted. + * @retval BLE_BMS_OPCODE_OPERATION_FAILED If the received event is not relevant for any of this module's attributes. + * @retval BLE_BMS_OPCODE_NOT_SUPPORTED If the received opcode is not supported. + */ +uint16_t on_qwr_exec_write(nrf_ble_bms_t * p_bms, nrf_ble_qwr_t * p_qwr, nrf_ble_qwr_evt_t * p_evt) +{ + ret_code_t err_code; + uint16_t len = NRF_BLE_BMS_CTRLPT_MAX_LEN; + uint8_t mem_buffer[NRF_BLE_BMS_CTRLPT_MAX_LEN]; + nrf_ble_bms_ctrlpt_t ctrlpt; + ble_gatts_value_t ctrlpt_value; + + ctrlpt_value.len = NRF_BLE_BMS_CTRLPT_MAX_LEN; + ctrlpt_value.offset = 0; + ctrlpt_value.p_value = mem_buffer; + + const uint16_t ctrlpt_handle = p_bms->ctrlpt_handles.value_handle; + err_code = sd_ble_gatts_value_get(p_bms->conn_handle, ctrlpt_handle, &ctrlpt_value); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Control point write: Operation failed.\r\n"); + return NRF_BLE_BMS_OPERATION_FAILED; + } + + /* Decode operation */ + err_code = ctrlpt_decode(ctrlpt_value.p_value, len, &ctrlpt); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Control point write: Operation failed.\r\n"); + return NRF_BLE_BMS_OPERATION_FAILED; + } + + /* Execute the requested operation. */ + ctrlpt_execute(p_bms, ctrlpt.op_code); + + /* Reset authorization status */ + p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_DENIED; + + return BLE_GATT_STATUS_SUCCESS; +} + + +uint16_t nrf_ble_bms_on_qwr_evt(nrf_ble_bms_t * p_bms, + nrf_ble_qwr_t * p_qwr, + nrf_ble_qwr_evt_t * p_evt) +{ + VERIFY_TRUE(p_bms != NULL, (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE)); + VERIFY_TRUE(p_qwr != NULL, (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE)); + VERIFY_TRUE(p_evt != NULL, (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE)); + VERIFY_TRUE(p_evt->attr_handle == p_bms->ctrlpt_handles.value_handle, + (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE)); + + if (p_evt->evt_type == NRF_BLE_QWR_EVT_AUTH_REQUEST) + { + return on_qwr_auth_req(p_bms, p_qwr, p_evt); + } + else if ((p_evt->evt_type == NRF_BLE_QWR_EVT_EXECUTE_WRITE) && + (p_bms->auth_status == NRF_BLE_BMS_AUTH_STATUS_ALLOWED)) + { + return on_qwr_exec_write(p_bms, p_qwr, p_evt); + } + + return BLE_GATT_STATUS_SUCCESS; +} + + +void nrf_ble_bms_on_ble_evt(nrf_ble_bms_t * p_bms, ble_evt_t * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_bms); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + on_rw_auth_req(p_bms, &p_ble_evt->evt.gatts_evt); + break; + + default: + break; + } +} + + +ret_code_t nrf_ble_bms_set_conn_handle(nrf_ble_bms_t * p_bms, uint16_t conn_handle) +{ + VERIFY_PARAM_NOT_NULL(p_bms); + + p_bms->conn_handle = conn_handle; + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_bms_init(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t * p_bms_init) +{ + ret_code_t err_code; + ble_uuid_t ble_uuid; + + VERIFY_PARAM_NOT_NULL(p_bms_init); + VERIFY_PARAM_NOT_NULL(p_bms); + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BMS_SERVICE); + + p_bms->evt_handler = p_bms_init->evt_handler; + p_bms->error_handler = p_bms_init->error_handler; + p_bms->feature = p_bms_init->feature; + p_bms->bond_callbacks = p_bms_init->bond_callbacks; + p_bms->conn_handle = BLE_CONN_HANDLE_INVALID; + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_bms->service_handle); + VERIFY_SUCCESS(err_code); + + err_code = feature_char_add(p_bms, p_bms_init); + VERIFY_SUCCESS(err_code); + + err_code = ctrlpt_char_add(p_bms, p_bms_init); + VERIFY_SUCCESS(err_code); + + if (p_bms_init->p_qwr != NULL) + { + return nrf_ble_qwr_attr_register(p_bms_init->p_qwr, p_bms->ctrlpt_handles.value_handle); + } + + NRF_LOG_INFO("Init complete.\r\n"); + + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_bms_auth_response(nrf_ble_bms_t * p_bms, bool authorize) +{ + VERIFY_PARAM_NOT_NULL(p_bms); + VERIFY_TRUE(p_bms->auth_status == NRF_BLE_BMS_AUTH_STATUS_PENDING, NRF_ERROR_INVALID_STATE); + + if (authorize) + { + p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_ALLOWED; + } + else + { + p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_DENIED; + } + + return NRF_SUCCESS; +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.h new file mode 100644 index 0000000000000000000000000000000000000000..794a9685b8de333d33fe70a53decdba38e71c16b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.h @@ -0,0 +1,317 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_bms Bond Management Service + * @{ + * @ingroup ble_sdk_srv + * @brief Bond Management Service (BMS) module. + * + * @details This module implements the Bond Management Service (BMS). + * By writing to the Bond Management Control Point, the connected peer can request the deletion of + * bond information from the device. + * If authorization is configured, the application must supply an event handler for receiving Bond + * Management Service events. Using this handler, the service requests authorization when + * a procedure is requested by writing to the Bond Management Control Point. + * + * @msc + * hscale = "1.3"; + * APP,BMS,PEER; + * |||; + * APP rbox PEER [label="Connection established"]; + * |||; + * BMS<=PEER [label="BMCP write request {procedure}"]; + * APP<-BMS [label="NRF_BLE_BMS_EVT_AUTH {auth_code}"]; + * --- [label="Variant #1: app grants authorization"]; + * APP->BMS [label="nrf_ble_bms_auth_reponse (true)"]; + * BMS>>APP [label="NRF_SUCCESS"]; + * BMS=>PEER [label="BMCP write response"]; + * BMS rbox BMS [label="Procedure initiated"]; + * --- [label="Variant #2: app denies authorization"]; + * APP->BMS [label="nrf_ble_bms_auth_reponse (false)"]; + * BMS>>APP [label="NRF_SUCCESS"]; + * BMS=>PEER [label="BMCP error response"]; + * @endmsc + * + * @note The application must propagate BLE stack events to the Bond Management Service module by calling + * @ref nrf_ble_bms_on_ble_evt() from the @ref softdevice_handler callback. + * If the application uses the Queued Writes module, the application must propagate Queued Write events + * to the Bond Management Service module by calling @ref nrf_ble_bms_on_qwr_evt() from the + * @ref nrf_ble_qwr callback. + */ + +#ifndef NRF_BLE_BMS_H__ +#define NRF_BLE_BMS_H__ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "nrf_ble_qwr.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define NRF_BLE_BMS_FEATURE_LEN 3 //!< Length of the Feature Characteristic (in bytes). +#define NRF_BLE_BMS_CTRLPT_MAX_LEN 128 //!< Maximum length of the Bond Management Control Point Characteristic (in bytes). +#define NRF_BLE_BMS_CTRLPT_MIN_LEN 1 //!< Minimum length of the Bond Management Control Point Characteristic (in bytes). +#define NRF_BLE_BMS_AUTH_CODE_MAX_LEN NRF_BLE_BMS_CTRLPT_MAX_LEN - 1 //!< Maximum length of the Bond Management Control Point Authorization Code (in bytes). + + +/** @defgroup NRF_BLE_BMS_FEATURES BMS feature bits + * @{ */ +#define NRF_BLE_BMS_REQUESTING_DEVICE_BR_LE (0x01 << 0) //!< Delete bond of the requesting device (BR/EDR and LE). +#define NRF_BLE_BMS_REQUESTING_DEVICE_BR_LE_AUTH_CODE (0x01 << 1) //!< Delete bond of the requesting device (BR/EDR and LE) with an authorization code. +#define NRF_BLE_BMS_REQUESTING_DEVICE_BR (0x01 << 2) //!< Delete bond of the requesting device (BR/EDR transport only). +#define NRF_BLE_BMS_REQUESTING_DEVICE_BR_AUTH_CODE (0x01 << 3) //!< Delete bond of the requesting device (BR/EDR transport only) with an authorization code. +#define NRF_BLE_BMS_REQUESTING_DEVICE_LE (0x01 << 4) //!< Delete bond of the requesting device (LE transport only). +#define NRF_BLE_BMS_REQUESTING_DEVICE_LE_AUTH_CODE (0x01 << 5) //!< Delete bond of the requesting device (LE transport only) with an authorization code. +#define NRF_BLE_BMS_ALL_BONDS_BR_LE (0x01 << 6) //!< Delete all bonds on the device (BR/EDR and LE). +#define NRF_BLE_BMS_ALL_BONDS_BR_LE_AUTH_CODE (0x01 << 7) //!< Delete all bonds on the device (BR/EDR and LE) with an authorization code. +#define NRF_BLE_BMS_ALL_BONDS_BR (0x01 << 8) //!< Delete all bonds on the device (BR/EDR transport only). +#define NRF_BLE_BMS_ALL_BONDS_BR_AUTH_CODE (0x01 << 9) //!< Delete all bonds on the device (BR/EDR transport only) with an authorization code. +#define NRF_BLE_BMS_ALL_BONDS_LE (0x01 << 10) //!< Delete all bonds on the device (LE transport only). +#define NRF_BLE_BMS_ALL_BONDS_LE_AUTH_CODE (0x01 << 11) //!< Delete all bonds on the device (LE transport only) with an authorization code. +#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_BR_LE (0x01 << 12) //!< Delete all bonds on the device except for the bond of the requesting device (BR/EDR and LE). +#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_BR_LE_AUTH_CODE (0x01 << 13) //!< Delete all bonds on the device except for the bond of the requesting device (BR/EDR and LE) with an authorization code. +#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_BR (0x01 << 14) //!< Delete all bonds on the device except for the bond of the requesting device (BR/EDR transport only). +#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_BR_AUTH_CODE (0x01 << 15) //!< Delete all bonds on the device except for the bond of the requesting device (BR/EDR transport only) with an authorization code. +#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE (0x01 << 16) //!< Delete all bonds on the device except for the bond of the requesting device (LE transport only). +#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE_AUTH_CODE (0x01 << 17) //!< Delete all bonds on the device except for the bond of the requesting device (LE transport only) with an authorization code. +/** @} */ + + +#define NRF_BLE_BMS_OPCODE_NOT_SUPPORTED (BLE_GATT_STATUS_ATTERR_APP_BEGIN + 0) //!< Error sent back when receiving a control point write with an unsupported opcode. +#define NRF_BLE_BMS_OPERATION_FAILED (BLE_GATT_STATUS_ATTERR_APP_BEGIN + 1) //!< Error sent back when a control point operation fails. + + +/**@brief Supported features. */ +typedef struct +{ + bool delete_all : 1; //!< Indicates whether the application wants to support the operation to delete all bonds. + bool delete_all_auth : 1; //!< Indicates whether the application wants to support the operation to delete all bonds with authorization code. + bool delete_requesting : 1; //!< Indicates whether the application wants to support the operation to delete the bonds of the requesting device. + bool delete_requesting_auth : 1; //!< Indicates whether the application wants to support the operation to delete the bonds of the requesting device with authorization code. + bool delete_all_but_requesting : 1; //!< Indicates whether the application wants to support the operation to delete all bonds except for the bond of the requesting device. + bool delete_all_but_requesting_auth : 1; //!< Indicates whether the application wants to support the operation to delete all bonds except for the bond of the requesting device with authorization code. +} nrf_ble_bms_features_t; + + +/**@brief BMS Control Point opcodes. */ +typedef enum +{ + NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_BR_LE = 0x01, //!< Initiates the procedure to delete the bond of the requesting device on BR/EDR and LE transports. + NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_BR_ONLY = 0x02, //!< Initiates the procedure to delete the bond of the requesting device on BR/EDR transport. + NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY = 0x03, //!< Initiates the procedure to delete the bond of the requesting device on LE transport. + NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_BR_LE = 0x04, //!< Initiates the procedure to delete all bonds on the device on BR/EDR and LE transports. + NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_BR_ONLY = 0x05, //!< Initiates the procedure to delete all bonds on the device on BR/EDR transport. + NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY = 0x06, //!< Initiates the procedure to delete all bonds on the device on LE transport. + NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_BR_LE = 0x07, //!< Initiates the procedure to delete all bonds except for the one of the requesting device on BR/EDR and LE transports. + NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_BR_ONLY = 0x08, //!< Initiates the procedure to delete all bonds except for the one of the requesting device on BR/EDR transport. + NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY = 0x09, //!< Initiates the procedure to delete all bonds except for the one of the requesting device on LE transport. + NRF_BLE_BMS_OP_NONE = 0xFF //!< Indicates an invalid opcode or no pending opcode. +} nrf_ble_bms_op_t; + + +/**@brief Authorization status values. */ +typedef enum +{ + NRF_BLE_BMS_AUTH_STATUS_ALLOWED, //!< Authorization is granted. + NRF_BLE_BMS_AUTH_STATUS_DENIED, //!< Authorization is denied. + NRF_BLE_BMS_AUTH_STATUS_PENDING //!< Authorization is pending. +} nrf_ble_bms_auth_status_t; + + +/**@brief Received authorization codes. */ +typedef struct +{ + uint8_t code[NRF_BLE_BMS_AUTH_CODE_MAX_LEN]; //!< Authorization code. + uint16_t len; //!< Length of the authorization code. +} nrf_ble_bms_auth_code_t; + + +/**@brief BMS event types. */ +typedef enum +{ + NRF_BLE_BMS_EVT_AUTH, //!< Event that indicates that the application shall verify the supplied authentication code. +} nrf_ble_bms_evt_type_t; + + +/**@brief BMS events. */ +typedef struct +{ + nrf_ble_bms_evt_type_t evt_type; //!< Type of event. + nrf_ble_bms_auth_code_t auth_code; //!< Received authorization code. +} nrf_ble_bms_evt_t; + +/**@brief BMS control points. */ +typedef struct +{ + nrf_ble_bms_op_t op_code; //!< Control Point Op Code. + nrf_ble_bms_auth_code_t auth_code; //!< Control Point Authorization Code. +} nrf_ble_bms_ctrlpt_t; + + +// Forward declaration of the nrf_ble_bms_t type. +typedef struct nrf_ble_bms_s nrf_ble_bms_t; + + +/**@brief BMS event handler type. */ +typedef void (* nrf_ble_bms_bond_handler_t) (nrf_ble_bms_t const * p_bms); + + +/**@brief BMS bond management callbacks. */ +typedef struct +{ + nrf_ble_bms_bond_handler_t delete_requesting; //!< Function to be called to delete the bonding information of the requesting device. + nrf_ble_bms_bond_handler_t delete_all; //!< Function to be called to delete the bonding information of all bonded devices. + nrf_ble_bms_bond_handler_t delete_all_except_requesting; //!< Function to be called to delete the bonding information of all bonded devices except for the requesting device. +} nrf_ble_bms_bond_cbs_t; + + +/**@brief BMS event handler type. The event handler returns a @ref BLE_GATT_STATUS_CODES "BLE GATT status code". */ +typedef void (* ble_bms_evt_handler_t) (nrf_ble_bms_t * p_bms, nrf_ble_bms_evt_t * p_evt); + + +/**@brief BMS initialization structure that contains all information + * needed to initialize the service. */ +typedef struct +{ + ble_bms_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Bond Management Service. + ble_srv_error_handler_t error_handler; //!< Function to be called if an error occurs. + nrf_ble_bms_features_t feature; //!< Initial value for features of the service. + security_req_t bms_feature_sec_req; //!< Initial security level for the Feature characteristic. + security_req_t bms_ctrlpt_sec_req; //!< Initial security level for the Control Point characteristic. + nrf_ble_qwr_t * p_qwr; //!< Pointer to the initialized Queued Write context. + nrf_ble_bms_bond_cbs_t bond_callbacks; //!< Callback functions for deleting bonds. +} nrf_ble_bms_init_t; + + +/**@brief Status information for the service. */ +struct nrf_ble_bms_s +{ + uint16_t service_handle; //!< Handle of the Bond Management Service (as provided by the BLE stack). + uint16_t conn_handle; //!< Handle of the current connection (as provided by the BLE stack). @ref BLE_CONN_HANDLE_INVALID if not in a connection. + ble_bms_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Bond Management Service. + ble_srv_error_handler_t error_handler; //!< Function to be called if an error occurs. + nrf_ble_bms_features_t feature; //!< Value for features of the service (see @ref NRF_BLE_BMS_FEATURES). + ble_gatts_char_handles_t feature_handles; //!< Handles related to the Bond Management Feature characteristic. + ble_gatts_char_handles_t ctrlpt_handles; //!< Handles related to the Bond Management Control Point characteristic. + nrf_ble_bms_bond_cbs_t bond_callbacks; //!< Callback functions for deleting bonds. + nrf_ble_bms_auth_status_t auth_status; //!< Authorization status. +}; + + +/**@brief Function for responding to an authorization request. + * + * @details This function should be called when receiving the @ref NRF_BLE_BMS_EVT_AUTH event to + * respond to the service with an authorization result. + * + * @param[in] p_bms BMS structure. + * @param[in] authorize Authorization response. True if the authorization is considered successful. + * + * @retval NRF_ERROR_NULL If @p p_bms was NULL. + * @retval NRF_ERROR_INVALID_STATE If no authorization request was pending. + * @retval NRF_SUCCESS If the response was received successfully. + */ +ret_code_t nrf_ble_bms_auth_response(nrf_ble_bms_t * p_bms, bool authorize); + + +/**@brief Function for initializing the Bond Management Service. + * + * @param[out] p_bms BMS structure. + * @param[in] p_bms_init Information needed to initialize the service. + * + * @retval NRF_ERROR_NULL If @p p_bms or @p p_bms_init was NULL. + * @retval NRF_SUCCESS If the service was initialized successfully. + * Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_bms_init(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t * p_bms_init); + + +/**@brief Function for assigning handles to the Bond Management Service instance. + * + * @details Call this function when a link with a peer has been established to + * associate the link to this instance of the module. + * + * @param[in] p_bms Pointer to the BMS structure instance to associate. + * @param[in] conn_handle Connection handle to be associated with the given BMS instance. + * + * @retval NRF_ERROR_NULL If @p p_bms was NULL. + * @retval NRF_SUCCESS If the operation was successful. + */ +ret_code_t nrf_ble_bms_set_conn_handle(nrf_ble_bms_t * p_bms, uint16_t conn_handle); + + +/**@brief Function for handling Bond Management BLE stack events. + * + * @details This function handles all events from the BLE stack that are of interest to the Bond Management Service. + * + * @param[in] p_bms BMS structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void nrf_ble_bms_on_ble_evt(nrf_ble_bms_t * p_bms, ble_evt_t * p_ble_evt); + + +/**@brief Function for handling events from the @ref nrf_ble_qwr. + * + * @param[in] p_bms BMS structure. + * @param[in] p_qwr Queued Write structure. + * @param[in] p_evt Event received from the Queued Writes module. + * + * @retval BLE_GATT_STATUS_SUCCESS If the received event is accepted. + * @retval NRF_BLE_QWR_REJ_REQUEST_ERR_CODE If the received event is not relevant for any of this module's attributes. + * @retval BLE_BMS_OPCODE_NOT_SUPPORTED If the received opcode is not supported. + * @retval BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION If the application handler returns that the authorization code is not valid. + */ +uint16_t nrf_ble_bms_on_qwr_evt(nrf_ble_bms_t * p_bms, + nrf_ble_qwr_t * p_qwr, + nrf_ble_qwr_evt_t * p_evt); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_BMS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.c new file mode 100644 index 0000000000000000000000000000000000000000..2ae2fb6ffc6d3eafc829c03d656078dda3d39be3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.c @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "cgms_db.h" + +typedef struct +{ + bool in_use_flag; + ble_cgms_rec_t record; +} database_entry_t; + +static database_entry_t m_database[CGMS_DB_MAX_RECORDS]; +static uint8_t m_database_crossref[CGMS_DB_MAX_RECORDS]; +static uint16_t m_num_records; + + +ret_code_t cgms_db_init(void) +{ + int i; + + for (i = 0; i < CGMS_DB_MAX_RECORDS; i++) + { + m_database[i].in_use_flag = false; + m_database_crossref[i] = 0xFF; + } + + m_num_records = 0; + + return NRF_SUCCESS; +} + + +uint16_t cgms_db_num_records_get(void) +{ + return m_num_records; +} + + +ret_code_t cgms_db_record_get(uint8_t record_num, ble_cgms_rec_t * p_rec) +{ + if (record_num >= m_num_records) + { + return NRF_ERROR_NOT_FOUND; + } + + // copy record to the specified memory + *p_rec = m_database[m_database_crossref[record_num]].record; + + return NRF_SUCCESS; +} + + +ret_code_t cgms_db_record_add(ble_cgms_rec_t * p_rec) +{ + int i; + + if (m_num_records == CGMS_DB_MAX_RECORDS) + { + return NRF_ERROR_NO_MEM; + } + + // find next available database entry + for (i = 0; i < CGMS_DB_MAX_RECORDS; i++) + { + if (!m_database[i].in_use_flag) + { + m_database[i].in_use_flag = true; + m_database[i].record = *p_rec; + + m_database_crossref[m_num_records] = i; + m_num_records++; + + return NRF_SUCCESS; + } + } + + return NRF_ERROR_NO_MEM; +} + + +ret_code_t cgms_db_record_delete(uint8_t record_num) +{ + int i; + + if (record_num >= m_num_records) + { + // Deleting a non-existent record is not an error + return NRF_SUCCESS; + } + + // free entry + m_database[m_database_crossref[record_num]].in_use_flag = false; + + // decrease number of records + m_num_records--; + + // remove cross reference index + for (i = record_num; i < m_num_records; i++) + { + m_database_crossref[i] = m_database_crossref[i + 1]; + } + + return NRF_SUCCESS; +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.h new file mode 100644 index 0000000000000000000000000000000000000000..ebd1c668f017423c4f88409c94b7e9ddad34f172 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.h @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_srv_cgms_db Continuous Glucose Monitoring Service database + * @{ + * @ingroup ble_cgms + * + * @brief Continuous Glucose Monitoring Service database module. + * + * @details This module implements a database of stored glucose measurement values. + * This database is meant as an example of a database that the @ref ble_cgms can use. + * Replace this module if this implementation does not suit + * your application. Any replacement implementation should follow the API below to ensure + * that the qualification of the @ref ble_cgms is not compromised. + */ + +#ifndef BLE_CGMS_DB_H__ +#define BLE_CGMS_DB_H__ + +#include "sdk_errors.h" +#include "nrf_ble_cgms.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CGMS_DB_MAX_RECORDS 100 // !< Number of records that can be stored in the database. + + +/**@brief Function for initializing the glucose record database. + * + * @retval NRF_SUCCESS If the database was successfully initialized. + */ +ret_code_t cgms_db_init(void); + + +/**@brief Function for getting the number of records in the database. + * + * @return The number of records in the database. + */ +uint16_t cgms_db_num_records_get(void); + + +/**@brief Function for getting a specific record from the database. + * + * @param[in] record_num Index of the record to retrieve. + * @param[out] p_rec Pointer to the record structure to which the retrieved record is copied. + * + * @retval NRF_SUCCESS If the record was successfully retrieved. + */ +ret_code_t cgms_db_record_get(uint8_t record_num, ble_cgms_rec_t * p_rec); + + +/**@brief Function for adding a record at the end of the database. + * + * @param[in] p_rec Pointer to the record to add to the database. + * + * @retval NRF_SUCCESS If the record was successfully added to the database. + */ +ret_code_t cgms_db_record_add(ble_cgms_rec_t * p_rec); + + +/**@brief Function for deleting a database entry. + * + * @details This call deletes an record from the database. + * + * @param[in] record_num Index of the record to delete. + * + * @retval NRF_SUCCESS If the record was successfully deleted from the database. + */ +ret_code_t cgms_db_record_delete(uint8_t record_num); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_CGMS_DB_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.c new file mode 100644 index 0000000000000000000000000000000000000000..e9ce68eaa3b1b7168f916e1ba928334328e639b3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.c @@ -0,0 +1,248 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "ble.h" +#include "sdk_macros.h" +#include "ble_srv_common.h" +#include "nrf_ble_cgms.h" +#include "cgms_meas.h" +#include "cgms_db.h" + +/**@brief Function for encoding a Glucose measurement. + * + * @param[in] p_meas Measurement to be encoded. + * @param[out] p_encoded_buffer Pointer to buffer where the encoded measurement is to be stored. + * + * @return Size of encoded measurement. + */ +static uint8_t cgms_meas_encode(nrf_ble_cgms_t * p_cgms, + const nrf_ble_cgms_meas_t * p_meas, + uint8_t * p_encoded_buffer) +{ + uint8_t len = 2; + + uint8_t flags = p_meas->flags; + + len += uint16_encode(p_meas->glucose_concentration, + &p_encoded_buffer[len]); + len += uint16_encode(p_meas->time_offset, + &p_encoded_buffer[len]); + + if (p_meas->sensor_status_annunciation.warning != 0) + { + p_encoded_buffer[len++] = p_meas->sensor_status_annunciation.warning; + flags |= NRF_BLE_CGMS_STATUS_FLAGS_WARNING_OCT_PRESENT; + } + + if (p_meas->sensor_status_annunciation.calib_temp != 0) + { + p_encoded_buffer[len++] = p_meas->sensor_status_annunciation.calib_temp; + flags |= NRF_BLE_CGMS_STATUS_FLAGS_CALTEMP_OCT_PRESENT; + } + + if (p_meas->sensor_status_annunciation.status != 0) + { + p_encoded_buffer[len++] = p_meas->sensor_status_annunciation.status; + flags |= NRF_BLE_CGMS_STATUS_FLAGS_STATUS_OCT_PRESENT; + } + + // Trend field + if (p_cgms->feature.feature & NRF_BLE_CGMS_FEAT_CGM_TREND_INFORMATION_SUPPORTED) + { + if (flags & NRF_BLE_CGMS_FLAG_TREND_INFO_PRESENT) + { + len += uint16_encode(p_meas->trend, &p_encoded_buffer[len]); + } + } + + // Quality field + if (p_cgms->feature.feature & NRF_BLE_CGMS_FEAT_CGM_QUALITY_SUPPORTED) + { + if (flags & NRF_BLE_CGMS_FLAGS_QUALITY_PRESENT) + { + len += uint16_encode(p_meas->quality, &p_encoded_buffer[len]); + } + } + + p_encoded_buffer[1] = flags; + p_encoded_buffer[0] = len; + return len; +} + + +/**@brief Function for adding a characteristic for the Continuous Glucose Meter Measurement. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +ret_code_t cgms_meas_char_add(nrf_ble_cgms_t * p_cgms) +{ + uint8_t num_recs; + uint8_t encoded_cgms_meas[NRF_BLE_CGMS_MEAS_LEN_MAX]; + ble_add_char_params_t add_char_params; + ble_cgms_rec_t initial_cgms_rec_value; + + memset(&add_char_params, 0, sizeof(add_char_params)); + memset(&initial_cgms_rec_value, 0, sizeof(ble_cgms_rec_t)); + + num_recs = cgms_db_num_records_get(); + if (num_recs > 0) + { + uint32_t err_code = cgms_db_record_get(num_recs - 1, &initial_cgms_rec_value); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + add_char_params.uuid = BLE_UUID_CGM_MEASUREMENT; + add_char_params.max_len = NRF_BLE_CGMS_MEAS_LEN_MAX; + add_char_params.init_len = cgms_meas_encode(p_cgms, + &initial_cgms_rec_value.meas, + encoded_cgms_meas); + add_char_params.p_init_value = encoded_cgms_meas; + add_char_params.is_var_len = true; + add_char_params.char_props.notify = true; + add_char_params.cccd_write_access = SEC_JUST_WORKS; + + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.measurment); +} + + +ret_code_t cgms_meas_send(nrf_ble_cgms_t * p_cgms, ble_cgms_rec_t * p_rec, uint8_t * p_count) +{ + + uint32_t err_code; + uint8_t encoded_meas[NRF_BLE_CGMS_MEAS_LEN_MAX + NRF_BLE_CGMS_MEAS_REC_LEN_MAX]; + uint16_t len = 0; + uint16_t hvx_len = NRF_BLE_CGMS_MEAS_LEN_MAX; + int i; + ble_gatts_hvx_params_t hvx_params; + + for (i = 0; i < *p_count; i++) + { + uint8_t meas_len = cgms_meas_encode(p_cgms, &(p_rec[i].meas), (encoded_meas + len)); + if (len + meas_len >= NRF_BLE_CGMS_MEAS_LEN_MAX) + { + break; + } + len += meas_len; + } + *p_count = i; + hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_cgms->char_handles.measurment.value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_meas; + + err_code = sd_ble_gatts_hvx(p_cgms->conn_handle, &hvx_params); + if (err_code == NRF_SUCCESS) + { + if (hvx_len != len) + { + err_code = NRF_ERROR_DATA_SIZE; + } + else + { + // Measurement successfully sent + p_cgms->racp_data.racp_proc_records_reported++; + p_cgms->racp_data.racp_proc_records_reported_since_txcomplete++; + } + } + + return err_code; +} + + +/**@brief Function for handling the Glucose measurement CCCD write event. + * + * @param[in] p_cgms Service instance. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_meas_cccd_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t * p_evt_write) +{ + if (p_evt_write->len == 2) + { + // CCCD written, update notification state + if (p_cgms->evt_handler != NULL) + { + nrf_ble_cgms_evt_t evt; + + if (ble_srv_is_notification_enabled(p_evt_write->data)) + { + evt.evt_type = NRF_BLE_CGMS_EVT_NOTIFICATION_ENABLED; + } + else + { + evt.evt_type = NRF_BLE_CGMS_EVT_NOTIFICATION_DISABLED; + } + + p_cgms->evt_handler(p_cgms, &evt); + } + } +} + + +/**@brief Function for handling the WRITE event. + * + * @details Handles WRITE events from the BLE stack. + * + * @param[in] p_cgms Glucose Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void cgms_meas_on_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t * p_evt_write) +{ + + if (p_evt_write->handle == p_cgms->char_handles.measurment.cccd_handle) + { + on_meas_cccd_write(p_cgms, p_evt_write); + } +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.h new file mode 100644 index 0000000000000000000000000000000000000000..59dfd13e313d689554f3052aa092eb53f3d92268 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.h @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_srv_cgms_meas Continuous Glucose Monitoring Service Measurement + * @{ + * @ingroup ble_cgms + * @brief Continuous Glucose Monitoring Service Measurement module. + * + * @details This module implements parts of the Continuous Glucose Monitoring that relate to the + * Measurement characteristic. Events are propagated to this module from @ref ble_cgms + * using @ref cgms_meas_on_write. + * + */ + + +#ifndef NRF_BLE_CGMS_MEAS_H__ +#define NRF_BLE_CGMS_MEAS_H__ + +#include "ble.h" +#include "ble_srv_common.h" +#include "sdk_errors.h" +#include "nrf_ble_cgms.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Function for adding a characteristic for the Continuous Glucose Monitoring Measurement. + * + * @param[in] p_cgms Instance of the CGM Service. + * + * @retval NRF_SUCCESS If the characteristic was successfully added. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t cgms_meas_char_add(nrf_ble_cgms_t * p_cgms); + +/**@brief Function for sending a CGM Measurement. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_rec Measurement to be sent. + * @param[in] count Number of measurements to encode. + * + * @retval NRF_SUCCESS If the measurement was successfully sent. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t cgms_meas_send(nrf_ble_cgms_t * p_cgms, ble_cgms_rec_t * p_rec, uint8_t * count); + + +/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the BLE stack. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_evt_write Event received from the BLE stack. + */ +void cgms_meas_on_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t * p_evt_write); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_CGMS_MEAS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.c new file mode 100644 index 0000000000000000000000000000000000000000..f80c963d2918fdd9941e388ff0fd1e34b919e8d9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.c @@ -0,0 +1,795 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "cgms_racp.h" +#include "cgms_db.h" +#include "cgms_meas.h" + +#define OPERAND_FILTER_TYPE_RESV 0x00 // !< Filter type value reserved for future use. +#define OPERAND_FILTER_TYPE_SEQ_NUM 0x01 // !< Filter data using Sequence Number criteria. +#define OPERAND_FILTER_TYPE_FACING_TIME 0x02 // !< Filter data using User Facing Time criteria. + +/**@brief Function for adding a characteristic for the Record Access Control Point. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +ret_code_t cgms_racp_char_add(nrf_ble_cgms_t * p_cgms) +{ + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + add_char_params.uuid = BLE_UUID_RECORD_ACCESS_CONTROL_POINT_CHAR; + add_char_params.max_len = BLE_GATT_ATT_MTU_DEFAULT; + add_char_params.init_len = 0; + add_char_params.p_init_value = 0; + add_char_params.is_var_len = true; + add_char_params.write_access = SEC_JUST_WORKS; + add_char_params.char_props.write = true; + add_char_params.char_props.indicate = true; + add_char_params.cccd_write_access = SEC_JUST_WORKS; + add_char_params.is_defered_write = 1; + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.racp); +} + + +/**@brief Function for sending response from Specific Operation Control Point. + * + * @param[in] p_cgms Service instance. + * @param[in] p_racp_val RACP value to be sent. + */ +static void racp_send(nrf_ble_cgms_t * p_cgms, ble_racp_value_t * p_racp_val) +{ + uint32_t err_code; + uint8_t encoded_resp[25]; + uint8_t len; + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + + if ( + (p_cgms->cgms_com_state != STATE_RACP_RESPONSE_PENDING) + && + (p_cgms->racp_data.racp_proc_records_reported_since_txcomplete > 0) + ) + { + p_cgms->cgms_com_state = STATE_RACP_RESPONSE_PENDING; + return; + } + + // Send indication + len = ble_racp_encode(p_racp_val, encoded_resp); + hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_cgms->char_handles.racp.value_handle; + hvx_params.type = BLE_GATT_HVX_INDICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_resp; + + err_code = sd_ble_gatts_hvx(p_cgms->conn_handle, &hvx_params); + + // Error handling + if ((err_code == NRF_SUCCESS) && (hvx_len != len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + + switch (err_code) + { + case NRF_SUCCESS: + // Wait for HVC event. + p_cgms->cgms_com_state = STATE_RACP_RESPONSE_IND_VERIF; + break; + + case NRF_ERROR_RESOURCES: + // Wait for TX_COMPLETE event to retry transmission. + p_cgms->cgms_com_state = STATE_RACP_RESPONSE_PENDING; + break; + + case NRF_ERROR_INVALID_STATE: + // Make sure state machine returns to the default state. + p_cgms->cgms_com_state = STATE_NO_COMM; + break; + + default: + // Report error to application. + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + + // Make sure state machine returns to the default state. + p_cgms->cgms_com_state = STATE_NO_COMM; + break; + } +} + + +/**@brief Function for sending a RACP response containing a Response Code Op Code and Response Code Value. + * + * @param[in] p_cgms Service instance. + * @param[in] opcode RACP Op Code. + * @param[in] value RACP Response Code Value. + */ +static void racp_response_code_send(nrf_ble_cgms_t * p_cgms, uint8_t opcode, uint8_t value) +{ + p_cgms->racp_data.pending_racp_response.opcode = RACP_OPCODE_RESPONSE_CODE; + p_cgms->racp_data.pending_racp_response.operator = RACP_OPERATOR_NULL; + p_cgms->racp_data.pending_racp_response.operand_len = 2; + p_cgms->racp_data.pending_racp_response.p_operand = + p_cgms->racp_data.pending_racp_response_operand; + + p_cgms->racp_data.pending_racp_response_operand[0] = opcode; + p_cgms->racp_data.pending_racp_response_operand[1] = value; + + racp_send(p_cgms, &p_cgms->racp_data.pending_racp_response); +} + + +/**@brief Function for responding to the ALL operation. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t racp_report_records_all(nrf_ble_cgms_t * p_cgms) +{ + uint16_t total_records = cgms_db_num_records_get(); + uint16_t cur_nb_rec; + uint8_t i; + uint8_t nb_rec_to_send; + + if (p_cgms->racp_data.racp_proc_record_ndx >= total_records) + { + p_cgms->cgms_com_state = STATE_NO_COMM; + } + else + { + uint32_t err_code; + ble_cgms_rec_t rec[NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX]; + + cur_nb_rec = total_records - p_cgms->racp_data.racp_proc_record_ndx; + if (cur_nb_rec > NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX) + { + cur_nb_rec = NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX; + } + nb_rec_to_send = (uint8_t)cur_nb_rec; + + for (i = 0; i < cur_nb_rec; i++) + { + err_code = cgms_db_record_get(p_cgms->racp_data.racp_proc_record_ndx + i, &(rec[i])); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + err_code = cgms_meas_send(p_cgms, rec, &nb_rec_to_send); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + p_cgms->racp_data.racp_proc_record_ndx += nb_rec_to_send; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for responding to the FIRST or the LAST operation. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t racp_report_records_first_last(nrf_ble_cgms_t * p_cgms) +{ + uint32_t err_code; + ble_cgms_rec_t rec; + uint16_t total_records; + uint8_t nb_rec_to_send = 1; + + total_records = cgms_db_num_records_get(); + + if ((p_cgms->racp_data.racp_proc_records_reported != 0) || (total_records == 0)) + { + p_cgms->cgms_com_state = STATE_NO_COMM; + } + else + { + if (p_cgms->racp_data.racp_proc_operator == RACP_OPERATOR_FIRST) + { + err_code = cgms_db_record_get(0, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else if (p_cgms->racp_data.racp_proc_operator == RACP_OPERATOR_LAST) + { + err_code = cgms_db_record_get(total_records - 1, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + err_code = cgms_meas_send(p_cgms, &rec, &nb_rec_to_send); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + p_cgms->racp_data.racp_proc_record_ndx++; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for responding to the LESS OR EQUAL operation. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static ret_code_t racp_report_records_less_equal(nrf_ble_cgms_t * p_cgms) +{ + uint16_t total_rec_nb; + uint16_t total_rec_nb_to_send; + uint16_t rec_nb_left_to_send; + uint8_t nb_rec_to_send; + uint16_t offset; + uint16_t i; + + if(p_cgms->racp_data.racp_request.operand_len != 2) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(NRF_ERROR_INVALID_LENGTH); + } + } + + total_rec_nb = cgms_db_num_records_get(); + + offset = uint16_decode(p_cgms->racp_data.racp_request.p_operand); + if (offset >= total_rec_nb) + { + p_cgms->cgms_com_state = STATE_NO_COMM; + return NRF_SUCCESS; + } + + total_rec_nb_to_send = offset; + + if (p_cgms->racp_data.racp_proc_record_ndx >= total_rec_nb_to_send) + { + p_cgms->cgms_com_state = STATE_NO_COMM; + } + else + { + uint32_t err_code; + ble_cgms_rec_t rec[NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX]; + + rec_nb_left_to_send = total_rec_nb_to_send - p_cgms->racp_data.racp_proc_records_reported; + + if (rec_nb_left_to_send > NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX) + { + nb_rec_to_send = NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX; + } + else + { + nb_rec_to_send = (uint8_t)rec_nb_left_to_send; + } + + p_cgms->racp_data.racp_proc_record_ndx = 0; + + for (i = 0; i < nb_rec_to_send; i++) + { + err_code = cgms_db_record_get(p_cgms->racp_data.racp_proc_record_ndx + i, &(rec[i])); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + err_code = cgms_meas_send(p_cgms, rec, &nb_rec_to_send); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + p_cgms->racp_data.racp_proc_record_ndx += nb_rec_to_send; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for responding to the GREATER OR EQUAL operation. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static ret_code_t racp_report_records_greater_equal(nrf_ble_cgms_t * p_cgms) +{ + uint16_t total_rec_nb; + uint16_t total_rec_nb_to_send; + uint16_t rec_nb_left_to_send; + uint8_t nb_rec_to_send; + uint16_t offset; + uint16_t i; + + if(p_cgms->racp_data.racp_request.operand_len != 2) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(NRF_ERROR_INVALID_LENGTH); + } + } + + total_rec_nb = cgms_db_num_records_get(); + + offset = uint16_decode(p_cgms->racp_data.racp_request.p_operand); + if (offset >= total_rec_nb) + { + p_cgms->cgms_com_state = STATE_NO_COMM; + return NRF_SUCCESS; + } + + total_rec_nb_to_send = total_rec_nb - offset; + + if (p_cgms->racp_data.racp_proc_record_ndx >= total_rec_nb_to_send) + { + p_cgms->cgms_com_state = STATE_NO_COMM; + } + else + { + uint32_t err_code; + ble_cgms_rec_t rec[NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX]; + + rec_nb_left_to_send = total_rec_nb_to_send - p_cgms->racp_data.racp_proc_records_reported; + + if (rec_nb_left_to_send > NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX) + { + nb_rec_to_send = NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX; + } + else + { + nb_rec_to_send = (uint8_t)rec_nb_left_to_send; + } + + p_cgms->racp_data.racp_proc_record_ndx = offset; + + for (i = 0; i < nb_rec_to_send; i++) + { + err_code = cgms_db_record_get(p_cgms->racp_data.racp_proc_record_ndx + i, &(rec[i])); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + err_code = cgms_meas_send(p_cgms, rec, &nb_rec_to_send); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + p_cgms->racp_data.racp_proc_record_ndx += nb_rec_to_send; + } + + return NRF_SUCCESS; +} + +/**@brief Function for informing that the REPORT RECORDS procedure is completed. + * + * @param[in] p_cgms Service instance. + */ +static void racp_report_records_completed(nrf_ble_cgms_t * p_cgms) +{ + uint8_t resp_code_value; + + if (p_cgms->racp_data.racp_proc_records_reported > 0) + { + resp_code_value = RACP_RESPONSE_SUCCESS; + } + else + { + resp_code_value = RACP_RESPONSE_NO_RECORDS_FOUND; + } + + racp_response_code_send(p_cgms, RACP_OPCODE_REPORT_RECS, resp_code_value); +} + + +/**@brief Function for the RACP report records procedure. + * + * @param[in] p_cgms Service instance. + */ +static void racp_report_records_procedure(nrf_ble_cgms_t * p_cgms) +{ + uint32_t err_code; + + while (p_cgms->cgms_com_state == STATE_RACP_PROC_ACTIVE) + { + // Execute requested procedure + switch (p_cgms->racp_data.racp_proc_operator) + { + case RACP_OPERATOR_ALL: + err_code = racp_report_records_all(p_cgms); + break; + + case RACP_OPERATOR_FIRST: + case RACP_OPERATOR_LAST: + err_code = racp_report_records_first_last(p_cgms); + break; + case RACP_OPERATOR_GREATER_OR_EQUAL: + err_code = racp_report_records_greater_equal(p_cgms); + break; + case RACP_OPERATOR_LESS_OR_EQUAL: + err_code = racp_report_records_less_equal(p_cgms); + break; + default: + // Report error to application + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(NRF_ERROR_INTERNAL); + } + + // Make sure state machine returns to the default state + // state_set(STATE_NO_COMM); + p_cgms->cgms_com_state = STATE_NO_COMM; + return; + } + + // Error handling + switch (err_code) + { + case NRF_SUCCESS: + if (p_cgms->cgms_com_state != STATE_RACP_PROC_ACTIVE) + { + racp_report_records_completed(p_cgms); + } + break; + + case NRF_ERROR_RESOURCES: + // Wait for TX_COMPLETE event to resume transmission. + return; + + case NRF_ERROR_INVALID_STATE: + // Notification is probably not enabled. Ignore request. + p_cgms->cgms_com_state = STATE_NO_COMM; + return; + + default: + // Report error to application. + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + + // Make sure state machine returns to the default state. + p_cgms->cgms_com_state = STATE_NO_COMM; + return; + } + } +} + + +/**@brief Function for testing if the received request is to be executed. + * + * @param[in] p_racp_request Request to be checked. + * @param[out] p_response_code Response code to be sent in case the request is rejected. + * RACP_RESPONSE_RESERVED is returned if the received message is + * to be rejected without sending a respone. + * + * @return TRUE if the request is to be executed, FALSE if it is to be rejected. + * If it is to be rejected, p_response_code will contain the response code to be + * returned to the central. + */ +static bool is_request_to_be_executed(nrf_ble_cgms_t * p_cgms, + const ble_racp_value_t * p_racp_request, + uint8_t * p_response_code) +{ + *p_response_code = RACP_RESPONSE_RESERVED; + + if (p_racp_request->opcode == RACP_OPCODE_ABORT_OPERATION) + { + if (p_cgms->cgms_com_state == STATE_RACP_PROC_ACTIVE) + { + if (p_racp_request->operator != RACP_OPERATOR_NULL) + { + *p_response_code = RACP_RESPONSE_INVALID_OPERATOR; + } + else if (p_racp_request->operand_len != 0) + { + *p_response_code = RACP_RESPONSE_INVALID_OPERAND; + } + else + { + *p_response_code = RACP_RESPONSE_SUCCESS; + } + } + else + { + *p_response_code = RACP_RESPONSE_ABORT_FAILED; + } + } + else if (p_cgms->cgms_com_state != STATE_NO_COMM) + { + return false; + } + // supported opcodes + else if ((p_racp_request->opcode == RACP_OPCODE_REPORT_RECS) || + (p_racp_request->opcode == RACP_OPCODE_REPORT_NUM_RECS)) + { + switch (p_racp_request->operator) + { + // operators WITHOUT a filter + case RACP_OPERATOR_ALL: + case RACP_OPERATOR_FIRST: + case RACP_OPERATOR_LAST: + if (p_racp_request->operand_len != 0) + { + *p_response_code = RACP_RESPONSE_INVALID_OPERAND; + } + break; + + // operators WITH a filter + case RACP_OPERATOR_GREATER_OR_EQUAL: + //*p_response_code = RACP_RESPONSE_OPERATOR_UNSUPPORTED; + break; + + // unsupported operators + case RACP_OPERATOR_LESS_OR_EQUAL: + break; + case RACP_OPERATOR_RANGE: + *p_response_code = RACP_RESPONSE_OPERATOR_UNSUPPORTED; + break; + + // invalid operators + case RACP_OPERATOR_NULL: + default: + *p_response_code = RACP_RESPONSE_INVALID_OPERATOR; + break; + } + } + // unsupported opcodes + else if (p_racp_request->opcode == RACP_OPCODE_DELETE_RECS) + { + *p_response_code = RACP_RESPONSE_OPCODE_UNSUPPORTED; + } + // unknown opcodes + else + { + *p_response_code = RACP_RESPONSE_OPCODE_UNSUPPORTED; + } + + // NOTE: The computation of the return value will change slightly when deferred write has been + // implemented in the stack. + return (*p_response_code == RACP_RESPONSE_RESERVED); +} + + +/**@brief Function for processing a REPORT RECORDS request. + * + * @param[in] p_cgms Service instance. + * @param[in] p_racp_request Request to be executed. + */ +static void report_records_request_execute(nrf_ble_cgms_t * p_cgms, + ble_racp_value_t * p_racp_request) +{ + p_cgms->cgms_com_state = STATE_RACP_PROC_ACTIVE; + + p_cgms->racp_data.racp_proc_record_ndx = 0; + p_cgms->racp_data.racp_proc_operator = p_racp_request->operator; + p_cgms->racp_data.racp_proc_records_reported = 0; + //p_cgms-> + racp_report_records_procedure(p_cgms); +} + + +/**@brief Function for processing a REPORT NUM RECORDS request. + * + * @param[in] p_cgms Service instance. + * @param[in] p_racp_request Request to be executed. + */ +static void report_num_records_request_execute(nrf_ble_cgms_t * p_cgms, + ble_racp_value_t * p_racp_request) +{ + uint16_t total_records; + uint16_t num_records; + + total_records = cgms_db_num_records_get(); + num_records = 0; + + if (p_racp_request->operator == RACP_OPERATOR_ALL) + { + num_records = total_records; + } + else if ((p_racp_request->operator == RACP_OPERATOR_FIRST) || + (p_racp_request->operator == RACP_OPERATOR_LAST)) + { + if (total_records > 0) + { + num_records = 1; + } + } + + p_cgms->racp_data.pending_racp_response.opcode = RACP_OPCODE_NUM_RECS_RESPONSE; + p_cgms->racp_data.pending_racp_response.operator = RACP_OPERATOR_NULL; + p_cgms->racp_data.pending_racp_response.operand_len = sizeof(uint16_t); + p_cgms->racp_data.pending_racp_response.p_operand = + p_cgms->racp_data.pending_racp_response_operand; + + p_cgms->racp_data.pending_racp_response_operand[0] = num_records & 0xFF; + p_cgms->racp_data.pending_racp_response_operand[1] = num_records >> 8; + + racp_send(p_cgms, &p_cgms->racp_data.pending_racp_response); +} + + +/**@brief Function for handling a write event to the Record Access Control Point. + * + * @param[in] p_cgms Service instance. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_racp_value_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t * p_evt_write) +{ +// ble_racp_value_t racp_request; + uint8_t response_code; + + // set up reply to authorized write. + ble_gatts_rw_authorize_reply_params_t auth_reply; + uint32_t err_code; + + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.params.write.offset = 0; + auth_reply.params.write.len = 0; + auth_reply.params.write.p_data = NULL; + + // Decode request + ble_racp_decode(p_evt_write->len, p_evt_write->data, &p_cgms->racp_data.racp_request); + + // Check if request is to be executed + if (is_request_to_be_executed(p_cgms,&p_cgms->racp_data.racp_request, &response_code)) + { + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; + + err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, + &auth_reply); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + return; + } + + // Execute request + if (p_cgms->racp_data.racp_request.opcode == RACP_OPCODE_REPORT_RECS) + { + report_records_request_execute(p_cgms, &p_cgms->racp_data.racp_request); + } + else if (p_cgms->racp_data.racp_request.opcode == RACP_OPCODE_REPORT_NUM_RECS) + { + report_num_records_request_execute(p_cgms, &p_cgms->racp_data.racp_request); + } + } + else if (response_code != RACP_RESPONSE_RESERVED) + { + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; + err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, + &auth_reply); + + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + return; + } + // Abort any running procedure + p_cgms->cgms_com_state = STATE_NO_COMM; + + // Respond with error code + racp_response_code_send(p_cgms, p_cgms->racp_data.racp_request.opcode, response_code); + } + else + { + // ignore request + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; + err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, + &auth_reply); + + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + return; + } + } +} + + +void cgms_racp_on_rw_auth_req(nrf_ble_cgms_t * p_cgms, + ble_gatts_evt_rw_authorize_request_t * p_auth_req) +{ + if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + if (p_auth_req->request.write.handle == p_cgms->char_handles.racp.value_handle) + { + on_racp_value_write(p_cgms, &p_auth_req->request.write); + } + } +} + + +/**@brief Function for handling BLE_GATTS_EVT_HVN_TX_COMPLETE events. + * + * @param[in] p_cgms Glucose Service structure. + */ +void cgms_racp_on_tx_complete(nrf_ble_cgms_t * p_cgms) +{ + p_cgms->racp_data.racp_proc_records_reported_since_txcomplete = 0; + + if (p_cgms->cgms_com_state == STATE_RACP_RESPONSE_PENDING) + { + racp_send(p_cgms, &p_cgms->racp_data.pending_racp_response); + } + else if (p_cgms->cgms_com_state == STATE_RACP_PROC_ACTIVE) + { + racp_report_records_procedure(p_cgms); + } +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.h new file mode 100644 index 0000000000000000000000000000000000000000..4aaf67bd52fd8fed2f9485e460fdac60e47f98ce --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.h @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_srv_cgms_racp Record Access Control Point + * @{ + * @ingroup ble_cgms + * @brief Continuous Glucose Monitoring Service RACP module. + * + * @details This module implements parts of the Continuous Glucose Monitoring that relate to the + * Record Access Control Point. Events are propagated to this module from @ref ble_cgms + * using @ref cgms_racp_on_rw_auth_req and @ref cgms_racp_on_tx_complete. + * + */ + +#ifndef NRF_BLE_CGMS_RACP_H__ +#define NRF_BLE_CGMS_RACP_H__ + +#include "ble.h" +#include "ble_srv_common.h" +#include "sdk_errors.h" +#include "nrf_ble_cgms.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Function for adding a characteristic for the Record Access Control Point. + * + * @param[in] p_cgms Instance of the CGM Service. + * + * @retval NRF_SUCCESS If the characteristic was successfully added. + * @retval NRF_ERROR_NULL If any of the input parameters are NULL. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t cgms_racp_char_add(nrf_ble_cgms_t * p_cgms); + + +/**@brief Function for handling @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST events. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_auth_req Authorize request event to be handled. + */ +void cgms_racp_on_rw_auth_req(nrf_ble_cgms_t * p_cgms, + ble_gatts_evt_rw_authorize_request_t * p_auth_req); + + +/**@brief Function for handling @ref BLE_GATTS_EVT_HVN_TX_COMPLETE events. + * + * @param[in] p_cgms Instance of the CGM Service. + */ +void cgms_racp_on_tx_complete(nrf_ble_cgms_t * p_cgms); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_CGMS_RACP_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.c new file mode 100644 index 0000000000000000000000000000000000000000..4ecc7e32fd0e00ce2c9462165bda83b835515bfa --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.c @@ -0,0 +1,431 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "cgms_sst.h" +#include "cgms_socp.h" + + +#define NRF_BLE_CGMS_PLUS_INFINTE 0x07FE +#define NRF_BLE_CGMS_MINUS_INFINTE 0x0802 + +/**@brief Specific Operation Control Point opcodes. */ +#define SOCP_OPCODE_RESERVED 0x00 /**< Specific Operation Control Point opcode - Reserved for future use. */ +#define SOCP_WRITE_CGM_COMMUNICATION_INTERVAL 0x01 +#define SOCP_READ_CGM_COMMUNICATION_INTERVAL 0x02 +#define SOCP_READ_CGM_COMMUNICATION_INTERVAL_RESPONSE 0x03 +#define SOCP_WRITE_GLUCOSE_CALIBRATION_VALUE 0x04 +#define SOCP_READ_GLUCOSE_CALIBRATION_VALUE 0x05 +#define SOCP_READ_GLUCOSE_CALIBRATION_VALUE_RESPONSE 0x06 +#define SOCP_WRITE_PATIENT_HIGH_ALERT_LEVEL 0x07 +#define SOCP_READ_PATIENT_HIGH_ALERT_LEVEL 0x08 +#define SOCP_READ_PATIENT_HIGH_ALERT_LEVEL_RESPONSE 0x09 +#define SOCP_WRITE_PATIENT_LOW_ALERT_LEVEL 0x0A +#define SOCP_READ_PATIENT_LOW_ALERT_LEVEL 0x0B +#define SOCP_READ_PATIENT_LOW_ALERT_LEVEL_RESPONSE 0x0C +#define SOCP_SET_HYPO_ALERT_LEVEL 0x0D /**Set Hypo Alert Level Hypo Alert Level value in mg/dL The response to this control point is Response Code. */ +#define SOCP_GET_HYPO_ALERT_LEVEL 0x0E /**Get Hypo Alert Level N/A The normal response to this control point is Op Code 0x0F. For error conditions, the response is Response Code */ +#define SOCP_HYPO_ALERT_LEVEL_RESPONSE 0x0F /**Hypo Alert Level Response Hypo Alert Level value in mg/dL This is the normal response to Op Code 0x0E */ +#define SOCP_SET_HYPER_ALERT_LEVEL 0x10 /**Set Hyper Alert Level Hyper Alert Level value in mg/dL The response to this control point is Response Code. */ +#define SOCP_GET_HYPER_ALERT_LEVEL 0x11 /**Get Hyper Alert Level N/A The normal response to this control point is Op Code 0x12. For error conditions, the response is Response Code */ +#define SOCP_HYPER_ALERT_LEVEL_RESPONSE 0x12 /**Hyper Alert Level Response Hyper Alert Level value in mg/dL This is the normal response to Op Code 0x11 */ +#define SOCP_SET_RATE_OF_DECREASE_ALERT_LEVEL 0x13 /**Set Rate of Decrease Alert Level Rate of Decrease Alert Level value in mg/dL/min The response to this control point is Response Code. */ +#define SOCP_GET_RATE_OF_DECREASE_ALERT_LEVEL 0x14 /**Get Rate of Decrease Alert Level N/A The normal response to this control point is Op Code 0x15. For error conditions, the response is Response Code */ +#define SOCP_RATE_OF_DECREASE_ALERT_LEVEL_RESPONSE 0x15 /**Rate of Decrease Alert Level Response Rate of Decrease Alert Level value in mg/dL/min This is the normal response to Op Code 0x14 */ +#define SOCP_SET_RATE_OF_INCREASE_ALERT_LEVEL 0x16 /**Set Rate of Increase Alert Level Rate of Increase Alert Level value in mg/dL/min The response to this control point is Response Code. */ +#define SOCP_GET_RATE_OF_INCREASE_ALERT_LEVEL 0x17 /**Get Rate of Increase Alert Level N/A The normal response to this control point is Op Code 0x18. For error conditions, the response is Response Code */ +#define SOCP_RATE_OF_INCREASE_ALERT_LEVEL_RESPONSE 0x18 /**Rate of Increase Alert Level Response Rate of Increase Alert Level value in mg/dL/min This is the normal response to Op Code 0x17 */ +#define SOCP_RESET_DEVICE_SPECIFIC_ALERT 0x19 /**Reset Device Specific Alert N/A The response to this control point is Response Code. */ + +#define SOCP_START_THE_SESSION 0x1A +#define SOCP_STOP_THE_SESSION 0x1B +#define SOCP_RESPONSE_CODE 0x1C + +#define SOCP_RSP_RESERVED_FOR_FUTURE_USE 0x00 +#define SOCP_RSP_SUCCESS 0x01 +#define SOCP_RSP_OP_CODE_NOT_SUPPORTED 0x02 +#define SOCP_RSP_INVALID_OPERAND 0x03 +#define SOCP_RSP_PROCEDURE_NOT_COMPLETED 0x04 +#define SOCP_RSP_OUT_OF_RANGE 0x05 + +static void ble_socp_decode(uint8_t data_len, uint8_t * p_data, ble_cgms_socp_value_t * p_socp_val) +{ + p_socp_val->opcode = 0xFF; + p_socp_val->operand_len = 0; + p_socp_val->p_operand = NULL; + + if (data_len > 0) + { + p_socp_val->opcode = p_data[0]; + } + if (data_len > 1) + { + p_socp_val->operand_len = data_len - 1; + p_socp_val->p_operand = &p_data[1]; // lint !e416 + } +} + + +uint8_t ble_socp_encode(const ble_socp_rsp_t * p_socp_rsp, uint8_t * p_data) +{ + uint8_t len = 0; + int i; + + + if (p_data != NULL) + { + p_data[len++] = p_socp_rsp->opcode; + + if ( + (p_socp_rsp->opcode != SOCP_READ_CGM_COMMUNICATION_INTERVAL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_READ_PATIENT_HIGH_ALERT_LEVEL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_READ_PATIENT_LOW_ALERT_LEVEL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_HYPO_ALERT_LEVEL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_HYPER_ALERT_LEVEL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_RATE_OF_DECREASE_ALERT_LEVEL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_RATE_OF_INCREASE_ALERT_LEVEL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_READ_GLUCOSE_CALIBRATION_VALUE_RESPONSE) + ) + { + p_data[len++] = p_socp_rsp->req_opcode; + p_data[len++] = p_socp_rsp->rsp_code; + } + + for (i = 0; i < p_socp_rsp->size_val; i++) + { + p_data[len++] = p_socp_rsp->resp_val[i]; + } + } + + return len; +} + + +/**@brief Function for adding a characteristic for the Specific Operations Control Point. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +ret_code_t cgms_socp_char_add(nrf_ble_cgms_t * p_cgms) +{ + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + add_char_params.uuid = BLE_UUID_CGM_SPECIFIC_OPS_CTRLPT; + add_char_params.max_len = BLE_GATT_ATT_MTU_DEFAULT; + add_char_params.init_len = 0; + add_char_params.p_init_value = 0; + add_char_params.is_var_len = true; + add_char_params.char_props.indicate = true; + add_char_params.char_props.write = true; + add_char_params.write_access = SEC_JUST_WORKS; + add_char_params.cccd_write_access = SEC_JUST_WORKS; + add_char_params.is_defered_write = 1; + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.socp); +} + + +/**@brief Function for sending a response from the Specific Operation Control Point. + * + * @param[in] p_cgms Service instance. + */ +static void socp_send(nrf_ble_cgms_t * p_cgms) +{ + uint32_t err_code; + uint8_t encoded_resp[25]; + uint8_t len; + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + + // Send indication + len = ble_socp_encode(&(p_cgms->socp_response), encoded_resp); + hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_cgms->char_handles.socp.value_handle; + hvx_params.type = BLE_GATT_HVX_INDICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_resp; + + err_code = sd_ble_gatts_hvx(p_cgms->conn_handle, &hvx_params); + + // Error handling + if ((err_code == NRF_SUCCESS) && (hvx_len != len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + + switch (err_code) + { + case NRF_SUCCESS: + // Wait for HVC event. + p_cgms->cgms_com_state = STATE_SOCP_RESPONSE_IND_VERIF; + break; + + case NRF_ERROR_RESOURCES: + // Wait for TX_COMPLETE event to retry transmission. + p_cgms->cgms_com_state = STATE_SOCP_RESPONSE_PENDING; + break; + + case NRF_ERROR_INVALID_STATE: + // Make sure state machine returns to the default state. + p_cgms->cgms_com_state = STATE_NO_COMM; + break; + + default: + // Report error to application. + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + + // Make sure state machine returns to the default state. + p_cgms->cgms_com_state = STATE_NO_COMM; + break; + } +} + + +void encode_get_response(uint8_t rsp_code, ble_socp_rsp_t * p_rsp, uint16_t in_val) +{ + p_rsp->opcode = rsp_code; + p_rsp->rsp_code = SOCP_RSP_SUCCESS; + p_rsp->size_val += uint16_encode(in_val, &(p_rsp->resp_val[p_rsp->size_val])); +} + + +void decode_set_opcode(nrf_ble_cgms_t * p_cgms, + ble_cgms_socp_value_t * rcv_val, + uint16_t min, + uint16_t max, + uint16_t * p_val) +{ + uint16_t rcvd_val = uint16_decode(rcv_val->p_operand); + + if ((rcvd_val == NRF_BLE_CGMS_PLUS_INFINTE) + || (rcvd_val == NRF_BLE_CGMS_MINUS_INFINTE) + || (rcvd_val > max) + || (rcvd_val < min)) + { + p_cgms->socp_response.rsp_code = SOCP_RSP_OUT_OF_RANGE; + } + else + { + p_cgms->socp_response.rsp_code = SOCP_RSP_SUCCESS; + *p_val = rcvd_val; + } +} + + +static bool is_feature_present(nrf_ble_cgms_t * p_cgms, uint32_t feature) +{ + return (p_cgms->feature.feature & feature); +} + + +/**@brief Function for handling a write event to the Specific Operation Control Point. + * + * @param[in] p_cgms Service instance. + * @param[in] p_evt_write WRITE event to be handled. + */ +void on_socp_value_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t * p_evt_write) +{ + ble_cgms_socp_value_t socp_request; + nrf_ble_cgms_evt_t evt; + ble_gatts_rw_authorize_reply_params_t auth_reply; + uint32_t err_code; + + memset(&auth_reply, 0, sizeof(auth_reply)); + + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; + + err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + return; + } + + // Decode request + ble_socp_decode(p_evt_write->len, p_evt_write->data, &socp_request); + + p_cgms->socp_response.opcode = SOCP_RESPONSE_CODE; + p_cgms->socp_response.req_opcode = socp_request.opcode; + p_cgms->socp_response.rsp_code = SOCP_RSP_OP_CODE_NOT_SUPPORTED; + p_cgms->socp_response.size_val = 0; + + + switch (socp_request.opcode) + { + case SOCP_WRITE_CGM_COMMUNICATION_INTERVAL: + p_cgms->socp_response.rsp_code = SOCP_RSP_SUCCESS; + p_cgms->comm_interval = socp_request.p_operand[0]; + evt.evt_type = NRF_BLE_CGMS_EVT_WRITE_COMM_INTERVAL; + p_cgms->evt_handler(p_cgms, &evt); + break; + + case SOCP_READ_CGM_COMMUNICATION_INTERVAL: + p_cgms->socp_response.opcode = SOCP_READ_CGM_COMMUNICATION_INTERVAL_RESPONSE; + p_cgms->socp_response.resp_val[0] = p_cgms->comm_interval; + p_cgms->socp_response.size_val++; + break; + + case SOCP_START_THE_SESSION: + if (p_cgms->is_session_started) + { + p_cgms->socp_response.rsp_code = SOCP_RSP_PROCEDURE_NOT_COMPLETED; + } + else if ((p_cgms->nb_run_session != 0) && + !(is_feature_present(p_cgms, NRF_BLE_CGMS_FEAT_MULTIPLE_SESSIONS_SUPPORTED))) + { + p_cgms->socp_response.rsp_code = SOCP_RSP_PROCEDURE_NOT_COMPLETED; + } + else + { + p_cgms->socp_response.rsp_code = SOCP_RSP_SUCCESS; + p_cgms->is_session_started = true; + p_cgms->nb_run_session++; + + if (p_cgms->evt_handler != NULL) + { + evt.evt_type = NRF_BLE_CGMS_EVT_START_SESSION; + p_cgms->evt_handler(p_cgms, &evt); + } + + ble_cgms_sst_t sst; + memset(&sst, 0, sizeof(ble_cgms_sst_t)); + + err_code = cgms_sst_set(p_cgms, &sst); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + } + p_cgms->sensor_status.time_offset = 0; + p_cgms->sensor_status.status.status &= (~NRF_BLE_CGMS_STATUS_SESSION_STOPPED); + + err_code = nrf_ble_cgms_update_status(p_cgms, &p_cgms->sensor_status); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + } + } + break; + + case SOCP_STOP_THE_SESSION: + { + nrf_ble_cgm_status_t status; + memset(&status, 0, sizeof(nrf_ble_cgm_status_t)); + + p_cgms->evt_handler(p_cgms, &evt); + p_cgms->socp_response.rsp_code = SOCP_RSP_SUCCESS; + p_cgms->is_session_started = false; + + status.time_offset = p_cgms->sensor_status.time_offset; + status.status.status = p_cgms->sensor_status.status.status | + NRF_BLE_CGMS_STATUS_SESSION_STOPPED; + + if (p_cgms->evt_handler != NULL) + { + evt.evt_type = NRF_BLE_CGMS_EVT_STOP_SESSION; + p_cgms->evt_handler(p_cgms, &evt); + } + err_code = nrf_ble_cgms_update_status(p_cgms, &status); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + } + break; + } + + default: + p_cgms->socp_response.rsp_code = SOCP_RSP_OP_CODE_NOT_SUPPORTED; + break; + } + + socp_send(p_cgms); +} + + +void cgms_socp_on_rw_auth_req(nrf_ble_cgms_t * p_cgms, + ble_gatts_evt_rw_authorize_request_t * p_auth_req) +{ + if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + if (p_auth_req->request.write.handle == p_cgms->char_handles.socp.value_handle) + { + on_socp_value_write(p_cgms, &p_auth_req->request.write); + } + } +} + + +void cgms_socp_on_tx_complete(nrf_ble_cgms_t * p_cgms) +{ + if (p_cgms->cgms_com_state == STATE_SOCP_RESPONSE_PENDING) + { + socp_send(p_cgms); + } +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.h new file mode 100644 index 0000000000000000000000000000000000000000..e8777b43142e7a8a9659b6770eaff90064737a94 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.h @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_srv_cgms_socp Specific Operations Control Point + * @{ + * @ingroup ble_cgms + * @brief Continuous Glucose Monitoring Service SOCP module. + * + * @details This module implements parts of the Continuous Glucose Monitoring that relate to the + * Specific Operations Control Point. Events are propagated to this module from @ref ble_cgms + * using @ref cgms_socp_on_rw_auth_req and @ref cgms_socp_on_tx_complete. + * + */ + +#ifndef NRF_BLE_CGMS_SOCP_H__ +#define NRF_BLE_CGMS_SOCP_H__ + +#include "ble.h" +#include "ble_srv_common.h" +#include "sdk_errors.h" +#include "nrf_ble_cgms.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Specific Operation Control Point value. */ +typedef struct +{ + uint8_t opcode; /**< Opcode. */ + uint8_t operand_len; /**< Length of the operand. */ + uint8_t * p_operand; /**< Pointer to the operand. */ +} ble_cgms_socp_value_t; + + +/**@brief Function for adding a characteristic for the Specific Operations Control Point. + * + * @param[in] p_cgms Instance of the CGM Service. + * + * @retval NRF_SUCCESS If the characteristic was successfully added. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t cgms_socp_char_add(nrf_ble_cgms_t * p_cgms); + + +/**@brief Function for handling @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST events. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_auth_req Authorize request event to be handled. + */ +void cgms_socp_on_rw_auth_req(nrf_ble_cgms_t * p_cgms, + ble_gatts_evt_rw_authorize_request_t * p_auth_req); + + +/**@brief Function for handling @ref BLE_GATTS_EVT_HVN_TX_COMPLETE events. + * + * @param[in] p_cgms Instance of the CGM Service. + */ +void cgms_socp_on_tx_complete(nrf_ble_cgms_t * p_cgms); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_CGMS_SOCP_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c new file mode 100644 index 0000000000000000000000000000000000000000..e328796eb195784952632a8d8d077bcb8e0ff90c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c @@ -0,0 +1,234 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "nrf_ble_cgms.h" +#include "cgms_sst.h" + + +void sst_decode(ble_cgms_sst_t * p_sst, const uint8_t * p_data, const uint16_t len) +{ + uint32_t index; + + if (len != NRF_BLE_CGMS_SST_LEN) + { + return; + } + + index = ble_date_time_decode(&p_sst->date_time, p_data); + + p_sst->time_zone = p_data[index++]; + p_sst->dst = p_data[index++]; +} + + +void convert_ble_time_c_time(ble_cgms_sst_t * p_sst, struct tm * p_c_time_date) +{ + p_c_time_date->tm_sec = p_sst->date_time.seconds; + p_c_time_date->tm_min = p_sst->date_time.minutes; + p_c_time_date->tm_hour = p_sst->date_time.hours; + p_c_time_date->tm_mday = p_sst->date_time.day; + p_c_time_date->tm_mon = p_sst->date_time.month; + p_c_time_date->tm_year = p_sst->date_time.year - 1900; + + // Ignore daylight saving for this conversion. + p_c_time_date->tm_isdst = 0; +} + + +void calc_sst(uint16_t offset, struct tm * p_c_time_date) +{ + time_t c_time_in_sec; + + c_time_in_sec = mktime(p_c_time_date); + c_time_in_sec = c_time_in_sec - (offset * 60); + *p_c_time_date = *(localtime(&c_time_in_sec)); + + if(p_c_time_date->tm_isdst == 1) + { + // Daylight saving time is not used and must be removed. + p_c_time_date->tm_hour = p_c_time_date->tm_hour - 1; + p_c_time_date->tm_isdst = 0; + } +} + + +static void convert_c_time_ble_time(ble_cgms_sst_t * p_sst, struct tm * p_c_time_date) +{ + p_sst->date_time.seconds = p_c_time_date->tm_sec; + p_sst->date_time.minutes = p_c_time_date->tm_min; + p_sst->date_time.hours = p_c_time_date->tm_hour; + p_sst->date_time.day = p_c_time_date->tm_mday; + p_sst->date_time.month = p_c_time_date->tm_mon; + p_sst->date_time.year = p_c_time_date->tm_year + 1900; +} + + +static uint8_t sst_encode(ble_cgms_sst_t * p_sst, uint8_t * p_encoded_sst) +{ + uint8_t len; + + len = ble_date_time_encode(&p_sst->date_time, p_encoded_sst); + + p_encoded_sst[len++] = p_sst->time_zone; + p_encoded_sst[len++] = p_sst->dst; + + return len; +} + + +static ret_code_t cgm_update_sst(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write) +{ + ble_cgms_sst_t sst; + struct tm c_time_and_date; + + memset(&sst, 0, sizeof(ble_cgms_sst_t)); + + sst_decode(&sst, p_evt_write->data, p_evt_write->len); + convert_ble_time_c_time(&sst, &c_time_and_date); + calc_sst(p_cgms->sensor_status.time_offset, &c_time_and_date); + convert_c_time_ble_time(&sst, &c_time_and_date); + + return cgms_sst_set(p_cgms, &sst); +} + + +/**@brief Function for handling the Glucose session start time write event. + * + * @param[in] p_cgms Service instance. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_sst_value_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write) +{ + ble_gatts_rw_authorize_reply_params_t auth_reply; + uint32_t err_code; + + memset(&auth_reply, 0, sizeof(auth_reply)); + + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.params.write.update = 1; + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + + err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + } + + err_code = cgm_update_sst(p_cgms, p_evt_write); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + } +} + + +/**@brief Function for adding a characteristic for the Session Start Time. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +ret_code_t cgms_sst_char_add(nrf_ble_cgms_t * p_cgms) +{ + ble_add_char_params_t add_char_params; + uint8_t init_value[NRF_BLE_CGMS_SST_LEN] = {0}; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + add_char_params.uuid = BLE_UUID_CGM_SESSION_START_TIME; + add_char_params.max_len = NRF_BLE_CGMS_SST_LEN; + + add_char_params.init_len = NRF_BLE_CGMS_SST_LEN; + add_char_params.p_init_value = init_value; + + add_char_params.read_access = SEC_JUST_WORKS; + add_char_params.write_access = SEC_JUST_WORKS; + add_char_params.is_defered_write = 1; + add_char_params.char_props.write = true; + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.sst); +} + + +ret_code_t cgms_sst_set(nrf_ble_cgms_t * p_cgms, ble_cgms_sst_t * p_sst) +{ + uint16_t conn_handle; + uint16_t value_handle; + ble_gatts_value_t sst_val; + uint8_t encoded_start_session_time[NRF_BLE_CGMS_SST_LEN]; + uint8_t gatts_value_set_len = 0; + + gatts_value_set_len = sst_encode(p_sst, encoded_start_session_time); + conn_handle = p_cgms->conn_handle; + value_handle = p_cgms->char_handles.sst.value_handle; + memset(&sst_val, 0, sizeof(ble_gatts_value_t)); + sst_val.len = gatts_value_set_len; + sst_val.p_value = encoded_start_session_time; + sst_val.offset = 0; + + return (sd_ble_gatts_value_set(conn_handle, value_handle, &sst_val)); +} + + +void cgms_sst_on_rw_auth_req(nrf_ble_cgms_t * p_cgms, + ble_gatts_evt_rw_authorize_request_t const * p_auth_req) +{ + if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + if (p_auth_req->request.write.handle == p_cgms->char_handles.sst.value_handle) + { + on_sst_value_write(p_cgms, &p_auth_req->request.write); + } + } +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.h new file mode 100644 index 0000000000000000000000000000000000000000..483d656f2bdda6307acdecb449bc2d6aa6937b33 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.h @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_srv_cgms_sst Session Start Time + * @{ + * @ingroup ble_cgms + * + * @brief Continuous Glucose Monitoring Service SST module. + * + * @details This module implements parts of the Continuous Glucose Monitoring that relate to the + * Session Start Time characteristic. Events are propagated to this module from @ref ble_cgms + * using @ref cgms_sst_on_rw_auth_req. + * + */ + +#ifndef NRF_BLE_CGMS_SST_H__ +#define NRF_BLE_CGMS_SST_H__ + + +#include "ble.h" +#include "ble_srv_common.h" +#include "ble_date_time.h" +#include "sdk_errors.h" +#include "nrf_ble_cgms.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Required data for setting the SST characteristic value. */ +typedef struct +{ + ble_date_time_t date_time; /**< Date and time. */ + uint8_t time_zone; /**< Time zone. */ + uint8_t dst; /**< Daylight saving time. */ +}ble_cgms_sst_t; + +/**@brief Function for adding a characteristic for the Session Start Time. + * + * @param[in] p_cgms Instance of the CGM Service. + * + * @retval NRF_SUCCESS If the characteristic was successfully added. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t cgms_sst_char_add(nrf_ble_cgms_t * p_cgms); + + +/**@brief Function for setting the Session Run Time attribute. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_sst Time and date that will be displayed in the session start time attribute. + * + * @retval NRF_SUCCESS If the Session Run Time Attribute was successfully set. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t cgms_sst_set(nrf_ble_cgms_t * p_cgms, ble_cgms_sst_t * p_sst); + + +/**@brief Function for handling @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST events. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_auth_req Authorize request event to be handled. + */ +void cgms_sst_on_rw_auth_req(nrf_ble_cgms_t * p_cgms, + ble_gatts_evt_rw_authorize_request_t const * p_auth_req); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_CGMS_SST_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.c new file mode 100644 index 0000000000000000000000000000000000000000..7dcb221e6c13588fe112142c61edb2b6d433d3a1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.c @@ -0,0 +1,501 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_racp.h" +#include "ble_srv_common.h" + +#include "ble_date_time.h" +#include "sdk_common.h" + +#include "nrf_ble_cgms.h" +#include "cgms_db.h" +#include "cgms_meas.h" +#include "cgms_racp.h" +#include "cgms_socp.h" +#include "cgms_sst.h" + +#define OPERAND_FILTER_TYPE_RESV 0x00 /**< Filter type value reserved for future use. */ +#define OPERAND_FILTER_TYPE_SEQ_NUM 0x01 /**< Filter data using Sequence Number criteria. */ +#define OPERAND_FILTER_TYPE_FACING_TIME 0x02 /**< Filter data using User Facing Time criteria. */ + + +/**@brief Function for setting next sequence number by reading the last record in the data base. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +static uint32_t next_sequence_number_set(void) +{ + uint16_t num_records; + ble_cgms_rec_t rec; + + num_records = cgms_db_num_records_get(); + if (num_records > 0) + { + // Get last record + uint32_t err_code = cgms_db_record_get(num_records - 1, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +uint8_t encode_feature_location_type(uint8_t * p_out_buffer, nrf_ble_cgms_feature_t * p_in_feature) +{ + uint8_t len = 0; + + len += uint24_encode(p_in_feature->feature, &p_out_buffer[len]); + p_out_buffer[len++] = (p_in_feature->sample_location << 4) | (p_in_feature->type & 0x0F); + len += uint16_encode(0xFFFF, &p_out_buffer[len]); + + return len; +} + + +/**@brief Function for adding a characteristic for the glucose feature. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +static uint32_t glucose_feature_char_add(nrf_ble_cgms_t * p_cgms) +{ + uint8_t init_value_len; + uint8_t encoded_initial_feature[NRF_BLE_CGMS_FEATURE_LEN]; + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + init_value_len = encode_feature_location_type(encoded_initial_feature, &(p_cgms->feature)); + + add_char_params.uuid = BLE_UUID_CGM_FEATURE; + add_char_params.max_len = init_value_len; + add_char_params.init_len = init_value_len; + add_char_params.p_init_value = encoded_initial_feature; + add_char_params.read_access = SEC_JUST_WORKS; + add_char_params.write_access = SEC_NO_ACCESS; + + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.feature); +} + + +uint8_t encode_status(uint8_t * p_out_buffer, nrf_ble_cgms_t * p_cgms) +{ + uint8_t len = 0; + + len += uint16_encode(p_cgms->sensor_status.time_offset, &p_out_buffer[len]); + + p_out_buffer[len++] = p_cgms->sensor_status.status.status; + p_out_buffer[len++] = p_cgms->sensor_status.status.calib_temp; + p_out_buffer[len++] = p_cgms->sensor_status.status.warning; + + return len; +} + + +/**@brief Function for adding a status characteristic for the CGMS. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +static uint32_t status_char_add(nrf_ble_cgms_t * p_cgms) +{ + uint8_t init_value_len; + uint8_t encoded_initial_status[NRF_BLE_CGMS_STATUS_LEN]; + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + init_value_len = encode_status(encoded_initial_status, p_cgms); + + add_char_params.uuid = BLE_UUID_CGM_STATUS; + add_char_params.max_len = init_value_len; + add_char_params.init_len = init_value_len; + add_char_params.p_init_value = encoded_initial_status; + add_char_params.read_access = SEC_JUST_WORKS; + add_char_params.write_access = SEC_NO_ACCESS; + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.status); +} + + +/**@brief Function for adding a characteristic for the Session Run Time. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +static uint32_t srt_char_add(nrf_ble_cgms_t * p_cgms) +{ + uint8_t len = 0; + uint8_t encoded_initial_srt[NRF_BLE_CGMS_SRT_LEN]; + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + + len += uint16_encode(p_cgms->session_run_time, &(encoded_initial_srt[len])); + + add_char_params.uuid = BLE_UUID_CGM_SESSION_RUN_TIME; + add_char_params.max_len = NRF_BLE_CGMS_SRT_LEN; + add_char_params.init_len = len; + add_char_params.p_init_value = encoded_initial_srt; + add_char_params.read_access = SEC_JUST_WORKS; + add_char_params.write_access = SEC_NO_ACCESS; + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.srt); +} + + +uint8_t init_calib_val[] = { + 0x3E, + 0x00, + 0x07, + 0x00, + 0x06, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, +}; +ret_code_t nrf_ble_cgms_init(nrf_ble_cgms_t * p_cgms, const nrf_ble_cgms_init_t * p_cgms_init) +{ + VERIFY_PARAM_NOT_NULL(p_cgms); + VERIFY_PARAM_NOT_NULL(p_cgms_init); + VERIFY_PARAM_NOT_NULL(p_cgms_init->evt_handler); + + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Initialize data base + err_code = cgms_db_init(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = next_sequence_number_set(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Initialize service structure + p_cgms->evt_handler = p_cgms_init->evt_handler; + p_cgms->error_handler = p_cgms_init->error_handler; + p_cgms->feature = p_cgms_init->feature; + p_cgms->sensor_status = p_cgms_init->initial_sensor_status; + p_cgms->session_run_time = p_cgms_init->initial_run_time; + p_cgms->is_session_started = false; + p_cgms->nb_run_session = 0; + p_cgms->conn_handle = BLE_CONN_HANDLE_INVALID; + + p_cgms->feature.feature = 0; + p_cgms->feature.feature |= NRF_BLE_CGMS_FEAT_MULTIPLE_BOND_SUPPORTED; + p_cgms->feature.feature |= NRF_BLE_CGMS_FEAT_MULTIPLE_SESSIONS_SUPPORTED; + p_cgms->feature.type = NRF_BLE_CGMS_MEAS_TYPE_VEN_BLOOD; + p_cgms->feature.sample_location = NRF_BLE_CGMS_MEAS_LOC_AST; + p_cgms->feature.feature |= NRF_BLE_CGMS_FEAT_MULTIPLE_BOND_SUPPORTED; + + memcpy(p_cgms->calibration_val[0].value, init_calib_val, NRF_BLE_CGMS_MAX_CALIB_LEN); + + // Initialize global variables + p_cgms->cgms_com_state = STATE_NO_COMM; + p_cgms->racp_data.racp_proc_records_reported_since_txcomplete = 0; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CGM_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_cgms->service_handle); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add glucose measurement characteristic + err_code = cgms_meas_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add glucose measurement feature characteristic + err_code = glucose_feature_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add glucose measurement status characteristic + err_code = status_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add record control access point characteristic + err_code = cgms_racp_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add Start Session Time characteristic + err_code = cgms_sst_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add Session Run Time characteristic + err_code = srt_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add Specific Operations Control Point characteristic + err_code = cgms_socp_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for handling the WRITE event. + * + * @details Handles WRITE events from the BLE stack. + * + * @param[in] p_cgms Glucose Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(nrf_ble_cgms_t * p_cgms, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + cgms_meas_on_write(p_cgms, p_evt_write); +} + + +/**@brief Function for handling the TX_COMPLETE event. + * + * @details Handles TX_COMPLETE events from the BLE stack. + * + * @param[in] p_cgms Glucose Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_tx_complete(nrf_ble_cgms_t * p_cgms, ble_evt_t * p_ble_evt) +{ + p_cgms->racp_data.racp_proc_records_reported_since_txcomplete = 0; + + cgms_racp_on_tx_complete(p_cgms); + cgms_socp_on_tx_complete(p_cgms); +} + + +/**@brief Function for handling the HVC event. + * + * @details Handles HVC events from the BLE stack. + * + * @param[in] p_cgms Glucose Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_hvc(nrf_ble_cgms_t * p_cgms, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_hvc_t * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc; + + if (p_hvc->handle == p_cgms->char_handles.racp.value_handle) + { + if (p_cgms->cgms_com_state == STATE_RACP_RESPONSE_IND_VERIF) + { + // Indication has been acknowledged. Return to default state. + p_cgms->cgms_com_state = STATE_NO_COMM; + } + else + { + // We did not expect this event in this state. Report error to application. + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(NRF_ERROR_INVALID_STATE); + } + } + } + if (p_hvc->handle == p_cgms->char_handles.socp.value_handle) + { + if (p_cgms->cgms_com_state == STATE_SOCP_RESPONSE_IND_VERIF) + { + // Indication has been acknowledged. Return to default state. + p_cgms->cgms_com_state = STATE_NO_COMM; + } + else + { + // We did not expect this event in this state. Report error to application. + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(NRF_ERROR_INVALID_STATE); + } + } + } +} + + +static void on_rw_authorize_request(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_t * p_gatts_evt) +{ + ble_gatts_evt_rw_authorize_request_t * p_auth_req = &p_gatts_evt->params.authorize_request; + + cgms_racp_on_rw_auth_req(p_cgms, p_auth_req); + cgms_socp_on_rw_auth_req(p_cgms, p_auth_req); + cgms_sst_on_rw_auth_req(p_cgms, p_auth_req); +} + + +void nrf_ble_cgms_on_ble_evt(nrf_ble_cgms_t * p_cgms, ble_evt_t * p_ble_evt) +{ + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + p_cgms->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + p_cgms->cgms_com_state = STATE_NO_COMM; + break; + + case BLE_GAP_EVT_DISCONNECTED: + p_cgms->conn_handle = BLE_CONN_HANDLE_INVALID; + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_cgms, p_ble_evt); + break; + + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + on_tx_complete(p_cgms, p_ble_evt); + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + on_rw_authorize_request(p_cgms, &p_ble_evt->evt.gatts_evt); + break; + + case BLE_GATTS_EVT_HVC: + on_hvc(p_cgms, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +ret_code_t nrf_ble_cgms_meas_create(nrf_ble_cgms_t * p_cgms, ble_cgms_rec_t * p_rec) +{ + uint32_t err_code = NRF_SUCCESS; + uint8_t nb_rec_to_send = 1; + + err_code = cgms_db_record_add(p_rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + if ((p_cgms->conn_handle != BLE_CONN_HANDLE_INVALID) && (p_cgms->comm_interval != 0)) + { + err_code = cgms_meas_send(p_cgms, p_rec, &nb_rec_to_send); + } + return err_code; +} + + +ret_code_t nrf_ble_cgms_update_status(nrf_ble_cgms_t * p_cgms, nrf_ble_cgm_status_t * p_status) +{ + uint8_t encoded_status[NRF_BLE_CGMS_STATUS_LEN]; + ble_gatts_value_t status_val; + + memset(&status_val, 0, sizeof(status_val)); + p_cgms->sensor_status = *p_status; + status_val.len = encode_status(encoded_status, p_cgms); + status_val.p_value = encoded_status; + status_val.offset = 0; + + return (sd_ble_gatts_value_set(p_cgms->conn_handle, p_cgms->char_handles.status.value_handle, + &status_val)); +} + + +ret_code_t nrf_ble_cgms_conn_handle_assign(nrf_ble_cgms_t * p_cgms, uint16_t conn_handle) +{ + VERIFY_PARAM_NOT_NULL(p_cgms); + p_cgms->conn_handle = conn_handle; + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_cgms_srt_set(nrf_ble_cgms_t * p_cgms, uint16_t run_time) +{ + ble_gatts_value_t srt_val; + uint8_t encoded_session_run_time[NRF_BLE_CGMS_SRT_LEN]; + uint8_t gatts_value_set_len = 0; + + gatts_value_set_len = uint16_encode(run_time, encoded_session_run_time); // (p_sst, encoded_start_session_time); + + memset(&srt_val, 0, sizeof(ble_gatts_value_t)); + srt_val.len = gatts_value_set_len; + srt_val.p_value = encoded_session_run_time; + srt_val.offset = 0; + + return (sd_ble_gatts_value_set(p_cgms->conn_handle, p_cgms->char_handles.srt.value_handle, + &srt_val)); +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.h new file mode 100644 index 0000000000000000000000000000000000000000..a9a98df911f963a8346d7f3a175be2eac6860931 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.h @@ -0,0 +1,435 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_cgms Continuous Glucose Monitoring Service + * @{ + * @ingroup ble_sdk_srv + * @brief Continuous Glucose Monitoring Service (CGMS) module. + * + * @details This module implements a sensor for the Continuous Glucose Monitoring Service. + * The sensor is a GATT Server that sends CGM measurements to a connected CGMS + * Collector. The CGMS Sensor stores records that can be accessed with the + * Record Access Control Point (RACP). The collector can access the features and status + * of the sensor. Session Run Time and Session Start Time can be used to convey timing + * information between the sensor and the collector. The Specific Operations Control Point + * is used to stop and start monitoring sessions, among other things. + * + * @note The application must propagate BLE stack events to the Continuous Glucose Monitoring + * Service module by calling @ref nrf_ble_cgms_on_ble_evt() from the + * @ref softdevice_handler callback. + */ + +#ifndef NRF_BLE_CGMS_H__ +#define NRF_BLE_CGMS_H__ + +#include "ble_srv_common.h" +#include "sdk_errors.h" +#include "ble_racp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@name CGM Feature characteristic defines + * @{ */ +#define NRF_BLE_CGMS_FEAT_CALIBRATION_SUPPORTED (0x01 << 0) //!< Calibration supported. +#define NRF_BLE_CGMS_FEAT_PATIENT_HIGH_LOW_ALERTS_SUPPORTED (0x01 << 1) //!< Patient High/Low Alerts supported. +#define NRF_BLE_CGMS_FEAT_HYPO_ALERTS_SUPPORTED (0x01 << 2) //!< Hypo Alerts supported. +#define NRF_BLE_CGMS_FEAT_HYPER_ALERTS_SUPPORTED (0x01 << 3) //!< Hyper Alerts supported. +#define NRF_BLE_CGMS_FEAT_RATE_OF_INCREASE_DECREASE_ALERTS_SUPPORTED (0x01 << 4) //!< Rate of Increase/Decrease Alerts supported. +#define NRF_BLE_CGMS_FEAT_DEVICE_SPECIFIC_ALERT_SUPPORTED (0x01 << 5) //!< Device Specific Alert supported. +#define NRF_BLE_CGMS_FEAT_SENSOR_MALFUNCTION_DETECTION_SUPPORTED (0x01 << 6) //!< Sensor Malfunction Detection supported. +#define NRF_BLE_CGMS_FEAT_SENSOR_TEMPERATURE_HIGH_LOW_DETECTION_SUPPORTED (0x01 << 7) //!< Sensor Temperature High-Low Detection supported. +#define NRF_BLE_CGMS_FEAT_SENSOR_RESULT_HIGH_LOW_DETECTION_SUPPORTED (0x01 << 8) //!< Sensor Result High-Low Detection supported. +#define NRF_BLE_CGMS_FEAT_LOW_BATTERY_DETECTION_SUPPORTED (0x01 << 9) //!< Low Battery Detection supported. +#define NRF_BLE_CGMS_FEAT_SENSOR_TYPE_ERROR_DETECTION_SUPPORTED (0x01 << 10) //!< Sensor Type Error Detection supported. +#define NRF_BLE_CGMS_FEAT_GENERAL_DEVICE_FAULT_SUPPORTED (0x01 << 11) //!< General Device Fault supported. +#define NRF_BLE_CGMS_FEAT_E2E_CRC_SUPPORTED (0x01 << 12) //!< E2E-CRC supported. +#define NRF_BLE_CGMS_FEAT_MULTIPLE_BOND_SUPPORTED (0x01 << 13) //!< Multiple Bond supported. +#define NRF_BLE_CGMS_FEAT_MULTIPLE_SESSIONS_SUPPORTED (0x01 << 14) //!< Multiple Sessions supported. +#define NRF_BLE_CGMS_FEAT_CGM_TREND_INFORMATION_SUPPORTED (0x01 << 15) //!< CGM Trend Information supported. +#define NRF_BLE_CGMS_FEAT_CGM_QUALITY_SUPPORTED (0x01 << 16) //!< CGM Quality supported. +/** @} */ + +/**@name Continuous Glucose Monitoring type + * @{ */ +#define NRF_BLE_CGMS_MEAS_TYPE_CAP_BLOOD 0x01 //!< Capillary Whole blood. +#define NRF_BLE_CGMS_MEAS_TYPE_CAP_PLASMA 0x02 //!< Capillary Plasma. +#define NRF_BLE_CGMS_MEAS_TYPE_VEN_BLOOD 0x03 //!< Venous Whole blood. +#define NRF_BLE_CGMS_MEAS_TYPE_VEN_PLASMA 0x04 //!< Venous Plasma. +#define NRF_BLE_CGMS_MEAS_TYPE_ART_BLOOD 0x05 //!< Arterial Whole blood. +#define NRF_BLE_CGMS_MEAS_TYPE_ART_PLASMA 0x06 //!< Arterial Plasma. +#define NRF_BLE_CGMS_MEAS_TYPE_UNDET_BLOOD 0x07 //!< Undetermined Whole blood. +#define NRF_BLE_CGMS_MEAS_TYPE_UNDET_PLASMA 0x08 //!< Undetermined Plasma. +#define NRF_BLE_CGMS_MEAS_TYPE_FLUID 0x09 //!< Interstitial Fluid (ISF). +#define NRF_BLE_CGMS_MEAS_TYPE_CONTROL 0x0A //!< Control Solution. +/** @} */ + +/**@name CGM sample location + * @{ */ +#define NRF_BLE_CGMS_MEAS_LOC_FINGER 0x01 //!< Finger. +#define NRF_BLE_CGMS_MEAS_LOC_AST 0x02 //!< Alternate Site Test (AST). +#define NRF_BLE_CGMS_MEAS_LOC_EAR 0x03 //!< Earlobe. +#define NRF_BLE_CGMS_MEAS_LOC_CONTROL 0x04 //!< Control solution. +#define NRF_BLE_CGMS_MEAS_LOC_SUB_TISSUE 0x05 //!< Subcutaneous tissue. +#define NRF_BLE_CGMS_MEAS_LOC_NOT_AVAIL 0x0F //!< Sample Location value not available. +/** @} */ + +/**@name CGM Measurement Sensor Status Annunciation + * @{ */ +#define NRF_BLE_CGMS_STATUS_SESSION_STOPPED (0x01 << 0) //!< Status: Session Stopped. +#define NRF_BLE_CGMS_STATUS_DEVICE_BATTERY_LOW (0x01 << 1) //!< Status: Device Battery Low. +#define NRF_BLE_CGMS_STATUS_SENSOR_TYPE_INCORRECT_FOR_DEVICE (0x01 << 2) //!< Status: Sensor type incorrect for device. +#define NRF_BLE_CGMS_STATUS_SENSOR_MALFUNCTION (0x01 << 3) //!< Status: Sensor malfunction. +#define NRF_BLE_CGMS_STATUS_DEVICE_SPECIFIC_ALERT (0x01 << 4) //!< Status: Device Specific Alert. +#define NRF_BLE_CGMS_STATUS_GENERAL_DEVICE_FAULT (0x01 << 5) //!< Status: General device fault has occurred in the sensor. +/** @} */ + +/**@name CGM Measurement flags + * @{ */ +#define NRF_BLE_CGMS_FLAG_TREND_INFO_PRESENT 0x01 //!< CGM Trend Information Present. +#define NRF_BLE_CGMS_FLAGS_QUALITY_PRESENT 0x02 //!< CGM Quality Present. +#define NRF_BLE_CGMS_STATUS_FLAGS_WARNING_OCT_PRESENT 0x20 //!< Sensor Status Annunciation Field, Warning-Octet present. +#define NRF_BLE_CGMS_STATUS_FLAGS_CALTEMP_OCT_PRESENT 0x40 //!< Sensor Status Annunciation Field, Cal/Temp-Octet present. +#define NRF_BLE_CGMS_STATUS_FLAGS_STATUS_OCT_PRESENT 0x80 //!< Sensor Status Annunciation Field, Status-Octet present. +/** @} */ + +/**@name Byte length of various commands (used for validating, encoding, and decoding data). + * @{ */ +#define NRF_BLE_CGMS_MEAS_OP_LEN 1 //!< Length of the opcode inside the Glucose Measurement packet. +#define NRF_BLE_CGMS_MEAS_HANDLE_LEN 2 //!< Length of the handle inside the Glucose Measurement packet. +#define NRF_BLE_CGMS_MEAS_LEN_MAX (BLE_GATT_ATT_MTU_DEFAULT - \ + NRF_BLE_CGMS_MEAS_OP_LEN - \ + NRF_BLE_CGMS_MEAS_HANDLE_LEN) //!< Maximum size of a transmitted Glucose Measurement. + +#define NRF_BLE_CGMS_MEAS_REC_LEN_MAX 15 //!< Maximum length of one measurement record. Size 1 byte, flags 1 byte, glucose concentration 2 bytes, offset 2 bytes, status 3 bytes, trend 2 bytes, quality 2 bytes, CRC 2 bytes. +#define NRF_BLE_CGMS_MEAS_REC_LEN_MIN 6 //!< Minimum length of one measurement record. Size 1 byte, flags 1 byte, glucose concentration 2 bytes, offset 2 bytes. +#define NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX (NRF_BLE_CGMS_MEAS_LEN_MAX / \ + NRF_BLE_CGMS_MEAS_REC_LEN_MIN) //!< Maximum number of records per notification. We can send more than one measurement record per notification, but we do not want a a single record split over two notifications. + +#define NRF_BLE_CGMS_SOCP_RESP_CODE_LEN 2 //!< Length of a response. Response code 1 byte, response value 1 byte. +#define NRF_BLE_CGMS_FEATURE_LEN 6 //!< Length of a feature. Feature 3 bytes, type 4 bits, sample location 4 bits, CRC 2 bytes. +#define NRF_BLE_CGMS_STATUS_LEN 7 //!< Length of a status. Offset 2 bytes, status 3 bytes, CRC 2 bytes. +#define NRF_BLE_CGMS_MAX_CALIB_LEN 10 //!< Length of a calibration record. Concentration 2 bytes, time 2 bytes, calibration 4 bits, calibration sample location 4 bits, next calibration time 2 bytes, record number 2 bytes, calibration status 1 byte. +#define NRF_BLE_CGMS_CALIBS_NB_MAX 5 //!< Maximum number of calibration values that can be stored. +#define NRF_BLE_CGMS_SST_LEN 9 //!< Length of the start time. Date time 7 bytes, time zone 1 byte, DST 1 byte. +#define NRF_BLE_CGMS_CRC_LEN 2 //!< Length of the CRC bytes (if used). +#define NRF_BLE_CGMS_SRT_LEN 2 //!< Length of the Session Run Time attribute. + +#define NRF_BLE_CGMS_SOCP_RESP_LEN (NRF_BLE_CGMS_MEAS_LEN_MAX - \ + NRF_BLE_CGMS_SOCP_RESP_CODE_LEN) //!< Max lenth of a SOCP response. + +#define NRF_BLE_CGMS_RACP_PENDING_OPERANDS_MAX 2 // !< Maximum number of pending Record Access Control Point operations. +/** @} */ + +/** + * @defgroup nrf_ble_cgms_enums Enumerations + * @{ + */ + +/**@brief CGM Service events. */ +typedef enum +{ + NRF_BLE_CGMS_EVT_NOTIFICATION_ENABLED, /**< Glucose value notification enabled. */ + NRF_BLE_CGMS_EVT_NOTIFICATION_DISABLED, /**< Glucose value notification disabled. */ + NRF_BLE_CGMS_EVT_START_SESSION, /**< Glucose value notification start session. */ + NRF_BLE_CGMS_EVT_STOP_SESSION, /**< Glucose value notification stop session. */ + NRF_BLE_CGMS_EVT_WRITE_COMM_INTERVAL, /**< Glucose value write communication interval. */ +} nrf_ble_cgms_evt_type_t; + + +/**@brief CGM Service communication states. */ +typedef enum +{ + STATE_NO_COMM, /**< The service is not in a communicating state. */ + STATE_RACP_PROC_ACTIVE, /**< Processing requested data. */ + STATE_RACP_RESPONSE_PENDING, /**< There is an RACP indication waiting to be sent. */ + STATE_RACP_RESPONSE_IND_VERIF, /**< Waiting for a verification of an RACP indication. */ + STATE_SOCP_RESPONSE_PENDING, /**< There is an SOCP indication waiting to be sent. */ + STATE_SOCP_RESPONSE_IND_VERIF /**< Waiting for a verification of an SOCP indication. */ +} nrf_ble_cgms_com_state_t; + +/** @} */ // End tag for Enumeration group. + +/** + * @defgroup nrf_ble_cgms_structs Structures + * @{ + */ + +/**@brief CGM Service event. */ +typedef struct +{ + nrf_ble_cgms_evt_type_t evt_type; /**< Type of event. */ +} nrf_ble_cgms_evt_t; + +/** @} */ // End tag for Structure group. + +/** + * @defgroup nrf_ble_cgms_types Types + * @{ + */ + +/**@brief Forward declaration of the nrf_ble_cgms_t type. */ +typedef struct ble_cgms_s nrf_ble_cgms_t; + + +/**@brief CGM Service event handler type. */ +typedef void (* ble_cgms_evt_handler_t) (nrf_ble_cgms_t * p_cgms, nrf_ble_cgms_evt_t * p_evt); + +/** @} */ // End tag for Types group. + +/** + * @addtogroup nrf_ble_cgms_structs + * @{ + */ + +/**@brief CGM Measurement Sensor Status Annunciation. */ +typedef struct +{ + uint8_t warning; /**< Warning annunciation. */ + uint8_t calib_temp; /**< Calibration and Temperature annunciation. */ + uint8_t status; /**< Status annunciation. */ +} nrf_ble_cgms_sensor_annunc_t; + + +/**@brief CGM measurement. */ +typedef struct +{ + uint8_t flags; /**< Indicates the presence of optional fields and the Sensor Status Annunciation field. */ + uint16_t glucose_concentration; /**< Glucose concentration. 16-bit word comprising 4-bit exponent and signed 12-bit mantissa. */ + uint16_t time_offset; /**< Time offset. Represents the time difference between measurements. */ + nrf_ble_cgms_sensor_annunc_t sensor_status_annunciation; /**< Sensor Status Annunciation. Variable length, can include Status, Cal/Temp, and Warning. */ + uint16_t trend; /**< Optional field that can include Trend Information. */ + uint16_t quality; /**< Optional field that includes the Quality of the measurement. */ +} nrf_ble_cgms_meas_t; + + +/**@brief CGM Measurement record. */ +typedef struct +{ + nrf_ble_cgms_meas_t meas; /**< CGM measurement. */ +} ble_cgms_rec_t; + + +/**@brief Features supported by the CGM Service. */ +typedef struct +{ + uint32_t feature; /**< Information on supported features in the CGM Service. */ + uint8_t type; /**< Type. */ + uint8_t sample_location; /**< Sample location. */ +}nrf_ble_cgms_feature_t; + + +/**@brief Status of the CGM measurement. */ +typedef struct +{ + uint16_t time_offset; /**< Time offset. */ + nrf_ble_cgms_sensor_annunc_t status; /**< Status. */ +} nrf_ble_cgm_status_t; + + +/**@brief CGM Service initialization structure that contains all options and data needed for + * initializing the service. */ +typedef struct +{ + ble_cgms_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the CGM Service. */ + ble_srv_error_handler_t error_handler; /**< Function to be called when an error occurs. */ + nrf_ble_cgms_feature_t feature; /**< Features supported by the service. */ + nrf_ble_cgm_status_t initial_sensor_status; /**< Sensor status. */ + uint16_t initial_run_time; /**< Run time. */ +} nrf_ble_cgms_init_t; + + +/**@brief Specific Operation Control Point response structure. */ +typedef struct +{ + uint8_t opcode; /**< Opcode describing the response. */ + uint8_t req_opcode; /**< The original opcode for the request to which this response belongs. */ + uint8_t rsp_code; /**< Response code. */ + uint8_t resp_val[NRF_BLE_CGMS_SOCP_RESP_LEN]; /**< Array containing the response value. */ + uint8_t size_val; /**< Length of the response value. */ +} ble_socp_rsp_t; + + +/**@brief Calibration value. */ +typedef struct +{ + uint8_t value[NRF_BLE_CGMS_MAX_CALIB_LEN]; /**< Array containing the calibration value. */ +} nrf_ble_cgms_calib_t; + + +/**@brief Record Access Control Point transaction data. */ +typedef struct +{ + uint8_t racp_proc_operator; /**< Operator of the current request. */ + uint8_t racp_proc_record_ndx; /**< Current record index. */ + uint8_t racp_proc_records_reported; /**< Number of reported records. */ + uint8_t racp_proc_records_reported_since_txcomplete; /**< Number of reported records since the last TX_COMPLETE event. */ + ble_racp_value_t racp_request; + ble_racp_value_t pending_racp_response; /**< RACP response to be sent. */ + uint8_t pending_racp_response_operand[NRF_BLE_CGMS_RACP_PENDING_OPERANDS_MAX]; /**< Operand of the RACP response to be sent. */ +} nrf_ble_cgms_racp_t; + + +/** @brief Handles related to CGM characteristics. */ +typedef struct +{ + ble_gatts_char_handles_t measurment; /**< Handles related to the CGM Measurement characteristic. */ + ble_gatts_char_handles_t feature; /**< Handles related to the CGM Feature characteristic. */ + ble_gatts_char_handles_t sst; /**< Handles related to the CGM Session Start Time characteristic. */ + ble_gatts_char_handles_t racp; /**< Handles related to the CGM Record Access Control Point characteristic. */ + ble_gatts_char_handles_t srt; /**< Handles related to the CGM Session Run Time characteristic. */ + ble_gatts_char_handles_t socp; /**< Handles related to the CGM Specific Operations Control Point characteristic. */ + ble_gatts_char_handles_t status; /**< Handles related to the CGM Status characteristic. */ +} nrf_ble_cgms_char_handler_t; + + +/**@brief Status information for the CGM Service. */ +struct ble_cgms_s +{ + ble_cgms_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the CGM Service. */ + ble_srv_error_handler_t error_handler; /**< Function to be called if an error occurs. */ + uint16_t service_handle; /**< Handle of the CGM Service (as provided by the BLE stack). */ + nrf_ble_cgms_char_handler_t char_handles; /**< GATTS characteristic handles for the different characteristics in the service. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack; @ref BLE_CONN_HANDLE_INVALID if not in a connection). */ + nrf_ble_cgms_feature_t feature; /**< Structure to store the value of the feature characteristic. */ + uint8_t comm_interval; /**< Variable to keep track of the communication interval. */ + ble_socp_rsp_t socp_response; /**< Structure containing reponse data to be indicated to the peer device. */ + nrf_ble_cgms_calib_t calibration_val[NRF_BLE_CGMS_CALIBS_NB_MAX]; /**< Calibration value. Can be read from and written to SOCP. */ + bool is_session_started; /**< Indicator if we are currently in a session. */ + uint8_t nb_run_session; /**< Variable to keep track of the number of sessions that were run. */ + uint16_t session_run_time; /**< Variable to store the expected run time of a session. */ + nrf_ble_cgm_status_t sensor_status; /**< Structure to keep track of the sensor status. */ + nrf_ble_cgms_com_state_t cgms_com_state; /**< Current communication state. */ + nrf_ble_cgms_racp_t racp_data; /**< Structure to manage Record Access requests. */ +}; + +/** @} */ + +/** + * @defgroup nrf_ble_cgms_functions Functions + * @{ + */ + +/**@brief Function for updating the status. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_status New status. + * + * @retval NRF_SUCCESS If the status was updated successfully. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t nrf_ble_cgms_update_status(nrf_ble_cgms_t * p_cgms, nrf_ble_cgm_status_t * p_status); + + +/**@brief Function for initializing the CGM Service. + * + * @param[out] p_cgms CGM Service structure. This structure must be supplied by + * the application. It is initialized by this function and will later + * be used to identify this particular service instance. + * @param[in] p_cgms_init Information needed to initialize the service. + * + * @retval NRF_SUCCESS If the service was initialized successfully. + * @retval NRF_ERROR_NULL If any of the input parameters are NULL. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t nrf_ble_cgms_init(nrf_ble_cgms_t * p_cgms, const nrf_ble_cgms_init_t * p_cgms_init); + + +/**@brief Function for handling the application's BLE stack events. + * + * @details Handles all events from the BLE stack that are of interest to the CGM Service. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void nrf_ble_cgms_on_ble_evt(nrf_ble_cgms_t * p_cgms, ble_evt_t * p_ble_evt); + + +/**@brief Function for reporting a new glucose measurement to the CGM Service module. + * + * @details The application calls this function after having performed a new glucose measurement. + * The new measurement is recorded in the RACP database. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_rec Pointer to the glucose record (measurement plus context). + * + * @retval NRF_SUCCESS If a measurement was successfully created. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t nrf_ble_cgms_meas_create(nrf_ble_cgms_t * p_cgms, ble_cgms_rec_t * p_rec); + + +/**@brief Function for assigning a connection handle to a CGM Service instance. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] conn_handle Connection Handle to use for this instance of the CGM Service. + * + * @retval NRF_SUCCESS If the connection handle was successfully stored in the CGM Service instance. + * @retval NRF_ERROR_NULL If any of the input parameters are NULL. + */ +ret_code_t nrf_ble_cgms_conn_handle_assign(nrf_ble_cgms_t * p_cgms, uint16_t conn_handle); + + +/**@brief Function for setting the Session Run Time attribute value. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] run_time Run Time that will be displayed in the Session Run Time + * attribute value. + * + * @retval NRF_SUCCESS If the Session Run Time attribute value was set successfully. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t nrf_ble_cgms_srt_set(nrf_ble_cgms_t * p_cgms, uint16_t run_time); + +/** @} */ // End tag for Function group. + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_CGMS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_advdata.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_advdata.c new file mode 100644 index 0000000000000000000000000000000000000000..3c4c867963133ed2143193b71e8129dccdeae8f3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_advdata.c @@ -0,0 +1,681 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_advdata.h" +#include "ble_gap.h" +#include "ble_srv_common.h" +#include "sdk_common.h" + +// NOTE: For now, Security Manager Out of Band Flags (OOB) are omitted from the advertising data. + +// Types of LE Bluetooth Device Address AD type +#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC 0UL +#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM 1UL + +static uint32_t ble_device_addr_encode(uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + uint32_t err_code; + ble_gap_addr_t device_addr; + + // Check for buffer overflow. + if (((*p_offset) + AD_TYPE_BLE_DEVICE_ADDR_SIZE) > max_size) + { + return NRF_ERROR_DATA_SIZE; + } + + // Get BLE address. + #if (NRF_SD_BLE_API_VERSION >= 3) + err_code = sd_ble_gap_addr_get(&device_addr); + #else + err_code = sd_ble_gap_address_get(&device_addr); + #endif + VERIFY_SUCCESS(err_code); + + // Encode LE Bluetooth Device Address. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + + AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + memcpy(&p_encoded_data[*p_offset], &device_addr.addr[0], BLE_GAP_ADDR_LEN); + *p_offset += BLE_GAP_ADDR_LEN; + if (BLE_GAP_ADDR_TYPE_PUBLIC == device_addr.addr_type) + { + p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC; + } + else + { + p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM; + } + *p_offset += AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE; + + return NRF_SUCCESS; +} + +static uint32_t name_encode(const ble_advdata_t * p_advdata, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + uint32_t err_code; + uint16_t rem_adv_data_len; + uint16_t actual_length; + uint8_t adv_data_format; + + + // Validate parameters + if ((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && (0 == p_advdata->short_name_len)) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Check for buffer overflow. + if ( (((*p_offset) + ADV_AD_DATA_OFFSET) > max_size) || + ( (BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && + (((*p_offset) + ADV_AD_DATA_OFFSET + p_advdata->short_name_len) > max_size))) + { + return NRF_ERROR_DATA_SIZE; + } + + rem_adv_data_len = max_size - (*p_offset) - ADV_AD_DATA_OFFSET; + actual_length = rem_adv_data_len; + + // Get GAP device name and length + err_code = sd_ble_gap_device_name_get(&p_encoded_data[(*p_offset) + ADV_AD_DATA_OFFSET], + &actual_length); + VERIFY_SUCCESS(err_code); + + // Check if device intend to use short name and it can fit available data size. + if ((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) && (actual_length <= rem_adv_data_len)) + { + // Complete device name can fit, setting Complete Name in Adv Data. + adv_data_format = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME; + } + else + { + // Else short name needs to be used. Or application has requested use of short name. + adv_data_format = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME; + + // If application has set a preference on the short name size, it needs to be considered, + // else fit what can be fit. + if ((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && + (p_advdata->short_name_len <= rem_adv_data_len)) + { + // Short name fits available size. + actual_length = p_advdata->short_name_len; + } + // Else whatever can fit the data buffer will be packed. + else + { + actual_length = rem_adv_data_len; + } + } + + // There is only 1 byte intended to encode length which is (actual_length + ADV_AD_TYPE_FIELD_SIZE) + if (actual_length > (0x00FF - ADV_AD_TYPE_FIELD_SIZE)) + { + return NRF_ERROR_DATA_SIZE; + } + + // Complete name field in encoded data. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + actual_length); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = adv_data_format; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + *p_offset += actual_length; + + return NRF_SUCCESS; +} + + +static uint32_t appearance_encode(uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + uint32_t err_code; + uint16_t appearance; + + // Check for buffer overflow. + if (((*p_offset) + AD_TYPE_APPEARANCE_SIZE) > max_size) + { + return NRF_ERROR_DATA_SIZE; + } + + // Get GAP appearance field. + err_code = sd_ble_gap_appearance_get(&appearance); + VERIFY_SUCCESS(err_code); + + // Encode Length, AD Type and Appearance. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_APPEARANCE_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_APPEARANCE; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + *p_offset += uint16_encode(appearance, &p_encoded_data[*p_offset]); + + return NRF_SUCCESS; +} + +static uint32_t flags_encode(int8_t flags, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + // Check for buffer overflow. + if (((*p_offset) + AD_TYPE_FLAGS_SIZE) > max_size) + { + return NRF_ERROR_DATA_SIZE; + } + + // Encode flags. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_FLAGS_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_FLAGS; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + p_encoded_data[*p_offset] = flags; + *p_offset += AD_TYPE_FLAGS_DATA_SIZE; + + return NRF_SUCCESS; +} + +static uint32_t tx_power_level_encode(int8_t tx_power_level, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + // Check for buffer overflow. + if (((*p_offset) + AD_TYPE_TX_POWER_LEVEL_SIZE) > max_size) + { + return NRF_ERROR_DATA_SIZE; + } + + // Encode TX Power Level. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + + AD_TYPE_TX_POWER_LEVEL_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_TX_POWER_LEVEL; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + p_encoded_data[*p_offset] = tx_power_level; + *p_offset += AD_TYPE_TX_POWER_LEVEL_DATA_SIZE; + + return NRF_SUCCESS; +} + + +static uint32_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_list, + uint8_t adv_type, + uint8_t uuid_size, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + int i; + bool is_heading_written = false; + uint16_t start_pos = *p_offset; + uint16_t length; + + for (i = 0; i < p_uuid_list->uuid_cnt; i++) + { + uint32_t err_code; + uint8_t encoded_size; + ble_uuid_t uuid = p_uuid_list->p_uuids[i]; + + // Find encoded uuid size. + err_code = sd_ble_uuid_encode(&uuid, &encoded_size, NULL); + VERIFY_SUCCESS(err_code); + + // Check size. + if (encoded_size == uuid_size) + { + uint8_t heading_bytes = (is_heading_written) ? 0 : ADV_AD_DATA_OFFSET; + + // Check for buffer overflow + if (((*p_offset) + encoded_size + heading_bytes) > max_size) + { + return NRF_ERROR_DATA_SIZE; + } + + if (!is_heading_written) + { + // Write AD structure heading. + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = adv_type; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + is_heading_written = true; + } + + // Write UUID. + err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &p_encoded_data[*p_offset]); + VERIFY_SUCCESS(err_code); + *p_offset += encoded_size; + } + } + + if (is_heading_written) + { + // Write length. + length = (*p_offset) - (start_pos + ADV_LENGTH_FIELD_SIZE); + // There is only 1 byte intended to encode length + if (length > 0x00FF) + { + return NRF_ERROR_DATA_SIZE; + } + p_encoded_data[start_pos] = (uint8_t)length; + } + + return NRF_SUCCESS; +} + + +static uint32_t uuid_list_encode(const ble_advdata_uuid_list_t * p_uuid_list, + uint8_t adv_type_16, + uint8_t adv_type_128, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + uint32_t err_code; + + // Encode 16 bit UUIDs. + err_code = uuid_list_sized_encode(p_uuid_list, + adv_type_16, + sizeof(uint16_le_t), + p_encoded_data, + p_offset, + max_size); + VERIFY_SUCCESS(err_code); + + // Encode 128 bit UUIDs. + err_code = uuid_list_sized_encode(p_uuid_list, + adv_type_128, + sizeof(ble_uuid128_t), + p_encoded_data, + p_offset, + max_size); + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} + + +static uint32_t conn_int_check(const ble_advdata_conn_int_t *p_conn_int) +{ + // Check Minimum Connection Interval. + if ((p_conn_int->min_conn_interval < 0x0006) || + ( + (p_conn_int->min_conn_interval > 0x0c80) && + (p_conn_int->min_conn_interval != 0xffff) + ) + ) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Check Maximum Connection Interval. + if ((p_conn_int->max_conn_interval < 0x0006) || + ( + (p_conn_int->max_conn_interval > 0x0c80) && + (p_conn_int->max_conn_interval != 0xffff) + ) + ) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Make sure Minimum Connection Interval is not bigger than Maximum Connection Interval. + if ((p_conn_int->min_conn_interval != 0xffff) && + (p_conn_int->max_conn_interval != 0xffff) && + (p_conn_int->min_conn_interval > p_conn_int->max_conn_interval) + ) + { + return NRF_ERROR_INVALID_PARAM; + } + + return NRF_SUCCESS; +} + + +static uint32_t conn_int_encode(const ble_advdata_conn_int_t * p_conn_int, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + uint32_t err_code; + + // Check for buffer overflow. + if (((*p_offset) + AD_TYPE_CONN_INT_SIZE) > max_size) + { + return NRF_ERROR_DATA_SIZE; + } + + // Check parameters. + err_code = conn_int_check(p_conn_int); + VERIFY_SUCCESS(err_code); + + // Encode Length and AD Type. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_CONN_INT_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + + // Encode Minimum and Maximum Connection Intervals. + *p_offset += uint16_encode(p_conn_int->min_conn_interval, &p_encoded_data[*p_offset]); + *p_offset += uint16_encode(p_conn_int->max_conn_interval, &p_encoded_data[*p_offset]); + + return NRF_SUCCESS; +} + + +static uint32_t manuf_specific_data_encode(const ble_advdata_manuf_data_t * p_manuf_sp_data, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + uint32_t data_size = AD_TYPE_MANUF_SPEC_DATA_ID_SIZE + p_manuf_sp_data->data.size; + + // Check for buffer overflow. + if (((*p_offset) + ADV_AD_DATA_OFFSET + data_size) > max_size) + { + return NRF_ERROR_DATA_SIZE; + } + + // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE) + if (data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE)) + { + return NRF_ERROR_DATA_SIZE; + } + + // Encode Length and AD Type. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + + // Encode Company Identifier. + *p_offset += uint16_encode(p_manuf_sp_data->company_identifier, &p_encoded_data[*p_offset]); + + // Encode additional manufacturer specific data. + if (p_manuf_sp_data->data.size > 0) + { + if (p_manuf_sp_data->data.p_data == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + memcpy(&p_encoded_data[*p_offset], p_manuf_sp_data->data.p_data, p_manuf_sp_data->data.size); + *p_offset += p_manuf_sp_data->data.size; + } + + return NRF_SUCCESS; +} + +// Implemented only for 16-bit UUIDs +static uint32_t service_data_encode(const ble_advdata_t * p_advdata, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + uint8_t i; + + // Check parameter consistency. + if (p_advdata->p_service_data_array == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + for (i = 0; i < p_advdata->service_data_count; i++) + { + ble_advdata_service_data_t * p_service_data; + uint32_t data_size; + + p_service_data = &p_advdata->p_service_data_array[i]; + // For now implemented only for 16-bit UUIDs + data_size = AD_TYPE_SERV_DATA_16BIT_UUID_SIZE + p_service_data->data.size; + + // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE) + if (data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE)) + { + return NRF_ERROR_DATA_SIZE; + } + + // Encode Length and AD Type. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SERVICE_DATA; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + + // Encode service 16-bit UUID. + *p_offset += uint16_encode(p_service_data->service_uuid, &p_encoded_data[*p_offset]); + + // Encode additional service data. + if (p_service_data->data.size > 0) + { + if (p_service_data->data.p_data == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + memcpy(&p_encoded_data[*p_offset], p_service_data->data.p_data, p_service_data->data.size); + *p_offset += p_service_data->data.size; + } + } + + return NRF_SUCCESS; +} + +uint32_t adv_data_encode(ble_advdata_t const * const p_advdata, + uint8_t * const p_encoded_data, + uint16_t * const p_len) +{ + uint32_t err_code = NRF_SUCCESS; + uint16_t max_size = *p_len; + *p_len = 0; + + // Encode LE Bluetooth Device Address + if (p_advdata->include_ble_device_addr) + { + err_code = ble_device_addr_encode(p_encoded_data, p_len, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode appearance. + if (p_advdata->include_appearance) + { + err_code = appearance_encode(p_encoded_data, p_len, max_size); + VERIFY_SUCCESS(err_code); + } + + //Encode Flags + if (p_advdata->flags != 0 ) + { + err_code = flags_encode(p_advdata->flags, p_encoded_data, p_len, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode TX power level. + if (p_advdata->p_tx_power_level != NULL) + { + err_code = tx_power_level_encode(*p_advdata->p_tx_power_level, + p_encoded_data, + p_len, + max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode 'more available' uuid list. + if (p_advdata->uuids_more_available.uuid_cnt > 0) + { + err_code = uuid_list_encode(&p_advdata->uuids_more_available, + BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE, + BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE, + p_encoded_data, + p_len, + max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode 'complete' uuid list. + if (p_advdata->uuids_complete.uuid_cnt > 0) + { + err_code = uuid_list_encode(&p_advdata->uuids_complete, + BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, + BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE, + p_encoded_data, + p_len, + max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode 'solicited service' uuid list. + if (p_advdata->uuids_solicited.uuid_cnt > 0) + { + err_code = uuid_list_encode(&p_advdata->uuids_solicited, + BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT, + BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT, + p_encoded_data, + p_len, + max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode Slave Connection Interval Range. + if (p_advdata->p_slave_conn_int != NULL) + { + err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode Manufacturer Specific Data. + if (p_advdata->p_manuf_specific_data != NULL) + { + err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data, + p_encoded_data, + p_len, + max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode Service Data. + if (p_advdata->service_data_count > 0) + { + err_code = service_data_encode(p_advdata, p_encoded_data, p_len, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode name. WARNING: it is encoded last on purpose since too long device name is truncated. + if (p_advdata->name_type != BLE_ADVDATA_NO_NAME) + { + err_code = name_encode(p_advdata, p_encoded_data, p_len, max_size); + VERIFY_SUCCESS(err_code); + } + + return err_code; +} + + +static uint32_t advdata_check(const ble_advdata_t * p_advdata) +{ + // Flags must be included in advertising data, and the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag must be set. + if ( + ((p_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0) + ) + { + return NRF_ERROR_INVALID_PARAM; + } + + return NRF_SUCCESS; +} + + +static uint32_t srdata_check(const ble_advdata_t * p_srdata) +{ + // Flags shall not be included in the scan response data. + if (p_srdata->flags) + { + return NRF_ERROR_INVALID_PARAM; + } + + return NRF_SUCCESS; +} + + +uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata) +{ + uint32_t err_code; + uint16_t len_advdata = BLE_GAP_ADV_MAX_SIZE; + uint16_t len_srdata = BLE_GAP_ADV_MAX_SIZE; + uint8_t encoded_advdata[BLE_GAP_ADV_MAX_SIZE]; + uint8_t encoded_srdata[BLE_GAP_ADV_MAX_SIZE]; + uint8_t * p_encoded_advdata; + uint8_t * p_encoded_srdata; + + // Encode advertising data (if supplied). + if (p_advdata != NULL) + { + err_code = advdata_check(p_advdata); + VERIFY_SUCCESS(err_code); + + err_code = adv_data_encode(p_advdata, encoded_advdata, &len_advdata); + VERIFY_SUCCESS(err_code); + p_encoded_advdata = encoded_advdata; + } + else + { + p_encoded_advdata = NULL; + len_advdata = 0; + } + + // Encode scan response data (if supplied). + if (p_srdata != NULL) + { + err_code = srdata_check(p_srdata); + VERIFY_SUCCESS(err_code); + + err_code = adv_data_encode(p_srdata, encoded_srdata, &len_srdata); + VERIFY_SUCCESS(err_code); + p_encoded_srdata = encoded_srdata; + } + else + { + p_encoded_srdata = NULL; + len_srdata = 0; + } + + // Pass encoded advertising data and/or scan response data to the stack. + return sd_ble_gap_adv_data_set(p_encoded_advdata, len_advdata, p_encoded_srdata, len_srdata); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_advdata.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_advdata.h new file mode 100644 index 0000000000000000000000000000000000000000..2188592d6d8ee8470748aa7f8bf4f7dc8e9c0ffd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_advdata.h @@ -0,0 +1,232 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_lib_advdata Advertising and Scan Response Data Encoder + * @{ + * @ingroup ble_sdk_lib + * @brief Functions for encoding data in the Advertising and Scan Response Data format, + * and for passing the data to the stack. + */ + +#ifndef BLE_ADVDATA_H__ +#define BLE_ADVDATA_H__ + +#include +#include +#include +#include "ble.h" +#include "app_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ADV_LENGTH_FIELD_SIZE 1UL /**< Advertising Data and Scan Response format contains 1 octet for the length. */ +#define ADV_AD_TYPE_FIELD_SIZE 1UL /**< Advertising Data and Scan Response format contains 1 octet for the AD type. */ +#define ADV_AD_DATA_OFFSET (ADV_LENGTH_FIELD_SIZE + \ + ADV_AD_TYPE_FIELD_SIZE) /**< Offset for the AD data field of the Advertising Data and Scan Response format. */ +#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE 1UL /**< Data size (in octets) of the Address type of the LE Bluetooth Device Address AD type. */ +#define AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE (BLE_GAP_ADDR_LEN + \ + AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE) /**< Data size (in octets) of the LE Bluetooth Device Address AD type. */ +#define AD_TYPE_BLE_DEVICE_ADDR_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE) /**< Size (in octets) of the LE Bluetooth Device Address AD type. */ +#define AD_TYPE_APPEARANCE_DATA_SIZE 2UL /**< Data size (in octets) of the Appearance AD type. */ +#define AD_TYPE_APPEARANCE_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_APPEARANCE_DATA_SIZE) /**< Size (in octets) of the Appearance AD type. */ +#define AD_TYPE_FLAGS_DATA_SIZE 1UL /**< Data size (in octets) of the Flags AD type. */ +#define AD_TYPE_FLAGS_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_FLAGS_DATA_SIZE) /**< Size (in octets) of the Flags AD type. */ +#define AD_TYPE_TX_POWER_LEVEL_DATA_SIZE 1UL /**< Data size (in octets) of the TX Power Level AD type. */ +#define AD_TYPE_TX_POWER_LEVEL_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_TX_POWER_LEVEL_DATA_SIZE) /**< Size (in octets) of the TX Power Level AD type. */ +#define AD_TYPE_CONN_INT_DATA_SIZE 4UL /**< Data size (in octets) of the Slave Connection Interval Range AD type. */ +#define AD_TYPE_CONN_INT_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_CONN_INT_DATA_SIZE) /**< Data size (in octets) of the Slave Connection Interval Range AD type. */ +#define AD_TYPE_MANUF_SPEC_DATA_ID_SIZE 2UL /**< Size (in octets) of the Company Identifier Code, which is a part of the Manufacturer Specific Data AD type. */ +#define AD_TYPE_SERV_DATA_16BIT_UUID_SIZE 2UL /**< Size (in octets) of the 16-bit UUID, which is a part of the Service Data AD type. */ + +/**@brief Security Manager TK value. */ +typedef struct +{ + uint8_t tk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing TK value in little-endian format. */ +} ble_advdata_tk_value_t; + +/**@brief Advertising data LE Role types. This enumeration contains the options available for the LE role inside + * the advertising data. */ +typedef enum +{ + BLE_ADVDATA_ROLE_NOT_PRESENT = 0, /**< LE Role AD structure not present. */ + BLE_ADVDATA_ROLE_ONLY_PERIPH, /**< Only Peripheral Role supported. */ + BLE_ADVDATA_ROLE_ONLY_CENTRAL, /**< Only Central Role supported. */ + BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED, /**< Peripheral and Central Role supported. Peripheral Role preferred for connection establishment. */ + BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED /**< Peripheral and Central Role supported. Central Role preferred for connection establishment */ +} ble_advdata_le_role_t; + +/**@brief Advertising data name type. This enumeration contains the options available for the device name inside + * the advertising data. */ +typedef enum +{ + BLE_ADVDATA_NO_NAME, /**< Include no device name in advertising data. */ + BLE_ADVDATA_SHORT_NAME, /**< Include short device name in advertising data. */ + BLE_ADVDATA_FULL_NAME /**< Include full device name in advertising data. */ +} ble_advdata_name_type_t; + +/**@brief UUID list type. */ +typedef struct +{ + uint16_t uuid_cnt; /**< Number of UUID entries. */ + ble_uuid_t * p_uuids; /**< Pointer to UUID array entries. */ +} ble_advdata_uuid_list_t; + +/**@brief Connection interval range structure. */ +typedef struct +{ + uint16_t min_conn_interval; /**< Minimum connection interval, in units of 1.25 ms, range 6 to 3200 (7.5 ms to 4 s). */ + uint16_t max_conn_interval; /**< Maximum connection interval, in units of 1.25 ms, range 6 to 3200 (7.5 ms to 4 s). The value 0xFFFF indicates no specific maximum. */ +} ble_advdata_conn_int_t; + +/**@brief Manufacturer specific data structure. */ +typedef struct +{ + uint16_t company_identifier; /**< Company identifier code. */ + uint8_array_t data; /**< Additional manufacturer specific data. */ +} ble_advdata_manuf_data_t; + +/**@brief Service data structure. */ +typedef struct +{ + uint16_t service_uuid; /**< Service UUID. */ + uint8_array_t data; /**< Additional service data. */ +} ble_advdata_service_data_t; + +/**@brief Advertising data structure. This structure contains all options and data needed for encoding and + * setting the advertising data. */ +typedef struct +{ + ble_advdata_name_type_t name_type; /**< Type of device name. */ + uint8_t short_name_len; /**< Length of short device name (if short type is specified). */ + bool include_appearance; /**< Determines if Appearance shall be included. */ + uint8_t flags; /**< Advertising data Flags field. */ + int8_t * p_tx_power_level; /**< TX Power Level field. */ + ble_advdata_uuid_list_t uuids_more_available; /**< List of UUIDs in the 'More Available' list. */ + ble_advdata_uuid_list_t uuids_complete; /**< List of UUIDs in the 'Complete' list. */ + ble_advdata_uuid_list_t uuids_solicited; /**< List of solicited UUIDs. */ + ble_advdata_conn_int_t * p_slave_conn_int; /**< Slave Connection Interval Range. */ + ble_advdata_manuf_data_t * p_manuf_specific_data; /**< Manufacturer specific data. */ + ble_advdata_service_data_t * p_service_data_array; /**< Array of Service data structures. */ + uint8_t service_data_count; /**< Number of Service data structures. */ + bool include_ble_device_addr; /**< Determines if LE Bluetooth Device Address shall be included. */ + ble_advdata_le_role_t le_role; /**< LE Role field. Included when different from @ref BLE_ADVDATA_ROLE_NOT_PRESENT. @warning This field can be used only for NFC. For BLE advertising, set it to NULL. */ + ble_advdata_tk_value_t * p_tk_value; /**< Security Manager TK value field. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/ + uint8_t * p_sec_mgr_oob_flags; /**< Security Manager Out Of Band Flags field. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/ +#if (NRF_SD_BLE_API_VERSION > 1) + ble_gap_lesc_oob_data_t * p_lesc_data; /**< LE Secure Connections OOB data. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/ +#endif +} ble_advdata_t; + +/**@brief Function for encoding data in the Advertising and Scan Response data format + * (AD structures). + * + * @details This function encodes data into the Advertising and Scan Response data format + * (AD structures) based on the selections in the supplied structures. This function can be used to + * create a payload of Advertising packet or Scan Response packet, or a payload of NFC + * message intended for initiating the Out-of-Band pairing. + * + * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_len \c in: Size of \p p_encoded_data buffer. + * \c out: Length of encoded data. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in \p p_advdata. + * @retval NRF_ERROR_DATA_SIZE If the operation failed because not all the requested data could fit into the + * provided buffer or some encoded AD structure is too long and its + * length cannot be encoded with one octet. + * + * @warning This API may override the application's request to use the long name and use a short name + * instead. This truncation will occur in case the long name does not fit the provided buffer size. + * The application can specify a preferred short name length if truncation is required. + * For example, if the complete device name is ABCD_HRMonitor, the application can specify the short name + * length to be 8, so that the short device name appears as ABCD_HRM instead of ABCD_HRMo or ABCD_HRMoni + * if the available size for the short name is 9 or 12 respectively, to have a more appropriate short name. + * However, it should be noted that this is just a preference that the application can specify, and + * if the preference is too large to fit in the provided buffer, the name can be truncated further. + */ +uint32_t adv_data_encode(ble_advdata_t const * const p_advdata, + uint8_t * const p_encoded_data, + uint16_t * const p_len); + +/**@brief Function for encoding and setting the advertising data and/or scan response data. + * + * @details This function encodes advertising data and/or scan response data based on the selections + * in the supplied structures, and passes the encoded data to the stack. + * + * @param[in] p_advdata Structure for specifying the content of the advertising data. + * Set to NULL if advertising data is not to be set. + * @param[in] p_srdata Structure for specifying the content of the scan response data. + * Set to NULL if scan response data is not to be set. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in \p p_advdata. + * @retval NRF_ERROR_DATA_SIZE If the operation failed because not all the requested data could fit into the + * advertising packet. The maximum size of the advertisement packet + * is @ref BLE_GAP_ADV_MAX_SIZE. + * + * @warning This API may override the application's request to use the long name and use a short name + * instead. This truncation will occur in case the long name does not fit the provided buffer size. + * The application can specify a preferred short name length if truncation is required. + * For example, if the complete device name is ABCD_HRMonitor, the application can specify the short name + * length to be 8, so that the short device name appears as ABCD_HRM instead of ABCD_HRMo or ABCD_HRMoni + * if the available size for the short name is 9 or 12 respectively, to have a more appropriate short name. + * However, it should be noted that this is just a preference that the application can specify, and + * if the preference is too large to fit in the provided buffer, the name can be truncated further. + */ +uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_ADVDATA_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_conn_params.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_conn_params.c new file mode 100644 index 0000000000000000000000000000000000000000..138e33e26631bc0f51afa726be6327b27f5bead1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_conn_params.c @@ -0,0 +1,350 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_conn_params.h" +#include +#include "nordic_common.h" +#include "ble_hci.h" +#include "app_timer.h" +#include "ble_srv_common.h" +#include "app_util.h" + + +static ble_conn_params_init_t m_conn_params_config; /**< Configuration as specified by the application. */ +static ble_gap_conn_params_t m_preferred_conn_params; /**< Connection parameters preferred by the application. */ +static uint8_t m_update_count; /**< Number of Connection Parameter Update messages that has currently been sent. */ +static uint16_t m_conn_handle; /**< Current connection handle. */ +static ble_gap_conn_params_t m_current_conn_params; /**< Connection parameters received in the most recent Connect event. */ +APP_TIMER_DEF(m_conn_params_timer_id); /**< Connection parameters timer. */ + +static bool m_change_param = false; + +static bool is_conn_params_ok(ble_gap_conn_params_t * p_conn_params) +{ + // Check if interval is within the acceptable range. + // NOTE: Using max_conn_interval in the received event data because this contains + // the client's connection interval. + if ( + (p_conn_params->max_conn_interval >= m_preferred_conn_params.min_conn_interval) + && + (p_conn_params->max_conn_interval <= m_preferred_conn_params.max_conn_interval) + ) + { + return true; + } + else + { + return false; + } +} + + +static void update_timeout_handler(void * p_context) +{ + UNUSED_PARAMETER(p_context); + + if (m_conn_handle != BLE_CONN_HANDLE_INVALID) + { + // Check if we have reached the maximum number of attempts + m_update_count++; + if (m_update_count <= m_conn_params_config.max_conn_params_update_count) + { + uint32_t err_code; + + // Parameters are not ok, send connection parameters update request. + err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params); + if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) + { + m_conn_params_config.error_handler(err_code); + } + } + else + { + m_update_count = 0; + + // Negotiation failed, disconnect automatically if this has been configured + if (m_conn_params_config.disconnect_on_fail) + { + uint32_t err_code; + + err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); + if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) + { + m_conn_params_config.error_handler(err_code); + } + } + + // Notify the application that the procedure has failed + if (m_conn_params_config.evt_handler != NULL) + { + ble_conn_params_evt_t evt; + + evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED; + m_conn_params_config.evt_handler(&evt); + } + } + } +} + + +uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init) +{ + uint32_t err_code; + + m_conn_params_config = *p_init; + m_change_param = false; + if (p_init->p_conn_params != NULL) + { + m_preferred_conn_params = *p_init->p_conn_params; + + // Set the connection params in stack + err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else + { + // Fetch the connection params from stack + err_code = sd_ble_gap_ppcp_get(&m_preferred_conn_params); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + m_conn_handle = BLE_CONN_HANDLE_INVALID; + m_update_count = 0; + + return app_timer_create(&m_conn_params_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + update_timeout_handler); +} + + +uint32_t ble_conn_params_stop(void) +{ + return app_timer_stop(m_conn_params_timer_id); +} + + +static void conn_params_negotiation(void) +{ + // Start negotiation if the received connection parameters are not acceptable + if (!is_conn_params_ok(&m_current_conn_params)) + { + uint32_t err_code; + uint32_t timeout_ticks; + + if (m_change_param) + { + // Notify the application that the procedure has failed + if (m_conn_params_config.evt_handler != NULL) + { + ble_conn_params_evt_t evt; + + evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED; + m_conn_params_config.evt_handler(&evt); + } + } + else + { + if (m_update_count == 0) + { + // First connection parameter update + timeout_ticks = m_conn_params_config.first_conn_params_update_delay; + } + else + { + timeout_ticks = m_conn_params_config.next_conn_params_update_delay; + } + + err_code = app_timer_start(m_conn_params_timer_id, timeout_ticks, NULL); + if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) + { + m_conn_params_config.error_handler(err_code); + } + } + } + else + { + // Notify the application that the procedure has succeeded + if (m_conn_params_config.evt_handler != NULL) + { + ble_conn_params_evt_t evt; + + evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED; + m_conn_params_config.evt_handler(&evt); + } + } + m_change_param = false; +} + + +static void on_connect(ble_evt_t * p_ble_evt) +{ + // Save connection parameters + m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + m_current_conn_params = p_ble_evt->evt.gap_evt.params.connected.conn_params; + m_update_count = 0; // Connection parameter negotiation should re-start every connection + + // Check if we shall handle negotiation on connect + if (m_conn_params_config.start_on_notify_cccd_handle == BLE_GATT_HANDLE_INVALID) + { + conn_params_negotiation(); + } +} + + +static void on_disconnect(ble_evt_t * p_ble_evt) +{ + uint32_t err_code; + + m_conn_handle = BLE_CONN_HANDLE_INVALID; + + // Stop timer if running + m_update_count = 0; // Connection parameters updates should happen during every connection + + err_code = app_timer_stop(m_conn_params_timer_id); + if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) + { + m_conn_params_config.error_handler(err_code); + } +} + + +static void on_write(ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + // Check if this the correct CCCD + if ( + (p_evt_write->handle == m_conn_params_config.start_on_notify_cccd_handle) + && + (p_evt_write->len == 2) + ) + { + // Check if this is a 'start notification' + if (ble_srv_is_notification_enabled(p_evt_write->data)) + { + // Do connection parameter negotiation if necessary + conn_params_negotiation(); + } + else + { + uint32_t err_code; + + // Stop timer if running + err_code = app_timer_stop(m_conn_params_timer_id); + if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL)) + { + m_conn_params_config.error_handler(err_code); + } + } + } +} + + +static void on_conn_params_update(ble_evt_t * p_ble_evt) +{ + // Copy the parameters + m_current_conn_params = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params; + + conn_params_negotiation(); +} + + +void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_ble_evt); + break; + + case BLE_GAP_EVT_CONN_PARAM_UPDATE: + on_conn_params_update(p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t * new_params) +{ + uint32_t err_code; + + m_preferred_conn_params = *new_params; + // Set the connection params in stack + err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params); + if (err_code == NRF_SUCCESS) + { + if (!is_conn_params_ok(&m_current_conn_params)) + { + m_change_param = true; + err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params); + m_update_count = 1; + } + else + { + // Notify the application that the procedure has succeded + if (m_conn_params_config.evt_handler != NULL) + { + ble_conn_params_evt_t evt; + + evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED; + m_conn_params_config.evt_handler(&evt); + } + err_code = NRF_SUCCESS; + } + } + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_conn_params.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_conn_params.h new file mode 100644 index 0000000000000000000000000000000000000000..3bcebc4a58c658418178eddbbe131125f76c2ce7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_conn_params.h @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_lib_conn_params Connection Parameters Negotiation + * @{ + * @ingroup ble_sdk_lib + * @brief Module for initiating and executing a connection parameters negotiation procedure. + */ + +#ifndef BLE_CONN_PARAMS_H__ +#define BLE_CONN_PARAMS_H__ + +#include +#include "ble.h" +#include "ble_srv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Connection Parameters Module event type. */ +typedef enum +{ + BLE_CONN_PARAMS_EVT_FAILED , /**< Negotiation procedure failed. */ + BLE_CONN_PARAMS_EVT_SUCCEEDED /**< Negotiation procedure succeeded. */ +} ble_conn_params_evt_type_t; + +/**@brief Connection Parameters Module event. */ +typedef struct +{ + ble_conn_params_evt_type_t evt_type; /**< Type of event. */ +} ble_conn_params_evt_t; + +/**@brief Connection Parameters Module event handler type. */ +typedef void (*ble_conn_params_evt_handler_t) (ble_conn_params_evt_t * p_evt); + +/**@brief Connection Parameters Module init structure. This contains all options and data needed for + * initialization of the connection parameters negotiation module. */ +typedef struct +{ + ble_gap_conn_params_t * p_conn_params; /**< Pointer to the connection parameters desired by the application. When calling ble_conn_params_init, if this parameter is set to NULL, the connection parameters will be fetched from host. */ + uint32_t first_conn_params_update_delay; /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (in number of timer ticks). */ + uint32_t next_conn_params_update_delay; /**< Time between each call to sd_ble_gap_conn_param_update after the first (in number of timer ticks). Recommended value 30 seconds as per BLUETOOTH SPECIFICATION Version 4.0. */ + uint8_t max_conn_params_update_count; /**< Number of attempts before giving up the negotiation. */ + uint16_t start_on_notify_cccd_handle; /**< If procedure is to be started when notification is started, set this to the handle of the corresponding CCCD. Set to BLE_GATT_HANDLE_INVALID if procedure is to be started on connect event. */ + bool disconnect_on_fail; /**< Set to TRUE if a failed connection parameters update shall cause an automatic disconnection, set to FALSE otherwise. */ + ble_conn_params_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Connection Parameters. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ +} ble_conn_params_init_t; + + +/**@brief Function for initializing the Connection Parameters module. + * + * @note If the negotiation procedure should be triggered when notification/indication of + * any characteristic is enabled by the peer, then this function must be called after + * having initialized the services. + * + * @param[in] p_init This contains information needed to initialize this module. + * + * @return NRF_SUCCESS on successful initialization, otherwise an error code. + */ +uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init); + +/**@brief Function for stopping the Connection Parameters module. + * + * @details This function is intended to be used by the application to clean up the connection + * parameters update module. This will stop the connection parameters update timer if + * running, thereby preventing any impending connection parameters update procedure. This + * function must be called by the application when it needs to clean itself up (for + * example, before disabling the bluetooth SoftDevice) so that an unwanted timer expiry + * event can be avoided. + * + * @return NRF_SUCCESS on successful initialization, otherwise an error code. + */ +uint32_t ble_conn_params_stop(void); + +/**@brief Function for changing the current connection parameters to a new set. + * + * @details Use this function to change the connection parameters to a new set of parameter + * (ie different from the ones given at init of the module). + * This function is useful for scenario where most of the time the application + * needs a relatively big connection interval, and just sometimes, for a temporary + * period requires shorter connection interval, for example to transfer a higher + * amount of data. + * If the given parameters does not match the current connection's parameters + * this function initiates a new negotiation. + * + * @param[in] new_params This contains the new connections parameters to setup. + * + * @return NRF_SUCCESS on successful initialization, otherwise an error code. + */ +uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t *new_params); + +/**@brief Function for handling the Application's BLE Stack events. + * + * @details Handles all events from the BLE stack that are of interest to this module. + * + * @param[in] p_ble_evt The event received from the BLE stack. + */ +void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_CONN_PARAMS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_conn_state.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_conn_state.c new file mode 100644 index 0000000000000000000000000000000000000000..6fbabe491b0d28a8938fbd4961e136150961b93e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_conn_state.c @@ -0,0 +1,414 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_conn_state.h" +#include +#include +#include +#include "ble.h" +#include "sdk_mapped_flags.h" +#include "app_error.h" + + +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#endif + + +#define BLE_CONN_STATE_N_DEFAULT_FLAGS 5 /**< The number of flags kept for each connection, excluding user flags. */ +#define BLE_CONN_STATE_N_FLAGS (BLE_CONN_STATE_N_DEFAULT_FLAGS + BLE_CONN_STATE_N_USER_FLAGS) /**< The number of flags kept for each connection, including user flags. */ + + +/**@brief Structure containing all the flag collections maintained by the Connection State module. + */ +typedef struct +{ + sdk_mapped_flags_t valid_flags; /**< Flags indicating which connection handles are valid. */ + sdk_mapped_flags_t connected_flags; /**< Flags indicating which connections are connected, since disconnected connection handles will not immediately be invalidated. */ + sdk_mapped_flags_t central_flags; /**< Flags indicating in which connections the local device is the central. */ + sdk_mapped_flags_t encrypted_flags; /**< Flags indicating which connections are encrypted. */ + sdk_mapped_flags_t mitm_protected_flags; /**< Flags indicating which connections have encryption with protection from man-in-the-middle attacks. */ + sdk_mapped_flags_t user_flags[BLE_CONN_STATE_N_USER_FLAGS]; /**< Flags that can be reserved by the user. The flags will be cleared when a connection is invalidated, otherwise, the user is wholly responsible for the flag states. */ +} ble_conn_state_flag_collections_t; + + +/**@brief Structure containing the internal state of the Connection State module. + */ +typedef struct +{ + uint32_t acquired_flags; /**< Bitmap for keeping track of which user flags have been acquired. */ + uint16_t valid_conn_handles[SDK_MAPPED_FLAGS_N_KEYS]; /**< List of connection handles used as keys for the sdk_mapped_flags module. */ + union + { + ble_conn_state_flag_collections_t flags; /**< Flag collections kept by the Connection State module. */ + sdk_mapped_flags_t flag_array[BLE_CONN_STATE_N_FLAGS]; /**< Flag collections as array to allow use of @ref sdk_mapped_flags_bulk_update_by_key() when setting all flags. */ + }; +} ble_conn_state_t; + + +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + /* leave anonymous unions enabled */ +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#endif + + +static ble_conn_state_t m_bcs = {0}; /**< Instantiation of the internal state. */ + + +/**@brief Function for resetting all internal memory to the values it had at initialization. + */ +void bcs_internal_state_reset(void) +{ + memset( &m_bcs, 0, sizeof(ble_conn_state_t) ); +} + + +/**@brief Function for activating a connection record. + * + * @param p_record The record to activate. + * @param conn_handle The connection handle to copy into the record. + * @param role The role of the connection. + * + * @return whether the record was activated successfully. + */ +static bool record_activate(uint16_t conn_handle) +{ + uint16_t available_index = sdk_mapped_flags_first_key_index_get(~m_bcs.flags.valid_flags); + + if (available_index != SDK_MAPPED_FLAGS_INVALID_INDEX) + { + m_bcs.valid_conn_handles[available_index] = conn_handle; + sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles, + &m_bcs.flags.connected_flags, + conn_handle, + 1); + sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles, + &m_bcs.flags.valid_flags, + conn_handle, + 1); + + return true; + } + + return false; +} + + +/**@brief Function for marking a connection record as invalid and resetting the values. + * + * @param p_record The record to invalidate. + */ +static void record_invalidate(uint16_t conn_handle) +{ + sdk_mapped_flags_bulk_update_by_key(m_bcs.valid_conn_handles, + m_bcs.flag_array, + BLE_CONN_STATE_N_FLAGS, + conn_handle, + 0); +} + + +/**@brief Function for marking a connection as disconnected. See @ref BLE_CONN_STATUS_DISCONNECTED. + * + * @param p_record The record of the connection to set as disconnected. + */ +static void record_set_disconnected(uint16_t conn_handle) +{ + sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles, + &m_bcs.flags.connected_flags, + conn_handle, + 0); +} + + +/**@brief Function for invalidating records with a @ref BLE_CONN_STATUS_DISCONNECTED + * connection status + */ +static void record_purge_disconnected() +{ + sdk_mapped_flags_key_list_t disconnected_list; + + disconnected_list = sdk_mapped_flags_key_list_get( + m_bcs.valid_conn_handles, + (~m_bcs.flags.connected_flags) & (m_bcs.flags.valid_flags)); + + for (uint32_t i = 0; i < disconnected_list.len; i++) + { + record_invalidate(disconnected_list.flag_keys[i]); + } +} + + +/**@brief Function for checking if a user flag has been acquired. + * + * @param[in] flag_id Which flag to check. + * + * @return Whether the flag has been acquired. + */ +static bool user_flag_is_acquired(ble_conn_state_user_flag_id_t flag_id) +{ + return ((m_bcs.acquired_flags & (1 << flag_id)) != 0); +} + + +/**@brief Function for marking a user flag as acquired. + * + * @param[in] flag_id Which flag to mark. + */ +static void user_flag_acquire(ble_conn_state_user_flag_id_t flag_id) +{ + m_bcs.acquired_flags |= (1 << flag_id); +} + + +void ble_conn_state_init(void) +{ + bcs_internal_state_reset(); +} + + +void ble_conn_state_on_ble_evt(ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + record_purge_disconnected(); + + if ( !record_activate(p_ble_evt->evt.gap_evt.conn_handle) ) + { + // No more records available. Should not happen. + APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); + } + else + { + bool is_central = + (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_CENTRAL); + + sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles, + &m_bcs.flags.central_flags, + p_ble_evt->evt.gap_evt.conn_handle, + is_central); + } + + break; + + case BLE_GAP_EVT_DISCONNECTED: + record_set_disconnected(p_ble_evt->evt.gap_evt.conn_handle); + break; + + case BLE_GAP_EVT_CONN_SEC_UPDATE: + sdk_mapped_flags_update_by_key( + m_bcs.valid_conn_handles, + &m_bcs.flags.encrypted_flags, + p_ble_evt->evt.gap_evt.conn_handle, + (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv > 1)); + sdk_mapped_flags_update_by_key( + m_bcs.valid_conn_handles, + &m_bcs.flags.mitm_protected_flags, + p_ble_evt->evt.gap_evt.conn_handle, + (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv > 2)); + break; + } +} + + +bool ble_conn_state_valid(uint16_t conn_handle) +{ + return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, + m_bcs.flags.valid_flags, + conn_handle); +} + + +uint8_t ble_conn_state_role(uint16_t conn_handle) +{ + uint8_t role = BLE_GAP_ROLE_INVALID; + + if ( sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, m_bcs.flags.valid_flags, conn_handle) ) + { + bool central = sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, + m_bcs.flags.central_flags, + conn_handle); + + role = central ? BLE_GAP_ROLE_CENTRAL : BLE_GAP_ROLE_PERIPH; + } + + return role; +} + + +ble_conn_state_status_t ble_conn_state_status(uint16_t conn_handle) +{ + ble_conn_state_status_t conn_status = BLE_CONN_STATUS_INVALID; + bool valid = sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, + m_bcs.flags.valid_flags, + conn_handle); + + if (valid) + { + bool connected = sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, + m_bcs.flags.connected_flags, + conn_handle); + + conn_status = connected ? BLE_CONN_STATUS_CONNECTED : BLE_CONN_STATUS_DISCONNECTED; + } + + return conn_status; +} + + +bool ble_conn_state_encrypted(uint16_t conn_handle) +{ + return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, + m_bcs.flags.encrypted_flags, + conn_handle); +} + + +bool ble_conn_state_mitm_protected(uint16_t conn_handle) +{ + return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, + m_bcs.flags.mitm_protected_flags, + conn_handle); +} + + +uint32_t ble_conn_state_n_connections(void) +{ + return sdk_mapped_flags_n_flags_set(m_bcs.flags.connected_flags); +} + + +uint32_t ble_conn_state_n_centrals(void) +{ + return sdk_mapped_flags_n_flags_set((m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags)); +} + + +uint32_t ble_conn_state_n_peripherals(void) +{ + return sdk_mapped_flags_n_flags_set((~m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags)); +} + + +sdk_mapped_flags_key_list_t ble_conn_state_conn_handles(void) +{ + return sdk_mapped_flags_key_list_get(m_bcs.valid_conn_handles, m_bcs.flags.valid_flags); +} + + +sdk_mapped_flags_key_list_t ble_conn_state_central_handles(void) +{ + return sdk_mapped_flags_key_list_get(m_bcs.valid_conn_handles, + (m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags)); +} + + +sdk_mapped_flags_key_list_t ble_conn_state_periph_handles(void) +{ + return sdk_mapped_flags_key_list_get(m_bcs.valid_conn_handles, + (~m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags)); +} + + +ble_conn_state_user_flag_id_t ble_conn_state_user_flag_acquire(void) +{ + for (ble_conn_state_user_flag_id_t i = BLE_CONN_STATE_USER_FLAG0; + i < BLE_CONN_STATE_N_USER_FLAGS; + i++) + { + if ( !user_flag_is_acquired(i) ) + { + user_flag_acquire(i); + return i; + } + } + + return BLE_CONN_STATE_USER_FLAG_INVALID; +} + + +bool ble_conn_state_user_flag_get(uint16_t conn_handle, ble_conn_state_user_flag_id_t flag_id) +{ + if (user_flag_is_acquired(flag_id)) + { + return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, + m_bcs.flags.user_flags[flag_id], + conn_handle); + } + else + { + return false; + } +} + + +void ble_conn_state_user_flag_set(uint16_t conn_handle, + ble_conn_state_user_flag_id_t flag_id, + bool value) +{ + if (user_flag_is_acquired(flag_id)) + { + sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles, + &m_bcs.flags.user_flags[flag_id], + conn_handle, + value); + } +} + + +sdk_mapped_flags_t ble_conn_state_user_flag_collection(ble_conn_state_user_flag_id_t flag_id) +{ + if ( user_flag_is_acquired(flag_id) ) + { + return m_bcs.flags.user_flags[flag_id]; + } + else + { + return 0; + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_conn_state.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_conn_state.h new file mode 100644 index 0000000000000000000000000000000000000000..c8a99bdd381484a044fa92d33aec807efcb1397f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_conn_state.h @@ -0,0 +1,311 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * + * @defgroup ble_conn_state Connection state + * @ingroup ble_sdk_lib + * @{ + * @brief Module for storing data on BLE connections. + * + * @details This module stores certain states for each connection, which can be queried by + * connection handle. The module uses BLE events to keep the states updated. + * + * In addition to the preprogrammed states, this module can also keep track of a number of + * binary user states, or user flags. These are reset to 0 for new connections, but + * otherwise not touched by this module. + * + * This module uses the @ref sdk_mapped_flags module, with connection handles as keys and + * the connection states as flags. + * + * @note A connection handle is not immediately invalidated when it is disconnected. Certain states, + * such as the role, can still be queried until the next time a new connection is established + * to any device. + * + * To function properly, this module must be provided with BLE events from the SoftDevice + * through the @ref ble_conn_state_on_ble_evt() function. This module should be the first + * to receive BLE events if they are dispatched to multiple modules. + */ + +#ifndef BLE_CONN_STATE_H__ +#define BLE_CONN_STATE_H__ + +#include +#include +#include "ble.h" +#include "sdk_mapped_flags.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Connection handle statuses. + */ +typedef enum +{ + BLE_CONN_STATUS_INVALID, /**< The connection handle is invalid. */ + BLE_CONN_STATUS_DISCONNECTED, /**< The connection handle refers to a connection that has been disconnected, but not yet invalidated. */ + BLE_CONN_STATUS_CONNECTED, /**< The connection handle refers to an active connection. */ +} ble_conn_state_status_t; + +#define BLE_CONN_STATE_N_USER_FLAGS 24 /**< The number of available user flags. */ + + +/**@brief One ID for each user flag collection. + * + * @details These IDs are used to identify user flag collections in the API calls. + */ +typedef enum +{ + BLE_CONN_STATE_USER_FLAG0 = 0, + BLE_CONN_STATE_USER_FLAG1, + BLE_CONN_STATE_USER_FLAG2, + BLE_CONN_STATE_USER_FLAG3, + BLE_CONN_STATE_USER_FLAG4, + BLE_CONN_STATE_USER_FLAG5, + BLE_CONN_STATE_USER_FLAG6, + BLE_CONN_STATE_USER_FLAG7, + BLE_CONN_STATE_USER_FLAG8, + BLE_CONN_STATE_USER_FLAG9, + BLE_CONN_STATE_USER_FLAG10, + BLE_CONN_STATE_USER_FLAG11, + BLE_CONN_STATE_USER_FLAG12, + BLE_CONN_STATE_USER_FLAG13, + BLE_CONN_STATE_USER_FLAG14, + BLE_CONN_STATE_USER_FLAG15, + BLE_CONN_STATE_USER_FLAG16, + BLE_CONN_STATE_USER_FLAG17, + BLE_CONN_STATE_USER_FLAG18, + BLE_CONN_STATE_USER_FLAG19, + BLE_CONN_STATE_USER_FLAG20, + BLE_CONN_STATE_USER_FLAG21, + BLE_CONN_STATE_USER_FLAG22, + BLE_CONN_STATE_USER_FLAG23, + BLE_CONN_STATE_USER_FLAG_INVALID, +} ble_conn_state_user_flag_id_t; + + +/** + * @defgroup ble_conn_state_functions BLE connection state functions + * @{ + */ + + +/**@brief Function for initializing or resetting the module. + * + * @details This function sets all states to their default, removing all records of connection handles. + */ +void ble_conn_state_init(void); + + +/**@brief Function for providing BLE SoftDevice events to the connection state module. + * + * @param[in] p_ble_evt The SoftDevice event. + */ +void ble_conn_state_on_ble_evt(ble_evt_t * p_ble_evt); + + +/**@brief Function for querying whether a connection handle represents a valid connection. + * + * @details A connection might be valid and have a BLE_CONN_STATUS_DISCONNECTED status. + * Those connections are invalidated after a new connection occurs. + * + * @param[in] conn_handle Handle of the connection. + * + * @retval true If conn_handle represents a valid connection, thus a connection for which + we have a record. + * @retval false If conn_handle is @ref BLE_GAP_ROLE_INVALID, or if it has never been recorded. + */ +bool ble_conn_state_valid(uint16_t conn_handle); + + +/**@brief Function for querying the role of the local device in a connection. + * + * @param[in] conn_handle Handle of the connection to get the role for. + * + * @return The role of the local device in the connection (see @ref BLE_GAP_ROLES). + * If conn_handle is not valid, the function returns BLE_GAP_ROLE_INVALID. + */ +uint8_t ble_conn_state_role(uint16_t conn_handle); + + +/**@brief Function for querying the status of a connection. + * + * @param[in] conn_handle Handle of the connection. + * + * @return The status of the connection. + * If conn_handle is not valid, the function returns BLE_CONN_STATE_INVALID. + */ +ble_conn_state_status_t ble_conn_state_status(uint16_t conn_handle); + + +/**@brief Function for querying whether a connection is encrypted. + * + * @param[in] conn_handle Handle of connection to get the encryption state for. + * + * @retval true If the connection is encrypted. + * @retval false If the connection is not encrypted or conn_handle is invalid. + */ +bool ble_conn_state_encrypted(uint16_t conn_handle); + + +/**@brief Function for querying whether a connection encryption is protected from Man in the Middle + * attacks. + * + * @param[in] conn_handle Handle of connection to get the MITM state for. + * + * @retval true If the connection is encrypted with MITM protection. + * @retval false If the connection is not encrypted, or encryption is not MITM protected, or + * conn_handle is invalid. + */ +bool ble_conn_state_mitm_protected(uint16_t conn_handle); + + +/**@brief Function for querying the total number of connections. + * + * @return The total number of valid connections for which the module has a record. + */ +uint32_t ble_conn_state_n_connections(void); + + +/**@brief Function for querying the total number of connections in which the role of the local + * device is @ref BLE_GAP_ROLE_CENTRAL. + * + * @return The number of connections in which the role of the local device is + * @ref BLE_GAP_ROLE_CENTRAL. + */ +uint32_t ble_conn_state_n_centrals(void); + + +/**@brief Function for querying the total number of connections in which the role of the local + * device is @ref BLE_GAP_ROLE_PERIPH. + * + * @return The number of connections in which the role of the local device is + * @ref BLE_GAP_ROLE_PERIPH. + */ +uint32_t ble_conn_state_n_peripherals(void); + + +/**@brief Function for obtaining a list of all connection handles for which the module has a record. + * + * @details This function takes into account connections whose state is BLE_CONN_STATUS_DISCONNECTED. + * + * @return A list of all valid connection handles for which the module has a record. + */ +sdk_mapped_flags_key_list_t ble_conn_state_conn_handles(void); + + +/**@brief Function for obtaining a list of connection handles in which the role of the local + * device is @ref BLE_GAP_ROLE_CENTRAL. + * + * @details This function takes into account connections whose state is BLE_CONN_STATUS_DISCONNECTED. + * + * @return A list of all valid connection handles for which the module has a record and in which + * the role of local device is @ref BLE_GAP_ROLE_CENTRAL. + */ +sdk_mapped_flags_key_list_t ble_conn_state_central_handles(void); + + +/**@brief Function for obtaining the handle for the connection in which the role of the local device + * is @ref BLE_GAP_ROLE_PERIPH. + * + * @details This function takes into account connections whose state is BLE_CONN_STATUS_DISCONNECTED. + * + * @return A list of all valid connection handles for which the module has a record and in which + * the role of local device is @ref BLE_GAP_ROLE_PERIPH. + */ +sdk_mapped_flags_key_list_t ble_conn_state_periph_handles(void); + + +/**@brief Function for obtaining exclusive access to one of the user flag collections. + * + * @details The acquired collection contains one flag for each connection. These flags can be set + * and read individually for each connection. + * + * The state of user flags will not be modified by the connection state module, except to + * set it to 0 for a connection when that connection is invalidated. + * + * @return The ID of the acquired flag, or BLE_CONN_STATE_USER_FLAG_INVALID if none are available. + */ +ble_conn_state_user_flag_id_t ble_conn_state_user_flag_acquire(void); + + +/**@brief Function for reading the value of a user flag. + * + * @param[in] conn_handle Handle of connection to get the flag state for. + * @param[in] flag_id Which flag to get the state for. + * + * @return The state of the flag. If conn_handle is invalid, the function returns false. + */ +bool ble_conn_state_user_flag_get(uint16_t conn_handle, ble_conn_state_user_flag_id_t flag_id); + + +/**@brief Function for setting the value of a user flag. + * + * @param[in] conn_handle Handle of connection to set the flag state for. + * @param[in] flag_id Which flag to set the state for. + * @param[in] value Value to set the flag state to. + */ +void ble_conn_state_user_flag_set(uint16_t conn_handle, + ble_conn_state_user_flag_id_t flag_id, + bool value); + + +/**@brief Function for getting the state of a user flag for all connection handles. + * + * @details The returned collection can be used with the @ref sdk_mapped_flags API. The returned + * collection is a copy, so modifying it has no effect on the conn_state module. + * + * @param[in] flag_id Which flag to get states for. + * + * @return The collection of flag states. The collection is always all zeros when the flag_id is + * unregistered. + */ +sdk_mapped_flags_t ble_conn_state_user_flag_collection(ble_conn_state_user_flag_id_t flag_id); + +/** @} */ +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* BLE_CONN_STATE_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_date_time.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_date_time.h new file mode 100644 index 0000000000000000000000000000000000000000..762784c11aec66c4b2db7db1e2e0e5de564c533f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_date_time.h @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ + +/** @file + * @brief Contains definition of ble_date_time structure. + */ + +/** @file + * + * @defgroup ble_sdk_srv_date_time BLE Date Time characteristic type + * @{ + * @ingroup ble_sdk_lib + * @brief Definition of ble_date_time_t type. + */ + +#ifndef BLE_DATE_TIME_H__ +#define BLE_DATE_TIME_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Date and Time structure. */ +typedef struct +{ + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hours; + uint8_t minutes; + uint8_t seconds; +} ble_date_time_t; + +static __INLINE uint8_t ble_date_time_encode(const ble_date_time_t * p_date_time, + uint8_t * p_encoded_data) +{ + uint8_t len = uint16_encode(p_date_time->year, p_encoded_data); + + p_encoded_data[len++] = p_date_time->month; + p_encoded_data[len++] = p_date_time->day; + p_encoded_data[len++] = p_date_time->hours; + p_encoded_data[len++] = p_date_time->minutes; + p_encoded_data[len++] = p_date_time->seconds; + + return len; +} + +static __INLINE uint8_t ble_date_time_decode(ble_date_time_t * p_date_time, + const uint8_t * p_encoded_data) +{ + uint8_t len = sizeof(uint16_t); + + p_date_time->year = uint16_decode(p_encoded_data); + p_date_time->month = p_encoded_data[len++]; + p_date_time->day = p_encoded_data[len++]; + p_date_time->hours = p_encoded_data[len++]; + p_date_time->minutes = p_encoded_data[len++]; + p_date_time->seconds = p_encoded_data[len++]; + + return len; +} + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_DATE_TIME_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_gatt_db.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_gatt_db.h new file mode 100644 index 0000000000000000000000000000000000000000..4fd2b34a2f247cd6fbec8d960033fabeb9f2a40f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_gatt_db.h @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ble_sdk_lib_gatt_db GATT Database Service Structure + * @{ + * @ingroup ble_sdk_lib + */ + +#ifndef BLE_GATT_DB_H__ +#define BLE_GATT_DB_H__ + +#include +#include "ble.h" +#include "ble_gattc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_GATT_DB_MAX_CHARS 5 /**< The maximum number of characteristics present in a service record. */ + +/**@brief Structure for holding the characteristic and the handle of its CCCD present on a server. + */ +typedef struct +{ + ble_gattc_char_t characteristic; /**< Structure containing information about the characteristic. */ + uint16_t cccd_handle; /**< CCCD Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if a CCCD is not present at the server. */ + uint16_t ext_prop_handle; /**< Extended Properties Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if an Extended Properties descriptor is not present at the server. */ + uint16_t user_desc_handle; /**< User Description Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if a User Description descriptor is not present at the server. */ + uint16_t report_ref_handle; /**< Report Reference Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if a Report Reference descriptor is not present at the server. */ +} ble_gatt_db_char_t; + +/**@brief Structure for holding information about the service and the characteristics present on a + * server. + */ +typedef struct +{ + ble_uuid_t srv_uuid; /**< UUID of the service. */ + uint8_t char_count; /**< Number of characteristics present in the service. */ + ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */ + ble_gatt_db_char_t charateristics[BLE_GATT_DB_MAX_CHARS]; /**< Array of information related to the characteristics present in the service. This list can extend further than one. */ +} ble_gatt_db_srv_t; + + +#ifdef __cplusplus +} +#endif + +#endif /* BLE_GATT_DB_H__ */ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_sensor_location.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_sensor_location.h new file mode 100644 index 0000000000000000000000000000000000000000..ca259f1450728b35fbdcd3ff49a0ca3a9b6194cf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_sensor_location.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ + +#ifndef BLE_SENSOR_LOCATION_H__ +#define BLE_SENSOR_LOCATION_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + BLE_SENSOR_LOCATION_OTHER = 0 , /**<-- Other */ + BLE_SENSOR_LOCATION_TOP_OF_SHOE = 1 , /**<-- Top of shoe */ + BLE_SENSOR_LOCATION_IN_SHOE = 2 , /**<-- In shoe */ + BLE_SENSOR_LOCATION_HIP = 3 , /**<-- Hip */ + BLE_SENSOR_LOCATION_FRONT_WHEEL = 4 , /**<-- Front Wheel */ + BLE_SENSOR_LOCATION_LEFT_CRANK = 5 , /**<-- Left Crank */ + BLE_SENSOR_LOCATION_RIGHT_CRANK = 6 , /**<-- Right Crank */ + BLE_SENSOR_LOCATION_LEFT_PEDAL = 7 , /**<-- Left Pedal */ + BLE_SENSOR_LOCATION_RIGHT_PEDAL = 8 , /**<-- Right Pedal */ + BLE_SENSOR_LOCATION_FRONT_HUB = 9 , /**<-- Front Hub */ + BLE_SENSOR_LOCATION_REAR_DROPOUT = 10, /**<-- Rear Dropout */ + BLE_SENSOR_LOCATION_CHAINSTAY = 11, /**<-- Chainstay */ + BLE_SENSOR_LOCATION_REAR_WHEEL = 12, /**<-- Rear Wheel */ + BLE_SENSOR_LOCATION_REAR_HUB = 13, /**<-- Rear Hub */ +}ble_sensor_location_t; + +#define BLE_NB_MAX_SENSOR_LOCATIONS 14 + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_SENSOR_LOCATION_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_srv_common.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_srv_common.c new file mode 100644 index 0000000000000000000000000000000000000000..58277bac7232d1ba8c6578cede008b394ecdb5bb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_srv_common.c @@ -0,0 +1,237 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ + +#include "ble_srv_common.h" +#include +#include "nordic_common.h" +#include "app_error.h" +#include "ble.h" + +bool ble_srv_is_notification_enabled(uint8_t const * p_encoded_data) +{ + uint16_t cccd_value = uint16_decode(p_encoded_data); + return ((cccd_value & BLE_GATT_HVX_NOTIFICATION) != 0); +} + +bool ble_srv_is_indication_enabled(uint8_t const * p_encoded_data) +{ + uint16_t cccd_value = uint16_decode(p_encoded_data); + return ((cccd_value & BLE_GATT_HVX_INDICATION) != 0); +} + +uint8_t ble_srv_report_ref_encode(uint8_t * p_encoded_buffer, + const ble_srv_report_ref_t * p_report_ref) +{ + uint8_t len = 0; + + p_encoded_buffer[len++] = p_report_ref->report_id; + p_encoded_buffer[len++] = p_report_ref->report_type; + + APP_ERROR_CHECK_BOOL(len == BLE_SRV_ENCODED_REPORT_REF_LEN); + return len; +} + + +void ble_srv_ascii_to_utf8(ble_srv_utf8_str_t * p_utf8, char * p_ascii) +{ + p_utf8->length = (uint16_t)strlen(p_ascii); + p_utf8->p_str = (uint8_t *)p_ascii; +} + + +/**@brief Function for setting security requirements of a characteristic. + * + * @param[in] level required security level. + * @param[out] p_perm Characteristic security requirements. + * + * @return encoded security level and security mode. + */ +static inline void set_security_req(security_req_t level, ble_gap_conn_sec_mode_t * p_perm) +{ + + + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(p_perm); + switch (level) + { + case SEC_NO_ACCESS: + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(p_perm); + break; + case SEC_OPEN: + BLE_GAP_CONN_SEC_MODE_SET_OPEN(p_perm); + break; + case SEC_JUST_WORKS: + BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(p_perm); + break; + case SEC_MITM: + BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(p_perm); + break; + case SEC_SIGNED: + BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(p_perm); + break; + case SEC_SIGNED_MITM: + BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(p_perm); + break; + } + return; +} + + +uint32_t characteristic_add(uint16_t service_handle, + ble_add_char_params_t * p_char_props, + ble_gatts_char_handles_t * p_char_handle) +{ + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t char_uuid; + ble_gatts_attr_md_t attr_md; + ble_gatts_attr_md_t user_descr_attr_md; + ble_gatts_attr_md_t cccd_md; + + if (p_char_props->uuid_type == 0) + { + char_uuid.type = BLE_UUID_TYPE_BLE; + } + else + { + char_uuid.type = p_char_props->uuid_type; + } + char_uuid.uuid = p_char_props->uuid; + + memset(&attr_md, 0, sizeof(ble_gatts_attr_md_t)); + set_security_req(p_char_props->read_access, &attr_md.read_perm); + set_security_req(p_char_props->write_access, & attr_md.write_perm); + attr_md.rd_auth = (p_char_props->is_defered_read ? 1 : 0); + attr_md.wr_auth = (p_char_props->is_defered_write ? 1 : 0); + attr_md.vlen = (p_char_props->is_var_len ? 1 : 0); + attr_md.vloc = (p_char_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK); + + + memset(&char_md, 0, sizeof(ble_gatts_char_md_t)); + if ((p_char_props->char_props.notify == 1)||(p_char_props->char_props.indicate == 1)) + { + + memset(&cccd_md, 0, sizeof(cccd_md)); + set_security_req(p_char_props->cccd_write_access, &cccd_md.write_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + + char_md.p_cccd_md = &cccd_md; + } + char_md.char_props = p_char_props->char_props; + char_md.char_ext_props = p_char_props->char_ext_props; + + memset(&attr_char_value, 0, sizeof(ble_gatts_attr_t)); + attr_char_value.p_uuid = &char_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.max_len = p_char_props->max_len; + if (p_char_props->p_init_value != NULL) + { + attr_char_value.init_len = p_char_props->init_len; + attr_char_value.p_value = p_char_props->p_init_value; + } + if (p_char_props->p_user_descr != NULL) + { + memset(&user_descr_attr_md, 0, sizeof(ble_gatts_attr_md_t)); + char_md.char_user_desc_max_size = p_char_props->p_user_descr->max_size; + char_md.char_user_desc_size = p_char_props->p_user_descr->size; + char_md.p_char_user_desc = p_char_props->p_user_descr->p_char_user_desc; + + char_md.p_user_desc_md = &user_descr_attr_md; + + set_security_req(p_char_props->p_user_descr->read_access, &user_descr_attr_md.read_perm); + set_security_req(p_char_props->p_user_descr->write_access, &user_descr_attr_md.write_perm); + + user_descr_attr_md.rd_auth = (p_char_props->p_user_descr->is_defered_read ? 1 : 0); + user_descr_attr_md.wr_auth = (p_char_props->p_user_descr->is_defered_write ? 1 : 0); + user_descr_attr_md.vlen = (p_char_props->p_user_descr->is_var_len ? 1 : 0); + user_descr_attr_md.vloc = (p_char_props->p_user_descr->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK); + } + if (p_char_props->p_presentation_format != NULL) + { + char_md.p_char_pf = p_char_props->p_presentation_format; + } + return sd_ble_gatts_characteristic_add(service_handle, + &char_md, + &attr_char_value, + p_char_handle); +} + + +uint32_t descriptor_add(uint16_t char_handle, + ble_add_descr_params_t * p_descr_props, + uint16_t * p_descr_handle) +{ + ble_gatts_attr_t descr_params; + ble_uuid_t desc_uuid; + ble_gatts_attr_md_t attr_md; + + memset(&descr_params, 0, sizeof(descr_params)); + if (p_descr_props->uuid_type == 0) + { + desc_uuid.type = BLE_UUID_TYPE_BLE; + } + else + { + desc_uuid.type = p_descr_props->uuid_type; + } + desc_uuid.uuid = p_descr_props->uuid; + descr_params.p_uuid = &desc_uuid; + + set_security_req(p_descr_props->read_access, &attr_md.read_perm); + set_security_req(p_descr_props->write_access,&attr_md.write_perm); + + attr_md.rd_auth = (p_descr_props->is_defered_read ? 1 : 0); + attr_md.wr_auth = (p_descr_props->is_defered_write ? 1 : 0); + attr_md.vlen = (p_descr_props->is_var_len ? 1 : 0); + attr_md.vloc = (p_descr_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK); + descr_params.p_attr_md = &attr_md; + + descr_params.init_len = p_descr_props->init_len; + descr_params.init_offs = p_descr_props->init_offs; + descr_params.max_len = p_descr_props->max_len; + descr_params.p_value = p_descr_props->p_value; + + return sd_ble_gatts_descriptor_add(char_handle, &descr_params, p_descr_handle); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_srv_common.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_srv_common.h new file mode 100644 index 0000000000000000000000000000000000000000..b8d16d07ba5311d03c90553bfbbecf4b76b7a811 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/common/ble_srv_common.h @@ -0,0 +1,398 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_srv_common Common service definitions + * @{ + * @ingroup ble_sdk_srv + * @brief Constants, type definitions, and functions that are common to all services. + */ + +#ifndef BLE_SRV_COMMON_H__ +#define BLE_SRV_COMMON_H__ + +#include +#include +#include "ble_types.h" +#include "app_util.h" +#include "ble.h" +#include "ble_gap.h" +#include "ble_gatt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup UUID_SERVICES Service UUID definitions + * @{ */ +#define BLE_UUID_ALERT_NOTIFICATION_SERVICE 0x1811 /**< Alert Notification service UUID. */ +#define BLE_UUID_BATTERY_SERVICE 0x180F /**< Battery service UUID. */ +#define BLE_UUID_BLOOD_PRESSURE_SERVICE 0x1810 /**< Blood Pressure service UUID. */ +#define BLE_UUID_CURRENT_TIME_SERVICE 0x1805 /**< Current Time service UUID. */ +#define BLE_UUID_CYCLING_SPEED_AND_CADENCE 0x1816 /**< Cycling Speed and Cadence service UUID. */ +#define BLE_UUID_LOCATION_AND_NAVIGATION_SERVICE 0x1819 /**< Location and Navigation service UUID. */ +#define BLE_UUID_DEVICE_INFORMATION_SERVICE 0x180A /**< Device Information service UUID. */ +#define BLE_UUID_GLUCOSE_SERVICE 0x1808 /**< Glucose service UUID. */ +#define BLE_UUID_HEALTH_THERMOMETER_SERVICE 0x1809 /**< Health Thermometer service UUID. */ +#define BLE_UUID_HEART_RATE_SERVICE 0x180D /**< Heart Rate service UUID. */ +#define BLE_UUID_HUMAN_INTERFACE_DEVICE_SERVICE 0x1812 /**< Human Interface Device service UUID. */ +#define BLE_UUID_IMMEDIATE_ALERT_SERVICE 0x1802 /**< Immediate Alert service UUID. */ +#define BLE_UUID_LINK_LOSS_SERVICE 0x1803 /**< Link Loss service UUID. */ +#define BLE_UUID_NEXT_DST_CHANGE_SERVICE 0x1807 /**< Next Dst Change service UUID. */ +#define BLE_UUID_PHONE_ALERT_STATUS_SERVICE 0x180E /**< Phone Alert Status service UUID. */ +#define BLE_UUID_REFERENCE_TIME_UPDATE_SERVICE 0x1806 /**< Reference Time Update service UUID. */ +#define BLE_UUID_RUNNING_SPEED_AND_CADENCE 0x1814 /**< Running Speed and Cadence service UUID. */ +#define BLE_UUID_SCAN_PARAMETERS_SERVICE 0x1813 /**< Scan Parameters service UUID. */ +#define BLE_UUID_TX_POWER_SERVICE 0x1804 /**< TX Power service UUID. */ +#define BLE_UUID_IPSP_SERVICE 0x1820 /**< Internet Protocol Support service UUID. */ +#define BLE_UUID_BMS_SERVICE 0x181E /**< BOND MANAGEMENT service UUID*/ +#define BLE_UUID_CGM_SERVICE 0x181F /**< Continuous Glucose Monitoring service UUID*/ +#define BLE_UUID_PLX_SERVICE 0x1822 /**< Pulse Oximeter Service UUID*/ + + +/** @} */ + +/** @defgroup UUID_CHARACTERISTICS Characteristic UUID definitions + * @{ */ +#define BLE_UUID_REMOVABLE_CHAR 0x2A3A /**< Removable characteristic UUID. */ +#define BLE_UUID_SERVICE_REQUIRED_CHAR 0x2A3B /**< Service Required characteristic UUID. */ +#define BLE_UUID_ALERT_CATEGORY_ID_CHAR 0x2A43 /**< Alert Category Id characteristic UUID. */ +#define BLE_UUID_ALERT_CATEGORY_ID_BIT_MASK_CHAR 0x2A42 /**< Alert Category Id Bit Mask characteristic UUID. */ +#define BLE_UUID_ALERT_LEVEL_CHAR 0x2A06 /**< Alert Level characteristic UUID. */ +#define BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR 0x2A44 /**< Alert Notification Control Point characteristic UUID. */ +#define BLE_UUID_ALERT_STATUS_CHAR 0x2A3F /**< Alert Status characteristic UUID. */ +#define BLE_UUID_BATTERY_LEVEL_CHAR 0x2A19 /**< Battery Level characteristic UUID. */ +#define BLE_UUID_BLOOD_PRESSURE_FEATURE_CHAR 0x2A49 /**< Blood Pressure Feature characteristic UUID. */ +#define BLE_UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR 0x2A35 /**< Blood Pressure Measurement characteristic UUID. */ +#define BLE_UUID_BODY_SENSOR_LOCATION_CHAR 0x2A38 /**< Body Sensor Location characteristic UUID. */ +#define BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR 0x2A22 /**< Boot Keyboard Input Report characteristic UUID. */ +#define BLE_UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR 0x2A32 /**< Boot Keyboard Output Report characteristic UUID. */ +#define BLE_UUID_BOOT_MOUSE_INPUT_REPORT_CHAR 0x2A33 /**< Boot Mouse Input Report characteristic UUID. */ +#define BLE_UUID_CURRENT_TIME_CHAR 0x2A2B /**< Current Time characteristic UUID. */ +#define BLE_UUID_DATE_TIME_CHAR 0x2A08 /**< Date Time characteristic UUID. */ +#define BLE_UUID_DAY_DATE_TIME_CHAR 0x2A0A /**< Day Date Time characteristic UUID. */ +#define BLE_UUID_DAY_OF_WEEK_CHAR 0x2A09 /**< Day Of Week characteristic UUID. */ +#define BLE_UUID_DST_OFFSET_CHAR 0x2A0D /**< Dst Offset characteristic UUID. */ +#define BLE_UUID_EXACT_TIME_256_CHAR 0x2A0C /**< Exact Time 256 characteristic UUID. */ +#define BLE_UUID_FIRMWARE_REVISION_STRING_CHAR 0x2A26 /**< Firmware Revision String characteristic UUID. */ +#define BLE_UUID_GLUCOSE_FEATURE_CHAR 0x2A51 /**< Glucose Feature characteristic UUID. */ +#define BLE_UUID_GLUCOSE_MEASUREMENT_CHAR 0x2A18 /**< Glucose Measurement characteristic UUID. */ +#define BLE_UUID_GLUCOSE_MEASUREMENT_CONTEXT_CHAR 0x2A34 /**< Glucose Measurement Context characteristic UUID. */ +#define BLE_UUID_HARDWARE_REVISION_STRING_CHAR 0x2A27 /**< Hardware Revision String characteristic UUID. */ +#define BLE_UUID_HEART_RATE_CONTROL_POINT_CHAR 0x2A39 /**< Heart Rate Control Point characteristic UUID. */ +#define BLE_UUID_HEART_RATE_MEASUREMENT_CHAR 0x2A37 /**< Heart Rate Measurement characteristic UUID. */ +#define BLE_UUID_HID_CONTROL_POINT_CHAR 0x2A4C /**< Hid Control Point characteristic UUID. */ +#define BLE_UUID_HID_INFORMATION_CHAR 0x2A4A /**< Hid Information characteristic UUID. */ +#define BLE_UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR 0x2A2A /**< IEEE Regulatory Certification Data List characteristic UUID. */ +#define BLE_UUID_INTERMEDIATE_CUFF_PRESSURE_CHAR 0x2A36 /**< Intermediate Cuff Pressure characteristic UUID. */ +#define BLE_UUID_INTERMEDIATE_TEMPERATURE_CHAR 0x2A1E /**< Intermediate Temperature characteristic UUID. */ +#define BLE_UUID_LOCAL_TIME_INFORMATION_CHAR 0x2A0F /**< Local Time Information characteristic UUID. */ +#define BLE_UUID_MANUFACTURER_NAME_STRING_CHAR 0x2A29 /**< Manufacturer Name String characteristic UUID. */ +#define BLE_UUID_MEASUREMENT_INTERVAL_CHAR 0x2A21 /**< Measurement Interval characteristic UUID. */ +#define BLE_UUID_MODEL_NUMBER_STRING_CHAR 0x2A24 /**< Model Number String characteristic UUID. */ +#define BLE_UUID_UNREAD_ALERT_CHAR 0x2A45 /**< Unread Alert characteristic UUID. */ +#define BLE_UUID_NEW_ALERT_CHAR 0x2A46 /**< New Alert characteristic UUID. */ +#define BLE_UUID_PNP_ID_CHAR 0x2A50 /**< PNP Id characteristic UUID. */ +#define BLE_UUID_PROTOCOL_MODE_CHAR 0x2A4E /**< Protocol Mode characteristic UUID. */ +#define BLE_UUID_RECORD_ACCESS_CONTROL_POINT_CHAR 0x2A52 /**< Record Access Control Point characteristic UUID. */ +#define BLE_UUID_REFERENCE_TIME_INFORMATION_CHAR 0x2A14 /**< Reference Time Information characteristic UUID. */ +#define BLE_UUID_REPORT_CHAR 0x2A4D /**< Report characteristic UUID. */ +#define BLE_UUID_REPORT_MAP_CHAR 0x2A4B /**< Report Map characteristic UUID. */ +#define BLE_UUID_RINGER_CONTROL_POINT_CHAR 0x2A40 /**< Ringer Control Point characteristic UUID. */ +#define BLE_UUID_RINGER_SETTING_CHAR 0x2A41 /**< Ringer Setting characteristic UUID. */ +#define BLE_UUID_SCAN_INTERVAL_WINDOW_CHAR 0x2A4F /**< Scan Interval Window characteristic UUID. */ +#define BLE_UUID_SCAN_REFRESH_CHAR 0x2A31 /**< Scan Refresh characteristic UUID. */ +#define BLE_UUID_SERIAL_NUMBER_STRING_CHAR 0x2A25 /**< Serial Number String characteristic UUID. */ +#define BLE_UUID_SOFTWARE_REVISION_STRING_CHAR 0x2A28 /**< Software Revision String characteristic UUID. */ +#define BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR 0x2A47 /**< Supported New Alert Category characteristic UUID. */ +#define BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR 0x2A48 /**< Supported Unread Alert Category characteristic UUID. */ +#define BLE_UUID_SYSTEM_ID_CHAR 0x2A23 /**< System Id characteristic UUID. */ +#define BLE_UUID_TEMPERATURE_MEASUREMENT_CHAR 0x2A1C /**< Temperature Measurement characteristic UUID. */ +#define BLE_UUID_TEMPERATURE_TYPE_CHAR 0x2A1D /**< Temperature Type characteristic UUID. */ +#define BLE_UUID_TIME_ACCURACY_CHAR 0x2A12 /**< Time Accuracy characteristic UUID. */ +#define BLE_UUID_TIME_SOURCE_CHAR 0x2A13 /**< Time Source characteristic UUID. */ +#define BLE_UUID_TIME_UPDATE_CONTROL_POINT_CHAR 0x2A16 /**< Time Update Control Point characteristic UUID. */ +#define BLE_UUID_TIME_UPDATE_STATE_CHAR 0x2A17 /**< Time Update State characteristic UUID. */ +#define BLE_UUID_TIME_WITH_DST_CHAR 0x2A11 /**< Time With Dst characteristic UUID. */ +#define BLE_UUID_TIME_ZONE_CHAR 0x2A0E /**< Time Zone characteristic UUID. */ +#define BLE_UUID_TX_POWER_LEVEL_CHAR 0x2A07 /**< TX Power Level characteristic UUID. */ +#define BLE_UUID_CSC_FEATURE_CHAR 0x2A5C /**< Cycling Speed and Cadence Feature characteristic UUID. */ +#define BLE_UUID_CSC_MEASUREMENT_CHAR 0x2A5B /**< Cycling Speed and Cadence Measurement characteristic UUID. */ +#define BLE_UUID_RSC_FEATURE_CHAR 0x2A54 /**< Running Speed and Cadence Feature characteristic UUID. */ +#define BLE_UUID_SC_CTRLPT_CHAR 0x2A55 /**< Speed and Cadence Control Point UUID. */ +#define BLE_UUID_RSC_MEASUREMENT_CHAR 0x2A53 /**< Running Speed and Cadence Measurement characteristic UUID. */ +#define BLE_UUID_SENSOR_LOCATION_CHAR 0x2A5D /**< Sensor Location characteristic UUID. */ +#define BLE_UUID_EXTERNAL_REPORT_REF_DESCR 0x2907 /**< External Report Reference descriptor UUID. */ +#define BLE_UUID_REPORT_REF_DESCR 0x2908 /**< Report Reference descriptor UUID. */ +#define BLE_UUID_LN_FEATURE_CHAR 0x2A6A /**< Location Navigation Service, Feature characteristic UUID. */ +#define BLE_UUID_LN_POSITION_QUALITY_CHAR 0x2A69 /**< Location Navigation Service, Position quality UUID. */ +#define BLE_UUID_LN_LOCATION_AND_SPEED_CHAR 0x2A67 /**< Location Navigation Service, Location and Speed characteristic UUID. */ +#define BLE_UUID_LN_NAVIGATION_CHAR 0x2A68 /**< Location Navigation Service, Navigation characteristic UUID. */ +#define BLE_UUID_LN_CONTROL_POINT_CHAR 0x2A6B /**< Location Navigation Service, Control point characteristic UUID. */ +#define BLE_UUID_BMS_CTRLPT 0x2AA4 /**< BMS Control Point characteristic UUID. */ +#define BLE_UUID_BMS_FEATURE 0x2AA5 /**< BMS Feature characteristic UUID. */ +#define BLE_UUID_CGM_MEASUREMENT 0x2AA7 /**< CGM Service, Measurement characteristic UUID*/ +#define BLE_UUID_CGM_FEATURE 0x2AA8 /**< CGM Service, Feature characteristic UUID*/ +#define BLE_UUID_CGM_STATUS 0x2AA9 /**< CGM Service, Status characteristic UUID*/ +#define BLE_UUID_CGM_SESSION_START_TIME 0x2AAA /**< CGM Service, session start time characteristic UUID*/ +#define BLE_UUID_CGM_SESSION_RUN_TIME 0x2AAB /**< CGM Service, session run time characteristic UUID*/ +#define BLE_UUID_CGM_SPECIFIC_OPS_CTRLPT 0x2AAC /**< CGM Service, specific ops ctrlpt characteristic UUID*/ +#define BLE_UUID_PLX_SPOT_CHECK_MEAS 0x2A5E /**< PLX Service, spot check measurement characteristic UUID*/ +#define BLE_UUID_PLX_CONTINUOUS_MEAS 0x2A5F /**< PLX Service, continuous measurement characteristic UUID*/ +#define BLE_UUID_PLX_FEATURES 0x2A60 /**< PLX Service, feature characteristic UUID*/ + + + + + +/** @} */ + +/** @defgroup ALERT_LEVEL_VALUES Definitions for the Alert Level characteristic values + * @{ */ +#define BLE_CHAR_ALERT_LEVEL_NO_ALERT 0x00 /**< No Alert. */ +#define BLE_CHAR_ALERT_LEVEL_MILD_ALERT 0x01 /**< Mild Alert. */ +#define BLE_CHAR_ALERT_LEVEL_HIGH_ALERT 0x02 /**< High Alert. */ +/** @} */ + +#define BLE_SRV_ENCODED_REPORT_REF_LEN 2 /**< The length of an encoded Report Reference Descriptor. */ +#define BLE_CCCD_VALUE_LEN 2 /**< The length of a CCCD value. */ + +/**@brief Type definition for error handler function that will be called in case of an error in + * a service or a service library module. */ +typedef void (*ble_srv_error_handler_t) (uint32_t nrf_error); + + + +/**@brief Value of a Report Reference descriptor. + * + * @details This is mapping information that maps the parent characteristic to the Report ID(s) and + * Report Type(s) defined within a Report Map characteristic. + */ +typedef struct +{ + uint8_t report_id; /**< Non-zero value if there is more than one instance of the same Report Type */ + uint8_t report_type; /**< Type of Report characteristic (see @ref BLE_HIDS_REPORT_TYPE) */ +} ble_srv_report_ref_t; + +/**@brief UTF-8 string data type. + * + * @note The type can only hold a pointer to the string data (i.e. not the actual data). + */ +typedef struct +{ + uint16_t length; /**< String length. */ + uint8_t * p_str; /**< String data. */ +} ble_srv_utf8_str_t; + + +/**@brief Security settings structure. + * @details This structure contains the security options needed during initialization of the + * service. + */ +typedef struct +{ + ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */ + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ +} ble_srv_security_mode_t; + +/**@brief Security settings structure. + * @details This structure contains the security options needed during initialization of the + * service. It can be used when the characteristics contains a CCCD. + */ +typedef struct +{ + ble_gap_conn_sec_mode_t cccd_write_perm; /**< Write permissions for Client Characteristic Configuration Descriptor. */ + ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */ + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ +} ble_srv_cccd_security_mode_t; + +/**@brief Function for decoding a CCCD value, and then testing if notification is + * enabled. + * + * @param[in] p_encoded_data Buffer where the encoded CCCD is stored. + * + * @retval TRUE If notification is enabled. + * @retval FALSE Otherwise. + */ +bool ble_srv_is_notification_enabled(uint8_t const * p_encoded_data); + + +/**@brief Function for decoding a CCCD value, and then testing if indication is + * enabled. + * + * @param[in] p_encoded_data Buffer where the encoded CCCD is stored. + * + * @retval TRUE If indication is enabled. + * @retval FALSE Otherwise. + */ +bool ble_srv_is_indication_enabled(uint8_t const * p_encoded_data); + + +/**@brief Function for encoding a Report Reference Descriptor. + * + * @param[in] p_encoded_buffer The buffer of the encoded data. + * @param[in] p_report_ref Report Reference value to be encoded. + * + * @return Length of the encoded data. + */ +uint8_t ble_srv_report_ref_encode(uint8_t * p_encoded_buffer, + const ble_srv_report_ref_t * p_report_ref); + +/**@brief Function for making a UTF-8 structure refer to an ASCII string. + * + * @param[out] p_utf8 UTF-8 structure to be set. + * @param[in] p_ascii ASCII string to be referred to. + */ +void ble_srv_ascii_to_utf8(ble_srv_utf8_str_t * p_utf8, char * p_ascii); + + +/**@brief Security Access enumeration. + * @details This enumeration gives the possible requirements for accessing a characteristic value. + */ +typedef enum +{ + SEC_NO_ACCESS = 0, /**< Not possible to access. */ + SEC_OPEN = 1, /**< Access open. */ + SEC_JUST_WORKS = 2, /**< Access possible with 'Just Works' security at least. */ + SEC_MITM = 3, /**< Access possible with 'MITM' security at least. */ + SEC_SIGNED = 4, /**< Access possible with 'signed' security at least. */ + SEC_SIGNED_MITM = 5 /**< Access possible with 'signed and MITM' security at least. */ +}security_req_t; + + +/**@brief Characteristic User Descriptor parameters. + * @details This structure contains the parameters for User Descriptor. + */ +typedef struct +{ + uint16_t max_size; /**< Maximum size of the user descriptor*/ + uint16_t size; /**< Size of the user descriptor*/ + uint8_t *p_char_user_desc; /**< User descriptor content, pointer to a UTF-8 encoded string (non-NULL terminated)*/ + bool is_var_len; /**< Indicates if the user descriptor has variable length.*/ + ble_gatt_char_props_t char_props; /**< user descriptor properties.*/ + bool is_defered_read; /**< Indicate if deferred read operations are supported.*/ + bool is_defered_write; /**< Indicate if deferred write operations are supported.*/ + security_req_t read_access; /**< Security requirement for reading the user descriptor.*/ + security_req_t write_access; /**< Security requirement for writing the user descriptor.*/ + bool is_value_user; /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/ +}ble_add_char_user_desc_t; + + +/**@brief Add characteristic parameters structure. + * @details This structure contains the parameters needed to use the @ref characteristic_add function. + */ +typedef struct +{ + uint16_t uuid; /**< Characteristic UUID (16 bits UUIDs).*/ + uint8_t uuid_type; /**< Base UUID. If 0, the Bluetooth SIG UUID will be used. Otherwise, this should be a value returned by @ref sd_ble_uuid_vs_add when adding the base UUID.*/ + uint16_t max_len; /**< Maximum length of the characteristic value.*/ + uint16_t init_len; /**< Initial length of the characteristic value.*/ + uint8_t * p_init_value; /**< Initial encoded value of the characteristic.*/ + bool is_var_len; /**< Indicates if the characteristic value has variable length.*/ + ble_gatt_char_props_t char_props; /**< Characteristic properties.*/ + ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic extended properties.*/ + bool is_defered_read; /**< Indicate if deferred read operations are supported.*/ + bool is_defered_write; /**< Indicate if deferred write operations are supported.*/ + security_req_t read_access; /**< Security requirement for reading the characteristic value.*/ + security_req_t write_access; /**< Security requirement for writing the characteristic value.*/ + security_req_t cccd_write_access; /**< Security requirement for writing the characteristic's CCCD.*/ + bool is_value_user; /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/ + ble_add_char_user_desc_t *p_user_descr; /**< Pointer to user descriptor if needed*/ + ble_gatts_char_pf_t *p_presentation_format; /**< Pointer to characteristic format if needed*/ +} ble_add_char_params_t; + + +/**@brief Add descriptor parameters structure. + * @details This structure contains the parameters needed to use the @ref descriptor_add function. + */ +typedef struct +{ + uint16_t uuid; /**< descriptor UUID (16 bits UUIDs).*/ + uint8_t uuid_type; /**< Base UUID. If 0, the Bluetooth SIG UUID will be used. Otherwise, this should be a value returned by @ref sd_ble_uuid_vs_add when adding the base UUID.*/ + bool is_defered_read; /**< Indicate if deferred read operations are supported.*/ + bool is_defered_write; /**< Indicate if deferred write operations are supported.*/ + bool is_var_len; /**< Indicates if the descriptor value has variable length.*/ + security_req_t read_access; /**< Security requirement for reading the descriptor value.*/ + security_req_t write_access; /**< Security requirement for writing the descriptor value.*/ + bool is_value_user; /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/ + uint16_t init_len; /**< Initial descriptor value length in bytes. */ + uint16_t init_offs; /**< Initial descriptor value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */ + uint16_t max_len; /**< Maximum descriptor value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */ + uint8_t* p_value; /**< Pointer to the value of the descriptor*/ +} ble_add_descr_params_t; + + +/**@brief Function for adding a characteristic to a given service. + * + * If no pointer is given for the initial value, + * the initial length parameter will be ignored and the initial length will be 0. + * + * @param[in] service_handle Handle of the service to which the characteristic is to be added. + * @param[in] p_char_props Information needed to add the characteristic. + * @param[out] p_char_handle Handle of the added characteristic. + * + * @retval NRF_SUCCESS If the characteristic was added successfully. Otherwise, an error code is returned. + */ +uint32_t characteristic_add(uint16_t service_handle, + ble_add_char_params_t * p_char_props, + ble_gatts_char_handles_t * p_char_handle); + + +/**@brief Function for adding a characteristic's descriptor to a given characteristic. + * + * @param[in] char_handle Handle of the characteristic to which the descriptor is to be added, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] p_descr_props Information needed to add the descriptor. + * @param[out] p_descr_handle Handle of the added descriptor. + * + * @retval NRF_SUCCESS If the characteristic was added successfully. Otherwise, an error code is returned. + */ +uint32_t descriptor_add(uint16_t char_handle, + ble_add_descr_params_t * p_descr_props, + uint16_t * p_descr_handle); + + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_SRV_COMMON_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/nrf_ble_gatt/nrf_ble_gatt.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/nrf_ble_gatt/nrf_ble_gatt.c new file mode 100644 index 0000000000000000000000000000000000000000..e39429684661f8fec0d563fbc31ba7a641e96746 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/nrf_ble_gatt/nrf_ble_gatt.c @@ -0,0 +1,539 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" + +#if NRF_BLE_GATT_ENABLED +#include "nrf_ble_gatt.h" +#include "ble_srv_common.h" +#include "sdk_common.h" +#include "app_error.h" +#include "sdk_macros.h" + +#define NRF_LOG_MODULE_NAME "nrf_ble_gatt" +#include "nrf_log.h" + +#define LL_HEADER_LEN 4 //!< Length of a link layer header, in bytes. + + +STATIC_ASSERT(NRF_BLE_GATT_MAX_MTU_SIZE <= 251); +STATIC_ASSERT(NRF_BLE_GATT_MAX_MTU_SIZE + LL_HEADER_LEN <= 255); + + +/**@brief Initialize a link's parameters to defaults. */ +static void link_init(nrf_ble_gatt_link_t * p_link) +{ + p_link->att_mtu_desired = NRF_BLE_GATT_MAX_MTU_SIZE; + p_link->att_mtu_effective = BLE_GATT_ATT_MTU_DEFAULT; + p_link->att_mtu_exchange_pending = false; + p_link->att_mtu_exchange_requested = false; + p_link->data_length_desired = NRF_BLE_GATT_MAX_MTU_SIZE + LL_HEADER_LEN; + p_link->data_length_effective = BLE_GATT_ATT_MTU_DEFAULT + LL_HEADER_LEN; +} + +/**@brief Start a data length update request. + * @details This function is called to request a data length update upon connection. + * When the peer requests a data length update, sd_ble_gap_data_length_update() + * is called directly in response to the BLE_GAP_EVT_DATA_LENGTH_UPDATE event in + * on_data_length_update_evt(). + */ +static void data_length_update(uint16_t conn_handle, nrf_ble_gatt_t const * p_gatt) +{ + NRF_LOG_DEBUG("Requesting to update data length to %u on connection 0x%x.\r\n", + p_gatt->links[conn_handle].data_length_desired, conn_handle); + + ble_gap_data_length_params_t const dlp = + { + .max_rx_octets = p_gatt->links[conn_handle].data_length_desired, + .max_tx_octets = p_gatt->links[conn_handle].data_length_desired, + .max_rx_time_us = BLE_GAP_DATA_LENGTH_AUTO, + .max_tx_time_us = BLE_GAP_DATA_LENGTH_AUTO, + }; + + ret_code_t err_code = sd_ble_gap_data_length_update(conn_handle, &dlp, NULL); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("sd_ble_gap_data_length_update() (request)" + " on connection 0x%x returned unexpected value 0x%x.\r\n", + conn_handle, err_code); + } +} + + +/**@brief Handle a connected event. + * + * @param[in] p_gatt GATT structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_connected_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt) +{ + ret_code_t err_code; + uint16_t conn_handle = p_ble_evt->evt.common_evt.conn_handle; + nrf_ble_gatt_link_t * p_link = &p_gatt->links[conn_handle]; + + // Update the link desired settings to reflect the current global settings. + + p_link->data_length_desired = p_gatt->data_length; + + switch (p_ble_evt->evt.gap_evt.params.connected.role) + { + case BLE_GAP_ROLE_PERIPH: + p_link->att_mtu_desired = p_gatt->att_mtu_desired_periph; + break; + + case BLE_GAP_ROLE_CENTRAL: + p_link->att_mtu_desired = p_gatt->att_mtu_desired_central; + break; + + default: + // Ignore. + break; + } + + // Begin an ATT MTU exchange if necessary. + if (p_link->att_mtu_desired > p_link->att_mtu_effective) + { + NRF_LOG_DEBUG("Requesting to update ATT MTU to %u bytes on connection 0x%x.\r\n", + p_link->att_mtu_desired, conn_handle); + + err_code = sd_ble_gattc_exchange_mtu_request(conn_handle, p_link->att_mtu_desired); + + if (err_code == NRF_SUCCESS) + { + p_link->att_mtu_exchange_requested = true; + } + else if (err_code == NRF_ERROR_BUSY) + { + p_link->att_mtu_exchange_pending = true; + NRF_LOG_DEBUG("sd_ble_gattc_exchange_mtu_request()" + " on connection 0x%x returned busy, will retry.\r\n", conn_handle); + } + else + { + NRF_LOG_ERROR("sd_ble_gattc_exchange_mtu_request()" + " returned unexpected value 0x%x.\r\n", + err_code); + } + } + + // Send a data length update request if necessary. + if (p_link->data_length_desired > p_link->data_length_effective) + { + data_length_update(conn_handle, p_gatt); + } +} + + +static void on_disconnected_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt) +{ + // Reset connection parameters. + link_init(&p_gatt->links[p_ble_evt->evt.gap_evt.conn_handle]); +} + + +/**@brief Handle a BLE_GATTC_EVT_EXCHANGE_MTU_RSP event. + * + * @details The effective ATT MTU is set to the lowest between what we requested and the peer's + * response. This events concludes the ATT MTU exchange. An event is sent to the user + * and a data length update procedure is started if necessary. + * + * @param[in] p_gatt GATT structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_exchange_mtu_rsp_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt) +{ + uint16_t conn_handle = p_ble_evt->evt.gattc_evt.conn_handle; + uint16_t server_rx_mtu = p_ble_evt->evt.gattc_evt.params.exchange_mtu_rsp.server_rx_mtu; + + nrf_ble_gatt_link_t * p_link = &p_gatt->links[conn_handle]; + + // Determine the lowest MTU between our own desired MTU and the peer's. + // The MTU may not be less than BLE_GATT_ATT_MTU_DEFAULT. + p_link->att_mtu_effective = MIN(server_rx_mtu, p_link->att_mtu_desired); + p_link->att_mtu_effective = MAX(p_link->att_mtu_effective, BLE_GATT_ATT_MTU_DEFAULT); + + NRF_LOG_DEBUG("ATT MTU updated to %u bytes on connection 0x%x (response).\r\n", + p_link->att_mtu_effective, conn_handle); + + // Trigger an event indicating that the ATT MTU size has changed. + // Send an event to the application only if an ATT MTU exchange was requested. + if ((p_gatt->evt_handler != NULL) && (p_link->att_mtu_exchange_requested)) + { + nrf_ble_gatt_evt_t const evt = + { + .evt_id = NRF_BLE_GATT_EVT_ATT_MTU_UPDATED, + .conn_handle = conn_handle, + .params.att_mtu_effective = p_link->att_mtu_effective, + }; + + p_gatt->evt_handler(p_gatt, &evt); + } + + p_link->att_mtu_exchange_requested = false; + p_link->att_mtu_exchange_pending = false; +} + + +/**@brief Handle a BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. + * + * @param[in] p_gatt GATT structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_exchange_mtu_request_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt) +{ + ret_code_t err_code; + uint16_t conn_handle = p_ble_evt->evt.gatts_evt.conn_handle; + uint16_t client_mtu = p_ble_evt->evt.gatts_evt.params.exchange_mtu_request.client_rx_mtu; + + nrf_ble_gatt_link_t * p_link = &p_gatt->links[conn_handle]; + + NRF_LOG_DEBUG("Peer on connection 0x%x requested an ATT MTU of %u bytes.\r\n", + conn_handle, client_mtu); + + client_mtu = MAX(client_mtu, BLE_GATT_ATT_MTU_DEFAULT); + p_link->att_mtu_effective = MIN(client_mtu, p_link->att_mtu_desired); + p_link->att_mtu_exchange_pending = false; + + NRF_LOG_DEBUG("Updating ATT MTU to %u bytes (desired: %u) on connection 0x%x.\r\n", + p_link->att_mtu_effective, p_link->att_mtu_desired, conn_handle); + + err_code = sd_ble_gatts_exchange_mtu_reply(conn_handle, p_link->att_mtu_desired); + + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("sd_ble_gatts_exchange_mtu_reply() returned unexpected value 0x%x.\r\n", + err_code); + } + + // If an ATT_MTU exchange was requested to the peer, defer sending + // the data length update request and the event to the application until + // the response for that request is received. + if (p_link->att_mtu_exchange_requested) + { + return; + } + + // The ATT MTU exchange has finished. Send an event to the application. + if (p_gatt->evt_handler != NULL) + { + nrf_ble_gatt_evt_t const evt = + { + .evt_id = NRF_BLE_GATT_EVT_ATT_MTU_UPDATED, + .conn_handle = conn_handle, + .params.att_mtu_effective = p_link->att_mtu_effective, + }; + + p_gatt->evt_handler(p_gatt, &evt); + } +} + + +/**@brief Handle a BLE_GAP_EVT_DATA_LENGTH_UPDATE event. + * + * @details Update the connection data length and send an event to the user. + * + * @param[in] p_gatt GATT structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_data_length_update_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt) +{ + ble_gap_evt_t const gap_evt = p_ble_evt->evt.gap_evt; + uint16_t const conn_handle = gap_evt.conn_handle; + + // Update the connection data length. + p_gatt->links[conn_handle].data_length_effective = + gap_evt.params.data_length_update.effective_params.max_tx_octets; + + NRF_LOG_DEBUG("Data length updated to %u on connection 0x%0x.\r\n", + p_gatt->links[conn_handle].data_length_effective, + conn_handle); + + NRF_LOG_DEBUG("max_rx_octets: %u\r\n", + gap_evt.params.data_length_update.effective_params.max_rx_octets); + NRF_LOG_DEBUG("max_tx_octets: %u\r\n", + gap_evt.params.data_length_update.effective_params.max_tx_octets); + NRF_LOG_DEBUG("max_rx_time: %u\r\n", + gap_evt.params.data_length_update.effective_params.max_rx_time_us); + NRF_LOG_DEBUG("max_tx_time: %u\r\n", + gap_evt.params.data_length_update.effective_params.max_tx_time_us); + + if (p_gatt->evt_handler != NULL) + { + nrf_ble_gatt_evt_t const evt = + { + .evt_id = NRF_BLE_GATT_EVT_DATA_LENGTH_UPDATED, + .conn_handle = conn_handle, + .params.data_length = p_gatt->links[conn_handle].data_length_effective, + }; + + p_gatt->evt_handler(p_gatt, &evt); + } +} + + +/**@brief Handle a BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event. + * + *@details Reply with a sd_ble_gap_data_length_update() call, using the minimum between the + * link's preferred data length, and what requested by the peer. + * The link preferred data length is set to the global preferred data length + * upon connection and can be overridden by calling nrf_ble_gatt_data_length_set(). + * The default is NRF_BLE_GATT_MAX_MTU_SIZE + LL_HEADER_LEN. + * + *@note The SoftDevice will not send any BLE_GAP_EVT_DATA_LENGTH_UPDATE events on this side. + * Therefore, the connection data length is updated immediately and an event is sent + * to the user. + * + * @param[in] p_gatt GATT structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_data_length_update_request_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt) +{ + ret_code_t err_code; + + ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt; + nrf_ble_gatt_link_t * p_link = &p_gatt->links[p_gap_evt->conn_handle]; + + uint8_t const data_length_peer = + p_gap_evt->params.data_length_update_request.peer_params.max_tx_octets; + + NRF_LOG_DEBUG("Peer on connection 0x%x requested a data length of %u bytes.\r\n", + p_gap_evt->conn_handle, data_length_peer); + + uint8_t const data_length = MIN(p_link->data_length_desired, data_length_peer); + + ble_gap_data_length_params_t const dlp = + { + .max_rx_octets = data_length, + .max_tx_octets = data_length, + }; + + NRF_LOG_DEBUG("Updating data length to %u bytes on connection 0x%x.\r\n", + data_length, p_gap_evt->conn_handle); + + err_code = sd_ble_gap_data_length_update(p_gap_evt->conn_handle, &dlp, NULL); + + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("sd_ble_gap_data_length_update() (reply)" + " returned unexpected value 0x%x.\r\n", + err_code); + } +} + + +ret_code_t nrf_ble_gatt_init(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_handler_t evt_handler) +{ + VERIFY_PARAM_NOT_NULL(p_gatt); + + p_gatt->evt_handler = evt_handler; + p_gatt->att_mtu_desired_periph = NRF_BLE_GATT_MAX_MTU_SIZE; + p_gatt->att_mtu_desired_central = NRF_BLE_GATT_MAX_MTU_SIZE; + p_gatt->data_length = NRF_BLE_GATT_MAX_MTU_SIZE + LL_HEADER_LEN; + + for (uint32_t i = 0; i < NRF_BLE_GATT_LINK_COUNT; i++) + { + link_init(&p_gatt->links[i]); + } + + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_gatt_att_mtu_periph_set(nrf_ble_gatt_t * p_gatt, uint16_t desired_mtu) +{ + VERIFY_PARAM_NOT_NULL(p_gatt); + + if ((desired_mtu < BLE_GATT_ATT_MTU_DEFAULT) || (desired_mtu > NRF_BLE_GATT_MAX_MTU_SIZE)) + { + return NRF_ERROR_INVALID_PARAM; + } + + p_gatt->att_mtu_desired_periph = desired_mtu; + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_gatt_att_mtu_central_set(nrf_ble_gatt_t * p_gatt, uint16_t desired_mtu) +{ + VERIFY_PARAM_NOT_NULL(p_gatt); + + if ((desired_mtu < BLE_GATT_ATT_MTU_DEFAULT) || (desired_mtu > NRF_BLE_GATT_MAX_MTU_SIZE)) + { + return NRF_ERROR_INVALID_PARAM; + } + + p_gatt->att_mtu_desired_central = desired_mtu; + return NRF_SUCCESS; +} + + +uint16_t nrf_ble_gatt_eff_mtu_get(nrf_ble_gatt_t const * p_gatt, uint16_t conn_handle) +{ + if ((p_gatt == NULL) || (conn_handle >= NRF_BLE_GATT_LINK_COUNT)) + { + return 0; + } + + return p_gatt->links[conn_handle].att_mtu_effective; +} + + +ret_code_t nrf_ble_gatt_data_length_set(nrf_ble_gatt_t * p_gatt, + uint16_t conn_handle, + uint8_t data_length) +{ + ret_code_t err_code; + + if (p_gatt == NULL) + { + return NRF_ERROR_NULL; + } + + if (conn_handle == BLE_CONN_HANDLE_INVALID) + { + p_gatt->data_length = MIN(data_length, NRF_BLE_GATT_MAX_MTU_SIZE + LL_HEADER_LEN); + return NRF_SUCCESS; + } + + if (conn_handle >= NRF_BLE_GATT_LINK_COUNT) + { + return NRF_ERROR_INVALID_PARAM; + } + + p_gatt->links[conn_handle].data_length_desired = data_length; + + ble_gap_data_length_params_t const dlp = + { + .max_rx_octets = data_length, + .max_tx_octets = data_length, + }; + + err_code = sd_ble_gap_data_length_update(conn_handle, &dlp, NULL); + return err_code; +} + + +ret_code_t nrf_ble_gatt_data_length_get(nrf_ble_gatt_t const * p_gatt, + uint16_t conn_handle, + uint8_t * p_data_length) +{ + if ((p_gatt == NULL) || (p_data_length == NULL)) + { + return NRF_ERROR_NULL; + } + + if (conn_handle == BLE_CONN_HANDLE_INVALID) + { + *p_data_length = p_gatt->data_length; + return NRF_SUCCESS; + } + + if (conn_handle >= NRF_BLE_GATT_LINK_COUNT) + { + return NRF_ERROR_INVALID_PARAM; + } + + *p_data_length = p_gatt->links[conn_handle].data_length_effective; + return NRF_SUCCESS; +} + + +void nrf_ble_gatt_on_ble_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt) +{ + uint16_t conn_handle = p_ble_evt->evt.common_evt.conn_handle; + + if (conn_handle >= NRF_BLE_GATT_LINK_COUNT) + { + return; + } + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connected_evt(p_gatt, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected_evt(p_gatt, p_ble_evt); + break; + + case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: + on_exchange_mtu_rsp_evt(p_gatt, p_ble_evt); + break; + + case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: + on_exchange_mtu_request_evt(p_gatt, p_ble_evt); + break; + + case BLE_GAP_EVT_DATA_LENGTH_UPDATE: + on_data_length_update_evt(p_gatt, p_ble_evt); + break; + + case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: + on_data_length_update_request_evt(p_gatt, p_ble_evt); + break; + + default: + break; + } + + if (p_gatt->links[conn_handle].att_mtu_exchange_pending) + { + ret_code_t err_code; + + err_code = sd_ble_gattc_exchange_mtu_request(conn_handle, + p_gatt->links[conn_handle].att_mtu_desired); + + if (err_code == NRF_SUCCESS) + { + p_gatt->links[conn_handle].att_mtu_exchange_pending = false; + p_gatt->links[conn_handle].att_mtu_exchange_requested = true; + + NRF_LOG_DEBUG("Requesting to update ATT MTU to %u bytes on connection 0x%x (retry).\r\n", + p_gatt->links[conn_handle].att_mtu_desired, conn_handle); + } + else if (err_code != NRF_ERROR_BUSY) + { + NRF_LOG_ERROR("sd_ble_gattc_exchange_mtu_request() returned unexpected value 0x%x.\r\n", + err_code); + } + } +} + +#endif //NRF_BLE_GATT_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/nrf_ble_gatt/nrf_ble_gatt.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/nrf_ble_gatt/nrf_ble_gatt.h new file mode 100644 index 0000000000000000000000000000000000000000..f12a9e37cd89e59b51c7d78cb90b45672a44fd1a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/nrf_ble_gatt/nrf_ble_gatt.h @@ -0,0 +1,265 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup nrf_ble_gatt GATT module + * @{ + * @ingroup ble_sdk_lib + * @brief Module for negotiating and keeping track of GATT connection parameters and updating the data length. + */ + +#ifndef NRF_BLE_GATT_H__ +#define NRF_BLE_GATT_H__ + +#include +#include +#include +#include "ble.h" +#include "app_util.h" +#include "sdk_errors.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Default maximum ATT_MTU size. + * + * This define specifies a fallback value for the case where + * NRF_BLE_GATT_MAX_MTU_SIZE is not set in the @ref nrf_ble_gatt_config. + */ +#ifndef NRF_BLE_GATT_MAX_MTU_SIZE + #if (NRF_SD_BLE_API_VERSION <= 3) + #define NRF_BLE_GATT_MAX_MTU_SIZE GATT_MTU_SIZE_DEFAULT + #else + #define NRF_BLE_GATT_MAX_MTU_SIZE BLE_GATT_ATT_MTU_DEFAULT + #endif +#endif + + +/**@brief Default maximum number of peripheral connections. + * + * To override this default value, define the maximum number of peripheral + * connections in your module. + */ +#ifndef NRF_BLE_CENTRAL_LINK_COUNT + #define NRF_BLE_CENTRAL_LINK_COUNT 1 +#endif + +/**@brief Default maximum number of central connections. + * + * To override this default value, define the maximum number of central + * connections in your module. + */ +#ifndef NRF_BLE_PERIPHERAL_LINK_COUNT + #define NRF_BLE_PERIPHERAL_LINK_COUNT 1 +#endif + +/**@brief The maximum number of peripheral and central connections combined. */ +#define NRF_BLE_GATT_LINK_COUNT (NRF_BLE_PERIPHERAL_LINK_COUNT + NRF_BLE_CENTRAL_LINK_COUNT) + + /**@brief GATT module event types. */ +typedef enum +{ + NRF_BLE_GATT_EVT_ATT_MTU_UPDATED = 0xA77, //!< The ATT_MTU size was updated. + NRF_BLE_GATT_EVT_DATA_LENGTH_UPDATED = 0xDA7A, //!< The data length was updated. +} nrf_ble_gatt_evt_id_t; + +/**@brief GATT module event. */ +typedef struct +{ + nrf_ble_gatt_evt_id_t evt_id; //!< Event ID. + uint16_t conn_handle; //!< Connection handle on which the event happened. + union + { + uint16_t att_mtu_effective; //!< Effective ATT_MTU. + uint8_t data_length; //!< Data length value. + } params; +} nrf_ble_gatt_evt_t; + +// Forward declaration of the nrf_ble_gatt_t type. +typedef struct nrf_ble_gatt_s nrf_ble_gatt_t; + +/**@brief GATT module event handler type. + * + * The GATT module calls a function of this type when a parameter value is changed. + */ +typedef void (*nrf_ble_gatt_evt_handler_t) (nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt); + +/**@brief GATT information for each connection. */ +typedef struct +{ + uint16_t att_mtu_desired; //!< Requested ATT_MTU size (in bytes). + uint16_t att_mtu_effective; //!< Effective ATT_MTU size (in bytes). + bool att_mtu_exchange_pending; //!< Indicates that an ATT_MTU exchange request is pending (the call to @ref sd_ble_gattc_exchange_mtu_request returned @ref NRF_ERROR_BUSY). + bool att_mtu_exchange_requested; //!< Indicates that an ATT_MTU exchange request was made. + uint8_t data_length_desired; //!< Desired data length (in bytes). + uint8_t data_length_effective; //!< Requested data length (in bytes). +} nrf_ble_gatt_link_t; + + +/**@brief GATT structure that contains status information for the GATT module. */ +struct nrf_ble_gatt_s +{ + uint16_t att_mtu_desired_periph; //!< Requested ATT_MTU size for the next peripheral connection that is established. + uint16_t att_mtu_desired_central; //!< Requested ATT_MTU size for the next central connection that is established. + uint8_t data_length; //!< Data length to use for the next connection that is established. + nrf_ble_gatt_link_t links[NRF_BLE_GATT_LINK_COUNT]; //!< GATT related information for all active connections. + nrf_ble_gatt_evt_handler_t evt_handler; //!< GATT event handler. +}; + + +/**@brief Function for initializing the GATT module. + * + * @param[in] evt_handler Event handler. + * @param[out] p_gatt Pointer to the GATT structure. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If @p p_gatt is NULL. + */ +ret_code_t nrf_ble_gatt_init(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_handler_t evt_handler); + + +/**@brief Function for setting the ATT_MTU size for the next connection that is established as peripheral. + * + * @param[in] p_gatt Pointer to the GATT structure. + * @param[in] desired_mtu Requested ATT_MTU size. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If @p p_gatt is NULL. + * @retval NRF_ERROR_INVALID_PARAM If the size of @p desired_mtu is bigger than + * @ref NRF_BLE_GATT_MAX_MTU_SIZE or smaller than + * @ref BLE_GATT_ATT_MTU_DEFAULT. + */ +ret_code_t nrf_ble_gatt_att_mtu_periph_set(nrf_ble_gatt_t * p_gatt, uint16_t desired_mtu); + + +/**@brief Function for setting the ATT_MTU size for the next connection that is established as central. + * + * @param[in,out] p_gatt Pointer to the GATT structure. + * @param[in] desired_mtu Requested ATT_MTU size. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If @p p_gatt is NULL. + * @retval NRF_ERROR_INVALID_PARAM If the size of @p desired_mtu is bigger than + * @ref NRF_BLE_GATT_MAX_MTU_SIZE or smaller + * than @ref BLE_GATT_ATT_MTU_DEFAULT. + */ +ret_code_t nrf_ble_gatt_att_mtu_central_set(nrf_ble_gatt_t * p_gatt, uint16_t desired_mtu); + + +/**@brief Function for setting the data length for a connection. + * + * @details If @p conn_handle is a handle to an existing connection, a data length update + * request is sent on that connection. + * If @p conn_handle is @ref BLE_CONN_HANDLE_INVALID, a data length update request + * is sent on the next connection that is established after the ATT_MTU + * exchange has completed. If no ATT_MTU exchange procedure is carried + * out (for example, if a default ATT_MTU size is used), the data length + * is not changed. + * + * + * @param[in,out] p_gatt Pointer to the GATT structure. + * @param[in] conn_handle The connection for which to set the data length, or + * @ref BLE_CONN_HANDLE_INVALID to set the data length for the + * next connection. + * @param[in] data_length Requested data length. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If @p p_gatt is NULL. + * @retval NRF_ERROR_INVALID_PARAM If @p conn_handle is larger than @ref NRF_BLE_GATT_LINK_COUNT. + */ +ret_code_t nrf_ble_gatt_data_length_set(nrf_ble_gatt_t * p_gatt, + uint16_t conn_handle, + uint8_t data_length); + + +/**@brief Function for retrieving the data length of a connection. + * + * @details If @p conn_handle is @ref BLE_CONN_HANDLE_INVALID, the function retrieves the data + * length that will be requested for the next connection. + * If @p conn_handle is a handle to an existing connection, the function retrieves + * the effective data length that was negotiated for that connection. + * + * @param[in,out] p_gatt Pointer to the GATT structure. + * @param[in] conn_handle The connection for which to retrieve the data length, or + * @ref BLE_CONN_HANDLE_INVALID to retrieve the requested data length + * for the next connection. + * @param[out] p_data_length The connection data length. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If @p p_gatt or @p p_data_length is NULL. + * @retval NRF_ERROR_INVALID_PARAM If @p conn_handle is larger than @ref NRF_BLE_GATT_LINK_COUNT. + */ +ret_code_t nrf_ble_gatt_data_length_get(nrf_ble_gatt_t const * p_gatt, + uint16_t conn_handle, + uint8_t * p_data_length); + + +/**@brief Function for handling BLE stack events. + * + * @details This function handles events from the BLE stack that are of interest to the module. + * + * @param[in] p_gatt Pointer to the GATT structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void nrf_ble_gatt_on_ble_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt); + + +/**@brief Function for getting the current ATT_MTU size for a given connection. + * + * @param[in] p_gatt Pointer to the GATT structure. + * @param[in] conn_handle Connection handle of the connection. + * + * @return ATT_MTU size for the given connection. + * @retval 0 If @p p_gatt is NULL or if @p conn_handle is larger than + * the supported maximum number of connections. + * + */ +uint16_t nrf_ble_gatt_eff_mtu_get(nrf_ble_gatt_t const * p_gatt, uint16_t conn_handle); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_GATT_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/nrf_ble_qwr/nrf_ble_qwr.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/nrf_ble_qwr/nrf_ble_qwr.c new file mode 100644 index 0000000000000000000000000000000000000000..f597f4e43a479c82225167026c1921e436bb754d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/nrf_ble_qwr/nrf_ble_qwr.c @@ -0,0 +1,445 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_BLE_QWR) +#include +#include "nrf_ble_qwr.h" +#include "ble.h" +#include "ble_srv_common.h" + + +#define NRF_BLE_QWR_INITIALIZED 0xDE // Non-zero value used to make sure the given structure has been initialized by the module. +#define MODULE_INITIALIZED (p_qwr->initialized == NRF_BLE_QWR_INITIALIZED) +#include "sdk_macros.h" + +ret_code_t nrf_ble_qwr_init(nrf_ble_qwr_t * p_qwr, + nrf_ble_qwr_init_t const * p_qwr_init) +{ + VERIFY_PARAM_NOT_NULL(p_qwr); + VERIFY_PARAM_NOT_NULL(p_qwr_init); + if (MODULE_INITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + + memset(p_qwr->attr_handles, 0, sizeof(p_qwr->attr_handles)); + p_qwr->nb_registered_attr = 0; + p_qwr->error_handler = p_qwr_init->error_handler; + p_qwr->is_user_mem_reply_pending = false; + p_qwr->conn_handle = BLE_CONN_HANDLE_INVALID; + p_qwr->initialized = NRF_BLE_QWR_INITIALIZED; + p_qwr->mem_buffer = p_qwr_init->mem_buffer; + p_qwr->callback = p_qwr_init->callback; + p_qwr->nb_written_handles = 0; + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_qwr_attr_register(nrf_ble_qwr_t * p_qwr, uint16_t attr_handle) +{ + VERIFY_PARAM_NOT_NULL(p_qwr); + VERIFY_MODULE_INITIALIZED(); + + if (p_qwr->nb_registered_attr == NRF_BLE_QWR_ATTR_LIST_SIZE) + { + return (NRF_ERROR_NO_MEM); + } + + if (attr_handle == BLE_GATT_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_PARAM; + } + + p_qwr->attr_handles[p_qwr->nb_registered_attr] = attr_handle; + p_qwr->nb_registered_attr++; + + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_qwr_value_get(nrf_ble_qwr_t * p_qwr, + uint16_t attr_handle, + uint8_t * p_mem, + uint16_t * p_len) +{ + VERIFY_PARAM_NOT_NULL(p_qwr); + VERIFY_PARAM_NOT_NULL(p_mem); + VERIFY_PARAM_NOT_NULL(p_len); + VERIFY_MODULE_INITIALIZED(); + + uint16_t i = 0; + uint16_t handle = BLE_GATT_HANDLE_INVALID; + uint16_t val_len = 0; + uint16_t val_offset = 0; + uint16_t cur_len = 0; + + do + { + handle = uint16_decode(&(p_qwr->mem_buffer.p_mem[i])); + + if (handle == BLE_GATT_HANDLE_INVALID) + { + break; + } + + i += sizeof(uint16_t); + val_offset = uint16_decode(&(p_qwr->mem_buffer.p_mem[i])); + i += sizeof(uint16_t); + val_len = uint16_decode(&(p_qwr->mem_buffer.p_mem[i])); + i += sizeof(uint16_t); + + if (handle == attr_handle) + { + cur_len = val_offset + val_len; + if (cur_len <= *p_len) + { + memcpy((p_mem + val_offset), &(p_qwr->mem_buffer.p_mem[i]), val_len); + } + else + { + return NRF_ERROR_NO_MEM; + } + } + + i += val_len; + } + while (i < p_qwr->mem_buffer.len); + + *p_len = cur_len; + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_qwr_conn_handle_assign(nrf_ble_qwr_t * p_qwr, + uint16_t conn_handle) +{ + VERIFY_PARAM_NOT_NULL(p_qwr); + VERIFY_MODULE_INITIALIZED(); + p_qwr->conn_handle = conn_handle; + return NRF_SUCCESS; +} + + +/**@brief checks if a user_mem_reply is pending, if so attempts to send it. + * + * @param[in] p_qwr QWR structure. + */ +static void user_mem_reply(nrf_ble_qwr_t * p_qwr) +{ + if (p_qwr->is_user_mem_reply_pending) + { + ret_code_t err_code = sd_ble_user_mem_reply(p_qwr->conn_handle, &p_qwr->mem_buffer); + if (err_code == NRF_SUCCESS) + { + p_qwr->is_user_mem_reply_pending = false; + } + else if (err_code == NRF_ERROR_BUSY) + { + p_qwr->is_user_mem_reply_pending = true; + } + else + { + p_qwr->error_handler(err_code); + } + } +} + + +/**@brief Handle a user memory request event. + * + * @param[in] p_qwr QWR structure. + * @param[in] p_common_evt User_mem_request event to be handled. + */ +static void on_user_mem_request(nrf_ble_qwr_t * p_qwr, + ble_common_evt_t const * p_common_evt) +{ + if (p_common_evt->conn_handle == p_qwr->conn_handle) + { + if (p_common_evt->params.user_mem_request.type == BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES) + { + p_qwr->is_user_mem_reply_pending = true; + user_mem_reply(p_qwr); + } + } +} + + +/**@brief Handle a user memory release event. + * + * @param[in] p_qwr QWR structure. + * @param[in] p_common_evt User_mem_release event to be handled. + */ +static void on_user_mem_release(nrf_ble_qwr_t * p_qwr, + ble_common_evt_t const * p_common_evt) +{ + if (p_common_evt->conn_handle == p_qwr->conn_handle) + { + if (p_common_evt->params.user_mem_release.type == BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES) + { + // Cancel the current operation. + p_qwr->nb_written_handles = 0; + } + } +} + + +/**@brief Handle a prepare write event. + * + * @param[in] p_qwr QWR structure. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_prepare_write(nrf_ble_qwr_t * p_qwr, + ble_gatts_evt_write_t const * p_evt_write) +{ + uint32_t err_code; + ble_gatts_rw_authorize_reply_params_t auth_reply; + memset(&auth_reply, 0, sizeof(auth_reply)); + + auth_reply.params.write.gatt_status = NRF_BLE_QWR_REJ_REQUEST_ERR_CODE; + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + + uint32_t i; + + for (i = 0; i < p_qwr->nb_written_handles; i++) + { + if (p_qwr->written_attr_handles[i] == p_evt_write->handle) + { + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + break; + } + } + + if (auth_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS) + { + for (i = 0; i < p_qwr->nb_registered_attr; i++) + { + if (p_qwr->attr_handles[i] == p_evt_write->handle) + { + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + p_qwr->written_attr_handles[p_qwr->nb_written_handles++] = p_evt_write->handle; + break; + } + } + } + + err_code = sd_ble_gatts_rw_authorize_reply(p_qwr->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + // Cancel the current operation. + p_qwr->nb_written_handles = 0; + + // Report error to application. + p_qwr->error_handler(err_code); + } + +} + + +/**@brief Handle an execute write event. + * + * @param[in] p_qwr QWR structure. + * @param[in] p_evt_write EXEC WRITE event to be handled. + */ +static void on_execute_write(nrf_ble_qwr_t * p_qwr, + ble_gatts_evt_write_t const * p_evt_write) +{ + uint32_t err_code; + ble_gatts_rw_authorize_reply_params_t auth_reply; + memset(&auth_reply, 0, sizeof(auth_reply)); + + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + + if (p_qwr->nb_written_handles == 0) + { + auth_reply.params.write.gatt_status = NRF_BLE_QWR_REJ_REQUEST_ERR_CODE; + err_code = sd_ble_gatts_rw_authorize_reply(p_qwr->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + // Report error to application. + p_qwr->error_handler(err_code); + } + return; + } + + for (uint16_t i = 0; i < p_qwr->nb_written_handles; i++) + { + nrf_ble_qwr_evt_t evt; + uint16_t ret_val; + + evt.evt_type = NRF_BLE_QWR_EVT_AUTH_REQUEST; + evt.attr_handle = p_qwr->written_attr_handles[i]; + ret_val = p_qwr->callback(p_qwr, &evt); + if (ret_val != BLE_GATT_STATUS_SUCCESS) + { + auth_reply.params.write.gatt_status = ret_val; + } + } + + err_code = sd_ble_gatts_rw_authorize_reply(p_qwr->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + // Report error to application. + p_qwr->error_handler(err_code); + } + + // If the execute has not been rejected by any of the registered applications, propagate execute write event to all written handles. */ + if (auth_reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) + { + for (uint16_t i = 0; i < p_qwr->nb_written_handles; i++) + { + nrf_ble_qwr_evt_t evt; + evt.evt_type = NRF_BLE_QWR_EVT_EXECUTE_WRITE; + evt.attr_handle = p_qwr->written_attr_handles[i]; + /*lint -e534 -save "Ignoring return value of function" */ + p_qwr->callback(p_qwr, &evt); + /*lint -restore*/ + + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + } + } + p_qwr->nb_written_handles = 0; +} + + +/**@brief Handle a cancel write event. + * + * @param[in] p_qwr QWR structure. + * @param[in] p_evt_write EXEC WRITE event to be handled. + */ +static void on_cancel_write(nrf_ble_qwr_t * p_qwr, + ble_gatts_evt_write_t const * p_evt_write) +{ + uint32_t err_code; + ble_gatts_rw_authorize_reply_params_t auth_reply; + memset(&auth_reply, 0, sizeof(auth_reply)); + + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + + err_code = sd_ble_gatts_rw_authorize_reply(p_qwr->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + // Report error to application. + p_qwr->error_handler(err_code); + } + p_qwr->nb_written_handles = 0; +} + + +/**@brief Handle a rw_authorize_request event. + * + * @param[in] p_qwr QWR structure. + * @param[in] p_gatts_evt RW_authorize_request event to be handled. + */ +static void on_rw_authorize_request(nrf_ble_qwr_t * p_qwr, + ble_gatts_evt_t const * p_gatts_evt) +{ + if (p_gatts_evt->conn_handle != p_qwr->conn_handle) + { + return; + } + + ble_gatts_evt_rw_authorize_request_t const * p_auth_req = &p_gatts_evt->params.authorize_request; + if (p_auth_req->type != BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + return; + } + + switch (p_auth_req->request.write.op) + { + case BLE_GATTS_OP_PREP_WRITE_REQ: + on_prepare_write(p_qwr, &p_auth_req->request.write); + break; // BLE_GATTS_OP_PREP_WRITE_REQ + + case BLE_GATTS_OP_EXEC_WRITE_REQ_NOW: + on_execute_write(p_qwr, &p_auth_req->request.write); + break; // BLE_GATTS_OP_EXEC_WRITE_REQ_NOW + + case BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL: + on_cancel_write(p_qwr, &p_auth_req->request.write); + break; // BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL + + default: + // No implementation needed. + break; + } +} + + +void nrf_ble_qwr_on_ble_evt(nrf_ble_qwr_t * p_qwr, + ble_evt_t * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_qwr); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + VERIFY_MODULE_INITIALIZED_VOID(); + + if (p_ble_evt->evt.common_evt.conn_handle == p_qwr->conn_handle) + { + user_mem_reply(p_qwr); + } + switch (p_ble_evt->header.evt_id) + { + case BLE_EVT_USER_MEM_REQUEST: + on_user_mem_request(p_qwr, &p_ble_evt->evt.common_evt); + break; // BLE_EVT_USER_MEM_REQUEST + + case BLE_EVT_USER_MEM_RELEASE: + on_user_mem_release(p_qwr, &p_ble_evt->evt.common_evt); + break; // BLE_EVT_USER_MEM_REQUEST + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + on_rw_authorize_request(p_qwr, &p_ble_evt->evt.gatts_evt); + break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST + + case BLE_GAP_EVT_DISCONNECTED: + if (p_ble_evt->evt.gap_evt.conn_handle == p_qwr->conn_handle) + { + p_qwr->conn_handle = BLE_CONN_HANDLE_INVALID; + p_qwr->nb_written_handles = 0; + } + break; // BLE_GAP_EVT_DISCONNECTED + + default: + break; + } + +} +#endif // NRF_MODULE_ENABLED(NRF_BLE_QWR) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/nrf_ble_qwr/nrf_ble_qwr.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/nrf_ble_qwr/nrf_ble_qwr.h new file mode 100644 index 0000000000000000000000000000000000000000..dc307c943aba7c1f59c1d04e2665abe2e77dc87d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/nrf_ble_qwr/nrf_ble_qwr.h @@ -0,0 +1,219 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup nrf_ble_qwr Queued Writes module + * @{ + * @ingroup ble_sdk_lib + * @brief Module for handling Queued Write operations. + * + * @details This module handles prepare write, execute write, and cancel write + * commands. It also manages memory requests related to these operations. + * + * @note The application must propagate BLE stack events to this module by calling + * @ref nrf_ble_qwr_on_ble_evt(). + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NRF_BLE_QUEUED_WRITES_H__ +#define NRF_BLE_QUEUED_WRITES_H__ + +#include +#include "nordic_common.h" +#include "sdk_common.h" +#include "ble.h" +#include "ble_srv_common.h" + +#ifndef NRF_BLE_QWR_ATTR_LIST_SIZE +#define NRF_BLE_QWR_ATTR_LIST_SIZE 10 //!< Maximum number of attribute handles that can be registered. This number must be adjusted according to the number of attributes for which Queued Writes will be enabled. +#endif + +#define NRF_BLE_QWR_REJ_REQUEST_ERR_CODE BLE_GATT_STATUS_ATTERR_APP_BEGIN + 0 //!< Error code used by the module to reject prepare write requests on non-registered attributes. + +/**@brief Queued Writes module event types. */ +typedef enum +{ + NRF_BLE_QWR_EVT_EXECUTE_WRITE, //!< Event that indicates that an execute write command was received for a registered handle and that the received data was actually written and is now ready. + NRF_BLE_QWR_EVT_AUTH_REQUEST, //!< Event that indicates that an execute write command was received for a registered handle and that the write request must now be accepted or rejected. +} nrf_ble_qwr_evt_type_t; + + +/**@brief Queued Writes module events. */ +typedef struct +{ + nrf_ble_qwr_evt_type_t evt_type; //!< Type of the event. + uint16_t attr_handle; //!< Handle of the attribute to which the event relates. +} nrf_ble_qwr_evt_t; + + +// Forward declaration of the nrf_ble_qwr_t type. +struct nrf_ble_qwr_t; + +/**@brief Queued Writes module event handler type. + * + * If the provided event is of type @ref NRF_BLE_QWR_EVT_AUTH_REQUEST, + * this function must accept or reject the execute write request by returning + * one of the @ref BLE_GATT_STATUS_CODES.*/ +typedef uint16_t (* nrf_ble_qwr_evt_handler_t) (struct nrf_ble_qwr_t * p_qwr, + nrf_ble_qwr_evt_t * p_evt); + + +/**@brief Queued Writes structure. + * @details This structure contains status information for the Queued Writes module. */ +typedef struct nrf_ble_qwr_t +{ + uint8_t initialized; //!< Flag that indicates whether the module has been initialized. + uint16_t attr_handles[NRF_BLE_QWR_ATTR_LIST_SIZE]; //!< List of handles for registered attributes, for which the module accepts and handles prepare write operations. + uint8_t nb_registered_attr; //!< Number of registered attributes. + uint16_t written_attr_handles[NRF_BLE_QWR_ATTR_LIST_SIZE]; //!< List of attribute handles that have been written to during the current prepare write or execute write operation. + uint8_t nb_written_handles; //!< Number of attributes that have been written to during the current prepare write or execute write operation. + ble_user_mem_block_t mem_buffer; //!< Memory buffer that is provided to the SoftDevice on an ON_USER_MEM_REQUEST event. + ble_srv_error_handler_t error_handler; //!< Error handler. + bool is_user_mem_reply_pending; //!< Flag that indicates whether a mem_reply is pending (because a previous attempt returned busy). + uint16_t conn_handle; //!< Connection handle. + nrf_ble_qwr_evt_handler_t callback; //!< Event handler function that is called for events concerning the handles of all registered attributes. +} nrf_ble_qwr_t; + + +/**@brief Queued Writes init structure. + * @details This structure contains all information + * that is needed to initialize the Queued Writes module. */ +typedef struct +{ + ble_srv_error_handler_t error_handler; //!< Error handler. + ble_user_mem_block_t mem_buffer; //!< Memory buffer that is provided to the SoftDevice on an ON_USER_MEM_REQUEST event. + nrf_ble_qwr_evt_handler_t callback; //!< Event handler function that is called for events concerning the handles of all registered attributes. +} nrf_ble_qwr_init_t; + + +/**@brief Function for initializing the Queued Writes module. + * + * @details Call this function in the main entry of your application to + * initialize the Queued Writes module. It must be called only once with a + * given Queued Writes structure. + * + * @param[out] p_qwr Queued Writes structure. This structure must be + * supplied by the application. It is initialized by this function + * and is later used to identify the particular Queued Writes instance. + * @param[in] p_qwr_init Initialization structure. + * + * @retval NRF_SUCCESS If the Queued Writes module was initialized successfully. + * @retval NRF_ERROR_NULL If any of the given pointers is NULL. + * @retval NRF_ERROR_INVALID_STATE If the given context has already been initialized. + */ +ret_code_t nrf_ble_qwr_init(nrf_ble_qwr_t * p_qwr, + nrf_ble_qwr_init_t const * p_qwr_init); + + +/**@brief Function for registering an attribute with the Queued Writes module. + * + * @details Call this function for each attribute that you want to enable for + * Queued Writes (thus a series of prepare write and execute write operations). + * + * @param[in] p_qwr Queued Writes structure. + * @param[in] attr_handle Handle of the attribute to register. + * + * @retval NRF_SUCCESS If the registration was successful. + * @retval NRF_ERROR_NO_MEM If no more memory is available to add this registration. + * @retval NRF_ERROR_NULL If any of the given pointers is NULL. + * @retval NRF_ERROR_INVALID_STATE If the given context has not been initialized. + */ +ret_code_t nrf_ble_qwr_attr_register(nrf_ble_qwr_t * p_qwr, uint16_t attr_handle); + + +/**@brief Function for handling BLE stack events. + * + * @details Handles all events from the BLE stack that are of interest to the Queued Writes module. + * + * @param[in] p_qwr Queued Writes structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void nrf_ble_qwr_on_ble_evt(nrf_ble_qwr_t * p_qwr, ble_evt_t * p_ble_evt); + + +/**@brief Function for retrieving the received data for a given attribute. + * + * @details Call this function after receiving an @ref NRF_BLE_QWR_EVT_AUTH_REQUEST + * event to retrieve a linear copy of the data that was received for the given attribute. + * + * @param[in] p_qwr Queued Writes structure. + * @param[in] attr_handle Handle of the attribute. + * @param[out] p_mem Pointer to the application buffer where the received data will be copied. + * @param[in,out] p_len Input: length of the input buffer. Output: length of the received data. + * + * + * @retval NRF_SUCCESS If the data was retrieved and stored successfully. + * @retval NRF_ERROR_NO_MEM If the provided buffer was smaller than the received data. + * @retval NRF_ERROR_NULL If any of the given pointers is NULL. + * @retval NRF_ERROR_INVALID_STATE If the given context has not been initialized. + */ +ret_code_t nrf_ble_qwr_value_get(nrf_ble_qwr_t * p_qwr, + uint16_t attr_handle, + uint8_t * p_mem, + uint16_t * p_len); + + +/**@brief Function for assigning a connection handle to a given instance of the Queued Writes module. + * + * @details Call this function when a link with a peer has been established to + * associate this link to the instance of the module. This makes it + * possible to handle several links and associate each link to a particular + * instance of this module. + * + * @param[in] p_qwr Queued Writes structure. + * @param[in] conn_handle Connection handle to be associated with the given Queued Writes instance. + * + * @retval NRF_SUCCESS If the assignment was successful. + * @retval NRF_ERROR_NULL If any of the given pointers is NULL. + * @retval NRF_ERROR_INVALID_STATE If the given context has not been initialized. + */ +ret_code_t nrf_ble_qwr_conn_handle_assign(nrf_ble_qwr_t * p_qwr, + uint16_t conn_handle); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_QUEUED_WRITES_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/gatt_cache_manager.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/gatt_cache_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..90de78666e4201d43aedb350eac9bfc73112db63 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/gatt_cache_manager.c @@ -0,0 +1,561 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) +#include "gatt_cache_manager.h" + +#include "ble_gap.h" +#include "ble_conn_state.h" +#include "peer_manager_types.h" +#include "peer_manager_internal.h" +#include "id_manager.h" +#include "security_dispatcher.h" +#include "gatts_cache_manager.h" + + +// The number of registered event handlers. +#define GCM_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0])) + +// GATT Cache Manager event handler in Peer Manager. +extern void pm_gcm_evt_handler(gcm_evt_t const * p_gcm_evt); + +// GATT Cache Manager events' handlers. +// The number of elements in this array is GCM_EVENT_HANDLERS_CNT. +static gcm_evt_handler_t m_evt_handlers[] = +{ + pm_gcm_evt_handler +}; + +static bool m_module_initialized; +static ble_conn_state_user_flag_id_t m_flag_local_db_update_pending; /**< Flag ID for flag collection to keep track of which connections need a local DB update procedure. */ +static ble_conn_state_user_flag_id_t m_flag_local_db_apply_pending; /**< Flag ID for flag collection to keep track of which connections need a local DB apply procedure. */ +static ble_conn_state_user_flag_id_t m_flag_service_changed_pending; /**< Flag ID for flag collection to keep track of which connections need to be sent a service changed indication. */ +static ble_conn_state_user_flag_id_t m_flag_service_changed_sent; /**< Flag ID for flag collection to keep track of which connections have been sent a service changed indication and are waiting for a handle value confirmation. */ + + +static void service_changed_pending_flags_check(void); + + +/**@brief Function for resetting the module variable(s) of the GSCM module. + * + * @param[out] The instance to reset. + */ +static void internal_state_reset() +{ + m_module_initialized = false; +} + + +static void evt_send(gcm_evt_t const * p_gcm_evt) +{ + for (uint32_t i = 0; i < GCM_EVENT_HANDLERS_CNT; i++) + { + m_evt_handlers[i](p_gcm_evt); + } +} + + +/**@brief Function for checking a write event for whether a CCCD was written during the write + * operation. + * + * @param[in] p_write_evt The parameters of the write event. + * + * @return Whether the write was on a CCCD. + */ +static bool cccd_written(ble_gatts_evt_write_t * p_write_evt) +{ + return ( (p_write_evt->op == BLE_GATTS_OP_WRITE_REQ) + && (p_write_evt->uuid.type == BLE_UUID_TYPE_BLE) + && (p_write_evt->uuid.uuid == BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG) + ); +} + + +/**@brief Function for performing the local DB update procedure in an event context, where no return + * code can be given. + * + * @details This function will do the procedure, and check the result, set a flag if needed, and + * send an event if needed. + * + * @param[in] conn_handle The connection to perform the procedure on. + */ +static void local_db_apply_in_evt(uint16_t conn_handle) +{ + bool set_procedure_as_pending = false; + ret_code_t err_code; + gcm_evt_t event; + + if (conn_handle == BLE_CONN_HANDLE_INVALID) + { + return; + } + + err_code = gscm_local_db_cache_apply(conn_handle); + + switch (err_code) + { + case NRF_SUCCESS: + event.evt_id = GCM_EVT_LOCAL_DB_CACHE_APPLIED; + event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); + event.params.local_db_cache_applied.conn_handle = conn_handle; + + evt_send(&event); + break; + + case NRF_ERROR_BUSY: + set_procedure_as_pending = true; + break; + + case NRF_ERROR_INVALID_DATA: + event.evt_id = GCM_EVT_ERROR_LOCAL_DB_CACHE_APPLY; + event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); + event.params.error_local_db_cache_apply.conn_handle = conn_handle; + + evt_send(&event); + break; + + case BLE_ERROR_INVALID_CONN_HANDLE: + /* Do nothing */ + break; + + default: + event.evt_id = GCM_EVT_ERROR_UNEXPECTED; + event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); + event.params.error_unexpected.conn_handle = conn_handle; + event.params.error_unexpected.error = err_code; + + evt_send(&event); + break; + } + + ble_conn_state_user_flag_set(conn_handle, m_flag_local_db_apply_pending, set_procedure_as_pending); +} + + +/**@brief Function for performing the local DB apply procedure in an event context, where no return + * code can be given. + * + * @details This function will do the procedure, and check the result, set a flag if needed, and + * send an event if needed. + * + * @param[in] conn_handle The connection to perform the procedure on. + */ +static void local_db_update_in_evt(uint16_t conn_handle) +{ + gcm_evt_t event; + bool set_procedure_as_pending = false; + ret_code_t err_code = gscm_local_db_cache_update(conn_handle); + + switch (err_code) + { + case NRF_SUCCESS: + event.evt_id = GCM_EVT_LOCAL_DB_CACHE_UPDATED; + event.params.local_db_cache_applied.conn_handle = conn_handle; + event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); + + evt_send(&event); + break; + + case BLE_ERROR_INVALID_CONN_HANDLE: + /* Do nothing */ + break; + + case NRF_ERROR_BUSY: + set_procedure_as_pending = true; + break; + + case NRF_ERROR_DATA_SIZE: + event.evt_id = GCM_EVT_ERROR_DATA_SIZE; + event.params.error_data_size.conn_handle = conn_handle; + event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); + + evt_send(&event); + break; + + case NRF_ERROR_STORAGE_FULL: + event.evt_id = GCM_EVT_ERROR_STORAGE_FULL; + event.params.error_no_mem.conn_handle = conn_handle; + event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); + + evt_send(&event); + break; + + default: + event.evt_id = GCM_EVT_ERROR_UNEXPECTED; + event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); + event.params.error_unexpected.conn_handle = conn_handle; + event.params.error_unexpected.error = err_code; + + evt_send(&event); + break; + } + + ble_conn_state_user_flag_set(conn_handle, m_flag_local_db_update_pending, set_procedure_as_pending); +} + + +/**@brief Function for sending a service changed indication in an event context, where no return + * code can be given. + * + * @details This function will do the procedure, and check the result, set a flag if needed, and + * send an event if needed. + * + * @param[in] conn_handle The connection to perform the procedure on. + */ +static void service_changed_send_in_evt(uint16_t conn_handle) +{ + gcm_evt_t event; + bool sc_pending_state = true; + bool sc_sent_state = false; + ret_code_t err_code = gscm_service_changed_ind_send(conn_handle); + + switch (err_code) + { + case NRF_SUCCESS: + sc_sent_state = true; + + event.evt_id = GCM_EVT_SERVICE_CHANGED_IND_SENT; + event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); + event.params.service_changed_ind_sent.conn_handle = conn_handle; + + evt_send(&event); + break; + + case NRF_ERROR_BUSY: + // Do nothing. + break; + + case NRF_ERROR_INVALID_STATE: + // CCCDs not enabled. Drop indication. + // Fallthrough. + + case NRF_ERROR_NOT_SUPPORTED: + // Service changed not supported. Drop indication. + sc_pending_state = false; + gscm_db_change_notification_done(im_peer_id_get_by_conn_handle(conn_handle)); + break; + + case BLE_ERROR_GATTS_SYS_ATTR_MISSING: + local_db_apply_in_evt(conn_handle); + break; + + case BLE_ERROR_INVALID_CONN_HANDLE: + // Do nothing. + break; + + default: + event.evt_id = GCM_EVT_ERROR_UNEXPECTED; + event.params.error_unexpected.conn_handle = conn_handle; + event.params.error_unexpected.error = err_code; + event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); + + evt_send(&event); + break; + } + + ble_conn_state_user_flag_set(conn_handle, m_flag_service_changed_pending, sc_pending_state); + ble_conn_state_user_flag_set(conn_handle, m_flag_service_changed_sent, sc_sent_state); +} + + +/**@brief Callback function for events from the GATT Cache Server Manager module. + * This handler is extern in GATTS Cache Manager module. + * + * @param[in] p_event The event from the GATT Cache Server Manager module. + */ +void gcm_gscm_evt_handler(gscm_evt_t const * p_event) +{ + gcm_evt_t event; + event.peer_id = p_event->peer_id; + + switch (p_event->evt_id) + { + case GSCM_EVT_LOCAL_DB_CACHE_STORED: + event.evt_id = GCM_EVT_LOCAL_DB_CACHE_STORED; + + evt_send(&event); + local_db_apply_in_evt(im_conn_handle_get(p_event->peer_id)); + break; + + case GSCM_EVT_LOCAL_DB_CACHE_UPDATED: + event.evt_id = GCM_EVT_LOCAL_DB_CACHE_UPDATED; + event.params.local_db_cache_updated.conn_handle = p_event->params.local_db_cache_updated.conn_handle; + + evt_send(&event); + break; + + case GSCM_EVT_SC_STATE_STORED: + if (p_event->params.sc_state_stored.state) + { + uint16_t conn_handle = im_conn_handle_get(p_event->peer_id); + if (conn_handle != BLE_CONN_HANDLE_INVALID) + { + ble_conn_state_user_flag_set(conn_handle, m_flag_service_changed_pending, true); + service_changed_pending_flags_check(); + } + } + break; + } +} + + +/**@brief Callback function for events from the ID Manager module. + * This function is registered in the ID Manager module. + * + * @param[in] p_event The event from the ID Manager module. + */ +void gcm_im_evt_handler(im_evt_t const * p_event) +{ + switch (p_event->evt_id) + { + case IM_EVT_BONDED_PEER_CONNECTED: + local_db_apply_in_evt(p_event->conn_handle); + if (gscm_service_changed_ind_needed(p_event->conn_handle)) + { + ble_conn_state_user_flag_set(p_event->conn_handle, m_flag_service_changed_pending, true); + } + break; + default: + break; + } +} + + +/**@brief Callback function for events from the Security Dispatcher module. + * This handler is extern in Security Dispatcher. + * + * @param[in] p_event The event from the Security Dispatcher module. + */ +void gcm_smd_evt_handler(smd_evt_t const * p_event) +{ + switch (p_event->evt_id) + { + case SMD_EVT_BONDING_INFO_STORED: + local_db_update_in_evt(p_event->conn_handle); + break; + default: + break; + } +} + + +ret_code_t gcm_init() +{ + NRF_PM_DEBUG_CHECK(!m_module_initialized); + + internal_state_reset(); + + m_flag_local_db_update_pending = ble_conn_state_user_flag_acquire(); + m_flag_local_db_apply_pending = ble_conn_state_user_flag_acquire(); + m_flag_service_changed_pending = ble_conn_state_user_flag_acquire(); + m_flag_service_changed_sent = ble_conn_state_user_flag_acquire(); + + if ((m_flag_local_db_update_pending == BLE_CONN_STATE_USER_FLAG_INVALID) + || (m_flag_local_db_apply_pending == BLE_CONN_STATE_USER_FLAG_INVALID) + || (m_flag_service_changed_pending == BLE_CONN_STATE_USER_FLAG_INVALID) + || (m_flag_service_changed_sent == BLE_CONN_STATE_USER_FLAG_INVALID)) + { + return NRF_ERROR_INTERNAL; + } + + m_module_initialized = true; + + return NRF_SUCCESS; +} + + +// @todo emdi: apply_pending_flags_check() and update_pending_flags_check() should really be +// refactored into one function.. + +/**@brief Function for performing the Local DB apply procedure if it is pending on any connections. + */ +static void apply_pending_flags_check(void) +{ + sdk_mapped_flags_t apply_pending_flags; + + apply_pending_flags = ble_conn_state_user_flag_collection(m_flag_local_db_apply_pending); + if (sdk_mapped_flags_any_set(apply_pending_flags)) + { + sdk_mapped_flags_key_list_t conn_handle_list; + conn_handle_list = ble_conn_state_conn_handles(); + + for (uint32_t i = 0; i < conn_handle_list.len; i++) + { + if (ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_flag_local_db_apply_pending)) + { + local_db_apply_in_evt(conn_handle_list.flag_keys[i]); + } + } + } +} + + +/**@brief Function for performing the Local DB update procedure if it is pending on any connections. + */ +static void update_pending_flags_check(void) +{ + sdk_mapped_flags_t update_pending_flags; + + update_pending_flags = ble_conn_state_user_flag_collection(m_flag_local_db_update_pending); + if (sdk_mapped_flags_any_set(update_pending_flags)) + { + sdk_mapped_flags_key_list_t conn_handle_list; + conn_handle_list = ble_conn_state_conn_handles(); + + for (uint32_t i = 0; i < conn_handle_list.len; i++) + { + if (ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_flag_local_db_update_pending)) + { + local_db_update_in_evt(conn_handle_list.flag_keys[i]); + } + } + } +} + + +/**@brief Function for sending service changed indications if it is pending on any connections. + */ +static void service_changed_pending_flags_check(void) +{ + sdk_mapped_flags_t service_changed_pending_flags; + + service_changed_pending_flags = ble_conn_state_user_flag_collection(m_flag_service_changed_pending); + if (sdk_mapped_flags_any_set(service_changed_pending_flags)) + { + sdk_mapped_flags_key_list_t conn_handle_list; + conn_handle_list = ble_conn_state_conn_handles(); + + for (uint32_t i = 0; i < conn_handle_list.len; i++) + { + if ( ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], + m_flag_service_changed_pending) + && !ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], + m_flag_service_changed_sent)) + { + service_changed_send_in_evt(conn_handle_list.flag_keys[i]); + } + } + } +} + + +/**@brief Callback function for BLE events from the SoftDevice. + * + * @param[in] p_ble_evt The BLE event from the SoftDevice. + */ +void gcm_ble_evt_handler(ble_evt_t * p_ble_evt) +{ + gcm_evt_t event; + + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTS_EVT_SYS_ATTR_MISSING: + local_db_apply_in_evt(p_ble_evt->evt.gatts_evt.conn_handle); + break; + + case BLE_GATTS_EVT_SC_CONFIRM: + event.evt_id = GCM_EVT_SERVICE_CHANGED_IND_CONFIRMED; + event.peer_id = im_peer_id_get_by_conn_handle(p_ble_evt->evt.gatts_evt.conn_handle); + event.params.service_changed_ind_sent.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle; + + gscm_db_change_notification_done(event.peer_id); + ble_conn_state_user_flag_set(p_ble_evt->evt.gatts_evt.conn_handle, m_flag_service_changed_pending, false); + + evt_send(&event); + break; + + case BLE_GATTS_EVT_WRITE: + if (cccd_written(&p_ble_evt->evt.gatts_evt.params.write)) + { + local_db_update_in_evt(p_ble_evt->evt.gatts_evt.conn_handle); + } + break; + } + + apply_pending_flags_check(); + update_pending_flags_check(); + service_changed_pending_flags_check(); +} + + +ret_code_t gcm_local_db_cache_update(uint16_t conn_handle) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + ret_code_t err_code = gscm_local_db_cache_update(conn_handle); + bool set_procedure_as_pending = false; + + if (err_code == NRF_ERROR_BUSY) + { + set_procedure_as_pending = true; + err_code = NRF_SUCCESS; + } + + ble_conn_state_user_flag_set(conn_handle, m_flag_local_db_update_pending, set_procedure_as_pending); + + return err_code; +} + + +ret_code_t gcm_local_db_cache_set(pm_peer_id_t peer_id, pm_peer_data_local_gatt_db_t * p_local_db) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + return gscm_local_db_cache_set(peer_id, p_local_db); +} + + +void gcm_local_database_has_changed(void) +{ + gscm_local_database_has_changed(); + + sdk_mapped_flags_key_list_t conn_handles = ble_conn_state_conn_handles(); + + for (uint16_t i = 0; i < conn_handles.len; i++) + { + if (im_peer_id_get_by_conn_handle(conn_handles.flag_keys[i]) == PM_PEER_ID_INVALID) + { + ble_conn_state_user_flag_set(conn_handles.flag_keys[i], m_flag_service_changed_pending, true); + } + } + + service_changed_pending_flags_check(); +} +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/gatt_cache_manager.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/gatt_cache_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..9a49043d37181b88e2da6d00854dfda797b5a4ec --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/gatt_cache_manager.h @@ -0,0 +1,242 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef GATT_CACHE_MANAGER_H__ +#define GATT_CACHE_MANAGER_H__ + +#include +#include "sdk_errors.h" +#include "ble.h" +#include "ble_gap.h" +#include "peer_manager_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/** + * @cond NO_DOXYGEN + * @defgroup gatt_cache_manager GATT Cache Manager + * @ingroup peer_manager + * @{ + * @brief An internal module of @ref peer_manager. A module for managing persistent storing of GATT + * attributes. + */ + + +/**@brief Events that can come from the GATT Cache Manager module. + */ +typedef enum +{ + GCM_EVT_LOCAL_DB_CACHE_STORED, /**< The persistent cache for the local database has been updated with provided values, for one peer. */ + GCM_EVT_LOCAL_DB_CACHE_UPDATED, /**< The persistent cache for the local database has been updated with values from the SoftDevice, for one peer. */ + GCM_EVT_LOCAL_DB_CACHE_APPLIED, /**< The SoftDevice has been given local database values from the persistent cache, for one peer. */ + GCM_EVT_ERROR_LOCAL_DB_CACHE_APPLY, /**< The stored local database values for a peer were rejected by the SoftDevice, which means the database has changed. */ + GCM_EVT_REMOTE_DB_CACHE_UPDATED, /**< The persistent cache for the remote database has been updated with provided values, for one peer. */ + GCM_EVT_SERVICE_CHANGED_IND_SENT, /**< A service changed indication has been sent to a peer. */ + GCM_EVT_SERVICE_CHANGED_IND_CONFIRMED, /**< A sent service changed indication has been confirmed by a peer. */ + GCM_EVT_ERROR_DATA_SIZE, /**< An operation failed because the write buffer of the Peer Database module was not large enough. This is a fatal error. */ + GCM_EVT_ERROR_STORAGE_FULL, /**< An operation failed because there was no available storage room in persistent storage. Please free up room, and the operation will automatically continue. */ + GCM_EVT_ERROR_UNEXPECTED, /**< An operation failed with an unexpected error. The error is provided. This is possibly a fatal error. */ +} gcm_evt_id_t; + + +/**@brief A structure meant to be used for event parameters for multiple event types. + */ +typedef struct +{ + uint16_t conn_handle; /**< The connection handle. Likely the connection handle an event pertains to. */ +} gcm_evt_param_conn_handle_t; + + +/**@brief Structure containing an event from the GCM module. + */ +typedef struct +{ + gcm_evt_id_t evt_id; /**< The type of event this is. */ + pm_peer_id_t peer_id; /**< The peer ID this event pertains to. */ + union + { + gcm_evt_param_conn_handle_t local_db_cache_updated; + gcm_evt_param_conn_handle_t local_db_cache_applied; + gcm_evt_param_conn_handle_t error_local_db_cache_apply; + gcm_evt_param_conn_handle_t service_changed_ind_sent; + gcm_evt_param_conn_handle_t service_changed_ind_confirmed; + gcm_evt_param_conn_handle_t error_data_size; + gcm_evt_param_conn_handle_t error_no_mem; + struct + { + uint16_t conn_handle; /**< The handle of the connection the event pertains to. */ + ret_code_t error; /**< The unexpected error that occurred. */ + } error_unexpected; + } params; /**< Event specific parameters. Chosen based on evt_id. */ +} gcm_evt_t; + +/**@brief Event handler for events from the GATT Cache Manager module. + * + * @param[in] event The event that has happened. + * @param[in] peer The id of the peer the event pertains to. + * @param[in] flags The data the event pertains to. + */ +typedef void (*gcm_evt_handler_t)(gcm_evt_t const * p_event); + + +/**@brief Function for initializing the GATT Cache Manager module. + * + * @retval NRF_SUCCESS Initialization was successful. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t gcm_init(void); + + +/**@brief Function for dispatching SoftDevice events to the GATT Cache Manager module. + * + * @param[in] p_ble_evt The SoftDevice event. + */ +void gcm_ble_evt_handler(ble_evt_t * p_ble_evt); + + + +/**@brief Function for storing a discovered remote database persistently. + * + * @param[in] peer_id Peer to store the database for. + * @param[in] p_remote_db Database values to store as an array. Can be NULL if n_services is 0. + * @param[in] n_services Number of services in p_remote_db array. If 0, values are cleared. + * + * @retval NRF_SUCCESS Store procedure successfully started. + * @retval NRF_ERROR_NOT_FOUND The peer id is invalid or unallocated. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + */ +ret_code_t gcm_remote_db_store(pm_peer_id_t peer_id, + ble_gatt_db_srv_t * p_remote_db, + uint32_t n_services); + + +/**@brief Function for retrieving a persistently stored remote database. + * + * @param[in] peer_id Peer to retrieve data for. + * @param[out] p_remote_db If p_n_services was large enough: Copied database values. + * @param[inout] p_n_services In: Size of provided p_remote_db array. Out: Size of data in flash. + * + * @note p_n_services is always updated with the size of the data to be retrieved. The data is only + * copied if p_remote_db is large enough (p_n_services is large enough initially). + * + * @retval NRF_SUCCESS Data retrieved successfully. + * @retval NRF_ERROR_NOT_FOUND The peer ID is invalid or unallocated. + * @retval NRF_ERROR_NULL p_remote_db is NULL. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + */ +ret_code_t gcm_remote_db_retrieve(pm_peer_id_t peer_id, + ble_gatt_db_srv_t * p_remote_db, + uint32_t * p_n_services); + + +/**@brief Function for triggering local GATT database data to be stored persistently. Values are + * retrieved from SoftDevice and written to persistent storage. + * + * @note This function is only needed when you want to override the regular functionality of the + * module, e.g. to immediately store to flash instead of waiting for the native logic to + * perform the update. + * + * @param[in] conn_handle Connection handle to perform update on. + * + * @retval NRF_SUCCESS Store operation started. + * @retval BLE_ERROR_INVALID_CONN_HANDLE conn_handle does not refer to an active, bonded connection. + * @retval NRF_ERROR_DATA_SIZE Write buffer not large enough. Call will never work with + * this GATT database. + * @retval NRF_ERROR_STORAGE_FULL No room in persistent_storage. Free up space; the + * operation will be automatically reattempted after the + * next FDS garbage collection procedure. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + */ +ret_code_t gcm_local_db_cache_update(uint16_t conn_handle); + + +/**@brief Function for setting new values in the local database cache. + * + * @note If the peer is connected, the values will also be applied immediately to the connection. + * @note This function is only needed when you want to override the regular functionality of the + * module. + * @note The data in the pointer must be available until the GCM_EVT_LOCAL_DB_CACHE_SET event is + * received. + * + * @param[in] peer_id Peer to set values for. + * @param[in] p_local_db Database values to apply. If NULL, the values will instead be cleared. + * + * @retval NRF_SUCCESS Operation started, and values were applied (if connected). + * @retval NRF_ERROR_NOT_FOUND The peer ID was invalid or unallocated. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + */ +ret_code_t gcm_local_db_cache_set(pm_peer_id_t peer_id, pm_peer_data_local_gatt_db_t * p_local_db); + + +/**@brief Function for retrieving values in the local database cache. + * + * @note This function is not needed for regular operation of the module. + * + * @param[in] peer_id Peer to get values for. + * @param[out] p_local_db Database values. + * + * @retval NRF_SUCCESS Values retrieved successfully. + * @retval NRF_ERROR_NOT_FOUND The peer ID was invalid or unallocated. + * @retval NRF_ERROR_NULL p_local_db was NULL. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + */ +ret_code_t gcm_local_db_cache_get(pm_peer_id_t peer_id, pm_peer_data_local_gatt_db_t * p_local_db); + + +/**@brief Function for manually informing that the local database has changed. + * + * @details This causes a service changed notification to be sent to all bonded peers that + * subscribe to it. + */ +void gcm_local_database_has_changed(void); + +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* GATT_CACHE_MANAGER_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/gatts_cache_manager.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/gatts_cache_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..b5901e63ea66614f5f012598ef77a35ffa4fceb6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/gatts_cache_manager.c @@ -0,0 +1,390 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) +#include "gatts_cache_manager.h" + +#include +#include "ble_gap.h" +#include "peer_manager_types.h" +#include "peer_manager_internal.h" +#include "peer_database.h" +#include "id_manager.h" + + +// Syntactic sugar, two spoons. +#define SYS_ATTR_SYS (BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS) +#define SYS_ATTR_USR (BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS) +#define SYS_ATTR_BOTH (SYS_ATTR_SYS | SYS_ATTR_USR) + +// The number of registered event handlers. +#define GSCM_EVENT_HANDLERS_CNT (sizeof(m_evt_handler) / sizeof(m_evt_handler[0])) + + +// GATTS Cache Manager event handler in Peer Manager. +extern void gcm_gscm_evt_handler(gscm_evt_t const * p_event); + +// GATTS Cache Manager events' handlers. +// The number of elements in this array is GSCM_EVENT_HANDLERS_CNT. +static gscm_evt_handler_t m_evt_handler[] = +{ + gcm_gscm_evt_handler +}; + +static bool m_module_initialized; +static pm_peer_id_t m_current_sc_store_peer_id; + + +/**@brief Function for resetting the module variable(s) of the GSCM module. + */ +static void internal_state_reset() +{ + m_module_initialized = false; + m_current_sc_store_peer_id = PM_PEER_ID_INVALID; +} + + +static void evt_send(gscm_evt_t const * p_event) +{ + for (uint32_t i = 0; i < GSCM_EVENT_HANDLERS_CNT; i++) + { + m_evt_handler[i](p_event); + } +} + + +//lint -save -e550 +/**@brief Function for storing service_changed_pending = true to flash for all peers, in sequence. + * + * This function aborts if it gets @ref NRF_ERROR_BUSY when trying to store. A subsequent call will + * continue where the last call was aborted. + */ +static void service_changed_pending_set(void) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + ret_code_t err_code; + // Use a uint32_t to enforce 4-byte alignment. + static const uint32_t service_changed_pending = true; + + //lint -save -e65 -e64 + pm_peer_data_const_t peer_data = + { + .data_id = PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, + .length_words = PM_SC_STATE_N_WORDS(), + .p_service_changed_pending = (bool*)&service_changed_pending, + }; + //lint -restore + + err_code = pdb_raw_store(m_current_sc_store_peer_id, &peer_data, NULL); + while ((m_current_sc_store_peer_id != PM_PEER_ID_INVALID) && (err_code != NRF_ERROR_BUSY)) + { + m_current_sc_store_peer_id = pdb_next_peer_id_get(m_current_sc_store_peer_id); + err_code = pdb_raw_store(m_current_sc_store_peer_id, &peer_data, NULL); + } +} +//lint -restore + + + +/**@brief Event handler for events from the Peer Database module. + * This function is extern in Peer Database. + * + * @param[in] p_event The event that has happend with peer id and flags. + */ +void gscm_pdb_evt_handler(pdb_evt_t const * p_event) +{ + if (p_event->evt_id == PDB_EVT_RAW_STORED) + { + if (p_event->data_id == PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING) + { + ret_code_t err_code; + pm_peer_data_flash_t peer_data; + + err_code = pdb_peer_data_ptr_get(p_event->peer_id, + PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, + &peer_data); + + if (err_code == NRF_SUCCESS) + { + gscm_evt_t gscm_evt; + gscm_evt.evt_id = GSCM_EVT_SC_STATE_STORED; + gscm_evt.peer_id = p_event->peer_id; + gscm_evt.params.sc_state_stored.state = &peer_data.p_service_changed_pending; + + evt_send(&gscm_evt); + } + } + } + + if (m_current_sc_store_peer_id != PM_PEER_ID_INVALID) + { + service_changed_pending_set(); + } +} + + +ret_code_t gscm_init() +{ + NRF_PM_DEBUG_CHECK(!m_module_initialized); + + internal_state_reset(); + m_module_initialized = true; + + return NRF_SUCCESS; +} + + +ret_code_t gscm_local_db_cache_update(uint16_t conn_handle) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle); + ret_code_t err_code; + + if (peer_id == PM_PEER_ID_INVALID) + { + return BLE_ERROR_INVALID_CONN_HANDLE; + } + else + { + pm_peer_data_t peer_data; + uint16_t n_bufs = 1; + bool retry_with_bigger_buffer = false; + + do + { + retry_with_bigger_buffer = false; + + err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_GATT_LOCAL, n_bufs++, &peer_data); + if (err_code == NRF_SUCCESS) + { + pm_peer_data_local_gatt_db_t * p_local_gatt_db = peer_data.p_local_gatt_db; + + p_local_gatt_db->flags = SYS_ATTR_BOTH; + + err_code = sd_ble_gatts_sys_attr_get(conn_handle, &p_local_gatt_db->data[0], &p_local_gatt_db->len, p_local_gatt_db->flags); + + if (err_code == NRF_SUCCESS) + { + err_code = pdb_write_buf_store(peer_id, PM_PEER_DATA_ID_GATT_LOCAL); + } + else + { + if (err_code == NRF_ERROR_DATA_SIZE) + { + // The sys attributes are bigger than the requested write buffer. + retry_with_bigger_buffer = true; + } + else if (err_code == NRF_ERROR_NOT_FOUND) + { + // There are no sys attributes in the GATT db, so nothing needs to be stored. + err_code = NRF_SUCCESS; + } + + ret_code_t err_code_release = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_GATT_LOCAL); + if (err_code_release != NRF_SUCCESS) + { + err_code = NRF_ERROR_INTERNAL; + } + } + } + else if (err_code == NRF_ERROR_INVALID_PARAM) + { + // The sys attributes are bigger than the entire write buffer. + err_code = NRF_ERROR_DATA_SIZE; + } + } while (retry_with_bigger_buffer); + } + + return err_code; +} + + +ret_code_t gscm_local_db_cache_apply(uint16_t conn_handle) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle); + ret_code_t err_code; + pm_peer_data_flash_t peer_data; + uint8_t const * p_sys_attr_data = NULL; + uint16_t sys_attr_len = 0; + uint32_t sys_attr_flags = (SYS_ATTR_BOTH); + bool all_attributes_applied = true; + + if (peer_id != PM_PEER_ID_INVALID) + { + err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_GATT_LOCAL, &peer_data); + if (err_code == NRF_SUCCESS) + { + pm_peer_data_local_gatt_db_t const * p_local_gatt_db; + + p_local_gatt_db = peer_data.p_local_gatt_db; + p_sys_attr_data = p_local_gatt_db->data; + sys_attr_len = p_local_gatt_db->len; + sys_attr_flags = p_local_gatt_db->flags; + } + } + + do + { + err_code = sd_ble_gatts_sys_attr_set(conn_handle, p_sys_attr_data, sys_attr_len, sys_attr_flags); + + if (err_code == NRF_ERROR_NO_MEM) + { + err_code = NRF_ERROR_BUSY; + } + else if (err_code == NRF_ERROR_INVALID_STATE) + { + err_code = NRF_SUCCESS; + } + else if (err_code == NRF_ERROR_INVALID_DATA) + { + all_attributes_applied = false; + + if (sys_attr_flags & SYS_ATTR_USR) + { + // Try setting only system attributes. + sys_attr_flags = SYS_ATTR_SYS; + } + else if (p_sys_attr_data || sys_attr_len) + { + // Try reporting that none exist. + p_sys_attr_data = NULL; + sys_attr_len = 0; + sys_attr_flags = SYS_ATTR_BOTH; + } + else + { + err_code = NRF_ERROR_INTERNAL; + } + } + } while (err_code == NRF_ERROR_INVALID_DATA); + + if (!all_attributes_applied) + { + err_code = NRF_ERROR_INVALID_DATA; + } + + return err_code; +} + + +ret_code_t gscm_local_db_cache_set(pm_peer_id_t peer_id, pm_peer_data_local_gatt_db_t * p_local_db) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + pm_peer_data_const_t peer_data; + + memset(&peer_data, 0, sizeof(pm_peer_data_const_t)); + peer_data.data_id = PM_PEER_DATA_ID_GATT_LOCAL; + peer_data.p_local_gatt_db = p_local_db; + + return pdb_raw_store(peer_id, &peer_data, NULL); +} + + +void gscm_local_database_has_changed(void) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + m_current_sc_store_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); + service_changed_pending_set(); +} + + +bool gscm_service_changed_ind_needed(uint16_t conn_handle) +{ + ret_code_t err_code; + pm_peer_data_flash_t peer_data; + pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle); + + err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, &peer_data); + + if (err_code != NRF_SUCCESS) + { + return false; + } + + return *peer_data.p_service_changed_pending; +} + + +ret_code_t gscm_service_changed_ind_send(uint16_t conn_handle) +{ + static uint16_t start_handle = 0x0000; + const uint16_t end_handle = 0xFFFF; + ret_code_t err_code; + + do + { + err_code = sd_ble_gatts_service_changed(conn_handle, start_handle, end_handle); + if (err_code == BLE_ERROR_INVALID_ATTR_HANDLE) + { + start_handle += 1; + } + } while (err_code == BLE_ERROR_INVALID_ATTR_HANDLE); + + return err_code; +} + + +void gscm_db_change_notification_done(pm_peer_id_t peer_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + // Use a uint32_t to enforce 4-byte alignment. + static const uint32_t service_changed_pending = false; + + //lint -save -e65 -e64 + pm_peer_data_const_t peer_data = + { + .data_id = PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, + .length_words = PM_SC_STATE_N_WORDS(), + .p_service_changed_pending = (bool*)&service_changed_pending, + }; + //lint -restore + + // Don't need to check return code, because all error conditions can be ignored. + //lint -save -e550 + (void) pdb_raw_store(peer_id, &peer_data, NULL); + //lint -restore +} +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/gatts_cache_manager.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/gatts_cache_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..19f11796a8f1165b9fef88463b3379836573b61f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/gatts_cache_manager.h @@ -0,0 +1,234 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef GATTS_CACHE_MANAGER_H__ +#define GATTS_CACHE_MANAGER_H__ + +#include +#include "sdk_errors.h" +#include "ble.h" +#include "ble_gap.h" +#include "peer_manager_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/** + * @cond NO_DOXYGEN + * @defgroup gatts_cache_manager GATT Server Cache Manager + * @ingroup peer_manager + * @{ + * @brief An internal module of @ref peer_manager. A module for managing persistent storing of GATT + * attributes pertaining to the GATT server role of the local device. + */ + + +/**@brief Events that can come from the GATT Server Cache Manager module. + */ +typedef enum +{ + GSCM_EVT_LOCAL_DB_CACHE_STORED, /**< The persistent cache for the local database has been updated with provided values, for one peer. */ + GSCM_EVT_LOCAL_DB_CACHE_UPDATED, /**< The persistent cache for the local database has been updated with values from the SoftDevice, for one peer. */ + GSCM_EVT_SC_STATE_STORED, /**< The service changed pending flag in persistent storage has been updated, for one peer. */ +} gscm_evt_id_t; + + +/**@brief Structure containing an event from the GSCM module. + */ +typedef struct +{ + gscm_evt_id_t evt_id; /**< The type of event this is. */ + pm_peer_id_t peer_id; /**< The peer ID this event pertains to. */ + union + { + struct + { + uint16_t conn_handle; /**< The connection this event pertains to. */ + } local_db_cache_updated; + struct + { + bool state; /**< The newly stored state of the Service Changed pending flag. */ + } sc_state_stored; + } params; /**< Event parameters specific to certain event types. */ +} gscm_evt_t; + +/**@brief Event handler for events from the GATT Server Cache Manager module. + * + * @param[in] event The event that has happened. + * @param[in] peer The id of the peer the event pertains to. + * @param[in] flags The data the event pertains to. + */ +typedef void (*gscm_evt_handler_t)(gscm_evt_t const * p_event); + + +/**@brief Function for initializing the GATT Server Cache Manager module. + * + * @retval NRF_SUCCESS Initialization was successful. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t gscm_init(void); + + +/**@brief Function for triggering local GATT database data to be stored persistently. Values are + * retrieved from the SoftDevice and written to persistent storage. + * + * @param[in] conn_handle Connection handle to perform update on. + * + * @retval NRF_SUCCESS Store operation started. + * @retval BLE_ERROR_INVALID_CONN_HANDLE conn_handle does not refer to an active connection with a + * bonded peer. + * @retval NRF_ERROR_BUSY Unable to perform operation at this time. Reattempt later. + * @retval NRF_ERROR_DATA_SIZE Write buffer not large enough. Call will never work with + * this GATT database. + * @retval NRF_ERROR_STORAGE_FULL No room in persistent_storage. Free up space; the + * operation will be automatically reattempted after the + * next FDS garbage collection procedure. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + */ +ret_code_t gscm_local_db_cache_update(uint16_t conn_handle); + + +/**@brief Function for applying stored local GATT database data to the SoftDevice. Values are + * retrieved from persistent storage and given to the SoftDevice. + * + * @param[in] conn_handle Connection handle to apply values to. + * + * @retval NRF_SUCCESS Store operation started. + * @retval BLE_ERROR_INVALID_CONN_HANDLE conn_handle does not refer to an active connection with a + * bonded peer. + * @retval NRF_ERROR_INVALID_DATA The stored data was rejected by the SoftDevice, which + * probably means that the local database has changed. The + * system part of the sys_attributes was attempted applied, + * so service changed indications can be sent to subscribers. + * @retval NRF_ERROR_BUSY Unable to perform operation at this time. Reattempt later. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @return An unexpected return value from an internal function call. + */ +ret_code_t gscm_local_db_cache_apply(uint16_t conn_handle); + + +/**@brief Function for setting new values in the local database cache. + * + * @note If the peer is connected, the values will also be applied immediately to the connection. + * @note The data in the pointer must be available until the GSCM_EVT_LOCAL_DB_STORED event is + * received. + * + * @param[in] peer_id Peer to set values for. + * @param[in] p_local_db Database values to apply. If NULL, the values will instead be cleared. + * + * @retval NRF_SUCCESS Operation started, and values were applied (if connected). + * @retval NRF_ERROR_NOT_FOUND The peer ID was invalid or unallocated. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @return An unexpected return value from an internal function call. + */ +ret_code_t gscm_local_db_cache_set(pm_peer_id_t peer_id, pm_peer_data_local_gatt_db_t * p_local_db); + + +/**@brief Function for retrieving values in the local database cache. + * + * @param[in] peer_id Peer to get values for. + * @param[inout] p_local_db Where to store the data. The length field needs to reflect the + * available buffer space. On a successful read, the length field is + * updated to match the length of the read data. + * + * @retval NRF_SUCCESS Values retrieved successfully. + * @retval NRF_ERROR_NOT_FOUND The peer ID was invalid or unallocated. + * @retval NRF_ERROR_NULL p_local_db was NULL. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + */ +ret_code_t gscm_local_db_cache_get(pm_peer_id_t peer_id, pm_peer_data_local_gatt_db_t * p_local_db); + + +/**@brief Function for storing the fact that the local database has changed, for all currently + * bonded peers. + * + * @note This will cause a later call to @ref gscm_service_changed_ind_needed to return true for + * a connection with a currently bonded peer. + */ +void gscm_local_database_has_changed(void); + + +/**@brief Function for checking if a service changed indication should be sent. + * + * @param[in] conn_handle The connection to check. + * + * @return true if a service changed indication should be sent, false if not. + */ +bool gscm_service_changed_ind_needed(uint16_t conn_handle); + + +/**@brief Function for sending a service changed indication to a connected peer. + * + * @param[in] conn_handle The connection to send the indication on. + * + * @retval NRF_SUCCESS Indication sent or not needed. + * @retval BLE_ERROR_INVALID_CONN_HANDLE conn_handle does not refer to an active connection. + * @retval NRF_ERROR_BUSY Unable to send indication at this time. Reattempt later. + * @retval BLE_ERROR_GATTS_SYS_ATTR_MISSING Information missing. Apply local cache, then reattempt. + * @retval NRF_ERROR_INVALID_PARAM From @ref sd_ble_gatts_service_changed. Unexpected. + * @retval NRF_ERROR_NOT_SUPPORTED Service changed characteristic is not present. + * @retval NRF_ERROR_INVALID_STATE Service changed cannot be indicated to this peer + * because the peer has not subscribed to it. + */ +ret_code_t gscm_service_changed_ind_send(uint16_t conn_handle); + + +/**@brief Function for specifying that a peer has been made aware of the latest local database + * change. + * + * @note After calling this, a later call to @ref gscm_service_changed_ind_needed will to return + * false for this peer unless @ref gscm_local_database_has_changed is called again. + * + * @param[in] peer_id The connection to send the indication on. + */ +void gscm_db_change_notification_done(pm_peer_id_t peer_id); + +/** @} + * @endcond +*/ + + +#ifdef __cplusplus +} +#endif + +#endif /* GATTS_CACHE_MANAGER_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/id_manager.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/id_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..ed1fbdbd5c68ecae4b0b06be5d83a27cfebf64ad --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/id_manager.c @@ -0,0 +1,1094 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) +#include "id_manager.h" + +#include +#include "ble.h" +#include "ble_gap.h" +#include "ble_conn_state.h" +#include "peer_manager_types.h" +#include "peer_database.h" +#include "peer_data_storage.h" +#include "nrf_soc.h" + + +#define IM_MAX_CONN_HANDLES (20) +#define IM_NO_INVALID_CONN_HANDLES (0xFF) +#define IM_ADDR_CLEARTEXT_LENGTH (3) +#define IM_ADDR_CIPHERTEXT_LENGTH (3) + +// The number of registered event handlers. +#define IM_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0])) + + +// Identity Manager event handlers in Peer Manager and GATT Cache Manager. +extern void pm_im_evt_handler(im_evt_t const * p_event); +extern void gcm_im_evt_handler(im_evt_t const * p_event); + +// Identity Manager events' handlers. +// The number of elements in this array is IM_EVENT_HANDLERS_CNT. +static im_evt_handler_t const m_evt_handlers[] = +{ + pm_im_evt_handler, + gcm_im_evt_handler +}; + + +typedef struct +{ + pm_peer_id_t peer_id; + uint16_t conn_handle; + ble_gap_addr_t peer_address; +} im_connection_t; + +static bool m_module_initialized; +static im_connection_t m_connections[IM_MAX_CONN_HANDLES]; +static ble_conn_state_user_flag_id_t m_conn_state_user_flag_id; + +static uint8_t m_wlisted_peer_cnt; +static pm_peer_id_t m_wlisted_peers[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + +#if (NRF_SD_BLE_API_VERSION <= 2) + static ble_gap_addr_t m_current_id_addr; +#endif + + +static void internal_state_reset() +{ + m_conn_state_user_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID; + + for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++) + { + m_connections[i].conn_handle = BLE_CONN_HANDLE_INVALID; + } +} + + +/**@brief Function for sending an event to all registered event handlers. + * + * @param[in] p_event The event to distribute. + */ +static void evt_send(im_evt_t * p_event) +{ + for (uint32_t i = 0; i < IM_EVENT_HANDLERS_CNT; i++) + { + m_evt_handlers[i](p_event); + } +} + +/**@brief Function finding a free position in m_connections. + * + * @detail All connection handles in the m_connections array are checked against the connection + * state module. The index of the first one that is not a connection handle for a current + * connection is returned. This position in the array can safely be used for a new connection. + * + * @return Either the index of a free position in the array or IM_NO_INVALID_CONN_HANDLES if no free + position exists. + */ +uint8_t get_free_connection() +{ + for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++) + { + // Query the connection state module to check if the + // connection handle does not belong to a valid connection. + if (!ble_conn_state_user_flag_get(m_connections[i].conn_handle, m_conn_state_user_flag_id)) + { + return i; + } + } + // If all connection handles belong to a valid connection, return IM_NO_INVALID_CONN_HANDLES. + return IM_NO_INVALID_CONN_HANDLES; +} + + +/**@brief Function finding a particular connection handle m_connections. + * + * @param[in] conn_handle The handle to find. + * + * @return Either the index of the conn_handle in the array or IM_NO_INVALID_CONN_HANDLES if the + * handle was not found. + */ +uint8_t get_connection_by_conn_handle(uint16_t conn_handle) +{ + if (ble_conn_state_user_flag_get(conn_handle, m_conn_state_user_flag_id)) + { + for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++) + { + if (m_connections[i].conn_handle == conn_handle) + { + return i; + } + } + } + // If all connection handles belong to a valid connection, return IM_NO_INVALID_CONN_HANDLES. + return IM_NO_INVALID_CONN_HANDLES; +} + + +/**@brief Function for registering a new connection instance. + * + * @param[in] conn_handle The handle of the new connection. + * @param[in] p_ble_addr The address used to connect. + * + * @return Either the index of the new connection in the array or IM_NO_INVALID_CONN_HANDLES if no + * free position exists. + */ +uint8_t new_connection(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr) +{ + uint8_t conn_index = IM_NO_INVALID_CONN_HANDLES; + + if ((p_ble_addr != NULL) && (conn_handle != BLE_CONN_HANDLE_INVALID)) + { + ble_conn_state_user_flag_set(conn_handle, m_conn_state_user_flag_id, true); + + conn_index = get_connection_by_conn_handle(conn_handle); + if (conn_index == IM_NO_INVALID_CONN_HANDLES) + { + conn_index = get_free_connection(); + } + + if (conn_index != IM_NO_INVALID_CONN_HANDLES) + { + m_connections[conn_index].conn_handle = conn_handle; + m_connections[conn_index].peer_id = PM_PEER_ID_INVALID; + m_connections[conn_index].peer_address = *p_ble_addr; + } + } + return conn_index; +} + + +/**@brief Function checking the validity of an IRK + * + * @detail An all-zero IRK is not valid. This function will check if a given IRK is valid. + * + * @param[in] p_irk The IRK for which the validity is going to be checked. + * + * @retval true The IRK is valid. + * @retval false The IRK is invalid. + */ +bool is_valid_irk(ble_gap_irk_t const * p_irk) +{ + NRF_PM_DEBUG_CHECK(p_irk != NULL); + + for (uint32_t i = 0; i < BLE_GAP_SEC_KEY_LEN; i++) + { + if (p_irk->irk[i] != 0) + { + return true; + } + } + return false; +} + + +/**@brief Function for comparing two addresses to determine if they are identical + * + * @note The address type need to be identical, as well as every bit in the address itself. + * + * @param[in] p_addr1 The first address to be compared. + * @param[in] p_addr2 The second address to be compared. + * + * @retval true The addresses are identical. + * @retval false The addresses are not identical. + */ +bool addr_compare(ble_gap_addr_t const * p_addr1, ble_gap_addr_t const * p_addr2) +{ + // @note emdi: use NRF_PM_DEBUG_CHECK ? + if ((p_addr1 == NULL) || (p_addr2 == NULL)) + { + return false; + } + + // Check that the addr type is identical, return false if it is not + if (p_addr1->addr_type != p_addr2->addr_type) + { + return false; + } + // Check if the addr bytes are is identical + return (memcmp(p_addr1->addr, p_addr2->addr, BLE_GAP_ADDR_LEN) == 0); +} + + +void im_ble_evt_handler(ble_evt_t * ble_evt) +{ + ble_gap_evt_t gap_evt; + pm_peer_id_t bonded_matching_peer_id; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + + if (ble_evt->header.evt_id != BLE_GAP_EVT_CONNECTED) + { + // Nothing to do. + return; + } + + gap_evt = ble_evt->evt.gap_evt; + bonded_matching_peer_id = PM_PEER_ID_INVALID; + + if ( gap_evt.params.connected.peer_addr.addr_type + != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) + { + /* Search the database for bonding data matching the one that triggered the event. + * Public and static addresses can be matched on address alone, while resolvable + * random addresses can be resolved agains known IRKs. Non-resolvable random addresses + * are never matching because they are not longterm form of identification. + */ + + pm_peer_id_t peer_id; + pm_peer_data_flash_t peer_data; + + pds_peer_data_iterate_prepare(); + + switch (gap_evt.params.connected.peer_addr.addr_type) + { + case BLE_GAP_ADDR_TYPE_PUBLIC: + case BLE_GAP_ADDR_TYPE_RANDOM_STATIC: + { + while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data)) + { + if (addr_compare(&gap_evt.params.connected.peer_addr, + &peer_data.p_bonding_data->peer_ble_id.id_addr_info)) + { + bonded_matching_peer_id = peer_id; + break; + } + } + } + break; + + case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE: + { + while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data)) + { + if (im_address_resolve(&gap_evt.params.connected.peer_addr, + &peer_data.p_bonding_data->peer_ble_id.id_info)) + { + bonded_matching_peer_id = peer_id; + break; + } + } + } + break; + + default: + NRF_PM_DEBUG_CHECK(false); + break; + } + } + + uint8_t new_index = new_connection(gap_evt.conn_handle, + &gap_evt.params.connected.peer_addr); + UNUSED_VARIABLE(new_index); + + if (bonded_matching_peer_id != PM_PEER_ID_INVALID) + { + im_new_peer_id(gap_evt.conn_handle, bonded_matching_peer_id); + + // Send a bonded peer event + im_evt_t im_evt; + im_evt.conn_handle = gap_evt.conn_handle; + im_evt.evt_id = IM_EVT_BONDED_PEER_CONNECTED; + evt_send(&im_evt); + } +} + + +/**@brief Function to compare two sets of bonding data to check if they belong to the same device. + * @note Invalid irks will never match even though they are identical. + * + * @param[in] p_bonding_data1 First bonding data for comparison + * @param[in] p_bonding_data2 Second bonding data for comparison + * + * @return True if the input matches, false if it does not. + */ +bool im_is_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data1, + pm_peer_data_bonding_t const * p_bonding_data2) +{ + NRF_PM_DEBUG_CHECK(p_bonding_data1 != NULL); + NRF_PM_DEBUG_CHECK(p_bonding_data2 != NULL); + + if (!is_valid_irk(&p_bonding_data1->peer_ble_id.id_info)) + { + return false; + } + + bool duplicate_irk = (memcmp(p_bonding_data1->peer_ble_id.id_info.irk, + p_bonding_data2->peer_ble_id.id_info.irk, + BLE_GAP_SEC_KEY_LEN) == 0); + + bool duplicate_addr = addr_compare(&p_bonding_data1->peer_ble_id.id_addr_info, + &p_bonding_data2->peer_ble_id.id_addr_info); + + return duplicate_irk || duplicate_addr; +} + + +/**@brief Event handler for events from the Peer Database module. + * This function is extern in Peer Database. + * + * @param[in] p_event The event that has happend with peer id and flags. + */ +void im_pdb_evt_handler(pdb_evt_t const * p_event) +{ + ret_code_t ret; + pm_peer_id_t peer_id; + pm_peer_data_flash_t peer_data; + pm_peer_data_flash_t peer_data_duplicate; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_event != NULL); + + if ((p_event->evt_id != PDB_EVT_WRITE_BUF_STORED) || + (p_event->data_id != PM_PEER_DATA_ID_BONDING)) + { + return; + } + + // If new data about peer id has been stored it is compared to other peers peer ids in + // search of duplicates. + + ret = pdb_peer_data_ptr_get(p_event->peer_id, PM_PEER_DATA_ID_BONDING, &peer_data); + + if (ret != NRF_SUCCESS) + { + // @note emdi: this shouldn't happen, since the data was just stored, right? + NRF_PM_DEBUG_CHECK(false); + return; + } + + pds_peer_data_iterate_prepare(); + + while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data_duplicate)) + { + if (p_event->peer_id == peer_id) + { + // Skip the iteration if the bonding data retrieved is for a peer + // with the same ID as the one contained in the event. + continue; + } + + if (im_is_duplicate_bonding_data(peer_data.p_bonding_data, + peer_data_duplicate.p_bonding_data)) + { + im_evt_t im_evt; + im_evt.conn_handle = im_conn_handle_get(p_event->peer_id); + im_evt.evt_id = IM_EVT_DUPLICATE_ID; + im_evt.params.duplicate_id.peer_id_1 = p_event->peer_id; + im_evt.params.duplicate_id.peer_id_2 = peer_id; + evt_send(&im_evt); + break; + } + } +} + + +ret_code_t im_init(void) +{ + NRF_PM_DEBUG_CHECK(!m_module_initialized); + + internal_state_reset(); + + m_conn_state_user_flag_id = ble_conn_state_user_flag_acquire(); + if (m_conn_state_user_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) + { + return NRF_ERROR_INTERNAL; + } + + #if (NRF_SD_BLE_API_VERSION <= 2) + ret_code_t ret_code = sd_ble_gap_address_get(&m_current_id_addr); + if (ret_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + #endif + + m_module_initialized = true; + + return NRF_SUCCESS; +} + + +pm_peer_id_t im_peer_id_get_by_conn_handle(uint16_t conn_handle) +{ + uint8_t conn_index; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + + conn_index = get_connection_by_conn_handle(conn_handle); + + if (conn_index != IM_NO_INVALID_CONN_HANDLES) + { + return m_connections[conn_index].peer_id; + } + + return PM_PEER_ID_INVALID; +} + + +ret_code_t im_ble_addr_get(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr) +{ + uint8_t conn_index; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_ble_addr != NULL); + + conn_index = get_connection_by_conn_handle(conn_handle); + + if (conn_index != IM_NO_INVALID_CONN_HANDLES) + { + *p_ble_addr = m_connections[conn_index].peer_address; + return NRF_SUCCESS; + } + + return NRF_ERROR_NOT_FOUND; +} + + +bool im_master_ids_compare(ble_gap_master_id_t const * p_master_id1, + ble_gap_master_id_t const * p_master_id2) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_master_id1 != NULL); + NRF_PM_DEBUG_CHECK(p_master_id2 != NULL); + + if (!im_master_id_is_valid(p_master_id1)) + { + return false; + } + + if (p_master_id1->ediv != p_master_id2->ediv) + { + return false; + } + + return (memcmp(p_master_id1->rand, p_master_id2->rand, BLE_GAP_SEC_RAND_LEN) == 0); +} + + +pm_peer_id_t im_peer_id_get_by_master_id(ble_gap_master_id_t * p_master_id) +{ + pm_peer_id_t peer_id; + pm_peer_data_flash_t peer_data; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_master_id != NULL); + + pds_peer_data_iterate_prepare(); + + // For each stored peer, check if the master_id matches p_master_id + while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data)) + { + if (im_master_ids_compare(p_master_id, &peer_data.p_bonding_data->own_ltk.master_id) || + im_master_ids_compare(p_master_id, &peer_data.p_bonding_data->peer_ltk.master_id)) + { + // If a matching master ID is found then return the peer ID. + return peer_id; + } + } + + // If no matching master ID is found return PM_PEER_ID_INVALID. + return PM_PEER_ID_INVALID; +} + + +uint16_t im_conn_handle_get(pm_peer_id_t peer_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++) + { + if (peer_id == m_connections[i].peer_id) + { + return m_connections[i].conn_handle; + } + } + return BLE_CONN_HANDLE_INVALID; +} + + +bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + if (p_master_id->ediv != 0) + { + return true; + } + + for (uint32_t i = 0; i < BLE_GAP_SEC_RAND_LEN; i++) + { + if (p_master_id->rand[i] != 0) + { + return true; + } + } + return false; +} + + +/**@brief Function to set the peer ID associated with a connection handle. + * + * @param[in] conn_handle The connection handle. + * @param[in] peer_id The peer ID to associate with @c conn_handle. + */ +static void peer_id_set(uint16_t conn_handle, pm_peer_id_t peer_id) +{ + uint8_t conn_index = get_connection_by_conn_handle(conn_handle); + if (conn_index != IM_NO_INVALID_CONN_HANDLES) + { + m_connections[conn_index].peer_id = peer_id; + } +} + + +void im_new_peer_id(uint16_t conn_handle, pm_peer_id_t peer_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + peer_id_set(conn_handle, peer_id); +} + + +ret_code_t im_peer_free(pm_peer_id_t peer_id) +{ + uint16_t conn_handle; + ret_code_t ret; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + + conn_handle = im_conn_handle_get(peer_id); + ret = pdb_peer_free(peer_id); + + if ((conn_handle != BLE_CONN_HANDLE_INVALID) && (ret == NRF_SUCCESS)) + { + peer_id_set(conn_handle, PM_PEER_ID_INVALID); + } + return ret; +} + + +/**@brief Given a list of peers, loads their GAP address and IRK into the provided buffers. + */ +static ret_code_t peers_id_keys_get(pm_peer_id_t const * p_peers, + uint32_t peer_cnt, + ble_gap_addr_t * p_gap_addrs, + uint32_t * p_addr_cnt, + ble_gap_irk_t * p_gap_irks, + uint32_t * p_irk_cnt) +{ + ret_code_t ret; + + pm_peer_data_bonding_t bond_data; + pm_peer_data_t peer_data; + + uint32_t const buf_size = sizeof(bond_data); + + bool copy_addrs = false; + bool copy_irks = false; + + NRF_PM_DEBUG_CHECK(p_peers != NULL); + + // One of these two has to be provided. + NRF_PM_DEBUG_CHECK((p_gap_addrs != NULL) || (p_gap_irks != NULL)); + + if ((p_gap_addrs != NULL) && (p_addr_cnt != NULL)) + { + NRF_PM_DEBUG_CHECK((*p_addr_cnt) >= peer_cnt); + + copy_addrs = true; + *p_addr_cnt = 0; + } + + if ((p_gap_irks != NULL) && (p_irk_cnt != NULL)) + { + NRF_PM_DEBUG_CHECK((*p_irk_cnt) >= peer_cnt); + + copy_irks = true; + *p_irk_cnt = 0; + } + + memset(&peer_data, 0x00, sizeof(peer_data)); + peer_data.p_bonding_data = &bond_data; + + // Read through flash memory and look for peers ID keys. + + for (uint32_t i = 0; i < peer_cnt; i++) + { + memset(&bond_data, 0x00, sizeof(bond_data)); + + // Read peer data from flash. + ret = pds_peer_data_read(p_peers[i], PM_PEER_DATA_ID_BONDING, + &peer_data, &buf_size); + + if ((ret == NRF_ERROR_NOT_FOUND) || (ret == NRF_ERROR_INVALID_PARAM)) + { + // Peer data coulnd't be found in flash or peer ID is not valid. + return NRF_ERROR_NOT_FOUND; + } + + uint8_t const addr_type = bond_data.peer_ble_id.id_addr_info.addr_type; + + if ((addr_type != BLE_GAP_ADDR_TYPE_PUBLIC) && + (addr_type != BLE_GAP_ADDR_TYPE_RANDOM_STATIC)) + { + // The address shared by the peer during bonding can't be used for whitelisting. + return BLE_ERROR_GAP_INVALID_BLE_ADDR; + } + + // Copy the GAP address. + if (copy_addrs) + { + memcpy(&p_gap_addrs[i], &bond_data.peer_ble_id.id_addr_info, sizeof(ble_gap_addr_t)); + (*p_addr_cnt)++; + } + + // Copy the IRK. + if (copy_irks) + { + memcpy(&p_gap_irks[i], bond_data.peer_ble_id.id_info.irk, BLE_GAP_SEC_KEY_LEN); + (*p_irk_cnt)++; + } + } + + return NRF_SUCCESS; +} + + +ret_code_t im_device_identities_list_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt) +{ + #if (NRF_SD_BLE_API_VERSION >= 3) + + ret_code_t ret; + pm_peer_data_t peer_data; + pm_peer_data_bonding_t bond_data; + + ble_gap_id_key_t keys[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + ble_gap_id_key_t const * key_ptrs[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + + if ((p_peers == NULL) || (peer_cnt == 0)) + { + // Clear the device identities list. + return sd_ble_gap_device_identities_set(NULL, NULL, 0); + } + + peer_data.p_bonding_data = &bond_data; + uint32_t const buf_size = sizeof(bond_data); + + memset(keys, 0x00, sizeof(keys)); + for (uint32_t i = 0; i < BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT; i++) + { + key_ptrs[i] = &keys[i]; + } + + for (uint32_t i = 0; i < peer_cnt; i++) + { + memset(&bond_data, 0x00, sizeof(bond_data)); + + // Read peer data from flash. + ret = pds_peer_data_read(p_peers[i], PM_PEER_DATA_ID_BONDING, + &peer_data, &buf_size); + + if ((ret == NRF_ERROR_NOT_FOUND) || (ret == NRF_ERROR_INVALID_PARAM)) + { + // Peer data coulnd't be found in flash or peer ID is not valid. + return NRF_ERROR_NOT_FOUND; + } + + uint8_t const addr_type = bond_data.peer_ble_id.id_addr_info.addr_type; + + if ((addr_type != BLE_GAP_ADDR_TYPE_PUBLIC) && + (addr_type != BLE_GAP_ADDR_TYPE_RANDOM_STATIC)) + { + // The address shared by the peer during bonding can't be whitelisted. + return BLE_ERROR_GAP_INVALID_BLE_ADDR; + } + + // Copy data to the buffer. + memcpy(&keys[i], &bond_data.peer_ble_id, sizeof(ble_gap_id_key_t)); + } + + return sd_ble_gap_device_identities_set(key_ptrs, NULL, peer_cnt); + + #else + + return NRF_ERROR_NOT_SUPPORTED; + + #endif +} + + +#if (NRF_SD_BLE_API_VERSION <= 2) + +static ret_code_t address_set_v2(uint8_t cycle_mode, ble_gap_addr_t * p_addr) +{ + NRF_PM_DEBUG_CHECK(p_addr != NULL); + + ret_code_t ret = sd_ble_gap_address_set(cycle_mode, p_addr); + + switch (ret) + { + case NRF_SUCCESS: + case NRF_ERROR_BUSY: + case NRF_ERROR_INVALID_STATE: + case NRF_ERROR_INVALID_PARAM: // If cycle_mode is not AUTO or NONE. + case BLE_ERROR_GAP_INVALID_BLE_ADDR: // If the GAP address is not valid. + return ret; + + default: + return NRF_ERROR_INTERNAL; + } +} + +#endif + + +ret_code_t im_id_addr_set(ble_gap_addr_t const * p_addr) +{ + #if (NRF_SD_BLE_API_VERSION <= 2) + + ret_code_t ret; + ble_gap_addr_t current_addr; + + NRF_PM_DEBUG_CHECK(p_addr != NULL); + + (void) sd_ble_gap_address_get(¤t_addr); + + ret = address_set_v2(BLE_GAP_ADDR_CYCLE_MODE_NONE, (ble_gap_addr_t *)p_addr); + if (ret != NRF_SUCCESS) + { + return ret; + } + + if ( current_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE + || current_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) + { + // If currently using privacy, it must be re-enabled. + // We force AUTO when privacy is enabled. + ret = address_set_v2(BLE_GAP_ADDR_CYCLE_MODE_AUTO, ¤t_addr); + if (ret != NRF_SUCCESS) + { + return ret; + } + } + + memcpy(&m_current_id_addr, p_addr, sizeof(ble_gap_addr_t)); + + return NRF_SUCCESS; + + #else + + return sd_ble_gap_addr_set(p_addr); + + #endif +} + + +ret_code_t im_id_addr_get(ble_gap_addr_t * p_addr) +{ + NRF_PM_DEBUG_CHECK(p_addr != NULL); + + #if (NRF_SD_BLE_API_VERSION <= 2) + memcpy(p_addr, &m_current_id_addr, sizeof(ble_gap_addr_t)); + return NRF_SUCCESS; + #else + return sd_ble_gap_addr_get(p_addr); + #endif +} + + +ret_code_t im_privacy_set(pm_privacy_params_t const * p_privacy_params) +{ + #if (NRF_SD_BLE_API_VERSION <= 2) + + ret_code_t ret; + ble_gap_addr_t privacy_addr; + ble_gap_irk_t current_irk; + ble_opt_t privacy_options; + ble_opt_t current_privacy_options; + + NRF_PM_DEBUG_CHECK(p_privacy_params != NULL); + + privacy_addr.addr_type = p_privacy_params->private_addr_type; + privacy_options.gap_opt.privacy.p_irk = p_privacy_params->p_device_irk; + privacy_options.gap_opt.privacy.interval_s = p_privacy_params->private_addr_cycle_s; + current_privacy_options.gap_opt.privacy.p_irk = ¤t_irk; + + // Can not fail. + (void) sd_ble_opt_get(BLE_GAP_OPT_PRIVACY, ¤t_privacy_options); + (void) sd_ble_opt_set(BLE_GAP_OPT_PRIVACY, &privacy_options); + + if (p_privacy_params->privacy_mode == BLE_GAP_PRIVACY_MODE_OFF) + { + ret = address_set_v2(BLE_GAP_ADDR_CYCLE_MODE_NONE, &m_current_id_addr); + } + else + { + ret = address_set_v2(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &privacy_addr); + } + + if (ret != NRF_SUCCESS) + { + // Restore previous settings. + (void) sd_ble_opt_set(BLE_GAP_OPT_PRIVACY, ¤t_privacy_options); + } + + // NRF_ERROR_BUSY, + // NRF_ERROR_INVALID_STATE, + // NRF_ERROR_INVALID_PARAM, if address type is not valid. + return ret; + + #else + + return sd_ble_gap_privacy_set(p_privacy_params); + + #endif +} + + +ret_code_t im_privacy_get(pm_privacy_params_t * p_privacy_params) +{ + #if (NRF_SD_BLE_API_VERSION <= 2) + + ble_gap_addr_t cur_addr; + ble_opt_t cur_privacy_opt; + + NRF_PM_DEBUG_CHECK(p_privacy_params != NULL); + NRF_PM_DEBUG_CHECK(p_privacy_params->p_device_irk != NULL); + + cur_privacy_opt.gap_opt.privacy.p_irk = p_privacy_params->p_device_irk; + + // Can not fail. + (void) sd_ble_gap_address_get(&cur_addr); + + if ( cur_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE + || cur_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) + { + p_privacy_params->privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY; + p_privacy_params->private_addr_type = cur_addr.addr_type; + } + else + { + p_privacy_params->privacy_mode = BLE_GAP_PRIVACY_MODE_OFF; + } + + // Can not fail. + (void) sd_ble_opt_get(BLE_GAP_OPT_PRIVACY, &cur_privacy_opt); + + p_privacy_params->private_addr_cycle_s = cur_privacy_opt.gap_opt.privacy.interval_s; + + return NRF_SUCCESS; + + #else + + return sd_ble_gap_privacy_get(p_privacy_params); + + #endif +} + + +/* Create a whitelist for the user using the cached list of peers. + * This whitelist is meant to be provided by the application to the Advertising module. + */ +ret_code_t im_whitelist_get(ble_gap_addr_t * p_addrs, + uint32_t * p_addr_cnt, + ble_gap_irk_t * p_irks, + uint32_t * p_irk_cnt) +{ + // One of the two buffers has to be provided. + NRF_PM_DEBUG_CHECK((p_addrs != NULL) || (p_irks != NULL)); + NRF_PM_DEBUG_CHECK((p_addr_cnt != NULL) || (p_irk_cnt != NULL)); + + if (((p_addr_cnt != NULL) && (m_wlisted_peer_cnt > *p_addr_cnt)) || + ((p_irk_cnt != NULL) && (m_wlisted_peer_cnt > *p_irk_cnt))) + { + // The size of the cached list of peers is larger than the provided buffers. + return NRF_ERROR_NO_MEM; + } + + // NRF_SUCCESS or + // NRF_ERROR_NOT_FOUND, if a peer or its data were not found. + // BLE_ERROR_GAP_INVALID_BLE_ADDR, if a peer address can not be used for whitelisting. + return peers_id_keys_get(m_wlisted_peers, m_wlisted_peer_cnt, + p_addrs, p_addr_cnt, + p_irks, p_irk_cnt); +} + + +/* Copies the peers to whitelist into a local cache. + * The cached list will be used by im_whitelist_get() to retrieve the active whitelist. + * For SoftDevices 3x, also loads the peers' GAP addresses and whitelists them using + * sd_ble_gap_whitelist_set(). + */ +ret_code_t im_whitelist_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt) +{ + // Clear the cache of whitelisted peers. + memset(m_wlisted_peers, 0x00, sizeof(m_wlisted_peers)); + + if ((p_peers == NULL) || (peer_cnt == 0)) + { + // Clear the current whitelist. + m_wlisted_peer_cnt = 0; + #if (NRF_SD_BLE_API_VERSION >= 3) + // NRF_SUCCESS, or + // BLE_GAP_ERROR_WHITELIST_IN_USE + return sd_ble_gap_whitelist_set(NULL, 0); + #else + // The cached list of whitelisted peers is already cleared; nothing to do. + return NRF_SUCCESS; + #endif + } + + // @todo emdi: should not ever cache more than BLE_GAP_WHITELIST_ADDR_MAX_COUNT... + + // Copy the new whitelisted peers. + m_wlisted_peer_cnt = peer_cnt; + memcpy(m_wlisted_peers, p_peers, sizeof(pm_peer_id_t) * peer_cnt); + + #if (NRF_SD_BLE_API_VERSION >= 3) + + ret_code_t ret; + uint32_t wlist_addr_cnt = 0; + + ble_gap_addr_t const * addr_ptrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + ble_gap_addr_t addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + + memset(addrs, 0x00, sizeof(addrs)); + + // Fetch GAP addresses for these peers, but don't fetch IRKs. + ret = peers_id_keys_get(p_peers, peer_cnt, addrs, &wlist_addr_cnt, NULL, NULL); + + if (ret != NRF_SUCCESS) + { + // NRF_ERROR_NOT_FOUND, if a peer or its data were not found. + // BLE_ERROR_GAP_INVALID_BLE_ADDR, if a peer address can not be used for whitelisting. + return ret; + } + + for (uint32_t i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; i++) + { + addr_ptrs[i] = &addrs[i]; + } + + // NRF_ERROR_DATA_SIZE, if peer_cnt > BLE_GAP_WHITELIST_ADDR_MAX_COUNT. + // BLE_ERROR_GAP_WHITELIST_IN_USE, if a whitelist is in use. + return sd_ble_gap_whitelist_set(addr_ptrs, peer_cnt); + + #else + + return NRF_SUCCESS; + + #endif +} + + +/**@brief Function for calculating the ah() hash function described in Bluetooth core specification + * 4.2 section 3.H.2.2.2. + * + * @detail BLE uses a hash function to calculate the first half of a resolvable address + * from the second half of the address and an irk. This function will use the ECB + * periferal to hash these data acording to the Bluetooth core specification. + * + * @note The ECB expect little endian input and output. + * This function expect big endian and will reverse the data as necessary. + * + * @param[in] p_k The key used in the hash function. + * For address resolution this is should be the irk. + * The array must have a length of 16. + * @param[in] p_r The rand used in the hash function. For generating a new address + * this would be a random number. For resolving a resolvable address + * this would be the last half of the address being resolved. + * The array must have a length of 3. + * @param[out] p_local_hash The result of the hash operation. For address resolution this + * will match the first half of the address being resolved if and only + * if the irk used in the hash function is the same one used to generate + * the address. + * The array must have a length of 16. + */ +void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash) +{ + nrf_ecb_hal_data_t ecb_hal_data; + + for (uint32_t i = 0; i < SOC_ECB_KEY_LENGTH; i++) + { + ecb_hal_data.key[i] = p_k[SOC_ECB_KEY_LENGTH - 1 - i]; + } + + memset(ecb_hal_data.cleartext, 0, SOC_ECB_KEY_LENGTH - IM_ADDR_CLEARTEXT_LENGTH); + + for (uint32_t i = 0; i < IM_ADDR_CLEARTEXT_LENGTH; i++) + { + ecb_hal_data.cleartext[SOC_ECB_KEY_LENGTH - 1 - i] = p_r[i]; + } + + // Can only return NRF_SUCCESS. + (void) sd_ecb_block_encrypt(&ecb_hal_data); + + for (uint32_t i = 0; i < IM_ADDR_CIPHERTEXT_LENGTH; i++) + { + p_local_hash[i] = ecb_hal_data.ciphertext[SOC_ECB_KEY_LENGTH - 1 - i]; + } +} + + +bool im_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + uint8_t hash[IM_ADDR_CIPHERTEXT_LENGTH]; + uint8_t local_hash[IM_ADDR_CIPHERTEXT_LENGTH]; + uint8_t prand[IM_ADDR_CLEARTEXT_LENGTH]; + + if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE) + { + return false; + } + + memcpy(hash, p_addr->addr, IM_ADDR_CIPHERTEXT_LENGTH); + memcpy(prand, &p_addr->addr[IM_ADDR_CIPHERTEXT_LENGTH], IM_ADDR_CLEARTEXT_LENGTH); + ah(p_irk->irk, prand, local_hash); + + return (memcmp(hash, local_hash, IM_ADDR_CIPHERTEXT_LENGTH) == 0); +} +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/id_manager.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/id_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..53f0831f6379244c55615dd88dd2fb73f846618c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/id_manager.h @@ -0,0 +1,339 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef PEER_ID_MANAGER_H__ +#define PEER_ID_MANAGER_H__ + +#include +#include "sdk_errors.h" +#include "ble.h" +#include "ble_gap.h" +#include "peer_manager_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @cond NO_DOXYGEN + * @defgroup id_manager ID Manager + * @ingroup peer_manager + * @{ + * @brief An internal module of @ref peer_manager. A module for keeping track of peer identities + * (IRK and peer address). + */ + + +/**@brief Events that can come from the ID Manager module. + */ +typedef enum +{ + IM_EVT_DUPLICATE_ID, /**< The ID Manager module has detected that two stored peers represent the same peer. */ + IM_EVT_BONDED_PEER_CONNECTED, /**< A connected peer has been identified as one of the bonded peers. This can happen immediately on connection, or at a later time. */ +} im_evt_id_t; + + +typedef struct +{ + im_evt_id_t evt_id; + uint16_t conn_handle; + union + { + struct + { + pm_peer_id_t peer_id_1; + pm_peer_id_t peer_id_2; + } duplicate_id; + } params; +} im_evt_t; + + +/**@brief Event handler for events from the ID Manager module. + * + * @param[in] p_event The event that has happened. + */ +typedef void (*im_evt_handler_t)(im_evt_t const * p_event); + + +/**@brief Function for initializing the Identity manager. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INTERNAL If an error occurred. + */ +ret_code_t im_init(void); + + +/**@brief Function for dispatching SoftDevice events to the ID Manager module. + * + * @param[in] p_ble_evt The SoftDevice event. + */ +void im_ble_evt_handler(ble_evt_t * p_ble_evt); + + +/**@brief Function for getting the corresponding peer ID from a connection handle. + * + * @param[in] conn_handle The connection handle. + * + * @return The corresponding peer ID, or @ref PM_PEER_ID_INVALID if none could be resolved. + */ +pm_peer_id_t im_peer_id_get_by_conn_handle(uint16_t conn_handle); + + +/**@brief Function for getting the corresponding peer ID from a master ID (EDIV and rand). + * + * @param[in] p_master_id The master ID. + * + * @return The corresponding peer ID, or @ref PM_PEER_ID_INVALID if none could be resolved. + */ +pm_peer_id_t im_peer_id_get_by_master_id(ble_gap_master_id_t * p_master_id); + + +/**@brief Function for getting the corresponding connection handle from a peer ID. + * + * @param[in] peer_id The peer ID. + * + * @return The corresponding connection handle, or @ref BLE_CONN_HANDLE_INVALID if none could be + * resolved. + */ +uint16_t im_conn_handle_get(pm_peer_id_t peer_id); + + +/**@brief Function for comparing two master ids + * @note Two invalid master IDs will not match. + * + * @param[in] p_master_id1 First master id for comparison + * @param[in] p_master_id2 Second master id for comparison + * + * @return True if the input matches, false if it does not. + */ +bool im_master_ids_compare(ble_gap_master_id_t const * p_master_id1, + ble_gap_master_id_t const * p_master_id2); + + +/**@brief Function for getting the BLE address used by the peer when connecting. + * + * @param[in] conn_handle The connection handle. + * @param[out] p_ble_addr The BLE address used by the peer when the connection specified by + * conn_handle was established. + * + * @retval NRF_SUCCESS The address was found and copied. + * @retval NRF_ERROR_INVALID_STATE Module not initialized. + * @retval BLE_ERROR_CONN_HANDLE_INVALID conn_handle does not refer to an active connection. + * @retval NRF_ERROR_NULL p_ble_addr was NULL. + */ +ret_code_t im_ble_addr_get(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr); + + +/**@brief Function for checking whether a master ID is valid or invalid + * + * @param[in] p_master_id The master ID. + * + * @retval true The master id is valid. + * @retval true The master id is invalid (i.e. all zeros). + */ +bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id); + + +bool im_is_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data1, + pm_peer_data_bonding_t const * p_bonding_data2); + + +/**@brief Function for reporting that a new peer ID has been allocated for a specified connection. + * + * @param[in] conn_handle The connection. + * @param[in] peer_id The new peer ID. + */ +void im_new_peer_id(uint16_t conn_handle, pm_peer_id_t peer_id); + + +/**@brief Function for deleting all of a peer's data from flash and disassociating it from any + * connection handles it is associated with. + * + * @param[in] peer_id The peer to free. + * + * @return Any error code returned by @ref pdb_peer_free. + */ +ret_code_t im_peer_free(pm_peer_id_t peer_id); + + +/**@brief Function to set the local Bluetooth identity address. + * + * @details The local Bluetooth identity address is the address that identifies this device to other + * peers. The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref + * BLE_GAP_ADDR_TYPE_RANDOM_STATIC. The identity address cannot be changed while roles are + * running. + * + * @note This address will be distributed to the peer during bonding. + * If the address changes, the address stored in the peer device will not be valid and the + * ability to reconnect using the old address will be lost. + * + * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC + * upon being enabled. The address is a random number populated during the IC manufacturing + * process and remains unchanged for the lifetime of each IC. + * + * @param[in] p_addr Pointer to address structure. + * + * @retval NRF_SUCCESS Address successfully set. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If the GAP address is invalid. + * @retval NRF_ERROR_BUSY Could not process at this time. Process SoftDevice events + * and retry. + * @retval NRF_ERROR_INVALID_STATE The identity address cannot be changed while advertising, + * scanning, or while in a connection. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t im_id_addr_set(ble_gap_addr_t const * p_addr); + + +/**@brief Function to get the local Bluetooth identity address. + * + * @note This will always return the identity address irrespective of the privacy settings, + * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref + * BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * + * @param[out] p_addr Pointer to address structure to be filled in. + * + * @retval NRF_SUCCESS If the address was successfully retrieved. + */ +ret_code_t im_id_addr_get(ble_gap_addr_t * p_addr); + + +/**@brief Function to set privacy settings. + * + * @details Privacy settings cannot be set while advertising, scanning, or while in a connection. + * + * @param[in] p_privacy_params Privacy settings. + * + * @retval NRF_SUCCESS If privacy options were set successfully. + * @retval NRF_ERROR_NULL If @p p_privacy_params is NULL. + * @retval NRF_ERROR_INVALID_PARAM If the address type is not valid. + * @retval NRF_ERROR_BUSY If the request could not be processed at this time. + * Process SoftDevice events and retry. + * @retval NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while BLE roles using + * privacy are enabled. + */ +ret_code_t im_privacy_set(pm_privacy_params_t const * p_privacy_params); + + +/**@brief Function to retrieve the current privacy settings. + * + * @details The privacy settings returned include the current device irk as well. + * + * @param[in] p_privacy_params Privacy settings. + * + * @retval NRF_SUCCESS Successfully retrieved privacy settings. + * @retval NRF_ERROR_NULL @c p_privacy_params is NULL. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t im_privacy_get(pm_privacy_params_t * p_privacy_params); + + +/**@brief Function for resolving a resolvable address with an identity resolution key (IRK). + * + * @details This function will use the ECB peripheral to resolve a resolvable address. + * This can be used to resolve the identity of a device distributing a random + * resolvable address based on any IRKs you have received earlier. If an address is + * resolved by an IRK, the device disributing the address must also know the IRK. + * + * @param[in] p_addr A random resolvable address. + * @param[in] p_irk An identity resolution key (IRK). + * + * @retval true The irk used matched the one used to create the address. + * @retval false The irk used did not match the one used to create the address, or an argument was + * NULL. + */ +bool im_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk); + + +/**@brief Function for setting / clearing the whitelist. + * + * @param p_peers The peers to whitelist. Pass NULL to clear the whitelist. + * @param peer_cnt The number of peers to whitelist. Pass zero to clear the whitelist. + * + * @retval NRF_SUCCESS If the whitelist was successfully set or cleared. + * @retval BLE_GAP_ERROR_WHITELIST_IN_USE If a whitelist is in use. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If any peer has an address which can not be used + * for whitelisting. + * @retval NRF_ERROR_NOT_FOUND If any peer or its data could not be found. + * @retval NRF_ERROR_DATA_SIZE If @p peer_cnt is greater than + * @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. + */ +ret_code_t im_whitelist_set(pm_peer_id_t const * p_peers, + uint32_t const peer_cnt); + + +/**@brief Retrieves the current whitelist, set by a previous call to @ref im_whitelist_set. + * + * @param[out] A buffer where to copy the GAP addresses. + * @param[inout] In: the size of the @p p_addrs buffer. + * Out: the number of address copied into the buffer. + * @param[out] A buffer where to copy the IRKs. + * @param[inout] In: the size of the @p p_irks buffer. + * Out: the number of IRKs copied into the buffer. + * + * @retval NRF_SUCCESS If the whitelist was successfully retreived. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If any peer has an address which can not be used for + * whitelisting. + * @retval NRF_ERROR_NOT_FOUND If the data for any of the cached whitelisted peers + * can not be found anymore. It might have been deleted in + * the meanwhile. + * @retval NRF_ERROR_NO_MEM If the provided buffers are too small. + */ +ret_code_t im_whitelist_get(ble_gap_addr_t * p_addrs, + uint32_t * p_addr_cnt, + ble_gap_irk_t * p_irks, + uint32_t * p_irk_cnt); + + +/**@brief Set the device identities list. + */ +ret_code_t im_device_identities_list_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt); + + +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* PEER_ID_MANAGER_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_data_storage.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_data_storage.c new file mode 100644 index 0000000000000000000000000000000000000000..0a8d8d43942f06ba151cbdd0087a56246a9c9f83 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_data_storage.c @@ -0,0 +1,691 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) +#include "peer_data_storage.h" + +#include +#include +#include "sdk_errors.h" +#include "peer_manager_types.h" +#include "peer_manager_internal.h" +#include "peer_id.h" +#include "fds.h" + + +// Macro for verifying that the peer id is within a valid range. +#define VERIFY_PEER_ID_IN_RANGE(id) VERIFY_FALSE((id >= PM_PEER_ID_N_AVAILABLE_IDS), \ + NRF_ERROR_INVALID_PARAM) + +// Macro for verifying that the peer data id is withing a valid range. +#define VERIFY_PEER_DATA_ID_IN_RANGE(id) VERIFY_TRUE(peer_data_id_is_valid(id), \ + NRF_ERROR_INVALID_PARAM) + +// The number of registered event handlers. +#define PDS_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0])) + + +// Peer Data Storage event handler in Peer Database. +extern void pdb_pds_evt_handler(pds_evt_t const *); + +// Peer Data Storage events' handlers. +// The number of elements in this array is PDS_EVENT_HANDLERS_CNT. +static pds_evt_handler_t const m_evt_handlers[] = +{ + pdb_pds_evt_handler, +}; + +static bool m_module_initialized = false; +static bool m_peer_delete_queued = false; +static bool m_peer_delete_ongoing = false; + +// A token used for Flash Data Storage searches. +static fds_find_token_t m_fds_ftok; + + +// Function for dispatching events to all registered event handlers. +static void pds_evt_send(pds_evt_t * p_event) +{ + for (uint32_t i = 0; i < PDS_EVENT_HANDLERS_CNT; i++) + { + m_evt_handlers[i](p_event); + } +} + + +// Function to convert peer IDs to file IDs. +static uint16_t peer_id_to_file_id(pm_peer_id_t peer_id) +{ + return (uint16_t)(peer_id + PEER_ID_TO_FILE_ID); +} + + +// Function to convert peer data id to type id. +static pm_peer_id_t file_id_to_peer_id(uint16_t file_id) +{ + return (pm_peer_id_t)(file_id + FILE_ID_TO_PEER_ID); +} + + +// Function to convert peer data IDs to record keys. +static uint16_t peer_data_id_to_record_key(pm_peer_data_id_t peer_data_id) +{ + return (uint16_t)(peer_data_id + DATA_ID_TO_RECORD_KEY); +} + + +// Function to convert record keys to peer data IDs. +static pm_peer_data_id_t record_key_to_peer_data_id(uint16_t record_key) +{ + return (pm_peer_data_id_t)(record_key + RECORD_KEY_TO_DATA_ID); +} + + +// Function for checking whether a file ID is relevant for the Peer Manager. +static bool file_id_within_pm_range(uint16_t file_id) +{ + return ((PDS_FIRST_RESERVED_FILE_ID <= file_id) + && (file_id <= PDS_LAST_RESERVED_FILE_ID)); +} + + +// Function for checking whether a record key is relevant for the Peer Manager. +static bool record_key_within_pm_range(uint16_t record_key) +{ + return ((PDS_FIRST_RESERVED_RECORD_KEY <= record_key) + && (record_key <= PDS_LAST_RESERVED_RECORD_KEY)); +} + + +static bool peer_data_id_is_valid(pm_peer_data_id_t data_id) +{ + return ((data_id == PM_PEER_DATA_ID_BONDING) || + (data_id == PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING) || + (data_id == PM_PEER_DATA_ID_GATT_LOCAL) || + (data_id == PM_PEER_DATA_ID_GATT_REMOTE) || + (data_id == PM_PEER_DATA_ID_PEER_RANK) || + (data_id == PM_PEER_DATA_ID_APPLICATION)); +} + + +// Function for deleting all data beloning to a peer. +// These operations will be sent to FDS one at a time. +static void peer_data_delete() +{ + ret_code_t ret; + pm_peer_id_t peer_id; + uint16_t file_id; + fds_record_desc_t desc; + fds_find_token_t ftok; + + memset(&ftok, 0x00, sizeof(fds_find_token_t)); + peer_id = peer_id_get_next_deleted(PM_PEER_ID_INVALID); + + while ( (peer_id != PM_PEER_ID_INVALID) + && (fds_record_find_in_file(peer_id_to_file_id(peer_id), &desc, &ftok) + == FDS_ERR_NOT_FOUND)) + { + peer_id_free(peer_id); + peer_id = peer_id_get_next_deleted(peer_id); + } + + if (!m_peer_delete_ongoing && (peer_id != PM_PEER_ID_INVALID)) + { + m_peer_delete_ongoing = true; + + file_id = peer_id_to_file_id(peer_id); + ret = fds_file_delete(file_id); + + if (ret == FDS_ERR_NO_SPACE_IN_QUEUES) + { + m_peer_delete_queued = true; + } + else if (ret != NRF_SUCCESS) + { + m_peer_delete_ongoing = false; + + pds_evt_t pds_evt; + + pds_evt.evt_id = PDS_EVT_ERROR_UNEXPECTED; + pds_evt.peer_id = peer_id; + pds_evt.data_id = PM_PEER_DATA_ID_INVALID; + pds_evt.store_token = PM_STORE_TOKEN_INVALID; + pds_evt.result = ret; + + pds_evt_send(&pds_evt); + } + } +} + + +static ret_code_t peer_data_find(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + fds_record_desc_t * const p_desc) +{ + ret_code_t ret; + fds_find_token_t ftok; + + NRF_PM_DEBUG_CHECK(peer_id < PM_PEER_ID_N_AVAILABLE_IDS); + NRF_PM_DEBUG_CHECK(peer_data_id_is_valid(data_id)); + NRF_PM_DEBUG_CHECK(p_desc != NULL); + + memset(&ftok, 0x00, sizeof(fds_find_token_t)); + + uint16_t file_id = peer_id_to_file_id(peer_id); + uint16_t record_key = peer_data_id_to_record_key(data_id); + + ret = fds_record_find(file_id, record_key, p_desc, &ftok); + + if (ret != FDS_SUCCESS) + { + return NRF_ERROR_NOT_FOUND; + } + + return NRF_SUCCESS; +} + + +static void peer_ids_load() +{ + fds_record_desc_t record_desc; + fds_flash_record_t record; + fds_find_token_t ftok; + + memset(&ftok, 0x00, sizeof(fds_find_token_t)); + + uint16_t const record_key = peer_data_id_to_record_key(PM_PEER_DATA_ID_BONDING); + + while (fds_record_find_by_key(record_key, &record_desc, &ftok) == FDS_SUCCESS) + { + pm_peer_id_t peer_id; + + // It is safe to ignore the return value since the descriptor was + // just obtained and also 'record' is different from NULL. + (void)fds_record_open(&record_desc, &record); + peer_id = file_id_to_peer_id(record.p_header->ic.file_id); + (void)fds_record_close(&record_desc); + + (void)peer_id_allocate(peer_id); + } +} + + +static void fds_evt_handler(fds_evt_t const * const p_fds_evt) +{ + pds_evt_t pds_evt; + + pds_evt.result = (p_fds_evt->result == FDS_SUCCESS); + + switch (p_fds_evt->id) + { + case FDS_EVT_WRITE: + case FDS_EVT_UPDATE: + if ( file_id_within_pm_range(p_fds_evt->write.file_id) + || record_key_within_pm_range(p_fds_evt->write.record_key)) + { + pds_evt.peer_id = file_id_to_peer_id(p_fds_evt->write.file_id); + pds_evt.data_id = record_key_to_peer_data_id(p_fds_evt->write.record_key); + + if (p_fds_evt->id == FDS_EVT_WRITE) + { + pds_evt.evt_id = (p_fds_evt->result == FDS_SUCCESS) ? PDS_EVT_STORED : + PDS_EVT_ERROR_STORE; + } + else + { + pds_evt.evt_id = (p_fds_evt->result == FDS_SUCCESS) ? PDS_EVT_UPDATED : + PDS_EVT_ERROR_UPDATE; + } + + pds_evt.result = p_fds_evt->result; + pds_evt.store_token = p_fds_evt->write.record_id; + + pds_evt_send(&pds_evt); + } + break; + + case FDS_EVT_DEL_RECORD: + if ( file_id_within_pm_range(p_fds_evt->del.file_id) + || record_key_within_pm_range(p_fds_evt->del.record_key)) + { + pds_evt.peer_id = file_id_to_peer_id(p_fds_evt->del.file_id); + pds_evt.data_id = record_key_to_peer_data_id(p_fds_evt->del.record_key); + + pds_evt.evt_id = (p_fds_evt->result == FDS_SUCCESS) ? PDS_EVT_CLEARED : + PDS_EVT_ERROR_CLEAR; + + pds_evt.store_token = p_fds_evt->del.record_id; + + pds_evt_send(&pds_evt); + } + break; + + case FDS_EVT_DEL_FILE: + { + if ( file_id_within_pm_range(p_fds_evt->del.file_id) + && (p_fds_evt->del.record_key == FDS_RECORD_KEY_DIRTY)) + { + pds_evt.peer_id = file_id_to_peer_id(p_fds_evt->del.file_id); + pds_evt.data_id = record_key_to_peer_data_id(p_fds_evt->del.record_key); + + pds_evt.data_id = PM_PEER_DATA_ID_INVALID; + if (p_fds_evt->result == FDS_SUCCESS) + { + pds_evt.evt_id = PDS_EVT_PEER_ID_CLEAR; + peer_id_free(pds_evt.peer_id); + } + else + { + pds_evt.evt_id = PDS_EVT_ERROR_PEER_ID_CLEAR; + } + + m_peer_delete_queued = false; + m_peer_delete_ongoing = false; + + peer_data_delete(); + + pds_evt_send(&pds_evt); + } + } + break; + + case FDS_EVT_GC: + pds_evt.evt_id = PDS_EVT_COMPRESSED; + pds_evt_send(&pds_evt); + break; + + default: + break; + } + + if (m_peer_delete_queued) + { + m_peer_delete_queued = false; + peer_data_delete(); + } +} + + +ret_code_t pds_init() +{ + ret_code_t ret; + + // Check for re-initialization if debugging. + NRF_PM_DEBUG_CHECK(!m_module_initialized); + + ret = fds_register(fds_evt_handler); + if (ret != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + ret = fds_init(); + if (ret != NRF_SUCCESS) + { + return NRF_ERROR_STORAGE_FULL; + } + + peer_id_init(); + peer_ids_load(); + + m_module_initialized = true; + + return NRF_SUCCESS; +} + + +ret_code_t pds_peer_data_read(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + pm_peer_data_t * const p_data, + uint32_t const * const p_buf_len) +{ + ret_code_t ret; + fds_record_desc_t rec_desc; + fds_flash_record_t rec_flash; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_data != NULL); + + VERIFY_PEER_ID_IN_RANGE(peer_id); + VERIFY_PEER_DATA_ID_IN_RANGE(data_id); + + ret = peer_data_find(peer_id, data_id, &rec_desc); + + if (ret != NRF_SUCCESS) + { + return NRF_ERROR_NOT_FOUND; + } + + // Shouldn't fail, unless the record was deleted in the meanwhile or the CRC check has failed. + ret = fds_record_open(&rec_desc, &rec_flash); + + if (ret != NRF_SUCCESS) + { + return NRF_ERROR_NOT_FOUND; + } + + // @note emdi: could this actually be set by the caller and used instead + // of an additional parameter (data_id) ? + p_data->data_id = data_id; + p_data->length_words = rec_flash.p_header->tl.length_words; + + // If p_buf_len is NULL, provide a pointer to data in flash, otherwise, + // check that the buffer is large enough and copy the data in flash into the buffer. + if (p_buf_len != NULL) + { + uint32_t const data_len_bytes = (p_data->length_words * sizeof(uint32_t)); + + if ((*p_buf_len) <= data_len_bytes) + { + memcpy(p_data->p_all_data, rec_flash.p_data, data_len_bytes); + } + else + { + return NRF_ERROR_NO_MEM; + } + } + else + { + // The cast is necessary because if no buffer is provided, we just copy the pointer, + // but it that case it should be considered a pointer to const data by the caller, + // since it is a pointer to data in flash. + p_data->p_all_data = (void*)rec_flash.p_data; + } + + // Shouldn't fail unless the record was already closed, in which case it can be ignored. + (void)fds_record_close(&rec_desc); + + return NRF_SUCCESS; +} + + +void pds_peer_data_iterate_prepare(void) +{ + memset(&m_fds_ftok, 0x00, sizeof(fds_find_token_t)); +} + + +bool pds_peer_data_iterate(pm_peer_data_id_t data_id, + pm_peer_id_t * const p_peer_id, + pm_peer_data_flash_t * const p_data) +{ + ret_code_t ret; + uint16_t rec_key; + fds_record_desc_t rec_desc; + fds_flash_record_t rec_flash; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_peer_id != NULL); + NRF_PM_DEBUG_CHECK(p_data != NULL); + + // @note emdi: should we check the data_id ? + rec_key = peer_data_id_to_record_key(data_id); + + if (fds_record_find_by_key(rec_key, &rec_desc, &m_fds_ftok) != NRF_SUCCESS) + { + return false; + } + + ret = fds_record_open(&rec_desc, &rec_flash); + + if (ret != NRF_SUCCESS) + { + // It can only happen if the record was deleted after the call to fds_record_find_by_key(), + // before we could open it, or if CRC support was enabled in Flash Data Storage at compile + // time and the CRC check failed. + return false; + } + + p_data->data_id = data_id; + p_data->length_words = rec_flash.p_header->tl.length_words; + p_data->p_all_data = rec_flash.p_data; + + *p_peer_id = file_id_to_peer_id(rec_flash.p_header->ic.file_id); + + (void)fds_record_close(&rec_desc); + + return true; +} + + +ret_code_t pds_space_reserve(pm_peer_data_const_t const * p_peer_data, + pm_prepare_token_t * p_prepare_token) +{ + ret_code_t ret; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_peer_data != NULL); + NRF_PM_DEBUG_CHECK(p_prepare_token != NULL); + + VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_id); + + ret = fds_reserve((fds_reserve_token_t*)p_prepare_token, p_peer_data->length_words); + + switch (ret) + { + case FDS_SUCCESS: + return NRF_SUCCESS; + + case FDS_ERR_RECORD_TOO_LARGE: + return NRF_ERROR_INVALID_LENGTH; + + case FDS_ERR_NO_SPACE_IN_FLASH: + return NRF_ERROR_STORAGE_FULL; + + default: + return NRF_ERROR_INTERNAL; + } +} + + +ret_code_t pds_space_reserve_cancel(pm_prepare_token_t prepare_token) +{ + ret_code_t ret; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(prepare_token != PDS_PREPARE_TOKEN_INVALID); + + ret = fds_reserve_cancel((fds_reserve_token_t*)&prepare_token); + + if (ret != FDS_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + return NRF_SUCCESS; +} + + +ret_code_t pds_peer_data_store(pm_peer_id_t peer_id, + pm_peer_data_const_t const * p_peer_data, + pm_prepare_token_t prepare_token, + pm_store_token_t * p_store_token) +{ + ret_code_t ret; + fds_record_t rec; + fds_record_desc_t rec_desc; + fds_record_chunk_t rec_chunk; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_peer_data != NULL); + + VERIFY_PEER_ID_IN_RANGE(peer_id); + VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_id); + + // Prepare chunk. + rec_chunk.p_data = p_peer_data->p_all_data; + rec_chunk.length_words = p_peer_data->length_words; + + // Prepare the record to be stored in flash. + rec.file_id = peer_id_to_file_id(peer_id); + rec.key = peer_data_id_to_record_key(p_peer_data->data_id); + rec.data.p_chunks = &rec_chunk; + rec.data.num_chunks = 1; + + ret = peer_data_find(peer_id, p_peer_data->data_id, &rec_desc); + + if (ret == NRF_ERROR_NOT_FOUND) + { + // No previous data exists in flash. + if (prepare_token == PDS_PREPARE_TOKEN_INVALID) + { + // No space was previously reserved. + ret = fds_record_write(&rec_desc, &rec); + } + else + { + // Space for this record was previously reserved. + ret = fds_record_write_reserved(&rec_desc, &rec, (fds_reserve_token_t*)&prepare_token); + } + } + else // NRF_SUCCESS + { + if (prepare_token != PDS_PREPARE_TOKEN_INVALID) + { + (void)fds_reserve_cancel((fds_reserve_token_t*)&prepare_token); + } + + // Update existing record. + ret = fds_record_update(&rec_desc, &rec); + } + + switch (ret) + { + case FDS_SUCCESS: + if (p_store_token != NULL) + { + // Update the store token. + (void)fds_record_id_from_desc(&rec_desc, (uint32_t*)p_store_token); + } + return NRF_SUCCESS; + + case FDS_ERR_BUSY: + case FDS_ERR_NO_SPACE_IN_QUEUES: + return NRF_ERROR_BUSY; + + case FDS_ERR_NO_SPACE_IN_FLASH: + return NRF_ERROR_STORAGE_FULL; + + default: + return NRF_ERROR_INTERNAL; + } +} + + +// @note emdi: unused.. +ret_code_t pds_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) +{ + ret_code_t ret; + fds_record_desc_t record_desc; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + + VERIFY_PEER_ID_IN_RANGE(peer_id); + VERIFY_PEER_DATA_ID_IN_RANGE(data_id); + + ret = peer_data_find(peer_id, data_id, &record_desc); + + if (ret != NRF_SUCCESS) + { + return NRF_ERROR_NOT_FOUND; + } + + ret = fds_record_delete(&record_desc); + + switch (ret) + { + case FDS_SUCCESS: + return NRF_SUCCESS; + + case FDS_ERR_NO_SPACE_IN_QUEUES: + return NRF_ERROR_BUSY; + + default: + return NRF_ERROR_INTERNAL; + } +} + + +pm_peer_id_t pds_peer_id_allocate(void) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + return peer_id_allocate(PM_PEER_ID_INVALID); +} + + +ret_code_t pds_peer_id_free(pm_peer_id_t peer_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + VERIFY_PEER_ID_IN_RANGE(peer_id); + + (void)peer_id_delete(peer_id); + peer_data_delete(); + + return NRF_SUCCESS; +} + + +bool pds_peer_id_is_allocated(pm_peer_id_t peer_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + return peer_id_is_allocated(peer_id); +} + + +pm_peer_id_t pds_next_peer_id_get(pm_peer_id_t prev_peer_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + return peer_id_get_next_used(prev_peer_id); +} + + +pm_peer_id_t pds_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + return peer_id_get_next_deleted(prev_peer_id); +} + + +uint32_t pds_peer_count_get(void) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + return peer_id_n_ids(); +} +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_data_storage.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_data_storage.h new file mode 100644 index 0000000000000000000000000000000000000000..1770631f4c3193a604ac0bccea607a758bbefc20 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_data_storage.h @@ -0,0 +1,306 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef PEER_DATA_STORAGE_H__ +#define PEER_DATA_STORAGE_H__ + + +#include +#include "sdk_errors.h" +#include "ble_gap.h" +#include "peer_manager_types.h" +#include "peer_manager_internal.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @cond NO_DOXYGEN + * @defgroup peer_data_storage Peer Data Storage + * @ingroup peer_manager + * @{ + * @brief An internal module of @ref peer_manager. This module provides a Peer Manager-specific API + * to the persistent storage. + * + * @details This module uses Flash Data Storage (FDS) to interface with persistent storage. + */ + +#define PDS_PREPARE_TOKEN_INVALID (0) /**< Invalid value for prepare token. */ +#define PDS_FIRST_RESERVED_FILE_ID (0xC000) /**< The beginning of the range of file IDs reserved for Peer Manager. */ +#define PDS_LAST_RESERVED_FILE_ID (0xFFFE) /**< The end of the range of file IDs reserved for Peer Manager. */ +#define PDS_FIRST_RESERVED_RECORD_KEY (0xC000) /**< The beginning of the range of record keys reserved for Peer Manager. */ +#define PDS_LAST_RESERVED_RECORD_KEY (0xFFFE) /**< The end of the range of record keys reserved for Peer Manager. */ + +#define PEER_ID_TO_FILE_ID ( PDS_FIRST_RESERVED_FILE_ID) //!< Macro for converting a @ref pm_peer_id_t to an FDS file ID. +#define FILE_ID_TO_PEER_ID (-PDS_FIRST_RESERVED_FILE_ID) //!< Macro for converting an FDS file ID to a @ref pm_peer_id_t. +#define DATA_ID_TO_RECORD_KEY ( PDS_FIRST_RESERVED_RECORD_KEY) //!< Macro for converting a @ref pm_peer_data_id_t to an FDS record ID. +#define RECORD_KEY_TO_DATA_ID (-PDS_FIRST_RESERVED_RECORD_KEY) //!< Macro for converting an FDS record ID to a @ref pm_peer_data_id_t. + + +/**@brief The events that come from this module. + */ +typedef enum +{ + PDS_EVT_STORED, //!< The specified data has been successfully stored. + PDS_EVT_UPDATED, //!< The specified data has been successfully updated. + PDS_EVT_CLEARED, //!< The specified data has been successfully cleared. + PDS_EVT_ERROR_STORE, //!< The specified data could not be stored. + PDS_EVT_ERROR_UPDATE, //!< The specified data could not be updated. + PDS_EVT_ERROR_CLEAR, //!< The specified data could not be cleared. + PDS_EVT_PEER_ID_CLEAR, //!< The peer id has been successfully cleared. + PDS_EVT_ERROR_PEER_ID_CLEAR, //!< The peer id has been successfully cleared. + PDS_EVT_COMPRESSED, //!< A compress procedure has finished successfully. + PDS_EVT_ERROR_UNEXPECTED, //!< An unexpected, possibly fatal error occurred. +} pds_evt_id_t; + + +/**@brief The event structure for events generated by the this module. + */ +typedef struct +{ + pds_evt_id_t evt_id; /**< The type of event. */ + pm_peer_id_t peer_id; /**< The peer the event pertains to. */ + pm_peer_data_id_t data_id; /**< The data the event pertains to. */ + pm_store_token_t store_token; /**< A unique identifier for the operation. Can be compare to the token received when starting the operation. */ + ret_code_t result; /**< The result of the operation, or the unexpected error. */ +} pds_evt_t; + + +/**@brief Event handler for events from the peer_data_storage module. + * + * @param[in] event The event that has happened. + * @param[in] peer_id The id of the peer the event pertains to. + * @param[in] flags The data the event pertains to. + */ +typedef void (*pds_evt_handler_t)(pds_evt_t const * p_event); + + +/**@brief Function for initializing the module. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_STORAGE_FULL If no flash pages were available for use. + * @retval NRF_ERROR_INTERNAL If the module couldn't register with the flash filesystem. + */ +ret_code_t pds_init(void); + + +/**@brief Function for reading peer data in flash. + * + * @param[in] peer_id The peer the data belongs to. + * @param[in] data_id The data to retrieve. + * @param[out] p_data The peer data. May not be @c NULL. + * @param[in] p_buf_len Length of the provided buffer, in bytes. Pass @c NULL to only copy + * a pointer to the data in flash. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_PARAM If @p peer_id or @p data_id are invalid. + * @retval NRF_ERROR_NOT_FOUND If the data was not found in flash. + * @retval NRF_ERROR_NO_MEM If the provided buffer is too small. + */ +ret_code_t pds_peer_data_read(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + pm_peer_data_t * const p_data, + uint32_t const * const p_buf_len); + + +/**@brief Function to prepare iterating over peer data in flash using @ref pds_peer_data_iterate. + * Call this function once each time before iterating using @ref pds_peer_data_iterate. + */ +void pds_peer_data_iterate_prepare(void); + + +/**@brief Function for iterating peers' data in flash. + * Always call @ref pds_peer_data_iterate_prepare before starting iterating. + * + * @param[in] data_id The peer data to iterate over. + * @param[out] p_peer_id The peer the data belongs to. + * @param[out] p_data The peer data in flash. + * + * @retval true If the operation was successful. + * @retval false If the data was not found in flash, or another error occurred. + */ +bool pds_peer_data_iterate(pm_peer_data_id_t data_id, + pm_peer_id_t * const p_peer_id, + pm_peer_data_flash_t * const p_data); + + +/**@brief Function for reserving space in flash to store data. + * + * @param[in] p_peer_data The data to be stored in flash. Only data length and type (ID) are + * relevant for this operation. May not be @c NULL. + * @param[out] p_prepare_token A token identifying the reserved space. May not be @c NULL. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_PARAM If the data ID in @p p_peer_data is invalid. + * @retval NRF_ERROR_INVALID_LENGTH If data length exceeds the maximum allowed length. + * @retval NRF_ERROR_STORAGE_FULL If no space is available in flash. + * @retval NRF_ERROR_INTERNAL If an unexpected error occurred. + */ +ret_code_t pds_space_reserve(pm_peer_data_const_t const * p_peer_data, + pm_prepare_token_t * p_prepare_token); + + +/**@brief Function for undoing a previous call to @ref pds_space_reserve. + * + * @param[in] prepare_token A token identifying the reservation to cancel. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INTERNAL If an unexpected error occurred. + */ +ret_code_t pds_space_reserve_cancel(pm_prepare_token_t prepare_token); + + +/**@brief Function for storing peer data in flash. If the same piece of data already exists for the + * given peer, it will be updated. This operation is asynchronous. + * Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE event. + * + * @param[in] peer_id The peer the data belongs to. + * @param[in] p_peer_data The peer data. May not be @c NULL. + * @param[in] prepare_token A token identifying the reservation made in flash to store the data. + * Pass @ref PDS_PREPARE_TOKEN_INVALID if no space was reserved. + * @param[out] p_store_token A token identifying this particular store operation. The token can be + * used to identify events pertaining to this operation. Pass @p NULL + * if not used. + * + * @retval NRF_SUCCESS If the operation was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM If @p peer_id or the data ID in @p_peer_data are invalid. + * @retval NRF_ERROR_STORAGE_FULL If no space is available in flash. This can only happen if + * @p p_prepare_token is @ref PDS_PREPARE_TOKEN_INVALID. + * @retval NRF_ERROR_BUSY If the flash filesystem was busy. + * @retval NRF_ERROR_INTERNAL If an unexpected error occurred. + */ +ret_code_t pds_peer_data_store(pm_peer_id_t peer_id, + pm_peer_data_const_t const * p_peer_data, + pm_prepare_token_t prepare_token, + pm_store_token_t * p_store_token); + + +/**@brief Function for deleting peer data in flash. This operation is asynchronous. + * Expect a @ref PDS_EVT_CLEARED or @ref PDS_EVT_ERROR_CLEAR event. + * + * @param[in] peer_id The peer the data belongs to + * @param[in] data_id The data to delete. + * + * @retval NRF_SUCCESS If the operation was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM If @p peer_id or @p data_id are invalid. + * @retval NRF_ERROR_NOT_FOUND If data was not found in flash. + * @retval NRF_ERROR_BUSY If the flash filesystem was busy. + * @retval NRF_ERROR_INTERNAL If an unexpected error occurred. + */ +ret_code_t pds_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id); + + +/**@brief Function for claiming an unused peer ID. + * + * @retval PM_PEER_ID_INVALID If no peer ID was available. + */ +pm_peer_id_t pds_peer_id_allocate(void); + + +/**@brief Function for freeing a peer ID and deleting all data associated with it in flash. + * + * @param[in] peer_id The ID of the peer to free. + * + * @retval NRF_SUCCESS The operation was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM If @p peer_id is invalid. + */ +ret_code_t pds_peer_id_free(pm_peer_id_t peer_id); + + +/**@brief Function for finding out whether a peer ID is in use. + * + * @param[in] peer_id The peer ID to inquire about. + * + * @retval true @p peer_id is in use. + * @retval false @p peer_id is free. + */ +bool pds_peer_id_is_allocated(pm_peer_id_t peer_id); + + +/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be + * used to loop through all used peer IDs. + * + * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary + * peer ID. + * + * @param[in] prev_peer_id The previous peer ID. + * + * @return The first ordinary peer ID If @p prev_peer_id is @ref PM_PEER_ID_INVALID. + * @retval PM_PEER_ID_INVALID If @p prev_peer_id is the last ordinary peer ID or the module + * is not initialized. + */ +pm_peer_id_t pds_next_peer_id_get(pm_peer_id_t prev_peer_id); + + +/**@brief Function for getting the next peer ID in the sequence of all peer IDs pending deletion. + * Can be used to loop through all used peer IDs. + * + * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary + * peer ID. + * + * @param[in] prev_peer_id The previous peer ID. + * + * @return The next peer ID pending deletion. + * @return The first ordinary peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID. + * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID or the module + * is not initialized. + */ +pm_peer_id_t pds_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id); + + +/**@brief Function for querying the number of valid peer IDs available. I.E the number of peers + * in persistent storage. + * + * @return The number of valid peer IDs. + */ +uint32_t pds_peer_count_get(void); + + +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* PEER_DATA_STORAGE_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_database.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_database.c new file mode 100644 index 0000000000000000000000000000000000000000..e81b31d690b4b9f15b553890c509b0c66d114afc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_database.c @@ -0,0 +1,783 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) +#include "peer_database.h" + +#include +#include "peer_manager_types.h" +#include "peer_manager_internal.h" +#include "peer_data_storage.h" +#include "pm_buffer.h" + + +#define N_WRITE_BUFFERS (8) /**< The number of write buffers available. */ +#define N_WRITE_BUFFER_RECORDS (N_WRITE_BUFFERS) /**< The number of write buffer records. */ + + +/**@brief Macro for verifying that the data ID is among the values eligible for using the write buffer. + * + * @param[in] data_id The data ID to verify. + */ +// @note emdi: could this maybe be a function? +#define VERIFY_DATA_ID_WRITE_BUF(data_id) \ +do \ +{ \ + if (((data_id) != PM_PEER_DATA_ID_BONDING) && ((data_id) != PM_PEER_DATA_ID_GATT_LOCAL)) \ + { \ + return NRF_ERROR_INVALID_PARAM; \ + } \ +} while (0) + + +// The number of registered event handlers. +#define PDB_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0])) + + +// Peer Database event handlers in other Peer Manager submodules. +extern void pm_pdb_evt_handler(pdb_evt_t const * p_event); +extern void im_pdb_evt_handler(pdb_evt_t const * p_event); +extern void sm_pdb_evt_handler(pdb_evt_t const * p_event); +extern void smd_pdb_evt_handler(pdb_evt_t const * p_event); +extern void gscm_pdb_evt_handler(pdb_evt_t const * p_event); + +// Peer Database events' handlers. +// The number of elements in this array is PDB_EVENT_HANDLERS_CNT. +static pdb_evt_handler_t const m_evt_handlers[] = +{ + pm_pdb_evt_handler, + im_pdb_evt_handler, + sm_pdb_evt_handler, + smd_pdb_evt_handler, + gscm_pdb_evt_handler, +}; + + +/**@brief Struct for keeping track of one write buffer, from allocation, until it is fully written + * or cancelled. + */ +typedef struct +{ + pm_peer_id_t peer_id; /**< The peer ID this buffer belongs to. */ + pm_peer_data_id_t data_id; /**< The data ID this buffer belongs to. */ + pm_prepare_token_t prepare_token; /**< Token given by Peer Data Storage if room in flash has been reserved. */ + pm_store_token_t store_token; /**< Token given by Peer Data Storage when a flash write has been successfully requested. */ + uint32_t n_bufs; /**< The number of buffer blocks containing peer data. */ + uint8_t buffer_block_id; /**< The index of the first (or only) buffer block containing peer data. */ + uint8_t store_requested : 1; /**< Flag indicating that the buffer is being written to flash. */ + uint8_t store_flash_full : 1; /**< Flag indicating that the buffer was attempted written to flash, but a flash full error was returned and the operation should be retried after room has been made. */ + uint8_t store_busy : 1; /**< Flag indicating that the buffer was attempted written to flash, but a busy error was returned and the operation should be retried. */ +} pdb_buffer_record_t; + + +static bool m_module_initialized; +static pm_buffer_t m_write_buffer; /**< The state of the write buffer. */ +static pdb_buffer_record_t m_write_buffer_records[N_WRITE_BUFFER_RECORDS]; /**< The available write buffer records. */ +static uint32_t m_n_writes; /**< The number of pending (Not yet successfully requested in Peer Data Storage) store operations. */ + + + +/**@brief Function for invalidating a record of a write buffer allocation. + * + * @param[in] p_record The record to invalidate. + */ +static void write_buffer_record_invalidate(pdb_buffer_record_t * p_record) +{ + p_record->peer_id = PM_PEER_ID_INVALID; + p_record->data_id = PM_PEER_DATA_ID_INVALID; + p_record->buffer_block_id = PM_BUFFER_INVALID_ID; + p_record->store_busy = false; + p_record->store_flash_full = false; + p_record->store_requested = false; + p_record->n_bufs = 0; + p_record->prepare_token = PDS_PREPARE_TOKEN_INVALID; + p_record->store_token = PM_STORE_TOKEN_INVALID; +} + + +/**@brief Function for finding a record of a write buffer allocation. + * + * @param[in] peer_id The peer ID in the record. + * @param[inout] p_index In: The starting index, out: The index of the record + * + * @return A pointer to the matching record, or NULL if none was found. + */ +static pdb_buffer_record_t * write_buffer_record_find_next(pm_peer_id_t peer_id, int * p_index) +{ + for (uint32_t i = *p_index; i < N_WRITE_BUFFER_RECORDS; i++) + { + if ((m_write_buffer_records[i].peer_id == peer_id)) + { + return &m_write_buffer_records[i]; + } + } + return NULL; +} + + +/**@brief Function for finding a record of a write buffer allocation. + * + * @param[in] peer_id The peer ID in the record. + * @param[in] data_id The data ID in the record. + * + * @return A pointer to the matching record, or NULL if none was found. + */ +static pdb_buffer_record_t * write_buffer_record_find(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id) +{ + int index = 0; + pdb_buffer_record_t * p_record = write_buffer_record_find_next(peer_id, &index); + + while ((p_record != NULL) && (p_record->data_id != data_id)) + { + index++; + p_record = write_buffer_record_find_next(peer_id, &index); + } + + return p_record; +} + + +/**@brief Function for finding an available record for write buffer allocation. + * + * @return A pointer to the available record, or NULL if none was found. + */ +static pdb_buffer_record_t * write_buffer_record_find_unused(void) +{ + return write_buffer_record_find(PM_PEER_ID_INVALID, PM_PEER_DATA_ID_INVALID); +} + + +/**@brief Function for gracefully deactivating a write buffer record. + * + * @details This function will first release any buffers, then invalidate the record. + * + * @param[inout] p_write_buffer_record The record to release. + * + * @return A pointer to the matching record, or NULL if none was found. + */ +static void write_buffer_record_release(pdb_buffer_record_t * p_write_buffer_record) +{ + for (uint32_t i = 0; i < p_write_buffer_record->n_bufs; i++) + { + pm_buffer_release(&m_write_buffer, p_write_buffer_record->buffer_block_id + i); + } + + write_buffer_record_invalidate(p_write_buffer_record); +} + + +/**@brief Function for claiming and activating a write buffer record. + * + * @param[out] pp_write_buffer_record The claimed record. + * @param[in] peer_id The peer ID this record should have. + * @param[in] data_id The data ID this record should have. + */ +static void write_buffer_record_get(pdb_buffer_record_t ** pp_write_buffer_record, pm_peer_id_t peer_id, pm_peer_data_id_t data_id) +{ + if (pp_write_buffer_record == NULL) + { + return; + } + *pp_write_buffer_record = write_buffer_record_find_unused(); + if (*pp_write_buffer_record == NULL) + { + // This also means the buffer is full. + return; + } + (*pp_write_buffer_record)->peer_id = peer_id; + (*pp_write_buffer_record)->data_id = data_id; +} + + +/**@brief Function for dispatching outbound events to all registered event handlers. + * + * @param[in] p_event The event to dispatch. + */ +static void pdb_evt_send(pdb_evt_t * p_event) +{ + for (uint32_t i = 0; i < PDB_EVENT_HANDLERS_CNT; i++) + { + m_evt_handlers[i](p_event); + } +} + + +/**@brief Function for resetting the internal state of the Peer Database module. + * + * @param[out] p_event The event to dispatch. + */ +static void internal_state_reset() +{ + for (uint32_t i = 0; i < N_WRITE_BUFFER_RECORDS; i++) + { + write_buffer_record_invalidate(&m_write_buffer_records[i]); + } +} + + +/**@brief Function for handling events from the Peer Data Storage module. + * This function is extern in Peer Data Storage. + * + * @param[in] p_event The event to handle. + */ +void pdb_pds_evt_handler(pds_evt_t const * p_event) +{ + ret_code_t err_code; + pdb_buffer_record_t * p_write_buffer_record; + bool retry_flash_full = false; + pdb_evt_t event = + { + .peer_id = p_event->peer_id, + .data_id = p_event->data_id, + }; + + p_write_buffer_record = write_buffer_record_find(p_event->peer_id, p_event->data_id); + + switch (p_event->evt_id) + { + case PDS_EVT_STORED: + case PDS_EVT_UPDATED: + if ( (p_write_buffer_record != NULL) + //&& (p_write_buffer_record->store_token == p_event->store_token) + && (p_write_buffer_record->store_requested)) + { + write_buffer_record_release(p_write_buffer_record); + event.evt_id = PDB_EVT_WRITE_BUF_STORED; + event.params.write_buf_stored_evt.update = (p_event->evt_id == PDS_EVT_UPDATED); + pdb_evt_send(&event); + } + else + { + event.evt_id = PDB_EVT_RAW_STORED; + event.params.raw_stored_evt.store_token = p_event->store_token; + pdb_evt_send(&event); + } + break; + case PDS_EVT_ERROR_STORE: + case PDS_EVT_ERROR_UPDATE: + if ( (p_write_buffer_record != NULL) + && (p_write_buffer_record->store_token == p_event->store_token) + && (p_write_buffer_record->store_requested)) + { + // Retry if internal buffer. + m_n_writes++; + p_write_buffer_record->store_requested = false; + p_write_buffer_record->store_busy = true; + } + else + { + event.evt_id = PDB_EVT_RAW_STORE_FAILED; + event.params.error_raw_store_evt.err_code = p_event->result; + pdb_evt_send(&event); + } + break; + case PDS_EVT_CLEARED: + event.evt_id = PDB_EVT_CLEARED; + pdb_evt_send(&event); + break; + case PDS_EVT_ERROR_CLEAR: + event.evt_id = PDB_EVT_CLEAR_FAILED; + event.params.clear_failed_evt.err_code = p_event->result; + pdb_evt_send(&event); + break; + case PDS_EVT_PEER_ID_CLEAR: + event.evt_id = PDB_EVT_PEER_FREED; + pdb_evt_send(&event); + break; + case PDS_EVT_ERROR_PEER_ID_CLEAR: + event.evt_id = PDB_EVT_PEER_FREE_FAILED; + event.params.peer_free_failed_evt.err_code = p_event->result; + pdb_evt_send(&event); + break; + case PDS_EVT_COMPRESSED: + retry_flash_full = true; + event.evt_id = PDB_EVT_COMPRESSED; + pdb_evt_send(&event); + break; + case PDS_EVT_ERROR_UNEXPECTED: + event.params.error_unexpected.err_code = p_event->result; + break; + default: + break; + } + + if (m_n_writes > 0) + { + for (uint32_t i = 0; i < N_WRITE_BUFFER_RECORDS; i++) + { + if ((m_write_buffer_records[i].store_busy) + || (m_write_buffer_records[i].store_flash_full && retry_flash_full)) + { + err_code = pdb_write_buf_store(m_write_buffer_records[i].peer_id, + m_write_buffer_records[i].data_id); + if (err_code != NRF_SUCCESS) + { + event.peer_id = m_write_buffer_records[i].peer_id; + event.data_id = m_write_buffer_records[i].data_id; + if (err_code == NRF_ERROR_STORAGE_FULL) + { + event.evt_id = PDB_EVT_ERROR_NO_MEM; + } + else + { + event.evt_id = PDB_EVT_ERROR_UNEXPECTED; + event.params.error_unexpected.err_code = err_code; + } + + pdb_evt_send(&event); + break; + } + } + } + } +} + + +ret_code_t pdb_init() +{ + ret_code_t ret; + + NRF_PM_DEBUG_CHECK(!m_module_initialized); + + internal_state_reset(); + + PM_BUFFER_INIT(&m_write_buffer, N_WRITE_BUFFERS, PDB_WRITE_BUF_SIZE, ret); + + if (ret != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + m_module_initialized = true; + + return NRF_SUCCESS; +} + + +pm_peer_id_t pdb_peer_allocate(void) +{ + #if 0 + if (!MODULE_INITIALIZED) + { + return PM_PEER_ID_INVALID; + } + #endif + + NRF_PM_DEBUG_CHECK(m_module_initialized); + return pds_peer_id_allocate(); +} + + +ret_code_t pdb_peer_free(pm_peer_id_t peer_id) +{ + ret_code_t err_code_in = NRF_SUCCESS; + ret_code_t err_code_out = NRF_SUCCESS; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + + int index = 0; + pdb_buffer_record_t * p_record = write_buffer_record_find_next(peer_id, &index); + + while (p_record != NULL) + { + err_code_in = pdb_write_buf_release(peer_id, p_record->data_id); + + if ( (err_code_in != NRF_SUCCESS) + && (err_code_in != NRF_ERROR_NOT_FOUND)) + { + err_code_out = NRF_ERROR_INTERNAL; + } + + index++; + p_record = write_buffer_record_find_next(peer_id, &index); + } + + if (err_code_out == NRF_SUCCESS) + { + err_code_in = pds_peer_id_free(peer_id); + + if (err_code_in == NRF_SUCCESS) + { + // No action needed. + } + else if (err_code_in == NRF_ERROR_INVALID_PARAM) + { + err_code_out = NRF_ERROR_INVALID_PARAM; + } + else + { + err_code_out = NRF_ERROR_INTERNAL; + } + } + + return err_code_out; +} + + +ret_code_t pdb_peer_data_ptr_get(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + pm_peer_data_flash_t * const p_peer_data) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_peer_data != NULL); + + // Pass NULL to only retrieve a pointer. + return pds_peer_data_read(peer_id, data_id, (pm_peer_data_t*)p_peer_data, NULL); +} + + +static void peer_data_point_to_buffer(pm_peer_data_t * p_peer_data, pm_peer_data_id_t data_id, uint8_t * p_buffer_memory, uint16_t n_bufs) +{ + uint16_t n_bytes = n_bufs * PDB_WRITE_BUF_SIZE; + p_peer_data->data_id = data_id; + + p_peer_data->p_all_data = (pm_peer_data_bonding_t *)p_buffer_memory; + p_peer_data->length_words = BYTES_TO_WORDS(n_bytes); +} + + +static void peer_data_const_point_to_buffer(pm_peer_data_const_t * p_peer_data, pm_peer_data_id_t data_id, uint8_t * p_buffer_memory, uint32_t n_bufs) +{ + peer_data_point_to_buffer((pm_peer_data_t*)p_peer_data, data_id, p_buffer_memory, n_bufs); +} + + +static void write_buf_length_words_set(pm_peer_data_const_t * p_peer_data) +{ + switch (p_peer_data->data_id) + { + case PM_PEER_DATA_ID_BONDING: + p_peer_data->length_words = PM_BONDING_DATA_N_WORDS(); + break; + case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING: + p_peer_data->length_words = PM_SC_STATE_N_WORDS(); + break; + case PM_PEER_DATA_ID_PEER_RANK: + p_peer_data->length_words = PM_USAGE_INDEX_N_WORDS(); + break; + case PM_PEER_DATA_ID_GATT_LOCAL: + p_peer_data->length_words = PM_LOCAL_DB_N_WORDS(p_peer_data->p_local_gatt_db->len); + break; + default: + // No action needed. + break; + } +} + + +ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + uint32_t n_bufs, + pm_peer_data_t * p_peer_data) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + VERIFY_PARAM_NOT_NULL(p_peer_data); + VERIFY_DATA_ID_WRITE_BUF(data_id); + + if ( (n_bufs == 0) + || (n_bufs > N_WRITE_BUFFERS) + || !pds_peer_id_is_allocated(peer_id)) + { + return NRF_ERROR_INVALID_PARAM; + } + + pdb_buffer_record_t * write_buffer_record; + uint8_t * p_buffer_memory; + bool new_record = false; + + write_buffer_record = write_buffer_record_find(peer_id, data_id); + + if ((write_buffer_record != NULL) && (write_buffer_record->n_bufs < n_bufs)) + { + // @TODO: Copy? + // Existing buffer is too small. + for (uint8_t i = 0; i < write_buffer_record->n_bufs; i++) + { + pm_buffer_release(&m_write_buffer, write_buffer_record->buffer_block_id + i); + } + write_buffer_record_invalidate(write_buffer_record); + write_buffer_record = NULL; + } + else if ((write_buffer_record != NULL) && write_buffer_record->n_bufs > n_bufs) + { + // Release excess blocks. + for (uint8_t i = n_bufs; i < write_buffer_record->n_bufs; i++) + { + pm_buffer_release(&m_write_buffer, write_buffer_record->buffer_block_id + i); + } + } + + if (write_buffer_record == NULL) + { + write_buffer_record_get(&write_buffer_record, peer_id, data_id); + if (write_buffer_record == NULL) + { + return NRF_ERROR_BUSY; + } + } + + if (write_buffer_record->buffer_block_id == PM_BUFFER_INVALID_ID) + { + write_buffer_record->buffer_block_id = pm_buffer_block_acquire(&m_write_buffer, n_bufs); + + if (write_buffer_record->buffer_block_id == PM_BUFFER_INVALID_ID) + { + write_buffer_record_invalidate(write_buffer_record); + return NRF_ERROR_BUSY; + } + + new_record = true; + } + + write_buffer_record->n_bufs = n_bufs; + + p_buffer_memory = pm_buffer_ptr_get(&m_write_buffer, write_buffer_record->buffer_block_id); + + if (p_buffer_memory == NULL) + { + return NRF_ERROR_INTERNAL; + } + + peer_data_point_to_buffer(p_peer_data, data_id, p_buffer_memory, n_bufs); + if (new_record && (data_id == PM_PEER_DATA_ID_GATT_LOCAL)) + { + p_peer_data->p_local_gatt_db->len = PM_LOCAL_DB_LEN(p_peer_data->length_words); + } + + return NRF_SUCCESS; +} + + +ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + ret_code_t err_code = NRF_SUCCESS; + pdb_buffer_record_t * p_write_buffer_record; + p_write_buffer_record = write_buffer_record_find(peer_id, data_id); + + if (p_write_buffer_record == NULL) + { + return NRF_ERROR_NOT_FOUND; + } + + if (p_write_buffer_record->prepare_token != PDS_PREPARE_TOKEN_INVALID) + { + err_code = pds_space_reserve_cancel(p_write_buffer_record->prepare_token); + if (err_code != NRF_SUCCESS) + { + err_code = NRF_ERROR_INTERNAL; + } + } + + write_buffer_record_release(p_write_buffer_record); + + return err_code; +} + + +ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + VERIFY_DATA_ID_WRITE_BUF(data_id); + + ret_code_t err_code = NRF_SUCCESS; + pdb_buffer_record_t * p_write_buffer_record; + p_write_buffer_record = write_buffer_record_find(peer_id, data_id); + + if (p_write_buffer_record == NULL) + { + return NRF_ERROR_NOT_FOUND; + } + + if (p_write_buffer_record->prepare_token == PDS_PREPARE_TOKEN_INVALID) + { + uint8_t * p_buffer_memory = pm_buffer_ptr_get(&m_write_buffer, p_write_buffer_record->buffer_block_id); + pm_peer_data_const_t peer_data = {.data_id = data_id}; + + if (p_buffer_memory == NULL) + { + return NRF_ERROR_INTERNAL; + } + + peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs); + + write_buf_length_words_set(&peer_data); + + err_code = pds_space_reserve(&peer_data, &p_write_buffer_record->prepare_token); + if (err_code == NRF_ERROR_INVALID_LENGTH) + { + return NRF_ERROR_INTERNAL; + } + } + + return err_code; +} + + +ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + VERIFY_DATA_ID_WRITE_BUF(data_id); + + ret_code_t err_code = NRF_SUCCESS; + pdb_buffer_record_t * p_write_buffer_record; + uint8_t * p_buffer_memory; + pm_peer_data_const_t peer_data = {.data_id = data_id}; + + + p_write_buffer_record = write_buffer_record_find(peer_id, data_id); + + if (p_write_buffer_record == NULL) + { + return NRF_ERROR_NOT_FOUND; + } + + if (p_write_buffer_record->store_requested) + { + return NRF_SUCCESS; + } + + p_buffer_memory = pm_buffer_ptr_get(&m_write_buffer, p_write_buffer_record->buffer_block_id); + + if (p_buffer_memory == NULL) + { + return NRF_ERROR_INTERNAL; + } + + peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs); + + write_buf_length_words_set(&peer_data); + + err_code = pds_peer_data_store(peer_id, + &peer_data, + p_write_buffer_record->prepare_token, + &p_write_buffer_record->store_token); + + if (p_write_buffer_record->store_busy && p_write_buffer_record->store_flash_full) + { + m_n_writes--; + } + + if (err_code == NRF_SUCCESS) + { + p_write_buffer_record->store_requested = true; + p_write_buffer_record->store_busy = false; + p_write_buffer_record->store_flash_full = false; + } + else + { + if (err_code == NRF_ERROR_BUSY) + { + m_n_writes++; + p_write_buffer_record->store_busy = true; + p_write_buffer_record->store_flash_full = false; + err_code = NRF_SUCCESS; + } + else if (err_code == NRF_ERROR_STORAGE_FULL) + { + m_n_writes++; + p_write_buffer_record->store_busy = false; + p_write_buffer_record->store_flash_full = true; + } + else if (err_code != NRF_ERROR_INVALID_PARAM) + { + err_code = NRF_ERROR_INTERNAL; + } + } + + return err_code; +} + + +ret_code_t pdb_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + return pds_peer_data_delete(peer_id, data_id); +} + + +uint32_t pdb_n_peers(void) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + return pds_peer_count_get(); +} + + +pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + return pds_next_peer_id_get(prev_peer_id); +} + + +pm_peer_id_t pdb_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + return pds_next_deleted_peer_id_get(prev_peer_id); +} + + +ret_code_t pdb_peer_data_load(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + pm_peer_data_t * const p_peer_data) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_peer_data != NULL); + + // Provide the buffer length in bytes. + uint32_t const data_len_bytes = (p_peer_data->length_words * sizeof(uint32_t)); + return pds_peer_data_read(peer_id, data_id, p_peer_data, &data_len_bytes); +} + + +ret_code_t pdb_raw_store(pm_peer_id_t peer_id, + pm_peer_data_const_t * p_peer_data, + pm_store_token_t * p_store_token) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + return pds_peer_data_store(peer_id, p_peer_data, PDS_PREPARE_TOKEN_INVALID, p_store_token); +} +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_database.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_database.h new file mode 100644 index 0000000000000000000000000000000000000000..d2b0116e4d6484f3ddf2d40dbd2a8196ed11bdd4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_database.h @@ -0,0 +1,393 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef PEER_DATABASE_H__ +#define PEER_DATABASE_H__ + +#include +#include "peer_manager_types.h" +#include "peer_manager_internal.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @cond NO_DOXYGEN + * @defgroup peer_database Peer Database + * @ingroup peer_manager + * @{ + * @brief An internal module of @ref peer_manager. A module for simple management of reading and + * writing of peer data into persistent storage. + * + */ + +#define PDB_WRITE_BUF_SIZE (sizeof(pm_peer_data_bonding_t)) //!< The size (in bytes) of each block in the internal buffer accessible via @ref pdb_write_buf_get. + +/**@brief Events that can come from the peer_database module. + */ +typedef enum +{ + PDB_EVT_WRITE_BUF_STORED, /**< A @ref pdb_write_buf_store operation has completed successfully. */ + PDB_EVT_RAW_STORED, /**< A @ref pdb_raw_store operation has completed successfully. */ + PDB_EVT_RAW_STORE_FAILED, /**< A @ref pdb_raw_store operation has failed. */ + PDB_EVT_CLEARED, /**< A @ref pdb_clear operation has completed successfully. */ + PDB_EVT_CLEAR_FAILED, /**< A @ref pdb_clear operation has failed. */ + PDB_EVT_PEER_FREED, /**< A @ref pdb_peer_free operation has completed successfully. All associated data has been erased. */ + PDB_EVT_PEER_FREE_FAILED, /**< A @ref pdb_peer_free operation has failed. */ + PDB_EVT_COMPRESSED, /**< A compress procedure has completed. */ + PDB_EVT_ERROR_NO_MEM, /**< An operation is blocked because the flash is full. It will be reattempted automatically after the next compress procedure. */ + PDB_EVT_ERROR_UNEXPECTED, /**< An unexpected error occurred. This is a fatal error. */ +} pdb_evt_id_t; + +/**@brief Events that can come from the peer_database module. + */ +typedef struct +{ + pdb_evt_id_t evt_id; /**< The event that has happened. */ + pm_peer_id_t peer_id; /**< The id of the peer the event pertains to. */ + pm_peer_data_id_t data_id; /**< The data the event pertains to. */ + union + { + struct + { + bool update; /**< If true, an existing value was overwritten. */ + } write_buf_stored_evt; /**< Additional information pertaining to the @ref PDB_EVT_WRITE_BUF_STORED event. */ + struct + { + pm_store_token_t store_token; /**< A token identifying the store operation this event pertains to. */ + } raw_stored_evt; /**< Additional information pertaining to the @ref PDB_EVT_RAW_STORED event. */ + struct + { + pm_store_token_t store_token; /**< A token identifying the store operation this event pertains to. */ + ret_code_t err_code; /**< Error code specifying what went wrong. */ + } error_raw_store_evt; /**< Additional information pertaining to the @ref PDB_EVT_RAW_STORE_FAILED event. */ + struct + { + ret_code_t err_code; /**< The error that occurred. */ + } clear_failed_evt; /**< Additional information pertaining to the @ref PDB_EVT_CLEAR_FAILED event. */ + struct + { + ret_code_t err_code; /**< The error that occurred. */ + } peer_free_failed_evt; /**< Additional information pertaining to the @ref PDB_EVT_PEER_FREE_FAILED event. */ + struct + { + ret_code_t err_code; /**< The unexpected error that occurred. */ + } error_unexpected; /**< Additional information pertaining to the @ref PDB_EVT_ERROR_UNEXPECTED event. */ + } params; +} pdb_evt_t; + +/**@brief Event handler for events from the peer_data_storage module. + * + * @param[in] p_event The event that has happened. + */ +typedef void (*pdb_evt_handler_t)(pdb_evt_t const * p_event); + + +/**@brief Function for initializing the module. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INTERNAL An unexpected error happened. + */ +ret_code_t pdb_init(void); + + +/**@brief Function for allocating persistent bond storage for a peer. + * + * @return The ID of the newly allocated storage. + * @retval PM_PEER_ID_INVALID If no peer ID is available. + */ +pm_peer_id_t pdb_peer_allocate(void); + + +/**@brief Function for freeing a peer's persistent bond storage. + * + * @note This function will call @ref pdb_write_buf_release on the data for this peer. + * + * @param[in] peer_id ID to be freed. + * + * @retval NRF_SUCCESS Peer ID was released and clear operation was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM Peer ID was invalid. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + */ +ret_code_t pdb_peer_free(pm_peer_id_t peer_id); + + +/**@brief Function for retrieving a pointer to peer data in flash (read-only). + * + * @note Dereferencing this pointer is not the safest thing to do if interrupts are enabled, + * because Flash Data Storage garbage collection might move the data around. Either disable + * interrupts while using the data, or use @ref pdb_peer_data_load. + * + * @param[in] peer_id The peer the data belongs to. + * @param[in] data_id The data to read. + * @param[out] p_peer_data The peer data, read-only. + * + * @retval NRF_SUCCESS If the pointer to the data was retrieved successfully. + * @retval NRF_ERROR_INVALID_PARAM If either @p peer_id or @p data_id are invalid. + * @retval NRF_ERROR_NOT_FOUND If data was not found in flash. + */ +ret_code_t pdb_peer_data_ptr_get(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + pm_peer_data_flash_t * const p_peer_data); + + +/**@brief Function for retrieving pointers to a write buffer for peer data. + * + * @details This function will provide pointers to a buffer of the data. The data buffer will not be + * written to persistent storage until @ref pdb_write_buf_store is called. The buffer is + * released by calling either @ref pdb_write_buf_release, @ref pdb_write_buf_store, or + * @ref pdb_peer_free. + * + * When the data_id refers to a variable length data type, the available size is written + * to the data, both the top-level, and any internal length fields. + * + * @note Calling this function on a peer_id/data_id pair that already has a buffer created will + * give the same buffer, not create a new one. If n_bufs was increased since last time, the + * buffer might be relocated to be able to provide additional room. In this case, the data + * will be copied. If n_bufs was increased since last time, this function might return @ref + * NRF_ERROR_BUSY. In that case, the buffer is automatically released. + * + * @param[in] peer_id ID of peer to get a write buffer for. + * @param[in] data_id Which piece of data to get. + * @param[in] n_bufs The number of contiguous buffers needed. + * @param[out] p_peer_data Pointers to mutable peer data. + * + * @retval NRF_SUCCESS Data retrieved successfully. + * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated, or n_bufs was 0 + * or more than the total available buffers. + * @retval NRF_ERROR_NULL p_peer_data was NULL. + * @retval NRF_ERROR_BUSY Not enough buffer(s) available. + * @retval NRF_ERROR_INTERNAL Unexpected internal error. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + */ +ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + uint32_t n_bufs, + pm_peer_data_t * p_peer_data); + + +/**@brief Function for freeing a write buffer allocated with @ref pdb_write_buf_get. + * + * @note This function will not write peer data to persistent memory. Data in released buffer will + * be lost. + * + * @note This function will undo any previous call to @ref pdb_write_buf_store_prepare for this + * piece of data. + * + * @param[in] peer_id ID of peer to release buffer for. + * @param[in] data_id Which piece of data to release buffer for. + * + * @retval NRF_SUCCESS Successfully released buffer. + * @retval NRF_ERROR_NOT_FOUND No buffer was allocated for this peer ID/data ID pair. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @retval NRF_ERROR_INTERNAL Unexpected internal error. + */ +ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id); + + +/**@brief Function for reserving space in persistent storage for data in a buffer. + * + * @note This function only works for data which has a write buffer allocated. If the write buffer + * is released, this prepare is undone. + * + * @note If space has already been reserved for this data, nothing is done. + * + * @param[in] peer_id The peer whose data to reserve space for. + * @param[in] data_id The type of data to reserve space for. + * + * @retval NRF_SUCCESS Successfully reserved space in persistent storage. + * @retval NRF_ERROR_STORAGE_FULL Not enough room in persistent storage. + * @retval NRF_ERROR_BUSY Could not process request at this time. Reattempt later. + * @retval NRF_ERROR_NOT_FOUND No buffer has been allocated for this peer ID/data ID pair. + * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + */ +ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t data_id); + + +/**@brief Function for writing data into persistent storage. Writing happens asynchronously. + * + * @note This will unlock the data after it has been written. + * + * @param[in] peer_id ID of peer to store data for. + * @param[in] data_id Which piece of data to store. + * + * @retval NRF_SUCCESS Data storing was successfully started. + * @retval NRF_ERROR_STORAGE_FULL No space available in persistent storage. Please clear some + * space, the operation will be reattempted after the next compress + * procedure. This error will not happen if + * @ref pdb_write_buf_store_prepare is called beforehand. + * @retval NRF_ERROR_INVALID_PARAM Data ID was invalid. + * @retval NRF_ERROR_NOT_FOUND No buffer has been allocated for this peer ID/data ID pair. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @retval NRF_ERROR_INTERNAL Unexpected internal error. + */ +ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id); + + +/**@brief Function for clearing data from persistent storage. + * + * @param[in] peer_id ID of peer to clear data for. + * @param[in] data_id Which piece of data to clear. + * + * @retval NRF_SUCCESS The clear was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM Data ID or peer ID was invalid. + * @retval NRF_ERROR_NOT_FOUND Nothing to clear for this peer ID/data ID combination. + * @retval NRF_ERROR_BUSY Underlying modules are busy and can't take any more requests at + * this moment. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @retval NRF_ERROR_INTERNAL Internal error. + */ +ret_code_t pdb_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id); + + +/**@brief Function for querying the number of valid peer IDs available. I.E the number of peers + * in persistent storage. + * + * @return The number of valid peer IDs. + */ +uint32_t pdb_n_peers(void); + + +/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be + * used to loop through all used peer IDs. + * + * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary + * peer ID. + * + * @param[in] prev_peer_id The previous peer ID. + * + * @return The next peer ID. + * @return The first ordinary peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID. + * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID. + */ +pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id); + + +/**@brief Function for getting the next peer ID in the sequence of all peer IDs pending deletion. + * Can be used to loop through all used peer IDs. + * + * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary + * peer ID. + * + * @param[in] prev_peer_id The previous peer ID. + * + * @return The next peer ID pending deletion. + * @return The first ordinary peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID. + * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID. + */ +pm_peer_id_t pdb_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id); + + +/**@brief Function for updating currently stored peer data to a new version + * + * @details Updating happens asynchronously. + * Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE for the store token + * and a @ref PDS_EVT_ERROR_CLEAR or @ref PDS_EVT_ERROR_CLEAR for the old token + * + * @param[in] peer_data New data + * @param[in] old_token Store token for the old data + * @param[out] p_store_token Store token for the new data + * + * @retval NRF_SUCESS The update was initiated successfully + * @retval NRF_ERROR_NOT_FOUND The old store token was invalid. + * @retval NRF_ERROR_NULL Data contained a NULL pointer. + * @retval NRF_ERROR_STORAGE_FULL No space available in persistent storage. + * @retval NRF_ERROR_BUSY FDS or underlying modules are busy and can't take any + * more requests + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + */ +ret_code_t pdb_peer_data_update(pm_peer_data_const_t peer_data, + pm_store_token_t old_token, + pm_store_token_t * p_store_token); + + +/**@brief Function for copy peer data from flash into a provided buffer. + * + * @param[in] peer_id The peer the data belongs to. + * @param[in] data_id The data to read. + * @param[inout] p_peer_data The buffer where to copy data into. The field @c length_words in this + * parameter must represent the buffer length in words. + * + * @note Actually, it represents the buffer length in bytes upon entering the function, + * and upon exit it represents the length of the data in words.. not good. Fix this. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_PARAM If @p peer_id or @p data_id are invalid. + * @retval NRF_ERROR_NOT_FOUND If the data was not found in flash. + * @retval NRF_ERROR_NO_MEM If the provided buffer is too small. + */ +ret_code_t pdb_peer_data_load(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + pm_peer_data_t * const p_peer_data); + + +/**@brief Function for writing data directly to persistent storage from external memory. + * + * @param[in] peer_id ID of peer to write data for. + * @param[in] p_peer_data Data to store. + * @param[out] p_store_token A token identifying this particular store operation. The token can be + * used to identify events pertaining to this operation. + * + * @retval NRF_SUCCESS Data successfully written. + * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated. + * @retval NRF_ERROR_NULL p_peer_data contained a NULL pointer. + * @retval NRF_ERROR_STORAGE_FULL No space available in persistent storage. + * @retval NRF_ERROR_INVALID_LENGTH Data length above the maximum allowed. + * @retval NRF_ERROR_BUSY Unable to perform operation at this time. + */ +ret_code_t pdb_raw_store(pm_peer_id_t peer_id, + pm_peer_data_const_t * p_peer_data, + pm_store_token_t * p_store_token); + +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* PEER_DATABASE_H__ */ + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_id.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_id.c new file mode 100644 index 0000000000000000000000000000000000000000..06b0594c71d0e06625c21e4cdc5df340ec987305 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_id.c @@ -0,0 +1,202 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) +#include "peer_id.h" + +#include +#include +#include "sdk_errors.h" +#include "peer_manager_types.h" +#include "pm_mutex.h" + + +typedef struct +{ + uint8_t used_peer_ids[MUTEX_STORAGE_SIZE(PM_PEER_ID_N_AVAILABLE_IDS)]; /**< Bitmap designating which peer IDs are in use. */ + uint8_t deleted_peer_ids[MUTEX_STORAGE_SIZE(PM_PEER_ID_N_AVAILABLE_IDS)]; /**< Bitmap designating which peer IDs are marked for deletion. */ +} pi_t; + + +static pi_t m_pi = {{0}, {0}}; + + +static void internal_state_reset(pi_t * p_pi) +{ + memset(p_pi, 0, sizeof(pi_t)); +} + + +void peer_id_init(void) +{ + internal_state_reset(&m_pi); + pm_mutex_init(m_pi.used_peer_ids, PM_PEER_ID_N_AVAILABLE_IDS); + pm_mutex_init(m_pi.deleted_peer_ids, PM_PEER_ID_N_AVAILABLE_IDS); +} + + +static pm_peer_id_t claim(pm_peer_id_t peer_id, uint8_t * mutex_group) +{ + pm_peer_id_t allocated_peer_id = PM_PEER_ID_INVALID; + if (peer_id == PM_PEER_ID_INVALID) + { + allocated_peer_id = pm_mutex_lock_first_available(mutex_group, PM_PEER_ID_N_AVAILABLE_IDS); + if (allocated_peer_id == PM_PEER_ID_N_AVAILABLE_IDS) + { + allocated_peer_id = PM_PEER_ID_INVALID; + } + } + else if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS) + { + bool lock_success = pm_mutex_lock(mutex_group, peer_id); + allocated_peer_id = lock_success ? peer_id : PM_PEER_ID_INVALID; + } + return allocated_peer_id; +} + + +static void release(pm_peer_id_t peer_id, uint8_t * mutex_group) +{ + if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS) + { + pm_mutex_unlock(mutex_group, peer_id); + } +} + + +pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id) +{ + return claim(peer_id, m_pi.used_peer_ids); +} + + +bool peer_id_delete(pm_peer_id_t peer_id) +{ + pm_peer_id_t deleted_peer_id; + + if (peer_id == PM_PEER_ID_INVALID) + { + return false; + } + + deleted_peer_id = claim(peer_id, m_pi.deleted_peer_ids); + + return (deleted_peer_id == peer_id); +} + + +void peer_id_free(pm_peer_id_t peer_id) +{ + release(peer_id, m_pi.used_peer_ids); + release(peer_id, m_pi.deleted_peer_ids); +} + + +bool peer_id_is_allocated(pm_peer_id_t peer_id) +{ + if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS) + { + return pm_mutex_lock_status_get(m_pi.used_peer_ids, peer_id); + } + return false; +} + + +bool peer_id_is_deleted(pm_peer_id_t peer_id) +{ + if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS) + { + return pm_mutex_lock_status_get(m_pi.deleted_peer_ids, peer_id); + } + return false; +} + + +pm_peer_id_t next_id_get(pm_peer_id_t prev_peer_id, uint8_t * mutex_group) +{ + pm_peer_id_t i = (prev_peer_id == PM_PEER_ID_INVALID) ? 0 : (prev_peer_id + 1); + for (; i < PM_PEER_ID_N_AVAILABLE_IDS; i++) + { + if (pm_mutex_lock_status_get(mutex_group, i)) + { + return i; + } + } + + return PM_PEER_ID_INVALID; +} + + +pm_peer_id_t peer_id_get_next_used(pm_peer_id_t peer_id) +{ + peer_id = next_id_get(peer_id, m_pi.used_peer_ids); + + while (peer_id != PM_PEER_ID_INVALID) + { + if (!peer_id_is_deleted(peer_id)) + { + return peer_id; + } + + peer_id = next_id_get(peer_id, m_pi.used_peer_ids); + } + + return peer_id; +} + + +pm_peer_id_t peer_id_get_next_deleted(pm_peer_id_t prev_peer_id) +{ + return next_id_get(prev_peer_id, m_pi.deleted_peer_ids); +} + + +uint32_t peer_id_n_ids(void) +{ + uint32_t n_ids = 0; + + for (pm_peer_id_t i = 0; i < PM_PEER_ID_N_AVAILABLE_IDS; i++) + { + n_ids += pm_mutex_lock_status_get(m_pi.used_peer_ids, i); + } + + return n_ids; +} +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_id.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_id.h new file mode 100644 index 0000000000000000000000000000000000000000..5664ccc5743513294af68985371c2620e90b3eca --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_id.h @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef PEER_ID_H__ +#define PEER_ID_H__ + + +#include +#include "sdk_errors.h" +#include "ble_gap.h" +#include "peer_manager_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @cond NO_DOXYGEN + * @defgroup peer_id Peer IDs + * @ingroup peer_manager + * @{ + * @brief An internal module of @ref peer_manager. This module keeps track of which peer IDs are in + * use and which are free. + */ + + +/**@brief Function for initializing the module. + */ +void peer_id_init(void); + + +/**@brief Function for claiming an unused peer ID. + * + * @param peer_id The peer ID to allocate. If this is @ref PM_PEER_ID_INVALID, the first available + * will be allocated. + * + * @return The allocated peer ID. + * @retval PM_PEER_ID_INVALID If no peer ID could be allocated or module is not initialized. + */ +pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id); + + +/**@brief Function for marking a peer ID for deletion. + * + * @param peer_id The peer ID to delete. + * + * @retval true Deletion was successful. + * @retval false Peer ID already marked for deletion, peer_id was PM_PEER_ID_INVALID, or module is + * not initialized. + */ +bool peer_id_delete(pm_peer_id_t peer_id); + + +/**@brief Function for freeing a peer ID and clearing all data associated with it in persistent + * storage. + * + * @param[in] peer_id Peer ID to free. + */ +void peer_id_free(pm_peer_id_t peer_id); + + +/**@brief Function for finding out whether a peer ID is marked for deletion. + * + * @param[in] peer_id The peer ID to inquire about. + * + * @retval true peer_id is in marked for deletion. + * @retval false peer_id is not marked for deletion, or the module is not initialized. + */ +bool peer_id_is_deleted(pm_peer_id_t peer_id); + + +/**@brief Function for finding out whether a peer ID is in use. + * + * @param[in] peer_id The peer ID to inquire about. + * + * @retval true peer_id is in use. + * @retval false peer_id is free, or the module is not initialized. + */ +bool peer_id_is_allocated(pm_peer_id_t peer_id); + + +/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be + * used to loop through all used peer IDs. + * + * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary + * peer ID. + * + * @param[in] prev_peer_id The previous peer ID. + * + * @return The next peer ID. + * @return The first used peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID. + * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID or the module is + * not initialized. + */ +pm_peer_id_t peer_id_get_next_used(pm_peer_id_t prev_peer_id); + + +/**@brief Function for getting the next peer ID in the sequence of all peer IDs marked for deletion. + * Can be used to loop through all peer IDs marked for deletion. + * + * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary + * peer ID. + * + * @param[in] prev_peer_id The previous peer ID. + * + * @return The next peer ID. + * @return The first used peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID. + * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID or the module is + * not initialized. + */ +pm_peer_id_t peer_id_get_next_deleted(pm_peer_id_t prev_peer_id); + + +/**@brief Function for querying the number of valid peer IDs available. I.E the number of peers + * in persistent storage. + * + * @return The number of valid peer IDs, or 0 if module is not initialized. + */ +uint32_t peer_id_n_ids(void); + +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* PEER_ID_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_manager.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..a963294d446f685c0edb1991ed9fff35310a34a5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_manager.c @@ -0,0 +1,1136 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) +#include "peer_manager.h" +#include +#include "security_manager.h" +#include "security_dispatcher.h" +#include "gatt_cache_manager.h" +#include "gatts_cache_manager.h" +#include "peer_database.h" +#include "peer_data_storage.h" +#include "id_manager.h" +#include "ble_conn_state.h" +#include "peer_manager_internal.h" + +/**< The number of event handlers that can be registered with the module. */ +#define MAX_REGISTRANTS (3) +/**< Macro indicating whether the module has been initialized properly. */ +#define MODULE_INITIALIZED (m_module_initialized) + + +static bool m_module_initialized; /**< Whether or not @ref pm_init has been called successfully. */ +static bool m_peer_rank_initialized; /**< Whether or not @ref rank_init has been called successfully. */ +static bool m_deleting_all; /**< True from when @ref pm_peers_delete is called until all peers have been deleted. */ +static pm_store_token_t m_peer_rank_token; /**< The store token of an ongoing peer rank update via a call to @ref pm_peer_rank_highest. If @ref PM_STORE_TOKEN_INVALID, there is no ongoing update. */ +static uint32_t m_current_highest_peer_rank; /**< The current highest peer rank. Used by @ref pm_peer_rank_highest. */ +static pm_peer_id_t m_highest_ranked_peer; /**< The peer with the highest peer rank. Used by @ref pm_peer_rank_highest. */ +static pm_evt_handler_t m_evt_handlers[MAX_REGISTRANTS]; /**< The subscribers to Peer Manager events, as registered through @ref pm_register. */ +static uint8_t m_n_registrants; /**< The number of event handlers registered through @ref pm_register. */ +static ble_conn_state_user_flag_id_t m_pairing_flag_id; /**< The flag ID for which connections are paired. */ +static ble_conn_state_user_flag_id_t m_bonding_flag_id; /**< The flag ID for which connections are bonded. */ + + +/**@brief Function for sending a Peer Manager event to all subscribers. + * + * @param[in] p_pm_evt The event to send. + */ +static void evt_send(pm_evt_t * p_pm_evt) +{ + for (int i = 0; i < m_n_registrants; i++) + { + m_evt_handlers[i](p_pm_evt); + } +} + + +/**@brief Event handler for events from the Peer Database module. + * This handler is extern in the Peer Database module. + * + * @param[in] p_pdb_evt The incoming Peer Database event. + */ +void pm_pdb_evt_handler(pdb_evt_t const * p_pdb_evt) +{ + bool send_evt = true; + pm_evt_t pm_evt; + + memset(&pm_evt, 0, sizeof(pm_evt_t)); + pm_evt.peer_id = p_pdb_evt->peer_id; + pm_evt.conn_handle = im_conn_handle_get(pm_evt.peer_id); + + switch (p_pdb_evt->evt_id) + { + case PDB_EVT_WRITE_BUF_STORED: + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; + pm_evt.params.peer_data_update_succeeded.flash_changed = true; + break; + + case PDB_EVT_RAW_STORED: + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_succeeded.token + = p_pdb_evt->params.raw_stored_evt.store_token; + pm_evt.params.peer_data_update_succeeded.flash_changed = true; + + if ( (m_peer_rank_token != PM_STORE_TOKEN_INVALID) + && (m_peer_rank_token == p_pdb_evt->params.raw_stored_evt.store_token)) + { + m_peer_rank_token = PM_STORE_TOKEN_INVALID; + m_highest_ranked_peer = pm_evt.peer_id; + + pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; + } + break; + + case PDB_EVT_RAW_STORE_FAILED: + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED; + pm_evt.params.peer_data_update_failed.data_id = p_pdb_evt->data_id; + pm_evt.params.peer_data_update_failed.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_failed.token + = p_pdb_evt->params.error_raw_store_evt.store_token; + pm_evt.params.peer_data_update_failed.error + = p_pdb_evt->params.error_raw_store_evt.err_code; + + if ( (m_peer_rank_token != PM_STORE_TOKEN_INVALID) + && (m_peer_rank_token == p_pdb_evt->params.raw_stored_evt.store_token)) + { + m_peer_rank_token = PM_STORE_TOKEN_INVALID; + m_current_highest_peer_rank -= 1; + + pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; + } + break; + + case PDB_EVT_CLEARED: + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_DELETE; + pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; + break; + + case PDB_EVT_CLEAR_FAILED: + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED; + pm_evt.params.peer_data_update_failed.data_id = p_pdb_evt->data_id; + pm_evt.params.peer_data_update_failed.action = PM_PEER_DATA_OP_DELETE; + pm_evt.params.peer_data_update_failed.error + = p_pdb_evt->params.clear_failed_evt.err_code; + break; + + case PDB_EVT_PEER_FREED: + pm_evt.evt_id = PM_EVT_PEER_DELETE_SUCCEEDED; + // Check that no peers marked for deletion are left. + if (m_deleting_all + && (pdb_next_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID) + && (pdb_next_deleted_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID)) + { + // pm_peers_delete() has been called and this is the last peer to be deleted. + m_deleting_all = false; + + pm_evt_t pm_delete_all_evt; + memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t)); + pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_SUCCEEDED; + pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID; + pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID; + + evt_send(&pm_delete_all_evt); + } + break; + + case PDB_EVT_PEER_FREE_FAILED: + pm_evt.evt_id = PM_EVT_PEER_DELETE_FAILED; + pm_evt.params.peer_delete_failed.error + = p_pdb_evt->params.peer_free_failed_evt.err_code; + if (m_deleting_all) + { + // pm_peers_delete() has been called and has thus failed. + + m_deleting_all = false; + + pm_evt_t pm_delete_all_evt; + memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t)); + pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_FAILED; + pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID; + pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID; + pm_delete_all_evt.params.peers_delete_failed_evt.error + = p_pdb_evt->params.peer_free_failed_evt.err_code; + + evt_send(&pm_delete_all_evt); + } + break; + + case PDB_EVT_COMPRESSED: + send_evt = false; + // Do nothing + break; + + case PDB_EVT_ERROR_NO_MEM: + pm_evt.evt_id = PM_EVT_STORAGE_FULL; + break; + + case PDB_EVT_ERROR_UNEXPECTED: + pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED; + break; + + default: + send_evt = false; + break; + } + + if (send_evt) + { + evt_send(&pm_evt); + } +} + + +/**@brief Event handler for events from the Security Manager module. + * This handler is extern in the Security Manager module. + * + * @param[in] p_sm_evt The incoming Security Manager event. + */ +void pm_sm_evt_handler(sm_evt_t const * p_sm_evt) +{ + bool find_peer_id = true; + bool send_evt = true; + pm_evt_t pm_evt; + memset(&pm_evt, 0, sizeof(pm_evt_t)); + pm_evt.conn_handle = p_sm_evt->conn_handle; + + switch (p_sm_evt->evt_id) + { + case SM_EVT_SLAVE_SECURITY_REQ: + find_peer_id = false; + send_evt = false; + break; + + case SM_EVT_SEC_PROCEDURE_START: + { + pm_evt.evt_id = PM_EVT_CONN_SEC_START; + bool pairing = p_sm_evt->params.sec_procedure_start.procedure + != PM_LINK_SECURED_PROCEDURE_ENCRYPTION; + bool bonding = p_sm_evt->params.sec_procedure_start.procedure + == PM_LINK_SECURED_PROCEDURE_BONDING; + ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pairing_flag_id, pairing); + ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_bonding_flag_id, bonding); + break; + } + + case SM_EVT_PAIRING_SUCCESS: + pm_evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED; + pm_evt.params.conn_sec_succeeded.procedure = + p_sm_evt->params.pairing_success.bonded + ? PM_LINK_SECURED_PROCEDURE_BONDING + : PM_LINK_SECURED_PROCEDURE_PAIRING; + ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pairing_flag_id, true); + ble_conn_state_user_flag_set(p_sm_evt->conn_handle, + m_bonding_flag_id, + p_sm_evt->params.pairing_success.bonded + ); + break; + + case SM_EVT_PAIRING_FAIL: + pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED; + pm_evt.params.conn_sec_failed.procedure = + ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_bonding_flag_id) + ? PM_LINK_SECURED_PROCEDURE_BONDING + : PM_LINK_SECURED_PROCEDURE_PAIRING; + pm_evt.params.conn_sec_failed.error_src + = p_sm_evt->params.pairing_failed.error_src; + pm_evt.params.conn_sec_failed.error + = p_sm_evt->params.pairing_failed.error; + break; + + case SM_EVT_LINK_ENCRYPTION_UPDATE: + if (!ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_pairing_flag_id)) + { + pm_evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED; + pm_evt.params.conn_sec_succeeded.procedure = PM_LINK_SECURED_PROCEDURE_ENCRYPTION; + } + else + { + find_peer_id = false; + send_evt = false; + } + break; + + case SM_EVT_LINK_ENCRYPTION_FAILED: + pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED; + pm_evt.params.conn_sec_failed.procedure + = PM_LINK_SECURED_PROCEDURE_ENCRYPTION; + pm_evt.params.conn_sec_failed.error_src + = p_sm_evt->params.link_encryption_failed.error_src; + pm_evt.params.conn_sec_failed.error + = p_sm_evt->params.link_encryption_failed.error; + break; + + case SM_EVT_BONDING_INFO_STORED: + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.peer_id = p_sm_evt->params.bonding_info_stored.peer_id; + pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_BONDING; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + find_peer_id = false; + break; + + case SM_EVT_ERROR_BONDING_INFO: + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED; + pm_evt.peer_id = p_sm_evt->params.error_bonding_info.peer_id; + pm_evt.params.peer_data_update_failed.data_id = PM_PEER_DATA_ID_BONDING; + pm_evt.params.peer_data_update_failed.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_failed.error + = p_sm_evt->params.error_bonding_info.error; + find_peer_id = false; + break; + + case SM_EVT_ERROR_UNEXPECTED: + pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED; + pm_evt.params.error_unexpected.error = p_sm_evt->params.error_unexpected.error; + break; + + case SM_EVT_ERROR_NO_MEM: + pm_evt.evt_id = PM_EVT_STORAGE_FULL; + break; + + case SM_EVT_ERROR_SMP_TIMEOUT: + pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED; + pm_evt.params.conn_sec_failed.procedure + = ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_bonding_flag_id) + ? PM_LINK_SECURED_PROCEDURE_BONDING + : PM_LINK_SECURED_PROCEDURE_PAIRING; + pm_evt.params.conn_sec_failed.error_src = BLE_GAP_SEC_STATUS_SOURCE_LOCAL; + pm_evt.params.conn_sec_failed.error = PM_CONN_SEC_ERROR_SMP_TIMEOUT; + break; + + case SM_EVT_CONN_SEC_CONFIG_REQ: + pm_evt.evt_id = PM_EVT_CONN_SEC_CONFIG_REQ; + break; + + default: + send_evt = false; + break; + } + + if (find_peer_id) + { + pm_evt.peer_id = im_peer_id_get_by_conn_handle(p_sm_evt->conn_handle); + } + + if (send_evt) + { + evt_send(&pm_evt); + } +} + + +/**@brief Event handler for events from the GATT Cache Manager module. + * This handler is extern in GATT Cache Manager. + * + * @param[in] p_gcm_evt The incoming GATT Cache Manager event. + */ +void pm_gcm_evt_handler(gcm_evt_t const * p_gcm_evt) +{ + bool send_evt = true; + pm_evt_t pm_evt; + + memset(&pm_evt, 0, sizeof(pm_evt_t)); + pm_evt.peer_id = p_gcm_evt->peer_id; + pm_evt.conn_handle = im_conn_handle_get(pm_evt.peer_id); + + switch (p_gcm_evt->evt_id) + { + case GCM_EVT_LOCAL_DB_CACHE_STORED: + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_GATT_LOCAL; + break; + + case GCM_EVT_LOCAL_DB_CACHE_UPDATED: + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_GATT_LOCAL; + break; + + case GCM_EVT_LOCAL_DB_CACHE_APPLIED: + pm_evt.evt_id = PM_EVT_LOCAL_DB_CACHE_APPLIED; + break; + + case GCM_EVT_ERROR_LOCAL_DB_CACHE_APPLY: + pm_evt.evt_id = PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED; + break; + + case GCM_EVT_REMOTE_DB_CACHE_UPDATED: + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_GATT_REMOTE; + break; + + case GCM_EVT_SERVICE_CHANGED_IND_SENT: + pm_evt.evt_id = PM_EVT_SERVICE_CHANGED_IND_SENT; + break; + + case GCM_EVT_SERVICE_CHANGED_IND_CONFIRMED: + pm_evt.evt_id = PM_EVT_SERVICE_CHANGED_IND_CONFIRMED; + break; + + case GCM_EVT_ERROR_DATA_SIZE: + send_evt = false; + break; + + case GCM_EVT_ERROR_STORAGE_FULL: + pm_evt.evt_id = PM_EVT_STORAGE_FULL; + break; + + case GCM_EVT_ERROR_UNEXPECTED: + pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED; + pm_evt.params.error_unexpected.error = p_gcm_evt->params.error_unexpected.error; + pm_evt.conn_handle = p_gcm_evt->params.error_unexpected.conn_handle; + break; + } + + if (send_evt) + { + evt_send(&pm_evt); + } +} + + +/**@brief Event handler for events from the ID Manager module. + * This function is registered in the ID Manager. + * + * @param[in] p_im_evt The incoming ID Manager event. + */ +void pm_im_evt_handler(im_evt_t const * p_im_evt) +{ + pm_evt_t pm_evt; + ret_code_t err_code; + + switch (p_im_evt->evt_id) + { + case IM_EVT_DUPLICATE_ID: + // Attempt to delete the duplicate data to free space and avoid finding old data when + // scanning in the future + err_code = pm_peer_delete(p_im_evt->params.duplicate_id.peer_id_2); + UNUSED_VARIABLE(err_code); + break; + + case IM_EVT_BONDED_PEER_CONNECTED: + ble_conn_state_user_flag_set(p_im_evt->conn_handle, m_bonding_flag_id, true); + memset(&pm_evt, 0, sizeof(pm_evt_t)); + pm_evt.conn_handle = p_im_evt->conn_handle; + pm_evt.peer_id = im_peer_id_get_by_conn_handle(p_im_evt->conn_handle); + pm_evt.evt_id = PM_EVT_BONDED_PEER_CONNECTED; + evt_send(&pm_evt); + break; + } +} + + +void pm_on_ble_evt(ble_evt_t * p_ble_evt) +{ + VERIFY_MODULE_INITIALIZED_VOID(); + + im_ble_evt_handler(p_ble_evt); + sm_ble_evt_handler(p_ble_evt); + gcm_ble_evt_handler(p_ble_evt); +} + + +/**@brief Function for resetting the internal state of this module. + */ +static void internal_state_reset() +{ + m_highest_ranked_peer = PM_PEER_ID_INVALID; + m_peer_rank_token = PM_STORE_TOKEN_INVALID; + m_pairing_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID; + m_bonding_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID; +} + + +ret_code_t pm_init(void) +{ + ret_code_t err_code; + + err_code = pds_init(); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + err_code = pdb_init(); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + err_code = sm_init(); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + err_code = smd_init(); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + err_code = gcm_init(); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + err_code = gscm_init(); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + err_code = im_init(); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + internal_state_reset(); + + m_pairing_flag_id = ble_conn_state_user_flag_acquire(); + if (m_pairing_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) + { + return NRF_ERROR_INTERNAL; + } + + m_bonding_flag_id = ble_conn_state_user_flag_acquire(); + if (m_bonding_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) + { + return NRF_ERROR_INTERNAL; + } + + m_peer_rank_initialized = false; + m_module_initialized = true; + + return NRF_SUCCESS; +} + + +ret_code_t pm_register(pm_evt_handler_t event_handler) +{ + VERIFY_MODULE_INITIALIZED(); + + if (m_n_registrants >= MAX_REGISTRANTS) + { + return NRF_ERROR_NO_MEM; + } + + m_evt_handlers[m_n_registrants] = event_handler; + m_n_registrants += 1; + + return NRF_SUCCESS; +} + + +ret_code_t pm_sec_params_set(ble_gap_sec_params_t * p_sec_params) +{ + VERIFY_MODULE_INITIALIZED(); + + ret_code_t err_code; + + err_code = sm_sec_params_set(p_sec_params); + + // NRF_ERROR_INVALID_PARAM if parameters are invalid, + // NRF_SUCCESS otherwise. + return err_code; +} + + +ret_code_t pm_conn_secure(uint16_t conn_handle, bool force_repairing) +{ + VERIFY_MODULE_INITIALIZED(); + + ret_code_t err_code; + + err_code = sm_link_secure(conn_handle, force_repairing); + + return err_code; +} + + +void pm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config) +{ + sm_conn_sec_config_reply(conn_handle, p_conn_sec_config); +} + + +ret_code_t pm_sec_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params) +{ + VERIFY_MODULE_INITIALIZED(); + return NRF_SUCCESS; +} + + +void pm_local_database_has_changed(void) +{ + VERIFY_MODULE_INITIALIZED_VOID(); + gcm_local_database_has_changed(); +} + + +ret_code_t pm_id_addr_set(ble_gap_addr_t const * p_addr) +{ + VERIFY_MODULE_INITIALIZED(); + return im_id_addr_set(p_addr); +} + + +ret_code_t pm_id_addr_get(ble_gap_addr_t * p_addr) +{ + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_addr); + return im_id_addr_get(p_addr); +} + + +ret_code_t pm_privacy_set(pm_privacy_params_t const * p_privacy_params) +{ + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_privacy_params); + return im_privacy_set(p_privacy_params); +} + + +ret_code_t pm_privacy_get(pm_privacy_params_t * p_privacy_params) +{ + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_privacy_params); + VERIFY_PARAM_NOT_NULL(p_privacy_params->p_device_irk); + return im_privacy_get(p_privacy_params); +} + + +ret_code_t pm_whitelist_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt) +{ + VERIFY_MODULE_INITIALIZED(); + return im_whitelist_set(p_peers, peer_cnt); +} + + +ret_code_t pm_whitelist_get(ble_gap_addr_t * p_addrs, + uint32_t * p_addr_cnt, + ble_gap_irk_t * p_irks, + uint32_t * p_irk_cnt) +{ + VERIFY_MODULE_INITIALIZED(); + + if (((p_addrs == NULL) && (p_irks == NULL)) || + ((p_addrs != NULL) && (p_addr_cnt == NULL)) || + ((p_irks != NULL) && (p_irk_cnt == NULL))) + { + // The buffers can't be both NULL, and if a buffer is provided its size must be specified. + return NRF_ERROR_NULL; + } + + return im_whitelist_get(p_addrs, p_addr_cnt, p_irks, p_irk_cnt); +} + + +ret_code_t pm_device_identities_list_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt) +{ + VERIFY_MODULE_INITIALIZED(); + return im_device_identities_list_set(p_peers, peer_cnt); +} + + +ret_code_t pm_conn_sec_status_get(uint16_t conn_handle, pm_conn_sec_status_t * p_conn_sec_status) +{ + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_conn_sec_status); + + ble_conn_state_status_t status = ble_conn_state_status(conn_handle); + + if (status == BLE_CONN_STATUS_INVALID) + { + return BLE_ERROR_INVALID_CONN_HANDLE; + } + + p_conn_sec_status->connected = (status == BLE_CONN_STATUS_CONNECTED); + p_conn_sec_status->bonded = ble_conn_state_user_flag_get(conn_handle, m_bonding_flag_id); + p_conn_sec_status->encrypted = ble_conn_state_encrypted(conn_handle); + p_conn_sec_status->mitm_protected = ble_conn_state_mitm_protected(conn_handle); + return NRF_SUCCESS; +} + + +ret_code_t pm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key) +{ + VERIFY_MODULE_INITIALIZED(); + return sm_lesc_public_key_set(p_public_key); +} + + +ret_code_t pm_conn_handle_get(pm_peer_id_t peer_id, uint16_t * p_conn_handle) +{ + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_conn_handle); + *p_conn_handle = im_conn_handle_get(peer_id); + return NRF_SUCCESS; +} + + +ret_code_t pm_peer_id_get(uint16_t conn_handle, pm_peer_id_t * p_peer_id) +{ + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_peer_id); + *p_peer_id = im_peer_id_get_by_conn_handle(conn_handle); + return NRF_SUCCESS; +} + + +uint32_t pm_peer_count(void) +{ + if (!MODULE_INITIALIZED) + { + return 0; + } + return pdb_n_peers(); +} + + +pm_peer_id_t pm_next_peer_id_get(pm_peer_id_t prev_peer_id) +{ + if (!MODULE_INITIALIZED) + { + return PM_PEER_ID_INVALID; + } + return pdb_next_peer_id_get(prev_peer_id); +} + + +ret_code_t pm_peer_data_load(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + void * p_data, + uint16_t * p_length) +{ + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_data); + VERIFY_PARAM_NOT_NULL(p_length); + if (ALIGN_NUM(4, *p_length) != *p_length) + { + return NRF_ERROR_INVALID_PARAM; + } + + pm_peer_data_t peer_data; + memset(&peer_data, 0, sizeof(peer_data)); + peer_data.length_words = BYTES_TO_WORDS(*p_length); + peer_data.data_id = data_id; + peer_data.p_all_data = p_data; + + ret_code_t err_code = pdb_peer_data_load(peer_id, data_id, &peer_data); + + *p_length = peer_data.length_words * BYTES_PER_WORD; + + return err_code; +} + + +ret_code_t pm_peer_data_bonding_load(pm_peer_id_t peer_id, + pm_peer_data_bonding_t * p_data) +{ + uint16_t length = sizeof(pm_peer_data_bonding_t); + return pm_peer_data_load(peer_id, + PM_PEER_DATA_ID_BONDING, + p_data, + &length); +} + + +ret_code_t pm_peer_data_remote_db_load(pm_peer_id_t peer_id, + ble_gatt_db_srv_t * p_data, + uint16_t * p_length) +{ + return pm_peer_data_load(peer_id, + PM_PEER_DATA_ID_GATT_REMOTE, + p_data, + p_length); +} + + +ret_code_t pm_peer_data_app_data_load(pm_peer_id_t peer_id, + uint8_t * p_data, + uint16_t * p_length) +{ + return pm_peer_data_load(peer_id, + PM_PEER_DATA_ID_APPLICATION, + p_data, + p_length); +} + + +ret_code_t pm_peer_data_store(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + void const * p_data, + uint16_t length, + pm_store_token_t * p_token) +{ + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_data); + if (ALIGN_NUM(4, length) != length) + { + return NRF_ERROR_INVALID_PARAM; + } + + pm_peer_data_flash_t peer_data; + memset(&peer_data, 0, sizeof(peer_data)); + peer_data.length_words = BYTES_TO_WORDS(length); + peer_data.data_id = data_id; + peer_data.p_all_data = p_data; + + return pdb_raw_store(peer_id, &peer_data, p_token); +} + + +ret_code_t pm_peer_data_bonding_store(pm_peer_id_t peer_id, + pm_peer_data_bonding_t const * p_data, + pm_store_token_t * p_token) +{ + return pm_peer_data_store(peer_id, + PM_PEER_DATA_ID_BONDING, + p_data, + ALIGN_NUM(4, sizeof(pm_peer_data_bonding_t)), + p_token); +} + + +ret_code_t pm_peer_data_remote_db_store(pm_peer_id_t peer_id, + ble_gatt_db_srv_t const * p_data, + uint16_t length, + pm_store_token_t * p_token) +{ + return pm_peer_data_store(peer_id, + PM_PEER_DATA_ID_GATT_REMOTE, + p_data, + length, + p_token); +} + + +ret_code_t pm_peer_data_app_data_store(pm_peer_id_t peer_id, + uint8_t const * p_data, + uint16_t length, + pm_store_token_t * p_token) +{ + return pm_peer_data_store(peer_id, + PM_PEER_DATA_ID_APPLICATION, + p_data, + length, + p_token); +} + + +ret_code_t pm_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) +{ + VERIFY_MODULE_INITIALIZED(); + + if (data_id == PM_PEER_DATA_ID_BONDING) + { + return NRF_ERROR_INVALID_PARAM; + } + + return pdb_clear(peer_id, data_id); +} + + +ret_code_t pm_peer_new(pm_peer_id_t * p_new_peer_id, + pm_peer_data_bonding_t * p_bonding_data, + pm_store_token_t * p_token) +{ + ret_code_t err_code; + pm_peer_id_t peer_id; + pm_peer_data_flash_t peer_data; + + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_bonding_data); + VERIFY_PARAM_NOT_NULL(p_new_peer_id); + + memset(&peer_data, 0, sizeof(pm_peer_data_flash_t)); + + // Search through existing bonds to look for a duplicate. + pds_peer_data_iterate_prepare(); + + // @note emdi: should maybe use a critical section, since data is not copied while iterating. + while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data)) + { + if (im_is_duplicate_bonding_data(p_bonding_data, peer_data.p_bonding_data)) + { + *p_new_peer_id = peer_id; + return NRF_SUCCESS; + } + } + + // If no duplicate data is found, prepare to write a new bond to flash. + + *p_new_peer_id = pdb_peer_allocate(); + + if (*p_new_peer_id == PM_PEER_ID_INVALID) + { + return NRF_ERROR_NO_MEM; + } + + memset(&peer_data, 0, sizeof(pm_peer_data_flash_t)); + + peer_data.data_id = PM_PEER_DATA_ID_BONDING; + peer_data.p_bonding_data = p_bonding_data; + peer_data.length_words = BYTES_TO_WORDS(sizeof(pm_peer_data_bonding_t)); + + err_code = pdb_raw_store(*p_new_peer_id, &peer_data, p_token); + + if (err_code != NRF_SUCCESS) + { + if (im_peer_free(*p_new_peer_id) != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + // NRF_ERROR_STORAGE_FULL, if no space in flash. + // NRF_ERROR_BUSY, if flash filesystem was busy. + // NRF_ERROR_INTENRAL, on internal error. + return err_code; + } + + return NRF_SUCCESS; +} + + +ret_code_t pm_peer_delete(pm_peer_id_t peer_id) +{ + VERIFY_MODULE_INITIALIZED(); + + return im_peer_free(peer_id); +} + + +ret_code_t pm_peers_delete(void) +{ + VERIFY_MODULE_INITIALIZED(); + + m_deleting_all = true; + + pm_peer_id_t current_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); + + if (current_peer_id == PM_PEER_ID_INVALID) + { + // No peers bonded. + m_deleting_all = false; + + pm_evt_t pm_delete_all_evt; + memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t)); + pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_SUCCEEDED; + pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID; + pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID; + + evt_send(&pm_delete_all_evt); + } + + while (current_peer_id != PM_PEER_ID_INVALID) + { + ret_code_t err_code = pm_peer_delete(current_peer_id); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + current_peer_id = pdb_next_peer_id_get(current_peer_id); + } + + return NRF_SUCCESS; +} + + +ret_code_t pm_peer_ranks_get(pm_peer_id_t * p_highest_ranked_peer, + uint32_t * p_highest_rank, + pm_peer_id_t * p_lowest_ranked_peer, + uint32_t * p_lowest_rank) +{ + VERIFY_MODULE_INITIALIZED(); + + pm_peer_id_t peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); + uint32_t peer_rank = 0; + //lint -save -e65 -e64 + pm_peer_data_t peer_data = {.length_words = BYTES_TO_WORDS(sizeof(peer_rank)), + .p_peer_rank = &peer_rank}; + //lint -restore + ret_code_t err_code = pdb_peer_data_load(peer_id, PM_PEER_DATA_ID_PEER_RANK, &peer_data); + uint32_t highest_rank = 0; + uint32_t lowest_rank = 0xFFFFFFFF; + pm_peer_id_t highest_ranked_peer = PM_PEER_ID_INVALID; + pm_peer_id_t lowest_ranked_peer = PM_PEER_ID_INVALID; + + if (err_code == NRF_ERROR_INVALID_PARAM) + { + // No peer IDs exist. + return NRF_ERROR_NOT_FOUND; + } + + while ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND)) + { + if (err_code == NRF_ERROR_NOT_FOUND) + { + peer_rank = 0; + } + if (peer_rank >= highest_rank) + { + highest_rank = peer_rank; + highest_ranked_peer = peer_id; + } + if (peer_rank < lowest_rank) + { + lowest_rank = peer_rank; + lowest_ranked_peer = peer_id; + } + peer_id = pdb_next_peer_id_get(peer_id); + err_code = pdb_peer_data_load(peer_id, PM_PEER_DATA_ID_PEER_RANK, &peer_data); + } + if (peer_id == PM_PEER_ID_INVALID) + { + err_code = NRF_SUCCESS; + if (p_highest_ranked_peer != NULL) + { + *p_highest_ranked_peer = highest_ranked_peer; + } + if (p_highest_rank != NULL) + { + *p_highest_rank = highest_rank; + } + if (p_lowest_ranked_peer != NULL) + { + *p_lowest_ranked_peer = lowest_ranked_peer; + } + if (p_lowest_rank != NULL) + { + *p_lowest_rank = lowest_rank; + } + } + else + { + err_code = NRF_ERROR_INTERNAL; + } + return err_code; +} + + +/**@brief Function for initializing peer rank statistics. + */ +static void rank_init(void) +{ + ret_code_t err_code = pm_peer_ranks_get(&m_highest_ranked_peer, + &m_current_highest_peer_rank, + NULL, + NULL); + if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND)) + { + m_peer_rank_initialized = true; + } +} + + +ret_code_t pm_peer_rank_highest(pm_peer_id_t peer_id) +{ + VERIFY_MODULE_INITIALIZED(); + + ret_code_t err_code; + //lint -save -e65 -e64 + pm_peer_data_flash_t peer_data = {.length_words = BYTES_TO_WORDS(sizeof(m_current_highest_peer_rank)), + .data_id = PM_PEER_DATA_ID_PEER_RANK, + .p_peer_rank = &m_current_highest_peer_rank}; + //lint -restore + + + if (!m_peer_rank_initialized) + { + rank_init(); + } + + if (!m_peer_rank_initialized || (m_peer_rank_token != PM_STORE_TOKEN_INVALID)) + { + err_code = NRF_ERROR_BUSY; + } + else + { + if ((peer_id == m_highest_ranked_peer) && (m_current_highest_peer_rank > 0)) + { + pm_evt_t pm_evt; + + // The reported peer is already regarded as highest (provided it has an index at all) + err_code = NRF_SUCCESS; + + memset(&pm_evt, 0, sizeof(pm_evt)); + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.conn_handle = im_conn_handle_get(peer_id); + pm_evt.peer_id = peer_id; + pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_PEER_RANK; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; + pm_evt.params.peer_data_update_succeeded.flash_changed = false; + + evt_send(&pm_evt); + } + else + { + m_current_highest_peer_rank += 1; + err_code = pdb_raw_store(peer_id, &peer_data, &m_peer_rank_token); + if (err_code != NRF_SUCCESS) + { + m_peer_rank_token = PM_STORE_TOKEN_INVALID; + m_current_highest_peer_rank -= 1; + { + if ((err_code != NRF_ERROR_BUSY) && (err_code != NRF_ERROR_STORAGE_FULL)) + err_code = NRF_ERROR_INTERNAL; + } + } + } + } + return err_code; +} +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_manager.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..68ea03c6670402bf2f02b62f04dc6e0ff4c97f59 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_manager.h @@ -0,0 +1,858 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file peer_manager.h + * + * @defgroup peer_manager Peer Manager + * @ingroup ble_sdk_lib + * @{ + * @brief Module for managing BLE bonding, which includes controlling encryption and pairing + * procedures as well as persistently storing different pieces of data that must be stored + * when bonded. + * + * @details The API consists of functions for configuring the pairing and encryption behavior of the + * device and functions for manipulating the stored data. + * + * This module uses Flash Data Storage (FDS) to interface with persistent storage. The + * Peer Manager needs exclusive use of certain FDS file IDs and record keys. See + * @ref lib_fds_functionality_keys for more information. + */ + + +#ifndef PEER_MANAGER_H__ +#define PEER_MANAGER_H__ + +#include +#include +#include "sdk_common.h" +#include "ble.h" +#include "ble_gap.h" +#include "peer_manager_types.h" +#include "peer_database.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/**@brief Security status of a connection. + */ +typedef struct +{ + uint8_t connected : 1; /**< @brief The connection is active (not disconnected). */ + uint8_t encrypted : 1; /**< @brief Communication on this link is encrypted. */ + uint8_t mitm_protected : 1; /**< @brief The encrypted communication is also protected against man-in-the-middle attacks. */ + uint8_t bonded : 1; /**< @brief The peer is bonded with us. */ +} pm_conn_sec_status_t; + + +/**@brief Types of events that can come from the @ref peer_manager module. + */ +typedef enum +{ + PM_EVT_BONDED_PEER_CONNECTED, /**< @brief A connected peer has been identified as one with which we have a bond. When performing bonding with a peer for the first time, this event will not be sent until a new connection is established with the peer. When we are central, this event is always sent when the Peer Manager receives the @ref BLE_GAP_EVT_CONNECTED event. When we are peripheral, this event might in rare cases arrive later. */ + PM_EVT_CONN_SEC_START, /**< @brief A security procedure has started on a link, initiated either locally or remotely. The security procedure is using the last parameters provided via @ref pm_sec_params_set. This event is always followed by either a @ref PM_EVT_CONN_SEC_SUCCEEDED or a @ref PM_EVT_CONN_SEC_FAILED event. This is an informational event; no action is needed for the procedure to proceed. */ + PM_EVT_CONN_SEC_SUCCEEDED, /**< @brief A link has been encrypted, either as a result of a call to @ref pm_conn_secure or a result of an action by the peer. The event structure contains more information about the circumstances. This event might contain a peer ID with the value @ref PM_PEER_ID_INVALID, which means that the peer (central) used an address that could not be identified, but it used an encryption key (LTK) that is present in the database. */ + PM_EVT_CONN_SEC_FAILED, /**< @brief A pairing or encryption procedure has failed. In some cases, this means that security is not possible on this link (temporarily or permanently). How to handle this error depends on the application. */ + PM_EVT_CONN_SEC_CONFIG_REQ, /**< @brief The peer (central) has requested pairing, but a bond already exists with that peer. Reply by calling @ref pm_conn_sec_config_reply before the event handler returns. If no reply is sent, a default is used. */ + PM_EVT_STORAGE_FULL, /**< @brief There is no more room for peer data in flash storage. To solve this problem, delete data that is not needed anymore and run a garbage collection procedure in FDS. */ + PM_EVT_ERROR_UNEXPECTED, /**< @brief An unrecoverable error happened inside Peer Manager. An operation failed with the provided error. */ + PM_EVT_PEER_DATA_UPDATE_SUCCEEDED, /**< @brief A piece of peer data was stored, updated, or cleared in flash storage. This event is sent for all successful changes to peer data, also those initiated internally in Peer Manager. To identify an operation, compare the store token in the event with the store token received during the initiating function call. Events from internally initiated changes might have invalid store tokens. */ + PM_EVT_PEER_DATA_UPDATE_FAILED, /**< @brief A piece of peer data could not be stored, updated, or cleared in flash storage. This event is sent instead of @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED for the failed operation. */ + PM_EVT_PEER_DELETE_SUCCEEDED, /**< @brief A peer was cleared from flash storage, for example because a call to @ref pm_peer_delete succeeded. This event can also be sent as part of a call to @ref pm_peers_delete or internal cleanup. */ + PM_EVT_PEER_DELETE_FAILED, /**< @brief A peer could not be cleared from flash storage. This event is sent instead of @ref PM_EVT_PEER_DELETE_SUCCEEDED for the failed operation. */ + PM_EVT_PEERS_DELETE_SUCCEEDED, /**< @brief A call to @ref pm_peers_delete has completed successfully. Flash storage now contains no peer data. */ + PM_EVT_PEERS_DELETE_FAILED, /**< @brief A call to @ref pm_peers_delete has failed, which means that at least one of the peers could not be deleted. Other peers might have been deleted, or might still be queued to be deleted. No more @ref PM_EVT_PEERS_DELETE_SUCCEEDED or @ref PM_EVT_PEERS_DELETE_FAILED events are sent until the next time @ref pm_peers_delete is called. */ + PM_EVT_LOCAL_DB_CACHE_APPLIED, /**< @brief Local database values for a peer (taken from flash storage) have been provided to the SoftDevice. */ + PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED, /**< @brief Local database values for a peer (taken from flash storage) were rejected by the SoftDevice, which means that either the database has changed or the user has manually set the local database to an invalid value (using @ref pm_peer_data_store). */ + PM_EVT_SERVICE_CHANGED_IND_SENT, /**< @brief A service changed indication has been sent to a peer, as a result of a call to @ref pm_local_database_has_changed. This event will be followed by a @ref PM_EVT_SERVICE_CHANGED_IND_CONFIRMED event if the peer acknowledges the indication. */ + PM_EVT_SERVICE_CHANGED_IND_CONFIRMED, /**< @brief A service changed indication that was sent has been confirmed by a peer. The peer can now be considered aware that the local database has changed. */ +} pm_evt_id_t; + + +/**@brief Parameters specific to the @ref PM_EVT_CONN_SEC_SUCCEEDED event. + */ +typedef struct +{ + pm_conn_sec_procedure_t procedure; /**< @brief The procedure that led to securing the link. */ +} pm_conn_secured_evt_t; + + +/**@brief Parameters specific to the @ref PM_EVT_CONN_SEC_FAILED event. + */ +typedef struct +{ + pm_conn_sec_procedure_t procedure; /**< @brief The procedure that failed. */ + pm_sec_error_code_t error; /**< @brief An error code that describes the failure. */ + uint8_t error_src; /**< @brief The party that raised the error, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ +} pm_conn_secure_failed_evt_t; + + +/**@brief Actions that can be performed to peer data in persistent storage. + */ +typedef enum +{ + PM_PEER_DATA_OP_UPDATE, /**< @brief Writing or overwriting the data. */ + PM_PEER_DATA_OP_DELETE, /**< @brief Removing the data. */ +} pm_peer_data_op_t; + + +/**@brief Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event. + */ +typedef struct +{ + pm_peer_data_id_t data_id; /**< @brief The type of the data that was changed. */ + pm_peer_data_op_t action; /**< @brief What happened to the data. */ + uint8_t flash_changed : 1; /**< @brief If this is false, no operation was done in flash, because the value was already what it should be. Please note that in certain scenarios, this flag will be true even if the new value is the same as the old. */ + pm_store_token_t token; /**< @brief Token that identifies the operation. For @ref PM_PEER_DATA_OP_DELETE actions, this token can be disregarded. For @ref PM_PEER_DATA_OP_UPDATE actions, compare this token with the token that is received from a call to a @ref PM_PEER_DATA_FUNCTIONS function. */ +} pm_peer_data_update_succeeded_evt_t; + + +/**@brief Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_FAILED event. + */ +typedef struct +{ + pm_peer_data_id_t data_id; /**< @brief The type of the data that was supposed to be changed. */ + pm_peer_data_op_t action; /**< @brief The action that failed. */ + pm_store_token_t token; /**< @brief Token that identifies the operation. For @ref PM_PEER_DATA_OP_DELETE actions, this token can be disregarded. For @ref PM_PEER_DATA_OP_UPDATE actions, compare this token with the token that is received from a call to a @ref PM_PEER_DATA_FUNCTIONS function. */ + ret_code_t error; /**< @brief An error code that describes the failure. */ +} pm_peer_data_update_failed_t; + + +/**@brief Standard parameters for failure events. + */ +typedef struct +{ + ret_code_t error; /**< @brief The error that occurred. */ +} pm_failure_evt_t; + + +/**@brief An event from the @ref peer_manager module. + * + * @details The structure contains both standard parameters and parameters that are specific to some events. + */ +typedef struct +{ + pm_evt_id_t evt_id; /**< @brief The type of the event. */ + uint16_t conn_handle; /**< @brief The connection that this event pertains to, or @ref BLE_CONN_HANDLE_INVALID. */ + pm_peer_id_t peer_id; /**< @brief The bonded peer that this event pertains to, or @ref PM_PEER_ID_INVALID. */ + union + { + pm_conn_secured_evt_t conn_sec_succeeded; /**< @brief Parameters specific to the @ref PM_EVT_CONN_SEC_SUCCEEDED event. */ + pm_conn_secure_failed_evt_t conn_sec_failed; /**< @brief Parameters specific to the @ref PM_EVT_CONN_SEC_FAILED event. */ + pm_peer_data_update_succeeded_evt_t peer_data_update_succeeded; /**< @brief Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event. */ + pm_peer_data_update_failed_t peer_data_update_failed; /**< @brief Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_FAILED event. */ + pm_failure_evt_t peer_delete_failed; /**< @brief Parameters specific to the @ref PM_EVT_PEER_DELETE_FAILED event. */ + pm_failure_evt_t peers_delete_failed_evt; /**< @brief Parameters specific to the @ref PM_EVT_PEERS_DELETE_FAILED event. */ + pm_failure_evt_t error_unexpected; /**< @brief Parameters specific to the @ref PM_EVT_PEER_DELETE_FAILED event. */ + } params; +} pm_evt_t; + + +/**@brief Event handler for events from the @ref peer_manager module. + * + * @sa pm_register + * + * @param[in] p_event The event that has occurred. + */ +typedef void (*pm_evt_handler_t)(pm_evt_t const * p_event); + + +/**@brief Function for initializing the Peer Manager. + * + * @details You must initialize the Peer Manager before you can call any other Peer Manager + * functions. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_init(void); + + +/**@brief Function for registering an event handler with the Peer Manager. + * + * @param[in] event_handler Callback for events from the @ref peer_manager module. @p event_handler + * is called for every event that the Peer Manager sends after this + * function is called. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_NULL If @p event_handler was NULL. + * @retval NRF_ERROR_NO_MEM If no more registrations can happen. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_register(pm_evt_handler_t event_handler); + + +/**@brief Function for providing pairing and bonding parameters to use for pairing procedures. + * + * @details Until this function is called, all bonding procedures that are initiated by the + * peer are rejected. + * + * This function can be called multiple times with different parameters, even with NULL as + * @p p_sec_params, in which case the Peer Manager starts rejecting all procedures again. + * + * @param[in] p_sec_params Security parameters to be used for subsequent security procedures. + * + * @retval NRF_SUCCESS If the parameters were set successfully. + * @retval NRF_ERROR_INVALID_PARAM If the combination of parameters is invalid. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_sec_params_set(ble_gap_sec_params_t * p_sec_params); + + +/**@brief Function for passing BLE events to the Peer Manager. + * + * @details For the module to work as expected, this function must be called with each BLE event + * from the SoftDevice. It must be called after @ref ble_conn_state_on_ble_evt, but before + * the application processes the event. + * + * Calling this function before @ref pm_init is safe, but without effect. + * + * @param[in] p_ble_evt BLE stack event that is dispatched to the function. + */ +void pm_on_ble_evt(ble_evt_t * p_ble_evt); + + +/**@brief Function for establishing encryption on a connection, and optionally establishing a bond. + * + * @details This function attempts to secure the link that is specified by @p conn_handle. It uses + * the parameters that were previously provided in a call to @ref pm_sec_params_set. + * + * If the connection is a master connection, calling this function starts a security + * procedure on the link. If we have keys from a previous bonding procedure with this peer + * and the keys meet the security requirements in the currently active sec_params, the + * function attempts to establish encryption with the existing keys. If no key exists, the + * function attempts to pair and bond according to the currently active sec_params. + * + * If the function completes successfully, a @ref PM_EVT_CONN_SEC_START event is sent. + * The procedure might be queued, in which case the @ref PM_EVT_CONN_SEC_START event is + * delayed until the procedure is initiated in the SoftDevice. + * + * If the connection is a slave connection, the function sends a security request to + * the peer (master). It is up to the peer then to initiate pairing or encryption. + * If the peer ignores the request, a @ref BLE_GAP_EVT_TIMEOUT event occurs + * with the source @ref BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST. Otherwise, the peer initiates + * security, in which case things happen as if the peer had initiated security itself. + * See @ref PM_EVT_CONN_SEC_START for information about peer-initiated security. + * + * @param[in] conn_handle Connection handle of the link as provided by the SoftDevice. + * @param[in] force_repairing Whether to force a pairing procedure even if there is an existing + * encryption key. This argument is relevant only for + * the central role. Recommended value: false. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_ERROR_TIMEOUT If there was an SMP time-out, so that no more SMP + * operations can be performed on this link. + * @retval BLE_ERROR_INVALID_CONN_HANDLE If the connection handle is invalid. + * @retval NRF_ERROR_NOT_FOUND If the security parameters have not been set. + * @retval NRF_ERROR_STORAGE_FULL If there is no more space in persistent storage. + * @retval NRF_ERROR_NO_MEM If no more authentication procedures can run in parallel + * for the given role. See @ref sd_ble_gap_authenticate. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized, or the peer is + * disconnected or in the process of disconnecting. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_conn_secure(uint16_t conn_handle, bool force_repairing); + + +/**@brief Function for providing security configuration for a link. + * + * @details This function is optional, and must be called in reply to a @ref + * PM_EVT_CONN_SEC_CONFIG_REQ event, before the Peer Manager event handler returns. If it + * is not called in time, a default configuration is used. See @ref pm_conn_sec_config_t + * for the value of the default. + * + * @param[in] conn_handle The connection to set the configuration for. + * @param[in] p_conn_sec_config The configuration. + */ +void pm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config); + + +/**@brief Function for manually informing that the local database has changed. + * + * @details This function sends a service changed indication to all bonded and/or connected peers + * that subscribe to this indication. If a bonded peer is not connected, the indication is + * sent when it reconnects. Every time an indication is sent, a @ref + * PM_EVT_SERVICE_CHANGED_IND_SENT event occurs, followed by a @ref + * PM_EVT_SERVICE_CHANGED_IND_CONFIRMED when the peer sends its confirmation. Peers that + * are not subscribed to the service changed indication when this function is called do not + * receive an indication, and no events are sent to the user. Likewise, if the service + * changed characteristic is not present in the local database, this no indications are + * sent peers, and no events are sent to the user. + */ +void pm_local_database_has_changed(void); + + +/**@brief Function for getting the security status of a connection. + * + * @param[in] conn_handle Connection handle of the link as provided by the SoftDevice. + * @param[out] p_conn_sec_status Security status of the link. + * + * @retval NRF_SUCCESS If pairing was initiated successfully. + * @retval BLE_ERROR_INVALID_CONN_HANDLE If the connection handle is invalid. + * @retval NRF_ERROR_NULL If @p p_conn_sec_status was NULL. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_conn_sec_status_get(uint16_t conn_handle, pm_conn_sec_status_t * p_conn_sec_status); + + +/**@brief Experimental function for specifying the public key to use for LESC operations. + * + * @details This function can be called multiple times. The specified public key will be used for + * all subsequent LESC (LE Secure Connections) operations until the next time this function + * is called. + * + * @note The key must continue to reside in application memory as it is not copied by Peer Manager. + * + * @param[in] p_public_key The public key to use for all subsequent LESC operations. + * + * @retval NRF_SUCCESS If pairing was initiated successfully. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key); + + +/**@brief Function for setting or clearing the whitelist. + * + * When using the S13x SoftDevice v3.x, this function sets or clears the whitelist. + * When using the S13x SoftDevice v2.x, this function caches a list of + * peers that can be retrieved later by @ref pm_whitelist_get to pass to the @ref lib_ble_advertising. + * + * To clear the current whitelist, pass either NULL as @p p_peers or zero as @p peer_cnt. + * + * @param[in] p_peers The peers to add to the whitelist. Pass NULL to clear the current whitelist. + * @param[in] peer_cnt The number of peers to add to the whitelist. The number must not be greater than + * @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. Pass zero to clear the current + * whitelist. + * + * @retval NRF_SUCCESS If the whitelist was successfully set or cleared. + * @retval BLE_GAP_ERROR_WHITELIST_IN_USE If a whitelist is already in use and cannot be set. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If a peer in @p p_peers has an address that cannot + * be used for whitelisting. + * @retval NRF_ERROR_NOT_FOUND If any of the peers in @p p_peers cannot be found. + * @retval NRF_ERROR_DATA_SIZE If @p peer_cnt is greater than + * @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_whitelist_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt); + + +/**@brief Function for retrieving the previously set whitelist. + * + * The function retrieves the whitelist of GAP addresses and IRKs that was + * previously set by @ref pm_whitelist_set. + * + * To retrieve only GAP addresses or only IRKs, provide only one of the + * buffers. If a buffer is provided, its size must be specified. + * + * @param[out] p_addrs The buffer where to store GAP addresses. Pass NULL to retrieve + * only IRKs (in that case, @p p_irks must not be NULL). + * @param[in,out] p_addr_cnt In: The size of the @p p_addrs buffer. + * May be NULL if and only if @p p_addrs is NULL. + * Out: The number of GAP addresses copied into the buffer. + * If @p p_addrs is NULL, this parameter remains unchanged. + * @param[out] p_irks The buffer where to store IRKs. Pass NULL to retrieve + * only GAP addresses (in that case, @p p_addrs must not NULL). + * @param[in,out] p_irk_cnt In: The size of the @p p_irks buffer. + * May be NULL if and only if @p p_irks is NULL. + * Out: The number of IRKs copied into the buffer. + * If @p p_irks is NULL, this paramater remains unchanged. + * + * @retval NRF_SUCCESS If the whitelist was successfully retrieved. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If a peer has an address that cannot be used for + * whitelisting (this error can occur only + * when using the S13x SoftDevice v2.x). + * @retval NRF_ERROR_NULL If a required parameter is NULL. + * @retval NRF_ERROR_NO_MEM If the provided buffers are too small. + * @retval NRF_ERROR_NOT_FOUND If the data for any of the cached whitelisted peers + * cannot be found. It might have been deleted. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_whitelist_get(ble_gap_addr_t * p_addrs, + uint32_t * p_addr_cnt, + ble_gap_irk_t * p_irks, + uint32_t * p_irk_cnt); + + +/**@brief Function for setting and clearing the device identities list. + * + * @param[in] p_peers The peers to add to the device identities list. Pass NULL to clear + * the device identities list. + * @param[in] peer_cnt The number of peers. Pass zero to clear the device identities list. + * + * @retval NRF_SUCCESS If the device identities list was successfully + * set or cleared. + * @retval NRF_ERROR_NOT_FOUND If a peer is invalid or its data could not + * be found in flash. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If a peer has an address that cannot be + * used for whitelisting. + * @retval BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE If the device identities list is in use and + * cannot be set. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_NOT_SUPPORTED If using a SoftDevice that does not support + * device identities, e.g. S130 v2.0. + */ +ret_code_t pm_device_identities_list_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt); + + +/**@brief Function for setting the local Bluetooth identity address. + * + * @details The local Bluetooth identity address is the address that identifies the device to other + * peers. The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref + * BLE_GAP_ADDR_TYPE_RANDOM_STATIC. The identity address cannot be changed while roles are + * running. + * + * The SoftDevice sets a default address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC + * when it is enabled. This default address is a random number that is populated during + * the IC manufacturing process. It remains unchanged for the lifetime of each IC, but the application can assign a different identity address. + * + * The identity address is distributed to the peer during bonding. + * If the address changes, the address stored in the peer device will not be valid and the + * ability to reconnect using the old address will be lost. + * + * + * @note The SoftDevice functions @ref sd_ble_gap_addr_set + * and @ref sd_ble_gap_privacy_set must not be called when using the Peer Manager. + * Use this function instead. + * + * @param[in] p_addr The GAP address to be set. + * + * @retval NRF_SUCCESS If the identity address was set successfully. + * @retval NRF_ERROR_NULL If @p p_addr is NULL. + * @retval NRF_ERROR_INVALID_ADDR If the @p p_addr pointer is invalid. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If the BLE address is invalid. + * @retval NRF_ERROR_BUSY If the SoftDevice was busy. Process SoftDevice events + * and retry. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized or if this function + * was called while advertising, scanning, or while connected. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_id_addr_set(ble_gap_addr_t const * p_addr); + + +/**@brief Function for retrieving the local Bluetooth identity address. + * + * This function always returns the identity address, irrespective of the privacy settings. + * This means that the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref + * BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * + * @param[out] p_addr Pointer to the address structure to be filled in. + * + * @retval NRF_SUCCESS If the address was retrieved successfully. + * @retval NRF_ERROR_NULL If @p p_addr is NULL. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_id_addr_get(ble_gap_addr_t * p_addr); + + +/**@brief Function for configuring privacy settings. + * + * The privacy settings cannot be configured while advertising, scanning, or while in a connection. + * + * @note The SoftDevice functions @ref sd_ble_gap_addr_set + * and @ref sd_ble_gap_privacy_set must not be called when using the Peer Manager. + * Use this function instead. + * + * @param[in] p_privacy_params Privacy settings. + * + * @retval NRF_SUCCESS If the privacy settings were configured successfully. + * @retval NRF_ERROR_NULL If @p p_privacy_params is NULL. + * @retval NRF_ERROR_BUSY If the operation could not be performed at this time. + * Process SoftDevice events and retry. + * @retval NRF_ERROR_INVALID_PARAM If the address type is invalid. + * @retval NRF_ERROR_INVALID_STATE If this function is called while BLE roles using + * privacy are enabled. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_privacy_set(pm_privacy_params_t const * p_privacy_params); + + +/**@brief Function for retrieving privacy settings. + * + * The privacy settings that are returned include the current IRK as well. + * + * @param[out] p_privacy_params Privacy settings. + * + * @retval NRF_SUCCESS If the privacy settings were retrieved successfully. + * @retval NRF_ERROR_NULL If @p p_privacy_params or @p p_privacy_params->p_device_irk is + * NULL. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_privacy_get(pm_privacy_params_t * p_privacy_params); + + +/**@brief Function for getting the connection handle of the connection with a bonded peer. + * + * @param[in] peer_id The peer ID of the bonded peer. + * @param[out] p_conn_handle Connection handle, or @ref BLE_ERROR_INVALID_CONN_HANDLE if the peer + * is not connected. + * + * @retval NRF_SUCCESS If the connection handle was retrieved successfully. + * @retval NRF_ERROR_NULL If @p p_conn_handle was NULL. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_conn_handle_get(pm_peer_id_t peer_id, uint16_t * p_conn_handle); + + +/**@brief Function for retrieving the ID of a peer, given its connection handle. + * + * @param[in] conn_handle The connection handle of the peer. + * @param[out] p_peer_id The peer ID, or @ref PM_PEER_ID_INVALID if the peer is not bonded or + * @p conn_handle does not refer to a valid connection. + * + * @retval NRF_SUCCESS If the peer ID was retrieved successfully. + * @retval NRF_ERROR_NULL If @p p_peer_id was NULL. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_peer_id_get(uint16_t conn_handle, pm_peer_id_t * p_peer_id); + + +/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. + * + * @details This function can be used to loop through all used peer IDs. The order in which + * peer IDs are returned should be considered unpredictable. @ref PM_PEER_ID_INVALID + * is considered to be before the first and after the last used peer ID. + * + * @details To loop through all peer IDs exactly once, use the following constuct: + * @code{c} + * pm_peer_id_t current_peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID); + * while (current_peer_id != PM_PEER_ID_INVALID) + * { + * // Do something with current_peer_id. + * current_peer_id = pm_next_peer_id_get(current_peer_id) + * } + * @endcode + * + * @param[in] prev_peer_id The previous peer ID. + * + * @return The next peer ID. If @p prev_peer_id was @ref PM_PEER_ID_INVALID, the + * next peer ID is the first used peer ID. If @p prev_peer_id was the last + * used peer ID, the function returns @ref PM_PEER_ID_INVALID. + */ +pm_peer_id_t pm_next_peer_id_get(pm_peer_id_t prev_peer_id); + + +/**@brief Function for querying the number of valid peer IDs that are available. + * + * @details This function returns the number of peers for which there is data in persistent storage. + * + * @return The number of valid peer IDs. + */ +uint32_t pm_peer_count(void); + + + + +/**@anchor PM_PEER_DATA_FUNCTIONS + * @name Functions (Peer Data) + * Functions for manipulating peer data. + * @{ + */ + +/** + * @{ + */ + +/**@brief Function for retrieving stored data of a peer. + * + * @note The length of the provided buffer must be a multiple of 4. + * + * @param[in] peer_id Peer ID to get data for. + * @param[in] data_id Which type of data to read. + * @param[out] p_data Where to put the retrieved data. + * @param[inout] p_len In: The length in bytes of @p p_data. + * Out: The length in bytes of the read data, if the read was successful. + * + * @retval NRF_SUCCESS If the data was read successfully. + * @retval NRF_ERROR_INVALID_PARAM If the the data type or the peer ID was invalid or unallocated, + * or if the length in @p p_length was not a multiple of 4. + * @retval NRF_ERROR_NULL If a pointer parameter was NULL. + * @retval NRF_ERROR_NOT_FOUND If no stored data was found for this peer ID/data ID combination. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer was not large enough. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_peer_data_load(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + void * p_data, + uint16_t * p_len); + +/**@brief Function for reading a peer's bonding data (@ref PM_PEER_DATA_ID_BONDING). + * @details See @ref pm_peer_data_load for parameters and return values. */ +ret_code_t pm_peer_data_bonding_load(pm_peer_id_t peer_id, + pm_peer_data_bonding_t * p_data); + +/**@brief Function for reading a peer's remote DB values. (@ref PM_PEER_DATA_ID_GATT_REMOTE). + * @details See @ref pm_peer_data_load for parameters and return values. */ +ret_code_t pm_peer_data_remote_db_load(pm_peer_id_t peer_id, + ble_gatt_db_srv_t * p_data, + uint16_t * p_len); + +/**@brief Function for reading a peer's application data. (@ref PM_PEER_DATA_ID_APPLICATION). + * @details See @ref pm_peer_data_load for parameters and return values. */ +ret_code_t pm_peer_data_app_data_load(pm_peer_id_t peer_id, + uint8_t * p_data, + uint16_t * p_len); +/** @}*/ + + +/** + * @{ + */ + +/**@brief Function for setting or updating stored data of a peer. + * + * @note Writing the data to persistent storage happens asynchronously. Therefore, the buffer + * that contains the data must be kept alive until the operation has completed. + * + * @note The data written using this function might later be overwritten as a result of internal + * operations in the Peer Manager. A Peer Manager event is sent each time data is updated, + * regardless of whether the operation originated internally or from action by the user. + * + * @param[in] peer_id Peer ID to set data for. + * @param[in] data_id Which type of data to set. + * @param[in] p_data New value to set. + * @param[in] len The length in bytes of @p p_data. + * @param[out] p_token A token that identifies this particular store operation. The token can be + * used to identify events that pertain to this operation. This parameter can + * be NULL. + * + * @retval NRF_SUCCESS If the data is scheduled to be written to persistent storage. + * @retval NRF_ERROR_NULL If @p p_data is NULL. + * @retval NRF_ERROR_NOT_FOUND If no peer was found for the peer ID. + * @retval NRF_ERROR_BUSY If the underlying flash handler is busy with other flash + * operations. Try again after receiving a Peer Manager event. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_peer_data_store(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + void const * p_data, + uint16_t len, + pm_store_token_t * p_token); + +/**@brief Function for setting or updating a peer's bonding data (@ref PM_PEER_DATA_ID_BONDING). + * @details See @ref pm_peer_data_store for parameters and return values. */ +ret_code_t pm_peer_data_bonding_store(pm_peer_id_t peer_id, + pm_peer_data_bonding_t const * p_data, + pm_store_token_t * p_token); + +/**@brief Function for setting or updating a peer's remote DB values. (@ref PM_PEER_DATA_ID_GATT_REMOTE). + * @details See @ref pm_peer_data_store for parameters and return values. */ +ret_code_t pm_peer_data_remote_db_store(pm_peer_id_t peer_id, + ble_gatt_db_srv_t const * p_data, + uint16_t len, + pm_store_token_t * p_token); + +/**@brief Function for setting or updating a peer's application data. (@ref PM_PEER_DATA_ID_APPLICATION). + * @details See @ref pm_peer_data_store for parameters and return values. */ +ret_code_t pm_peer_data_app_data_store(pm_peer_id_t peer_id, + uint8_t const * p_data, + uint16_t len, + pm_store_token_t * p_token); +/** @}*/ + + +/** + * @{ + */ + +/**@brief Function for deleting a peer's stored pieces of data. + * + * @details This function deletes specific data that is stored for a peer. Note that bonding data + * cannot be cleared separately. + * + * To delete all data for a peer (including bonding data), use @ref pm_peer_delete. + * + * @note Clearing data in persistent storage happens asynchronously. + * + * @param[in] peer_id Peer ID to clear data for. + * @param[in] data_id Which data to clear. + * + * @retval NRF_SUCCESS If the clear procedure was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM If @p data_id was PM_PEER_DATA_ID_BONDING or invalid, or + * @p peer_id was invalid. + * @retval NRF_ERROR_NOT_FOUND If there was no data to clear for this peer ID/data ID combination. + * @retval NRF_ERROR_BUSY If the underlying flash handler is busy with other flash + * operations. Try again after receiving a Peer Manager event. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id); + + +/**@brief Function for manually adding a peer to the persistent storage. + * + * @details This function allocates a new peer ID and stores bonding data for the new peer. The + * bonding data is necessary to prevent ambiguity/inconsistency in peer data. + * + * @param[in] p_bonding_data The bonding data of the new peer (must contain a public/static + * address or a non-zero IRK). + * @param[out] p_new_peer_id Peer ID for the new peer, or an existing peer if a match was found. + * @param[out] p_token A token that identifies this particular store operation (storing the + * bonding data). The token can be used to identify events that pertain + * to this operation. This parameter can be NULL. + * + * @retval NRF_SUCCESS If the store operation for bonding data was initiated successfully. + * @retval NRF_ERROR_NULL If @p p_bonding_data or @p p_new_peer_id is NULL. + * @retval NRF_ERROR_STORAGE_FULL If there is no more space in persistent storage. + * @retval NRF_ERROR_NO_MEM If there are no more available peer IDs. + * @retval NRF_ERROR_BUSY If the underlying flash filesystem is busy with other flash + * operations. Try again after receiving a Peer Manager event. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_peer_new(pm_peer_id_t * p_new_peer_id, + pm_peer_data_bonding_t * p_bonding_data, + pm_store_token_t * p_token); + + +/**@brief Function for freeing persistent storage for a peer. + * + * @details This function deletes every piece of data that is associated with the specified peer and + * frees the peer ID to be used for another peer. The deletion happens asynchronously, and + * the peer ID is not freed until the data is deleted. When the operation finishes, a @ref + * PM_EVT_PEER_DELETE_SUCCEEDED or @ref PM_EVT_PEER_DELETE_FAILED event is sent. + * + * @warning Use this function only when not connected to or connectable for the peer that is being + * deleted. If the peer is or becomes connected or data is manually written in flash during + * this procedure (until the success or failure event happens), the behavior is undefined. + * + * @param[in] peer_id Peer ID to be freed and have all associated data deleted. + * + * @retval NRF_SUCCESS If the operation was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM If the peer ID was not valid. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_peer_delete(pm_peer_id_t peer_id); + + +/**@brief Function for deleting all data stored for all peers. + * + * @details This function sends either a @ref PM_EVT_PEERS_DELETE_SUCCEEDED or a @ref + * PM_EVT_PEERS_DELETE_FAILED event. In addition, a @ref PM_EVT_PEER_DELETE_SUCCEEDED or + * @ref PM_EVT_PEER_DELETE_FAILED event is sent for each deleted peer. + * + * @note When there is no peer data in flash the @ref PM_EVT_PEER_DELETE_SUCCEEDED event is sent synchronously. + * + * @warning Use this function only when not connected or connectable. If a peer is or becomes + * connected or a @ref PM_PEER_DATA_FUNCTIONS function is used during this procedure (until + * the success or failure event happens), the behavior is undefined. + * + * @retval NRF_SUCCESS If the deletion process was initiated successfully. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_peers_delete(void); +/** @}*/ + + +/** + * @{ + */ + + +/**@brief Function for finding the highest and lowest ranked peers. + * + * @details The rank is saved in persistent storage under the data ID @ref PM_PEER_DATA_ID_PEER_RANK. + * + * @details The interpretation of rank is up to the user, because the rank is only updated by + * calling @ref pm_peer_rank_highest or by manipulating the value using a @ref + * PM_PEER_DATA_FUNCTIONS function. + * + * @note Any argument that is NULL is ignored. + * + * @param[out] p_highest_ranked_peer The peer ID with the highest rank of all peers, for example, + * the most recently used peer. + * @param[out] p_highest_rank The highest rank. + * @param[out] p_lowest_ranked_peer The peer ID with the lowest rank of all peers, for example, + * the least recently used peer. + * @param[out] p_lowest_rank The lowest rank. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_ERROR_NOT_FOUND If no peers were found. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_peer_ranks_get(pm_peer_id_t * p_highest_ranked_peer, + uint32_t * p_highest_rank, + pm_peer_id_t * p_lowest_ranked_peer, + uint32_t * p_lowest_rank); + + +/**@brief Function for updating the rank of a peer to be highest among all stored peers. + * + * @details If this function returns @ref NRF_SUCCESS, either a @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED or a + * @ref PM_EVT_PEER_DATA_UPDATE_FAILED event is sent with a @ref + * PM_STORE_TOKEN_INVALID store token when the operation is complete. Until the operation + * is complete, this function returns @ref NRF_ERROR_BUSY. + * + * When the operation is complete, the peer is the highest ranked peer as reported by + * @ref pm_peer_ranks_get. + * + * @note The @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event can arrive before the function returns if the peer + * is already ranked highest. In this case, the @ref pm_peer_data_update_succeeded_evt_t::flash_changed flag + * in the event will be false. + * + * @param[in] peer_id The peer to rank highest. + * + * @retval NRF_SUCCESS If the peer's rank is, or will be updated to be highest. + * @retval NRF_ERROR_BUSY If the underlying flash handler is busy with other flash + * operations, or if a previous call to this function has not + * completed. Try again after receiving a Peer Manager event. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_peer_rank_highest(pm_peer_id_t peer_id); + +/** @}*/ + +/** @} */ + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif // PEER_MANAGER_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_manager_internal.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_manager_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..b1301fdbf0c47f4ec81f71e81fe4eabaec4e85b0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_manager_internal.h @@ -0,0 +1,198 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef PEER_MANAGER_INTERNAL_H__ +#define PEER_MANAGER_INTERNAL_H__ + +#include +#include "sdk_errors.h" +#include "ble.h" +#include "ble_gap.h" +#include "peer_manager_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @cond NO_DOXYGEN + * @file peer_manager_types.h + * + * @addtogroup peer_manager + * @brief File containing definitions used solely inside the Peer Manager's modules. + * @{ + */ + +ANON_UNIONS_ENABLE + +/**@brief One piece of data associated with a peer, together with its type. + * + * @note This type is deprecated. + */ +typedef struct +{ + uint16_t length_words; /**< @brief The length of the data in words. */ + pm_peer_data_id_t data_id; /**< @brief ID that specifies the type of data (defines which member of the union is used). */ + union + { + pm_peer_data_bonding_t * p_bonding_data; /**< @brief The exchanged bond information in addition to metadata of the bonding. */ + uint32_t * p_peer_rank; /**< @brief A value locally assigned to this peer. Its interpretation is up to the user. The rank is not set automatically by the Peer Manager, but it is assigned by the user using either @ref pm_peer_rank_highest or a @ref PM_PEER_DATA_FUNCTIONS function. */ + bool * p_service_changed_pending; /**< @brief Whether a service changed indication should be sent to the peer. */ + pm_peer_data_local_gatt_db_t * p_local_gatt_db; /**< @brief Persistent information pertaining to a peer GATT client. */ + ble_gatt_db_srv_t * p_remote_gatt_db; /**< @brief Persistent information pertaining to a peer GATT server. */ + uint8_t * p_application_data; /**< @brief Arbitrary data to associate with the peer. This data can be freely used by the application. */ + void * p_all_data; /**< @brief Generic access pointer to the data. It is used only to handle the data without regard to type. */ + }; /**< @brief The data. */ +} pm_peer_data_t; + + +/**@brief Immutable version of @ref pm_peer_data_t. + * + * @note This type is deprecated. + */ +typedef struct +{ + uint16_t length_words; /**< @brief The length of the data in words. */ + pm_peer_data_id_t data_id; /**< @brief ID that specifies the type of data (defines which member of the union is used). */ + union + { + pm_peer_data_bonding_t const * p_bonding_data; /**< @brief Immutable @ref pm_peer_data_t::p_bonding_data. */ + uint32_t const * p_peer_rank; /**< @brief Immutable @ref pm_peer_data_t::p_peer_rank. */ + bool const * p_service_changed_pending; /**< @brief Immutable @ref pm_peer_data_t::p_service_changed_pending. */ + pm_peer_data_local_gatt_db_t const * p_local_gatt_db; /**< @brief Immutable @ref pm_peer_data_t::p_local_gatt_db. */ + ble_gatt_db_srv_t const * p_remote_gatt_db; /**< @brief Immutable @ref pm_peer_data_t::p_remote_gatt_db. */ + uint8_t const * p_application_data; /**< @brief Immutable @ref pm_peer_data_t::p_application_data. */ + void const * p_all_data; /**< @brief Immutable @ref pm_peer_data_t::p_all_data. */ + }; /**< @brief The data. */ +} pm_peer_data_const_t; + +ANON_UNIONS_DISABLE + + +/**@brief Version of @ref pm_peer_data_t that reflects the structure of peer data in flash. + * + * @note This type is deprecated. + */ +typedef pm_peer_data_const_t pm_peer_data_flash_t; + + +/**@brief Macro for calculating the flash size of bonding data. + * + * @return The number of words that the data takes in flash. + */ +#define PM_BONDING_DATA_N_WORDS() BYTES_TO_WORDS(sizeof(pm_peer_data_bonding_t)) + + +/**@brief Macro for calculating the flash size of service changed pending state. + * + * @return The number of words that the data takes in flash. + */ +#define PM_SC_STATE_N_WORDS() BYTES_TO_WORDS(sizeof(bool)) + + +/**@brief Macro for calculating the flash size of local GATT database data. + * + * @param[in] local_db_len The length, in bytes, of the database as reported by the SoftDevice. + * + * @return The number of words that the data takes in flash. + */ +#define PM_LOCAL_DB_N_WORDS(local_db_len) \ + BYTES_TO_WORDS((local_db_len) + PM_LOCAL_DB_LEN_OVERHEAD_BYTES) + + +/**@brief Macro for calculating the length of a local GATT database attribute array. + * + * @param[in] n_words The number of words that the data takes in flash. + * + * @return The length of the database attribute array. + */ +#define PM_LOCAL_DB_LEN(n_words) (((n_words) * BYTES_PER_WORD) - PM_LOCAL_DB_LEN_OVERHEAD_BYTES) + + +/**@brief Macro for calculating the flash size of remote GATT database data. + * + * @param[in] service_count The number of services in the service array. + * + * @return The number of words that the data takes in flash. + */ +#define PM_REMOTE_DB_N_WORDS(service_count) BYTES_TO_WORDS(sizeof(ble_gatt_db_srv_t) * (service_count)) + + +/**@brief Macro for calculating the flash size of remote GATT database data. + * + * @param[in] n_words The length in number of words. + * + * @return The number of words that the data takes in flash. + */ +#define PM_REMOTE_DB_N_SERVICES(n_words) (((n_words) * BYTES_PER_WORD) / sizeof(ble_gatt_db_srv_t)) + + +/**@brief Function for calculating the flash size of the usage index. + * + * @return The number of words that the data takes in flash. + */ +#define PM_USAGE_INDEX_N_WORDS() BYTES_TO_WORDS(sizeof(uint32_t)) + +/** @} + * @endcond + */ + + +#ifdef NRF_PM_DEBUG + + #define NRF_PM_DEBUG_CHECK(condition) \ + if (!(condition)) \ + { \ + __asm("bkpt #0"); \ + } + +#else + + // Prevent "variable set but never used" compiler warnings. + #define NRF_PM_DEBUG_CHECK(condition) (void)(condition) + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* PEER_MANAGER_INTERNAL_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_manager_types.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_manager_types.h new file mode 100644 index 0000000000000000000000000000000000000000..2d6d0125eacee44e3dff82901e8f39e3d68f63dd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/peer_manager_types.h @@ -0,0 +1,233 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file peer_manager_types.h + * + * @addtogroup peer_manager + * @{ + */ + +#ifndef PEER_MANAGER_TYPES_H__ +#define PEER_MANAGER_TYPES_H__ + +#include +#include +#include +#include "nrf.h" +#include "ble_gap.h" +#include "ble_hci.h" +#include "ble_gatt_db.h" +#include "app_util.h" +#include "app_util_platform.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Handle to uniquely identify a peer for which we have persistently stored data. + */ +typedef uint16_t pm_peer_id_t; + +/**@brief Type that is used for write prepares (used to reserve space in flash). + */ +typedef uint32_t pm_prepare_token_t; + +/**@brief Type that is used to hold a reference to a stored item in flash. + */ +typedef uint32_t pm_store_token_t; + +/**@brief Errors from security procedures in Peer Manager. + * + * @details Possible values are defined in @ref PM_SEC_ERRORS and @ref BLE_GAP_SEC_STATUS. + */ +typedef uint16_t pm_sec_error_code_t; + + +//lint -emacro(516,PM_LOCAL_DB_LEN_OVERHEAD_BYTES) + +#define PM_PEER_ID_INVALID 0xFFFF /**< @brief Invalid value for @ref pm_peer_id_t. */ +#define PM_STORE_TOKEN_INVALID 0 /**< @brief Invalid value for store token. */ +#define PM_PEER_ID_N_AVAILABLE_IDS 256 /**< @brief The number of available peer IDs. */ +#define PM_LOCAL_DB_LEN_OVERHEAD_BYTES offsetof(pm_peer_data_local_gatt_db_t, data) /**< @brief The static-length part of the local GATT data struct. */ + + +#define PM_CONN_SEC_ERROR_BASE 0x1000 /**< @brief The base for Peer Manager defined errors. See @ref PM_SEC_ERRORS and @ref pm_sec_error_code_t. */ + + +/**@defgroup PM_SEC_ERRORS Peer Manager defined security errors + * + * @details The first 256 numbers in this range correspond to the status codes in + * @ref BLE_HCI_STATUS_CODES. + * @{ */ +#define PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING (PM_CONN_SEC_ERROR_BASE + 0x06) /**< @brief Encryption failed because the peripheral has lost the LTK for this bond. See also @ref BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING and Table 3.7 ("Pairing Failed Reason Codes") in the Bluetooth Core Specification 4.2, section 3.H.3.5.5 (@linkBLEcore). */ +#define PM_CONN_SEC_ERROR_MIC_FAILURE (PM_CONN_SEC_ERROR_BASE + 0x3D) /**< @brief Encryption ended with disconnection because of mismatching keys or a stray packet during a procedure. See the SoftDevice GAP Message Sequence Charts on encryption (@linkBLEMSCgap), the Bluetooth Core Specification 4.2, sections 6.B.5.1.3.1 and 3.H.3.5.5 (@linkBLEcore), and @ref BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE. */ +#define PM_CONN_SEC_ERROR_DISCONNECT (PM_CONN_SEC_ERROR_BASE + 0x100) /**< @brief Pairing or encryption did not finish before the link disconnected for an unrelated reason. */ +#define PM_CONN_SEC_ERROR_SMP_TIMEOUT (PM_CONN_SEC_ERROR_BASE + 0x101) /**< @brief Pairing/bonding could not start because an SMP time-out has already happened on this link. This means that no more pairing or bonding can happen on this link. To be able to pair or bond, the link must be disconnected and then reconnected. See Bluetooth Core Specification 4.2 section 3.H.3.4 (@linkBLEcore). */ + /** @} */ + + + +/**@defgroup PM_PEER_ID_VERSIONS All versions of Peer IDs. + * @brief The data ID for each iteration of the data formats in flash. + * @details Each time the format (in flash) of a piece of peer data changes, the data ID will also + * be updated. This list of defines is a record of each data ID that has ever existed, and + * code that caters to legacy formats can find the relevant IDs here. + * @{ */ +#define PM_PEER_DATA_ID_FIRST_VX 0 /**< @brief The smallest data ID. */ +#define PM_PEER_DATA_ID_BONDING_V1 0 /**< @brief The data ID of the first version of bonding data. */ +#define PM_PEER_DATA_ID_BONDING_V2 7 /**< @brief The data ID of the second version of bonding data. */ +#define PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING_V1 1 /**< @brief The data ID of the first version of the service changed pending flag. */ +#define PM_PEER_DATA_ID_GATT_LOCAL_V1 2 /**< @brief The data ID of the first version of local GATT data. */ +#define PM_PEER_DATA_ID_GATT_LOCAL_V2 8 /**< @brief The data ID of the second version of local GATT data. */ +#define PM_PEER_DATA_ID_GATT_REMOTE_V1 3 /**< @brief The data ID of the first version of remote GATT data. */ +#define PM_PEER_DATA_ID_APPLICATION_V1 4 /**< @brief The data ID of the first version of application data. */ +#define PM_PEER_DATA_ID_GATT_REMOTE_V2 5 /**< @brief The data ID of the second version of remote GATT data. */ +#define PM_PEER_DATA_ID_PEER_RANK_V1 6 /**< @brief The data ID of the first version of the rank. */ +#define PM_PEER_DATA_ID_LAST_VX 9 /**< @brief The data ID after the last valid one. */ +#define PM_PEER_DATA_ID_INVALID_VX 0xFF /**< @brief A data ID guaranteed to be invalid. */ +/**@}*/ + + +/**@brief The different types of data associated with a peer. + */ +typedef enum +{ + PM_PEER_DATA_ID_FIRST = PM_PEER_DATA_ID_FIRST_VX, /**< @brief The smallest data ID. */ + PM_PEER_DATA_ID_BONDING = PM_PEER_DATA_ID_BONDING_V2, /**< @brief The data ID for bonding data. See @ref pm_peer_data_bonding_t. */ + PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING = PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING_V1, /**< @brief The data ID for service changed state. */ + PM_PEER_DATA_ID_GATT_LOCAL = PM_PEER_DATA_ID_GATT_LOCAL_V2, /**< @brief The data ID for local GATT data (sys attributes). See @ref pm_peer_data_local_gatt_db_t. */ + PM_PEER_DATA_ID_GATT_REMOTE = PM_PEER_DATA_ID_GATT_REMOTE_V2, /**< @brief The data ID for remote GATT data. */ + PM_PEER_DATA_ID_PEER_RANK = PM_PEER_DATA_ID_PEER_RANK_V1, /**< @brief The data ID for peer rank. See @ref pm_peer_rank_highest. */ + PM_PEER_DATA_ID_APPLICATION = PM_PEER_DATA_ID_APPLICATION_V1, /**< @brief The data ID for application data. */ + PM_PEER_DATA_ID_LAST = PM_PEER_DATA_ID_LAST_VX, /**< @brief One more than the highest data ID. */ + PM_PEER_DATA_ID_INVALID = PM_PEER_DATA_ID_INVALID_VX, /**< @brief A data ID guaranteed to be invalid. */ +} pm_peer_data_id_t; + + +/**@brief Different procedures that can lead to an encrypted link. + */ +typedef enum +{ + PM_LINK_SECURED_PROCEDURE_ENCRYPTION, /**< @brief Using an LTK that was shared during a previous bonding procedure to encrypt the link. */ + PM_LINK_SECURED_PROCEDURE_BONDING, /**< @brief A pairing procedure, followed by a bonding procedure. */ + PM_LINK_SECURED_PROCEDURE_PAIRING, /**< @brief A pairing procedure with no bonding. */ +} pm_conn_sec_procedure_t; + + +/**@brief Configuration of a security procedure. + */ +typedef struct +{ + bool allow_repairing; /** @brief Whether to allow the peer to pair if it wants to, but is already bonded. If this is false, the procedure is rejected, and no more events are sent. Default: false. */ +} pm_conn_sec_config_t; + + +/**@brief Data associated with a bond to a peer. + */ +typedef struct +{ + uint8_t own_role; /**< @brief The BLE role of the local device during bonding. See @ref BLE_GAP_ROLES. */ + ble_gap_id_key_t peer_ble_id; /**< @brief The peer's Bluetooth address and identity resolution key (IRK). */ + ble_gap_enc_key_t peer_ltk; /**< @brief The peer's long-term encryption key (LTK) and master ID. */ + ble_gap_enc_key_t own_ltk; /**< @brief Locally generated long-term encryption key (LTK) and master ID, distributed to the peer. */ +} pm_peer_data_bonding_t; + + +/**@brief Data on a local GATT database. + */ +typedef struct +{ + uint32_t flags; /**< @brief Flags that describe the database attributes. */ + uint16_t len; /**< @brief Size of the attribute array. */ + uint8_t data[1]; /**< @brief Array to hold the database attributes. */ +} pm_peer_data_local_gatt_db_t; + + +/**@brief Device Privacy. + * + * The privacy feature provides a way for the device to avoid being tracked over a period of + * time. The privacy feature, when enabled, hides the local device identity and replaces it + * with a private address that is automatically refreshed at a specified interval. + * + * If a device still wants to be recognized by other peers, it needs to share it's Identity + * Resolving Key (IRK). With this key, a device can generate a random private address that + * can only be recognized by peers in possession of that key, and devices can establish + * connections without revealing their real identities. + * + * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all + * bonding procedures performed after @ref sd_ble_gap_privacy_set returns. + * The IRK distributed during bonding procedure is the device IRK that is active when @ref + * sd_ble_gap_sec_params_reply is called. + */ +#if (NRF_SD_BLE_API_VERSION < 3) + +typedef struct +{ + uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */ + uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */ + uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */ + ble_gap_irk_t * p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used. + When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored. + By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */ +} pm_privacy_params_t; + + +/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes + * @{ */ +#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */ +#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */ +/**@} */ + +#else + +typedef ble_gap_privacy_params_t pm_privacy_params_t; + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* PEER_MANAGER_TYPES_H__ */ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/pm_buffer.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/pm_buffer.c new file mode 100644 index 0000000000000000000000000000000000000000..83fdf77f119d19c97463ad2b91f3f312affbf763 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/pm_buffer.c @@ -0,0 +1,151 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) +#include "pm_buffer.h" + +#include +#include +#include "nrf_error.h" +#include "pm_mutex.h" + + +#define BUFFER_IS_VALID(p_buffer) ((p_buffer != NULL) \ + && (p_buffer->p_memory != NULL) \ + && (p_buffer->p_mutex != NULL)) + + + +ret_code_t pm_buffer_init(pm_buffer_t * p_buffer, + uint8_t * p_buffer_memory, + uint32_t buffer_memory_size, + uint8_t * p_mutex_memory, + uint32_t mutex_memory_size, + uint32_t n_blocks, + uint32_t block_size) +{ + if ( (p_buffer != NULL) + && (p_buffer_memory != NULL) + && (p_mutex_memory != NULL) + && (buffer_memory_size >= (n_blocks * block_size)) + && (mutex_memory_size >= MUTEX_STORAGE_SIZE(n_blocks)) + && (n_blocks != 0) + && (block_size != 0)) + { + p_buffer->p_memory = p_buffer_memory; + p_buffer->p_mutex = p_mutex_memory; + p_buffer->n_blocks = n_blocks; + p_buffer->block_size = block_size; + pm_mutex_init(p_buffer->p_mutex, n_blocks); + + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INVALID_PARAM; + } +} + + +uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks) +{ + if (!BUFFER_IS_VALID(p_buffer)) + { + return ( PM_BUFFER_INVALID_ID ); + } + + uint8_t first_locked_mutex = PM_BUFFER_INVALID_ID; + + for (uint8_t i = 0; i < p_buffer->n_blocks; i++) + { + if (pm_mutex_lock(p_buffer->p_mutex, i)) + { + if (first_locked_mutex == PM_BUFFER_INVALID_ID) + { + first_locked_mutex = i; + } + if ((i - first_locked_mutex + 1) == n_blocks) + { + return first_locked_mutex; + } + } + else if (first_locked_mutex != PM_BUFFER_INVALID_ID) + { + for (uint8_t j = first_locked_mutex; j < i; j++) + { + pm_buffer_release(p_buffer, j); + } + first_locked_mutex = PM_BUFFER_INVALID_ID; + } + } + + return ( PM_BUFFER_INVALID_ID ); +} + + +uint8_t * pm_buffer_ptr_get(pm_buffer_t * p_buffer, uint8_t id) +{ + if (!BUFFER_IS_VALID(p_buffer)) + { + return ( NULL ); + } + + if ( (id != PM_BUFFER_INVALID_ID) + && pm_mutex_lock_status_get(p_buffer->p_mutex, id) ) + { + return ( &p_buffer->p_memory[id * p_buffer->block_size] ); + } + else + { + return ( NULL ); + } +} + + +void pm_buffer_release(pm_buffer_t * p_buffer, uint8_t id) +{ + if ( BUFFER_IS_VALID(p_buffer) + && (id != PM_BUFFER_INVALID_ID) + && pm_mutex_lock_status_get(p_buffer->p_mutex, id)) + { + pm_mutex_unlock(p_buffer->p_mutex, id); + } +} +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/pm_buffer.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/pm_buffer.h new file mode 100644 index 0000000000000000000000000000000000000000..1b1a6966ed7a04085c52fa5314799d2e98095330 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/pm_buffer.h @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BUFFER_H__ +#define BUFFER_H__ + +#include +#include "compiler_abstraction.h" +#include "sdk_errors.h" +#include "pm_mutex.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @cond NO_DOXYGEN + * @defgroup pm_buffer Buffer + * @ingroup peer_manager + * @{ + * @brief An internal module of @ref peer_manager. This module provides a simple buffer. + */ + + +#define PM_BUFFER_INVALID_ID 0xFF //!< Invalid buffer block ID. + + +/**@brief Convenience macro for declaring memory and initializing a buffer instance. + * + * @param[out] p_buffer The buffer instance to initialize. + * @param[in] n_blocks The desired number of blocks in the buffer. + * @param[in] block_size The desired block size of the buffer. + * @param[out] err_code The return code from @ref pm_buffer_init. + */ +#define PM_BUFFER_INIT(p_buffer, n_blocks, block_size, err_code) \ +do \ +{ \ + __ALIGN(4) static uint8_t buffer_memory[(n_blocks) * (block_size)]; \ + __ALIGN(4) static uint8_t mutex_memory[MUTEX_STORAGE_SIZE(n_blocks)]; \ + err_code = pm_buffer_init((p_buffer), \ + buffer_memory, \ + (n_blocks) * (block_size), \ + mutex_memory, \ + MUTEX_STORAGE_SIZE(n_blocks), \ + (n_blocks), \ + (block_size)); \ +} while (0) + + +typedef struct +{ + uint8_t * p_memory; /**< The storage for all buffer entries. The size of the buffer must be n_blocks*block_size. */ + uint8_t * p_mutex; /**< A mutex group with one mutex for each buffer entry. */ + uint32_t n_blocks; /**< The number of allocatable blocks in the buffer. */ + uint32_t block_size; /**< The size of each block in the buffer. */ +} pm_buffer_t; + +/**@brief Function for initializing a buffer instance. + * + * @param[out] p_buffer The buffer instance to initialize. + * @param[in] p_buffer_memory The memory this buffer will use. + * @param[in] buffer_memory_size The size of p_buffer_memory. This must be at least + * n_blocks*block_size. + * @param[in] p_mutex_memory The memory for the mutexes. This must be at least + * @ref MUTEX_STORAGE_SIZE(n_blocks). + * @param[in] mutex_memory_size The size of p_mutex_memory. + * @param[in] n_blocks The number of blocks in the buffer. + * @param[in] block_size The size of each block. + * + * @retval NRF_SUCCESS Successfully initialized buffer instance. + * @retval NRF_ERROR_INVALID_PARAM A parameter was 0 or NULL or a size was too small. + */ +ret_code_t pm_buffer_init(pm_buffer_t * p_buffer, + uint8_t * p_buffer_memory, + uint32_t buffer_memory_size, + uint8_t * p_mutex_memory, + uint32_t mutex_memory_size, + uint32_t n_blocks, + uint32_t block_size); + + +/**@brief Function for acquiring a buffer block in a buffer. + * + * @param[in] p_buffer The buffer instance acquire from. + * @param[in] n_blocks The number of contiguous blocks to acquire. + * + * @return The id of the acquired block, if successful. + * @retval PM_BUFFER_INVALID_ID If unsuccessful. + */ +uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks); + + +/**@brief Function for getting a pointer to a specific buffer block. + * + * @param[in] p_buffer The buffer instance get from. + * @param[in] id The id of the buffer to get the pointer for. + * + * @return A pointer to the buffer for the specified id, if the id is valid. + * @retval NULL If the id is invalid. + */ +uint8_t * pm_buffer_ptr_get(pm_buffer_t * p_buffer, uint8_t id); + + +/**@brief Function for releasing a buffer block. + * + * @param[in] p_buffer The buffer instance containing the block to release. + * @param[in] id The id of the block to release. + */ +void pm_buffer_release(pm_buffer_t * p_buffer, uint8_t id); + + + +#ifdef __cplusplus +} +#endif + +#endif // BUFFER_H__ + +/** + * @} + * @endcond + */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/pm_mutex.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/pm_mutex.c new file mode 100644 index 0000000000000000000000000000000000000000..10c26078b0913cfb45409198a332c1888ac5ad6c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/pm_mutex.c @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) +#include "pm_mutex.h" + +#include +#include +#include "nrf_error.h" +#include "app_util_platform.h" + + + +/**@brief Locks the mutex defined by the mask. + * + * @param p_mutex pointer to the mutex storage. + * @param mutex_mask the mask identifying the mutex position. + * + * @retval true if the mutex could be locked. + * @retval false if the mutex was already locked. + */ +static bool lock_by_mask(uint8_t * p_mutex, uint8_t mutex_mask) +{ + bool success = false; + + if ( (*p_mutex & mutex_mask) == 0 ) + { + CRITICAL_REGION_ENTER(); + if ( (*p_mutex & mutex_mask) == 0 ) + { + *p_mutex |= mutex_mask; + + success = true; + } + CRITICAL_REGION_EXIT(); + } + + return ( success ); +} + + +void pm_mutex_init(uint8_t * p_mutex, uint16_t mutex_size) +{ + if (p_mutex != NULL) + { + memset(&p_mutex[0], 0, MUTEX_STORAGE_SIZE(mutex_size)); + } +} + + +bool pm_mutex_lock(uint8_t * p_mutex, uint16_t mutex_id) +{ + if (p_mutex != NULL) + { + return ( lock_by_mask(&(p_mutex[mutex_id >> 3]), (1 << (mutex_id & 0x07))) ); + } + else + { + return false; + } +} + + +void pm_mutex_unlock(uint8_t * p_mutex, uint16_t mutex_id) +{ + uint8_t mutex_base = mutex_id >> 3; + uint8_t mutex_mask = (1 << (mutex_id & 0x07)); + + if ((p_mutex != NULL) + && (p_mutex[mutex_base] & mutex_mask)) + { + CRITICAL_REGION_ENTER(); + p_mutex[mutex_base] &= ~mutex_mask; + CRITICAL_REGION_EXIT(); + } +} + + +uint16_t pm_mutex_lock_first_available(uint8_t * p_mutex, uint16_t mutex_size) +{ + if (p_mutex != NULL) + { + for ( uint16_t i = 0; i < mutex_size; i++ ) + { + if ( lock_by_mask(&(p_mutex[i >> 3]), 1 << (i & 0x07)) ) + { + return ( i ); + } + } + } + + return ( mutex_size ); +} + + +bool pm_mutex_lock_status_get(uint8_t * p_mutex, uint16_t mutex_id) +{ + if (p_mutex != NULL) + { + return ( (p_mutex[mutex_id >> 3] & (1 << (mutex_id & 0x07))) ); + } + else + { + return true; + } +} +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/pm_mutex.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/pm_mutex.h new file mode 100644 index 0000000000000000000000000000000000000000..7031d73fcb190be04a8c9d5c435ebf9c4ed0e9e5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/pm_mutex.h @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MUTEX_H__ +#define MUTEX_H__ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @cond NO_DOXYGEN + * @defgroup pm_mutex Mutex + * @ingroup peer_manager + * @{ + * @brief An internal module of @ref peer_manager. This module provides thread-safe mutexes. + */ + + +/**@brief Defines the storage size of a specified mutex group. + * + * @param number_of_mutexes the number of mutexes in the group. + */ +#define MUTEX_STORAGE_SIZE(number_of_mutexes) ((7 + (number_of_mutexes)) >> 3) + + +/**@brief Initializes a mutex group. + * + * @param[in] p_mutex Pointer to the mutex group. See @ref MUTEX_STORAGE_SIZE(). + * @param[in] mutex_size The size of the mutex group in number of mutexes. + */ +void pm_mutex_init(uint8_t * p_mutex, uint16_t mutex_size); + + +/**@brief Locks the mutex specified by the bit id. + * + * @param[inout] p_mutex Pointer to the mutex group. + * @param[in] mutex_bit_id The bit id of the mutex. + * + * @retval true if it was possible to lock the mutex. + * @retval false otherwise. + */ +bool pm_mutex_lock(uint8_t * p_mutex, uint16_t mutex_bit_id); + + +/**@brief Locks the first unlocked mutex within the mutex group. + * + * @param[in, out] p_mutex Pointer to the mutex group. + * @param[in] mutex_size The size of the mutex group. + * + * @return The first unlocked mutex id in the group. + * @retval group-size if there was no unlocked mutex available. + */ +uint16_t pm_mutex_lock_first_available(uint8_t * p_mutex, uint16_t mutex_size); + + +/**@brief Unlocks the mutex specified by the bit id. + * + * @param[in, out] p_mutex Pointer to the mutex group. + * @param[in] mutex_bit_id The bit id of the mutex. + */ +void pm_mutex_unlock(uint8_t * p_mutex, uint16_t mutex_bit_id); + + +/**@brief Gets the locking status of the specified mutex. + * + * @param[in, out] p_mutex Pointer to the mutex group. + * @param[in] mutex_bit_id The bit id of the mutex. + * + * @retval true if the mutex was locked. + * @retval false otherwise. + */ +bool pm_mutex_lock_status_get(uint8_t * p_mutex, uint16_t mutex_bit_id); + + + +#ifdef __cplusplus +} +#endif + +#endif // MUTEX_H__ + +/** @} + * @endcond + */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/security_dispatcher.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/security_dispatcher.c new file mode 100644 index 0000000000000000000000000000000000000000..a2550f46491478d3083b6b358616964121165022 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/security_dispatcher.c @@ -0,0 +1,898 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) +#include "security_dispatcher.h" + +#include +#include "ble.h" +#include "ble_gap.h" +#include "ble_conn_state.h" +#include "peer_manager_types.h" +#include "peer_database.h" +#include "id_manager.h" + + +// The number of registered event handlers. +#define SMD_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0])) + + +// Security Dispacher event handlers in Security Manager and GATT Cache Manager. +extern void sm_smd_evt_handler(smd_evt_t const * p_event); +extern void gcm_smd_evt_handler(smd_evt_t const * p_event); + +// Security Dispatcher events' handlers. +// The number of elements in this array is SMD_EVENT_HANDLERS_CNT. +static smd_evt_handler_t const m_evt_handlers[] = +{ + sm_smd_evt_handler, + gcm_smd_evt_handler +}; + +static bool m_module_initialized; + +static ble_conn_state_user_flag_id_t m_flag_sec_proc = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_sec_proc_pairing = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_sec_proc_new_peer = BLE_CONN_STATE_USER_FLAG_INVALID; + +static ble_gap_lesc_p256_pk_t m_peer_pk; + + +static void evt_send(smd_evt_t * p_event) +{ + for (uint32_t i = 0; i < SMD_EVENT_HANDLERS_CNT; i++) + { + m_evt_handlers[i](p_event); + } +} + + +static void sec_start_send(uint16_t conn_handle, pm_conn_sec_procedure_t procedure) +{ + smd_evt_t evt = + { + .evt_id = SMD_EVT_SEC_PROCEDURE_START, + .conn_handle = conn_handle, + .params = {.sec_procedure_start = {.procedure = procedure}} + }; + evt_send(&evt); +} + + +/**@brief Event handler for events from the Peer Database module. + * This handler is extern in Peer Database. + * + * @param[in] p_event The event that has happened. + */ +void smd_pdb_evt_handler(pdb_evt_t const * p_event) +{ + if ((p_event->evt_id == PDB_EVT_WRITE_BUF_STORED) && (p_event->data_id == PM_PEER_DATA_ID_BONDING)) + { + smd_evt_t evt = + { + .evt_id = SMD_EVT_BONDING_INFO_STORED, + .conn_handle = im_conn_handle_get(p_event->peer_id), + .params = {.bonding_info_stored = {.peer_id = p_event->peer_id}} + }; + evt_send(&evt); + } +} + + +/**@brief Function for processing the @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST event from the SoftDevice. + * + * @param[in] p_gap_evt The event from the SoftDevice. + */ +static void sec_params_request_process(ble_gap_evt_t * p_gap_evt) +{ + smd_evt_t evt = + { + .evt_id = SMD_EVT_PARAMS_REQ, + .conn_handle = p_gap_evt->conn_handle + }; + evt_send(&evt); + return; +} + + +/**@brief Function for administrative actions to be taken when a security process has been attempted. + * + * @param[in] conn_handle The connection the security process was attempted on. + * @param[in] peer_id The peer ID given to the connected peer. + * @param[in] success Whether the process was started successfully. + * @param[in] pairing Whether the process was a pairing process. + * @param[in] new_peer_created Whether a new peer was created during the process attempt. + */ +static void sec_proc_start(uint16_t conn_handle, + pm_peer_id_t peer_id, + bool success, + bool pairing, + bool new_peer_created) +{ + ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc, success); + + if (success) + { + ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc_pairing, pairing); + ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc_new_peer, new_peer_created); + + if (new_peer_created) + { + im_new_peer_id(conn_handle, peer_id); + } + } + else + { + if (new_peer_created) + { + ret_code_t err_code = im_peer_free(peer_id); // Attempt to free allocated peer. + UNUSED_VARIABLE(err_code); + } + } +} + + + +/**@brief Function for processing the @ref BLE_GAP_EVT_SEC_INFO_REQUEST event from the SoftDevice. + * + * @param[in] p_gap_evt The event from the SoftDevice. + */ +static void sec_info_request_process(ble_gap_evt_t * p_gap_evt) +{ + ret_code_t err_code; + ble_gap_enc_info_t const * p_enc_info = NULL; + pm_peer_data_flash_t peer_data; + pm_peer_id_t peer_id = im_peer_id_get_by_master_id(&p_gap_evt->params.sec_info_request.master_id); + smd_evt_t evt; + + evt.conn_handle = p_gap_evt->conn_handle; + + if (peer_id == PM_PEER_ID_INVALID) + { + peer_id = im_peer_id_get_by_conn_handle(p_gap_evt->conn_handle); + } + + if (peer_id != PM_PEER_ID_INVALID) + { + err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_BONDING, &peer_data); + + if (err_code == NRF_SUCCESS) + { + // There is stored bonding data for this peer. + ble_gap_enc_key_t const * p_existing_key = &peer_data.p_bonding_data->own_ltk; + + if ( p_existing_key->enc_info.lesc + || (im_master_ids_compare(&p_existing_key->master_id, + &p_gap_evt->params.sec_info_request.master_id))) + { + p_enc_info = &p_existing_key->enc_info; + } + } + } + + // All return values from the following can be safely ignored. + err_code = sd_ble_gap_sec_info_reply(p_gap_evt->conn_handle, p_enc_info, NULL, NULL); + + if (err_code != NRF_SUCCESS) + { + evt.evt_id = SMD_EVT_ERROR_UNEXPECTED; + evt.params.error_unexpected.error = err_code; + + evt_send(&evt); + } + else if (p_enc_info == NULL) + { + evt.evt_id = SMD_EVT_LINK_ENCRYPTION_FAILED; + evt.params.link_encryption_failed.error = PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING; + evt.params.link_encryption_failed.error_src = BLE_GAP_SEC_STATUS_SOURCE_LOCAL; + + evt_send(&evt); + + sec_proc_start(p_gap_evt->conn_handle, peer_id, false, false, false); + } + else + { + sec_start_send(p_gap_evt->conn_handle, PM_LINK_SECURED_PROCEDURE_ENCRYPTION); + + sec_proc_start(p_gap_evt->conn_handle, peer_id, err_code == NRF_SUCCESS, false, false); + } + + + return; +} + + +/**@brief Function for processing the @ref BLE_GAP_EVT_SEC_REQUEST event from the SoftDevice. + * + * @param[in] p_gap_evt The event from the SoftDevice. + */ +static void sec_request_process(ble_gap_evt_t * p_gap_evt) +{ + smd_evt_t evt = + { + .evt_id = SMD_EVT_SLAVE_SECURITY_REQ, + .conn_handle = p_gap_evt->conn_handle, + .params = + { + .slave_security_req = + { + .bond = p_gap_evt->params.sec_request.bond, + .mitm = p_gap_evt->params.sec_request.mitm, + } + } + }; + evt_send(&evt); + return; +} + + +/**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice, when + * the auth_status is success. + * + * @param[in] p_gap_evt The event from the SoftDevice. + */ +static void auth_status_success_process(ble_gap_evt_t * p_gap_evt) +{ + ret_code_t err_code = NRF_SUCCESS; + uint8_t role = ble_conn_state_role(p_gap_evt->conn_handle); + pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(p_gap_evt->conn_handle); + ble_gap_sec_kdist_t kdist_own = p_gap_evt->params.auth_status.kdist_own; + ble_gap_sec_kdist_t kdist_peer = p_gap_evt->params.auth_status.kdist_peer; + + ble_conn_state_user_flag_set(p_gap_evt->conn_handle, m_flag_sec_proc, false); + + if (role == BLE_GAP_ROLE_INVALID) + { + /* Unlikely, but maybe possible? */ + return; + } + + if (p_gap_evt->params.auth_status.bonded) + { + + err_code = pdb_write_buf_store(peer_id, PM_PEER_DATA_ID_BONDING); + if (err_code != NRF_SUCCESS) + { + /* Unexpected */ + smd_evt_t error_evt; + + error_evt.evt_id = SMD_EVT_ERROR_BONDING_INFO; + error_evt.conn_handle = p_gap_evt->conn_handle; + error_evt.params.error_bonding_info.peer_id = peer_id; + error_evt.params.error_bonding_info.error = err_code; + + evt_send(&error_evt); + } + + } + else if (ble_conn_state_user_flag_get(p_gap_evt->conn_handle, m_flag_sec_proc_new_peer)) + { + ret_code_t err_code_free = im_peer_free(peer_id); + UNUSED_VARIABLE(err_code_free); // Errors can be safely ignored. + } + + smd_evt_t pairing_success_evt; + + pairing_success_evt.evt_id = SMD_EVT_PAIRING_SUCCESS; + pairing_success_evt.conn_handle = p_gap_evt->conn_handle; + pairing_success_evt.params.pairing_success.bonded = p_gap_evt->params.auth_status.bonded; + pairing_success_evt.params.pairing_success.mitm = p_gap_evt->params.auth_status.sm1_levels.lv3; + pairing_success_evt.params.pairing_success.kdist_own = kdist_own; + pairing_success_evt.params.pairing_success.kdist_peer = kdist_peer; + + evt_send(&pairing_success_evt); + return; +} + + +/**@brief Function for cleaning up after a failed pairing procedure. + * + * @param[in] conn_handle The handle of the connection the pairing procedure happens on. + * @param[in] peer_id The peer id used in the pairing procedure. + * @param[in] error The error the procedure failed with. + * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES. + */ +static void pairing_failure(uint16_t conn_handle, + pm_peer_id_t peer_id, + pm_sec_error_code_t error, + uint8_t error_src) +{ + ret_code_t err_code = NRF_SUCCESS; + + smd_evt_t evt = + { + .evt_id = SMD_EVT_PAIRING_FAIL, + .conn_handle = conn_handle, + .params = + { + .pairing_failed = + { + .error = error, + .error_src = error_src, + } + } + }; + + if (ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc_new_peer)) + { + // The peer_id was created during the procedure, and should be freed, because no data is + // stored under it. + err_code = im_peer_free(peer_id); // Attempt to free allocated peer. + UNUSED_VARIABLE(err_code); + } + else + { + err_code = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_BONDING); + if ((err_code != NRF_SUCCESS) && (err_code == NRF_ERROR_NOT_FOUND /* No buffer was allocated */)) + { + smd_evt_t error_evt; + error_evt.evt_id = SMD_EVT_ERROR_UNEXPECTED; + error_evt.conn_handle = conn_handle; + error_evt.params.error_unexpected.error = err_code; + evt_send(&error_evt); + } + } + + ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc, false); + + evt_send(&evt); + return; +} + + +/**@brief Function for cleaning up after a failed encryption procedure. + * + * @param[in] conn_handle The handle of the connection the encryption procedure happens on. + * @param[in] error The error the procedure failed with. + * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES. + */ +static void encryption_failure(uint16_t conn_handle, + pm_sec_error_code_t error, + uint8_t error_src) +{ + smd_evt_t evt = + { + .evt_id = SMD_EVT_LINK_ENCRYPTION_FAILED, + .conn_handle = conn_handle, + .params = + { + .link_encryption_failed = + { + .error = error, + .error_src = error_src, + } + } + }; + + ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc, false); + + evt_send(&evt); + return; +} + + +/**@brief Function for possibly cleaning up after a failed pairing or encryption procedure. + * + * @param[in] conn_handle The handle of the connection the pairing procedure happens on. + * @param[in] peer_id The peer id used in the pairing procedure. + * @param[in] error The error the procedure failed with. + * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES. + */ +static void link_secure_failure(uint16_t conn_handle, + pm_sec_error_code_t error, + uint8_t error_src) +{ + if (ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc)) + { + pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle); + + if (peer_id != PM_PEER_ID_INVALID) + { + if (ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc_pairing)) + { + pairing_failure(conn_handle, peer_id, error, error_src); + } + else + { + encryption_failure(conn_handle, error, error_src); + } + } + } +} + + +/**@brief Function for processing the @ref BLE_GAP_EVT_DISCONNECT event from the SoftDevice. + * + * @param[in] p_gap_evt The event from the SoftDevice. + */ +static void disconnect_process(ble_gap_evt_t * p_gap_evt) +{ + pm_sec_error_code_t error = (p_gap_evt->params.disconnected.reason + == BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE) + ? PM_CONN_SEC_ERROR_MIC_FAILURE : PM_CONN_SEC_ERROR_DISCONNECT; + + link_secure_failure(p_gap_evt->conn_handle, error, BLE_GAP_SEC_STATUS_SOURCE_LOCAL); +} + + +/**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice, when + * the auth_status is failure. + * + * @param[in] p_gap_evt The event from the SoftDevice. + */ +static void auth_status_failure_process(ble_gap_evt_t * p_gap_evt) +{ + link_secure_failure(p_gap_evt->conn_handle, + p_gap_evt->params.auth_status.auth_status, + p_gap_evt->params.auth_status.error_src); +} + + +/**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice. + * + * @param[in] p_gap_evt The event from the SoftDevice. + */ +static void auth_status_process(ble_gap_evt_t * p_gap_evt) +{ + switch (p_gap_evt->params.auth_status.auth_status) + { + case BLE_GAP_SEC_STATUS_SUCCESS: + auth_status_success_process(p_gap_evt); + break; + + default: + auth_status_failure_process(p_gap_evt); + break; + } +} + + +/**@brief Function for processing the @ref BLE_GAP_EVT_CONN_SEC_UPDATE event from the SoftDevice. + * + * @param[in] p_gap_evt The event from the SoftDevice. + */ +static void conn_sec_update_process(ble_gap_evt_t * p_gap_evt) +{ + if (ble_conn_state_encrypted(p_gap_evt->conn_handle)) + { + if (!ble_conn_state_user_flag_get(p_gap_evt->conn_handle, m_flag_sec_proc_pairing)) + { + ble_conn_state_user_flag_set(p_gap_evt->conn_handle, m_flag_sec_proc, false); + } + + smd_evt_t evt; + + evt.conn_handle = p_gap_evt->conn_handle; + evt.evt_id = SMD_EVT_LINK_ENCRYPTION_UPDATE; + evt.params.link_encryption_update.mitm_protected + = ble_conn_state_mitm_protected(p_gap_evt->conn_handle); + evt_send(&evt); + } + else + { + encryption_failure(p_gap_evt->conn_handle, + PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING, + BLE_GAP_SEC_STATUS_SOURCE_REMOTE); + } +} + + +/**@brief Funtion for initializing a BLE Connection State user flag. + * + * @param[out] flag_id The flag to initialize. + */ +static void flag_id_init(ble_conn_state_user_flag_id_t * p_flag_id) +{ + if (*p_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) + { + *p_flag_id = ble_conn_state_user_flag_acquire(); + } +} + + +ret_code_t smd_init(void) +{ + NRF_PM_DEBUG_CHECK(!m_module_initialized); + + flag_id_init(&m_flag_sec_proc); + flag_id_init(&m_flag_sec_proc_pairing); + flag_id_init(&m_flag_sec_proc_new_peer); + + if ((m_flag_sec_proc == BLE_CONN_STATE_USER_FLAG_INVALID) || + (m_flag_sec_proc_pairing == BLE_CONN_STATE_USER_FLAG_INVALID) || + (m_flag_sec_proc_new_peer == BLE_CONN_STATE_USER_FLAG_INVALID)) + { + return NRF_ERROR_INTERNAL; + } + + m_module_initialized = true; + + return NRF_SUCCESS; +} + + +ret_code_t smd_params_reply(uint16_t conn_handle, + ble_gap_sec_params_t * p_sec_params, + ble_gap_lesc_p256_pk_t * p_public_key) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + uint8_t role = ble_conn_state_role(conn_handle); + pm_peer_id_t peer_id = PM_PEER_ID_INVALID; + ret_code_t err_code = NRF_SUCCESS; + uint8_t sec_status = BLE_GAP_SEC_STATUS_SUCCESS; + ble_gap_sec_keyset_t sec_keyset; + bool new_peer_created = false; + + memset(&sec_keyset, 0, sizeof(ble_gap_sec_keyset_t)); + + if (role == BLE_GAP_ROLE_INVALID) + { + return BLE_ERROR_INVALID_CONN_HANDLE; + } + + if (p_sec_params == NULL) + { + // NULL params means reject pairing. + sec_status = BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP; + } + else if (p_sec_params->bond) + { + // Bonding is to be performed, prepare to receive bonding data. + pm_peer_data_t peer_data; + + peer_id = im_peer_id_get_by_conn_handle(conn_handle); + + if (peer_id == PM_PEER_ID_INVALID) + { + // Peer is unknown to us, allocate a new peer ID for it. + peer_id = pdb_peer_allocate(); + if (peer_id != PM_PEER_ID_INVALID) + { + new_peer_created = true; + } + else + { + err_code = NRF_ERROR_INTERNAL; + } + } + + if (err_code == NRF_SUCCESS) + { + // Peer ID is ready, acquire a memory buffer to receive bonding data into. + err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, 1, &peer_data); + if (err_code == NRF_SUCCESS) + { + memset(peer_data.p_bonding_data, 0, sizeof(pm_peer_data_bonding_t)); + + peer_data.p_bonding_data->own_role = role; + + sec_keyset.keys_own.p_enc_key = &peer_data.p_bonding_data->own_ltk; + sec_keyset.keys_own.p_pk = p_public_key; + sec_keyset.keys_peer.p_enc_key = &peer_data.p_bonding_data->peer_ltk; + sec_keyset.keys_peer.p_id_key = &peer_data.p_bonding_data->peer_ble_id; + sec_keyset.keys_peer.p_pk = &m_peer_pk; + + // Retrieve the address the peer used during connection establishment. + // This address will be overwritten if ID is shared. Should not fail. + ret_code_t err_code_addr = im_ble_addr_get(conn_handle, + &peer_data.p_bonding_data->peer_ble_id.id_addr_info); + UNUSED_VARIABLE(err_code_addr); + + // Buffer is OK, reserve room in flash for the data. + err_code = pdb_write_buf_store_prepare(peer_id, PM_PEER_DATA_ID_BONDING); + } + } + } + else + { + // Pairing, no bonding. + + sec_keyset.keys_own.p_pk = p_public_key; + sec_keyset.keys_peer.p_pk = &m_peer_pk; + } + + if (err_code == NRF_SUCCESS) + { + // Everything OK, reply to SoftDevice. If an error happened, the user is given an + // opportunity to change the parameters and retry the call. + if (role == BLE_GAP_ROLE_CENTRAL) + { + err_code = sd_ble_gap_sec_params_reply(conn_handle, sec_status, NULL, &sec_keyset); + } + else + { + err_code = sd_ble_gap_sec_params_reply(conn_handle, sec_status, p_sec_params, &sec_keyset); + + if ((p_sec_params != NULL) && (err_code == NRF_SUCCESS)) + { + pm_conn_sec_procedure_t procedure = p_sec_params->bond + ? PM_LINK_SECURED_PROCEDURE_BONDING + : PM_LINK_SECURED_PROCEDURE_PAIRING; + sec_start_send(conn_handle, procedure); + } + } + } + + sec_proc_start(conn_handle, + peer_id, + (err_code == NRF_SUCCESS) && (sec_status != BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP), + true, + new_peer_created); + + return err_code; +} + + +static ret_code_t link_secure_central_existing_peer(uint16_t conn_handle, + ble_gap_sec_params_t * p_sec_params, + bool force_repairing, + pm_peer_id_t peer_id, + pm_conn_sec_procedure_t * procedure) +{ + pm_peer_data_flash_t peer_data; + pm_peer_data_t dummy_peer_data; + ret_code_t err_code; + ble_gap_enc_key_t const * p_existing_key = NULL; + bool lesc = false; + + err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_BONDING, &peer_data); + + if (err_code == NRF_SUCCESS) + { + // Use peer's key since they are peripheral. + p_existing_key = &(peer_data.p_bonding_data->peer_ltk); + + lesc = peer_data.p_bonding_data->own_ltk.enc_info.lesc; + if (lesc) // LESC was used during bonding. + { + // For LESC, always use own key. + p_existing_key = &(peer_data.p_bonding_data->own_ltk); + } + } + + if (!force_repairing + && (err_code == NRF_SUCCESS) + && (p_existing_key != NULL) + && (lesc || im_master_id_is_valid(&(p_existing_key->master_id)))) /* There is a valid LTK stored. */ + //&& (p_existing_key->enc_info.auth >= p_sec_params->mitm) /* The requested MITM security is at or below the existing level. */ + //&& (!p_sec_params->mitm || (lesc >= p_sec_params->lesc))) /* The requested LESC security is at or below the existing level. We only care about LESC if MITM is required. */ + { + err_code = sd_ble_gap_encrypt(conn_handle, &(p_existing_key->master_id), &(p_existing_key->enc_info)); + + *procedure = PM_LINK_SECURED_PROCEDURE_ENCRYPTION; + } + else if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND)) + { + /* Re-pairing is needed, because there is no LTK available or the existing key is not + secure enough */ + err_code = NRF_SUCCESS; + + if (p_sec_params->bond) + { + err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, 1, &dummy_peer_data); + if (err_code == NRF_SUCCESS) + { + err_code = pdb_write_buf_store_prepare(peer_id, PM_PEER_DATA_ID_BONDING); + } + } + + if (err_code == NRF_SUCCESS) + { + err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params); + } + + if (err_code != NRF_SUCCESS) + { + ret_code_t err_code_release = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_BONDING); + if ((err_code_release != NRF_SUCCESS) && (err_code_release != NRF_ERROR_NOT_FOUND)) + { + err_code = NRF_ERROR_INTERNAL; + } + } + } + + sec_proc_start(conn_handle, + peer_id, + err_code == NRF_SUCCESS, + *procedure != PM_LINK_SECURED_PROCEDURE_ENCRYPTION, + false); + + return err_code; +} + + +static ret_code_t link_secure_central_new_peer(uint16_t conn_handle, + ble_gap_sec_params_t * p_sec_params) +{ + pm_peer_id_t peer_id = pdb_peer_allocate(); + pm_peer_data_t dummy_peer_data; + ret_code_t err_code; + + if (peer_id != PM_PEER_ID_INVALID) + { + err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, 1, &dummy_peer_data); + if (err_code == NRF_SUCCESS) + { + err_code = pdb_write_buf_store_prepare(peer_id, PM_PEER_DATA_ID_BONDING); + } + + if (err_code == NRF_SUCCESS) + { + err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params); + } + + if (err_code != NRF_SUCCESS) + { + ret_code_t err_code_free = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_BONDING); + if ((err_code_free != NRF_SUCCESS) && (err_code_free != NRF_ERROR_NOT_FOUND)) + { + err_code = NRF_ERROR_INTERNAL; + } + } + } + else + { + err_code = NRF_ERROR_INTERNAL; + } + + sec_proc_start(conn_handle, + peer_id, + err_code == NRF_SUCCESS, + true, + peer_id != PM_PEER_ID_INVALID); + + return err_code; +} + + +static ret_code_t link_secure_central(uint16_t conn_handle, + ble_gap_sec_params_t * p_sec_params, + bool force_repairing) +{ + ret_code_t err_code; + pm_peer_id_t peer_id; + + if (p_sec_params == NULL) + { + return sd_ble_gap_authenticate(conn_handle, NULL); + } + + pm_conn_sec_procedure_t procedure = p_sec_params->bond ? PM_LINK_SECURED_PROCEDURE_BONDING + : PM_LINK_SECURED_PROCEDURE_PAIRING; + + peer_id = im_peer_id_get_by_conn_handle(conn_handle); + + if (peer_id != PM_PEER_ID_INVALID) + { + // There is already data in flash for this peer. + err_code = link_secure_central_existing_peer(conn_handle, + p_sec_params, + force_repairing, + peer_id, + &procedure); + } + else if (p_sec_params->bond) + { + // New peer is required. + err_code = link_secure_central_new_peer(conn_handle, p_sec_params); + } + else + { + // No bonding, only pairing. + err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params); + + sec_proc_start(conn_handle, peer_id, err_code == NRF_SUCCESS, true, false); + } + + if (err_code == NRF_SUCCESS) + { + sec_start_send(conn_handle, procedure); + } + + return err_code; +} + + +static ret_code_t link_secure_peripheral(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params) +{ + // This should never happen for a peripheral. + NRF_PM_DEBUG_CHECK(p_sec_params != NULL); + + // VERIFY_PARAM_NOT_NULL(p_sec_params); + + ret_code_t err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params); + + return err_code; +} + + +ret_code_t smd_link_secure(uint16_t conn_handle, + ble_gap_sec_params_t * p_sec_params, + bool force_repairing) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + uint8_t role = ble_conn_state_role(conn_handle); + + switch (role) + { + case BLE_GAP_ROLE_CENTRAL: + return link_secure_central(conn_handle, p_sec_params, force_repairing); + + case BLE_GAP_ROLE_PERIPH: + return link_secure_peripheral(conn_handle, p_sec_params); + + default: + return BLE_ERROR_INVALID_CONN_HANDLE; + } +} + + +void smd_ble_evt_handler(ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_DISCONNECTED: + disconnect_process(&(p_ble_evt->evt.gap_evt)); + break; + + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + sec_params_request_process(&(p_ble_evt->evt.gap_evt)); + break; + + case BLE_GAP_EVT_SEC_INFO_REQUEST: + sec_info_request_process(&(p_ble_evt->evt.gap_evt)); + break; + + case BLE_GAP_EVT_SEC_REQUEST: + sec_request_process(&(p_ble_evt->evt.gap_evt)); + break; + + case BLE_GAP_EVT_AUTH_STATUS: + auth_status_process(&(p_ble_evt->evt.gap_evt)); + break; + + case BLE_GAP_EVT_CONN_SEC_UPDATE: + conn_sec_update_process(&(p_ble_evt->evt.gap_evt)); + break; + }; +} +#endif //NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/security_dispatcher.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/security_dispatcher.h new file mode 100644 index 0000000000000000000000000000000000000000..b1b3201bffa2665cef2336d301b8a7d7ffedc65b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/security_dispatcher.h @@ -0,0 +1,296 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SECURITY_DISPATCHER_H__ +#define SECURITY_DISPATCHER_H__ + +#include +#include "sdk_errors.h" +#include "ble.h" +#include "ble_gap.h" +#include "peer_manager_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @cond NO_DOXYGEN + * @defgroup security_dispatcher Security Dispatcher + * @ingroup peer_manager + * @{ + * @brief An internal module of @ref peer_manager. A module for streamlining pairing, bonding, and + * encryption, including flash storage of shared data. + * + */ + + +/**@brief Events that can come from the Security Dispatcher module. + */ +typedef enum +{ + SMD_EVT_PARAMS_REQ, /**< Parameters are required for a pairing procedure on the specified connection. The user must provide them using @ref smd_params_reply. */ + SMD_EVT_SLAVE_SECURITY_REQ, /**< The peer (slave) has requested link encryption. Call @ref smd_link_secure to honor the request. The data in the event structure must be used in the parameters. */ + SMD_EVT_SEC_PROCEDURE_START, /**< A security procedure has started. */ + SMD_EVT_PAIRING_SUCCESS, /**< A pairing procedure (and bonding if applicable) has completed with success. */ + SMD_EVT_PAIRING_FAIL, /**< A pairing procedure has failed which means no encryption and no bond could be established. */ + SMD_EVT_LINK_ENCRYPTION_UPDATE, /**< The security level of the link has been updated. The link is encrypted. */ + SMD_EVT_LINK_ENCRYPTION_FAILED, /**< An attempt to start encryption on an unencrypted link failed because the peripheral did not have the correct keys. If the peer is the peripheral, the force_repairing flag should be set when reattempting @ref smd_link_secure. */ + SMD_EVT_BONDING_INFO_STORED, /**< Information exchanged during bonding with a peer has been stored persistently. */ + SMD_EVT_ERROR_BONDING_INFO, /**< Information exchanged during bonding with a peer could not be stored persistently, because of an unexpected error. */ + // SMD_EVT_ERROR_NO_MEM, /**< An operation failed because there was no available storage room in persistent storage. Please free up room, and the operation will automatically continue. */ + SMD_EVT_ERROR_UNEXPECTED, /**< An operation failed with an unexpected error. The error is provided. This is possibly a fatal error. */ +} smd_evt_id_t; + + +/**@brief Events parameters specific to the @ref SMD_EVT_SLAVE_SECURITY_REQ event. + */ +typedef struct +{ + bool bond; + bool mitm; +} smd_evt_slave_security_req_t; + + +/**@brief Events parameters specific to the @ref SMD_EVT_SEC_PROCEDURE_START event. + */ +typedef struct +{ + pm_conn_sec_procedure_t procedure; /**< The procedure that has started. */ +} smd_evt_sec_procedure_start_t; + + +/**@brief Events parameters specific to the @ref SMD_EVT_PAIRING_SUCCESS event. + */ +typedef struct +{ + bool bonded; /**< Whether bonding was performed. */ + bool mitm; /**< Whether MITM protection was used during pairing. */ + ble_gap_sec_kdist_t kdist_own; /**< Which keys were distributed to the peer. Only relevant if bonding was performed. */ + ble_gap_sec_kdist_t kdist_peer; /**< Which keys were distributed by the peer. Only relevant if bonding was performed. */ +} smd_evt_pairing_success_t; + + +/**@brief Events parameters specific to the @ref SMD_EVT_PAIRING_FAIL event. + */ +typedef struct +{ + pm_sec_error_code_t error; /**< What went wrong. */ + uint8_t error_src; /**< The party that raised the error, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ +} smd_evt_pairing_failed_t; + + +/**@brief Events parameters specific to the @ref SMD_EVT_LINK_ENCRYPTION_UPDATE event. + */ +typedef struct +{ + bool mitm_protected; /**< Whether the link is now MITM protected. */ +} smd_evt_link_encryption_update_t; + + +/**@brief Events parameters specific to the @ref SMD_EVT_LINK_ENCRYPTION_FAILED event. + */ +typedef struct +{ + pm_sec_error_code_t error; /**< What went wrong. */ + uint8_t error_src; /**< The party that raised the error, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ +} smd_evt_link_encryption_failed_t; + + +/**@brief Events parameters specific to the @ref SMD_EVT_BONDING_INFO_STORED event. + */ +typedef struct +{ + pm_peer_id_t peer_id; /**< The peer this event pertains to. */ +} smd_evt_bonding_info_stored_t; + + +/**@brief Events parameters specific to the @ref SMD_EVT_ERROR_BONDING_INFO event. + */ +typedef struct +{ + pm_peer_id_t peer_id; /**< The peer this event pertains to, if previously bonded. @ref PM_PEER_ID_INVALID if no successful bonding has happened with the peer before. */ + ret_code_t error; /**< The unexpected error that occurred. */ +} smd_evt_error_bonding_info_t; + + +// typedef struct +// { + // pm_peer_id_t peer_id; /**< The peer this event pertains to. */ +// } smd_evt_error_no_mem_t; + + +/**@brief Events parameters specific to the @ref SMD_EVT_ERROR_UNEXPECTED event. + */ +typedef struct +{ + ret_code_t error; /**< The unexpected error that occurred. */ +} smd_evt_error_unexpected_t; + + +typedef union +{ + smd_evt_slave_security_req_t slave_security_req; + smd_evt_sec_procedure_start_t sec_procedure_start; + smd_evt_pairing_success_t pairing_success; + smd_evt_pairing_failed_t pairing_failed; + smd_evt_link_encryption_update_t link_encryption_update; + smd_evt_link_encryption_failed_t link_encryption_failed; + smd_evt_bonding_info_stored_t bonding_info_stored; + smd_evt_error_bonding_info_t error_bonding_info; + // smd_evt_error_no_mem_t error_no_mem; + smd_evt_error_unexpected_t error_unexpected; +} smd_evt_params_t; /**< Event specific parameters. Chosen based on evt_id. */ + + +/**@brief Structure describing events from the Security Dispatcher module. + */ +typedef struct +{ + smd_evt_id_t evt_id; /**< The type of event. */ + uint16_t conn_handle; /**< The connection this event pertains to. */ + smd_evt_params_t params; /**< Event specific parameters. Chosen based on evt_id. */ +} smd_evt_t; + + + +/**@brief Event handler for events from the Security Dispatcher module. + * + * @param[in] p_event The event that has happened. + */ +typedef void (*smd_evt_handler_t)(smd_evt_t const * p_event); + + +#if 0 +/**@brief Function for registering with the Security Dispatcher module. This function also + * initializes the module if uninitialized. + * + * @param[in] evt_handler Callback for events from the Security Dispatcher module. + * + * @retval NRF_SUCCESS Registration was successful. + * @retval NRF_ERROR_NO_MEM No more registrations possible. + * @retval NRF_ERROR_NULL evt_handler was NULL. + */ +ret_code_t smd_register(smd_evt_handler_t evt_handler); +#endif + + +ret_code_t smd_init(void); + + +/**@brief Function for dispatching SoftDevice events to the Security Dispatcher module. + * + * @param[in] ble_evt The SoftDevice event. + */ +void smd_ble_evt_handler(ble_evt_t * ble_evt); + + +/**@brief Function for providing pairing and bonding parameters to use for the current pairing + * procedure on a connection. + * + * @note If this function returns an @ref NRF_ERROR_NULL, @ref NRF_ERROR_INVALID_PARAM, @ref + * BLE_ERROR_INVALID_CONN_HANDLE, or @ref NRF_ERROR_STORAGE_FULL, this function can be called + * again after corrective action. + * + * @note To reject a request, call this function with NULL p_sec_params. + * + * @param[in] conn_handle The connection handle of the connection the pairing is happening on. + * @param[in] p_sec_params The security parameters to use for this link. + * @param[in] p_public_key A pointer to the public key to use if using LESC, or NULL. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized, or no parameters have been + * requested on that conn_handle, or this error originates + * from the SoftDevice. + * @retval NRF_ERROR_INVALID_PARAM Invalid combination of parameters (not including conn_handle). + * @retval NRF_ERROR_TIMEOUT There has been an SMP timeout, so no more SMP operations + * can be performed on this link. + * @retval BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval NRF_ERROR_STORAGE_FULL No more room in flash. Fix and reattempt after the next + * FDS garbage collection procedure. + * @retval NRF_ERROR_BUSY No write buffer. Reattempt later. + */ +ret_code_t smd_params_reply(uint16_t conn_handle, + ble_gap_sec_params_t * p_sec_params, + ble_gap_lesc_p256_pk_t * p_public_key); + + +/**@brief Function for initiating security on the link, with the specified parameters. + * + * @note If the connection is a peripheral connection, this will send a security request to the + * master, but the master is not obligated to initiate pairing or encryption in response. + * @note If the connection is a central connection and a key is available, the parameters will be + * used to determine whether to re-pair or to encrypt using the existing key. If no key is + * available, pairing will be started. + * + * @param[in] conn_handle Handle of the connection to initiate pairing on. + * @param[in] p_sec_params The security parameters to use for this link. As a central, this can + * be NULL to reject a slave security request. + * @param[in] force_repairing Whether to force a pairing procedure to happen regardless of whether + * an encryption key already exists. This argument is only relevant for + * the central role. Recommended value: false + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_NULL p_sec_params was NULL (peripheral only). + * @retval NRF_ERROR_INVALID_STATE Module is not initialized, or this error originates from + * the SoftDevice. + * @retval NRF_ERROR_INVALID_PARAM Invalid combination of parameters (not including conn_handle). + * @retval NRF_ERROR_BUSY Unable to initiate procedure at this time. + * @retval NRF_ERROR_TIMEOUT There has been an SMP timeout, so no more SMP operations + * can be performed on this link. + * @retval BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval NRF_ERROR_STORAGE_FULL No more room in flash. Fix and reattempt after the next + * FDS garbage collection procedure. + * @retval NRF_ERROR_INTERNAL No more available peer IDs. + */ +ret_code_t smd_link_secure(uint16_t conn_handle, + ble_gap_sec_params_t * p_sec_params, + bool force_repairing); + +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* SECURITY_DISPATCHER_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/security_manager.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/security_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..81bdad01db02d9e5b3fb24f044cbd74a0f8710a6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/security_manager.c @@ -0,0 +1,570 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) +#include "security_manager.h" + +#include +#include "security_dispatcher.h" +#include "peer_database.h" +#include "ble_conn_state.h" +#include "id_manager.h" + + +// The number of registered event handlers. +#define SM_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0])) + + +// Security Manager event handler in Peer Manager. +extern void pm_sm_evt_handler(sm_evt_t const * p_sm_evt); + +// Security Manager events' handlers. +// The number of elements in this array is SM_EVENT_HANDLERS_CNT. +static sm_evt_handler_t const m_evt_handlers[] = +{ + pm_sm_evt_handler +}; + +static bool m_module_initialized; + +static ble_gap_sec_params_t m_sec_params; +static bool m_sec_params_valid; + +static ble_gap_lesc_p256_pk_t * m_p_public_key; +static ble_conn_state_user_flag_id_t m_flag_link_secure_pending_busy = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_link_secure_pending_flash_full = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_link_secure_force_repairing = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_link_secure_null_params = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_params_reply_pending_busy = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_params_reply_pending_flash_full = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_reject_pairing = BLE_CONN_STATE_USER_FLAG_INVALID; + + +static void evt_send(sm_evt_t * p_event) +{ + for (uint32_t i = 0; i < SM_EVENT_HANDLERS_CNT; i++) + { + m_evt_handlers[i](p_event); + } +} + + +static void flags_set_from_err_code(uint16_t conn_handle, ret_code_t err_code, bool params_reply) +{ + bool flag_value_flash_full = false; + bool flag_value_busy = false; + + if ( (err_code == NRF_ERROR_STORAGE_FULL) + || (err_code == NRF_ERROR_BUSY) + || (err_code == NRF_SUCCESS)) + { + if ((err_code == NRF_ERROR_STORAGE_FULL)) + { + flag_value_busy = false; + flag_value_flash_full = true; + } + else if (err_code == NRF_ERROR_BUSY) + { + flag_value_busy = true; + flag_value_flash_full = false; + } + else if (err_code == NRF_SUCCESS) + { + flag_value_busy = false; + flag_value_flash_full = false; + } + + if (params_reply) + { + ble_conn_state_user_flag_set(conn_handle, + m_flag_params_reply_pending_flash_full, + flag_value_flash_full); + ble_conn_state_user_flag_set(conn_handle, + m_flag_params_reply_pending_busy, + flag_value_busy); + ble_conn_state_user_flag_set(conn_handle, + m_flag_link_secure_pending_flash_full, + false); + ble_conn_state_user_flag_set(conn_handle, + m_flag_link_secure_pending_busy, + false); + } + else + { + ble_conn_state_user_flag_set(conn_handle, + m_flag_link_secure_pending_flash_full, + flag_value_flash_full); + ble_conn_state_user_flag_set(conn_handle, + m_flag_link_secure_pending_busy, + flag_value_busy); + } + } +} + + +static void events_send_from_err_code(uint16_t conn_handle, ret_code_t err_code) +{ + if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY)) + { + sm_evt_t evt = + { + .conn_handle = conn_handle, + .params = {.error_unexpected = { + .error = err_code + }} + }; + if (err_code == NRF_ERROR_TIMEOUT) + { + evt.evt_id = SM_EVT_ERROR_SMP_TIMEOUT; + } + else if (err_code == NRF_ERROR_STORAGE_FULL) + { + evt.evt_id = SM_EVT_ERROR_NO_MEM; + } + else + { + evt.evt_id = SM_EVT_ERROR_UNEXPECTED; + } + evt_send(&evt); + } +} + + +static ret_code_t link_secure(uint16_t conn_handle, bool null_params, bool force_repairing, bool send_events) +{ + ret_code_t err_code; + + if (!null_params && !m_sec_params_valid) + { + return NRF_ERROR_NOT_FOUND; + } + + if (null_params) + { + err_code = smd_link_secure(conn_handle, NULL, force_repairing); + } + else + { + err_code = smd_link_secure(conn_handle, &m_sec_params, force_repairing); + } + + flags_set_from_err_code(conn_handle, err_code, false); + + if (send_events) + { + events_send_from_err_code(conn_handle, err_code); + } + + switch (err_code) + { + case NRF_ERROR_BUSY: + ble_conn_state_user_flag_set(conn_handle, m_flag_link_secure_null_params, null_params); + ble_conn_state_user_flag_set(conn_handle, m_flag_link_secure_force_repairing, force_repairing); + err_code = NRF_SUCCESS; + break; + case NRF_ERROR_STORAGE_FULL: + ble_conn_state_user_flag_set(conn_handle, m_flag_link_secure_null_params, null_params); + ble_conn_state_user_flag_set(conn_handle, m_flag_link_secure_force_repairing, force_repairing); + break; + case NRF_SUCCESS: + case NRF_ERROR_TIMEOUT: + case BLE_ERROR_INVALID_CONN_HANDLE: + case NRF_ERROR_INVALID_STATE: + /* No action */ + break; + default: + err_code = NRF_ERROR_INTERNAL; + break; + } + + return err_code; +} + + +static void send_config_req(uint16_t conn_handle) +{ + sm_evt_t sm_evt; + memset(&sm_evt, 0, sizeof(sm_evt)); + + sm_evt.evt_id = SM_EVT_CONN_SEC_CONFIG_REQ; + sm_evt.conn_handle = conn_handle; + + evt_send(&sm_evt); +} + + +static void smd_params_reply_perform(uint16_t conn_handle) +{ + ret_code_t err_code; + + if ( (ble_conn_state_role(conn_handle) == BLE_GAP_ROLE_PERIPH) + && im_peer_id_get_by_conn_handle(conn_handle) != PM_PEER_ID_INVALID) + { + // Bond already exists. Reject the pairing request if the user doesn't intervene. + ble_conn_state_user_flag_set(conn_handle, m_flag_reject_pairing, true); + send_config_req(conn_handle); + } + else + { + ble_conn_state_user_flag_set(conn_handle, m_flag_reject_pairing, false); + } + + if ( m_sec_params_valid + && !ble_conn_state_user_flag_get(conn_handle, m_flag_reject_pairing)) + { + err_code = smd_params_reply(conn_handle, &m_sec_params, m_p_public_key); + } + else + { + err_code = smd_params_reply(conn_handle, NULL, NULL); + } + + flags_set_from_err_code(conn_handle, err_code, true); + events_send_from_err_code(conn_handle, err_code); +} + + +/**@brief Event handler for events from the Security Dispatcher module. + * This handler is extern in Security Dispatcher. + * + * @param[in] p_event The event that has happened. + */ +void sm_smd_evt_handler(smd_evt_t const * p_event) +{ + switch (p_event->evt_id) + { + case SMD_EVT_PARAMS_REQ: + smd_params_reply_perform(p_event->conn_handle); + break; + case SMD_EVT_SLAVE_SECURITY_REQ: + { + bool null_params = false; + if (!m_sec_params_valid) + { + null_params = true; + } + else if ((bool)m_sec_params.bond < (bool)p_event->params.slave_security_req.bond) + { + null_params = true; + } + else if ((bool)m_sec_params.mitm < (bool)p_event->params.slave_security_req.mitm) + { + null_params = true; + } + ret_code_t err_code = link_secure(p_event->conn_handle, null_params, false, true); + UNUSED_VARIABLE(err_code); // It is acceptable to ignore the return code because it is + // acceptable to ignore a security request. + } + /* fallthrough */ + case SMD_EVT_PAIRING_SUCCESS: + case SMD_EVT_PAIRING_FAIL: + case SMD_EVT_LINK_ENCRYPTION_UPDATE: + case SMD_EVT_LINK_ENCRYPTION_FAILED: + case SMD_EVT_BONDING_INFO_STORED: + case SMD_EVT_ERROR_BONDING_INFO: + case SMD_EVT_ERROR_UNEXPECTED: + case SMD_EVT_SEC_PROCEDURE_START: + { + sm_evt_t evt; + evt.evt_id = (sm_evt_id_t)p_event->evt_id; + evt.conn_handle = p_event->conn_handle; + evt.params = p_event->params; + + evt_send(&evt); + } + break; + } +} + + +static void link_secure_pending_process(ble_conn_state_user_flag_id_t flag_id) +{ + sdk_mapped_flags_t flag_collection = ble_conn_state_user_flag_collection(flag_id); + if (sdk_mapped_flags_any_set(flag_collection)) + { + sdk_mapped_flags_key_list_t conn_handle_list = ble_conn_state_conn_handles(); + + for (uint32_t i = 0; i < conn_handle_list.len; i++) + { + bool pending = ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], flag_id); + if (pending) + { + bool force_repairing = ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_flag_link_secure_force_repairing); + bool null_params = ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_flag_link_secure_null_params); + + ret_code_t err_code = link_secure(conn_handle_list.flag_keys[i], null_params, force_repairing, true); // If this fails, it will be automatically retried. + UNUSED_VARIABLE(err_code); + } + } + } +} + + +static void params_reply_pending_process(ble_conn_state_user_flag_id_t flag_id) +{ + sdk_mapped_flags_t flag_collection = ble_conn_state_user_flag_collection(flag_id); + if (sdk_mapped_flags_any_set(flag_collection)) + { + sdk_mapped_flags_key_list_t conn_handle_list = ble_conn_state_conn_handles(); + + for (uint32_t i = 0; i < conn_handle_list.len; i++) + { + bool pending = ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], flag_id); + if (pending) + { + smd_params_reply_perform(conn_handle_list.flag_keys[i]); + } + } + } +} + + +/**@brief Event handler for events from the Peer Database module. + * This handler is extern in Peer Database. + * + * @param[in] p_event The event that has happened. + */ +void sm_pdb_evt_handler(pdb_evt_t const * p_event) +{ + switch (p_event->evt_id) + { + case PDB_EVT_COMPRESSED: + params_reply_pending_process(m_flag_params_reply_pending_flash_full); + link_secure_pending_process(m_flag_link_secure_pending_flash_full); + /* fallthrough */ + case PDB_EVT_WRITE_BUF_STORED: + case PDB_EVT_RAW_STORED: + case PDB_EVT_RAW_STORE_FAILED: + case PDB_EVT_CLEARED: + case PDB_EVT_CLEAR_FAILED: + case PDB_EVT_PEER_FREED: + case PDB_EVT_PEER_FREE_FAILED: + params_reply_pending_process(m_flag_params_reply_pending_busy); + link_secure_pending_process(m_flag_link_secure_pending_busy); + break; + case PDB_EVT_ERROR_NO_MEM: + case PDB_EVT_ERROR_UNEXPECTED: + break; + } +} + + +/**@brief Funtion for initializing a BLE Connection State user flag. + * + * @param[out] flag_id The flag to initialize. + */ +static void flag_id_init(ble_conn_state_user_flag_id_t * p_flag_id) +{ + if (*p_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) + { + *p_flag_id = ble_conn_state_user_flag_acquire(); + } +} + + +ret_code_t sm_init(void) +{ + NRF_PM_DEBUG_CHECK(!m_module_initialized); + + flag_id_init(&m_flag_link_secure_pending_busy); + flag_id_init(&m_flag_link_secure_pending_flash_full); + flag_id_init(&m_flag_link_secure_force_repairing); + flag_id_init(&m_flag_link_secure_null_params); + flag_id_init(&m_flag_params_reply_pending_busy); + flag_id_init(&m_flag_params_reply_pending_flash_full); + flag_id_init(&m_flag_reject_pairing); + + if (m_flag_reject_pairing == BLE_CONN_STATE_USER_FLAG_INVALID) + { + return NRF_ERROR_INTERNAL; + } + + m_module_initialized = true; + + return NRF_SUCCESS; +} + + +void sm_ble_evt_handler(ble_evt_t * p_ble_evt) +{ + NRF_PM_DEBUG_CHECK(p_ble_evt != NULL); + + smd_ble_evt_handler(p_ble_evt); + link_secure_pending_process(m_flag_link_secure_pending_busy); +} + + +static bool sec_params_verify(ble_gap_sec_params_t * p_sec_params) +{ + // NULL check. + if (p_sec_params == NULL) + { + return false; + } + + // OOB not allowed unless MITM. + if (!p_sec_params->mitm && p_sec_params->oob) + { + return false; + } + + // IO Capabilities must be one of the valid values from @ref BLE_GAP_IO_CAPS. + if (p_sec_params->io_caps > BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY) + { + return false; + } + + // Must have either IO capabilities or OOB if MITM. + if (p_sec_params->mitm && (p_sec_params->io_caps == BLE_GAP_IO_CAPS_NONE) && !p_sec_params->oob) + { + return false; + } + + // Minimum key size cannot be larger than maximum key size. + if (p_sec_params->min_key_size > p_sec_params->max_key_size) + { + return false; + } + + // Key size cannot be below 7 bytes. + if (p_sec_params->min_key_size < 7) + { + return false; + } + + // Key size cannot be above 16 bytes. + if (p_sec_params->max_key_size > 16) + { + return false; + } + + // Signing is not supported. + if (p_sec_params->kdist_own.sign || p_sec_params->kdist_peer.sign) + { + return false; + } + + // link bit must be 0. + if (p_sec_params->kdist_own.link || p_sec_params->kdist_peer.link) + { + return false; + } + + // If bonding is not enabled, no keys can be distributed. + if (!p_sec_params->bond && ( p_sec_params->kdist_own.enc + || p_sec_params->kdist_own.id + || p_sec_params->kdist_peer.enc + || p_sec_params->kdist_peer.id)) + { + return false; + } + + // If bonding is enabled, one or more keys must be distributed. + if ( p_sec_params->bond + && !p_sec_params->kdist_own.enc + && !p_sec_params->kdist_own.id + && !p_sec_params->kdist_peer.enc + && !p_sec_params->kdist_peer.id) + { + return false; + } + + return true; +} + + +ret_code_t sm_sec_params_set(ble_gap_sec_params_t * p_sec_params) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + if (p_sec_params == NULL) + { + m_sec_params_valid = false; + return NRF_SUCCESS; + } + else if (sec_params_verify(p_sec_params)) + { + m_sec_params = *p_sec_params; + m_sec_params_valid = true; + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INVALID_PARAM; + } +} + + +void sm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_conn_sec_config != NULL); + + ble_conn_state_user_flag_set(conn_handle, m_flag_reject_pairing, !p_conn_sec_config->allow_repairing); +} + + +ret_code_t sm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + m_p_public_key = p_public_key; + + return NRF_SUCCESS; +} + + +ret_code_t sm_sec_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + return NRF_SUCCESS; +} + + +ret_code_t sm_link_secure(uint16_t conn_handle, bool force_repairing) +{ + ret_code_t ret; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + + ret = link_secure(conn_handle, false, force_repairing, false); + return ret; +} +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/security_manager.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/security_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..baf03be6901e736a66846f38f6b1f35920647305 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/ble/peer_manager/security_manager.h @@ -0,0 +1,221 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SECURITY_MANAGER_H__ +#define SECURITY_MANAGER_H__ + +#include +#include "sdk_errors.h" +#include "ble.h" +#include "ble_gap.h" +#include "peer_manager_types.h" +#include "security_dispatcher.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @cond NO_DOXYGEN + * @defgroup security_manager Security Manager + * @ingroup peer_manager + * @{ + * @brief An internal module of @ref peer_manager. A module for streamlining pairing, bonding, and + * encryption, including flash storage of shared data. + */ + + +/**@brief Events that can come from the Security Manager module. + */ +typedef enum +{ + // SM_EVT_PARAMS_REQ = SMD_EVT_PARAMS_REQ, /**< Parameters are required for a pairing procedure on the specified connection. The user must provide them using @ref sm_sec_params_set or @ref sm_sec_params_reply (only this procedure, currently unimplemented). */ + SM_EVT_SLAVE_SECURITY_REQ = SMD_EVT_SLAVE_SECURITY_REQ, /**< The peer (peripheral) has requested link encryption, which has been enabled. */ + SM_EVT_SEC_PROCEDURE_START = SMD_EVT_SEC_PROCEDURE_START, /**< A security procedure has started. */ + SM_EVT_PAIRING_SUCCESS = SMD_EVT_PAIRING_SUCCESS, /**< A pairing procedure (and bonding if applicable) has completed with success. */ + SM_EVT_PAIRING_FAIL = SMD_EVT_PAIRING_FAIL, /**< A pairing procedure has failed which means no encryption and no bond could be established. */ + SM_EVT_LINK_ENCRYPTION_UPDATE = SMD_EVT_LINK_ENCRYPTION_UPDATE, /**< The security level of the link has been updated. The link is encrypted. */ + SM_EVT_LINK_ENCRYPTION_FAILED = SMD_EVT_LINK_ENCRYPTION_FAILED, /**< An attempt to start encryption on an unencrypted link failed because the peripheral did not have the correct keys. If the peer is the peripheral, the force_repairing flag should be set when reattempting @ref sm_link_secure. */ + SM_EVT_BONDING_INFO_STORED = SMD_EVT_BONDING_INFO_STORED, /**< Information exchanged during bonding with a peer has been stored persistently. */ + SM_EVT_ERROR_BONDING_INFO = SMD_EVT_ERROR_BONDING_INFO, /**< Information exchanged during bonding with a peer could not be stored persistently, because of an unexpected error. */ + SM_EVT_ERROR_UNEXPECTED = SMD_EVT_ERROR_UNEXPECTED, /**< An operation failed with an unexpected error. The error is provided. This is possibly a fatal error. */ + SM_EVT_ERROR_NO_MEM /*= SMD_EVT_ERROR_NO_MEM*/, /**< An operation failed because there was no available storage room in persistent storage. Please free up room and the operation will automatically continue after the next compression. */ + SM_EVT_ERROR_SMP_TIMEOUT, /**< An operation failed because there has been an SMP timeout on the link, which entails that no more security operations can be performed on it. */ + SM_EVT_CONN_SEC_CONFIG_REQ, /**< The peer (central) has requested pairing, but a bond already exists with that peer. Reply by calling @ref sm_conn_sec_config_reply before the event handler returns. If no reply is sent, a default is used. */ +} sm_evt_id_t; + + +typedef struct +{ + sm_evt_id_t evt_id; + uint16_t conn_handle; + smd_evt_params_t params; +} sm_evt_t; + + +/**@brief Event handler for events from the Security Manager module. + * + * @param[in] event The event that has happened. + * @param[in] conn_handle The connection handle the event pertains to. + */ +typedef void (*sm_evt_handler_t)(sm_evt_t const * p_event); + + +/**@brief Function for initializing the Security Manager module. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INTERNAL If an unexpected error occurred. + */ +ret_code_t sm_init(void); + + +/**@brief Function for dispatching SoftDevice events to the Security Manager module. + * + * @param[in] ble_evt The SoftDevice event. + */ +void sm_ble_evt_handler(ble_evt_t * ble_evt); + + +/**@brief Function for providing pairing and bonding parameters to use for pairing procedures. + * + * @details Until this is called, all bonding procedures initiated by the peer will be rejected. + * This function can be called multiple times, even with NULL p_sec_params, in which case + * it will go back to rejecting all procedures. + * + * @param[in] p_sec_params The security parameters to use for this link. Can be NULL to reject + * all pairing procedures. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_PARAM Invalid combination of parameters. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + */ +ret_code_t sm_sec_params_set(ble_gap_sec_params_t * p_sec_params); + + +/**@brief Function for providing security configuration for a link. + * + * @details This function is optional, and must be called in reply to a @ref + * SM_EVT_CONN_SEC_CONFIG_REQ event, before the Peer Manager event handler returns. If it + * is not called in time, a default configuration is used. See @ref pm_conn_sec_config_t + * for the value of the default. + * + * @param[in] conn_handle The connection to set the configuration for. + * @param[in] p_conn_sec_config The configuration. + */ +void sm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config); + + +/**@brief Experimental function for specifying the public key to use for LESC operations. + * + * @details This function can be called multiple times. The specified public key will be used for + * all subsequent LESC (LE Secure Connections) operations until the next time this function + * is called. + * + * @note The key must continue to reside in application memory as it is not copied by Peer Manager. + * + * @param[in] p_public_key The public key to use for all subsequent LESC operations. + * + * @retval NRF_SUCCESS Pairing initiated successfully. + * @retval NRF_ERROR_INVALID_STATE Peer Manager is not initialized. + */ +ret_code_t sm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key); + + +/**@brief Function for providing pairing and bonding parameters to use for the current pairing + * procedure on a connection. + * + * @warning This function is not yet implemented. + * + * @note If this function returns an @ref NRF_ERROR_NULL, @ref NRF_ERROR_INVALID_PARAM, @ref + * BLE_ERROR_INVALID_CONN_HANDLE, or @ref NRF_ERROR_STORAGE_FULL, this function can be called + * again after corrective action. + * + * @note To reject a request, call this function with NULL p_sec_params. + * + * @param[in] conn_handle The connection handle of the connection the pairing is happening on. + * @param[in] p_sec_params The security parameters to use for this link. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized, or no parameters have been + * requested on that conn_handle, or this error originates + * from the SoftDevice. + * @retval NRF_ERROR_INVALID_PARAM Invalid combination of parameters (not including conn_handle). + * @retval NRF_ERROR_TIMEOUT There has been an SMP timeout, so no more SMP operations + * can be performed on this link. + * @retval BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval NRF_ERROR_STORAGE_FULL No more room in flash. Fix and reattempt later. + * @retval NRF_ERROR_BUSY No write buffer. Reattempt later. + */ +ret_code_t sm_sec_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params); + + +/**@brief Function for initiating security on the link, with the specified parameters. + * + * @note If the connection is a peripheral connection, this will send a security request to the + * master, but the master is not obligated to initiate pairing or encryption in response. + * @note If the connection is a central connection and a key is available, the parameters will be + * used to determine whether to re-pair or to encrypt using the existing key. If no key is + * available, pairing will be started. + * + * @param[in] conn_handle Handle of the connection to initiate pairing on. + * @param[in] force_repairing Whether to force a pairing procedure to happen regardless of whether + * an encryption key already exists. This argument is only relevant for + * the central role. Recommended value: false + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_TIMEOUT There has been an SMP timeout, so no more SMP operations + * can be performed on this link. + * @retval BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval NRF_ERROR_NOT_FOUND Security parameters have not been set. + * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @retval NRF_ERROR_INTERNAL An unexpected error occurred. + */ +ret_code_t sm_link_secure(uint16_t conn_handle, bool force_repairing); + +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* SECURITY_MANAGER_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/boards/arduino_primo.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/boards/arduino_primo.h new file mode 100644 index 0000000000000000000000000000000000000000..3171382c459617a6e9e9a6d7801e72cdc6cc44fb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/boards/arduino_primo.h @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ARDUINO_PRIMO_H +#define ARDUINO_PRIMO_H + +#ifdef __cplusplus +extern "C" { +#endif + +// LEDs definitions +#define LEDS_NUMBER 1 + +#define LED_1 25 + +#define LEDS_ACTIVE_STATE 0 + +#define LEDS_LIST { LED_1} + +#define BSP_LED_0 LED_1 + +#define LEDS_INV_MASK 0 + +#define BUTTONS_NUMBER 1 + +#define BUTTON_START 7 +#define BUTTON_1 7 +#define BUTTON_STOP 7 +#define BUTTON_PULL NRF_GPIO_PIN_PULLUP + +#define BUTTONS_ACTIVE_STATE 0 + +#define BUTTONS_LIST { BUTTON_1 } + +#define BSP_BUTTON_0 BUTTON_1 + +#define RX_PIN_NUMBER 11 +#define TX_PIN_NUMBER 12 +#define CTS_PIN_NUMBER UART_PIN_DISCONNECTED +#define RTS_PIN_NUMBER UART_PIN_DISCONNECTED +#define HWFC false + +// Arduino board mappings +#define ARDUINO_SCL_PIN 27 // SCL signal pin +#define ARDUINO_SDA_PIN 26 // SDA signal pin +#define ARDUINO_AREF_PIN 2 // Aref pin +#define ARDUINO_13_PIN 25 // Digital pin 13 +#define ARDUINO_12_PIN 24 // Digital pin 12 +#define ARDUINO_11_PIN 23 // Digital pin 11 +#define ARDUINO_10_PIN 22 // Digital pin 10 +#define ARDUINO_9_PIN 20 // Digital pin 9 +#define ARDUINO_8_PIN 19 // Digital pin 8 + +#define ARDUINO_7_PIN 18 // Digital pin 7 +#define ARDUINO_6_PIN 17 // Digital pin 6 +#define ARDUINO_5_PIN 16 // Digital pin 5 +#define ARDUINO_4_PIN 15 // Digital pin 4 +#define ARDUINO_3_PIN 14 // Digital pin 3 +#define ARDUINO_2_PIN 13 // Digital pin 2 +#define ARDUINO_1_PIN 12 // Digital pin 1 +#define ARDUINO_0_PIN 11 // Digital pin 0 + +#define ARDUINO_A0_PIN 3 // Analog channel 0 +#define ARDUINO_A1_PIN 4 // Analog channel 1 +#define ARDUINO_A2_PIN 28 // Analog channel 2 +#define ARDUINO_A3_PIN 29 // Analog channel 3 +#define ARDUINO_A4_PIN 30 // Analog channel 4 +#define ARDUINO_A5_PIN 31 // Analog channel 5 + +// Low frequency clock source to be used by the SoftDevice +#define NRF_CLOCK_LFCLKSRC {.source = NRF_CLOCK_LF_SRC_XTAL, \ + .rc_ctiv = 0, \ + .rc_temp_ctiv = 0, \ + .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM} + + +#ifdef __cplusplus +} +#endif + +#endif // ARDUINO_PRIMO_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/boards/boards.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/boards/boards.c new file mode 100644 index 0000000000000000000000000000000000000000..7fb6fe4058b7b49e6c43b1c072fadf360206c097 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/boards/boards.c @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "boards.h" +#include +#include + +#if LEDS_NUMBER > 0 +static const uint8_t m_board_led_list[LEDS_NUMBER] = LEDS_LIST; +#endif + +#if BUTTONS_NUMBER > 0 +static const uint8_t m_board_btn_list[BUTTONS_NUMBER] = BUTTONS_LIST; +#endif + +#if LEDS_NUMBER > 0 +bool bsp_board_led_state_get(uint32_t led_idx) +{ + ASSERT(led_idx < LEDS_NUMBER); + bool pin_set = nrf_gpio_pin_out_read(m_board_led_list[led_idx]) ? true : false; + return (pin_set == (LEDS_ACTIVE_STATE ? true : false)); +} + +void bsp_board_led_on(uint32_t led_idx) +{ + ASSERT(led_idx < LEDS_NUMBER); + nrf_gpio_pin_write(m_board_led_list[led_idx], LEDS_ACTIVE_STATE ? 1 : 0); +} + +void bsp_board_led_off(uint32_t led_idx) +{ + ASSERT(led_idx < LEDS_NUMBER); + nrf_gpio_pin_write(m_board_led_list[led_idx], LEDS_ACTIVE_STATE ? 0 : 1); +} + +void bsp_board_leds_off(void) +{ + uint32_t i; + for(i = 0; i < LEDS_NUMBER; ++i) + { + bsp_board_led_off(i); + } +} + +void bsp_board_leds_on(void) +{ + uint32_t i; + for(i = 0; i < LEDS_NUMBER; ++i) + { + bsp_board_led_on(i); + } +} + +void bsp_board_led_invert(uint32_t led_idx) +{ + ASSERT(led_idx < LEDS_NUMBER); + nrf_gpio_pin_toggle(m_board_led_list[led_idx]); +} + +void bsp_board_leds_init(void) +{ + uint32_t i; + for(i = 0; i < LEDS_NUMBER; ++i) + { + nrf_gpio_cfg_output(m_board_led_list[i]); + } + bsp_board_leds_off(); +} + +uint32_t bsp_board_led_idx_to_pin(uint32_t led_idx) +{ + ASSERT(led_idx < LEDS_NUMBER); + return m_board_led_list[led_idx]; +} + +uint32_t bsp_board_pin_to_led_idx(uint32_t pin_number) +{ + uint32_t ret = 0xFFFFFFFF; + uint32_t i; + for(i = 0; i < LEDS_NUMBER; ++i) + { + if (m_board_led_list[i] == pin_number) + { + ret = i; + break; + } + } + return ret; +} +#endif //LEDS_NUMBER > 0 + +#if BUTTONS_NUMBER > 0 +bool bsp_board_button_state_get(uint32_t button_idx) +{ + ASSERT(button_idx < BUTTONS_NUMBER); + bool pin_set = nrf_gpio_pin_read(m_board_btn_list[button_idx]) ? true : false; + return (pin_set == (BUTTONS_ACTIVE_STATE ? true : false)); +} + +void bsp_board_buttons_init(void) +{ + uint32_t i; + for(i = 0; i < BUTTONS_NUMBER; ++i) + { + nrf_gpio_cfg_input(m_board_btn_list[i], BUTTON_PULL); + } +} + +uint32_t bsp_board_pin_to_button_idx(uint32_t pin_number) +{ + uint32_t i; + uint32_t ret = 0xFFFFFFFF; + for(i = 0; i < BUTTONS_NUMBER; ++i) + { + if (m_board_btn_list[i] == pin_number) + { + ret = i; + break; + } + } + return ret; +} + +uint32_t bsp_board_button_idx_to_pin(uint32_t button_idx) +{ + ASSERT(button_idx < BUTTONS_NUMBER); + return m_board_btn_list[button_idx]; +} +#endif //BUTTONS_NUMBER > 0 diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/boards/boards.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/boards/boards.h new file mode 100644 index 0000000000000000000000000000000000000000..87fca8023b633b46fb0b18ef869b188d1d6ab8e4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/boards/boards.h @@ -0,0 +1,319 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BOARDS_H +#define BOARDS_H + +#include "nrf_gpio.h" + +#if defined(BOARD_NRF6310) + #include "nrf6310.h" +#elif defined(BOARD_PCA10000) + #include "pca10000.h" +#elif defined(BOARD_PCA10001) + #include "pca10001.h" +#elif defined(BOARD_PCA10002) + #include "pca10000.h" +#elif defined(BOARD_PCA10003) + #include "pca10003.h" +#elif defined(BOARD_PCA20006) + #include "pca20006.h" +#elif defined(BOARD_PCA10028) + #include "pca10028.h" +#elif defined(BOARD_PCA10031) + #include "pca10031.h" +#elif defined(BOARD_PCA10036) + #include "pca10036.h" +#elif defined(BOARD_PCA10040) + #include "pca10040.h" +#elif defined(BOARD_PCA10056) + #include "pca10056.h" +#elif defined(BOARD_WT51822) + #include "wt51822.h" +#elif defined(BOARD_N5DK1) + #include "n5_starterkit.h" +#elif defined (BOARD_D52DK1) + #include "d52_starterkit.h" +#elif defined (BOARD_ARDUINO_PRIMO) + #include "arduino_primo.h" +#elif defined(BOARD_CUSTOM) + #include "custom_board.h" +#else +#error "Board is not defined" + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Function for returning the state of an LED. + * + * @param led_idx LED index (starting from 0), as defined in the board-specific header. + * + * @return True if the LED is turned on. + */ +bool bsp_board_led_state_get(uint32_t led_idx); + +/** + * Function for turning on an LED. + * + * @param led_idx LED index (starting from 0), as defined in the board-specific header. + */ +void bsp_board_led_on(uint32_t led_idx); + +/** + * Function for turning off an LED. + * + * @param led_idx LED index (starting from 0), as defined in the board-specific header. + */ +void bsp_board_led_off(uint32_t led_idx); + +/** + * Function for inverting the state of an LED. + * + * @param led_idx LED index (starting from 0), as defined in the board-specific header. + */ +void bsp_board_led_invert(uint32_t led_idx); +/** + * Function for turning off all LEDs. + */ +void bsp_board_leds_off(void); + +/** + * Function for turning on all LEDs. + */ +void bsp_board_leds_on(void); + +/** + * Function for initializing LEDs. + */ +void bsp_board_leds_init(void); + +/** + * Function for converting pin number to LED index. + * + * @param pin_number Pin number. + * + * @return LED index of the given pin or 0xFFFFFFFF if invalid pin provided. + */ +uint32_t bsp_board_pin_to_led_idx(uint32_t pin_number); + +/** + * Function for converting LED index to pin number. + * + * @param led_idx LED index. + * + * @return Pin number. + */ +uint32_t bsp_board_led_idx_to_pin(uint32_t led_idx); + +/** + * Function for returning the state of a button. + * + * @param button_idx Button index (starting from 0), as defined in the board-specific header. + * + * @return True if the button is pressed. + */ +bool bsp_board_button_state_get(uint32_t button_idx); + +/** + * Function for initializing buttons. + */ +void bsp_board_buttons_init(void); + +/** + * Function for converting pin number to button index. + * + * @param pin_number Pin number. + * + * @return Button index of the given pin or 0xFFFFFFFF if invalid pin provided. + */ +uint32_t bsp_board_pin_to_button_idx(uint32_t pin_number); + + +/** + * Function for converting button index to pin number. + * + * @param button_idx Button index. + * + * @return Pin number. + */ +uint32_t bsp_board_button_idx_to_pin(uint32_t button_idx); + +#define BSP_BOARD_LED_0 0 +#define BSP_BOARD_LED_1 1 +#define BSP_BOARD_LED_2 2 +#define BSP_BOARD_LED_3 3 +#define BSP_BOARD_LED_4 4 +#define BSP_BOARD_LED_5 5 +#define BSP_BOARD_LED_6 6 +#define BSP_BOARD_LED_7 7 + +#ifdef BSP_LED_0 +#define BSP_LED_0_MASK (1<OUTSET = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \ + NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0) + +#define LEDS_ON(leds_mask) do { ASSERT(sizeof(leds_mask) == 4); \ + NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \ + NRF_GPIO->OUTSET = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0) + +#define LED_IS_ON(leds_mask) ((leds_mask) & (NRF_GPIO->OUT ^ LEDS_INV_MASK) ) + +#define LEDS_INVERT(leds_mask) do { uint32_t gpio_state = NRF_GPIO->OUT; \ + ASSERT(sizeof(leds_mask) == 4); \ + NRF_GPIO->OUTSET = ((leds_mask) & ~gpio_state); \ + NRF_GPIO->OUTCLR = ((leds_mask) & gpio_state); } while (0) + +#define LEDS_CONFIGURE(leds_mask) do { uint32_t pin; \ + ASSERT(sizeof(leds_mask) == 4); \ + for (pin = 0; pin < 32; pin++) \ + if ( (leds_mask) & (1 << pin) ) \ + nrf_gpio_cfg_output(pin); } while (0) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/boards/d52_starterkit.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/boards/d52_starterkit.h new file mode 100644 index 0000000000000000000000000000000000000000..3ad2edb45d691ca12aad008e7ef411eff1c23577 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/boards/d52_starterkit.h @@ -0,0 +1,154 @@ +/** + * This software is subject to the ANT+ Shared Source License + * www.thisisant.com/swlicenses + * Copyright (c) Dynastream Innovations, Inc. 2016 + * 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 Dynastream nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * The following actions are prohibited: + * 1) Redistribution of source code containing the ANT+ Network + * Key. The ANT+ Network Key is available to ANT+ Adopters. + * Please refer to http://thisisant.com to become an ANT+ + * Adopter and access the key. + * + * 2) Reverse engineering, decompilation, and/or disassembly of + * software provided in binary form under this license. + * + * 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 HEREBY + * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW + * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE + * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. + * + */ +#ifndef D52STARTERKIT_H +#define D52STARTERKIT_H + +#include "nrf_gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// LEDs definitions for D52DK1 +#define LEDS_NUMBER 4 + +// IO board active low leds +// D52DK1 does not define LED_START or LED_STOP since the LEDS are not on sequential pins +#define LED_A 24 //LED A on D52 Starter Kit IO Board +#define LED_B 31 //LED B on D52 Starter Kit IO Board +#define LED_C 17 //LED C on D52 Starter Kit IO Board +#define LED_D 20 //LED D on D52 Starter Kit IO Board + +#define LEDS_ACTIVE_STATE 0 + +#define LEDS_LIST { LED_A, LED_B, LED_C, LED_D } + +#define BSP_LED_0 LED_A +#define BSP_LED_1 LED_B +#define BSP_LED_2 LED_C +#define BSP_LED_3 LED_D + +#define LEDS_INV_MASK LEDS_MASK + +#define BUTTONS_NUMBER 4 + +// IO board pull-up buttons +#define BUTTON_A 6 //BUTTON A on D52 Starter Kit IO Board +#define BUTTON_B 7 //BUTTON B on D52 Starter Kit IO Board +#define BUTTON_C 16 //BUTTON C on D52 Starter Kit IO Board +#define BUTTON_D 19 //BUTTON D on D52 Starter Kit IO Board +#define BUTTON_PULL NRF_GPIO_PIN_PULLUP + +#define BUTTONS_ACTIVE_STATE 0 + +#define BSP_BUTTON_0 BUTTON_A +#define BSP_BUTTON_1 BUTTON_B +#define BSP_BUTTON_2 BUTTON_C +#define BSP_BUTTON_3 BUTTON_D + +#define BUTTONS_LIST { BUTTON_A, BUTTON_B, BUTTON_C, BUTTON_D } + +// Battery board pull-up switches +#define SWITCH_1 12 // Switch 1 on D52 Starter Kit Battery Board +#define SWITCH_2 8 // Switch 2 on D52 Starter Kit Battery Board +#define SWITCH_3 15 // Switch 3 on D52 Starter Kit Battery Board +#define SWITCH_4 11 // Switch 4 on D52 Starter Kit Battery Board +#define SWITCH_5 14 // Switch 5 on D52 Starter Kit Battery Board +#define SWITCH_PULL NRF_GPIO_PIN_PULLUP + +#define SWITCHES_NUMBER 5 + +#define BSP_SWITCH_0 SWITCH_1 +#define BSP_SWITCH_1 SWITCH_2 +#define BSP_SWITCH_2 SWITCH_3 +#define BSP_SWITCH_3 SWITCH_4 +#define BSP_SWITCH_4 SWITCH_5 + +#define BSP_SWITCH_0_MASK (1<2S mode. */ + __IO uint32_t MODE; /*!< I2S mode. */ __IO uint32_t RXEN; /*!< Reception (RX) enable. */ __IO uint32_t TXEN; /*!< Transmission (TX) enable. */ __IO uint32_t MCKEN; /*!< Master clock generator enable. */ @@ -450,8 +480,7 @@ typedef struct { /*!< FICR Structure __I uint32_t RESERVED0[4]; __I uint32_t CODEPAGESIZE; /*!< Code memory page size */ __I uint32_t CODESIZE; /*!< Code memory size */ - __I uint32_t RESERVED1[17]; - __I uint32_t CONFIGID; /*!< Configuration identifier */ + __I uint32_t RESERVED1[18]; __I uint32_t DEVICEID[2]; /*!< Description collection[0]: Device identifier */ __I uint32_t RESERVED2[6]; __I uint32_t ER[4]; /*!< Description collection[0]: Encryption Root, word 0 */ @@ -460,7 +489,9 @@ typedef struct { /*!< FICR Structure __I uint32_t DEVICEADDR[2]; /*!< Description collection[0]: Device address 0 */ __I uint32_t RESERVED3[21]; FICR_INFO_Type INFO; /*!< Device info */ - __I uint32_t RESERVED4[204]; + __I uint32_t RESERVED4[185]; + FICR_TEMP_Type TEMP; /*!< Registers storing factory TEMP module linearization coefficients */ + __I uint32_t RESERVED5[2]; FICR_NFC_Type NFC; /*!< Unspecified */ } NRF_FICR_Type; @@ -486,7 +517,7 @@ typedef struct { /*!< UICR Structure __I uint32_t RESERVED1[64]; __IO uint32_t PSELRESET[2]; /*!< Description collection[0]: Mapping of the nRESET function (see POWER chapter for details) */ - __IO uint32_t APPROTECT; /*!< Access port protection */ + __IO uint32_t APPROTECT; /*!< Access Port protection */ __IO uint32_t NFCPINS; /*!< Setting of pins dedicated to NFC functionality: NFC antenna or GPIO */ } NRF_UICR_Type; @@ -505,7 +536,7 @@ typedef struct { /*!< BPROT Structure __I uint32_t RESERVED0[384]; __IO uint32_t CONFIG0; /*!< Block protect configuration register 0 */ __IO uint32_t CONFIG1; /*!< Block protect configuration register 1 */ - __IO uint32_t DISABLEINDEBUG; /*!< Disable protection mechanism in debug mode */ + __IO uint32_t DISABLEINDEBUG; /*!< Disable protection mechanism in debug interface mode */ __IO uint32_t UNUSED0; /*!< Unspecified */ __IO uint32_t CONFIG2; /*!< Block protect configuration register 2 */ __IO uint32_t CONFIG3; /*!< Block protect configuration register 3 */ @@ -570,7 +601,7 @@ typedef struct { /*!< CLOCK Structure __O uint32_t TASKS_HFCLKSTOP; /*!< Stop HFCLK crystal oscillator */ __O uint32_t TASKS_LFCLKSTART; /*!< Start LFCLK source */ __O uint32_t TASKS_LFCLKSTOP; /*!< Stop LFCLK source */ - __O uint32_t TASKS_CAL; /*!< Start calibration of LFRC or LFULP oscillator */ + __O uint32_t TASKS_CAL; /*!< Start calibration of LFRC oscillator */ __O uint32_t TASKS_CTSTART; /*!< Start calibration timer */ __O uint32_t TASKS_CTSTOP; /*!< Stop calibration timer */ __I uint32_t RESERVED0[57]; @@ -584,16 +615,15 @@ typedef struct { /*!< CLOCK Structure __IO uint32_t INTENCLR; /*!< Disable interrupt */ __I uint32_t RESERVED3[63]; __I uint32_t HFCLKRUN; /*!< Status indicating that HFCLKSTART task has been triggered */ - __I uint32_t HFCLKSTAT; /*!< Which HFCLK source is running */ + __I uint32_t HFCLKSTAT; /*!< HFCLK status */ __I uint32_t RESERVED4; __I uint32_t LFCLKRUN; /*!< Status indicating that LFCLKSTART task has been triggered */ - __I uint32_t LFCLKSTAT; /*!< Which LFCLK source is running */ + __I uint32_t LFCLKSTAT; /*!< LFCLK status */ __I uint32_t LFCLKSRCCOPY; /*!< Copy of LFCLKSRC register, set when LFCLKSTART task was triggered */ __I uint32_t RESERVED5[62]; __IO uint32_t LFCLKSRC; /*!< Clock source for the LFCLK */ __I uint32_t RESERVED6[7]; - __IO uint32_t CTIV; /*!< Calibration timer interval (retained register, same reset behaviour - as RESETREAS) */ + __IO uint32_t CTIV; /*!< Calibration timer interval */ __I uint32_t RESERVED7[8]; __IO uint32_t TRACECONFIG; /*!< Clocking options for the Trace Port debug interface */ } NRF_CLOCK_Type; @@ -627,11 +657,9 @@ typedef struct { /*!< RADIO Structure __IO uint32_t EVENTS_DISABLED; /*!< RADIO has been disabled */ __IO uint32_t EVENTS_DEVMATCH; /*!< A device address match occurred on the last received packet */ __IO uint32_t EVENTS_DEVMISS; /*!< No device address match occurred on the last received packet */ - __IO uint32_t EVENTS_RSSIEND; /*!< Sampling of receive signal strength complete. A new RSSI sample - is ready for readout from the "RADIO.RSSISAMPLE" register */ + __IO uint32_t EVENTS_RSSIEND; /*!< Sampling of receive signal strength complete. */ __I uint32_t RESERVED1[2]; - __IO uint32_t EVENTS_BCMATCH; /*!< Bit counter reached bit count value specified in the "RADIO.BCC" - register */ + __IO uint32_t EVENTS_BCMATCH; /*!< Bit counter reached bit count value. */ __I uint32_t RESERVED2; __IO uint32_t EVENTS_CRCOK; /*!< Packet received with CRC ok */ __IO uint32_t EVENTS_CRCERROR; /*!< Packet received with CRC error */ @@ -700,9 +728,12 @@ typedef struct { /*!< UARTE Structure __I uint32_t RESERVED1[52]; __IO uint32_t EVENTS_CTS; /*!< CTS is activated (set low). Clear To Send. */ __IO uint32_t EVENTS_NCTS; /*!< CTS is deactivated (set high). Not Clear To Send. */ - __I uint32_t RESERVED2[2]; + __IO uint32_t EVENTS_RXDRDY; /*!< Data received in RXD (but potentially not yet transferred to + Data RAM) */ + __I uint32_t RESERVED2; __IO uint32_t EVENTS_ENDRX; /*!< Receive buffer is filled up */ - __I uint32_t RESERVED3[3]; + __I uint32_t RESERVED3[2]; + __IO uint32_t EVENTS_TXDRDY; /*!< Data sent from TXD */ __IO uint32_t EVENTS_ENDTX; /*!< Last TX byte transmitted */ __IO uint32_t EVENTS_ERROR; /*!< Error detected */ __I uint32_t RESERVED4[7]; @@ -725,7 +756,7 @@ typedef struct { /*!< UARTE Structure __I uint32_t RESERVED11; UARTE_PSEL_Type PSEL; /*!< Unspecified */ __I uint32_t RESERVED12[3]; - __IO uint32_t BAUDRATE; /*!< Baud rate */ + __IO uint32_t BAUDRATE; /*!< Baud rate. Accuracy depends on the HFCLK source selected. */ __I uint32_t RESERVED13[3]; UARTE_RXD_Type RXD; /*!< RXD EasyDMA channel */ __I uint32_t RESERVED14; @@ -735,6 +766,55 @@ typedef struct { /*!< UARTE Structure } NRF_UARTE_Type; +/* ================================================================================ */ +/* ================ UART ================ */ +/* ================================================================================ */ + + +/** + * @brief Universal Asynchronous Receiver/Transmitter (UART) + */ + +typedef struct { /*!< UART Structure */ + __O uint32_t TASKS_STARTRX; /*!< Start UART receiver */ + __O uint32_t TASKS_STOPRX; /*!< Stop UART receiver */ + __O uint32_t TASKS_STARTTX; /*!< Start UART transmitter */ + __O uint32_t TASKS_STOPTX; /*!< Stop UART transmitter */ + __I uint32_t RESERVED0[3]; + __O uint32_t TASKS_SUSPEND; /*!< Suspend UART */ + __I uint32_t RESERVED1[56]; + __IO uint32_t EVENTS_CTS; /*!< CTS is activated (set low). Clear To Send. */ + __IO uint32_t EVENTS_NCTS; /*!< CTS is deactivated (set high). Not Clear To Send. */ + __IO uint32_t EVENTS_RXDRDY; /*!< Data received in RXD */ + __I uint32_t RESERVED2[4]; + __IO uint32_t EVENTS_TXDRDY; /*!< Data sent from TXD */ + __I uint32_t RESERVED3; + __IO uint32_t EVENTS_ERROR; /*!< Error detected */ + __I uint32_t RESERVED4[7]; + __IO uint32_t EVENTS_RXTO; /*!< Receiver timeout */ + __I uint32_t RESERVED5[46]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED6[64]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED7[93]; + __IO uint32_t ERRORSRC; /*!< Error source */ + __I uint32_t RESERVED8[31]; + __IO uint32_t ENABLE; /*!< Enable UART */ + __I uint32_t RESERVED9; + __IO uint32_t PSELRTS; /*!< Pin select for RTS */ + __IO uint32_t PSELTXD; /*!< Pin select for TXD */ + __IO uint32_t PSELCTS; /*!< Pin select for CTS */ + __IO uint32_t PSELRXD; /*!< Pin select for RXD */ + __I uint32_t RXD; /*!< RXD register */ + __O uint32_t TXD; /*!< TXD register */ + __I uint32_t RESERVED10; + __IO uint32_t BAUDRATE; /*!< Baud rate */ + __I uint32_t RESERVED11[17]; + __IO uint32_t CONFIG; /*!< Configuration of parity and hardware flow control */ +} NRF_UART_Type; + + /* ================================================================================ */ /* ================ SPIM ================ */ /* ================================================================================ */ @@ -797,31 +877,33 @@ typedef struct { /*!< SPIS Structure __O uint32_t TASKS_RELEASE; /*!< Release SPI semaphore, enabling the SPI slave to acquire it */ __I uint32_t RESERVED1[54]; __IO uint32_t EVENTS_END; /*!< Granted transaction completed */ - __I uint32_t RESERVED2[8]; + __I uint32_t RESERVED2[2]; + __IO uint32_t EVENTS_ENDRX; /*!< End of RXD buffer reached */ + __I uint32_t RESERVED3[5]; __IO uint32_t EVENTS_ACQUIRED; /*!< Semaphore acquired */ - __I uint32_t RESERVED3[53]; + __I uint32_t RESERVED4[53]; __IO uint32_t SHORTS; /*!< Shortcut register */ - __I uint32_t RESERVED4[64]; + __I uint32_t RESERVED5[64]; __IO uint32_t INTENSET; /*!< Enable interrupt */ __IO uint32_t INTENCLR; /*!< Disable interrupt */ - __I uint32_t RESERVED5[61]; + __I uint32_t RESERVED6[61]; __I uint32_t SEMSTAT; /*!< Semaphore status register */ - __I uint32_t RESERVED6[15]; + __I uint32_t RESERVED7[15]; __IO uint32_t STATUS; /*!< Status from last transaction */ - __I uint32_t RESERVED7[47]; + __I uint32_t RESERVED8[47]; __IO uint32_t ENABLE; /*!< Enable SPI slave */ - __I uint32_t RESERVED8; + __I uint32_t RESERVED9; SPIS_PSEL_Type PSEL; /*!< Unspecified */ - __I uint32_t RESERVED9[7]; + __I uint32_t RESERVED10[7]; SPIS_RXD_Type RXD; /*!< Unspecified */ - __I uint32_t RESERVED10; - SPIS_TXD_Type TXD; /*!< Unspecified */ __I uint32_t RESERVED11; - __IO uint32_t CONFIG; /*!< Configuration register */ + SPIS_TXD_Type TXD; /*!< Unspecified */ __I uint32_t RESERVED12; + __IO uint32_t CONFIG; /*!< Configuration register */ + __I uint32_t RESERVED13; __IO uint32_t DEF; /*!< Default character. Character clocked out in case of an ignored transaction. */ - __I uint32_t RESERVED13[24]; + __I uint32_t RESERVED14[24]; __IO uint32_t ORC; /*!< Over-read character */ } NRF_SPIS_Type; @@ -840,7 +922,8 @@ typedef struct { /*!< TWIM Structure __I uint32_t RESERVED0; __O uint32_t TASKS_STARTTX; /*!< Start TWI transmit sequence */ __I uint32_t RESERVED1[2]; - __O uint32_t TASKS_STOP; /*!< Stop TWI transaction */ + __O uint32_t TASKS_STOP; /*!< Stop TWI transaction. Must be issued while the TWI master is + not suspended. */ __I uint32_t RESERVED2; __O uint32_t TASKS_SUSPEND; /*!< Suspend TWI transaction */ __O uint32_t TASKS_RESUME; /*!< Resume TWI transaction */ @@ -848,7 +931,9 @@ typedef struct { /*!< TWIM Structure __IO uint32_t EVENTS_STOPPED; /*!< TWI stopped */ __I uint32_t RESERVED4[7]; __IO uint32_t EVENTS_ERROR; /*!< TWI error */ - __I uint32_t RESERVED5[9]; + __I uint32_t RESERVED5[8]; + __IO uint32_t EVENTS_SUSPENDED; /*!< Last byte has been sent out after the SUSPEND task has been + issued, TWI traffic is now suspended. */ __IO uint32_t EVENTS_RXSTARTED; /*!< Receive sequence started */ __IO uint32_t EVENTS_TXSTARTED; /*!< Transmit sequence started */ __I uint32_t RESERVED6[2]; @@ -1082,8 +1167,7 @@ typedef struct { /*!< NFCT Structure __IO uint32_t NFCID1_LAST; /*!< Last NFCID1 part (4, 7 or 10 bytes ID) */ __IO uint32_t NFCID1_2ND_LAST; /*!< Second last NFCID1 part (7 or 10 bytes ID) */ __IO uint32_t NFCID1_3RD_LAST; /*!< Third last NFCID1 part (10 bytes ID) */ - __IO uint32_t AUTOCOLRESCONFIG; /*!< Controls the Auto collision resolution function. This setting - must be done before the NFCT peripheral is enabled. */ + __I uint32_t RESERVED14; __IO uint32_t SENSRES; /*!< NFC-A SENS_RES auto-response settings */ __IO uint32_t SELRES; /*!< NFC-A SEL_RES auto-response settings */ } NRF_NFCT_Type; @@ -1142,7 +1226,7 @@ typedef struct { /*!< SAADC Structure __IO uint32_t EVENTS_DONE; /*!< A conversion task has been completed. Depending on the mode, multiple conversions might be needed for a result to be transferred to RAM. */ - __IO uint32_t EVENTS_RESULTDONE; /*!< A result is ready to get transferred to RAM */ + __IO uint32_t EVENTS_RESULTDONE; /*!< A result is ready to get transferred to RAM. */ __IO uint32_t EVENTS_CALIBRATEDONE; /*!< Calibration is complete */ __IO uint32_t EVENTS_STOPPED; /*!< The ADC has stopped */ SAADC_EVENTS_CH_Type EVENTS_CH[8]; /*!< Unspecified */ @@ -1181,7 +1265,7 @@ typedef struct { /*!< TIMER Structure __O uint32_t TASKS_STOP; /*!< Stop Timer */ __O uint32_t TASKS_COUNT; /*!< Increment Timer (Counter mode only) */ __O uint32_t TASKS_CLEAR; /*!< Clear time */ - __O uint32_t TASKS_SHUTDOWN; /*!< Shut down timer */ + __O uint32_t TASKS_SHUTDOWN; /*!< Deprecated register - Shut down timer */ __I uint32_t RESERVED0[11]; __O uint32_t TASKS_CAPTURE[6]; /*!< Description collection[0]: Capture Timer value to CC[0] register */ __I uint32_t RESERVED1[58]; @@ -1254,7 +1338,27 @@ typedef struct { /*!< TEMP Structure __IO uint32_t INTENSET; /*!< Enable interrupt */ __IO uint32_t INTENCLR; /*!< Disable interrupt */ __I uint32_t RESERVED2[127]; - __I int32_t TEMP; /*!< Temperature in degC */ + __I int32_t TEMP; /*!< Temperature in degC (0.25deg steps) */ + __I uint32_t RESERVED3[5]; + __IO uint32_t A0; /*!< Slope of 1st piece wise linear function */ + __IO uint32_t A1; /*!< Slope of 2nd piece wise linear function */ + __IO uint32_t A2; /*!< Slope of 3rd piece wise linear function */ + __IO uint32_t A3; /*!< Slope of 4th piece wise linear function */ + __IO uint32_t A4; /*!< Slope of 5th piece wise linear function */ + __IO uint32_t A5; /*!< Slope of 6th piece wise linear function */ + __I uint32_t RESERVED4[2]; + __IO uint32_t B0; /*!< y-intercept of 1st piece wise linear function */ + __IO uint32_t B1; /*!< y-intercept of 2nd piece wise linear function */ + __IO uint32_t B2; /*!< y-intercept of 3rd piece wise linear function */ + __IO uint32_t B3; /*!< y-intercept of 4th piece wise linear function */ + __IO uint32_t B4; /*!< y-intercept of 5th piece wise linear function */ + __IO uint32_t B5; /*!< y-intercept of 6th piece wise linear function */ + __I uint32_t RESERVED5[2]; + __IO uint32_t T0; /*!< End point of 1st piece wise linear function */ + __IO uint32_t T1; /*!< End point of 2nd piece wise linear function */ + __IO uint32_t T2; /*!< End point of 3rd piece wise linear function */ + __IO uint32_t T3; /*!< End point of 4th piece wise linear function */ + __IO uint32_t T4; /*!< End point of 5th piece wise linear function */ } NRF_TEMP_Type; @@ -1750,16 +1854,16 @@ typedef struct { /*!< MWU Structure */ typedef struct { /*!< I2S Structure */ - __O uint32_t TASKS_START; /*!< Starts continuous I2S transfer. Also starts MCK generator - when this is enabled. */ - __O uint32_t TASKS_STOP; /*!< Stops I2S transfer. Also stops MCK generator. Triggering - this task will cause the STOPPED event to be generated. */ + __O uint32_t TASKS_START; /*!< Starts continuous I2S transfer. Also starts MCK generator when + this is enabled. */ + __O uint32_t TASKS_STOP; /*!< Stops I2S transfer. Also stops MCK generator. Triggering this + task will cause the {event:STOPPED} event to be generated. */ __I uint32_t RESERVED0[63]; __IO uint32_t EVENTS_RXPTRUPD; /*!< The RXD.PTR register has been copied to internal double-buffers. When the I2S module is started and RX is enabled, this event will be generated for every RXTXD.MAXCNT words that are received on the SDIN pin. */ - __IO uint32_t EVENTS_STOPPED; /*!< I2S transfer stopped. */ + __IO uint32_t EVENTS_STOPPED; /*!< I2S transfer stopped. */ __I uint32_t RESERVED1[2]; __IO uint32_t EVENTS_TXPTRUPD; /*!< The TDX.PTR register has been copied to internal double-buffers. When the I2S module is started and TX is enabled, this event @@ -1770,7 +1874,7 @@ typedef struct { /*!< I2S Structure __IO uint32_t INTENSET; /*!< Enable interrupt */ __IO uint32_t INTENCLR; /*!< Disable interrupt */ __I uint32_t RESERVED3[125]; - __IO uint32_t ENABLE; /*!< Enable I2S module. */ + __IO uint32_t ENABLE; /*!< Enable I2S module. */ I2S_CONFIG_Type CONFIG; /*!< Unspecified */ __I uint32_t RESERVED4[3]; I2S_RXD_Type RXD; /*!< Unspecified */ @@ -1783,6 +1887,20 @@ typedef struct { /*!< I2S Structure } NRF_I2S_Type; +/* ================================================================================ */ +/* ================ FPU ================ */ +/* ================================================================================ */ + + +/** + * @brief FPU (FPU) + */ + +typedef struct { /*!< FPU Structure */ + __I uint32_t UNUSED; /*!< Unused. */ +} NRF_FPU_Type; + + /* ================================================================================ */ /* ================ GPIO ================ */ /* ================================================================================ */ @@ -1801,63 +1919,14 @@ typedef struct { /*!< GPIO Structure __IO uint32_t DIR; /*!< Direction of GPIO pins */ __IO uint32_t DIRSET; /*!< DIR set register */ __IO uint32_t DIRCLR; /*!< DIR clear register */ - __IO uint32_t LATCH; /*!< Latch indicating which GPIO pins have met the criteria set in - PIN_CNF[n].SENSE register */ + __IO uint32_t LATCH; /*!< Latch register indicating what GPIO pins that have met the criteria + set in the PIN_CNF[n].SENSE registers */ __IO uint32_t DETECTMODE; /*!< Select between default DETECT signal behaviour and LDETECT mode */ __I uint32_t RESERVED1[118]; __IO uint32_t PIN_CNF[32]; /*!< Description collection[0]: Configuration of GPIO pins */ } NRF_GPIO_Type; -/* ================================================================================ */ -/* ================ UART ================ */ -/* ================================================================================ */ - - -/** - * @brief Universal Asynchronous Receiver/Transmitter (UART) - */ - -typedef struct { /*!< UART Structure */ - __O uint32_t TASKS_STARTRX; /*!< Start UART receiver */ - __O uint32_t TASKS_STOPRX; /*!< Stop UART receiver */ - __O uint32_t TASKS_STARTTX; /*!< Start UART transmitter */ - __O uint32_t TASKS_STOPTX; /*!< Stop UART transmitter */ - __I uint32_t RESERVED0[3]; - __O uint32_t TASKS_SUSPEND; /*!< Suspend UART */ - __I uint32_t RESERVED1[56]; - __IO uint32_t EVENTS_CTS; /*!< CTS is activated (set low). Clear To Send. */ - __IO uint32_t EVENTS_NCTS; /*!< CTS is deactivated (set high). Not Clear To Send. */ - __IO uint32_t EVENTS_RXDRDY; /*!< Data received in RXD */ - __I uint32_t RESERVED2[4]; - __IO uint32_t EVENTS_TXDRDY; /*!< Data sent from TXD */ - __I uint32_t RESERVED3; - __IO uint32_t EVENTS_ERROR; /*!< Error detected */ - __I uint32_t RESERVED4[7]; - __IO uint32_t EVENTS_RXTO; /*!< Receiver timeout */ - __I uint32_t RESERVED5[46]; - __IO uint32_t SHORTS; /*!< Shortcut register */ - __I uint32_t RESERVED6[64]; - __IO uint32_t INTENSET; /*!< Enable interrupt */ - __IO uint32_t INTENCLR; /*!< Disable interrupt */ - __I uint32_t RESERVED7[93]; - __IO uint32_t ERRORSRC; /*!< Error source */ - __I uint32_t RESERVED8[31]; - __IO uint32_t ENABLE; /*!< Enable UART */ - __I uint32_t RESERVED9; - __IO uint32_t PSELRTS; /*!< Pin select for RTS */ - __IO uint32_t PSELTXD; /*!< Pin select for TXD */ - __IO uint32_t PSELCTS; /*!< Pin select for CTS */ - __IO uint32_t PSELRXD; /*!< Pin select for RXD */ - __I uint32_t RXD; /*!< RXD register */ - __O uint32_t TXD; /*!< TXD register */ - __I uint32_t RESERVED10; - __IO uint32_t BAUDRATE; /*!< Baud rate */ - __I uint32_t RESERVED11[17]; - __IO uint32_t CONFIG; /*!< Configuration of parity and hardware flow control */ -} NRF_UART_Type; - - /* -------------------- End of section using anonymous unions ------------------- */ #if defined(__CC_ARM) #pragma pop @@ -1887,6 +1956,7 @@ typedef struct { /*!< UART Structure #define NRF_CLOCK_BASE 0x40000000UL #define NRF_RADIO_BASE 0x40001000UL #define NRF_UARTE0_BASE 0x40002000UL +#define NRF_UART0_BASE 0x40002000UL #define NRF_SPIM0_BASE 0x40003000UL #define NRF_SPIS0_BASE 0x40003000UL #define NRF_TWIM0_BASE 0x40003000UL @@ -1898,6 +1968,7 @@ typedef struct { /*!< UART Structure #define NRF_TWIM1_BASE 0x40004000UL #define NRF_TWIS1_BASE 0x40004000UL #define NRF_SPI1_BASE 0x40004000UL +#define NRF_TWI1_BASE 0x40004000UL #define NRF_NFCT_BASE 0x40005000UL #define NRF_GPIOTE_BASE 0x40006000UL #define NRF_SAADC_BASE 0x40007000UL @@ -1941,9 +2012,8 @@ typedef struct { /*!< UART Structure #define NRF_SPI2_BASE 0x40023000UL #define NRF_RTC2_BASE 0x40024000UL #define NRF_I2S_BASE 0x40025000UL +#define NRF_FPU_BASE 0x40026000UL #define NRF_P0_BASE 0x50000000UL -#define NRF_TWI1_BASE 0x40004000UL -#define NRF_UART0_BASE 0x40002000UL /* ================================================================================ */ @@ -1957,6 +2027,7 @@ typedef struct { /*!< UART Structure #define NRF_CLOCK ((NRF_CLOCK_Type *) NRF_CLOCK_BASE) #define NRF_RADIO ((NRF_RADIO_Type *) NRF_RADIO_BASE) #define NRF_UARTE0 ((NRF_UARTE_Type *) NRF_UARTE0_BASE) +#define NRF_UART0 ((NRF_UART_Type *) NRF_UART0_BASE) #define NRF_SPIM0 ((NRF_SPIM_Type *) NRF_SPIM0_BASE) #define NRF_SPIS0 ((NRF_SPIS_Type *) NRF_SPIS0_BASE) #define NRF_TWIM0 ((NRF_TWIM_Type *) NRF_TWIM0_BASE) @@ -1968,6 +2039,7 @@ typedef struct { /*!< UART Structure #define NRF_TWIM1 ((NRF_TWIM_Type *) NRF_TWIM1_BASE) #define NRF_TWIS1 ((NRF_TWIS_Type *) NRF_TWIS1_BASE) #define NRF_SPI1 ((NRF_SPI_Type *) NRF_SPI1_BASE) +#define NRF_TWI1 ((NRF_TWI_Type *) NRF_TWI1_BASE) #define NRF_NFCT ((NRF_NFCT_Type *) NRF_NFCT_BASE) #define NRF_GPIOTE ((NRF_GPIOTE_Type *) NRF_GPIOTE_BASE) #define NRF_SAADC ((NRF_SAADC_Type *) NRF_SAADC_BASE) @@ -2011,9 +2083,8 @@ typedef struct { /*!< UART Structure #define NRF_SPI2 ((NRF_SPI_Type *) NRF_SPI2_BASE) #define NRF_RTC2 ((NRF_RTC_Type *) NRF_RTC2_BASE) #define NRF_I2S ((NRF_I2S_Type *) NRF_I2S_BASE) +#define NRF_FPU ((NRF_FPU_Type *) NRF_FPU_BASE) #define NRF_P0 ((NRF_GPIO_Type *) NRF_P0_BASE) -#define NRF_TWI1 ((NRF_TWI_Type *) NRF_TWI1_BASE) -#define NRF_UART0 ((NRF_UART_Type *) NRF_UART0_BASE) /** @} */ /* End of group Device_Peripheral_Registers */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52832_peripherals.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52832_peripherals.h new file mode 100644 index 0000000000000000000000000000000000000000..f9e22bbd020f2982f3d79280be5d94fac8edb35d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52832_peripherals.h @@ -0,0 +1,230 @@ +/* + +Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + +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, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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 Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + +*/ + +#ifndef _NRF52832_PERIPHERALS_H +#define _NRF52832_PERIPHERALS_H + + +/* Floating Point Unit */ +#define FPU_PRESENT +#define FPU_COUNT 1 + +/* Systick timer */ +#define SYSTICK_PRESENT +#define SYSTICK_COUNT 1 + +/* Software Interrupts */ +#define SWI_PRESENT +#define SWI_COUNT 6 + +/* Memory Watch Unit */ +#define MWU_PRESENT +#define MWU_COUNT 1 + +/* GPIO */ +#define GPIO_PRESENT +#define GPIO_COUNT 1 + +#define P0_PIN_NUM 32 + +/* MPU and BPROT */ +#define BPROT_PRESENT + +#define BPROT_REGIONS_SIZE 4096 +#define BPROT_REGIONS_NUM 128 + +/* Radio */ +#define RADIO_PRESENT +#define RADIO_COUNT 1 + +/* Accelerated Address Resolver */ +#define AAR_PRESENT +#define AAR_COUNT 1 + +#define AAR_MAX_IRK_NUM 16 + +/* AES Electronic CodeBook mode encryption */ +#define ECB_PRESENT +#define ECB_COUNT 1 + +/* AES CCM mode encryption */ +#define CCM_PRESENT +#define CCM_COUNT 1 + +/* NFC Tag */ +#define NFCT_PRESENT +#define NFCT_COUNT 1 + +/* Peripheral to Peripheral Interconnect */ +#define PPI_PRESENT +#define PPI_COUNT 1 + +#define PPI_CH_NUM 20 +#define PPI_FIXED_CH_NUM 12 +#define PPI_GROUP_NUM 6 +#define PPI_FEATURE_FORKS_PRESENT + +/* Event Generator Unit */ +#define EGU_PRESENT +#define EGU_COUNT 6 + +#define EGU0_CH_NUM 16 +#define EGU1_CH_NUM 16 +#define EGU2_CH_NUM 16 +#define EGU3_CH_NUM 16 +#define EGU4_CH_NUM 16 +#define EGU5_CH_NUM 16 + +/* Timer/Counter */ +#define TIMER_PRESENT +#define TIMER_COUNT 5 + +#define TIMER0_MAX_SIZE 32 +#define TIMER1_MAX_SIZE 32 +#define TIMER2_MAX_SIZE 32 +#define TIMER3_MAX_SIZE 32 +#define TIMER4_MAX_SIZE 32 + +#define TIMER0_CC_NUM 4 +#define TIMER1_CC_NUM 4 +#define TIMER2_CC_NUM 4 +#define TIMER3_CC_NUM 6 +#define TIMER4_CC_NUM 6 + +/* Real Time Counter */ +#define RTC_PRESENT +#define RTC_COUNT 3 + +#define RTC0_CC_NUM 3 +#define RTC1_CC_NUM 4 +#define RTC2_CC_NUM 4 + +/* RNG */ +#define RNG_PRESENT +#define RNG_COUNT 1 + +/* Watchdog Timer */ +#define WDT_PRESENT +#define WDT_COUNT 1 + +/* Temperature Sensor */ +#define TEMP_PRESENT +#define TEMP_COUNT 1 + +/* Serial Peripheral Interface Master */ +#define SPI_PRESENT +#define SPI_COUNT 3 + +/* Serial Peripheral Interface Master with DMA */ +#define SPIM_PRESENT +#define SPIM_COUNT 3 + +/* Serial Peripheral Interface Slave with DMA*/ +#define SPIS_PRESENT +#define SPIS_COUNT 3 + +/* Two Wire Interface Master */ +#define TWI_PRESENT +#define TWI_COUNT 2 + +/* Two Wire Interface Master with DMA */ +#define TWIM_PRESENT +#define TWIM_COUNT 2 + +/* Two Wire Interface Slave with DMA */ +#define TWIS_PRESENT +#define TWIS_COUNT 2 + +/* Universal Asynchronous Receiver-Transmitter */ +#define UART_PRESENT +#define UART_COUNT 1 + +/* Universal Asynchronous Receiver-Transmitter with DMA */ +#define UARTE_PRESENT +#define UARTE_COUNT 1 + +/* Quadrature Decoder */ +#define QDEC_PRESENT +#define QDEC_COUNT 1 + +/* Successive Approximation Analog to Digital Converter */ +#define SAADC_PRESENT +#define SAADC_COUNT 1 + +/* GPIO Tasks and Events */ +#define GPIOTE_PRESENT +#define GPIOTE_COUNT 1 + +#define GPIOTE_CH_NUM 8 + +#define GPIOTE_FEATURE_SET_PRESENT +#define GPIOTE_FEATURE_CLR_PRESENT + +/* Low Power Comparator */ +#define LPCOMP_PRESENT +#define LPCOMP_COUNT 1 + +#define LPCOMP_REFSEL_RESOLUTION 16 + +#define LPCOMP_FEATURE_HYST_PRESENT + +/* Comparator */ +#define COMP_PRESENT +#define COMP_COUNT 1 + +/* Pulse Width Modulator */ +#define PWM_PRESENT +#define PWM_COUNT 3 + +#define PWM0_CH_NUM 4 +#define PWM1_CH_NUM 4 +#define PWM2_CH_NUM 4 + +/* Pulse Density Modulator */ +#define PDM_PRESENT +#define PDM_COUNT 1 + +/* Inter-IC Sound Interface */ +#define I2S_PRESENT +#define I2S_COUNT 1 + + +#endif // _NRF52832_PERIPHERALS_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52840.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52840.h new file mode 100644 index 0000000000000000000000000000000000000000..1c2e95603aa51777948ff45de56fb4fc84731b9d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52840.h @@ -0,0 +1,2428 @@ + +/****************************************************************************************************//** + * @file nrf52840.h + * + * @brief CMSIS Cortex-M4 Peripheral Access Layer Header File for + * nrf52840 from Nordic Semiconductor. + * + * @version V1 + * @date 22. February 2017 + * + * @note Generated with SVDConv V2.81d + * from CMSIS SVD File 'nrf52840.svd' Version 1, + * + * @par Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 Nordic Semiconductor + * @{ + */ + +/** @addtogroup nrf52840 + * @{ + */ + +#ifndef NRF52840_H +#define NRF52840_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* ------------------------- Interrupt Number Definition ------------------------ */ + +typedef enum { +/* ------------------- Cortex-M4 Processor Exceptions Numbers ------------------- */ + Reset_IRQn = -15, /*!< 1 Reset Vector, invoked on Power up and warm reset */ + NonMaskableInt_IRQn = -14, /*!< 2 Non maskable Interrupt, cannot be stopped or preempted */ + HardFault_IRQn = -13, /*!< 3 Hard Fault, all classes of Fault */ + MemoryManagement_IRQn = -12, /*!< 4 Memory Management, MPU mismatch, including Access Violation + and No Match */ + BusFault_IRQn = -11, /*!< 5 Bus Fault, Pre-Fetch-, Memory Access Fault, other address/memory + related Fault */ + UsageFault_IRQn = -10, /*!< 6 Usage Fault, i.e. Undef Instruction, Illegal State Transition */ + SVCall_IRQn = -5, /*!< 11 System Service Call via SVC instruction */ + DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor */ + PendSV_IRQn = -2, /*!< 14 Pendable request for system service */ + SysTick_IRQn = -1, /*!< 15 System Tick Timer */ +/* --------------------- nrf52840 Specific Interrupt Numbers -------------------- */ + POWER_CLOCK_IRQn = 0, /*!< 0 POWER_CLOCK */ + RADIO_IRQn = 1, /*!< 1 RADIO */ + UARTE0_UART0_IRQn = 2, /*!< 2 UARTE0_UART0 */ + SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn= 3, /*!< 3 SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 */ + SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn= 4, /*!< 4 SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1 */ + NFCT_IRQn = 5, /*!< 5 NFCT */ + GPIOTE_IRQn = 6, /*!< 6 GPIOTE */ + SAADC_IRQn = 7, /*!< 7 SAADC */ + TIMER0_IRQn = 8, /*!< 8 TIMER0 */ + TIMER1_IRQn = 9, /*!< 9 TIMER1 */ + TIMER2_IRQn = 10, /*!< 10 TIMER2 */ + RTC0_IRQn = 11, /*!< 11 RTC0 */ + TEMP_IRQn = 12, /*!< 12 TEMP */ + RNG_IRQn = 13, /*!< 13 RNG */ + ECB_IRQn = 14, /*!< 14 ECB */ + CCM_AAR_IRQn = 15, /*!< 15 CCM_AAR */ + WDT_IRQn = 16, /*!< 16 WDT */ + RTC1_IRQn = 17, /*!< 17 RTC1 */ + QDEC_IRQn = 18, /*!< 18 QDEC */ + COMP_LPCOMP_IRQn = 19, /*!< 19 COMP_LPCOMP */ + SWI0_EGU0_IRQn = 20, /*!< 20 SWI0_EGU0 */ + SWI1_EGU1_IRQn = 21, /*!< 21 SWI1_EGU1 */ + SWI2_EGU2_IRQn = 22, /*!< 22 SWI2_EGU2 */ + SWI3_EGU3_IRQn = 23, /*!< 23 SWI3_EGU3 */ + SWI4_EGU4_IRQn = 24, /*!< 24 SWI4_EGU4 */ + SWI5_EGU5_IRQn = 25, /*!< 25 SWI5_EGU5 */ + TIMER3_IRQn = 26, /*!< 26 TIMER3 */ + TIMER4_IRQn = 27, /*!< 27 TIMER4 */ + PWM0_IRQn = 28, /*!< 28 PWM0 */ + PDM_IRQn = 29, /*!< 29 PDM */ + MWU_IRQn = 32, /*!< 32 MWU */ + PWM1_IRQn = 33, /*!< 33 PWM1 */ + PWM2_IRQn = 34, /*!< 34 PWM2 */ + SPIM2_SPIS2_SPI2_IRQn = 35, /*!< 35 SPIM2_SPIS2_SPI2 */ + RTC2_IRQn = 36, /*!< 36 RTC2 */ + I2S_IRQn = 37, /*!< 37 I2S */ + FPU_IRQn = 38, /*!< 38 FPU */ + USBD_IRQn = 39, /*!< 39 USBD */ + UARTE1_IRQn = 40, /*!< 40 UARTE1 */ + QSPI_IRQn = 41, /*!< 41 QSPI */ + CRYPTOCELL_IRQn = 42, /*!< 42 CRYPTOCELL */ + SPIM3_IRQn = 43, /*!< 43 SPIM3 */ + PWM3_IRQn = 45 /*!< 45 PWM3 */ +} IRQn_Type; + + +/** @addtogroup Configuration_of_CMSIS + * @{ + */ + + +/* ================================================================================ */ +/* ================ Processor and Core Peripheral Section ================ */ +/* ================================================================================ */ + +/* ----------------Configuration of the Cortex-M4 Processor and Core Peripherals---------------- */ +#define __CM4_REV 0x0001 /*!< Cortex-M4 Core Revision */ +#define __MPU_PRESENT 1 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ +#define __FPU_PRESENT 1 /*!< FPU present or not */ +/** @} */ /* End of group Configuration_of_CMSIS */ + +#include "core_cm4.h" /*!< Cortex-M4 processor and core peripherals */ +#include "system_nrf52840.h" /*!< nrf52840 System */ + + +/* ================================================================================ */ +/* ================ Device Specific Peripheral Section ================ */ +/* ================================================================================ */ + + +/** @addtogroup Device_Peripheral_Registers + * @{ + */ + + +/* ------------------- Start of section using anonymous unions ------------------ */ +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined(__TMS470__) +/* anonymous unions are enabled by default */ +#elif defined(__TASKING__) + #pragma warning 586 +#else + #warning Not supported compiler type +#endif + + +typedef struct { + __I uint32_t PART; /*!< Part code */ + __I uint32_t VARIANT; /*!< Part variant (hardware version and production configuration) */ + __I uint32_t PACKAGE; /*!< Package option */ + __I uint32_t RAM; /*!< RAM variant */ + __I uint32_t FLASH; /*!< Flash variant */ + __IO uint32_t UNUSED0[3]; /*!< Description collection[0]: Unspecified */ +} FICR_INFO_Type; + +typedef struct { + __I uint32_t A0; /*!< Slope definition A0 */ + __I uint32_t A1; /*!< Slope definition A1 */ + __I uint32_t A2; /*!< Slope definition A2 */ + __I uint32_t A3; /*!< Slope definition A3 */ + __I uint32_t A4; /*!< Slope definition A4 */ + __I uint32_t A5; /*!< Slope definition A5 */ + __I uint32_t B0; /*!< Y-intercept B0 */ + __I uint32_t B1; /*!< Y-intercept B1 */ + __I uint32_t B2; /*!< Y-intercept B2 */ + __I uint32_t B3; /*!< Y-intercept B3 */ + __I uint32_t B4; /*!< Y-intercept B4 */ + __I uint32_t B5; /*!< Y-intercept B5 */ + __I uint32_t T0; /*!< Segment end T0 */ + __I uint32_t T1; /*!< Segment end T1 */ + __I uint32_t T2; /*!< Segment end T2 */ + __I uint32_t T3; /*!< Segment end T3 */ + __I uint32_t T4; /*!< Segment end T4 */ +} FICR_TEMP_Type; + +typedef struct { + __I uint32_t TAGHEADER0; /*!< Default header for NFC tag. Software can read these values to + populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */ + __I uint32_t TAGHEADER1; /*!< Default header for NFC tag. Software can read these values to + populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */ + __I uint32_t TAGHEADER2; /*!< Default header for NFC tag. Software can read these values to + populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */ + __I uint32_t TAGHEADER3; /*!< Default header for NFC tag. Software can read these values to + populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */ +} FICR_NFC_Type; + +typedef struct { + __IO uint32_t POWER; /*!< Description cluster[0]: RAM0 power control register */ + __O uint32_t POWERSET; /*!< Description cluster[0]: RAM0 power control set register */ + __O uint32_t POWERCLR; /*!< Description cluster[0]: RAM0 power control clear register */ + __I uint32_t RESERVED0; +} POWER_RAM_Type; + +typedef struct { + __IO uint32_t RTS; /*!< Pin select for RTS signal */ + __IO uint32_t TXD; /*!< Pin select for TXD signal */ + __IO uint32_t CTS; /*!< Pin select for CTS signal */ + __IO uint32_t RXD; /*!< Pin select for RXD signal */ +} UARTE_PSEL_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Data pointer */ + __IO uint32_t MAXCNT; /*!< Maximum number of bytes in receive buffer */ + __I uint32_t AMOUNT; /*!< Number of bytes transferred in the last transaction */ +} UARTE_RXD_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Data pointer */ + __IO uint32_t MAXCNT; /*!< Maximum number of bytes in transmit buffer */ + __I uint32_t AMOUNT; /*!< Number of bytes transferred in the last transaction */ +} UARTE_TXD_Type; + +typedef struct { + __IO uint32_t RTS; /*!< Pin select for RTS */ + __IO uint32_t TXD; /*!< Pin select for TXD */ + __IO uint32_t CTS; /*!< Pin select for CTS */ + __IO uint32_t RXD; /*!< Pin select for RXD */ +} UART_PSEL_Type; + +typedef struct { + __IO uint32_t SCK; /*!< Pin select for SCK */ + __IO uint32_t MOSI; /*!< Pin select for MOSI signal */ + __IO uint32_t MISO; /*!< Pin select for MISO signal */ + __IO uint32_t CSN; /*!< Pin select for CSN */ +} SPIM_PSEL_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Data pointer */ + __IO uint32_t MAXCNT; /*!< Maximum number of bytes in receive buffer */ + __I uint32_t AMOUNT; /*!< Number of bytes transferred in the last transaction */ + __IO uint32_t LIST; /*!< EasyDMA list type */ +} SPIM_RXD_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Data pointer */ + __IO uint32_t MAXCNT; /*!< Number of bytes in transmit buffer */ + __I uint32_t AMOUNT; /*!< Number of bytes transferred in the last transaction */ + __IO uint32_t LIST; /*!< EasyDMA list type */ +} SPIM_TXD_Type; + +typedef struct { + __IO uint32_t RXDELAY; /*!< Sample delay for input serial data on MISO */ + __IO uint32_t CSNDUR; /*!< Minimum duration between edge of CSN and edge of SCK and minimum + duration CSN must stay high between transactions */ +} SPIM_IFTIMING_Type; + +typedef struct { + __IO uint32_t SCK; /*!< Pin select for SCK */ + __IO uint32_t MISO; /*!< Pin select for MISO signal */ + __IO uint32_t MOSI; /*!< Pin select for MOSI signal */ + __IO uint32_t CSN; /*!< Pin select for CSN signal */ +} SPIS_PSEL_Type; + +typedef struct { + __IO uint32_t PTR; /*!< RXD data pointer */ + __IO uint32_t MAXCNT; /*!< Maximum number of bytes in receive buffer */ + __I uint32_t AMOUNT; /*!< Number of bytes received in last granted transaction */ +} SPIS_RXD_Type; + +typedef struct { + __IO uint32_t PTR; /*!< TXD data pointer */ + __IO uint32_t MAXCNT; /*!< Maximum number of bytes in transmit buffer */ + __I uint32_t AMOUNT; /*!< Number of bytes transmitted in last granted transaction */ +} SPIS_TXD_Type; + +typedef struct { + __IO uint32_t SCL; /*!< Pin select for SCL signal */ + __IO uint32_t SDA; /*!< Pin select for SDA signal */ +} TWIM_PSEL_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Data pointer */ + __IO uint32_t MAXCNT; /*!< Maximum number of bytes in receive buffer */ + __I uint32_t AMOUNT; /*!< Number of bytes transferred in the last transaction */ + __IO uint32_t LIST; /*!< EasyDMA list type */ +} TWIM_RXD_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Data pointer */ + __IO uint32_t MAXCNT; /*!< Maximum number of bytes in transmit buffer */ + __I uint32_t AMOUNT; /*!< Number of bytes transferred in the last transaction */ + __IO uint32_t LIST; /*!< EasyDMA list type */ +} TWIM_TXD_Type; + +typedef struct { + __IO uint32_t SCL; /*!< Pin select for SCL signal */ + __IO uint32_t SDA; /*!< Pin select for SDA signal */ +} TWIS_PSEL_Type; + +typedef struct { + __IO uint32_t PTR; /*!< RXD Data pointer */ + __IO uint32_t MAXCNT; /*!< Maximum number of bytes in RXD buffer */ + __I uint32_t AMOUNT; /*!< Number of bytes transferred in the last RXD transaction */ +} TWIS_RXD_Type; + +typedef struct { + __IO uint32_t PTR; /*!< TXD Data pointer */ + __IO uint32_t MAXCNT; /*!< Maximum number of bytes in TXD buffer */ + __I uint32_t AMOUNT; /*!< Number of bytes transferred in the last TXD transaction */ +} TWIS_TXD_Type; + +typedef struct { + __IO uint32_t SCK; /*!< Pin select for SCK */ + __IO uint32_t MOSI; /*!< Pin select for MOSI signal */ + __IO uint32_t MISO; /*!< Pin select for MISO signal */ +} SPI_PSEL_Type; + +typedef struct { + __IO uint32_t SCL; /*!< Pin select for SCL */ + __IO uint32_t SDA; /*!< Pin select for SDA */ +} TWI_PSEL_Type; + +typedef struct { + __IO uint32_t RX; /*!< Result of last incoming frame */ +} NFCT_FRAMESTATUS_Type; + +typedef struct { + __IO uint32_t FRAMECONFIG; /*!< Configuration of outgoing frames */ + __IO uint32_t AMOUNT; /*!< Size of outgoing frame */ +} NFCT_TXD_Type; + +typedef struct { + __IO uint32_t FRAMECONFIG; /*!< Configuration of incoming frames */ + __I uint32_t AMOUNT; /*!< Size of last incoming frame */ +} NFCT_RXD_Type; + +typedef struct { + __IO uint32_t LIMITH; /*!< Description cluster[0]: Last results is equal or above CH[0].LIMIT.HIGH */ + __IO uint32_t LIMITL; /*!< Description cluster[0]: Last results is equal or below CH[0].LIMIT.LOW */ +} SAADC_EVENTS_CH_Type; + +typedef struct { + __IO uint32_t PSELP; /*!< Description cluster[0]: Input positive pin selection for CH[0] */ + __IO uint32_t PSELN; /*!< Description cluster[0]: Input negative pin selection for CH[0] */ + __IO uint32_t CONFIG; /*!< Description cluster[0]: Input configuration for CH[0] */ + __IO uint32_t LIMIT; /*!< Description cluster[0]: High/low limits for event monitoring + a channel */ +} SAADC_CH_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Data pointer */ + __IO uint32_t MAXCNT; /*!< Maximum number of buffer words to transfer */ + __I uint32_t AMOUNT; /*!< Number of buffer words transferred since last START */ +} SAADC_RESULT_Type; + +typedef struct { + __IO uint32_t LED; /*!< Pin select for LED signal */ + __IO uint32_t A; /*!< Pin select for A signal */ + __IO uint32_t B; /*!< Pin select for B signal */ +} QDEC_PSEL_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Description cluster[0]: Beginning address in Data RAM of this + sequence */ + __IO uint32_t CNT; /*!< Description cluster[0]: Amount of values (duty cycles) in this + sequence */ + __IO uint32_t REFRESH; /*!< Description cluster[0]: Amount of additional PWM periods between + samples loaded into compare register */ + __IO uint32_t ENDDELAY; /*!< Description cluster[0]: Time added after the sequence */ + __I uint32_t RESERVED1[4]; +} PWM_SEQ_Type; + +typedef struct { + __IO uint32_t OUT[4]; /*!< Description collection[0]: Output pin select for PWM channel + 0 */ +} PWM_PSEL_Type; + +typedef struct { + __IO uint32_t CLK; /*!< Pin number configuration for PDM CLK signal */ + __IO uint32_t DIN; /*!< Pin number configuration for PDM DIN signal */ +} PDM_PSEL_Type; + +typedef struct { + __IO uint32_t PTR; /*!< RAM address pointer to write samples to with EasyDMA */ + __IO uint32_t MAXCNT; /*!< Number of samples to allocate memory for in EasyDMA mode */ +} PDM_SAMPLE_Type; + +typedef struct { + __IO uint32_t ADDR; /*!< Description cluster[0]: Configure the word-aligned start address + of region 0 to protect */ + __IO uint32_t SIZE; /*!< Description cluster[0]: Size of region to protect counting from + address ACL[0].ADDR. Write '0' as no effect. */ + __IO uint32_t PERM; /*!< Description cluster[0]: Access permissions for region 0 as defined + by start address ACL[0].ADDR and size ACL[0].SIZE */ + __IO uint32_t UNUSED0; /*!< Unspecified */ +} ACL_ACL_Type; + +typedef struct { + __O uint32_t EN; /*!< Description cluster[0]: Enable channel group 0 */ + __O uint32_t DIS; /*!< Description cluster[0]: Disable channel group 0 */ +} PPI_TASKS_CHG_Type; + +typedef struct { + __IO uint32_t EEP; /*!< Description cluster[0]: Channel 0 event end-point */ + __IO uint32_t TEP; /*!< Description cluster[0]: Channel 0 task end-point */ +} PPI_CH_Type; + +typedef struct { + __IO uint32_t TEP; /*!< Description cluster[0]: Channel 0 task end-point */ +} PPI_FORK_Type; + +typedef struct { + __IO uint32_t WA; /*!< Description cluster[0]: Write access to region 0 detected */ + __IO uint32_t RA; /*!< Description cluster[0]: Read access to region 0 detected */ +} MWU_EVENTS_REGION_Type; + +typedef struct { + __IO uint32_t WA; /*!< Description cluster[0]: Write access to peripheral region 0 + detected */ + __IO uint32_t RA; /*!< Description cluster[0]: Read access to peripheral region 0 detected */ +} MWU_EVENTS_PREGION_Type; + +typedef struct { + __IO uint32_t SUBSTATWA; /*!< Description cluster[0]: Source of event/interrupt in region + 0, write access detected while corresponding subregion was enabled + for watching */ + __IO uint32_t SUBSTATRA; /*!< Description cluster[0]: Source of event/interrupt in region + 0, read access detected while corresponding subregion was enabled + for watching */ +} MWU_PERREGION_Type; + +typedef struct { + __IO uint32_t START; /*!< Description cluster[0]: Start address for region 0 */ + __IO uint32_t END; /*!< Description cluster[0]: End address of region 0 */ + __I uint32_t RESERVED2[2]; +} MWU_REGION_Type; + +typedef struct { + __I uint32_t START; /*!< Description cluster[0]: Reserved for future use */ + __I uint32_t END; /*!< Description cluster[0]: Reserved for future use */ + __IO uint32_t SUBS; /*!< Description cluster[0]: Subregions of region 0 */ + __I uint32_t RESERVED3; +} MWU_PREGION_Type; + +typedef struct { + __IO uint32_t MODE; /*!< I2S mode. */ + __IO uint32_t RXEN; /*!< Reception (RX) enable. */ + __IO uint32_t TXEN; /*!< Transmission (TX) enable. */ + __IO uint32_t MCKEN; /*!< Master clock generator enable. */ + __IO uint32_t MCKFREQ; /*!< Master clock generator frequency. */ + __IO uint32_t RATIO; /*!< MCK / LRCK ratio. */ + __IO uint32_t SWIDTH; /*!< Sample width. */ + __IO uint32_t ALIGN; /*!< Alignment of sample within a frame. */ + __IO uint32_t FORMAT; /*!< Frame format. */ + __IO uint32_t CHANNELS; /*!< Enable channels. */ +} I2S_CONFIG_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Receive buffer RAM start address. */ +} I2S_RXD_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Transmit buffer RAM start address. */ +} I2S_TXD_Type; + +typedef struct { + __IO uint32_t MAXCNT; /*!< Size of RXD and TXD buffers. */ +} I2S_RXTXD_Type; + +typedef struct { + __IO uint32_t MCK; /*!< Pin select for MCK signal. */ + __IO uint32_t SCK; /*!< Pin select for SCK signal. */ + __IO uint32_t LRCK; /*!< Pin select for LRCK signal. */ + __IO uint32_t SDIN; /*!< Pin select for SDIN signal. */ + __IO uint32_t SDOUT; /*!< Pin select for SDOUT signal. */ +} I2S_PSEL_Type; + +typedef struct { + __I uint32_t EPIN[8]; /*!< Description collection[0]: IN endpoint halted status. Can be + used as is as response to a GetStatus() request to endpoint. */ + __I uint32_t RESERVED4; + __I uint32_t EPOUT[8]; /*!< Description collection[0]: OUT endpoint halted status. Can be + used as is as response to a GetStatus() request to endpoint. */ +} USBD_HALTED_Type; + +typedef struct { + __IO uint32_t EPOUT[8]; /*!< Description collection[0]: Amount of bytes received last in + the data stage of this OUT endpoint */ + __IO uint32_t ISOOUT; /*!< Amount of bytes received last on this iso OUT data endpoint */ +} USBD_SIZE_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Description cluster[0]: Data pointer */ + __IO uint32_t MAXCNT; /*!< Description cluster[0]: Maximum number of bytes to transfer */ + __I uint32_t AMOUNT; /*!< Description cluster[0]: Number of bytes transferred in the last + transaction */ + __I uint32_t RESERVED5[2]; +} USBD_EPIN_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Data pointer */ + __IO uint32_t MAXCNT; /*!< Maximum number of bytes to transfer */ + __I uint32_t AMOUNT; /*!< Number of bytes transferred in the last transaction */ +} USBD_ISOIN_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Description cluster[0]: Data pointer */ + __IO uint32_t MAXCNT; /*!< Description cluster[0]: Maximum number of bytes to transfer */ + __I uint32_t AMOUNT; /*!< Description cluster[0]: Number of bytes transferred in the last + transaction */ + __I uint32_t RESERVED6[2]; +} USBD_EPOUT_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Data pointer */ + __IO uint32_t MAXCNT; /*!< Maximum number of bytes to transfer */ + __I uint32_t AMOUNT; /*!< Number of bytes transferred in the last transaction */ +} USBD_ISOOUT_Type; + +typedef struct { + __IO uint32_t SRC; /*!< Flash memory source address */ + __IO uint32_t DST; /*!< RAM destination address */ + __IO uint32_t CNT; /*!< Read transfer length */ +} QSPI_READ_Type; + +typedef struct { + __IO uint32_t DST; /*!< Flash destination address */ + __IO uint32_t SRC; /*!< RAM source address */ + __IO uint32_t CNT; /*!< Write transfer length */ +} QSPI_WRITE_Type; + +typedef struct { + __IO uint32_t PTR; /*!< Start address of flash block to be erased */ + __IO uint32_t LEN; /*!< Size of block to be erased. */ +} QSPI_ERASE_Type; + +typedef struct { + __IO uint32_t SCK; /*!< Pin select for serial clock SCK */ + __IO uint32_t CSN; /*!< Pin select for chip select signal CSN. */ + __I uint32_t RESERVED7; + __IO uint32_t IO0; /*!< Pin select for serial data MOSI/IO0. */ + __IO uint32_t IO1; /*!< Pin select for serial data MISO/IO1. */ + __IO uint32_t IO2; /*!< Pin select for serial data IO2. */ + __IO uint32_t IO3; /*!< Pin select for serial data IO3. */ +} QSPI_PSEL_Type; + + +/* ================================================================================ */ +/* ================ FICR ================ */ +/* ================================================================================ */ + + +/** + * @brief Factory information configuration registers (FICR) + */ + +typedef struct { /*!< FICR Structure */ + __I uint32_t RESERVED0[4]; + __I uint32_t CODEPAGESIZE; /*!< Code memory page size */ + __I uint32_t CODESIZE; /*!< Code memory size */ + __I uint32_t RESERVED1[18]; + __I uint32_t DEVICEID[2]; /*!< Description collection[0]: Device identifier */ + __I uint32_t RESERVED2[6]; + __I uint32_t ER[4]; /*!< Description collection[0]: Encryption root, word 0 */ + __I uint32_t IR[4]; /*!< Description collection[0]: Identity Root, word 0 */ + __I uint32_t DEVICEADDRTYPE; /*!< Device address type */ + __I uint32_t DEVICEADDR[2]; /*!< Description collection[0]: Device address 0 */ + __I uint32_t RESERVED3[21]; + FICR_INFO_Type INFO; /*!< Device info */ + __I uint32_t RESERVED4[185]; + FICR_TEMP_Type TEMP; /*!< Registers storing factory TEMP module linearization coefficients */ + __I uint32_t RESERVED5[2]; + FICR_NFC_Type NFC; /*!< Unspecified */ +} NRF_FICR_Type; + + +/* ================================================================================ */ +/* ================ UICR ================ */ +/* ================================================================================ */ + + +/** + * @brief User information configuration registers (UICR) + */ + +typedef struct { /*!< UICR Structure */ + __IO uint32_t UNUSED0; /*!< Unspecified */ + __IO uint32_t UNUSED1; /*!< Unspecified */ + __IO uint32_t UNUSED2; /*!< Unspecified */ + __I uint32_t RESERVED0; + __IO uint32_t UNUSED3; /*!< Unspecified */ + __IO uint32_t NRFFW[15]; /*!< Description collection[0]: Reserved for Nordic firmware design */ + __IO uint32_t NRFHW[12]; /*!< Description collection[0]: Reserved for Nordic hardware design */ + __IO uint32_t CUSTOMER[32]; /*!< Description collection[0]: Reserved for customer */ + __I uint32_t RESERVED1[64]; + __IO uint32_t PSELRESET[2]; /*!< Description collection[0]: Mapping of the nRESET function */ + __IO uint32_t APPROTECT; /*!< Access port protection */ + __IO uint32_t NFCPINS; /*!< Setting of pins dedicated to NFC functionality: NFC antenna + or GPIO */ + __I uint32_t RESERVED2[60]; + __IO uint32_t EXTSUPPLY; /*!< Enable external circuitry to be supplied from VDD pin. Applicable + in high voltage mode only. */ + __IO uint32_t REGOUT0; /*!< GPIO reference voltage / external output supply voltage in high + voltage mode */ +} NRF_UICR_Type; + + +/* ================================================================================ */ +/* ================ POWER ================ */ +/* ================================================================================ */ + + +/** + * @brief Power control (POWER) + */ + +typedef struct { /*!< POWER Structure */ + __I uint32_t RESERVED0[30]; + __O uint32_t TASKS_CONSTLAT; /*!< Enable constant latency mode */ + __O uint32_t TASKS_LOWPWR; /*!< Enable low power mode (variable latency) */ + __I uint32_t RESERVED1[34]; + __IO uint32_t EVENTS_POFWARN; /*!< Power failure warning */ + __I uint32_t RESERVED2[2]; + __IO uint32_t EVENTS_SLEEPENTER; /*!< CPU entered WFI/WFE sleep */ + __IO uint32_t EVENTS_SLEEPEXIT; /*!< CPU exited WFI/WFE sleep */ + __IO uint32_t EVENTS_USBDETECTED; /*!< Voltage supply detected on VBUS */ + __IO uint32_t EVENTS_USBREMOVED; /*!< Voltage supply removed from VBUS */ + __IO uint32_t EVENTS_USBPWRRDY; /*!< USB 3.3 V supply ready */ + __I uint32_t RESERVED3[119]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED4[61]; + __IO uint32_t RESETREAS; /*!< Reset reason */ + __I uint32_t RESERVED5[9]; + __I uint32_t RAMSTATUS; /*!< Deprecated register - RAM status register */ + __I uint32_t RESERVED6[3]; + __I uint32_t USBREGSTATUS; /*!< USB supply status */ + __I uint32_t RESERVED7[49]; + __O uint32_t SYSTEMOFF; /*!< System OFF register */ + __I uint32_t RESERVED8[3]; + __IO uint32_t POFCON; /*!< Power failure comparator configuration */ + __I uint32_t RESERVED9[2]; + __IO uint32_t GPREGRET; /*!< General purpose retention register */ + __IO uint32_t GPREGRET2; /*!< General purpose retention register */ + __I uint32_t RESERVED10[21]; + __IO uint32_t DCDCEN; /*!< Enable DC/DC converter for REG1 stage. */ + __I uint32_t RESERVED11; + __IO uint32_t DCDCEN0; /*!< Enable DC/DC converter for REG0 stage. */ + __I uint32_t RESERVED12[47]; + __I uint32_t MAINREGSTATUS; /*!< Main supply status */ + __I uint32_t RESERVED13[175]; + POWER_RAM_Type RAM[9]; /*!< Unspecified */ +} NRF_POWER_Type; + + +/* ================================================================================ */ +/* ================ CLOCK ================ */ +/* ================================================================================ */ + + +/** + * @brief Clock control (CLOCK) + */ + +typedef struct { /*!< CLOCK Structure */ + __O uint32_t TASKS_HFCLKSTART; /*!< Start HFCLK crystal oscillator */ + __O uint32_t TASKS_HFCLKSTOP; /*!< Stop HFCLK crystal oscillator */ + __O uint32_t TASKS_LFCLKSTART; /*!< Start LFCLK source */ + __O uint32_t TASKS_LFCLKSTOP; /*!< Stop LFCLK source */ + __O uint32_t TASKS_CAL; /*!< Start calibration of LFRC or LFULP oscillator */ + __O uint32_t TASKS_CTSTART; /*!< Start calibration timer */ + __O uint32_t TASKS_CTSTOP; /*!< Stop calibration timer */ + __I uint32_t RESERVED0[57]; + __IO uint32_t EVENTS_HFCLKSTARTED; /*!< HFCLK oscillator started */ + __IO uint32_t EVENTS_LFCLKSTARTED; /*!< LFCLK started */ + __I uint32_t RESERVED1; + __IO uint32_t EVENTS_DONE; /*!< Calibration of LFCLK RC oscillator complete event */ + __IO uint32_t EVENTS_CTTO; /*!< Calibration timer timeout */ + __I uint32_t RESERVED2[124]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED3[63]; + __I uint32_t HFCLKRUN; /*!< Status indicating that HFCLKSTART task has been triggered */ + __I uint32_t HFCLKSTAT; /*!< HFCLK status */ + __I uint32_t RESERVED4; + __I uint32_t LFCLKRUN; /*!< Status indicating that LFCLKSTART task has been triggered */ + __I uint32_t LFCLKSTAT; /*!< LFCLK status */ + __I uint32_t LFCLKSRCCOPY; /*!< Copy of LFCLKSRC register, set when LFCLKSTART task was triggered */ + __I uint32_t RESERVED5[62]; + __IO uint32_t LFCLKSRC; /*!< Clock source for the LFCLK */ + __I uint32_t RESERVED6[7]; + __IO uint32_t CTIV; /*!< Calibration timer interval */ + __I uint32_t RESERVED7[8]; + __IO uint32_t TRACECONFIG; /*!< Clocking options for the Trace Port debug interface */ + __I uint32_t RESERVED8[21]; + __IO uint32_t LFRCMODE; /*!< LFRC mode configuration */ +} NRF_CLOCK_Type; + + +/* ================================================================================ */ +/* ================ RADIO ================ */ +/* ================================================================================ */ + + +/** + * @brief 2.4 GHz Radio (RADIO) + */ + +typedef struct { /*!< RADIO Structure */ + __O uint32_t TASKS_TXEN; /*!< Enable RADIO in TX mode */ + __O uint32_t TASKS_RXEN; /*!< Enable RADIO in RX mode */ + __O uint32_t TASKS_START; /*!< Start RADIO */ + __O uint32_t TASKS_STOP; /*!< Stop RADIO */ + __O uint32_t TASKS_DISABLE; /*!< Disable RADIO */ + __O uint32_t TASKS_RSSISTART; /*!< Start the RSSI and take one single sample of the receive signal + strength. */ + __O uint32_t TASKS_RSSISTOP; /*!< Stop the RSSI measurement */ + __O uint32_t TASKS_BCSTART; /*!< Start the bit counter */ + __O uint32_t TASKS_BCSTOP; /*!< Stop the bit counter */ + __O uint32_t TASKS_EDSTART; /*!< Start the Energy Detect measurement used in IEEE 802.15.4 mode */ + __O uint32_t TASKS_EDSTOP; /*!< Stop the Energy Detect measurement */ + __O uint32_t TASKS_CCASTART; /*!< Start the Clear Channel Assessment used in IEEE 802.15.4 mode */ + __O uint32_t TASKS_CCASTOP; /*!< Stop the Clear Channel Assessment */ + __I uint32_t RESERVED0[51]; + __IO uint32_t EVENTS_READY; /*!< RADIO has ramped up and is ready to be started */ + __IO uint32_t EVENTS_ADDRESS; /*!< Address sent or received */ + __IO uint32_t EVENTS_PAYLOAD; /*!< Packet payload sent or received */ + __IO uint32_t EVENTS_END; /*!< Packet sent or received */ + __IO uint32_t EVENTS_DISABLED; /*!< RADIO has been disabled */ + __IO uint32_t EVENTS_DEVMATCH; /*!< A device address match occurred on the last received packet */ + __IO uint32_t EVENTS_DEVMISS; /*!< No device address match occurred on the last received packet */ + __IO uint32_t EVENTS_RSSIEND; /*!< Sampling of receive signal strength complete. */ + __I uint32_t RESERVED1[2]; + __IO uint32_t EVENTS_BCMATCH; /*!< Bit counter reached bit count value. */ + __I uint32_t RESERVED2; + __IO uint32_t EVENTS_CRCOK; /*!< Packet received with CRC ok */ + __IO uint32_t EVENTS_CRCERROR; /*!< Packet received with CRC error */ + __IO uint32_t EVENTS_FRAMESTART; /*!< IEEE 802.15.4 length field received */ + __IO uint32_t EVENTS_EDEND; /*!< Sampling of Energy Detection complete. A new ED sample is ready + for readout from the RADIO.EDSAMPLE register */ + __IO uint32_t EVENTS_EDSTOPPED; /*!< The sampling of Energy Detection has stopped */ + __IO uint32_t EVENTS_CCAIDLE; /*!< Wireless medium in idle - clear to send */ + __IO uint32_t EVENTS_CCABUSY; /*!< Wireless medium busy - do not send */ + __IO uint32_t EVENTS_CCASTOPPED; /*!< The CCA has stopped */ + __IO uint32_t EVENTS_RATEBOOST; /*!< Ble_LR CI field received, receive mode is changed from Ble_LR125Kbit + to Ble_LR500Kbit. */ + __IO uint32_t EVENTS_TXREADY; /*!< RADIO has ramped up and is ready to be started TX path */ + __IO uint32_t EVENTS_RXREADY; /*!< RADIO has ramped up and is ready to be started RX path */ + __IO uint32_t EVENTS_MHRMATCH; /*!< MAC Header match found. */ + __I uint32_t RESERVED3[40]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED4[64]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED5[61]; + __I uint32_t CRCSTATUS; /*!< CRC status */ + __I uint32_t RESERVED6; + __I uint32_t RXMATCH; /*!< Received address */ + __I uint32_t RXCRC; /*!< CRC field of previously received packet */ + __I uint32_t DAI; /*!< Device address match index */ + __I uint32_t RESERVED7[60]; + __IO uint32_t PACKETPTR; /*!< Packet pointer */ + __IO uint32_t FREQUENCY; /*!< Frequency */ + __IO uint32_t TXPOWER; /*!< Output power */ + __IO uint32_t MODE; /*!< Data rate and modulation */ + __IO uint32_t PCNF0; /*!< Packet configuration register 0 */ + __IO uint32_t PCNF1; /*!< Packet configuration register 1 */ + __IO uint32_t BASE0; /*!< Base address 0 */ + __IO uint32_t BASE1; /*!< Base address 1 */ + __IO uint32_t PREFIX0; /*!< Prefixes bytes for logical addresses 0-3 */ + __IO uint32_t PREFIX1; /*!< Prefixes bytes for logical addresses 4-7 */ + __IO uint32_t TXADDRESS; /*!< Transmit address select */ + __IO uint32_t RXADDRESSES; /*!< Receive address select */ + __IO uint32_t CRCCNF; /*!< CRC configuration */ + __IO uint32_t CRCPOLY; /*!< CRC polynomial */ + __IO uint32_t CRCINIT; /*!< CRC initial value */ + __I uint32_t RESERVED8; + __IO uint32_t TIFS; /*!< Inter Frame Spacing in us */ + __I uint32_t RSSISAMPLE; /*!< RSSI sample */ + __I uint32_t RESERVED9; + __I uint32_t STATE; /*!< Current radio state */ + __IO uint32_t DATAWHITEIV; /*!< Data whitening initial value */ + __I uint32_t RESERVED10[2]; + __IO uint32_t BCC; /*!< Bit counter compare */ + __I uint32_t RESERVED11[39]; + __IO uint32_t DAB[8]; /*!< Description collection[0]: Device address base segment 0 */ + __IO uint32_t DAP[8]; /*!< Description collection[0]: Device address prefix 0 */ + __IO uint32_t DACNF; /*!< Device address match configuration */ + __IO uint32_t MHRMATCHCONF; /*!< Search Pattern Configuration */ + __IO uint32_t MHRMATCHMAS; /*!< Pattern mask */ + __I uint32_t RESERVED12; + __IO uint32_t MODECNF0; /*!< Radio mode configuration register 0 */ + __I uint32_t RESERVED13[3]; + __IO uint32_t SFD; /*!< IEEE 802.15.4 Start of Frame Delimiter */ + __IO uint32_t EDCNT; /*!< IEEE 802.15.4 Energy Detect Loop Count */ + __IO uint32_t EDSAMPLE; /*!< IEEE 802.15.4 Energy Detect Level */ + __IO uint32_t CCACTRL; /*!< IEEE 802.15.4 Clear Channel Assessment Control */ + __I uint32_t RESERVED14[611]; + __IO uint32_t POWER; /*!< Peripheral power control */ +} NRF_RADIO_Type; + + +/* ================================================================================ */ +/* ================ UARTE ================ */ +/* ================================================================================ */ + + +/** + * @brief UART with EasyDMA 0 (UARTE) + */ + +typedef struct { /*!< UARTE Structure */ + __O uint32_t TASKS_STARTRX; /*!< Start UART receiver */ + __O uint32_t TASKS_STOPRX; /*!< Stop UART receiver */ + __O uint32_t TASKS_STARTTX; /*!< Start UART transmitter */ + __O uint32_t TASKS_STOPTX; /*!< Stop UART transmitter */ + __I uint32_t RESERVED0[7]; + __O uint32_t TASKS_FLUSHRX; /*!< Flush RX FIFO into RX buffer */ + __I uint32_t RESERVED1[52]; + __IO uint32_t EVENTS_CTS; /*!< CTS is activated (set low). Clear To Send. */ + __IO uint32_t EVENTS_NCTS; /*!< CTS is deactivated (set high). Not Clear To Send. */ + __IO uint32_t EVENTS_RXDRDY; /*!< Data received in RXD (but potentially not yet transferred to + Data RAM) */ + __I uint32_t RESERVED2; + __IO uint32_t EVENTS_ENDRX; /*!< Receive buffer is filled up */ + __I uint32_t RESERVED3[2]; + __IO uint32_t EVENTS_TXDRDY; /*!< Data sent from TXD */ + __IO uint32_t EVENTS_ENDTX; /*!< Last TX byte transmitted */ + __IO uint32_t EVENTS_ERROR; /*!< Error detected */ + __I uint32_t RESERVED4[7]; + __IO uint32_t EVENTS_RXTO; /*!< Receiver timeout */ + __I uint32_t RESERVED5; + __IO uint32_t EVENTS_RXSTARTED; /*!< UART receiver has started */ + __IO uint32_t EVENTS_TXSTARTED; /*!< UART transmitter has started */ + __I uint32_t RESERVED6; + __IO uint32_t EVENTS_TXSTOPPED; /*!< Transmitter stopped */ + __I uint32_t RESERVED7[41]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED8[63]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED9[93]; + __IO uint32_t ERRORSRC; /*!< Error source Note : this register is read / write one to clear. */ + __I uint32_t RESERVED10[31]; + __IO uint32_t ENABLE; /*!< Enable UART */ + __I uint32_t RESERVED11; + UARTE_PSEL_Type PSEL; /*!< Unspecified */ + __I uint32_t RESERVED12[3]; + __IO uint32_t BAUDRATE; /*!< Baud rate. Accuracy depends on the HFCLK source selected. */ + __I uint32_t RESERVED13[3]; + UARTE_RXD_Type RXD; /*!< RXD EasyDMA channel */ + __I uint32_t RESERVED14; + UARTE_TXD_Type TXD; /*!< TXD EasyDMA channel */ + __I uint32_t RESERVED15[7]; + __IO uint32_t CONFIG; /*!< Configuration of parity and hardware flow control */ +} NRF_UARTE_Type; + + +/* ================================================================================ */ +/* ================ UART ================ */ +/* ================================================================================ */ + + +/** + * @brief Universal Asynchronous Receiver/Transmitter (UART) + */ + +typedef struct { /*!< UART Structure */ + __O uint32_t TASKS_STARTRX; /*!< Start UART receiver */ + __O uint32_t TASKS_STOPRX; /*!< Stop UART receiver */ + __O uint32_t TASKS_STARTTX; /*!< Start UART transmitter */ + __O uint32_t TASKS_STOPTX; /*!< Stop UART transmitter */ + __I uint32_t RESERVED0[3]; + __O uint32_t TASKS_SUSPEND; /*!< Suspend UART */ + __I uint32_t RESERVED1[56]; + __IO uint32_t EVENTS_CTS; /*!< CTS is activated (set low). Clear To Send. */ + __IO uint32_t EVENTS_NCTS; /*!< CTS is deactivated (set high). Not Clear To Send. */ + __IO uint32_t EVENTS_RXDRDY; /*!< Data received in RXD */ + __I uint32_t RESERVED2[4]; + __IO uint32_t EVENTS_TXDRDY; /*!< Data sent from TXD */ + __I uint32_t RESERVED3; + __IO uint32_t EVENTS_ERROR; /*!< Error detected */ + __I uint32_t RESERVED4[7]; + __IO uint32_t EVENTS_RXTO; /*!< Receiver timeout */ + __I uint32_t RESERVED5[46]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED6[64]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED7[93]; + __IO uint32_t ERRORSRC; /*!< Error source */ + __I uint32_t RESERVED8[31]; + __IO uint32_t ENABLE; /*!< Enable UART */ + __I uint32_t RESERVED9; + UART_PSEL_Type PSEL; /*!< Unspecified */ + __I uint32_t RXD; /*!< RXD register */ + __O uint32_t TXD; /*!< TXD register */ + __I uint32_t RESERVED10; + __IO uint32_t BAUDRATE; /*!< Baud rate. Accuracy depends on the HFCLK source selected. */ + __I uint32_t RESERVED11[17]; + __IO uint32_t CONFIG; /*!< Configuration of parity and hardware flow control */ +} NRF_UART_Type; + + +/* ================================================================================ */ +/* ================ SPIM ================ */ +/* ================================================================================ */ + + +/** + * @brief Serial Peripheral Interface Master with EasyDMA 0 (SPIM) + */ + +typedef struct { /*!< SPIM Structure */ + __I uint32_t RESERVED0[4]; + __O uint32_t TASKS_START; /*!< Start SPI transaction */ + __O uint32_t TASKS_STOP; /*!< Stop SPI transaction */ + __I uint32_t RESERVED1; + __O uint32_t TASKS_SUSPEND; /*!< Suspend SPI transaction */ + __O uint32_t TASKS_RESUME; /*!< Resume SPI transaction */ + __I uint32_t RESERVED2[56]; + __IO uint32_t EVENTS_STOPPED; /*!< SPI transaction has stopped */ + __I uint32_t RESERVED3[2]; + __IO uint32_t EVENTS_ENDRX; /*!< End of RXD buffer reached */ + __I uint32_t RESERVED4; + __IO uint32_t EVENTS_END; /*!< End of RXD buffer and TXD buffer reached */ + __I uint32_t RESERVED5; + __IO uint32_t EVENTS_ENDTX; /*!< End of TXD buffer reached */ + __I uint32_t RESERVED6[10]; + __IO uint32_t EVENTS_STARTED; /*!< Transaction started */ + __I uint32_t RESERVED7[44]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED8[64]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED9[61]; + __IO uint32_t STALLSTAT; /*!< Stall status for EasyDMA RAM accesses. The fields in this register + is set to STALL by hardware whenever a stall occurres and can + be cleared (set to NOSTALL) by the CPU. */ + __I uint32_t RESERVED10[63]; + __IO uint32_t ENABLE; /*!< Enable SPIM */ + __I uint32_t RESERVED11; + SPIM_PSEL_Type PSEL; /*!< Unspecified */ + __I uint32_t RESERVED12[3]; + __IO uint32_t FREQUENCY; /*!< SPI frequency. Accuracy depends on the HFCLK source selected. */ + __I uint32_t RESERVED13[3]; + SPIM_RXD_Type RXD; /*!< RXD EasyDMA channel */ + SPIM_TXD_Type TXD; /*!< TXD EasyDMA channel */ + __IO uint32_t CONFIG; /*!< Configuration register */ + __I uint32_t RESERVED14[2]; + SPIM_IFTIMING_Type IFTIMING; /*!< Unspecified */ + __I uint32_t RESERVED15[22]; + __IO uint32_t ORC; /*!< Byte transmitted after TXD.MAXCNT bytes have been transmitted + in the case when RXD.MAXCNT is greater than TXD.MAXCNT */ +} NRF_SPIM_Type; + + +/* ================================================================================ */ +/* ================ SPIS ================ */ +/* ================================================================================ */ + + +/** + * @brief SPI Slave 0 (SPIS) + */ + +typedef struct { /*!< SPIS Structure */ + __I uint32_t RESERVED0[9]; + __O uint32_t TASKS_ACQUIRE; /*!< Acquire SPI semaphore */ + __O uint32_t TASKS_RELEASE; /*!< Release SPI semaphore, enabling the SPI slave to acquire it */ + __I uint32_t RESERVED1[54]; + __IO uint32_t EVENTS_END; /*!< Granted transaction completed */ + __I uint32_t RESERVED2[2]; + __IO uint32_t EVENTS_ENDRX; /*!< End of RXD buffer reached */ + __I uint32_t RESERVED3[5]; + __IO uint32_t EVENTS_ACQUIRED; /*!< Semaphore acquired */ + __I uint32_t RESERVED4[53]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED5[64]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED6[61]; + __I uint32_t SEMSTAT; /*!< Semaphore status register */ + __I uint32_t RESERVED7[15]; + __IO uint32_t STATUS; /*!< Status from last transaction */ + __I uint32_t RESERVED8[47]; + __IO uint32_t ENABLE; /*!< Enable SPI slave */ + __I uint32_t RESERVED9; + SPIS_PSEL_Type PSEL; /*!< Unspecified */ + __I uint32_t RESERVED10[7]; + SPIS_RXD_Type RXD; /*!< Unspecified */ + __I uint32_t RESERVED11; + SPIS_TXD_Type TXD; /*!< Unspecified */ + __I uint32_t RESERVED12; + __IO uint32_t CONFIG; /*!< Configuration register */ + __I uint32_t RESERVED13; + __IO uint32_t DEF; /*!< Default character. Character clocked out in case of an ignored + transaction. */ + __I uint32_t RESERVED14[24]; + __IO uint32_t ORC; /*!< Over-read character */ +} NRF_SPIS_Type; + + +/* ================================================================================ */ +/* ================ TWIM ================ */ +/* ================================================================================ */ + + +/** + * @brief I2C compatible Two-Wire Master Interface with EasyDMA 0 (TWIM) + */ + +typedef struct { /*!< TWIM Structure */ + __O uint32_t TASKS_STARTRX; /*!< Start TWI receive sequence */ + __I uint32_t RESERVED0; + __O uint32_t TASKS_STARTTX; /*!< Start TWI transmit sequence */ + __I uint32_t RESERVED1[2]; + __O uint32_t TASKS_STOP; /*!< Stop TWI transaction. Must be issued while the TWI master is + not suspended. */ + __I uint32_t RESERVED2; + __O uint32_t TASKS_SUSPEND; /*!< Suspend TWI transaction */ + __O uint32_t TASKS_RESUME; /*!< Resume TWI transaction */ + __I uint32_t RESERVED3[56]; + __IO uint32_t EVENTS_STOPPED; /*!< TWI stopped */ + __I uint32_t RESERVED4[7]; + __IO uint32_t EVENTS_ERROR; /*!< TWI error */ + __I uint32_t RESERVED5[8]; + __IO uint32_t EVENTS_SUSPENDED; /*!< Last byte has been sent out after the SUSPEND task has been + issued, TWI traffic is now suspended. */ + __IO uint32_t EVENTS_RXSTARTED; /*!< Receive sequence started */ + __IO uint32_t EVENTS_TXSTARTED; /*!< Transmit sequence started */ + __I uint32_t RESERVED6[2]; + __IO uint32_t EVENTS_LASTRX; /*!< Byte boundary, starting to receive the last byte */ + __IO uint32_t EVENTS_LASTTX; /*!< Byte boundary, starting to transmit the last byte */ + __I uint32_t RESERVED7[39]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED8[63]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED9[110]; + __IO uint32_t ERRORSRC; /*!< Error source */ + __I uint32_t RESERVED10[14]; + __IO uint32_t ENABLE; /*!< Enable TWIM */ + __I uint32_t RESERVED11; + TWIM_PSEL_Type PSEL; /*!< Unspecified */ + __I uint32_t RESERVED12[5]; + __IO uint32_t FREQUENCY; /*!< TWI frequency. Accuracy depends on the HFCLK source selected. */ + __I uint32_t RESERVED13[3]; + TWIM_RXD_Type RXD; /*!< RXD EasyDMA channel */ + TWIM_TXD_Type TXD; /*!< TXD EasyDMA channel */ + __I uint32_t RESERVED14[13]; + __IO uint32_t ADDRESS; /*!< Address used in the TWI transfer */ +} NRF_TWIM_Type; + + +/* ================================================================================ */ +/* ================ TWIS ================ */ +/* ================================================================================ */ + + +/** + * @brief I2C compatible Two-Wire Slave Interface with EasyDMA 0 (TWIS) + */ + +typedef struct { /*!< TWIS Structure */ + __I uint32_t RESERVED0[5]; + __O uint32_t TASKS_STOP; /*!< Stop TWI transaction */ + __I uint32_t RESERVED1; + __O uint32_t TASKS_SUSPEND; /*!< Suspend TWI transaction */ + __O uint32_t TASKS_RESUME; /*!< Resume TWI transaction */ + __I uint32_t RESERVED2[3]; + __O uint32_t TASKS_PREPARERX; /*!< Prepare the TWI slave to respond to a write command */ + __O uint32_t TASKS_PREPARETX; /*!< Prepare the TWI slave to respond to a read command */ + __I uint32_t RESERVED3[51]; + __IO uint32_t EVENTS_STOPPED; /*!< TWI stopped */ + __I uint32_t RESERVED4[7]; + __IO uint32_t EVENTS_ERROR; /*!< TWI error */ + __I uint32_t RESERVED5[9]; + __IO uint32_t EVENTS_RXSTARTED; /*!< Receive sequence started */ + __IO uint32_t EVENTS_TXSTARTED; /*!< Transmit sequence started */ + __I uint32_t RESERVED6[4]; + __IO uint32_t EVENTS_WRITE; /*!< Write command received */ + __IO uint32_t EVENTS_READ; /*!< Read command received */ + __I uint32_t RESERVED7[37]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED8[63]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED9[113]; + __IO uint32_t ERRORSRC; /*!< Error source */ + __I uint32_t MATCH; /*!< Status register indicating which address had a match */ + __I uint32_t RESERVED10[10]; + __IO uint32_t ENABLE; /*!< Enable TWIS */ + __I uint32_t RESERVED11; + TWIS_PSEL_Type PSEL; /*!< Unspecified */ + __I uint32_t RESERVED12[9]; + TWIS_RXD_Type RXD; /*!< RXD EasyDMA channel */ + __I uint32_t RESERVED13; + TWIS_TXD_Type TXD; /*!< TXD EasyDMA channel */ + __I uint32_t RESERVED14[14]; + __IO uint32_t ADDRESS[2]; /*!< Description collection[0]: TWI slave address 0 */ + __I uint32_t RESERVED15; + __IO uint32_t CONFIG; /*!< Configuration register for the address match mechanism */ + __I uint32_t RESERVED16[10]; + __IO uint32_t ORC; /*!< Over-read character. Character sent out in case of an over-read + of the transmit buffer. */ +} NRF_TWIS_Type; + + +/* ================================================================================ */ +/* ================ SPI ================ */ +/* ================================================================================ */ + + +/** + * @brief Serial Peripheral Interface 0 (SPI) + */ + +typedef struct { /*!< SPI Structure */ + __I uint32_t RESERVED0[66]; + __IO uint32_t EVENTS_READY; /*!< TXD byte sent and RXD byte received */ + __I uint32_t RESERVED1[126]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED2[125]; + __IO uint32_t ENABLE; /*!< Enable SPI */ + __I uint32_t RESERVED3; + SPI_PSEL_Type PSEL; /*!< Unspecified */ + __I uint32_t RESERVED4; + __I uint32_t RXD; /*!< RXD register */ + __IO uint32_t TXD; /*!< TXD register */ + __I uint32_t RESERVED5; + __IO uint32_t FREQUENCY; /*!< SPI frequency. Accuracy depends on the HFCLK source selected. */ + __I uint32_t RESERVED6[11]; + __IO uint32_t CONFIG; /*!< Configuration register */ +} NRF_SPI_Type; + + +/* ================================================================================ */ +/* ================ TWI ================ */ +/* ================================================================================ */ + + +/** + * @brief I2C compatible Two-Wire Interface 0 (TWI) + */ + +typedef struct { /*!< TWI Structure */ + __O uint32_t TASKS_STARTRX; /*!< Start TWI receive sequence */ + __I uint32_t RESERVED0; + __O uint32_t TASKS_STARTTX; /*!< Start TWI transmit sequence */ + __I uint32_t RESERVED1[2]; + __O uint32_t TASKS_STOP; /*!< Stop TWI transaction */ + __I uint32_t RESERVED2; + __O uint32_t TASKS_SUSPEND; /*!< Suspend TWI transaction */ + __O uint32_t TASKS_RESUME; /*!< Resume TWI transaction */ + __I uint32_t RESERVED3[56]; + __IO uint32_t EVENTS_STOPPED; /*!< TWI stopped */ + __IO uint32_t EVENTS_RXDREADY; /*!< TWI RXD byte received */ + __I uint32_t RESERVED4[4]; + __IO uint32_t EVENTS_TXDSENT; /*!< TWI TXD byte sent */ + __I uint32_t RESERVED5; + __IO uint32_t EVENTS_ERROR; /*!< TWI error */ + __I uint32_t RESERVED6[4]; + __IO uint32_t EVENTS_BB; /*!< TWI byte boundary, generated before each byte that is sent or + received */ + __I uint32_t RESERVED7[3]; + __IO uint32_t EVENTS_SUSPENDED; /*!< TWI entered the suspended state */ + __I uint32_t RESERVED8[45]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED9[64]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED10[110]; + __IO uint32_t ERRORSRC; /*!< Error source */ + __I uint32_t RESERVED11[14]; + __IO uint32_t ENABLE; /*!< Enable TWI */ + __I uint32_t RESERVED12; + TWI_PSEL_Type PSEL; /*!< Unspecified */ + __I uint32_t RESERVED13[2]; + __I uint32_t RXD; /*!< RXD register */ + __IO uint32_t TXD; /*!< TXD register */ + __I uint32_t RESERVED14; + __IO uint32_t FREQUENCY; /*!< TWI frequency. Accuracy depends on the HFCLK source selected. */ + __I uint32_t RESERVED15[24]; + __IO uint32_t ADDRESS; /*!< Address used in the TWI transfer */ +} NRF_TWI_Type; + + +/* ================================================================================ */ +/* ================ NFCT ================ */ +/* ================================================================================ */ + + +/** + * @brief NFC-A compatible radio (NFCT) + */ + +typedef struct { /*!< NFCT Structure */ + __O uint32_t TASKS_ACTIVATE; /*!< Activate NFCT peripheral for incoming and outgoing frames, change + state to activated */ + __O uint32_t TASKS_DISABLE; /*!< Disable NFCT peripheral */ + __O uint32_t TASKS_SENSE; /*!< Enable NFC sense field mode, change state to sense mode */ + __O uint32_t TASKS_STARTTX; /*!< Start transmission of an outgoing frame, change state to transmit */ + __I uint32_t RESERVED0[3]; + __O uint32_t TASKS_ENABLERXDATA; /*!< Initializes the EasyDMA for receive. */ + __I uint32_t RESERVED1; + __O uint32_t TASKS_GOIDLE; /*!< Force state machine to IDLE state */ + __O uint32_t TASKS_GOSLEEP; /*!< Force state machine to SLEEP_A state */ + __I uint32_t RESERVED2[53]; + __IO uint32_t EVENTS_READY; /*!< The NFCT peripheral is ready to receive and send frames */ + __IO uint32_t EVENTS_FIELDDETECTED; /*!< Remote NFC field detected */ + __IO uint32_t EVENTS_FIELDLOST; /*!< Remote NFC field lost */ + __IO uint32_t EVENTS_TXFRAMESTART; /*!< Marks the start of the first symbol of a transmitted frame */ + __IO uint32_t EVENTS_TXFRAMEEND; /*!< Marks the end of the last transmitted on-air symbol of a frame */ + __IO uint32_t EVENTS_RXFRAMESTART; /*!< Marks the end of the first symbol of a received frame */ + __IO uint32_t EVENTS_RXFRAMEEND; /*!< Received data has been checked (CRC, parity) and transferred + to RAM, and EasyDMA has ended accessing the RX buffer */ + __IO uint32_t EVENTS_ERROR; /*!< NFC error reported. The ERRORSTATUS register contains details + on the source of the error. */ + __I uint32_t RESERVED3[2]; + __IO uint32_t EVENTS_RXERROR; /*!< NFC RX frame error reported. The FRAMESTATUS.RX register contains + details on the source of the error. */ + __IO uint32_t EVENTS_ENDRX; /*!< RX buffer (as defined by PACKETPTR and MAXLEN) in Data RAM full. */ + __IO uint32_t EVENTS_ENDTX; /*!< Transmission of data in RAM has ended, and EasyDMA has ended + accessing the TX buffer */ + __I uint32_t RESERVED4; + __IO uint32_t EVENTS_AUTOCOLRESSTARTED; /*!< Auto collision resolution process has started */ + __I uint32_t RESERVED5[3]; + __IO uint32_t EVENTS_COLLISION; /*!< NFC auto collision resolution error reported. */ + __IO uint32_t EVENTS_SELECTED; /*!< NFC auto collision resolution successfully completed */ + __IO uint32_t EVENTS_STARTED; /*!< EasyDMA is ready to receive or send frames. */ + __I uint32_t RESERVED6[43]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED7[63]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED8[62]; + __IO uint32_t ERRORSTATUS; /*!< NFC Error Status register */ + __I uint32_t RESERVED9; + NFCT_FRAMESTATUS_Type FRAMESTATUS; /*!< Unspecified */ + __I uint32_t NFCTAGSTATE; /*!< NfcTag state register */ + __I uint32_t RESERVED10[10]; + __I uint32_t FIELDPRESENT; /*!< Indicates the presence or not of a valid field */ + __I uint32_t RESERVED11[49]; + __IO uint32_t FRAMEDELAYMIN; /*!< Minimum frame delay */ + __IO uint32_t FRAMEDELAYMAX; /*!< Maximum frame delay */ + __IO uint32_t FRAMEDELAYMODE; /*!< Configuration register for the Frame Delay Timer */ + __IO uint32_t PACKETPTR; /*!< Packet pointer for TXD and RXD data storage in Data RAM */ + __IO uint32_t MAXLEN; /*!< Size of the RAM buffer allocated to TXD and RXD data storage + each */ + NFCT_TXD_Type TXD; /*!< Unspecified */ + NFCT_RXD_Type RXD; /*!< Unspecified */ + __I uint32_t RESERVED12[26]; + __IO uint32_t NFCID1_LAST; /*!< Last NFCID1 part (4, 7 or 10 bytes ID) */ + __IO uint32_t NFCID1_2ND_LAST; /*!< Second last NFCID1 part (7 or 10 bytes ID) */ + __IO uint32_t NFCID1_3RD_LAST; /*!< Third last NFCID1 part (10 bytes ID) */ + __IO uint32_t AUTOCOLRESCONFIG; /*!< Controls the auto collision resolution function. This setting + must be done before the NFCT peripheral is enabled. */ + __IO uint32_t SENSRES; /*!< NFC-A SENS_RES auto-response settings */ + __IO uint32_t SELRES; /*!< NFC-A SEL_RES auto-response settings */ +} NRF_NFCT_Type; + + +/* ================================================================================ */ +/* ================ GPIOTE ================ */ +/* ================================================================================ */ + + +/** + * @brief GPIO Tasks and Events (GPIOTE) + */ + +typedef struct { /*!< GPIOTE Structure */ + __O uint32_t TASKS_OUT[8]; /*!< Description collection[0]: Task for writing to pin specified + in CONFIG[0].PSEL. Action on pin is configured in CONFIG[0].POLARITY. */ + __I uint32_t RESERVED0[4]; + __O uint32_t TASKS_SET[8]; /*!< Description collection[0]: Task for writing to pin specified + in CONFIG[0].PSEL. Action on pin is to set it high. */ + __I uint32_t RESERVED1[4]; + __O uint32_t TASKS_CLR[8]; /*!< Description collection[0]: Task for writing to pin specified + in CONFIG[0].PSEL. Action on pin is to set it low. */ + __I uint32_t RESERVED2[32]; + __IO uint32_t EVENTS_IN[8]; /*!< Description collection[0]: Event generated from pin specified + in CONFIG[0].PSEL */ + __I uint32_t RESERVED3[23]; + __IO uint32_t EVENTS_PORT; /*!< Event generated from multiple input GPIO pins with SENSE mechanism + enabled */ + __I uint32_t RESERVED4[97]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED5[129]; + __IO uint32_t CONFIG[8]; /*!< Description collection[0]: Configuration for OUT[n], SET[n] + and CLR[n] tasks and IN[n] event */ +} NRF_GPIOTE_Type; + + +/* ================================================================================ */ +/* ================ SAADC ================ */ +/* ================================================================================ */ + + +/** + * @brief Analog to Digital Converter (SAADC) + */ + +typedef struct { /*!< SAADC Structure */ + __O uint32_t TASKS_START; /*!< Start the ADC and prepare the result buffer in RAM */ + __O uint32_t TASKS_SAMPLE; /*!< Take one ADC sample, if scan is enabled all channels are sampled */ + __O uint32_t TASKS_STOP; /*!< Stop the ADC and terminate any on-going conversion */ + __O uint32_t TASKS_CALIBRATEOFFSET; /*!< Starts offset auto-calibration */ + __I uint32_t RESERVED0[60]; + __IO uint32_t EVENTS_STARTED; /*!< The ADC has started */ + __IO uint32_t EVENTS_END; /*!< The ADC has filled up the Result buffer */ + __IO uint32_t EVENTS_DONE; /*!< A conversion task has been completed. Depending on the mode, + multiple conversions might be needed for a result to be transferred + to RAM. */ + __IO uint32_t EVENTS_RESULTDONE; /*!< A result is ready to get transferred to RAM. */ + __IO uint32_t EVENTS_CALIBRATEDONE; /*!< Calibration is complete */ + __IO uint32_t EVENTS_STOPPED; /*!< The ADC has stopped */ + SAADC_EVENTS_CH_Type EVENTS_CH[8]; /*!< Unspecified */ + __I uint32_t RESERVED1[106]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED2[61]; + __I uint32_t STATUS; /*!< Status */ + __I uint32_t RESERVED3[63]; + __IO uint32_t ENABLE; /*!< Enable or disable ADC */ + __I uint32_t RESERVED4[3]; + SAADC_CH_Type CH[8]; /*!< Unspecified */ + __I uint32_t RESERVED5[24]; + __IO uint32_t RESOLUTION; /*!< Resolution configuration */ + __IO uint32_t OVERSAMPLE; /*!< Oversampling configuration. OVERSAMPLE should not be combined + with SCAN. The RESOLUTION is applied before averaging, thus + for high OVERSAMPLE a higher RESOLUTION should be used. */ + __IO uint32_t SAMPLERATE; /*!< Controls normal or continuous sample rate */ + __I uint32_t RESERVED6[12]; + SAADC_RESULT_Type RESULT; /*!< RESULT EasyDMA channel */ +} NRF_SAADC_Type; + + +/* ================================================================================ */ +/* ================ TIMER ================ */ +/* ================================================================================ */ + + +/** + * @brief Timer/Counter 0 (TIMER) + */ + +typedef struct { /*!< TIMER Structure */ + __O uint32_t TASKS_START; /*!< Start Timer */ + __O uint32_t TASKS_STOP; /*!< Stop Timer */ + __O uint32_t TASKS_COUNT; /*!< Increment Timer (Counter mode only) */ + __O uint32_t TASKS_CLEAR; /*!< Clear time */ + __O uint32_t TASKS_SHUTDOWN; /*!< Deprecated register - Shut down timer */ + __I uint32_t RESERVED0[11]; + __O uint32_t TASKS_CAPTURE[6]; /*!< Description collection[0]: Capture Timer value to CC[0] register */ + __I uint32_t RESERVED1[58]; + __IO uint32_t EVENTS_COMPARE[6]; /*!< Description collection[0]: Compare event on CC[0] match */ + __I uint32_t RESERVED2[42]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED3[64]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED4[61]; + __I uint32_t STATUS; /*!< Timer status */ + __I uint32_t RESERVED5[64]; + __IO uint32_t MODE; /*!< Timer mode selection */ + __IO uint32_t BITMODE; /*!< Configure the number of bits used by the TIMER */ + __I uint32_t RESERVED6; + __IO uint32_t PRESCALER; /*!< Timer prescaler register */ + __I uint32_t RESERVED7[11]; + __IO uint32_t CC[6]; /*!< Description collection[0]: Capture/Compare register 0 */ +} NRF_TIMER_Type; + + +/* ================================================================================ */ +/* ================ RTC ================ */ +/* ================================================================================ */ + + +/** + * @brief Real time counter 0 (RTC) + */ + +typedef struct { /*!< RTC Structure */ + __O uint32_t TASKS_START; /*!< Start RTC COUNTER */ + __O uint32_t TASKS_STOP; /*!< Stop RTC COUNTER */ + __O uint32_t TASKS_CLEAR; /*!< Clear RTC COUNTER */ + __O uint32_t TASKS_TRIGOVRFLW; /*!< Set COUNTER to 0xFFFFF0 */ + __I uint32_t RESERVED0[60]; + __IO uint32_t EVENTS_TICK; /*!< Event on COUNTER increment */ + __IO uint32_t EVENTS_OVRFLW; /*!< Event on COUNTER overflow */ + __I uint32_t RESERVED1[14]; + __IO uint32_t EVENTS_COMPARE[4]; /*!< Description collection[0]: Compare event on CC[0] match */ + __I uint32_t RESERVED2[109]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED3[13]; + __IO uint32_t EVTEN; /*!< Enable or disable event routing */ + __IO uint32_t EVTENSET; /*!< Enable event routing */ + __IO uint32_t EVTENCLR; /*!< Disable event routing */ + __I uint32_t RESERVED4[110]; + __I uint32_t COUNTER; /*!< Current COUNTER value */ + __IO uint32_t PRESCALER; /*!< 12 bit prescaler for COUNTER frequency (32768/(PRESCALER+1)).Must + be written when RTC is stopped */ + __I uint32_t RESERVED5[13]; + __IO uint32_t CC[4]; /*!< Description collection[0]: Compare register 0 */ +} NRF_RTC_Type; + + +/* ================================================================================ */ +/* ================ TEMP ================ */ +/* ================================================================================ */ + + +/** + * @brief Temperature Sensor (TEMP) + */ + +typedef struct { /*!< TEMP Structure */ + __O uint32_t TASKS_START; /*!< Start temperature measurement */ + __O uint32_t TASKS_STOP; /*!< Stop temperature measurement */ + __I uint32_t RESERVED0[62]; + __IO uint32_t EVENTS_DATARDY; /*!< Temperature measurement complete, data ready */ + __I uint32_t RESERVED1[128]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED2[127]; + __I int32_t TEMP; /*!< Temperature in degC (0.25deg steps) */ + __I uint32_t RESERVED3[5]; + __IO uint32_t A0; /*!< Slope of 1st piece wise linear function */ + __IO uint32_t A1; /*!< Slope of 2nd piece wise linear function */ + __IO uint32_t A2; /*!< Slope of 3rd piece wise linear function */ + __IO uint32_t A3; /*!< Slope of 4th piece wise linear function */ + __IO uint32_t A4; /*!< Slope of 5th piece wise linear function */ + __IO uint32_t A5; /*!< Slope of 6th piece wise linear function */ + __I uint32_t RESERVED4[2]; + __IO uint32_t B0; /*!< y-intercept of 1st piece wise linear function */ + __IO uint32_t B1; /*!< y-intercept of 2nd piece wise linear function */ + __IO uint32_t B2; /*!< y-intercept of 3rd piece wise linear function */ + __IO uint32_t B3; /*!< y-intercept of 4th piece wise linear function */ + __IO uint32_t B4; /*!< y-intercept of 5th piece wise linear function */ + __IO uint32_t B5; /*!< y-intercept of 6th piece wise linear function */ + __I uint32_t RESERVED5[2]; + __IO uint32_t T0; /*!< End point of 1st piece wise linear function */ + __IO uint32_t T1; /*!< End point of 2nd piece wise linear function */ + __IO uint32_t T2; /*!< End point of 3rd piece wise linear function */ + __IO uint32_t T3; /*!< End point of 4th piece wise linear function */ + __IO uint32_t T4; /*!< End point of 5th piece wise linear function */ +} NRF_TEMP_Type; + + +/* ================================================================================ */ +/* ================ RNG ================ */ +/* ================================================================================ */ + + +/** + * @brief Random Number Generator (RNG) + */ + +typedef struct { /*!< RNG Structure */ + __O uint32_t TASKS_START; /*!< Task starting the random number generator */ + __O uint32_t TASKS_STOP; /*!< Task stopping the random number generator */ + __I uint32_t RESERVED0[62]; + __IO uint32_t EVENTS_VALRDY; /*!< Event being generated for every new random number written to + the VALUE register */ + __I uint32_t RESERVED1[63]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED2[64]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED3[126]; + __IO uint32_t CONFIG; /*!< Configuration register */ + __I uint32_t VALUE; /*!< Output random number */ +} NRF_RNG_Type; + + +/* ================================================================================ */ +/* ================ ECB ================ */ +/* ================================================================================ */ + + +/** + * @brief AES ECB Mode Encryption (ECB) + */ + +typedef struct { /*!< ECB Structure */ + __O uint32_t TASKS_STARTECB; /*!< Start ECB block encrypt */ + __O uint32_t TASKS_STOPECB; /*!< Abort a possible executing ECB operation */ + __I uint32_t RESERVED0[62]; + __IO uint32_t EVENTS_ENDECB; /*!< ECB block encrypt complete */ + __IO uint32_t EVENTS_ERRORECB; /*!< ECB block encrypt aborted because of a STOPECB task or due to + an error */ + __I uint32_t RESERVED1[127]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED2[126]; + __IO uint32_t ECBDATAPTR; /*!< ECB block encrypt memory pointers */ +} NRF_ECB_Type; + + +/* ================================================================================ */ +/* ================ CCM ================ */ +/* ================================================================================ */ + + +/** + * @brief AES CCM Mode Encryption (CCM) + */ + +typedef struct { /*!< CCM Structure */ + __O uint32_t TASKS_KSGEN; /*!< Start generation of key-stream. This operation will stop by + itself when completed. */ + __O uint32_t TASKS_CRYPT; /*!< Start encryption/decryption. This operation will stop by itself + when completed. */ + __O uint32_t TASKS_STOP; /*!< Stop encryption/decryption */ + __O uint32_t TASKS_RATEOVERRIDE; /*!< Override DATARATE setting in MODE register with the contents + of the RATEOVERRIDE register for any ongoing encryption/decryption */ + __I uint32_t RESERVED0[60]; + __IO uint32_t EVENTS_ENDKSGEN; /*!< Key-stream generation complete */ + __IO uint32_t EVENTS_ENDCRYPT; /*!< Encrypt/decrypt complete */ + __IO uint32_t EVENTS_ERROR; /*!< Deprecated register - CCM error event */ + __I uint32_t RESERVED1[61]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED2[64]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED3[61]; + __I uint32_t MICSTATUS; /*!< MIC check result */ + __I uint32_t RESERVED4[63]; + __IO uint32_t ENABLE; /*!< Enable */ + __IO uint32_t MODE; /*!< Operation mode */ + __IO uint32_t CNFPTR; /*!< Pointer to data structure holding AES key and NONCE vector */ + __IO uint32_t INPTR; /*!< Input pointer */ + __IO uint32_t OUTPTR; /*!< Output pointer */ + __IO uint32_t SCRATCHPTR; /*!< Pointer to data area used for temporary storage */ + __IO uint32_t MAXPACKETSIZE; /*!< Length of key-stream generated when MODE.LENGTH = Extended. */ + __IO uint32_t RATEOVERRIDE; /*!< Data rate override setting. */ +} NRF_CCM_Type; + + +/* ================================================================================ */ +/* ================ AAR ================ */ +/* ================================================================================ */ + + +/** + * @brief Accelerated Address Resolver (AAR) + */ + +typedef struct { /*!< AAR Structure */ + __O uint32_t TASKS_START; /*!< Start resolving addresses based on IRKs specified in the IRK + data structure */ + __I uint32_t RESERVED0; + __O uint32_t TASKS_STOP; /*!< Stop resolving addresses */ + __I uint32_t RESERVED1[61]; + __IO uint32_t EVENTS_END; /*!< Address resolution procedure complete */ + __IO uint32_t EVENTS_RESOLVED; /*!< Address resolved */ + __IO uint32_t EVENTS_NOTRESOLVED; /*!< Address not resolved */ + __I uint32_t RESERVED2[126]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED3[61]; + __I uint32_t STATUS; /*!< Resolution status */ + __I uint32_t RESERVED4[63]; + __IO uint32_t ENABLE; /*!< Enable AAR */ + __IO uint32_t NIRK; /*!< Number of IRKs */ + __IO uint32_t IRKPTR; /*!< Pointer to IRK data structure */ + __I uint32_t RESERVED5; + __IO uint32_t ADDRPTR; /*!< Pointer to the resolvable address */ + __IO uint32_t SCRATCHPTR; /*!< Pointer to data area used for temporary storage */ +} NRF_AAR_Type; + + +/* ================================================================================ */ +/* ================ WDT ================ */ +/* ================================================================================ */ + + +/** + * @brief Watchdog Timer (WDT) + */ + +typedef struct { /*!< WDT Structure */ + __O uint32_t TASKS_START; /*!< Start the watchdog */ + __I uint32_t RESERVED0[63]; + __IO uint32_t EVENTS_TIMEOUT; /*!< Watchdog timeout */ + __I uint32_t RESERVED1[128]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED2[61]; + __I uint32_t RUNSTATUS; /*!< Run status */ + __I uint32_t REQSTATUS; /*!< Request status */ + __I uint32_t RESERVED3[63]; + __IO uint32_t CRV; /*!< Counter reload value */ + __IO uint32_t RREN; /*!< Enable register for reload request registers */ + __IO uint32_t CONFIG; /*!< Configuration register */ + __I uint32_t RESERVED4[60]; + __O uint32_t RR[8]; /*!< Description collection[0]: Reload request 0 */ +} NRF_WDT_Type; + + +/* ================================================================================ */ +/* ================ QDEC ================ */ +/* ================================================================================ */ + + +/** + * @brief Quadrature Decoder (QDEC) + */ + +typedef struct { /*!< QDEC Structure */ + __O uint32_t TASKS_START; /*!< Task starting the quadrature decoder */ + __O uint32_t TASKS_STOP; /*!< Task stopping the quadrature decoder */ + __O uint32_t TASKS_READCLRACC; /*!< Read and clear ACC and ACCDBL */ + __O uint32_t TASKS_RDCLRACC; /*!< Read and clear ACC */ + __O uint32_t TASKS_RDCLRDBL; /*!< Read and clear ACCDBL */ + __I uint32_t RESERVED0[59]; + __IO uint32_t EVENTS_SAMPLERDY; /*!< Event being generated for every new sample value written to + the SAMPLE register */ + __IO uint32_t EVENTS_REPORTRDY; /*!< Non-null report ready */ + __IO uint32_t EVENTS_ACCOF; /*!< ACC or ACCDBL register overflow */ + __IO uint32_t EVENTS_DBLRDY; /*!< Double displacement(s) detected */ + __IO uint32_t EVENTS_STOPPED; /*!< QDEC has been stopped */ + __I uint32_t RESERVED1[59]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED2[64]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED3[125]; + __IO uint32_t ENABLE; /*!< Enable the quadrature decoder */ + __IO uint32_t LEDPOL; /*!< LED output pin polarity */ + __IO uint32_t SAMPLEPER; /*!< Sample period */ + __I int32_t SAMPLE; /*!< Motion sample value */ + __IO uint32_t REPORTPER; /*!< Number of samples to be taken before REPORTRDY and DBLRDY events + can be generated */ + __I int32_t ACC; /*!< Register accumulating the valid transitions */ + __I int32_t ACCREAD; /*!< Snapshot of the ACC register, updated by the READCLRACC or RDCLRACC + task */ + QDEC_PSEL_Type PSEL; /*!< Unspecified */ + __IO uint32_t DBFEN; /*!< Enable input debounce filters */ + __I uint32_t RESERVED4[5]; + __IO uint32_t LEDPRE; /*!< Time period the LED is switched ON prior to sampling */ + __I uint32_t ACCDBL; /*!< Register accumulating the number of detected double transitions */ + __I uint32_t ACCDBLREAD; /*!< Snapshot of the ACCDBL, updated by the READCLRACC or RDCLRDBL + task */ +} NRF_QDEC_Type; + + +/* ================================================================================ */ +/* ================ COMP ================ */ +/* ================================================================================ */ + + +/** + * @brief Comparator (COMP) + */ + +typedef struct { /*!< COMP Structure */ + __O uint32_t TASKS_START; /*!< Start comparator */ + __O uint32_t TASKS_STOP; /*!< Stop comparator */ + __O uint32_t TASKS_SAMPLE; /*!< Sample comparator value */ + __I uint32_t RESERVED0[61]; + __IO uint32_t EVENTS_READY; /*!< COMP is ready and output is valid */ + __IO uint32_t EVENTS_DOWN; /*!< Downward crossing */ + __IO uint32_t EVENTS_UP; /*!< Upward crossing */ + __IO uint32_t EVENTS_CROSS; /*!< Downward or upward crossing */ + __I uint32_t RESERVED1[60]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED2[63]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED3[61]; + __I uint32_t RESULT; /*!< Compare result */ + __I uint32_t RESERVED4[63]; + __IO uint32_t ENABLE; /*!< COMP enable */ + __IO uint32_t PSEL; /*!< Pin select */ + __IO uint32_t REFSEL; /*!< Reference source select */ + __IO uint32_t EXTREFSEL; /*!< External reference select */ + __I uint32_t RESERVED5[8]; + __IO uint32_t TH; /*!< Threshold configuration for hysteresis unit */ + __IO uint32_t MODE; /*!< Mode configuration */ + __IO uint32_t HYST; /*!< Comparator hysteresis enable */ + __IO uint32_t ISOURCE; /*!< Current source select on analog input */ +} NRF_COMP_Type; + + +/* ================================================================================ */ +/* ================ LPCOMP ================ */ +/* ================================================================================ */ + + +/** + * @brief Low Power Comparator (LPCOMP) + */ + +typedef struct { /*!< LPCOMP Structure */ + __O uint32_t TASKS_START; /*!< Start comparator */ + __O uint32_t TASKS_STOP; /*!< Stop comparator */ + __O uint32_t TASKS_SAMPLE; /*!< Sample comparator value */ + __I uint32_t RESERVED0[61]; + __IO uint32_t EVENTS_READY; /*!< LPCOMP is ready and output is valid */ + __IO uint32_t EVENTS_DOWN; /*!< Downward crossing */ + __IO uint32_t EVENTS_UP; /*!< Upward crossing */ + __IO uint32_t EVENTS_CROSS; /*!< Downward or upward crossing */ + __I uint32_t RESERVED1[60]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED2[64]; + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED3[61]; + __I uint32_t RESULT; /*!< Compare result */ + __I uint32_t RESERVED4[63]; + __IO uint32_t ENABLE; /*!< Enable LPCOMP */ + __IO uint32_t PSEL; /*!< Input pin select */ + __IO uint32_t REFSEL; /*!< Reference select */ + __IO uint32_t EXTREFSEL; /*!< External reference select */ + __I uint32_t RESERVED5[4]; + __IO uint32_t ANADETECT; /*!< Analog detect configuration */ + __I uint32_t RESERVED6[5]; + __IO uint32_t HYST; /*!< Comparator hysteresis enable */ +} NRF_LPCOMP_Type; + + +/* ================================================================================ */ +/* ================ SWI ================ */ +/* ================================================================================ */ + + +/** + * @brief Software interrupt 0 (SWI) + */ + +typedef struct { /*!< SWI Structure */ + __I uint32_t UNUSED; /*!< Unused. */ +} NRF_SWI_Type; + + +/* ================================================================================ */ +/* ================ EGU ================ */ +/* ================================================================================ */ + + +/** + * @brief Event Generator Unit 0 (EGU) + */ + +typedef struct { /*!< EGU Structure */ + __O uint32_t TASKS_TRIGGER[16]; /*!< Description collection[0]: Trigger 0 for triggering the corresponding + TRIGGERED[0] event */ + __I uint32_t RESERVED0[48]; + __IO uint32_t EVENTS_TRIGGERED[16]; /*!< Description collection[0]: Event number 0 generated by triggering + the corresponding TRIGGER[0] task */ + __I uint32_t RESERVED1[112]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ +} NRF_EGU_Type; + + +/* ================================================================================ */ +/* ================ PWM ================ */ +/* ================================================================================ */ + + +/** + * @brief Pulse Width Modulation Unit 0 (PWM) + */ + +typedef struct { /*!< PWM Structure */ + __I uint32_t RESERVED0; + __O uint32_t TASKS_STOP; /*!< Stops PWM pulse generation on all channels at the end of current + PWM period, and stops sequence playback */ + __O uint32_t TASKS_SEQSTART[2]; /*!< Description collection[0]: Loads the first PWM value on all + enabled channels from sequence 0, and starts playing that sequence + at the rate defined in SEQ[0]REFRESH and/or DECODER.MODE. Causes + PWM generation to start it was not running. */ + __O uint32_t TASKS_NEXTSTEP; /*!< Steps by one value in the current sequence on all enabled channels + if DECODER.MODE=NextStep. Does not cause PWM generation to start + it was not running. */ + __I uint32_t RESERVED1[60]; + __IO uint32_t EVENTS_STOPPED; /*!< Response to STOP task, emitted when PWM pulses are no longer + generated */ + __IO uint32_t EVENTS_SEQSTARTED[2]; /*!< Description collection[0]: First PWM period started on sequence + 0 */ + __IO uint32_t EVENTS_SEQEND[2]; /*!< Description collection[0]: Emitted at end of every sequence + 0, when last value from RAM has been applied to wave counter */ + __IO uint32_t EVENTS_PWMPERIODEND; /*!< Emitted at the end of each PWM period */ + __IO uint32_t EVENTS_LOOPSDONE; /*!< Concatenated sequences have been played the amount of times + defined in LOOP.CNT */ + __I uint32_t RESERVED2[56]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED3[63]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED4[125]; + __IO uint32_t ENABLE; /*!< PWM module enable register */ + __IO uint32_t MODE; /*!< Selects operating mode of the wave counter */ + __IO uint32_t COUNTERTOP; /*!< Value up to which the pulse generator counter counts */ + __IO uint32_t PRESCALER; /*!< Configuration for PWM_CLK */ + __IO uint32_t DECODER; /*!< Configuration of the decoder */ + __IO uint32_t LOOP; /*!< Amount of playback of a loop */ + __I uint32_t RESERVED5[2]; + PWM_SEQ_Type SEQ[2]; /*!< Unspecified */ + PWM_PSEL_Type PSEL; /*!< Unspecified */ +} NRF_PWM_Type; + + +/* ================================================================================ */ +/* ================ PDM ================ */ +/* ================================================================================ */ + + +/** + * @brief Pulse Density Modulation (Digital Microphone) Interface (PDM) + */ + +typedef struct { /*!< PDM Structure */ + __O uint32_t TASKS_START; /*!< Starts continuous PDM transfer */ + __O uint32_t TASKS_STOP; /*!< Stops PDM transfer */ + __I uint32_t RESERVED0[62]; + __IO uint32_t EVENTS_STARTED; /*!< PDM transfer has started */ + __IO uint32_t EVENTS_STOPPED; /*!< PDM transfer has finished */ + __IO uint32_t EVENTS_END; /*!< The PDM has written the last sample specified by SAMPLE.MAXCNT + (or the last sample after a STOP task has been received) to + Data RAM */ + __I uint32_t RESERVED1[125]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED2[125]; + __IO uint32_t ENABLE; /*!< PDM module enable register */ + __IO uint32_t PDMCLKCTRL; /*!< PDM clock generator control */ + __IO uint32_t MODE; /*!< Defines the routing of the connected PDM microphones' signals */ + __I uint32_t RESERVED3[3]; + __IO uint32_t GAINL; /*!< Left output gain adjustment */ + __IO uint32_t GAINR; /*!< Right output gain adjustment */ + __IO uint32_t RATIO; /*!< Selects the ratio between PDM_CLK and output sample rate. Change + PDMCLKCTRL accordingly. */ + __I uint32_t RESERVED4[7]; + PDM_PSEL_Type PSEL; /*!< Unspecified */ + __I uint32_t RESERVED5[6]; + PDM_SAMPLE_Type SAMPLE; /*!< Unspecified */ +} NRF_PDM_Type; + + +/* ================================================================================ */ +/* ================ NVMC ================ */ +/* ================================================================================ */ + + +/** + * @brief Non Volatile Memory Controller (NVMC) + */ + +typedef struct { /*!< NVMC Structure */ + __I uint32_t RESERVED0[256]; + __I uint32_t READY; /*!< Ready flag */ + __I uint32_t RESERVED1[64]; + __IO uint32_t CONFIG; /*!< Configuration register */ + + union { + __IO uint32_t ERASEPCR1; /*!< Deprecated register - Register for erasing a page in code area. + Equivalent to ERASEPAGE. */ + __IO uint32_t ERASEPAGE; /*!< Register for erasing a page in code area */ + }; + __IO uint32_t ERASEALL; /*!< Register for erasing all non-volatile user memory */ + __IO uint32_t ERASEPCR0; /*!< Deprecated register - Register for erasing a page in code area. + Equivalent to ERASEPAGE. */ + __IO uint32_t ERASEUICR; /*!< Register for erasing user information configuration registers */ + __I uint32_t RESERVED2[10]; + __IO uint32_t ICACHECNF; /*!< I-code cache configuration register. */ + __I uint32_t RESERVED3; + __IO uint32_t IHIT; /*!< I-code cache hit counter. */ + __IO uint32_t IMISS; /*!< I-code cache miss counter. */ +} NRF_NVMC_Type; + + +/* ================================================================================ */ +/* ================ ACL ================ */ +/* ================================================================================ */ + + +/** + * @brief Access control lists (ACL) + */ + +typedef struct { /*!< ACL Structure */ + __I uint32_t RESERVED0[449]; + __IO uint32_t DISABLEINDEBUG; /*!< Disable all ACL protection mechanisms for regions while in debug + mode */ + __I uint32_t RESERVED1[62]; + ACL_ACL_Type ACL[8]; /*!< Unspecified */ +} NRF_ACL_Type; + + +/* ================================================================================ */ +/* ================ PPI ================ */ +/* ================================================================================ */ + + +/** + * @brief Programmable Peripheral Interconnect (PPI) + */ + +typedef struct { /*!< PPI Structure */ + PPI_TASKS_CHG_Type TASKS_CHG[6]; /*!< Channel group tasks */ + __I uint32_t RESERVED0[308]; + __IO uint32_t CHEN; /*!< Channel enable register */ + __IO uint32_t CHENSET; /*!< Channel enable set register */ + __IO uint32_t CHENCLR; /*!< Channel enable clear register */ + __I uint32_t RESERVED1; + PPI_CH_Type CH[20]; /*!< PPI Channel */ + __I uint32_t RESERVED2[148]; + __IO uint32_t CHG[6]; /*!< Description collection[0]: Channel group 0 */ + __I uint32_t RESERVED3[62]; + PPI_FORK_Type FORK[32]; /*!< Fork */ +} NRF_PPI_Type; + + +/* ================================================================================ */ +/* ================ MWU ================ */ +/* ================================================================================ */ + + +/** + * @brief Memory Watch Unit (MWU) + */ + +typedef struct { /*!< MWU Structure */ + __I uint32_t RESERVED0[64]; + MWU_EVENTS_REGION_Type EVENTS_REGION[4]; /*!< Unspecified */ + __I uint32_t RESERVED1[16]; + MWU_EVENTS_PREGION_Type EVENTS_PREGION[2]; /*!< Unspecified */ + __I uint32_t RESERVED2[100]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED3[5]; + __IO uint32_t NMIEN; /*!< Enable or disable non-maskable interrupt */ + __IO uint32_t NMIENSET; /*!< Enable non-maskable interrupt */ + __IO uint32_t NMIENCLR; /*!< Disable non-maskable interrupt */ + __I uint32_t RESERVED4[53]; + MWU_PERREGION_Type PERREGION[2]; /*!< Unspecified */ + __I uint32_t RESERVED5[64]; + __IO uint32_t REGIONEN; /*!< Enable/disable regions watch */ + __IO uint32_t REGIONENSET; /*!< Enable regions watch */ + __IO uint32_t REGIONENCLR; /*!< Disable regions watch */ + __I uint32_t RESERVED6[57]; + MWU_REGION_Type REGION[4]; /*!< Unspecified */ + __I uint32_t RESERVED7[32]; + MWU_PREGION_Type PREGION[2]; /*!< Unspecified */ +} NRF_MWU_Type; + + +/* ================================================================================ */ +/* ================ I2S ================ */ +/* ================================================================================ */ + + +/** + * @brief Inter-IC Sound (I2S) + */ + +typedef struct { /*!< I2S Structure */ + __O uint32_t TASKS_START; /*!< Starts continuous I2S transfer. Also starts MCK generator when + this is enabled. */ + __O uint32_t TASKS_STOP; /*!< Stops I2S transfer. Also stops MCK generator. Triggering this + task will cause the {event:STOPPED} event to be generated. */ + __I uint32_t RESERVED0[63]; + __IO uint32_t EVENTS_RXPTRUPD; /*!< The RXD.PTR register has been copied to internal double-buffers. + When the I2S module is started and RX is enabled, this event + will be generated for every RXTXD.MAXCNT words that are received + on the SDIN pin. */ + __IO uint32_t EVENTS_STOPPED; /*!< I2S transfer stopped. */ + __I uint32_t RESERVED1[2]; + __IO uint32_t EVENTS_TXPTRUPD; /*!< The TDX.PTR register has been copied to internal double-buffers. + When the I2S module is started and TX is enabled, this event + will be generated for every RXTXD.MAXCNT words that are sent + on the SDOUT pin. */ + __I uint32_t RESERVED2[122]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED3[125]; + __IO uint32_t ENABLE; /*!< Enable I2S module. */ + I2S_CONFIG_Type CONFIG; /*!< Unspecified */ + __I uint32_t RESERVED4[3]; + I2S_RXD_Type RXD; /*!< Unspecified */ + __I uint32_t RESERVED5; + I2S_TXD_Type TXD; /*!< Unspecified */ + __I uint32_t RESERVED6[3]; + I2S_RXTXD_Type RXTXD; /*!< Unspecified */ + __I uint32_t RESERVED7[3]; + I2S_PSEL_Type PSEL; /*!< Unspecified */ +} NRF_I2S_Type; + + +/* ================================================================================ */ +/* ================ FPU ================ */ +/* ================================================================================ */ + + +/** + * @brief FPU (FPU) + */ + +typedef struct { /*!< FPU Structure */ + __I uint32_t UNUSED; /*!< Unused. */ +} NRF_FPU_Type; + + +/* ================================================================================ */ +/* ================ USBD ================ */ +/* ================================================================================ */ + + +/** + * @brief Universal Serial Bus device (USBD) + */ + +typedef struct { /*!< USBD Structure */ + __I uint32_t RESERVED0; + __O uint32_t TASKS_STARTEPIN[8]; /*!< Description collection[0]: Captures the EPIN[0].PTR, EPIN[0].MAXCNT + and EPIN[0].CONFIG registers values, and enables endpoint IN + 0 to respond to traffic from host */ + __O uint32_t TASKS_STARTISOIN; /*!< Captures the ISOIN.PTR, ISOIN.MAXCNT and ISOIN.CONFIG registers + values, and enables sending data on iso endpoint */ + __O uint32_t TASKS_STARTEPOUT[8]; /*!< Description collection[0]: Captures the EPOUT[0].PTR, EPOUT[0].MAXCNT + and EPOUT[0].CONFIG registers values, and enables endpoint 0 + to respond to traffic from host */ + __O uint32_t TASKS_STARTISOOUT; /*!< Captures the ISOOUT.PTR, ISOOUT.MAXCNT and ISOOUT.CONFIG registers + values, and enables receiving of data on iso endpoint */ + __O uint32_t TASKS_EP0RCVOUT; /*!< Allows OUT data stage on control endpoint 0 */ + __O uint32_t TASKS_EP0STATUS; /*!< Allows status stage on control endpoint 0 */ + __O uint32_t TASKS_EP0STALL; /*!< STALLs data and status stage on control endpoint 0 */ + __O uint32_t TASKS_DPDMDRIVE; /*!< Forces D+ and D-lines to the state defined in the DPDMVALUE + register */ + __O uint32_t TASKS_DPDMNODRIVE; /*!< Stops forcing D+ and D- lines to any state (USB engine takes + control) */ + __I uint32_t RESERVED1[40]; + __IO uint32_t EVENTS_USBRESET; /*!< Signals that a USB reset condition has been detected on the + USB lines */ + __IO uint32_t EVENTS_STARTED; /*!< Confirms that the EPIN[n].PTR, EPIN[n].MAXCNT, EPIN[n].CONFIG, + or EPOUT[n].PTR, EPOUT[n].MAXCNT and EPOUT[n].CONFIG registers + have been captured on all endpoints reported in the EPSTATUS + register */ + __IO uint32_t EVENTS_ENDEPIN[8]; /*!< Description collection[0]: The whole EPIN[0] buffer has been + consumed. The RAM buffer can be accessed safely by software. */ + __IO uint32_t EVENTS_EP0DATADONE; /*!< An acknowledged data transfer has taken place on the control + endpoint */ + __IO uint32_t EVENTS_ENDISOIN; /*!< The whole ISOIN buffer has been consumed. The RAM buffer can + be accessed safely by software. */ + __IO uint32_t EVENTS_ENDEPOUT[8]; /*!< Description collection[0]: The whole EPOUT[0] buffer has been + consumed. The RAM buffer can be accessed safely by software. */ + __IO uint32_t EVENTS_ENDISOOUT; /*!< The whole ISOOUT buffer has been consumed. The RAM buffer can + be accessed safely by software. */ + __IO uint32_t EVENTS_SOF; /*!< Signals that a SOF (start of frame) condition has been detected + on the USB lines */ + __IO uint32_t EVENTS_USBEVENT; /*!< An event or an error not covered by specific events has occurred, + check EVENTCAUSE register to find the cause */ + __IO uint32_t EVENTS_EP0SETUP; /*!< A valid SETUP token has been received (and acknowledged) on + the control endpoint */ + __IO uint32_t EVENTS_EPDATA; /*!< A data transfer has occurred on a data endpoint, indicated by + the EPDATASTATUS register */ + __IO uint32_t EVENTS_ACCESSFAULT; /*!< Access to an unavailable USB register has been attempted (software + or EasyDMA). This event can get fired even when USBD is not + ENABLEd. */ + __I uint32_t RESERVED2[38]; + __IO uint32_t SHORTS; /*!< Shortcut register */ + __I uint32_t RESERVED3[63]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED4[61]; + __IO uint32_t EVENTCAUSE; /*!< Details on event that caused the USBEVENT event */ + __I uint32_t BUSSTATE; /*!< Provides the logic state of the D+ and D- lines */ + __I uint32_t RESERVED5[6]; + USBD_HALTED_Type HALTED; /*!< Unspecified */ + __I uint32_t RESERVED6; + __IO uint32_t EPSTATUS; /*!< Provides information on which endpoint's EasyDMA registers have + been captured */ + __IO uint32_t EPDATASTATUS; /*!< Provides information on which endpoint(s) an acknowledged data + transfer has occurred (EPDATA event) */ + __I uint32_t USBADDR; /*!< Device USB address */ + __I uint32_t RESERVED7[3]; + __I uint32_t BMREQUESTTYPE; /*!< SETUP data, byte 0, bmRequestType */ + __I uint32_t BREQUEST; /*!< SETUP data, byte 1, bRequest */ + __I uint32_t WVALUEL; /*!< SETUP data, byte 2, LSB of wValue */ + __I uint32_t WVALUEH; /*!< SETUP data, byte 3, MSB of wValue */ + __I uint32_t WINDEXL; /*!< SETUP data, byte 4, LSB of wIndex */ + __I uint32_t WINDEXH; /*!< SETUP data, byte 5, MSB of wIndex */ + __I uint32_t WLENGTHL; /*!< SETUP data, byte 6, LSB of wLength */ + __I uint32_t WLENGTHH; /*!< SETUP data, byte 7, MSB of wLength */ + USBD_SIZE_Type SIZE; /*!< Unspecified */ + __I uint32_t RESERVED8[15]; + __IO uint32_t ENABLE; /*!< Enable USB */ + __IO uint32_t USBPULLUP; /*!< Control of the USB pull-up */ + __IO uint32_t DPDMVALUE; /*!< State at which the DPDMDRIVE task will force D+ and D-. The + DPDMNODRIVE task reverts the control of the lines to MAC IP + (no forcing). */ + __IO uint32_t DTOGGLE; /*!< Data toggle control and status. */ + __IO uint32_t EPINEN; /*!< Endpoint IN enable */ + __IO uint32_t EPOUTEN; /*!< Endpoint OUT enable */ + __O uint32_t EPSTALL; /*!< STALL endpoints */ + __IO uint32_t ISOSPLIT; /*!< Controls the split of ISO buffers */ + __I uint32_t FRAMECNTR; /*!< Returns the current value of the start of frame counter */ + __I uint32_t RESERVED9[3]; + __IO uint32_t ISOINCONFIG; /*!< Controls the response of the ISO IN endpoint to an IN token + when no data is ready to be sent */ + __I uint32_t RESERVED10[51]; + USBD_EPIN_Type EPIN[8]; /*!< Unspecified */ + USBD_ISOIN_Type ISOIN; /*!< Unspecified */ + __I uint32_t RESERVED11[21]; + USBD_EPOUT_Type EPOUT[8]; /*!< Unspecified */ + USBD_ISOOUT_Type ISOOUT; /*!< Unspecified */ +} NRF_USBD_Type; + + +/* ================================================================================ */ +/* ================ QSPI ================ */ +/* ================================================================================ */ + + +/** + * @brief External flash interface (QSPI) + */ + +typedef struct { /*!< QSPI Structure */ + __O uint32_t TASKS_ACTIVATE; /*!< Activate QSPI interface */ + __O uint32_t TASKS_READSTART; /*!< Start transfer from external flash memory to internal RAM */ + __O uint32_t TASKS_WRITESTART; /*!< Start transfer from internal RAM to external flash memory */ + __O uint32_t TASKS_ERASESTART; /*!< Start external flash memory erase operation */ + __I uint32_t RESERVED0[60]; + __IO uint32_t EVENTS_READY; /*!< QSPI peripheral is ready. This event will be generated as a + response to any QSPI task. */ + __I uint32_t RESERVED1[127]; + __IO uint32_t INTEN; /*!< Enable or disable interrupt */ + __IO uint32_t INTENSET; /*!< Enable interrupt */ + __IO uint32_t INTENCLR; /*!< Disable interrupt */ + __I uint32_t RESERVED2[125]; + __IO uint32_t ENABLE; /*!< Enable QSPI peripheral and acquire the pins selected in PSELn + registers */ + QSPI_READ_Type READ; /*!< Unspecified */ + QSPI_WRITE_Type WRITE; /*!< Unspecified */ + QSPI_ERASE_Type ERASE; /*!< Unspecified */ + QSPI_PSEL_Type PSEL; /*!< Unspecified */ + __IO uint32_t XIPOFFSET; /*!< Address offset into the external memory for Execute in Place + operation. */ + __IO uint32_t IFCONFIG0; /*!< Interface configuration. */ + __I uint32_t RESERVED3[46]; + __IO uint32_t IFCONFIG1; /*!< Interface configuration. */ + __I uint32_t STATUS; /*!< Status register. */ + __I uint32_t RESERVED4[3]; + __IO uint32_t DPMDUR; /*!< Set the duration required to enter/exit deep power-down mode + (DPM). */ + __I uint32_t RESERVED5[3]; + __IO uint32_t ADDRCONF; /*!< Extended address configuration. */ + __I uint32_t RESERVED6[3]; + __IO uint32_t CINSTRCONF; /*!< Custom instruction configuration register. */ + __IO uint32_t CINSTRDAT0; /*!< Custom instruction data register 0. */ + __IO uint32_t CINSTRDAT1; /*!< Custom instruction data register 1. */ + __IO uint32_t IFTIMING; /*!< SPI interface timing. */ +} NRF_QSPI_Type; + + +/* ================================================================================ */ +/* ================ GPIO ================ */ +/* ================================================================================ */ + + +/** + * @brief GPIO Port 1 (GPIO) + */ + +typedef struct { /*!< GPIO Structure */ + __I uint32_t RESERVED0[321]; + __IO uint32_t OUT; /*!< Write GPIO port */ + __IO uint32_t OUTSET; /*!< Set individual bits in GPIO port */ + __IO uint32_t OUTCLR; /*!< Clear individual bits in GPIO port */ + __I uint32_t IN; /*!< Read GPIO port */ + __IO uint32_t DIR; /*!< Direction of GPIO pins */ + __IO uint32_t DIRSET; /*!< DIR set register */ + __IO uint32_t DIRCLR; /*!< DIR clear register */ + __IO uint32_t LATCH; /*!< Latch register indicating what GPIO pins that have met the criteria + set in the PIN_CNF[n].SENSE registers */ + __IO uint32_t DETECTMODE; /*!< Select between default DETECT signal behaviour and LDETECT mode */ + __I uint32_t RESERVED1[118]; + __IO uint32_t PIN_CNF[32]; /*!< Description collection[0]: Configuration of GPIO pins */ +} NRF_GPIO_Type; + + +/* ================================================================================ */ +/* ================ CRYPTOCELL ================ */ +/* ================================================================================ */ + + +/** + * @brief ARM CryptoCell register interface (CRYPTOCELL) + */ + +typedef struct { /*!< CRYPTOCELL Structure */ + __I uint32_t RESERVED0[320]; + __IO uint32_t ENABLE; /*!< Control power and clock for ARM CryptoCell subsystem */ +} NRF_CRYPTOCELL_Type; + + +/* -------------------- End of section using anonymous unions ------------------- */ +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + /* leave anonymous unions enabled */ +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#elif defined(__TMS470__) + /* anonymous unions are enabled by default */ +#elif defined(__TASKING__) + #pragma warning restore +#else + #warning Not supported compiler type +#endif + + + + +/* ================================================================================ */ +/* ================ Peripheral memory map ================ */ +/* ================================================================================ */ + +#define NRF_FICR_BASE 0x10000000UL +#define NRF_UICR_BASE 0x10001000UL +#define NRF_POWER_BASE 0x40000000UL +#define NRF_CLOCK_BASE 0x40000000UL +#define NRF_RADIO_BASE 0x40001000UL +#define NRF_UARTE0_BASE 0x40002000UL +#define NRF_UART0_BASE 0x40002000UL +#define NRF_SPIM0_BASE 0x40003000UL +#define NRF_SPIS0_BASE 0x40003000UL +#define NRF_TWIM0_BASE 0x40003000UL +#define NRF_TWIS0_BASE 0x40003000UL +#define NRF_SPI0_BASE 0x40003000UL +#define NRF_TWI0_BASE 0x40003000UL +#define NRF_SPIM1_BASE 0x40004000UL +#define NRF_SPIS1_BASE 0x40004000UL +#define NRF_TWIM1_BASE 0x40004000UL +#define NRF_TWIS1_BASE 0x40004000UL +#define NRF_SPI1_BASE 0x40004000UL +#define NRF_TWI1_BASE 0x40004000UL +#define NRF_NFCT_BASE 0x40005000UL +#define NRF_GPIOTE_BASE 0x40006000UL +#define NRF_SAADC_BASE 0x40007000UL +#define NRF_TIMER0_BASE 0x40008000UL +#define NRF_TIMER1_BASE 0x40009000UL +#define NRF_TIMER2_BASE 0x4000A000UL +#define NRF_RTC0_BASE 0x4000B000UL +#define NRF_TEMP_BASE 0x4000C000UL +#define NRF_RNG_BASE 0x4000D000UL +#define NRF_ECB_BASE 0x4000E000UL +#define NRF_CCM_BASE 0x4000F000UL +#define NRF_AAR_BASE 0x4000F000UL +#define NRF_WDT_BASE 0x40010000UL +#define NRF_RTC1_BASE 0x40011000UL +#define NRF_QDEC_BASE 0x40012000UL +#define NRF_COMP_BASE 0x40013000UL +#define NRF_LPCOMP_BASE 0x40013000UL +#define NRF_SWI0_BASE 0x40014000UL +#define NRF_EGU0_BASE 0x40014000UL +#define NRF_SWI1_BASE 0x40015000UL +#define NRF_EGU1_BASE 0x40015000UL +#define NRF_SWI2_BASE 0x40016000UL +#define NRF_EGU2_BASE 0x40016000UL +#define NRF_SWI3_BASE 0x40017000UL +#define NRF_EGU3_BASE 0x40017000UL +#define NRF_SWI4_BASE 0x40018000UL +#define NRF_EGU4_BASE 0x40018000UL +#define NRF_SWI5_BASE 0x40019000UL +#define NRF_EGU5_BASE 0x40019000UL +#define NRF_TIMER3_BASE 0x4001A000UL +#define NRF_TIMER4_BASE 0x4001B000UL +#define NRF_PWM0_BASE 0x4001C000UL +#define NRF_PDM_BASE 0x4001D000UL +#define NRF_NVMC_BASE 0x4001E000UL +#define NRF_ACL_BASE 0x4001E000UL +#define NRF_PPI_BASE 0x4001F000UL +#define NRF_MWU_BASE 0x40020000UL +#define NRF_PWM1_BASE 0x40021000UL +#define NRF_PWM2_BASE 0x40022000UL +#define NRF_SPIM2_BASE 0x40023000UL +#define NRF_SPIS2_BASE 0x40023000UL +#define NRF_SPI2_BASE 0x40023000UL +#define NRF_RTC2_BASE 0x40024000UL +#define NRF_I2S_BASE 0x40025000UL +#define NRF_FPU_BASE 0x40026000UL +#define NRF_USBD_BASE 0x40027000UL +#define NRF_UARTE1_BASE 0x40028000UL +#define NRF_QSPI_BASE 0x40029000UL +#define NRF_SPIM3_BASE 0x4002B000UL +#define NRF_PWM3_BASE 0x4002D000UL +#define NRF_P0_BASE 0x50000000UL +#define NRF_P1_BASE 0x50000300UL +#define NRF_CRYPTOCELL_BASE 0x5002A000UL + + +/* ================================================================================ */ +/* ================ Peripheral declaration ================ */ +/* ================================================================================ */ + +#define NRF_FICR ((NRF_FICR_Type *) NRF_FICR_BASE) +#define NRF_UICR ((NRF_UICR_Type *) NRF_UICR_BASE) +#define NRF_POWER ((NRF_POWER_Type *) NRF_POWER_BASE) +#define NRF_CLOCK ((NRF_CLOCK_Type *) NRF_CLOCK_BASE) +#define NRF_RADIO ((NRF_RADIO_Type *) NRF_RADIO_BASE) +#define NRF_UARTE0 ((NRF_UARTE_Type *) NRF_UARTE0_BASE) +#define NRF_UART0 ((NRF_UART_Type *) NRF_UART0_BASE) +#define NRF_SPIM0 ((NRF_SPIM_Type *) NRF_SPIM0_BASE) +#define NRF_SPIS0 ((NRF_SPIS_Type *) NRF_SPIS0_BASE) +#define NRF_TWIM0 ((NRF_TWIM_Type *) NRF_TWIM0_BASE) +#define NRF_TWIS0 ((NRF_TWIS_Type *) NRF_TWIS0_BASE) +#define NRF_SPI0 ((NRF_SPI_Type *) NRF_SPI0_BASE) +#define NRF_TWI0 ((NRF_TWI_Type *) NRF_TWI0_BASE) +#define NRF_SPIM1 ((NRF_SPIM_Type *) NRF_SPIM1_BASE) +#define NRF_SPIS1 ((NRF_SPIS_Type *) NRF_SPIS1_BASE) +#define NRF_TWIM1 ((NRF_TWIM_Type *) NRF_TWIM1_BASE) +#define NRF_TWIS1 ((NRF_TWIS_Type *) NRF_TWIS1_BASE) +#define NRF_SPI1 ((NRF_SPI_Type *) NRF_SPI1_BASE) +#define NRF_TWI1 ((NRF_TWI_Type *) NRF_TWI1_BASE) +#define NRF_NFCT ((NRF_NFCT_Type *) NRF_NFCT_BASE) +#define NRF_GPIOTE ((NRF_GPIOTE_Type *) NRF_GPIOTE_BASE) +#define NRF_SAADC ((NRF_SAADC_Type *) NRF_SAADC_BASE) +#define NRF_TIMER0 ((NRF_TIMER_Type *) NRF_TIMER0_BASE) +#define NRF_TIMER1 ((NRF_TIMER_Type *) NRF_TIMER1_BASE) +#define NRF_TIMER2 ((NRF_TIMER_Type *) NRF_TIMER2_BASE) +#define NRF_RTC0 ((NRF_RTC_Type *) NRF_RTC0_BASE) +#define NRF_TEMP ((NRF_TEMP_Type *) NRF_TEMP_BASE) +#define NRF_RNG ((NRF_RNG_Type *) NRF_RNG_BASE) +#define NRF_ECB ((NRF_ECB_Type *) NRF_ECB_BASE) +#define NRF_CCM ((NRF_CCM_Type *) NRF_CCM_BASE) +#define NRF_AAR ((NRF_AAR_Type *) NRF_AAR_BASE) +#define NRF_WDT ((NRF_WDT_Type *) NRF_WDT_BASE) +#define NRF_RTC1 ((NRF_RTC_Type *) NRF_RTC1_BASE) +#define NRF_QDEC ((NRF_QDEC_Type *) NRF_QDEC_BASE) +#define NRF_COMP ((NRF_COMP_Type *) NRF_COMP_BASE) +#define NRF_LPCOMP ((NRF_LPCOMP_Type *) NRF_LPCOMP_BASE) +#define NRF_SWI0 ((NRF_SWI_Type *) NRF_SWI0_BASE) +#define NRF_EGU0 ((NRF_EGU_Type *) NRF_EGU0_BASE) +#define NRF_SWI1 ((NRF_SWI_Type *) NRF_SWI1_BASE) +#define NRF_EGU1 ((NRF_EGU_Type *) NRF_EGU1_BASE) +#define NRF_SWI2 ((NRF_SWI_Type *) NRF_SWI2_BASE) +#define NRF_EGU2 ((NRF_EGU_Type *) NRF_EGU2_BASE) +#define NRF_SWI3 ((NRF_SWI_Type *) NRF_SWI3_BASE) +#define NRF_EGU3 ((NRF_EGU_Type *) NRF_EGU3_BASE) +#define NRF_SWI4 ((NRF_SWI_Type *) NRF_SWI4_BASE) +#define NRF_EGU4 ((NRF_EGU_Type *) NRF_EGU4_BASE) +#define NRF_SWI5 ((NRF_SWI_Type *) NRF_SWI5_BASE) +#define NRF_EGU5 ((NRF_EGU_Type *) NRF_EGU5_BASE) +#define NRF_TIMER3 ((NRF_TIMER_Type *) NRF_TIMER3_BASE) +#define NRF_TIMER4 ((NRF_TIMER_Type *) NRF_TIMER4_BASE) +#define NRF_PWM0 ((NRF_PWM_Type *) NRF_PWM0_BASE) +#define NRF_PDM ((NRF_PDM_Type *) NRF_PDM_BASE) +#define NRF_NVMC ((NRF_NVMC_Type *) NRF_NVMC_BASE) +#define NRF_ACL ((NRF_ACL_Type *) NRF_ACL_BASE) +#define NRF_PPI ((NRF_PPI_Type *) NRF_PPI_BASE) +#define NRF_MWU ((NRF_MWU_Type *) NRF_MWU_BASE) +#define NRF_PWM1 ((NRF_PWM_Type *) NRF_PWM1_BASE) +#define NRF_PWM2 ((NRF_PWM_Type *) NRF_PWM2_BASE) +#define NRF_SPIM2 ((NRF_SPIM_Type *) NRF_SPIM2_BASE) +#define NRF_SPIS2 ((NRF_SPIS_Type *) NRF_SPIS2_BASE) +#define NRF_SPI2 ((NRF_SPI_Type *) NRF_SPI2_BASE) +#define NRF_RTC2 ((NRF_RTC_Type *) NRF_RTC2_BASE) +#define NRF_I2S ((NRF_I2S_Type *) NRF_I2S_BASE) +#define NRF_FPU ((NRF_FPU_Type *) NRF_FPU_BASE) +#define NRF_USBD ((NRF_USBD_Type *) NRF_USBD_BASE) +#define NRF_UARTE1 ((NRF_UARTE_Type *) NRF_UARTE1_BASE) +#define NRF_QSPI ((NRF_QSPI_Type *) NRF_QSPI_BASE) +#define NRF_SPIM3 ((NRF_SPIM_Type *) NRF_SPIM3_BASE) +#define NRF_PWM3 ((NRF_PWM_Type *) NRF_PWM3_BASE) +#define NRF_P0 ((NRF_GPIO_Type *) NRF_P0_BASE) +#define NRF_P1 ((NRF_GPIO_Type *) NRF_P1_BASE) +#define NRF_CRYPTOCELL ((NRF_CRYPTOCELL_Type *) NRF_CRYPTOCELL_BASE) + + +/** @} */ /* End of group Device_Peripheral_Registers */ +/** @} */ /* End of group nrf52840 */ +/** @} */ /* End of group Nordic Semiconductor */ + +#ifdef __cplusplus +} +#endif + + +#endif /* nrf52840_H */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52840_bitfields.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52840_bitfields.h new file mode 100644 index 0000000000000000000000000000000000000000..ab28d14ed9aca0c68db135de57a1e981d080510c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52840_bitfields.h @@ -0,0 +1,14656 @@ +/* + +Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + +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, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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 Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + +*/ + +#ifndef __NRF52840_BITS_H +#define __NRF52840_BITS_H + +/*lint ++flb "Enter library region" */ + +/* Peripheral: AAR */ +/* Description: Accelerated Address Resolver */ + +/* Register: AAR_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 2 : Write '1' to Enable interrupt for NOTRESOLVED event */ +#define AAR_INTENSET_NOTRESOLVED_Pos (2UL) /*!< Position of NOTRESOLVED field. */ +#define AAR_INTENSET_NOTRESOLVED_Msk (0x1UL << AAR_INTENSET_NOTRESOLVED_Pos) /*!< Bit mask of NOTRESOLVED field. */ +#define AAR_INTENSET_NOTRESOLVED_Disabled (0UL) /*!< Read: Disabled */ +#define AAR_INTENSET_NOTRESOLVED_Enabled (1UL) /*!< Read: Enabled */ +#define AAR_INTENSET_NOTRESOLVED_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for RESOLVED event */ +#define AAR_INTENSET_RESOLVED_Pos (1UL) /*!< Position of RESOLVED field. */ +#define AAR_INTENSET_RESOLVED_Msk (0x1UL << AAR_INTENSET_RESOLVED_Pos) /*!< Bit mask of RESOLVED field. */ +#define AAR_INTENSET_RESOLVED_Disabled (0UL) /*!< Read: Disabled */ +#define AAR_INTENSET_RESOLVED_Enabled (1UL) /*!< Read: Enabled */ +#define AAR_INTENSET_RESOLVED_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for END event */ +#define AAR_INTENSET_END_Pos (0UL) /*!< Position of END field. */ +#define AAR_INTENSET_END_Msk (0x1UL << AAR_INTENSET_END_Pos) /*!< Bit mask of END field. */ +#define AAR_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ +#define AAR_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ +#define AAR_INTENSET_END_Set (1UL) /*!< Enable */ + +/* Register: AAR_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 2 : Write '1' to Disable interrupt for NOTRESOLVED event */ +#define AAR_INTENCLR_NOTRESOLVED_Pos (2UL) /*!< Position of NOTRESOLVED field. */ +#define AAR_INTENCLR_NOTRESOLVED_Msk (0x1UL << AAR_INTENCLR_NOTRESOLVED_Pos) /*!< Bit mask of NOTRESOLVED field. */ +#define AAR_INTENCLR_NOTRESOLVED_Disabled (0UL) /*!< Read: Disabled */ +#define AAR_INTENCLR_NOTRESOLVED_Enabled (1UL) /*!< Read: Enabled */ +#define AAR_INTENCLR_NOTRESOLVED_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for RESOLVED event */ +#define AAR_INTENCLR_RESOLVED_Pos (1UL) /*!< Position of RESOLVED field. */ +#define AAR_INTENCLR_RESOLVED_Msk (0x1UL << AAR_INTENCLR_RESOLVED_Pos) /*!< Bit mask of RESOLVED field. */ +#define AAR_INTENCLR_RESOLVED_Disabled (0UL) /*!< Read: Disabled */ +#define AAR_INTENCLR_RESOLVED_Enabled (1UL) /*!< Read: Enabled */ +#define AAR_INTENCLR_RESOLVED_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for END event */ +#define AAR_INTENCLR_END_Pos (0UL) /*!< Position of END field. */ +#define AAR_INTENCLR_END_Msk (0x1UL << AAR_INTENCLR_END_Pos) /*!< Bit mask of END field. */ +#define AAR_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ +#define AAR_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ +#define AAR_INTENCLR_END_Clear (1UL) /*!< Disable */ + +/* Register: AAR_STATUS */ +/* Description: Resolution status */ + +/* Bits 3..0 : The IRK that was used last time an address was resolved */ +#define AAR_STATUS_STATUS_Pos (0UL) /*!< Position of STATUS field. */ +#define AAR_STATUS_STATUS_Msk (0xFUL << AAR_STATUS_STATUS_Pos) /*!< Bit mask of STATUS field. */ + +/* Register: AAR_ENABLE */ +/* Description: Enable AAR */ + +/* Bits 1..0 : Enable or disable AAR */ +#define AAR_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define AAR_ENABLE_ENABLE_Msk (0x3UL << AAR_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define AAR_ENABLE_ENABLE_Disabled (0UL) /*!< Disable */ +#define AAR_ENABLE_ENABLE_Enabled (3UL) /*!< Enable */ + +/* Register: AAR_NIRK */ +/* Description: Number of IRKs */ + +/* Bits 4..0 : Number of Identity root keys available in the IRK data structure */ +#define AAR_NIRK_NIRK_Pos (0UL) /*!< Position of NIRK field. */ +#define AAR_NIRK_NIRK_Msk (0x1FUL << AAR_NIRK_NIRK_Pos) /*!< Bit mask of NIRK field. */ + +/* Register: AAR_IRKPTR */ +/* Description: Pointer to IRK data structure */ + +/* Bits 31..0 : Pointer to the IRK data structure */ +#define AAR_IRKPTR_IRKPTR_Pos (0UL) /*!< Position of IRKPTR field. */ +#define AAR_IRKPTR_IRKPTR_Msk (0xFFFFFFFFUL << AAR_IRKPTR_IRKPTR_Pos) /*!< Bit mask of IRKPTR field. */ + +/* Register: AAR_ADDRPTR */ +/* Description: Pointer to the resolvable address */ + +/* Bits 31..0 : Pointer to the resolvable address (6-bytes) */ +#define AAR_ADDRPTR_ADDRPTR_Pos (0UL) /*!< Position of ADDRPTR field. */ +#define AAR_ADDRPTR_ADDRPTR_Msk (0xFFFFFFFFUL << AAR_ADDRPTR_ADDRPTR_Pos) /*!< Bit mask of ADDRPTR field. */ + +/* Register: AAR_SCRATCHPTR */ +/* Description: Pointer to data area used for temporary storage */ + +/* Bits 31..0 : Pointer to a scratch data area used for temporary storage during resolution.A space of minimum 3 bytes must be reserved. */ +#define AAR_SCRATCHPTR_SCRATCHPTR_Pos (0UL) /*!< Position of SCRATCHPTR field. */ +#define AAR_SCRATCHPTR_SCRATCHPTR_Msk (0xFFFFFFFFUL << AAR_SCRATCHPTR_SCRATCHPTR_Pos) /*!< Bit mask of SCRATCHPTR field. */ + + +/* Peripheral: ACL */ +/* Description: Access control lists */ + +/* Register: ACL_DISABLEINDEBUG */ +/* Description: Disable all ACL protection mechanisms for regions while in debug mode */ + +/* Bit 0 : Disable the protection mechanism for regions while in debug mode. */ +#define ACL_DISABLEINDEBUG_DISABLEINDEBUG_Pos (0UL) /*!< Position of DISABLEINDEBUG field. */ +#define ACL_DISABLEINDEBUG_DISABLEINDEBUG_Msk (0x1UL << ACL_DISABLEINDEBUG_DISABLEINDEBUG_Pos) /*!< Bit mask of DISABLEINDEBUG field. */ +#define ACL_DISABLEINDEBUG_DISABLEINDEBUG_Enabled (0UL) /*!< ACL is enabled in debug mode */ +#define ACL_DISABLEINDEBUG_DISABLEINDEBUG_Disabled (1UL) /*!< ACL is disabled in debug mode */ + +/* Register: ACL_ACL_ADDR */ +/* Description: Description cluster[0]: Configure the word-aligned start address of region 0 to protect */ + +/* Bits 31..0 : Valid word-aligned start address of region 0 to protect. Address must point to a flash page boundary. */ +#define ACL_ACL_ADDR_ADDR_Pos (0UL) /*!< Position of ADDR field. */ +#define ACL_ACL_ADDR_ADDR_Msk (0xFFFFFFFFUL << ACL_ACL_ADDR_ADDR_Pos) /*!< Bit mask of ADDR field. */ + +/* Register: ACL_ACL_SIZE */ +/* Description: Description cluster[0]: Size of region to protect counting from address ACL[0].ADDR. Write '0' as no effect. */ + +/* Bits 31..0 : Size of flash region 0 in bytes. Must be a multiple of the flash page size. */ +#define ACL_ACL_SIZE_SIZE_Pos (0UL) /*!< Position of SIZE field. */ +#define ACL_ACL_SIZE_SIZE_Msk (0xFFFFFFFFUL << ACL_ACL_SIZE_SIZE_Pos) /*!< Bit mask of SIZE field. */ + +/* Register: ACL_ACL_PERM */ +/* Description: Description cluster[0]: Access permissions for region 0 as defined by start address ACL[0].ADDR and size ACL[0].SIZE */ + +/* Bit 2 : Configure read permissions for region 0. Write '0' has no effect. */ +#define ACL_ACL_PERM_READ_Pos (2UL) /*!< Position of READ field. */ +#define ACL_ACL_PERM_READ_Msk (0x1UL << ACL_ACL_PERM_READ_Pos) /*!< Bit mask of READ field. */ +#define ACL_ACL_PERM_READ_Enable (0UL) /*!< Allow read instructions to region 0 */ +#define ACL_ACL_PERM_READ_Disable (1UL) /*!< Block read instructions to region 0 */ + +/* Bit 1 : Configure write and erase permissions for region 0. Write '0' has no effect. */ +#define ACL_ACL_PERM_WRITE_Pos (1UL) /*!< Position of WRITE field. */ +#define ACL_ACL_PERM_WRITE_Msk (0x1UL << ACL_ACL_PERM_WRITE_Pos) /*!< Bit mask of WRITE field. */ +#define ACL_ACL_PERM_WRITE_Enable (0UL) /*!< Allow write and erase instructions to region 0 */ +#define ACL_ACL_PERM_WRITE_Disable (1UL) /*!< Block write and erase instructions to region 0 */ + + +/* Peripheral: CCM */ +/* Description: AES CCM Mode Encryption */ + +/* Register: CCM_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 0 : Shortcut between ENDKSGEN event and CRYPT task */ +#define CCM_SHORTS_ENDKSGEN_CRYPT_Pos (0UL) /*!< Position of ENDKSGEN_CRYPT field. */ +#define CCM_SHORTS_ENDKSGEN_CRYPT_Msk (0x1UL << CCM_SHORTS_ENDKSGEN_CRYPT_Pos) /*!< Bit mask of ENDKSGEN_CRYPT field. */ +#define CCM_SHORTS_ENDKSGEN_CRYPT_Disabled (0UL) /*!< Disable shortcut */ +#define CCM_SHORTS_ENDKSGEN_CRYPT_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: CCM_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 2 : Write '1' to Enable interrupt for ERROR event */ +#define CCM_INTENSET_ERROR_Pos (2UL) /*!< Position of ERROR field. */ +#define CCM_INTENSET_ERROR_Msk (0x1UL << CCM_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define CCM_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define CCM_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define CCM_INTENSET_ERROR_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for ENDCRYPT event */ +#define CCM_INTENSET_ENDCRYPT_Pos (1UL) /*!< Position of ENDCRYPT field. */ +#define CCM_INTENSET_ENDCRYPT_Msk (0x1UL << CCM_INTENSET_ENDCRYPT_Pos) /*!< Bit mask of ENDCRYPT field. */ +#define CCM_INTENSET_ENDCRYPT_Disabled (0UL) /*!< Read: Disabled */ +#define CCM_INTENSET_ENDCRYPT_Enabled (1UL) /*!< Read: Enabled */ +#define CCM_INTENSET_ENDCRYPT_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for ENDKSGEN event */ +#define CCM_INTENSET_ENDKSGEN_Pos (0UL) /*!< Position of ENDKSGEN field. */ +#define CCM_INTENSET_ENDKSGEN_Msk (0x1UL << CCM_INTENSET_ENDKSGEN_Pos) /*!< Bit mask of ENDKSGEN field. */ +#define CCM_INTENSET_ENDKSGEN_Disabled (0UL) /*!< Read: Disabled */ +#define CCM_INTENSET_ENDKSGEN_Enabled (1UL) /*!< Read: Enabled */ +#define CCM_INTENSET_ENDKSGEN_Set (1UL) /*!< Enable */ + +/* Register: CCM_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 2 : Write '1' to Disable interrupt for ERROR event */ +#define CCM_INTENCLR_ERROR_Pos (2UL) /*!< Position of ERROR field. */ +#define CCM_INTENCLR_ERROR_Msk (0x1UL << CCM_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define CCM_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define CCM_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define CCM_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for ENDCRYPT event */ +#define CCM_INTENCLR_ENDCRYPT_Pos (1UL) /*!< Position of ENDCRYPT field. */ +#define CCM_INTENCLR_ENDCRYPT_Msk (0x1UL << CCM_INTENCLR_ENDCRYPT_Pos) /*!< Bit mask of ENDCRYPT field. */ +#define CCM_INTENCLR_ENDCRYPT_Disabled (0UL) /*!< Read: Disabled */ +#define CCM_INTENCLR_ENDCRYPT_Enabled (1UL) /*!< Read: Enabled */ +#define CCM_INTENCLR_ENDCRYPT_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for ENDKSGEN event */ +#define CCM_INTENCLR_ENDKSGEN_Pos (0UL) /*!< Position of ENDKSGEN field. */ +#define CCM_INTENCLR_ENDKSGEN_Msk (0x1UL << CCM_INTENCLR_ENDKSGEN_Pos) /*!< Bit mask of ENDKSGEN field. */ +#define CCM_INTENCLR_ENDKSGEN_Disabled (0UL) /*!< Read: Disabled */ +#define CCM_INTENCLR_ENDKSGEN_Enabled (1UL) /*!< Read: Enabled */ +#define CCM_INTENCLR_ENDKSGEN_Clear (1UL) /*!< Disable */ + +/* Register: CCM_MICSTATUS */ +/* Description: MIC check result */ + +/* Bit 0 : The result of the MIC check performed during the previous decryption operation */ +#define CCM_MICSTATUS_MICSTATUS_Pos (0UL) /*!< Position of MICSTATUS field. */ +#define CCM_MICSTATUS_MICSTATUS_Msk (0x1UL << CCM_MICSTATUS_MICSTATUS_Pos) /*!< Bit mask of MICSTATUS field. */ +#define CCM_MICSTATUS_MICSTATUS_CheckFailed (0UL) /*!< MIC check failed */ +#define CCM_MICSTATUS_MICSTATUS_CheckPassed (1UL) /*!< MIC check passed */ + +/* Register: CCM_ENABLE */ +/* Description: Enable */ + +/* Bits 1..0 : Enable or disable CCM */ +#define CCM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define CCM_ENABLE_ENABLE_Msk (0x3UL << CCM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define CCM_ENABLE_ENABLE_Disabled (0UL) /*!< Disable */ +#define CCM_ENABLE_ENABLE_Enabled (2UL) /*!< Enable */ + +/* Register: CCM_MODE */ +/* Description: Operation mode */ + +/* Bit 24 : Packet length configuration */ +#define CCM_MODE_LENGTH_Pos (24UL) /*!< Position of LENGTH field. */ +#define CCM_MODE_LENGTH_Msk (0x1UL << CCM_MODE_LENGTH_Pos) /*!< Bit mask of LENGTH field. */ +#define CCM_MODE_LENGTH_Default (0UL) /*!< Default length. Effective length of LENGTH field in encrypted/decrypted packet is 5 bits. A key-stream for packets up to 27 bytes will be generated. */ +#define CCM_MODE_LENGTH_Extended (1UL) /*!< Extended length. Effective length of LENGTH field in encrypted/decrypted packet is 8 bits. A key-stream for packets up to MAXPACKETSIZE bytes will be generated. */ + +/* Bits 17..16 : Radio data rate that the CCM shall run synchronous with */ +#define CCM_MODE_DATARATE_Pos (16UL) /*!< Position of DATARATE field. */ +#define CCM_MODE_DATARATE_Msk (0x3UL << CCM_MODE_DATARATE_Pos) /*!< Bit mask of DATARATE field. */ +#define CCM_MODE_DATARATE_1Mbit (0UL) /*!< 1 Mbps */ +#define CCM_MODE_DATARATE_2Mbit (1UL) /*!< 2 Mbps */ +#define CCM_MODE_DATARATE_125Kbps (2UL) /*!< 125 Kbps */ +#define CCM_MODE_DATARATE_500Kbps (3UL) /*!< 500 Kbps */ + +/* Bit 0 : The mode of operation to be used. The settings in this register apply whenever either the KSGEN or CRYPT tasks are triggered. */ +#define CCM_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */ +#define CCM_MODE_MODE_Msk (0x1UL << CCM_MODE_MODE_Pos) /*!< Bit mask of MODE field. */ +#define CCM_MODE_MODE_Encryption (0UL) /*!< AES CCM packet encryption mode */ +#define CCM_MODE_MODE_Decryption (1UL) /*!< AES CCM packet decryption mode */ + +/* Register: CCM_CNFPTR */ +/* Description: Pointer to data structure holding AES key and NONCE vector */ + +/* Bits 31..0 : Pointer to the data structure holding the AES key and the CCM NONCE vector (see Table 1 CCM data structure overview) */ +#define CCM_CNFPTR_CNFPTR_Pos (0UL) /*!< Position of CNFPTR field. */ +#define CCM_CNFPTR_CNFPTR_Msk (0xFFFFFFFFUL << CCM_CNFPTR_CNFPTR_Pos) /*!< Bit mask of CNFPTR field. */ + +/* Register: CCM_INPTR */ +/* Description: Input pointer */ + +/* Bits 31..0 : Input pointer */ +#define CCM_INPTR_INPTR_Pos (0UL) /*!< Position of INPTR field. */ +#define CCM_INPTR_INPTR_Msk (0xFFFFFFFFUL << CCM_INPTR_INPTR_Pos) /*!< Bit mask of INPTR field. */ + +/* Register: CCM_OUTPTR */ +/* Description: Output pointer */ + +/* Bits 31..0 : Output pointer */ +#define CCM_OUTPTR_OUTPTR_Pos (0UL) /*!< Position of OUTPTR field. */ +#define CCM_OUTPTR_OUTPTR_Msk (0xFFFFFFFFUL << CCM_OUTPTR_OUTPTR_Pos) /*!< Bit mask of OUTPTR field. */ + +/* Register: CCM_SCRATCHPTR */ +/* Description: Pointer to data area used for temporary storage */ + +/* Bits 31..0 : Pointer to a scratch data area used for temporary storage during key-stream generation, MIC generation and encryption/decryption. */ +#define CCM_SCRATCHPTR_SCRATCHPTR_Pos (0UL) /*!< Position of SCRATCHPTR field. */ +#define CCM_SCRATCHPTR_SCRATCHPTR_Msk (0xFFFFFFFFUL << CCM_SCRATCHPTR_SCRATCHPTR_Pos) /*!< Bit mask of SCRATCHPTR field. */ + +/* Register: CCM_MAXPACKETSIZE */ +/* Description: Length of key-stream generated when MODE.LENGTH = Extended. */ + +/* Bits 7..0 : Length of key-stream generated when MODE.LENGTH = Extended. This value must be greater or equal to the subsequent packet to be encrypted/decrypted. */ +#define CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos (0UL) /*!< Position of MAXPACKETSIZE field. */ +#define CCM_MAXPACKETSIZE_MAXPACKETSIZE_Msk (0xFFUL << CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos) /*!< Bit mask of MAXPACKETSIZE field. */ + +/* Register: CCM_RATEOVERRIDE */ +/* Description: Data rate override setting. */ + +/* Bits 1..0 : Data rate override setting. */ +#define CCM_RATEOVERRIDE_RATEOVERRIDE_Pos (0UL) /*!< Position of RATEOVERRIDE field. */ +#define CCM_RATEOVERRIDE_RATEOVERRIDE_Msk (0x3UL << CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) /*!< Bit mask of RATEOVERRIDE field. */ +#define CCM_RATEOVERRIDE_RATEOVERRIDE_1Mbit (0UL) /*!< 1 Mbps */ +#define CCM_RATEOVERRIDE_RATEOVERRIDE_2Mbit (1UL) /*!< 2 Mbps */ +#define CCM_RATEOVERRIDE_RATEOVERRIDE_125Kbps (2UL) /*!< 125 Kbps */ +#define CCM_RATEOVERRIDE_RATEOVERRIDE_500Kbps (3UL) /*!< 500 Kbps */ + + +/* Peripheral: CLOCK */ +/* Description: Clock control */ + +/* Register: CLOCK_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 4 : Write '1' to Enable interrupt for CTTO event */ +#define CLOCK_INTENSET_CTTO_Pos (4UL) /*!< Position of CTTO field. */ +#define CLOCK_INTENSET_CTTO_Msk (0x1UL << CLOCK_INTENSET_CTTO_Pos) /*!< Bit mask of CTTO field. */ +#define CLOCK_INTENSET_CTTO_Disabled (0UL) /*!< Read: Disabled */ +#define CLOCK_INTENSET_CTTO_Enabled (1UL) /*!< Read: Enabled */ +#define CLOCK_INTENSET_CTTO_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for DONE event */ +#define CLOCK_INTENSET_DONE_Pos (3UL) /*!< Position of DONE field. */ +#define CLOCK_INTENSET_DONE_Msk (0x1UL << CLOCK_INTENSET_DONE_Pos) /*!< Bit mask of DONE field. */ +#define CLOCK_INTENSET_DONE_Disabled (0UL) /*!< Read: Disabled */ +#define CLOCK_INTENSET_DONE_Enabled (1UL) /*!< Read: Enabled */ +#define CLOCK_INTENSET_DONE_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for LFCLKSTARTED event */ +#define CLOCK_INTENSET_LFCLKSTARTED_Pos (1UL) /*!< Position of LFCLKSTARTED field. */ +#define CLOCK_INTENSET_LFCLKSTARTED_Msk (0x1UL << CLOCK_INTENSET_LFCLKSTARTED_Pos) /*!< Bit mask of LFCLKSTARTED field. */ +#define CLOCK_INTENSET_LFCLKSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define CLOCK_INTENSET_LFCLKSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define CLOCK_INTENSET_LFCLKSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for HFCLKSTARTED event */ +#define CLOCK_INTENSET_HFCLKSTARTED_Pos (0UL) /*!< Position of HFCLKSTARTED field. */ +#define CLOCK_INTENSET_HFCLKSTARTED_Msk (0x1UL << CLOCK_INTENSET_HFCLKSTARTED_Pos) /*!< Bit mask of HFCLKSTARTED field. */ +#define CLOCK_INTENSET_HFCLKSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define CLOCK_INTENSET_HFCLKSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define CLOCK_INTENSET_HFCLKSTARTED_Set (1UL) /*!< Enable */ + +/* Register: CLOCK_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 4 : Write '1' to Disable interrupt for CTTO event */ +#define CLOCK_INTENCLR_CTTO_Pos (4UL) /*!< Position of CTTO field. */ +#define CLOCK_INTENCLR_CTTO_Msk (0x1UL << CLOCK_INTENCLR_CTTO_Pos) /*!< Bit mask of CTTO field. */ +#define CLOCK_INTENCLR_CTTO_Disabled (0UL) /*!< Read: Disabled */ +#define CLOCK_INTENCLR_CTTO_Enabled (1UL) /*!< Read: Enabled */ +#define CLOCK_INTENCLR_CTTO_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for DONE event */ +#define CLOCK_INTENCLR_DONE_Pos (3UL) /*!< Position of DONE field. */ +#define CLOCK_INTENCLR_DONE_Msk (0x1UL << CLOCK_INTENCLR_DONE_Pos) /*!< Bit mask of DONE field. */ +#define CLOCK_INTENCLR_DONE_Disabled (0UL) /*!< Read: Disabled */ +#define CLOCK_INTENCLR_DONE_Enabled (1UL) /*!< Read: Enabled */ +#define CLOCK_INTENCLR_DONE_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for LFCLKSTARTED event */ +#define CLOCK_INTENCLR_LFCLKSTARTED_Pos (1UL) /*!< Position of LFCLKSTARTED field. */ +#define CLOCK_INTENCLR_LFCLKSTARTED_Msk (0x1UL << CLOCK_INTENCLR_LFCLKSTARTED_Pos) /*!< Bit mask of LFCLKSTARTED field. */ +#define CLOCK_INTENCLR_LFCLKSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define CLOCK_INTENCLR_LFCLKSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define CLOCK_INTENCLR_LFCLKSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for HFCLKSTARTED event */ +#define CLOCK_INTENCLR_HFCLKSTARTED_Pos (0UL) /*!< Position of HFCLKSTARTED field. */ +#define CLOCK_INTENCLR_HFCLKSTARTED_Msk (0x1UL << CLOCK_INTENCLR_HFCLKSTARTED_Pos) /*!< Bit mask of HFCLKSTARTED field. */ +#define CLOCK_INTENCLR_HFCLKSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define CLOCK_INTENCLR_HFCLKSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define CLOCK_INTENCLR_HFCLKSTARTED_Clear (1UL) /*!< Disable */ + +/* Register: CLOCK_HFCLKRUN */ +/* Description: Status indicating that HFCLKSTART task has been triggered */ + +/* Bit 0 : HFCLKSTART task triggered or not */ +#define CLOCK_HFCLKRUN_STATUS_Pos (0UL) /*!< Position of STATUS field. */ +#define CLOCK_HFCLKRUN_STATUS_Msk (0x1UL << CLOCK_HFCLKRUN_STATUS_Pos) /*!< Bit mask of STATUS field. */ +#define CLOCK_HFCLKRUN_STATUS_NotTriggered (0UL) /*!< Task not triggered */ +#define CLOCK_HFCLKRUN_STATUS_Triggered (1UL) /*!< Task triggered */ + +/* Register: CLOCK_HFCLKSTAT */ +/* Description: HFCLK status */ + +/* Bit 16 : HFCLK state */ +#define CLOCK_HFCLKSTAT_STATE_Pos (16UL) /*!< Position of STATE field. */ +#define CLOCK_HFCLKSTAT_STATE_Msk (0x1UL << CLOCK_HFCLKSTAT_STATE_Pos) /*!< Bit mask of STATE field. */ +#define CLOCK_HFCLKSTAT_STATE_NotRunning (0UL) /*!< HFCLK not running */ +#define CLOCK_HFCLKSTAT_STATE_Running (1UL) /*!< HFCLK running */ + +/* Bit 0 : Source of HFCLK */ +#define CLOCK_HFCLKSTAT_SRC_Pos (0UL) /*!< Position of SRC field. */ +#define CLOCK_HFCLKSTAT_SRC_Msk (0x1UL << CLOCK_HFCLKSTAT_SRC_Pos) /*!< Bit mask of SRC field. */ +#define CLOCK_HFCLKSTAT_SRC_RC (0UL) /*!< 64 MHz internal oscillator (HFINT) */ +#define CLOCK_HFCLKSTAT_SRC_Xtal (1UL) /*!< 64 MHz crystal oscillator (HFXO) */ + +/* Register: CLOCK_LFCLKRUN */ +/* Description: Status indicating that LFCLKSTART task has been triggered */ + +/* Bit 0 : LFCLKSTART task triggered or not */ +#define CLOCK_LFCLKRUN_STATUS_Pos (0UL) /*!< Position of STATUS field. */ +#define CLOCK_LFCLKRUN_STATUS_Msk (0x1UL << CLOCK_LFCLKRUN_STATUS_Pos) /*!< Bit mask of STATUS field. */ +#define CLOCK_LFCLKRUN_STATUS_NotTriggered (0UL) /*!< Task not triggered */ +#define CLOCK_LFCLKRUN_STATUS_Triggered (1UL) /*!< Task triggered */ + +/* Register: CLOCK_LFCLKSTAT */ +/* Description: LFCLK status */ + +/* Bit 16 : LFCLK state */ +#define CLOCK_LFCLKSTAT_STATE_Pos (16UL) /*!< Position of STATE field. */ +#define CLOCK_LFCLKSTAT_STATE_Msk (0x1UL << CLOCK_LFCLKSTAT_STATE_Pos) /*!< Bit mask of STATE field. */ +#define CLOCK_LFCLKSTAT_STATE_NotRunning (0UL) /*!< LFCLK not running */ +#define CLOCK_LFCLKSTAT_STATE_Running (1UL) /*!< LFCLK running */ + +/* Bits 1..0 : Source of LFCLK */ +#define CLOCK_LFCLKSTAT_SRC_Pos (0UL) /*!< Position of SRC field. */ +#define CLOCK_LFCLKSTAT_SRC_Msk (0x3UL << CLOCK_LFCLKSTAT_SRC_Pos) /*!< Bit mask of SRC field. */ +#define CLOCK_LFCLKSTAT_SRC_RC (0UL) /*!< 32.768 kHz RC oscillator */ +#define CLOCK_LFCLKSTAT_SRC_Xtal (1UL) /*!< 32.768 kHz crystal oscillator */ +#define CLOCK_LFCLKSTAT_SRC_Synth (2UL) /*!< 32.768 kHz synthesized from HFCLK */ + +/* Register: CLOCK_LFCLKSRCCOPY */ +/* Description: Copy of LFCLKSRC register, set when LFCLKSTART task was triggered */ + +/* Bits 1..0 : Clock source */ +#define CLOCK_LFCLKSRCCOPY_SRC_Pos (0UL) /*!< Position of SRC field. */ +#define CLOCK_LFCLKSRCCOPY_SRC_Msk (0x3UL << CLOCK_LFCLKSRCCOPY_SRC_Pos) /*!< Bit mask of SRC field. */ +#define CLOCK_LFCLKSRCCOPY_SRC_RC (0UL) /*!< 32.768 kHz RC oscillator */ +#define CLOCK_LFCLKSRCCOPY_SRC_Xtal (1UL) /*!< 32.768 kHz crystal oscillator */ +#define CLOCK_LFCLKSRCCOPY_SRC_Synth (2UL) /*!< 32.768 kHz synthesized from HFCLK */ + +/* Register: CLOCK_LFCLKSRC */ +/* Description: Clock source for the LFCLK */ + +/* Bit 17 : Enable or disable external source for LFCLK */ +#define CLOCK_LFCLKSRC_EXTERNAL_Pos (17UL) /*!< Position of EXTERNAL field. */ +#define CLOCK_LFCLKSRC_EXTERNAL_Msk (0x1UL << CLOCK_LFCLKSRC_EXTERNAL_Pos) /*!< Bit mask of EXTERNAL field. */ +#define CLOCK_LFCLKSRC_EXTERNAL_Disabled (0UL) /*!< Disable external source (use with Xtal) */ +#define CLOCK_LFCLKSRC_EXTERNAL_Enabled (1UL) /*!< Enable use of external source instead of Xtal (SRC needs to be set to Xtal) */ + +/* Bit 16 : Enable or disable bypass of LFCLK crystal oscillator with external clock source */ +#define CLOCK_LFCLKSRC_BYPASS_Pos (16UL) /*!< Position of BYPASS field. */ +#define CLOCK_LFCLKSRC_BYPASS_Msk (0x1UL << CLOCK_LFCLKSRC_BYPASS_Pos) /*!< Bit mask of BYPASS field. */ +#define CLOCK_LFCLKSRC_BYPASS_Disabled (0UL) /*!< Disable (use with Xtal or low-swing external source) */ +#define CLOCK_LFCLKSRC_BYPASS_Enabled (1UL) /*!< Enable (use with rail-to-rail external source) */ + +/* Bits 1..0 : Clock source */ +#define CLOCK_LFCLKSRC_SRC_Pos (0UL) /*!< Position of SRC field. */ +#define CLOCK_LFCLKSRC_SRC_Msk (0x3UL << CLOCK_LFCLKSRC_SRC_Pos) /*!< Bit mask of SRC field. */ +#define CLOCK_LFCLKSRC_SRC_RC (0UL) /*!< 32.768 kHz RC oscillator */ +#define CLOCK_LFCLKSRC_SRC_Xtal (1UL) /*!< 32.768 kHz crystal oscillator */ +#define CLOCK_LFCLKSRC_SRC_Synth (2UL) /*!< 32.768 kHz synthesized from HFCLK */ + +/* Register: CLOCK_CTIV */ +/* Description: Calibration timer interval */ + +/* Bits 6..0 : Calibration timer interval in multiple of 0.25 seconds. Range: 0.25 seconds to 31.75 seconds. */ +#define CLOCK_CTIV_CTIV_Pos (0UL) /*!< Position of CTIV field. */ +#define CLOCK_CTIV_CTIV_Msk (0x7FUL << CLOCK_CTIV_CTIV_Pos) /*!< Bit mask of CTIV field. */ + +/* Register: CLOCK_TRACECONFIG */ +/* Description: Clocking options for the Trace Port debug interface */ + +/* Bits 17..16 : Pin multiplexing of trace signals. */ +#define CLOCK_TRACECONFIG_TRACEMUX_Pos (16UL) /*!< Position of TRACEMUX field. */ +#define CLOCK_TRACECONFIG_TRACEMUX_Msk (0x3UL << CLOCK_TRACECONFIG_TRACEMUX_Pos) /*!< Bit mask of TRACEMUX field. */ +#define CLOCK_TRACECONFIG_TRACEMUX_GPIO (0UL) /*!< GPIOs multiplexed onto all trace-pins */ +#define CLOCK_TRACECONFIG_TRACEMUX_Serial (1UL) /*!< SWO multiplexed onto P0.18, GPIO multiplexed onto other trace pins */ +#define CLOCK_TRACECONFIG_TRACEMUX_Parallel (2UL) /*!< TRACECLK and TRACEDATA multiplexed onto P0.20, P0.18, P0.16, P0.15 and P0.14. */ + +/* Bits 1..0 : Speed of Trace Port clock. Note that the TRACECLK pin will output this clock divided by two. */ +#define CLOCK_TRACECONFIG_TRACEPORTSPEED_Pos (0UL) /*!< Position of TRACEPORTSPEED field. */ +#define CLOCK_TRACECONFIG_TRACEPORTSPEED_Msk (0x3UL << CLOCK_TRACECONFIG_TRACEPORTSPEED_Pos) /*!< Bit mask of TRACEPORTSPEED field. */ +#define CLOCK_TRACECONFIG_TRACEPORTSPEED_32MHz (0UL) /*!< 32 MHz Trace Port clock (TRACECLK = 16 MHz) */ +#define CLOCK_TRACECONFIG_TRACEPORTSPEED_16MHz (1UL) /*!< 16 MHz Trace Port clock (TRACECLK = 8 MHz) */ +#define CLOCK_TRACECONFIG_TRACEPORTSPEED_8MHz (2UL) /*!< 8 MHz Trace Port clock (TRACECLK = 4 MHz) */ +#define CLOCK_TRACECONFIG_TRACEPORTSPEED_4MHz (3UL) /*!< 4 MHz Trace Port clock (TRACECLK = 2 MHz) */ + +/* Register: CLOCK_LFRCMODE */ +/* Description: LFRC mode configuration */ + +/* Bit 16 : Active LFRC mode. This field is read only. */ +#define CLOCK_LFRCMODE_STATUS_Pos (16UL) /*!< Position of STATUS field. */ +#define CLOCK_LFRCMODE_STATUS_Msk (0x1UL << CLOCK_LFRCMODE_STATUS_Pos) /*!< Bit mask of STATUS field. */ +#define CLOCK_LFRCMODE_STATUS_Normal (0UL) /*!< Normal mode */ +#define CLOCK_LFRCMODE_STATUS_ULP (1UL) /*!< Ultra-low power mode (ULP) */ + +/* Bit 0 : Set LFRC mode */ +#define CLOCK_LFRCMODE_MODE_Pos (0UL) /*!< Position of MODE field. */ +#define CLOCK_LFRCMODE_MODE_Msk (0x1UL << CLOCK_LFRCMODE_MODE_Pos) /*!< Bit mask of MODE field. */ +#define CLOCK_LFRCMODE_MODE_Normal (0UL) /*!< Normal mode */ +#define CLOCK_LFRCMODE_MODE_ULP (1UL) /*!< Ultra-low power mode (ULP) */ + + +/* Peripheral: COMP */ +/* Description: Comparator */ + +/* Register: COMP_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 4 : Shortcut between CROSS event and STOP task */ +#define COMP_SHORTS_CROSS_STOP_Pos (4UL) /*!< Position of CROSS_STOP field. */ +#define COMP_SHORTS_CROSS_STOP_Msk (0x1UL << COMP_SHORTS_CROSS_STOP_Pos) /*!< Bit mask of CROSS_STOP field. */ +#define COMP_SHORTS_CROSS_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define COMP_SHORTS_CROSS_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between UP event and STOP task */ +#define COMP_SHORTS_UP_STOP_Pos (3UL) /*!< Position of UP_STOP field. */ +#define COMP_SHORTS_UP_STOP_Msk (0x1UL << COMP_SHORTS_UP_STOP_Pos) /*!< Bit mask of UP_STOP field. */ +#define COMP_SHORTS_UP_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define COMP_SHORTS_UP_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 2 : Shortcut between DOWN event and STOP task */ +#define COMP_SHORTS_DOWN_STOP_Pos (2UL) /*!< Position of DOWN_STOP field. */ +#define COMP_SHORTS_DOWN_STOP_Msk (0x1UL << COMP_SHORTS_DOWN_STOP_Pos) /*!< Bit mask of DOWN_STOP field. */ +#define COMP_SHORTS_DOWN_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define COMP_SHORTS_DOWN_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between READY event and STOP task */ +#define COMP_SHORTS_READY_STOP_Pos (1UL) /*!< Position of READY_STOP field. */ +#define COMP_SHORTS_READY_STOP_Msk (0x1UL << COMP_SHORTS_READY_STOP_Pos) /*!< Bit mask of READY_STOP field. */ +#define COMP_SHORTS_READY_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define COMP_SHORTS_READY_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between READY event and SAMPLE task */ +#define COMP_SHORTS_READY_SAMPLE_Pos (0UL) /*!< Position of READY_SAMPLE field. */ +#define COMP_SHORTS_READY_SAMPLE_Msk (0x1UL << COMP_SHORTS_READY_SAMPLE_Pos) /*!< Bit mask of READY_SAMPLE field. */ +#define COMP_SHORTS_READY_SAMPLE_Disabled (0UL) /*!< Disable shortcut */ +#define COMP_SHORTS_READY_SAMPLE_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: COMP_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 3 : Enable or disable interrupt for CROSS event */ +#define COMP_INTEN_CROSS_Pos (3UL) /*!< Position of CROSS field. */ +#define COMP_INTEN_CROSS_Msk (0x1UL << COMP_INTEN_CROSS_Pos) /*!< Bit mask of CROSS field. */ +#define COMP_INTEN_CROSS_Disabled (0UL) /*!< Disable */ +#define COMP_INTEN_CROSS_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for UP event */ +#define COMP_INTEN_UP_Pos (2UL) /*!< Position of UP field. */ +#define COMP_INTEN_UP_Msk (0x1UL << COMP_INTEN_UP_Pos) /*!< Bit mask of UP field. */ +#define COMP_INTEN_UP_Disabled (0UL) /*!< Disable */ +#define COMP_INTEN_UP_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for DOWN event */ +#define COMP_INTEN_DOWN_Pos (1UL) /*!< Position of DOWN field. */ +#define COMP_INTEN_DOWN_Msk (0x1UL << COMP_INTEN_DOWN_Pos) /*!< Bit mask of DOWN field. */ +#define COMP_INTEN_DOWN_Disabled (0UL) /*!< Disable */ +#define COMP_INTEN_DOWN_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable interrupt for READY event */ +#define COMP_INTEN_READY_Pos (0UL) /*!< Position of READY field. */ +#define COMP_INTEN_READY_Msk (0x1UL << COMP_INTEN_READY_Pos) /*!< Bit mask of READY field. */ +#define COMP_INTEN_READY_Disabled (0UL) /*!< Disable */ +#define COMP_INTEN_READY_Enabled (1UL) /*!< Enable */ + +/* Register: COMP_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 3 : Write '1' to Enable interrupt for CROSS event */ +#define COMP_INTENSET_CROSS_Pos (3UL) /*!< Position of CROSS field. */ +#define COMP_INTENSET_CROSS_Msk (0x1UL << COMP_INTENSET_CROSS_Pos) /*!< Bit mask of CROSS field. */ +#define COMP_INTENSET_CROSS_Disabled (0UL) /*!< Read: Disabled */ +#define COMP_INTENSET_CROSS_Enabled (1UL) /*!< Read: Enabled */ +#define COMP_INTENSET_CROSS_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for UP event */ +#define COMP_INTENSET_UP_Pos (2UL) /*!< Position of UP field. */ +#define COMP_INTENSET_UP_Msk (0x1UL << COMP_INTENSET_UP_Pos) /*!< Bit mask of UP field. */ +#define COMP_INTENSET_UP_Disabled (0UL) /*!< Read: Disabled */ +#define COMP_INTENSET_UP_Enabled (1UL) /*!< Read: Enabled */ +#define COMP_INTENSET_UP_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for DOWN event */ +#define COMP_INTENSET_DOWN_Pos (1UL) /*!< Position of DOWN field. */ +#define COMP_INTENSET_DOWN_Msk (0x1UL << COMP_INTENSET_DOWN_Pos) /*!< Bit mask of DOWN field. */ +#define COMP_INTENSET_DOWN_Disabled (0UL) /*!< Read: Disabled */ +#define COMP_INTENSET_DOWN_Enabled (1UL) /*!< Read: Enabled */ +#define COMP_INTENSET_DOWN_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for READY event */ +#define COMP_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */ +#define COMP_INTENSET_READY_Msk (0x1UL << COMP_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ +#define COMP_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ +#define COMP_INTENSET_READY_Enabled (1UL) /*!< Read: Enabled */ +#define COMP_INTENSET_READY_Set (1UL) /*!< Enable */ + +/* Register: COMP_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 3 : Write '1' to Disable interrupt for CROSS event */ +#define COMP_INTENCLR_CROSS_Pos (3UL) /*!< Position of CROSS field. */ +#define COMP_INTENCLR_CROSS_Msk (0x1UL << COMP_INTENCLR_CROSS_Pos) /*!< Bit mask of CROSS field. */ +#define COMP_INTENCLR_CROSS_Disabled (0UL) /*!< Read: Disabled */ +#define COMP_INTENCLR_CROSS_Enabled (1UL) /*!< Read: Enabled */ +#define COMP_INTENCLR_CROSS_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for UP event */ +#define COMP_INTENCLR_UP_Pos (2UL) /*!< Position of UP field. */ +#define COMP_INTENCLR_UP_Msk (0x1UL << COMP_INTENCLR_UP_Pos) /*!< Bit mask of UP field. */ +#define COMP_INTENCLR_UP_Disabled (0UL) /*!< Read: Disabled */ +#define COMP_INTENCLR_UP_Enabled (1UL) /*!< Read: Enabled */ +#define COMP_INTENCLR_UP_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for DOWN event */ +#define COMP_INTENCLR_DOWN_Pos (1UL) /*!< Position of DOWN field. */ +#define COMP_INTENCLR_DOWN_Msk (0x1UL << COMP_INTENCLR_DOWN_Pos) /*!< Bit mask of DOWN field. */ +#define COMP_INTENCLR_DOWN_Disabled (0UL) /*!< Read: Disabled */ +#define COMP_INTENCLR_DOWN_Enabled (1UL) /*!< Read: Enabled */ +#define COMP_INTENCLR_DOWN_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for READY event */ +#define COMP_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */ +#define COMP_INTENCLR_READY_Msk (0x1UL << COMP_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ +#define COMP_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ +#define COMP_INTENCLR_READY_Enabled (1UL) /*!< Read: Enabled */ +#define COMP_INTENCLR_READY_Clear (1UL) /*!< Disable */ + +/* Register: COMP_RESULT */ +/* Description: Compare result */ + +/* Bit 0 : Result of last compare. Decision point SAMPLE task. */ +#define COMP_RESULT_RESULT_Pos (0UL) /*!< Position of RESULT field. */ +#define COMP_RESULT_RESULT_Msk (0x1UL << COMP_RESULT_RESULT_Pos) /*!< Bit mask of RESULT field. */ +#define COMP_RESULT_RESULT_Below (0UL) /*!< Input voltage is below the threshold (VIN+ < VIN-) */ +#define COMP_RESULT_RESULT_Above (1UL) /*!< Input voltage is above the threshold (VIN+ > VIN-) */ + +/* Register: COMP_ENABLE */ +/* Description: COMP enable */ + +/* Bits 1..0 : Enable or disable COMP */ +#define COMP_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define COMP_ENABLE_ENABLE_Msk (0x3UL << COMP_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define COMP_ENABLE_ENABLE_Disabled (0UL) /*!< Disable */ +#define COMP_ENABLE_ENABLE_Enabled (2UL) /*!< Enable */ + +/* Register: COMP_PSEL */ +/* Description: Pin select */ + +/* Bits 2..0 : Analog pin select */ +#define COMP_PSEL_PSEL_Pos (0UL) /*!< Position of PSEL field. */ +#define COMP_PSEL_PSEL_Msk (0x7UL << COMP_PSEL_PSEL_Pos) /*!< Bit mask of PSEL field. */ +#define COMP_PSEL_PSEL_AnalogInput0 (0UL) /*!< AIN0 selected as analog input */ +#define COMP_PSEL_PSEL_AnalogInput1 (1UL) /*!< AIN1 selected as analog input */ +#define COMP_PSEL_PSEL_AnalogInput2 (2UL) /*!< AIN2 selected as analog input */ +#define COMP_PSEL_PSEL_AnalogInput3 (3UL) /*!< AIN3 selected as analog input */ +#define COMP_PSEL_PSEL_AnalogInput4 (4UL) /*!< AIN4 selected as analog input */ +#define COMP_PSEL_PSEL_AnalogInput5 (5UL) /*!< AIN5 selected as analog input */ +#define COMP_PSEL_PSEL_AnalogInput6 (6UL) /*!< AIN6 selected as analog input */ +#define COMP_PSEL_PSEL_AnalogInput7 (7UL) /*!< AIN7 selected as analog input */ + +/* Register: COMP_REFSEL */ +/* Description: Reference source select */ + +/* Bits 2..0 : Reference select */ +#define COMP_REFSEL_REFSEL_Pos (0UL) /*!< Position of REFSEL field. */ +#define COMP_REFSEL_REFSEL_Msk (0x7UL << COMP_REFSEL_REFSEL_Pos) /*!< Bit mask of REFSEL field. */ +#define COMP_REFSEL_REFSEL_Int1V2 (0UL) /*!< VREF = internal 1.2 V reference (VDD >= 1.7 V) */ +#define COMP_REFSEL_REFSEL_Int1V8 (1UL) /*!< VREF = internal 1.8 V reference (VDD >= VREF + 0.2 V) */ +#define COMP_REFSEL_REFSEL_Int2V4 (2UL) /*!< VREF = internal 2.4 V reference (VDD >= VREF + 0.2 V) */ +#define COMP_REFSEL_REFSEL_VDD (4UL) /*!< VREF = VDD */ +#define COMP_REFSEL_REFSEL_ARef (7UL) /*!< VREF = AREF (VDD >= VREF >= AREFMIN) */ + +/* Register: COMP_EXTREFSEL */ +/* Description: External reference select */ + +/* Bit 0 : External analog reference select */ +#define COMP_EXTREFSEL_EXTREFSEL_Pos (0UL) /*!< Position of EXTREFSEL field. */ +#define COMP_EXTREFSEL_EXTREFSEL_Msk (0x1UL << COMP_EXTREFSEL_EXTREFSEL_Pos) /*!< Bit mask of EXTREFSEL field. */ +#define COMP_EXTREFSEL_EXTREFSEL_AnalogReference0 (0UL) /*!< Use AIN0 as external analog reference */ +#define COMP_EXTREFSEL_EXTREFSEL_AnalogReference1 (1UL) /*!< Use AIN1 as external analog reference */ + +/* Register: COMP_TH */ +/* Description: Threshold configuration for hysteresis unit */ + +/* Bits 13..8 : VUP = (THUP+1)/64*VREF */ +#define COMP_TH_THUP_Pos (8UL) /*!< Position of THUP field. */ +#define COMP_TH_THUP_Msk (0x3FUL << COMP_TH_THUP_Pos) /*!< Bit mask of THUP field. */ + +/* Bits 5..0 : VDOWN = (THDOWN+1)/64*VREF */ +#define COMP_TH_THDOWN_Pos (0UL) /*!< Position of THDOWN field. */ +#define COMP_TH_THDOWN_Msk (0x3FUL << COMP_TH_THDOWN_Pos) /*!< Bit mask of THDOWN field. */ + +/* Register: COMP_MODE */ +/* Description: Mode configuration */ + +/* Bit 8 : Main operation mode */ +#define COMP_MODE_MAIN_Pos (8UL) /*!< Position of MAIN field. */ +#define COMP_MODE_MAIN_Msk (0x1UL << COMP_MODE_MAIN_Pos) /*!< Bit mask of MAIN field. */ +#define COMP_MODE_MAIN_SE (0UL) /*!< Single ended mode */ +#define COMP_MODE_MAIN_Diff (1UL) /*!< Differential mode */ + +/* Bits 1..0 : Speed and power mode */ +#define COMP_MODE_SP_Pos (0UL) /*!< Position of SP field. */ +#define COMP_MODE_SP_Msk (0x3UL << COMP_MODE_SP_Pos) /*!< Bit mask of SP field. */ +#define COMP_MODE_SP_Low (0UL) /*!< Low power mode */ +#define COMP_MODE_SP_Normal (1UL) /*!< Normal mode */ +#define COMP_MODE_SP_High (2UL) /*!< High speed mode */ + +/* Register: COMP_HYST */ +/* Description: Comparator hysteresis enable */ + +/* Bit 0 : Comparator hysteresis */ +#define COMP_HYST_HYST_Pos (0UL) /*!< Position of HYST field. */ +#define COMP_HYST_HYST_Msk (0x1UL << COMP_HYST_HYST_Pos) /*!< Bit mask of HYST field. */ +#define COMP_HYST_HYST_NoHyst (0UL) /*!< Comparator hysteresis disabled */ +#define COMP_HYST_HYST_Hyst50mV (1UL) /*!< Comparator hysteresis enabled */ + +/* Register: COMP_ISOURCE */ +/* Description: Current source select on analog input */ + +/* Bits 1..0 : Comparator hysteresis */ +#define COMP_ISOURCE_ISOURCE_Pos (0UL) /*!< Position of ISOURCE field. */ +#define COMP_ISOURCE_ISOURCE_Msk (0x3UL << COMP_ISOURCE_ISOURCE_Pos) /*!< Bit mask of ISOURCE field. */ +#define COMP_ISOURCE_ISOURCE_Off (0UL) /*!< Current source disabled */ +#define COMP_ISOURCE_ISOURCE_Ien2mA5 (1UL) /*!< Current source enabled (+/- 2.5 uA) */ +#define COMP_ISOURCE_ISOURCE_Ien5mA (2UL) /*!< Current source enabled (+/- 5 uA) */ +#define COMP_ISOURCE_ISOURCE_Ien10mA (3UL) /*!< Current source enabled (+/- 10 uA) */ + + +/* Peripheral: CRYPTOCELL */ +/* Description: ARM CryptoCell register interface */ + +/* Register: CRYPTOCELL_ENABLE */ +/* Description: Control power and clock for ARM CryptoCell subsystem */ + +/* Bit 0 : Enable or disable the CryptoCell subsystem */ +#define CRYPTOCELL_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define CRYPTOCELL_ENABLE_ENABLE_Msk (0x1UL << CRYPTOCELL_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define CRYPTOCELL_ENABLE_ENABLE_Disabled (0UL) /*!< CryptoCell subsystem disabled */ +#define CRYPTOCELL_ENABLE_ENABLE_Enabled (1UL) /*!< CryptoCell subsystem enabled */ + + +/* Peripheral: ECB */ +/* Description: AES ECB Mode Encryption */ + +/* Register: ECB_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 1 : Write '1' to Enable interrupt for ERRORECB event */ +#define ECB_INTENSET_ERRORECB_Pos (1UL) /*!< Position of ERRORECB field. */ +#define ECB_INTENSET_ERRORECB_Msk (0x1UL << ECB_INTENSET_ERRORECB_Pos) /*!< Bit mask of ERRORECB field. */ +#define ECB_INTENSET_ERRORECB_Disabled (0UL) /*!< Read: Disabled */ +#define ECB_INTENSET_ERRORECB_Enabled (1UL) /*!< Read: Enabled */ +#define ECB_INTENSET_ERRORECB_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for ENDECB event */ +#define ECB_INTENSET_ENDECB_Pos (0UL) /*!< Position of ENDECB field. */ +#define ECB_INTENSET_ENDECB_Msk (0x1UL << ECB_INTENSET_ENDECB_Pos) /*!< Bit mask of ENDECB field. */ +#define ECB_INTENSET_ENDECB_Disabled (0UL) /*!< Read: Disabled */ +#define ECB_INTENSET_ENDECB_Enabled (1UL) /*!< Read: Enabled */ +#define ECB_INTENSET_ENDECB_Set (1UL) /*!< Enable */ + +/* Register: ECB_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 1 : Write '1' to Disable interrupt for ERRORECB event */ +#define ECB_INTENCLR_ERRORECB_Pos (1UL) /*!< Position of ERRORECB field. */ +#define ECB_INTENCLR_ERRORECB_Msk (0x1UL << ECB_INTENCLR_ERRORECB_Pos) /*!< Bit mask of ERRORECB field. */ +#define ECB_INTENCLR_ERRORECB_Disabled (0UL) /*!< Read: Disabled */ +#define ECB_INTENCLR_ERRORECB_Enabled (1UL) /*!< Read: Enabled */ +#define ECB_INTENCLR_ERRORECB_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for ENDECB event */ +#define ECB_INTENCLR_ENDECB_Pos (0UL) /*!< Position of ENDECB field. */ +#define ECB_INTENCLR_ENDECB_Msk (0x1UL << ECB_INTENCLR_ENDECB_Pos) /*!< Bit mask of ENDECB field. */ +#define ECB_INTENCLR_ENDECB_Disabled (0UL) /*!< Read: Disabled */ +#define ECB_INTENCLR_ENDECB_Enabled (1UL) /*!< Read: Enabled */ +#define ECB_INTENCLR_ENDECB_Clear (1UL) /*!< Disable */ + +/* Register: ECB_ECBDATAPTR */ +/* Description: ECB block encrypt memory pointers */ + +/* Bits 31..0 : Pointer to the ECB data structure (see Table 1 ECB data structure overview) */ +#define ECB_ECBDATAPTR_ECBDATAPTR_Pos (0UL) /*!< Position of ECBDATAPTR field. */ +#define ECB_ECBDATAPTR_ECBDATAPTR_Msk (0xFFFFFFFFUL << ECB_ECBDATAPTR_ECBDATAPTR_Pos) /*!< Bit mask of ECBDATAPTR field. */ + + +/* Peripheral: EGU */ +/* Description: Event Generator Unit 0 */ + +/* Register: EGU_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 15 : Enable or disable interrupt for TRIGGERED[15] event */ +#define EGU_INTEN_TRIGGERED15_Pos (15UL) /*!< Position of TRIGGERED15 field. */ +#define EGU_INTEN_TRIGGERED15_Msk (0x1UL << EGU_INTEN_TRIGGERED15_Pos) /*!< Bit mask of TRIGGERED15 field. */ +#define EGU_INTEN_TRIGGERED15_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED15_Enabled (1UL) /*!< Enable */ + +/* Bit 14 : Enable or disable interrupt for TRIGGERED[14] event */ +#define EGU_INTEN_TRIGGERED14_Pos (14UL) /*!< Position of TRIGGERED14 field. */ +#define EGU_INTEN_TRIGGERED14_Msk (0x1UL << EGU_INTEN_TRIGGERED14_Pos) /*!< Bit mask of TRIGGERED14 field. */ +#define EGU_INTEN_TRIGGERED14_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED14_Enabled (1UL) /*!< Enable */ + +/* Bit 13 : Enable or disable interrupt for TRIGGERED[13] event */ +#define EGU_INTEN_TRIGGERED13_Pos (13UL) /*!< Position of TRIGGERED13 field. */ +#define EGU_INTEN_TRIGGERED13_Msk (0x1UL << EGU_INTEN_TRIGGERED13_Pos) /*!< Bit mask of TRIGGERED13 field. */ +#define EGU_INTEN_TRIGGERED13_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED13_Enabled (1UL) /*!< Enable */ + +/* Bit 12 : Enable or disable interrupt for TRIGGERED[12] event */ +#define EGU_INTEN_TRIGGERED12_Pos (12UL) /*!< Position of TRIGGERED12 field. */ +#define EGU_INTEN_TRIGGERED12_Msk (0x1UL << EGU_INTEN_TRIGGERED12_Pos) /*!< Bit mask of TRIGGERED12 field. */ +#define EGU_INTEN_TRIGGERED12_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED12_Enabled (1UL) /*!< Enable */ + +/* Bit 11 : Enable or disable interrupt for TRIGGERED[11] event */ +#define EGU_INTEN_TRIGGERED11_Pos (11UL) /*!< Position of TRIGGERED11 field. */ +#define EGU_INTEN_TRIGGERED11_Msk (0x1UL << EGU_INTEN_TRIGGERED11_Pos) /*!< Bit mask of TRIGGERED11 field. */ +#define EGU_INTEN_TRIGGERED11_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED11_Enabled (1UL) /*!< Enable */ + +/* Bit 10 : Enable or disable interrupt for TRIGGERED[10] event */ +#define EGU_INTEN_TRIGGERED10_Pos (10UL) /*!< Position of TRIGGERED10 field. */ +#define EGU_INTEN_TRIGGERED10_Msk (0x1UL << EGU_INTEN_TRIGGERED10_Pos) /*!< Bit mask of TRIGGERED10 field. */ +#define EGU_INTEN_TRIGGERED10_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED10_Enabled (1UL) /*!< Enable */ + +/* Bit 9 : Enable or disable interrupt for TRIGGERED[9] event */ +#define EGU_INTEN_TRIGGERED9_Pos (9UL) /*!< Position of TRIGGERED9 field. */ +#define EGU_INTEN_TRIGGERED9_Msk (0x1UL << EGU_INTEN_TRIGGERED9_Pos) /*!< Bit mask of TRIGGERED9 field. */ +#define EGU_INTEN_TRIGGERED9_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED9_Enabled (1UL) /*!< Enable */ + +/* Bit 8 : Enable or disable interrupt for TRIGGERED[8] event */ +#define EGU_INTEN_TRIGGERED8_Pos (8UL) /*!< Position of TRIGGERED8 field. */ +#define EGU_INTEN_TRIGGERED8_Msk (0x1UL << EGU_INTEN_TRIGGERED8_Pos) /*!< Bit mask of TRIGGERED8 field. */ +#define EGU_INTEN_TRIGGERED8_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED8_Enabled (1UL) /*!< Enable */ + +/* Bit 7 : Enable or disable interrupt for TRIGGERED[7] event */ +#define EGU_INTEN_TRIGGERED7_Pos (7UL) /*!< Position of TRIGGERED7 field. */ +#define EGU_INTEN_TRIGGERED7_Msk (0x1UL << EGU_INTEN_TRIGGERED7_Pos) /*!< Bit mask of TRIGGERED7 field. */ +#define EGU_INTEN_TRIGGERED7_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED7_Enabled (1UL) /*!< Enable */ + +/* Bit 6 : Enable or disable interrupt for TRIGGERED[6] event */ +#define EGU_INTEN_TRIGGERED6_Pos (6UL) /*!< Position of TRIGGERED6 field. */ +#define EGU_INTEN_TRIGGERED6_Msk (0x1UL << EGU_INTEN_TRIGGERED6_Pos) /*!< Bit mask of TRIGGERED6 field. */ +#define EGU_INTEN_TRIGGERED6_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED6_Enabled (1UL) /*!< Enable */ + +/* Bit 5 : Enable or disable interrupt for TRIGGERED[5] event */ +#define EGU_INTEN_TRIGGERED5_Pos (5UL) /*!< Position of TRIGGERED5 field. */ +#define EGU_INTEN_TRIGGERED5_Msk (0x1UL << EGU_INTEN_TRIGGERED5_Pos) /*!< Bit mask of TRIGGERED5 field. */ +#define EGU_INTEN_TRIGGERED5_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED5_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable interrupt for TRIGGERED[4] event */ +#define EGU_INTEN_TRIGGERED4_Pos (4UL) /*!< Position of TRIGGERED4 field. */ +#define EGU_INTEN_TRIGGERED4_Msk (0x1UL << EGU_INTEN_TRIGGERED4_Pos) /*!< Bit mask of TRIGGERED4 field. */ +#define EGU_INTEN_TRIGGERED4_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED4_Enabled (1UL) /*!< Enable */ + +/* Bit 3 : Enable or disable interrupt for TRIGGERED[3] event */ +#define EGU_INTEN_TRIGGERED3_Pos (3UL) /*!< Position of TRIGGERED3 field. */ +#define EGU_INTEN_TRIGGERED3_Msk (0x1UL << EGU_INTEN_TRIGGERED3_Pos) /*!< Bit mask of TRIGGERED3 field. */ +#define EGU_INTEN_TRIGGERED3_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED3_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for TRIGGERED[2] event */ +#define EGU_INTEN_TRIGGERED2_Pos (2UL) /*!< Position of TRIGGERED2 field. */ +#define EGU_INTEN_TRIGGERED2_Msk (0x1UL << EGU_INTEN_TRIGGERED2_Pos) /*!< Bit mask of TRIGGERED2 field. */ +#define EGU_INTEN_TRIGGERED2_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED2_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for TRIGGERED[1] event */ +#define EGU_INTEN_TRIGGERED1_Pos (1UL) /*!< Position of TRIGGERED1 field. */ +#define EGU_INTEN_TRIGGERED1_Msk (0x1UL << EGU_INTEN_TRIGGERED1_Pos) /*!< Bit mask of TRIGGERED1 field. */ +#define EGU_INTEN_TRIGGERED1_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED1_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable interrupt for TRIGGERED[0] event */ +#define EGU_INTEN_TRIGGERED0_Pos (0UL) /*!< Position of TRIGGERED0 field. */ +#define EGU_INTEN_TRIGGERED0_Msk (0x1UL << EGU_INTEN_TRIGGERED0_Pos) /*!< Bit mask of TRIGGERED0 field. */ +#define EGU_INTEN_TRIGGERED0_Disabled (0UL) /*!< Disable */ +#define EGU_INTEN_TRIGGERED0_Enabled (1UL) /*!< Enable */ + +/* Register: EGU_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 15 : Write '1' to Enable interrupt for TRIGGERED[15] event */ +#define EGU_INTENSET_TRIGGERED15_Pos (15UL) /*!< Position of TRIGGERED15 field. */ +#define EGU_INTENSET_TRIGGERED15_Msk (0x1UL << EGU_INTENSET_TRIGGERED15_Pos) /*!< Bit mask of TRIGGERED15 field. */ +#define EGU_INTENSET_TRIGGERED15_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED15_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED15_Set (1UL) /*!< Enable */ + +/* Bit 14 : Write '1' to Enable interrupt for TRIGGERED[14] event */ +#define EGU_INTENSET_TRIGGERED14_Pos (14UL) /*!< Position of TRIGGERED14 field. */ +#define EGU_INTENSET_TRIGGERED14_Msk (0x1UL << EGU_INTENSET_TRIGGERED14_Pos) /*!< Bit mask of TRIGGERED14 field. */ +#define EGU_INTENSET_TRIGGERED14_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED14_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED14_Set (1UL) /*!< Enable */ + +/* Bit 13 : Write '1' to Enable interrupt for TRIGGERED[13] event */ +#define EGU_INTENSET_TRIGGERED13_Pos (13UL) /*!< Position of TRIGGERED13 field. */ +#define EGU_INTENSET_TRIGGERED13_Msk (0x1UL << EGU_INTENSET_TRIGGERED13_Pos) /*!< Bit mask of TRIGGERED13 field. */ +#define EGU_INTENSET_TRIGGERED13_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED13_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED13_Set (1UL) /*!< Enable */ + +/* Bit 12 : Write '1' to Enable interrupt for TRIGGERED[12] event */ +#define EGU_INTENSET_TRIGGERED12_Pos (12UL) /*!< Position of TRIGGERED12 field. */ +#define EGU_INTENSET_TRIGGERED12_Msk (0x1UL << EGU_INTENSET_TRIGGERED12_Pos) /*!< Bit mask of TRIGGERED12 field. */ +#define EGU_INTENSET_TRIGGERED12_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED12_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED12_Set (1UL) /*!< Enable */ + +/* Bit 11 : Write '1' to Enable interrupt for TRIGGERED[11] event */ +#define EGU_INTENSET_TRIGGERED11_Pos (11UL) /*!< Position of TRIGGERED11 field. */ +#define EGU_INTENSET_TRIGGERED11_Msk (0x1UL << EGU_INTENSET_TRIGGERED11_Pos) /*!< Bit mask of TRIGGERED11 field. */ +#define EGU_INTENSET_TRIGGERED11_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED11_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED11_Set (1UL) /*!< Enable */ + +/* Bit 10 : Write '1' to Enable interrupt for TRIGGERED[10] event */ +#define EGU_INTENSET_TRIGGERED10_Pos (10UL) /*!< Position of TRIGGERED10 field. */ +#define EGU_INTENSET_TRIGGERED10_Msk (0x1UL << EGU_INTENSET_TRIGGERED10_Pos) /*!< Bit mask of TRIGGERED10 field. */ +#define EGU_INTENSET_TRIGGERED10_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED10_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED10_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for TRIGGERED[9] event */ +#define EGU_INTENSET_TRIGGERED9_Pos (9UL) /*!< Position of TRIGGERED9 field. */ +#define EGU_INTENSET_TRIGGERED9_Msk (0x1UL << EGU_INTENSET_TRIGGERED9_Pos) /*!< Bit mask of TRIGGERED9 field. */ +#define EGU_INTENSET_TRIGGERED9_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED9_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED9_Set (1UL) /*!< Enable */ + +/* Bit 8 : Write '1' to Enable interrupt for TRIGGERED[8] event */ +#define EGU_INTENSET_TRIGGERED8_Pos (8UL) /*!< Position of TRIGGERED8 field. */ +#define EGU_INTENSET_TRIGGERED8_Msk (0x1UL << EGU_INTENSET_TRIGGERED8_Pos) /*!< Bit mask of TRIGGERED8 field. */ +#define EGU_INTENSET_TRIGGERED8_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED8_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED8_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for TRIGGERED[7] event */ +#define EGU_INTENSET_TRIGGERED7_Pos (7UL) /*!< Position of TRIGGERED7 field. */ +#define EGU_INTENSET_TRIGGERED7_Msk (0x1UL << EGU_INTENSET_TRIGGERED7_Pos) /*!< Bit mask of TRIGGERED7 field. */ +#define EGU_INTENSET_TRIGGERED7_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED7_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED7_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for TRIGGERED[6] event */ +#define EGU_INTENSET_TRIGGERED6_Pos (6UL) /*!< Position of TRIGGERED6 field. */ +#define EGU_INTENSET_TRIGGERED6_Msk (0x1UL << EGU_INTENSET_TRIGGERED6_Pos) /*!< Bit mask of TRIGGERED6 field. */ +#define EGU_INTENSET_TRIGGERED6_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED6_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED6_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for TRIGGERED[5] event */ +#define EGU_INTENSET_TRIGGERED5_Pos (5UL) /*!< Position of TRIGGERED5 field. */ +#define EGU_INTENSET_TRIGGERED5_Msk (0x1UL << EGU_INTENSET_TRIGGERED5_Pos) /*!< Bit mask of TRIGGERED5 field. */ +#define EGU_INTENSET_TRIGGERED5_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED5_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED5_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for TRIGGERED[4] event */ +#define EGU_INTENSET_TRIGGERED4_Pos (4UL) /*!< Position of TRIGGERED4 field. */ +#define EGU_INTENSET_TRIGGERED4_Msk (0x1UL << EGU_INTENSET_TRIGGERED4_Pos) /*!< Bit mask of TRIGGERED4 field. */ +#define EGU_INTENSET_TRIGGERED4_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED4_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED4_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for TRIGGERED[3] event */ +#define EGU_INTENSET_TRIGGERED3_Pos (3UL) /*!< Position of TRIGGERED3 field. */ +#define EGU_INTENSET_TRIGGERED3_Msk (0x1UL << EGU_INTENSET_TRIGGERED3_Pos) /*!< Bit mask of TRIGGERED3 field. */ +#define EGU_INTENSET_TRIGGERED3_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED3_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED3_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for TRIGGERED[2] event */ +#define EGU_INTENSET_TRIGGERED2_Pos (2UL) /*!< Position of TRIGGERED2 field. */ +#define EGU_INTENSET_TRIGGERED2_Msk (0x1UL << EGU_INTENSET_TRIGGERED2_Pos) /*!< Bit mask of TRIGGERED2 field. */ +#define EGU_INTENSET_TRIGGERED2_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED2_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED2_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for TRIGGERED[1] event */ +#define EGU_INTENSET_TRIGGERED1_Pos (1UL) /*!< Position of TRIGGERED1 field. */ +#define EGU_INTENSET_TRIGGERED1_Msk (0x1UL << EGU_INTENSET_TRIGGERED1_Pos) /*!< Bit mask of TRIGGERED1 field. */ +#define EGU_INTENSET_TRIGGERED1_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED1_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED1_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for TRIGGERED[0] event */ +#define EGU_INTENSET_TRIGGERED0_Pos (0UL) /*!< Position of TRIGGERED0 field. */ +#define EGU_INTENSET_TRIGGERED0_Msk (0x1UL << EGU_INTENSET_TRIGGERED0_Pos) /*!< Bit mask of TRIGGERED0 field. */ +#define EGU_INTENSET_TRIGGERED0_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENSET_TRIGGERED0_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENSET_TRIGGERED0_Set (1UL) /*!< Enable */ + +/* Register: EGU_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 15 : Write '1' to Disable interrupt for TRIGGERED[15] event */ +#define EGU_INTENCLR_TRIGGERED15_Pos (15UL) /*!< Position of TRIGGERED15 field. */ +#define EGU_INTENCLR_TRIGGERED15_Msk (0x1UL << EGU_INTENCLR_TRIGGERED15_Pos) /*!< Bit mask of TRIGGERED15 field. */ +#define EGU_INTENCLR_TRIGGERED15_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED15_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED15_Clear (1UL) /*!< Disable */ + +/* Bit 14 : Write '1' to Disable interrupt for TRIGGERED[14] event */ +#define EGU_INTENCLR_TRIGGERED14_Pos (14UL) /*!< Position of TRIGGERED14 field. */ +#define EGU_INTENCLR_TRIGGERED14_Msk (0x1UL << EGU_INTENCLR_TRIGGERED14_Pos) /*!< Bit mask of TRIGGERED14 field. */ +#define EGU_INTENCLR_TRIGGERED14_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED14_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED14_Clear (1UL) /*!< Disable */ + +/* Bit 13 : Write '1' to Disable interrupt for TRIGGERED[13] event */ +#define EGU_INTENCLR_TRIGGERED13_Pos (13UL) /*!< Position of TRIGGERED13 field. */ +#define EGU_INTENCLR_TRIGGERED13_Msk (0x1UL << EGU_INTENCLR_TRIGGERED13_Pos) /*!< Bit mask of TRIGGERED13 field. */ +#define EGU_INTENCLR_TRIGGERED13_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED13_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED13_Clear (1UL) /*!< Disable */ + +/* Bit 12 : Write '1' to Disable interrupt for TRIGGERED[12] event */ +#define EGU_INTENCLR_TRIGGERED12_Pos (12UL) /*!< Position of TRIGGERED12 field. */ +#define EGU_INTENCLR_TRIGGERED12_Msk (0x1UL << EGU_INTENCLR_TRIGGERED12_Pos) /*!< Bit mask of TRIGGERED12 field. */ +#define EGU_INTENCLR_TRIGGERED12_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED12_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED12_Clear (1UL) /*!< Disable */ + +/* Bit 11 : Write '1' to Disable interrupt for TRIGGERED[11] event */ +#define EGU_INTENCLR_TRIGGERED11_Pos (11UL) /*!< Position of TRIGGERED11 field. */ +#define EGU_INTENCLR_TRIGGERED11_Msk (0x1UL << EGU_INTENCLR_TRIGGERED11_Pos) /*!< Bit mask of TRIGGERED11 field. */ +#define EGU_INTENCLR_TRIGGERED11_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED11_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED11_Clear (1UL) /*!< Disable */ + +/* Bit 10 : Write '1' to Disable interrupt for TRIGGERED[10] event */ +#define EGU_INTENCLR_TRIGGERED10_Pos (10UL) /*!< Position of TRIGGERED10 field. */ +#define EGU_INTENCLR_TRIGGERED10_Msk (0x1UL << EGU_INTENCLR_TRIGGERED10_Pos) /*!< Bit mask of TRIGGERED10 field. */ +#define EGU_INTENCLR_TRIGGERED10_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED10_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED10_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for TRIGGERED[9] event */ +#define EGU_INTENCLR_TRIGGERED9_Pos (9UL) /*!< Position of TRIGGERED9 field. */ +#define EGU_INTENCLR_TRIGGERED9_Msk (0x1UL << EGU_INTENCLR_TRIGGERED9_Pos) /*!< Bit mask of TRIGGERED9 field. */ +#define EGU_INTENCLR_TRIGGERED9_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED9_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED9_Clear (1UL) /*!< Disable */ + +/* Bit 8 : Write '1' to Disable interrupt for TRIGGERED[8] event */ +#define EGU_INTENCLR_TRIGGERED8_Pos (8UL) /*!< Position of TRIGGERED8 field. */ +#define EGU_INTENCLR_TRIGGERED8_Msk (0x1UL << EGU_INTENCLR_TRIGGERED8_Pos) /*!< Bit mask of TRIGGERED8 field. */ +#define EGU_INTENCLR_TRIGGERED8_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED8_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED8_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for TRIGGERED[7] event */ +#define EGU_INTENCLR_TRIGGERED7_Pos (7UL) /*!< Position of TRIGGERED7 field. */ +#define EGU_INTENCLR_TRIGGERED7_Msk (0x1UL << EGU_INTENCLR_TRIGGERED7_Pos) /*!< Bit mask of TRIGGERED7 field. */ +#define EGU_INTENCLR_TRIGGERED7_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED7_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED7_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for TRIGGERED[6] event */ +#define EGU_INTENCLR_TRIGGERED6_Pos (6UL) /*!< Position of TRIGGERED6 field. */ +#define EGU_INTENCLR_TRIGGERED6_Msk (0x1UL << EGU_INTENCLR_TRIGGERED6_Pos) /*!< Bit mask of TRIGGERED6 field. */ +#define EGU_INTENCLR_TRIGGERED6_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED6_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED6_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for TRIGGERED[5] event */ +#define EGU_INTENCLR_TRIGGERED5_Pos (5UL) /*!< Position of TRIGGERED5 field. */ +#define EGU_INTENCLR_TRIGGERED5_Msk (0x1UL << EGU_INTENCLR_TRIGGERED5_Pos) /*!< Bit mask of TRIGGERED5 field. */ +#define EGU_INTENCLR_TRIGGERED5_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED5_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED5_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for TRIGGERED[4] event */ +#define EGU_INTENCLR_TRIGGERED4_Pos (4UL) /*!< Position of TRIGGERED4 field. */ +#define EGU_INTENCLR_TRIGGERED4_Msk (0x1UL << EGU_INTENCLR_TRIGGERED4_Pos) /*!< Bit mask of TRIGGERED4 field. */ +#define EGU_INTENCLR_TRIGGERED4_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED4_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED4_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for TRIGGERED[3] event */ +#define EGU_INTENCLR_TRIGGERED3_Pos (3UL) /*!< Position of TRIGGERED3 field. */ +#define EGU_INTENCLR_TRIGGERED3_Msk (0x1UL << EGU_INTENCLR_TRIGGERED3_Pos) /*!< Bit mask of TRIGGERED3 field. */ +#define EGU_INTENCLR_TRIGGERED3_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED3_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED3_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for TRIGGERED[2] event */ +#define EGU_INTENCLR_TRIGGERED2_Pos (2UL) /*!< Position of TRIGGERED2 field. */ +#define EGU_INTENCLR_TRIGGERED2_Msk (0x1UL << EGU_INTENCLR_TRIGGERED2_Pos) /*!< Bit mask of TRIGGERED2 field. */ +#define EGU_INTENCLR_TRIGGERED2_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED2_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED2_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for TRIGGERED[1] event */ +#define EGU_INTENCLR_TRIGGERED1_Pos (1UL) /*!< Position of TRIGGERED1 field. */ +#define EGU_INTENCLR_TRIGGERED1_Msk (0x1UL << EGU_INTENCLR_TRIGGERED1_Pos) /*!< Bit mask of TRIGGERED1 field. */ +#define EGU_INTENCLR_TRIGGERED1_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED1_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED1_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for TRIGGERED[0] event */ +#define EGU_INTENCLR_TRIGGERED0_Pos (0UL) /*!< Position of TRIGGERED0 field. */ +#define EGU_INTENCLR_TRIGGERED0_Msk (0x1UL << EGU_INTENCLR_TRIGGERED0_Pos) /*!< Bit mask of TRIGGERED0 field. */ +#define EGU_INTENCLR_TRIGGERED0_Disabled (0UL) /*!< Read: Disabled */ +#define EGU_INTENCLR_TRIGGERED0_Enabled (1UL) /*!< Read: Enabled */ +#define EGU_INTENCLR_TRIGGERED0_Clear (1UL) /*!< Disable */ + + +/* Peripheral: FICR */ +/* Description: Factory information configuration registers */ + +/* Register: FICR_CODEPAGESIZE */ +/* Description: Code memory page size */ + +/* Bits 31..0 : Code memory page size */ +#define FICR_CODEPAGESIZE_CODEPAGESIZE_Pos (0UL) /*!< Position of CODEPAGESIZE field. */ +#define FICR_CODEPAGESIZE_CODEPAGESIZE_Msk (0xFFFFFFFFUL << FICR_CODEPAGESIZE_CODEPAGESIZE_Pos) /*!< Bit mask of CODEPAGESIZE field. */ + +/* Register: FICR_CODESIZE */ +/* Description: Code memory size */ + +/* Bits 31..0 : Code memory size in number of pages */ +#define FICR_CODESIZE_CODESIZE_Pos (0UL) /*!< Position of CODESIZE field. */ +#define FICR_CODESIZE_CODESIZE_Msk (0xFFFFFFFFUL << FICR_CODESIZE_CODESIZE_Pos) /*!< Bit mask of CODESIZE field. */ + +/* Register: FICR_DEVICEID */ +/* Description: Description collection[0]: Device identifier */ + +/* Bits 31..0 : 64 bit unique device identifier */ +#define FICR_DEVICEID_DEVICEID_Pos (0UL) /*!< Position of DEVICEID field. */ +#define FICR_DEVICEID_DEVICEID_Msk (0xFFFFFFFFUL << FICR_DEVICEID_DEVICEID_Pos) /*!< Bit mask of DEVICEID field. */ + +/* Register: FICR_ER */ +/* Description: Description collection[0]: Encryption root, word 0 */ + +/* Bits 31..0 : Encryption root, word 0 */ +#define FICR_ER_ER_Pos (0UL) /*!< Position of ER field. */ +#define FICR_ER_ER_Msk (0xFFFFFFFFUL << FICR_ER_ER_Pos) /*!< Bit mask of ER field. */ + +/* Register: FICR_IR */ +/* Description: Description collection[0]: Identity Root, word 0 */ + +/* Bits 31..0 : Identity Root, word 0 */ +#define FICR_IR_IR_Pos (0UL) /*!< Position of IR field. */ +#define FICR_IR_IR_Msk (0xFFFFFFFFUL << FICR_IR_IR_Pos) /*!< Bit mask of IR field. */ + +/* Register: FICR_DEVICEADDRTYPE */ +/* Description: Device address type */ + +/* Bit 0 : Device address type */ +#define FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Pos (0UL) /*!< Position of DEVICEADDRTYPE field. */ +#define FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Msk (0x1UL << FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Pos) /*!< Bit mask of DEVICEADDRTYPE field. */ +#define FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Public (0UL) /*!< Public address */ +#define FICR_DEVICEADDRTYPE_DEVICEADDRTYPE_Random (1UL) /*!< Random address */ + +/* Register: FICR_DEVICEADDR */ +/* Description: Description collection[0]: Device address 0 */ + +/* Bits 31..0 : 48 bit device address */ +#define FICR_DEVICEADDR_DEVICEADDR_Pos (0UL) /*!< Position of DEVICEADDR field. */ +#define FICR_DEVICEADDR_DEVICEADDR_Msk (0xFFFFFFFFUL << FICR_DEVICEADDR_DEVICEADDR_Pos) /*!< Bit mask of DEVICEADDR field. */ + +/* Register: FICR_INFO_PART */ +/* Description: Part code */ + +/* Bits 31..0 : Part code */ +#define FICR_INFO_PART_PART_Pos (0UL) /*!< Position of PART field. */ +#define FICR_INFO_PART_PART_Msk (0xFFFFFFFFUL << FICR_INFO_PART_PART_Pos) /*!< Bit mask of PART field. */ +#define FICR_INFO_PART_PART_N52840 (0x52840UL) /*!< nRF52840 */ +#define FICR_INFO_PART_PART_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ + +/* Register: FICR_INFO_VARIANT */ +/* Description: Part variant (hardware version and production configuration) */ + +/* Bits 31..0 : Part variant (hardware version and production configuration). Encoded as ASCII. */ +#define FICR_INFO_VARIANT_VARIANT_Pos (0UL) /*!< Position of VARIANT field. */ +#define FICR_INFO_VARIANT_VARIANT_Msk (0xFFFFFFFFUL << FICR_INFO_VARIANT_VARIANT_Pos) /*!< Bit mask of VARIANT field. */ +#define FICR_INFO_VARIANT_VARIANT_AAAA (0x41414141UL) /*!< AAAA */ +#define FICR_INFO_VARIANT_VARIANT_AAAB (0x41414142UL) /*!< AAAB */ +#define FICR_INFO_VARIANT_VARIANT_AAB0 (0x41414230UL) /*!< AAB0 */ +#define FICR_INFO_VARIANT_VARIANT_AABA (0x41414241UL) /*!< AABA */ +#define FICR_INFO_VARIANT_VARIANT_AABB (0x41414242UL) /*!< AABB */ +#define FICR_INFO_VARIANT_VARIANT_ABBA (0x41424241UL) /*!< ABBA */ +#define FICR_INFO_VARIANT_VARIANT_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ + +/* Register: FICR_INFO_PACKAGE */ +/* Description: Package option */ + +/* Bits 31..0 : Package option */ +#define FICR_INFO_PACKAGE_PACKAGE_Pos (0UL) /*!< Position of PACKAGE field. */ +#define FICR_INFO_PACKAGE_PACKAGE_Msk (0xFFFFFFFFUL << FICR_INFO_PACKAGE_PACKAGE_Pos) /*!< Bit mask of PACKAGE field. */ +#define FICR_INFO_PACKAGE_PACKAGE_QI (0x2004UL) /*!< QIxx - 73-pin aQFN */ +#define FICR_INFO_PACKAGE_PACKAGE_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ + +/* Register: FICR_INFO_RAM */ +/* Description: RAM variant */ + +/* Bits 31..0 : RAM variant */ +#define FICR_INFO_RAM_RAM_Pos (0UL) /*!< Position of RAM field. */ +#define FICR_INFO_RAM_RAM_Msk (0xFFFFFFFFUL << FICR_INFO_RAM_RAM_Pos) /*!< Bit mask of RAM field. */ +#define FICR_INFO_RAM_RAM_K16 (0x10UL) /*!< 16 kByte RAM */ +#define FICR_INFO_RAM_RAM_K32 (0x20UL) /*!< 32 kByte RAM */ +#define FICR_INFO_RAM_RAM_K64 (0x40UL) /*!< 64 kByte RAM */ +#define FICR_INFO_RAM_RAM_K128 (0x80UL) /*!< 128 kByte RAM */ +#define FICR_INFO_RAM_RAM_K256 (0x100UL) /*!< 256 kByte RAM */ +#define FICR_INFO_RAM_RAM_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ + +/* Register: FICR_INFO_FLASH */ +/* Description: Flash variant */ + +/* Bits 31..0 : Flash variant */ +#define FICR_INFO_FLASH_FLASH_Pos (0UL) /*!< Position of FLASH field. */ +#define FICR_INFO_FLASH_FLASH_Msk (0xFFFFFFFFUL << FICR_INFO_FLASH_FLASH_Pos) /*!< Bit mask of FLASH field. */ +#define FICR_INFO_FLASH_FLASH_K128 (0x80UL) /*!< 128 kByte FLASH */ +#define FICR_INFO_FLASH_FLASH_K256 (0x100UL) /*!< 256 kByte FLASH */ +#define FICR_INFO_FLASH_FLASH_K512 (0x200UL) /*!< 512 kByte FLASH */ +#define FICR_INFO_FLASH_FLASH_K1024 (0x400UL) /*!< 1 MByte FLASH */ +#define FICR_INFO_FLASH_FLASH_K2048 (0x800UL) /*!< 2 MByte FLASH */ +#define FICR_INFO_FLASH_FLASH_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ + +/* Register: FICR_TEMP_A0 */ +/* Description: Slope definition A0 */ + +/* Bits 11..0 : A (slope definition) register. */ +#define FICR_TEMP_A0_A_Pos (0UL) /*!< Position of A field. */ +#define FICR_TEMP_A0_A_Msk (0xFFFUL << FICR_TEMP_A0_A_Pos) /*!< Bit mask of A field. */ + +/* Register: FICR_TEMP_A1 */ +/* Description: Slope definition A1 */ + +/* Bits 11..0 : A (slope definition) register. */ +#define FICR_TEMP_A1_A_Pos (0UL) /*!< Position of A field. */ +#define FICR_TEMP_A1_A_Msk (0xFFFUL << FICR_TEMP_A1_A_Pos) /*!< Bit mask of A field. */ + +/* Register: FICR_TEMP_A2 */ +/* Description: Slope definition A2 */ + +/* Bits 11..0 : A (slope definition) register. */ +#define FICR_TEMP_A2_A_Pos (0UL) /*!< Position of A field. */ +#define FICR_TEMP_A2_A_Msk (0xFFFUL << FICR_TEMP_A2_A_Pos) /*!< Bit mask of A field. */ + +/* Register: FICR_TEMP_A3 */ +/* Description: Slope definition A3 */ + +/* Bits 11..0 : A (slope definition) register. */ +#define FICR_TEMP_A3_A_Pos (0UL) /*!< Position of A field. */ +#define FICR_TEMP_A3_A_Msk (0xFFFUL << FICR_TEMP_A3_A_Pos) /*!< Bit mask of A field. */ + +/* Register: FICR_TEMP_A4 */ +/* Description: Slope definition A4 */ + +/* Bits 11..0 : A (slope definition) register. */ +#define FICR_TEMP_A4_A_Pos (0UL) /*!< Position of A field. */ +#define FICR_TEMP_A4_A_Msk (0xFFFUL << FICR_TEMP_A4_A_Pos) /*!< Bit mask of A field. */ + +/* Register: FICR_TEMP_A5 */ +/* Description: Slope definition A5 */ + +/* Bits 11..0 : A (slope definition) register. */ +#define FICR_TEMP_A5_A_Pos (0UL) /*!< Position of A field. */ +#define FICR_TEMP_A5_A_Msk (0xFFFUL << FICR_TEMP_A5_A_Pos) /*!< Bit mask of A field. */ + +/* Register: FICR_TEMP_B0 */ +/* Description: Y-intercept B0 */ + +/* Bits 13..0 : B (y-intercept) */ +#define FICR_TEMP_B0_B_Pos (0UL) /*!< Position of B field. */ +#define FICR_TEMP_B0_B_Msk (0x3FFFUL << FICR_TEMP_B0_B_Pos) /*!< Bit mask of B field. */ + +/* Register: FICR_TEMP_B1 */ +/* Description: Y-intercept B1 */ + +/* Bits 13..0 : B (y-intercept) */ +#define FICR_TEMP_B1_B_Pos (0UL) /*!< Position of B field. */ +#define FICR_TEMP_B1_B_Msk (0x3FFFUL << FICR_TEMP_B1_B_Pos) /*!< Bit mask of B field. */ + +/* Register: FICR_TEMP_B2 */ +/* Description: Y-intercept B2 */ + +/* Bits 13..0 : B (y-intercept) */ +#define FICR_TEMP_B2_B_Pos (0UL) /*!< Position of B field. */ +#define FICR_TEMP_B2_B_Msk (0x3FFFUL << FICR_TEMP_B2_B_Pos) /*!< Bit mask of B field. */ + +/* Register: FICR_TEMP_B3 */ +/* Description: Y-intercept B3 */ + +/* Bits 13..0 : B (y-intercept) */ +#define FICR_TEMP_B3_B_Pos (0UL) /*!< Position of B field. */ +#define FICR_TEMP_B3_B_Msk (0x3FFFUL << FICR_TEMP_B3_B_Pos) /*!< Bit mask of B field. */ + +/* Register: FICR_TEMP_B4 */ +/* Description: Y-intercept B4 */ + +/* Bits 13..0 : B (y-intercept) */ +#define FICR_TEMP_B4_B_Pos (0UL) /*!< Position of B field. */ +#define FICR_TEMP_B4_B_Msk (0x3FFFUL << FICR_TEMP_B4_B_Pos) /*!< Bit mask of B field. */ + +/* Register: FICR_TEMP_B5 */ +/* Description: Y-intercept B5 */ + +/* Bits 13..0 : B (y-intercept) */ +#define FICR_TEMP_B5_B_Pos (0UL) /*!< Position of B field. */ +#define FICR_TEMP_B5_B_Msk (0x3FFFUL << FICR_TEMP_B5_B_Pos) /*!< Bit mask of B field. */ + +/* Register: FICR_TEMP_T0 */ +/* Description: Segment end T0 */ + +/* Bits 7..0 : T (segment end) register */ +#define FICR_TEMP_T0_T_Pos (0UL) /*!< Position of T field. */ +#define FICR_TEMP_T0_T_Msk (0xFFUL << FICR_TEMP_T0_T_Pos) /*!< Bit mask of T field. */ + +/* Register: FICR_TEMP_T1 */ +/* Description: Segment end T1 */ + +/* Bits 7..0 : T (segment end) register */ +#define FICR_TEMP_T1_T_Pos (0UL) /*!< Position of T field. */ +#define FICR_TEMP_T1_T_Msk (0xFFUL << FICR_TEMP_T1_T_Pos) /*!< Bit mask of T field. */ + +/* Register: FICR_TEMP_T2 */ +/* Description: Segment end T2 */ + +/* Bits 7..0 : T (segment end) register */ +#define FICR_TEMP_T2_T_Pos (0UL) /*!< Position of T field. */ +#define FICR_TEMP_T2_T_Msk (0xFFUL << FICR_TEMP_T2_T_Pos) /*!< Bit mask of T field. */ + +/* Register: FICR_TEMP_T3 */ +/* Description: Segment end T3 */ + +/* Bits 7..0 : T (segment end) register */ +#define FICR_TEMP_T3_T_Pos (0UL) /*!< Position of T field. */ +#define FICR_TEMP_T3_T_Msk (0xFFUL << FICR_TEMP_T3_T_Pos) /*!< Bit mask of T field. */ + +/* Register: FICR_TEMP_T4 */ +/* Description: Segment end T4 */ + +/* Bits 7..0 : T (segment end) register */ +#define FICR_TEMP_T4_T_Pos (0UL) /*!< Position of T field. */ +#define FICR_TEMP_T4_T_Msk (0xFFUL << FICR_TEMP_T4_T_Pos) /*!< Bit mask of T field. */ + +/* Register: FICR_NFC_TAGHEADER0 */ +/* Description: Default header for NFC tag. Software can read these values to populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */ + +/* Bits 31..24 : Unique identifier byte 3 */ +#define FICR_NFC_TAGHEADER0_UD3_Pos (24UL) /*!< Position of UD3 field. */ +#define FICR_NFC_TAGHEADER0_UD3_Msk (0xFFUL << FICR_NFC_TAGHEADER0_UD3_Pos) /*!< Bit mask of UD3 field. */ + +/* Bits 23..16 : Unique identifier byte 2 */ +#define FICR_NFC_TAGHEADER0_UD2_Pos (16UL) /*!< Position of UD2 field. */ +#define FICR_NFC_TAGHEADER0_UD2_Msk (0xFFUL << FICR_NFC_TAGHEADER0_UD2_Pos) /*!< Bit mask of UD2 field. */ + +/* Bits 15..8 : Unique identifier byte 1 */ +#define FICR_NFC_TAGHEADER0_UD1_Pos (8UL) /*!< Position of UD1 field. */ +#define FICR_NFC_TAGHEADER0_UD1_Msk (0xFFUL << FICR_NFC_TAGHEADER0_UD1_Pos) /*!< Bit mask of UD1 field. */ + +/* Bits 7..0 : Default Manufacturer ID: Nordic Semiconductor ASA has ICM 0x5F */ +#define FICR_NFC_TAGHEADER0_MFGID_Pos (0UL) /*!< Position of MFGID field. */ +#define FICR_NFC_TAGHEADER0_MFGID_Msk (0xFFUL << FICR_NFC_TAGHEADER0_MFGID_Pos) /*!< Bit mask of MFGID field. */ + +/* Register: FICR_NFC_TAGHEADER1 */ +/* Description: Default header for NFC tag. Software can read these values to populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */ + +/* Bits 31..24 : Unique identifier byte 7 */ +#define FICR_NFC_TAGHEADER1_UD7_Pos (24UL) /*!< Position of UD7 field. */ +#define FICR_NFC_TAGHEADER1_UD7_Msk (0xFFUL << FICR_NFC_TAGHEADER1_UD7_Pos) /*!< Bit mask of UD7 field. */ + +/* Bits 23..16 : Unique identifier byte 6 */ +#define FICR_NFC_TAGHEADER1_UD6_Pos (16UL) /*!< Position of UD6 field. */ +#define FICR_NFC_TAGHEADER1_UD6_Msk (0xFFUL << FICR_NFC_TAGHEADER1_UD6_Pos) /*!< Bit mask of UD6 field. */ + +/* Bits 15..8 : Unique identifier byte 5 */ +#define FICR_NFC_TAGHEADER1_UD5_Pos (8UL) /*!< Position of UD5 field. */ +#define FICR_NFC_TAGHEADER1_UD5_Msk (0xFFUL << FICR_NFC_TAGHEADER1_UD5_Pos) /*!< Bit mask of UD5 field. */ + +/* Bits 7..0 : Unique identifier byte 4 */ +#define FICR_NFC_TAGHEADER1_UD4_Pos (0UL) /*!< Position of UD4 field. */ +#define FICR_NFC_TAGHEADER1_UD4_Msk (0xFFUL << FICR_NFC_TAGHEADER1_UD4_Pos) /*!< Bit mask of UD4 field. */ + +/* Register: FICR_NFC_TAGHEADER2 */ +/* Description: Default header for NFC tag. Software can read these values to populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */ + +/* Bits 31..24 : Unique identifier byte 11 */ +#define FICR_NFC_TAGHEADER2_UD11_Pos (24UL) /*!< Position of UD11 field. */ +#define FICR_NFC_TAGHEADER2_UD11_Msk (0xFFUL << FICR_NFC_TAGHEADER2_UD11_Pos) /*!< Bit mask of UD11 field. */ + +/* Bits 23..16 : Unique identifier byte 10 */ +#define FICR_NFC_TAGHEADER2_UD10_Pos (16UL) /*!< Position of UD10 field. */ +#define FICR_NFC_TAGHEADER2_UD10_Msk (0xFFUL << FICR_NFC_TAGHEADER2_UD10_Pos) /*!< Bit mask of UD10 field. */ + +/* Bits 15..8 : Unique identifier byte 9 */ +#define FICR_NFC_TAGHEADER2_UD9_Pos (8UL) /*!< Position of UD9 field. */ +#define FICR_NFC_TAGHEADER2_UD9_Msk (0xFFUL << FICR_NFC_TAGHEADER2_UD9_Pos) /*!< Bit mask of UD9 field. */ + +/* Bits 7..0 : Unique identifier byte 8 */ +#define FICR_NFC_TAGHEADER2_UD8_Pos (0UL) /*!< Position of UD8 field. */ +#define FICR_NFC_TAGHEADER2_UD8_Msk (0xFFUL << FICR_NFC_TAGHEADER2_UD8_Pos) /*!< Bit mask of UD8 field. */ + +/* Register: FICR_NFC_TAGHEADER3 */ +/* Description: Default header for NFC tag. Software can read these values to populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */ + +/* Bits 31..24 : Unique identifier byte 15 */ +#define FICR_NFC_TAGHEADER3_UD15_Pos (24UL) /*!< Position of UD15 field. */ +#define FICR_NFC_TAGHEADER3_UD15_Msk (0xFFUL << FICR_NFC_TAGHEADER3_UD15_Pos) /*!< Bit mask of UD15 field. */ + +/* Bits 23..16 : Unique identifier byte 14 */ +#define FICR_NFC_TAGHEADER3_UD14_Pos (16UL) /*!< Position of UD14 field. */ +#define FICR_NFC_TAGHEADER3_UD14_Msk (0xFFUL << FICR_NFC_TAGHEADER3_UD14_Pos) /*!< Bit mask of UD14 field. */ + +/* Bits 15..8 : Unique identifier byte 13 */ +#define FICR_NFC_TAGHEADER3_UD13_Pos (8UL) /*!< Position of UD13 field. */ +#define FICR_NFC_TAGHEADER3_UD13_Msk (0xFFUL << FICR_NFC_TAGHEADER3_UD13_Pos) /*!< Bit mask of UD13 field. */ + +/* Bits 7..0 : Unique identifier byte 12 */ +#define FICR_NFC_TAGHEADER3_UD12_Pos (0UL) /*!< Position of UD12 field. */ +#define FICR_NFC_TAGHEADER3_UD12_Msk (0xFFUL << FICR_NFC_TAGHEADER3_UD12_Pos) /*!< Bit mask of UD12 field. */ + + +/* Peripheral: GPIOTE */ +/* Description: GPIO Tasks and Events */ + +/* Register: GPIOTE_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 31 : Write '1' to Enable interrupt for PORT event */ +#define GPIOTE_INTENSET_PORT_Pos (31UL) /*!< Position of PORT field. */ +#define GPIOTE_INTENSET_PORT_Msk (0x1UL << GPIOTE_INTENSET_PORT_Pos) /*!< Bit mask of PORT field. */ +#define GPIOTE_INTENSET_PORT_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENSET_PORT_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENSET_PORT_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for IN[7] event */ +#define GPIOTE_INTENSET_IN7_Pos (7UL) /*!< Position of IN7 field. */ +#define GPIOTE_INTENSET_IN7_Msk (0x1UL << GPIOTE_INTENSET_IN7_Pos) /*!< Bit mask of IN7 field. */ +#define GPIOTE_INTENSET_IN7_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENSET_IN7_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENSET_IN7_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for IN[6] event */ +#define GPIOTE_INTENSET_IN6_Pos (6UL) /*!< Position of IN6 field. */ +#define GPIOTE_INTENSET_IN6_Msk (0x1UL << GPIOTE_INTENSET_IN6_Pos) /*!< Bit mask of IN6 field. */ +#define GPIOTE_INTENSET_IN6_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENSET_IN6_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENSET_IN6_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for IN[5] event */ +#define GPIOTE_INTENSET_IN5_Pos (5UL) /*!< Position of IN5 field. */ +#define GPIOTE_INTENSET_IN5_Msk (0x1UL << GPIOTE_INTENSET_IN5_Pos) /*!< Bit mask of IN5 field. */ +#define GPIOTE_INTENSET_IN5_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENSET_IN5_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENSET_IN5_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for IN[4] event */ +#define GPIOTE_INTENSET_IN4_Pos (4UL) /*!< Position of IN4 field. */ +#define GPIOTE_INTENSET_IN4_Msk (0x1UL << GPIOTE_INTENSET_IN4_Pos) /*!< Bit mask of IN4 field. */ +#define GPIOTE_INTENSET_IN4_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENSET_IN4_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENSET_IN4_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for IN[3] event */ +#define GPIOTE_INTENSET_IN3_Pos (3UL) /*!< Position of IN3 field. */ +#define GPIOTE_INTENSET_IN3_Msk (0x1UL << GPIOTE_INTENSET_IN3_Pos) /*!< Bit mask of IN3 field. */ +#define GPIOTE_INTENSET_IN3_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENSET_IN3_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENSET_IN3_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for IN[2] event */ +#define GPIOTE_INTENSET_IN2_Pos (2UL) /*!< Position of IN2 field. */ +#define GPIOTE_INTENSET_IN2_Msk (0x1UL << GPIOTE_INTENSET_IN2_Pos) /*!< Bit mask of IN2 field. */ +#define GPIOTE_INTENSET_IN2_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENSET_IN2_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENSET_IN2_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for IN[1] event */ +#define GPIOTE_INTENSET_IN1_Pos (1UL) /*!< Position of IN1 field. */ +#define GPIOTE_INTENSET_IN1_Msk (0x1UL << GPIOTE_INTENSET_IN1_Pos) /*!< Bit mask of IN1 field. */ +#define GPIOTE_INTENSET_IN1_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENSET_IN1_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENSET_IN1_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for IN[0] event */ +#define GPIOTE_INTENSET_IN0_Pos (0UL) /*!< Position of IN0 field. */ +#define GPIOTE_INTENSET_IN0_Msk (0x1UL << GPIOTE_INTENSET_IN0_Pos) /*!< Bit mask of IN0 field. */ +#define GPIOTE_INTENSET_IN0_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENSET_IN0_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENSET_IN0_Set (1UL) /*!< Enable */ + +/* Register: GPIOTE_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 31 : Write '1' to Disable interrupt for PORT event */ +#define GPIOTE_INTENCLR_PORT_Pos (31UL) /*!< Position of PORT field. */ +#define GPIOTE_INTENCLR_PORT_Msk (0x1UL << GPIOTE_INTENCLR_PORT_Pos) /*!< Bit mask of PORT field. */ +#define GPIOTE_INTENCLR_PORT_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENCLR_PORT_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENCLR_PORT_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for IN[7] event */ +#define GPIOTE_INTENCLR_IN7_Pos (7UL) /*!< Position of IN7 field. */ +#define GPIOTE_INTENCLR_IN7_Msk (0x1UL << GPIOTE_INTENCLR_IN7_Pos) /*!< Bit mask of IN7 field. */ +#define GPIOTE_INTENCLR_IN7_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENCLR_IN7_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENCLR_IN7_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for IN[6] event */ +#define GPIOTE_INTENCLR_IN6_Pos (6UL) /*!< Position of IN6 field. */ +#define GPIOTE_INTENCLR_IN6_Msk (0x1UL << GPIOTE_INTENCLR_IN6_Pos) /*!< Bit mask of IN6 field. */ +#define GPIOTE_INTENCLR_IN6_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENCLR_IN6_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENCLR_IN6_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for IN[5] event */ +#define GPIOTE_INTENCLR_IN5_Pos (5UL) /*!< Position of IN5 field. */ +#define GPIOTE_INTENCLR_IN5_Msk (0x1UL << GPIOTE_INTENCLR_IN5_Pos) /*!< Bit mask of IN5 field. */ +#define GPIOTE_INTENCLR_IN5_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENCLR_IN5_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENCLR_IN5_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for IN[4] event */ +#define GPIOTE_INTENCLR_IN4_Pos (4UL) /*!< Position of IN4 field. */ +#define GPIOTE_INTENCLR_IN4_Msk (0x1UL << GPIOTE_INTENCLR_IN4_Pos) /*!< Bit mask of IN4 field. */ +#define GPIOTE_INTENCLR_IN4_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENCLR_IN4_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENCLR_IN4_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for IN[3] event */ +#define GPIOTE_INTENCLR_IN3_Pos (3UL) /*!< Position of IN3 field. */ +#define GPIOTE_INTENCLR_IN3_Msk (0x1UL << GPIOTE_INTENCLR_IN3_Pos) /*!< Bit mask of IN3 field. */ +#define GPIOTE_INTENCLR_IN3_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENCLR_IN3_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENCLR_IN3_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for IN[2] event */ +#define GPIOTE_INTENCLR_IN2_Pos (2UL) /*!< Position of IN2 field. */ +#define GPIOTE_INTENCLR_IN2_Msk (0x1UL << GPIOTE_INTENCLR_IN2_Pos) /*!< Bit mask of IN2 field. */ +#define GPIOTE_INTENCLR_IN2_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENCLR_IN2_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENCLR_IN2_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for IN[1] event */ +#define GPIOTE_INTENCLR_IN1_Pos (1UL) /*!< Position of IN1 field. */ +#define GPIOTE_INTENCLR_IN1_Msk (0x1UL << GPIOTE_INTENCLR_IN1_Pos) /*!< Bit mask of IN1 field. */ +#define GPIOTE_INTENCLR_IN1_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENCLR_IN1_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENCLR_IN1_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for IN[0] event */ +#define GPIOTE_INTENCLR_IN0_Pos (0UL) /*!< Position of IN0 field. */ +#define GPIOTE_INTENCLR_IN0_Msk (0x1UL << GPIOTE_INTENCLR_IN0_Pos) /*!< Bit mask of IN0 field. */ +#define GPIOTE_INTENCLR_IN0_Disabled (0UL) /*!< Read: Disabled */ +#define GPIOTE_INTENCLR_IN0_Enabled (1UL) /*!< Read: Enabled */ +#define GPIOTE_INTENCLR_IN0_Clear (1UL) /*!< Disable */ + +/* Register: GPIOTE_CONFIG */ +/* Description: Description collection[0]: Configuration for OUT[n], SET[n] and CLR[n] tasks and IN[n] event */ + +/* Bit 20 : When in task mode: Initial value of the output when the GPIOTE channel is configured. When in event mode: No effect. */ +#define GPIOTE_CONFIG_OUTINIT_Pos (20UL) /*!< Position of OUTINIT field. */ +#define GPIOTE_CONFIG_OUTINIT_Msk (0x1UL << GPIOTE_CONFIG_OUTINIT_Pos) /*!< Bit mask of OUTINIT field. */ +#define GPIOTE_CONFIG_OUTINIT_Low (0UL) /*!< Task mode: Initial value of pin before task triggering is low */ +#define GPIOTE_CONFIG_OUTINIT_High (1UL) /*!< Task mode: Initial value of pin before task triggering is high */ + +/* Bits 17..16 : When In task mode: Operation to be performed on output when OUT[n] task is triggered. When In event mode: Operation on input that shall trigger IN[n] event. */ +#define GPIOTE_CONFIG_POLARITY_Pos (16UL) /*!< Position of POLARITY field. */ +#define GPIOTE_CONFIG_POLARITY_Msk (0x3UL << GPIOTE_CONFIG_POLARITY_Pos) /*!< Bit mask of POLARITY field. */ +#define GPIOTE_CONFIG_POLARITY_None (0UL) /*!< Task mode: No effect on pin from OUT[n] task. Event mode: no IN[n] event generated on pin activity. */ +#define GPIOTE_CONFIG_POLARITY_LoToHi (1UL) /*!< Task mode: Set pin from OUT[n] task. Event mode: Generate IN[n] event when rising edge on pin. */ +#define GPIOTE_CONFIG_POLARITY_HiToLo (2UL) /*!< Task mode: Clear pin from OUT[n] task. Event mode: Generate IN[n] event when falling edge on pin. */ +#define GPIOTE_CONFIG_POLARITY_Toggle (3UL) /*!< Task mode: Toggle pin from OUT[n]. Event mode: Generate IN[n] when any change on pin. */ + +/* Bit 13 : Port number */ +#define GPIOTE_CONFIG_PORT_Pos (13UL) /*!< Position of PORT field. */ +#define GPIOTE_CONFIG_PORT_Msk (0x1UL << GPIOTE_CONFIG_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 12..8 : GPIO number associated with SET[n], CLR[n] and OUT[n] tasks and IN[n] event */ +#define GPIOTE_CONFIG_PSEL_Pos (8UL) /*!< Position of PSEL field. */ +#define GPIOTE_CONFIG_PSEL_Msk (0x1FUL << GPIOTE_CONFIG_PSEL_Pos) /*!< Bit mask of PSEL field. */ + +/* Bits 1..0 : Mode */ +#define GPIOTE_CONFIG_MODE_Pos (0UL) /*!< Position of MODE field. */ +#define GPIOTE_CONFIG_MODE_Msk (0x3UL << GPIOTE_CONFIG_MODE_Pos) /*!< Bit mask of MODE field. */ +#define GPIOTE_CONFIG_MODE_Disabled (0UL) /*!< Disabled. Pin specified by PSEL will not be acquired by the GPIOTE module. */ +#define GPIOTE_CONFIG_MODE_Event (1UL) /*!< Event mode */ +#define GPIOTE_CONFIG_MODE_Task (3UL) /*!< Task mode */ + + +/* Peripheral: I2S */ +/* Description: Inter-IC Sound */ + +/* Register: I2S_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 5 : Enable or disable interrupt for TXPTRUPD event */ +#define I2S_INTEN_TXPTRUPD_Pos (5UL) /*!< Position of TXPTRUPD field. */ +#define I2S_INTEN_TXPTRUPD_Msk (0x1UL << I2S_INTEN_TXPTRUPD_Pos) /*!< Bit mask of TXPTRUPD field. */ +#define I2S_INTEN_TXPTRUPD_Disabled (0UL) /*!< Disable */ +#define I2S_INTEN_TXPTRUPD_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for STOPPED event */ +#define I2S_INTEN_STOPPED_Pos (2UL) /*!< Position of STOPPED field. */ +#define I2S_INTEN_STOPPED_Msk (0x1UL << I2S_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define I2S_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ +#define I2S_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for RXPTRUPD event */ +#define I2S_INTEN_RXPTRUPD_Pos (1UL) /*!< Position of RXPTRUPD field. */ +#define I2S_INTEN_RXPTRUPD_Msk (0x1UL << I2S_INTEN_RXPTRUPD_Pos) /*!< Bit mask of RXPTRUPD field. */ +#define I2S_INTEN_RXPTRUPD_Disabled (0UL) /*!< Disable */ +#define I2S_INTEN_RXPTRUPD_Enabled (1UL) /*!< Enable */ + +/* Register: I2S_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 5 : Write '1' to Enable interrupt for TXPTRUPD event */ +#define I2S_INTENSET_TXPTRUPD_Pos (5UL) /*!< Position of TXPTRUPD field. */ +#define I2S_INTENSET_TXPTRUPD_Msk (0x1UL << I2S_INTENSET_TXPTRUPD_Pos) /*!< Bit mask of TXPTRUPD field. */ +#define I2S_INTENSET_TXPTRUPD_Disabled (0UL) /*!< Read: Disabled */ +#define I2S_INTENSET_TXPTRUPD_Enabled (1UL) /*!< Read: Enabled */ +#define I2S_INTENSET_TXPTRUPD_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for STOPPED event */ +#define I2S_INTENSET_STOPPED_Pos (2UL) /*!< Position of STOPPED field. */ +#define I2S_INTENSET_STOPPED_Msk (0x1UL << I2S_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define I2S_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define I2S_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define I2S_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for RXPTRUPD event */ +#define I2S_INTENSET_RXPTRUPD_Pos (1UL) /*!< Position of RXPTRUPD field. */ +#define I2S_INTENSET_RXPTRUPD_Msk (0x1UL << I2S_INTENSET_RXPTRUPD_Pos) /*!< Bit mask of RXPTRUPD field. */ +#define I2S_INTENSET_RXPTRUPD_Disabled (0UL) /*!< Read: Disabled */ +#define I2S_INTENSET_RXPTRUPD_Enabled (1UL) /*!< Read: Enabled */ +#define I2S_INTENSET_RXPTRUPD_Set (1UL) /*!< Enable */ + +/* Register: I2S_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 5 : Write '1' to Disable interrupt for TXPTRUPD event */ +#define I2S_INTENCLR_TXPTRUPD_Pos (5UL) /*!< Position of TXPTRUPD field. */ +#define I2S_INTENCLR_TXPTRUPD_Msk (0x1UL << I2S_INTENCLR_TXPTRUPD_Pos) /*!< Bit mask of TXPTRUPD field. */ +#define I2S_INTENCLR_TXPTRUPD_Disabled (0UL) /*!< Read: Disabled */ +#define I2S_INTENCLR_TXPTRUPD_Enabled (1UL) /*!< Read: Enabled */ +#define I2S_INTENCLR_TXPTRUPD_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for STOPPED event */ +#define I2S_INTENCLR_STOPPED_Pos (2UL) /*!< Position of STOPPED field. */ +#define I2S_INTENCLR_STOPPED_Msk (0x1UL << I2S_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define I2S_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define I2S_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define I2S_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for RXPTRUPD event */ +#define I2S_INTENCLR_RXPTRUPD_Pos (1UL) /*!< Position of RXPTRUPD field. */ +#define I2S_INTENCLR_RXPTRUPD_Msk (0x1UL << I2S_INTENCLR_RXPTRUPD_Pos) /*!< Bit mask of RXPTRUPD field. */ +#define I2S_INTENCLR_RXPTRUPD_Disabled (0UL) /*!< Read: Disabled */ +#define I2S_INTENCLR_RXPTRUPD_Enabled (1UL) /*!< Read: Enabled */ +#define I2S_INTENCLR_RXPTRUPD_Clear (1UL) /*!< Disable */ + +/* Register: I2S_ENABLE */ +/* Description: Enable I2S module. */ + +/* Bit 0 : Enable I2S module. */ +#define I2S_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define I2S_ENABLE_ENABLE_Msk (0x1UL << I2S_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define I2S_ENABLE_ENABLE_Disabled (0UL) /*!< Disable */ +#define I2S_ENABLE_ENABLE_Enabled (1UL) /*!< Enable */ + +/* Register: I2S_CONFIG_MODE */ +/* Description: I2S mode. */ + +/* Bit 0 : I2S mode. */ +#define I2S_CONFIG_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */ +#define I2S_CONFIG_MODE_MODE_Msk (0x1UL << I2S_CONFIG_MODE_MODE_Pos) /*!< Bit mask of MODE field. */ +#define I2S_CONFIG_MODE_MODE_Master (0UL) /*!< Master mode. SCK and LRCK generated from internal master clcok (MCK) and output on pins defined by PSEL.xxx. */ +#define I2S_CONFIG_MODE_MODE_Slave (1UL) /*!< Slave mode. SCK and LRCK generated by external master and received on pins defined by PSEL.xxx */ + +/* Register: I2S_CONFIG_RXEN */ +/* Description: Reception (RX) enable. */ + +/* Bit 0 : Reception (RX) enable. */ +#define I2S_CONFIG_RXEN_RXEN_Pos (0UL) /*!< Position of RXEN field. */ +#define I2S_CONFIG_RXEN_RXEN_Msk (0x1UL << I2S_CONFIG_RXEN_RXEN_Pos) /*!< Bit mask of RXEN field. */ +#define I2S_CONFIG_RXEN_RXEN_Disabled (0UL) /*!< Reception disabled and now data will be written to the RXD.PTR address. */ +#define I2S_CONFIG_RXEN_RXEN_Enabled (1UL) /*!< Reception enabled. */ + +/* Register: I2S_CONFIG_TXEN */ +/* Description: Transmission (TX) enable. */ + +/* Bit 0 : Transmission (TX) enable. */ +#define I2S_CONFIG_TXEN_TXEN_Pos (0UL) /*!< Position of TXEN field. */ +#define I2S_CONFIG_TXEN_TXEN_Msk (0x1UL << I2S_CONFIG_TXEN_TXEN_Pos) /*!< Bit mask of TXEN field. */ +#define I2S_CONFIG_TXEN_TXEN_Disabled (0UL) /*!< Transmission disabled and now data will be read from the RXD.TXD address. */ +#define I2S_CONFIG_TXEN_TXEN_Enabled (1UL) /*!< Transmission enabled. */ + +/* Register: I2S_CONFIG_MCKEN */ +/* Description: Master clock generator enable. */ + +/* Bit 0 : Master clock generator enable. */ +#define I2S_CONFIG_MCKEN_MCKEN_Pos (0UL) /*!< Position of MCKEN field. */ +#define I2S_CONFIG_MCKEN_MCKEN_Msk (0x1UL << I2S_CONFIG_MCKEN_MCKEN_Pos) /*!< Bit mask of MCKEN field. */ +#define I2S_CONFIG_MCKEN_MCKEN_Disabled (0UL) /*!< Master clock generator disabled and PSEL.MCK not connected(available as GPIO). */ +#define I2S_CONFIG_MCKEN_MCKEN_Enabled (1UL) /*!< Master clock generator running and MCK output on PSEL.MCK. */ + +/* Register: I2S_CONFIG_MCKFREQ */ +/* Description: Master clock generator frequency. */ + +/* Bits 31..0 : Master clock generator frequency. */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_Pos (0UL) /*!< Position of MCKFREQ field. */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_Msk (0xFFFFFFFFUL << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos) /*!< Bit mask of MCKFREQ field. */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV125 (0x020C0000UL) /*!< 32 MHz / 125 = 0.256 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV63 (0x04100000UL) /*!< 32 MHz / 63 = 0.5079365 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV42 (0x06000000UL) /*!< 32 MHz / 42 = 0.7619048 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV32 (0x08000000UL) /*!< 32 MHz / 32 = 1.0 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31 (0x08400000UL) /*!< 32 MHz / 31 = 1.0322581 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV30 (0x08800000UL) /*!< 32 MHz / 30 = 1.0666667 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV23 (0x0B000000UL) /*!< 32 MHz / 23 = 1.3913043 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV21 (0x0C000000UL) /*!< 32 MHz / 21 = 1.5238095 */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16 (0x10000000UL) /*!< 32 MHz / 16 = 2.0 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV15 (0x11000000UL) /*!< 32 MHz / 15 = 2.1333333 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV11 (0x16000000UL) /*!< 32 MHz / 11 = 2.9090909 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV10 (0x18000000UL) /*!< 32 MHz / 10 = 3.2 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8 (0x20000000UL) /*!< 32 MHz / 8 = 4.0 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV6 (0x28000000UL) /*!< 32 MHz / 6 = 5.3333333 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV5 (0x30000000UL) /*!< 32 MHz / 5 = 6.4 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV4 (0x40000000UL) /*!< 32 MHz / 4 = 8.0 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV3 (0x50000000UL) /*!< 32 MHz / 3 = 10.6666667 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2 (0x80000000UL) /*!< 32 MHz / 2 = 16.0 MHz */ + +/* Register: I2S_CONFIG_RATIO */ +/* Description: MCK / LRCK ratio. */ + +/* Bits 3..0 : MCK / LRCK ratio. */ +#define I2S_CONFIG_RATIO_RATIO_Pos (0UL) /*!< Position of RATIO field. */ +#define I2S_CONFIG_RATIO_RATIO_Msk (0xFUL << I2S_CONFIG_RATIO_RATIO_Pos) /*!< Bit mask of RATIO field. */ +#define I2S_CONFIG_RATIO_RATIO_32X (0UL) /*!< LRCK = MCK / 32 */ +#define I2S_CONFIG_RATIO_RATIO_48X (1UL) /*!< LRCK = MCK / 48 */ +#define I2S_CONFIG_RATIO_RATIO_64X (2UL) /*!< LRCK = MCK / 64 */ +#define I2S_CONFIG_RATIO_RATIO_96X (3UL) /*!< LRCK = MCK / 96 */ +#define I2S_CONFIG_RATIO_RATIO_128X (4UL) /*!< LRCK = MCK / 128 */ +#define I2S_CONFIG_RATIO_RATIO_192X (5UL) /*!< LRCK = MCK / 192 */ +#define I2S_CONFIG_RATIO_RATIO_256X (6UL) /*!< LRCK = MCK / 256 */ +#define I2S_CONFIG_RATIO_RATIO_384X (7UL) /*!< LRCK = MCK / 384 */ +#define I2S_CONFIG_RATIO_RATIO_512X (8UL) /*!< LRCK = MCK / 512 */ + +/* Register: I2S_CONFIG_SWIDTH */ +/* Description: Sample width. */ + +/* Bits 1..0 : Sample width. */ +#define I2S_CONFIG_SWIDTH_SWIDTH_Pos (0UL) /*!< Position of SWIDTH field. */ +#define I2S_CONFIG_SWIDTH_SWIDTH_Msk (0x3UL << I2S_CONFIG_SWIDTH_SWIDTH_Pos) /*!< Bit mask of SWIDTH field. */ +#define I2S_CONFIG_SWIDTH_SWIDTH_8Bit (0UL) /*!< 8 bit. */ +#define I2S_CONFIG_SWIDTH_SWIDTH_16Bit (1UL) /*!< 16 bit. */ +#define I2S_CONFIG_SWIDTH_SWIDTH_24Bit (2UL) /*!< 24 bit. */ + +/* Register: I2S_CONFIG_ALIGN */ +/* Description: Alignment of sample within a frame. */ + +/* Bit 0 : Alignment of sample within a frame. */ +#define I2S_CONFIG_ALIGN_ALIGN_Pos (0UL) /*!< Position of ALIGN field. */ +#define I2S_CONFIG_ALIGN_ALIGN_Msk (0x1UL << I2S_CONFIG_ALIGN_ALIGN_Pos) /*!< Bit mask of ALIGN field. */ +#define I2S_CONFIG_ALIGN_ALIGN_Left (0UL) /*!< Left-aligned. */ +#define I2S_CONFIG_ALIGN_ALIGN_Right (1UL) /*!< Right-aligned. */ + +/* Register: I2S_CONFIG_FORMAT */ +/* Description: Frame format. */ + +/* Bit 0 : Frame format. */ +#define I2S_CONFIG_FORMAT_FORMAT_Pos (0UL) /*!< Position of FORMAT field. */ +#define I2S_CONFIG_FORMAT_FORMAT_Msk (0x1UL << I2S_CONFIG_FORMAT_FORMAT_Pos) /*!< Bit mask of FORMAT field. */ +#define I2S_CONFIG_FORMAT_FORMAT_I2S (0UL) /*!< Original I2S format. */ +#define I2S_CONFIG_FORMAT_FORMAT_Aligned (1UL) /*!< Alternate (left- or right-aligned) format. */ + +/* Register: I2S_CONFIG_CHANNELS */ +/* Description: Enable channels. */ + +/* Bits 1..0 : Enable channels. */ +#define I2S_CONFIG_CHANNELS_CHANNELS_Pos (0UL) /*!< Position of CHANNELS field. */ +#define I2S_CONFIG_CHANNELS_CHANNELS_Msk (0x3UL << I2S_CONFIG_CHANNELS_CHANNELS_Pos) /*!< Bit mask of CHANNELS field. */ +#define I2S_CONFIG_CHANNELS_CHANNELS_Stereo (0UL) /*!< Stereo. */ +#define I2S_CONFIG_CHANNELS_CHANNELS_Left (1UL) /*!< Left only. */ +#define I2S_CONFIG_CHANNELS_CHANNELS_Right (2UL) /*!< Right only. */ + +/* Register: I2S_RXD_PTR */ +/* Description: Receive buffer RAM start address. */ + +/* Bits 31..0 : Receive buffer Data RAM start address. When receiving, words containing samples will be written to this address. This address is a word aligned Data RAM address. */ +#define I2S_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define I2S_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << I2S_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: I2S_TXD_PTR */ +/* Description: Transmit buffer RAM start address. */ + +/* Bits 31..0 : Transmit buffer Data RAM start address. When transmitting, words containing samples will be fetched from this address. This address is a word aligned Data RAM address. */ +#define I2S_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define I2S_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << I2S_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: I2S_RXTXD_MAXCNT */ +/* Description: Size of RXD and TXD buffers. */ + +/* Bits 13..0 : Size of RXD and TXD buffers in number of 32 bit words. */ +#define I2S_RXTXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define I2S_RXTXD_MAXCNT_MAXCNT_Msk (0x3FFFUL << I2S_RXTXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: I2S_PSEL_MCK */ +/* Description: Pin select for MCK signal. */ + +/* Bit 31 : Connection */ +#define I2S_PSEL_MCK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define I2S_PSEL_MCK_CONNECT_Msk (0x1UL << I2S_PSEL_MCK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define I2S_PSEL_MCK_CONNECT_Connected (0UL) /*!< Connect */ +#define I2S_PSEL_MCK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define I2S_PSEL_MCK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define I2S_PSEL_MCK_PORT_Msk (0x1UL << I2S_PSEL_MCK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define I2S_PSEL_MCK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define I2S_PSEL_MCK_PIN_Msk (0x1FUL << I2S_PSEL_MCK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: I2S_PSEL_SCK */ +/* Description: Pin select for SCK signal. */ + +/* Bit 31 : Connection */ +#define I2S_PSEL_SCK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define I2S_PSEL_SCK_CONNECT_Msk (0x1UL << I2S_PSEL_SCK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define I2S_PSEL_SCK_CONNECT_Connected (0UL) /*!< Connect */ +#define I2S_PSEL_SCK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define I2S_PSEL_SCK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define I2S_PSEL_SCK_PORT_Msk (0x1UL << I2S_PSEL_SCK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define I2S_PSEL_SCK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define I2S_PSEL_SCK_PIN_Msk (0x1FUL << I2S_PSEL_SCK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: I2S_PSEL_LRCK */ +/* Description: Pin select for LRCK signal. */ + +/* Bit 31 : Connection */ +#define I2S_PSEL_LRCK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define I2S_PSEL_LRCK_CONNECT_Msk (0x1UL << I2S_PSEL_LRCK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define I2S_PSEL_LRCK_CONNECT_Connected (0UL) /*!< Connect */ +#define I2S_PSEL_LRCK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define I2S_PSEL_LRCK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define I2S_PSEL_LRCK_PORT_Msk (0x1UL << I2S_PSEL_LRCK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define I2S_PSEL_LRCK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define I2S_PSEL_LRCK_PIN_Msk (0x1FUL << I2S_PSEL_LRCK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: I2S_PSEL_SDIN */ +/* Description: Pin select for SDIN signal. */ + +/* Bit 31 : Connection */ +#define I2S_PSEL_SDIN_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define I2S_PSEL_SDIN_CONNECT_Msk (0x1UL << I2S_PSEL_SDIN_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define I2S_PSEL_SDIN_CONNECT_Connected (0UL) /*!< Connect */ +#define I2S_PSEL_SDIN_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define I2S_PSEL_SDIN_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define I2S_PSEL_SDIN_PORT_Msk (0x1UL << I2S_PSEL_SDIN_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define I2S_PSEL_SDIN_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define I2S_PSEL_SDIN_PIN_Msk (0x1FUL << I2S_PSEL_SDIN_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: I2S_PSEL_SDOUT */ +/* Description: Pin select for SDOUT signal. */ + +/* Bit 31 : Connection */ +#define I2S_PSEL_SDOUT_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define I2S_PSEL_SDOUT_CONNECT_Msk (0x1UL << I2S_PSEL_SDOUT_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define I2S_PSEL_SDOUT_CONNECT_Connected (0UL) /*!< Connect */ +#define I2S_PSEL_SDOUT_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define I2S_PSEL_SDOUT_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define I2S_PSEL_SDOUT_PORT_Msk (0x1UL << I2S_PSEL_SDOUT_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define I2S_PSEL_SDOUT_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define I2S_PSEL_SDOUT_PIN_Msk (0x1FUL << I2S_PSEL_SDOUT_PIN_Pos) /*!< Bit mask of PIN field. */ + + +/* Peripheral: LPCOMP */ +/* Description: Low Power Comparator */ + +/* Register: LPCOMP_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 4 : Shortcut between CROSS event and STOP task */ +#define LPCOMP_SHORTS_CROSS_STOP_Pos (4UL) /*!< Position of CROSS_STOP field. */ +#define LPCOMP_SHORTS_CROSS_STOP_Msk (0x1UL << LPCOMP_SHORTS_CROSS_STOP_Pos) /*!< Bit mask of CROSS_STOP field. */ +#define LPCOMP_SHORTS_CROSS_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define LPCOMP_SHORTS_CROSS_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between UP event and STOP task */ +#define LPCOMP_SHORTS_UP_STOP_Pos (3UL) /*!< Position of UP_STOP field. */ +#define LPCOMP_SHORTS_UP_STOP_Msk (0x1UL << LPCOMP_SHORTS_UP_STOP_Pos) /*!< Bit mask of UP_STOP field. */ +#define LPCOMP_SHORTS_UP_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define LPCOMP_SHORTS_UP_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 2 : Shortcut between DOWN event and STOP task */ +#define LPCOMP_SHORTS_DOWN_STOP_Pos (2UL) /*!< Position of DOWN_STOP field. */ +#define LPCOMP_SHORTS_DOWN_STOP_Msk (0x1UL << LPCOMP_SHORTS_DOWN_STOP_Pos) /*!< Bit mask of DOWN_STOP field. */ +#define LPCOMP_SHORTS_DOWN_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define LPCOMP_SHORTS_DOWN_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between READY event and STOP task */ +#define LPCOMP_SHORTS_READY_STOP_Pos (1UL) /*!< Position of READY_STOP field. */ +#define LPCOMP_SHORTS_READY_STOP_Msk (0x1UL << LPCOMP_SHORTS_READY_STOP_Pos) /*!< Bit mask of READY_STOP field. */ +#define LPCOMP_SHORTS_READY_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define LPCOMP_SHORTS_READY_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between READY event and SAMPLE task */ +#define LPCOMP_SHORTS_READY_SAMPLE_Pos (0UL) /*!< Position of READY_SAMPLE field. */ +#define LPCOMP_SHORTS_READY_SAMPLE_Msk (0x1UL << LPCOMP_SHORTS_READY_SAMPLE_Pos) /*!< Bit mask of READY_SAMPLE field. */ +#define LPCOMP_SHORTS_READY_SAMPLE_Disabled (0UL) /*!< Disable shortcut */ +#define LPCOMP_SHORTS_READY_SAMPLE_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: LPCOMP_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 3 : Write '1' to Enable interrupt for CROSS event */ +#define LPCOMP_INTENSET_CROSS_Pos (3UL) /*!< Position of CROSS field. */ +#define LPCOMP_INTENSET_CROSS_Msk (0x1UL << LPCOMP_INTENSET_CROSS_Pos) /*!< Bit mask of CROSS field. */ +#define LPCOMP_INTENSET_CROSS_Disabled (0UL) /*!< Read: Disabled */ +#define LPCOMP_INTENSET_CROSS_Enabled (1UL) /*!< Read: Enabled */ +#define LPCOMP_INTENSET_CROSS_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for UP event */ +#define LPCOMP_INTENSET_UP_Pos (2UL) /*!< Position of UP field. */ +#define LPCOMP_INTENSET_UP_Msk (0x1UL << LPCOMP_INTENSET_UP_Pos) /*!< Bit mask of UP field. */ +#define LPCOMP_INTENSET_UP_Disabled (0UL) /*!< Read: Disabled */ +#define LPCOMP_INTENSET_UP_Enabled (1UL) /*!< Read: Enabled */ +#define LPCOMP_INTENSET_UP_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for DOWN event */ +#define LPCOMP_INTENSET_DOWN_Pos (1UL) /*!< Position of DOWN field. */ +#define LPCOMP_INTENSET_DOWN_Msk (0x1UL << LPCOMP_INTENSET_DOWN_Pos) /*!< Bit mask of DOWN field. */ +#define LPCOMP_INTENSET_DOWN_Disabled (0UL) /*!< Read: Disabled */ +#define LPCOMP_INTENSET_DOWN_Enabled (1UL) /*!< Read: Enabled */ +#define LPCOMP_INTENSET_DOWN_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for READY event */ +#define LPCOMP_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */ +#define LPCOMP_INTENSET_READY_Msk (0x1UL << LPCOMP_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ +#define LPCOMP_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ +#define LPCOMP_INTENSET_READY_Enabled (1UL) /*!< Read: Enabled */ +#define LPCOMP_INTENSET_READY_Set (1UL) /*!< Enable */ + +/* Register: LPCOMP_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 3 : Write '1' to Disable interrupt for CROSS event */ +#define LPCOMP_INTENCLR_CROSS_Pos (3UL) /*!< Position of CROSS field. */ +#define LPCOMP_INTENCLR_CROSS_Msk (0x1UL << LPCOMP_INTENCLR_CROSS_Pos) /*!< Bit mask of CROSS field. */ +#define LPCOMP_INTENCLR_CROSS_Disabled (0UL) /*!< Read: Disabled */ +#define LPCOMP_INTENCLR_CROSS_Enabled (1UL) /*!< Read: Enabled */ +#define LPCOMP_INTENCLR_CROSS_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for UP event */ +#define LPCOMP_INTENCLR_UP_Pos (2UL) /*!< Position of UP field. */ +#define LPCOMP_INTENCLR_UP_Msk (0x1UL << LPCOMP_INTENCLR_UP_Pos) /*!< Bit mask of UP field. */ +#define LPCOMP_INTENCLR_UP_Disabled (0UL) /*!< Read: Disabled */ +#define LPCOMP_INTENCLR_UP_Enabled (1UL) /*!< Read: Enabled */ +#define LPCOMP_INTENCLR_UP_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for DOWN event */ +#define LPCOMP_INTENCLR_DOWN_Pos (1UL) /*!< Position of DOWN field. */ +#define LPCOMP_INTENCLR_DOWN_Msk (0x1UL << LPCOMP_INTENCLR_DOWN_Pos) /*!< Bit mask of DOWN field. */ +#define LPCOMP_INTENCLR_DOWN_Disabled (0UL) /*!< Read: Disabled */ +#define LPCOMP_INTENCLR_DOWN_Enabled (1UL) /*!< Read: Enabled */ +#define LPCOMP_INTENCLR_DOWN_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for READY event */ +#define LPCOMP_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */ +#define LPCOMP_INTENCLR_READY_Msk (0x1UL << LPCOMP_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ +#define LPCOMP_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ +#define LPCOMP_INTENCLR_READY_Enabled (1UL) /*!< Read: Enabled */ +#define LPCOMP_INTENCLR_READY_Clear (1UL) /*!< Disable */ + +/* Register: LPCOMP_RESULT */ +/* Description: Compare result */ + +/* Bit 0 : Result of last compare. Decision point SAMPLE task. */ +#define LPCOMP_RESULT_RESULT_Pos (0UL) /*!< Position of RESULT field. */ +#define LPCOMP_RESULT_RESULT_Msk (0x1UL << LPCOMP_RESULT_RESULT_Pos) /*!< Bit mask of RESULT field. */ +#define LPCOMP_RESULT_RESULT_Below (0UL) /*!< Input voltage is below the reference threshold (VIN+ < VIN-). */ +#define LPCOMP_RESULT_RESULT_Above (1UL) /*!< Input voltage is above the reference threshold (VIN+ > VIN-). */ + +/* Register: LPCOMP_ENABLE */ +/* Description: Enable LPCOMP */ + +/* Bits 1..0 : Enable or disable LPCOMP */ +#define LPCOMP_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define LPCOMP_ENABLE_ENABLE_Msk (0x3UL << LPCOMP_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define LPCOMP_ENABLE_ENABLE_Disabled (0UL) /*!< Disable */ +#define LPCOMP_ENABLE_ENABLE_Enabled (1UL) /*!< Enable */ + +/* Register: LPCOMP_PSEL */ +/* Description: Input pin select */ + +/* Bits 2..0 : Analog pin select */ +#define LPCOMP_PSEL_PSEL_Pos (0UL) /*!< Position of PSEL field. */ +#define LPCOMP_PSEL_PSEL_Msk (0x7UL << LPCOMP_PSEL_PSEL_Pos) /*!< Bit mask of PSEL field. */ +#define LPCOMP_PSEL_PSEL_AnalogInput0 (0UL) /*!< AIN0 selected as analog input */ +#define LPCOMP_PSEL_PSEL_AnalogInput1 (1UL) /*!< AIN1 selected as analog input */ +#define LPCOMP_PSEL_PSEL_AnalogInput2 (2UL) /*!< AIN2 selected as analog input */ +#define LPCOMP_PSEL_PSEL_AnalogInput3 (3UL) /*!< AIN3 selected as analog input */ +#define LPCOMP_PSEL_PSEL_AnalogInput4 (4UL) /*!< AIN4 selected as analog input */ +#define LPCOMP_PSEL_PSEL_AnalogInput5 (5UL) /*!< AIN5 selected as analog input */ +#define LPCOMP_PSEL_PSEL_AnalogInput6 (6UL) /*!< AIN6 selected as analog input */ +#define LPCOMP_PSEL_PSEL_AnalogInput7 (7UL) /*!< AIN7 selected as analog input */ + +/* Register: LPCOMP_REFSEL */ +/* Description: Reference select */ + +/* Bits 3..0 : Reference select */ +#define LPCOMP_REFSEL_REFSEL_Pos (0UL) /*!< Position of REFSEL field. */ +#define LPCOMP_REFSEL_REFSEL_Msk (0xFUL << LPCOMP_REFSEL_REFSEL_Pos) /*!< Bit mask of REFSEL field. */ +#define LPCOMP_REFSEL_REFSEL_Ref1_8Vdd (0UL) /*!< VDD * 1/8 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref2_8Vdd (1UL) /*!< VDD * 2/8 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref3_8Vdd (2UL) /*!< VDD * 3/8 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref4_8Vdd (3UL) /*!< VDD * 4/8 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref5_8Vdd (4UL) /*!< VDD * 5/8 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref6_8Vdd (5UL) /*!< VDD * 6/8 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref7_8Vdd (6UL) /*!< VDD * 7/8 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_ARef (7UL) /*!< External analog reference selected */ +#define LPCOMP_REFSEL_REFSEL_Ref1_16Vdd (8UL) /*!< VDD * 1/16 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref3_16Vdd (9UL) /*!< VDD * 3/16 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref5_16Vdd (10UL) /*!< VDD * 5/16 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref7_16Vdd (11UL) /*!< VDD * 7/16 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref9_16Vdd (12UL) /*!< VDD * 9/16 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref11_16Vdd (13UL) /*!< VDD * 11/16 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref13_16Vdd (14UL) /*!< VDD * 13/16 selected as reference */ +#define LPCOMP_REFSEL_REFSEL_Ref15_16Vdd (15UL) /*!< VDD * 15/16 selected as reference */ + +/* Register: LPCOMP_EXTREFSEL */ +/* Description: External reference select */ + +/* Bit 0 : External analog reference select */ +#define LPCOMP_EXTREFSEL_EXTREFSEL_Pos (0UL) /*!< Position of EXTREFSEL field. */ +#define LPCOMP_EXTREFSEL_EXTREFSEL_Msk (0x1UL << LPCOMP_EXTREFSEL_EXTREFSEL_Pos) /*!< Bit mask of EXTREFSEL field. */ +#define LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference0 (0UL) /*!< Use AIN0 as external analog reference */ +#define LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference1 (1UL) /*!< Use AIN1 as external analog reference */ + +/* Register: LPCOMP_ANADETECT */ +/* Description: Analog detect configuration */ + +/* Bits 1..0 : Analog detect configuration */ +#define LPCOMP_ANADETECT_ANADETECT_Pos (0UL) /*!< Position of ANADETECT field. */ +#define LPCOMP_ANADETECT_ANADETECT_Msk (0x3UL << LPCOMP_ANADETECT_ANADETECT_Pos) /*!< Bit mask of ANADETECT field. */ +#define LPCOMP_ANADETECT_ANADETECT_Cross (0UL) /*!< Generate ANADETECT on crossing, both upward crossing and downward crossing */ +#define LPCOMP_ANADETECT_ANADETECT_Up (1UL) /*!< Generate ANADETECT on upward crossing only */ +#define LPCOMP_ANADETECT_ANADETECT_Down (2UL) /*!< Generate ANADETECT on downward crossing only */ + +/* Register: LPCOMP_HYST */ +/* Description: Comparator hysteresis enable */ + +/* Bit 0 : Comparator hysteresis enable */ +#define LPCOMP_HYST_HYST_Pos (0UL) /*!< Position of HYST field. */ +#define LPCOMP_HYST_HYST_Msk (0x1UL << LPCOMP_HYST_HYST_Pos) /*!< Bit mask of HYST field. */ +#define LPCOMP_HYST_HYST_NoHyst (0UL) /*!< Comparator hysteresis disabled */ +#define LPCOMP_HYST_HYST_Hyst50mV (1UL) /*!< Comparator hysteresis disabled (typ. 50 mV) */ + + +/* Peripheral: MWU */ +/* Description: Memory Watch Unit */ + +/* Register: MWU_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 27 : Enable or disable interrupt for PREGION[1].RA event */ +#define MWU_INTEN_PREGION1RA_Pos (27UL) /*!< Position of PREGION1RA field. */ +#define MWU_INTEN_PREGION1RA_Msk (0x1UL << MWU_INTEN_PREGION1RA_Pos) /*!< Bit mask of PREGION1RA field. */ +#define MWU_INTEN_PREGION1RA_Disabled (0UL) /*!< Disable */ +#define MWU_INTEN_PREGION1RA_Enabled (1UL) /*!< Enable */ + +/* Bit 26 : Enable or disable interrupt for PREGION[1].WA event */ +#define MWU_INTEN_PREGION1WA_Pos (26UL) /*!< Position of PREGION1WA field. */ +#define MWU_INTEN_PREGION1WA_Msk (0x1UL << MWU_INTEN_PREGION1WA_Pos) /*!< Bit mask of PREGION1WA field. */ +#define MWU_INTEN_PREGION1WA_Disabled (0UL) /*!< Disable */ +#define MWU_INTEN_PREGION1WA_Enabled (1UL) /*!< Enable */ + +/* Bit 25 : Enable or disable interrupt for PREGION[0].RA event */ +#define MWU_INTEN_PREGION0RA_Pos (25UL) /*!< Position of PREGION0RA field. */ +#define MWU_INTEN_PREGION0RA_Msk (0x1UL << MWU_INTEN_PREGION0RA_Pos) /*!< Bit mask of PREGION0RA field. */ +#define MWU_INTEN_PREGION0RA_Disabled (0UL) /*!< Disable */ +#define MWU_INTEN_PREGION0RA_Enabled (1UL) /*!< Enable */ + +/* Bit 24 : Enable or disable interrupt for PREGION[0].WA event */ +#define MWU_INTEN_PREGION0WA_Pos (24UL) /*!< Position of PREGION0WA field. */ +#define MWU_INTEN_PREGION0WA_Msk (0x1UL << MWU_INTEN_PREGION0WA_Pos) /*!< Bit mask of PREGION0WA field. */ +#define MWU_INTEN_PREGION0WA_Disabled (0UL) /*!< Disable */ +#define MWU_INTEN_PREGION0WA_Enabled (1UL) /*!< Enable */ + +/* Bit 7 : Enable or disable interrupt for REGION[3].RA event */ +#define MWU_INTEN_REGION3RA_Pos (7UL) /*!< Position of REGION3RA field. */ +#define MWU_INTEN_REGION3RA_Msk (0x1UL << MWU_INTEN_REGION3RA_Pos) /*!< Bit mask of REGION3RA field. */ +#define MWU_INTEN_REGION3RA_Disabled (0UL) /*!< Disable */ +#define MWU_INTEN_REGION3RA_Enabled (1UL) /*!< Enable */ + +/* Bit 6 : Enable or disable interrupt for REGION[3].WA event */ +#define MWU_INTEN_REGION3WA_Pos (6UL) /*!< Position of REGION3WA field. */ +#define MWU_INTEN_REGION3WA_Msk (0x1UL << MWU_INTEN_REGION3WA_Pos) /*!< Bit mask of REGION3WA field. */ +#define MWU_INTEN_REGION3WA_Disabled (0UL) /*!< Disable */ +#define MWU_INTEN_REGION3WA_Enabled (1UL) /*!< Enable */ + +/* Bit 5 : Enable or disable interrupt for REGION[2].RA event */ +#define MWU_INTEN_REGION2RA_Pos (5UL) /*!< Position of REGION2RA field. */ +#define MWU_INTEN_REGION2RA_Msk (0x1UL << MWU_INTEN_REGION2RA_Pos) /*!< Bit mask of REGION2RA field. */ +#define MWU_INTEN_REGION2RA_Disabled (0UL) /*!< Disable */ +#define MWU_INTEN_REGION2RA_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable interrupt for REGION[2].WA event */ +#define MWU_INTEN_REGION2WA_Pos (4UL) /*!< Position of REGION2WA field. */ +#define MWU_INTEN_REGION2WA_Msk (0x1UL << MWU_INTEN_REGION2WA_Pos) /*!< Bit mask of REGION2WA field. */ +#define MWU_INTEN_REGION2WA_Disabled (0UL) /*!< Disable */ +#define MWU_INTEN_REGION2WA_Enabled (1UL) /*!< Enable */ + +/* Bit 3 : Enable or disable interrupt for REGION[1].RA event */ +#define MWU_INTEN_REGION1RA_Pos (3UL) /*!< Position of REGION1RA field. */ +#define MWU_INTEN_REGION1RA_Msk (0x1UL << MWU_INTEN_REGION1RA_Pos) /*!< Bit mask of REGION1RA field. */ +#define MWU_INTEN_REGION1RA_Disabled (0UL) /*!< Disable */ +#define MWU_INTEN_REGION1RA_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for REGION[1].WA event */ +#define MWU_INTEN_REGION1WA_Pos (2UL) /*!< Position of REGION1WA field. */ +#define MWU_INTEN_REGION1WA_Msk (0x1UL << MWU_INTEN_REGION1WA_Pos) /*!< Bit mask of REGION1WA field. */ +#define MWU_INTEN_REGION1WA_Disabled (0UL) /*!< Disable */ +#define MWU_INTEN_REGION1WA_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for REGION[0].RA event */ +#define MWU_INTEN_REGION0RA_Pos (1UL) /*!< Position of REGION0RA field. */ +#define MWU_INTEN_REGION0RA_Msk (0x1UL << MWU_INTEN_REGION0RA_Pos) /*!< Bit mask of REGION0RA field. */ +#define MWU_INTEN_REGION0RA_Disabled (0UL) /*!< Disable */ +#define MWU_INTEN_REGION0RA_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable interrupt for REGION[0].WA event */ +#define MWU_INTEN_REGION0WA_Pos (0UL) /*!< Position of REGION0WA field. */ +#define MWU_INTEN_REGION0WA_Msk (0x1UL << MWU_INTEN_REGION0WA_Pos) /*!< Bit mask of REGION0WA field. */ +#define MWU_INTEN_REGION0WA_Disabled (0UL) /*!< Disable */ +#define MWU_INTEN_REGION0WA_Enabled (1UL) /*!< Enable */ + +/* Register: MWU_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 27 : Write '1' to Enable interrupt for PREGION[1].RA event */ +#define MWU_INTENSET_PREGION1RA_Pos (27UL) /*!< Position of PREGION1RA field. */ +#define MWU_INTENSET_PREGION1RA_Msk (0x1UL << MWU_INTENSET_PREGION1RA_Pos) /*!< Bit mask of PREGION1RA field. */ +#define MWU_INTENSET_PREGION1RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENSET_PREGION1RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENSET_PREGION1RA_Set (1UL) /*!< Enable */ + +/* Bit 26 : Write '1' to Enable interrupt for PREGION[1].WA event */ +#define MWU_INTENSET_PREGION1WA_Pos (26UL) /*!< Position of PREGION1WA field. */ +#define MWU_INTENSET_PREGION1WA_Msk (0x1UL << MWU_INTENSET_PREGION1WA_Pos) /*!< Bit mask of PREGION1WA field. */ +#define MWU_INTENSET_PREGION1WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENSET_PREGION1WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENSET_PREGION1WA_Set (1UL) /*!< Enable */ + +/* Bit 25 : Write '1' to Enable interrupt for PREGION[0].RA event */ +#define MWU_INTENSET_PREGION0RA_Pos (25UL) /*!< Position of PREGION0RA field. */ +#define MWU_INTENSET_PREGION0RA_Msk (0x1UL << MWU_INTENSET_PREGION0RA_Pos) /*!< Bit mask of PREGION0RA field. */ +#define MWU_INTENSET_PREGION0RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENSET_PREGION0RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENSET_PREGION0RA_Set (1UL) /*!< Enable */ + +/* Bit 24 : Write '1' to Enable interrupt for PREGION[0].WA event */ +#define MWU_INTENSET_PREGION0WA_Pos (24UL) /*!< Position of PREGION0WA field. */ +#define MWU_INTENSET_PREGION0WA_Msk (0x1UL << MWU_INTENSET_PREGION0WA_Pos) /*!< Bit mask of PREGION0WA field. */ +#define MWU_INTENSET_PREGION0WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENSET_PREGION0WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENSET_PREGION0WA_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for REGION[3].RA event */ +#define MWU_INTENSET_REGION3RA_Pos (7UL) /*!< Position of REGION3RA field. */ +#define MWU_INTENSET_REGION3RA_Msk (0x1UL << MWU_INTENSET_REGION3RA_Pos) /*!< Bit mask of REGION3RA field. */ +#define MWU_INTENSET_REGION3RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENSET_REGION3RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENSET_REGION3RA_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for REGION[3].WA event */ +#define MWU_INTENSET_REGION3WA_Pos (6UL) /*!< Position of REGION3WA field. */ +#define MWU_INTENSET_REGION3WA_Msk (0x1UL << MWU_INTENSET_REGION3WA_Pos) /*!< Bit mask of REGION3WA field. */ +#define MWU_INTENSET_REGION3WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENSET_REGION3WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENSET_REGION3WA_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for REGION[2].RA event */ +#define MWU_INTENSET_REGION2RA_Pos (5UL) /*!< Position of REGION2RA field. */ +#define MWU_INTENSET_REGION2RA_Msk (0x1UL << MWU_INTENSET_REGION2RA_Pos) /*!< Bit mask of REGION2RA field. */ +#define MWU_INTENSET_REGION2RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENSET_REGION2RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENSET_REGION2RA_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for REGION[2].WA event */ +#define MWU_INTENSET_REGION2WA_Pos (4UL) /*!< Position of REGION2WA field. */ +#define MWU_INTENSET_REGION2WA_Msk (0x1UL << MWU_INTENSET_REGION2WA_Pos) /*!< Bit mask of REGION2WA field. */ +#define MWU_INTENSET_REGION2WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENSET_REGION2WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENSET_REGION2WA_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for REGION[1].RA event */ +#define MWU_INTENSET_REGION1RA_Pos (3UL) /*!< Position of REGION1RA field. */ +#define MWU_INTENSET_REGION1RA_Msk (0x1UL << MWU_INTENSET_REGION1RA_Pos) /*!< Bit mask of REGION1RA field. */ +#define MWU_INTENSET_REGION1RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENSET_REGION1RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENSET_REGION1RA_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for REGION[1].WA event */ +#define MWU_INTENSET_REGION1WA_Pos (2UL) /*!< Position of REGION1WA field. */ +#define MWU_INTENSET_REGION1WA_Msk (0x1UL << MWU_INTENSET_REGION1WA_Pos) /*!< Bit mask of REGION1WA field. */ +#define MWU_INTENSET_REGION1WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENSET_REGION1WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENSET_REGION1WA_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for REGION[0].RA event */ +#define MWU_INTENSET_REGION0RA_Pos (1UL) /*!< Position of REGION0RA field. */ +#define MWU_INTENSET_REGION0RA_Msk (0x1UL << MWU_INTENSET_REGION0RA_Pos) /*!< Bit mask of REGION0RA field. */ +#define MWU_INTENSET_REGION0RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENSET_REGION0RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENSET_REGION0RA_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for REGION[0].WA event */ +#define MWU_INTENSET_REGION0WA_Pos (0UL) /*!< Position of REGION0WA field. */ +#define MWU_INTENSET_REGION0WA_Msk (0x1UL << MWU_INTENSET_REGION0WA_Pos) /*!< Bit mask of REGION0WA field. */ +#define MWU_INTENSET_REGION0WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENSET_REGION0WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENSET_REGION0WA_Set (1UL) /*!< Enable */ + +/* Register: MWU_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 27 : Write '1' to Disable interrupt for PREGION[1].RA event */ +#define MWU_INTENCLR_PREGION1RA_Pos (27UL) /*!< Position of PREGION1RA field. */ +#define MWU_INTENCLR_PREGION1RA_Msk (0x1UL << MWU_INTENCLR_PREGION1RA_Pos) /*!< Bit mask of PREGION1RA field. */ +#define MWU_INTENCLR_PREGION1RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENCLR_PREGION1RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENCLR_PREGION1RA_Clear (1UL) /*!< Disable */ + +/* Bit 26 : Write '1' to Disable interrupt for PREGION[1].WA event */ +#define MWU_INTENCLR_PREGION1WA_Pos (26UL) /*!< Position of PREGION1WA field. */ +#define MWU_INTENCLR_PREGION1WA_Msk (0x1UL << MWU_INTENCLR_PREGION1WA_Pos) /*!< Bit mask of PREGION1WA field. */ +#define MWU_INTENCLR_PREGION1WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENCLR_PREGION1WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENCLR_PREGION1WA_Clear (1UL) /*!< Disable */ + +/* Bit 25 : Write '1' to Disable interrupt for PREGION[0].RA event */ +#define MWU_INTENCLR_PREGION0RA_Pos (25UL) /*!< Position of PREGION0RA field. */ +#define MWU_INTENCLR_PREGION0RA_Msk (0x1UL << MWU_INTENCLR_PREGION0RA_Pos) /*!< Bit mask of PREGION0RA field. */ +#define MWU_INTENCLR_PREGION0RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENCLR_PREGION0RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENCLR_PREGION0RA_Clear (1UL) /*!< Disable */ + +/* Bit 24 : Write '1' to Disable interrupt for PREGION[0].WA event */ +#define MWU_INTENCLR_PREGION0WA_Pos (24UL) /*!< Position of PREGION0WA field. */ +#define MWU_INTENCLR_PREGION0WA_Msk (0x1UL << MWU_INTENCLR_PREGION0WA_Pos) /*!< Bit mask of PREGION0WA field. */ +#define MWU_INTENCLR_PREGION0WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENCLR_PREGION0WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENCLR_PREGION0WA_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for REGION[3].RA event */ +#define MWU_INTENCLR_REGION3RA_Pos (7UL) /*!< Position of REGION3RA field. */ +#define MWU_INTENCLR_REGION3RA_Msk (0x1UL << MWU_INTENCLR_REGION3RA_Pos) /*!< Bit mask of REGION3RA field. */ +#define MWU_INTENCLR_REGION3RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENCLR_REGION3RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENCLR_REGION3RA_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for REGION[3].WA event */ +#define MWU_INTENCLR_REGION3WA_Pos (6UL) /*!< Position of REGION3WA field. */ +#define MWU_INTENCLR_REGION3WA_Msk (0x1UL << MWU_INTENCLR_REGION3WA_Pos) /*!< Bit mask of REGION3WA field. */ +#define MWU_INTENCLR_REGION3WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENCLR_REGION3WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENCLR_REGION3WA_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for REGION[2].RA event */ +#define MWU_INTENCLR_REGION2RA_Pos (5UL) /*!< Position of REGION2RA field. */ +#define MWU_INTENCLR_REGION2RA_Msk (0x1UL << MWU_INTENCLR_REGION2RA_Pos) /*!< Bit mask of REGION2RA field. */ +#define MWU_INTENCLR_REGION2RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENCLR_REGION2RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENCLR_REGION2RA_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for REGION[2].WA event */ +#define MWU_INTENCLR_REGION2WA_Pos (4UL) /*!< Position of REGION2WA field. */ +#define MWU_INTENCLR_REGION2WA_Msk (0x1UL << MWU_INTENCLR_REGION2WA_Pos) /*!< Bit mask of REGION2WA field. */ +#define MWU_INTENCLR_REGION2WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENCLR_REGION2WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENCLR_REGION2WA_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for REGION[1].RA event */ +#define MWU_INTENCLR_REGION1RA_Pos (3UL) /*!< Position of REGION1RA field. */ +#define MWU_INTENCLR_REGION1RA_Msk (0x1UL << MWU_INTENCLR_REGION1RA_Pos) /*!< Bit mask of REGION1RA field. */ +#define MWU_INTENCLR_REGION1RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENCLR_REGION1RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENCLR_REGION1RA_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for REGION[1].WA event */ +#define MWU_INTENCLR_REGION1WA_Pos (2UL) /*!< Position of REGION1WA field. */ +#define MWU_INTENCLR_REGION1WA_Msk (0x1UL << MWU_INTENCLR_REGION1WA_Pos) /*!< Bit mask of REGION1WA field. */ +#define MWU_INTENCLR_REGION1WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENCLR_REGION1WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENCLR_REGION1WA_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for REGION[0].RA event */ +#define MWU_INTENCLR_REGION0RA_Pos (1UL) /*!< Position of REGION0RA field. */ +#define MWU_INTENCLR_REGION0RA_Msk (0x1UL << MWU_INTENCLR_REGION0RA_Pos) /*!< Bit mask of REGION0RA field. */ +#define MWU_INTENCLR_REGION0RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENCLR_REGION0RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENCLR_REGION0RA_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for REGION[0].WA event */ +#define MWU_INTENCLR_REGION0WA_Pos (0UL) /*!< Position of REGION0WA field. */ +#define MWU_INTENCLR_REGION0WA_Msk (0x1UL << MWU_INTENCLR_REGION0WA_Pos) /*!< Bit mask of REGION0WA field. */ +#define MWU_INTENCLR_REGION0WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_INTENCLR_REGION0WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_INTENCLR_REGION0WA_Clear (1UL) /*!< Disable */ + +/* Register: MWU_NMIEN */ +/* Description: Enable or disable non-maskable interrupt */ + +/* Bit 27 : Enable or disable non-maskable interrupt for PREGION[1].RA event */ +#define MWU_NMIEN_PREGION1RA_Pos (27UL) /*!< Position of PREGION1RA field. */ +#define MWU_NMIEN_PREGION1RA_Msk (0x1UL << MWU_NMIEN_PREGION1RA_Pos) /*!< Bit mask of PREGION1RA field. */ +#define MWU_NMIEN_PREGION1RA_Disabled (0UL) /*!< Disable */ +#define MWU_NMIEN_PREGION1RA_Enabled (1UL) /*!< Enable */ + +/* Bit 26 : Enable or disable non-maskable interrupt for PREGION[1].WA event */ +#define MWU_NMIEN_PREGION1WA_Pos (26UL) /*!< Position of PREGION1WA field. */ +#define MWU_NMIEN_PREGION1WA_Msk (0x1UL << MWU_NMIEN_PREGION1WA_Pos) /*!< Bit mask of PREGION1WA field. */ +#define MWU_NMIEN_PREGION1WA_Disabled (0UL) /*!< Disable */ +#define MWU_NMIEN_PREGION1WA_Enabled (1UL) /*!< Enable */ + +/* Bit 25 : Enable or disable non-maskable interrupt for PREGION[0].RA event */ +#define MWU_NMIEN_PREGION0RA_Pos (25UL) /*!< Position of PREGION0RA field. */ +#define MWU_NMIEN_PREGION0RA_Msk (0x1UL << MWU_NMIEN_PREGION0RA_Pos) /*!< Bit mask of PREGION0RA field. */ +#define MWU_NMIEN_PREGION0RA_Disabled (0UL) /*!< Disable */ +#define MWU_NMIEN_PREGION0RA_Enabled (1UL) /*!< Enable */ + +/* Bit 24 : Enable or disable non-maskable interrupt for PREGION[0].WA event */ +#define MWU_NMIEN_PREGION0WA_Pos (24UL) /*!< Position of PREGION0WA field. */ +#define MWU_NMIEN_PREGION0WA_Msk (0x1UL << MWU_NMIEN_PREGION0WA_Pos) /*!< Bit mask of PREGION0WA field. */ +#define MWU_NMIEN_PREGION0WA_Disabled (0UL) /*!< Disable */ +#define MWU_NMIEN_PREGION0WA_Enabled (1UL) /*!< Enable */ + +/* Bit 7 : Enable or disable non-maskable interrupt for REGION[3].RA event */ +#define MWU_NMIEN_REGION3RA_Pos (7UL) /*!< Position of REGION3RA field. */ +#define MWU_NMIEN_REGION3RA_Msk (0x1UL << MWU_NMIEN_REGION3RA_Pos) /*!< Bit mask of REGION3RA field. */ +#define MWU_NMIEN_REGION3RA_Disabled (0UL) /*!< Disable */ +#define MWU_NMIEN_REGION3RA_Enabled (1UL) /*!< Enable */ + +/* Bit 6 : Enable or disable non-maskable interrupt for REGION[3].WA event */ +#define MWU_NMIEN_REGION3WA_Pos (6UL) /*!< Position of REGION3WA field. */ +#define MWU_NMIEN_REGION3WA_Msk (0x1UL << MWU_NMIEN_REGION3WA_Pos) /*!< Bit mask of REGION3WA field. */ +#define MWU_NMIEN_REGION3WA_Disabled (0UL) /*!< Disable */ +#define MWU_NMIEN_REGION3WA_Enabled (1UL) /*!< Enable */ + +/* Bit 5 : Enable or disable non-maskable interrupt for REGION[2].RA event */ +#define MWU_NMIEN_REGION2RA_Pos (5UL) /*!< Position of REGION2RA field. */ +#define MWU_NMIEN_REGION2RA_Msk (0x1UL << MWU_NMIEN_REGION2RA_Pos) /*!< Bit mask of REGION2RA field. */ +#define MWU_NMIEN_REGION2RA_Disabled (0UL) /*!< Disable */ +#define MWU_NMIEN_REGION2RA_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable non-maskable interrupt for REGION[2].WA event */ +#define MWU_NMIEN_REGION2WA_Pos (4UL) /*!< Position of REGION2WA field. */ +#define MWU_NMIEN_REGION2WA_Msk (0x1UL << MWU_NMIEN_REGION2WA_Pos) /*!< Bit mask of REGION2WA field. */ +#define MWU_NMIEN_REGION2WA_Disabled (0UL) /*!< Disable */ +#define MWU_NMIEN_REGION2WA_Enabled (1UL) /*!< Enable */ + +/* Bit 3 : Enable or disable non-maskable interrupt for REGION[1].RA event */ +#define MWU_NMIEN_REGION1RA_Pos (3UL) /*!< Position of REGION1RA field. */ +#define MWU_NMIEN_REGION1RA_Msk (0x1UL << MWU_NMIEN_REGION1RA_Pos) /*!< Bit mask of REGION1RA field. */ +#define MWU_NMIEN_REGION1RA_Disabled (0UL) /*!< Disable */ +#define MWU_NMIEN_REGION1RA_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable non-maskable interrupt for REGION[1].WA event */ +#define MWU_NMIEN_REGION1WA_Pos (2UL) /*!< Position of REGION1WA field. */ +#define MWU_NMIEN_REGION1WA_Msk (0x1UL << MWU_NMIEN_REGION1WA_Pos) /*!< Bit mask of REGION1WA field. */ +#define MWU_NMIEN_REGION1WA_Disabled (0UL) /*!< Disable */ +#define MWU_NMIEN_REGION1WA_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable non-maskable interrupt for REGION[0].RA event */ +#define MWU_NMIEN_REGION0RA_Pos (1UL) /*!< Position of REGION0RA field. */ +#define MWU_NMIEN_REGION0RA_Msk (0x1UL << MWU_NMIEN_REGION0RA_Pos) /*!< Bit mask of REGION0RA field. */ +#define MWU_NMIEN_REGION0RA_Disabled (0UL) /*!< Disable */ +#define MWU_NMIEN_REGION0RA_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable non-maskable interrupt for REGION[0].WA event */ +#define MWU_NMIEN_REGION0WA_Pos (0UL) /*!< Position of REGION0WA field. */ +#define MWU_NMIEN_REGION0WA_Msk (0x1UL << MWU_NMIEN_REGION0WA_Pos) /*!< Bit mask of REGION0WA field. */ +#define MWU_NMIEN_REGION0WA_Disabled (0UL) /*!< Disable */ +#define MWU_NMIEN_REGION0WA_Enabled (1UL) /*!< Enable */ + +/* Register: MWU_NMIENSET */ +/* Description: Enable non-maskable interrupt */ + +/* Bit 27 : Write '1' to Enable non-maskable interrupt for PREGION[1].RA event */ +#define MWU_NMIENSET_PREGION1RA_Pos (27UL) /*!< Position of PREGION1RA field. */ +#define MWU_NMIENSET_PREGION1RA_Msk (0x1UL << MWU_NMIENSET_PREGION1RA_Pos) /*!< Bit mask of PREGION1RA field. */ +#define MWU_NMIENSET_PREGION1RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENSET_PREGION1RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENSET_PREGION1RA_Set (1UL) /*!< Enable */ + +/* Bit 26 : Write '1' to Enable non-maskable interrupt for PREGION[1].WA event */ +#define MWU_NMIENSET_PREGION1WA_Pos (26UL) /*!< Position of PREGION1WA field. */ +#define MWU_NMIENSET_PREGION1WA_Msk (0x1UL << MWU_NMIENSET_PREGION1WA_Pos) /*!< Bit mask of PREGION1WA field. */ +#define MWU_NMIENSET_PREGION1WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENSET_PREGION1WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENSET_PREGION1WA_Set (1UL) /*!< Enable */ + +/* Bit 25 : Write '1' to Enable non-maskable interrupt for PREGION[0].RA event */ +#define MWU_NMIENSET_PREGION0RA_Pos (25UL) /*!< Position of PREGION0RA field. */ +#define MWU_NMIENSET_PREGION0RA_Msk (0x1UL << MWU_NMIENSET_PREGION0RA_Pos) /*!< Bit mask of PREGION0RA field. */ +#define MWU_NMIENSET_PREGION0RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENSET_PREGION0RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENSET_PREGION0RA_Set (1UL) /*!< Enable */ + +/* Bit 24 : Write '1' to Enable non-maskable interrupt for PREGION[0].WA event */ +#define MWU_NMIENSET_PREGION0WA_Pos (24UL) /*!< Position of PREGION0WA field. */ +#define MWU_NMIENSET_PREGION0WA_Msk (0x1UL << MWU_NMIENSET_PREGION0WA_Pos) /*!< Bit mask of PREGION0WA field. */ +#define MWU_NMIENSET_PREGION0WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENSET_PREGION0WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENSET_PREGION0WA_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable non-maskable interrupt for REGION[3].RA event */ +#define MWU_NMIENSET_REGION3RA_Pos (7UL) /*!< Position of REGION3RA field. */ +#define MWU_NMIENSET_REGION3RA_Msk (0x1UL << MWU_NMIENSET_REGION3RA_Pos) /*!< Bit mask of REGION3RA field. */ +#define MWU_NMIENSET_REGION3RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENSET_REGION3RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENSET_REGION3RA_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable non-maskable interrupt for REGION[3].WA event */ +#define MWU_NMIENSET_REGION3WA_Pos (6UL) /*!< Position of REGION3WA field. */ +#define MWU_NMIENSET_REGION3WA_Msk (0x1UL << MWU_NMIENSET_REGION3WA_Pos) /*!< Bit mask of REGION3WA field. */ +#define MWU_NMIENSET_REGION3WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENSET_REGION3WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENSET_REGION3WA_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable non-maskable interrupt for REGION[2].RA event */ +#define MWU_NMIENSET_REGION2RA_Pos (5UL) /*!< Position of REGION2RA field. */ +#define MWU_NMIENSET_REGION2RA_Msk (0x1UL << MWU_NMIENSET_REGION2RA_Pos) /*!< Bit mask of REGION2RA field. */ +#define MWU_NMIENSET_REGION2RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENSET_REGION2RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENSET_REGION2RA_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable non-maskable interrupt for REGION[2].WA event */ +#define MWU_NMIENSET_REGION2WA_Pos (4UL) /*!< Position of REGION2WA field. */ +#define MWU_NMIENSET_REGION2WA_Msk (0x1UL << MWU_NMIENSET_REGION2WA_Pos) /*!< Bit mask of REGION2WA field. */ +#define MWU_NMIENSET_REGION2WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENSET_REGION2WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENSET_REGION2WA_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable non-maskable interrupt for REGION[1].RA event */ +#define MWU_NMIENSET_REGION1RA_Pos (3UL) /*!< Position of REGION1RA field. */ +#define MWU_NMIENSET_REGION1RA_Msk (0x1UL << MWU_NMIENSET_REGION1RA_Pos) /*!< Bit mask of REGION1RA field. */ +#define MWU_NMIENSET_REGION1RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENSET_REGION1RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENSET_REGION1RA_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable non-maskable interrupt for REGION[1].WA event */ +#define MWU_NMIENSET_REGION1WA_Pos (2UL) /*!< Position of REGION1WA field. */ +#define MWU_NMIENSET_REGION1WA_Msk (0x1UL << MWU_NMIENSET_REGION1WA_Pos) /*!< Bit mask of REGION1WA field. */ +#define MWU_NMIENSET_REGION1WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENSET_REGION1WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENSET_REGION1WA_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable non-maskable interrupt for REGION[0].RA event */ +#define MWU_NMIENSET_REGION0RA_Pos (1UL) /*!< Position of REGION0RA field. */ +#define MWU_NMIENSET_REGION0RA_Msk (0x1UL << MWU_NMIENSET_REGION0RA_Pos) /*!< Bit mask of REGION0RA field. */ +#define MWU_NMIENSET_REGION0RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENSET_REGION0RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENSET_REGION0RA_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable non-maskable interrupt for REGION[0].WA event */ +#define MWU_NMIENSET_REGION0WA_Pos (0UL) /*!< Position of REGION0WA field. */ +#define MWU_NMIENSET_REGION0WA_Msk (0x1UL << MWU_NMIENSET_REGION0WA_Pos) /*!< Bit mask of REGION0WA field. */ +#define MWU_NMIENSET_REGION0WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENSET_REGION0WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENSET_REGION0WA_Set (1UL) /*!< Enable */ + +/* Register: MWU_NMIENCLR */ +/* Description: Disable non-maskable interrupt */ + +/* Bit 27 : Write '1' to Disable non-maskable interrupt for PREGION[1].RA event */ +#define MWU_NMIENCLR_PREGION1RA_Pos (27UL) /*!< Position of PREGION1RA field. */ +#define MWU_NMIENCLR_PREGION1RA_Msk (0x1UL << MWU_NMIENCLR_PREGION1RA_Pos) /*!< Bit mask of PREGION1RA field. */ +#define MWU_NMIENCLR_PREGION1RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENCLR_PREGION1RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENCLR_PREGION1RA_Clear (1UL) /*!< Disable */ + +/* Bit 26 : Write '1' to Disable non-maskable interrupt for PREGION[1].WA event */ +#define MWU_NMIENCLR_PREGION1WA_Pos (26UL) /*!< Position of PREGION1WA field. */ +#define MWU_NMIENCLR_PREGION1WA_Msk (0x1UL << MWU_NMIENCLR_PREGION1WA_Pos) /*!< Bit mask of PREGION1WA field. */ +#define MWU_NMIENCLR_PREGION1WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENCLR_PREGION1WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENCLR_PREGION1WA_Clear (1UL) /*!< Disable */ + +/* Bit 25 : Write '1' to Disable non-maskable interrupt for PREGION[0].RA event */ +#define MWU_NMIENCLR_PREGION0RA_Pos (25UL) /*!< Position of PREGION0RA field. */ +#define MWU_NMIENCLR_PREGION0RA_Msk (0x1UL << MWU_NMIENCLR_PREGION0RA_Pos) /*!< Bit mask of PREGION0RA field. */ +#define MWU_NMIENCLR_PREGION0RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENCLR_PREGION0RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENCLR_PREGION0RA_Clear (1UL) /*!< Disable */ + +/* Bit 24 : Write '1' to Disable non-maskable interrupt for PREGION[0].WA event */ +#define MWU_NMIENCLR_PREGION0WA_Pos (24UL) /*!< Position of PREGION0WA field. */ +#define MWU_NMIENCLR_PREGION0WA_Msk (0x1UL << MWU_NMIENCLR_PREGION0WA_Pos) /*!< Bit mask of PREGION0WA field. */ +#define MWU_NMIENCLR_PREGION0WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENCLR_PREGION0WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENCLR_PREGION0WA_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable non-maskable interrupt for REGION[3].RA event */ +#define MWU_NMIENCLR_REGION3RA_Pos (7UL) /*!< Position of REGION3RA field. */ +#define MWU_NMIENCLR_REGION3RA_Msk (0x1UL << MWU_NMIENCLR_REGION3RA_Pos) /*!< Bit mask of REGION3RA field. */ +#define MWU_NMIENCLR_REGION3RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENCLR_REGION3RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENCLR_REGION3RA_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable non-maskable interrupt for REGION[3].WA event */ +#define MWU_NMIENCLR_REGION3WA_Pos (6UL) /*!< Position of REGION3WA field. */ +#define MWU_NMIENCLR_REGION3WA_Msk (0x1UL << MWU_NMIENCLR_REGION3WA_Pos) /*!< Bit mask of REGION3WA field. */ +#define MWU_NMIENCLR_REGION3WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENCLR_REGION3WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENCLR_REGION3WA_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable non-maskable interrupt for REGION[2].RA event */ +#define MWU_NMIENCLR_REGION2RA_Pos (5UL) /*!< Position of REGION2RA field. */ +#define MWU_NMIENCLR_REGION2RA_Msk (0x1UL << MWU_NMIENCLR_REGION2RA_Pos) /*!< Bit mask of REGION2RA field. */ +#define MWU_NMIENCLR_REGION2RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENCLR_REGION2RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENCLR_REGION2RA_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable non-maskable interrupt for REGION[2].WA event */ +#define MWU_NMIENCLR_REGION2WA_Pos (4UL) /*!< Position of REGION2WA field. */ +#define MWU_NMIENCLR_REGION2WA_Msk (0x1UL << MWU_NMIENCLR_REGION2WA_Pos) /*!< Bit mask of REGION2WA field. */ +#define MWU_NMIENCLR_REGION2WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENCLR_REGION2WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENCLR_REGION2WA_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable non-maskable interrupt for REGION[1].RA event */ +#define MWU_NMIENCLR_REGION1RA_Pos (3UL) /*!< Position of REGION1RA field. */ +#define MWU_NMIENCLR_REGION1RA_Msk (0x1UL << MWU_NMIENCLR_REGION1RA_Pos) /*!< Bit mask of REGION1RA field. */ +#define MWU_NMIENCLR_REGION1RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENCLR_REGION1RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENCLR_REGION1RA_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable non-maskable interrupt for REGION[1].WA event */ +#define MWU_NMIENCLR_REGION1WA_Pos (2UL) /*!< Position of REGION1WA field. */ +#define MWU_NMIENCLR_REGION1WA_Msk (0x1UL << MWU_NMIENCLR_REGION1WA_Pos) /*!< Bit mask of REGION1WA field. */ +#define MWU_NMIENCLR_REGION1WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENCLR_REGION1WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENCLR_REGION1WA_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable non-maskable interrupt for REGION[0].RA event */ +#define MWU_NMIENCLR_REGION0RA_Pos (1UL) /*!< Position of REGION0RA field. */ +#define MWU_NMIENCLR_REGION0RA_Msk (0x1UL << MWU_NMIENCLR_REGION0RA_Pos) /*!< Bit mask of REGION0RA field. */ +#define MWU_NMIENCLR_REGION0RA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENCLR_REGION0RA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENCLR_REGION0RA_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable non-maskable interrupt for REGION[0].WA event */ +#define MWU_NMIENCLR_REGION0WA_Pos (0UL) /*!< Position of REGION0WA field. */ +#define MWU_NMIENCLR_REGION0WA_Msk (0x1UL << MWU_NMIENCLR_REGION0WA_Pos) /*!< Bit mask of REGION0WA field. */ +#define MWU_NMIENCLR_REGION0WA_Disabled (0UL) /*!< Read: Disabled */ +#define MWU_NMIENCLR_REGION0WA_Enabled (1UL) /*!< Read: Enabled */ +#define MWU_NMIENCLR_REGION0WA_Clear (1UL) /*!< Disable */ + +/* Register: MWU_PERREGION_SUBSTATWA */ +/* Description: Description cluster[0]: Source of event/interrupt in region 0, write access detected while corresponding subregion was enabled for watching */ + +/* Bit 31 : Subregion 31 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR31_Pos (31UL) /*!< Position of SR31 field. */ +#define MWU_PERREGION_SUBSTATWA_SR31_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR31_Pos) /*!< Bit mask of SR31 field. */ +#define MWU_PERREGION_SUBSTATWA_SR31_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR31_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 30 : Subregion 30 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR30_Pos (30UL) /*!< Position of SR30 field. */ +#define MWU_PERREGION_SUBSTATWA_SR30_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR30_Pos) /*!< Bit mask of SR30 field. */ +#define MWU_PERREGION_SUBSTATWA_SR30_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR30_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 29 : Subregion 29 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR29_Pos (29UL) /*!< Position of SR29 field. */ +#define MWU_PERREGION_SUBSTATWA_SR29_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR29_Pos) /*!< Bit mask of SR29 field. */ +#define MWU_PERREGION_SUBSTATWA_SR29_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR29_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 28 : Subregion 28 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR28_Pos (28UL) /*!< Position of SR28 field. */ +#define MWU_PERREGION_SUBSTATWA_SR28_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR28_Pos) /*!< Bit mask of SR28 field. */ +#define MWU_PERREGION_SUBSTATWA_SR28_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR28_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 27 : Subregion 27 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR27_Pos (27UL) /*!< Position of SR27 field. */ +#define MWU_PERREGION_SUBSTATWA_SR27_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR27_Pos) /*!< Bit mask of SR27 field. */ +#define MWU_PERREGION_SUBSTATWA_SR27_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR27_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 26 : Subregion 26 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR26_Pos (26UL) /*!< Position of SR26 field. */ +#define MWU_PERREGION_SUBSTATWA_SR26_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR26_Pos) /*!< Bit mask of SR26 field. */ +#define MWU_PERREGION_SUBSTATWA_SR26_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR26_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 25 : Subregion 25 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR25_Pos (25UL) /*!< Position of SR25 field. */ +#define MWU_PERREGION_SUBSTATWA_SR25_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR25_Pos) /*!< Bit mask of SR25 field. */ +#define MWU_PERREGION_SUBSTATWA_SR25_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR25_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 24 : Subregion 24 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR24_Pos (24UL) /*!< Position of SR24 field. */ +#define MWU_PERREGION_SUBSTATWA_SR24_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR24_Pos) /*!< Bit mask of SR24 field. */ +#define MWU_PERREGION_SUBSTATWA_SR24_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR24_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 23 : Subregion 23 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR23_Pos (23UL) /*!< Position of SR23 field. */ +#define MWU_PERREGION_SUBSTATWA_SR23_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR23_Pos) /*!< Bit mask of SR23 field. */ +#define MWU_PERREGION_SUBSTATWA_SR23_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR23_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 22 : Subregion 22 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR22_Pos (22UL) /*!< Position of SR22 field. */ +#define MWU_PERREGION_SUBSTATWA_SR22_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR22_Pos) /*!< Bit mask of SR22 field. */ +#define MWU_PERREGION_SUBSTATWA_SR22_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR22_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 21 : Subregion 21 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR21_Pos (21UL) /*!< Position of SR21 field. */ +#define MWU_PERREGION_SUBSTATWA_SR21_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR21_Pos) /*!< Bit mask of SR21 field. */ +#define MWU_PERREGION_SUBSTATWA_SR21_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR21_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 20 : Subregion 20 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR20_Pos (20UL) /*!< Position of SR20 field. */ +#define MWU_PERREGION_SUBSTATWA_SR20_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR20_Pos) /*!< Bit mask of SR20 field. */ +#define MWU_PERREGION_SUBSTATWA_SR20_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR20_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 19 : Subregion 19 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR19_Pos (19UL) /*!< Position of SR19 field. */ +#define MWU_PERREGION_SUBSTATWA_SR19_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR19_Pos) /*!< Bit mask of SR19 field. */ +#define MWU_PERREGION_SUBSTATWA_SR19_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR19_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 18 : Subregion 18 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR18_Pos (18UL) /*!< Position of SR18 field. */ +#define MWU_PERREGION_SUBSTATWA_SR18_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR18_Pos) /*!< Bit mask of SR18 field. */ +#define MWU_PERREGION_SUBSTATWA_SR18_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR18_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 17 : Subregion 17 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR17_Pos (17UL) /*!< Position of SR17 field. */ +#define MWU_PERREGION_SUBSTATWA_SR17_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR17_Pos) /*!< Bit mask of SR17 field. */ +#define MWU_PERREGION_SUBSTATWA_SR17_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR17_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 16 : Subregion 16 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR16_Pos (16UL) /*!< Position of SR16 field. */ +#define MWU_PERREGION_SUBSTATWA_SR16_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR16_Pos) /*!< Bit mask of SR16 field. */ +#define MWU_PERREGION_SUBSTATWA_SR16_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR16_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 15 : Subregion 15 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR15_Pos (15UL) /*!< Position of SR15 field. */ +#define MWU_PERREGION_SUBSTATWA_SR15_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR15_Pos) /*!< Bit mask of SR15 field. */ +#define MWU_PERREGION_SUBSTATWA_SR15_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR15_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 14 : Subregion 14 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR14_Pos (14UL) /*!< Position of SR14 field. */ +#define MWU_PERREGION_SUBSTATWA_SR14_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR14_Pos) /*!< Bit mask of SR14 field. */ +#define MWU_PERREGION_SUBSTATWA_SR14_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR14_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 13 : Subregion 13 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR13_Pos (13UL) /*!< Position of SR13 field. */ +#define MWU_PERREGION_SUBSTATWA_SR13_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR13_Pos) /*!< Bit mask of SR13 field. */ +#define MWU_PERREGION_SUBSTATWA_SR13_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR13_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 12 : Subregion 12 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR12_Pos (12UL) /*!< Position of SR12 field. */ +#define MWU_PERREGION_SUBSTATWA_SR12_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR12_Pos) /*!< Bit mask of SR12 field. */ +#define MWU_PERREGION_SUBSTATWA_SR12_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR12_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 11 : Subregion 11 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR11_Pos (11UL) /*!< Position of SR11 field. */ +#define MWU_PERREGION_SUBSTATWA_SR11_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR11_Pos) /*!< Bit mask of SR11 field. */ +#define MWU_PERREGION_SUBSTATWA_SR11_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR11_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 10 : Subregion 10 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR10_Pos (10UL) /*!< Position of SR10 field. */ +#define MWU_PERREGION_SUBSTATWA_SR10_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR10_Pos) /*!< Bit mask of SR10 field. */ +#define MWU_PERREGION_SUBSTATWA_SR10_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR10_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 9 : Subregion 9 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR9_Pos (9UL) /*!< Position of SR9 field. */ +#define MWU_PERREGION_SUBSTATWA_SR9_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR9_Pos) /*!< Bit mask of SR9 field. */ +#define MWU_PERREGION_SUBSTATWA_SR9_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR9_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 8 : Subregion 8 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR8_Pos (8UL) /*!< Position of SR8 field. */ +#define MWU_PERREGION_SUBSTATWA_SR8_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR8_Pos) /*!< Bit mask of SR8 field. */ +#define MWU_PERREGION_SUBSTATWA_SR8_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR8_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 7 : Subregion 7 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR7_Pos (7UL) /*!< Position of SR7 field. */ +#define MWU_PERREGION_SUBSTATWA_SR7_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR7_Pos) /*!< Bit mask of SR7 field. */ +#define MWU_PERREGION_SUBSTATWA_SR7_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR7_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 6 : Subregion 6 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR6_Pos (6UL) /*!< Position of SR6 field. */ +#define MWU_PERREGION_SUBSTATWA_SR6_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR6_Pos) /*!< Bit mask of SR6 field. */ +#define MWU_PERREGION_SUBSTATWA_SR6_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR6_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 5 : Subregion 5 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR5_Pos (5UL) /*!< Position of SR5 field. */ +#define MWU_PERREGION_SUBSTATWA_SR5_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR5_Pos) /*!< Bit mask of SR5 field. */ +#define MWU_PERREGION_SUBSTATWA_SR5_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR5_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 4 : Subregion 4 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR4_Pos (4UL) /*!< Position of SR4 field. */ +#define MWU_PERREGION_SUBSTATWA_SR4_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR4_Pos) /*!< Bit mask of SR4 field. */ +#define MWU_PERREGION_SUBSTATWA_SR4_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR4_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 3 : Subregion 3 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR3_Pos (3UL) /*!< Position of SR3 field. */ +#define MWU_PERREGION_SUBSTATWA_SR3_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR3_Pos) /*!< Bit mask of SR3 field. */ +#define MWU_PERREGION_SUBSTATWA_SR3_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR3_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 2 : Subregion 2 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR2_Pos (2UL) /*!< Position of SR2 field. */ +#define MWU_PERREGION_SUBSTATWA_SR2_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR2_Pos) /*!< Bit mask of SR2 field. */ +#define MWU_PERREGION_SUBSTATWA_SR2_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR2_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 1 : Subregion 1 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR1_Pos (1UL) /*!< Position of SR1 field. */ +#define MWU_PERREGION_SUBSTATWA_SR1_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR1_Pos) /*!< Bit mask of SR1 field. */ +#define MWU_PERREGION_SUBSTATWA_SR1_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR1_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Bit 0 : Subregion 0 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATWA_SR0_Pos (0UL) /*!< Position of SR0 field. */ +#define MWU_PERREGION_SUBSTATWA_SR0_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR0_Pos) /*!< Bit mask of SR0 field. */ +#define MWU_PERREGION_SUBSTATWA_SR0_NoAccess (0UL) /*!< No write access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATWA_SR0_Access (1UL) /*!< Write access(es) occurred in this subregion */ + +/* Register: MWU_PERREGION_SUBSTATRA */ +/* Description: Description cluster[0]: Source of event/interrupt in region 0, read access detected while corresponding subregion was enabled for watching */ + +/* Bit 31 : Subregion 31 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR31_Pos (31UL) /*!< Position of SR31 field. */ +#define MWU_PERREGION_SUBSTATRA_SR31_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR31_Pos) /*!< Bit mask of SR31 field. */ +#define MWU_PERREGION_SUBSTATRA_SR31_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR31_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 30 : Subregion 30 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR30_Pos (30UL) /*!< Position of SR30 field. */ +#define MWU_PERREGION_SUBSTATRA_SR30_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR30_Pos) /*!< Bit mask of SR30 field. */ +#define MWU_PERREGION_SUBSTATRA_SR30_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR30_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 29 : Subregion 29 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR29_Pos (29UL) /*!< Position of SR29 field. */ +#define MWU_PERREGION_SUBSTATRA_SR29_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR29_Pos) /*!< Bit mask of SR29 field. */ +#define MWU_PERREGION_SUBSTATRA_SR29_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR29_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 28 : Subregion 28 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR28_Pos (28UL) /*!< Position of SR28 field. */ +#define MWU_PERREGION_SUBSTATRA_SR28_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR28_Pos) /*!< Bit mask of SR28 field. */ +#define MWU_PERREGION_SUBSTATRA_SR28_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR28_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 27 : Subregion 27 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR27_Pos (27UL) /*!< Position of SR27 field. */ +#define MWU_PERREGION_SUBSTATRA_SR27_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR27_Pos) /*!< Bit mask of SR27 field. */ +#define MWU_PERREGION_SUBSTATRA_SR27_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR27_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 26 : Subregion 26 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR26_Pos (26UL) /*!< Position of SR26 field. */ +#define MWU_PERREGION_SUBSTATRA_SR26_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR26_Pos) /*!< Bit mask of SR26 field. */ +#define MWU_PERREGION_SUBSTATRA_SR26_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR26_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 25 : Subregion 25 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR25_Pos (25UL) /*!< Position of SR25 field. */ +#define MWU_PERREGION_SUBSTATRA_SR25_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR25_Pos) /*!< Bit mask of SR25 field. */ +#define MWU_PERREGION_SUBSTATRA_SR25_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR25_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 24 : Subregion 24 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR24_Pos (24UL) /*!< Position of SR24 field. */ +#define MWU_PERREGION_SUBSTATRA_SR24_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR24_Pos) /*!< Bit mask of SR24 field. */ +#define MWU_PERREGION_SUBSTATRA_SR24_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR24_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 23 : Subregion 23 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR23_Pos (23UL) /*!< Position of SR23 field. */ +#define MWU_PERREGION_SUBSTATRA_SR23_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR23_Pos) /*!< Bit mask of SR23 field. */ +#define MWU_PERREGION_SUBSTATRA_SR23_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR23_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 22 : Subregion 22 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR22_Pos (22UL) /*!< Position of SR22 field. */ +#define MWU_PERREGION_SUBSTATRA_SR22_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR22_Pos) /*!< Bit mask of SR22 field. */ +#define MWU_PERREGION_SUBSTATRA_SR22_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR22_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 21 : Subregion 21 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR21_Pos (21UL) /*!< Position of SR21 field. */ +#define MWU_PERREGION_SUBSTATRA_SR21_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR21_Pos) /*!< Bit mask of SR21 field. */ +#define MWU_PERREGION_SUBSTATRA_SR21_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR21_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 20 : Subregion 20 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR20_Pos (20UL) /*!< Position of SR20 field. */ +#define MWU_PERREGION_SUBSTATRA_SR20_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR20_Pos) /*!< Bit mask of SR20 field. */ +#define MWU_PERREGION_SUBSTATRA_SR20_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR20_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 19 : Subregion 19 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR19_Pos (19UL) /*!< Position of SR19 field. */ +#define MWU_PERREGION_SUBSTATRA_SR19_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR19_Pos) /*!< Bit mask of SR19 field. */ +#define MWU_PERREGION_SUBSTATRA_SR19_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR19_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 18 : Subregion 18 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR18_Pos (18UL) /*!< Position of SR18 field. */ +#define MWU_PERREGION_SUBSTATRA_SR18_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR18_Pos) /*!< Bit mask of SR18 field. */ +#define MWU_PERREGION_SUBSTATRA_SR18_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR18_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 17 : Subregion 17 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR17_Pos (17UL) /*!< Position of SR17 field. */ +#define MWU_PERREGION_SUBSTATRA_SR17_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR17_Pos) /*!< Bit mask of SR17 field. */ +#define MWU_PERREGION_SUBSTATRA_SR17_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR17_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 16 : Subregion 16 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR16_Pos (16UL) /*!< Position of SR16 field. */ +#define MWU_PERREGION_SUBSTATRA_SR16_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR16_Pos) /*!< Bit mask of SR16 field. */ +#define MWU_PERREGION_SUBSTATRA_SR16_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR16_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 15 : Subregion 15 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR15_Pos (15UL) /*!< Position of SR15 field. */ +#define MWU_PERREGION_SUBSTATRA_SR15_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR15_Pos) /*!< Bit mask of SR15 field. */ +#define MWU_PERREGION_SUBSTATRA_SR15_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR15_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 14 : Subregion 14 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR14_Pos (14UL) /*!< Position of SR14 field. */ +#define MWU_PERREGION_SUBSTATRA_SR14_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR14_Pos) /*!< Bit mask of SR14 field. */ +#define MWU_PERREGION_SUBSTATRA_SR14_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR14_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 13 : Subregion 13 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR13_Pos (13UL) /*!< Position of SR13 field. */ +#define MWU_PERREGION_SUBSTATRA_SR13_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR13_Pos) /*!< Bit mask of SR13 field. */ +#define MWU_PERREGION_SUBSTATRA_SR13_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR13_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 12 : Subregion 12 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR12_Pos (12UL) /*!< Position of SR12 field. */ +#define MWU_PERREGION_SUBSTATRA_SR12_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR12_Pos) /*!< Bit mask of SR12 field. */ +#define MWU_PERREGION_SUBSTATRA_SR12_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR12_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 11 : Subregion 11 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR11_Pos (11UL) /*!< Position of SR11 field. */ +#define MWU_PERREGION_SUBSTATRA_SR11_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR11_Pos) /*!< Bit mask of SR11 field. */ +#define MWU_PERREGION_SUBSTATRA_SR11_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR11_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 10 : Subregion 10 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR10_Pos (10UL) /*!< Position of SR10 field. */ +#define MWU_PERREGION_SUBSTATRA_SR10_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR10_Pos) /*!< Bit mask of SR10 field. */ +#define MWU_PERREGION_SUBSTATRA_SR10_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR10_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 9 : Subregion 9 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR9_Pos (9UL) /*!< Position of SR9 field. */ +#define MWU_PERREGION_SUBSTATRA_SR9_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR9_Pos) /*!< Bit mask of SR9 field. */ +#define MWU_PERREGION_SUBSTATRA_SR9_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR9_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 8 : Subregion 8 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR8_Pos (8UL) /*!< Position of SR8 field. */ +#define MWU_PERREGION_SUBSTATRA_SR8_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR8_Pos) /*!< Bit mask of SR8 field. */ +#define MWU_PERREGION_SUBSTATRA_SR8_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR8_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 7 : Subregion 7 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR7_Pos (7UL) /*!< Position of SR7 field. */ +#define MWU_PERREGION_SUBSTATRA_SR7_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR7_Pos) /*!< Bit mask of SR7 field. */ +#define MWU_PERREGION_SUBSTATRA_SR7_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR7_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 6 : Subregion 6 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR6_Pos (6UL) /*!< Position of SR6 field. */ +#define MWU_PERREGION_SUBSTATRA_SR6_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR6_Pos) /*!< Bit mask of SR6 field. */ +#define MWU_PERREGION_SUBSTATRA_SR6_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR6_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 5 : Subregion 5 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR5_Pos (5UL) /*!< Position of SR5 field. */ +#define MWU_PERREGION_SUBSTATRA_SR5_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR5_Pos) /*!< Bit mask of SR5 field. */ +#define MWU_PERREGION_SUBSTATRA_SR5_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR5_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 4 : Subregion 4 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR4_Pos (4UL) /*!< Position of SR4 field. */ +#define MWU_PERREGION_SUBSTATRA_SR4_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR4_Pos) /*!< Bit mask of SR4 field. */ +#define MWU_PERREGION_SUBSTATRA_SR4_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR4_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 3 : Subregion 3 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR3_Pos (3UL) /*!< Position of SR3 field. */ +#define MWU_PERREGION_SUBSTATRA_SR3_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR3_Pos) /*!< Bit mask of SR3 field. */ +#define MWU_PERREGION_SUBSTATRA_SR3_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR3_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 2 : Subregion 2 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR2_Pos (2UL) /*!< Position of SR2 field. */ +#define MWU_PERREGION_SUBSTATRA_SR2_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR2_Pos) /*!< Bit mask of SR2 field. */ +#define MWU_PERREGION_SUBSTATRA_SR2_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR2_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 1 : Subregion 1 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR1_Pos (1UL) /*!< Position of SR1 field. */ +#define MWU_PERREGION_SUBSTATRA_SR1_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR1_Pos) /*!< Bit mask of SR1 field. */ +#define MWU_PERREGION_SUBSTATRA_SR1_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR1_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Bit 0 : Subregion 0 in region 0 (write '1' to clear) */ +#define MWU_PERREGION_SUBSTATRA_SR0_Pos (0UL) /*!< Position of SR0 field. */ +#define MWU_PERREGION_SUBSTATRA_SR0_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR0_Pos) /*!< Bit mask of SR0 field. */ +#define MWU_PERREGION_SUBSTATRA_SR0_NoAccess (0UL) /*!< No read access occurred in this subregion */ +#define MWU_PERREGION_SUBSTATRA_SR0_Access (1UL) /*!< Read access(es) occurred in this subregion */ + +/* Register: MWU_REGIONEN */ +/* Description: Enable/disable regions watch */ + +/* Bit 27 : Enable/disable read access watch in PREGION[1] */ +#define MWU_REGIONEN_PRGN1RA_Pos (27UL) /*!< Position of PRGN1RA field. */ +#define MWU_REGIONEN_PRGN1RA_Msk (0x1UL << MWU_REGIONEN_PRGN1RA_Pos) /*!< Bit mask of PRGN1RA field. */ +#define MWU_REGIONEN_PRGN1RA_Disable (0UL) /*!< Disable read access watch in this PREGION */ +#define MWU_REGIONEN_PRGN1RA_Enable (1UL) /*!< Enable read access watch in this PREGION */ + +/* Bit 26 : Enable/disable write access watch in PREGION[1] */ +#define MWU_REGIONEN_PRGN1WA_Pos (26UL) /*!< Position of PRGN1WA field. */ +#define MWU_REGIONEN_PRGN1WA_Msk (0x1UL << MWU_REGIONEN_PRGN1WA_Pos) /*!< Bit mask of PRGN1WA field. */ +#define MWU_REGIONEN_PRGN1WA_Disable (0UL) /*!< Disable write access watch in this PREGION */ +#define MWU_REGIONEN_PRGN1WA_Enable (1UL) /*!< Enable write access watch in this PREGION */ + +/* Bit 25 : Enable/disable read access watch in PREGION[0] */ +#define MWU_REGIONEN_PRGN0RA_Pos (25UL) /*!< Position of PRGN0RA field. */ +#define MWU_REGIONEN_PRGN0RA_Msk (0x1UL << MWU_REGIONEN_PRGN0RA_Pos) /*!< Bit mask of PRGN0RA field. */ +#define MWU_REGIONEN_PRGN0RA_Disable (0UL) /*!< Disable read access watch in this PREGION */ +#define MWU_REGIONEN_PRGN0RA_Enable (1UL) /*!< Enable read access watch in this PREGION */ + +/* Bit 24 : Enable/disable write access watch in PREGION[0] */ +#define MWU_REGIONEN_PRGN0WA_Pos (24UL) /*!< Position of PRGN0WA field. */ +#define MWU_REGIONEN_PRGN0WA_Msk (0x1UL << MWU_REGIONEN_PRGN0WA_Pos) /*!< Bit mask of PRGN0WA field. */ +#define MWU_REGIONEN_PRGN0WA_Disable (0UL) /*!< Disable write access watch in this PREGION */ +#define MWU_REGIONEN_PRGN0WA_Enable (1UL) /*!< Enable write access watch in this PREGION */ + +/* Bit 7 : Enable/disable read access watch in region[3] */ +#define MWU_REGIONEN_RGN3RA_Pos (7UL) /*!< Position of RGN3RA field. */ +#define MWU_REGIONEN_RGN3RA_Msk (0x1UL << MWU_REGIONEN_RGN3RA_Pos) /*!< Bit mask of RGN3RA field. */ +#define MWU_REGIONEN_RGN3RA_Disable (0UL) /*!< Disable read access watch in this region */ +#define MWU_REGIONEN_RGN3RA_Enable (1UL) /*!< Enable read access watch in this region */ + +/* Bit 6 : Enable/disable write access watch in region[3] */ +#define MWU_REGIONEN_RGN3WA_Pos (6UL) /*!< Position of RGN3WA field. */ +#define MWU_REGIONEN_RGN3WA_Msk (0x1UL << MWU_REGIONEN_RGN3WA_Pos) /*!< Bit mask of RGN3WA field. */ +#define MWU_REGIONEN_RGN3WA_Disable (0UL) /*!< Disable write access watch in this region */ +#define MWU_REGIONEN_RGN3WA_Enable (1UL) /*!< Enable write access watch in this region */ + +/* Bit 5 : Enable/disable read access watch in region[2] */ +#define MWU_REGIONEN_RGN2RA_Pos (5UL) /*!< Position of RGN2RA field. */ +#define MWU_REGIONEN_RGN2RA_Msk (0x1UL << MWU_REGIONEN_RGN2RA_Pos) /*!< Bit mask of RGN2RA field. */ +#define MWU_REGIONEN_RGN2RA_Disable (0UL) /*!< Disable read access watch in this region */ +#define MWU_REGIONEN_RGN2RA_Enable (1UL) /*!< Enable read access watch in this region */ + +/* Bit 4 : Enable/disable write access watch in region[2] */ +#define MWU_REGIONEN_RGN2WA_Pos (4UL) /*!< Position of RGN2WA field. */ +#define MWU_REGIONEN_RGN2WA_Msk (0x1UL << MWU_REGIONEN_RGN2WA_Pos) /*!< Bit mask of RGN2WA field. */ +#define MWU_REGIONEN_RGN2WA_Disable (0UL) /*!< Disable write access watch in this region */ +#define MWU_REGIONEN_RGN2WA_Enable (1UL) /*!< Enable write access watch in this region */ + +/* Bit 3 : Enable/disable read access watch in region[1] */ +#define MWU_REGIONEN_RGN1RA_Pos (3UL) /*!< Position of RGN1RA field. */ +#define MWU_REGIONEN_RGN1RA_Msk (0x1UL << MWU_REGIONEN_RGN1RA_Pos) /*!< Bit mask of RGN1RA field. */ +#define MWU_REGIONEN_RGN1RA_Disable (0UL) /*!< Disable read access watch in this region */ +#define MWU_REGIONEN_RGN1RA_Enable (1UL) /*!< Enable read access watch in this region */ + +/* Bit 2 : Enable/disable write access watch in region[1] */ +#define MWU_REGIONEN_RGN1WA_Pos (2UL) /*!< Position of RGN1WA field. */ +#define MWU_REGIONEN_RGN1WA_Msk (0x1UL << MWU_REGIONEN_RGN1WA_Pos) /*!< Bit mask of RGN1WA field. */ +#define MWU_REGIONEN_RGN1WA_Disable (0UL) /*!< Disable write access watch in this region */ +#define MWU_REGIONEN_RGN1WA_Enable (1UL) /*!< Enable write access watch in this region */ + +/* Bit 1 : Enable/disable read access watch in region[0] */ +#define MWU_REGIONEN_RGN0RA_Pos (1UL) /*!< Position of RGN0RA field. */ +#define MWU_REGIONEN_RGN0RA_Msk (0x1UL << MWU_REGIONEN_RGN0RA_Pos) /*!< Bit mask of RGN0RA field. */ +#define MWU_REGIONEN_RGN0RA_Disable (0UL) /*!< Disable read access watch in this region */ +#define MWU_REGIONEN_RGN0RA_Enable (1UL) /*!< Enable read access watch in this region */ + +/* Bit 0 : Enable/disable write access watch in region[0] */ +#define MWU_REGIONEN_RGN0WA_Pos (0UL) /*!< Position of RGN0WA field. */ +#define MWU_REGIONEN_RGN0WA_Msk (0x1UL << MWU_REGIONEN_RGN0WA_Pos) /*!< Bit mask of RGN0WA field. */ +#define MWU_REGIONEN_RGN0WA_Disable (0UL) /*!< Disable write access watch in this region */ +#define MWU_REGIONEN_RGN0WA_Enable (1UL) /*!< Enable write access watch in this region */ + +/* Register: MWU_REGIONENSET */ +/* Description: Enable regions watch */ + +/* Bit 27 : Enable read access watch in PREGION[1] */ +#define MWU_REGIONENSET_PRGN1RA_Pos (27UL) /*!< Position of PRGN1RA field. */ +#define MWU_REGIONENSET_PRGN1RA_Msk (0x1UL << MWU_REGIONENSET_PRGN1RA_Pos) /*!< Bit mask of PRGN1RA field. */ +#define MWU_REGIONENSET_PRGN1RA_Disabled (0UL) /*!< Read access watch in this PREGION is disabled */ +#define MWU_REGIONENSET_PRGN1RA_Enabled (1UL) /*!< Read access watch in this PREGION is enabled */ +#define MWU_REGIONENSET_PRGN1RA_Set (1UL) /*!< Enable read access watch in this PREGION */ + +/* Bit 26 : Enable write access watch in PREGION[1] */ +#define MWU_REGIONENSET_PRGN1WA_Pos (26UL) /*!< Position of PRGN1WA field. */ +#define MWU_REGIONENSET_PRGN1WA_Msk (0x1UL << MWU_REGIONENSET_PRGN1WA_Pos) /*!< Bit mask of PRGN1WA field. */ +#define MWU_REGIONENSET_PRGN1WA_Disabled (0UL) /*!< Write access watch in this PREGION is disabled */ +#define MWU_REGIONENSET_PRGN1WA_Enabled (1UL) /*!< Write access watch in this PREGION is enabled */ +#define MWU_REGIONENSET_PRGN1WA_Set (1UL) /*!< Enable write access watch in this PREGION */ + +/* Bit 25 : Enable read access watch in PREGION[0] */ +#define MWU_REGIONENSET_PRGN0RA_Pos (25UL) /*!< Position of PRGN0RA field. */ +#define MWU_REGIONENSET_PRGN0RA_Msk (0x1UL << MWU_REGIONENSET_PRGN0RA_Pos) /*!< Bit mask of PRGN0RA field. */ +#define MWU_REGIONENSET_PRGN0RA_Disabled (0UL) /*!< Read access watch in this PREGION is disabled */ +#define MWU_REGIONENSET_PRGN0RA_Enabled (1UL) /*!< Read access watch in this PREGION is enabled */ +#define MWU_REGIONENSET_PRGN0RA_Set (1UL) /*!< Enable read access watch in this PREGION */ + +/* Bit 24 : Enable write access watch in PREGION[0] */ +#define MWU_REGIONENSET_PRGN0WA_Pos (24UL) /*!< Position of PRGN0WA field. */ +#define MWU_REGIONENSET_PRGN0WA_Msk (0x1UL << MWU_REGIONENSET_PRGN0WA_Pos) /*!< Bit mask of PRGN0WA field. */ +#define MWU_REGIONENSET_PRGN0WA_Disabled (0UL) /*!< Write access watch in this PREGION is disabled */ +#define MWU_REGIONENSET_PRGN0WA_Enabled (1UL) /*!< Write access watch in this PREGION is enabled */ +#define MWU_REGIONENSET_PRGN0WA_Set (1UL) /*!< Enable write access watch in this PREGION */ + +/* Bit 7 : Enable read access watch in region[3] */ +#define MWU_REGIONENSET_RGN3RA_Pos (7UL) /*!< Position of RGN3RA field. */ +#define MWU_REGIONENSET_RGN3RA_Msk (0x1UL << MWU_REGIONENSET_RGN3RA_Pos) /*!< Bit mask of RGN3RA field. */ +#define MWU_REGIONENSET_RGN3RA_Disabled (0UL) /*!< Read access watch in this region is disabled */ +#define MWU_REGIONENSET_RGN3RA_Enabled (1UL) /*!< Read access watch in this region is enabled */ +#define MWU_REGIONENSET_RGN3RA_Set (1UL) /*!< Enable read access watch in this region */ + +/* Bit 6 : Enable write access watch in region[3] */ +#define MWU_REGIONENSET_RGN3WA_Pos (6UL) /*!< Position of RGN3WA field. */ +#define MWU_REGIONENSET_RGN3WA_Msk (0x1UL << MWU_REGIONENSET_RGN3WA_Pos) /*!< Bit mask of RGN3WA field. */ +#define MWU_REGIONENSET_RGN3WA_Disabled (0UL) /*!< Write access watch in this region is disabled */ +#define MWU_REGIONENSET_RGN3WA_Enabled (1UL) /*!< Write access watch in this region is enabled */ +#define MWU_REGIONENSET_RGN3WA_Set (1UL) /*!< Enable write access watch in this region */ + +/* Bit 5 : Enable read access watch in region[2] */ +#define MWU_REGIONENSET_RGN2RA_Pos (5UL) /*!< Position of RGN2RA field. */ +#define MWU_REGIONENSET_RGN2RA_Msk (0x1UL << MWU_REGIONENSET_RGN2RA_Pos) /*!< Bit mask of RGN2RA field. */ +#define MWU_REGIONENSET_RGN2RA_Disabled (0UL) /*!< Read access watch in this region is disabled */ +#define MWU_REGIONENSET_RGN2RA_Enabled (1UL) /*!< Read access watch in this region is enabled */ +#define MWU_REGIONENSET_RGN2RA_Set (1UL) /*!< Enable read access watch in this region */ + +/* Bit 4 : Enable write access watch in region[2] */ +#define MWU_REGIONENSET_RGN2WA_Pos (4UL) /*!< Position of RGN2WA field. */ +#define MWU_REGIONENSET_RGN2WA_Msk (0x1UL << MWU_REGIONENSET_RGN2WA_Pos) /*!< Bit mask of RGN2WA field. */ +#define MWU_REGIONENSET_RGN2WA_Disabled (0UL) /*!< Write access watch in this region is disabled */ +#define MWU_REGIONENSET_RGN2WA_Enabled (1UL) /*!< Write access watch in this region is enabled */ +#define MWU_REGIONENSET_RGN2WA_Set (1UL) /*!< Enable write access watch in this region */ + +/* Bit 3 : Enable read access watch in region[1] */ +#define MWU_REGIONENSET_RGN1RA_Pos (3UL) /*!< Position of RGN1RA field. */ +#define MWU_REGIONENSET_RGN1RA_Msk (0x1UL << MWU_REGIONENSET_RGN1RA_Pos) /*!< Bit mask of RGN1RA field. */ +#define MWU_REGIONENSET_RGN1RA_Disabled (0UL) /*!< Read access watch in this region is disabled */ +#define MWU_REGIONENSET_RGN1RA_Enabled (1UL) /*!< Read access watch in this region is enabled */ +#define MWU_REGIONENSET_RGN1RA_Set (1UL) /*!< Enable read access watch in this region */ + +/* Bit 2 : Enable write access watch in region[1] */ +#define MWU_REGIONENSET_RGN1WA_Pos (2UL) /*!< Position of RGN1WA field. */ +#define MWU_REGIONENSET_RGN1WA_Msk (0x1UL << MWU_REGIONENSET_RGN1WA_Pos) /*!< Bit mask of RGN1WA field. */ +#define MWU_REGIONENSET_RGN1WA_Disabled (0UL) /*!< Write access watch in this region is disabled */ +#define MWU_REGIONENSET_RGN1WA_Enabled (1UL) /*!< Write access watch in this region is enabled */ +#define MWU_REGIONENSET_RGN1WA_Set (1UL) /*!< Enable write access watch in this region */ + +/* Bit 1 : Enable read access watch in region[0] */ +#define MWU_REGIONENSET_RGN0RA_Pos (1UL) /*!< Position of RGN0RA field. */ +#define MWU_REGIONENSET_RGN0RA_Msk (0x1UL << MWU_REGIONENSET_RGN0RA_Pos) /*!< Bit mask of RGN0RA field. */ +#define MWU_REGIONENSET_RGN0RA_Disabled (0UL) /*!< Read access watch in this region is disabled */ +#define MWU_REGIONENSET_RGN0RA_Enabled (1UL) /*!< Read access watch in this region is enabled */ +#define MWU_REGIONENSET_RGN0RA_Set (1UL) /*!< Enable read access watch in this region */ + +/* Bit 0 : Enable write access watch in region[0] */ +#define MWU_REGIONENSET_RGN0WA_Pos (0UL) /*!< Position of RGN0WA field. */ +#define MWU_REGIONENSET_RGN0WA_Msk (0x1UL << MWU_REGIONENSET_RGN0WA_Pos) /*!< Bit mask of RGN0WA field. */ +#define MWU_REGIONENSET_RGN0WA_Disabled (0UL) /*!< Write access watch in this region is disabled */ +#define MWU_REGIONENSET_RGN0WA_Enabled (1UL) /*!< Write access watch in this region is enabled */ +#define MWU_REGIONENSET_RGN0WA_Set (1UL) /*!< Enable write access watch in this region */ + +/* Register: MWU_REGIONENCLR */ +/* Description: Disable regions watch */ + +/* Bit 27 : Disable read access watch in PREGION[1] */ +#define MWU_REGIONENCLR_PRGN1RA_Pos (27UL) /*!< Position of PRGN1RA field. */ +#define MWU_REGIONENCLR_PRGN1RA_Msk (0x1UL << MWU_REGIONENCLR_PRGN1RA_Pos) /*!< Bit mask of PRGN1RA field. */ +#define MWU_REGIONENCLR_PRGN1RA_Disabled (0UL) /*!< Read access watch in this PREGION is disabled */ +#define MWU_REGIONENCLR_PRGN1RA_Enabled (1UL) /*!< Read access watch in this PREGION is enabled */ +#define MWU_REGIONENCLR_PRGN1RA_Clear (1UL) /*!< Disable read access watch in this PREGION */ + +/* Bit 26 : Disable write access watch in PREGION[1] */ +#define MWU_REGIONENCLR_PRGN1WA_Pos (26UL) /*!< Position of PRGN1WA field. */ +#define MWU_REGIONENCLR_PRGN1WA_Msk (0x1UL << MWU_REGIONENCLR_PRGN1WA_Pos) /*!< Bit mask of PRGN1WA field. */ +#define MWU_REGIONENCLR_PRGN1WA_Disabled (0UL) /*!< Write access watch in this PREGION is disabled */ +#define MWU_REGIONENCLR_PRGN1WA_Enabled (1UL) /*!< Write access watch in this PREGION is enabled */ +#define MWU_REGIONENCLR_PRGN1WA_Clear (1UL) /*!< Disable write access watch in this PREGION */ + +/* Bit 25 : Disable read access watch in PREGION[0] */ +#define MWU_REGIONENCLR_PRGN0RA_Pos (25UL) /*!< Position of PRGN0RA field. */ +#define MWU_REGIONENCLR_PRGN0RA_Msk (0x1UL << MWU_REGIONENCLR_PRGN0RA_Pos) /*!< Bit mask of PRGN0RA field. */ +#define MWU_REGIONENCLR_PRGN0RA_Disabled (0UL) /*!< Read access watch in this PREGION is disabled */ +#define MWU_REGIONENCLR_PRGN0RA_Enabled (1UL) /*!< Read access watch in this PREGION is enabled */ +#define MWU_REGIONENCLR_PRGN0RA_Clear (1UL) /*!< Disable read access watch in this PREGION */ + +/* Bit 24 : Disable write access watch in PREGION[0] */ +#define MWU_REGIONENCLR_PRGN0WA_Pos (24UL) /*!< Position of PRGN0WA field. */ +#define MWU_REGIONENCLR_PRGN0WA_Msk (0x1UL << MWU_REGIONENCLR_PRGN0WA_Pos) /*!< Bit mask of PRGN0WA field. */ +#define MWU_REGIONENCLR_PRGN0WA_Disabled (0UL) /*!< Write access watch in this PREGION is disabled */ +#define MWU_REGIONENCLR_PRGN0WA_Enabled (1UL) /*!< Write access watch in this PREGION is enabled */ +#define MWU_REGIONENCLR_PRGN0WA_Clear (1UL) /*!< Disable write access watch in this PREGION */ + +/* Bit 7 : Disable read access watch in region[3] */ +#define MWU_REGIONENCLR_RGN3RA_Pos (7UL) /*!< Position of RGN3RA field. */ +#define MWU_REGIONENCLR_RGN3RA_Msk (0x1UL << MWU_REGIONENCLR_RGN3RA_Pos) /*!< Bit mask of RGN3RA field. */ +#define MWU_REGIONENCLR_RGN3RA_Disabled (0UL) /*!< Read access watch in this region is disabled */ +#define MWU_REGIONENCLR_RGN3RA_Enabled (1UL) /*!< Read access watch in this region is enabled */ +#define MWU_REGIONENCLR_RGN3RA_Clear (1UL) /*!< Disable read access watch in this region */ + +/* Bit 6 : Disable write access watch in region[3] */ +#define MWU_REGIONENCLR_RGN3WA_Pos (6UL) /*!< Position of RGN3WA field. */ +#define MWU_REGIONENCLR_RGN3WA_Msk (0x1UL << MWU_REGIONENCLR_RGN3WA_Pos) /*!< Bit mask of RGN3WA field. */ +#define MWU_REGIONENCLR_RGN3WA_Disabled (0UL) /*!< Write access watch in this region is disabled */ +#define MWU_REGIONENCLR_RGN3WA_Enabled (1UL) /*!< Write access watch in this region is enabled */ +#define MWU_REGIONENCLR_RGN3WA_Clear (1UL) /*!< Disable write access watch in this region */ + +/* Bit 5 : Disable read access watch in region[2] */ +#define MWU_REGIONENCLR_RGN2RA_Pos (5UL) /*!< Position of RGN2RA field. */ +#define MWU_REGIONENCLR_RGN2RA_Msk (0x1UL << MWU_REGIONENCLR_RGN2RA_Pos) /*!< Bit mask of RGN2RA field. */ +#define MWU_REGIONENCLR_RGN2RA_Disabled (0UL) /*!< Read access watch in this region is disabled */ +#define MWU_REGIONENCLR_RGN2RA_Enabled (1UL) /*!< Read access watch in this region is enabled */ +#define MWU_REGIONENCLR_RGN2RA_Clear (1UL) /*!< Disable read access watch in this region */ + +/* Bit 4 : Disable write access watch in region[2] */ +#define MWU_REGIONENCLR_RGN2WA_Pos (4UL) /*!< Position of RGN2WA field. */ +#define MWU_REGIONENCLR_RGN2WA_Msk (0x1UL << MWU_REGIONENCLR_RGN2WA_Pos) /*!< Bit mask of RGN2WA field. */ +#define MWU_REGIONENCLR_RGN2WA_Disabled (0UL) /*!< Write access watch in this region is disabled */ +#define MWU_REGIONENCLR_RGN2WA_Enabled (1UL) /*!< Write access watch in this region is enabled */ +#define MWU_REGIONENCLR_RGN2WA_Clear (1UL) /*!< Disable write access watch in this region */ + +/* Bit 3 : Disable read access watch in region[1] */ +#define MWU_REGIONENCLR_RGN1RA_Pos (3UL) /*!< Position of RGN1RA field. */ +#define MWU_REGIONENCLR_RGN1RA_Msk (0x1UL << MWU_REGIONENCLR_RGN1RA_Pos) /*!< Bit mask of RGN1RA field. */ +#define MWU_REGIONENCLR_RGN1RA_Disabled (0UL) /*!< Read access watch in this region is disabled */ +#define MWU_REGIONENCLR_RGN1RA_Enabled (1UL) /*!< Read access watch in this region is enabled */ +#define MWU_REGIONENCLR_RGN1RA_Clear (1UL) /*!< Disable read access watch in this region */ + +/* Bit 2 : Disable write access watch in region[1] */ +#define MWU_REGIONENCLR_RGN1WA_Pos (2UL) /*!< Position of RGN1WA field. */ +#define MWU_REGIONENCLR_RGN1WA_Msk (0x1UL << MWU_REGIONENCLR_RGN1WA_Pos) /*!< Bit mask of RGN1WA field. */ +#define MWU_REGIONENCLR_RGN1WA_Disabled (0UL) /*!< Write access watch in this region is disabled */ +#define MWU_REGIONENCLR_RGN1WA_Enabled (1UL) /*!< Write access watch in this region is enabled */ +#define MWU_REGIONENCLR_RGN1WA_Clear (1UL) /*!< Disable write access watch in this region */ + +/* Bit 1 : Disable read access watch in region[0] */ +#define MWU_REGIONENCLR_RGN0RA_Pos (1UL) /*!< Position of RGN0RA field. */ +#define MWU_REGIONENCLR_RGN0RA_Msk (0x1UL << MWU_REGIONENCLR_RGN0RA_Pos) /*!< Bit mask of RGN0RA field. */ +#define MWU_REGIONENCLR_RGN0RA_Disabled (0UL) /*!< Read access watch in this region is disabled */ +#define MWU_REGIONENCLR_RGN0RA_Enabled (1UL) /*!< Read access watch in this region is enabled */ +#define MWU_REGIONENCLR_RGN0RA_Clear (1UL) /*!< Disable read access watch in this region */ + +/* Bit 0 : Disable write access watch in region[0] */ +#define MWU_REGIONENCLR_RGN0WA_Pos (0UL) /*!< Position of RGN0WA field. */ +#define MWU_REGIONENCLR_RGN0WA_Msk (0x1UL << MWU_REGIONENCLR_RGN0WA_Pos) /*!< Bit mask of RGN0WA field. */ +#define MWU_REGIONENCLR_RGN0WA_Disabled (0UL) /*!< Write access watch in this region is disabled */ +#define MWU_REGIONENCLR_RGN0WA_Enabled (1UL) /*!< Write access watch in this region is enabled */ +#define MWU_REGIONENCLR_RGN0WA_Clear (1UL) /*!< Disable write access watch in this region */ + +/* Register: MWU_REGION_START */ +/* Description: Description cluster[0]: Start address for region 0 */ + +/* Bits 31..0 : Start address for region */ +#define MWU_REGION_START_START_Pos (0UL) /*!< Position of START field. */ +#define MWU_REGION_START_START_Msk (0xFFFFFFFFUL << MWU_REGION_START_START_Pos) /*!< Bit mask of START field. */ + +/* Register: MWU_REGION_END */ +/* Description: Description cluster[0]: End address of region 0 */ + +/* Bits 31..0 : End address of region. */ +#define MWU_REGION_END_END_Pos (0UL) /*!< Position of END field. */ +#define MWU_REGION_END_END_Msk (0xFFFFFFFFUL << MWU_REGION_END_END_Pos) /*!< Bit mask of END field. */ + +/* Register: MWU_PREGION_START */ +/* Description: Description cluster[0]: Reserved for future use */ + +/* Bits 31..0 : Reserved for future use */ +#define MWU_PREGION_START_START_Pos (0UL) /*!< Position of START field. */ +#define MWU_PREGION_START_START_Msk (0xFFFFFFFFUL << MWU_PREGION_START_START_Pos) /*!< Bit mask of START field. */ + +/* Register: MWU_PREGION_END */ +/* Description: Description cluster[0]: Reserved for future use */ + +/* Bits 31..0 : Reserved for future use */ +#define MWU_PREGION_END_END_Pos (0UL) /*!< Position of END field. */ +#define MWU_PREGION_END_END_Msk (0xFFFFFFFFUL << MWU_PREGION_END_END_Pos) /*!< Bit mask of END field. */ + +/* Register: MWU_PREGION_SUBS */ +/* Description: Description cluster[0]: Subregions of region 0 */ + +/* Bit 31 : Include or exclude subregion 31 in region */ +#define MWU_PREGION_SUBS_SR31_Pos (31UL) /*!< Position of SR31 field. */ +#define MWU_PREGION_SUBS_SR31_Msk (0x1UL << MWU_PREGION_SUBS_SR31_Pos) /*!< Bit mask of SR31 field. */ +#define MWU_PREGION_SUBS_SR31_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR31_Include (1UL) /*!< Include */ + +/* Bit 30 : Include or exclude subregion 30 in region */ +#define MWU_PREGION_SUBS_SR30_Pos (30UL) /*!< Position of SR30 field. */ +#define MWU_PREGION_SUBS_SR30_Msk (0x1UL << MWU_PREGION_SUBS_SR30_Pos) /*!< Bit mask of SR30 field. */ +#define MWU_PREGION_SUBS_SR30_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR30_Include (1UL) /*!< Include */ + +/* Bit 29 : Include or exclude subregion 29 in region */ +#define MWU_PREGION_SUBS_SR29_Pos (29UL) /*!< Position of SR29 field. */ +#define MWU_PREGION_SUBS_SR29_Msk (0x1UL << MWU_PREGION_SUBS_SR29_Pos) /*!< Bit mask of SR29 field. */ +#define MWU_PREGION_SUBS_SR29_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR29_Include (1UL) /*!< Include */ + +/* Bit 28 : Include or exclude subregion 28 in region */ +#define MWU_PREGION_SUBS_SR28_Pos (28UL) /*!< Position of SR28 field. */ +#define MWU_PREGION_SUBS_SR28_Msk (0x1UL << MWU_PREGION_SUBS_SR28_Pos) /*!< Bit mask of SR28 field. */ +#define MWU_PREGION_SUBS_SR28_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR28_Include (1UL) /*!< Include */ + +/* Bit 27 : Include or exclude subregion 27 in region */ +#define MWU_PREGION_SUBS_SR27_Pos (27UL) /*!< Position of SR27 field. */ +#define MWU_PREGION_SUBS_SR27_Msk (0x1UL << MWU_PREGION_SUBS_SR27_Pos) /*!< Bit mask of SR27 field. */ +#define MWU_PREGION_SUBS_SR27_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR27_Include (1UL) /*!< Include */ + +/* Bit 26 : Include or exclude subregion 26 in region */ +#define MWU_PREGION_SUBS_SR26_Pos (26UL) /*!< Position of SR26 field. */ +#define MWU_PREGION_SUBS_SR26_Msk (0x1UL << MWU_PREGION_SUBS_SR26_Pos) /*!< Bit mask of SR26 field. */ +#define MWU_PREGION_SUBS_SR26_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR26_Include (1UL) /*!< Include */ + +/* Bit 25 : Include or exclude subregion 25 in region */ +#define MWU_PREGION_SUBS_SR25_Pos (25UL) /*!< Position of SR25 field. */ +#define MWU_PREGION_SUBS_SR25_Msk (0x1UL << MWU_PREGION_SUBS_SR25_Pos) /*!< Bit mask of SR25 field. */ +#define MWU_PREGION_SUBS_SR25_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR25_Include (1UL) /*!< Include */ + +/* Bit 24 : Include or exclude subregion 24 in region */ +#define MWU_PREGION_SUBS_SR24_Pos (24UL) /*!< Position of SR24 field. */ +#define MWU_PREGION_SUBS_SR24_Msk (0x1UL << MWU_PREGION_SUBS_SR24_Pos) /*!< Bit mask of SR24 field. */ +#define MWU_PREGION_SUBS_SR24_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR24_Include (1UL) /*!< Include */ + +/* Bit 23 : Include or exclude subregion 23 in region */ +#define MWU_PREGION_SUBS_SR23_Pos (23UL) /*!< Position of SR23 field. */ +#define MWU_PREGION_SUBS_SR23_Msk (0x1UL << MWU_PREGION_SUBS_SR23_Pos) /*!< Bit mask of SR23 field. */ +#define MWU_PREGION_SUBS_SR23_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR23_Include (1UL) /*!< Include */ + +/* Bit 22 : Include or exclude subregion 22 in region */ +#define MWU_PREGION_SUBS_SR22_Pos (22UL) /*!< Position of SR22 field. */ +#define MWU_PREGION_SUBS_SR22_Msk (0x1UL << MWU_PREGION_SUBS_SR22_Pos) /*!< Bit mask of SR22 field. */ +#define MWU_PREGION_SUBS_SR22_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR22_Include (1UL) /*!< Include */ + +/* Bit 21 : Include or exclude subregion 21 in region */ +#define MWU_PREGION_SUBS_SR21_Pos (21UL) /*!< Position of SR21 field. */ +#define MWU_PREGION_SUBS_SR21_Msk (0x1UL << MWU_PREGION_SUBS_SR21_Pos) /*!< Bit mask of SR21 field. */ +#define MWU_PREGION_SUBS_SR21_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR21_Include (1UL) /*!< Include */ + +/* Bit 20 : Include or exclude subregion 20 in region */ +#define MWU_PREGION_SUBS_SR20_Pos (20UL) /*!< Position of SR20 field. */ +#define MWU_PREGION_SUBS_SR20_Msk (0x1UL << MWU_PREGION_SUBS_SR20_Pos) /*!< Bit mask of SR20 field. */ +#define MWU_PREGION_SUBS_SR20_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR20_Include (1UL) /*!< Include */ + +/* Bit 19 : Include or exclude subregion 19 in region */ +#define MWU_PREGION_SUBS_SR19_Pos (19UL) /*!< Position of SR19 field. */ +#define MWU_PREGION_SUBS_SR19_Msk (0x1UL << MWU_PREGION_SUBS_SR19_Pos) /*!< Bit mask of SR19 field. */ +#define MWU_PREGION_SUBS_SR19_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR19_Include (1UL) /*!< Include */ + +/* Bit 18 : Include or exclude subregion 18 in region */ +#define MWU_PREGION_SUBS_SR18_Pos (18UL) /*!< Position of SR18 field. */ +#define MWU_PREGION_SUBS_SR18_Msk (0x1UL << MWU_PREGION_SUBS_SR18_Pos) /*!< Bit mask of SR18 field. */ +#define MWU_PREGION_SUBS_SR18_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR18_Include (1UL) /*!< Include */ + +/* Bit 17 : Include or exclude subregion 17 in region */ +#define MWU_PREGION_SUBS_SR17_Pos (17UL) /*!< Position of SR17 field. */ +#define MWU_PREGION_SUBS_SR17_Msk (0x1UL << MWU_PREGION_SUBS_SR17_Pos) /*!< Bit mask of SR17 field. */ +#define MWU_PREGION_SUBS_SR17_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR17_Include (1UL) /*!< Include */ + +/* Bit 16 : Include or exclude subregion 16 in region */ +#define MWU_PREGION_SUBS_SR16_Pos (16UL) /*!< Position of SR16 field. */ +#define MWU_PREGION_SUBS_SR16_Msk (0x1UL << MWU_PREGION_SUBS_SR16_Pos) /*!< Bit mask of SR16 field. */ +#define MWU_PREGION_SUBS_SR16_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR16_Include (1UL) /*!< Include */ + +/* Bit 15 : Include or exclude subregion 15 in region */ +#define MWU_PREGION_SUBS_SR15_Pos (15UL) /*!< Position of SR15 field. */ +#define MWU_PREGION_SUBS_SR15_Msk (0x1UL << MWU_PREGION_SUBS_SR15_Pos) /*!< Bit mask of SR15 field. */ +#define MWU_PREGION_SUBS_SR15_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR15_Include (1UL) /*!< Include */ + +/* Bit 14 : Include or exclude subregion 14 in region */ +#define MWU_PREGION_SUBS_SR14_Pos (14UL) /*!< Position of SR14 field. */ +#define MWU_PREGION_SUBS_SR14_Msk (0x1UL << MWU_PREGION_SUBS_SR14_Pos) /*!< Bit mask of SR14 field. */ +#define MWU_PREGION_SUBS_SR14_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR14_Include (1UL) /*!< Include */ + +/* Bit 13 : Include or exclude subregion 13 in region */ +#define MWU_PREGION_SUBS_SR13_Pos (13UL) /*!< Position of SR13 field. */ +#define MWU_PREGION_SUBS_SR13_Msk (0x1UL << MWU_PREGION_SUBS_SR13_Pos) /*!< Bit mask of SR13 field. */ +#define MWU_PREGION_SUBS_SR13_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR13_Include (1UL) /*!< Include */ + +/* Bit 12 : Include or exclude subregion 12 in region */ +#define MWU_PREGION_SUBS_SR12_Pos (12UL) /*!< Position of SR12 field. */ +#define MWU_PREGION_SUBS_SR12_Msk (0x1UL << MWU_PREGION_SUBS_SR12_Pos) /*!< Bit mask of SR12 field. */ +#define MWU_PREGION_SUBS_SR12_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR12_Include (1UL) /*!< Include */ + +/* Bit 11 : Include or exclude subregion 11 in region */ +#define MWU_PREGION_SUBS_SR11_Pos (11UL) /*!< Position of SR11 field. */ +#define MWU_PREGION_SUBS_SR11_Msk (0x1UL << MWU_PREGION_SUBS_SR11_Pos) /*!< Bit mask of SR11 field. */ +#define MWU_PREGION_SUBS_SR11_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR11_Include (1UL) /*!< Include */ + +/* Bit 10 : Include or exclude subregion 10 in region */ +#define MWU_PREGION_SUBS_SR10_Pos (10UL) /*!< Position of SR10 field. */ +#define MWU_PREGION_SUBS_SR10_Msk (0x1UL << MWU_PREGION_SUBS_SR10_Pos) /*!< Bit mask of SR10 field. */ +#define MWU_PREGION_SUBS_SR10_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR10_Include (1UL) /*!< Include */ + +/* Bit 9 : Include or exclude subregion 9 in region */ +#define MWU_PREGION_SUBS_SR9_Pos (9UL) /*!< Position of SR9 field. */ +#define MWU_PREGION_SUBS_SR9_Msk (0x1UL << MWU_PREGION_SUBS_SR9_Pos) /*!< Bit mask of SR9 field. */ +#define MWU_PREGION_SUBS_SR9_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR9_Include (1UL) /*!< Include */ + +/* Bit 8 : Include or exclude subregion 8 in region */ +#define MWU_PREGION_SUBS_SR8_Pos (8UL) /*!< Position of SR8 field. */ +#define MWU_PREGION_SUBS_SR8_Msk (0x1UL << MWU_PREGION_SUBS_SR8_Pos) /*!< Bit mask of SR8 field. */ +#define MWU_PREGION_SUBS_SR8_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR8_Include (1UL) /*!< Include */ + +/* Bit 7 : Include or exclude subregion 7 in region */ +#define MWU_PREGION_SUBS_SR7_Pos (7UL) /*!< Position of SR7 field. */ +#define MWU_PREGION_SUBS_SR7_Msk (0x1UL << MWU_PREGION_SUBS_SR7_Pos) /*!< Bit mask of SR7 field. */ +#define MWU_PREGION_SUBS_SR7_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR7_Include (1UL) /*!< Include */ + +/* Bit 6 : Include or exclude subregion 6 in region */ +#define MWU_PREGION_SUBS_SR6_Pos (6UL) /*!< Position of SR6 field. */ +#define MWU_PREGION_SUBS_SR6_Msk (0x1UL << MWU_PREGION_SUBS_SR6_Pos) /*!< Bit mask of SR6 field. */ +#define MWU_PREGION_SUBS_SR6_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR6_Include (1UL) /*!< Include */ + +/* Bit 5 : Include or exclude subregion 5 in region */ +#define MWU_PREGION_SUBS_SR5_Pos (5UL) /*!< Position of SR5 field. */ +#define MWU_PREGION_SUBS_SR5_Msk (0x1UL << MWU_PREGION_SUBS_SR5_Pos) /*!< Bit mask of SR5 field. */ +#define MWU_PREGION_SUBS_SR5_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR5_Include (1UL) /*!< Include */ + +/* Bit 4 : Include or exclude subregion 4 in region */ +#define MWU_PREGION_SUBS_SR4_Pos (4UL) /*!< Position of SR4 field. */ +#define MWU_PREGION_SUBS_SR4_Msk (0x1UL << MWU_PREGION_SUBS_SR4_Pos) /*!< Bit mask of SR4 field. */ +#define MWU_PREGION_SUBS_SR4_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR4_Include (1UL) /*!< Include */ + +/* Bit 3 : Include or exclude subregion 3 in region */ +#define MWU_PREGION_SUBS_SR3_Pos (3UL) /*!< Position of SR3 field. */ +#define MWU_PREGION_SUBS_SR3_Msk (0x1UL << MWU_PREGION_SUBS_SR3_Pos) /*!< Bit mask of SR3 field. */ +#define MWU_PREGION_SUBS_SR3_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR3_Include (1UL) /*!< Include */ + +/* Bit 2 : Include or exclude subregion 2 in region */ +#define MWU_PREGION_SUBS_SR2_Pos (2UL) /*!< Position of SR2 field. */ +#define MWU_PREGION_SUBS_SR2_Msk (0x1UL << MWU_PREGION_SUBS_SR2_Pos) /*!< Bit mask of SR2 field. */ +#define MWU_PREGION_SUBS_SR2_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR2_Include (1UL) /*!< Include */ + +/* Bit 1 : Include or exclude subregion 1 in region */ +#define MWU_PREGION_SUBS_SR1_Pos (1UL) /*!< Position of SR1 field. */ +#define MWU_PREGION_SUBS_SR1_Msk (0x1UL << MWU_PREGION_SUBS_SR1_Pos) /*!< Bit mask of SR1 field. */ +#define MWU_PREGION_SUBS_SR1_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR1_Include (1UL) /*!< Include */ + +/* Bit 0 : Include or exclude subregion 0 in region */ +#define MWU_PREGION_SUBS_SR0_Pos (0UL) /*!< Position of SR0 field. */ +#define MWU_PREGION_SUBS_SR0_Msk (0x1UL << MWU_PREGION_SUBS_SR0_Pos) /*!< Bit mask of SR0 field. */ +#define MWU_PREGION_SUBS_SR0_Exclude (0UL) /*!< Exclude */ +#define MWU_PREGION_SUBS_SR0_Include (1UL) /*!< Include */ + + +/* Peripheral: NFCT */ +/* Description: NFC-A compatible radio */ + +/* Register: NFCT_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 5 : Shortcut between TXFRAMEEND event and ENABLERXDATA task */ +#define NFCT_SHORTS_TXFRAMEEND_ENABLERXDATA_Pos (5UL) /*!< Position of TXFRAMEEND_ENABLERXDATA field. */ +#define NFCT_SHORTS_TXFRAMEEND_ENABLERXDATA_Msk (0x1UL << NFCT_SHORTS_TXFRAMEEND_ENABLERXDATA_Pos) /*!< Bit mask of TXFRAMEEND_ENABLERXDATA field. */ +#define NFCT_SHORTS_TXFRAMEEND_ENABLERXDATA_Disabled (0UL) /*!< Disable shortcut */ +#define NFCT_SHORTS_TXFRAMEEND_ENABLERXDATA_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between FIELDLOST event and SENSE task */ +#define NFCT_SHORTS_FIELDLOST_SENSE_Pos (1UL) /*!< Position of FIELDLOST_SENSE field. */ +#define NFCT_SHORTS_FIELDLOST_SENSE_Msk (0x1UL << NFCT_SHORTS_FIELDLOST_SENSE_Pos) /*!< Bit mask of FIELDLOST_SENSE field. */ +#define NFCT_SHORTS_FIELDLOST_SENSE_Disabled (0UL) /*!< Disable shortcut */ +#define NFCT_SHORTS_FIELDLOST_SENSE_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between FIELDDETECTED event and ACTIVATE task */ +#define NFCT_SHORTS_FIELDDETECTED_ACTIVATE_Pos (0UL) /*!< Position of FIELDDETECTED_ACTIVATE field. */ +#define NFCT_SHORTS_FIELDDETECTED_ACTIVATE_Msk (0x1UL << NFCT_SHORTS_FIELDDETECTED_ACTIVATE_Pos) /*!< Bit mask of FIELDDETECTED_ACTIVATE field. */ +#define NFCT_SHORTS_FIELDDETECTED_ACTIVATE_Disabled (0UL) /*!< Disable shortcut */ +#define NFCT_SHORTS_FIELDDETECTED_ACTIVATE_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: NFCT_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 20 : Enable or disable interrupt for STARTED event */ +#define NFCT_INTEN_STARTED_Pos (20UL) /*!< Position of STARTED field. */ +#define NFCT_INTEN_STARTED_Msk (0x1UL << NFCT_INTEN_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define NFCT_INTEN_STARTED_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_STARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 19 : Enable or disable interrupt for SELECTED event */ +#define NFCT_INTEN_SELECTED_Pos (19UL) /*!< Position of SELECTED field. */ +#define NFCT_INTEN_SELECTED_Msk (0x1UL << NFCT_INTEN_SELECTED_Pos) /*!< Bit mask of SELECTED field. */ +#define NFCT_INTEN_SELECTED_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_SELECTED_Enabled (1UL) /*!< Enable */ + +/* Bit 18 : Enable or disable interrupt for COLLISION event */ +#define NFCT_INTEN_COLLISION_Pos (18UL) /*!< Position of COLLISION field. */ +#define NFCT_INTEN_COLLISION_Msk (0x1UL << NFCT_INTEN_COLLISION_Pos) /*!< Bit mask of COLLISION field. */ +#define NFCT_INTEN_COLLISION_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_COLLISION_Enabled (1UL) /*!< Enable */ + +/* Bit 14 : Enable or disable interrupt for AUTOCOLRESSTARTED event */ +#define NFCT_INTEN_AUTOCOLRESSTARTED_Pos (14UL) /*!< Position of AUTOCOLRESSTARTED field. */ +#define NFCT_INTEN_AUTOCOLRESSTARTED_Msk (0x1UL << NFCT_INTEN_AUTOCOLRESSTARTED_Pos) /*!< Bit mask of AUTOCOLRESSTARTED field. */ +#define NFCT_INTEN_AUTOCOLRESSTARTED_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_AUTOCOLRESSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 12 : Enable or disable interrupt for ENDTX event */ +#define NFCT_INTEN_ENDTX_Pos (12UL) /*!< Position of ENDTX field. */ +#define NFCT_INTEN_ENDTX_Msk (0x1UL << NFCT_INTEN_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define NFCT_INTEN_ENDTX_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_ENDTX_Enabled (1UL) /*!< Enable */ + +/* Bit 11 : Enable or disable interrupt for ENDRX event */ +#define NFCT_INTEN_ENDRX_Pos (11UL) /*!< Position of ENDRX field. */ +#define NFCT_INTEN_ENDRX_Msk (0x1UL << NFCT_INTEN_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define NFCT_INTEN_ENDRX_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_ENDRX_Enabled (1UL) /*!< Enable */ + +/* Bit 10 : Enable or disable interrupt for RXERROR event */ +#define NFCT_INTEN_RXERROR_Pos (10UL) /*!< Position of RXERROR field. */ +#define NFCT_INTEN_RXERROR_Msk (0x1UL << NFCT_INTEN_RXERROR_Pos) /*!< Bit mask of RXERROR field. */ +#define NFCT_INTEN_RXERROR_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_RXERROR_Enabled (1UL) /*!< Enable */ + +/* Bit 7 : Enable or disable interrupt for ERROR event */ +#define NFCT_INTEN_ERROR_Pos (7UL) /*!< Position of ERROR field. */ +#define NFCT_INTEN_ERROR_Msk (0x1UL << NFCT_INTEN_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define NFCT_INTEN_ERROR_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_ERROR_Enabled (1UL) /*!< Enable */ + +/* Bit 6 : Enable or disable interrupt for RXFRAMEEND event */ +#define NFCT_INTEN_RXFRAMEEND_Pos (6UL) /*!< Position of RXFRAMEEND field. */ +#define NFCT_INTEN_RXFRAMEEND_Msk (0x1UL << NFCT_INTEN_RXFRAMEEND_Pos) /*!< Bit mask of RXFRAMEEND field. */ +#define NFCT_INTEN_RXFRAMEEND_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_RXFRAMEEND_Enabled (1UL) /*!< Enable */ + +/* Bit 5 : Enable or disable interrupt for RXFRAMESTART event */ +#define NFCT_INTEN_RXFRAMESTART_Pos (5UL) /*!< Position of RXFRAMESTART field. */ +#define NFCT_INTEN_RXFRAMESTART_Msk (0x1UL << NFCT_INTEN_RXFRAMESTART_Pos) /*!< Bit mask of RXFRAMESTART field. */ +#define NFCT_INTEN_RXFRAMESTART_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_RXFRAMESTART_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable interrupt for TXFRAMEEND event */ +#define NFCT_INTEN_TXFRAMEEND_Pos (4UL) /*!< Position of TXFRAMEEND field. */ +#define NFCT_INTEN_TXFRAMEEND_Msk (0x1UL << NFCT_INTEN_TXFRAMEEND_Pos) /*!< Bit mask of TXFRAMEEND field. */ +#define NFCT_INTEN_TXFRAMEEND_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_TXFRAMEEND_Enabled (1UL) /*!< Enable */ + +/* Bit 3 : Enable or disable interrupt for TXFRAMESTART event */ +#define NFCT_INTEN_TXFRAMESTART_Pos (3UL) /*!< Position of TXFRAMESTART field. */ +#define NFCT_INTEN_TXFRAMESTART_Msk (0x1UL << NFCT_INTEN_TXFRAMESTART_Pos) /*!< Bit mask of TXFRAMESTART field. */ +#define NFCT_INTEN_TXFRAMESTART_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_TXFRAMESTART_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for FIELDLOST event */ +#define NFCT_INTEN_FIELDLOST_Pos (2UL) /*!< Position of FIELDLOST field. */ +#define NFCT_INTEN_FIELDLOST_Msk (0x1UL << NFCT_INTEN_FIELDLOST_Pos) /*!< Bit mask of FIELDLOST field. */ +#define NFCT_INTEN_FIELDLOST_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_FIELDLOST_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for FIELDDETECTED event */ +#define NFCT_INTEN_FIELDDETECTED_Pos (1UL) /*!< Position of FIELDDETECTED field. */ +#define NFCT_INTEN_FIELDDETECTED_Msk (0x1UL << NFCT_INTEN_FIELDDETECTED_Pos) /*!< Bit mask of FIELDDETECTED field. */ +#define NFCT_INTEN_FIELDDETECTED_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_FIELDDETECTED_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable interrupt for READY event */ +#define NFCT_INTEN_READY_Pos (0UL) /*!< Position of READY field. */ +#define NFCT_INTEN_READY_Msk (0x1UL << NFCT_INTEN_READY_Pos) /*!< Bit mask of READY field. */ +#define NFCT_INTEN_READY_Disabled (0UL) /*!< Disable */ +#define NFCT_INTEN_READY_Enabled (1UL) /*!< Enable */ + +/* Register: NFCT_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 20 : Write '1' to Enable interrupt for STARTED event */ +#define NFCT_INTENSET_STARTED_Pos (20UL) /*!< Position of STARTED field. */ +#define NFCT_INTENSET_STARTED_Msk (0x1UL << NFCT_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define NFCT_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_STARTED_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for SELECTED event */ +#define NFCT_INTENSET_SELECTED_Pos (19UL) /*!< Position of SELECTED field. */ +#define NFCT_INTENSET_SELECTED_Msk (0x1UL << NFCT_INTENSET_SELECTED_Pos) /*!< Bit mask of SELECTED field. */ +#define NFCT_INTENSET_SELECTED_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_SELECTED_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_SELECTED_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for COLLISION event */ +#define NFCT_INTENSET_COLLISION_Pos (18UL) /*!< Position of COLLISION field. */ +#define NFCT_INTENSET_COLLISION_Msk (0x1UL << NFCT_INTENSET_COLLISION_Pos) /*!< Bit mask of COLLISION field. */ +#define NFCT_INTENSET_COLLISION_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_COLLISION_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_COLLISION_Set (1UL) /*!< Enable */ + +/* Bit 14 : Write '1' to Enable interrupt for AUTOCOLRESSTARTED event */ +#define NFCT_INTENSET_AUTOCOLRESSTARTED_Pos (14UL) /*!< Position of AUTOCOLRESSTARTED field. */ +#define NFCT_INTENSET_AUTOCOLRESSTARTED_Msk (0x1UL << NFCT_INTENSET_AUTOCOLRESSTARTED_Pos) /*!< Bit mask of AUTOCOLRESSTARTED field. */ +#define NFCT_INTENSET_AUTOCOLRESSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_AUTOCOLRESSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_AUTOCOLRESSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 12 : Write '1' to Enable interrupt for ENDTX event */ +#define NFCT_INTENSET_ENDTX_Pos (12UL) /*!< Position of ENDTX field. */ +#define NFCT_INTENSET_ENDTX_Msk (0x1UL << NFCT_INTENSET_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define NFCT_INTENSET_ENDTX_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_ENDTX_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_ENDTX_Set (1UL) /*!< Enable */ + +/* Bit 11 : Write '1' to Enable interrupt for ENDRX event */ +#define NFCT_INTENSET_ENDRX_Pos (11UL) /*!< Position of ENDRX field. */ +#define NFCT_INTENSET_ENDRX_Msk (0x1UL << NFCT_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define NFCT_INTENSET_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_ENDRX_Set (1UL) /*!< Enable */ + +/* Bit 10 : Write '1' to Enable interrupt for RXERROR event */ +#define NFCT_INTENSET_RXERROR_Pos (10UL) /*!< Position of RXERROR field. */ +#define NFCT_INTENSET_RXERROR_Msk (0x1UL << NFCT_INTENSET_RXERROR_Pos) /*!< Bit mask of RXERROR field. */ +#define NFCT_INTENSET_RXERROR_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_RXERROR_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_RXERROR_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for ERROR event */ +#define NFCT_INTENSET_ERROR_Pos (7UL) /*!< Position of ERROR field. */ +#define NFCT_INTENSET_ERROR_Msk (0x1UL << NFCT_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define NFCT_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_ERROR_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for RXFRAMEEND event */ +#define NFCT_INTENSET_RXFRAMEEND_Pos (6UL) /*!< Position of RXFRAMEEND field. */ +#define NFCT_INTENSET_RXFRAMEEND_Msk (0x1UL << NFCT_INTENSET_RXFRAMEEND_Pos) /*!< Bit mask of RXFRAMEEND field. */ +#define NFCT_INTENSET_RXFRAMEEND_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_RXFRAMEEND_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_RXFRAMEEND_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for RXFRAMESTART event */ +#define NFCT_INTENSET_RXFRAMESTART_Pos (5UL) /*!< Position of RXFRAMESTART field. */ +#define NFCT_INTENSET_RXFRAMESTART_Msk (0x1UL << NFCT_INTENSET_RXFRAMESTART_Pos) /*!< Bit mask of RXFRAMESTART field. */ +#define NFCT_INTENSET_RXFRAMESTART_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_RXFRAMESTART_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_RXFRAMESTART_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for TXFRAMEEND event */ +#define NFCT_INTENSET_TXFRAMEEND_Pos (4UL) /*!< Position of TXFRAMEEND field. */ +#define NFCT_INTENSET_TXFRAMEEND_Msk (0x1UL << NFCT_INTENSET_TXFRAMEEND_Pos) /*!< Bit mask of TXFRAMEEND field. */ +#define NFCT_INTENSET_TXFRAMEEND_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_TXFRAMEEND_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_TXFRAMEEND_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for TXFRAMESTART event */ +#define NFCT_INTENSET_TXFRAMESTART_Pos (3UL) /*!< Position of TXFRAMESTART field. */ +#define NFCT_INTENSET_TXFRAMESTART_Msk (0x1UL << NFCT_INTENSET_TXFRAMESTART_Pos) /*!< Bit mask of TXFRAMESTART field. */ +#define NFCT_INTENSET_TXFRAMESTART_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_TXFRAMESTART_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_TXFRAMESTART_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for FIELDLOST event */ +#define NFCT_INTENSET_FIELDLOST_Pos (2UL) /*!< Position of FIELDLOST field. */ +#define NFCT_INTENSET_FIELDLOST_Msk (0x1UL << NFCT_INTENSET_FIELDLOST_Pos) /*!< Bit mask of FIELDLOST field. */ +#define NFCT_INTENSET_FIELDLOST_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_FIELDLOST_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_FIELDLOST_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for FIELDDETECTED event */ +#define NFCT_INTENSET_FIELDDETECTED_Pos (1UL) /*!< Position of FIELDDETECTED field. */ +#define NFCT_INTENSET_FIELDDETECTED_Msk (0x1UL << NFCT_INTENSET_FIELDDETECTED_Pos) /*!< Bit mask of FIELDDETECTED field. */ +#define NFCT_INTENSET_FIELDDETECTED_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_FIELDDETECTED_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_FIELDDETECTED_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for READY event */ +#define NFCT_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */ +#define NFCT_INTENSET_READY_Msk (0x1UL << NFCT_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ +#define NFCT_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENSET_READY_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENSET_READY_Set (1UL) /*!< Enable */ + +/* Register: NFCT_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 20 : Write '1' to Disable interrupt for STARTED event */ +#define NFCT_INTENCLR_STARTED_Pos (20UL) /*!< Position of STARTED field. */ +#define NFCT_INTENCLR_STARTED_Msk (0x1UL << NFCT_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define NFCT_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_STARTED_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for SELECTED event */ +#define NFCT_INTENCLR_SELECTED_Pos (19UL) /*!< Position of SELECTED field. */ +#define NFCT_INTENCLR_SELECTED_Msk (0x1UL << NFCT_INTENCLR_SELECTED_Pos) /*!< Bit mask of SELECTED field. */ +#define NFCT_INTENCLR_SELECTED_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_SELECTED_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_SELECTED_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for COLLISION event */ +#define NFCT_INTENCLR_COLLISION_Pos (18UL) /*!< Position of COLLISION field. */ +#define NFCT_INTENCLR_COLLISION_Msk (0x1UL << NFCT_INTENCLR_COLLISION_Pos) /*!< Bit mask of COLLISION field. */ +#define NFCT_INTENCLR_COLLISION_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_COLLISION_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_COLLISION_Clear (1UL) /*!< Disable */ + +/* Bit 14 : Write '1' to Disable interrupt for AUTOCOLRESSTARTED event */ +#define NFCT_INTENCLR_AUTOCOLRESSTARTED_Pos (14UL) /*!< Position of AUTOCOLRESSTARTED field. */ +#define NFCT_INTENCLR_AUTOCOLRESSTARTED_Msk (0x1UL << NFCT_INTENCLR_AUTOCOLRESSTARTED_Pos) /*!< Bit mask of AUTOCOLRESSTARTED field. */ +#define NFCT_INTENCLR_AUTOCOLRESSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_AUTOCOLRESSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_AUTOCOLRESSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 12 : Write '1' to Disable interrupt for ENDTX event */ +#define NFCT_INTENCLR_ENDTX_Pos (12UL) /*!< Position of ENDTX field. */ +#define NFCT_INTENCLR_ENDTX_Msk (0x1UL << NFCT_INTENCLR_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define NFCT_INTENCLR_ENDTX_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_ENDTX_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_ENDTX_Clear (1UL) /*!< Disable */ + +/* Bit 11 : Write '1' to Disable interrupt for ENDRX event */ +#define NFCT_INTENCLR_ENDRX_Pos (11UL) /*!< Position of ENDRX field. */ +#define NFCT_INTENCLR_ENDRX_Msk (0x1UL << NFCT_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define NFCT_INTENCLR_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_ENDRX_Clear (1UL) /*!< Disable */ + +/* Bit 10 : Write '1' to Disable interrupt for RXERROR event */ +#define NFCT_INTENCLR_RXERROR_Pos (10UL) /*!< Position of RXERROR field. */ +#define NFCT_INTENCLR_RXERROR_Msk (0x1UL << NFCT_INTENCLR_RXERROR_Pos) /*!< Bit mask of RXERROR field. */ +#define NFCT_INTENCLR_RXERROR_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_RXERROR_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_RXERROR_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for ERROR event */ +#define NFCT_INTENCLR_ERROR_Pos (7UL) /*!< Position of ERROR field. */ +#define NFCT_INTENCLR_ERROR_Msk (0x1UL << NFCT_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define NFCT_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for RXFRAMEEND event */ +#define NFCT_INTENCLR_RXFRAMEEND_Pos (6UL) /*!< Position of RXFRAMEEND field. */ +#define NFCT_INTENCLR_RXFRAMEEND_Msk (0x1UL << NFCT_INTENCLR_RXFRAMEEND_Pos) /*!< Bit mask of RXFRAMEEND field. */ +#define NFCT_INTENCLR_RXFRAMEEND_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_RXFRAMEEND_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_RXFRAMEEND_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for RXFRAMESTART event */ +#define NFCT_INTENCLR_RXFRAMESTART_Pos (5UL) /*!< Position of RXFRAMESTART field. */ +#define NFCT_INTENCLR_RXFRAMESTART_Msk (0x1UL << NFCT_INTENCLR_RXFRAMESTART_Pos) /*!< Bit mask of RXFRAMESTART field. */ +#define NFCT_INTENCLR_RXFRAMESTART_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_RXFRAMESTART_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_RXFRAMESTART_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for TXFRAMEEND event */ +#define NFCT_INTENCLR_TXFRAMEEND_Pos (4UL) /*!< Position of TXFRAMEEND field. */ +#define NFCT_INTENCLR_TXFRAMEEND_Msk (0x1UL << NFCT_INTENCLR_TXFRAMEEND_Pos) /*!< Bit mask of TXFRAMEEND field. */ +#define NFCT_INTENCLR_TXFRAMEEND_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_TXFRAMEEND_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_TXFRAMEEND_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for TXFRAMESTART event */ +#define NFCT_INTENCLR_TXFRAMESTART_Pos (3UL) /*!< Position of TXFRAMESTART field. */ +#define NFCT_INTENCLR_TXFRAMESTART_Msk (0x1UL << NFCT_INTENCLR_TXFRAMESTART_Pos) /*!< Bit mask of TXFRAMESTART field. */ +#define NFCT_INTENCLR_TXFRAMESTART_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_TXFRAMESTART_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_TXFRAMESTART_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for FIELDLOST event */ +#define NFCT_INTENCLR_FIELDLOST_Pos (2UL) /*!< Position of FIELDLOST field. */ +#define NFCT_INTENCLR_FIELDLOST_Msk (0x1UL << NFCT_INTENCLR_FIELDLOST_Pos) /*!< Bit mask of FIELDLOST field. */ +#define NFCT_INTENCLR_FIELDLOST_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_FIELDLOST_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_FIELDLOST_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for FIELDDETECTED event */ +#define NFCT_INTENCLR_FIELDDETECTED_Pos (1UL) /*!< Position of FIELDDETECTED field. */ +#define NFCT_INTENCLR_FIELDDETECTED_Msk (0x1UL << NFCT_INTENCLR_FIELDDETECTED_Pos) /*!< Bit mask of FIELDDETECTED field. */ +#define NFCT_INTENCLR_FIELDDETECTED_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_FIELDDETECTED_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_FIELDDETECTED_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for READY event */ +#define NFCT_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */ +#define NFCT_INTENCLR_READY_Msk (0x1UL << NFCT_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ +#define NFCT_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ +#define NFCT_INTENCLR_READY_Enabled (1UL) /*!< Read: Enabled */ +#define NFCT_INTENCLR_READY_Clear (1UL) /*!< Disable */ + +/* Register: NFCT_ERRORSTATUS */ +/* Description: NFC Error Status register */ + +/* Bit 0 : No STARTTX task triggered before expiration of the time set in FRAMEDELAYMAX */ +#define NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Pos (0UL) /*!< Position of FRAMEDELAYTIMEOUT field. */ +#define NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk (0x1UL << NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Pos) /*!< Bit mask of FRAMEDELAYTIMEOUT field. */ + +/* Register: NFCT_FRAMESTATUS_RX */ +/* Description: Result of last incoming frame */ + +/* Bit 3 : Overrun detected */ +#define NFCT_FRAMESTATUS_RX_OVERRUN_Pos (3UL) /*!< Position of OVERRUN field. */ +#define NFCT_FRAMESTATUS_RX_OVERRUN_Msk (0x1UL << NFCT_FRAMESTATUS_RX_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ +#define NFCT_FRAMESTATUS_RX_OVERRUN_NoOverrun (0UL) /*!< No overrun detected */ +#define NFCT_FRAMESTATUS_RX_OVERRUN_Overrun (1UL) /*!< Overrun error */ + +/* Bit 2 : Parity status of received frame */ +#define NFCT_FRAMESTATUS_RX_PARITYSTATUS_Pos (2UL) /*!< Position of PARITYSTATUS field. */ +#define NFCT_FRAMESTATUS_RX_PARITYSTATUS_Msk (0x1UL << NFCT_FRAMESTATUS_RX_PARITYSTATUS_Pos) /*!< Bit mask of PARITYSTATUS field. */ +#define NFCT_FRAMESTATUS_RX_PARITYSTATUS_ParityOK (0UL) /*!< Frame received with parity OK */ +#define NFCT_FRAMESTATUS_RX_PARITYSTATUS_ParityError (1UL) /*!< Frame received with parity error */ + +/* Bit 0 : No valid end of frame (EoF) detected */ +#define NFCT_FRAMESTATUS_RX_CRCERROR_Pos (0UL) /*!< Position of CRCERROR field. */ +#define NFCT_FRAMESTATUS_RX_CRCERROR_Msk (0x1UL << NFCT_FRAMESTATUS_RX_CRCERROR_Pos) /*!< Bit mask of CRCERROR field. */ +#define NFCT_FRAMESTATUS_RX_CRCERROR_CRCCorrect (0UL) /*!< Valid CRC detected */ +#define NFCT_FRAMESTATUS_RX_CRCERROR_CRCError (1UL) /*!< CRC received does not match local check */ + +/* Register: NFCT_NFCTAGSTATE */ +/* Description: NfcTag state register */ + +/* Bits 2..0 : NfcTag state */ +#define NFCT_NFCTAGSTATE_NFCTAGSTATE_Pos (0UL) /*!< Position of NFCTAGSTATE field. */ +#define NFCT_NFCTAGSTATE_NFCTAGSTATE_Msk (0x7UL << NFCT_NFCTAGSTATE_NFCTAGSTATE_Pos) /*!< Bit mask of NFCTAGSTATE field. */ +#define NFCT_NFCTAGSTATE_NFCTAGSTATE_Disabled (0UL) /*!< Disabled or sense */ +#define NFCT_NFCTAGSTATE_NFCTAGSTATE_RampUp (2UL) /*!< RampUp */ +#define NFCT_NFCTAGSTATE_NFCTAGSTATE_Idle (3UL) /*!< Idle */ +#define NFCT_NFCTAGSTATE_NFCTAGSTATE_Receive (4UL) /*!< Receive */ +#define NFCT_NFCTAGSTATE_NFCTAGSTATE_FrameDelay (5UL) /*!< FrameDelay */ +#define NFCT_NFCTAGSTATE_NFCTAGSTATE_Transmit (6UL) /*!< Transmit */ + +/* Register: NFCT_FIELDPRESENT */ +/* Description: Indicates the presence or not of a valid field */ + +/* Bit 1 : Indicates if the low level has locked to the field */ +#define NFCT_FIELDPRESENT_LOCKDETECT_Pos (1UL) /*!< Position of LOCKDETECT field. */ +#define NFCT_FIELDPRESENT_LOCKDETECT_Msk (0x1UL << NFCT_FIELDPRESENT_LOCKDETECT_Pos) /*!< Bit mask of LOCKDETECT field. */ +#define NFCT_FIELDPRESENT_LOCKDETECT_NotLocked (0UL) /*!< Not locked to field */ +#define NFCT_FIELDPRESENT_LOCKDETECT_Locked (1UL) /*!< Locked to field */ + +/* Bit 0 : Indicates if a valid field is present. Available only in the activated state. */ +#define NFCT_FIELDPRESENT_FIELDPRESENT_Pos (0UL) /*!< Position of FIELDPRESENT field. */ +#define NFCT_FIELDPRESENT_FIELDPRESENT_Msk (0x1UL << NFCT_FIELDPRESENT_FIELDPRESENT_Pos) /*!< Bit mask of FIELDPRESENT field. */ +#define NFCT_FIELDPRESENT_FIELDPRESENT_NoField (0UL) /*!< No valid field detected */ +#define NFCT_FIELDPRESENT_FIELDPRESENT_FieldPresent (1UL) /*!< Valid field detected */ + +/* Register: NFCT_FRAMEDELAYMIN */ +/* Description: Minimum frame delay */ + +/* Bits 15..0 : Minimum frame delay in number of 13.56 MHz clocks */ +#define NFCT_FRAMEDELAYMIN_FRAMEDELAYMIN_Pos (0UL) /*!< Position of FRAMEDELAYMIN field. */ +#define NFCT_FRAMEDELAYMIN_FRAMEDELAYMIN_Msk (0xFFFFUL << NFCT_FRAMEDELAYMIN_FRAMEDELAYMIN_Pos) /*!< Bit mask of FRAMEDELAYMIN field. */ + +/* Register: NFCT_FRAMEDELAYMAX */ +/* Description: Maximum frame delay */ + +/* Bits 15..0 : Maximum frame delay in number of 13.56 MHz clocks */ +#define NFCT_FRAMEDELAYMAX_FRAMEDELAYMAX_Pos (0UL) /*!< Position of FRAMEDELAYMAX field. */ +#define NFCT_FRAMEDELAYMAX_FRAMEDELAYMAX_Msk (0xFFFFUL << NFCT_FRAMEDELAYMAX_FRAMEDELAYMAX_Pos) /*!< Bit mask of FRAMEDELAYMAX field. */ + +/* Register: NFCT_FRAMEDELAYMODE */ +/* Description: Configuration register for the Frame Delay Timer */ + +/* Bits 1..0 : Configuration register for the Frame Delay Timer */ +#define NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos (0UL) /*!< Position of FRAMEDELAYMODE field. */ +#define NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Msk (0x3UL << NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos) /*!< Bit mask of FRAMEDELAYMODE field. */ +#define NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_FreeRun (0UL) /*!< Transmission is independent of frame timer and will start when the STARTTX task is triggered. No timeout. */ +#define NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Window (1UL) /*!< Frame is transmitted between FRAMEDELAYMIN and FRAMEDELAYMAX */ +#define NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_ExactVal (2UL) /*!< Frame is transmitted exactly at FRAMEDELAYMAX */ +#define NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid (3UL) /*!< Frame is transmitted on a bit grid between FRAMEDELAYMIN and FRAMEDELAYMAX */ + +/* Register: NFCT_PACKETPTR */ +/* Description: Packet pointer for TXD and RXD data storage in Data RAM */ + +/* Bits 31..0 : Packet pointer for TXD and RXD data storage in Data RAM. This address is a byte-aligned RAM address. */ +#define NFCT_PACKETPTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define NFCT_PACKETPTR_PTR_Msk (0xFFFFFFFFUL << NFCT_PACKETPTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: NFCT_MAXLEN */ +/* Description: Size of the RAM buffer allocated to TXD and RXD data storage each */ + +/* Bits 8..0 : Size of the RAM buffer allocated to TXD and RXD data storage each */ +#define NFCT_MAXLEN_MAXLEN_Pos (0UL) /*!< Position of MAXLEN field. */ +#define NFCT_MAXLEN_MAXLEN_Msk (0x1FFUL << NFCT_MAXLEN_MAXLEN_Pos) /*!< Bit mask of MAXLEN field. */ + +/* Register: NFCT_TXD_FRAMECONFIG */ +/* Description: Configuration of outgoing frames */ + +/* Bit 4 : CRC mode for outgoing frames */ +#define NFCT_TXD_FRAMECONFIG_CRCMODETX_Pos (4UL) /*!< Position of CRCMODETX field. */ +#define NFCT_TXD_FRAMECONFIG_CRCMODETX_Msk (0x1UL << NFCT_TXD_FRAMECONFIG_CRCMODETX_Pos) /*!< Bit mask of CRCMODETX field. */ +#define NFCT_TXD_FRAMECONFIG_CRCMODETX_NoCRCTX (0UL) /*!< CRC is not added to the frame */ +#define NFCT_TXD_FRAMECONFIG_CRCMODETX_CRC16TX (1UL) /*!< 16 bit CRC added to the frame based on all the data read from RAM that is used in the frame */ + +/* Bit 2 : Adding SoF or not in TX frames */ +#define NFCT_TXD_FRAMECONFIG_SOF_Pos (2UL) /*!< Position of SOF field. */ +#define NFCT_TXD_FRAMECONFIG_SOF_Msk (0x1UL << NFCT_TXD_FRAMECONFIG_SOF_Pos) /*!< Bit mask of SOF field. */ +#define NFCT_TXD_FRAMECONFIG_SOF_NoSoF (0UL) /*!< SoF symbol not added */ +#define NFCT_TXD_FRAMECONFIG_SOF_SoF (1UL) /*!< SoF symbol added */ + +/* Bit 1 : Discarding unused bits at start or end of a frame */ +#define NFCT_TXD_FRAMECONFIG_DISCARDMODE_Pos (1UL) /*!< Position of DISCARDMODE field. */ +#define NFCT_TXD_FRAMECONFIG_DISCARDMODE_Msk (0x1UL << NFCT_TXD_FRAMECONFIG_DISCARDMODE_Pos) /*!< Bit mask of DISCARDMODE field. */ +#define NFCT_TXD_FRAMECONFIG_DISCARDMODE_DiscardEnd (0UL) /*!< Unused bits are discarded at end of frame (EoF) */ +#define NFCT_TXD_FRAMECONFIG_DISCARDMODE_DiscardStart (1UL) /*!< Unused bits are discarded at start of frame (SoF) */ + +/* Bit 0 : Indicates if parity is added to the frame */ +#define NFCT_TXD_FRAMECONFIG_PARITY_Pos (0UL) /*!< Position of PARITY field. */ +#define NFCT_TXD_FRAMECONFIG_PARITY_Msk (0x1UL << NFCT_TXD_FRAMECONFIG_PARITY_Pos) /*!< Bit mask of PARITY field. */ +#define NFCT_TXD_FRAMECONFIG_PARITY_NoParity (0UL) /*!< Parity is not added to TX frames */ +#define NFCT_TXD_FRAMECONFIG_PARITY_Parity (1UL) /*!< Parity is added to TX frames */ + +/* Register: NFCT_TXD_AMOUNT */ +/* Description: Size of outgoing frame */ + +/* Bits 11..3 : Number of complete bytes that shall be included in the frame, excluding CRC, parity and framing */ +#define NFCT_TXD_AMOUNT_TXDATABYTES_Pos (3UL) /*!< Position of TXDATABYTES field. */ +#define NFCT_TXD_AMOUNT_TXDATABYTES_Msk (0x1FFUL << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) /*!< Bit mask of TXDATABYTES field. */ + +/* Bits 2..0 : Number of bits in the last or first byte read from RAM that shall be included in the frame (excluding parity bit). */ +#define NFCT_TXD_AMOUNT_TXDATABITS_Pos (0UL) /*!< Position of TXDATABITS field. */ +#define NFCT_TXD_AMOUNT_TXDATABITS_Msk (0x7UL << NFCT_TXD_AMOUNT_TXDATABITS_Pos) /*!< Bit mask of TXDATABITS field. */ + +/* Register: NFCT_RXD_FRAMECONFIG */ +/* Description: Configuration of incoming frames */ + +/* Bit 4 : CRC mode for incoming frames */ +#define NFCT_RXD_FRAMECONFIG_CRCMODERX_Pos (4UL) /*!< Position of CRCMODERX field. */ +#define NFCT_RXD_FRAMECONFIG_CRCMODERX_Msk (0x1UL << NFCT_RXD_FRAMECONFIG_CRCMODERX_Pos) /*!< Bit mask of CRCMODERX field. */ +#define NFCT_RXD_FRAMECONFIG_CRCMODERX_NoCRCRX (0UL) /*!< CRC is not expected in RX frames */ +#define NFCT_RXD_FRAMECONFIG_CRCMODERX_CRC16RX (1UL) /*!< Last 16 bits in RX frame is CRC, CRC is checked and CRCSTATUS updated */ + +/* Bit 2 : SoF expected or not in RX frames */ +#define NFCT_RXD_FRAMECONFIG_SOF_Pos (2UL) /*!< Position of SOF field. */ +#define NFCT_RXD_FRAMECONFIG_SOF_Msk (0x1UL << NFCT_RXD_FRAMECONFIG_SOF_Pos) /*!< Bit mask of SOF field. */ +#define NFCT_RXD_FRAMECONFIG_SOF_NoSoF (0UL) /*!< SoF symbol is not expected in RX frames */ +#define NFCT_RXD_FRAMECONFIG_SOF_SoF (1UL) /*!< SoF symbol is expected in RX frames */ + +/* Bit 0 : Indicates if parity expected in RX frame */ +#define NFCT_RXD_FRAMECONFIG_PARITY_Pos (0UL) /*!< Position of PARITY field. */ +#define NFCT_RXD_FRAMECONFIG_PARITY_Msk (0x1UL << NFCT_RXD_FRAMECONFIG_PARITY_Pos) /*!< Bit mask of PARITY field. */ +#define NFCT_RXD_FRAMECONFIG_PARITY_NoParity (0UL) /*!< Parity is not expected in RX frames */ +#define NFCT_RXD_FRAMECONFIG_PARITY_Parity (1UL) /*!< Parity is expected in RX frames */ + +/* Register: NFCT_RXD_AMOUNT */ +/* Description: Size of last incoming frame */ + +/* Bits 11..3 : Number of complete bytes received in the frame (including CRC, but excluding parity and SoF/EoF framing) */ +#define NFCT_RXD_AMOUNT_RXDATABYTES_Pos (3UL) /*!< Position of RXDATABYTES field. */ +#define NFCT_RXD_AMOUNT_RXDATABYTES_Msk (0x1FFUL << NFCT_RXD_AMOUNT_RXDATABYTES_Pos) /*!< Bit mask of RXDATABYTES field. */ + +/* Bits 2..0 : Number of bits in the last byte in the frame, if less than 8 (including CRC, but excluding parity and SoF/EoF framing). */ +#define NFCT_RXD_AMOUNT_RXDATABITS_Pos (0UL) /*!< Position of RXDATABITS field. */ +#define NFCT_RXD_AMOUNT_RXDATABITS_Msk (0x7UL << NFCT_RXD_AMOUNT_RXDATABITS_Pos) /*!< Bit mask of RXDATABITS field. */ + +/* Register: NFCT_NFCID1_LAST */ +/* Description: Last NFCID1 part (4, 7 or 10 bytes ID) */ + +/* Bits 31..24 : NFCID1 byte W */ +#define NFCT_NFCID1_LAST_NFCID1_W_Pos (24UL) /*!< Position of NFCID1_W field. */ +#define NFCT_NFCID1_LAST_NFCID1_W_Msk (0xFFUL << NFCT_NFCID1_LAST_NFCID1_W_Pos) /*!< Bit mask of NFCID1_W field. */ + +/* Bits 23..16 : NFCID1 byte X */ +#define NFCT_NFCID1_LAST_NFCID1_X_Pos (16UL) /*!< Position of NFCID1_X field. */ +#define NFCT_NFCID1_LAST_NFCID1_X_Msk (0xFFUL << NFCT_NFCID1_LAST_NFCID1_X_Pos) /*!< Bit mask of NFCID1_X field. */ + +/* Bits 15..8 : NFCID1 byte Y */ +#define NFCT_NFCID1_LAST_NFCID1_Y_Pos (8UL) /*!< Position of NFCID1_Y field. */ +#define NFCT_NFCID1_LAST_NFCID1_Y_Msk (0xFFUL << NFCT_NFCID1_LAST_NFCID1_Y_Pos) /*!< Bit mask of NFCID1_Y field. */ + +/* Bits 7..0 : NFCID1 byte Z (very last byte sent) */ +#define NFCT_NFCID1_LAST_NFCID1_Z_Pos (0UL) /*!< Position of NFCID1_Z field. */ +#define NFCT_NFCID1_LAST_NFCID1_Z_Msk (0xFFUL << NFCT_NFCID1_LAST_NFCID1_Z_Pos) /*!< Bit mask of NFCID1_Z field. */ + +/* Register: NFCT_NFCID1_2ND_LAST */ +/* Description: Second last NFCID1 part (7 or 10 bytes ID) */ + +/* Bits 23..16 : NFCID1 byte T */ +#define NFCT_NFCID1_2ND_LAST_NFCID1_T_Pos (16UL) /*!< Position of NFCID1_T field. */ +#define NFCT_NFCID1_2ND_LAST_NFCID1_T_Msk (0xFFUL << NFCT_NFCID1_2ND_LAST_NFCID1_T_Pos) /*!< Bit mask of NFCID1_T field. */ + +/* Bits 15..8 : NFCID1 byte U */ +#define NFCT_NFCID1_2ND_LAST_NFCID1_U_Pos (8UL) /*!< Position of NFCID1_U field. */ +#define NFCT_NFCID1_2ND_LAST_NFCID1_U_Msk (0xFFUL << NFCT_NFCID1_2ND_LAST_NFCID1_U_Pos) /*!< Bit mask of NFCID1_U field. */ + +/* Bits 7..0 : NFCID1 byte V */ +#define NFCT_NFCID1_2ND_LAST_NFCID1_V_Pos (0UL) /*!< Position of NFCID1_V field. */ +#define NFCT_NFCID1_2ND_LAST_NFCID1_V_Msk (0xFFUL << NFCT_NFCID1_2ND_LAST_NFCID1_V_Pos) /*!< Bit mask of NFCID1_V field. */ + +/* Register: NFCT_NFCID1_3RD_LAST */ +/* Description: Third last NFCID1 part (10 bytes ID) */ + +/* Bits 23..16 : NFCID1 byte Q */ +#define NFCT_NFCID1_3RD_LAST_NFCID1_Q_Pos (16UL) /*!< Position of NFCID1_Q field. */ +#define NFCT_NFCID1_3RD_LAST_NFCID1_Q_Msk (0xFFUL << NFCT_NFCID1_3RD_LAST_NFCID1_Q_Pos) /*!< Bit mask of NFCID1_Q field. */ + +/* Bits 15..8 : NFCID1 byte R */ +#define NFCT_NFCID1_3RD_LAST_NFCID1_R_Pos (8UL) /*!< Position of NFCID1_R field. */ +#define NFCT_NFCID1_3RD_LAST_NFCID1_R_Msk (0xFFUL << NFCT_NFCID1_3RD_LAST_NFCID1_R_Pos) /*!< Bit mask of NFCID1_R field. */ + +/* Bits 7..0 : NFCID1 byte S */ +#define NFCT_NFCID1_3RD_LAST_NFCID1_S_Pos (0UL) /*!< Position of NFCID1_S field. */ +#define NFCT_NFCID1_3RD_LAST_NFCID1_S_Msk (0xFFUL << NFCT_NFCID1_3RD_LAST_NFCID1_S_Pos) /*!< Bit mask of NFCID1_S field. */ + +/* Register: NFCT_AUTOCOLRESCONFIG */ +/* Description: Controls the auto collision resolution function. This setting must be done before the NFCT peripheral is enabled. */ + +/* Bit 0 : Enables/disables auto collision resolution */ +#define NFCT_AUTOCOLRESCONFIG_MODE_Pos (0UL) /*!< Position of MODE field. */ +#define NFCT_AUTOCOLRESCONFIG_MODE_Msk (0x1UL << NFCT_AUTOCOLRESCONFIG_MODE_Pos) /*!< Bit mask of MODE field. */ +#define NFCT_AUTOCOLRESCONFIG_MODE_Enabled (0UL) /*!< Auto collision resolution enabled */ +#define NFCT_AUTOCOLRESCONFIG_MODE_Disabled (1UL) /*!< Auto collision resolution disabled */ + +/* Register: NFCT_SENSRES */ +/* Description: NFC-A SENS_RES auto-response settings */ + +/* Bits 15..12 : Reserved for future use. Shall be 0. */ +#define NFCT_SENSRES_RFU74_Pos (12UL) /*!< Position of RFU74 field. */ +#define NFCT_SENSRES_RFU74_Msk (0xFUL << NFCT_SENSRES_RFU74_Pos) /*!< Bit mask of RFU74 field. */ + +/* Bits 11..8 : Tag platform configuration as defined by the b4:b1 of byte 2 in SENS_RES response in the NFC Forum, NFC Digital Protocol Technical Specification */ +#define NFCT_SENSRES_PLATFCONFIG_Pos (8UL) /*!< Position of PLATFCONFIG field. */ +#define NFCT_SENSRES_PLATFCONFIG_Msk (0xFUL << NFCT_SENSRES_PLATFCONFIG_Pos) /*!< Bit mask of PLATFCONFIG field. */ + +/* Bits 7..6 : NFCID1 size. This value is used by the auto collision resolution engine. */ +#define NFCT_SENSRES_NFCIDSIZE_Pos (6UL) /*!< Position of NFCIDSIZE field. */ +#define NFCT_SENSRES_NFCIDSIZE_Msk (0x3UL << NFCT_SENSRES_NFCIDSIZE_Pos) /*!< Bit mask of NFCIDSIZE field. */ +#define NFCT_SENSRES_NFCIDSIZE_NFCID1Single (0UL) /*!< NFCID1 size: single (4 bytes) */ +#define NFCT_SENSRES_NFCIDSIZE_NFCID1Double (1UL) /*!< NFCID1 size: double (7 bytes) */ +#define NFCT_SENSRES_NFCIDSIZE_NFCID1Triple (2UL) /*!< NFCID1 size: triple (10 bytes) */ + +/* Bit 5 : Reserved for future use. Shall be 0. */ +#define NFCT_SENSRES_RFU5_Pos (5UL) /*!< Position of RFU5 field. */ +#define NFCT_SENSRES_RFU5_Msk (0x1UL << NFCT_SENSRES_RFU5_Pos) /*!< Bit mask of RFU5 field. */ + +/* Bits 4..0 : Bit frame SDD as defined by the b5:b1 of byte 1 in SENS_RES response in the NFC Forum, NFC Digital Protocol Technical Specification */ +#define NFCT_SENSRES_BITFRAMESDD_Pos (0UL) /*!< Position of BITFRAMESDD field. */ +#define NFCT_SENSRES_BITFRAMESDD_Msk (0x1FUL << NFCT_SENSRES_BITFRAMESDD_Pos) /*!< Bit mask of BITFRAMESDD field. */ +#define NFCT_SENSRES_BITFRAMESDD_SDD00000 (0UL) /*!< SDD pattern 00000 */ +#define NFCT_SENSRES_BITFRAMESDD_SDD00001 (1UL) /*!< SDD pattern 00001 */ +#define NFCT_SENSRES_BITFRAMESDD_SDD00010 (2UL) /*!< SDD pattern 00010 */ +#define NFCT_SENSRES_BITFRAMESDD_SDD00100 (4UL) /*!< SDD pattern 00100 */ +#define NFCT_SENSRES_BITFRAMESDD_SDD01000 (8UL) /*!< SDD pattern 01000 */ +#define NFCT_SENSRES_BITFRAMESDD_SDD10000 (16UL) /*!< SDD pattern 10000 */ + +/* Register: NFCT_SELRES */ +/* Description: NFC-A SEL_RES auto-response settings */ + +/* Bit 7 : Reserved for future use. Shall be 0. */ +#define NFCT_SELRES_RFU7_Pos (7UL) /*!< Position of RFU7 field. */ +#define NFCT_SELRES_RFU7_Msk (0x1UL << NFCT_SELRES_RFU7_Pos) /*!< Bit mask of RFU7 field. */ + +/* Bits 6..5 : Protocol as defined by the b7:b6 of SEL_RES response in the NFC Forum, NFC Digital Protocol Technical Specification */ +#define NFCT_SELRES_PROTOCOL_Pos (5UL) /*!< Position of PROTOCOL field. */ +#define NFCT_SELRES_PROTOCOL_Msk (0x3UL << NFCT_SELRES_PROTOCOL_Pos) /*!< Bit mask of PROTOCOL field. */ + +/* Bits 4..3 : Reserved for future use. Shall be 0. */ +#define NFCT_SELRES_RFU43_Pos (3UL) /*!< Position of RFU43 field. */ +#define NFCT_SELRES_RFU43_Msk (0x3UL << NFCT_SELRES_RFU43_Pos) /*!< Bit mask of RFU43 field. */ + +/* Bit 2 : Cascade as defined by the b3 of SEL_RES response in the NFC Forum, NFC Digital Protocol Technical Specification (controlled by hardware, shall be 0) */ +#define NFCT_SELRES_CASCADE_Pos (2UL) /*!< Position of CASCADE field. */ +#define NFCT_SELRES_CASCADE_Msk (0x1UL << NFCT_SELRES_CASCADE_Pos) /*!< Bit mask of CASCADE field. */ + +/* Bits 1..0 : Reserved for future use. Shall be 0. */ +#define NFCT_SELRES_RFU10_Pos (0UL) /*!< Position of RFU10 field. */ +#define NFCT_SELRES_RFU10_Msk (0x3UL << NFCT_SELRES_RFU10_Pos) /*!< Bit mask of RFU10 field. */ + + +/* Peripheral: NVMC */ +/* Description: Non Volatile Memory Controller */ + +/* Register: NVMC_READY */ +/* Description: Ready flag */ + +/* Bit 0 : NVMC is ready or busy */ +#define NVMC_READY_READY_Pos (0UL) /*!< Position of READY field. */ +#define NVMC_READY_READY_Msk (0x1UL << NVMC_READY_READY_Pos) /*!< Bit mask of READY field. */ +#define NVMC_READY_READY_Busy (0UL) /*!< NVMC is busy (on-going write or erase operation) */ +#define NVMC_READY_READY_Ready (1UL) /*!< NVMC is ready */ + +/* Register: NVMC_CONFIG */ +/* Description: Configuration register */ + +/* Bits 1..0 : Program memory access mode. It is strongly recommended to only activate erase and write modes when they are actively used. Enabling write or erase will invalidate the cache and keep it invalidated. */ +#define NVMC_CONFIG_WEN_Pos (0UL) /*!< Position of WEN field. */ +#define NVMC_CONFIG_WEN_Msk (0x3UL << NVMC_CONFIG_WEN_Pos) /*!< Bit mask of WEN field. */ +#define NVMC_CONFIG_WEN_Ren (0UL) /*!< Read only access */ +#define NVMC_CONFIG_WEN_Wen (1UL) /*!< Write enabled */ +#define NVMC_CONFIG_WEN_Een (2UL) /*!< Erase enabled */ + +/* Register: NVMC_ERASEPAGE */ +/* Description: Register for erasing a page in code area */ + +/* Bits 31..0 : Register for starting erase of a page in code area */ +#define NVMC_ERASEPAGE_ERASEPAGE_Pos (0UL) /*!< Position of ERASEPAGE field. */ +#define NVMC_ERASEPAGE_ERASEPAGE_Msk (0xFFFFFFFFUL << NVMC_ERASEPAGE_ERASEPAGE_Pos) /*!< Bit mask of ERASEPAGE field. */ + +/* Register: NVMC_ERASEPCR1 */ +/* Description: Deprecated register - Register for erasing a page in code area. Equivalent to ERASEPAGE. */ + +/* Bits 31..0 : Register for erasing a page in code area. Equivalent to ERASEPAGE. */ +#define NVMC_ERASEPCR1_ERASEPCR1_Pos (0UL) /*!< Position of ERASEPCR1 field. */ +#define NVMC_ERASEPCR1_ERASEPCR1_Msk (0xFFFFFFFFUL << NVMC_ERASEPCR1_ERASEPCR1_Pos) /*!< Bit mask of ERASEPCR1 field. */ + +/* Register: NVMC_ERASEALL */ +/* Description: Register for erasing all non-volatile user memory */ + +/* Bit 0 : Erase all non-volatile memory including UICR registers. Note that the erase must be enabled using CONFIG.WEN before the non-volatile memory can be erased. */ +#define NVMC_ERASEALL_ERASEALL_Pos (0UL) /*!< Position of ERASEALL field. */ +#define NVMC_ERASEALL_ERASEALL_Msk (0x1UL << NVMC_ERASEALL_ERASEALL_Pos) /*!< Bit mask of ERASEALL field. */ +#define NVMC_ERASEALL_ERASEALL_NoOperation (0UL) /*!< No operation */ +#define NVMC_ERASEALL_ERASEALL_Erase (1UL) /*!< Start chip erase */ + +/* Register: NVMC_ERASEPCR0 */ +/* Description: Deprecated register - Register for erasing a page in code area. Equivalent to ERASEPAGE. */ + +/* Bits 31..0 : Register for starting erase of a page in code area. Equivalent to ERASEPAGE. */ +#define NVMC_ERASEPCR0_ERASEPCR0_Pos (0UL) /*!< Position of ERASEPCR0 field. */ +#define NVMC_ERASEPCR0_ERASEPCR0_Msk (0xFFFFFFFFUL << NVMC_ERASEPCR0_ERASEPCR0_Pos) /*!< Bit mask of ERASEPCR0 field. */ + +/* Register: NVMC_ERASEUICR */ +/* Description: Register for erasing user information configuration registers */ + +/* Bit 0 : Register starting erase of all user information configuration registers. Note that the erase must be enabled using CONFIG.WEN before the UICR can be erased. */ +#define NVMC_ERASEUICR_ERASEUICR_Pos (0UL) /*!< Position of ERASEUICR field. */ +#define NVMC_ERASEUICR_ERASEUICR_Msk (0x1UL << NVMC_ERASEUICR_ERASEUICR_Pos) /*!< Bit mask of ERASEUICR field. */ +#define NVMC_ERASEUICR_ERASEUICR_NoOperation (0UL) /*!< No operation */ +#define NVMC_ERASEUICR_ERASEUICR_Erase (1UL) /*!< Start erase of UICR */ + +/* Register: NVMC_ICACHECNF */ +/* Description: I-code cache configuration register. */ + +/* Bit 8 : Cache profiling enable */ +#define NVMC_ICACHECNF_CACHEPROFEN_Pos (8UL) /*!< Position of CACHEPROFEN field. */ +#define NVMC_ICACHECNF_CACHEPROFEN_Msk (0x1UL << NVMC_ICACHECNF_CACHEPROFEN_Pos) /*!< Bit mask of CACHEPROFEN field. */ +#define NVMC_ICACHECNF_CACHEPROFEN_Disabled (0UL) /*!< Disable cache profiling */ +#define NVMC_ICACHECNF_CACHEPROFEN_Enabled (1UL) /*!< Enable cache profiling */ + +/* Bit 0 : Cache enable */ +#define NVMC_ICACHECNF_CACHEEN_Pos (0UL) /*!< Position of CACHEEN field. */ +#define NVMC_ICACHECNF_CACHEEN_Msk (0x1UL << NVMC_ICACHECNF_CACHEEN_Pos) /*!< Bit mask of CACHEEN field. */ +#define NVMC_ICACHECNF_CACHEEN_Disabled (0UL) /*!< Disable cache. Invalidates all cache entries. */ +#define NVMC_ICACHECNF_CACHEEN_Enabled (1UL) /*!< Enable cache */ + +/* Register: NVMC_IHIT */ +/* Description: I-code cache hit counter. */ + +/* Bits 31..0 : Number of cache hits */ +#define NVMC_IHIT_HITS_Pos (0UL) /*!< Position of HITS field. */ +#define NVMC_IHIT_HITS_Msk (0xFFFFFFFFUL << NVMC_IHIT_HITS_Pos) /*!< Bit mask of HITS field. */ + +/* Register: NVMC_IMISS */ +/* Description: I-code cache miss counter. */ + +/* Bits 31..0 : Number of cache misses */ +#define NVMC_IMISS_MISSES_Pos (0UL) /*!< Position of MISSES field. */ +#define NVMC_IMISS_MISSES_Msk (0xFFFFFFFFUL << NVMC_IMISS_MISSES_Pos) /*!< Bit mask of MISSES field. */ + + +/* Peripheral: GPIO */ +/* Description: GPIO Port 1 */ + +/* Register: GPIO_OUT */ +/* Description: Write GPIO port */ + +/* Bit 31 : Pin 31 */ +#define GPIO_OUT_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_OUT_PIN31_Msk (0x1UL << GPIO_OUT_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_OUT_PIN31_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN31_High (1UL) /*!< Pin driver is high */ + +/* Bit 30 : Pin 30 */ +#define GPIO_OUT_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_OUT_PIN30_Msk (0x1UL << GPIO_OUT_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_OUT_PIN30_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN30_High (1UL) /*!< Pin driver is high */ + +/* Bit 29 : Pin 29 */ +#define GPIO_OUT_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_OUT_PIN29_Msk (0x1UL << GPIO_OUT_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_OUT_PIN29_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN29_High (1UL) /*!< Pin driver is high */ + +/* Bit 28 : Pin 28 */ +#define GPIO_OUT_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_OUT_PIN28_Msk (0x1UL << GPIO_OUT_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_OUT_PIN28_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN28_High (1UL) /*!< Pin driver is high */ + +/* Bit 27 : Pin 27 */ +#define GPIO_OUT_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_OUT_PIN27_Msk (0x1UL << GPIO_OUT_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_OUT_PIN27_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN27_High (1UL) /*!< Pin driver is high */ + +/* Bit 26 : Pin 26 */ +#define GPIO_OUT_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_OUT_PIN26_Msk (0x1UL << GPIO_OUT_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_OUT_PIN26_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN26_High (1UL) /*!< Pin driver is high */ + +/* Bit 25 : Pin 25 */ +#define GPIO_OUT_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_OUT_PIN25_Msk (0x1UL << GPIO_OUT_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_OUT_PIN25_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN25_High (1UL) /*!< Pin driver is high */ + +/* Bit 24 : Pin 24 */ +#define GPIO_OUT_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_OUT_PIN24_Msk (0x1UL << GPIO_OUT_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_OUT_PIN24_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN24_High (1UL) /*!< Pin driver is high */ + +/* Bit 23 : Pin 23 */ +#define GPIO_OUT_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_OUT_PIN23_Msk (0x1UL << GPIO_OUT_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_OUT_PIN23_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN23_High (1UL) /*!< Pin driver is high */ + +/* Bit 22 : Pin 22 */ +#define GPIO_OUT_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_OUT_PIN22_Msk (0x1UL << GPIO_OUT_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_OUT_PIN22_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN22_High (1UL) /*!< Pin driver is high */ + +/* Bit 21 : Pin 21 */ +#define GPIO_OUT_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_OUT_PIN21_Msk (0x1UL << GPIO_OUT_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_OUT_PIN21_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN21_High (1UL) /*!< Pin driver is high */ + +/* Bit 20 : Pin 20 */ +#define GPIO_OUT_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_OUT_PIN20_Msk (0x1UL << GPIO_OUT_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_OUT_PIN20_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN20_High (1UL) /*!< Pin driver is high */ + +/* Bit 19 : Pin 19 */ +#define GPIO_OUT_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_OUT_PIN19_Msk (0x1UL << GPIO_OUT_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_OUT_PIN19_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN19_High (1UL) /*!< Pin driver is high */ + +/* Bit 18 : Pin 18 */ +#define GPIO_OUT_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_OUT_PIN18_Msk (0x1UL << GPIO_OUT_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_OUT_PIN18_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN18_High (1UL) /*!< Pin driver is high */ + +/* Bit 17 : Pin 17 */ +#define GPIO_OUT_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_OUT_PIN17_Msk (0x1UL << GPIO_OUT_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_OUT_PIN17_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN17_High (1UL) /*!< Pin driver is high */ + +/* Bit 16 : Pin 16 */ +#define GPIO_OUT_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_OUT_PIN16_Msk (0x1UL << GPIO_OUT_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_OUT_PIN16_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN16_High (1UL) /*!< Pin driver is high */ + +/* Bit 15 : Pin 15 */ +#define GPIO_OUT_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_OUT_PIN15_Msk (0x1UL << GPIO_OUT_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_OUT_PIN15_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN15_High (1UL) /*!< Pin driver is high */ + +/* Bit 14 : Pin 14 */ +#define GPIO_OUT_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_OUT_PIN14_Msk (0x1UL << GPIO_OUT_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_OUT_PIN14_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN14_High (1UL) /*!< Pin driver is high */ + +/* Bit 13 : Pin 13 */ +#define GPIO_OUT_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_OUT_PIN13_Msk (0x1UL << GPIO_OUT_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_OUT_PIN13_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN13_High (1UL) /*!< Pin driver is high */ + +/* Bit 12 : Pin 12 */ +#define GPIO_OUT_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_OUT_PIN12_Msk (0x1UL << GPIO_OUT_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_OUT_PIN12_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN12_High (1UL) /*!< Pin driver is high */ + +/* Bit 11 : Pin 11 */ +#define GPIO_OUT_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_OUT_PIN11_Msk (0x1UL << GPIO_OUT_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_OUT_PIN11_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN11_High (1UL) /*!< Pin driver is high */ + +/* Bit 10 : Pin 10 */ +#define GPIO_OUT_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_OUT_PIN10_Msk (0x1UL << GPIO_OUT_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_OUT_PIN10_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN10_High (1UL) /*!< Pin driver is high */ + +/* Bit 9 : Pin 9 */ +#define GPIO_OUT_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_OUT_PIN9_Msk (0x1UL << GPIO_OUT_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_OUT_PIN9_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN9_High (1UL) /*!< Pin driver is high */ + +/* Bit 8 : Pin 8 */ +#define GPIO_OUT_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_OUT_PIN8_Msk (0x1UL << GPIO_OUT_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_OUT_PIN8_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN8_High (1UL) /*!< Pin driver is high */ + +/* Bit 7 : Pin 7 */ +#define GPIO_OUT_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_OUT_PIN7_Msk (0x1UL << GPIO_OUT_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_OUT_PIN7_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN7_High (1UL) /*!< Pin driver is high */ + +/* Bit 6 : Pin 6 */ +#define GPIO_OUT_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_OUT_PIN6_Msk (0x1UL << GPIO_OUT_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_OUT_PIN6_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN6_High (1UL) /*!< Pin driver is high */ + +/* Bit 5 : Pin 5 */ +#define GPIO_OUT_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_OUT_PIN5_Msk (0x1UL << GPIO_OUT_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_OUT_PIN5_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN5_High (1UL) /*!< Pin driver is high */ + +/* Bit 4 : Pin 4 */ +#define GPIO_OUT_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_OUT_PIN4_Msk (0x1UL << GPIO_OUT_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_OUT_PIN4_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN4_High (1UL) /*!< Pin driver is high */ + +/* Bit 3 : Pin 3 */ +#define GPIO_OUT_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_OUT_PIN3_Msk (0x1UL << GPIO_OUT_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_OUT_PIN3_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN3_High (1UL) /*!< Pin driver is high */ + +/* Bit 2 : Pin 2 */ +#define GPIO_OUT_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_OUT_PIN2_Msk (0x1UL << GPIO_OUT_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_OUT_PIN2_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN2_High (1UL) /*!< Pin driver is high */ + +/* Bit 1 : Pin 1 */ +#define GPIO_OUT_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_OUT_PIN1_Msk (0x1UL << GPIO_OUT_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_OUT_PIN1_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN1_High (1UL) /*!< Pin driver is high */ + +/* Bit 0 : Pin 0 */ +#define GPIO_OUT_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_OUT_PIN0_Msk (0x1UL << GPIO_OUT_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_OUT_PIN0_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN0_High (1UL) /*!< Pin driver is high */ + +/* Register: GPIO_OUTSET */ +/* Description: Set individual bits in GPIO port */ + +/* Bit 31 : Pin 31 */ +#define GPIO_OUTSET_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_OUTSET_PIN31_Msk (0x1UL << GPIO_OUTSET_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_OUTSET_PIN31_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN31_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN31_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 30 : Pin 30 */ +#define GPIO_OUTSET_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_OUTSET_PIN30_Msk (0x1UL << GPIO_OUTSET_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_OUTSET_PIN30_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN30_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN30_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 29 : Pin 29 */ +#define GPIO_OUTSET_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_OUTSET_PIN29_Msk (0x1UL << GPIO_OUTSET_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_OUTSET_PIN29_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN29_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN29_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 28 : Pin 28 */ +#define GPIO_OUTSET_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_OUTSET_PIN28_Msk (0x1UL << GPIO_OUTSET_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_OUTSET_PIN28_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN28_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN28_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 27 : Pin 27 */ +#define GPIO_OUTSET_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_OUTSET_PIN27_Msk (0x1UL << GPIO_OUTSET_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_OUTSET_PIN27_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN27_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN27_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 26 : Pin 26 */ +#define GPIO_OUTSET_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_OUTSET_PIN26_Msk (0x1UL << GPIO_OUTSET_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_OUTSET_PIN26_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN26_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN26_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 25 : Pin 25 */ +#define GPIO_OUTSET_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_OUTSET_PIN25_Msk (0x1UL << GPIO_OUTSET_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_OUTSET_PIN25_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN25_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN25_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 24 : Pin 24 */ +#define GPIO_OUTSET_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_OUTSET_PIN24_Msk (0x1UL << GPIO_OUTSET_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_OUTSET_PIN24_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN24_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN24_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 23 : Pin 23 */ +#define GPIO_OUTSET_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_OUTSET_PIN23_Msk (0x1UL << GPIO_OUTSET_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_OUTSET_PIN23_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN23_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN23_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 22 : Pin 22 */ +#define GPIO_OUTSET_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_OUTSET_PIN22_Msk (0x1UL << GPIO_OUTSET_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_OUTSET_PIN22_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN22_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN22_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 21 : Pin 21 */ +#define GPIO_OUTSET_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_OUTSET_PIN21_Msk (0x1UL << GPIO_OUTSET_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_OUTSET_PIN21_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN21_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN21_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 20 : Pin 20 */ +#define GPIO_OUTSET_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_OUTSET_PIN20_Msk (0x1UL << GPIO_OUTSET_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_OUTSET_PIN20_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN20_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN20_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 19 : Pin 19 */ +#define GPIO_OUTSET_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_OUTSET_PIN19_Msk (0x1UL << GPIO_OUTSET_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_OUTSET_PIN19_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN19_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN19_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 18 : Pin 18 */ +#define GPIO_OUTSET_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_OUTSET_PIN18_Msk (0x1UL << GPIO_OUTSET_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_OUTSET_PIN18_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN18_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN18_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 17 : Pin 17 */ +#define GPIO_OUTSET_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_OUTSET_PIN17_Msk (0x1UL << GPIO_OUTSET_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_OUTSET_PIN17_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN17_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN17_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 16 : Pin 16 */ +#define GPIO_OUTSET_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_OUTSET_PIN16_Msk (0x1UL << GPIO_OUTSET_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_OUTSET_PIN16_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN16_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN16_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 15 : Pin 15 */ +#define GPIO_OUTSET_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_OUTSET_PIN15_Msk (0x1UL << GPIO_OUTSET_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_OUTSET_PIN15_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN15_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN15_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 14 : Pin 14 */ +#define GPIO_OUTSET_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_OUTSET_PIN14_Msk (0x1UL << GPIO_OUTSET_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_OUTSET_PIN14_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN14_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN14_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 13 : Pin 13 */ +#define GPIO_OUTSET_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_OUTSET_PIN13_Msk (0x1UL << GPIO_OUTSET_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_OUTSET_PIN13_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN13_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN13_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 12 : Pin 12 */ +#define GPIO_OUTSET_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_OUTSET_PIN12_Msk (0x1UL << GPIO_OUTSET_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_OUTSET_PIN12_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN12_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN12_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 11 : Pin 11 */ +#define GPIO_OUTSET_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_OUTSET_PIN11_Msk (0x1UL << GPIO_OUTSET_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_OUTSET_PIN11_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN11_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN11_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 10 : Pin 10 */ +#define GPIO_OUTSET_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_OUTSET_PIN10_Msk (0x1UL << GPIO_OUTSET_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_OUTSET_PIN10_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN10_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN10_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 9 : Pin 9 */ +#define GPIO_OUTSET_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_OUTSET_PIN9_Msk (0x1UL << GPIO_OUTSET_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_OUTSET_PIN9_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN9_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN9_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 8 : Pin 8 */ +#define GPIO_OUTSET_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_OUTSET_PIN8_Msk (0x1UL << GPIO_OUTSET_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_OUTSET_PIN8_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN8_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN8_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 7 : Pin 7 */ +#define GPIO_OUTSET_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_OUTSET_PIN7_Msk (0x1UL << GPIO_OUTSET_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_OUTSET_PIN7_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN7_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN7_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 6 : Pin 6 */ +#define GPIO_OUTSET_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_OUTSET_PIN6_Msk (0x1UL << GPIO_OUTSET_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_OUTSET_PIN6_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN6_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN6_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 5 : Pin 5 */ +#define GPIO_OUTSET_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_OUTSET_PIN5_Msk (0x1UL << GPIO_OUTSET_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_OUTSET_PIN5_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN5_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN5_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 4 : Pin 4 */ +#define GPIO_OUTSET_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_OUTSET_PIN4_Msk (0x1UL << GPIO_OUTSET_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_OUTSET_PIN4_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN4_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN4_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 3 : Pin 3 */ +#define GPIO_OUTSET_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_OUTSET_PIN3_Msk (0x1UL << GPIO_OUTSET_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_OUTSET_PIN3_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN3_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN3_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 2 : Pin 2 */ +#define GPIO_OUTSET_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_OUTSET_PIN2_Msk (0x1UL << GPIO_OUTSET_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_OUTSET_PIN2_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN2_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN2_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 1 : Pin 1 */ +#define GPIO_OUTSET_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_OUTSET_PIN1_Msk (0x1UL << GPIO_OUTSET_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_OUTSET_PIN1_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN1_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN1_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 0 : Pin 0 */ +#define GPIO_OUTSET_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_OUTSET_PIN0_Msk (0x1UL << GPIO_OUTSET_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_OUTSET_PIN0_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN0_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN0_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Register: GPIO_OUTCLR */ +/* Description: Clear individual bits in GPIO port */ + +/* Bit 31 : Pin 31 */ +#define GPIO_OUTCLR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_OUTCLR_PIN31_Msk (0x1UL << GPIO_OUTCLR_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_OUTCLR_PIN31_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN31_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN31_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 30 : Pin 30 */ +#define GPIO_OUTCLR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_OUTCLR_PIN30_Msk (0x1UL << GPIO_OUTCLR_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_OUTCLR_PIN30_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN30_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN30_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 29 : Pin 29 */ +#define GPIO_OUTCLR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_OUTCLR_PIN29_Msk (0x1UL << GPIO_OUTCLR_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_OUTCLR_PIN29_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN29_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN29_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 28 : Pin 28 */ +#define GPIO_OUTCLR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_OUTCLR_PIN28_Msk (0x1UL << GPIO_OUTCLR_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_OUTCLR_PIN28_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN28_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN28_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 27 : Pin 27 */ +#define GPIO_OUTCLR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_OUTCLR_PIN27_Msk (0x1UL << GPIO_OUTCLR_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_OUTCLR_PIN27_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN27_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN27_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 26 : Pin 26 */ +#define GPIO_OUTCLR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_OUTCLR_PIN26_Msk (0x1UL << GPIO_OUTCLR_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_OUTCLR_PIN26_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN26_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN26_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 25 : Pin 25 */ +#define GPIO_OUTCLR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_OUTCLR_PIN25_Msk (0x1UL << GPIO_OUTCLR_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_OUTCLR_PIN25_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN25_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN25_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 24 : Pin 24 */ +#define GPIO_OUTCLR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_OUTCLR_PIN24_Msk (0x1UL << GPIO_OUTCLR_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_OUTCLR_PIN24_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN24_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN24_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 23 : Pin 23 */ +#define GPIO_OUTCLR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_OUTCLR_PIN23_Msk (0x1UL << GPIO_OUTCLR_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_OUTCLR_PIN23_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN23_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN23_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 22 : Pin 22 */ +#define GPIO_OUTCLR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_OUTCLR_PIN22_Msk (0x1UL << GPIO_OUTCLR_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_OUTCLR_PIN22_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN22_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN22_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 21 : Pin 21 */ +#define GPIO_OUTCLR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_OUTCLR_PIN21_Msk (0x1UL << GPIO_OUTCLR_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_OUTCLR_PIN21_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN21_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN21_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 20 : Pin 20 */ +#define GPIO_OUTCLR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_OUTCLR_PIN20_Msk (0x1UL << GPIO_OUTCLR_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_OUTCLR_PIN20_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN20_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN20_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 19 : Pin 19 */ +#define GPIO_OUTCLR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_OUTCLR_PIN19_Msk (0x1UL << GPIO_OUTCLR_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_OUTCLR_PIN19_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN19_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN19_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 18 : Pin 18 */ +#define GPIO_OUTCLR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_OUTCLR_PIN18_Msk (0x1UL << GPIO_OUTCLR_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_OUTCLR_PIN18_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN18_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN18_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 17 : Pin 17 */ +#define GPIO_OUTCLR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_OUTCLR_PIN17_Msk (0x1UL << GPIO_OUTCLR_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_OUTCLR_PIN17_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN17_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN17_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 16 : Pin 16 */ +#define GPIO_OUTCLR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_OUTCLR_PIN16_Msk (0x1UL << GPIO_OUTCLR_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_OUTCLR_PIN16_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN16_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN16_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 15 : Pin 15 */ +#define GPIO_OUTCLR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_OUTCLR_PIN15_Msk (0x1UL << GPIO_OUTCLR_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_OUTCLR_PIN15_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN15_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN15_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 14 : Pin 14 */ +#define GPIO_OUTCLR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_OUTCLR_PIN14_Msk (0x1UL << GPIO_OUTCLR_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_OUTCLR_PIN14_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN14_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN14_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 13 : Pin 13 */ +#define GPIO_OUTCLR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_OUTCLR_PIN13_Msk (0x1UL << GPIO_OUTCLR_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_OUTCLR_PIN13_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN13_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN13_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 12 : Pin 12 */ +#define GPIO_OUTCLR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_OUTCLR_PIN12_Msk (0x1UL << GPIO_OUTCLR_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_OUTCLR_PIN12_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN12_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN12_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 11 : Pin 11 */ +#define GPIO_OUTCLR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_OUTCLR_PIN11_Msk (0x1UL << GPIO_OUTCLR_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_OUTCLR_PIN11_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN11_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN11_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 10 : Pin 10 */ +#define GPIO_OUTCLR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_OUTCLR_PIN10_Msk (0x1UL << GPIO_OUTCLR_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_OUTCLR_PIN10_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN10_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN10_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 9 : Pin 9 */ +#define GPIO_OUTCLR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_OUTCLR_PIN9_Msk (0x1UL << GPIO_OUTCLR_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_OUTCLR_PIN9_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN9_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN9_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 8 : Pin 8 */ +#define GPIO_OUTCLR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_OUTCLR_PIN8_Msk (0x1UL << GPIO_OUTCLR_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_OUTCLR_PIN8_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN8_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN8_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 7 : Pin 7 */ +#define GPIO_OUTCLR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_OUTCLR_PIN7_Msk (0x1UL << GPIO_OUTCLR_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_OUTCLR_PIN7_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN7_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN7_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 6 : Pin 6 */ +#define GPIO_OUTCLR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_OUTCLR_PIN6_Msk (0x1UL << GPIO_OUTCLR_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_OUTCLR_PIN6_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN6_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN6_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 5 : Pin 5 */ +#define GPIO_OUTCLR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_OUTCLR_PIN5_Msk (0x1UL << GPIO_OUTCLR_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_OUTCLR_PIN5_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN5_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN5_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 4 : Pin 4 */ +#define GPIO_OUTCLR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_OUTCLR_PIN4_Msk (0x1UL << GPIO_OUTCLR_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_OUTCLR_PIN4_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN4_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN4_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 3 : Pin 3 */ +#define GPIO_OUTCLR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_OUTCLR_PIN3_Msk (0x1UL << GPIO_OUTCLR_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_OUTCLR_PIN3_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN3_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN3_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 2 : Pin 2 */ +#define GPIO_OUTCLR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_OUTCLR_PIN2_Msk (0x1UL << GPIO_OUTCLR_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_OUTCLR_PIN2_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN2_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN2_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 1 : Pin 1 */ +#define GPIO_OUTCLR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_OUTCLR_PIN1_Msk (0x1UL << GPIO_OUTCLR_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_OUTCLR_PIN1_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN1_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN1_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 0 : Pin 0 */ +#define GPIO_OUTCLR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_OUTCLR_PIN0_Msk (0x1UL << GPIO_OUTCLR_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_OUTCLR_PIN0_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN0_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN0_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Register: GPIO_IN */ +/* Description: Read GPIO port */ + +/* Bit 31 : Pin 31 */ +#define GPIO_IN_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_IN_PIN31_Msk (0x1UL << GPIO_IN_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_IN_PIN31_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN31_High (1UL) /*!< Pin input is high */ + +/* Bit 30 : Pin 30 */ +#define GPIO_IN_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_IN_PIN30_Msk (0x1UL << GPIO_IN_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_IN_PIN30_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN30_High (1UL) /*!< Pin input is high */ + +/* Bit 29 : Pin 29 */ +#define GPIO_IN_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_IN_PIN29_Msk (0x1UL << GPIO_IN_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_IN_PIN29_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN29_High (1UL) /*!< Pin input is high */ + +/* Bit 28 : Pin 28 */ +#define GPIO_IN_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_IN_PIN28_Msk (0x1UL << GPIO_IN_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_IN_PIN28_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN28_High (1UL) /*!< Pin input is high */ + +/* Bit 27 : Pin 27 */ +#define GPIO_IN_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_IN_PIN27_Msk (0x1UL << GPIO_IN_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_IN_PIN27_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN27_High (1UL) /*!< Pin input is high */ + +/* Bit 26 : Pin 26 */ +#define GPIO_IN_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_IN_PIN26_Msk (0x1UL << GPIO_IN_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_IN_PIN26_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN26_High (1UL) /*!< Pin input is high */ + +/* Bit 25 : Pin 25 */ +#define GPIO_IN_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_IN_PIN25_Msk (0x1UL << GPIO_IN_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_IN_PIN25_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN25_High (1UL) /*!< Pin input is high */ + +/* Bit 24 : Pin 24 */ +#define GPIO_IN_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_IN_PIN24_Msk (0x1UL << GPIO_IN_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_IN_PIN24_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN24_High (1UL) /*!< Pin input is high */ + +/* Bit 23 : Pin 23 */ +#define GPIO_IN_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_IN_PIN23_Msk (0x1UL << GPIO_IN_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_IN_PIN23_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN23_High (1UL) /*!< Pin input is high */ + +/* Bit 22 : Pin 22 */ +#define GPIO_IN_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_IN_PIN22_Msk (0x1UL << GPIO_IN_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_IN_PIN22_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN22_High (1UL) /*!< Pin input is high */ + +/* Bit 21 : Pin 21 */ +#define GPIO_IN_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_IN_PIN21_Msk (0x1UL << GPIO_IN_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_IN_PIN21_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN21_High (1UL) /*!< Pin input is high */ + +/* Bit 20 : Pin 20 */ +#define GPIO_IN_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_IN_PIN20_Msk (0x1UL << GPIO_IN_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_IN_PIN20_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN20_High (1UL) /*!< Pin input is high */ + +/* Bit 19 : Pin 19 */ +#define GPIO_IN_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_IN_PIN19_Msk (0x1UL << GPIO_IN_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_IN_PIN19_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN19_High (1UL) /*!< Pin input is high */ + +/* Bit 18 : Pin 18 */ +#define GPIO_IN_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_IN_PIN18_Msk (0x1UL << GPIO_IN_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_IN_PIN18_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN18_High (1UL) /*!< Pin input is high */ + +/* Bit 17 : Pin 17 */ +#define GPIO_IN_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_IN_PIN17_Msk (0x1UL << GPIO_IN_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_IN_PIN17_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN17_High (1UL) /*!< Pin input is high */ + +/* Bit 16 : Pin 16 */ +#define GPIO_IN_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_IN_PIN16_Msk (0x1UL << GPIO_IN_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_IN_PIN16_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN16_High (1UL) /*!< Pin input is high */ + +/* Bit 15 : Pin 15 */ +#define GPIO_IN_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_IN_PIN15_Msk (0x1UL << GPIO_IN_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_IN_PIN15_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN15_High (1UL) /*!< Pin input is high */ + +/* Bit 14 : Pin 14 */ +#define GPIO_IN_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_IN_PIN14_Msk (0x1UL << GPIO_IN_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_IN_PIN14_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN14_High (1UL) /*!< Pin input is high */ + +/* Bit 13 : Pin 13 */ +#define GPIO_IN_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_IN_PIN13_Msk (0x1UL << GPIO_IN_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_IN_PIN13_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN13_High (1UL) /*!< Pin input is high */ + +/* Bit 12 : Pin 12 */ +#define GPIO_IN_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_IN_PIN12_Msk (0x1UL << GPIO_IN_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_IN_PIN12_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN12_High (1UL) /*!< Pin input is high */ + +/* Bit 11 : Pin 11 */ +#define GPIO_IN_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_IN_PIN11_Msk (0x1UL << GPIO_IN_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_IN_PIN11_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN11_High (1UL) /*!< Pin input is high */ + +/* Bit 10 : Pin 10 */ +#define GPIO_IN_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_IN_PIN10_Msk (0x1UL << GPIO_IN_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_IN_PIN10_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN10_High (1UL) /*!< Pin input is high */ + +/* Bit 9 : Pin 9 */ +#define GPIO_IN_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_IN_PIN9_Msk (0x1UL << GPIO_IN_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_IN_PIN9_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN9_High (1UL) /*!< Pin input is high */ + +/* Bit 8 : Pin 8 */ +#define GPIO_IN_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_IN_PIN8_Msk (0x1UL << GPIO_IN_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_IN_PIN8_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN8_High (1UL) /*!< Pin input is high */ + +/* Bit 7 : Pin 7 */ +#define GPIO_IN_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_IN_PIN7_Msk (0x1UL << GPIO_IN_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_IN_PIN7_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN7_High (1UL) /*!< Pin input is high */ + +/* Bit 6 : Pin 6 */ +#define GPIO_IN_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_IN_PIN6_Msk (0x1UL << GPIO_IN_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_IN_PIN6_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN6_High (1UL) /*!< Pin input is high */ + +/* Bit 5 : Pin 5 */ +#define GPIO_IN_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_IN_PIN5_Msk (0x1UL << GPIO_IN_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_IN_PIN5_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN5_High (1UL) /*!< Pin input is high */ + +/* Bit 4 : Pin 4 */ +#define GPIO_IN_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_IN_PIN4_Msk (0x1UL << GPIO_IN_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_IN_PIN4_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN4_High (1UL) /*!< Pin input is high */ + +/* Bit 3 : Pin 3 */ +#define GPIO_IN_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_IN_PIN3_Msk (0x1UL << GPIO_IN_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_IN_PIN3_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN3_High (1UL) /*!< Pin input is high */ + +/* Bit 2 : Pin 2 */ +#define GPIO_IN_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_IN_PIN2_Msk (0x1UL << GPIO_IN_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_IN_PIN2_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN2_High (1UL) /*!< Pin input is high */ + +/* Bit 1 : Pin 1 */ +#define GPIO_IN_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_IN_PIN1_Msk (0x1UL << GPIO_IN_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_IN_PIN1_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN1_High (1UL) /*!< Pin input is high */ + +/* Bit 0 : Pin 0 */ +#define GPIO_IN_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_IN_PIN0_Msk (0x1UL << GPIO_IN_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_IN_PIN0_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN0_High (1UL) /*!< Pin input is high */ + +/* Register: GPIO_DIR */ +/* Description: Direction of GPIO pins */ + +/* Bit 31 : Pin 31 */ +#define GPIO_DIR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_DIR_PIN31_Msk (0x1UL << GPIO_DIR_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_DIR_PIN31_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN31_Output (1UL) /*!< Pin set as output */ + +/* Bit 30 : Pin 30 */ +#define GPIO_DIR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_DIR_PIN30_Msk (0x1UL << GPIO_DIR_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_DIR_PIN30_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN30_Output (1UL) /*!< Pin set as output */ + +/* Bit 29 : Pin 29 */ +#define GPIO_DIR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_DIR_PIN29_Msk (0x1UL << GPIO_DIR_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_DIR_PIN29_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN29_Output (1UL) /*!< Pin set as output */ + +/* Bit 28 : Pin 28 */ +#define GPIO_DIR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_DIR_PIN28_Msk (0x1UL << GPIO_DIR_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_DIR_PIN28_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN28_Output (1UL) /*!< Pin set as output */ + +/* Bit 27 : Pin 27 */ +#define GPIO_DIR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_DIR_PIN27_Msk (0x1UL << GPIO_DIR_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_DIR_PIN27_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN27_Output (1UL) /*!< Pin set as output */ + +/* Bit 26 : Pin 26 */ +#define GPIO_DIR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_DIR_PIN26_Msk (0x1UL << GPIO_DIR_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_DIR_PIN26_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN26_Output (1UL) /*!< Pin set as output */ + +/* Bit 25 : Pin 25 */ +#define GPIO_DIR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_DIR_PIN25_Msk (0x1UL << GPIO_DIR_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_DIR_PIN25_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN25_Output (1UL) /*!< Pin set as output */ + +/* Bit 24 : Pin 24 */ +#define GPIO_DIR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_DIR_PIN24_Msk (0x1UL << GPIO_DIR_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_DIR_PIN24_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN24_Output (1UL) /*!< Pin set as output */ + +/* Bit 23 : Pin 23 */ +#define GPIO_DIR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_DIR_PIN23_Msk (0x1UL << GPIO_DIR_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_DIR_PIN23_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN23_Output (1UL) /*!< Pin set as output */ + +/* Bit 22 : Pin 22 */ +#define GPIO_DIR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_DIR_PIN22_Msk (0x1UL << GPIO_DIR_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_DIR_PIN22_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN22_Output (1UL) /*!< Pin set as output */ + +/* Bit 21 : Pin 21 */ +#define GPIO_DIR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_DIR_PIN21_Msk (0x1UL << GPIO_DIR_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_DIR_PIN21_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN21_Output (1UL) /*!< Pin set as output */ + +/* Bit 20 : Pin 20 */ +#define GPIO_DIR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_DIR_PIN20_Msk (0x1UL << GPIO_DIR_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_DIR_PIN20_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN20_Output (1UL) /*!< Pin set as output */ + +/* Bit 19 : Pin 19 */ +#define GPIO_DIR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_DIR_PIN19_Msk (0x1UL << GPIO_DIR_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_DIR_PIN19_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN19_Output (1UL) /*!< Pin set as output */ + +/* Bit 18 : Pin 18 */ +#define GPIO_DIR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_DIR_PIN18_Msk (0x1UL << GPIO_DIR_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_DIR_PIN18_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN18_Output (1UL) /*!< Pin set as output */ + +/* Bit 17 : Pin 17 */ +#define GPIO_DIR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_DIR_PIN17_Msk (0x1UL << GPIO_DIR_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_DIR_PIN17_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN17_Output (1UL) /*!< Pin set as output */ + +/* Bit 16 : Pin 16 */ +#define GPIO_DIR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_DIR_PIN16_Msk (0x1UL << GPIO_DIR_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_DIR_PIN16_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN16_Output (1UL) /*!< Pin set as output */ + +/* Bit 15 : Pin 15 */ +#define GPIO_DIR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_DIR_PIN15_Msk (0x1UL << GPIO_DIR_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_DIR_PIN15_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN15_Output (1UL) /*!< Pin set as output */ + +/* Bit 14 : Pin 14 */ +#define GPIO_DIR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_DIR_PIN14_Msk (0x1UL << GPIO_DIR_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_DIR_PIN14_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN14_Output (1UL) /*!< Pin set as output */ + +/* Bit 13 : Pin 13 */ +#define GPIO_DIR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_DIR_PIN13_Msk (0x1UL << GPIO_DIR_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_DIR_PIN13_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN13_Output (1UL) /*!< Pin set as output */ + +/* Bit 12 : Pin 12 */ +#define GPIO_DIR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_DIR_PIN12_Msk (0x1UL << GPIO_DIR_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_DIR_PIN12_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN12_Output (1UL) /*!< Pin set as output */ + +/* Bit 11 : Pin 11 */ +#define GPIO_DIR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_DIR_PIN11_Msk (0x1UL << GPIO_DIR_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_DIR_PIN11_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN11_Output (1UL) /*!< Pin set as output */ + +/* Bit 10 : Pin 10 */ +#define GPIO_DIR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_DIR_PIN10_Msk (0x1UL << GPIO_DIR_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_DIR_PIN10_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN10_Output (1UL) /*!< Pin set as output */ + +/* Bit 9 : Pin 9 */ +#define GPIO_DIR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_DIR_PIN9_Msk (0x1UL << GPIO_DIR_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_DIR_PIN9_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN9_Output (1UL) /*!< Pin set as output */ + +/* Bit 8 : Pin 8 */ +#define GPIO_DIR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_DIR_PIN8_Msk (0x1UL << GPIO_DIR_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_DIR_PIN8_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN8_Output (1UL) /*!< Pin set as output */ + +/* Bit 7 : Pin 7 */ +#define GPIO_DIR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_DIR_PIN7_Msk (0x1UL << GPIO_DIR_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_DIR_PIN7_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN7_Output (1UL) /*!< Pin set as output */ + +/* Bit 6 : Pin 6 */ +#define GPIO_DIR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_DIR_PIN6_Msk (0x1UL << GPIO_DIR_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_DIR_PIN6_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN6_Output (1UL) /*!< Pin set as output */ + +/* Bit 5 : Pin 5 */ +#define GPIO_DIR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_DIR_PIN5_Msk (0x1UL << GPIO_DIR_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_DIR_PIN5_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN5_Output (1UL) /*!< Pin set as output */ + +/* Bit 4 : Pin 4 */ +#define GPIO_DIR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_DIR_PIN4_Msk (0x1UL << GPIO_DIR_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_DIR_PIN4_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN4_Output (1UL) /*!< Pin set as output */ + +/* Bit 3 : Pin 3 */ +#define GPIO_DIR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_DIR_PIN3_Msk (0x1UL << GPIO_DIR_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_DIR_PIN3_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN3_Output (1UL) /*!< Pin set as output */ + +/* Bit 2 : Pin 2 */ +#define GPIO_DIR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_DIR_PIN2_Msk (0x1UL << GPIO_DIR_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_DIR_PIN2_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN2_Output (1UL) /*!< Pin set as output */ + +/* Bit 1 : Pin 1 */ +#define GPIO_DIR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_DIR_PIN1_Msk (0x1UL << GPIO_DIR_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_DIR_PIN1_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN1_Output (1UL) /*!< Pin set as output */ + +/* Bit 0 : Pin 0 */ +#define GPIO_DIR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_DIR_PIN0_Msk (0x1UL << GPIO_DIR_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_DIR_PIN0_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN0_Output (1UL) /*!< Pin set as output */ + +/* Register: GPIO_DIRSET */ +/* Description: DIR set register */ + +/* Bit 31 : Set as output pin 31 */ +#define GPIO_DIRSET_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_DIRSET_PIN31_Msk (0x1UL << GPIO_DIRSET_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_DIRSET_PIN31_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN31_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN31_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 30 : Set as output pin 30 */ +#define GPIO_DIRSET_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_DIRSET_PIN30_Msk (0x1UL << GPIO_DIRSET_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_DIRSET_PIN30_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN30_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN30_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 29 : Set as output pin 29 */ +#define GPIO_DIRSET_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_DIRSET_PIN29_Msk (0x1UL << GPIO_DIRSET_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_DIRSET_PIN29_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN29_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN29_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 28 : Set as output pin 28 */ +#define GPIO_DIRSET_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_DIRSET_PIN28_Msk (0x1UL << GPIO_DIRSET_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_DIRSET_PIN28_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN28_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN28_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 27 : Set as output pin 27 */ +#define GPIO_DIRSET_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_DIRSET_PIN27_Msk (0x1UL << GPIO_DIRSET_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_DIRSET_PIN27_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN27_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN27_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 26 : Set as output pin 26 */ +#define GPIO_DIRSET_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_DIRSET_PIN26_Msk (0x1UL << GPIO_DIRSET_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_DIRSET_PIN26_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN26_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN26_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 25 : Set as output pin 25 */ +#define GPIO_DIRSET_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_DIRSET_PIN25_Msk (0x1UL << GPIO_DIRSET_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_DIRSET_PIN25_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN25_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN25_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 24 : Set as output pin 24 */ +#define GPIO_DIRSET_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_DIRSET_PIN24_Msk (0x1UL << GPIO_DIRSET_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_DIRSET_PIN24_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN24_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN24_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 23 : Set as output pin 23 */ +#define GPIO_DIRSET_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_DIRSET_PIN23_Msk (0x1UL << GPIO_DIRSET_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_DIRSET_PIN23_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN23_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN23_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 22 : Set as output pin 22 */ +#define GPIO_DIRSET_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_DIRSET_PIN22_Msk (0x1UL << GPIO_DIRSET_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_DIRSET_PIN22_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN22_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN22_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 21 : Set as output pin 21 */ +#define GPIO_DIRSET_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_DIRSET_PIN21_Msk (0x1UL << GPIO_DIRSET_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_DIRSET_PIN21_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN21_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN21_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 20 : Set as output pin 20 */ +#define GPIO_DIRSET_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_DIRSET_PIN20_Msk (0x1UL << GPIO_DIRSET_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_DIRSET_PIN20_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN20_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN20_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 19 : Set as output pin 19 */ +#define GPIO_DIRSET_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_DIRSET_PIN19_Msk (0x1UL << GPIO_DIRSET_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_DIRSET_PIN19_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN19_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN19_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 18 : Set as output pin 18 */ +#define GPIO_DIRSET_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_DIRSET_PIN18_Msk (0x1UL << GPIO_DIRSET_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_DIRSET_PIN18_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN18_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN18_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 17 : Set as output pin 17 */ +#define GPIO_DIRSET_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_DIRSET_PIN17_Msk (0x1UL << GPIO_DIRSET_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_DIRSET_PIN17_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN17_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN17_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 16 : Set as output pin 16 */ +#define GPIO_DIRSET_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_DIRSET_PIN16_Msk (0x1UL << GPIO_DIRSET_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_DIRSET_PIN16_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN16_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN16_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 15 : Set as output pin 15 */ +#define GPIO_DIRSET_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_DIRSET_PIN15_Msk (0x1UL << GPIO_DIRSET_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_DIRSET_PIN15_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN15_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN15_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 14 : Set as output pin 14 */ +#define GPIO_DIRSET_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_DIRSET_PIN14_Msk (0x1UL << GPIO_DIRSET_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_DIRSET_PIN14_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN14_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN14_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 13 : Set as output pin 13 */ +#define GPIO_DIRSET_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_DIRSET_PIN13_Msk (0x1UL << GPIO_DIRSET_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_DIRSET_PIN13_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN13_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN13_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 12 : Set as output pin 12 */ +#define GPIO_DIRSET_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_DIRSET_PIN12_Msk (0x1UL << GPIO_DIRSET_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_DIRSET_PIN12_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN12_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN12_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 11 : Set as output pin 11 */ +#define GPIO_DIRSET_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_DIRSET_PIN11_Msk (0x1UL << GPIO_DIRSET_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_DIRSET_PIN11_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN11_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN11_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 10 : Set as output pin 10 */ +#define GPIO_DIRSET_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_DIRSET_PIN10_Msk (0x1UL << GPIO_DIRSET_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_DIRSET_PIN10_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN10_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN10_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 9 : Set as output pin 9 */ +#define GPIO_DIRSET_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_DIRSET_PIN9_Msk (0x1UL << GPIO_DIRSET_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_DIRSET_PIN9_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN9_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN9_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 8 : Set as output pin 8 */ +#define GPIO_DIRSET_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_DIRSET_PIN8_Msk (0x1UL << GPIO_DIRSET_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_DIRSET_PIN8_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN8_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN8_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 7 : Set as output pin 7 */ +#define GPIO_DIRSET_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_DIRSET_PIN7_Msk (0x1UL << GPIO_DIRSET_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_DIRSET_PIN7_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN7_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN7_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 6 : Set as output pin 6 */ +#define GPIO_DIRSET_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_DIRSET_PIN6_Msk (0x1UL << GPIO_DIRSET_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_DIRSET_PIN6_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN6_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN6_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 5 : Set as output pin 5 */ +#define GPIO_DIRSET_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_DIRSET_PIN5_Msk (0x1UL << GPIO_DIRSET_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_DIRSET_PIN5_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN5_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN5_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 4 : Set as output pin 4 */ +#define GPIO_DIRSET_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_DIRSET_PIN4_Msk (0x1UL << GPIO_DIRSET_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_DIRSET_PIN4_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN4_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN4_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 3 : Set as output pin 3 */ +#define GPIO_DIRSET_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_DIRSET_PIN3_Msk (0x1UL << GPIO_DIRSET_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_DIRSET_PIN3_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN3_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN3_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 2 : Set as output pin 2 */ +#define GPIO_DIRSET_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_DIRSET_PIN2_Msk (0x1UL << GPIO_DIRSET_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_DIRSET_PIN2_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN2_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN2_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 1 : Set as output pin 1 */ +#define GPIO_DIRSET_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_DIRSET_PIN1_Msk (0x1UL << GPIO_DIRSET_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_DIRSET_PIN1_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN1_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN1_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 0 : Set as output pin 0 */ +#define GPIO_DIRSET_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_DIRSET_PIN0_Msk (0x1UL << GPIO_DIRSET_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_DIRSET_PIN0_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN0_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN0_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Register: GPIO_DIRCLR */ +/* Description: DIR clear register */ + +/* Bit 31 : Set as input pin 31 */ +#define GPIO_DIRCLR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_DIRCLR_PIN31_Msk (0x1UL << GPIO_DIRCLR_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_DIRCLR_PIN31_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN31_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN31_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 30 : Set as input pin 30 */ +#define GPIO_DIRCLR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_DIRCLR_PIN30_Msk (0x1UL << GPIO_DIRCLR_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_DIRCLR_PIN30_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN30_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN30_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 29 : Set as input pin 29 */ +#define GPIO_DIRCLR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_DIRCLR_PIN29_Msk (0x1UL << GPIO_DIRCLR_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_DIRCLR_PIN29_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN29_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN29_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 28 : Set as input pin 28 */ +#define GPIO_DIRCLR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_DIRCLR_PIN28_Msk (0x1UL << GPIO_DIRCLR_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_DIRCLR_PIN28_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN28_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN28_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 27 : Set as input pin 27 */ +#define GPIO_DIRCLR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_DIRCLR_PIN27_Msk (0x1UL << GPIO_DIRCLR_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_DIRCLR_PIN27_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN27_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN27_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 26 : Set as input pin 26 */ +#define GPIO_DIRCLR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_DIRCLR_PIN26_Msk (0x1UL << GPIO_DIRCLR_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_DIRCLR_PIN26_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN26_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN26_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 25 : Set as input pin 25 */ +#define GPIO_DIRCLR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_DIRCLR_PIN25_Msk (0x1UL << GPIO_DIRCLR_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_DIRCLR_PIN25_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN25_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN25_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 24 : Set as input pin 24 */ +#define GPIO_DIRCLR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_DIRCLR_PIN24_Msk (0x1UL << GPIO_DIRCLR_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_DIRCLR_PIN24_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN24_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN24_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 23 : Set as input pin 23 */ +#define GPIO_DIRCLR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_DIRCLR_PIN23_Msk (0x1UL << GPIO_DIRCLR_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_DIRCLR_PIN23_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN23_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN23_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 22 : Set as input pin 22 */ +#define GPIO_DIRCLR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_DIRCLR_PIN22_Msk (0x1UL << GPIO_DIRCLR_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_DIRCLR_PIN22_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN22_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN22_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 21 : Set as input pin 21 */ +#define GPIO_DIRCLR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_DIRCLR_PIN21_Msk (0x1UL << GPIO_DIRCLR_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_DIRCLR_PIN21_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN21_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN21_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 20 : Set as input pin 20 */ +#define GPIO_DIRCLR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_DIRCLR_PIN20_Msk (0x1UL << GPIO_DIRCLR_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_DIRCLR_PIN20_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN20_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN20_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 19 : Set as input pin 19 */ +#define GPIO_DIRCLR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_DIRCLR_PIN19_Msk (0x1UL << GPIO_DIRCLR_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_DIRCLR_PIN19_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN19_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN19_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 18 : Set as input pin 18 */ +#define GPIO_DIRCLR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_DIRCLR_PIN18_Msk (0x1UL << GPIO_DIRCLR_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_DIRCLR_PIN18_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN18_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN18_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 17 : Set as input pin 17 */ +#define GPIO_DIRCLR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_DIRCLR_PIN17_Msk (0x1UL << GPIO_DIRCLR_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_DIRCLR_PIN17_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN17_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN17_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 16 : Set as input pin 16 */ +#define GPIO_DIRCLR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_DIRCLR_PIN16_Msk (0x1UL << GPIO_DIRCLR_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_DIRCLR_PIN16_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN16_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN16_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 15 : Set as input pin 15 */ +#define GPIO_DIRCLR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_DIRCLR_PIN15_Msk (0x1UL << GPIO_DIRCLR_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_DIRCLR_PIN15_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN15_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN15_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 14 : Set as input pin 14 */ +#define GPIO_DIRCLR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_DIRCLR_PIN14_Msk (0x1UL << GPIO_DIRCLR_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_DIRCLR_PIN14_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN14_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN14_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 13 : Set as input pin 13 */ +#define GPIO_DIRCLR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_DIRCLR_PIN13_Msk (0x1UL << GPIO_DIRCLR_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_DIRCLR_PIN13_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN13_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN13_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 12 : Set as input pin 12 */ +#define GPIO_DIRCLR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_DIRCLR_PIN12_Msk (0x1UL << GPIO_DIRCLR_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_DIRCLR_PIN12_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN12_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN12_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 11 : Set as input pin 11 */ +#define GPIO_DIRCLR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_DIRCLR_PIN11_Msk (0x1UL << GPIO_DIRCLR_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_DIRCLR_PIN11_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN11_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN11_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 10 : Set as input pin 10 */ +#define GPIO_DIRCLR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_DIRCLR_PIN10_Msk (0x1UL << GPIO_DIRCLR_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_DIRCLR_PIN10_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN10_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN10_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 9 : Set as input pin 9 */ +#define GPIO_DIRCLR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_DIRCLR_PIN9_Msk (0x1UL << GPIO_DIRCLR_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_DIRCLR_PIN9_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN9_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN9_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 8 : Set as input pin 8 */ +#define GPIO_DIRCLR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_DIRCLR_PIN8_Msk (0x1UL << GPIO_DIRCLR_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_DIRCLR_PIN8_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN8_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN8_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 7 : Set as input pin 7 */ +#define GPIO_DIRCLR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_DIRCLR_PIN7_Msk (0x1UL << GPIO_DIRCLR_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_DIRCLR_PIN7_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN7_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN7_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 6 : Set as input pin 6 */ +#define GPIO_DIRCLR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_DIRCLR_PIN6_Msk (0x1UL << GPIO_DIRCLR_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_DIRCLR_PIN6_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN6_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN6_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 5 : Set as input pin 5 */ +#define GPIO_DIRCLR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_DIRCLR_PIN5_Msk (0x1UL << GPIO_DIRCLR_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_DIRCLR_PIN5_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN5_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN5_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 4 : Set as input pin 4 */ +#define GPIO_DIRCLR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_DIRCLR_PIN4_Msk (0x1UL << GPIO_DIRCLR_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_DIRCLR_PIN4_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN4_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN4_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 3 : Set as input pin 3 */ +#define GPIO_DIRCLR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_DIRCLR_PIN3_Msk (0x1UL << GPIO_DIRCLR_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_DIRCLR_PIN3_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN3_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN3_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 2 : Set as input pin 2 */ +#define GPIO_DIRCLR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_DIRCLR_PIN2_Msk (0x1UL << GPIO_DIRCLR_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_DIRCLR_PIN2_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN2_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN2_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 1 : Set as input pin 1 */ +#define GPIO_DIRCLR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_DIRCLR_PIN1_Msk (0x1UL << GPIO_DIRCLR_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_DIRCLR_PIN1_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN1_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN1_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 0 : Set as input pin 0 */ +#define GPIO_DIRCLR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_DIRCLR_PIN0_Msk (0x1UL << GPIO_DIRCLR_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_DIRCLR_PIN0_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN0_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN0_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Register: GPIO_LATCH */ +/* Description: Latch register indicating what GPIO pins that have met the criteria set in the PIN_CNF[n].SENSE registers */ + +/* Bit 31 : Status on whether PIN31 has met criteria set in PIN_CNF31.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_LATCH_PIN31_Msk (0x1UL << GPIO_LATCH_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_LATCH_PIN31_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN31_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 30 : Status on whether PIN30 has met criteria set in PIN_CNF30.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_LATCH_PIN30_Msk (0x1UL << GPIO_LATCH_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_LATCH_PIN30_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN30_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 29 : Status on whether PIN29 has met criteria set in PIN_CNF29.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_LATCH_PIN29_Msk (0x1UL << GPIO_LATCH_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_LATCH_PIN29_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN29_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 28 : Status on whether PIN28 has met criteria set in PIN_CNF28.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_LATCH_PIN28_Msk (0x1UL << GPIO_LATCH_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_LATCH_PIN28_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN28_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 27 : Status on whether PIN27 has met criteria set in PIN_CNF27.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_LATCH_PIN27_Msk (0x1UL << GPIO_LATCH_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_LATCH_PIN27_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN27_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 26 : Status on whether PIN26 has met criteria set in PIN_CNF26.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_LATCH_PIN26_Msk (0x1UL << GPIO_LATCH_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_LATCH_PIN26_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN26_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 25 : Status on whether PIN25 has met criteria set in PIN_CNF25.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_LATCH_PIN25_Msk (0x1UL << GPIO_LATCH_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_LATCH_PIN25_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN25_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 24 : Status on whether PIN24 has met criteria set in PIN_CNF24.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_LATCH_PIN24_Msk (0x1UL << GPIO_LATCH_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_LATCH_PIN24_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN24_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 23 : Status on whether PIN23 has met criteria set in PIN_CNF23.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_LATCH_PIN23_Msk (0x1UL << GPIO_LATCH_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_LATCH_PIN23_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN23_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 22 : Status on whether PIN22 has met criteria set in PIN_CNF22.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_LATCH_PIN22_Msk (0x1UL << GPIO_LATCH_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_LATCH_PIN22_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN22_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 21 : Status on whether PIN21 has met criteria set in PIN_CNF21.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_LATCH_PIN21_Msk (0x1UL << GPIO_LATCH_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_LATCH_PIN21_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN21_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 20 : Status on whether PIN20 has met criteria set in PIN_CNF20.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_LATCH_PIN20_Msk (0x1UL << GPIO_LATCH_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_LATCH_PIN20_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN20_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 19 : Status on whether PIN19 has met criteria set in PIN_CNF19.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_LATCH_PIN19_Msk (0x1UL << GPIO_LATCH_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_LATCH_PIN19_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN19_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 18 : Status on whether PIN18 has met criteria set in PIN_CNF18.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_LATCH_PIN18_Msk (0x1UL << GPIO_LATCH_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_LATCH_PIN18_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN18_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 17 : Status on whether PIN17 has met criteria set in PIN_CNF17.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_LATCH_PIN17_Msk (0x1UL << GPIO_LATCH_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_LATCH_PIN17_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN17_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 16 : Status on whether PIN16 has met criteria set in PIN_CNF16.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_LATCH_PIN16_Msk (0x1UL << GPIO_LATCH_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_LATCH_PIN16_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN16_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 15 : Status on whether PIN15 has met criteria set in PIN_CNF15.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_LATCH_PIN15_Msk (0x1UL << GPIO_LATCH_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_LATCH_PIN15_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN15_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 14 : Status on whether PIN14 has met criteria set in PIN_CNF14.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_LATCH_PIN14_Msk (0x1UL << GPIO_LATCH_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_LATCH_PIN14_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN14_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 13 : Status on whether PIN13 has met criteria set in PIN_CNF13.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_LATCH_PIN13_Msk (0x1UL << GPIO_LATCH_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_LATCH_PIN13_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN13_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 12 : Status on whether PIN12 has met criteria set in PIN_CNF12.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_LATCH_PIN12_Msk (0x1UL << GPIO_LATCH_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_LATCH_PIN12_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN12_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 11 : Status on whether PIN11 has met criteria set in PIN_CNF11.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_LATCH_PIN11_Msk (0x1UL << GPIO_LATCH_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_LATCH_PIN11_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN11_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 10 : Status on whether PIN10 has met criteria set in PIN_CNF10.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_LATCH_PIN10_Msk (0x1UL << GPIO_LATCH_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_LATCH_PIN10_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN10_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 9 : Status on whether PIN9 has met criteria set in PIN_CNF9.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_LATCH_PIN9_Msk (0x1UL << GPIO_LATCH_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_LATCH_PIN9_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN9_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 8 : Status on whether PIN8 has met criteria set in PIN_CNF8.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_LATCH_PIN8_Msk (0x1UL << GPIO_LATCH_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_LATCH_PIN8_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN8_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 7 : Status on whether PIN7 has met criteria set in PIN_CNF7.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_LATCH_PIN7_Msk (0x1UL << GPIO_LATCH_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_LATCH_PIN7_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN7_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 6 : Status on whether PIN6 has met criteria set in PIN_CNF6.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_LATCH_PIN6_Msk (0x1UL << GPIO_LATCH_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_LATCH_PIN6_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN6_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 5 : Status on whether PIN5 has met criteria set in PIN_CNF5.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_LATCH_PIN5_Msk (0x1UL << GPIO_LATCH_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_LATCH_PIN5_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN5_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 4 : Status on whether PIN4 has met criteria set in PIN_CNF4.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_LATCH_PIN4_Msk (0x1UL << GPIO_LATCH_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_LATCH_PIN4_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN4_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 3 : Status on whether PIN3 has met criteria set in PIN_CNF3.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_LATCH_PIN3_Msk (0x1UL << GPIO_LATCH_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_LATCH_PIN3_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN3_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 2 : Status on whether PIN2 has met criteria set in PIN_CNF2.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_LATCH_PIN2_Msk (0x1UL << GPIO_LATCH_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_LATCH_PIN2_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN2_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 1 : Status on whether PIN1 has met criteria set in PIN_CNF1.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_LATCH_PIN1_Msk (0x1UL << GPIO_LATCH_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_LATCH_PIN1_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN1_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 0 : Status on whether PIN0 has met criteria set in PIN_CNF0.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_LATCH_PIN0_Msk (0x1UL << GPIO_LATCH_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_LATCH_PIN0_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN0_Latched (1UL) /*!< Criteria has been met */ + +/* Register: GPIO_DETECTMODE */ +/* Description: Select between default DETECT signal behaviour and LDETECT mode */ + +/* Bit 0 : Select between default DETECT signal behaviour and LDETECT mode */ +#define GPIO_DETECTMODE_DETECTMODE_Pos (0UL) /*!< Position of DETECTMODE field. */ +#define GPIO_DETECTMODE_DETECTMODE_Msk (0x1UL << GPIO_DETECTMODE_DETECTMODE_Pos) /*!< Bit mask of DETECTMODE field. */ +#define GPIO_DETECTMODE_DETECTMODE_Default (0UL) /*!< DETECT directly connected to PIN DETECT signals */ +#define GPIO_DETECTMODE_DETECTMODE_LDETECT (1UL) /*!< Use the latched LDETECT behaviour */ + +/* Register: GPIO_PIN_CNF */ +/* Description: Description collection[0]: Configuration of GPIO pins */ + +/* Bits 17..16 : Pin sensing mechanism */ +#define GPIO_PIN_CNF_SENSE_Pos (16UL) /*!< Position of SENSE field. */ +#define GPIO_PIN_CNF_SENSE_Msk (0x3UL << GPIO_PIN_CNF_SENSE_Pos) /*!< Bit mask of SENSE field. */ +#define GPIO_PIN_CNF_SENSE_Disabled (0UL) /*!< Disabled */ +#define GPIO_PIN_CNF_SENSE_High (2UL) /*!< Sense for high level */ +#define GPIO_PIN_CNF_SENSE_Low (3UL) /*!< Sense for low level */ + +/* Bits 10..8 : Drive configuration */ +#define GPIO_PIN_CNF_DRIVE_Pos (8UL) /*!< Position of DRIVE field. */ +#define GPIO_PIN_CNF_DRIVE_Msk (0x7UL << GPIO_PIN_CNF_DRIVE_Pos) /*!< Bit mask of DRIVE field. */ +#define GPIO_PIN_CNF_DRIVE_S0S1 (0UL) /*!< Standard '0', standard '1' */ +#define GPIO_PIN_CNF_DRIVE_H0S1 (1UL) /*!< High drive '0', standard '1' */ +#define GPIO_PIN_CNF_DRIVE_S0H1 (2UL) /*!< Standard '0', high drive '1' */ +#define GPIO_PIN_CNF_DRIVE_H0H1 (3UL) /*!< High drive '0', high 'drive '1'' */ +#define GPIO_PIN_CNF_DRIVE_D0S1 (4UL) /*!< Disconnect '0' standard '1' (normally used for wired-or connections) */ +#define GPIO_PIN_CNF_DRIVE_D0H1 (5UL) /*!< Disconnect '0', high drive '1' (normally used for wired-or connections) */ +#define GPIO_PIN_CNF_DRIVE_S0D1 (6UL) /*!< Standard '0'. disconnect '1' (normally used for wired-and connections) */ +#define GPIO_PIN_CNF_DRIVE_H0D1 (7UL) /*!< High drive '0', disconnect '1' (normally used for wired-and connections) */ + +/* Bits 3..2 : Pull configuration */ +#define GPIO_PIN_CNF_PULL_Pos (2UL) /*!< Position of PULL field. */ +#define GPIO_PIN_CNF_PULL_Msk (0x3UL << GPIO_PIN_CNF_PULL_Pos) /*!< Bit mask of PULL field. */ +#define GPIO_PIN_CNF_PULL_Disabled (0UL) /*!< No pull */ +#define GPIO_PIN_CNF_PULL_Pulldown (1UL) /*!< Pull down on pin */ +#define GPIO_PIN_CNF_PULL_Pullup (3UL) /*!< Pull up on pin */ + +/* Bit 1 : Connect or disconnect input buffer */ +#define GPIO_PIN_CNF_INPUT_Pos (1UL) /*!< Position of INPUT field. */ +#define GPIO_PIN_CNF_INPUT_Msk (0x1UL << GPIO_PIN_CNF_INPUT_Pos) /*!< Bit mask of INPUT field. */ +#define GPIO_PIN_CNF_INPUT_Connect (0UL) /*!< Connect input buffer */ +#define GPIO_PIN_CNF_INPUT_Disconnect (1UL) /*!< Disconnect input buffer */ + +/* Bit 0 : Pin direction. Same physical register as DIR register */ +#define GPIO_PIN_CNF_DIR_Pos (0UL) /*!< Position of DIR field. */ +#define GPIO_PIN_CNF_DIR_Msk (0x1UL << GPIO_PIN_CNF_DIR_Pos) /*!< Bit mask of DIR field. */ +#define GPIO_PIN_CNF_DIR_Input (0UL) /*!< Configure pin as an input pin */ +#define GPIO_PIN_CNF_DIR_Output (1UL) /*!< Configure pin as an output pin */ + + +/* Peripheral: PDM */ +/* Description: Pulse Density Modulation (Digital Microphone) Interface */ + +/* Register: PDM_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 2 : Enable or disable interrupt for END event */ +#define PDM_INTEN_END_Pos (2UL) /*!< Position of END field. */ +#define PDM_INTEN_END_Msk (0x1UL << PDM_INTEN_END_Pos) /*!< Bit mask of END field. */ +#define PDM_INTEN_END_Disabled (0UL) /*!< Disable */ +#define PDM_INTEN_END_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for STOPPED event */ +#define PDM_INTEN_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define PDM_INTEN_STOPPED_Msk (0x1UL << PDM_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define PDM_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ +#define PDM_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable interrupt for STARTED event */ +#define PDM_INTEN_STARTED_Pos (0UL) /*!< Position of STARTED field. */ +#define PDM_INTEN_STARTED_Msk (0x1UL << PDM_INTEN_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define PDM_INTEN_STARTED_Disabled (0UL) /*!< Disable */ +#define PDM_INTEN_STARTED_Enabled (1UL) /*!< Enable */ + +/* Register: PDM_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 2 : Write '1' to Enable interrupt for END event */ +#define PDM_INTENSET_END_Pos (2UL) /*!< Position of END field. */ +#define PDM_INTENSET_END_Msk (0x1UL << PDM_INTENSET_END_Pos) /*!< Bit mask of END field. */ +#define PDM_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ +#define PDM_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ +#define PDM_INTENSET_END_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ +#define PDM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define PDM_INTENSET_STOPPED_Msk (0x1UL << PDM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define PDM_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define PDM_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define PDM_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for STARTED event */ +#define PDM_INTENSET_STARTED_Pos (0UL) /*!< Position of STARTED field. */ +#define PDM_INTENSET_STARTED_Msk (0x1UL << PDM_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define PDM_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define PDM_INTENSET_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define PDM_INTENSET_STARTED_Set (1UL) /*!< Enable */ + +/* Register: PDM_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 2 : Write '1' to Disable interrupt for END event */ +#define PDM_INTENCLR_END_Pos (2UL) /*!< Position of END field. */ +#define PDM_INTENCLR_END_Msk (0x1UL << PDM_INTENCLR_END_Pos) /*!< Bit mask of END field. */ +#define PDM_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ +#define PDM_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ +#define PDM_INTENCLR_END_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ +#define PDM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define PDM_INTENCLR_STOPPED_Msk (0x1UL << PDM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define PDM_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define PDM_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define PDM_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for STARTED event */ +#define PDM_INTENCLR_STARTED_Pos (0UL) /*!< Position of STARTED field. */ +#define PDM_INTENCLR_STARTED_Msk (0x1UL << PDM_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define PDM_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define PDM_INTENCLR_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define PDM_INTENCLR_STARTED_Clear (1UL) /*!< Disable */ + +/* Register: PDM_ENABLE */ +/* Description: PDM module enable register */ + +/* Bit 0 : Enable or disable PDM module */ +#define PDM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define PDM_ENABLE_ENABLE_Msk (0x1UL << PDM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define PDM_ENABLE_ENABLE_Disabled (0UL) /*!< Disable */ +#define PDM_ENABLE_ENABLE_Enabled (1UL) /*!< Enable */ + +/* Register: PDM_PDMCLKCTRL */ +/* Description: PDM clock generator control */ + +/* Bits 31..0 : PDM_CLK frequency */ +#define PDM_PDMCLKCTRL_FREQ_Pos (0UL) /*!< Position of FREQ field. */ +#define PDM_PDMCLKCTRL_FREQ_Msk (0xFFFFFFFFUL << PDM_PDMCLKCTRL_FREQ_Pos) /*!< Bit mask of FREQ field. */ +#define PDM_PDMCLKCTRL_FREQ_1000K (0x08000000UL) /*!< PDM_CLK = 32 MHz / 32 = 1.000 MHz */ +#define PDM_PDMCLKCTRL_FREQ_Default (0x08400000UL) /*!< PDM_CLK = 32 MHz / 31 = 1.032 MHz. Nominal clock for RATIO=Ratio64. */ +#define PDM_PDMCLKCTRL_FREQ_1067K (0x08800000UL) /*!< PDM_CLK = 32 MHz / 30 = 1.067 MHz */ +#define PDM_PDMCLKCTRL_FREQ_1231K (0x09800000UL) /*!< PDM_CLK = 32 MHz / 26 = 1.231 MHz */ +#define PDM_PDMCLKCTRL_FREQ_1280K (0x0A000000UL) /*!< PDM_CLK = 32 MHz / 25 = 1.280 MHz. Nominal clock for RATIO=Ratio80. */ +#define PDM_PDMCLKCTRL_FREQ_1333K (0x0A800000UL) /*!< PDM_CLK = 32 MHz / 24 = 1.333 MHz */ + +/* Register: PDM_MODE */ +/* Description: Defines the routing of the connected PDM microphones' signals */ + +/* Bit 1 : Defines on which PDM_CLK edge Left (or mono) is sampled */ +#define PDM_MODE_EDGE_Pos (1UL) /*!< Position of EDGE field. */ +#define PDM_MODE_EDGE_Msk (0x1UL << PDM_MODE_EDGE_Pos) /*!< Bit mask of EDGE field. */ +#define PDM_MODE_EDGE_LeftFalling (0UL) /*!< Left (or mono) is sampled on falling edge of PDM_CLK */ +#define PDM_MODE_EDGE_LeftRising (1UL) /*!< Left (or mono) is sampled on rising edge of PDM_CLK */ + +/* Bit 0 : Mono or stereo operation */ +#define PDM_MODE_OPERATION_Pos (0UL) /*!< Position of OPERATION field. */ +#define PDM_MODE_OPERATION_Msk (0x1UL << PDM_MODE_OPERATION_Pos) /*!< Bit mask of OPERATION field. */ +#define PDM_MODE_OPERATION_Stereo (0UL) /*!< Sample and store one pair (Left + Right) of 16bit samples per RAM word R=[31:16]; L=[15:0] */ +#define PDM_MODE_OPERATION_Mono (1UL) /*!< Sample and store two successive Left samples (16 bit each) per RAM word L1=[31:16]; L0=[15:0] */ + +/* Register: PDM_GAINL */ +/* Description: Left output gain adjustment */ + +/* Bits 6..0 : Left output gain adjustment, in 0.5 dB steps, around the default module gain (see electrical parameters) 0x00 -20 dB gain adjust 0x01 -19.5 dB gain adjust (...) 0x27 -0.5 dB gain adjust 0x28 0 dB gain adjust 0x29 +0.5 dB gain adjust (...) 0x4F +19.5 dB gain adjust 0x50 +20 dB gain adjust */ +#define PDM_GAINL_GAINL_Pos (0UL) /*!< Position of GAINL field. */ +#define PDM_GAINL_GAINL_Msk (0x7FUL << PDM_GAINL_GAINL_Pos) /*!< Bit mask of GAINL field. */ +#define PDM_GAINL_GAINL_MinGain (0x00UL) /*!< -20dB gain adjustment (minimum) */ +#define PDM_GAINL_GAINL_DefaultGain (0x28UL) /*!< 0dB gain adjustment ('2500 RMS' requirement) */ +#define PDM_GAINL_GAINL_MaxGain (0x50UL) /*!< +20dB gain adjustment (maximum) */ + +/* Register: PDM_GAINR */ +/* Description: Right output gain adjustment */ + +/* Bits 7..0 : Right output gain adjustment, in 0.5 dB steps, around the default module gain (see electrical parameters) */ +#define PDM_GAINR_GAINR_Pos (0UL) /*!< Position of GAINR field. */ +#define PDM_GAINR_GAINR_Msk (0xFFUL << PDM_GAINR_GAINR_Pos) /*!< Bit mask of GAINR field. */ +#define PDM_GAINR_GAINR_MinGain (0x00UL) /*!< -20dB gain adjustment (minimum) */ +#define PDM_GAINR_GAINR_DefaultGain (0x28UL) /*!< 0dB gain adjustment ('2500 RMS' requirement) */ +#define PDM_GAINR_GAINR_MaxGain (0x50UL) /*!< +20dB gain adjustment (maximum) */ + +/* Register: PDM_RATIO */ +/* Description: Selects the ratio between PDM_CLK and output sample rate. Change PDMCLKCTRL accordingly. */ + +/* Bit 0 : Selects the ratio between PDM_CLK and output sample rate */ +#define PDM_RATIO_RATIO_Pos (0UL) /*!< Position of RATIO field. */ +#define PDM_RATIO_RATIO_Msk (0x1UL << PDM_RATIO_RATIO_Pos) /*!< Bit mask of RATIO field. */ +#define PDM_RATIO_RATIO_Ratio64 (0UL) /*!< Ratio of 64 */ +#define PDM_RATIO_RATIO_Ratio80 (1UL) /*!< Ratio of 80 */ + +/* Register: PDM_PSEL_CLK */ +/* Description: Pin number configuration for PDM CLK signal */ + +/* Bit 31 : Connection */ +#define PDM_PSEL_CLK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define PDM_PSEL_CLK_CONNECT_Msk (0x1UL << PDM_PSEL_CLK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define PDM_PSEL_CLK_CONNECT_Connected (0UL) /*!< Connect */ +#define PDM_PSEL_CLK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define PDM_PSEL_CLK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define PDM_PSEL_CLK_PORT_Msk (0x1UL << PDM_PSEL_CLK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define PDM_PSEL_CLK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define PDM_PSEL_CLK_PIN_Msk (0x1FUL << PDM_PSEL_CLK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: PDM_PSEL_DIN */ +/* Description: Pin number configuration for PDM DIN signal */ + +/* Bit 31 : Connection */ +#define PDM_PSEL_DIN_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define PDM_PSEL_DIN_CONNECT_Msk (0x1UL << PDM_PSEL_DIN_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define PDM_PSEL_DIN_CONNECT_Connected (0UL) /*!< Connect */ +#define PDM_PSEL_DIN_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define PDM_PSEL_DIN_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define PDM_PSEL_DIN_PORT_Msk (0x1UL << PDM_PSEL_DIN_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define PDM_PSEL_DIN_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define PDM_PSEL_DIN_PIN_Msk (0x1FUL << PDM_PSEL_DIN_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: PDM_SAMPLE_PTR */ +/* Description: RAM address pointer to write samples to with EasyDMA */ + +/* Bits 31..0 : Address to write PDM samples to over DMA */ +#define PDM_SAMPLE_PTR_SAMPLEPTR_Pos (0UL) /*!< Position of SAMPLEPTR field. */ +#define PDM_SAMPLE_PTR_SAMPLEPTR_Msk (0xFFFFFFFFUL << PDM_SAMPLE_PTR_SAMPLEPTR_Pos) /*!< Bit mask of SAMPLEPTR field. */ + +/* Register: PDM_SAMPLE_MAXCNT */ +/* Description: Number of samples to allocate memory for in EasyDMA mode */ + +/* Bits 14..0 : Length of DMA RAM allocation in number of samples */ +#define PDM_SAMPLE_MAXCNT_BUFFSIZE_Pos (0UL) /*!< Position of BUFFSIZE field. */ +#define PDM_SAMPLE_MAXCNT_BUFFSIZE_Msk (0x7FFFUL << PDM_SAMPLE_MAXCNT_BUFFSIZE_Pos) /*!< Bit mask of BUFFSIZE field. */ + + +/* Peripheral: POWER */ +/* Description: Power control */ + +/* Register: POWER_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 9 : Write '1' to Enable interrupt for USBPWRRDY event */ +#define POWER_INTENSET_USBPWRRDY_Pos (9UL) /*!< Position of USBPWRRDY field. */ +#define POWER_INTENSET_USBPWRRDY_Msk (0x1UL << POWER_INTENSET_USBPWRRDY_Pos) /*!< Bit mask of USBPWRRDY field. */ +#define POWER_INTENSET_USBPWRRDY_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENSET_USBPWRRDY_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENSET_USBPWRRDY_Set (1UL) /*!< Enable */ + +/* Bit 8 : Write '1' to Enable interrupt for USBREMOVED event */ +#define POWER_INTENSET_USBREMOVED_Pos (8UL) /*!< Position of USBREMOVED field. */ +#define POWER_INTENSET_USBREMOVED_Msk (0x1UL << POWER_INTENSET_USBREMOVED_Pos) /*!< Bit mask of USBREMOVED field. */ +#define POWER_INTENSET_USBREMOVED_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENSET_USBREMOVED_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENSET_USBREMOVED_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for USBDETECTED event */ +#define POWER_INTENSET_USBDETECTED_Pos (7UL) /*!< Position of USBDETECTED field. */ +#define POWER_INTENSET_USBDETECTED_Msk (0x1UL << POWER_INTENSET_USBDETECTED_Pos) /*!< Bit mask of USBDETECTED field. */ +#define POWER_INTENSET_USBDETECTED_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENSET_USBDETECTED_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENSET_USBDETECTED_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for SLEEPEXIT event */ +#define POWER_INTENSET_SLEEPEXIT_Pos (6UL) /*!< Position of SLEEPEXIT field. */ +#define POWER_INTENSET_SLEEPEXIT_Msk (0x1UL << POWER_INTENSET_SLEEPEXIT_Pos) /*!< Bit mask of SLEEPEXIT field. */ +#define POWER_INTENSET_SLEEPEXIT_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENSET_SLEEPEXIT_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENSET_SLEEPEXIT_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for SLEEPENTER event */ +#define POWER_INTENSET_SLEEPENTER_Pos (5UL) /*!< Position of SLEEPENTER field. */ +#define POWER_INTENSET_SLEEPENTER_Msk (0x1UL << POWER_INTENSET_SLEEPENTER_Pos) /*!< Bit mask of SLEEPENTER field. */ +#define POWER_INTENSET_SLEEPENTER_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENSET_SLEEPENTER_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENSET_SLEEPENTER_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for POFWARN event */ +#define POWER_INTENSET_POFWARN_Pos (2UL) /*!< Position of POFWARN field. */ +#define POWER_INTENSET_POFWARN_Msk (0x1UL << POWER_INTENSET_POFWARN_Pos) /*!< Bit mask of POFWARN field. */ +#define POWER_INTENSET_POFWARN_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENSET_POFWARN_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENSET_POFWARN_Set (1UL) /*!< Enable */ + +/* Register: POWER_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 9 : Write '1' to Disable interrupt for USBPWRRDY event */ +#define POWER_INTENCLR_USBPWRRDY_Pos (9UL) /*!< Position of USBPWRRDY field. */ +#define POWER_INTENCLR_USBPWRRDY_Msk (0x1UL << POWER_INTENCLR_USBPWRRDY_Pos) /*!< Bit mask of USBPWRRDY field. */ +#define POWER_INTENCLR_USBPWRRDY_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENCLR_USBPWRRDY_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENCLR_USBPWRRDY_Clear (1UL) /*!< Disable */ + +/* Bit 8 : Write '1' to Disable interrupt for USBREMOVED event */ +#define POWER_INTENCLR_USBREMOVED_Pos (8UL) /*!< Position of USBREMOVED field. */ +#define POWER_INTENCLR_USBREMOVED_Msk (0x1UL << POWER_INTENCLR_USBREMOVED_Pos) /*!< Bit mask of USBREMOVED field. */ +#define POWER_INTENCLR_USBREMOVED_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENCLR_USBREMOVED_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENCLR_USBREMOVED_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for USBDETECTED event */ +#define POWER_INTENCLR_USBDETECTED_Pos (7UL) /*!< Position of USBDETECTED field. */ +#define POWER_INTENCLR_USBDETECTED_Msk (0x1UL << POWER_INTENCLR_USBDETECTED_Pos) /*!< Bit mask of USBDETECTED field. */ +#define POWER_INTENCLR_USBDETECTED_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENCLR_USBDETECTED_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENCLR_USBDETECTED_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for SLEEPEXIT event */ +#define POWER_INTENCLR_SLEEPEXIT_Pos (6UL) /*!< Position of SLEEPEXIT field. */ +#define POWER_INTENCLR_SLEEPEXIT_Msk (0x1UL << POWER_INTENCLR_SLEEPEXIT_Pos) /*!< Bit mask of SLEEPEXIT field. */ +#define POWER_INTENCLR_SLEEPEXIT_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENCLR_SLEEPEXIT_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENCLR_SLEEPEXIT_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for SLEEPENTER event */ +#define POWER_INTENCLR_SLEEPENTER_Pos (5UL) /*!< Position of SLEEPENTER field. */ +#define POWER_INTENCLR_SLEEPENTER_Msk (0x1UL << POWER_INTENCLR_SLEEPENTER_Pos) /*!< Bit mask of SLEEPENTER field. */ +#define POWER_INTENCLR_SLEEPENTER_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENCLR_SLEEPENTER_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENCLR_SLEEPENTER_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for POFWARN event */ +#define POWER_INTENCLR_POFWARN_Pos (2UL) /*!< Position of POFWARN field. */ +#define POWER_INTENCLR_POFWARN_Msk (0x1UL << POWER_INTENCLR_POFWARN_Pos) /*!< Bit mask of POFWARN field. */ +#define POWER_INTENCLR_POFWARN_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENCLR_POFWARN_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENCLR_POFWARN_Clear (1UL) /*!< Disable */ + +/* Register: POWER_RESETREAS */ +/* Description: Reset reason */ + +/* Bit 20 : Reset due to wake up from System OFF mode by Vbus rising into valid range */ +#define POWER_RESETREAS_VBUS_Pos (20UL) /*!< Position of VBUS field. */ +#define POWER_RESETREAS_VBUS_Msk (0x1UL << POWER_RESETREAS_VBUS_Pos) /*!< Bit mask of VBUS field. */ +#define POWER_RESETREAS_VBUS_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_VBUS_Detected (1UL) /*!< Detected */ + +/* Bit 19 : Reset due to wake up from System OFF mode by NFC field detect */ +#define POWER_RESETREAS_NFC_Pos (19UL) /*!< Position of NFC field. */ +#define POWER_RESETREAS_NFC_Msk (0x1UL << POWER_RESETREAS_NFC_Pos) /*!< Bit mask of NFC field. */ +#define POWER_RESETREAS_NFC_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_NFC_Detected (1UL) /*!< Detected */ + +/* Bit 18 : Reset due to wake up from System OFF mode when wakeup is triggered from entering into debug interface mode */ +#define POWER_RESETREAS_DIF_Pos (18UL) /*!< Position of DIF field. */ +#define POWER_RESETREAS_DIF_Msk (0x1UL << POWER_RESETREAS_DIF_Pos) /*!< Bit mask of DIF field. */ +#define POWER_RESETREAS_DIF_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_DIF_Detected (1UL) /*!< Detected */ + +/* Bit 17 : Reset due to wake up from System OFF mode when wakeup is triggered from ANADETECT signal from LPCOMP */ +#define POWER_RESETREAS_LPCOMP_Pos (17UL) /*!< Position of LPCOMP field. */ +#define POWER_RESETREAS_LPCOMP_Msk (0x1UL << POWER_RESETREAS_LPCOMP_Pos) /*!< Bit mask of LPCOMP field. */ +#define POWER_RESETREAS_LPCOMP_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_LPCOMP_Detected (1UL) /*!< Detected */ + +/* Bit 16 : Reset due to wake up from System OFF mode when wakeup is triggered from DETECT signal from GPIO */ +#define POWER_RESETREAS_OFF_Pos (16UL) /*!< Position of OFF field. */ +#define POWER_RESETREAS_OFF_Msk (0x1UL << POWER_RESETREAS_OFF_Pos) /*!< Bit mask of OFF field. */ +#define POWER_RESETREAS_OFF_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_OFF_Detected (1UL) /*!< Detected */ + +/* Bit 3 : Reset from CPU lock-up detected */ +#define POWER_RESETREAS_LOCKUP_Pos (3UL) /*!< Position of LOCKUP field. */ +#define POWER_RESETREAS_LOCKUP_Msk (0x1UL << POWER_RESETREAS_LOCKUP_Pos) /*!< Bit mask of LOCKUP field. */ +#define POWER_RESETREAS_LOCKUP_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_LOCKUP_Detected (1UL) /*!< Detected */ + +/* Bit 2 : Reset from soft reset detected */ +#define POWER_RESETREAS_SREQ_Pos (2UL) /*!< Position of SREQ field. */ +#define POWER_RESETREAS_SREQ_Msk (0x1UL << POWER_RESETREAS_SREQ_Pos) /*!< Bit mask of SREQ field. */ +#define POWER_RESETREAS_SREQ_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_SREQ_Detected (1UL) /*!< Detected */ + +/* Bit 1 : Reset from watchdog detected */ +#define POWER_RESETREAS_DOG_Pos (1UL) /*!< Position of DOG field. */ +#define POWER_RESETREAS_DOG_Msk (0x1UL << POWER_RESETREAS_DOG_Pos) /*!< Bit mask of DOG field. */ +#define POWER_RESETREAS_DOG_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_DOG_Detected (1UL) /*!< Detected */ + +/* Bit 0 : Reset from pin-reset detected */ +#define POWER_RESETREAS_RESETPIN_Pos (0UL) /*!< Position of RESETPIN field. */ +#define POWER_RESETREAS_RESETPIN_Msk (0x1UL << POWER_RESETREAS_RESETPIN_Pos) /*!< Bit mask of RESETPIN field. */ +#define POWER_RESETREAS_RESETPIN_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_RESETPIN_Detected (1UL) /*!< Detected */ + +/* Register: POWER_RAMSTATUS */ +/* Description: Deprecated register - RAM status register */ + +/* Bit 3 : RAM block 3 is on or off/powering up */ +#define POWER_RAMSTATUS_RAMBLOCK3_Pos (3UL) /*!< Position of RAMBLOCK3 field. */ +#define POWER_RAMSTATUS_RAMBLOCK3_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK3_Pos) /*!< Bit mask of RAMBLOCK3 field. */ +#define POWER_RAMSTATUS_RAMBLOCK3_Off (0UL) /*!< Off */ +#define POWER_RAMSTATUS_RAMBLOCK3_On (1UL) /*!< On */ + +/* Bit 2 : RAM block 2 is on or off/powering up */ +#define POWER_RAMSTATUS_RAMBLOCK2_Pos (2UL) /*!< Position of RAMBLOCK2 field. */ +#define POWER_RAMSTATUS_RAMBLOCK2_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK2_Pos) /*!< Bit mask of RAMBLOCK2 field. */ +#define POWER_RAMSTATUS_RAMBLOCK2_Off (0UL) /*!< Off */ +#define POWER_RAMSTATUS_RAMBLOCK2_On (1UL) /*!< On */ + +/* Bit 1 : RAM block 1 is on or off/powering up */ +#define POWER_RAMSTATUS_RAMBLOCK1_Pos (1UL) /*!< Position of RAMBLOCK1 field. */ +#define POWER_RAMSTATUS_RAMBLOCK1_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK1_Pos) /*!< Bit mask of RAMBLOCK1 field. */ +#define POWER_RAMSTATUS_RAMBLOCK1_Off (0UL) /*!< Off */ +#define POWER_RAMSTATUS_RAMBLOCK1_On (1UL) /*!< On */ + +/* Bit 0 : RAM block 0 is on or off/powering up */ +#define POWER_RAMSTATUS_RAMBLOCK0_Pos (0UL) /*!< Position of RAMBLOCK0 field. */ +#define POWER_RAMSTATUS_RAMBLOCK0_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK0_Pos) /*!< Bit mask of RAMBLOCK0 field. */ +#define POWER_RAMSTATUS_RAMBLOCK0_Off (0UL) /*!< Off */ +#define POWER_RAMSTATUS_RAMBLOCK0_On (1UL) /*!< On */ + +/* Register: POWER_USBREGSTATUS */ +/* Description: USB supply status */ + +/* Bit 1 : USB supply output settling time elapsed */ +#define POWER_USBREGSTATUS_OUTPUTRDY_Pos (1UL) /*!< Position of OUTPUTRDY field. */ +#define POWER_USBREGSTATUS_OUTPUTRDY_Msk (0x1UL << POWER_USBREGSTATUS_OUTPUTRDY_Pos) /*!< Bit mask of OUTPUTRDY field. */ +#define POWER_USBREGSTATUS_OUTPUTRDY_NotReady (0UL) /*!< USBREG output settling time not elapsed */ +#define POWER_USBREGSTATUS_OUTPUTRDY_Ready (1UL) /*!< USBREG output settling time elapsed (same information as USBPWRRDY event) */ + +/* Bit 0 : VBUS input detection status (USBDETECTED and USBREMOVED events are derived from this information) */ +#define POWER_USBREGSTATUS_VBUSDETECT_Pos (0UL) /*!< Position of VBUSDETECT field. */ +#define POWER_USBREGSTATUS_VBUSDETECT_Msk (0x1UL << POWER_USBREGSTATUS_VBUSDETECT_Pos) /*!< Bit mask of VBUSDETECT field. */ +#define POWER_USBREGSTATUS_VBUSDETECT_NoVbus (0UL) /*!< VBUS voltage below valid threshold */ +#define POWER_USBREGSTATUS_VBUSDETECT_VbusPresent (1UL) /*!< VBUS voltage above valid threshold */ + +/* Register: POWER_SYSTEMOFF */ +/* Description: System OFF register */ + +/* Bit 0 : Enable System OFF mode */ +#define POWER_SYSTEMOFF_SYSTEMOFF_Pos (0UL) /*!< Position of SYSTEMOFF field. */ +#define POWER_SYSTEMOFF_SYSTEMOFF_Msk (0x1UL << POWER_SYSTEMOFF_SYSTEMOFF_Pos) /*!< Bit mask of SYSTEMOFF field. */ +#define POWER_SYSTEMOFF_SYSTEMOFF_Enter (1UL) /*!< Enable System OFF mode */ + +/* Register: POWER_POFCON */ +/* Description: Power failure comparator configuration */ + +/* Bits 11..8 : Power failure comparator threshold setting for voltage supply on VDDH */ +#define POWER_POFCON_THRESHOLDVDDH_Pos (8UL) /*!< Position of THRESHOLDVDDH field. */ +#define POWER_POFCON_THRESHOLDVDDH_Msk (0xFUL << POWER_POFCON_THRESHOLDVDDH_Pos) /*!< Bit mask of THRESHOLDVDDH field. */ +#define POWER_POFCON_THRESHOLDVDDH_V27 (0UL) /*!< Set threshold to 2.7 V */ +#define POWER_POFCON_THRESHOLDVDDH_V28 (1UL) /*!< Set threshold to 2.8 V */ +#define POWER_POFCON_THRESHOLDVDDH_V29 (2UL) /*!< Set threshold to 2.9 V */ +#define POWER_POFCON_THRESHOLDVDDH_V30 (3UL) /*!< Set threshold to 3.0 V */ +#define POWER_POFCON_THRESHOLDVDDH_V31 (4UL) /*!< Set threshold to 3.1 V */ +#define POWER_POFCON_THRESHOLDVDDH_V32 (5UL) /*!< Set threshold to 3.2 V */ +#define POWER_POFCON_THRESHOLDVDDH_V33 (6UL) /*!< Set threshold to 3.3 V */ +#define POWER_POFCON_THRESHOLDVDDH_V34 (7UL) /*!< Set threshold to 3.4 V */ +#define POWER_POFCON_THRESHOLDVDDH_V35 (8UL) /*!< Set threshold to 3.5 V */ +#define POWER_POFCON_THRESHOLDVDDH_V36 (9UL) /*!< Set threshold to 3.6 V */ +#define POWER_POFCON_THRESHOLDVDDH_V37 (10UL) /*!< Set threshold to 3.7 V */ +#define POWER_POFCON_THRESHOLDVDDH_V38 (11UL) /*!< Set threshold to 3.8 V */ +#define POWER_POFCON_THRESHOLDVDDH_V39 (12UL) /*!< Set threshold to 3.9 V */ +#define POWER_POFCON_THRESHOLDVDDH_V40 (13UL) /*!< Set threshold to 4.0 V */ +#define POWER_POFCON_THRESHOLDVDDH_V41 (14UL) /*!< Set threshold to 4.1 V */ +#define POWER_POFCON_THRESHOLDVDDH_V42 (15UL) /*!< Set threshold to 4.2 V */ + +/* Bits 4..1 : Power failure comparator threshold setting */ +#define POWER_POFCON_THRESHOLD_Pos (1UL) /*!< Position of THRESHOLD field. */ +#define POWER_POFCON_THRESHOLD_Msk (0xFUL << POWER_POFCON_THRESHOLD_Pos) /*!< Bit mask of THRESHOLD field. */ +#define POWER_POFCON_THRESHOLD_V17 (4UL) /*!< Set threshold to 1.7 V */ +#define POWER_POFCON_THRESHOLD_V18 (5UL) /*!< Set threshold to 1.8 V */ +#define POWER_POFCON_THRESHOLD_V19 (6UL) /*!< Set threshold to 1.9 V */ +#define POWER_POFCON_THRESHOLD_V20 (7UL) /*!< Set threshold to 2.0 V */ +#define POWER_POFCON_THRESHOLD_V21 (8UL) /*!< Set threshold to 2.1 V */ +#define POWER_POFCON_THRESHOLD_V22 (9UL) /*!< Set threshold to 2.2 V */ +#define POWER_POFCON_THRESHOLD_V23 (10UL) /*!< Set threshold to 2.3 V */ +#define POWER_POFCON_THRESHOLD_V24 (11UL) /*!< Set threshold to 2.4 V */ +#define POWER_POFCON_THRESHOLD_V25 (12UL) /*!< Set threshold to 2.5 V */ +#define POWER_POFCON_THRESHOLD_V26 (13UL) /*!< Set threshold to 2.6 V */ +#define POWER_POFCON_THRESHOLD_V27 (14UL) /*!< Set threshold to 2.7 V */ +#define POWER_POFCON_THRESHOLD_V28 (15UL) /*!< Set threshold to 2.8 V */ + +/* Bit 0 : Enable or disable power failure comparator */ +#define POWER_POFCON_POF_Pos (0UL) /*!< Position of POF field. */ +#define POWER_POFCON_POF_Msk (0x1UL << POWER_POFCON_POF_Pos) /*!< Bit mask of POF field. */ +#define POWER_POFCON_POF_Disabled (0UL) /*!< Disable */ +#define POWER_POFCON_POF_Enabled (1UL) /*!< Enable */ + +/* Register: POWER_GPREGRET */ +/* Description: General purpose retention register */ + +/* Bits 7..0 : General purpose retention register */ +#define POWER_GPREGRET_GPREGRET_Pos (0UL) /*!< Position of GPREGRET field. */ +#define POWER_GPREGRET_GPREGRET_Msk (0xFFUL << POWER_GPREGRET_GPREGRET_Pos) /*!< Bit mask of GPREGRET field. */ + +/* Register: POWER_GPREGRET2 */ +/* Description: General purpose retention register */ + +/* Bits 7..0 : General purpose retention register */ +#define POWER_GPREGRET2_GPREGRET_Pos (0UL) /*!< Position of GPREGRET field. */ +#define POWER_GPREGRET2_GPREGRET_Msk (0xFFUL << POWER_GPREGRET2_GPREGRET_Pos) /*!< Bit mask of GPREGRET field. */ + +/* Register: POWER_DCDCEN */ +/* Description: Enable DC/DC converter for REG1 stage. */ + +/* Bit 0 : Enable DC/DC converter for REG1 stage. */ +#define POWER_DCDCEN_DCDCEN_Pos (0UL) /*!< Position of DCDCEN field. */ +#define POWER_DCDCEN_DCDCEN_Msk (0x1UL << POWER_DCDCEN_DCDCEN_Pos) /*!< Bit mask of DCDCEN field. */ +#define POWER_DCDCEN_DCDCEN_Disabled (0UL) /*!< Disable */ +#define POWER_DCDCEN_DCDCEN_Enabled (1UL) /*!< Enable */ + +/* Register: POWER_DCDCEN0 */ +/* Description: Enable DC/DC converter for REG0 stage. */ + +/* Bit 0 : Enable DC/DC converter for REG0 stage. */ +#define POWER_DCDCEN0_DCDCEN_Pos (0UL) /*!< Position of DCDCEN field. */ +#define POWER_DCDCEN0_DCDCEN_Msk (0x1UL << POWER_DCDCEN0_DCDCEN_Pos) /*!< Bit mask of DCDCEN field. */ +#define POWER_DCDCEN0_DCDCEN_Disabled (0UL) /*!< Disable */ +#define POWER_DCDCEN0_DCDCEN_Enabled (1UL) /*!< Enable */ + +/* Register: POWER_MAINREGSTATUS */ +/* Description: Main supply status */ + +/* Bit 0 : Main supply status */ +#define POWER_MAINREGSTATUS_MAINREGSTATUS_Pos (0UL) /*!< Position of MAINREGSTATUS field. */ +#define POWER_MAINREGSTATUS_MAINREGSTATUS_Msk (0x1UL << POWER_MAINREGSTATUS_MAINREGSTATUS_Pos) /*!< Bit mask of MAINREGSTATUS field. */ +#define POWER_MAINREGSTATUS_MAINREGSTATUS_Normal (0UL) /*!< Normal voltage mode. Voltage supplied on VDD. */ +#define POWER_MAINREGSTATUS_MAINREGSTATUS_High (1UL) /*!< High voltage mode. Voltage supplied on VDDH. */ + +/* Register: POWER_RAM_POWER */ +/* Description: Description cluster[0]: RAM0 power control register */ + +/* Bit 31 : Keep retention on RAM section S15 when RAM section is in OFF */ +#define POWER_RAM_POWER_S15RETENTION_Pos (31UL) /*!< Position of S15RETENTION field. */ +#define POWER_RAM_POWER_S15RETENTION_Msk (0x1UL << POWER_RAM_POWER_S15RETENTION_Pos) /*!< Bit mask of S15RETENTION field. */ +#define POWER_RAM_POWER_S15RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S15RETENTION_On (1UL) /*!< On */ + +/* Bit 30 : Keep retention on RAM section S14 when RAM section is in OFF */ +#define POWER_RAM_POWER_S14RETENTION_Pos (30UL) /*!< Position of S14RETENTION field. */ +#define POWER_RAM_POWER_S14RETENTION_Msk (0x1UL << POWER_RAM_POWER_S14RETENTION_Pos) /*!< Bit mask of S14RETENTION field. */ +#define POWER_RAM_POWER_S14RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S14RETENTION_On (1UL) /*!< On */ + +/* Bit 29 : Keep retention on RAM section S13 when RAM section is in OFF */ +#define POWER_RAM_POWER_S13RETENTION_Pos (29UL) /*!< Position of S13RETENTION field. */ +#define POWER_RAM_POWER_S13RETENTION_Msk (0x1UL << POWER_RAM_POWER_S13RETENTION_Pos) /*!< Bit mask of S13RETENTION field. */ +#define POWER_RAM_POWER_S13RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S13RETENTION_On (1UL) /*!< On */ + +/* Bit 28 : Keep retention on RAM section S12 when RAM section is in OFF */ +#define POWER_RAM_POWER_S12RETENTION_Pos (28UL) /*!< Position of S12RETENTION field. */ +#define POWER_RAM_POWER_S12RETENTION_Msk (0x1UL << POWER_RAM_POWER_S12RETENTION_Pos) /*!< Bit mask of S12RETENTION field. */ +#define POWER_RAM_POWER_S12RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S12RETENTION_On (1UL) /*!< On */ + +/* Bit 27 : Keep retention on RAM section S11 when RAM section is in OFF */ +#define POWER_RAM_POWER_S11RETENTION_Pos (27UL) /*!< Position of S11RETENTION field. */ +#define POWER_RAM_POWER_S11RETENTION_Msk (0x1UL << POWER_RAM_POWER_S11RETENTION_Pos) /*!< Bit mask of S11RETENTION field. */ +#define POWER_RAM_POWER_S11RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S11RETENTION_On (1UL) /*!< On */ + +/* Bit 26 : Keep retention on RAM section S10 when RAM section is in OFF */ +#define POWER_RAM_POWER_S10RETENTION_Pos (26UL) /*!< Position of S10RETENTION field. */ +#define POWER_RAM_POWER_S10RETENTION_Msk (0x1UL << POWER_RAM_POWER_S10RETENTION_Pos) /*!< Bit mask of S10RETENTION field. */ +#define POWER_RAM_POWER_S10RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S10RETENTION_On (1UL) /*!< On */ + +/* Bit 25 : Keep retention on RAM section S9 when RAM section is in OFF */ +#define POWER_RAM_POWER_S9RETENTION_Pos (25UL) /*!< Position of S9RETENTION field. */ +#define POWER_RAM_POWER_S9RETENTION_Msk (0x1UL << POWER_RAM_POWER_S9RETENTION_Pos) /*!< Bit mask of S9RETENTION field. */ +#define POWER_RAM_POWER_S9RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S9RETENTION_On (1UL) /*!< On */ + +/* Bit 24 : Keep retention on RAM section S8 when RAM section is in OFF */ +#define POWER_RAM_POWER_S8RETENTION_Pos (24UL) /*!< Position of S8RETENTION field. */ +#define POWER_RAM_POWER_S8RETENTION_Msk (0x1UL << POWER_RAM_POWER_S8RETENTION_Pos) /*!< Bit mask of S8RETENTION field. */ +#define POWER_RAM_POWER_S8RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S8RETENTION_On (1UL) /*!< On */ + +/* Bit 23 : Keep retention on RAM section S7 when RAM section is in OFF */ +#define POWER_RAM_POWER_S7RETENTION_Pos (23UL) /*!< Position of S7RETENTION field. */ +#define POWER_RAM_POWER_S7RETENTION_Msk (0x1UL << POWER_RAM_POWER_S7RETENTION_Pos) /*!< Bit mask of S7RETENTION field. */ +#define POWER_RAM_POWER_S7RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S7RETENTION_On (1UL) /*!< On */ + +/* Bit 22 : Keep retention on RAM section S6 when RAM section is in OFF */ +#define POWER_RAM_POWER_S6RETENTION_Pos (22UL) /*!< Position of S6RETENTION field. */ +#define POWER_RAM_POWER_S6RETENTION_Msk (0x1UL << POWER_RAM_POWER_S6RETENTION_Pos) /*!< Bit mask of S6RETENTION field. */ +#define POWER_RAM_POWER_S6RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S6RETENTION_On (1UL) /*!< On */ + +/* Bit 21 : Keep retention on RAM section S5 when RAM section is in OFF */ +#define POWER_RAM_POWER_S5RETENTION_Pos (21UL) /*!< Position of S5RETENTION field. */ +#define POWER_RAM_POWER_S5RETENTION_Msk (0x1UL << POWER_RAM_POWER_S5RETENTION_Pos) /*!< Bit mask of S5RETENTION field. */ +#define POWER_RAM_POWER_S5RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S5RETENTION_On (1UL) /*!< On */ + +/* Bit 20 : Keep retention on RAM section S4 when RAM section is in OFF */ +#define POWER_RAM_POWER_S4RETENTION_Pos (20UL) /*!< Position of S4RETENTION field. */ +#define POWER_RAM_POWER_S4RETENTION_Msk (0x1UL << POWER_RAM_POWER_S4RETENTION_Pos) /*!< Bit mask of S4RETENTION field. */ +#define POWER_RAM_POWER_S4RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S4RETENTION_On (1UL) /*!< On */ + +/* Bit 19 : Keep retention on RAM section S3 when RAM section is in OFF */ +#define POWER_RAM_POWER_S3RETENTION_Pos (19UL) /*!< Position of S3RETENTION field. */ +#define POWER_RAM_POWER_S3RETENTION_Msk (0x1UL << POWER_RAM_POWER_S3RETENTION_Pos) /*!< Bit mask of S3RETENTION field. */ +#define POWER_RAM_POWER_S3RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S3RETENTION_On (1UL) /*!< On */ + +/* Bit 18 : Keep retention on RAM section S2 when RAM section is in OFF */ +#define POWER_RAM_POWER_S2RETENTION_Pos (18UL) /*!< Position of S2RETENTION field. */ +#define POWER_RAM_POWER_S2RETENTION_Msk (0x1UL << POWER_RAM_POWER_S2RETENTION_Pos) /*!< Bit mask of S2RETENTION field. */ +#define POWER_RAM_POWER_S2RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S2RETENTION_On (1UL) /*!< On */ + +/* Bit 17 : Keep retention on RAM section S1 when RAM section is in OFF */ +#define POWER_RAM_POWER_S1RETENTION_Pos (17UL) /*!< Position of S1RETENTION field. */ +#define POWER_RAM_POWER_S1RETENTION_Msk (0x1UL << POWER_RAM_POWER_S1RETENTION_Pos) /*!< Bit mask of S1RETENTION field. */ +#define POWER_RAM_POWER_S1RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S1RETENTION_On (1UL) /*!< On */ + +/* Bit 16 : Keep retention on RAM section S0 when RAM section is in OFF */ +#define POWER_RAM_POWER_S0RETENTION_Pos (16UL) /*!< Position of S0RETENTION field. */ +#define POWER_RAM_POWER_S0RETENTION_Msk (0x1UL << POWER_RAM_POWER_S0RETENTION_Pos) /*!< Bit mask of S0RETENTION field. */ +#define POWER_RAM_POWER_S0RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S0RETENTION_On (1UL) /*!< On */ + +/* Bit 15 : Keep RAM section S15 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S15POWER_Pos (15UL) /*!< Position of S15POWER field. */ +#define POWER_RAM_POWER_S15POWER_Msk (0x1UL << POWER_RAM_POWER_S15POWER_Pos) /*!< Bit mask of S15POWER field. */ +#define POWER_RAM_POWER_S15POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S15POWER_On (1UL) /*!< On */ + +/* Bit 14 : Keep RAM section S14 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S14POWER_Pos (14UL) /*!< Position of S14POWER field. */ +#define POWER_RAM_POWER_S14POWER_Msk (0x1UL << POWER_RAM_POWER_S14POWER_Pos) /*!< Bit mask of S14POWER field. */ +#define POWER_RAM_POWER_S14POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S14POWER_On (1UL) /*!< On */ + +/* Bit 13 : Keep RAM section S13 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S13POWER_Pos (13UL) /*!< Position of S13POWER field. */ +#define POWER_RAM_POWER_S13POWER_Msk (0x1UL << POWER_RAM_POWER_S13POWER_Pos) /*!< Bit mask of S13POWER field. */ +#define POWER_RAM_POWER_S13POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S13POWER_On (1UL) /*!< On */ + +/* Bit 12 : Keep RAM section S12 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S12POWER_Pos (12UL) /*!< Position of S12POWER field. */ +#define POWER_RAM_POWER_S12POWER_Msk (0x1UL << POWER_RAM_POWER_S12POWER_Pos) /*!< Bit mask of S12POWER field. */ +#define POWER_RAM_POWER_S12POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S12POWER_On (1UL) /*!< On */ + +/* Bit 11 : Keep RAM section S11 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S11POWER_Pos (11UL) /*!< Position of S11POWER field. */ +#define POWER_RAM_POWER_S11POWER_Msk (0x1UL << POWER_RAM_POWER_S11POWER_Pos) /*!< Bit mask of S11POWER field. */ +#define POWER_RAM_POWER_S11POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S11POWER_On (1UL) /*!< On */ + +/* Bit 10 : Keep RAM section S10 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S10POWER_Pos (10UL) /*!< Position of S10POWER field. */ +#define POWER_RAM_POWER_S10POWER_Msk (0x1UL << POWER_RAM_POWER_S10POWER_Pos) /*!< Bit mask of S10POWER field. */ +#define POWER_RAM_POWER_S10POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S10POWER_On (1UL) /*!< On */ + +/* Bit 9 : Keep RAM section S9 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S9POWER_Pos (9UL) /*!< Position of S9POWER field. */ +#define POWER_RAM_POWER_S9POWER_Msk (0x1UL << POWER_RAM_POWER_S9POWER_Pos) /*!< Bit mask of S9POWER field. */ +#define POWER_RAM_POWER_S9POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S9POWER_On (1UL) /*!< On */ + +/* Bit 8 : Keep RAM section S8 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S8POWER_Pos (8UL) /*!< Position of S8POWER field. */ +#define POWER_RAM_POWER_S8POWER_Msk (0x1UL << POWER_RAM_POWER_S8POWER_Pos) /*!< Bit mask of S8POWER field. */ +#define POWER_RAM_POWER_S8POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S8POWER_On (1UL) /*!< On */ + +/* Bit 7 : Keep RAM section S7 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S7POWER_Pos (7UL) /*!< Position of S7POWER field. */ +#define POWER_RAM_POWER_S7POWER_Msk (0x1UL << POWER_RAM_POWER_S7POWER_Pos) /*!< Bit mask of S7POWER field. */ +#define POWER_RAM_POWER_S7POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S7POWER_On (1UL) /*!< On */ + +/* Bit 6 : Keep RAM section S6 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S6POWER_Pos (6UL) /*!< Position of S6POWER field. */ +#define POWER_RAM_POWER_S6POWER_Msk (0x1UL << POWER_RAM_POWER_S6POWER_Pos) /*!< Bit mask of S6POWER field. */ +#define POWER_RAM_POWER_S6POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S6POWER_On (1UL) /*!< On */ + +/* Bit 5 : Keep RAM section S5 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S5POWER_Pos (5UL) /*!< Position of S5POWER field. */ +#define POWER_RAM_POWER_S5POWER_Msk (0x1UL << POWER_RAM_POWER_S5POWER_Pos) /*!< Bit mask of S5POWER field. */ +#define POWER_RAM_POWER_S5POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S5POWER_On (1UL) /*!< On */ + +/* Bit 4 : Keep RAM section S4 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S4POWER_Pos (4UL) /*!< Position of S4POWER field. */ +#define POWER_RAM_POWER_S4POWER_Msk (0x1UL << POWER_RAM_POWER_S4POWER_Pos) /*!< Bit mask of S4POWER field. */ +#define POWER_RAM_POWER_S4POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S4POWER_On (1UL) /*!< On */ + +/* Bit 3 : Keep RAM section S3 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S3POWER_Pos (3UL) /*!< Position of S3POWER field. */ +#define POWER_RAM_POWER_S3POWER_Msk (0x1UL << POWER_RAM_POWER_S3POWER_Pos) /*!< Bit mask of S3POWER field. */ +#define POWER_RAM_POWER_S3POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S3POWER_On (1UL) /*!< On */ + +/* Bit 2 : Keep RAM section S2 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S2POWER_Pos (2UL) /*!< Position of S2POWER field. */ +#define POWER_RAM_POWER_S2POWER_Msk (0x1UL << POWER_RAM_POWER_S2POWER_Pos) /*!< Bit mask of S2POWER field. */ +#define POWER_RAM_POWER_S2POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S2POWER_On (1UL) /*!< On */ + +/* Bit 1 : Keep RAM section S1 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S1POWER_Pos (1UL) /*!< Position of S1POWER field. */ +#define POWER_RAM_POWER_S1POWER_Msk (0x1UL << POWER_RAM_POWER_S1POWER_Pos) /*!< Bit mask of S1POWER field. */ +#define POWER_RAM_POWER_S1POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S1POWER_On (1UL) /*!< On */ + +/* Bit 0 : Keep RAM section S0 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S0POWER_Pos (0UL) /*!< Position of S0POWER field. */ +#define POWER_RAM_POWER_S0POWER_Msk (0x1UL << POWER_RAM_POWER_S0POWER_Pos) /*!< Bit mask of S0POWER field. */ +#define POWER_RAM_POWER_S0POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S0POWER_On (1UL) /*!< On */ + +/* Register: POWER_RAM_POWERSET */ +/* Description: Description cluster[0]: RAM0 power control set register */ + +/* Bit 31 : Keep retention on RAM section S15 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S15RETENTION_Pos (31UL) /*!< Position of S15RETENTION field. */ +#define POWER_RAM_POWERSET_S15RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S15RETENTION_Pos) /*!< Bit mask of S15RETENTION field. */ +#define POWER_RAM_POWERSET_S15RETENTION_On (1UL) /*!< On */ + +/* Bit 30 : Keep retention on RAM section S14 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S14RETENTION_Pos (30UL) /*!< Position of S14RETENTION field. */ +#define POWER_RAM_POWERSET_S14RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S14RETENTION_Pos) /*!< Bit mask of S14RETENTION field. */ +#define POWER_RAM_POWERSET_S14RETENTION_On (1UL) /*!< On */ + +/* Bit 29 : Keep retention on RAM section S13 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S13RETENTION_Pos (29UL) /*!< Position of S13RETENTION field. */ +#define POWER_RAM_POWERSET_S13RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S13RETENTION_Pos) /*!< Bit mask of S13RETENTION field. */ +#define POWER_RAM_POWERSET_S13RETENTION_On (1UL) /*!< On */ + +/* Bit 28 : Keep retention on RAM section S12 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S12RETENTION_Pos (28UL) /*!< Position of S12RETENTION field. */ +#define POWER_RAM_POWERSET_S12RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S12RETENTION_Pos) /*!< Bit mask of S12RETENTION field. */ +#define POWER_RAM_POWERSET_S12RETENTION_On (1UL) /*!< On */ + +/* Bit 27 : Keep retention on RAM section S11 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S11RETENTION_Pos (27UL) /*!< Position of S11RETENTION field. */ +#define POWER_RAM_POWERSET_S11RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S11RETENTION_Pos) /*!< Bit mask of S11RETENTION field. */ +#define POWER_RAM_POWERSET_S11RETENTION_On (1UL) /*!< On */ + +/* Bit 26 : Keep retention on RAM section S10 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S10RETENTION_Pos (26UL) /*!< Position of S10RETENTION field. */ +#define POWER_RAM_POWERSET_S10RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S10RETENTION_Pos) /*!< Bit mask of S10RETENTION field. */ +#define POWER_RAM_POWERSET_S10RETENTION_On (1UL) /*!< On */ + +/* Bit 25 : Keep retention on RAM section S9 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S9RETENTION_Pos (25UL) /*!< Position of S9RETENTION field. */ +#define POWER_RAM_POWERSET_S9RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S9RETENTION_Pos) /*!< Bit mask of S9RETENTION field. */ +#define POWER_RAM_POWERSET_S9RETENTION_On (1UL) /*!< On */ + +/* Bit 24 : Keep retention on RAM section S8 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S8RETENTION_Pos (24UL) /*!< Position of S8RETENTION field. */ +#define POWER_RAM_POWERSET_S8RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S8RETENTION_Pos) /*!< Bit mask of S8RETENTION field. */ +#define POWER_RAM_POWERSET_S8RETENTION_On (1UL) /*!< On */ + +/* Bit 23 : Keep retention on RAM section S7 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S7RETENTION_Pos (23UL) /*!< Position of S7RETENTION field. */ +#define POWER_RAM_POWERSET_S7RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S7RETENTION_Pos) /*!< Bit mask of S7RETENTION field. */ +#define POWER_RAM_POWERSET_S7RETENTION_On (1UL) /*!< On */ + +/* Bit 22 : Keep retention on RAM section S6 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S6RETENTION_Pos (22UL) /*!< Position of S6RETENTION field. */ +#define POWER_RAM_POWERSET_S6RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S6RETENTION_Pos) /*!< Bit mask of S6RETENTION field. */ +#define POWER_RAM_POWERSET_S6RETENTION_On (1UL) /*!< On */ + +/* Bit 21 : Keep retention on RAM section S5 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S5RETENTION_Pos (21UL) /*!< Position of S5RETENTION field. */ +#define POWER_RAM_POWERSET_S5RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S5RETENTION_Pos) /*!< Bit mask of S5RETENTION field. */ +#define POWER_RAM_POWERSET_S5RETENTION_On (1UL) /*!< On */ + +/* Bit 20 : Keep retention on RAM section S4 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S4RETENTION_Pos (20UL) /*!< Position of S4RETENTION field. */ +#define POWER_RAM_POWERSET_S4RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S4RETENTION_Pos) /*!< Bit mask of S4RETENTION field. */ +#define POWER_RAM_POWERSET_S4RETENTION_On (1UL) /*!< On */ + +/* Bit 19 : Keep retention on RAM section S3 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S3RETENTION_Pos (19UL) /*!< Position of S3RETENTION field. */ +#define POWER_RAM_POWERSET_S3RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S3RETENTION_Pos) /*!< Bit mask of S3RETENTION field. */ +#define POWER_RAM_POWERSET_S3RETENTION_On (1UL) /*!< On */ + +/* Bit 18 : Keep retention on RAM section S2 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S2RETENTION_Pos (18UL) /*!< Position of S2RETENTION field. */ +#define POWER_RAM_POWERSET_S2RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S2RETENTION_Pos) /*!< Bit mask of S2RETENTION field. */ +#define POWER_RAM_POWERSET_S2RETENTION_On (1UL) /*!< On */ + +/* Bit 17 : Keep retention on RAM section S1 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S1RETENTION_Pos (17UL) /*!< Position of S1RETENTION field. */ +#define POWER_RAM_POWERSET_S1RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S1RETENTION_Pos) /*!< Bit mask of S1RETENTION field. */ +#define POWER_RAM_POWERSET_S1RETENTION_On (1UL) /*!< On */ + +/* Bit 16 : Keep retention on RAM section S0 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S0RETENTION_Pos (16UL) /*!< Position of S0RETENTION field. */ +#define POWER_RAM_POWERSET_S0RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S0RETENTION_Pos) /*!< Bit mask of S0RETENTION field. */ +#define POWER_RAM_POWERSET_S0RETENTION_On (1UL) /*!< On */ + +/* Bit 15 : Keep RAM section S15 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S15POWER_Pos (15UL) /*!< Position of S15POWER field. */ +#define POWER_RAM_POWERSET_S15POWER_Msk (0x1UL << POWER_RAM_POWERSET_S15POWER_Pos) /*!< Bit mask of S15POWER field. */ +#define POWER_RAM_POWERSET_S15POWER_On (1UL) /*!< On */ + +/* Bit 14 : Keep RAM section S14 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S14POWER_Pos (14UL) /*!< Position of S14POWER field. */ +#define POWER_RAM_POWERSET_S14POWER_Msk (0x1UL << POWER_RAM_POWERSET_S14POWER_Pos) /*!< Bit mask of S14POWER field. */ +#define POWER_RAM_POWERSET_S14POWER_On (1UL) /*!< On */ + +/* Bit 13 : Keep RAM section S13 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S13POWER_Pos (13UL) /*!< Position of S13POWER field. */ +#define POWER_RAM_POWERSET_S13POWER_Msk (0x1UL << POWER_RAM_POWERSET_S13POWER_Pos) /*!< Bit mask of S13POWER field. */ +#define POWER_RAM_POWERSET_S13POWER_On (1UL) /*!< On */ + +/* Bit 12 : Keep RAM section S12 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S12POWER_Pos (12UL) /*!< Position of S12POWER field. */ +#define POWER_RAM_POWERSET_S12POWER_Msk (0x1UL << POWER_RAM_POWERSET_S12POWER_Pos) /*!< Bit mask of S12POWER field. */ +#define POWER_RAM_POWERSET_S12POWER_On (1UL) /*!< On */ + +/* Bit 11 : Keep RAM section S11 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S11POWER_Pos (11UL) /*!< Position of S11POWER field. */ +#define POWER_RAM_POWERSET_S11POWER_Msk (0x1UL << POWER_RAM_POWERSET_S11POWER_Pos) /*!< Bit mask of S11POWER field. */ +#define POWER_RAM_POWERSET_S11POWER_On (1UL) /*!< On */ + +/* Bit 10 : Keep RAM section S10 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S10POWER_Pos (10UL) /*!< Position of S10POWER field. */ +#define POWER_RAM_POWERSET_S10POWER_Msk (0x1UL << POWER_RAM_POWERSET_S10POWER_Pos) /*!< Bit mask of S10POWER field. */ +#define POWER_RAM_POWERSET_S10POWER_On (1UL) /*!< On */ + +/* Bit 9 : Keep RAM section S9 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S9POWER_Pos (9UL) /*!< Position of S9POWER field. */ +#define POWER_RAM_POWERSET_S9POWER_Msk (0x1UL << POWER_RAM_POWERSET_S9POWER_Pos) /*!< Bit mask of S9POWER field. */ +#define POWER_RAM_POWERSET_S9POWER_On (1UL) /*!< On */ + +/* Bit 8 : Keep RAM section S8 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S8POWER_Pos (8UL) /*!< Position of S8POWER field. */ +#define POWER_RAM_POWERSET_S8POWER_Msk (0x1UL << POWER_RAM_POWERSET_S8POWER_Pos) /*!< Bit mask of S8POWER field. */ +#define POWER_RAM_POWERSET_S8POWER_On (1UL) /*!< On */ + +/* Bit 7 : Keep RAM section S7 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S7POWER_Pos (7UL) /*!< Position of S7POWER field. */ +#define POWER_RAM_POWERSET_S7POWER_Msk (0x1UL << POWER_RAM_POWERSET_S7POWER_Pos) /*!< Bit mask of S7POWER field. */ +#define POWER_RAM_POWERSET_S7POWER_On (1UL) /*!< On */ + +/* Bit 6 : Keep RAM section S6 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S6POWER_Pos (6UL) /*!< Position of S6POWER field. */ +#define POWER_RAM_POWERSET_S6POWER_Msk (0x1UL << POWER_RAM_POWERSET_S6POWER_Pos) /*!< Bit mask of S6POWER field. */ +#define POWER_RAM_POWERSET_S6POWER_On (1UL) /*!< On */ + +/* Bit 5 : Keep RAM section S5 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S5POWER_Pos (5UL) /*!< Position of S5POWER field. */ +#define POWER_RAM_POWERSET_S5POWER_Msk (0x1UL << POWER_RAM_POWERSET_S5POWER_Pos) /*!< Bit mask of S5POWER field. */ +#define POWER_RAM_POWERSET_S5POWER_On (1UL) /*!< On */ + +/* Bit 4 : Keep RAM section S4 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S4POWER_Pos (4UL) /*!< Position of S4POWER field. */ +#define POWER_RAM_POWERSET_S4POWER_Msk (0x1UL << POWER_RAM_POWERSET_S4POWER_Pos) /*!< Bit mask of S4POWER field. */ +#define POWER_RAM_POWERSET_S4POWER_On (1UL) /*!< On */ + +/* Bit 3 : Keep RAM section S3 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S3POWER_Pos (3UL) /*!< Position of S3POWER field. */ +#define POWER_RAM_POWERSET_S3POWER_Msk (0x1UL << POWER_RAM_POWERSET_S3POWER_Pos) /*!< Bit mask of S3POWER field. */ +#define POWER_RAM_POWERSET_S3POWER_On (1UL) /*!< On */ + +/* Bit 2 : Keep RAM section S2 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S2POWER_Pos (2UL) /*!< Position of S2POWER field. */ +#define POWER_RAM_POWERSET_S2POWER_Msk (0x1UL << POWER_RAM_POWERSET_S2POWER_Pos) /*!< Bit mask of S2POWER field. */ +#define POWER_RAM_POWERSET_S2POWER_On (1UL) /*!< On */ + +/* Bit 1 : Keep RAM section S1 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S1POWER_Pos (1UL) /*!< Position of S1POWER field. */ +#define POWER_RAM_POWERSET_S1POWER_Msk (0x1UL << POWER_RAM_POWERSET_S1POWER_Pos) /*!< Bit mask of S1POWER field. */ +#define POWER_RAM_POWERSET_S1POWER_On (1UL) /*!< On */ + +/* Bit 0 : Keep RAM section S0 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S0POWER_Pos (0UL) /*!< Position of S0POWER field. */ +#define POWER_RAM_POWERSET_S0POWER_Msk (0x1UL << POWER_RAM_POWERSET_S0POWER_Pos) /*!< Bit mask of S0POWER field. */ +#define POWER_RAM_POWERSET_S0POWER_On (1UL) /*!< On */ + +/* Register: POWER_RAM_POWERCLR */ +/* Description: Description cluster[0]: RAM0 power control clear register */ + +/* Bit 31 : Keep retention on RAM section S15 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S15RETENTION_Pos (31UL) /*!< Position of S15RETENTION field. */ +#define POWER_RAM_POWERCLR_S15RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S15RETENTION_Pos) /*!< Bit mask of S15RETENTION field. */ +#define POWER_RAM_POWERCLR_S15RETENTION_Off (1UL) /*!< Off */ + +/* Bit 30 : Keep retention on RAM section S14 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S14RETENTION_Pos (30UL) /*!< Position of S14RETENTION field. */ +#define POWER_RAM_POWERCLR_S14RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S14RETENTION_Pos) /*!< Bit mask of S14RETENTION field. */ +#define POWER_RAM_POWERCLR_S14RETENTION_Off (1UL) /*!< Off */ + +/* Bit 29 : Keep retention on RAM section S13 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S13RETENTION_Pos (29UL) /*!< Position of S13RETENTION field. */ +#define POWER_RAM_POWERCLR_S13RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S13RETENTION_Pos) /*!< Bit mask of S13RETENTION field. */ +#define POWER_RAM_POWERCLR_S13RETENTION_Off (1UL) /*!< Off */ + +/* Bit 28 : Keep retention on RAM section S12 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S12RETENTION_Pos (28UL) /*!< Position of S12RETENTION field. */ +#define POWER_RAM_POWERCLR_S12RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S12RETENTION_Pos) /*!< Bit mask of S12RETENTION field. */ +#define POWER_RAM_POWERCLR_S12RETENTION_Off (1UL) /*!< Off */ + +/* Bit 27 : Keep retention on RAM section S11 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S11RETENTION_Pos (27UL) /*!< Position of S11RETENTION field. */ +#define POWER_RAM_POWERCLR_S11RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S11RETENTION_Pos) /*!< Bit mask of S11RETENTION field. */ +#define POWER_RAM_POWERCLR_S11RETENTION_Off (1UL) /*!< Off */ + +/* Bit 26 : Keep retention on RAM section S10 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S10RETENTION_Pos (26UL) /*!< Position of S10RETENTION field. */ +#define POWER_RAM_POWERCLR_S10RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S10RETENTION_Pos) /*!< Bit mask of S10RETENTION field. */ +#define POWER_RAM_POWERCLR_S10RETENTION_Off (1UL) /*!< Off */ + +/* Bit 25 : Keep retention on RAM section S9 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S9RETENTION_Pos (25UL) /*!< Position of S9RETENTION field. */ +#define POWER_RAM_POWERCLR_S9RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S9RETENTION_Pos) /*!< Bit mask of S9RETENTION field. */ +#define POWER_RAM_POWERCLR_S9RETENTION_Off (1UL) /*!< Off */ + +/* Bit 24 : Keep retention on RAM section S8 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S8RETENTION_Pos (24UL) /*!< Position of S8RETENTION field. */ +#define POWER_RAM_POWERCLR_S8RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S8RETENTION_Pos) /*!< Bit mask of S8RETENTION field. */ +#define POWER_RAM_POWERCLR_S8RETENTION_Off (1UL) /*!< Off */ + +/* Bit 23 : Keep retention on RAM section S7 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S7RETENTION_Pos (23UL) /*!< Position of S7RETENTION field. */ +#define POWER_RAM_POWERCLR_S7RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S7RETENTION_Pos) /*!< Bit mask of S7RETENTION field. */ +#define POWER_RAM_POWERCLR_S7RETENTION_Off (1UL) /*!< Off */ + +/* Bit 22 : Keep retention on RAM section S6 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S6RETENTION_Pos (22UL) /*!< Position of S6RETENTION field. */ +#define POWER_RAM_POWERCLR_S6RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S6RETENTION_Pos) /*!< Bit mask of S6RETENTION field. */ +#define POWER_RAM_POWERCLR_S6RETENTION_Off (1UL) /*!< Off */ + +/* Bit 21 : Keep retention on RAM section S5 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S5RETENTION_Pos (21UL) /*!< Position of S5RETENTION field. */ +#define POWER_RAM_POWERCLR_S5RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S5RETENTION_Pos) /*!< Bit mask of S5RETENTION field. */ +#define POWER_RAM_POWERCLR_S5RETENTION_Off (1UL) /*!< Off */ + +/* Bit 20 : Keep retention on RAM section S4 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S4RETENTION_Pos (20UL) /*!< Position of S4RETENTION field. */ +#define POWER_RAM_POWERCLR_S4RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S4RETENTION_Pos) /*!< Bit mask of S4RETENTION field. */ +#define POWER_RAM_POWERCLR_S4RETENTION_Off (1UL) /*!< Off */ + +/* Bit 19 : Keep retention on RAM section S3 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S3RETENTION_Pos (19UL) /*!< Position of S3RETENTION field. */ +#define POWER_RAM_POWERCLR_S3RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S3RETENTION_Pos) /*!< Bit mask of S3RETENTION field. */ +#define POWER_RAM_POWERCLR_S3RETENTION_Off (1UL) /*!< Off */ + +/* Bit 18 : Keep retention on RAM section S2 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S2RETENTION_Pos (18UL) /*!< Position of S2RETENTION field. */ +#define POWER_RAM_POWERCLR_S2RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S2RETENTION_Pos) /*!< Bit mask of S2RETENTION field. */ +#define POWER_RAM_POWERCLR_S2RETENTION_Off (1UL) /*!< Off */ + +/* Bit 17 : Keep retention on RAM section S1 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S1RETENTION_Pos (17UL) /*!< Position of S1RETENTION field. */ +#define POWER_RAM_POWERCLR_S1RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S1RETENTION_Pos) /*!< Bit mask of S1RETENTION field. */ +#define POWER_RAM_POWERCLR_S1RETENTION_Off (1UL) /*!< Off */ + +/* Bit 16 : Keep retention on RAM section S0 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S0RETENTION_Pos (16UL) /*!< Position of S0RETENTION field. */ +#define POWER_RAM_POWERCLR_S0RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S0RETENTION_Pos) /*!< Bit mask of S0RETENTION field. */ +#define POWER_RAM_POWERCLR_S0RETENTION_Off (1UL) /*!< Off */ + +/* Bit 15 : Keep RAM section S15 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S15POWER_Pos (15UL) /*!< Position of S15POWER field. */ +#define POWER_RAM_POWERCLR_S15POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S15POWER_Pos) /*!< Bit mask of S15POWER field. */ +#define POWER_RAM_POWERCLR_S15POWER_Off (1UL) /*!< Off */ + +/* Bit 14 : Keep RAM section S14 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S14POWER_Pos (14UL) /*!< Position of S14POWER field. */ +#define POWER_RAM_POWERCLR_S14POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S14POWER_Pos) /*!< Bit mask of S14POWER field. */ +#define POWER_RAM_POWERCLR_S14POWER_Off (1UL) /*!< Off */ + +/* Bit 13 : Keep RAM section S13 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S13POWER_Pos (13UL) /*!< Position of S13POWER field. */ +#define POWER_RAM_POWERCLR_S13POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S13POWER_Pos) /*!< Bit mask of S13POWER field. */ +#define POWER_RAM_POWERCLR_S13POWER_Off (1UL) /*!< Off */ + +/* Bit 12 : Keep RAM section S12 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S12POWER_Pos (12UL) /*!< Position of S12POWER field. */ +#define POWER_RAM_POWERCLR_S12POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S12POWER_Pos) /*!< Bit mask of S12POWER field. */ +#define POWER_RAM_POWERCLR_S12POWER_Off (1UL) /*!< Off */ + +/* Bit 11 : Keep RAM section S11 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S11POWER_Pos (11UL) /*!< Position of S11POWER field. */ +#define POWER_RAM_POWERCLR_S11POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S11POWER_Pos) /*!< Bit mask of S11POWER field. */ +#define POWER_RAM_POWERCLR_S11POWER_Off (1UL) /*!< Off */ + +/* Bit 10 : Keep RAM section S10 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S10POWER_Pos (10UL) /*!< Position of S10POWER field. */ +#define POWER_RAM_POWERCLR_S10POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S10POWER_Pos) /*!< Bit mask of S10POWER field. */ +#define POWER_RAM_POWERCLR_S10POWER_Off (1UL) /*!< Off */ + +/* Bit 9 : Keep RAM section S9 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S9POWER_Pos (9UL) /*!< Position of S9POWER field. */ +#define POWER_RAM_POWERCLR_S9POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S9POWER_Pos) /*!< Bit mask of S9POWER field. */ +#define POWER_RAM_POWERCLR_S9POWER_Off (1UL) /*!< Off */ + +/* Bit 8 : Keep RAM section S8 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S8POWER_Pos (8UL) /*!< Position of S8POWER field. */ +#define POWER_RAM_POWERCLR_S8POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S8POWER_Pos) /*!< Bit mask of S8POWER field. */ +#define POWER_RAM_POWERCLR_S8POWER_Off (1UL) /*!< Off */ + +/* Bit 7 : Keep RAM section S7 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S7POWER_Pos (7UL) /*!< Position of S7POWER field. */ +#define POWER_RAM_POWERCLR_S7POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S7POWER_Pos) /*!< Bit mask of S7POWER field. */ +#define POWER_RAM_POWERCLR_S7POWER_Off (1UL) /*!< Off */ + +/* Bit 6 : Keep RAM section S6 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S6POWER_Pos (6UL) /*!< Position of S6POWER field. */ +#define POWER_RAM_POWERCLR_S6POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S6POWER_Pos) /*!< Bit mask of S6POWER field. */ +#define POWER_RAM_POWERCLR_S6POWER_Off (1UL) /*!< Off */ + +/* Bit 5 : Keep RAM section S5 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S5POWER_Pos (5UL) /*!< Position of S5POWER field. */ +#define POWER_RAM_POWERCLR_S5POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S5POWER_Pos) /*!< Bit mask of S5POWER field. */ +#define POWER_RAM_POWERCLR_S5POWER_Off (1UL) /*!< Off */ + +/* Bit 4 : Keep RAM section S4 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S4POWER_Pos (4UL) /*!< Position of S4POWER field. */ +#define POWER_RAM_POWERCLR_S4POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S4POWER_Pos) /*!< Bit mask of S4POWER field. */ +#define POWER_RAM_POWERCLR_S4POWER_Off (1UL) /*!< Off */ + +/* Bit 3 : Keep RAM section S3 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S3POWER_Pos (3UL) /*!< Position of S3POWER field. */ +#define POWER_RAM_POWERCLR_S3POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S3POWER_Pos) /*!< Bit mask of S3POWER field. */ +#define POWER_RAM_POWERCLR_S3POWER_Off (1UL) /*!< Off */ + +/* Bit 2 : Keep RAM section S2 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S2POWER_Pos (2UL) /*!< Position of S2POWER field. */ +#define POWER_RAM_POWERCLR_S2POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S2POWER_Pos) /*!< Bit mask of S2POWER field. */ +#define POWER_RAM_POWERCLR_S2POWER_Off (1UL) /*!< Off */ + +/* Bit 1 : Keep RAM section S1 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S1POWER_Pos (1UL) /*!< Position of S1POWER field. */ +#define POWER_RAM_POWERCLR_S1POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S1POWER_Pos) /*!< Bit mask of S1POWER field. */ +#define POWER_RAM_POWERCLR_S1POWER_Off (1UL) /*!< Off */ + +/* Bit 0 : Keep RAM section S0 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S0POWER_Pos (0UL) /*!< Position of S0POWER field. */ +#define POWER_RAM_POWERCLR_S0POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S0POWER_Pos) /*!< Bit mask of S0POWER field. */ +#define POWER_RAM_POWERCLR_S0POWER_Off (1UL) /*!< Off */ + + +/* Peripheral: PPI */ +/* Description: Programmable Peripheral Interconnect */ + +/* Register: PPI_CHEN */ +/* Description: Channel enable register */ + +/* Bit 31 : Enable or disable channel 31 */ +#define PPI_CHEN_CH31_Pos (31UL) /*!< Position of CH31 field. */ +#define PPI_CHEN_CH31_Msk (0x1UL << PPI_CHEN_CH31_Pos) /*!< Bit mask of CH31 field. */ +#define PPI_CHEN_CH31_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH31_Enabled (1UL) /*!< Enable channel */ + +/* Bit 30 : Enable or disable channel 30 */ +#define PPI_CHEN_CH30_Pos (30UL) /*!< Position of CH30 field. */ +#define PPI_CHEN_CH30_Msk (0x1UL << PPI_CHEN_CH30_Pos) /*!< Bit mask of CH30 field. */ +#define PPI_CHEN_CH30_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH30_Enabled (1UL) /*!< Enable channel */ + +/* Bit 29 : Enable or disable channel 29 */ +#define PPI_CHEN_CH29_Pos (29UL) /*!< Position of CH29 field. */ +#define PPI_CHEN_CH29_Msk (0x1UL << PPI_CHEN_CH29_Pos) /*!< Bit mask of CH29 field. */ +#define PPI_CHEN_CH29_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH29_Enabled (1UL) /*!< Enable channel */ + +/* Bit 28 : Enable or disable channel 28 */ +#define PPI_CHEN_CH28_Pos (28UL) /*!< Position of CH28 field. */ +#define PPI_CHEN_CH28_Msk (0x1UL << PPI_CHEN_CH28_Pos) /*!< Bit mask of CH28 field. */ +#define PPI_CHEN_CH28_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH28_Enabled (1UL) /*!< Enable channel */ + +/* Bit 27 : Enable or disable channel 27 */ +#define PPI_CHEN_CH27_Pos (27UL) /*!< Position of CH27 field. */ +#define PPI_CHEN_CH27_Msk (0x1UL << PPI_CHEN_CH27_Pos) /*!< Bit mask of CH27 field. */ +#define PPI_CHEN_CH27_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH27_Enabled (1UL) /*!< Enable channel */ + +/* Bit 26 : Enable or disable channel 26 */ +#define PPI_CHEN_CH26_Pos (26UL) /*!< Position of CH26 field. */ +#define PPI_CHEN_CH26_Msk (0x1UL << PPI_CHEN_CH26_Pos) /*!< Bit mask of CH26 field. */ +#define PPI_CHEN_CH26_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH26_Enabled (1UL) /*!< Enable channel */ + +/* Bit 25 : Enable or disable channel 25 */ +#define PPI_CHEN_CH25_Pos (25UL) /*!< Position of CH25 field. */ +#define PPI_CHEN_CH25_Msk (0x1UL << PPI_CHEN_CH25_Pos) /*!< Bit mask of CH25 field. */ +#define PPI_CHEN_CH25_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH25_Enabled (1UL) /*!< Enable channel */ + +/* Bit 24 : Enable or disable channel 24 */ +#define PPI_CHEN_CH24_Pos (24UL) /*!< Position of CH24 field. */ +#define PPI_CHEN_CH24_Msk (0x1UL << PPI_CHEN_CH24_Pos) /*!< Bit mask of CH24 field. */ +#define PPI_CHEN_CH24_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH24_Enabled (1UL) /*!< Enable channel */ + +/* Bit 23 : Enable or disable channel 23 */ +#define PPI_CHEN_CH23_Pos (23UL) /*!< Position of CH23 field. */ +#define PPI_CHEN_CH23_Msk (0x1UL << PPI_CHEN_CH23_Pos) /*!< Bit mask of CH23 field. */ +#define PPI_CHEN_CH23_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH23_Enabled (1UL) /*!< Enable channel */ + +/* Bit 22 : Enable or disable channel 22 */ +#define PPI_CHEN_CH22_Pos (22UL) /*!< Position of CH22 field. */ +#define PPI_CHEN_CH22_Msk (0x1UL << PPI_CHEN_CH22_Pos) /*!< Bit mask of CH22 field. */ +#define PPI_CHEN_CH22_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH22_Enabled (1UL) /*!< Enable channel */ + +/* Bit 21 : Enable or disable channel 21 */ +#define PPI_CHEN_CH21_Pos (21UL) /*!< Position of CH21 field. */ +#define PPI_CHEN_CH21_Msk (0x1UL << PPI_CHEN_CH21_Pos) /*!< Bit mask of CH21 field. */ +#define PPI_CHEN_CH21_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH21_Enabled (1UL) /*!< Enable channel */ + +/* Bit 20 : Enable or disable channel 20 */ +#define PPI_CHEN_CH20_Pos (20UL) /*!< Position of CH20 field. */ +#define PPI_CHEN_CH20_Msk (0x1UL << PPI_CHEN_CH20_Pos) /*!< Bit mask of CH20 field. */ +#define PPI_CHEN_CH20_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH20_Enabled (1UL) /*!< Enable channel */ + +/* Bit 19 : Enable or disable channel 19 */ +#define PPI_CHEN_CH19_Pos (19UL) /*!< Position of CH19 field. */ +#define PPI_CHEN_CH19_Msk (0x1UL << PPI_CHEN_CH19_Pos) /*!< Bit mask of CH19 field. */ +#define PPI_CHEN_CH19_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH19_Enabled (1UL) /*!< Enable channel */ + +/* Bit 18 : Enable or disable channel 18 */ +#define PPI_CHEN_CH18_Pos (18UL) /*!< Position of CH18 field. */ +#define PPI_CHEN_CH18_Msk (0x1UL << PPI_CHEN_CH18_Pos) /*!< Bit mask of CH18 field. */ +#define PPI_CHEN_CH18_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH18_Enabled (1UL) /*!< Enable channel */ + +/* Bit 17 : Enable or disable channel 17 */ +#define PPI_CHEN_CH17_Pos (17UL) /*!< Position of CH17 field. */ +#define PPI_CHEN_CH17_Msk (0x1UL << PPI_CHEN_CH17_Pos) /*!< Bit mask of CH17 field. */ +#define PPI_CHEN_CH17_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH17_Enabled (1UL) /*!< Enable channel */ + +/* Bit 16 : Enable or disable channel 16 */ +#define PPI_CHEN_CH16_Pos (16UL) /*!< Position of CH16 field. */ +#define PPI_CHEN_CH16_Msk (0x1UL << PPI_CHEN_CH16_Pos) /*!< Bit mask of CH16 field. */ +#define PPI_CHEN_CH16_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH16_Enabled (1UL) /*!< Enable channel */ + +/* Bit 15 : Enable or disable channel 15 */ +#define PPI_CHEN_CH15_Pos (15UL) /*!< Position of CH15 field. */ +#define PPI_CHEN_CH15_Msk (0x1UL << PPI_CHEN_CH15_Pos) /*!< Bit mask of CH15 field. */ +#define PPI_CHEN_CH15_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH15_Enabled (1UL) /*!< Enable channel */ + +/* Bit 14 : Enable or disable channel 14 */ +#define PPI_CHEN_CH14_Pos (14UL) /*!< Position of CH14 field. */ +#define PPI_CHEN_CH14_Msk (0x1UL << PPI_CHEN_CH14_Pos) /*!< Bit mask of CH14 field. */ +#define PPI_CHEN_CH14_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH14_Enabled (1UL) /*!< Enable channel */ + +/* Bit 13 : Enable or disable channel 13 */ +#define PPI_CHEN_CH13_Pos (13UL) /*!< Position of CH13 field. */ +#define PPI_CHEN_CH13_Msk (0x1UL << PPI_CHEN_CH13_Pos) /*!< Bit mask of CH13 field. */ +#define PPI_CHEN_CH13_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH13_Enabled (1UL) /*!< Enable channel */ + +/* Bit 12 : Enable or disable channel 12 */ +#define PPI_CHEN_CH12_Pos (12UL) /*!< Position of CH12 field. */ +#define PPI_CHEN_CH12_Msk (0x1UL << PPI_CHEN_CH12_Pos) /*!< Bit mask of CH12 field. */ +#define PPI_CHEN_CH12_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH12_Enabled (1UL) /*!< Enable channel */ + +/* Bit 11 : Enable or disable channel 11 */ +#define PPI_CHEN_CH11_Pos (11UL) /*!< Position of CH11 field. */ +#define PPI_CHEN_CH11_Msk (0x1UL << PPI_CHEN_CH11_Pos) /*!< Bit mask of CH11 field. */ +#define PPI_CHEN_CH11_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH11_Enabled (1UL) /*!< Enable channel */ + +/* Bit 10 : Enable or disable channel 10 */ +#define PPI_CHEN_CH10_Pos (10UL) /*!< Position of CH10 field. */ +#define PPI_CHEN_CH10_Msk (0x1UL << PPI_CHEN_CH10_Pos) /*!< Bit mask of CH10 field. */ +#define PPI_CHEN_CH10_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH10_Enabled (1UL) /*!< Enable channel */ + +/* Bit 9 : Enable or disable channel 9 */ +#define PPI_CHEN_CH9_Pos (9UL) /*!< Position of CH9 field. */ +#define PPI_CHEN_CH9_Msk (0x1UL << PPI_CHEN_CH9_Pos) /*!< Bit mask of CH9 field. */ +#define PPI_CHEN_CH9_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH9_Enabled (1UL) /*!< Enable channel */ + +/* Bit 8 : Enable or disable channel 8 */ +#define PPI_CHEN_CH8_Pos (8UL) /*!< Position of CH8 field. */ +#define PPI_CHEN_CH8_Msk (0x1UL << PPI_CHEN_CH8_Pos) /*!< Bit mask of CH8 field. */ +#define PPI_CHEN_CH8_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH8_Enabled (1UL) /*!< Enable channel */ + +/* Bit 7 : Enable or disable channel 7 */ +#define PPI_CHEN_CH7_Pos (7UL) /*!< Position of CH7 field. */ +#define PPI_CHEN_CH7_Msk (0x1UL << PPI_CHEN_CH7_Pos) /*!< Bit mask of CH7 field. */ +#define PPI_CHEN_CH7_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH7_Enabled (1UL) /*!< Enable channel */ + +/* Bit 6 : Enable or disable channel 6 */ +#define PPI_CHEN_CH6_Pos (6UL) /*!< Position of CH6 field. */ +#define PPI_CHEN_CH6_Msk (0x1UL << PPI_CHEN_CH6_Pos) /*!< Bit mask of CH6 field. */ +#define PPI_CHEN_CH6_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH6_Enabled (1UL) /*!< Enable channel */ + +/* Bit 5 : Enable or disable channel 5 */ +#define PPI_CHEN_CH5_Pos (5UL) /*!< Position of CH5 field. */ +#define PPI_CHEN_CH5_Msk (0x1UL << PPI_CHEN_CH5_Pos) /*!< Bit mask of CH5 field. */ +#define PPI_CHEN_CH5_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH5_Enabled (1UL) /*!< Enable channel */ + +/* Bit 4 : Enable or disable channel 4 */ +#define PPI_CHEN_CH4_Pos (4UL) /*!< Position of CH4 field. */ +#define PPI_CHEN_CH4_Msk (0x1UL << PPI_CHEN_CH4_Pos) /*!< Bit mask of CH4 field. */ +#define PPI_CHEN_CH4_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH4_Enabled (1UL) /*!< Enable channel */ + +/* Bit 3 : Enable or disable channel 3 */ +#define PPI_CHEN_CH3_Pos (3UL) /*!< Position of CH3 field. */ +#define PPI_CHEN_CH3_Msk (0x1UL << PPI_CHEN_CH3_Pos) /*!< Bit mask of CH3 field. */ +#define PPI_CHEN_CH3_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH3_Enabled (1UL) /*!< Enable channel */ + +/* Bit 2 : Enable or disable channel 2 */ +#define PPI_CHEN_CH2_Pos (2UL) /*!< Position of CH2 field. */ +#define PPI_CHEN_CH2_Msk (0x1UL << PPI_CHEN_CH2_Pos) /*!< Bit mask of CH2 field. */ +#define PPI_CHEN_CH2_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH2_Enabled (1UL) /*!< Enable channel */ + +/* Bit 1 : Enable or disable channel 1 */ +#define PPI_CHEN_CH1_Pos (1UL) /*!< Position of CH1 field. */ +#define PPI_CHEN_CH1_Msk (0x1UL << PPI_CHEN_CH1_Pos) /*!< Bit mask of CH1 field. */ +#define PPI_CHEN_CH1_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH1_Enabled (1UL) /*!< Enable channel */ + +/* Bit 0 : Enable or disable channel 0 */ +#define PPI_CHEN_CH0_Pos (0UL) /*!< Position of CH0 field. */ +#define PPI_CHEN_CH0_Msk (0x1UL << PPI_CHEN_CH0_Pos) /*!< Bit mask of CH0 field. */ +#define PPI_CHEN_CH0_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH0_Enabled (1UL) /*!< Enable channel */ + +/* Register: PPI_CHENSET */ +/* Description: Channel enable set register */ + +/* Bit 31 : Channel 31 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH31_Pos (31UL) /*!< Position of CH31 field. */ +#define PPI_CHENSET_CH31_Msk (0x1UL << PPI_CHENSET_CH31_Pos) /*!< Bit mask of CH31 field. */ +#define PPI_CHENSET_CH31_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH31_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH31_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 30 : Channel 30 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH30_Pos (30UL) /*!< Position of CH30 field. */ +#define PPI_CHENSET_CH30_Msk (0x1UL << PPI_CHENSET_CH30_Pos) /*!< Bit mask of CH30 field. */ +#define PPI_CHENSET_CH30_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH30_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH30_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 29 : Channel 29 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH29_Pos (29UL) /*!< Position of CH29 field. */ +#define PPI_CHENSET_CH29_Msk (0x1UL << PPI_CHENSET_CH29_Pos) /*!< Bit mask of CH29 field. */ +#define PPI_CHENSET_CH29_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH29_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH29_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 28 : Channel 28 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH28_Pos (28UL) /*!< Position of CH28 field. */ +#define PPI_CHENSET_CH28_Msk (0x1UL << PPI_CHENSET_CH28_Pos) /*!< Bit mask of CH28 field. */ +#define PPI_CHENSET_CH28_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH28_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH28_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 27 : Channel 27 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH27_Pos (27UL) /*!< Position of CH27 field. */ +#define PPI_CHENSET_CH27_Msk (0x1UL << PPI_CHENSET_CH27_Pos) /*!< Bit mask of CH27 field. */ +#define PPI_CHENSET_CH27_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH27_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH27_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 26 : Channel 26 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH26_Pos (26UL) /*!< Position of CH26 field. */ +#define PPI_CHENSET_CH26_Msk (0x1UL << PPI_CHENSET_CH26_Pos) /*!< Bit mask of CH26 field. */ +#define PPI_CHENSET_CH26_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH26_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH26_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 25 : Channel 25 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH25_Pos (25UL) /*!< Position of CH25 field. */ +#define PPI_CHENSET_CH25_Msk (0x1UL << PPI_CHENSET_CH25_Pos) /*!< Bit mask of CH25 field. */ +#define PPI_CHENSET_CH25_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH25_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH25_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 24 : Channel 24 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH24_Pos (24UL) /*!< Position of CH24 field. */ +#define PPI_CHENSET_CH24_Msk (0x1UL << PPI_CHENSET_CH24_Pos) /*!< Bit mask of CH24 field. */ +#define PPI_CHENSET_CH24_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH24_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH24_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 23 : Channel 23 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH23_Pos (23UL) /*!< Position of CH23 field. */ +#define PPI_CHENSET_CH23_Msk (0x1UL << PPI_CHENSET_CH23_Pos) /*!< Bit mask of CH23 field. */ +#define PPI_CHENSET_CH23_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH23_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH23_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 22 : Channel 22 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH22_Pos (22UL) /*!< Position of CH22 field. */ +#define PPI_CHENSET_CH22_Msk (0x1UL << PPI_CHENSET_CH22_Pos) /*!< Bit mask of CH22 field. */ +#define PPI_CHENSET_CH22_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH22_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH22_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 21 : Channel 21 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH21_Pos (21UL) /*!< Position of CH21 field. */ +#define PPI_CHENSET_CH21_Msk (0x1UL << PPI_CHENSET_CH21_Pos) /*!< Bit mask of CH21 field. */ +#define PPI_CHENSET_CH21_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH21_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH21_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 20 : Channel 20 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH20_Pos (20UL) /*!< Position of CH20 field. */ +#define PPI_CHENSET_CH20_Msk (0x1UL << PPI_CHENSET_CH20_Pos) /*!< Bit mask of CH20 field. */ +#define PPI_CHENSET_CH20_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH20_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH20_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 19 : Channel 19 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH19_Pos (19UL) /*!< Position of CH19 field. */ +#define PPI_CHENSET_CH19_Msk (0x1UL << PPI_CHENSET_CH19_Pos) /*!< Bit mask of CH19 field. */ +#define PPI_CHENSET_CH19_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH19_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH19_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 18 : Channel 18 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH18_Pos (18UL) /*!< Position of CH18 field. */ +#define PPI_CHENSET_CH18_Msk (0x1UL << PPI_CHENSET_CH18_Pos) /*!< Bit mask of CH18 field. */ +#define PPI_CHENSET_CH18_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH18_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH18_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 17 : Channel 17 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH17_Pos (17UL) /*!< Position of CH17 field. */ +#define PPI_CHENSET_CH17_Msk (0x1UL << PPI_CHENSET_CH17_Pos) /*!< Bit mask of CH17 field. */ +#define PPI_CHENSET_CH17_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH17_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH17_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 16 : Channel 16 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH16_Pos (16UL) /*!< Position of CH16 field. */ +#define PPI_CHENSET_CH16_Msk (0x1UL << PPI_CHENSET_CH16_Pos) /*!< Bit mask of CH16 field. */ +#define PPI_CHENSET_CH16_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH16_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH16_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 15 : Channel 15 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH15_Pos (15UL) /*!< Position of CH15 field. */ +#define PPI_CHENSET_CH15_Msk (0x1UL << PPI_CHENSET_CH15_Pos) /*!< Bit mask of CH15 field. */ +#define PPI_CHENSET_CH15_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH15_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH15_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 14 : Channel 14 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH14_Pos (14UL) /*!< Position of CH14 field. */ +#define PPI_CHENSET_CH14_Msk (0x1UL << PPI_CHENSET_CH14_Pos) /*!< Bit mask of CH14 field. */ +#define PPI_CHENSET_CH14_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH14_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH14_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 13 : Channel 13 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH13_Pos (13UL) /*!< Position of CH13 field. */ +#define PPI_CHENSET_CH13_Msk (0x1UL << PPI_CHENSET_CH13_Pos) /*!< Bit mask of CH13 field. */ +#define PPI_CHENSET_CH13_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH13_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH13_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 12 : Channel 12 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH12_Pos (12UL) /*!< Position of CH12 field. */ +#define PPI_CHENSET_CH12_Msk (0x1UL << PPI_CHENSET_CH12_Pos) /*!< Bit mask of CH12 field. */ +#define PPI_CHENSET_CH12_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH12_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH12_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 11 : Channel 11 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH11_Pos (11UL) /*!< Position of CH11 field. */ +#define PPI_CHENSET_CH11_Msk (0x1UL << PPI_CHENSET_CH11_Pos) /*!< Bit mask of CH11 field. */ +#define PPI_CHENSET_CH11_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH11_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH11_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 10 : Channel 10 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH10_Pos (10UL) /*!< Position of CH10 field. */ +#define PPI_CHENSET_CH10_Msk (0x1UL << PPI_CHENSET_CH10_Pos) /*!< Bit mask of CH10 field. */ +#define PPI_CHENSET_CH10_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH10_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH10_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 9 : Channel 9 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH9_Pos (9UL) /*!< Position of CH9 field. */ +#define PPI_CHENSET_CH9_Msk (0x1UL << PPI_CHENSET_CH9_Pos) /*!< Bit mask of CH9 field. */ +#define PPI_CHENSET_CH9_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH9_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH9_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 8 : Channel 8 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH8_Pos (8UL) /*!< Position of CH8 field. */ +#define PPI_CHENSET_CH8_Msk (0x1UL << PPI_CHENSET_CH8_Pos) /*!< Bit mask of CH8 field. */ +#define PPI_CHENSET_CH8_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH8_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH8_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 7 : Channel 7 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH7_Pos (7UL) /*!< Position of CH7 field. */ +#define PPI_CHENSET_CH7_Msk (0x1UL << PPI_CHENSET_CH7_Pos) /*!< Bit mask of CH7 field. */ +#define PPI_CHENSET_CH7_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH7_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH7_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 6 : Channel 6 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH6_Pos (6UL) /*!< Position of CH6 field. */ +#define PPI_CHENSET_CH6_Msk (0x1UL << PPI_CHENSET_CH6_Pos) /*!< Bit mask of CH6 field. */ +#define PPI_CHENSET_CH6_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH6_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH6_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 5 : Channel 5 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH5_Pos (5UL) /*!< Position of CH5 field. */ +#define PPI_CHENSET_CH5_Msk (0x1UL << PPI_CHENSET_CH5_Pos) /*!< Bit mask of CH5 field. */ +#define PPI_CHENSET_CH5_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH5_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH5_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 4 : Channel 4 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH4_Pos (4UL) /*!< Position of CH4 field. */ +#define PPI_CHENSET_CH4_Msk (0x1UL << PPI_CHENSET_CH4_Pos) /*!< Bit mask of CH4 field. */ +#define PPI_CHENSET_CH4_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH4_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH4_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 3 : Channel 3 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH3_Pos (3UL) /*!< Position of CH3 field. */ +#define PPI_CHENSET_CH3_Msk (0x1UL << PPI_CHENSET_CH3_Pos) /*!< Bit mask of CH3 field. */ +#define PPI_CHENSET_CH3_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH3_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH3_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 2 : Channel 2 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH2_Pos (2UL) /*!< Position of CH2 field. */ +#define PPI_CHENSET_CH2_Msk (0x1UL << PPI_CHENSET_CH2_Pos) /*!< Bit mask of CH2 field. */ +#define PPI_CHENSET_CH2_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH2_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH2_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 1 : Channel 1 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH1_Pos (1UL) /*!< Position of CH1 field. */ +#define PPI_CHENSET_CH1_Msk (0x1UL << PPI_CHENSET_CH1_Pos) /*!< Bit mask of CH1 field. */ +#define PPI_CHENSET_CH1_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH1_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH1_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 0 : Channel 0 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH0_Pos (0UL) /*!< Position of CH0 field. */ +#define PPI_CHENSET_CH0_Msk (0x1UL << PPI_CHENSET_CH0_Pos) /*!< Bit mask of CH0 field. */ +#define PPI_CHENSET_CH0_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH0_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH0_Set (1UL) /*!< Write: Enable channel */ + +/* Register: PPI_CHENCLR */ +/* Description: Channel enable clear register */ + +/* Bit 31 : Channel 31 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH31_Pos (31UL) /*!< Position of CH31 field. */ +#define PPI_CHENCLR_CH31_Msk (0x1UL << PPI_CHENCLR_CH31_Pos) /*!< Bit mask of CH31 field. */ +#define PPI_CHENCLR_CH31_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH31_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH31_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 30 : Channel 30 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH30_Pos (30UL) /*!< Position of CH30 field. */ +#define PPI_CHENCLR_CH30_Msk (0x1UL << PPI_CHENCLR_CH30_Pos) /*!< Bit mask of CH30 field. */ +#define PPI_CHENCLR_CH30_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH30_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH30_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 29 : Channel 29 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH29_Pos (29UL) /*!< Position of CH29 field. */ +#define PPI_CHENCLR_CH29_Msk (0x1UL << PPI_CHENCLR_CH29_Pos) /*!< Bit mask of CH29 field. */ +#define PPI_CHENCLR_CH29_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH29_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH29_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 28 : Channel 28 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH28_Pos (28UL) /*!< Position of CH28 field. */ +#define PPI_CHENCLR_CH28_Msk (0x1UL << PPI_CHENCLR_CH28_Pos) /*!< Bit mask of CH28 field. */ +#define PPI_CHENCLR_CH28_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH28_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH28_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 27 : Channel 27 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH27_Pos (27UL) /*!< Position of CH27 field. */ +#define PPI_CHENCLR_CH27_Msk (0x1UL << PPI_CHENCLR_CH27_Pos) /*!< Bit mask of CH27 field. */ +#define PPI_CHENCLR_CH27_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH27_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH27_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 26 : Channel 26 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH26_Pos (26UL) /*!< Position of CH26 field. */ +#define PPI_CHENCLR_CH26_Msk (0x1UL << PPI_CHENCLR_CH26_Pos) /*!< Bit mask of CH26 field. */ +#define PPI_CHENCLR_CH26_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH26_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH26_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 25 : Channel 25 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH25_Pos (25UL) /*!< Position of CH25 field. */ +#define PPI_CHENCLR_CH25_Msk (0x1UL << PPI_CHENCLR_CH25_Pos) /*!< Bit mask of CH25 field. */ +#define PPI_CHENCLR_CH25_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH25_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH25_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 24 : Channel 24 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH24_Pos (24UL) /*!< Position of CH24 field. */ +#define PPI_CHENCLR_CH24_Msk (0x1UL << PPI_CHENCLR_CH24_Pos) /*!< Bit mask of CH24 field. */ +#define PPI_CHENCLR_CH24_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH24_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH24_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 23 : Channel 23 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH23_Pos (23UL) /*!< Position of CH23 field. */ +#define PPI_CHENCLR_CH23_Msk (0x1UL << PPI_CHENCLR_CH23_Pos) /*!< Bit mask of CH23 field. */ +#define PPI_CHENCLR_CH23_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH23_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH23_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 22 : Channel 22 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH22_Pos (22UL) /*!< Position of CH22 field. */ +#define PPI_CHENCLR_CH22_Msk (0x1UL << PPI_CHENCLR_CH22_Pos) /*!< Bit mask of CH22 field. */ +#define PPI_CHENCLR_CH22_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH22_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH22_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 21 : Channel 21 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH21_Pos (21UL) /*!< Position of CH21 field. */ +#define PPI_CHENCLR_CH21_Msk (0x1UL << PPI_CHENCLR_CH21_Pos) /*!< Bit mask of CH21 field. */ +#define PPI_CHENCLR_CH21_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH21_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH21_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 20 : Channel 20 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH20_Pos (20UL) /*!< Position of CH20 field. */ +#define PPI_CHENCLR_CH20_Msk (0x1UL << PPI_CHENCLR_CH20_Pos) /*!< Bit mask of CH20 field. */ +#define PPI_CHENCLR_CH20_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH20_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH20_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 19 : Channel 19 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH19_Pos (19UL) /*!< Position of CH19 field. */ +#define PPI_CHENCLR_CH19_Msk (0x1UL << PPI_CHENCLR_CH19_Pos) /*!< Bit mask of CH19 field. */ +#define PPI_CHENCLR_CH19_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH19_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH19_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 18 : Channel 18 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH18_Pos (18UL) /*!< Position of CH18 field. */ +#define PPI_CHENCLR_CH18_Msk (0x1UL << PPI_CHENCLR_CH18_Pos) /*!< Bit mask of CH18 field. */ +#define PPI_CHENCLR_CH18_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH18_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH18_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 17 : Channel 17 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH17_Pos (17UL) /*!< Position of CH17 field. */ +#define PPI_CHENCLR_CH17_Msk (0x1UL << PPI_CHENCLR_CH17_Pos) /*!< Bit mask of CH17 field. */ +#define PPI_CHENCLR_CH17_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH17_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH17_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 16 : Channel 16 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH16_Pos (16UL) /*!< Position of CH16 field. */ +#define PPI_CHENCLR_CH16_Msk (0x1UL << PPI_CHENCLR_CH16_Pos) /*!< Bit mask of CH16 field. */ +#define PPI_CHENCLR_CH16_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH16_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH16_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 15 : Channel 15 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH15_Pos (15UL) /*!< Position of CH15 field. */ +#define PPI_CHENCLR_CH15_Msk (0x1UL << PPI_CHENCLR_CH15_Pos) /*!< Bit mask of CH15 field. */ +#define PPI_CHENCLR_CH15_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH15_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH15_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 14 : Channel 14 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH14_Pos (14UL) /*!< Position of CH14 field. */ +#define PPI_CHENCLR_CH14_Msk (0x1UL << PPI_CHENCLR_CH14_Pos) /*!< Bit mask of CH14 field. */ +#define PPI_CHENCLR_CH14_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH14_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH14_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 13 : Channel 13 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH13_Pos (13UL) /*!< Position of CH13 field. */ +#define PPI_CHENCLR_CH13_Msk (0x1UL << PPI_CHENCLR_CH13_Pos) /*!< Bit mask of CH13 field. */ +#define PPI_CHENCLR_CH13_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH13_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH13_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 12 : Channel 12 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH12_Pos (12UL) /*!< Position of CH12 field. */ +#define PPI_CHENCLR_CH12_Msk (0x1UL << PPI_CHENCLR_CH12_Pos) /*!< Bit mask of CH12 field. */ +#define PPI_CHENCLR_CH12_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH12_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH12_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 11 : Channel 11 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH11_Pos (11UL) /*!< Position of CH11 field. */ +#define PPI_CHENCLR_CH11_Msk (0x1UL << PPI_CHENCLR_CH11_Pos) /*!< Bit mask of CH11 field. */ +#define PPI_CHENCLR_CH11_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH11_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH11_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 10 : Channel 10 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH10_Pos (10UL) /*!< Position of CH10 field. */ +#define PPI_CHENCLR_CH10_Msk (0x1UL << PPI_CHENCLR_CH10_Pos) /*!< Bit mask of CH10 field. */ +#define PPI_CHENCLR_CH10_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH10_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH10_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 9 : Channel 9 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH9_Pos (9UL) /*!< Position of CH9 field. */ +#define PPI_CHENCLR_CH9_Msk (0x1UL << PPI_CHENCLR_CH9_Pos) /*!< Bit mask of CH9 field. */ +#define PPI_CHENCLR_CH9_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH9_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH9_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 8 : Channel 8 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH8_Pos (8UL) /*!< Position of CH8 field. */ +#define PPI_CHENCLR_CH8_Msk (0x1UL << PPI_CHENCLR_CH8_Pos) /*!< Bit mask of CH8 field. */ +#define PPI_CHENCLR_CH8_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH8_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH8_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 7 : Channel 7 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH7_Pos (7UL) /*!< Position of CH7 field. */ +#define PPI_CHENCLR_CH7_Msk (0x1UL << PPI_CHENCLR_CH7_Pos) /*!< Bit mask of CH7 field. */ +#define PPI_CHENCLR_CH7_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH7_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH7_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 6 : Channel 6 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH6_Pos (6UL) /*!< Position of CH6 field. */ +#define PPI_CHENCLR_CH6_Msk (0x1UL << PPI_CHENCLR_CH6_Pos) /*!< Bit mask of CH6 field. */ +#define PPI_CHENCLR_CH6_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH6_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH6_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 5 : Channel 5 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH5_Pos (5UL) /*!< Position of CH5 field. */ +#define PPI_CHENCLR_CH5_Msk (0x1UL << PPI_CHENCLR_CH5_Pos) /*!< Bit mask of CH5 field. */ +#define PPI_CHENCLR_CH5_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH5_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH5_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 4 : Channel 4 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH4_Pos (4UL) /*!< Position of CH4 field. */ +#define PPI_CHENCLR_CH4_Msk (0x1UL << PPI_CHENCLR_CH4_Pos) /*!< Bit mask of CH4 field. */ +#define PPI_CHENCLR_CH4_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH4_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH4_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 3 : Channel 3 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH3_Pos (3UL) /*!< Position of CH3 field. */ +#define PPI_CHENCLR_CH3_Msk (0x1UL << PPI_CHENCLR_CH3_Pos) /*!< Bit mask of CH3 field. */ +#define PPI_CHENCLR_CH3_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH3_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH3_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 2 : Channel 2 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH2_Pos (2UL) /*!< Position of CH2 field. */ +#define PPI_CHENCLR_CH2_Msk (0x1UL << PPI_CHENCLR_CH2_Pos) /*!< Bit mask of CH2 field. */ +#define PPI_CHENCLR_CH2_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH2_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH2_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 1 : Channel 1 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH1_Pos (1UL) /*!< Position of CH1 field. */ +#define PPI_CHENCLR_CH1_Msk (0x1UL << PPI_CHENCLR_CH1_Pos) /*!< Bit mask of CH1 field. */ +#define PPI_CHENCLR_CH1_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH1_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH1_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 0 : Channel 0 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH0_Pos (0UL) /*!< Position of CH0 field. */ +#define PPI_CHENCLR_CH0_Msk (0x1UL << PPI_CHENCLR_CH0_Pos) /*!< Bit mask of CH0 field. */ +#define PPI_CHENCLR_CH0_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH0_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH0_Clear (1UL) /*!< Write: disable channel */ + +/* Register: PPI_CH_EEP */ +/* Description: Description cluster[0]: Channel 0 event end-point */ + +/* Bits 31..0 : Pointer to event register. Accepts only addresses to registers from the Event group. */ +#define PPI_CH_EEP_EEP_Pos (0UL) /*!< Position of EEP field. */ +#define PPI_CH_EEP_EEP_Msk (0xFFFFFFFFUL << PPI_CH_EEP_EEP_Pos) /*!< Bit mask of EEP field. */ + +/* Register: PPI_CH_TEP */ +/* Description: Description cluster[0]: Channel 0 task end-point */ + +/* Bits 31..0 : Pointer to task register. Accepts only addresses to registers from the Task group. */ +#define PPI_CH_TEP_TEP_Pos (0UL) /*!< Position of TEP field. */ +#define PPI_CH_TEP_TEP_Msk (0xFFFFFFFFUL << PPI_CH_TEP_TEP_Pos) /*!< Bit mask of TEP field. */ + +/* Register: PPI_CHG */ +/* Description: Description collection[0]: Channel group 0 */ + +/* Bit 31 : Include or exclude channel 31 */ +#define PPI_CHG_CH31_Pos (31UL) /*!< Position of CH31 field. */ +#define PPI_CHG_CH31_Msk (0x1UL << PPI_CHG_CH31_Pos) /*!< Bit mask of CH31 field. */ +#define PPI_CHG_CH31_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH31_Included (1UL) /*!< Include */ + +/* Bit 30 : Include or exclude channel 30 */ +#define PPI_CHG_CH30_Pos (30UL) /*!< Position of CH30 field. */ +#define PPI_CHG_CH30_Msk (0x1UL << PPI_CHG_CH30_Pos) /*!< Bit mask of CH30 field. */ +#define PPI_CHG_CH30_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH30_Included (1UL) /*!< Include */ + +/* Bit 29 : Include or exclude channel 29 */ +#define PPI_CHG_CH29_Pos (29UL) /*!< Position of CH29 field. */ +#define PPI_CHG_CH29_Msk (0x1UL << PPI_CHG_CH29_Pos) /*!< Bit mask of CH29 field. */ +#define PPI_CHG_CH29_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH29_Included (1UL) /*!< Include */ + +/* Bit 28 : Include or exclude channel 28 */ +#define PPI_CHG_CH28_Pos (28UL) /*!< Position of CH28 field. */ +#define PPI_CHG_CH28_Msk (0x1UL << PPI_CHG_CH28_Pos) /*!< Bit mask of CH28 field. */ +#define PPI_CHG_CH28_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH28_Included (1UL) /*!< Include */ + +/* Bit 27 : Include or exclude channel 27 */ +#define PPI_CHG_CH27_Pos (27UL) /*!< Position of CH27 field. */ +#define PPI_CHG_CH27_Msk (0x1UL << PPI_CHG_CH27_Pos) /*!< Bit mask of CH27 field. */ +#define PPI_CHG_CH27_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH27_Included (1UL) /*!< Include */ + +/* Bit 26 : Include or exclude channel 26 */ +#define PPI_CHG_CH26_Pos (26UL) /*!< Position of CH26 field. */ +#define PPI_CHG_CH26_Msk (0x1UL << PPI_CHG_CH26_Pos) /*!< Bit mask of CH26 field. */ +#define PPI_CHG_CH26_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH26_Included (1UL) /*!< Include */ + +/* Bit 25 : Include or exclude channel 25 */ +#define PPI_CHG_CH25_Pos (25UL) /*!< Position of CH25 field. */ +#define PPI_CHG_CH25_Msk (0x1UL << PPI_CHG_CH25_Pos) /*!< Bit mask of CH25 field. */ +#define PPI_CHG_CH25_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH25_Included (1UL) /*!< Include */ + +/* Bit 24 : Include or exclude channel 24 */ +#define PPI_CHG_CH24_Pos (24UL) /*!< Position of CH24 field. */ +#define PPI_CHG_CH24_Msk (0x1UL << PPI_CHG_CH24_Pos) /*!< Bit mask of CH24 field. */ +#define PPI_CHG_CH24_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH24_Included (1UL) /*!< Include */ + +/* Bit 23 : Include or exclude channel 23 */ +#define PPI_CHG_CH23_Pos (23UL) /*!< Position of CH23 field. */ +#define PPI_CHG_CH23_Msk (0x1UL << PPI_CHG_CH23_Pos) /*!< Bit mask of CH23 field. */ +#define PPI_CHG_CH23_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH23_Included (1UL) /*!< Include */ + +/* Bit 22 : Include or exclude channel 22 */ +#define PPI_CHG_CH22_Pos (22UL) /*!< Position of CH22 field. */ +#define PPI_CHG_CH22_Msk (0x1UL << PPI_CHG_CH22_Pos) /*!< Bit mask of CH22 field. */ +#define PPI_CHG_CH22_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH22_Included (1UL) /*!< Include */ + +/* Bit 21 : Include or exclude channel 21 */ +#define PPI_CHG_CH21_Pos (21UL) /*!< Position of CH21 field. */ +#define PPI_CHG_CH21_Msk (0x1UL << PPI_CHG_CH21_Pos) /*!< Bit mask of CH21 field. */ +#define PPI_CHG_CH21_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH21_Included (1UL) /*!< Include */ + +/* Bit 20 : Include or exclude channel 20 */ +#define PPI_CHG_CH20_Pos (20UL) /*!< Position of CH20 field. */ +#define PPI_CHG_CH20_Msk (0x1UL << PPI_CHG_CH20_Pos) /*!< Bit mask of CH20 field. */ +#define PPI_CHG_CH20_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH20_Included (1UL) /*!< Include */ + +/* Bit 19 : Include or exclude channel 19 */ +#define PPI_CHG_CH19_Pos (19UL) /*!< Position of CH19 field. */ +#define PPI_CHG_CH19_Msk (0x1UL << PPI_CHG_CH19_Pos) /*!< Bit mask of CH19 field. */ +#define PPI_CHG_CH19_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH19_Included (1UL) /*!< Include */ + +/* Bit 18 : Include or exclude channel 18 */ +#define PPI_CHG_CH18_Pos (18UL) /*!< Position of CH18 field. */ +#define PPI_CHG_CH18_Msk (0x1UL << PPI_CHG_CH18_Pos) /*!< Bit mask of CH18 field. */ +#define PPI_CHG_CH18_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH18_Included (1UL) /*!< Include */ + +/* Bit 17 : Include or exclude channel 17 */ +#define PPI_CHG_CH17_Pos (17UL) /*!< Position of CH17 field. */ +#define PPI_CHG_CH17_Msk (0x1UL << PPI_CHG_CH17_Pos) /*!< Bit mask of CH17 field. */ +#define PPI_CHG_CH17_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH17_Included (1UL) /*!< Include */ + +/* Bit 16 : Include or exclude channel 16 */ +#define PPI_CHG_CH16_Pos (16UL) /*!< Position of CH16 field. */ +#define PPI_CHG_CH16_Msk (0x1UL << PPI_CHG_CH16_Pos) /*!< Bit mask of CH16 field. */ +#define PPI_CHG_CH16_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH16_Included (1UL) /*!< Include */ + +/* Bit 15 : Include or exclude channel 15 */ +#define PPI_CHG_CH15_Pos (15UL) /*!< Position of CH15 field. */ +#define PPI_CHG_CH15_Msk (0x1UL << PPI_CHG_CH15_Pos) /*!< Bit mask of CH15 field. */ +#define PPI_CHG_CH15_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH15_Included (1UL) /*!< Include */ + +/* Bit 14 : Include or exclude channel 14 */ +#define PPI_CHG_CH14_Pos (14UL) /*!< Position of CH14 field. */ +#define PPI_CHG_CH14_Msk (0x1UL << PPI_CHG_CH14_Pos) /*!< Bit mask of CH14 field. */ +#define PPI_CHG_CH14_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH14_Included (1UL) /*!< Include */ + +/* Bit 13 : Include or exclude channel 13 */ +#define PPI_CHG_CH13_Pos (13UL) /*!< Position of CH13 field. */ +#define PPI_CHG_CH13_Msk (0x1UL << PPI_CHG_CH13_Pos) /*!< Bit mask of CH13 field. */ +#define PPI_CHG_CH13_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH13_Included (1UL) /*!< Include */ + +/* Bit 12 : Include or exclude channel 12 */ +#define PPI_CHG_CH12_Pos (12UL) /*!< Position of CH12 field. */ +#define PPI_CHG_CH12_Msk (0x1UL << PPI_CHG_CH12_Pos) /*!< Bit mask of CH12 field. */ +#define PPI_CHG_CH12_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH12_Included (1UL) /*!< Include */ + +/* Bit 11 : Include or exclude channel 11 */ +#define PPI_CHG_CH11_Pos (11UL) /*!< Position of CH11 field. */ +#define PPI_CHG_CH11_Msk (0x1UL << PPI_CHG_CH11_Pos) /*!< Bit mask of CH11 field. */ +#define PPI_CHG_CH11_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH11_Included (1UL) /*!< Include */ + +/* Bit 10 : Include or exclude channel 10 */ +#define PPI_CHG_CH10_Pos (10UL) /*!< Position of CH10 field. */ +#define PPI_CHG_CH10_Msk (0x1UL << PPI_CHG_CH10_Pos) /*!< Bit mask of CH10 field. */ +#define PPI_CHG_CH10_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH10_Included (1UL) /*!< Include */ + +/* Bit 9 : Include or exclude channel 9 */ +#define PPI_CHG_CH9_Pos (9UL) /*!< Position of CH9 field. */ +#define PPI_CHG_CH9_Msk (0x1UL << PPI_CHG_CH9_Pos) /*!< Bit mask of CH9 field. */ +#define PPI_CHG_CH9_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH9_Included (1UL) /*!< Include */ + +/* Bit 8 : Include or exclude channel 8 */ +#define PPI_CHG_CH8_Pos (8UL) /*!< Position of CH8 field. */ +#define PPI_CHG_CH8_Msk (0x1UL << PPI_CHG_CH8_Pos) /*!< Bit mask of CH8 field. */ +#define PPI_CHG_CH8_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH8_Included (1UL) /*!< Include */ + +/* Bit 7 : Include or exclude channel 7 */ +#define PPI_CHG_CH7_Pos (7UL) /*!< Position of CH7 field. */ +#define PPI_CHG_CH7_Msk (0x1UL << PPI_CHG_CH7_Pos) /*!< Bit mask of CH7 field. */ +#define PPI_CHG_CH7_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH7_Included (1UL) /*!< Include */ + +/* Bit 6 : Include or exclude channel 6 */ +#define PPI_CHG_CH6_Pos (6UL) /*!< Position of CH6 field. */ +#define PPI_CHG_CH6_Msk (0x1UL << PPI_CHG_CH6_Pos) /*!< Bit mask of CH6 field. */ +#define PPI_CHG_CH6_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH6_Included (1UL) /*!< Include */ + +/* Bit 5 : Include or exclude channel 5 */ +#define PPI_CHG_CH5_Pos (5UL) /*!< Position of CH5 field. */ +#define PPI_CHG_CH5_Msk (0x1UL << PPI_CHG_CH5_Pos) /*!< Bit mask of CH5 field. */ +#define PPI_CHG_CH5_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH5_Included (1UL) /*!< Include */ + +/* Bit 4 : Include or exclude channel 4 */ +#define PPI_CHG_CH4_Pos (4UL) /*!< Position of CH4 field. */ +#define PPI_CHG_CH4_Msk (0x1UL << PPI_CHG_CH4_Pos) /*!< Bit mask of CH4 field. */ +#define PPI_CHG_CH4_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH4_Included (1UL) /*!< Include */ + +/* Bit 3 : Include or exclude channel 3 */ +#define PPI_CHG_CH3_Pos (3UL) /*!< Position of CH3 field. */ +#define PPI_CHG_CH3_Msk (0x1UL << PPI_CHG_CH3_Pos) /*!< Bit mask of CH3 field. */ +#define PPI_CHG_CH3_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH3_Included (1UL) /*!< Include */ + +/* Bit 2 : Include or exclude channel 2 */ +#define PPI_CHG_CH2_Pos (2UL) /*!< Position of CH2 field. */ +#define PPI_CHG_CH2_Msk (0x1UL << PPI_CHG_CH2_Pos) /*!< Bit mask of CH2 field. */ +#define PPI_CHG_CH2_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH2_Included (1UL) /*!< Include */ + +/* Bit 1 : Include or exclude channel 1 */ +#define PPI_CHG_CH1_Pos (1UL) /*!< Position of CH1 field. */ +#define PPI_CHG_CH1_Msk (0x1UL << PPI_CHG_CH1_Pos) /*!< Bit mask of CH1 field. */ +#define PPI_CHG_CH1_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH1_Included (1UL) /*!< Include */ + +/* Bit 0 : Include or exclude channel 0 */ +#define PPI_CHG_CH0_Pos (0UL) /*!< Position of CH0 field. */ +#define PPI_CHG_CH0_Msk (0x1UL << PPI_CHG_CH0_Pos) /*!< Bit mask of CH0 field. */ +#define PPI_CHG_CH0_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH0_Included (1UL) /*!< Include */ + +/* Register: PPI_FORK_TEP */ +/* Description: Description cluster[0]: Channel 0 task end-point */ + +/* Bits 31..0 : Pointer to task register */ +#define PPI_FORK_TEP_TEP_Pos (0UL) /*!< Position of TEP field. */ +#define PPI_FORK_TEP_TEP_Msk (0xFFFFFFFFUL << PPI_FORK_TEP_TEP_Pos) /*!< Bit mask of TEP field. */ + + +/* Peripheral: PWM */ +/* Description: Pulse Width Modulation Unit 0 */ + +/* Register: PWM_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 4 : Shortcut between LOOPSDONE event and STOP task */ +#define PWM_SHORTS_LOOPSDONE_STOP_Pos (4UL) /*!< Position of LOOPSDONE_STOP field. */ +#define PWM_SHORTS_LOOPSDONE_STOP_Msk (0x1UL << PWM_SHORTS_LOOPSDONE_STOP_Pos) /*!< Bit mask of LOOPSDONE_STOP field. */ +#define PWM_SHORTS_LOOPSDONE_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define PWM_SHORTS_LOOPSDONE_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between LOOPSDONE event and SEQSTART[1] task */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART1_Pos (3UL) /*!< Position of LOOPSDONE_SEQSTART1 field. */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART1_Msk (0x1UL << PWM_SHORTS_LOOPSDONE_SEQSTART1_Pos) /*!< Bit mask of LOOPSDONE_SEQSTART1 field. */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART1_Disabled (0UL) /*!< Disable shortcut */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART1_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 2 : Shortcut between LOOPSDONE event and SEQSTART[0] task */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART0_Pos (2UL) /*!< Position of LOOPSDONE_SEQSTART0 field. */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART0_Msk (0x1UL << PWM_SHORTS_LOOPSDONE_SEQSTART0_Pos) /*!< Bit mask of LOOPSDONE_SEQSTART0 field. */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART0_Disabled (0UL) /*!< Disable shortcut */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART0_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between SEQEND[1] event and STOP task */ +#define PWM_SHORTS_SEQEND1_STOP_Pos (1UL) /*!< Position of SEQEND1_STOP field. */ +#define PWM_SHORTS_SEQEND1_STOP_Msk (0x1UL << PWM_SHORTS_SEQEND1_STOP_Pos) /*!< Bit mask of SEQEND1_STOP field. */ +#define PWM_SHORTS_SEQEND1_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define PWM_SHORTS_SEQEND1_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between SEQEND[0] event and STOP task */ +#define PWM_SHORTS_SEQEND0_STOP_Pos (0UL) /*!< Position of SEQEND0_STOP field. */ +#define PWM_SHORTS_SEQEND0_STOP_Msk (0x1UL << PWM_SHORTS_SEQEND0_STOP_Pos) /*!< Bit mask of SEQEND0_STOP field. */ +#define PWM_SHORTS_SEQEND0_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define PWM_SHORTS_SEQEND0_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: PWM_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 7 : Enable or disable interrupt for LOOPSDONE event */ +#define PWM_INTEN_LOOPSDONE_Pos (7UL) /*!< Position of LOOPSDONE field. */ +#define PWM_INTEN_LOOPSDONE_Msk (0x1UL << PWM_INTEN_LOOPSDONE_Pos) /*!< Bit mask of LOOPSDONE field. */ +#define PWM_INTEN_LOOPSDONE_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_LOOPSDONE_Enabled (1UL) /*!< Enable */ + +/* Bit 6 : Enable or disable interrupt for PWMPERIODEND event */ +#define PWM_INTEN_PWMPERIODEND_Pos (6UL) /*!< Position of PWMPERIODEND field. */ +#define PWM_INTEN_PWMPERIODEND_Msk (0x1UL << PWM_INTEN_PWMPERIODEND_Pos) /*!< Bit mask of PWMPERIODEND field. */ +#define PWM_INTEN_PWMPERIODEND_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_PWMPERIODEND_Enabled (1UL) /*!< Enable */ + +/* Bit 5 : Enable or disable interrupt for SEQEND[1] event */ +#define PWM_INTEN_SEQEND1_Pos (5UL) /*!< Position of SEQEND1 field. */ +#define PWM_INTEN_SEQEND1_Msk (0x1UL << PWM_INTEN_SEQEND1_Pos) /*!< Bit mask of SEQEND1 field. */ +#define PWM_INTEN_SEQEND1_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_SEQEND1_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable interrupt for SEQEND[0] event */ +#define PWM_INTEN_SEQEND0_Pos (4UL) /*!< Position of SEQEND0 field. */ +#define PWM_INTEN_SEQEND0_Msk (0x1UL << PWM_INTEN_SEQEND0_Pos) /*!< Bit mask of SEQEND0 field. */ +#define PWM_INTEN_SEQEND0_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_SEQEND0_Enabled (1UL) /*!< Enable */ + +/* Bit 3 : Enable or disable interrupt for SEQSTARTED[1] event */ +#define PWM_INTEN_SEQSTARTED1_Pos (3UL) /*!< Position of SEQSTARTED1 field. */ +#define PWM_INTEN_SEQSTARTED1_Msk (0x1UL << PWM_INTEN_SEQSTARTED1_Pos) /*!< Bit mask of SEQSTARTED1 field. */ +#define PWM_INTEN_SEQSTARTED1_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_SEQSTARTED1_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for SEQSTARTED[0] event */ +#define PWM_INTEN_SEQSTARTED0_Pos (2UL) /*!< Position of SEQSTARTED0 field. */ +#define PWM_INTEN_SEQSTARTED0_Msk (0x1UL << PWM_INTEN_SEQSTARTED0_Pos) /*!< Bit mask of SEQSTARTED0 field. */ +#define PWM_INTEN_SEQSTARTED0_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_SEQSTARTED0_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for STOPPED event */ +#define PWM_INTEN_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define PWM_INTEN_STOPPED_Msk (0x1UL << PWM_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define PWM_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ + +/* Register: PWM_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 7 : Write '1' to Enable interrupt for LOOPSDONE event */ +#define PWM_INTENSET_LOOPSDONE_Pos (7UL) /*!< Position of LOOPSDONE field. */ +#define PWM_INTENSET_LOOPSDONE_Msk (0x1UL << PWM_INTENSET_LOOPSDONE_Pos) /*!< Bit mask of LOOPSDONE field. */ +#define PWM_INTENSET_LOOPSDONE_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_LOOPSDONE_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_LOOPSDONE_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for PWMPERIODEND event */ +#define PWM_INTENSET_PWMPERIODEND_Pos (6UL) /*!< Position of PWMPERIODEND field. */ +#define PWM_INTENSET_PWMPERIODEND_Msk (0x1UL << PWM_INTENSET_PWMPERIODEND_Pos) /*!< Bit mask of PWMPERIODEND field. */ +#define PWM_INTENSET_PWMPERIODEND_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_PWMPERIODEND_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_PWMPERIODEND_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for SEQEND[1] event */ +#define PWM_INTENSET_SEQEND1_Pos (5UL) /*!< Position of SEQEND1 field. */ +#define PWM_INTENSET_SEQEND1_Msk (0x1UL << PWM_INTENSET_SEQEND1_Pos) /*!< Bit mask of SEQEND1 field. */ +#define PWM_INTENSET_SEQEND1_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_SEQEND1_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_SEQEND1_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for SEQEND[0] event */ +#define PWM_INTENSET_SEQEND0_Pos (4UL) /*!< Position of SEQEND0 field. */ +#define PWM_INTENSET_SEQEND0_Msk (0x1UL << PWM_INTENSET_SEQEND0_Pos) /*!< Bit mask of SEQEND0 field. */ +#define PWM_INTENSET_SEQEND0_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_SEQEND0_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_SEQEND0_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for SEQSTARTED[1] event */ +#define PWM_INTENSET_SEQSTARTED1_Pos (3UL) /*!< Position of SEQSTARTED1 field. */ +#define PWM_INTENSET_SEQSTARTED1_Msk (0x1UL << PWM_INTENSET_SEQSTARTED1_Pos) /*!< Bit mask of SEQSTARTED1 field. */ +#define PWM_INTENSET_SEQSTARTED1_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_SEQSTARTED1_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_SEQSTARTED1_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for SEQSTARTED[0] event */ +#define PWM_INTENSET_SEQSTARTED0_Pos (2UL) /*!< Position of SEQSTARTED0 field. */ +#define PWM_INTENSET_SEQSTARTED0_Msk (0x1UL << PWM_INTENSET_SEQSTARTED0_Pos) /*!< Bit mask of SEQSTARTED0 field. */ +#define PWM_INTENSET_SEQSTARTED0_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_SEQSTARTED0_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_SEQSTARTED0_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ +#define PWM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define PWM_INTENSET_STOPPED_Msk (0x1UL << PWM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define PWM_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Register: PWM_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 7 : Write '1' to Disable interrupt for LOOPSDONE event */ +#define PWM_INTENCLR_LOOPSDONE_Pos (7UL) /*!< Position of LOOPSDONE field. */ +#define PWM_INTENCLR_LOOPSDONE_Msk (0x1UL << PWM_INTENCLR_LOOPSDONE_Pos) /*!< Bit mask of LOOPSDONE field. */ +#define PWM_INTENCLR_LOOPSDONE_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_LOOPSDONE_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_LOOPSDONE_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for PWMPERIODEND event */ +#define PWM_INTENCLR_PWMPERIODEND_Pos (6UL) /*!< Position of PWMPERIODEND field. */ +#define PWM_INTENCLR_PWMPERIODEND_Msk (0x1UL << PWM_INTENCLR_PWMPERIODEND_Pos) /*!< Bit mask of PWMPERIODEND field. */ +#define PWM_INTENCLR_PWMPERIODEND_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_PWMPERIODEND_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_PWMPERIODEND_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for SEQEND[1] event */ +#define PWM_INTENCLR_SEQEND1_Pos (5UL) /*!< Position of SEQEND1 field. */ +#define PWM_INTENCLR_SEQEND1_Msk (0x1UL << PWM_INTENCLR_SEQEND1_Pos) /*!< Bit mask of SEQEND1 field. */ +#define PWM_INTENCLR_SEQEND1_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_SEQEND1_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_SEQEND1_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for SEQEND[0] event */ +#define PWM_INTENCLR_SEQEND0_Pos (4UL) /*!< Position of SEQEND0 field. */ +#define PWM_INTENCLR_SEQEND0_Msk (0x1UL << PWM_INTENCLR_SEQEND0_Pos) /*!< Bit mask of SEQEND0 field. */ +#define PWM_INTENCLR_SEQEND0_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_SEQEND0_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_SEQEND0_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for SEQSTARTED[1] event */ +#define PWM_INTENCLR_SEQSTARTED1_Pos (3UL) /*!< Position of SEQSTARTED1 field. */ +#define PWM_INTENCLR_SEQSTARTED1_Msk (0x1UL << PWM_INTENCLR_SEQSTARTED1_Pos) /*!< Bit mask of SEQSTARTED1 field. */ +#define PWM_INTENCLR_SEQSTARTED1_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_SEQSTARTED1_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_SEQSTARTED1_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for SEQSTARTED[0] event */ +#define PWM_INTENCLR_SEQSTARTED0_Pos (2UL) /*!< Position of SEQSTARTED0 field. */ +#define PWM_INTENCLR_SEQSTARTED0_Msk (0x1UL << PWM_INTENCLR_SEQSTARTED0_Pos) /*!< Bit mask of SEQSTARTED0 field. */ +#define PWM_INTENCLR_SEQSTARTED0_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_SEQSTARTED0_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_SEQSTARTED0_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ +#define PWM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define PWM_INTENCLR_STOPPED_Msk (0x1UL << PWM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define PWM_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Register: PWM_ENABLE */ +/* Description: PWM module enable register */ + +/* Bit 0 : Enable or disable PWM module */ +#define PWM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define PWM_ENABLE_ENABLE_Msk (0x1UL << PWM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define PWM_ENABLE_ENABLE_Disabled (0UL) /*!< Disabled */ +#define PWM_ENABLE_ENABLE_Enabled (1UL) /*!< Enable */ + +/* Register: PWM_MODE */ +/* Description: Selects operating mode of the wave counter */ + +/* Bit 0 : Selects up or up and down as wave counter mode */ +#define PWM_MODE_UPDOWN_Pos (0UL) /*!< Position of UPDOWN field. */ +#define PWM_MODE_UPDOWN_Msk (0x1UL << PWM_MODE_UPDOWN_Pos) /*!< Bit mask of UPDOWN field. */ +#define PWM_MODE_UPDOWN_Up (0UL) /*!< Up counter - edge aligned PWM duty-cycle */ +#define PWM_MODE_UPDOWN_UpAndDown (1UL) /*!< Up and down counter - center aligned PWM duty cycle */ + +/* Register: PWM_COUNTERTOP */ +/* Description: Value up to which the pulse generator counter counts */ + +/* Bits 14..0 : Value up to which the pulse generator counter counts. This register is ignored when DECODER.MODE=WaveForm and only values from RAM will be used. */ +#define PWM_COUNTERTOP_COUNTERTOP_Pos (0UL) /*!< Position of COUNTERTOP field. */ +#define PWM_COUNTERTOP_COUNTERTOP_Msk (0x7FFFUL << PWM_COUNTERTOP_COUNTERTOP_Pos) /*!< Bit mask of COUNTERTOP field. */ + +/* Register: PWM_PRESCALER */ +/* Description: Configuration for PWM_CLK */ + +/* Bits 2..0 : Pre-scaler of PWM_CLK */ +#define PWM_PRESCALER_PRESCALER_Pos (0UL) /*!< Position of PRESCALER field. */ +#define PWM_PRESCALER_PRESCALER_Msk (0x7UL << PWM_PRESCALER_PRESCALER_Pos) /*!< Bit mask of PRESCALER field. */ +#define PWM_PRESCALER_PRESCALER_DIV_1 (0UL) /*!< Divide by 1 (16MHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_2 (1UL) /*!< Divide by 2 ( 8MHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_4 (2UL) /*!< Divide by 4 ( 4MHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_8 (3UL) /*!< Divide by 8 ( 2MHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_16 (4UL) /*!< Divide by 16 ( 1MHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_32 (5UL) /*!< Divide by 32 ( 500kHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_64 (6UL) /*!< Divide by 64 ( 250kHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_128 (7UL) /*!< Divide by 128 ( 125kHz) */ + +/* Register: PWM_DECODER */ +/* Description: Configuration of the decoder */ + +/* Bit 8 : Selects source for advancing the active sequence */ +#define PWM_DECODER_MODE_Pos (8UL) /*!< Position of MODE field. */ +#define PWM_DECODER_MODE_Msk (0x1UL << PWM_DECODER_MODE_Pos) /*!< Bit mask of MODE field. */ +#define PWM_DECODER_MODE_RefreshCount (0UL) /*!< SEQ[n].REFRESH is used to determine loading internal compare registers */ +#define PWM_DECODER_MODE_NextStep (1UL) /*!< NEXTSTEP task causes a new value to be loaded to internal compare registers */ + +/* Bits 2..0 : How a sequence is read from RAM and spread to the compare register */ +#define PWM_DECODER_LOAD_Pos (0UL) /*!< Position of LOAD field. */ +#define PWM_DECODER_LOAD_Msk (0x7UL << PWM_DECODER_LOAD_Pos) /*!< Bit mask of LOAD field. */ +#define PWM_DECODER_LOAD_Common (0UL) /*!< 1st half word (16-bit) used in all PWM channels 0..3 */ +#define PWM_DECODER_LOAD_Grouped (1UL) /*!< 1st half word (16-bit) used in channel 0..1; 2nd word in channel 2..3 */ +#define PWM_DECODER_LOAD_Individual (2UL) /*!< 1st half word (16-bit) in ch.0; 2nd in ch.1; ...; 4th in ch.3 */ +#define PWM_DECODER_LOAD_WaveForm (3UL) /*!< 1st half word (16-bit) in ch.0; 2nd in ch.1; ...; 4th in COUNTERTOP */ + +/* Register: PWM_LOOP */ +/* Description: Amount of playback of a loop */ + +/* Bits 15..0 : Amount of playback of pattern cycles */ +#define PWM_LOOP_CNT_Pos (0UL) /*!< Position of CNT field. */ +#define PWM_LOOP_CNT_Msk (0xFFFFUL << PWM_LOOP_CNT_Pos) /*!< Bit mask of CNT field. */ +#define PWM_LOOP_CNT_Disabled (0UL) /*!< Looping disabled (stop at the end of the sequence) */ + +/* Register: PWM_SEQ_PTR */ +/* Description: Description cluster[0]: Beginning address in Data RAM of this sequence */ + +/* Bits 31..0 : Beginning address in Data RAM of this sequence */ +#define PWM_SEQ_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define PWM_SEQ_PTR_PTR_Msk (0xFFFFFFFFUL << PWM_SEQ_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: PWM_SEQ_CNT */ +/* Description: Description cluster[0]: Amount of values (duty cycles) in this sequence */ + +/* Bits 14..0 : Amount of values (duty cycles) in this sequence */ +#define PWM_SEQ_CNT_CNT_Pos (0UL) /*!< Position of CNT field. */ +#define PWM_SEQ_CNT_CNT_Msk (0x7FFFUL << PWM_SEQ_CNT_CNT_Pos) /*!< Bit mask of CNT field. */ +#define PWM_SEQ_CNT_CNT_Disabled (0UL) /*!< Sequence is disabled, and shall not be started as it is empty */ + +/* Register: PWM_SEQ_REFRESH */ +/* Description: Description cluster[0]: Amount of additional PWM periods between samples loaded into compare register */ + +/* Bits 23..0 : Amount of additional PWM periods between samples loaded into compare register (load every REFRESH.CNT+1 PWM periods) */ +#define PWM_SEQ_REFRESH_CNT_Pos (0UL) /*!< Position of CNT field. */ +#define PWM_SEQ_REFRESH_CNT_Msk (0xFFFFFFUL << PWM_SEQ_REFRESH_CNT_Pos) /*!< Bit mask of CNT field. */ +#define PWM_SEQ_REFRESH_CNT_Continuous (0UL) /*!< Update every PWM period */ + +/* Register: PWM_SEQ_ENDDELAY */ +/* Description: Description cluster[0]: Time added after the sequence */ + +/* Bits 23..0 : Time added after the sequence in PWM periods */ +#define PWM_SEQ_ENDDELAY_CNT_Pos (0UL) /*!< Position of CNT field. */ +#define PWM_SEQ_ENDDELAY_CNT_Msk (0xFFFFFFUL << PWM_SEQ_ENDDELAY_CNT_Pos) /*!< Bit mask of CNT field. */ + +/* Register: PWM_PSEL_OUT */ +/* Description: Description collection[0]: Output pin select for PWM channel 0 */ + +/* Bit 31 : Connection */ +#define PWM_PSEL_OUT_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define PWM_PSEL_OUT_CONNECT_Msk (0x1UL << PWM_PSEL_OUT_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define PWM_PSEL_OUT_CONNECT_Connected (0UL) /*!< Connect */ +#define PWM_PSEL_OUT_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define PWM_PSEL_OUT_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define PWM_PSEL_OUT_PORT_Msk (0x1UL << PWM_PSEL_OUT_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define PWM_PSEL_OUT_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define PWM_PSEL_OUT_PIN_Msk (0x1FUL << PWM_PSEL_OUT_PIN_Pos) /*!< Bit mask of PIN field. */ + + +/* Peripheral: QDEC */ +/* Description: Quadrature Decoder */ + +/* Register: QDEC_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 6 : Shortcut between SAMPLERDY event and READCLRACC task */ +#define QDEC_SHORTS_SAMPLERDY_READCLRACC_Pos (6UL) /*!< Position of SAMPLERDY_READCLRACC field. */ +#define QDEC_SHORTS_SAMPLERDY_READCLRACC_Msk (0x1UL << QDEC_SHORTS_SAMPLERDY_READCLRACC_Pos) /*!< Bit mask of SAMPLERDY_READCLRACC field. */ +#define QDEC_SHORTS_SAMPLERDY_READCLRACC_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_SAMPLERDY_READCLRACC_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 5 : Shortcut between DBLRDY event and STOP task */ +#define QDEC_SHORTS_DBLRDY_STOP_Pos (5UL) /*!< Position of DBLRDY_STOP field. */ +#define QDEC_SHORTS_DBLRDY_STOP_Msk (0x1UL << QDEC_SHORTS_DBLRDY_STOP_Pos) /*!< Bit mask of DBLRDY_STOP field. */ +#define QDEC_SHORTS_DBLRDY_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_DBLRDY_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 4 : Shortcut between DBLRDY event and RDCLRDBL task */ +#define QDEC_SHORTS_DBLRDY_RDCLRDBL_Pos (4UL) /*!< Position of DBLRDY_RDCLRDBL field. */ +#define QDEC_SHORTS_DBLRDY_RDCLRDBL_Msk (0x1UL << QDEC_SHORTS_DBLRDY_RDCLRDBL_Pos) /*!< Bit mask of DBLRDY_RDCLRDBL field. */ +#define QDEC_SHORTS_DBLRDY_RDCLRDBL_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_DBLRDY_RDCLRDBL_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between REPORTRDY event and STOP task */ +#define QDEC_SHORTS_REPORTRDY_STOP_Pos (3UL) /*!< Position of REPORTRDY_STOP field. */ +#define QDEC_SHORTS_REPORTRDY_STOP_Msk (0x1UL << QDEC_SHORTS_REPORTRDY_STOP_Pos) /*!< Bit mask of REPORTRDY_STOP field. */ +#define QDEC_SHORTS_REPORTRDY_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_REPORTRDY_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 2 : Shortcut between REPORTRDY event and RDCLRACC task */ +#define QDEC_SHORTS_REPORTRDY_RDCLRACC_Pos (2UL) /*!< Position of REPORTRDY_RDCLRACC field. */ +#define QDEC_SHORTS_REPORTRDY_RDCLRACC_Msk (0x1UL << QDEC_SHORTS_REPORTRDY_RDCLRACC_Pos) /*!< Bit mask of REPORTRDY_RDCLRACC field. */ +#define QDEC_SHORTS_REPORTRDY_RDCLRACC_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_REPORTRDY_RDCLRACC_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between SAMPLERDY event and STOP task */ +#define QDEC_SHORTS_SAMPLERDY_STOP_Pos (1UL) /*!< Position of SAMPLERDY_STOP field. */ +#define QDEC_SHORTS_SAMPLERDY_STOP_Msk (0x1UL << QDEC_SHORTS_SAMPLERDY_STOP_Pos) /*!< Bit mask of SAMPLERDY_STOP field. */ +#define QDEC_SHORTS_SAMPLERDY_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_SAMPLERDY_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between REPORTRDY event and READCLRACC task */ +#define QDEC_SHORTS_REPORTRDY_READCLRACC_Pos (0UL) /*!< Position of REPORTRDY_READCLRACC field. */ +#define QDEC_SHORTS_REPORTRDY_READCLRACC_Msk (0x1UL << QDEC_SHORTS_REPORTRDY_READCLRACC_Pos) /*!< Bit mask of REPORTRDY_READCLRACC field. */ +#define QDEC_SHORTS_REPORTRDY_READCLRACC_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_REPORTRDY_READCLRACC_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: QDEC_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 4 : Write '1' to Enable interrupt for STOPPED event */ +#define QDEC_INTENSET_STOPPED_Pos (4UL) /*!< Position of STOPPED field. */ +#define QDEC_INTENSET_STOPPED_Msk (0x1UL << QDEC_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define QDEC_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for DBLRDY event */ +#define QDEC_INTENSET_DBLRDY_Pos (3UL) /*!< Position of DBLRDY field. */ +#define QDEC_INTENSET_DBLRDY_Msk (0x1UL << QDEC_INTENSET_DBLRDY_Pos) /*!< Bit mask of DBLRDY field. */ +#define QDEC_INTENSET_DBLRDY_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENSET_DBLRDY_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENSET_DBLRDY_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for ACCOF event */ +#define QDEC_INTENSET_ACCOF_Pos (2UL) /*!< Position of ACCOF field. */ +#define QDEC_INTENSET_ACCOF_Msk (0x1UL << QDEC_INTENSET_ACCOF_Pos) /*!< Bit mask of ACCOF field. */ +#define QDEC_INTENSET_ACCOF_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENSET_ACCOF_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENSET_ACCOF_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for REPORTRDY event */ +#define QDEC_INTENSET_REPORTRDY_Pos (1UL) /*!< Position of REPORTRDY field. */ +#define QDEC_INTENSET_REPORTRDY_Msk (0x1UL << QDEC_INTENSET_REPORTRDY_Pos) /*!< Bit mask of REPORTRDY field. */ +#define QDEC_INTENSET_REPORTRDY_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENSET_REPORTRDY_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENSET_REPORTRDY_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for SAMPLERDY event */ +#define QDEC_INTENSET_SAMPLERDY_Pos (0UL) /*!< Position of SAMPLERDY field. */ +#define QDEC_INTENSET_SAMPLERDY_Msk (0x1UL << QDEC_INTENSET_SAMPLERDY_Pos) /*!< Bit mask of SAMPLERDY field. */ +#define QDEC_INTENSET_SAMPLERDY_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENSET_SAMPLERDY_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENSET_SAMPLERDY_Set (1UL) /*!< Enable */ + +/* Register: QDEC_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 4 : Write '1' to Disable interrupt for STOPPED event */ +#define QDEC_INTENCLR_STOPPED_Pos (4UL) /*!< Position of STOPPED field. */ +#define QDEC_INTENCLR_STOPPED_Msk (0x1UL << QDEC_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define QDEC_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for DBLRDY event */ +#define QDEC_INTENCLR_DBLRDY_Pos (3UL) /*!< Position of DBLRDY field. */ +#define QDEC_INTENCLR_DBLRDY_Msk (0x1UL << QDEC_INTENCLR_DBLRDY_Pos) /*!< Bit mask of DBLRDY field. */ +#define QDEC_INTENCLR_DBLRDY_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENCLR_DBLRDY_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENCLR_DBLRDY_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for ACCOF event */ +#define QDEC_INTENCLR_ACCOF_Pos (2UL) /*!< Position of ACCOF field. */ +#define QDEC_INTENCLR_ACCOF_Msk (0x1UL << QDEC_INTENCLR_ACCOF_Pos) /*!< Bit mask of ACCOF field. */ +#define QDEC_INTENCLR_ACCOF_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENCLR_ACCOF_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENCLR_ACCOF_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for REPORTRDY event */ +#define QDEC_INTENCLR_REPORTRDY_Pos (1UL) /*!< Position of REPORTRDY field. */ +#define QDEC_INTENCLR_REPORTRDY_Msk (0x1UL << QDEC_INTENCLR_REPORTRDY_Pos) /*!< Bit mask of REPORTRDY field. */ +#define QDEC_INTENCLR_REPORTRDY_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENCLR_REPORTRDY_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENCLR_REPORTRDY_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for SAMPLERDY event */ +#define QDEC_INTENCLR_SAMPLERDY_Pos (0UL) /*!< Position of SAMPLERDY field. */ +#define QDEC_INTENCLR_SAMPLERDY_Msk (0x1UL << QDEC_INTENCLR_SAMPLERDY_Pos) /*!< Bit mask of SAMPLERDY field. */ +#define QDEC_INTENCLR_SAMPLERDY_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENCLR_SAMPLERDY_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENCLR_SAMPLERDY_Clear (1UL) /*!< Disable */ + +/* Register: QDEC_ENABLE */ +/* Description: Enable the quadrature decoder */ + +/* Bit 0 : Enable or disable the quadrature decoder */ +#define QDEC_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define QDEC_ENABLE_ENABLE_Msk (0x1UL << QDEC_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define QDEC_ENABLE_ENABLE_Disabled (0UL) /*!< Disable */ +#define QDEC_ENABLE_ENABLE_Enabled (1UL) /*!< Enable */ + +/* Register: QDEC_LEDPOL */ +/* Description: LED output pin polarity */ + +/* Bit 0 : LED output pin polarity */ +#define QDEC_LEDPOL_LEDPOL_Pos (0UL) /*!< Position of LEDPOL field. */ +#define QDEC_LEDPOL_LEDPOL_Msk (0x1UL << QDEC_LEDPOL_LEDPOL_Pos) /*!< Bit mask of LEDPOL field. */ +#define QDEC_LEDPOL_LEDPOL_ActiveLow (0UL) /*!< Led active on output pin low */ +#define QDEC_LEDPOL_LEDPOL_ActiveHigh (1UL) /*!< Led active on output pin high */ + +/* Register: QDEC_SAMPLEPER */ +/* Description: Sample period */ + +/* Bits 3..0 : Sample period. The SAMPLE register will be updated for every new sample */ +#define QDEC_SAMPLEPER_SAMPLEPER_Pos (0UL) /*!< Position of SAMPLEPER field. */ +#define QDEC_SAMPLEPER_SAMPLEPER_Msk (0xFUL << QDEC_SAMPLEPER_SAMPLEPER_Pos) /*!< Bit mask of SAMPLEPER field. */ +#define QDEC_SAMPLEPER_SAMPLEPER_128us (0UL) /*!< 128 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_256us (1UL) /*!< 256 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_512us (2UL) /*!< 512 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_1024us (3UL) /*!< 1024 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_2048us (4UL) /*!< 2048 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_4096us (5UL) /*!< 4096 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_8192us (6UL) /*!< 8192 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_16384us (7UL) /*!< 16384 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_32ms (8UL) /*!< 32768 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_65ms (9UL) /*!< 65536 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_131ms (10UL) /*!< 131072 us */ + +/* Register: QDEC_SAMPLE */ +/* Description: Motion sample value */ + +/* Bits 31..0 : Last motion sample */ +#define QDEC_SAMPLE_SAMPLE_Pos (0UL) /*!< Position of SAMPLE field. */ +#define QDEC_SAMPLE_SAMPLE_Msk (0xFFFFFFFFUL << QDEC_SAMPLE_SAMPLE_Pos) /*!< Bit mask of SAMPLE field. */ + +/* Register: QDEC_REPORTPER */ +/* Description: Number of samples to be taken before REPORTRDY and DBLRDY events can be generated */ + +/* Bits 3..0 : Specifies the number of samples to be accumulated in the ACC register before the REPORTRDY and DBLRDY events can be generated */ +#define QDEC_REPORTPER_REPORTPER_Pos (0UL) /*!< Position of REPORTPER field. */ +#define QDEC_REPORTPER_REPORTPER_Msk (0xFUL << QDEC_REPORTPER_REPORTPER_Pos) /*!< Bit mask of REPORTPER field. */ +#define QDEC_REPORTPER_REPORTPER_10Smpl (0UL) /*!< 10 samples / report */ +#define QDEC_REPORTPER_REPORTPER_40Smpl (1UL) /*!< 40 samples / report */ +#define QDEC_REPORTPER_REPORTPER_80Smpl (2UL) /*!< 80 samples / report */ +#define QDEC_REPORTPER_REPORTPER_120Smpl (3UL) /*!< 120 samples / report */ +#define QDEC_REPORTPER_REPORTPER_160Smpl (4UL) /*!< 160 samples / report */ +#define QDEC_REPORTPER_REPORTPER_200Smpl (5UL) /*!< 200 samples / report */ +#define QDEC_REPORTPER_REPORTPER_240Smpl (6UL) /*!< 240 samples / report */ +#define QDEC_REPORTPER_REPORTPER_280Smpl (7UL) /*!< 280 samples / report */ +#define QDEC_REPORTPER_REPORTPER_1Smpl (8UL) /*!< 1 sample / report */ + +/* Register: QDEC_ACC */ +/* Description: Register accumulating the valid transitions */ + +/* Bits 31..0 : Register accumulating all valid samples (not double transition) read from the SAMPLE register */ +#define QDEC_ACC_ACC_Pos (0UL) /*!< Position of ACC field. */ +#define QDEC_ACC_ACC_Msk (0xFFFFFFFFUL << QDEC_ACC_ACC_Pos) /*!< Bit mask of ACC field. */ + +/* Register: QDEC_ACCREAD */ +/* Description: Snapshot of the ACC register, updated by the READCLRACC or RDCLRACC task */ + +/* Bits 31..0 : Snapshot of the ACC register. */ +#define QDEC_ACCREAD_ACCREAD_Pos (0UL) /*!< Position of ACCREAD field. */ +#define QDEC_ACCREAD_ACCREAD_Msk (0xFFFFFFFFUL << QDEC_ACCREAD_ACCREAD_Pos) /*!< Bit mask of ACCREAD field. */ + +/* Register: QDEC_PSEL_LED */ +/* Description: Pin select for LED signal */ + +/* Bit 31 : Connection */ +#define QDEC_PSEL_LED_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QDEC_PSEL_LED_CONNECT_Msk (0x1UL << QDEC_PSEL_LED_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QDEC_PSEL_LED_CONNECT_Connected (0UL) /*!< Connect */ +#define QDEC_PSEL_LED_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define QDEC_PSEL_LED_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QDEC_PSEL_LED_PORT_Msk (0x1UL << QDEC_PSEL_LED_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QDEC_PSEL_LED_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QDEC_PSEL_LED_PIN_Msk (0x1FUL << QDEC_PSEL_LED_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QDEC_PSEL_A */ +/* Description: Pin select for A signal */ + +/* Bit 31 : Connection */ +#define QDEC_PSEL_A_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QDEC_PSEL_A_CONNECT_Msk (0x1UL << QDEC_PSEL_A_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QDEC_PSEL_A_CONNECT_Connected (0UL) /*!< Connect */ +#define QDEC_PSEL_A_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define QDEC_PSEL_A_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QDEC_PSEL_A_PORT_Msk (0x1UL << QDEC_PSEL_A_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QDEC_PSEL_A_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QDEC_PSEL_A_PIN_Msk (0x1FUL << QDEC_PSEL_A_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QDEC_PSEL_B */ +/* Description: Pin select for B signal */ + +/* Bit 31 : Connection */ +#define QDEC_PSEL_B_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QDEC_PSEL_B_CONNECT_Msk (0x1UL << QDEC_PSEL_B_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QDEC_PSEL_B_CONNECT_Connected (0UL) /*!< Connect */ +#define QDEC_PSEL_B_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define QDEC_PSEL_B_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QDEC_PSEL_B_PORT_Msk (0x1UL << QDEC_PSEL_B_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QDEC_PSEL_B_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QDEC_PSEL_B_PIN_Msk (0x1FUL << QDEC_PSEL_B_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QDEC_DBFEN */ +/* Description: Enable input debounce filters */ + +/* Bit 0 : Enable input debounce filters */ +#define QDEC_DBFEN_DBFEN_Pos (0UL) /*!< Position of DBFEN field. */ +#define QDEC_DBFEN_DBFEN_Msk (0x1UL << QDEC_DBFEN_DBFEN_Pos) /*!< Bit mask of DBFEN field. */ +#define QDEC_DBFEN_DBFEN_Disabled (0UL) /*!< Debounce input filters disabled */ +#define QDEC_DBFEN_DBFEN_Enabled (1UL) /*!< Debounce input filters enabled */ + +/* Register: QDEC_LEDPRE */ +/* Description: Time period the LED is switched ON prior to sampling */ + +/* Bits 8..0 : Period in us the LED is switched on prior to sampling */ +#define QDEC_LEDPRE_LEDPRE_Pos (0UL) /*!< Position of LEDPRE field. */ +#define QDEC_LEDPRE_LEDPRE_Msk (0x1FFUL << QDEC_LEDPRE_LEDPRE_Pos) /*!< Bit mask of LEDPRE field. */ + +/* Register: QDEC_ACCDBL */ +/* Description: Register accumulating the number of detected double transitions */ + +/* Bits 3..0 : Register accumulating the number of detected double or illegal transitions. ( SAMPLE = 2 ). */ +#define QDEC_ACCDBL_ACCDBL_Pos (0UL) /*!< Position of ACCDBL field. */ +#define QDEC_ACCDBL_ACCDBL_Msk (0xFUL << QDEC_ACCDBL_ACCDBL_Pos) /*!< Bit mask of ACCDBL field. */ + +/* Register: QDEC_ACCDBLREAD */ +/* Description: Snapshot of the ACCDBL, updated by the READCLRACC or RDCLRDBL task */ + +/* Bits 3..0 : Snapshot of the ACCDBL register. This field is updated when the READCLRACC or RDCLRDBL task is triggered. */ +#define QDEC_ACCDBLREAD_ACCDBLREAD_Pos (0UL) /*!< Position of ACCDBLREAD field. */ +#define QDEC_ACCDBLREAD_ACCDBLREAD_Msk (0xFUL << QDEC_ACCDBLREAD_ACCDBLREAD_Pos) /*!< Bit mask of ACCDBLREAD field. */ + + +/* Peripheral: QSPI */ +/* Description: External flash interface */ + +/* Register: QSPI_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 0 : Enable or disable interrupt for READY event */ +#define QSPI_INTEN_READY_Pos (0UL) /*!< Position of READY field. */ +#define QSPI_INTEN_READY_Msk (0x1UL << QSPI_INTEN_READY_Pos) /*!< Bit mask of READY field. */ +#define QSPI_INTEN_READY_Disabled (0UL) /*!< Disable */ +#define QSPI_INTEN_READY_Enabled (1UL) /*!< Enable */ + +/* Register: QSPI_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 0 : Write '1' to Enable interrupt for READY event */ +#define QSPI_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */ +#define QSPI_INTENSET_READY_Msk (0x1UL << QSPI_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ +#define QSPI_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ +#define QSPI_INTENSET_READY_Enabled (1UL) /*!< Read: Enabled */ +#define QSPI_INTENSET_READY_Set (1UL) /*!< Enable */ + +/* Register: QSPI_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 0 : Write '1' to Disable interrupt for READY event */ +#define QSPI_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */ +#define QSPI_INTENCLR_READY_Msk (0x1UL << QSPI_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ +#define QSPI_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ +#define QSPI_INTENCLR_READY_Enabled (1UL) /*!< Read: Enabled */ +#define QSPI_INTENCLR_READY_Clear (1UL) /*!< Disable */ + +/* Register: QSPI_ENABLE */ +/* Description: Enable QSPI peripheral and acquire the pins selected in PSELn registers */ + +/* Bit 0 : Enable or disable QSPI */ +#define QSPI_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define QSPI_ENABLE_ENABLE_Msk (0x1UL << QSPI_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define QSPI_ENABLE_ENABLE_Disabled (0UL) /*!< Disable QSPI */ +#define QSPI_ENABLE_ENABLE_Enabled (1UL) /*!< Enable QSPI */ + +/* Register: QSPI_READ_SRC */ +/* Description: Flash memory source address */ + +/* Bits 31..0 : Word-aligned flash memory source address. */ +#define QSPI_READ_SRC_SRC_Pos (0UL) /*!< Position of SRC field. */ +#define QSPI_READ_SRC_SRC_Msk (0xFFFFFFFFUL << QSPI_READ_SRC_SRC_Pos) /*!< Bit mask of SRC field. */ + +/* Register: QSPI_READ_DST */ +/* Description: RAM destination address */ + +/* Bits 31..0 : Word-aligned RAM destination address. */ +#define QSPI_READ_DST_DST_Pos (0UL) /*!< Position of DST field. */ +#define QSPI_READ_DST_DST_Msk (0xFFFFFFFFUL << QSPI_READ_DST_DST_Pos) /*!< Bit mask of DST field. */ + +/* Register: QSPI_READ_CNT */ +/* Description: Read transfer length */ + +/* Bits 20..0 : Read transfer length in number of bytes. The length must be a multiple of 4 bytes. */ +#define QSPI_READ_CNT_CNT_Pos (0UL) /*!< Position of CNT field. */ +#define QSPI_READ_CNT_CNT_Msk (0x1FFFFFUL << QSPI_READ_CNT_CNT_Pos) /*!< Bit mask of CNT field. */ + +/* Register: QSPI_WRITE_DST */ +/* Description: Flash destination address */ + +/* Bits 31..0 : Word-aligned flash destination address. */ +#define QSPI_WRITE_DST_DST_Pos (0UL) /*!< Position of DST field. */ +#define QSPI_WRITE_DST_DST_Msk (0xFFFFFFFFUL << QSPI_WRITE_DST_DST_Pos) /*!< Bit mask of DST field. */ + +/* Register: QSPI_WRITE_SRC */ +/* Description: RAM source address */ + +/* Bits 31..0 : Word-aligned RAM source address. */ +#define QSPI_WRITE_SRC_SRC_Pos (0UL) /*!< Position of SRC field. */ +#define QSPI_WRITE_SRC_SRC_Msk (0xFFFFFFFFUL << QSPI_WRITE_SRC_SRC_Pos) /*!< Bit mask of SRC field. */ + +/* Register: QSPI_WRITE_CNT */ +/* Description: Write transfer length */ + +/* Bits 20..0 : Write transfer length in number of bytes. The length must be a multiple of 4 bytes. */ +#define QSPI_WRITE_CNT_CNT_Pos (0UL) /*!< Position of CNT field. */ +#define QSPI_WRITE_CNT_CNT_Msk (0x1FFFFFUL << QSPI_WRITE_CNT_CNT_Pos) /*!< Bit mask of CNT field. */ + +/* Register: QSPI_ERASE_PTR */ +/* Description: Start address of flash block to be erased */ + +/* Bits 31..0 : Word-aligned start address of block to be erased. */ +#define QSPI_ERASE_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define QSPI_ERASE_PTR_PTR_Msk (0xFFFFFFFFUL << QSPI_ERASE_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: QSPI_ERASE_LEN */ +/* Description: Size of block to be erased. */ + +/* Bits 1..0 : LEN */ +#define QSPI_ERASE_LEN_LEN_Pos (0UL) /*!< Position of LEN field. */ +#define QSPI_ERASE_LEN_LEN_Msk (0x3UL << QSPI_ERASE_LEN_LEN_Pos) /*!< Bit mask of LEN field. */ +#define QSPI_ERASE_LEN_LEN_4KB (0UL) /*!< Erase 4 kB block (flash command 0x20) */ +#define QSPI_ERASE_LEN_LEN_64KB (1UL) /*!< Erase 64 kB block (flash command 0xD8) */ +#define QSPI_ERASE_LEN_LEN_All (2UL) /*!< Erase all (flash command 0xC7) */ + +/* Register: QSPI_PSEL_SCK */ +/* Description: Pin select for serial clock SCK */ + +/* Bit 31 : Connection */ +#define QSPI_PSEL_SCK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QSPI_PSEL_SCK_CONNECT_Msk (0x1UL << QSPI_PSEL_SCK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QSPI_PSEL_SCK_CONNECT_Connected (0UL) /*!< Connect */ +#define QSPI_PSEL_SCK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define QSPI_PSEL_SCK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QSPI_PSEL_SCK_PORT_Msk (0x1UL << QSPI_PSEL_SCK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QSPI_PSEL_SCK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QSPI_PSEL_SCK_PIN_Msk (0x1FUL << QSPI_PSEL_SCK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QSPI_PSEL_CSN */ +/* Description: Pin select for chip select signal CSN. */ + +/* Bit 31 : Connection */ +#define QSPI_PSEL_CSN_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QSPI_PSEL_CSN_CONNECT_Msk (0x1UL << QSPI_PSEL_CSN_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QSPI_PSEL_CSN_CONNECT_Connected (0UL) /*!< Connect */ +#define QSPI_PSEL_CSN_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define QSPI_PSEL_CSN_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QSPI_PSEL_CSN_PORT_Msk (0x1UL << QSPI_PSEL_CSN_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QSPI_PSEL_CSN_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QSPI_PSEL_CSN_PIN_Msk (0x1FUL << QSPI_PSEL_CSN_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QSPI_PSEL_IO0 */ +/* Description: Pin select for serial data MOSI/IO0. */ + +/* Bit 31 : Connection */ +#define QSPI_PSEL_IO0_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QSPI_PSEL_IO0_CONNECT_Msk (0x1UL << QSPI_PSEL_IO0_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QSPI_PSEL_IO0_CONNECT_Connected (0UL) /*!< Connect */ +#define QSPI_PSEL_IO0_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define QSPI_PSEL_IO0_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QSPI_PSEL_IO0_PORT_Msk (0x1UL << QSPI_PSEL_IO0_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QSPI_PSEL_IO0_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QSPI_PSEL_IO0_PIN_Msk (0x1FUL << QSPI_PSEL_IO0_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QSPI_PSEL_IO1 */ +/* Description: Pin select for serial data MISO/IO1. */ + +/* Bit 31 : Connection */ +#define QSPI_PSEL_IO1_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QSPI_PSEL_IO1_CONNECT_Msk (0x1UL << QSPI_PSEL_IO1_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QSPI_PSEL_IO1_CONNECT_Connected (0UL) /*!< Connect */ +#define QSPI_PSEL_IO1_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define QSPI_PSEL_IO1_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QSPI_PSEL_IO1_PORT_Msk (0x1UL << QSPI_PSEL_IO1_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QSPI_PSEL_IO1_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QSPI_PSEL_IO1_PIN_Msk (0x1FUL << QSPI_PSEL_IO1_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QSPI_PSEL_IO2 */ +/* Description: Pin select for serial data IO2. */ + +/* Bit 31 : Connection */ +#define QSPI_PSEL_IO2_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QSPI_PSEL_IO2_CONNECT_Msk (0x1UL << QSPI_PSEL_IO2_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QSPI_PSEL_IO2_CONNECT_Connected (0UL) /*!< Connect */ +#define QSPI_PSEL_IO2_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define QSPI_PSEL_IO2_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QSPI_PSEL_IO2_PORT_Msk (0x1UL << QSPI_PSEL_IO2_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QSPI_PSEL_IO2_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QSPI_PSEL_IO2_PIN_Msk (0x1FUL << QSPI_PSEL_IO2_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QSPI_PSEL_IO3 */ +/* Description: Pin select for serial data IO3. */ + +/* Bit 31 : Connection */ +#define QSPI_PSEL_IO3_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QSPI_PSEL_IO3_CONNECT_Msk (0x1UL << QSPI_PSEL_IO3_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QSPI_PSEL_IO3_CONNECT_Connected (0UL) /*!< Connect */ +#define QSPI_PSEL_IO3_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define QSPI_PSEL_IO3_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QSPI_PSEL_IO3_PORT_Msk (0x1UL << QSPI_PSEL_IO3_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QSPI_PSEL_IO3_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QSPI_PSEL_IO3_PIN_Msk (0x1FUL << QSPI_PSEL_IO3_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QSPI_XIPOFFSET */ +/* Description: Address offset into the external memory for Execute in Place operation. */ + +/* Bits 31..0 : Address offset into the external memory for Execute in Place operation. Value must be a multiple of 4. */ +#define QSPI_XIPOFFSET_XIPOFFSET_Pos (0UL) /*!< Position of XIPOFFSET field. */ +#define QSPI_XIPOFFSET_XIPOFFSET_Msk (0xFFFFFFFFUL << QSPI_XIPOFFSET_XIPOFFSET_Pos) /*!< Bit mask of XIPOFFSET field. */ + +/* Register: QSPI_IFCONFIG0 */ +/* Description: Interface configuration. */ + +/* Bit 7 : Enable deep power-down mode (DPM) feature. */ +#define QSPI_IFCONFIG0_DPMENABLE_Pos (7UL) /*!< Position of DPMENABLE field. */ +#define QSPI_IFCONFIG0_DPMENABLE_Msk (0x1UL << QSPI_IFCONFIG0_DPMENABLE_Pos) /*!< Bit mask of DPMENABLE field. */ +#define QSPI_IFCONFIG0_DPMENABLE_Disable (0UL) /*!< Disable DPM feature. */ +#define QSPI_IFCONFIG0_DPMENABLE_Enable (1UL) /*!< Enable DPM feature. */ + +/* Bit 6 : Addressing mode. */ +#define QSPI_IFCONFIG0_ADDRMODE_Pos (6UL) /*!< Position of ADDRMODE field. */ +#define QSPI_IFCONFIG0_ADDRMODE_Msk (0x1UL << QSPI_IFCONFIG0_ADDRMODE_Pos) /*!< Bit mask of ADDRMODE field. */ +#define QSPI_IFCONFIG0_ADDRMODE_24BIT (0UL) /*!< 24-bit addressing. */ +#define QSPI_IFCONFIG0_ADDRMODE_32BIT (1UL) /*!< 32-bit addressing. */ + +/* Bits 5..3 : Configure number of data lines and opcode used for writing. */ +#define QSPI_IFCONFIG0_WRITEOC_Pos (3UL) /*!< Position of WRITEOC field. */ +#define QSPI_IFCONFIG0_WRITEOC_Msk (0x7UL << QSPI_IFCONFIG0_WRITEOC_Pos) /*!< Bit mask of WRITEOC field. */ +#define QSPI_IFCONFIG0_WRITEOC_PP (0UL) /*!< Single data line SPI. PP (opcode 0x02). */ +#define QSPI_IFCONFIG0_WRITEOC_PP2O (1UL) /*!< Dual data line SPI. PP2O (opcode 0xA2). */ +#define QSPI_IFCONFIG0_WRITEOC_PP4O (2UL) /*!< Quad data line SPI. PP4O (opcode 0x32). */ +#define QSPI_IFCONFIG0_WRITEOC_PP4IO (3UL) /*!< Quad data line SPI. PP4IO (opcode 0x38). */ + +/* Bits 2..0 : Configure number of data lines and opcode used for reading. */ +#define QSPI_IFCONFIG0_READOC_Pos (0UL) /*!< Position of READOC field. */ +#define QSPI_IFCONFIG0_READOC_Msk (0x7UL << QSPI_IFCONFIG0_READOC_Pos) /*!< Bit mask of READOC field. */ +#define QSPI_IFCONFIG0_READOC_FASTREAD (0UL) /*!< Single data line SPI. FAST_READ (opcode 0x0B). */ +#define QSPI_IFCONFIG0_READOC_READ2O (1UL) /*!< Dual data line SPI. READ2O (opcode 0x3B). */ +#define QSPI_IFCONFIG0_READOC_READ2IO (2UL) /*!< Dual data line SPI. READ2IO (opcode 0xBB). */ +#define QSPI_IFCONFIG0_READOC_READ4O (3UL) /*!< Quad data line SPI. READ4O (opcode 0x6B). */ +#define QSPI_IFCONFIG0_READOC_READ4IO (4UL) /*!< Quad data line SPI. READ4IO (opcode 0xEB). */ + +/* Register: QSPI_IFCONFIG1 */ +/* Description: Interface configuration. */ + +/* Bits 31..28 : SCK frequency is given as 32 MHz / (SCKFREQ + 1). */ +#define QSPI_IFCONFIG1_SCKFREQ_Pos (28UL) /*!< Position of SCKFREQ field. */ +#define QSPI_IFCONFIG1_SCKFREQ_Msk (0xFUL << QSPI_IFCONFIG1_SCKFREQ_Pos) /*!< Bit mask of SCKFREQ field. */ + +/* Bit 25 : Select SPI mode. */ +#define QSPI_IFCONFIG1_SPIMODE_Pos (25UL) /*!< Position of SPIMODE field. */ +#define QSPI_IFCONFIG1_SPIMODE_Msk (0x1UL << QSPI_IFCONFIG1_SPIMODE_Pos) /*!< Bit mask of SPIMODE field. */ +#define QSPI_IFCONFIG1_SPIMODE_MODE0 (0UL) /*!< Mode 0: Data are captured on the clock rising edge and data is output on a falling edge. Base level of clock is 0 (CPOL=0, CPHA=0). */ +#define QSPI_IFCONFIG1_SPIMODE_MODE3 (1UL) /*!< Mode 3: Data are captured on the clock falling edge and data is output on a rising edge. Base level of clock is 1 (CPOL=1, CPHA=1). */ + +/* Bit 24 : Enter/exit deep power-down mode (DPM) for external flash memory. */ +#define QSPI_IFCONFIG1_DPMEN_Pos (24UL) /*!< Position of DPMEN field. */ +#define QSPI_IFCONFIG1_DPMEN_Msk (0x1UL << QSPI_IFCONFIG1_DPMEN_Pos) /*!< Bit mask of DPMEN field. */ +#define QSPI_IFCONFIG1_DPMEN_Exit (0UL) /*!< Exit DPM. */ +#define QSPI_IFCONFIG1_DPMEN_Enter (1UL) /*!< Enter DPM. */ + +/* Bits 7..0 : Minimum amount of time that the CSN pin must stay high before it can go low again. Value is specified in number of 16 MHz periods (62.5 ns). */ +#define QSPI_IFCONFIG1_SCKDELAY_Pos (0UL) /*!< Position of SCKDELAY field. */ +#define QSPI_IFCONFIG1_SCKDELAY_Msk (0xFFUL << QSPI_IFCONFIG1_SCKDELAY_Pos) /*!< Bit mask of SCKDELAY field. */ + +/* Register: QSPI_STATUS */ +/* Description: Status register. */ + +/* Bits 31..24 : Value of external flash device Status Register. When the external flash has two bytes status register this field includes the value of the low byte. */ +#define QSPI_STATUS_SREG_Pos (24UL) /*!< Position of SREG field. */ +#define QSPI_STATUS_SREG_Msk (0xFFUL << QSPI_STATUS_SREG_Pos) /*!< Bit mask of SREG field. */ + +/* Bit 3 : Ready status. */ +#define QSPI_STATUS_READY_Pos (3UL) /*!< Position of READY field. */ +#define QSPI_STATUS_READY_Msk (0x1UL << QSPI_STATUS_READY_Pos) /*!< Bit mask of READY field. */ +#define QSPI_STATUS_READY_BUSY (0UL) /*!< QSPI peripheral is busy. It is not allowed to trigger any new tasks, writing custom instructions or enter/exit DPM. */ +#define QSPI_STATUS_READY_READY (1UL) /*!< QSPI peripheral is ready. It is allowed to trigger new tasks, writing custom instructions or enter/exit DPM. */ + +/* Bit 2 : Deep power-down mode (DPM) status of external flash. */ +#define QSPI_STATUS_DPM_Pos (2UL) /*!< Position of DPM field. */ +#define QSPI_STATUS_DPM_Msk (0x1UL << QSPI_STATUS_DPM_Pos) /*!< Bit mask of DPM field. */ +#define QSPI_STATUS_DPM_Disabled (0UL) /*!< External flash is not in DPM. */ +#define QSPI_STATUS_DPM_Enabled (1UL) /*!< External flash is in DPM. */ + +/* Register: QSPI_DPMDUR */ +/* Description: Set the duration required to enter/exit deep power-down mode (DPM). */ + +/* Bits 31..16 : Duration needed by external flash to exit DPM. Duration is given as EXIT * 256 * 62.5 ns. */ +#define QSPI_DPMDUR_EXIT_Pos (16UL) /*!< Position of EXIT field. */ +#define QSPI_DPMDUR_EXIT_Msk (0xFFFFUL << QSPI_DPMDUR_EXIT_Pos) /*!< Bit mask of EXIT field. */ + +/* Bits 15..0 : Duration needed by external flash to enter DPM. Duration is given as ENTER * 256 * 62.5 ns. */ +#define QSPI_DPMDUR_ENTER_Pos (0UL) /*!< Position of ENTER field. */ +#define QSPI_DPMDUR_ENTER_Msk (0xFFFFUL << QSPI_DPMDUR_ENTER_Pos) /*!< Bit mask of ENTER field. */ + +/* Register: QSPI_ADDRCONF */ +/* Description: Extended address configuration. */ + +/* Bit 27 : Send WREN (write enable opcode 0x06) before instruction. */ +#define QSPI_ADDRCONF_WREN_Pos (27UL) /*!< Position of WREN field. */ +#define QSPI_ADDRCONF_WREN_Msk (0x1UL << QSPI_ADDRCONF_WREN_Pos) /*!< Bit mask of WREN field. */ +#define QSPI_ADDRCONF_WREN_Disable (0UL) /*!< Do not send WREN. */ +#define QSPI_ADDRCONF_WREN_Enable (1UL) /*!< Send WREN. */ + +/* Bit 26 : Wait for write complete before sending command. */ +#define QSPI_ADDRCONF_WIPWAIT_Pos (26UL) /*!< Position of WIPWAIT field. */ +#define QSPI_ADDRCONF_WIPWAIT_Msk (0x1UL << QSPI_ADDRCONF_WIPWAIT_Pos) /*!< Bit mask of WIPWAIT field. */ +#define QSPI_ADDRCONF_WIPWAIT_Disable (0UL) /*!< No wait. */ +#define QSPI_ADDRCONF_WIPWAIT_Enable (1UL) /*!< Wait. */ + +/* Bits 25..24 : Extended addressing mode. */ +#define QSPI_ADDRCONF_MODE_Pos (24UL) /*!< Position of MODE field. */ +#define QSPI_ADDRCONF_MODE_Msk (0x3UL << QSPI_ADDRCONF_MODE_Pos) /*!< Bit mask of MODE field. */ +#define QSPI_ADDRCONF_MODE_NoInstr (0UL) /*!< Do not send any instruction. */ +#define QSPI_ADDRCONF_MODE_Opcode (1UL) /*!< Send opcode. */ +#define QSPI_ADDRCONF_MODE_OpByte0 (2UL) /*!< Send opcode, byte0. */ +#define QSPI_ADDRCONF_MODE_All (3UL) /*!< Send opcode, byte0, byte1. */ + +/* Bits 23..16 : Byte 1 following byte 0. */ +#define QSPI_ADDRCONF_BYTE1_Pos (16UL) /*!< Position of BYTE1 field. */ +#define QSPI_ADDRCONF_BYTE1_Msk (0xFFUL << QSPI_ADDRCONF_BYTE1_Pos) /*!< Bit mask of BYTE1 field. */ + +/* Bits 15..8 : Byte 0 following opcode. */ +#define QSPI_ADDRCONF_BYTE0_Pos (8UL) /*!< Position of BYTE0 field. */ +#define QSPI_ADDRCONF_BYTE0_Msk (0xFFUL << QSPI_ADDRCONF_BYTE0_Pos) /*!< Bit mask of BYTE0 field. */ + +/* Bits 7..0 : Opcode that enters the 32-bit addressing mode. */ +#define QSPI_ADDRCONF_OPCODE_Pos (0UL) /*!< Position of OPCODE field. */ +#define QSPI_ADDRCONF_OPCODE_Msk (0xFFUL << QSPI_ADDRCONF_OPCODE_Pos) /*!< Bit mask of OPCODE field. */ + +/* Register: QSPI_CINSTRCONF */ +/* Description: Custom instruction configuration register. */ + +/* Bit 15 : Send WREN (write enable opcode 0x06) before instruction. */ +#define QSPI_CINSTRCONF_WREN_Pos (15UL) /*!< Position of WREN field. */ +#define QSPI_CINSTRCONF_WREN_Msk (0x1UL << QSPI_CINSTRCONF_WREN_Pos) /*!< Bit mask of WREN field. */ +#define QSPI_CINSTRCONF_WREN_Disable (0UL) /*!< Do not send WREN. */ +#define QSPI_CINSTRCONF_WREN_Enable (1UL) /*!< Send WREN. */ + +/* Bit 14 : Wait for write complete before sending command. */ +#define QSPI_CINSTRCONF_WIPWAIT_Pos (14UL) /*!< Position of WIPWAIT field. */ +#define QSPI_CINSTRCONF_WIPWAIT_Msk (0x1UL << QSPI_CINSTRCONF_WIPWAIT_Pos) /*!< Bit mask of WIPWAIT field. */ +#define QSPI_CINSTRCONF_WIPWAIT_Disable (0UL) /*!< No wait. */ +#define QSPI_CINSTRCONF_WIPWAIT_Enable (1UL) /*!< Wait. */ + +/* Bit 13 : Level of the IO3 pin (if connected) during transmission of custom instruction. */ +#define QSPI_CINSTRCONF_LIO3_Pos (13UL) /*!< Position of LIO3 field. */ +#define QSPI_CINSTRCONF_LIO3_Msk (0x1UL << QSPI_CINSTRCONF_LIO3_Pos) /*!< Bit mask of LIO3 field. */ + +/* Bit 12 : Level of the IO2 pin (if connected) during transmission of custom instruction. */ +#define QSPI_CINSTRCONF_LIO2_Pos (12UL) /*!< Position of LIO2 field. */ +#define QSPI_CINSTRCONF_LIO2_Msk (0x1UL << QSPI_CINSTRCONF_LIO2_Pos) /*!< Bit mask of LIO2 field. */ + +/* Bits 11..8 : Length of custom instruction in number of bytes. */ +#define QSPI_CINSTRCONF_LENGTH_Pos (8UL) /*!< Position of LENGTH field. */ +#define QSPI_CINSTRCONF_LENGTH_Msk (0xFUL << QSPI_CINSTRCONF_LENGTH_Pos) /*!< Bit mask of LENGTH field. */ +#define QSPI_CINSTRCONF_LENGTH_1B (1UL) /*!< Send opcode only. */ +#define QSPI_CINSTRCONF_LENGTH_2B (2UL) /*!< Send opcode, CINSTRDAT0.BYTE0. */ +#define QSPI_CINSTRCONF_LENGTH_3B (3UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE1. */ +#define QSPI_CINSTRCONF_LENGTH_4B (4UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE2. */ +#define QSPI_CINSTRCONF_LENGTH_5B (5UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE3. */ +#define QSPI_CINSTRCONF_LENGTH_6B (6UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE4. */ +#define QSPI_CINSTRCONF_LENGTH_7B (7UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE5. */ +#define QSPI_CINSTRCONF_LENGTH_8B (8UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE6. */ +#define QSPI_CINSTRCONF_LENGTH_9B (9UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE7. */ + +/* Bits 7..0 : Opcode of Custom instruction. */ +#define QSPI_CINSTRCONF_OPCODE_Pos (0UL) /*!< Position of OPCODE field. */ +#define QSPI_CINSTRCONF_OPCODE_Msk (0xFFUL << QSPI_CINSTRCONF_OPCODE_Pos) /*!< Bit mask of OPCODE field. */ + +/* Register: QSPI_CINSTRDAT0 */ +/* Description: Custom instruction data register 0. */ + +/* Bits 31..24 : Data byte 3 */ +#define QSPI_CINSTRDAT0_BYTE3_Pos (24UL) /*!< Position of BYTE3 field. */ +#define QSPI_CINSTRDAT0_BYTE3_Msk (0xFFUL << QSPI_CINSTRDAT0_BYTE3_Pos) /*!< Bit mask of BYTE3 field. */ + +/* Bits 23..16 : Data byte 2 */ +#define QSPI_CINSTRDAT0_BYTE2_Pos (16UL) /*!< Position of BYTE2 field. */ +#define QSPI_CINSTRDAT0_BYTE2_Msk (0xFFUL << QSPI_CINSTRDAT0_BYTE2_Pos) /*!< Bit mask of BYTE2 field. */ + +/* Bits 15..8 : Data byte 1 */ +#define QSPI_CINSTRDAT0_BYTE1_Pos (8UL) /*!< Position of BYTE1 field. */ +#define QSPI_CINSTRDAT0_BYTE1_Msk (0xFFUL << QSPI_CINSTRDAT0_BYTE1_Pos) /*!< Bit mask of BYTE1 field. */ + +/* Bits 7..0 : Data byte 0 */ +#define QSPI_CINSTRDAT0_BYTE0_Pos (0UL) /*!< Position of BYTE0 field. */ +#define QSPI_CINSTRDAT0_BYTE0_Msk (0xFFUL << QSPI_CINSTRDAT0_BYTE0_Pos) /*!< Bit mask of BYTE0 field. */ + +/* Register: QSPI_CINSTRDAT1 */ +/* Description: Custom instruction data register 1. */ + +/* Bits 31..24 : Data byte 7 */ +#define QSPI_CINSTRDAT1_BYTE7_Pos (24UL) /*!< Position of BYTE7 field. */ +#define QSPI_CINSTRDAT1_BYTE7_Msk (0xFFUL << QSPI_CINSTRDAT1_BYTE7_Pos) /*!< Bit mask of BYTE7 field. */ + +/* Bits 23..16 : Data byte 6 */ +#define QSPI_CINSTRDAT1_BYTE6_Pos (16UL) /*!< Position of BYTE6 field. */ +#define QSPI_CINSTRDAT1_BYTE6_Msk (0xFFUL << QSPI_CINSTRDAT1_BYTE6_Pos) /*!< Bit mask of BYTE6 field. */ + +/* Bits 15..8 : Data byte 5 */ +#define QSPI_CINSTRDAT1_BYTE5_Pos (8UL) /*!< Position of BYTE5 field. */ +#define QSPI_CINSTRDAT1_BYTE5_Msk (0xFFUL << QSPI_CINSTRDAT1_BYTE5_Pos) /*!< Bit mask of BYTE5 field. */ + +/* Bits 7..0 : Data byte 4 */ +#define QSPI_CINSTRDAT1_BYTE4_Pos (0UL) /*!< Position of BYTE4 field. */ +#define QSPI_CINSTRDAT1_BYTE4_Msk (0xFFUL << QSPI_CINSTRDAT1_BYTE4_Pos) /*!< Bit mask of BYTE4 field. */ + +/* Register: QSPI_IFTIMING */ +/* Description: SPI interface timing. */ + +/* Bits 10..8 : Timing related to sampling of the input serial data. The value of RXDELAY specifies the number of 64 MHz cycles (15.625 ns) delay from the the rising edge of the SPI Clock (SCK) until the input serial data is sampled. As en example, if set to 0 the input serial data is sampled on the rising edge of SCK. */ +#define QSPI_IFTIMING_RXDELAY_Pos (8UL) /*!< Position of RXDELAY field. */ +#define QSPI_IFTIMING_RXDELAY_Msk (0x7UL << QSPI_IFTIMING_RXDELAY_Pos) /*!< Bit mask of RXDELAY field. */ + + +/* Peripheral: RADIO */ +/* Description: 2.4 GHz Radio */ + +/* Register: RADIO_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 19 : Shortcut between RXREADY event and START task */ +#define RADIO_SHORTS_RXREADY_START_Pos (19UL) /*!< Position of RXREADY_START field. */ +#define RADIO_SHORTS_RXREADY_START_Msk (0x1UL << RADIO_SHORTS_RXREADY_START_Pos) /*!< Bit mask of RXREADY_START field. */ +#define RADIO_SHORTS_RXREADY_START_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_RXREADY_START_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 18 : Shortcut between TXREADY event and START task */ +#define RADIO_SHORTS_TXREADY_START_Pos (18UL) /*!< Position of TXREADY_START field. */ +#define RADIO_SHORTS_TXREADY_START_Msk (0x1UL << RADIO_SHORTS_TXREADY_START_Pos) /*!< Bit mask of TXREADY_START field. */ +#define RADIO_SHORTS_TXREADY_START_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_TXREADY_START_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 17 : Shortcut between CCAIDLE event and STOP task */ +#define RADIO_SHORTS_CCAIDLE_STOP_Pos (17UL) /*!< Position of CCAIDLE_STOP field. */ +#define RADIO_SHORTS_CCAIDLE_STOP_Msk (0x1UL << RADIO_SHORTS_CCAIDLE_STOP_Pos) /*!< Bit mask of CCAIDLE_STOP field. */ +#define RADIO_SHORTS_CCAIDLE_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_CCAIDLE_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 16 : Shortcut between EDEND event and DISABLE task */ +#define RADIO_SHORTS_EDEND_DISABLE_Pos (16UL) /*!< Position of EDEND_DISABLE field. */ +#define RADIO_SHORTS_EDEND_DISABLE_Msk (0x1UL << RADIO_SHORTS_EDEND_DISABLE_Pos) /*!< Bit mask of EDEND_DISABLE field. */ +#define RADIO_SHORTS_EDEND_DISABLE_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_EDEND_DISABLE_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 15 : Shortcut between READY event and EDSTART task */ +#define RADIO_SHORTS_READY_EDSTART_Pos (15UL) /*!< Position of READY_EDSTART field. */ +#define RADIO_SHORTS_READY_EDSTART_Msk (0x1UL << RADIO_SHORTS_READY_EDSTART_Pos) /*!< Bit mask of READY_EDSTART field. */ +#define RADIO_SHORTS_READY_EDSTART_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_READY_EDSTART_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 14 : Shortcut between FRAMESTART event and BCSTART task */ +#define RADIO_SHORTS_FRAMESTART_BCSTART_Pos (14UL) /*!< Position of FRAMESTART_BCSTART field. */ +#define RADIO_SHORTS_FRAMESTART_BCSTART_Msk (0x1UL << RADIO_SHORTS_FRAMESTART_BCSTART_Pos) /*!< Bit mask of FRAMESTART_BCSTART field. */ +#define RADIO_SHORTS_FRAMESTART_BCSTART_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_FRAMESTART_BCSTART_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 13 : Shortcut between CCABUSY event and DISABLE task */ +#define RADIO_SHORTS_CCABUSY_DISABLE_Pos (13UL) /*!< Position of CCABUSY_DISABLE field. */ +#define RADIO_SHORTS_CCABUSY_DISABLE_Msk (0x1UL << RADIO_SHORTS_CCABUSY_DISABLE_Pos) /*!< Bit mask of CCABUSY_DISABLE field. */ +#define RADIO_SHORTS_CCABUSY_DISABLE_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_CCABUSY_DISABLE_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 12 : Shortcut between CCAIDLE event and TXEN task */ +#define RADIO_SHORTS_CCAIDLE_TXEN_Pos (12UL) /*!< Position of CCAIDLE_TXEN field. */ +#define RADIO_SHORTS_CCAIDLE_TXEN_Msk (0x1UL << RADIO_SHORTS_CCAIDLE_TXEN_Pos) /*!< Bit mask of CCAIDLE_TXEN field. */ +#define RADIO_SHORTS_CCAIDLE_TXEN_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_CCAIDLE_TXEN_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 11 : Shortcut between RXREADY event and CCASTART task */ +#define RADIO_SHORTS_RXREADY_CCASTART_Pos (11UL) /*!< Position of RXREADY_CCASTART field. */ +#define RADIO_SHORTS_RXREADY_CCASTART_Msk (0x1UL << RADIO_SHORTS_RXREADY_CCASTART_Pos) /*!< Bit mask of RXREADY_CCASTART field. */ +#define RADIO_SHORTS_RXREADY_CCASTART_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_RXREADY_CCASTART_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 8 : Shortcut between DISABLED event and RSSISTOP task */ +#define RADIO_SHORTS_DISABLED_RSSISTOP_Pos (8UL) /*!< Position of DISABLED_RSSISTOP field. */ +#define RADIO_SHORTS_DISABLED_RSSISTOP_Msk (0x1UL << RADIO_SHORTS_DISABLED_RSSISTOP_Pos) /*!< Bit mask of DISABLED_RSSISTOP field. */ +#define RADIO_SHORTS_DISABLED_RSSISTOP_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_DISABLED_RSSISTOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 6 : Shortcut between ADDRESS event and BCSTART task */ +#define RADIO_SHORTS_ADDRESS_BCSTART_Pos (6UL) /*!< Position of ADDRESS_BCSTART field. */ +#define RADIO_SHORTS_ADDRESS_BCSTART_Msk (0x1UL << RADIO_SHORTS_ADDRESS_BCSTART_Pos) /*!< Bit mask of ADDRESS_BCSTART field. */ +#define RADIO_SHORTS_ADDRESS_BCSTART_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_ADDRESS_BCSTART_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 5 : Shortcut between END event and START task */ +#define RADIO_SHORTS_END_START_Pos (5UL) /*!< Position of END_START field. */ +#define RADIO_SHORTS_END_START_Msk (0x1UL << RADIO_SHORTS_END_START_Pos) /*!< Bit mask of END_START field. */ +#define RADIO_SHORTS_END_START_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_END_START_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 4 : Shortcut between ADDRESS event and RSSISTART task */ +#define RADIO_SHORTS_ADDRESS_RSSISTART_Pos (4UL) /*!< Position of ADDRESS_RSSISTART field. */ +#define RADIO_SHORTS_ADDRESS_RSSISTART_Msk (0x1UL << RADIO_SHORTS_ADDRESS_RSSISTART_Pos) /*!< Bit mask of ADDRESS_RSSISTART field. */ +#define RADIO_SHORTS_ADDRESS_RSSISTART_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_ADDRESS_RSSISTART_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between DISABLED event and RXEN task */ +#define RADIO_SHORTS_DISABLED_RXEN_Pos (3UL) /*!< Position of DISABLED_RXEN field. */ +#define RADIO_SHORTS_DISABLED_RXEN_Msk (0x1UL << RADIO_SHORTS_DISABLED_RXEN_Pos) /*!< Bit mask of DISABLED_RXEN field. */ +#define RADIO_SHORTS_DISABLED_RXEN_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_DISABLED_RXEN_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 2 : Shortcut between DISABLED event and TXEN task */ +#define RADIO_SHORTS_DISABLED_TXEN_Pos (2UL) /*!< Position of DISABLED_TXEN field. */ +#define RADIO_SHORTS_DISABLED_TXEN_Msk (0x1UL << RADIO_SHORTS_DISABLED_TXEN_Pos) /*!< Bit mask of DISABLED_TXEN field. */ +#define RADIO_SHORTS_DISABLED_TXEN_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_DISABLED_TXEN_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between END event and DISABLE task */ +#define RADIO_SHORTS_END_DISABLE_Pos (1UL) /*!< Position of END_DISABLE field. */ +#define RADIO_SHORTS_END_DISABLE_Msk (0x1UL << RADIO_SHORTS_END_DISABLE_Pos) /*!< Bit mask of END_DISABLE field. */ +#define RADIO_SHORTS_END_DISABLE_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_END_DISABLE_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between READY event and START task */ +#define RADIO_SHORTS_READY_START_Pos (0UL) /*!< Position of READY_START field. */ +#define RADIO_SHORTS_READY_START_Msk (0x1UL << RADIO_SHORTS_READY_START_Pos) /*!< Bit mask of READY_START field. */ +#define RADIO_SHORTS_READY_START_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_READY_START_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: RADIO_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 23 : Write '1' to Enable interrupt for MHRMATCH event */ +#define RADIO_INTENSET_MHRMATCH_Pos (23UL) /*!< Position of MHRMATCH field. */ +#define RADIO_INTENSET_MHRMATCH_Msk (0x1UL << RADIO_INTENSET_MHRMATCH_Pos) /*!< Bit mask of MHRMATCH field. */ +#define RADIO_INTENSET_MHRMATCH_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_MHRMATCH_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_MHRMATCH_Set (1UL) /*!< Enable */ + +/* Bit 22 : Write '1' to Enable interrupt for RXREADY event */ +#define RADIO_INTENSET_RXREADY_Pos (22UL) /*!< Position of RXREADY field. */ +#define RADIO_INTENSET_RXREADY_Msk (0x1UL << RADIO_INTENSET_RXREADY_Pos) /*!< Bit mask of RXREADY field. */ +#define RADIO_INTENSET_RXREADY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_RXREADY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_RXREADY_Set (1UL) /*!< Enable */ + +/* Bit 21 : Write '1' to Enable interrupt for TXREADY event */ +#define RADIO_INTENSET_TXREADY_Pos (21UL) /*!< Position of TXREADY field. */ +#define RADIO_INTENSET_TXREADY_Msk (0x1UL << RADIO_INTENSET_TXREADY_Pos) /*!< Bit mask of TXREADY field. */ +#define RADIO_INTENSET_TXREADY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_TXREADY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_TXREADY_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for RATEBOOST event */ +#define RADIO_INTENSET_RATEBOOST_Pos (20UL) /*!< Position of RATEBOOST field. */ +#define RADIO_INTENSET_RATEBOOST_Msk (0x1UL << RADIO_INTENSET_RATEBOOST_Pos) /*!< Bit mask of RATEBOOST field. */ +#define RADIO_INTENSET_RATEBOOST_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_RATEBOOST_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_RATEBOOST_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for CCASTOPPED event */ +#define RADIO_INTENSET_CCASTOPPED_Pos (19UL) /*!< Position of CCASTOPPED field. */ +#define RADIO_INTENSET_CCASTOPPED_Msk (0x1UL << RADIO_INTENSET_CCASTOPPED_Pos) /*!< Bit mask of CCASTOPPED field. */ +#define RADIO_INTENSET_CCASTOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_CCASTOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_CCASTOPPED_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for CCABUSY event */ +#define RADIO_INTENSET_CCABUSY_Pos (18UL) /*!< Position of CCABUSY field. */ +#define RADIO_INTENSET_CCABUSY_Msk (0x1UL << RADIO_INTENSET_CCABUSY_Pos) /*!< Bit mask of CCABUSY field. */ +#define RADIO_INTENSET_CCABUSY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_CCABUSY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_CCABUSY_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable interrupt for CCAIDLE event */ +#define RADIO_INTENSET_CCAIDLE_Pos (17UL) /*!< Position of CCAIDLE field. */ +#define RADIO_INTENSET_CCAIDLE_Msk (0x1UL << RADIO_INTENSET_CCAIDLE_Pos) /*!< Bit mask of CCAIDLE field. */ +#define RADIO_INTENSET_CCAIDLE_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_CCAIDLE_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_CCAIDLE_Set (1UL) /*!< Enable */ + +/* Bit 16 : Write '1' to Enable interrupt for EDSTOPPED event */ +#define RADIO_INTENSET_EDSTOPPED_Pos (16UL) /*!< Position of EDSTOPPED field. */ +#define RADIO_INTENSET_EDSTOPPED_Msk (0x1UL << RADIO_INTENSET_EDSTOPPED_Pos) /*!< Bit mask of EDSTOPPED field. */ +#define RADIO_INTENSET_EDSTOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_EDSTOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_EDSTOPPED_Set (1UL) /*!< Enable */ + +/* Bit 15 : Write '1' to Enable interrupt for EDEND event */ +#define RADIO_INTENSET_EDEND_Pos (15UL) /*!< Position of EDEND field. */ +#define RADIO_INTENSET_EDEND_Msk (0x1UL << RADIO_INTENSET_EDEND_Pos) /*!< Bit mask of EDEND field. */ +#define RADIO_INTENSET_EDEND_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_EDEND_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_EDEND_Set (1UL) /*!< Enable */ + +/* Bit 14 : Write '1' to Enable interrupt for FRAMESTART event */ +#define RADIO_INTENSET_FRAMESTART_Pos (14UL) /*!< Position of FRAMESTART field. */ +#define RADIO_INTENSET_FRAMESTART_Msk (0x1UL << RADIO_INTENSET_FRAMESTART_Pos) /*!< Bit mask of FRAMESTART field. */ +#define RADIO_INTENSET_FRAMESTART_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_FRAMESTART_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_FRAMESTART_Set (1UL) /*!< Enable */ + +/* Bit 13 : Write '1' to Enable interrupt for CRCERROR event */ +#define RADIO_INTENSET_CRCERROR_Pos (13UL) /*!< Position of CRCERROR field. */ +#define RADIO_INTENSET_CRCERROR_Msk (0x1UL << RADIO_INTENSET_CRCERROR_Pos) /*!< Bit mask of CRCERROR field. */ +#define RADIO_INTENSET_CRCERROR_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_CRCERROR_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_CRCERROR_Set (1UL) /*!< Enable */ + +/* Bit 12 : Write '1' to Enable interrupt for CRCOK event */ +#define RADIO_INTENSET_CRCOK_Pos (12UL) /*!< Position of CRCOK field. */ +#define RADIO_INTENSET_CRCOK_Msk (0x1UL << RADIO_INTENSET_CRCOK_Pos) /*!< Bit mask of CRCOK field. */ +#define RADIO_INTENSET_CRCOK_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_CRCOK_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_CRCOK_Set (1UL) /*!< Enable */ + +/* Bit 10 : Write '1' to Enable interrupt for BCMATCH event */ +#define RADIO_INTENSET_BCMATCH_Pos (10UL) /*!< Position of BCMATCH field. */ +#define RADIO_INTENSET_BCMATCH_Msk (0x1UL << RADIO_INTENSET_BCMATCH_Pos) /*!< Bit mask of BCMATCH field. */ +#define RADIO_INTENSET_BCMATCH_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_BCMATCH_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_BCMATCH_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for RSSIEND event */ +#define RADIO_INTENSET_RSSIEND_Pos (7UL) /*!< Position of RSSIEND field. */ +#define RADIO_INTENSET_RSSIEND_Msk (0x1UL << RADIO_INTENSET_RSSIEND_Pos) /*!< Bit mask of RSSIEND field. */ +#define RADIO_INTENSET_RSSIEND_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_RSSIEND_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_RSSIEND_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for DEVMISS event */ +#define RADIO_INTENSET_DEVMISS_Pos (6UL) /*!< Position of DEVMISS field. */ +#define RADIO_INTENSET_DEVMISS_Msk (0x1UL << RADIO_INTENSET_DEVMISS_Pos) /*!< Bit mask of DEVMISS field. */ +#define RADIO_INTENSET_DEVMISS_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_DEVMISS_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_DEVMISS_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for DEVMATCH event */ +#define RADIO_INTENSET_DEVMATCH_Pos (5UL) /*!< Position of DEVMATCH field. */ +#define RADIO_INTENSET_DEVMATCH_Msk (0x1UL << RADIO_INTENSET_DEVMATCH_Pos) /*!< Bit mask of DEVMATCH field. */ +#define RADIO_INTENSET_DEVMATCH_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_DEVMATCH_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_DEVMATCH_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for DISABLED event */ +#define RADIO_INTENSET_DISABLED_Pos (4UL) /*!< Position of DISABLED field. */ +#define RADIO_INTENSET_DISABLED_Msk (0x1UL << RADIO_INTENSET_DISABLED_Pos) /*!< Bit mask of DISABLED field. */ +#define RADIO_INTENSET_DISABLED_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_DISABLED_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_DISABLED_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for END event */ +#define RADIO_INTENSET_END_Pos (3UL) /*!< Position of END field. */ +#define RADIO_INTENSET_END_Msk (0x1UL << RADIO_INTENSET_END_Pos) /*!< Bit mask of END field. */ +#define RADIO_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_END_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for PAYLOAD event */ +#define RADIO_INTENSET_PAYLOAD_Pos (2UL) /*!< Position of PAYLOAD field. */ +#define RADIO_INTENSET_PAYLOAD_Msk (0x1UL << RADIO_INTENSET_PAYLOAD_Pos) /*!< Bit mask of PAYLOAD field. */ +#define RADIO_INTENSET_PAYLOAD_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_PAYLOAD_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_PAYLOAD_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for ADDRESS event */ +#define RADIO_INTENSET_ADDRESS_Pos (1UL) /*!< Position of ADDRESS field. */ +#define RADIO_INTENSET_ADDRESS_Msk (0x1UL << RADIO_INTENSET_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */ +#define RADIO_INTENSET_ADDRESS_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_ADDRESS_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_ADDRESS_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for READY event */ +#define RADIO_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */ +#define RADIO_INTENSET_READY_Msk (0x1UL << RADIO_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ +#define RADIO_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_READY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_READY_Set (1UL) /*!< Enable */ + +/* Register: RADIO_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 23 : Write '1' to Disable interrupt for MHRMATCH event */ +#define RADIO_INTENCLR_MHRMATCH_Pos (23UL) /*!< Position of MHRMATCH field. */ +#define RADIO_INTENCLR_MHRMATCH_Msk (0x1UL << RADIO_INTENCLR_MHRMATCH_Pos) /*!< Bit mask of MHRMATCH field. */ +#define RADIO_INTENCLR_MHRMATCH_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_MHRMATCH_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_MHRMATCH_Clear (1UL) /*!< Disable */ + +/* Bit 22 : Write '1' to Disable interrupt for RXREADY event */ +#define RADIO_INTENCLR_RXREADY_Pos (22UL) /*!< Position of RXREADY field. */ +#define RADIO_INTENCLR_RXREADY_Msk (0x1UL << RADIO_INTENCLR_RXREADY_Pos) /*!< Bit mask of RXREADY field. */ +#define RADIO_INTENCLR_RXREADY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_RXREADY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_RXREADY_Clear (1UL) /*!< Disable */ + +/* Bit 21 : Write '1' to Disable interrupt for TXREADY event */ +#define RADIO_INTENCLR_TXREADY_Pos (21UL) /*!< Position of TXREADY field. */ +#define RADIO_INTENCLR_TXREADY_Msk (0x1UL << RADIO_INTENCLR_TXREADY_Pos) /*!< Bit mask of TXREADY field. */ +#define RADIO_INTENCLR_TXREADY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_TXREADY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_TXREADY_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for RATEBOOST event */ +#define RADIO_INTENCLR_RATEBOOST_Pos (20UL) /*!< Position of RATEBOOST field. */ +#define RADIO_INTENCLR_RATEBOOST_Msk (0x1UL << RADIO_INTENCLR_RATEBOOST_Pos) /*!< Bit mask of RATEBOOST field. */ +#define RADIO_INTENCLR_RATEBOOST_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_RATEBOOST_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_RATEBOOST_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for CCASTOPPED event */ +#define RADIO_INTENCLR_CCASTOPPED_Pos (19UL) /*!< Position of CCASTOPPED field. */ +#define RADIO_INTENCLR_CCASTOPPED_Msk (0x1UL << RADIO_INTENCLR_CCASTOPPED_Pos) /*!< Bit mask of CCASTOPPED field. */ +#define RADIO_INTENCLR_CCASTOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_CCASTOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_CCASTOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for CCABUSY event */ +#define RADIO_INTENCLR_CCABUSY_Pos (18UL) /*!< Position of CCABUSY field. */ +#define RADIO_INTENCLR_CCABUSY_Msk (0x1UL << RADIO_INTENCLR_CCABUSY_Pos) /*!< Bit mask of CCABUSY field. */ +#define RADIO_INTENCLR_CCABUSY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_CCABUSY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_CCABUSY_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable interrupt for CCAIDLE event */ +#define RADIO_INTENCLR_CCAIDLE_Pos (17UL) /*!< Position of CCAIDLE field. */ +#define RADIO_INTENCLR_CCAIDLE_Msk (0x1UL << RADIO_INTENCLR_CCAIDLE_Pos) /*!< Bit mask of CCAIDLE field. */ +#define RADIO_INTENCLR_CCAIDLE_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_CCAIDLE_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_CCAIDLE_Clear (1UL) /*!< Disable */ + +/* Bit 16 : Write '1' to Disable interrupt for EDSTOPPED event */ +#define RADIO_INTENCLR_EDSTOPPED_Pos (16UL) /*!< Position of EDSTOPPED field. */ +#define RADIO_INTENCLR_EDSTOPPED_Msk (0x1UL << RADIO_INTENCLR_EDSTOPPED_Pos) /*!< Bit mask of EDSTOPPED field. */ +#define RADIO_INTENCLR_EDSTOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_EDSTOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_EDSTOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 15 : Write '1' to Disable interrupt for EDEND event */ +#define RADIO_INTENCLR_EDEND_Pos (15UL) /*!< Position of EDEND field. */ +#define RADIO_INTENCLR_EDEND_Msk (0x1UL << RADIO_INTENCLR_EDEND_Pos) /*!< Bit mask of EDEND field. */ +#define RADIO_INTENCLR_EDEND_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_EDEND_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_EDEND_Clear (1UL) /*!< Disable */ + +/* Bit 14 : Write '1' to Disable interrupt for FRAMESTART event */ +#define RADIO_INTENCLR_FRAMESTART_Pos (14UL) /*!< Position of FRAMESTART field. */ +#define RADIO_INTENCLR_FRAMESTART_Msk (0x1UL << RADIO_INTENCLR_FRAMESTART_Pos) /*!< Bit mask of FRAMESTART field. */ +#define RADIO_INTENCLR_FRAMESTART_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_FRAMESTART_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_FRAMESTART_Clear (1UL) /*!< Disable */ + +/* Bit 13 : Write '1' to Disable interrupt for CRCERROR event */ +#define RADIO_INTENCLR_CRCERROR_Pos (13UL) /*!< Position of CRCERROR field. */ +#define RADIO_INTENCLR_CRCERROR_Msk (0x1UL << RADIO_INTENCLR_CRCERROR_Pos) /*!< Bit mask of CRCERROR field. */ +#define RADIO_INTENCLR_CRCERROR_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_CRCERROR_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_CRCERROR_Clear (1UL) /*!< Disable */ + +/* Bit 12 : Write '1' to Disable interrupt for CRCOK event */ +#define RADIO_INTENCLR_CRCOK_Pos (12UL) /*!< Position of CRCOK field. */ +#define RADIO_INTENCLR_CRCOK_Msk (0x1UL << RADIO_INTENCLR_CRCOK_Pos) /*!< Bit mask of CRCOK field. */ +#define RADIO_INTENCLR_CRCOK_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_CRCOK_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_CRCOK_Clear (1UL) /*!< Disable */ + +/* Bit 10 : Write '1' to Disable interrupt for BCMATCH event */ +#define RADIO_INTENCLR_BCMATCH_Pos (10UL) /*!< Position of BCMATCH field. */ +#define RADIO_INTENCLR_BCMATCH_Msk (0x1UL << RADIO_INTENCLR_BCMATCH_Pos) /*!< Bit mask of BCMATCH field. */ +#define RADIO_INTENCLR_BCMATCH_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_BCMATCH_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_BCMATCH_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for RSSIEND event */ +#define RADIO_INTENCLR_RSSIEND_Pos (7UL) /*!< Position of RSSIEND field. */ +#define RADIO_INTENCLR_RSSIEND_Msk (0x1UL << RADIO_INTENCLR_RSSIEND_Pos) /*!< Bit mask of RSSIEND field. */ +#define RADIO_INTENCLR_RSSIEND_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_RSSIEND_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_RSSIEND_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for DEVMISS event */ +#define RADIO_INTENCLR_DEVMISS_Pos (6UL) /*!< Position of DEVMISS field. */ +#define RADIO_INTENCLR_DEVMISS_Msk (0x1UL << RADIO_INTENCLR_DEVMISS_Pos) /*!< Bit mask of DEVMISS field. */ +#define RADIO_INTENCLR_DEVMISS_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_DEVMISS_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_DEVMISS_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for DEVMATCH event */ +#define RADIO_INTENCLR_DEVMATCH_Pos (5UL) /*!< Position of DEVMATCH field. */ +#define RADIO_INTENCLR_DEVMATCH_Msk (0x1UL << RADIO_INTENCLR_DEVMATCH_Pos) /*!< Bit mask of DEVMATCH field. */ +#define RADIO_INTENCLR_DEVMATCH_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_DEVMATCH_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_DEVMATCH_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for DISABLED event */ +#define RADIO_INTENCLR_DISABLED_Pos (4UL) /*!< Position of DISABLED field. */ +#define RADIO_INTENCLR_DISABLED_Msk (0x1UL << RADIO_INTENCLR_DISABLED_Pos) /*!< Bit mask of DISABLED field. */ +#define RADIO_INTENCLR_DISABLED_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_DISABLED_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_DISABLED_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for END event */ +#define RADIO_INTENCLR_END_Pos (3UL) /*!< Position of END field. */ +#define RADIO_INTENCLR_END_Msk (0x1UL << RADIO_INTENCLR_END_Pos) /*!< Bit mask of END field. */ +#define RADIO_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_END_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for PAYLOAD event */ +#define RADIO_INTENCLR_PAYLOAD_Pos (2UL) /*!< Position of PAYLOAD field. */ +#define RADIO_INTENCLR_PAYLOAD_Msk (0x1UL << RADIO_INTENCLR_PAYLOAD_Pos) /*!< Bit mask of PAYLOAD field. */ +#define RADIO_INTENCLR_PAYLOAD_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_PAYLOAD_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_PAYLOAD_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for ADDRESS event */ +#define RADIO_INTENCLR_ADDRESS_Pos (1UL) /*!< Position of ADDRESS field. */ +#define RADIO_INTENCLR_ADDRESS_Msk (0x1UL << RADIO_INTENCLR_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */ +#define RADIO_INTENCLR_ADDRESS_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_ADDRESS_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_ADDRESS_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for READY event */ +#define RADIO_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */ +#define RADIO_INTENCLR_READY_Msk (0x1UL << RADIO_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ +#define RADIO_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_READY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_READY_Clear (1UL) /*!< Disable */ + +/* Register: RADIO_CRCSTATUS */ +/* Description: CRC status */ + +/* Bit 0 : CRC status of packet received */ +#define RADIO_CRCSTATUS_CRCSTATUS_Pos (0UL) /*!< Position of CRCSTATUS field. */ +#define RADIO_CRCSTATUS_CRCSTATUS_Msk (0x1UL << RADIO_CRCSTATUS_CRCSTATUS_Pos) /*!< Bit mask of CRCSTATUS field. */ +#define RADIO_CRCSTATUS_CRCSTATUS_CRCError (0UL) /*!< Packet received with CRC error */ +#define RADIO_CRCSTATUS_CRCSTATUS_CRCOk (1UL) /*!< Packet received with CRC ok */ + +/* Register: RADIO_RXMATCH */ +/* Description: Received address */ + +/* Bits 2..0 : Received address */ +#define RADIO_RXMATCH_RXMATCH_Pos (0UL) /*!< Position of RXMATCH field. */ +#define RADIO_RXMATCH_RXMATCH_Msk (0x7UL << RADIO_RXMATCH_RXMATCH_Pos) /*!< Bit mask of RXMATCH field. */ + +/* Register: RADIO_RXCRC */ +/* Description: CRC field of previously received packet */ + +/* Bits 23..0 : CRC field of previously received packet */ +#define RADIO_RXCRC_RXCRC_Pos (0UL) /*!< Position of RXCRC field. */ +#define RADIO_RXCRC_RXCRC_Msk (0xFFFFFFUL << RADIO_RXCRC_RXCRC_Pos) /*!< Bit mask of RXCRC field. */ + +/* Register: RADIO_DAI */ +/* Description: Device address match index */ + +/* Bits 2..0 : Device address match index */ +#define RADIO_DAI_DAI_Pos (0UL) /*!< Position of DAI field. */ +#define RADIO_DAI_DAI_Msk (0x7UL << RADIO_DAI_DAI_Pos) /*!< Bit mask of DAI field. */ + +/* Register: RADIO_PACKETPTR */ +/* Description: Packet pointer */ + +/* Bits 31..0 : Packet pointer */ +#define RADIO_PACKETPTR_PACKETPTR_Pos (0UL) /*!< Position of PACKETPTR field. */ +#define RADIO_PACKETPTR_PACKETPTR_Msk (0xFFFFFFFFUL << RADIO_PACKETPTR_PACKETPTR_Pos) /*!< Bit mask of PACKETPTR field. */ + +/* Register: RADIO_FREQUENCY */ +/* Description: Frequency */ + +/* Bit 8 : Channel map selection. */ +#define RADIO_FREQUENCY_MAP_Pos (8UL) /*!< Position of MAP field. */ +#define RADIO_FREQUENCY_MAP_Msk (0x1UL << RADIO_FREQUENCY_MAP_Pos) /*!< Bit mask of MAP field. */ +#define RADIO_FREQUENCY_MAP_Default (0UL) /*!< Channel map between 2400 MHZ .. 2500 MHz */ +#define RADIO_FREQUENCY_MAP_Low (1UL) /*!< Channel map between 2360 MHZ .. 2460 MHz */ + +/* Bits 6..0 : Radio channel frequency */ +#define RADIO_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */ +#define RADIO_FREQUENCY_FREQUENCY_Msk (0x7FUL << RADIO_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */ + +/* Register: RADIO_TXPOWER */ +/* Description: Output power */ + +/* Bits 7..0 : RADIO output power. */ +#define RADIO_TXPOWER_TXPOWER_Pos (0UL) /*!< Position of TXPOWER field. */ +#define RADIO_TXPOWER_TXPOWER_Msk (0xFFUL << RADIO_TXPOWER_TXPOWER_Pos) /*!< Bit mask of TXPOWER field. */ +#define RADIO_TXPOWER_TXPOWER_0dBm (0x0UL) /*!< 0 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos2dBm (0x2UL) /*!< +2 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos3dBm (0x3UL) /*!< +3 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos4dBm (0x4UL) /*!< +4 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos5dBm (0x5UL) /*!< +5 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos6dBm (0x6UL) /*!< +6 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos7dBm (0x7UL) /*!< +7 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos8dBm (0x8UL) /*!< +8 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos9dBm (0x9UL) /*!< +9 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg30dBm (0xD8UL) /*!< Deprecated enumerator - -40 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg40dBm (0xD8UL) /*!< -40 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg20dBm (0xECUL) /*!< -20 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg16dBm (0xF0UL) /*!< -16 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg12dBm (0xF4UL) /*!< -12 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg8dBm (0xF8UL) /*!< -8 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg4dBm (0xFCUL) /*!< -4 dBm */ + +/* Register: RADIO_MODE */ +/* Description: Data rate and modulation */ + +/* Bits 3..0 : Radio data rate and modulation setting. The radio supports Frequency-shift Keying (FSK) modulation. */ +#define RADIO_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */ +#define RADIO_MODE_MODE_Msk (0xFUL << RADIO_MODE_MODE_Pos) /*!< Bit mask of MODE field. */ +#define RADIO_MODE_MODE_Nrf_1Mbit (0UL) /*!< 1 Mbit/s Nordic proprietary radio mode */ +#define RADIO_MODE_MODE_Nrf_2Mbit (1UL) /*!< 2 Mbit/s Nordic proprietary radio mode */ +#define RADIO_MODE_MODE_Nrf_250Kbit (2UL) /*!< Deprecated enumerator - 250 kbit/s Nordic proprietary radio mode */ +#define RADIO_MODE_MODE_Ble_1Mbit (3UL) /*!< 1 Mbit/s Bluetooth Low Energy */ +#define RADIO_MODE_MODE_Ble_2Mbit (4UL) /*!< 2 Mbit/s Bluetooth Low Energy */ +#define RADIO_MODE_MODE_Ble_LR125Kbit (5UL) /*!< Long range 125 kbit/s (TX Only - RX supports both) */ +#define RADIO_MODE_MODE_Ble_LR500Kbit (6UL) /*!< Long range 500 kbit/s (TX Only - RX supports both) */ +#define RADIO_MODE_MODE_Ieee802154_250Kbit (15UL) /*!< IEEE 802.15.4-2006 250 kbit/s */ + +/* Register: RADIO_PCNF0 */ +/* Description: Packet configuration register 0 */ + +/* Bits 30..29 : Length of TERM field in Long Range operation */ +#define RADIO_PCNF0_TERMLEN_Pos (29UL) /*!< Position of TERMLEN field. */ +#define RADIO_PCNF0_TERMLEN_Msk (0x3UL << RADIO_PCNF0_TERMLEN_Pos) /*!< Bit mask of TERMLEN field. */ + +/* Bit 26 : Indicates if LENGTH field contains CRC or not */ +#define RADIO_PCNF0_CRCINC_Pos (26UL) /*!< Position of CRCINC field. */ +#define RADIO_PCNF0_CRCINC_Msk (0x1UL << RADIO_PCNF0_CRCINC_Pos) /*!< Bit mask of CRCINC field. */ +#define RADIO_PCNF0_CRCINC_Exclude (0UL) /*!< LENGTH does not contain CRC */ +#define RADIO_PCNF0_CRCINC_Include (1UL) /*!< LENGTH includes CRC */ + +/* Bits 25..24 : Length of preamble on air. Decision point: TASKS_START task */ +#define RADIO_PCNF0_PLEN_Pos (24UL) /*!< Position of PLEN field. */ +#define RADIO_PCNF0_PLEN_Msk (0x3UL << RADIO_PCNF0_PLEN_Pos) /*!< Bit mask of PLEN field. */ +#define RADIO_PCNF0_PLEN_8bit (0UL) /*!< 8-bit preamble */ +#define RADIO_PCNF0_PLEN_16bit (1UL) /*!< 16-bit preamble */ +#define RADIO_PCNF0_PLEN_32bitZero (2UL) /*!< 32-bit zero preamble - used for IEEE 802.15.4 */ +#define RADIO_PCNF0_PLEN_LongRange (3UL) /*!< Preamble - used for BTLE Long Range */ + +/* Bits 23..22 : Length of Code Indicator - Long Range */ +#define RADIO_PCNF0_CILEN_Pos (22UL) /*!< Position of CILEN field. */ +#define RADIO_PCNF0_CILEN_Msk (0x3UL << RADIO_PCNF0_CILEN_Pos) /*!< Bit mask of CILEN field. */ + +/* Bit 20 : Include or exclude S1 field in RAM */ +#define RADIO_PCNF0_S1INCL_Pos (20UL) /*!< Position of S1INCL field. */ +#define RADIO_PCNF0_S1INCL_Msk (0x1UL << RADIO_PCNF0_S1INCL_Pos) /*!< Bit mask of S1INCL field. */ +#define RADIO_PCNF0_S1INCL_Automatic (0UL) /*!< Include S1 field in RAM only if S1LEN > 0 */ +#define RADIO_PCNF0_S1INCL_Include (1UL) /*!< Always include S1 field in RAM independent of S1LEN */ + +/* Bits 19..16 : Length on air of S1 field in number of bits. */ +#define RADIO_PCNF0_S1LEN_Pos (16UL) /*!< Position of S1LEN field. */ +#define RADIO_PCNF0_S1LEN_Msk (0xFUL << RADIO_PCNF0_S1LEN_Pos) /*!< Bit mask of S1LEN field. */ + +/* Bit 8 : Length on air of S0 field in number of bytes. */ +#define RADIO_PCNF0_S0LEN_Pos (8UL) /*!< Position of S0LEN field. */ +#define RADIO_PCNF0_S0LEN_Msk (0x1UL << RADIO_PCNF0_S0LEN_Pos) /*!< Bit mask of S0LEN field. */ + +/* Bits 3..0 : Length on air of LENGTH field in number of bits. */ +#define RADIO_PCNF0_LFLEN_Pos (0UL) /*!< Position of LFLEN field. */ +#define RADIO_PCNF0_LFLEN_Msk (0xFUL << RADIO_PCNF0_LFLEN_Pos) /*!< Bit mask of LFLEN field. */ + +/* Register: RADIO_PCNF1 */ +/* Description: Packet configuration register 1 */ + +/* Bit 25 : Enable or disable packet whitening */ +#define RADIO_PCNF1_WHITEEN_Pos (25UL) /*!< Position of WHITEEN field. */ +#define RADIO_PCNF1_WHITEEN_Msk (0x1UL << RADIO_PCNF1_WHITEEN_Pos) /*!< Bit mask of WHITEEN field. */ +#define RADIO_PCNF1_WHITEEN_Disabled (0UL) /*!< Disable */ +#define RADIO_PCNF1_WHITEEN_Enabled (1UL) /*!< Enable */ + +/* Bit 24 : On air endianness of packet, this applies to the S0, LENGTH, S1 and the PAYLOAD fields. */ +#define RADIO_PCNF1_ENDIAN_Pos (24UL) /*!< Position of ENDIAN field. */ +#define RADIO_PCNF1_ENDIAN_Msk (0x1UL << RADIO_PCNF1_ENDIAN_Pos) /*!< Bit mask of ENDIAN field. */ +#define RADIO_PCNF1_ENDIAN_Little (0UL) /*!< Least Significant bit on air first */ +#define RADIO_PCNF1_ENDIAN_Big (1UL) /*!< Most significant bit on air first */ + +/* Bits 18..16 : Base address length in number of bytes */ +#define RADIO_PCNF1_BALEN_Pos (16UL) /*!< Position of BALEN field. */ +#define RADIO_PCNF1_BALEN_Msk (0x7UL << RADIO_PCNF1_BALEN_Pos) /*!< Bit mask of BALEN field. */ + +/* Bits 15..8 : Static length in number of bytes */ +#define RADIO_PCNF1_STATLEN_Pos (8UL) /*!< Position of STATLEN field. */ +#define RADIO_PCNF1_STATLEN_Msk (0xFFUL << RADIO_PCNF1_STATLEN_Pos) /*!< Bit mask of STATLEN field. */ + +/* Bits 7..0 : Maximum length of packet payload. If the packet payload is larger than MAXLEN, the radio will truncate the payload to MAXLEN. */ +#define RADIO_PCNF1_MAXLEN_Pos (0UL) /*!< Position of MAXLEN field. */ +#define RADIO_PCNF1_MAXLEN_Msk (0xFFUL << RADIO_PCNF1_MAXLEN_Pos) /*!< Bit mask of MAXLEN field. */ + +/* Register: RADIO_BASE0 */ +/* Description: Base address 0 */ + +/* Bits 31..0 : Base address 0 */ +#define RADIO_BASE0_BASE0_Pos (0UL) /*!< Position of BASE0 field. */ +#define RADIO_BASE0_BASE0_Msk (0xFFFFFFFFUL << RADIO_BASE0_BASE0_Pos) /*!< Bit mask of BASE0 field. */ + +/* Register: RADIO_BASE1 */ +/* Description: Base address 1 */ + +/* Bits 31..0 : Base address 1 */ +#define RADIO_BASE1_BASE1_Pos (0UL) /*!< Position of BASE1 field. */ +#define RADIO_BASE1_BASE1_Msk (0xFFFFFFFFUL << RADIO_BASE1_BASE1_Pos) /*!< Bit mask of BASE1 field. */ + +/* Register: RADIO_PREFIX0 */ +/* Description: Prefixes bytes for logical addresses 0-3 */ + +/* Bits 31..24 : Address prefix 3. */ +#define RADIO_PREFIX0_AP3_Pos (24UL) /*!< Position of AP3 field. */ +#define RADIO_PREFIX0_AP3_Msk (0xFFUL << RADIO_PREFIX0_AP3_Pos) /*!< Bit mask of AP3 field. */ + +/* Bits 23..16 : Address prefix 2. */ +#define RADIO_PREFIX0_AP2_Pos (16UL) /*!< Position of AP2 field. */ +#define RADIO_PREFIX0_AP2_Msk (0xFFUL << RADIO_PREFIX0_AP2_Pos) /*!< Bit mask of AP2 field. */ + +/* Bits 15..8 : Address prefix 1. */ +#define RADIO_PREFIX0_AP1_Pos (8UL) /*!< Position of AP1 field. */ +#define RADIO_PREFIX0_AP1_Msk (0xFFUL << RADIO_PREFIX0_AP1_Pos) /*!< Bit mask of AP1 field. */ + +/* Bits 7..0 : Address prefix 0. */ +#define RADIO_PREFIX0_AP0_Pos (0UL) /*!< Position of AP0 field. */ +#define RADIO_PREFIX0_AP0_Msk (0xFFUL << RADIO_PREFIX0_AP0_Pos) /*!< Bit mask of AP0 field. */ + +/* Register: RADIO_PREFIX1 */ +/* Description: Prefixes bytes for logical addresses 4-7 */ + +/* Bits 31..24 : Address prefix 7. */ +#define RADIO_PREFIX1_AP7_Pos (24UL) /*!< Position of AP7 field. */ +#define RADIO_PREFIX1_AP7_Msk (0xFFUL << RADIO_PREFIX1_AP7_Pos) /*!< Bit mask of AP7 field. */ + +/* Bits 23..16 : Address prefix 6. */ +#define RADIO_PREFIX1_AP6_Pos (16UL) /*!< Position of AP6 field. */ +#define RADIO_PREFIX1_AP6_Msk (0xFFUL << RADIO_PREFIX1_AP6_Pos) /*!< Bit mask of AP6 field. */ + +/* Bits 15..8 : Address prefix 5. */ +#define RADIO_PREFIX1_AP5_Pos (8UL) /*!< Position of AP5 field. */ +#define RADIO_PREFIX1_AP5_Msk (0xFFUL << RADIO_PREFIX1_AP5_Pos) /*!< Bit mask of AP5 field. */ + +/* Bits 7..0 : Address prefix 4. */ +#define RADIO_PREFIX1_AP4_Pos (0UL) /*!< Position of AP4 field. */ +#define RADIO_PREFIX1_AP4_Msk (0xFFUL << RADIO_PREFIX1_AP4_Pos) /*!< Bit mask of AP4 field. */ + +/* Register: RADIO_TXADDRESS */ +/* Description: Transmit address select */ + +/* Bits 2..0 : Transmit address select */ +#define RADIO_TXADDRESS_TXADDRESS_Pos (0UL) /*!< Position of TXADDRESS field. */ +#define RADIO_TXADDRESS_TXADDRESS_Msk (0x7UL << RADIO_TXADDRESS_TXADDRESS_Pos) /*!< Bit mask of TXADDRESS field. */ + +/* Register: RADIO_RXADDRESSES */ +/* Description: Receive address select */ + +/* Bit 7 : Enable or disable reception on logical address 7. */ +#define RADIO_RXADDRESSES_ADDR7_Pos (7UL) /*!< Position of ADDR7 field. */ +#define RADIO_RXADDRESSES_ADDR7_Msk (0x1UL << RADIO_RXADDRESSES_ADDR7_Pos) /*!< Bit mask of ADDR7 field. */ +#define RADIO_RXADDRESSES_ADDR7_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR7_Enabled (1UL) /*!< Enable */ + +/* Bit 6 : Enable or disable reception on logical address 6. */ +#define RADIO_RXADDRESSES_ADDR6_Pos (6UL) /*!< Position of ADDR6 field. */ +#define RADIO_RXADDRESSES_ADDR6_Msk (0x1UL << RADIO_RXADDRESSES_ADDR6_Pos) /*!< Bit mask of ADDR6 field. */ +#define RADIO_RXADDRESSES_ADDR6_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR6_Enabled (1UL) /*!< Enable */ + +/* Bit 5 : Enable or disable reception on logical address 5. */ +#define RADIO_RXADDRESSES_ADDR5_Pos (5UL) /*!< Position of ADDR5 field. */ +#define RADIO_RXADDRESSES_ADDR5_Msk (0x1UL << RADIO_RXADDRESSES_ADDR5_Pos) /*!< Bit mask of ADDR5 field. */ +#define RADIO_RXADDRESSES_ADDR5_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR5_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable reception on logical address 4. */ +#define RADIO_RXADDRESSES_ADDR4_Pos (4UL) /*!< Position of ADDR4 field. */ +#define RADIO_RXADDRESSES_ADDR4_Msk (0x1UL << RADIO_RXADDRESSES_ADDR4_Pos) /*!< Bit mask of ADDR4 field. */ +#define RADIO_RXADDRESSES_ADDR4_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR4_Enabled (1UL) /*!< Enable */ + +/* Bit 3 : Enable or disable reception on logical address 3. */ +#define RADIO_RXADDRESSES_ADDR3_Pos (3UL) /*!< Position of ADDR3 field. */ +#define RADIO_RXADDRESSES_ADDR3_Msk (0x1UL << RADIO_RXADDRESSES_ADDR3_Pos) /*!< Bit mask of ADDR3 field. */ +#define RADIO_RXADDRESSES_ADDR3_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR3_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable reception on logical address 2. */ +#define RADIO_RXADDRESSES_ADDR2_Pos (2UL) /*!< Position of ADDR2 field. */ +#define RADIO_RXADDRESSES_ADDR2_Msk (0x1UL << RADIO_RXADDRESSES_ADDR2_Pos) /*!< Bit mask of ADDR2 field. */ +#define RADIO_RXADDRESSES_ADDR2_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR2_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable reception on logical address 1. */ +#define RADIO_RXADDRESSES_ADDR1_Pos (1UL) /*!< Position of ADDR1 field. */ +#define RADIO_RXADDRESSES_ADDR1_Msk (0x1UL << RADIO_RXADDRESSES_ADDR1_Pos) /*!< Bit mask of ADDR1 field. */ +#define RADIO_RXADDRESSES_ADDR1_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR1_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable reception on logical address 0. */ +#define RADIO_RXADDRESSES_ADDR0_Pos (0UL) /*!< Position of ADDR0 field. */ +#define RADIO_RXADDRESSES_ADDR0_Msk (0x1UL << RADIO_RXADDRESSES_ADDR0_Pos) /*!< Bit mask of ADDR0 field. */ +#define RADIO_RXADDRESSES_ADDR0_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR0_Enabled (1UL) /*!< Enable */ + +/* Register: RADIO_CRCCNF */ +/* Description: CRC configuration */ + +/* Bits 9..8 : Include or exclude packet address field out of CRC calculation. */ +#define RADIO_CRCCNF_SKIPADDR_Pos (8UL) /*!< Position of SKIPADDR field. */ +#define RADIO_CRCCNF_SKIPADDR_Msk (0x3UL << RADIO_CRCCNF_SKIPADDR_Pos) /*!< Bit mask of SKIPADDR field. */ +#define RADIO_CRCCNF_SKIPADDR_Include (0UL) /*!< CRC calculation includes address field */ +#define RADIO_CRCCNF_SKIPADDR_Skip (1UL) /*!< CRC calculation does not include address field. The CRC calculation will start at the first byte after the address. */ +#define RADIO_CRCCNF_SKIPADDR_Ieee802154 (2UL) /*!< CRC calculation as per 802.15.4 standard. Starting at first byte after length field. */ + +/* Bits 1..0 : CRC length in number of bytes. */ +#define RADIO_CRCCNF_LEN_Pos (0UL) /*!< Position of LEN field. */ +#define RADIO_CRCCNF_LEN_Msk (0x3UL << RADIO_CRCCNF_LEN_Pos) /*!< Bit mask of LEN field. */ +#define RADIO_CRCCNF_LEN_Disabled (0UL) /*!< CRC length is zero and CRC calculation is disabled */ +#define RADIO_CRCCNF_LEN_One (1UL) /*!< CRC length is one byte and CRC calculation is enabled */ +#define RADIO_CRCCNF_LEN_Two (2UL) /*!< CRC length is two bytes and CRC calculation is enabled */ +#define RADIO_CRCCNF_LEN_Three (3UL) /*!< CRC length is three bytes and CRC calculation is enabled */ + +/* Register: RADIO_CRCPOLY */ +/* Description: CRC polynomial */ + +/* Bits 23..0 : CRC polynomial */ +#define RADIO_CRCPOLY_CRCPOLY_Pos (0UL) /*!< Position of CRCPOLY field. */ +#define RADIO_CRCPOLY_CRCPOLY_Msk (0xFFFFFFUL << RADIO_CRCPOLY_CRCPOLY_Pos) /*!< Bit mask of CRCPOLY field. */ + +/* Register: RADIO_CRCINIT */ +/* Description: CRC initial value */ + +/* Bits 23..0 : CRC initial value */ +#define RADIO_CRCINIT_CRCINIT_Pos (0UL) /*!< Position of CRCINIT field. */ +#define RADIO_CRCINIT_CRCINIT_Msk (0xFFFFFFUL << RADIO_CRCINIT_CRCINIT_Pos) /*!< Bit mask of CRCINIT field. */ + +/* Register: RADIO_TIFS */ +/* Description: Inter Frame Spacing in us */ + +/* Bits 9..0 : Inter Frame Spacing in us */ +#define RADIO_TIFS_TIFS_Pos (0UL) /*!< Position of TIFS field. */ +#define RADIO_TIFS_TIFS_Msk (0x3FFUL << RADIO_TIFS_TIFS_Pos) /*!< Bit mask of TIFS field. */ + +/* Register: RADIO_RSSISAMPLE */ +/* Description: RSSI sample */ + +/* Bits 6..0 : RSSI sample */ +#define RADIO_RSSISAMPLE_RSSISAMPLE_Pos (0UL) /*!< Position of RSSISAMPLE field. */ +#define RADIO_RSSISAMPLE_RSSISAMPLE_Msk (0x7FUL << RADIO_RSSISAMPLE_RSSISAMPLE_Pos) /*!< Bit mask of RSSISAMPLE field. */ + +/* Register: RADIO_STATE */ +/* Description: Current radio state */ + +/* Bits 3..0 : Current radio state */ +#define RADIO_STATE_STATE_Pos (0UL) /*!< Position of STATE field. */ +#define RADIO_STATE_STATE_Msk (0xFUL << RADIO_STATE_STATE_Pos) /*!< Bit mask of STATE field. */ +#define RADIO_STATE_STATE_Disabled (0UL) /*!< RADIO is in the Disabled state */ +#define RADIO_STATE_STATE_RxRu (1UL) /*!< RADIO is in the RXRU state */ +#define RADIO_STATE_STATE_RxIdle (2UL) /*!< RADIO is in the RXIDLE state */ +#define RADIO_STATE_STATE_Rx (3UL) /*!< RADIO is in the RX state */ +#define RADIO_STATE_STATE_RxDisable (4UL) /*!< RADIO is in the RXDISABLED state */ +#define RADIO_STATE_STATE_TxRu (9UL) /*!< RADIO is in the TXRU state */ +#define RADIO_STATE_STATE_TxIdle (10UL) /*!< RADIO is in the TXIDLE state */ +#define RADIO_STATE_STATE_Tx (11UL) /*!< RADIO is in the TX state */ +#define RADIO_STATE_STATE_TxDisable (12UL) /*!< RADIO is in the TXDISABLED state */ + +/* Register: RADIO_DATAWHITEIV */ +/* Description: Data whitening initial value */ + +/* Bits 6..0 : Data whitening initial value. Bit 6 is hard-wired to '1', writing '0' to it has no effect, and it will always be read back and used by the device as '1'. */ +#define RADIO_DATAWHITEIV_DATAWHITEIV_Pos (0UL) /*!< Position of DATAWHITEIV field. */ +#define RADIO_DATAWHITEIV_DATAWHITEIV_Msk (0x7FUL << RADIO_DATAWHITEIV_DATAWHITEIV_Pos) /*!< Bit mask of DATAWHITEIV field. */ + +/* Register: RADIO_BCC */ +/* Description: Bit counter compare */ + +/* Bits 31..0 : Bit counter compare */ +#define RADIO_BCC_BCC_Pos (0UL) /*!< Position of BCC field. */ +#define RADIO_BCC_BCC_Msk (0xFFFFFFFFUL << RADIO_BCC_BCC_Pos) /*!< Bit mask of BCC field. */ + +/* Register: RADIO_DAB */ +/* Description: Description collection[0]: Device address base segment 0 */ + +/* Bits 31..0 : Device address base segment 0 */ +#define RADIO_DAB_DAB_Pos (0UL) /*!< Position of DAB field. */ +#define RADIO_DAB_DAB_Msk (0xFFFFFFFFUL << RADIO_DAB_DAB_Pos) /*!< Bit mask of DAB field. */ + +/* Register: RADIO_DAP */ +/* Description: Description collection[0]: Device address prefix 0 */ + +/* Bits 15..0 : Device address prefix 0 */ +#define RADIO_DAP_DAP_Pos (0UL) /*!< Position of DAP field. */ +#define RADIO_DAP_DAP_Msk (0xFFFFUL << RADIO_DAP_DAP_Pos) /*!< Bit mask of DAP field. */ + +/* Register: RADIO_DACNF */ +/* Description: Device address match configuration */ + +/* Bit 15 : TxAdd for device address 7 */ +#define RADIO_DACNF_TXADD7_Pos (15UL) /*!< Position of TXADD7 field. */ +#define RADIO_DACNF_TXADD7_Msk (0x1UL << RADIO_DACNF_TXADD7_Pos) /*!< Bit mask of TXADD7 field. */ + +/* Bit 14 : TxAdd for device address 6 */ +#define RADIO_DACNF_TXADD6_Pos (14UL) /*!< Position of TXADD6 field. */ +#define RADIO_DACNF_TXADD6_Msk (0x1UL << RADIO_DACNF_TXADD6_Pos) /*!< Bit mask of TXADD6 field. */ + +/* Bit 13 : TxAdd for device address 5 */ +#define RADIO_DACNF_TXADD5_Pos (13UL) /*!< Position of TXADD5 field. */ +#define RADIO_DACNF_TXADD5_Msk (0x1UL << RADIO_DACNF_TXADD5_Pos) /*!< Bit mask of TXADD5 field. */ + +/* Bit 12 : TxAdd for device address 4 */ +#define RADIO_DACNF_TXADD4_Pos (12UL) /*!< Position of TXADD4 field. */ +#define RADIO_DACNF_TXADD4_Msk (0x1UL << RADIO_DACNF_TXADD4_Pos) /*!< Bit mask of TXADD4 field. */ + +/* Bit 11 : TxAdd for device address 3 */ +#define RADIO_DACNF_TXADD3_Pos (11UL) /*!< Position of TXADD3 field. */ +#define RADIO_DACNF_TXADD3_Msk (0x1UL << RADIO_DACNF_TXADD3_Pos) /*!< Bit mask of TXADD3 field. */ + +/* Bit 10 : TxAdd for device address 2 */ +#define RADIO_DACNF_TXADD2_Pos (10UL) /*!< Position of TXADD2 field. */ +#define RADIO_DACNF_TXADD2_Msk (0x1UL << RADIO_DACNF_TXADD2_Pos) /*!< Bit mask of TXADD2 field. */ + +/* Bit 9 : TxAdd for device address 1 */ +#define RADIO_DACNF_TXADD1_Pos (9UL) /*!< Position of TXADD1 field. */ +#define RADIO_DACNF_TXADD1_Msk (0x1UL << RADIO_DACNF_TXADD1_Pos) /*!< Bit mask of TXADD1 field. */ + +/* Bit 8 : TxAdd for device address 0 */ +#define RADIO_DACNF_TXADD0_Pos (8UL) /*!< Position of TXADD0 field. */ +#define RADIO_DACNF_TXADD0_Msk (0x1UL << RADIO_DACNF_TXADD0_Pos) /*!< Bit mask of TXADD0 field. */ + +/* Bit 7 : Enable or disable device address matching using device address 7 */ +#define RADIO_DACNF_ENA7_Pos (7UL) /*!< Position of ENA7 field. */ +#define RADIO_DACNF_ENA7_Msk (0x1UL << RADIO_DACNF_ENA7_Pos) /*!< Bit mask of ENA7 field. */ +#define RADIO_DACNF_ENA7_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA7_Enabled (1UL) /*!< Enabled */ + +/* Bit 6 : Enable or disable device address matching using device address 6 */ +#define RADIO_DACNF_ENA6_Pos (6UL) /*!< Position of ENA6 field. */ +#define RADIO_DACNF_ENA6_Msk (0x1UL << RADIO_DACNF_ENA6_Pos) /*!< Bit mask of ENA6 field. */ +#define RADIO_DACNF_ENA6_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA6_Enabled (1UL) /*!< Enabled */ + +/* Bit 5 : Enable or disable device address matching using device address 5 */ +#define RADIO_DACNF_ENA5_Pos (5UL) /*!< Position of ENA5 field. */ +#define RADIO_DACNF_ENA5_Msk (0x1UL << RADIO_DACNF_ENA5_Pos) /*!< Bit mask of ENA5 field. */ +#define RADIO_DACNF_ENA5_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA5_Enabled (1UL) /*!< Enabled */ + +/* Bit 4 : Enable or disable device address matching using device address 4 */ +#define RADIO_DACNF_ENA4_Pos (4UL) /*!< Position of ENA4 field. */ +#define RADIO_DACNF_ENA4_Msk (0x1UL << RADIO_DACNF_ENA4_Pos) /*!< Bit mask of ENA4 field. */ +#define RADIO_DACNF_ENA4_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA4_Enabled (1UL) /*!< Enabled */ + +/* Bit 3 : Enable or disable device address matching using device address 3 */ +#define RADIO_DACNF_ENA3_Pos (3UL) /*!< Position of ENA3 field. */ +#define RADIO_DACNF_ENA3_Msk (0x1UL << RADIO_DACNF_ENA3_Pos) /*!< Bit mask of ENA3 field. */ +#define RADIO_DACNF_ENA3_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA3_Enabled (1UL) /*!< Enabled */ + +/* Bit 2 : Enable or disable device address matching using device address 2 */ +#define RADIO_DACNF_ENA2_Pos (2UL) /*!< Position of ENA2 field. */ +#define RADIO_DACNF_ENA2_Msk (0x1UL << RADIO_DACNF_ENA2_Pos) /*!< Bit mask of ENA2 field. */ +#define RADIO_DACNF_ENA2_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA2_Enabled (1UL) /*!< Enabled */ + +/* Bit 1 : Enable or disable device address matching using device address 1 */ +#define RADIO_DACNF_ENA1_Pos (1UL) /*!< Position of ENA1 field. */ +#define RADIO_DACNF_ENA1_Msk (0x1UL << RADIO_DACNF_ENA1_Pos) /*!< Bit mask of ENA1 field. */ +#define RADIO_DACNF_ENA1_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA1_Enabled (1UL) /*!< Enabled */ + +/* Bit 0 : Enable or disable device address matching using device address 0 */ +#define RADIO_DACNF_ENA0_Pos (0UL) /*!< Position of ENA0 field. */ +#define RADIO_DACNF_ENA0_Msk (0x1UL << RADIO_DACNF_ENA0_Pos) /*!< Bit mask of ENA0 field. */ +#define RADIO_DACNF_ENA0_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA0_Enabled (1UL) /*!< Enabled */ + +/* Register: RADIO_MODECNF0 */ +/* Description: Radio mode configuration register 0 */ + +/* Bits 9..8 : Default TX value */ +#define RADIO_MODECNF0_DTX_Pos (8UL) /*!< Position of DTX field. */ +#define RADIO_MODECNF0_DTX_Msk (0x3UL << RADIO_MODECNF0_DTX_Pos) /*!< Bit mask of DTX field. */ +#define RADIO_MODECNF0_DTX_B1 (0UL) /*!< Transmit '1' */ +#define RADIO_MODECNF0_DTX_B0 (1UL) /*!< Transmit '0' */ +#define RADIO_MODECNF0_DTX_Center (2UL) /*!< Transmit center frequency */ + +/* Bit 0 : Radio ramp-up time */ +#define RADIO_MODECNF0_RU_Pos (0UL) /*!< Position of RU field. */ +#define RADIO_MODECNF0_RU_Msk (0x1UL << RADIO_MODECNF0_RU_Pos) /*!< Bit mask of RU field. */ +#define RADIO_MODECNF0_RU_Default (0UL) /*!< Default ramp-up time (tRXEN), compatible with firmware written for nRF51 */ +#define RADIO_MODECNF0_RU_Fast (1UL) /*!< Fast ramp-up (tRXEN,FAST), see electrical specification for more information */ + +/* Register: RADIO_SFD */ +/* Description: IEEE 802.15.4 Start of Frame Delimiter */ + +/* Bits 7..0 : IEEE 802.15.4 Start of Frame Delimiter */ +#define RADIO_SFD_SFD_Pos (0UL) /*!< Position of SFD field. */ +#define RADIO_SFD_SFD_Msk (0xFFUL << RADIO_SFD_SFD_Pos) /*!< Bit mask of SFD field. */ + +/* Register: RADIO_EDCNT */ +/* Description: IEEE 802.15.4 Energy Detect Loop Count */ + +/* Bits 20..0 : IEEE 802.15.4 Energy Detect Loop Count */ +#define RADIO_EDCNT_EDCNT_Pos (0UL) /*!< Position of EDCNT field. */ +#define RADIO_EDCNT_EDCNT_Msk (0x1FFFFFUL << RADIO_EDCNT_EDCNT_Pos) /*!< Bit mask of EDCNT field. */ + +/* Register: RADIO_EDSAMPLE */ +/* Description: IEEE 802.15.4 Energy Detect Level */ + +/* Bits 7..0 : IEEE 802.15.4 Energy Detect Level */ +#define RADIO_EDSAMPLE_EDLVL_Pos (0UL) /*!< Position of EDLVL field. */ +#define RADIO_EDSAMPLE_EDLVL_Msk (0xFFUL << RADIO_EDSAMPLE_EDLVL_Pos) /*!< Bit mask of EDLVL field. */ + +/* Register: RADIO_CCACTRL */ +/* Description: IEEE 802.15.4 Clear Channel Assessment Control */ + +/* Bits 31..24 : Limit for occurances above CCACORRTHRES. When not equal to zero the corrolator based signal detect is enabled. */ +#define RADIO_CCACTRL_CCACORRCNT_Pos (24UL) /*!< Position of CCACORRCNT field. */ +#define RADIO_CCACTRL_CCACORRCNT_Msk (0xFFUL << RADIO_CCACTRL_CCACORRCNT_Pos) /*!< Bit mask of CCACORRCNT field. */ + +/* Bits 23..16 : CCA Correlator Busy Threshold. Only relevant to CarrierMode, CarrierAndEdMode and CarrierOrEdMode. */ +#define RADIO_CCACTRL_CCACORRTHRES_Pos (16UL) /*!< Position of CCACORRTHRES field. */ +#define RADIO_CCACTRL_CCACORRTHRES_Msk (0xFFUL << RADIO_CCACTRL_CCACORRTHRES_Pos) /*!< Bit mask of CCACORRTHRES field. */ + +/* Bits 15..8 : CCA Energy Busy Threshold. Used in all the CCA modes except CarrierMode. */ +#define RADIO_CCACTRL_CCAEDTHRES_Pos (8UL) /*!< Position of CCAEDTHRES field. */ +#define RADIO_CCACTRL_CCAEDTHRES_Msk (0xFFUL << RADIO_CCACTRL_CCAEDTHRES_Pos) /*!< Bit mask of CCAEDTHRES field. */ + +/* Bits 2..0 : CCA Mode Of Operation */ +#define RADIO_CCACTRL_CCAMODE_Pos (0UL) /*!< Position of CCAMODE field. */ +#define RADIO_CCACTRL_CCAMODE_Msk (0x7UL << RADIO_CCACTRL_CCAMODE_Pos) /*!< Bit mask of CCAMODE field. */ +#define RADIO_CCACTRL_CCAMODE_EdMode (0UL) /*!< Energy Above Threshold */ +#define RADIO_CCACTRL_CCAMODE_CarrierMode (1UL) /*!< Carrier Seen */ +#define RADIO_CCACTRL_CCAMODE_CarrierAndEdMode (2UL) /*!< Energy Above Threshold AND Carrier Seen */ +#define RADIO_CCACTRL_CCAMODE_CarrierOrEdMode (3UL) /*!< Energy Above Threshold OR Carrier Seen */ +#define RADIO_CCACTRL_CCAMODE_EdModeTest1 (4UL) /*!< Energy Above Threshold test mode that will abort when first ED measurement over threshold is seen. No averaging. */ + +/* Register: RADIO_POWER */ +/* Description: Peripheral power control */ + +/* Bit 0 : Peripheral power control. The peripheral and its registers will be reset to its initial state by switching the peripheral off and then back on again. */ +#define RADIO_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */ +#define RADIO_POWER_POWER_Msk (0x1UL << RADIO_POWER_POWER_Pos) /*!< Bit mask of POWER field. */ +#define RADIO_POWER_POWER_Disabled (0UL) /*!< Peripheral is powered off */ +#define RADIO_POWER_POWER_Enabled (1UL) /*!< Peripheral is powered on */ + + +/* Peripheral: RNG */ +/* Description: Random Number Generator */ + +/* Register: RNG_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 0 : Shortcut between VALRDY event and STOP task */ +#define RNG_SHORTS_VALRDY_STOP_Pos (0UL) /*!< Position of VALRDY_STOP field. */ +#define RNG_SHORTS_VALRDY_STOP_Msk (0x1UL << RNG_SHORTS_VALRDY_STOP_Pos) /*!< Bit mask of VALRDY_STOP field. */ +#define RNG_SHORTS_VALRDY_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define RNG_SHORTS_VALRDY_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: RNG_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 0 : Write '1' to Enable interrupt for VALRDY event */ +#define RNG_INTENSET_VALRDY_Pos (0UL) /*!< Position of VALRDY field. */ +#define RNG_INTENSET_VALRDY_Msk (0x1UL << RNG_INTENSET_VALRDY_Pos) /*!< Bit mask of VALRDY field. */ +#define RNG_INTENSET_VALRDY_Disabled (0UL) /*!< Read: Disabled */ +#define RNG_INTENSET_VALRDY_Enabled (1UL) /*!< Read: Enabled */ +#define RNG_INTENSET_VALRDY_Set (1UL) /*!< Enable */ + +/* Register: RNG_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 0 : Write '1' to Disable interrupt for VALRDY event */ +#define RNG_INTENCLR_VALRDY_Pos (0UL) /*!< Position of VALRDY field. */ +#define RNG_INTENCLR_VALRDY_Msk (0x1UL << RNG_INTENCLR_VALRDY_Pos) /*!< Bit mask of VALRDY field. */ +#define RNG_INTENCLR_VALRDY_Disabled (0UL) /*!< Read: Disabled */ +#define RNG_INTENCLR_VALRDY_Enabled (1UL) /*!< Read: Enabled */ +#define RNG_INTENCLR_VALRDY_Clear (1UL) /*!< Disable */ + +/* Register: RNG_CONFIG */ +/* Description: Configuration register */ + +/* Bit 0 : Bias correction */ +#define RNG_CONFIG_DERCEN_Pos (0UL) /*!< Position of DERCEN field. */ +#define RNG_CONFIG_DERCEN_Msk (0x1UL << RNG_CONFIG_DERCEN_Pos) /*!< Bit mask of DERCEN field. */ +#define RNG_CONFIG_DERCEN_Disabled (0UL) /*!< Disabled */ +#define RNG_CONFIG_DERCEN_Enabled (1UL) /*!< Enabled */ + +/* Register: RNG_VALUE */ +/* Description: Output random number */ + +/* Bits 7..0 : Generated random number */ +#define RNG_VALUE_VALUE_Pos (0UL) /*!< Position of VALUE field. */ +#define RNG_VALUE_VALUE_Msk (0xFFUL << RNG_VALUE_VALUE_Pos) /*!< Bit mask of VALUE field. */ + + +/* Peripheral: RTC */ +/* Description: Real time counter 0 */ + +/* Register: RTC_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 19 : Write '1' to Enable interrupt for COMPARE[3] event */ +#define RTC_INTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define RTC_INTENSET_COMPARE3_Msk (0x1UL << RTC_INTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define RTC_INTENSET_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENSET_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENSET_COMPARE3_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for COMPARE[2] event */ +#define RTC_INTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define RTC_INTENSET_COMPARE2_Msk (0x1UL << RTC_INTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define RTC_INTENSET_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENSET_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENSET_COMPARE2_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable interrupt for COMPARE[1] event */ +#define RTC_INTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define RTC_INTENSET_COMPARE1_Msk (0x1UL << RTC_INTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define RTC_INTENSET_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENSET_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENSET_COMPARE1_Set (1UL) /*!< Enable */ + +/* Bit 16 : Write '1' to Enable interrupt for COMPARE[0] event */ +#define RTC_INTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define RTC_INTENSET_COMPARE0_Msk (0x1UL << RTC_INTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define RTC_INTENSET_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENSET_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENSET_COMPARE0_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for OVRFLW event */ +#define RTC_INTENSET_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ +#define RTC_INTENSET_OVRFLW_Msk (0x1UL << RTC_INTENSET_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ +#define RTC_INTENSET_OVRFLW_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENSET_OVRFLW_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENSET_OVRFLW_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for TICK event */ +#define RTC_INTENSET_TICK_Pos (0UL) /*!< Position of TICK field. */ +#define RTC_INTENSET_TICK_Msk (0x1UL << RTC_INTENSET_TICK_Pos) /*!< Bit mask of TICK field. */ +#define RTC_INTENSET_TICK_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENSET_TICK_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENSET_TICK_Set (1UL) /*!< Enable */ + +/* Register: RTC_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 19 : Write '1' to Disable interrupt for COMPARE[3] event */ +#define RTC_INTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define RTC_INTENCLR_COMPARE3_Msk (0x1UL << RTC_INTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define RTC_INTENCLR_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENCLR_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENCLR_COMPARE3_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for COMPARE[2] event */ +#define RTC_INTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define RTC_INTENCLR_COMPARE2_Msk (0x1UL << RTC_INTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define RTC_INTENCLR_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENCLR_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENCLR_COMPARE2_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable interrupt for COMPARE[1] event */ +#define RTC_INTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define RTC_INTENCLR_COMPARE1_Msk (0x1UL << RTC_INTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define RTC_INTENCLR_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENCLR_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENCLR_COMPARE1_Clear (1UL) /*!< Disable */ + +/* Bit 16 : Write '1' to Disable interrupt for COMPARE[0] event */ +#define RTC_INTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define RTC_INTENCLR_COMPARE0_Msk (0x1UL << RTC_INTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define RTC_INTENCLR_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENCLR_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENCLR_COMPARE0_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for OVRFLW event */ +#define RTC_INTENCLR_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ +#define RTC_INTENCLR_OVRFLW_Msk (0x1UL << RTC_INTENCLR_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ +#define RTC_INTENCLR_OVRFLW_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENCLR_OVRFLW_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENCLR_OVRFLW_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for TICK event */ +#define RTC_INTENCLR_TICK_Pos (0UL) /*!< Position of TICK field. */ +#define RTC_INTENCLR_TICK_Msk (0x1UL << RTC_INTENCLR_TICK_Pos) /*!< Bit mask of TICK field. */ +#define RTC_INTENCLR_TICK_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENCLR_TICK_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENCLR_TICK_Clear (1UL) /*!< Disable */ + +/* Register: RTC_EVTEN */ +/* Description: Enable or disable event routing */ + +/* Bit 19 : Enable or disable event routing for COMPARE[3] event */ +#define RTC_EVTEN_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define RTC_EVTEN_COMPARE3_Msk (0x1UL << RTC_EVTEN_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define RTC_EVTEN_COMPARE3_Disabled (0UL) /*!< Disable */ +#define RTC_EVTEN_COMPARE3_Enabled (1UL) /*!< Enable */ + +/* Bit 18 : Enable or disable event routing for COMPARE[2] event */ +#define RTC_EVTEN_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define RTC_EVTEN_COMPARE2_Msk (0x1UL << RTC_EVTEN_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define RTC_EVTEN_COMPARE2_Disabled (0UL) /*!< Disable */ +#define RTC_EVTEN_COMPARE2_Enabled (1UL) /*!< Enable */ + +/* Bit 17 : Enable or disable event routing for COMPARE[1] event */ +#define RTC_EVTEN_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define RTC_EVTEN_COMPARE1_Msk (0x1UL << RTC_EVTEN_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define RTC_EVTEN_COMPARE1_Disabled (0UL) /*!< Disable */ +#define RTC_EVTEN_COMPARE1_Enabled (1UL) /*!< Enable */ + +/* Bit 16 : Enable or disable event routing for COMPARE[0] event */ +#define RTC_EVTEN_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define RTC_EVTEN_COMPARE0_Msk (0x1UL << RTC_EVTEN_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define RTC_EVTEN_COMPARE0_Disabled (0UL) /*!< Disable */ +#define RTC_EVTEN_COMPARE0_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable event routing for OVRFLW event */ +#define RTC_EVTEN_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ +#define RTC_EVTEN_OVRFLW_Msk (0x1UL << RTC_EVTEN_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ +#define RTC_EVTEN_OVRFLW_Disabled (0UL) /*!< Disable */ +#define RTC_EVTEN_OVRFLW_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable event routing for TICK event */ +#define RTC_EVTEN_TICK_Pos (0UL) /*!< Position of TICK field. */ +#define RTC_EVTEN_TICK_Msk (0x1UL << RTC_EVTEN_TICK_Pos) /*!< Bit mask of TICK field. */ +#define RTC_EVTEN_TICK_Disabled (0UL) /*!< Disable */ +#define RTC_EVTEN_TICK_Enabled (1UL) /*!< Enable */ + +/* Register: RTC_EVTENSET */ +/* Description: Enable event routing */ + +/* Bit 19 : Write '1' to Enable event routing for COMPARE[3] event */ +#define RTC_EVTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define RTC_EVTENSET_COMPARE3_Msk (0x1UL << RTC_EVTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define RTC_EVTENSET_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENSET_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENSET_COMPARE3_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable event routing for COMPARE[2] event */ +#define RTC_EVTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define RTC_EVTENSET_COMPARE2_Msk (0x1UL << RTC_EVTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define RTC_EVTENSET_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENSET_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENSET_COMPARE2_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable event routing for COMPARE[1] event */ +#define RTC_EVTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define RTC_EVTENSET_COMPARE1_Msk (0x1UL << RTC_EVTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define RTC_EVTENSET_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENSET_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENSET_COMPARE1_Set (1UL) /*!< Enable */ + +/* Bit 16 : Write '1' to Enable event routing for COMPARE[0] event */ +#define RTC_EVTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define RTC_EVTENSET_COMPARE0_Msk (0x1UL << RTC_EVTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define RTC_EVTENSET_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENSET_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENSET_COMPARE0_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable event routing for OVRFLW event */ +#define RTC_EVTENSET_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ +#define RTC_EVTENSET_OVRFLW_Msk (0x1UL << RTC_EVTENSET_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ +#define RTC_EVTENSET_OVRFLW_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENSET_OVRFLW_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENSET_OVRFLW_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable event routing for TICK event */ +#define RTC_EVTENSET_TICK_Pos (0UL) /*!< Position of TICK field. */ +#define RTC_EVTENSET_TICK_Msk (0x1UL << RTC_EVTENSET_TICK_Pos) /*!< Bit mask of TICK field. */ +#define RTC_EVTENSET_TICK_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENSET_TICK_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENSET_TICK_Set (1UL) /*!< Enable */ + +/* Register: RTC_EVTENCLR */ +/* Description: Disable event routing */ + +/* Bit 19 : Write '1' to Disable event routing for COMPARE[3] event */ +#define RTC_EVTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define RTC_EVTENCLR_COMPARE3_Msk (0x1UL << RTC_EVTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define RTC_EVTENCLR_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENCLR_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENCLR_COMPARE3_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable event routing for COMPARE[2] event */ +#define RTC_EVTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define RTC_EVTENCLR_COMPARE2_Msk (0x1UL << RTC_EVTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define RTC_EVTENCLR_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENCLR_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENCLR_COMPARE2_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable event routing for COMPARE[1] event */ +#define RTC_EVTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define RTC_EVTENCLR_COMPARE1_Msk (0x1UL << RTC_EVTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define RTC_EVTENCLR_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENCLR_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENCLR_COMPARE1_Clear (1UL) /*!< Disable */ + +/* Bit 16 : Write '1' to Disable event routing for COMPARE[0] event */ +#define RTC_EVTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define RTC_EVTENCLR_COMPARE0_Msk (0x1UL << RTC_EVTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define RTC_EVTENCLR_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENCLR_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENCLR_COMPARE0_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable event routing for OVRFLW event */ +#define RTC_EVTENCLR_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ +#define RTC_EVTENCLR_OVRFLW_Msk (0x1UL << RTC_EVTENCLR_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ +#define RTC_EVTENCLR_OVRFLW_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENCLR_OVRFLW_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENCLR_OVRFLW_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable event routing for TICK event */ +#define RTC_EVTENCLR_TICK_Pos (0UL) /*!< Position of TICK field. */ +#define RTC_EVTENCLR_TICK_Msk (0x1UL << RTC_EVTENCLR_TICK_Pos) /*!< Bit mask of TICK field. */ +#define RTC_EVTENCLR_TICK_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENCLR_TICK_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENCLR_TICK_Clear (1UL) /*!< Disable */ + +/* Register: RTC_COUNTER */ +/* Description: Current COUNTER value */ + +/* Bits 23..0 : Counter value */ +#define RTC_COUNTER_COUNTER_Pos (0UL) /*!< Position of COUNTER field. */ +#define RTC_COUNTER_COUNTER_Msk (0xFFFFFFUL << RTC_COUNTER_COUNTER_Pos) /*!< Bit mask of COUNTER field. */ + +/* Register: RTC_PRESCALER */ +/* Description: 12 bit prescaler for COUNTER frequency (32768/(PRESCALER+1)).Must be written when RTC is stopped */ + +/* Bits 11..0 : Prescaler value */ +#define RTC_PRESCALER_PRESCALER_Pos (0UL) /*!< Position of PRESCALER field. */ +#define RTC_PRESCALER_PRESCALER_Msk (0xFFFUL << RTC_PRESCALER_PRESCALER_Pos) /*!< Bit mask of PRESCALER field. */ + +/* Register: RTC_CC */ +/* Description: Description collection[0]: Compare register 0 */ + +/* Bits 23..0 : Compare value */ +#define RTC_CC_COMPARE_Pos (0UL) /*!< Position of COMPARE field. */ +#define RTC_CC_COMPARE_Msk (0xFFFFFFUL << RTC_CC_COMPARE_Pos) /*!< Bit mask of COMPARE field. */ + + +/* Peripheral: SAADC */ +/* Description: Analog to Digital Converter */ + +/* Register: SAADC_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 21 : Enable or disable interrupt for CH[7].LIMITL event */ +#define SAADC_INTEN_CH7LIMITL_Pos (21UL) /*!< Position of CH7LIMITL field. */ +#define SAADC_INTEN_CH7LIMITL_Msk (0x1UL << SAADC_INTEN_CH7LIMITL_Pos) /*!< Bit mask of CH7LIMITL field. */ +#define SAADC_INTEN_CH7LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH7LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 20 : Enable or disable interrupt for CH[7].LIMITH event */ +#define SAADC_INTEN_CH7LIMITH_Pos (20UL) /*!< Position of CH7LIMITH field. */ +#define SAADC_INTEN_CH7LIMITH_Msk (0x1UL << SAADC_INTEN_CH7LIMITH_Pos) /*!< Bit mask of CH7LIMITH field. */ +#define SAADC_INTEN_CH7LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH7LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 19 : Enable or disable interrupt for CH[6].LIMITL event */ +#define SAADC_INTEN_CH6LIMITL_Pos (19UL) /*!< Position of CH6LIMITL field. */ +#define SAADC_INTEN_CH6LIMITL_Msk (0x1UL << SAADC_INTEN_CH6LIMITL_Pos) /*!< Bit mask of CH6LIMITL field. */ +#define SAADC_INTEN_CH6LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH6LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 18 : Enable or disable interrupt for CH[6].LIMITH event */ +#define SAADC_INTEN_CH6LIMITH_Pos (18UL) /*!< Position of CH6LIMITH field. */ +#define SAADC_INTEN_CH6LIMITH_Msk (0x1UL << SAADC_INTEN_CH6LIMITH_Pos) /*!< Bit mask of CH6LIMITH field. */ +#define SAADC_INTEN_CH6LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH6LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 17 : Enable or disable interrupt for CH[5].LIMITL event */ +#define SAADC_INTEN_CH5LIMITL_Pos (17UL) /*!< Position of CH5LIMITL field. */ +#define SAADC_INTEN_CH5LIMITL_Msk (0x1UL << SAADC_INTEN_CH5LIMITL_Pos) /*!< Bit mask of CH5LIMITL field. */ +#define SAADC_INTEN_CH5LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH5LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 16 : Enable or disable interrupt for CH[5].LIMITH event */ +#define SAADC_INTEN_CH5LIMITH_Pos (16UL) /*!< Position of CH5LIMITH field. */ +#define SAADC_INTEN_CH5LIMITH_Msk (0x1UL << SAADC_INTEN_CH5LIMITH_Pos) /*!< Bit mask of CH5LIMITH field. */ +#define SAADC_INTEN_CH5LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH5LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 15 : Enable or disable interrupt for CH[4].LIMITL event */ +#define SAADC_INTEN_CH4LIMITL_Pos (15UL) /*!< Position of CH4LIMITL field. */ +#define SAADC_INTEN_CH4LIMITL_Msk (0x1UL << SAADC_INTEN_CH4LIMITL_Pos) /*!< Bit mask of CH4LIMITL field. */ +#define SAADC_INTEN_CH4LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH4LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 14 : Enable or disable interrupt for CH[4].LIMITH event */ +#define SAADC_INTEN_CH4LIMITH_Pos (14UL) /*!< Position of CH4LIMITH field. */ +#define SAADC_INTEN_CH4LIMITH_Msk (0x1UL << SAADC_INTEN_CH4LIMITH_Pos) /*!< Bit mask of CH4LIMITH field. */ +#define SAADC_INTEN_CH4LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH4LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 13 : Enable or disable interrupt for CH[3].LIMITL event */ +#define SAADC_INTEN_CH3LIMITL_Pos (13UL) /*!< Position of CH3LIMITL field. */ +#define SAADC_INTEN_CH3LIMITL_Msk (0x1UL << SAADC_INTEN_CH3LIMITL_Pos) /*!< Bit mask of CH3LIMITL field. */ +#define SAADC_INTEN_CH3LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH3LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 12 : Enable or disable interrupt for CH[3].LIMITH event */ +#define SAADC_INTEN_CH3LIMITH_Pos (12UL) /*!< Position of CH3LIMITH field. */ +#define SAADC_INTEN_CH3LIMITH_Msk (0x1UL << SAADC_INTEN_CH3LIMITH_Pos) /*!< Bit mask of CH3LIMITH field. */ +#define SAADC_INTEN_CH3LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH3LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 11 : Enable or disable interrupt for CH[2].LIMITL event */ +#define SAADC_INTEN_CH2LIMITL_Pos (11UL) /*!< Position of CH2LIMITL field. */ +#define SAADC_INTEN_CH2LIMITL_Msk (0x1UL << SAADC_INTEN_CH2LIMITL_Pos) /*!< Bit mask of CH2LIMITL field. */ +#define SAADC_INTEN_CH2LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH2LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 10 : Enable or disable interrupt for CH[2].LIMITH event */ +#define SAADC_INTEN_CH2LIMITH_Pos (10UL) /*!< Position of CH2LIMITH field. */ +#define SAADC_INTEN_CH2LIMITH_Msk (0x1UL << SAADC_INTEN_CH2LIMITH_Pos) /*!< Bit mask of CH2LIMITH field. */ +#define SAADC_INTEN_CH2LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH2LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 9 : Enable or disable interrupt for CH[1].LIMITL event */ +#define SAADC_INTEN_CH1LIMITL_Pos (9UL) /*!< Position of CH1LIMITL field. */ +#define SAADC_INTEN_CH1LIMITL_Msk (0x1UL << SAADC_INTEN_CH1LIMITL_Pos) /*!< Bit mask of CH1LIMITL field. */ +#define SAADC_INTEN_CH1LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH1LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 8 : Enable or disable interrupt for CH[1].LIMITH event */ +#define SAADC_INTEN_CH1LIMITH_Pos (8UL) /*!< Position of CH1LIMITH field. */ +#define SAADC_INTEN_CH1LIMITH_Msk (0x1UL << SAADC_INTEN_CH1LIMITH_Pos) /*!< Bit mask of CH1LIMITH field. */ +#define SAADC_INTEN_CH1LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH1LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 7 : Enable or disable interrupt for CH[0].LIMITL event */ +#define SAADC_INTEN_CH0LIMITL_Pos (7UL) /*!< Position of CH0LIMITL field. */ +#define SAADC_INTEN_CH0LIMITL_Msk (0x1UL << SAADC_INTEN_CH0LIMITL_Pos) /*!< Bit mask of CH0LIMITL field. */ +#define SAADC_INTEN_CH0LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH0LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 6 : Enable or disable interrupt for CH[0].LIMITH event */ +#define SAADC_INTEN_CH0LIMITH_Pos (6UL) /*!< Position of CH0LIMITH field. */ +#define SAADC_INTEN_CH0LIMITH_Msk (0x1UL << SAADC_INTEN_CH0LIMITH_Pos) /*!< Bit mask of CH0LIMITH field. */ +#define SAADC_INTEN_CH0LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH0LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 5 : Enable or disable interrupt for STOPPED event */ +#define SAADC_INTEN_STOPPED_Pos (5UL) /*!< Position of STOPPED field. */ +#define SAADC_INTEN_STOPPED_Msk (0x1UL << SAADC_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define SAADC_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable interrupt for CALIBRATEDONE event */ +#define SAADC_INTEN_CALIBRATEDONE_Pos (4UL) /*!< Position of CALIBRATEDONE field. */ +#define SAADC_INTEN_CALIBRATEDONE_Msk (0x1UL << SAADC_INTEN_CALIBRATEDONE_Pos) /*!< Bit mask of CALIBRATEDONE field. */ +#define SAADC_INTEN_CALIBRATEDONE_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CALIBRATEDONE_Enabled (1UL) /*!< Enable */ + +/* Bit 3 : Enable or disable interrupt for RESULTDONE event */ +#define SAADC_INTEN_RESULTDONE_Pos (3UL) /*!< Position of RESULTDONE field. */ +#define SAADC_INTEN_RESULTDONE_Msk (0x1UL << SAADC_INTEN_RESULTDONE_Pos) /*!< Bit mask of RESULTDONE field. */ +#define SAADC_INTEN_RESULTDONE_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_RESULTDONE_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for DONE event */ +#define SAADC_INTEN_DONE_Pos (2UL) /*!< Position of DONE field. */ +#define SAADC_INTEN_DONE_Msk (0x1UL << SAADC_INTEN_DONE_Pos) /*!< Bit mask of DONE field. */ +#define SAADC_INTEN_DONE_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_DONE_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for END event */ +#define SAADC_INTEN_END_Pos (1UL) /*!< Position of END field. */ +#define SAADC_INTEN_END_Msk (0x1UL << SAADC_INTEN_END_Pos) /*!< Bit mask of END field. */ +#define SAADC_INTEN_END_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_END_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable interrupt for STARTED event */ +#define SAADC_INTEN_STARTED_Pos (0UL) /*!< Position of STARTED field. */ +#define SAADC_INTEN_STARTED_Msk (0x1UL << SAADC_INTEN_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define SAADC_INTEN_STARTED_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_STARTED_Enabled (1UL) /*!< Enable */ + +/* Register: SAADC_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 21 : Write '1' to Enable interrupt for CH[7].LIMITL event */ +#define SAADC_INTENSET_CH7LIMITL_Pos (21UL) /*!< Position of CH7LIMITL field. */ +#define SAADC_INTENSET_CH7LIMITL_Msk (0x1UL << SAADC_INTENSET_CH7LIMITL_Pos) /*!< Bit mask of CH7LIMITL field. */ +#define SAADC_INTENSET_CH7LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH7LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH7LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for CH[7].LIMITH event */ +#define SAADC_INTENSET_CH7LIMITH_Pos (20UL) /*!< Position of CH7LIMITH field. */ +#define SAADC_INTENSET_CH7LIMITH_Msk (0x1UL << SAADC_INTENSET_CH7LIMITH_Pos) /*!< Bit mask of CH7LIMITH field. */ +#define SAADC_INTENSET_CH7LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH7LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH7LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for CH[6].LIMITL event */ +#define SAADC_INTENSET_CH6LIMITL_Pos (19UL) /*!< Position of CH6LIMITL field. */ +#define SAADC_INTENSET_CH6LIMITL_Msk (0x1UL << SAADC_INTENSET_CH6LIMITL_Pos) /*!< Bit mask of CH6LIMITL field. */ +#define SAADC_INTENSET_CH6LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH6LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH6LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for CH[6].LIMITH event */ +#define SAADC_INTENSET_CH6LIMITH_Pos (18UL) /*!< Position of CH6LIMITH field. */ +#define SAADC_INTENSET_CH6LIMITH_Msk (0x1UL << SAADC_INTENSET_CH6LIMITH_Pos) /*!< Bit mask of CH6LIMITH field. */ +#define SAADC_INTENSET_CH6LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH6LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH6LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable interrupt for CH[5].LIMITL event */ +#define SAADC_INTENSET_CH5LIMITL_Pos (17UL) /*!< Position of CH5LIMITL field. */ +#define SAADC_INTENSET_CH5LIMITL_Msk (0x1UL << SAADC_INTENSET_CH5LIMITL_Pos) /*!< Bit mask of CH5LIMITL field. */ +#define SAADC_INTENSET_CH5LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH5LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH5LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 16 : Write '1' to Enable interrupt for CH[5].LIMITH event */ +#define SAADC_INTENSET_CH5LIMITH_Pos (16UL) /*!< Position of CH5LIMITH field. */ +#define SAADC_INTENSET_CH5LIMITH_Msk (0x1UL << SAADC_INTENSET_CH5LIMITH_Pos) /*!< Bit mask of CH5LIMITH field. */ +#define SAADC_INTENSET_CH5LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH5LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH5LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 15 : Write '1' to Enable interrupt for CH[4].LIMITL event */ +#define SAADC_INTENSET_CH4LIMITL_Pos (15UL) /*!< Position of CH4LIMITL field. */ +#define SAADC_INTENSET_CH4LIMITL_Msk (0x1UL << SAADC_INTENSET_CH4LIMITL_Pos) /*!< Bit mask of CH4LIMITL field. */ +#define SAADC_INTENSET_CH4LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH4LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH4LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 14 : Write '1' to Enable interrupt for CH[4].LIMITH event */ +#define SAADC_INTENSET_CH4LIMITH_Pos (14UL) /*!< Position of CH4LIMITH field. */ +#define SAADC_INTENSET_CH4LIMITH_Msk (0x1UL << SAADC_INTENSET_CH4LIMITH_Pos) /*!< Bit mask of CH4LIMITH field. */ +#define SAADC_INTENSET_CH4LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH4LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH4LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 13 : Write '1' to Enable interrupt for CH[3].LIMITL event */ +#define SAADC_INTENSET_CH3LIMITL_Pos (13UL) /*!< Position of CH3LIMITL field. */ +#define SAADC_INTENSET_CH3LIMITL_Msk (0x1UL << SAADC_INTENSET_CH3LIMITL_Pos) /*!< Bit mask of CH3LIMITL field. */ +#define SAADC_INTENSET_CH3LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH3LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH3LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 12 : Write '1' to Enable interrupt for CH[3].LIMITH event */ +#define SAADC_INTENSET_CH3LIMITH_Pos (12UL) /*!< Position of CH3LIMITH field. */ +#define SAADC_INTENSET_CH3LIMITH_Msk (0x1UL << SAADC_INTENSET_CH3LIMITH_Pos) /*!< Bit mask of CH3LIMITH field. */ +#define SAADC_INTENSET_CH3LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH3LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH3LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 11 : Write '1' to Enable interrupt for CH[2].LIMITL event */ +#define SAADC_INTENSET_CH2LIMITL_Pos (11UL) /*!< Position of CH2LIMITL field. */ +#define SAADC_INTENSET_CH2LIMITL_Msk (0x1UL << SAADC_INTENSET_CH2LIMITL_Pos) /*!< Bit mask of CH2LIMITL field. */ +#define SAADC_INTENSET_CH2LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH2LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH2LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 10 : Write '1' to Enable interrupt for CH[2].LIMITH event */ +#define SAADC_INTENSET_CH2LIMITH_Pos (10UL) /*!< Position of CH2LIMITH field. */ +#define SAADC_INTENSET_CH2LIMITH_Msk (0x1UL << SAADC_INTENSET_CH2LIMITH_Pos) /*!< Bit mask of CH2LIMITH field. */ +#define SAADC_INTENSET_CH2LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH2LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH2LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for CH[1].LIMITL event */ +#define SAADC_INTENSET_CH1LIMITL_Pos (9UL) /*!< Position of CH1LIMITL field. */ +#define SAADC_INTENSET_CH1LIMITL_Msk (0x1UL << SAADC_INTENSET_CH1LIMITL_Pos) /*!< Bit mask of CH1LIMITL field. */ +#define SAADC_INTENSET_CH1LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH1LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH1LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 8 : Write '1' to Enable interrupt for CH[1].LIMITH event */ +#define SAADC_INTENSET_CH1LIMITH_Pos (8UL) /*!< Position of CH1LIMITH field. */ +#define SAADC_INTENSET_CH1LIMITH_Msk (0x1UL << SAADC_INTENSET_CH1LIMITH_Pos) /*!< Bit mask of CH1LIMITH field. */ +#define SAADC_INTENSET_CH1LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH1LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH1LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for CH[0].LIMITL event */ +#define SAADC_INTENSET_CH0LIMITL_Pos (7UL) /*!< Position of CH0LIMITL field. */ +#define SAADC_INTENSET_CH0LIMITL_Msk (0x1UL << SAADC_INTENSET_CH0LIMITL_Pos) /*!< Bit mask of CH0LIMITL field. */ +#define SAADC_INTENSET_CH0LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH0LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH0LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for CH[0].LIMITH event */ +#define SAADC_INTENSET_CH0LIMITH_Pos (6UL) /*!< Position of CH0LIMITH field. */ +#define SAADC_INTENSET_CH0LIMITH_Msk (0x1UL << SAADC_INTENSET_CH0LIMITH_Pos) /*!< Bit mask of CH0LIMITH field. */ +#define SAADC_INTENSET_CH0LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH0LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH0LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for STOPPED event */ +#define SAADC_INTENSET_STOPPED_Pos (5UL) /*!< Position of STOPPED field. */ +#define SAADC_INTENSET_STOPPED_Msk (0x1UL << SAADC_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define SAADC_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for CALIBRATEDONE event */ +#define SAADC_INTENSET_CALIBRATEDONE_Pos (4UL) /*!< Position of CALIBRATEDONE field. */ +#define SAADC_INTENSET_CALIBRATEDONE_Msk (0x1UL << SAADC_INTENSET_CALIBRATEDONE_Pos) /*!< Bit mask of CALIBRATEDONE field. */ +#define SAADC_INTENSET_CALIBRATEDONE_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CALIBRATEDONE_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CALIBRATEDONE_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for RESULTDONE event */ +#define SAADC_INTENSET_RESULTDONE_Pos (3UL) /*!< Position of RESULTDONE field. */ +#define SAADC_INTENSET_RESULTDONE_Msk (0x1UL << SAADC_INTENSET_RESULTDONE_Pos) /*!< Bit mask of RESULTDONE field. */ +#define SAADC_INTENSET_RESULTDONE_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_RESULTDONE_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_RESULTDONE_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for DONE event */ +#define SAADC_INTENSET_DONE_Pos (2UL) /*!< Position of DONE field. */ +#define SAADC_INTENSET_DONE_Msk (0x1UL << SAADC_INTENSET_DONE_Pos) /*!< Bit mask of DONE field. */ +#define SAADC_INTENSET_DONE_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_DONE_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_DONE_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for END event */ +#define SAADC_INTENSET_END_Pos (1UL) /*!< Position of END field. */ +#define SAADC_INTENSET_END_Msk (0x1UL << SAADC_INTENSET_END_Pos) /*!< Bit mask of END field. */ +#define SAADC_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_END_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for STARTED event */ +#define SAADC_INTENSET_STARTED_Pos (0UL) /*!< Position of STARTED field. */ +#define SAADC_INTENSET_STARTED_Msk (0x1UL << SAADC_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define SAADC_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_STARTED_Set (1UL) /*!< Enable */ + +/* Register: SAADC_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 21 : Write '1' to Disable interrupt for CH[7].LIMITL event */ +#define SAADC_INTENCLR_CH7LIMITL_Pos (21UL) /*!< Position of CH7LIMITL field. */ +#define SAADC_INTENCLR_CH7LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH7LIMITL_Pos) /*!< Bit mask of CH7LIMITL field. */ +#define SAADC_INTENCLR_CH7LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH7LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH7LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for CH[7].LIMITH event */ +#define SAADC_INTENCLR_CH7LIMITH_Pos (20UL) /*!< Position of CH7LIMITH field. */ +#define SAADC_INTENCLR_CH7LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH7LIMITH_Pos) /*!< Bit mask of CH7LIMITH field. */ +#define SAADC_INTENCLR_CH7LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH7LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH7LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for CH[6].LIMITL event */ +#define SAADC_INTENCLR_CH6LIMITL_Pos (19UL) /*!< Position of CH6LIMITL field. */ +#define SAADC_INTENCLR_CH6LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH6LIMITL_Pos) /*!< Bit mask of CH6LIMITL field. */ +#define SAADC_INTENCLR_CH6LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH6LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH6LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for CH[6].LIMITH event */ +#define SAADC_INTENCLR_CH6LIMITH_Pos (18UL) /*!< Position of CH6LIMITH field. */ +#define SAADC_INTENCLR_CH6LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH6LIMITH_Pos) /*!< Bit mask of CH6LIMITH field. */ +#define SAADC_INTENCLR_CH6LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH6LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH6LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable interrupt for CH[5].LIMITL event */ +#define SAADC_INTENCLR_CH5LIMITL_Pos (17UL) /*!< Position of CH5LIMITL field. */ +#define SAADC_INTENCLR_CH5LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH5LIMITL_Pos) /*!< Bit mask of CH5LIMITL field. */ +#define SAADC_INTENCLR_CH5LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH5LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH5LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 16 : Write '1' to Disable interrupt for CH[5].LIMITH event */ +#define SAADC_INTENCLR_CH5LIMITH_Pos (16UL) /*!< Position of CH5LIMITH field. */ +#define SAADC_INTENCLR_CH5LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH5LIMITH_Pos) /*!< Bit mask of CH5LIMITH field. */ +#define SAADC_INTENCLR_CH5LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH5LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH5LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 15 : Write '1' to Disable interrupt for CH[4].LIMITL event */ +#define SAADC_INTENCLR_CH4LIMITL_Pos (15UL) /*!< Position of CH4LIMITL field. */ +#define SAADC_INTENCLR_CH4LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH4LIMITL_Pos) /*!< Bit mask of CH4LIMITL field. */ +#define SAADC_INTENCLR_CH4LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH4LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH4LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 14 : Write '1' to Disable interrupt for CH[4].LIMITH event */ +#define SAADC_INTENCLR_CH4LIMITH_Pos (14UL) /*!< Position of CH4LIMITH field. */ +#define SAADC_INTENCLR_CH4LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH4LIMITH_Pos) /*!< Bit mask of CH4LIMITH field. */ +#define SAADC_INTENCLR_CH4LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH4LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH4LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 13 : Write '1' to Disable interrupt for CH[3].LIMITL event */ +#define SAADC_INTENCLR_CH3LIMITL_Pos (13UL) /*!< Position of CH3LIMITL field. */ +#define SAADC_INTENCLR_CH3LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH3LIMITL_Pos) /*!< Bit mask of CH3LIMITL field. */ +#define SAADC_INTENCLR_CH3LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH3LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH3LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 12 : Write '1' to Disable interrupt for CH[3].LIMITH event */ +#define SAADC_INTENCLR_CH3LIMITH_Pos (12UL) /*!< Position of CH3LIMITH field. */ +#define SAADC_INTENCLR_CH3LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH3LIMITH_Pos) /*!< Bit mask of CH3LIMITH field. */ +#define SAADC_INTENCLR_CH3LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH3LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH3LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 11 : Write '1' to Disable interrupt for CH[2].LIMITL event */ +#define SAADC_INTENCLR_CH2LIMITL_Pos (11UL) /*!< Position of CH2LIMITL field. */ +#define SAADC_INTENCLR_CH2LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH2LIMITL_Pos) /*!< Bit mask of CH2LIMITL field. */ +#define SAADC_INTENCLR_CH2LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH2LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH2LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 10 : Write '1' to Disable interrupt for CH[2].LIMITH event */ +#define SAADC_INTENCLR_CH2LIMITH_Pos (10UL) /*!< Position of CH2LIMITH field. */ +#define SAADC_INTENCLR_CH2LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH2LIMITH_Pos) /*!< Bit mask of CH2LIMITH field. */ +#define SAADC_INTENCLR_CH2LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH2LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH2LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for CH[1].LIMITL event */ +#define SAADC_INTENCLR_CH1LIMITL_Pos (9UL) /*!< Position of CH1LIMITL field. */ +#define SAADC_INTENCLR_CH1LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH1LIMITL_Pos) /*!< Bit mask of CH1LIMITL field. */ +#define SAADC_INTENCLR_CH1LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH1LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH1LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 8 : Write '1' to Disable interrupt for CH[1].LIMITH event */ +#define SAADC_INTENCLR_CH1LIMITH_Pos (8UL) /*!< Position of CH1LIMITH field. */ +#define SAADC_INTENCLR_CH1LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH1LIMITH_Pos) /*!< Bit mask of CH1LIMITH field. */ +#define SAADC_INTENCLR_CH1LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH1LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH1LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for CH[0].LIMITL event */ +#define SAADC_INTENCLR_CH0LIMITL_Pos (7UL) /*!< Position of CH0LIMITL field. */ +#define SAADC_INTENCLR_CH0LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH0LIMITL_Pos) /*!< Bit mask of CH0LIMITL field. */ +#define SAADC_INTENCLR_CH0LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH0LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH0LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for CH[0].LIMITH event */ +#define SAADC_INTENCLR_CH0LIMITH_Pos (6UL) /*!< Position of CH0LIMITH field. */ +#define SAADC_INTENCLR_CH0LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH0LIMITH_Pos) /*!< Bit mask of CH0LIMITH field. */ +#define SAADC_INTENCLR_CH0LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH0LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH0LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for STOPPED event */ +#define SAADC_INTENCLR_STOPPED_Pos (5UL) /*!< Position of STOPPED field. */ +#define SAADC_INTENCLR_STOPPED_Msk (0x1UL << SAADC_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define SAADC_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for CALIBRATEDONE event */ +#define SAADC_INTENCLR_CALIBRATEDONE_Pos (4UL) /*!< Position of CALIBRATEDONE field. */ +#define SAADC_INTENCLR_CALIBRATEDONE_Msk (0x1UL << SAADC_INTENCLR_CALIBRATEDONE_Pos) /*!< Bit mask of CALIBRATEDONE field. */ +#define SAADC_INTENCLR_CALIBRATEDONE_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CALIBRATEDONE_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CALIBRATEDONE_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for RESULTDONE event */ +#define SAADC_INTENCLR_RESULTDONE_Pos (3UL) /*!< Position of RESULTDONE field. */ +#define SAADC_INTENCLR_RESULTDONE_Msk (0x1UL << SAADC_INTENCLR_RESULTDONE_Pos) /*!< Bit mask of RESULTDONE field. */ +#define SAADC_INTENCLR_RESULTDONE_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_RESULTDONE_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_RESULTDONE_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for DONE event */ +#define SAADC_INTENCLR_DONE_Pos (2UL) /*!< Position of DONE field. */ +#define SAADC_INTENCLR_DONE_Msk (0x1UL << SAADC_INTENCLR_DONE_Pos) /*!< Bit mask of DONE field. */ +#define SAADC_INTENCLR_DONE_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_DONE_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_DONE_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for END event */ +#define SAADC_INTENCLR_END_Pos (1UL) /*!< Position of END field. */ +#define SAADC_INTENCLR_END_Msk (0x1UL << SAADC_INTENCLR_END_Pos) /*!< Bit mask of END field. */ +#define SAADC_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_END_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for STARTED event */ +#define SAADC_INTENCLR_STARTED_Pos (0UL) /*!< Position of STARTED field. */ +#define SAADC_INTENCLR_STARTED_Msk (0x1UL << SAADC_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define SAADC_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_STARTED_Clear (1UL) /*!< Disable */ + +/* Register: SAADC_STATUS */ +/* Description: Status */ + +/* Bit 0 : Status */ +#define SAADC_STATUS_STATUS_Pos (0UL) /*!< Position of STATUS field. */ +#define SAADC_STATUS_STATUS_Msk (0x1UL << SAADC_STATUS_STATUS_Pos) /*!< Bit mask of STATUS field. */ +#define SAADC_STATUS_STATUS_Ready (0UL) /*!< ADC is ready. No on-going conversion. */ +#define SAADC_STATUS_STATUS_Busy (1UL) /*!< ADC is busy. Conversion in progress. */ + +/* Register: SAADC_ENABLE */ +/* Description: Enable or disable ADC */ + +/* Bit 0 : Enable or disable ADC */ +#define SAADC_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define SAADC_ENABLE_ENABLE_Msk (0x1UL << SAADC_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define SAADC_ENABLE_ENABLE_Disabled (0UL) /*!< Disable ADC */ +#define SAADC_ENABLE_ENABLE_Enabled (1UL) /*!< Enable ADC */ + +/* Register: SAADC_CH_PSELP */ +/* Description: Description cluster[0]: Input positive pin selection for CH[0] */ + +/* Bits 4..0 : Analog positive input channel */ +#define SAADC_CH_PSELP_PSELP_Pos (0UL) /*!< Position of PSELP field. */ +#define SAADC_CH_PSELP_PSELP_Msk (0x1FUL << SAADC_CH_PSELP_PSELP_Pos) /*!< Bit mask of PSELP field. */ +#define SAADC_CH_PSELP_PSELP_NC (0UL) /*!< Not connected */ +#define SAADC_CH_PSELP_PSELP_AnalogInput0 (1UL) /*!< AIN0 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput1 (2UL) /*!< AIN1 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput2 (3UL) /*!< AIN2 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput3 (4UL) /*!< AIN3 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput4 (5UL) /*!< AIN4 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput5 (6UL) /*!< AIN5 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput6 (7UL) /*!< AIN6 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput7 (8UL) /*!< AIN7 */ +#define SAADC_CH_PSELP_PSELP_VDD (9UL) /*!< VDD */ +#define SAADC_CH_PSELP_PSELP_VDDHDIV5 (0x11UL) /*!< VDDH/5 */ + +/* Register: SAADC_CH_PSELN */ +/* Description: Description cluster[0]: Input negative pin selection for CH[0] */ + +/* Bits 4..0 : Analog negative input, enables differential channel */ +#define SAADC_CH_PSELN_PSELN_Pos (0UL) /*!< Position of PSELN field. */ +#define SAADC_CH_PSELN_PSELN_Msk (0x1FUL << SAADC_CH_PSELN_PSELN_Pos) /*!< Bit mask of PSELN field. */ +#define SAADC_CH_PSELN_PSELN_NC (0UL) /*!< Not connected */ +#define SAADC_CH_PSELN_PSELN_AnalogInput0 (1UL) /*!< AIN0 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput1 (2UL) /*!< AIN1 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput2 (3UL) /*!< AIN2 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput3 (4UL) /*!< AIN3 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput4 (5UL) /*!< AIN4 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput5 (6UL) /*!< AIN5 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput6 (7UL) /*!< AIN6 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput7 (8UL) /*!< AIN7 */ +#define SAADC_CH_PSELN_PSELN_VDD (9UL) /*!< VDD */ +#define SAADC_CH_PSELN_PSELN_VDDHDIV5 (0x11UL) /*!< VDDH/5 */ + +/* Register: SAADC_CH_CONFIG */ +/* Description: Description cluster[0]: Input configuration for CH[0] */ + +/* Bit 24 : Enable burst mode */ +#define SAADC_CH_CONFIG_BURST_Pos (24UL) /*!< Position of BURST field. */ +#define SAADC_CH_CONFIG_BURST_Msk (0x1UL << SAADC_CH_CONFIG_BURST_Pos) /*!< Bit mask of BURST field. */ +#define SAADC_CH_CONFIG_BURST_Disabled (0UL) /*!< Burst mode is disabled (normal operation) */ +#define SAADC_CH_CONFIG_BURST_Enabled (1UL) /*!< Burst mode is enabled. SAADC takes 2^OVERSAMPLE number of samples as fast as it can, and sends the average to Data RAM. */ + +/* Bit 20 : Enable differential mode */ +#define SAADC_CH_CONFIG_MODE_Pos (20UL) /*!< Position of MODE field. */ +#define SAADC_CH_CONFIG_MODE_Msk (0x1UL << SAADC_CH_CONFIG_MODE_Pos) /*!< Bit mask of MODE field. */ +#define SAADC_CH_CONFIG_MODE_SE (0UL) /*!< Single ended, PSELN will be ignored, negative input to ADC shorted to GND */ +#define SAADC_CH_CONFIG_MODE_Diff (1UL) /*!< Differential */ + +/* Bits 18..16 : Acquisition time, the time the ADC uses to sample the input voltage */ +#define SAADC_CH_CONFIG_TACQ_Pos (16UL) /*!< Position of TACQ field. */ +#define SAADC_CH_CONFIG_TACQ_Msk (0x7UL << SAADC_CH_CONFIG_TACQ_Pos) /*!< Bit mask of TACQ field. */ +#define SAADC_CH_CONFIG_TACQ_3us (0UL) /*!< 3 us */ +#define SAADC_CH_CONFIG_TACQ_5us (1UL) /*!< 5 us */ +#define SAADC_CH_CONFIG_TACQ_10us (2UL) /*!< 10 us */ +#define SAADC_CH_CONFIG_TACQ_15us (3UL) /*!< 15 us */ +#define SAADC_CH_CONFIG_TACQ_20us (4UL) /*!< 20 us */ +#define SAADC_CH_CONFIG_TACQ_40us (5UL) /*!< 40 us */ + +/* Bit 12 : Reference control */ +#define SAADC_CH_CONFIG_REFSEL_Pos (12UL) /*!< Position of REFSEL field. */ +#define SAADC_CH_CONFIG_REFSEL_Msk (0x1UL << SAADC_CH_CONFIG_REFSEL_Pos) /*!< Bit mask of REFSEL field. */ +#define SAADC_CH_CONFIG_REFSEL_Internal (0UL) /*!< Internal reference (0.6 V) */ +#define SAADC_CH_CONFIG_REFSEL_VDD1_4 (1UL) /*!< VDD/4 as reference */ + +/* Bits 10..8 : Gain control */ +#define SAADC_CH_CONFIG_GAIN_Pos (8UL) /*!< Position of GAIN field. */ +#define SAADC_CH_CONFIG_GAIN_Msk (0x7UL << SAADC_CH_CONFIG_GAIN_Pos) /*!< Bit mask of GAIN field. */ +#define SAADC_CH_CONFIG_GAIN_Gain1_6 (0UL) /*!< 1/6 */ +#define SAADC_CH_CONFIG_GAIN_Gain1_5 (1UL) /*!< 1/5 */ +#define SAADC_CH_CONFIG_GAIN_Gain1_4 (2UL) /*!< 1/4 */ +#define SAADC_CH_CONFIG_GAIN_Gain1_3 (3UL) /*!< 1/3 */ +#define SAADC_CH_CONFIG_GAIN_Gain1_2 (4UL) /*!< 1/2 */ +#define SAADC_CH_CONFIG_GAIN_Gain1 (5UL) /*!< 1 */ +#define SAADC_CH_CONFIG_GAIN_Gain2 (6UL) /*!< 2 */ +#define SAADC_CH_CONFIG_GAIN_Gain4 (7UL) /*!< 4 */ + +/* Bits 5..4 : Negative channel resistor control */ +#define SAADC_CH_CONFIG_RESN_Pos (4UL) /*!< Position of RESN field. */ +#define SAADC_CH_CONFIG_RESN_Msk (0x3UL << SAADC_CH_CONFIG_RESN_Pos) /*!< Bit mask of RESN field. */ +#define SAADC_CH_CONFIG_RESN_Bypass (0UL) /*!< Bypass resistor ladder */ +#define SAADC_CH_CONFIG_RESN_Pulldown (1UL) /*!< Pull-down to GND */ +#define SAADC_CH_CONFIG_RESN_Pullup (2UL) /*!< Pull-up to VDD */ +#define SAADC_CH_CONFIG_RESN_VDD1_2 (3UL) /*!< Set input at VDD/2 */ + +/* Bits 1..0 : Positive channel resistor control */ +#define SAADC_CH_CONFIG_RESP_Pos (0UL) /*!< Position of RESP field. */ +#define SAADC_CH_CONFIG_RESP_Msk (0x3UL << SAADC_CH_CONFIG_RESP_Pos) /*!< Bit mask of RESP field. */ +#define SAADC_CH_CONFIG_RESP_Bypass (0UL) /*!< Bypass resistor ladder */ +#define SAADC_CH_CONFIG_RESP_Pulldown (1UL) /*!< Pull-down to GND */ +#define SAADC_CH_CONFIG_RESP_Pullup (2UL) /*!< Pull-up to VDD */ +#define SAADC_CH_CONFIG_RESP_VDD1_2 (3UL) /*!< Set input at VDD/2 */ + +/* Register: SAADC_CH_LIMIT */ +/* Description: Description cluster[0]: High/low limits for event monitoring a channel */ + +/* Bits 31..16 : High level limit */ +#define SAADC_CH_LIMIT_HIGH_Pos (16UL) /*!< Position of HIGH field. */ +#define SAADC_CH_LIMIT_HIGH_Msk (0xFFFFUL << SAADC_CH_LIMIT_HIGH_Pos) /*!< Bit mask of HIGH field. */ + +/* Bits 15..0 : Low level limit */ +#define SAADC_CH_LIMIT_LOW_Pos (0UL) /*!< Position of LOW field. */ +#define SAADC_CH_LIMIT_LOW_Msk (0xFFFFUL << SAADC_CH_LIMIT_LOW_Pos) /*!< Bit mask of LOW field. */ + +/* Register: SAADC_RESOLUTION */ +/* Description: Resolution configuration */ + +/* Bits 2..0 : Set the resolution */ +#define SAADC_RESOLUTION_VAL_Pos (0UL) /*!< Position of VAL field. */ +#define SAADC_RESOLUTION_VAL_Msk (0x7UL << SAADC_RESOLUTION_VAL_Pos) /*!< Bit mask of VAL field. */ +#define SAADC_RESOLUTION_VAL_8bit (0UL) /*!< 8 bit */ +#define SAADC_RESOLUTION_VAL_10bit (1UL) /*!< 10 bit */ +#define SAADC_RESOLUTION_VAL_12bit (2UL) /*!< 12 bit */ +#define SAADC_RESOLUTION_VAL_14bit (3UL) /*!< 14 bit */ + +/* Register: SAADC_OVERSAMPLE */ +/* Description: Oversampling configuration. OVERSAMPLE should not be combined with SCAN. The RESOLUTION is applied before averaging, thus for high OVERSAMPLE a higher RESOLUTION should be used. */ + +/* Bits 3..0 : Oversample control */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Pos (0UL) /*!< Position of OVERSAMPLE field. */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Msk (0xFUL << SAADC_OVERSAMPLE_OVERSAMPLE_Pos) /*!< Bit mask of OVERSAMPLE field. */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Bypass (0UL) /*!< Bypass oversampling */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over2x (1UL) /*!< Oversample 2x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over4x (2UL) /*!< Oversample 4x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over8x (3UL) /*!< Oversample 8x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over16x (4UL) /*!< Oversample 16x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over32x (5UL) /*!< Oversample 32x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over64x (6UL) /*!< Oversample 64x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over128x (7UL) /*!< Oversample 128x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over256x (8UL) /*!< Oversample 256x */ + +/* Register: SAADC_SAMPLERATE */ +/* Description: Controls normal or continuous sample rate */ + +/* Bit 12 : Select mode for sample rate control */ +#define SAADC_SAMPLERATE_MODE_Pos (12UL) /*!< Position of MODE field. */ +#define SAADC_SAMPLERATE_MODE_Msk (0x1UL << SAADC_SAMPLERATE_MODE_Pos) /*!< Bit mask of MODE field. */ +#define SAADC_SAMPLERATE_MODE_Task (0UL) /*!< Rate is controlled from SAMPLE task */ +#define SAADC_SAMPLERATE_MODE_Timers (1UL) /*!< Rate is controlled from local timer (use CC to control the rate) */ + +/* Bits 10..0 : Capture and compare value. Sample rate is 16 MHz/CC */ +#define SAADC_SAMPLERATE_CC_Pos (0UL) /*!< Position of CC field. */ +#define SAADC_SAMPLERATE_CC_Msk (0x7FFUL << SAADC_SAMPLERATE_CC_Pos) /*!< Bit mask of CC field. */ + +/* Register: SAADC_RESULT_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define SAADC_RESULT_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define SAADC_RESULT_PTR_PTR_Msk (0xFFFFFFFFUL << SAADC_RESULT_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: SAADC_RESULT_MAXCNT */ +/* Description: Maximum number of buffer words to transfer */ + +/* Bits 14..0 : Maximum number of buffer words to transfer */ +#define SAADC_RESULT_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define SAADC_RESULT_MAXCNT_MAXCNT_Msk (0x7FFFUL << SAADC_RESULT_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: SAADC_RESULT_AMOUNT */ +/* Description: Number of buffer words transferred since last START */ + +/* Bits 14..0 : Number of buffer words transferred since last START. This register can be read after an END or STOPPED event. */ +#define SAADC_RESULT_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define SAADC_RESULT_AMOUNT_AMOUNT_Msk (0x7FFFUL << SAADC_RESULT_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + + +/* Peripheral: SPI */ +/* Description: Serial Peripheral Interface 0 */ + +/* Register: SPI_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 2 : Write '1' to Enable interrupt for READY event */ +#define SPI_INTENSET_READY_Pos (2UL) /*!< Position of READY field. */ +#define SPI_INTENSET_READY_Msk (0x1UL << SPI_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ +#define SPI_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ +#define SPI_INTENSET_READY_Enabled (1UL) /*!< Read: Enabled */ +#define SPI_INTENSET_READY_Set (1UL) /*!< Enable */ + +/* Register: SPI_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 2 : Write '1' to Disable interrupt for READY event */ +#define SPI_INTENCLR_READY_Pos (2UL) /*!< Position of READY field. */ +#define SPI_INTENCLR_READY_Msk (0x1UL << SPI_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ +#define SPI_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ +#define SPI_INTENCLR_READY_Enabled (1UL) /*!< Read: Enabled */ +#define SPI_INTENCLR_READY_Clear (1UL) /*!< Disable */ + +/* Register: SPI_ENABLE */ +/* Description: Enable SPI */ + +/* Bits 3..0 : Enable or disable SPI */ +#define SPI_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define SPI_ENABLE_ENABLE_Msk (0xFUL << SPI_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define SPI_ENABLE_ENABLE_Disabled (0UL) /*!< Disable SPI */ +#define SPI_ENABLE_ENABLE_Enabled (1UL) /*!< Enable SPI */ + +/* Register: SPI_PSEL_SCK */ +/* Description: Pin select for SCK */ + +/* Bit 31 : Connection */ +#define SPI_PSEL_SCK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPI_PSEL_SCK_CONNECT_Msk (0x1UL << SPI_PSEL_SCK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPI_PSEL_SCK_CONNECT_Connected (0UL) /*!< Connect */ +#define SPI_PSEL_SCK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define SPI_PSEL_SCK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPI_PSEL_SCK_PORT_Msk (0x1UL << SPI_PSEL_SCK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPI_PSEL_SCK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPI_PSEL_SCK_PIN_Msk (0x1FUL << SPI_PSEL_SCK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPI_PSEL_MOSI */ +/* Description: Pin select for MOSI signal */ + +/* Bit 31 : Connection */ +#define SPI_PSEL_MOSI_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPI_PSEL_MOSI_CONNECT_Msk (0x1UL << SPI_PSEL_MOSI_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPI_PSEL_MOSI_CONNECT_Connected (0UL) /*!< Connect */ +#define SPI_PSEL_MOSI_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define SPI_PSEL_MOSI_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPI_PSEL_MOSI_PORT_Msk (0x1UL << SPI_PSEL_MOSI_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPI_PSEL_MOSI_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPI_PSEL_MOSI_PIN_Msk (0x1FUL << SPI_PSEL_MOSI_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPI_PSEL_MISO */ +/* Description: Pin select for MISO signal */ + +/* Bit 31 : Connection */ +#define SPI_PSEL_MISO_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPI_PSEL_MISO_CONNECT_Msk (0x1UL << SPI_PSEL_MISO_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPI_PSEL_MISO_CONNECT_Connected (0UL) /*!< Connect */ +#define SPI_PSEL_MISO_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define SPI_PSEL_MISO_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPI_PSEL_MISO_PORT_Msk (0x1UL << SPI_PSEL_MISO_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPI_PSEL_MISO_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPI_PSEL_MISO_PIN_Msk (0x1FUL << SPI_PSEL_MISO_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPI_RXD */ +/* Description: RXD register */ + +/* Bits 7..0 : RX data received. Double buffered */ +#define SPI_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */ +#define SPI_RXD_RXD_Msk (0xFFUL << SPI_RXD_RXD_Pos) /*!< Bit mask of RXD field. */ + +/* Register: SPI_TXD */ +/* Description: TXD register */ + +/* Bits 7..0 : TX data to send. Double buffered */ +#define SPI_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */ +#define SPI_TXD_TXD_Msk (0xFFUL << SPI_TXD_TXD_Pos) /*!< Bit mask of TXD field. */ + +/* Register: SPI_FREQUENCY */ +/* Description: SPI frequency. Accuracy depends on the HFCLK source selected. */ + +/* Bits 31..0 : SPI master data rate */ +#define SPI_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */ +#define SPI_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << SPI_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */ +#define SPI_FREQUENCY_FREQUENCY_K125 (0x02000000UL) /*!< 125 kbps */ +#define SPI_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps */ +#define SPI_FREQUENCY_FREQUENCY_K500 (0x08000000UL) /*!< 500 kbps */ +#define SPI_FREQUENCY_FREQUENCY_M1 (0x10000000UL) /*!< 1 Mbps */ +#define SPI_FREQUENCY_FREQUENCY_M2 (0x20000000UL) /*!< 2 Mbps */ +#define SPI_FREQUENCY_FREQUENCY_M4 (0x40000000UL) /*!< 4 Mbps */ +#define SPI_FREQUENCY_FREQUENCY_M8 (0x80000000UL) /*!< 8 Mbps */ + +/* Register: SPI_CONFIG */ +/* Description: Configuration register */ + +/* Bit 2 : Serial clock (SCK) polarity */ +#define SPI_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */ +#define SPI_CONFIG_CPOL_Msk (0x1UL << SPI_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */ +#define SPI_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high */ +#define SPI_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low */ + +/* Bit 1 : Serial clock (SCK) phase */ +#define SPI_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */ +#define SPI_CONFIG_CPHA_Msk (0x1UL << SPI_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */ +#define SPI_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of clock, shift serial data on trailing edge */ +#define SPI_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of clock, shift serial data on leading edge */ + +/* Bit 0 : Bit order */ +#define SPI_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */ +#define SPI_CONFIG_ORDER_Msk (0x1UL << SPI_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */ +#define SPI_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit shifted out first */ +#define SPI_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit shifted out first */ + + +/* Peripheral: SPIM */ +/* Description: Serial Peripheral Interface Master with EasyDMA 0 */ + +/* Register: SPIM_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 17 : Shortcut between END event and START task */ +#define SPIM_SHORTS_END_START_Pos (17UL) /*!< Position of END_START field. */ +#define SPIM_SHORTS_END_START_Msk (0x1UL << SPIM_SHORTS_END_START_Pos) /*!< Bit mask of END_START field. */ +#define SPIM_SHORTS_END_START_Disabled (0UL) /*!< Disable shortcut */ +#define SPIM_SHORTS_END_START_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: SPIM_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 19 : Write '1' to Enable interrupt for STARTED event */ +#define SPIM_INTENSET_STARTED_Pos (19UL) /*!< Position of STARTED field. */ +#define SPIM_INTENSET_STARTED_Msk (0x1UL << SPIM_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define SPIM_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENSET_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENSET_STARTED_Set (1UL) /*!< Enable */ + +/* Bit 8 : Write '1' to Enable interrupt for ENDTX event */ +#define SPIM_INTENSET_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ +#define SPIM_INTENSET_ENDTX_Msk (0x1UL << SPIM_INTENSET_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define SPIM_INTENSET_ENDTX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENSET_ENDTX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENSET_ENDTX_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for END event */ +#define SPIM_INTENSET_END_Pos (6UL) /*!< Position of END field. */ +#define SPIM_INTENSET_END_Msk (0x1UL << SPIM_INTENSET_END_Pos) /*!< Bit mask of END field. */ +#define SPIM_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENSET_END_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for ENDRX event */ +#define SPIM_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define SPIM_INTENSET_ENDRX_Msk (0x1UL << SPIM_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define SPIM_INTENSET_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENSET_ENDRX_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ +#define SPIM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define SPIM_INTENSET_STOPPED_Msk (0x1UL << SPIM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define SPIM_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Register: SPIM_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 19 : Write '1' to Disable interrupt for STARTED event */ +#define SPIM_INTENCLR_STARTED_Pos (19UL) /*!< Position of STARTED field. */ +#define SPIM_INTENCLR_STARTED_Msk (0x1UL << SPIM_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define SPIM_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENCLR_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENCLR_STARTED_Clear (1UL) /*!< Disable */ + +/* Bit 8 : Write '1' to Disable interrupt for ENDTX event */ +#define SPIM_INTENCLR_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ +#define SPIM_INTENCLR_ENDTX_Msk (0x1UL << SPIM_INTENCLR_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define SPIM_INTENCLR_ENDTX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENCLR_ENDTX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENCLR_ENDTX_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for END event */ +#define SPIM_INTENCLR_END_Pos (6UL) /*!< Position of END field. */ +#define SPIM_INTENCLR_END_Msk (0x1UL << SPIM_INTENCLR_END_Pos) /*!< Bit mask of END field. */ +#define SPIM_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENCLR_END_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for ENDRX event */ +#define SPIM_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define SPIM_INTENCLR_ENDRX_Msk (0x1UL << SPIM_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define SPIM_INTENCLR_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENCLR_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENCLR_ENDRX_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ +#define SPIM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define SPIM_INTENCLR_STOPPED_Msk (0x1UL << SPIM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define SPIM_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Register: SPIM_STALLSTAT */ +/* Description: Stall status for EasyDMA RAM accesses. The fields in this register is set to STALL by hardware whenever a stall occurres and can be cleared (set to NOSTALL) by the CPU. */ + +/* Bit 1 : Stall status for EasyDMA RAM writes */ +#define SPIM_STALLSTAT_RX_Pos (1UL) /*!< Position of RX field. */ +#define SPIM_STALLSTAT_RX_Msk (0x1UL << SPIM_STALLSTAT_RX_Pos) /*!< Bit mask of RX field. */ +#define SPIM_STALLSTAT_RX_NOSTALL (0UL) /*!< No stall */ +#define SPIM_STALLSTAT_RX_STALL (1UL) /*!< A stall has occurred */ + +/* Bit 0 : Stall status for EasyDMA RAM reads */ +#define SPIM_STALLSTAT_TX_Pos (0UL) /*!< Position of TX field. */ +#define SPIM_STALLSTAT_TX_Msk (0x1UL << SPIM_STALLSTAT_TX_Pos) /*!< Bit mask of TX field. */ +#define SPIM_STALLSTAT_TX_NOSTALL (0UL) /*!< No stall */ +#define SPIM_STALLSTAT_TX_STALL (1UL) /*!< A stall has occurred */ + +/* Register: SPIM_ENABLE */ +/* Description: Enable SPIM */ + +/* Bits 3..0 : Enable or disable SPIM */ +#define SPIM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define SPIM_ENABLE_ENABLE_Msk (0xFUL << SPIM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define SPIM_ENABLE_ENABLE_Disabled (0UL) /*!< Disable SPIM */ +#define SPIM_ENABLE_ENABLE_Enabled (7UL) /*!< Enable SPIM */ + +/* Register: SPIM_PSEL_SCK */ +/* Description: Pin select for SCK */ + +/* Bit 31 : Connection */ +#define SPIM_PSEL_SCK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIM_PSEL_SCK_CONNECT_Msk (0x1UL << SPIM_PSEL_SCK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIM_PSEL_SCK_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIM_PSEL_SCK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define SPIM_PSEL_SCK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIM_PSEL_SCK_PORT_Msk (0x1UL << SPIM_PSEL_SCK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIM_PSEL_SCK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIM_PSEL_SCK_PIN_Msk (0x1FUL << SPIM_PSEL_SCK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIM_PSEL_MOSI */ +/* Description: Pin select for MOSI signal */ + +/* Bit 31 : Connection */ +#define SPIM_PSEL_MOSI_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIM_PSEL_MOSI_CONNECT_Msk (0x1UL << SPIM_PSEL_MOSI_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIM_PSEL_MOSI_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIM_PSEL_MOSI_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define SPIM_PSEL_MOSI_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIM_PSEL_MOSI_PORT_Msk (0x1UL << SPIM_PSEL_MOSI_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIM_PSEL_MOSI_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIM_PSEL_MOSI_PIN_Msk (0x1FUL << SPIM_PSEL_MOSI_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIM_PSEL_MISO */ +/* Description: Pin select for MISO signal */ + +/* Bit 31 : Connection */ +#define SPIM_PSEL_MISO_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIM_PSEL_MISO_CONNECT_Msk (0x1UL << SPIM_PSEL_MISO_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIM_PSEL_MISO_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIM_PSEL_MISO_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define SPIM_PSEL_MISO_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIM_PSEL_MISO_PORT_Msk (0x1UL << SPIM_PSEL_MISO_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIM_PSEL_MISO_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIM_PSEL_MISO_PIN_Msk (0x1FUL << SPIM_PSEL_MISO_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIM_PSEL_CSN */ +/* Description: Pin select for CSN */ + +/* Bit 31 : Connection */ +#define SPIM_PSEL_CSN_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIM_PSEL_CSN_CONNECT_Msk (0x1UL << SPIM_PSEL_CSN_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIM_PSEL_CSN_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIM_PSEL_CSN_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define SPIM_PSEL_CSN_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIM_PSEL_CSN_PORT_Msk (0x1UL << SPIM_PSEL_CSN_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIM_PSEL_CSN_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIM_PSEL_CSN_PIN_Msk (0x1FUL << SPIM_PSEL_CSN_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIM_FREQUENCY */ +/* Description: SPI frequency. Accuracy depends on the HFCLK source selected. */ + +/* Bits 31..0 : SPI master data rate */ +#define SPIM_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */ +#define SPIM_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << SPIM_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */ +#define SPIM_FREQUENCY_FREQUENCY_K125 (0x02000000UL) /*!< 125 kbps */ +#define SPIM_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps */ +#define SPIM_FREQUENCY_FREQUENCY_K500 (0x08000000UL) /*!< 500 kbps */ +#define SPIM_FREQUENCY_FREQUENCY_M16 (0x0A000000UL) /*!< 16 Mbps */ +#define SPIM_FREQUENCY_FREQUENCY_M1 (0x10000000UL) /*!< 1 Mbps */ +#define SPIM_FREQUENCY_FREQUENCY_M32 (0x14000000UL) /*!< 32 Mbps */ +#define SPIM_FREQUENCY_FREQUENCY_M2 (0x20000000UL) /*!< 2 Mbps */ +#define SPIM_FREQUENCY_FREQUENCY_M4 (0x40000000UL) /*!< 4 Mbps */ +#define SPIM_FREQUENCY_FREQUENCY_M8 (0x80000000UL) /*!< 8 Mbps */ + +/* Register: SPIM_RXD_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define SPIM_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define SPIM_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIM_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: SPIM_RXD_MAXCNT */ +/* Description: Maximum number of bytes in receive buffer */ + +/* Bits 15..0 : Maximum number of bytes in receive buffer */ +#define SPIM_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define SPIM_RXD_MAXCNT_MAXCNT_Msk (0xFFFFUL << SPIM_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: SPIM_RXD_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 15..0 : Number of bytes transferred in the last transaction */ +#define SPIM_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define SPIM_RXD_AMOUNT_AMOUNT_Msk (0xFFFFUL << SPIM_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: SPIM_RXD_LIST */ +/* Description: EasyDMA list type */ + +/* Bits 1..0 : List type */ +#define SPIM_RXD_LIST_LIST_Pos (0UL) /*!< Position of LIST field. */ +#define SPIM_RXD_LIST_LIST_Msk (0x3UL << SPIM_RXD_LIST_LIST_Pos) /*!< Bit mask of LIST field. */ +#define SPIM_RXD_LIST_LIST_Disabled (0UL) /*!< Disable EasyDMA list */ +#define SPIM_RXD_LIST_LIST_ArrayList (1UL) /*!< Use array list */ + +/* Register: SPIM_TXD_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define SPIM_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define SPIM_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIM_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: SPIM_TXD_MAXCNT */ +/* Description: Number of bytes in transmit buffer */ + +/* Bits 15..0 : Maximum number of bytes in transmit buffer */ +#define SPIM_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define SPIM_TXD_MAXCNT_MAXCNT_Msk (0xFFFFUL << SPIM_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: SPIM_TXD_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 15..0 : Number of bytes transferred in the last transaction */ +#define SPIM_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define SPIM_TXD_AMOUNT_AMOUNT_Msk (0xFFFFUL << SPIM_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: SPIM_TXD_LIST */ +/* Description: EasyDMA list type */ + +/* Bits 1..0 : List type */ +#define SPIM_TXD_LIST_LIST_Pos (0UL) /*!< Position of LIST field. */ +#define SPIM_TXD_LIST_LIST_Msk (0x3UL << SPIM_TXD_LIST_LIST_Pos) /*!< Bit mask of LIST field. */ +#define SPIM_TXD_LIST_LIST_Disabled (0UL) /*!< Disable EasyDMA list */ +#define SPIM_TXD_LIST_LIST_ArrayList (1UL) /*!< Use array list */ + +/* Register: SPIM_CONFIG */ +/* Description: Configuration register */ + +/* Bit 2 : Serial clock (SCK) polarity */ +#define SPIM_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */ +#define SPIM_CONFIG_CPOL_Msk (0x1UL << SPIM_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */ +#define SPIM_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high */ +#define SPIM_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low */ + +/* Bit 1 : Serial clock (SCK) phase */ +#define SPIM_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */ +#define SPIM_CONFIG_CPHA_Msk (0x1UL << SPIM_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */ +#define SPIM_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of clock, shift serial data on trailing edge */ +#define SPIM_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of clock, shift serial data on leading edge */ + +/* Bit 0 : Bit order */ +#define SPIM_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */ +#define SPIM_CONFIG_ORDER_Msk (0x1UL << SPIM_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */ +#define SPIM_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit shifted out first */ +#define SPIM_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit shifted out first */ + +/* Register: SPIM_IFTIMING_RXDELAY */ +/* Description: Sample delay for input serial data on MISO */ + +/* Bits 2..0 : Sample delay for input serial data on MISO. The value specifies the number of 64 MHz clock cycles (15.625 ns) delay from the the sampling edge of SCK (leading edge for CONFIG.CPHA = 0, trailing edge for CONFIG.CPHA = 1) until the input serial data is sampled. As en example, if RXDELAY = 0 and CONFIG.CPHA = 0, the input serial data is sampled on the rising edge of SCK. */ +#define SPIM_IFTIMING_RXDELAY_RXDELAY_Pos (0UL) /*!< Position of RXDELAY field. */ +#define SPIM_IFTIMING_RXDELAY_RXDELAY_Msk (0x7UL << SPIM_IFTIMING_RXDELAY_RXDELAY_Pos) /*!< Bit mask of RXDELAY field. */ + +/* Register: SPIM_IFTIMING_CSNDUR */ +/* Description: Minimum duration between edge of CSN and edge of SCK and minimum duration CSN must stay high between transactions */ + +/* Bits 7..0 : Minimum duration between edge of CSN and edge of SCK and minimum duration CSN must stay high between transactions. The value is specified in number of 64 MHz clock cycles (15.625 ns). */ +#define SPIM_IFTIMING_CSNDUR_CSNDUR_Pos (0UL) /*!< Position of CSNDUR field. */ +#define SPIM_IFTIMING_CSNDUR_CSNDUR_Msk (0xFFUL << SPIM_IFTIMING_CSNDUR_CSNDUR_Pos) /*!< Bit mask of CSNDUR field. */ + +/* Register: SPIM_ORC */ +/* Description: Byte transmitted after TXD.MAXCNT bytes have been transmitted in the case when RXD.MAXCNT is greater than TXD.MAXCNT */ + +/* Bits 7..0 : Byte transmitted after TXD.MAXCNT bytes have been transmitted in the case when RXD.MAXCNT is greater than TXD.MAXCNT. */ +#define SPIM_ORC_ORC_Pos (0UL) /*!< Position of ORC field. */ +#define SPIM_ORC_ORC_Msk (0xFFUL << SPIM_ORC_ORC_Pos) /*!< Bit mask of ORC field. */ + + +/* Peripheral: SPIS */ +/* Description: SPI Slave 0 */ + +/* Register: SPIS_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 2 : Shortcut between END event and ACQUIRE task */ +#define SPIS_SHORTS_END_ACQUIRE_Pos (2UL) /*!< Position of END_ACQUIRE field. */ +#define SPIS_SHORTS_END_ACQUIRE_Msk (0x1UL << SPIS_SHORTS_END_ACQUIRE_Pos) /*!< Bit mask of END_ACQUIRE field. */ +#define SPIS_SHORTS_END_ACQUIRE_Disabled (0UL) /*!< Disable shortcut */ +#define SPIS_SHORTS_END_ACQUIRE_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: SPIS_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 10 : Write '1' to Enable interrupt for ACQUIRED event */ +#define SPIS_INTENSET_ACQUIRED_Pos (10UL) /*!< Position of ACQUIRED field. */ +#define SPIS_INTENSET_ACQUIRED_Msk (0x1UL << SPIS_INTENSET_ACQUIRED_Pos) /*!< Bit mask of ACQUIRED field. */ +#define SPIS_INTENSET_ACQUIRED_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENSET_ACQUIRED_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENSET_ACQUIRED_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for ENDRX event */ +#define SPIS_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define SPIS_INTENSET_ENDRX_Msk (0x1UL << SPIS_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define SPIS_INTENSET_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENSET_ENDRX_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for END event */ +#define SPIS_INTENSET_END_Pos (1UL) /*!< Position of END field. */ +#define SPIS_INTENSET_END_Msk (0x1UL << SPIS_INTENSET_END_Pos) /*!< Bit mask of END field. */ +#define SPIS_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENSET_END_Set (1UL) /*!< Enable */ + +/* Register: SPIS_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 10 : Write '1' to Disable interrupt for ACQUIRED event */ +#define SPIS_INTENCLR_ACQUIRED_Pos (10UL) /*!< Position of ACQUIRED field. */ +#define SPIS_INTENCLR_ACQUIRED_Msk (0x1UL << SPIS_INTENCLR_ACQUIRED_Pos) /*!< Bit mask of ACQUIRED field. */ +#define SPIS_INTENCLR_ACQUIRED_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENCLR_ACQUIRED_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENCLR_ACQUIRED_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for ENDRX event */ +#define SPIS_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define SPIS_INTENCLR_ENDRX_Msk (0x1UL << SPIS_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define SPIS_INTENCLR_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENCLR_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENCLR_ENDRX_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for END event */ +#define SPIS_INTENCLR_END_Pos (1UL) /*!< Position of END field. */ +#define SPIS_INTENCLR_END_Msk (0x1UL << SPIS_INTENCLR_END_Pos) /*!< Bit mask of END field. */ +#define SPIS_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENCLR_END_Clear (1UL) /*!< Disable */ + +/* Register: SPIS_SEMSTAT */ +/* Description: Semaphore status register */ + +/* Bits 1..0 : Semaphore status */ +#define SPIS_SEMSTAT_SEMSTAT_Pos (0UL) /*!< Position of SEMSTAT field. */ +#define SPIS_SEMSTAT_SEMSTAT_Msk (0x3UL << SPIS_SEMSTAT_SEMSTAT_Pos) /*!< Bit mask of SEMSTAT field. */ +#define SPIS_SEMSTAT_SEMSTAT_Free (0UL) /*!< Semaphore is free */ +#define SPIS_SEMSTAT_SEMSTAT_CPU (1UL) /*!< Semaphore is assigned to CPU */ +#define SPIS_SEMSTAT_SEMSTAT_SPIS (2UL) /*!< Semaphore is assigned to SPI slave */ +#define SPIS_SEMSTAT_SEMSTAT_CPUPending (3UL) /*!< Semaphore is assigned to SPI but a handover to the CPU is pending */ + +/* Register: SPIS_STATUS */ +/* Description: Status from last transaction */ + +/* Bit 1 : RX buffer overflow detected, and prevented */ +#define SPIS_STATUS_OVERFLOW_Pos (1UL) /*!< Position of OVERFLOW field. */ +#define SPIS_STATUS_OVERFLOW_Msk (0x1UL << SPIS_STATUS_OVERFLOW_Pos) /*!< Bit mask of OVERFLOW field. */ +#define SPIS_STATUS_OVERFLOW_NotPresent (0UL) /*!< Read: error not present */ +#define SPIS_STATUS_OVERFLOW_Present (1UL) /*!< Read: error present */ +#define SPIS_STATUS_OVERFLOW_Clear (1UL) /*!< Write: clear error on writing '1' */ + +/* Bit 0 : TX buffer over-read detected, and prevented */ +#define SPIS_STATUS_OVERREAD_Pos (0UL) /*!< Position of OVERREAD field. */ +#define SPIS_STATUS_OVERREAD_Msk (0x1UL << SPIS_STATUS_OVERREAD_Pos) /*!< Bit mask of OVERREAD field. */ +#define SPIS_STATUS_OVERREAD_NotPresent (0UL) /*!< Read: error not present */ +#define SPIS_STATUS_OVERREAD_Present (1UL) /*!< Read: error present */ +#define SPIS_STATUS_OVERREAD_Clear (1UL) /*!< Write: clear error on writing '1' */ + +/* Register: SPIS_ENABLE */ +/* Description: Enable SPI slave */ + +/* Bits 3..0 : Enable or disable SPI slave */ +#define SPIS_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define SPIS_ENABLE_ENABLE_Msk (0xFUL << SPIS_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define SPIS_ENABLE_ENABLE_Disabled (0UL) /*!< Disable SPI slave */ +#define SPIS_ENABLE_ENABLE_Enabled (2UL) /*!< Enable SPI slave */ + +/* Register: SPIS_PSEL_SCK */ +/* Description: Pin select for SCK */ + +/* Bit 31 : Connection */ +#define SPIS_PSEL_SCK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIS_PSEL_SCK_CONNECT_Msk (0x1UL << SPIS_PSEL_SCK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIS_PSEL_SCK_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIS_PSEL_SCK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define SPIS_PSEL_SCK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIS_PSEL_SCK_PORT_Msk (0x1UL << SPIS_PSEL_SCK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIS_PSEL_SCK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIS_PSEL_SCK_PIN_Msk (0x1FUL << SPIS_PSEL_SCK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIS_PSEL_MISO */ +/* Description: Pin select for MISO signal */ + +/* Bit 31 : Connection */ +#define SPIS_PSEL_MISO_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIS_PSEL_MISO_CONNECT_Msk (0x1UL << SPIS_PSEL_MISO_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIS_PSEL_MISO_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIS_PSEL_MISO_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define SPIS_PSEL_MISO_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIS_PSEL_MISO_PORT_Msk (0x1UL << SPIS_PSEL_MISO_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIS_PSEL_MISO_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIS_PSEL_MISO_PIN_Msk (0x1FUL << SPIS_PSEL_MISO_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIS_PSEL_MOSI */ +/* Description: Pin select for MOSI signal */ + +/* Bit 31 : Connection */ +#define SPIS_PSEL_MOSI_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIS_PSEL_MOSI_CONNECT_Msk (0x1UL << SPIS_PSEL_MOSI_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIS_PSEL_MOSI_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIS_PSEL_MOSI_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define SPIS_PSEL_MOSI_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIS_PSEL_MOSI_PORT_Msk (0x1UL << SPIS_PSEL_MOSI_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIS_PSEL_MOSI_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIS_PSEL_MOSI_PIN_Msk (0x1FUL << SPIS_PSEL_MOSI_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIS_PSEL_CSN */ +/* Description: Pin select for CSN signal */ + +/* Bit 31 : Connection */ +#define SPIS_PSEL_CSN_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIS_PSEL_CSN_CONNECT_Msk (0x1UL << SPIS_PSEL_CSN_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIS_PSEL_CSN_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIS_PSEL_CSN_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define SPIS_PSEL_CSN_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIS_PSEL_CSN_PORT_Msk (0x1UL << SPIS_PSEL_CSN_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIS_PSEL_CSN_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIS_PSEL_CSN_PIN_Msk (0x1FUL << SPIS_PSEL_CSN_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIS_RXD_PTR */ +/* Description: RXD data pointer */ + +/* Bits 31..0 : RXD data pointer */ +#define SPIS_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define SPIS_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIS_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: SPIS_RXD_MAXCNT */ +/* Description: Maximum number of bytes in receive buffer */ + +/* Bits 7..0 : Maximum number of bytes in receive buffer */ +#define SPIS_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define SPIS_RXD_MAXCNT_MAXCNT_Msk (0xFFUL << SPIS_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: SPIS_RXD_AMOUNT */ +/* Description: Number of bytes received in last granted transaction */ + +/* Bits 7..0 : Number of bytes received in the last granted transaction */ +#define SPIS_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define SPIS_RXD_AMOUNT_AMOUNT_Msk (0xFFUL << SPIS_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: SPIS_TXD_PTR */ +/* Description: TXD data pointer */ + +/* Bits 31..0 : TXD data pointer */ +#define SPIS_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define SPIS_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIS_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: SPIS_TXD_MAXCNT */ +/* Description: Maximum number of bytes in transmit buffer */ + +/* Bits 7..0 : Maximum number of bytes in transmit buffer */ +#define SPIS_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define SPIS_TXD_MAXCNT_MAXCNT_Msk (0xFFUL << SPIS_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: SPIS_TXD_AMOUNT */ +/* Description: Number of bytes transmitted in last granted transaction */ + +/* Bits 7..0 : Number of bytes transmitted in last granted transaction */ +#define SPIS_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define SPIS_TXD_AMOUNT_AMOUNT_Msk (0xFFUL << SPIS_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: SPIS_CONFIG */ +/* Description: Configuration register */ + +/* Bit 2 : Serial clock (SCK) polarity */ +#define SPIS_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */ +#define SPIS_CONFIG_CPOL_Msk (0x1UL << SPIS_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */ +#define SPIS_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high */ +#define SPIS_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low */ + +/* Bit 1 : Serial clock (SCK) phase */ +#define SPIS_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */ +#define SPIS_CONFIG_CPHA_Msk (0x1UL << SPIS_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */ +#define SPIS_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of clock, shift serial data on trailing edge */ +#define SPIS_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of clock, shift serial data on leading edge */ + +/* Bit 0 : Bit order */ +#define SPIS_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */ +#define SPIS_CONFIG_ORDER_Msk (0x1UL << SPIS_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */ +#define SPIS_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit shifted out first */ +#define SPIS_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit shifted out first */ + +/* Register: SPIS_DEF */ +/* Description: Default character. Character clocked out in case of an ignored transaction. */ + +/* Bits 7..0 : Default character. Character clocked out in case of an ignored transaction. */ +#define SPIS_DEF_DEF_Pos (0UL) /*!< Position of DEF field. */ +#define SPIS_DEF_DEF_Msk (0xFFUL << SPIS_DEF_DEF_Pos) /*!< Bit mask of DEF field. */ + +/* Register: SPIS_ORC */ +/* Description: Over-read character */ + +/* Bits 7..0 : Over-read character. Character clocked out after an over-read of the transmit buffer. */ +#define SPIS_ORC_ORC_Pos (0UL) /*!< Position of ORC field. */ +#define SPIS_ORC_ORC_Msk (0xFFUL << SPIS_ORC_ORC_Pos) /*!< Bit mask of ORC field. */ + + +/* Peripheral: TEMP */ +/* Description: Temperature Sensor */ + +/* Register: TEMP_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 0 : Write '1' to Enable interrupt for DATARDY event */ +#define TEMP_INTENSET_DATARDY_Pos (0UL) /*!< Position of DATARDY field. */ +#define TEMP_INTENSET_DATARDY_Msk (0x1UL << TEMP_INTENSET_DATARDY_Pos) /*!< Bit mask of DATARDY field. */ +#define TEMP_INTENSET_DATARDY_Disabled (0UL) /*!< Read: Disabled */ +#define TEMP_INTENSET_DATARDY_Enabled (1UL) /*!< Read: Enabled */ +#define TEMP_INTENSET_DATARDY_Set (1UL) /*!< Enable */ + +/* Register: TEMP_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 0 : Write '1' to Disable interrupt for DATARDY event */ +#define TEMP_INTENCLR_DATARDY_Pos (0UL) /*!< Position of DATARDY field. */ +#define TEMP_INTENCLR_DATARDY_Msk (0x1UL << TEMP_INTENCLR_DATARDY_Pos) /*!< Bit mask of DATARDY field. */ +#define TEMP_INTENCLR_DATARDY_Disabled (0UL) /*!< Read: Disabled */ +#define TEMP_INTENCLR_DATARDY_Enabled (1UL) /*!< Read: Enabled */ +#define TEMP_INTENCLR_DATARDY_Clear (1UL) /*!< Disable */ + +/* Register: TEMP_TEMP */ +/* Description: Temperature in degC (0.25deg steps) */ + +/* Bits 31..0 : Temperature in degC (0.25deg steps) */ +#define TEMP_TEMP_TEMP_Pos (0UL) /*!< Position of TEMP field. */ +#define TEMP_TEMP_TEMP_Msk (0xFFFFFFFFUL << TEMP_TEMP_TEMP_Pos) /*!< Bit mask of TEMP field. */ + +/* Register: TEMP_A0 */ +/* Description: Slope of 1st piece wise linear function */ + +/* Bits 11..0 : Slope of 1st piece wise linear function */ +#define TEMP_A0_A0_Pos (0UL) /*!< Position of A0 field. */ +#define TEMP_A0_A0_Msk (0xFFFUL << TEMP_A0_A0_Pos) /*!< Bit mask of A0 field. */ + +/* Register: TEMP_A1 */ +/* Description: Slope of 2nd piece wise linear function */ + +/* Bits 11..0 : Slope of 2nd piece wise linear function */ +#define TEMP_A1_A1_Pos (0UL) /*!< Position of A1 field. */ +#define TEMP_A1_A1_Msk (0xFFFUL << TEMP_A1_A1_Pos) /*!< Bit mask of A1 field. */ + +/* Register: TEMP_A2 */ +/* Description: Slope of 3rd piece wise linear function */ + +/* Bits 11..0 : Slope of 3rd piece wise linear function */ +#define TEMP_A2_A2_Pos (0UL) /*!< Position of A2 field. */ +#define TEMP_A2_A2_Msk (0xFFFUL << TEMP_A2_A2_Pos) /*!< Bit mask of A2 field. */ + +/* Register: TEMP_A3 */ +/* Description: Slope of 4th piece wise linear function */ + +/* Bits 11..0 : Slope of 4th piece wise linear function */ +#define TEMP_A3_A3_Pos (0UL) /*!< Position of A3 field. */ +#define TEMP_A3_A3_Msk (0xFFFUL << TEMP_A3_A3_Pos) /*!< Bit mask of A3 field. */ + +/* Register: TEMP_A4 */ +/* Description: Slope of 5th piece wise linear function */ + +/* Bits 11..0 : Slope of 5th piece wise linear function */ +#define TEMP_A4_A4_Pos (0UL) /*!< Position of A4 field. */ +#define TEMP_A4_A4_Msk (0xFFFUL << TEMP_A4_A4_Pos) /*!< Bit mask of A4 field. */ + +/* Register: TEMP_A5 */ +/* Description: Slope of 6th piece wise linear function */ + +/* Bits 11..0 : Slope of 6th piece wise linear function */ +#define TEMP_A5_A5_Pos (0UL) /*!< Position of A5 field. */ +#define TEMP_A5_A5_Msk (0xFFFUL << TEMP_A5_A5_Pos) /*!< Bit mask of A5 field. */ + +/* Register: TEMP_B0 */ +/* Description: y-intercept of 1st piece wise linear function */ + +/* Bits 13..0 : y-intercept of 1st piece wise linear function */ +#define TEMP_B0_B0_Pos (0UL) /*!< Position of B0 field. */ +#define TEMP_B0_B0_Msk (0x3FFFUL << TEMP_B0_B0_Pos) /*!< Bit mask of B0 field. */ + +/* Register: TEMP_B1 */ +/* Description: y-intercept of 2nd piece wise linear function */ + +/* Bits 13..0 : y-intercept of 2nd piece wise linear function */ +#define TEMP_B1_B1_Pos (0UL) /*!< Position of B1 field. */ +#define TEMP_B1_B1_Msk (0x3FFFUL << TEMP_B1_B1_Pos) /*!< Bit mask of B1 field. */ + +/* Register: TEMP_B2 */ +/* Description: y-intercept of 3rd piece wise linear function */ + +/* Bits 13..0 : y-intercept of 3rd piece wise linear function */ +#define TEMP_B2_B2_Pos (0UL) /*!< Position of B2 field. */ +#define TEMP_B2_B2_Msk (0x3FFFUL << TEMP_B2_B2_Pos) /*!< Bit mask of B2 field. */ + +/* Register: TEMP_B3 */ +/* Description: y-intercept of 4th piece wise linear function */ + +/* Bits 13..0 : y-intercept of 4th piece wise linear function */ +#define TEMP_B3_B3_Pos (0UL) /*!< Position of B3 field. */ +#define TEMP_B3_B3_Msk (0x3FFFUL << TEMP_B3_B3_Pos) /*!< Bit mask of B3 field. */ + +/* Register: TEMP_B4 */ +/* Description: y-intercept of 5th piece wise linear function */ + +/* Bits 13..0 : y-intercept of 5th piece wise linear function */ +#define TEMP_B4_B4_Pos (0UL) /*!< Position of B4 field. */ +#define TEMP_B4_B4_Msk (0x3FFFUL << TEMP_B4_B4_Pos) /*!< Bit mask of B4 field. */ + +/* Register: TEMP_B5 */ +/* Description: y-intercept of 6th piece wise linear function */ + +/* Bits 13..0 : y-intercept of 6th piece wise linear function */ +#define TEMP_B5_B5_Pos (0UL) /*!< Position of B5 field. */ +#define TEMP_B5_B5_Msk (0x3FFFUL << TEMP_B5_B5_Pos) /*!< Bit mask of B5 field. */ + +/* Register: TEMP_T0 */ +/* Description: End point of 1st piece wise linear function */ + +/* Bits 7..0 : End point of 1st piece wise linear function */ +#define TEMP_T0_T0_Pos (0UL) /*!< Position of T0 field. */ +#define TEMP_T0_T0_Msk (0xFFUL << TEMP_T0_T0_Pos) /*!< Bit mask of T0 field. */ + +/* Register: TEMP_T1 */ +/* Description: End point of 2nd piece wise linear function */ + +/* Bits 7..0 : End point of 2nd piece wise linear function */ +#define TEMP_T1_T1_Pos (0UL) /*!< Position of T1 field. */ +#define TEMP_T1_T1_Msk (0xFFUL << TEMP_T1_T1_Pos) /*!< Bit mask of T1 field. */ + +/* Register: TEMP_T2 */ +/* Description: End point of 3rd piece wise linear function */ + +/* Bits 7..0 : End point of 3rd piece wise linear function */ +#define TEMP_T2_T2_Pos (0UL) /*!< Position of T2 field. */ +#define TEMP_T2_T2_Msk (0xFFUL << TEMP_T2_T2_Pos) /*!< Bit mask of T2 field. */ + +/* Register: TEMP_T3 */ +/* Description: End point of 4th piece wise linear function */ + +/* Bits 7..0 : End point of 4th piece wise linear function */ +#define TEMP_T3_T3_Pos (0UL) /*!< Position of T3 field. */ +#define TEMP_T3_T3_Msk (0xFFUL << TEMP_T3_T3_Pos) /*!< Bit mask of T3 field. */ + +/* Register: TEMP_T4 */ +/* Description: End point of 5th piece wise linear function */ + +/* Bits 7..0 : End point of 5th piece wise linear function */ +#define TEMP_T4_T4_Pos (0UL) /*!< Position of T4 field. */ +#define TEMP_T4_T4_Msk (0xFFUL << TEMP_T4_T4_Pos) /*!< Bit mask of T4 field. */ + + +/* Peripheral: TIMER */ +/* Description: Timer/Counter 0 */ + +/* Register: TIMER_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 13 : Shortcut between COMPARE[5] event and STOP task */ +#define TIMER_SHORTS_COMPARE5_STOP_Pos (13UL) /*!< Position of COMPARE5_STOP field. */ +#define TIMER_SHORTS_COMPARE5_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE5_STOP_Pos) /*!< Bit mask of COMPARE5_STOP field. */ +#define TIMER_SHORTS_COMPARE5_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE5_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 12 : Shortcut between COMPARE[4] event and STOP task */ +#define TIMER_SHORTS_COMPARE4_STOP_Pos (12UL) /*!< Position of COMPARE4_STOP field. */ +#define TIMER_SHORTS_COMPARE4_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE4_STOP_Pos) /*!< Bit mask of COMPARE4_STOP field. */ +#define TIMER_SHORTS_COMPARE4_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE4_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 11 : Shortcut between COMPARE[3] event and STOP task */ +#define TIMER_SHORTS_COMPARE3_STOP_Pos (11UL) /*!< Position of COMPARE3_STOP field. */ +#define TIMER_SHORTS_COMPARE3_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE3_STOP_Pos) /*!< Bit mask of COMPARE3_STOP field. */ +#define TIMER_SHORTS_COMPARE3_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE3_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 10 : Shortcut between COMPARE[2] event and STOP task */ +#define TIMER_SHORTS_COMPARE2_STOP_Pos (10UL) /*!< Position of COMPARE2_STOP field. */ +#define TIMER_SHORTS_COMPARE2_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE2_STOP_Pos) /*!< Bit mask of COMPARE2_STOP field. */ +#define TIMER_SHORTS_COMPARE2_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE2_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 9 : Shortcut between COMPARE[1] event and STOP task */ +#define TIMER_SHORTS_COMPARE1_STOP_Pos (9UL) /*!< Position of COMPARE1_STOP field. */ +#define TIMER_SHORTS_COMPARE1_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE1_STOP_Pos) /*!< Bit mask of COMPARE1_STOP field. */ +#define TIMER_SHORTS_COMPARE1_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE1_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 8 : Shortcut between COMPARE[0] event and STOP task */ +#define TIMER_SHORTS_COMPARE0_STOP_Pos (8UL) /*!< Position of COMPARE0_STOP field. */ +#define TIMER_SHORTS_COMPARE0_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE0_STOP_Pos) /*!< Bit mask of COMPARE0_STOP field. */ +#define TIMER_SHORTS_COMPARE0_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE0_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 5 : Shortcut between COMPARE[5] event and CLEAR task */ +#define TIMER_SHORTS_COMPARE5_CLEAR_Pos (5UL) /*!< Position of COMPARE5_CLEAR field. */ +#define TIMER_SHORTS_COMPARE5_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE5_CLEAR_Pos) /*!< Bit mask of COMPARE5_CLEAR field. */ +#define TIMER_SHORTS_COMPARE5_CLEAR_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE5_CLEAR_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 4 : Shortcut between COMPARE[4] event and CLEAR task */ +#define TIMER_SHORTS_COMPARE4_CLEAR_Pos (4UL) /*!< Position of COMPARE4_CLEAR field. */ +#define TIMER_SHORTS_COMPARE4_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE4_CLEAR_Pos) /*!< Bit mask of COMPARE4_CLEAR field. */ +#define TIMER_SHORTS_COMPARE4_CLEAR_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE4_CLEAR_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between COMPARE[3] event and CLEAR task */ +#define TIMER_SHORTS_COMPARE3_CLEAR_Pos (3UL) /*!< Position of COMPARE3_CLEAR field. */ +#define TIMER_SHORTS_COMPARE3_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE3_CLEAR_Pos) /*!< Bit mask of COMPARE3_CLEAR field. */ +#define TIMER_SHORTS_COMPARE3_CLEAR_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE3_CLEAR_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 2 : Shortcut between COMPARE[2] event and CLEAR task */ +#define TIMER_SHORTS_COMPARE2_CLEAR_Pos (2UL) /*!< Position of COMPARE2_CLEAR field. */ +#define TIMER_SHORTS_COMPARE2_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE2_CLEAR_Pos) /*!< Bit mask of COMPARE2_CLEAR field. */ +#define TIMER_SHORTS_COMPARE2_CLEAR_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE2_CLEAR_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between COMPARE[1] event and CLEAR task */ +#define TIMER_SHORTS_COMPARE1_CLEAR_Pos (1UL) /*!< Position of COMPARE1_CLEAR field. */ +#define TIMER_SHORTS_COMPARE1_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE1_CLEAR_Pos) /*!< Bit mask of COMPARE1_CLEAR field. */ +#define TIMER_SHORTS_COMPARE1_CLEAR_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE1_CLEAR_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between COMPARE[0] event and CLEAR task */ +#define TIMER_SHORTS_COMPARE0_CLEAR_Pos (0UL) /*!< Position of COMPARE0_CLEAR field. */ +#define TIMER_SHORTS_COMPARE0_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE0_CLEAR_Pos) /*!< Bit mask of COMPARE0_CLEAR field. */ +#define TIMER_SHORTS_COMPARE0_CLEAR_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE0_CLEAR_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: TIMER_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 21 : Write '1' to Enable interrupt for COMPARE[5] event */ +#define TIMER_INTENSET_COMPARE5_Pos (21UL) /*!< Position of COMPARE5 field. */ +#define TIMER_INTENSET_COMPARE5_Msk (0x1UL << TIMER_INTENSET_COMPARE5_Pos) /*!< Bit mask of COMPARE5 field. */ +#define TIMER_INTENSET_COMPARE5_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENSET_COMPARE5_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENSET_COMPARE5_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for COMPARE[4] event */ +#define TIMER_INTENSET_COMPARE4_Pos (20UL) /*!< Position of COMPARE4 field. */ +#define TIMER_INTENSET_COMPARE4_Msk (0x1UL << TIMER_INTENSET_COMPARE4_Pos) /*!< Bit mask of COMPARE4 field. */ +#define TIMER_INTENSET_COMPARE4_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENSET_COMPARE4_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENSET_COMPARE4_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for COMPARE[3] event */ +#define TIMER_INTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define TIMER_INTENSET_COMPARE3_Msk (0x1UL << TIMER_INTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define TIMER_INTENSET_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENSET_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENSET_COMPARE3_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for COMPARE[2] event */ +#define TIMER_INTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define TIMER_INTENSET_COMPARE2_Msk (0x1UL << TIMER_INTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define TIMER_INTENSET_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENSET_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENSET_COMPARE2_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable interrupt for COMPARE[1] event */ +#define TIMER_INTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define TIMER_INTENSET_COMPARE1_Msk (0x1UL << TIMER_INTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define TIMER_INTENSET_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENSET_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENSET_COMPARE1_Set (1UL) /*!< Enable */ + +/* Bit 16 : Write '1' to Enable interrupt for COMPARE[0] event */ +#define TIMER_INTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define TIMER_INTENSET_COMPARE0_Msk (0x1UL << TIMER_INTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define TIMER_INTENSET_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENSET_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENSET_COMPARE0_Set (1UL) /*!< Enable */ + +/* Register: TIMER_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 21 : Write '1' to Disable interrupt for COMPARE[5] event */ +#define TIMER_INTENCLR_COMPARE5_Pos (21UL) /*!< Position of COMPARE5 field. */ +#define TIMER_INTENCLR_COMPARE5_Msk (0x1UL << TIMER_INTENCLR_COMPARE5_Pos) /*!< Bit mask of COMPARE5 field. */ +#define TIMER_INTENCLR_COMPARE5_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENCLR_COMPARE5_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENCLR_COMPARE5_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for COMPARE[4] event */ +#define TIMER_INTENCLR_COMPARE4_Pos (20UL) /*!< Position of COMPARE4 field. */ +#define TIMER_INTENCLR_COMPARE4_Msk (0x1UL << TIMER_INTENCLR_COMPARE4_Pos) /*!< Bit mask of COMPARE4 field. */ +#define TIMER_INTENCLR_COMPARE4_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENCLR_COMPARE4_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENCLR_COMPARE4_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for COMPARE[3] event */ +#define TIMER_INTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define TIMER_INTENCLR_COMPARE3_Msk (0x1UL << TIMER_INTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define TIMER_INTENCLR_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENCLR_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENCLR_COMPARE3_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for COMPARE[2] event */ +#define TIMER_INTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define TIMER_INTENCLR_COMPARE2_Msk (0x1UL << TIMER_INTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define TIMER_INTENCLR_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENCLR_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENCLR_COMPARE2_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable interrupt for COMPARE[1] event */ +#define TIMER_INTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define TIMER_INTENCLR_COMPARE1_Msk (0x1UL << TIMER_INTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define TIMER_INTENCLR_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENCLR_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENCLR_COMPARE1_Clear (1UL) /*!< Disable */ + +/* Bit 16 : Write '1' to Disable interrupt for COMPARE[0] event */ +#define TIMER_INTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define TIMER_INTENCLR_COMPARE0_Msk (0x1UL << TIMER_INTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define TIMER_INTENCLR_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENCLR_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENCLR_COMPARE0_Clear (1UL) /*!< Disable */ + +/* Register: TIMER_STATUS */ +/* Description: Timer status */ + +/* Bit 0 : Timer status */ +#define TIMER_STATUS_STATUS_Pos (0UL) /*!< Position of STATUS field. */ +#define TIMER_STATUS_STATUS_Msk (0x1UL << TIMER_STATUS_STATUS_Pos) /*!< Bit mask of STATUS field. */ +#define TIMER_STATUS_STATUS_Stopped (0UL) /*!< Timer is stopped */ +#define TIMER_STATUS_STATUS_Started (1UL) /*!< Timer is started */ + +/* Register: TIMER_MODE */ +/* Description: Timer mode selection */ + +/* Bits 1..0 : Timer mode */ +#define TIMER_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */ +#define TIMER_MODE_MODE_Msk (0x3UL << TIMER_MODE_MODE_Pos) /*!< Bit mask of MODE field. */ +#define TIMER_MODE_MODE_Timer (0UL) /*!< Select Timer mode */ +#define TIMER_MODE_MODE_Counter (1UL) /*!< Deprecated enumerator - Select Counter mode */ +#define TIMER_MODE_MODE_LowPowerCounter (2UL) /*!< Select Low Power Counter mode */ + +/* Register: TIMER_BITMODE */ +/* Description: Configure the number of bits used by the TIMER */ + +/* Bits 1..0 : Timer bit width */ +#define TIMER_BITMODE_BITMODE_Pos (0UL) /*!< Position of BITMODE field. */ +#define TIMER_BITMODE_BITMODE_Msk (0x3UL << TIMER_BITMODE_BITMODE_Pos) /*!< Bit mask of BITMODE field. */ +#define TIMER_BITMODE_BITMODE_16Bit (0UL) /*!< 16 bit timer bit width */ +#define TIMER_BITMODE_BITMODE_08Bit (1UL) /*!< 8 bit timer bit width */ +#define TIMER_BITMODE_BITMODE_24Bit (2UL) /*!< 24 bit timer bit width */ +#define TIMER_BITMODE_BITMODE_32Bit (3UL) /*!< 32 bit timer bit width */ + +/* Register: TIMER_PRESCALER */ +/* Description: Timer prescaler register */ + +/* Bits 3..0 : Prescaler value */ +#define TIMER_PRESCALER_PRESCALER_Pos (0UL) /*!< Position of PRESCALER field. */ +#define TIMER_PRESCALER_PRESCALER_Msk (0xFUL << TIMER_PRESCALER_PRESCALER_Pos) /*!< Bit mask of PRESCALER field. */ + +/* Register: TIMER_CC */ +/* Description: Description collection[0]: Capture/Compare register 0 */ + +/* Bits 31..0 : Capture/Compare value */ +#define TIMER_CC_CC_Pos (0UL) /*!< Position of CC field. */ +#define TIMER_CC_CC_Msk (0xFFFFFFFFUL << TIMER_CC_CC_Pos) /*!< Bit mask of CC field. */ + + +/* Peripheral: TWI */ +/* Description: I2C compatible Two-Wire Interface 0 */ + +/* Register: TWI_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 1 : Shortcut between BB event and STOP task */ +#define TWI_SHORTS_BB_STOP_Pos (1UL) /*!< Position of BB_STOP field. */ +#define TWI_SHORTS_BB_STOP_Msk (0x1UL << TWI_SHORTS_BB_STOP_Pos) /*!< Bit mask of BB_STOP field. */ +#define TWI_SHORTS_BB_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TWI_SHORTS_BB_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between BB event and SUSPEND task */ +#define TWI_SHORTS_BB_SUSPEND_Pos (0UL) /*!< Position of BB_SUSPEND field. */ +#define TWI_SHORTS_BB_SUSPEND_Msk (0x1UL << TWI_SHORTS_BB_SUSPEND_Pos) /*!< Bit mask of BB_SUSPEND field. */ +#define TWI_SHORTS_BB_SUSPEND_Disabled (0UL) /*!< Disable shortcut */ +#define TWI_SHORTS_BB_SUSPEND_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: TWI_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 18 : Write '1' to Enable interrupt for SUSPENDED event */ +#define TWI_INTENSET_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWI_INTENSET_SUSPENDED_Msk (0x1UL << TWI_INTENSET_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWI_INTENSET_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENSET_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENSET_SUSPENDED_Set (1UL) /*!< Enable */ + +/* Bit 14 : Write '1' to Enable interrupt for BB event */ +#define TWI_INTENSET_BB_Pos (14UL) /*!< Position of BB field. */ +#define TWI_INTENSET_BB_Msk (0x1UL << TWI_INTENSET_BB_Pos) /*!< Bit mask of BB field. */ +#define TWI_INTENSET_BB_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENSET_BB_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENSET_BB_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ +#define TWI_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWI_INTENSET_ERROR_Msk (0x1UL << TWI_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWI_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENSET_ERROR_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for TXDSENT event */ +#define TWI_INTENSET_TXDSENT_Pos (7UL) /*!< Position of TXDSENT field. */ +#define TWI_INTENSET_TXDSENT_Msk (0x1UL << TWI_INTENSET_TXDSENT_Pos) /*!< Bit mask of TXDSENT field. */ +#define TWI_INTENSET_TXDSENT_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENSET_TXDSENT_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENSET_TXDSENT_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for RXDREADY event */ +#define TWI_INTENSET_RXDREADY_Pos (2UL) /*!< Position of RXDREADY field. */ +#define TWI_INTENSET_RXDREADY_Msk (0x1UL << TWI_INTENSET_RXDREADY_Pos) /*!< Bit mask of RXDREADY field. */ +#define TWI_INTENSET_RXDREADY_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENSET_RXDREADY_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENSET_RXDREADY_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ +#define TWI_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWI_INTENSET_STOPPED_Msk (0x1UL << TWI_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWI_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Register: TWI_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 18 : Write '1' to Disable interrupt for SUSPENDED event */ +#define TWI_INTENCLR_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWI_INTENCLR_SUSPENDED_Msk (0x1UL << TWI_INTENCLR_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWI_INTENCLR_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENCLR_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENCLR_SUSPENDED_Clear (1UL) /*!< Disable */ + +/* Bit 14 : Write '1' to Disable interrupt for BB event */ +#define TWI_INTENCLR_BB_Pos (14UL) /*!< Position of BB field. */ +#define TWI_INTENCLR_BB_Msk (0x1UL << TWI_INTENCLR_BB_Pos) /*!< Bit mask of BB field. */ +#define TWI_INTENCLR_BB_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENCLR_BB_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENCLR_BB_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ +#define TWI_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWI_INTENCLR_ERROR_Msk (0x1UL << TWI_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWI_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for TXDSENT event */ +#define TWI_INTENCLR_TXDSENT_Pos (7UL) /*!< Position of TXDSENT field. */ +#define TWI_INTENCLR_TXDSENT_Msk (0x1UL << TWI_INTENCLR_TXDSENT_Pos) /*!< Bit mask of TXDSENT field. */ +#define TWI_INTENCLR_TXDSENT_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENCLR_TXDSENT_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENCLR_TXDSENT_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for RXDREADY event */ +#define TWI_INTENCLR_RXDREADY_Pos (2UL) /*!< Position of RXDREADY field. */ +#define TWI_INTENCLR_RXDREADY_Msk (0x1UL << TWI_INTENCLR_RXDREADY_Pos) /*!< Bit mask of RXDREADY field. */ +#define TWI_INTENCLR_RXDREADY_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENCLR_RXDREADY_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENCLR_RXDREADY_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ +#define TWI_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWI_INTENCLR_STOPPED_Msk (0x1UL << TWI_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWI_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Register: TWI_ERRORSRC */ +/* Description: Error source */ + +/* Bit 2 : NACK received after sending a data byte (write '1' to clear) */ +#define TWI_ERRORSRC_DNACK_Pos (2UL) /*!< Position of DNACK field. */ +#define TWI_ERRORSRC_DNACK_Msk (0x1UL << TWI_ERRORSRC_DNACK_Pos) /*!< Bit mask of DNACK field. */ +#define TWI_ERRORSRC_DNACK_NotPresent (0UL) /*!< Read: error not present */ +#define TWI_ERRORSRC_DNACK_Present (1UL) /*!< Read: error present */ + +/* Bit 1 : NACK received after sending the address (write '1' to clear) */ +#define TWI_ERRORSRC_ANACK_Pos (1UL) /*!< Position of ANACK field. */ +#define TWI_ERRORSRC_ANACK_Msk (0x1UL << TWI_ERRORSRC_ANACK_Pos) /*!< Bit mask of ANACK field. */ +#define TWI_ERRORSRC_ANACK_NotPresent (0UL) /*!< Read: error not present */ +#define TWI_ERRORSRC_ANACK_Present (1UL) /*!< Read: error present */ + +/* Bit 0 : Overrun error */ +#define TWI_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */ +#define TWI_ERRORSRC_OVERRUN_Msk (0x1UL << TWI_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ +#define TWI_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Read: no overrun occured */ +#define TWI_ERRORSRC_OVERRUN_Present (1UL) /*!< Read: overrun occured */ + +/* Register: TWI_ENABLE */ +/* Description: Enable TWI */ + +/* Bits 3..0 : Enable or disable TWI */ +#define TWI_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define TWI_ENABLE_ENABLE_Msk (0xFUL << TWI_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define TWI_ENABLE_ENABLE_Disabled (0UL) /*!< Disable TWI */ +#define TWI_ENABLE_ENABLE_Enabled (5UL) /*!< Enable TWI */ + +/* Register: TWI_PSEL_SCL */ +/* Description: Pin select for SCL */ + +/* Bit 31 : Connection */ +#define TWI_PSEL_SCL_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define TWI_PSEL_SCL_CONNECT_Msk (0x1UL << TWI_PSEL_SCL_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define TWI_PSEL_SCL_CONNECT_Connected (0UL) /*!< Connect */ +#define TWI_PSEL_SCL_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define TWI_PSEL_SCL_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define TWI_PSEL_SCL_PORT_Msk (0x1UL << TWI_PSEL_SCL_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define TWI_PSEL_SCL_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define TWI_PSEL_SCL_PIN_Msk (0x1FUL << TWI_PSEL_SCL_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: TWI_PSEL_SDA */ +/* Description: Pin select for SDA */ + +/* Bit 31 : Connection */ +#define TWI_PSEL_SDA_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define TWI_PSEL_SDA_CONNECT_Msk (0x1UL << TWI_PSEL_SDA_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define TWI_PSEL_SDA_CONNECT_Connected (0UL) /*!< Connect */ +#define TWI_PSEL_SDA_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define TWI_PSEL_SDA_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define TWI_PSEL_SDA_PORT_Msk (0x1UL << TWI_PSEL_SDA_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define TWI_PSEL_SDA_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define TWI_PSEL_SDA_PIN_Msk (0x1FUL << TWI_PSEL_SDA_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: TWI_RXD */ +/* Description: RXD register */ + +/* Bits 7..0 : RXD register */ +#define TWI_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */ +#define TWI_RXD_RXD_Msk (0xFFUL << TWI_RXD_RXD_Pos) /*!< Bit mask of RXD field. */ + +/* Register: TWI_TXD */ +/* Description: TXD register */ + +/* Bits 7..0 : TXD register */ +#define TWI_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */ +#define TWI_TXD_TXD_Msk (0xFFUL << TWI_TXD_TXD_Pos) /*!< Bit mask of TXD field. */ + +/* Register: TWI_FREQUENCY */ +/* Description: TWI frequency. Accuracy depends on the HFCLK source selected. */ + +/* Bits 31..0 : TWI master clock frequency */ +#define TWI_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */ +#define TWI_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << TWI_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */ +#define TWI_FREQUENCY_FREQUENCY_K100 (0x01980000UL) /*!< 100 kbps */ +#define TWI_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps */ +#define TWI_FREQUENCY_FREQUENCY_K400 (0x06680000UL) /*!< 400 kbps (actual rate 410.256 kbps) */ + +/* Register: TWI_ADDRESS */ +/* Description: Address used in the TWI transfer */ + +/* Bits 6..0 : Address used in the TWI transfer */ +#define TWI_ADDRESS_ADDRESS_Pos (0UL) /*!< Position of ADDRESS field. */ +#define TWI_ADDRESS_ADDRESS_Msk (0x7FUL << TWI_ADDRESS_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */ + + +/* Peripheral: TWIM */ +/* Description: I2C compatible Two-Wire Master Interface with EasyDMA 0 */ + +/* Register: TWIM_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 12 : Shortcut between LASTRX event and STOP task */ +#define TWIM_SHORTS_LASTRX_STOP_Pos (12UL) /*!< Position of LASTRX_STOP field. */ +#define TWIM_SHORTS_LASTRX_STOP_Msk (0x1UL << TWIM_SHORTS_LASTRX_STOP_Pos) /*!< Bit mask of LASTRX_STOP field. */ +#define TWIM_SHORTS_LASTRX_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TWIM_SHORTS_LASTRX_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 10 : Shortcut between LASTRX event and STARTTX task */ +#define TWIM_SHORTS_LASTRX_STARTTX_Pos (10UL) /*!< Position of LASTRX_STARTTX field. */ +#define TWIM_SHORTS_LASTRX_STARTTX_Msk (0x1UL << TWIM_SHORTS_LASTRX_STARTTX_Pos) /*!< Bit mask of LASTRX_STARTTX field. */ +#define TWIM_SHORTS_LASTRX_STARTTX_Disabled (0UL) /*!< Disable shortcut */ +#define TWIM_SHORTS_LASTRX_STARTTX_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 9 : Shortcut between LASTTX event and STOP task */ +#define TWIM_SHORTS_LASTTX_STOP_Pos (9UL) /*!< Position of LASTTX_STOP field. */ +#define TWIM_SHORTS_LASTTX_STOP_Msk (0x1UL << TWIM_SHORTS_LASTTX_STOP_Pos) /*!< Bit mask of LASTTX_STOP field. */ +#define TWIM_SHORTS_LASTTX_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TWIM_SHORTS_LASTTX_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 8 : Shortcut between LASTTX event and SUSPEND task */ +#define TWIM_SHORTS_LASTTX_SUSPEND_Pos (8UL) /*!< Position of LASTTX_SUSPEND field. */ +#define TWIM_SHORTS_LASTTX_SUSPEND_Msk (0x1UL << TWIM_SHORTS_LASTTX_SUSPEND_Pos) /*!< Bit mask of LASTTX_SUSPEND field. */ +#define TWIM_SHORTS_LASTTX_SUSPEND_Disabled (0UL) /*!< Disable shortcut */ +#define TWIM_SHORTS_LASTTX_SUSPEND_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 7 : Shortcut between LASTTX event and STARTRX task */ +#define TWIM_SHORTS_LASTTX_STARTRX_Pos (7UL) /*!< Position of LASTTX_STARTRX field. */ +#define TWIM_SHORTS_LASTTX_STARTRX_Msk (0x1UL << TWIM_SHORTS_LASTTX_STARTRX_Pos) /*!< Bit mask of LASTTX_STARTRX field. */ +#define TWIM_SHORTS_LASTTX_STARTRX_Disabled (0UL) /*!< Disable shortcut */ +#define TWIM_SHORTS_LASTTX_STARTRX_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: TWIM_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 24 : Enable or disable interrupt for LASTTX event */ +#define TWIM_INTEN_LASTTX_Pos (24UL) /*!< Position of LASTTX field. */ +#define TWIM_INTEN_LASTTX_Msk (0x1UL << TWIM_INTEN_LASTTX_Pos) /*!< Bit mask of LASTTX field. */ +#define TWIM_INTEN_LASTTX_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_LASTTX_Enabled (1UL) /*!< Enable */ + +/* Bit 23 : Enable or disable interrupt for LASTRX event */ +#define TWIM_INTEN_LASTRX_Pos (23UL) /*!< Position of LASTRX field. */ +#define TWIM_INTEN_LASTRX_Msk (0x1UL << TWIM_INTEN_LASTRX_Pos) /*!< Bit mask of LASTRX field. */ +#define TWIM_INTEN_LASTRX_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_LASTRX_Enabled (1UL) /*!< Enable */ + +/* Bit 20 : Enable or disable interrupt for TXSTARTED event */ +#define TWIM_INTEN_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define TWIM_INTEN_TXSTARTED_Msk (0x1UL << TWIM_INTEN_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define TWIM_INTEN_TXSTARTED_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_TXSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 19 : Enable or disable interrupt for RXSTARTED event */ +#define TWIM_INTEN_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define TWIM_INTEN_RXSTARTED_Msk (0x1UL << TWIM_INTEN_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define TWIM_INTEN_RXSTARTED_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_RXSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 18 : Enable or disable interrupt for SUSPENDED event */ +#define TWIM_INTEN_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWIM_INTEN_SUSPENDED_Msk (0x1UL << TWIM_INTEN_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWIM_INTEN_SUSPENDED_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_SUSPENDED_Enabled (1UL) /*!< Enable */ + +/* Bit 9 : Enable or disable interrupt for ERROR event */ +#define TWIM_INTEN_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWIM_INTEN_ERROR_Msk (0x1UL << TWIM_INTEN_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWIM_INTEN_ERROR_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_ERROR_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for STOPPED event */ +#define TWIM_INTEN_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWIM_INTEN_STOPPED_Msk (0x1UL << TWIM_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWIM_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ + +/* Register: TWIM_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 24 : Write '1' to Enable interrupt for LASTTX event */ +#define TWIM_INTENSET_LASTTX_Pos (24UL) /*!< Position of LASTTX field. */ +#define TWIM_INTENSET_LASTTX_Msk (0x1UL << TWIM_INTENSET_LASTTX_Pos) /*!< Bit mask of LASTTX field. */ +#define TWIM_INTENSET_LASTTX_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_LASTTX_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_LASTTX_Set (1UL) /*!< Enable */ + +/* Bit 23 : Write '1' to Enable interrupt for LASTRX event */ +#define TWIM_INTENSET_LASTRX_Pos (23UL) /*!< Position of LASTRX field. */ +#define TWIM_INTENSET_LASTRX_Msk (0x1UL << TWIM_INTENSET_LASTRX_Pos) /*!< Bit mask of LASTRX field. */ +#define TWIM_INTENSET_LASTRX_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_LASTRX_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_LASTRX_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for TXSTARTED event */ +#define TWIM_INTENSET_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define TWIM_INTENSET_TXSTARTED_Msk (0x1UL << TWIM_INTENSET_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define TWIM_INTENSET_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_TXSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for RXSTARTED event */ +#define TWIM_INTENSET_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define TWIM_INTENSET_RXSTARTED_Msk (0x1UL << TWIM_INTENSET_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define TWIM_INTENSET_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_RXSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for SUSPENDED event */ +#define TWIM_INTENSET_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWIM_INTENSET_SUSPENDED_Msk (0x1UL << TWIM_INTENSET_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWIM_INTENSET_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_SUSPENDED_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ +#define TWIM_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWIM_INTENSET_ERROR_Msk (0x1UL << TWIM_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWIM_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_ERROR_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ +#define TWIM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWIM_INTENSET_STOPPED_Msk (0x1UL << TWIM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWIM_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Register: TWIM_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 24 : Write '1' to Disable interrupt for LASTTX event */ +#define TWIM_INTENCLR_LASTTX_Pos (24UL) /*!< Position of LASTTX field. */ +#define TWIM_INTENCLR_LASTTX_Msk (0x1UL << TWIM_INTENCLR_LASTTX_Pos) /*!< Bit mask of LASTTX field. */ +#define TWIM_INTENCLR_LASTTX_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_LASTTX_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_LASTTX_Clear (1UL) /*!< Disable */ + +/* Bit 23 : Write '1' to Disable interrupt for LASTRX event */ +#define TWIM_INTENCLR_LASTRX_Pos (23UL) /*!< Position of LASTRX field. */ +#define TWIM_INTENCLR_LASTRX_Msk (0x1UL << TWIM_INTENCLR_LASTRX_Pos) /*!< Bit mask of LASTRX field. */ +#define TWIM_INTENCLR_LASTRX_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_LASTRX_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_LASTRX_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for TXSTARTED event */ +#define TWIM_INTENCLR_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define TWIM_INTENCLR_TXSTARTED_Msk (0x1UL << TWIM_INTENCLR_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define TWIM_INTENCLR_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_TXSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for RXSTARTED event */ +#define TWIM_INTENCLR_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define TWIM_INTENCLR_RXSTARTED_Msk (0x1UL << TWIM_INTENCLR_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define TWIM_INTENCLR_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_RXSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for SUSPENDED event */ +#define TWIM_INTENCLR_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWIM_INTENCLR_SUSPENDED_Msk (0x1UL << TWIM_INTENCLR_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWIM_INTENCLR_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_SUSPENDED_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ +#define TWIM_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWIM_INTENCLR_ERROR_Msk (0x1UL << TWIM_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWIM_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ +#define TWIM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWIM_INTENCLR_STOPPED_Msk (0x1UL << TWIM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWIM_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Register: TWIM_ERRORSRC */ +/* Description: Error source */ + +/* Bit 2 : NACK received after sending a data byte (write '1' to clear) */ +#define TWIM_ERRORSRC_DNACK_Pos (2UL) /*!< Position of DNACK field. */ +#define TWIM_ERRORSRC_DNACK_Msk (0x1UL << TWIM_ERRORSRC_DNACK_Pos) /*!< Bit mask of DNACK field. */ +#define TWIM_ERRORSRC_DNACK_NotReceived (0UL) /*!< Error did not occur */ +#define TWIM_ERRORSRC_DNACK_Received (1UL) /*!< Error occurred */ + +/* Bit 1 : NACK received after sending the address (write '1' to clear) */ +#define TWIM_ERRORSRC_ANACK_Pos (1UL) /*!< Position of ANACK field. */ +#define TWIM_ERRORSRC_ANACK_Msk (0x1UL << TWIM_ERRORSRC_ANACK_Pos) /*!< Bit mask of ANACK field. */ +#define TWIM_ERRORSRC_ANACK_NotReceived (0UL) /*!< Error did not occur */ +#define TWIM_ERRORSRC_ANACK_Received (1UL) /*!< Error occurred */ + +/* Bit 0 : Overrun error */ +#define TWIM_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */ +#define TWIM_ERRORSRC_OVERRUN_Msk (0x1UL << TWIM_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ +#define TWIM_ERRORSRC_OVERRUN_NotReceived (0UL) /*!< Error did not occur */ +#define TWIM_ERRORSRC_OVERRUN_Received (1UL) /*!< Error occurred */ + +/* Register: TWIM_ENABLE */ +/* Description: Enable TWIM */ + +/* Bits 3..0 : Enable or disable TWIM */ +#define TWIM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define TWIM_ENABLE_ENABLE_Msk (0xFUL << TWIM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define TWIM_ENABLE_ENABLE_Disabled (0UL) /*!< Disable TWIM */ +#define TWIM_ENABLE_ENABLE_Enabled (6UL) /*!< Enable TWIM */ + +/* Register: TWIM_PSEL_SCL */ +/* Description: Pin select for SCL signal */ + +/* Bit 31 : Connection */ +#define TWIM_PSEL_SCL_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define TWIM_PSEL_SCL_CONNECT_Msk (0x1UL << TWIM_PSEL_SCL_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define TWIM_PSEL_SCL_CONNECT_Connected (0UL) /*!< Connect */ +#define TWIM_PSEL_SCL_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define TWIM_PSEL_SCL_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define TWIM_PSEL_SCL_PORT_Msk (0x1UL << TWIM_PSEL_SCL_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define TWIM_PSEL_SCL_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define TWIM_PSEL_SCL_PIN_Msk (0x1FUL << TWIM_PSEL_SCL_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: TWIM_PSEL_SDA */ +/* Description: Pin select for SDA signal */ + +/* Bit 31 : Connection */ +#define TWIM_PSEL_SDA_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define TWIM_PSEL_SDA_CONNECT_Msk (0x1UL << TWIM_PSEL_SDA_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define TWIM_PSEL_SDA_CONNECT_Connected (0UL) /*!< Connect */ +#define TWIM_PSEL_SDA_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define TWIM_PSEL_SDA_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define TWIM_PSEL_SDA_PORT_Msk (0x1UL << TWIM_PSEL_SDA_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define TWIM_PSEL_SDA_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define TWIM_PSEL_SDA_PIN_Msk (0x1FUL << TWIM_PSEL_SDA_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: TWIM_FREQUENCY */ +/* Description: TWI frequency. Accuracy depends on the HFCLK source selected. */ + +/* Bits 31..0 : TWI master clock frequency */ +#define TWIM_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */ +#define TWIM_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << TWIM_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */ +#define TWIM_FREQUENCY_FREQUENCY_K100 (0x01980000UL) /*!< 100 kbps */ +#define TWIM_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps */ +#define TWIM_FREQUENCY_FREQUENCY_K400 (0x06400000UL) /*!< 400 kbps */ + +/* Register: TWIM_RXD_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define TWIM_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define TWIM_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << TWIM_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: TWIM_RXD_MAXCNT */ +/* Description: Maximum number of bytes in receive buffer */ + +/* Bits 7..0 : Maximum number of bytes in receive buffer */ +#define TWIM_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define TWIM_RXD_MAXCNT_MAXCNT_Msk (0xFFUL << TWIM_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: TWIM_RXD_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 7..0 : Number of bytes transferred in the last transaction. In case of NACK error, includes the NACK'ed byte. */ +#define TWIM_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define TWIM_RXD_AMOUNT_AMOUNT_Msk (0xFFUL << TWIM_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: TWIM_RXD_LIST */ +/* Description: EasyDMA list type */ + +/* Bits 2..0 : List type */ +#define TWIM_RXD_LIST_LIST_Pos (0UL) /*!< Position of LIST field. */ +#define TWIM_RXD_LIST_LIST_Msk (0x7UL << TWIM_RXD_LIST_LIST_Pos) /*!< Bit mask of LIST field. */ +#define TWIM_RXD_LIST_LIST_Disabled (0UL) /*!< Disable EasyDMA list */ +#define TWIM_RXD_LIST_LIST_ArrayList (1UL) /*!< Use array list */ + +/* Register: TWIM_TXD_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define TWIM_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define TWIM_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << TWIM_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: TWIM_TXD_MAXCNT */ +/* Description: Maximum number of bytes in transmit buffer */ + +/* Bits 7..0 : Maximum number of bytes in transmit buffer */ +#define TWIM_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define TWIM_TXD_MAXCNT_MAXCNT_Msk (0xFFUL << TWIM_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: TWIM_TXD_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 7..0 : Number of bytes transferred in the last transaction. In case of NACK error, includes the NACK'ed byte. */ +#define TWIM_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define TWIM_TXD_AMOUNT_AMOUNT_Msk (0xFFUL << TWIM_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: TWIM_TXD_LIST */ +/* Description: EasyDMA list type */ + +/* Bits 2..0 : List type */ +#define TWIM_TXD_LIST_LIST_Pos (0UL) /*!< Position of LIST field. */ +#define TWIM_TXD_LIST_LIST_Msk (0x7UL << TWIM_TXD_LIST_LIST_Pos) /*!< Bit mask of LIST field. */ +#define TWIM_TXD_LIST_LIST_Disabled (0UL) /*!< Disable EasyDMA list */ +#define TWIM_TXD_LIST_LIST_ArrayList (1UL) /*!< Use array list */ + +/* Register: TWIM_ADDRESS */ +/* Description: Address used in the TWI transfer */ + +/* Bits 6..0 : Address used in the TWI transfer */ +#define TWIM_ADDRESS_ADDRESS_Pos (0UL) /*!< Position of ADDRESS field. */ +#define TWIM_ADDRESS_ADDRESS_Msk (0x7FUL << TWIM_ADDRESS_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */ + + +/* Peripheral: TWIS */ +/* Description: I2C compatible Two-Wire Slave Interface with EasyDMA 0 */ + +/* Register: TWIS_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 14 : Shortcut between READ event and SUSPEND task */ +#define TWIS_SHORTS_READ_SUSPEND_Pos (14UL) /*!< Position of READ_SUSPEND field. */ +#define TWIS_SHORTS_READ_SUSPEND_Msk (0x1UL << TWIS_SHORTS_READ_SUSPEND_Pos) /*!< Bit mask of READ_SUSPEND field. */ +#define TWIS_SHORTS_READ_SUSPEND_Disabled (0UL) /*!< Disable shortcut */ +#define TWIS_SHORTS_READ_SUSPEND_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 13 : Shortcut between WRITE event and SUSPEND task */ +#define TWIS_SHORTS_WRITE_SUSPEND_Pos (13UL) /*!< Position of WRITE_SUSPEND field. */ +#define TWIS_SHORTS_WRITE_SUSPEND_Msk (0x1UL << TWIS_SHORTS_WRITE_SUSPEND_Pos) /*!< Bit mask of WRITE_SUSPEND field. */ +#define TWIS_SHORTS_WRITE_SUSPEND_Disabled (0UL) /*!< Disable shortcut */ +#define TWIS_SHORTS_WRITE_SUSPEND_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: TWIS_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 26 : Enable or disable interrupt for READ event */ +#define TWIS_INTEN_READ_Pos (26UL) /*!< Position of READ field. */ +#define TWIS_INTEN_READ_Msk (0x1UL << TWIS_INTEN_READ_Pos) /*!< Bit mask of READ field. */ +#define TWIS_INTEN_READ_Disabled (0UL) /*!< Disable */ +#define TWIS_INTEN_READ_Enabled (1UL) /*!< Enable */ + +/* Bit 25 : Enable or disable interrupt for WRITE event */ +#define TWIS_INTEN_WRITE_Pos (25UL) /*!< Position of WRITE field. */ +#define TWIS_INTEN_WRITE_Msk (0x1UL << TWIS_INTEN_WRITE_Pos) /*!< Bit mask of WRITE field. */ +#define TWIS_INTEN_WRITE_Disabled (0UL) /*!< Disable */ +#define TWIS_INTEN_WRITE_Enabled (1UL) /*!< Enable */ + +/* Bit 20 : Enable or disable interrupt for TXSTARTED event */ +#define TWIS_INTEN_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define TWIS_INTEN_TXSTARTED_Msk (0x1UL << TWIS_INTEN_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define TWIS_INTEN_TXSTARTED_Disabled (0UL) /*!< Disable */ +#define TWIS_INTEN_TXSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 19 : Enable or disable interrupt for RXSTARTED event */ +#define TWIS_INTEN_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define TWIS_INTEN_RXSTARTED_Msk (0x1UL << TWIS_INTEN_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define TWIS_INTEN_RXSTARTED_Disabled (0UL) /*!< Disable */ +#define TWIS_INTEN_RXSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 9 : Enable or disable interrupt for ERROR event */ +#define TWIS_INTEN_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWIS_INTEN_ERROR_Msk (0x1UL << TWIS_INTEN_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWIS_INTEN_ERROR_Disabled (0UL) /*!< Disable */ +#define TWIS_INTEN_ERROR_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for STOPPED event */ +#define TWIS_INTEN_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWIS_INTEN_STOPPED_Msk (0x1UL << TWIS_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWIS_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ +#define TWIS_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ + +/* Register: TWIS_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 26 : Write '1' to Enable interrupt for READ event */ +#define TWIS_INTENSET_READ_Pos (26UL) /*!< Position of READ field. */ +#define TWIS_INTENSET_READ_Msk (0x1UL << TWIS_INTENSET_READ_Pos) /*!< Bit mask of READ field. */ +#define TWIS_INTENSET_READ_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENSET_READ_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENSET_READ_Set (1UL) /*!< Enable */ + +/* Bit 25 : Write '1' to Enable interrupt for WRITE event */ +#define TWIS_INTENSET_WRITE_Pos (25UL) /*!< Position of WRITE field. */ +#define TWIS_INTENSET_WRITE_Msk (0x1UL << TWIS_INTENSET_WRITE_Pos) /*!< Bit mask of WRITE field. */ +#define TWIS_INTENSET_WRITE_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENSET_WRITE_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENSET_WRITE_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for TXSTARTED event */ +#define TWIS_INTENSET_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define TWIS_INTENSET_TXSTARTED_Msk (0x1UL << TWIS_INTENSET_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define TWIS_INTENSET_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENSET_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENSET_TXSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for RXSTARTED event */ +#define TWIS_INTENSET_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define TWIS_INTENSET_RXSTARTED_Msk (0x1UL << TWIS_INTENSET_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define TWIS_INTENSET_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENSET_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENSET_RXSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ +#define TWIS_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWIS_INTENSET_ERROR_Msk (0x1UL << TWIS_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWIS_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENSET_ERROR_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ +#define TWIS_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWIS_INTENSET_STOPPED_Msk (0x1UL << TWIS_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWIS_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Register: TWIS_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 26 : Write '1' to Disable interrupt for READ event */ +#define TWIS_INTENCLR_READ_Pos (26UL) /*!< Position of READ field. */ +#define TWIS_INTENCLR_READ_Msk (0x1UL << TWIS_INTENCLR_READ_Pos) /*!< Bit mask of READ field. */ +#define TWIS_INTENCLR_READ_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENCLR_READ_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENCLR_READ_Clear (1UL) /*!< Disable */ + +/* Bit 25 : Write '1' to Disable interrupt for WRITE event */ +#define TWIS_INTENCLR_WRITE_Pos (25UL) /*!< Position of WRITE field. */ +#define TWIS_INTENCLR_WRITE_Msk (0x1UL << TWIS_INTENCLR_WRITE_Pos) /*!< Bit mask of WRITE field. */ +#define TWIS_INTENCLR_WRITE_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENCLR_WRITE_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENCLR_WRITE_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for TXSTARTED event */ +#define TWIS_INTENCLR_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define TWIS_INTENCLR_TXSTARTED_Msk (0x1UL << TWIS_INTENCLR_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define TWIS_INTENCLR_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENCLR_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENCLR_TXSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for RXSTARTED event */ +#define TWIS_INTENCLR_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define TWIS_INTENCLR_RXSTARTED_Msk (0x1UL << TWIS_INTENCLR_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define TWIS_INTENCLR_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENCLR_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENCLR_RXSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ +#define TWIS_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWIS_INTENCLR_ERROR_Msk (0x1UL << TWIS_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWIS_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ +#define TWIS_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWIS_INTENCLR_STOPPED_Msk (0x1UL << TWIS_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWIS_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Register: TWIS_ERRORSRC */ +/* Description: Error source */ + +/* Bit 3 : TX buffer over-read detected, and prevented */ +#define TWIS_ERRORSRC_OVERREAD_Pos (3UL) /*!< Position of OVERREAD field. */ +#define TWIS_ERRORSRC_OVERREAD_Msk (0x1UL << TWIS_ERRORSRC_OVERREAD_Pos) /*!< Bit mask of OVERREAD field. */ +#define TWIS_ERRORSRC_OVERREAD_NotDetected (0UL) /*!< Error did not occur */ +#define TWIS_ERRORSRC_OVERREAD_Detected (1UL) /*!< Error occurred */ + +/* Bit 2 : NACK sent after receiving a data byte */ +#define TWIS_ERRORSRC_DNACK_Pos (2UL) /*!< Position of DNACK field. */ +#define TWIS_ERRORSRC_DNACK_Msk (0x1UL << TWIS_ERRORSRC_DNACK_Pos) /*!< Bit mask of DNACK field. */ +#define TWIS_ERRORSRC_DNACK_NotReceived (0UL) /*!< Error did not occur */ +#define TWIS_ERRORSRC_DNACK_Received (1UL) /*!< Error occurred */ + +/* Bit 0 : RX buffer overflow detected, and prevented */ +#define TWIS_ERRORSRC_OVERFLOW_Pos (0UL) /*!< Position of OVERFLOW field. */ +#define TWIS_ERRORSRC_OVERFLOW_Msk (0x1UL << TWIS_ERRORSRC_OVERFLOW_Pos) /*!< Bit mask of OVERFLOW field. */ +#define TWIS_ERRORSRC_OVERFLOW_NotDetected (0UL) /*!< Error did not occur */ +#define TWIS_ERRORSRC_OVERFLOW_Detected (1UL) /*!< Error occurred */ + +/* Register: TWIS_MATCH */ +/* Description: Status register indicating which address had a match */ + +/* Bit 0 : Which of the addresses in {ADDRESS} matched the incoming address */ +#define TWIS_MATCH_MATCH_Pos (0UL) /*!< Position of MATCH field. */ +#define TWIS_MATCH_MATCH_Msk (0x1UL << TWIS_MATCH_MATCH_Pos) /*!< Bit mask of MATCH field. */ + +/* Register: TWIS_ENABLE */ +/* Description: Enable TWIS */ + +/* Bits 3..0 : Enable or disable TWIS */ +#define TWIS_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define TWIS_ENABLE_ENABLE_Msk (0xFUL << TWIS_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define TWIS_ENABLE_ENABLE_Disabled (0UL) /*!< Disable TWIS */ +#define TWIS_ENABLE_ENABLE_Enabled (9UL) /*!< Enable TWIS */ + +/* Register: TWIS_PSEL_SCL */ +/* Description: Pin select for SCL signal */ + +/* Bit 31 : Connection */ +#define TWIS_PSEL_SCL_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define TWIS_PSEL_SCL_CONNECT_Msk (0x1UL << TWIS_PSEL_SCL_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define TWIS_PSEL_SCL_CONNECT_Connected (0UL) /*!< Connect */ +#define TWIS_PSEL_SCL_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define TWIS_PSEL_SCL_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define TWIS_PSEL_SCL_PORT_Msk (0x1UL << TWIS_PSEL_SCL_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define TWIS_PSEL_SCL_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define TWIS_PSEL_SCL_PIN_Msk (0x1FUL << TWIS_PSEL_SCL_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: TWIS_PSEL_SDA */ +/* Description: Pin select for SDA signal */ + +/* Bit 31 : Connection */ +#define TWIS_PSEL_SDA_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define TWIS_PSEL_SDA_CONNECT_Msk (0x1UL << TWIS_PSEL_SDA_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define TWIS_PSEL_SDA_CONNECT_Connected (0UL) /*!< Connect */ +#define TWIS_PSEL_SDA_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define TWIS_PSEL_SDA_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define TWIS_PSEL_SDA_PORT_Msk (0x1UL << TWIS_PSEL_SDA_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define TWIS_PSEL_SDA_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define TWIS_PSEL_SDA_PIN_Msk (0x1FUL << TWIS_PSEL_SDA_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: TWIS_RXD_PTR */ +/* Description: RXD Data pointer */ + +/* Bits 31..0 : RXD Data pointer */ +#define TWIS_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define TWIS_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << TWIS_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: TWIS_RXD_MAXCNT */ +/* Description: Maximum number of bytes in RXD buffer */ + +/* Bits 7..0 : Maximum number of bytes in RXD buffer */ +#define TWIS_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define TWIS_RXD_MAXCNT_MAXCNT_Msk (0xFFUL << TWIS_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: TWIS_RXD_AMOUNT */ +/* Description: Number of bytes transferred in the last RXD transaction */ + +/* Bits 7..0 : Number of bytes transferred in the last RXD transaction */ +#define TWIS_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define TWIS_RXD_AMOUNT_AMOUNT_Msk (0xFFUL << TWIS_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: TWIS_TXD_PTR */ +/* Description: TXD Data pointer */ + +/* Bits 31..0 : TXD Data pointer */ +#define TWIS_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define TWIS_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << TWIS_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: TWIS_TXD_MAXCNT */ +/* Description: Maximum number of bytes in TXD buffer */ + +/* Bits 7..0 : Maximum number of bytes in TXD buffer */ +#define TWIS_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define TWIS_TXD_MAXCNT_MAXCNT_Msk (0xFFUL << TWIS_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: TWIS_TXD_AMOUNT */ +/* Description: Number of bytes transferred in the last TXD transaction */ + +/* Bits 7..0 : Number of bytes transferred in the last TXD transaction */ +#define TWIS_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define TWIS_TXD_AMOUNT_AMOUNT_Msk (0xFFUL << TWIS_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: TWIS_ADDRESS */ +/* Description: Description collection[0]: TWI slave address 0 */ + +/* Bits 6..0 : TWI slave address */ +#define TWIS_ADDRESS_ADDRESS_Pos (0UL) /*!< Position of ADDRESS field. */ +#define TWIS_ADDRESS_ADDRESS_Msk (0x7FUL << TWIS_ADDRESS_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */ + +/* Register: TWIS_CONFIG */ +/* Description: Configuration register for the address match mechanism */ + +/* Bit 1 : Enable or disable address matching on ADDRESS[1] */ +#define TWIS_CONFIG_ADDRESS1_Pos (1UL) /*!< Position of ADDRESS1 field. */ +#define TWIS_CONFIG_ADDRESS1_Msk (0x1UL << TWIS_CONFIG_ADDRESS1_Pos) /*!< Bit mask of ADDRESS1 field. */ +#define TWIS_CONFIG_ADDRESS1_Disabled (0UL) /*!< Disabled */ +#define TWIS_CONFIG_ADDRESS1_Enabled (1UL) /*!< Enabled */ + +/* Bit 0 : Enable or disable address matching on ADDRESS[0] */ +#define TWIS_CONFIG_ADDRESS0_Pos (0UL) /*!< Position of ADDRESS0 field. */ +#define TWIS_CONFIG_ADDRESS0_Msk (0x1UL << TWIS_CONFIG_ADDRESS0_Pos) /*!< Bit mask of ADDRESS0 field. */ +#define TWIS_CONFIG_ADDRESS0_Disabled (0UL) /*!< Disabled */ +#define TWIS_CONFIG_ADDRESS0_Enabled (1UL) /*!< Enabled */ + +/* Register: TWIS_ORC */ +/* Description: Over-read character. Character sent out in case of an over-read of the transmit buffer. */ + +/* Bits 7..0 : Over-read character. Character sent out in case of an over-read of the transmit buffer. */ +#define TWIS_ORC_ORC_Pos (0UL) /*!< Position of ORC field. */ +#define TWIS_ORC_ORC_Msk (0xFFUL << TWIS_ORC_ORC_Pos) /*!< Bit mask of ORC field. */ + + +/* Peripheral: UART */ +/* Description: Universal Asynchronous Receiver/Transmitter */ + +/* Register: UART_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 4 : Shortcut between NCTS event and STOPRX task */ +#define UART_SHORTS_NCTS_STOPRX_Pos (4UL) /*!< Position of NCTS_STOPRX field. */ +#define UART_SHORTS_NCTS_STOPRX_Msk (0x1UL << UART_SHORTS_NCTS_STOPRX_Pos) /*!< Bit mask of NCTS_STOPRX field. */ +#define UART_SHORTS_NCTS_STOPRX_Disabled (0UL) /*!< Disable shortcut */ +#define UART_SHORTS_NCTS_STOPRX_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between CTS event and STARTRX task */ +#define UART_SHORTS_CTS_STARTRX_Pos (3UL) /*!< Position of CTS_STARTRX field. */ +#define UART_SHORTS_CTS_STARTRX_Msk (0x1UL << UART_SHORTS_CTS_STARTRX_Pos) /*!< Bit mask of CTS_STARTRX field. */ +#define UART_SHORTS_CTS_STARTRX_Disabled (0UL) /*!< Disable shortcut */ +#define UART_SHORTS_CTS_STARTRX_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: UART_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 17 : Write '1' to Enable interrupt for RXTO event */ +#define UART_INTENSET_RXTO_Pos (17UL) /*!< Position of RXTO field. */ +#define UART_INTENSET_RXTO_Msk (0x1UL << UART_INTENSET_RXTO_Pos) /*!< Bit mask of RXTO field. */ +#define UART_INTENSET_RXTO_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENSET_RXTO_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENSET_RXTO_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ +#define UART_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define UART_INTENSET_ERROR_Msk (0x1UL << UART_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define UART_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENSET_ERROR_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for TXDRDY event */ +#define UART_INTENSET_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UART_INTENSET_TXDRDY_Msk (0x1UL << UART_INTENSET_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UART_INTENSET_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENSET_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENSET_TXDRDY_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for RXDRDY event */ +#define UART_INTENSET_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UART_INTENSET_RXDRDY_Msk (0x1UL << UART_INTENSET_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UART_INTENSET_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENSET_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENSET_RXDRDY_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for NCTS event */ +#define UART_INTENSET_NCTS_Pos (1UL) /*!< Position of NCTS field. */ +#define UART_INTENSET_NCTS_Msk (0x1UL << UART_INTENSET_NCTS_Pos) /*!< Bit mask of NCTS field. */ +#define UART_INTENSET_NCTS_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENSET_NCTS_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENSET_NCTS_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for CTS event */ +#define UART_INTENSET_CTS_Pos (0UL) /*!< Position of CTS field. */ +#define UART_INTENSET_CTS_Msk (0x1UL << UART_INTENSET_CTS_Pos) /*!< Bit mask of CTS field. */ +#define UART_INTENSET_CTS_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENSET_CTS_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENSET_CTS_Set (1UL) /*!< Enable */ + +/* Register: UART_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 17 : Write '1' to Disable interrupt for RXTO event */ +#define UART_INTENCLR_RXTO_Pos (17UL) /*!< Position of RXTO field. */ +#define UART_INTENCLR_RXTO_Msk (0x1UL << UART_INTENCLR_RXTO_Pos) /*!< Bit mask of RXTO field. */ +#define UART_INTENCLR_RXTO_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENCLR_RXTO_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENCLR_RXTO_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ +#define UART_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define UART_INTENCLR_ERROR_Msk (0x1UL << UART_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define UART_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for TXDRDY event */ +#define UART_INTENCLR_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UART_INTENCLR_TXDRDY_Msk (0x1UL << UART_INTENCLR_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UART_INTENCLR_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENCLR_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENCLR_TXDRDY_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for RXDRDY event */ +#define UART_INTENCLR_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UART_INTENCLR_RXDRDY_Msk (0x1UL << UART_INTENCLR_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UART_INTENCLR_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENCLR_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENCLR_RXDRDY_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for NCTS event */ +#define UART_INTENCLR_NCTS_Pos (1UL) /*!< Position of NCTS field. */ +#define UART_INTENCLR_NCTS_Msk (0x1UL << UART_INTENCLR_NCTS_Pos) /*!< Bit mask of NCTS field. */ +#define UART_INTENCLR_NCTS_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENCLR_NCTS_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENCLR_NCTS_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for CTS event */ +#define UART_INTENCLR_CTS_Pos (0UL) /*!< Position of CTS field. */ +#define UART_INTENCLR_CTS_Msk (0x1UL << UART_INTENCLR_CTS_Pos) /*!< Bit mask of CTS field. */ +#define UART_INTENCLR_CTS_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENCLR_CTS_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENCLR_CTS_Clear (1UL) /*!< Disable */ + +/* Register: UART_ERRORSRC */ +/* Description: Error source */ + +/* Bit 3 : Break condition */ +#define UART_ERRORSRC_BREAK_Pos (3UL) /*!< Position of BREAK field. */ +#define UART_ERRORSRC_BREAK_Msk (0x1UL << UART_ERRORSRC_BREAK_Pos) /*!< Bit mask of BREAK field. */ +#define UART_ERRORSRC_BREAK_NotPresent (0UL) /*!< Read: error not present */ +#define UART_ERRORSRC_BREAK_Present (1UL) /*!< Read: error present */ + +/* Bit 2 : Framing error occurred */ +#define UART_ERRORSRC_FRAMING_Pos (2UL) /*!< Position of FRAMING field. */ +#define UART_ERRORSRC_FRAMING_Msk (0x1UL << UART_ERRORSRC_FRAMING_Pos) /*!< Bit mask of FRAMING field. */ +#define UART_ERRORSRC_FRAMING_NotPresent (0UL) /*!< Read: error not present */ +#define UART_ERRORSRC_FRAMING_Present (1UL) /*!< Read: error present */ + +/* Bit 1 : Parity error */ +#define UART_ERRORSRC_PARITY_Pos (1UL) /*!< Position of PARITY field. */ +#define UART_ERRORSRC_PARITY_Msk (0x1UL << UART_ERRORSRC_PARITY_Pos) /*!< Bit mask of PARITY field. */ +#define UART_ERRORSRC_PARITY_NotPresent (0UL) /*!< Read: error not present */ +#define UART_ERRORSRC_PARITY_Present (1UL) /*!< Read: error present */ + +/* Bit 0 : Overrun error */ +#define UART_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */ +#define UART_ERRORSRC_OVERRUN_Msk (0x1UL << UART_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ +#define UART_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Read: error not present */ +#define UART_ERRORSRC_OVERRUN_Present (1UL) /*!< Read: error present */ + +/* Register: UART_ENABLE */ +/* Description: Enable UART */ + +/* Bits 3..0 : Enable or disable UART */ +#define UART_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define UART_ENABLE_ENABLE_Msk (0xFUL << UART_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define UART_ENABLE_ENABLE_Disabled (0UL) /*!< Disable UART */ +#define UART_ENABLE_ENABLE_Enabled (4UL) /*!< Enable UART */ + +/* Register: UART_PSEL_RTS */ +/* Description: Pin select for RTS */ + +/* Bit 31 : Connection */ +#define UART_PSEL_RTS_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UART_PSEL_RTS_CONNECT_Msk (0x1UL << UART_PSEL_RTS_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UART_PSEL_RTS_CONNECT_Connected (0UL) /*!< Connect */ +#define UART_PSEL_RTS_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define UART_PSEL_RTS_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UART_PSEL_RTS_PORT_Msk (0x1UL << UART_PSEL_RTS_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UART_PSEL_RTS_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UART_PSEL_RTS_PIN_Msk (0x1FUL << UART_PSEL_RTS_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UART_PSEL_TXD */ +/* Description: Pin select for TXD */ + +/* Bit 31 : Connection */ +#define UART_PSEL_TXD_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UART_PSEL_TXD_CONNECT_Msk (0x1UL << UART_PSEL_TXD_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UART_PSEL_TXD_CONNECT_Connected (0UL) /*!< Connect */ +#define UART_PSEL_TXD_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define UART_PSEL_TXD_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UART_PSEL_TXD_PORT_Msk (0x1UL << UART_PSEL_TXD_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UART_PSEL_TXD_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UART_PSEL_TXD_PIN_Msk (0x1FUL << UART_PSEL_TXD_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UART_PSEL_CTS */ +/* Description: Pin select for CTS */ + +/* Bit 31 : Connection */ +#define UART_PSEL_CTS_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UART_PSEL_CTS_CONNECT_Msk (0x1UL << UART_PSEL_CTS_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UART_PSEL_CTS_CONNECT_Connected (0UL) /*!< Connect */ +#define UART_PSEL_CTS_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define UART_PSEL_CTS_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UART_PSEL_CTS_PORT_Msk (0x1UL << UART_PSEL_CTS_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UART_PSEL_CTS_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UART_PSEL_CTS_PIN_Msk (0x1FUL << UART_PSEL_CTS_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UART_PSEL_RXD */ +/* Description: Pin select for RXD */ + +/* Bit 31 : Connection */ +#define UART_PSEL_RXD_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UART_PSEL_RXD_CONNECT_Msk (0x1UL << UART_PSEL_RXD_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UART_PSEL_RXD_CONNECT_Connected (0UL) /*!< Connect */ +#define UART_PSEL_RXD_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define UART_PSEL_RXD_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UART_PSEL_RXD_PORT_Msk (0x1UL << UART_PSEL_RXD_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UART_PSEL_RXD_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UART_PSEL_RXD_PIN_Msk (0x1FUL << UART_PSEL_RXD_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UART_RXD */ +/* Description: RXD register */ + +/* Bits 7..0 : RX data received in previous transfers, double buffered */ +#define UART_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */ +#define UART_RXD_RXD_Msk (0xFFUL << UART_RXD_RXD_Pos) /*!< Bit mask of RXD field. */ + +/* Register: UART_TXD */ +/* Description: TXD register */ + +/* Bits 7..0 : TX data to be transferred */ +#define UART_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */ +#define UART_TXD_TXD_Msk (0xFFUL << UART_TXD_TXD_Pos) /*!< Bit mask of TXD field. */ + +/* Register: UART_BAUDRATE */ +/* Description: Baud rate. Accuracy depends on the HFCLK source selected. */ + +/* Bits 31..0 : Baud rate */ +#define UART_BAUDRATE_BAUDRATE_Pos (0UL) /*!< Position of BAUDRATE field. */ +#define UART_BAUDRATE_BAUDRATE_Msk (0xFFFFFFFFUL << UART_BAUDRATE_BAUDRATE_Pos) /*!< Bit mask of BAUDRATE field. */ +#define UART_BAUDRATE_BAUDRATE_Baud1200 (0x0004F000UL) /*!< 1200 baud (actual rate: 1205) */ +#define UART_BAUDRATE_BAUDRATE_Baud2400 (0x0009D000UL) /*!< 2400 baud (actual rate: 2396) */ +#define UART_BAUDRATE_BAUDRATE_Baud4800 (0x0013B000UL) /*!< 4800 baud (actual rate: 4808) */ +#define UART_BAUDRATE_BAUDRATE_Baud9600 (0x00275000UL) /*!< 9600 baud (actual rate: 9598) */ +#define UART_BAUDRATE_BAUDRATE_Baud14400 (0x003B0000UL) /*!< 14400 baud (actual rate: 14414) */ +#define UART_BAUDRATE_BAUDRATE_Baud19200 (0x004EA000UL) /*!< 19200 baud (actual rate: 19208) */ +#define UART_BAUDRATE_BAUDRATE_Baud28800 (0x0075F000UL) /*!< 28800 baud (actual rate: 28829) */ +#define UART_BAUDRATE_BAUDRATE_Baud31250 (0x00800000UL) /*!< 31250 baud */ +#define UART_BAUDRATE_BAUDRATE_Baud38400 (0x009D5000UL) /*!< 38400 baud (actual rate: 38462) */ +#define UART_BAUDRATE_BAUDRATE_Baud56000 (0x00E50000UL) /*!< 56000 baud (actual rate: 55944) */ +#define UART_BAUDRATE_BAUDRATE_Baud57600 (0x00EBF000UL) /*!< 57600 baud (actual rate: 57762) */ +#define UART_BAUDRATE_BAUDRATE_Baud76800 (0x013A9000UL) /*!< 76800 baud (actual rate: 76923) */ +#define UART_BAUDRATE_BAUDRATE_Baud115200 (0x01D7E000UL) /*!< 115200 baud (actual rate: 115942) */ +#define UART_BAUDRATE_BAUDRATE_Baud230400 (0x03AFB000UL) /*!< 230400 baud (actual rate: 231884) */ +#define UART_BAUDRATE_BAUDRATE_Baud250000 (0x04000000UL) /*!< 250000 baud */ +#define UART_BAUDRATE_BAUDRATE_Baud460800 (0x075F7000UL) /*!< 460800 baud (actual rate: 470588) */ +#define UART_BAUDRATE_BAUDRATE_Baud921600 (0x0EBED000UL) /*!< 921600 baud (actual rate: 941176) */ +#define UART_BAUDRATE_BAUDRATE_Baud1M (0x10000000UL) /*!< 1Mega baud */ + +/* Register: UART_CONFIG */ +/* Description: Configuration of parity and hardware flow control */ + +/* Bits 3..1 : Parity */ +#define UART_CONFIG_PARITY_Pos (1UL) /*!< Position of PARITY field. */ +#define UART_CONFIG_PARITY_Msk (0x7UL << UART_CONFIG_PARITY_Pos) /*!< Bit mask of PARITY field. */ +#define UART_CONFIG_PARITY_Excluded (0x0UL) /*!< Exclude parity bit */ +#define UART_CONFIG_PARITY_Included (0x7UL) /*!< Include parity bit */ + +/* Bit 0 : Hardware flow control */ +#define UART_CONFIG_HWFC_Pos (0UL) /*!< Position of HWFC field. */ +#define UART_CONFIG_HWFC_Msk (0x1UL << UART_CONFIG_HWFC_Pos) /*!< Bit mask of HWFC field. */ +#define UART_CONFIG_HWFC_Disabled (0UL) /*!< Disabled */ +#define UART_CONFIG_HWFC_Enabled (1UL) /*!< Enabled */ + + +/* Peripheral: UARTE */ +/* Description: UART with EasyDMA 0 */ + +/* Register: UARTE_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 6 : Shortcut between ENDRX event and STOPRX task */ +#define UARTE_SHORTS_ENDRX_STOPRX_Pos (6UL) /*!< Position of ENDRX_STOPRX field. */ +#define UARTE_SHORTS_ENDRX_STOPRX_Msk (0x1UL << UARTE_SHORTS_ENDRX_STOPRX_Pos) /*!< Bit mask of ENDRX_STOPRX field. */ +#define UARTE_SHORTS_ENDRX_STOPRX_Disabled (0UL) /*!< Disable shortcut */ +#define UARTE_SHORTS_ENDRX_STOPRX_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 5 : Shortcut between ENDRX event and STARTRX task */ +#define UARTE_SHORTS_ENDRX_STARTRX_Pos (5UL) /*!< Position of ENDRX_STARTRX field. */ +#define UARTE_SHORTS_ENDRX_STARTRX_Msk (0x1UL << UARTE_SHORTS_ENDRX_STARTRX_Pos) /*!< Bit mask of ENDRX_STARTRX field. */ +#define UARTE_SHORTS_ENDRX_STARTRX_Disabled (0UL) /*!< Disable shortcut */ +#define UARTE_SHORTS_ENDRX_STARTRX_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: UARTE_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 22 : Enable or disable interrupt for TXSTOPPED event */ +#define UARTE_INTEN_TXSTOPPED_Pos (22UL) /*!< Position of TXSTOPPED field. */ +#define UARTE_INTEN_TXSTOPPED_Msk (0x1UL << UARTE_INTEN_TXSTOPPED_Pos) /*!< Bit mask of TXSTOPPED field. */ +#define UARTE_INTEN_TXSTOPPED_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_TXSTOPPED_Enabled (1UL) /*!< Enable */ + +/* Bit 20 : Enable or disable interrupt for TXSTARTED event */ +#define UARTE_INTEN_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define UARTE_INTEN_TXSTARTED_Msk (0x1UL << UARTE_INTEN_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define UARTE_INTEN_TXSTARTED_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_TXSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 19 : Enable or disable interrupt for RXSTARTED event */ +#define UARTE_INTEN_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define UARTE_INTEN_RXSTARTED_Msk (0x1UL << UARTE_INTEN_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define UARTE_INTEN_RXSTARTED_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_RXSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 17 : Enable or disable interrupt for RXTO event */ +#define UARTE_INTEN_RXTO_Pos (17UL) /*!< Position of RXTO field. */ +#define UARTE_INTEN_RXTO_Msk (0x1UL << UARTE_INTEN_RXTO_Pos) /*!< Bit mask of RXTO field. */ +#define UARTE_INTEN_RXTO_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_RXTO_Enabled (1UL) /*!< Enable */ + +/* Bit 9 : Enable or disable interrupt for ERROR event */ +#define UARTE_INTEN_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define UARTE_INTEN_ERROR_Msk (0x1UL << UARTE_INTEN_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define UARTE_INTEN_ERROR_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_ERROR_Enabled (1UL) /*!< Enable */ + +/* Bit 8 : Enable or disable interrupt for ENDTX event */ +#define UARTE_INTEN_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ +#define UARTE_INTEN_ENDTX_Msk (0x1UL << UARTE_INTEN_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define UARTE_INTEN_ENDTX_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_ENDTX_Enabled (1UL) /*!< Enable */ + +/* Bit 7 : Enable or disable interrupt for TXDRDY event */ +#define UARTE_INTEN_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UARTE_INTEN_TXDRDY_Msk (0x1UL << UARTE_INTEN_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UARTE_INTEN_TXDRDY_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_TXDRDY_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable interrupt for ENDRX event */ +#define UARTE_INTEN_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define UARTE_INTEN_ENDRX_Msk (0x1UL << UARTE_INTEN_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define UARTE_INTEN_ENDRX_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_ENDRX_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for RXDRDY event */ +#define UARTE_INTEN_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UARTE_INTEN_RXDRDY_Msk (0x1UL << UARTE_INTEN_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UARTE_INTEN_RXDRDY_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_RXDRDY_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for NCTS event */ +#define UARTE_INTEN_NCTS_Pos (1UL) /*!< Position of NCTS field. */ +#define UARTE_INTEN_NCTS_Msk (0x1UL << UARTE_INTEN_NCTS_Pos) /*!< Bit mask of NCTS field. */ +#define UARTE_INTEN_NCTS_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_NCTS_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable interrupt for CTS event */ +#define UARTE_INTEN_CTS_Pos (0UL) /*!< Position of CTS field. */ +#define UARTE_INTEN_CTS_Msk (0x1UL << UARTE_INTEN_CTS_Pos) /*!< Bit mask of CTS field. */ +#define UARTE_INTEN_CTS_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_CTS_Enabled (1UL) /*!< Enable */ + +/* Register: UARTE_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 22 : Write '1' to Enable interrupt for TXSTOPPED event */ +#define UARTE_INTENSET_TXSTOPPED_Pos (22UL) /*!< Position of TXSTOPPED field. */ +#define UARTE_INTENSET_TXSTOPPED_Msk (0x1UL << UARTE_INTENSET_TXSTOPPED_Pos) /*!< Bit mask of TXSTOPPED field. */ +#define UARTE_INTENSET_TXSTOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_TXSTOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_TXSTOPPED_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for TXSTARTED event */ +#define UARTE_INTENSET_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define UARTE_INTENSET_TXSTARTED_Msk (0x1UL << UARTE_INTENSET_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define UARTE_INTENSET_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_TXSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for RXSTARTED event */ +#define UARTE_INTENSET_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define UARTE_INTENSET_RXSTARTED_Msk (0x1UL << UARTE_INTENSET_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define UARTE_INTENSET_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_RXSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable interrupt for RXTO event */ +#define UARTE_INTENSET_RXTO_Pos (17UL) /*!< Position of RXTO field. */ +#define UARTE_INTENSET_RXTO_Msk (0x1UL << UARTE_INTENSET_RXTO_Pos) /*!< Bit mask of RXTO field. */ +#define UARTE_INTENSET_RXTO_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_RXTO_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_RXTO_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ +#define UARTE_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define UARTE_INTENSET_ERROR_Msk (0x1UL << UARTE_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define UARTE_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_ERROR_Set (1UL) /*!< Enable */ + +/* Bit 8 : Write '1' to Enable interrupt for ENDTX event */ +#define UARTE_INTENSET_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ +#define UARTE_INTENSET_ENDTX_Msk (0x1UL << UARTE_INTENSET_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define UARTE_INTENSET_ENDTX_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_ENDTX_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_ENDTX_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for TXDRDY event */ +#define UARTE_INTENSET_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UARTE_INTENSET_TXDRDY_Msk (0x1UL << UARTE_INTENSET_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UARTE_INTENSET_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_TXDRDY_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for ENDRX event */ +#define UARTE_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define UARTE_INTENSET_ENDRX_Msk (0x1UL << UARTE_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define UARTE_INTENSET_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_ENDRX_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for RXDRDY event */ +#define UARTE_INTENSET_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UARTE_INTENSET_RXDRDY_Msk (0x1UL << UARTE_INTENSET_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UARTE_INTENSET_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_RXDRDY_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for NCTS event */ +#define UARTE_INTENSET_NCTS_Pos (1UL) /*!< Position of NCTS field. */ +#define UARTE_INTENSET_NCTS_Msk (0x1UL << UARTE_INTENSET_NCTS_Pos) /*!< Bit mask of NCTS field. */ +#define UARTE_INTENSET_NCTS_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_NCTS_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_NCTS_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for CTS event */ +#define UARTE_INTENSET_CTS_Pos (0UL) /*!< Position of CTS field. */ +#define UARTE_INTENSET_CTS_Msk (0x1UL << UARTE_INTENSET_CTS_Pos) /*!< Bit mask of CTS field. */ +#define UARTE_INTENSET_CTS_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_CTS_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_CTS_Set (1UL) /*!< Enable */ + +/* Register: UARTE_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 22 : Write '1' to Disable interrupt for TXSTOPPED event */ +#define UARTE_INTENCLR_TXSTOPPED_Pos (22UL) /*!< Position of TXSTOPPED field. */ +#define UARTE_INTENCLR_TXSTOPPED_Msk (0x1UL << UARTE_INTENCLR_TXSTOPPED_Pos) /*!< Bit mask of TXSTOPPED field. */ +#define UARTE_INTENCLR_TXSTOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_TXSTOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_TXSTOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for TXSTARTED event */ +#define UARTE_INTENCLR_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define UARTE_INTENCLR_TXSTARTED_Msk (0x1UL << UARTE_INTENCLR_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define UARTE_INTENCLR_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_TXSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for RXSTARTED event */ +#define UARTE_INTENCLR_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define UARTE_INTENCLR_RXSTARTED_Msk (0x1UL << UARTE_INTENCLR_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define UARTE_INTENCLR_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_RXSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable interrupt for RXTO event */ +#define UARTE_INTENCLR_RXTO_Pos (17UL) /*!< Position of RXTO field. */ +#define UARTE_INTENCLR_RXTO_Msk (0x1UL << UARTE_INTENCLR_RXTO_Pos) /*!< Bit mask of RXTO field. */ +#define UARTE_INTENCLR_RXTO_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_RXTO_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_RXTO_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ +#define UARTE_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define UARTE_INTENCLR_ERROR_Msk (0x1UL << UARTE_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define UARTE_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ + +/* Bit 8 : Write '1' to Disable interrupt for ENDTX event */ +#define UARTE_INTENCLR_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ +#define UARTE_INTENCLR_ENDTX_Msk (0x1UL << UARTE_INTENCLR_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define UARTE_INTENCLR_ENDTX_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_ENDTX_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_ENDTX_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for TXDRDY event */ +#define UARTE_INTENCLR_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UARTE_INTENCLR_TXDRDY_Msk (0x1UL << UARTE_INTENCLR_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UARTE_INTENCLR_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_TXDRDY_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for ENDRX event */ +#define UARTE_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define UARTE_INTENCLR_ENDRX_Msk (0x1UL << UARTE_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define UARTE_INTENCLR_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_ENDRX_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for RXDRDY event */ +#define UARTE_INTENCLR_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UARTE_INTENCLR_RXDRDY_Msk (0x1UL << UARTE_INTENCLR_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UARTE_INTENCLR_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_RXDRDY_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for NCTS event */ +#define UARTE_INTENCLR_NCTS_Pos (1UL) /*!< Position of NCTS field. */ +#define UARTE_INTENCLR_NCTS_Msk (0x1UL << UARTE_INTENCLR_NCTS_Pos) /*!< Bit mask of NCTS field. */ +#define UARTE_INTENCLR_NCTS_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_NCTS_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_NCTS_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for CTS event */ +#define UARTE_INTENCLR_CTS_Pos (0UL) /*!< Position of CTS field. */ +#define UARTE_INTENCLR_CTS_Msk (0x1UL << UARTE_INTENCLR_CTS_Pos) /*!< Bit mask of CTS field. */ +#define UARTE_INTENCLR_CTS_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_CTS_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_CTS_Clear (1UL) /*!< Disable */ + +/* Register: UARTE_ERRORSRC */ +/* Description: Error source Note : this register is read / write one to clear. */ + +/* Bit 3 : Break condition */ +#define UARTE_ERRORSRC_BREAK_Pos (3UL) /*!< Position of BREAK field. */ +#define UARTE_ERRORSRC_BREAK_Msk (0x1UL << UARTE_ERRORSRC_BREAK_Pos) /*!< Bit mask of BREAK field. */ +#define UARTE_ERRORSRC_BREAK_NotPresent (0UL) /*!< Read: error not present */ +#define UARTE_ERRORSRC_BREAK_Present (1UL) /*!< Read: error present */ + +/* Bit 2 : Framing error occurred */ +#define UARTE_ERRORSRC_FRAMING_Pos (2UL) /*!< Position of FRAMING field. */ +#define UARTE_ERRORSRC_FRAMING_Msk (0x1UL << UARTE_ERRORSRC_FRAMING_Pos) /*!< Bit mask of FRAMING field. */ +#define UARTE_ERRORSRC_FRAMING_NotPresent (0UL) /*!< Read: error not present */ +#define UARTE_ERRORSRC_FRAMING_Present (1UL) /*!< Read: error present */ + +/* Bit 1 : Parity error */ +#define UARTE_ERRORSRC_PARITY_Pos (1UL) /*!< Position of PARITY field. */ +#define UARTE_ERRORSRC_PARITY_Msk (0x1UL << UARTE_ERRORSRC_PARITY_Pos) /*!< Bit mask of PARITY field. */ +#define UARTE_ERRORSRC_PARITY_NotPresent (0UL) /*!< Read: error not present */ +#define UARTE_ERRORSRC_PARITY_Present (1UL) /*!< Read: error present */ + +/* Bit 0 : Overrun error */ +#define UARTE_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */ +#define UARTE_ERRORSRC_OVERRUN_Msk (0x1UL << UARTE_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ +#define UARTE_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Read: error not present */ +#define UARTE_ERRORSRC_OVERRUN_Present (1UL) /*!< Read: error present */ + +/* Register: UARTE_ENABLE */ +/* Description: Enable UART */ + +/* Bits 3..0 : Enable or disable UARTE */ +#define UARTE_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define UARTE_ENABLE_ENABLE_Msk (0xFUL << UARTE_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define UARTE_ENABLE_ENABLE_Disabled (0UL) /*!< Disable UARTE */ +#define UARTE_ENABLE_ENABLE_Enabled (8UL) /*!< Enable UARTE */ + +/* Register: UARTE_PSEL_RTS */ +/* Description: Pin select for RTS signal */ + +/* Bit 31 : Connection */ +#define UARTE_PSEL_RTS_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UARTE_PSEL_RTS_CONNECT_Msk (0x1UL << UARTE_PSEL_RTS_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UARTE_PSEL_RTS_CONNECT_Connected (0UL) /*!< Connect */ +#define UARTE_PSEL_RTS_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define UARTE_PSEL_RTS_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UARTE_PSEL_RTS_PORT_Msk (0x1UL << UARTE_PSEL_RTS_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UARTE_PSEL_RTS_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UARTE_PSEL_RTS_PIN_Msk (0x1FUL << UARTE_PSEL_RTS_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UARTE_PSEL_TXD */ +/* Description: Pin select for TXD signal */ + +/* Bit 31 : Connection */ +#define UARTE_PSEL_TXD_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UARTE_PSEL_TXD_CONNECT_Msk (0x1UL << UARTE_PSEL_TXD_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UARTE_PSEL_TXD_CONNECT_Connected (0UL) /*!< Connect */ +#define UARTE_PSEL_TXD_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define UARTE_PSEL_TXD_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UARTE_PSEL_TXD_PORT_Msk (0x1UL << UARTE_PSEL_TXD_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UARTE_PSEL_TXD_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UARTE_PSEL_TXD_PIN_Msk (0x1FUL << UARTE_PSEL_TXD_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UARTE_PSEL_CTS */ +/* Description: Pin select for CTS signal */ + +/* Bit 31 : Connection */ +#define UARTE_PSEL_CTS_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UARTE_PSEL_CTS_CONNECT_Msk (0x1UL << UARTE_PSEL_CTS_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UARTE_PSEL_CTS_CONNECT_Connected (0UL) /*!< Connect */ +#define UARTE_PSEL_CTS_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define UARTE_PSEL_CTS_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UARTE_PSEL_CTS_PORT_Msk (0x1UL << UARTE_PSEL_CTS_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UARTE_PSEL_CTS_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UARTE_PSEL_CTS_PIN_Msk (0x1FUL << UARTE_PSEL_CTS_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UARTE_PSEL_RXD */ +/* Description: Pin select for RXD signal */ + +/* Bit 31 : Connection */ +#define UARTE_PSEL_RXD_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UARTE_PSEL_RXD_CONNECT_Msk (0x1UL << UARTE_PSEL_RXD_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UARTE_PSEL_RXD_CONNECT_Connected (0UL) /*!< Connect */ +#define UARTE_PSEL_RXD_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number */ +#define UARTE_PSEL_RXD_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UARTE_PSEL_RXD_PORT_Msk (0x1UL << UARTE_PSEL_RXD_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UARTE_PSEL_RXD_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UARTE_PSEL_RXD_PIN_Msk (0x1FUL << UARTE_PSEL_RXD_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UARTE_BAUDRATE */ +/* Description: Baud rate. Accuracy depends on the HFCLK source selected. */ + +/* Bits 31..0 : Baud rate */ +#define UARTE_BAUDRATE_BAUDRATE_Pos (0UL) /*!< Position of BAUDRATE field. */ +#define UARTE_BAUDRATE_BAUDRATE_Msk (0xFFFFFFFFUL << UARTE_BAUDRATE_BAUDRATE_Pos) /*!< Bit mask of BAUDRATE field. */ +#define UARTE_BAUDRATE_BAUDRATE_Baud1200 (0x0004F000UL) /*!< 1200 baud (actual rate: 1205) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud2400 (0x0009D000UL) /*!< 2400 baud (actual rate: 2396) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud4800 (0x0013B000UL) /*!< 4800 baud (actual rate: 4808) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud9600 (0x00275000UL) /*!< 9600 baud (actual rate: 9598) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud14400 (0x003AF000UL) /*!< 14400 baud (actual rate: 14401) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud19200 (0x004EA000UL) /*!< 19200 baud (actual rate: 19208) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud28800 (0x0075C000UL) /*!< 28800 baud (actual rate: 28777) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud31250 (0x00800000UL) /*!< 31250 baud */ +#define UARTE_BAUDRATE_BAUDRATE_Baud38400 (0x009D0000UL) /*!< 38400 baud (actual rate: 38369) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud56000 (0x00E50000UL) /*!< 56000 baud (actual rate: 55944) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud57600 (0x00EB0000UL) /*!< 57600 baud (actual rate: 57554) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud76800 (0x013A9000UL) /*!< 76800 baud (actual rate: 76923) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud115200 (0x01D60000UL) /*!< 115200 baud (actual rate: 115108) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud230400 (0x03B00000UL) /*!< 230400 baud (actual rate: 231884) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud250000 (0x04000000UL) /*!< 250000 baud */ +#define UARTE_BAUDRATE_BAUDRATE_Baud460800 (0x07400000UL) /*!< 460800 baud (actual rate: 457143) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud921600 (0x0F000000UL) /*!< 921600 baud (actual rate: 941176) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud1M (0x10000000UL) /*!< 1Mega baud */ + +/* Register: UARTE_RXD_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define UARTE_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define UARTE_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << UARTE_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: UARTE_RXD_MAXCNT */ +/* Description: Maximum number of bytes in receive buffer */ + +/* Bits 9..0 : Maximum number of bytes in receive buffer */ +#define UARTE_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define UARTE_RXD_MAXCNT_MAXCNT_Msk (0x3FFUL << UARTE_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: UARTE_RXD_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 9..0 : Number of bytes transferred in the last transaction */ +#define UARTE_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define UARTE_RXD_AMOUNT_AMOUNT_Msk (0x3FFUL << UARTE_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: UARTE_TXD_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define UARTE_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define UARTE_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << UARTE_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: UARTE_TXD_MAXCNT */ +/* Description: Maximum number of bytes in transmit buffer */ + +/* Bits 9..0 : Maximum number of bytes in transmit buffer */ +#define UARTE_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define UARTE_TXD_MAXCNT_MAXCNT_Msk (0x3FFUL << UARTE_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: UARTE_TXD_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 9..0 : Number of bytes transferred in the last transaction */ +#define UARTE_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define UARTE_TXD_AMOUNT_AMOUNT_Msk (0x3FFUL << UARTE_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: UARTE_CONFIG */ +/* Description: Configuration of parity and hardware flow control */ + +/* Bit 4 : Stop bits */ +#define UARTE_CONFIG_STOP_Pos (4UL) /*!< Position of STOP field. */ +#define UARTE_CONFIG_STOP_Msk (0x1UL << UARTE_CONFIG_STOP_Pos) /*!< Bit mask of STOP field. */ +#define UARTE_CONFIG_STOP_One (0UL) /*!< One stop bit */ +#define UARTE_CONFIG_STOP_Two (1UL) /*!< Two stop bits */ + +/* Bits 3..1 : Parity */ +#define UARTE_CONFIG_PARITY_Pos (1UL) /*!< Position of PARITY field. */ +#define UARTE_CONFIG_PARITY_Msk (0x7UL << UARTE_CONFIG_PARITY_Pos) /*!< Bit mask of PARITY field. */ +#define UARTE_CONFIG_PARITY_Excluded (0x0UL) /*!< Exclude parity bit */ +#define UARTE_CONFIG_PARITY_Included (0x7UL) /*!< Include even parity bit */ + +/* Bit 0 : Hardware flow control */ +#define UARTE_CONFIG_HWFC_Pos (0UL) /*!< Position of HWFC field. */ +#define UARTE_CONFIG_HWFC_Msk (0x1UL << UARTE_CONFIG_HWFC_Pos) /*!< Bit mask of HWFC field. */ +#define UARTE_CONFIG_HWFC_Disabled (0UL) /*!< Disabled */ +#define UARTE_CONFIG_HWFC_Enabled (1UL) /*!< Enabled */ + + +/* Peripheral: UICR */ +/* Description: User information configuration registers */ + +/* Register: UICR_NRFFW */ +/* Description: Description collection[0]: Reserved for Nordic firmware design */ + +/* Bits 31..0 : Reserved for Nordic firmware design */ +#define UICR_NRFFW_NRFFW_Pos (0UL) /*!< Position of NRFFW field. */ +#define UICR_NRFFW_NRFFW_Msk (0xFFFFFFFFUL << UICR_NRFFW_NRFFW_Pos) /*!< Bit mask of NRFFW field. */ + +/* Register: UICR_NRFHW */ +/* Description: Description collection[0]: Reserved for Nordic hardware design */ + +/* Bits 31..0 : Reserved for Nordic hardware design */ +#define UICR_NRFHW_NRFHW_Pos (0UL) /*!< Position of NRFHW field. */ +#define UICR_NRFHW_NRFHW_Msk (0xFFFFFFFFUL << UICR_NRFHW_NRFHW_Pos) /*!< Bit mask of NRFHW field. */ + +/* Register: UICR_CUSTOMER */ +/* Description: Description collection[0]: Reserved for customer */ + +/* Bits 31..0 : Reserved for customer */ +#define UICR_CUSTOMER_CUSTOMER_Pos (0UL) /*!< Position of CUSTOMER field. */ +#define UICR_CUSTOMER_CUSTOMER_Msk (0xFFFFFFFFUL << UICR_CUSTOMER_CUSTOMER_Pos) /*!< Bit mask of CUSTOMER field. */ + +/* Register: UICR_PSELRESET */ +/* Description: Description collection[0]: Mapping of the nRESET function */ + +/* Bit 31 : Connection */ +#define UICR_PSELRESET_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UICR_PSELRESET_CONNECT_Msk (0x1UL << UICR_PSELRESET_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UICR_PSELRESET_CONNECT_Connected (0UL) /*!< Connect */ +#define UICR_PSELRESET_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bit 5 : Port number onto which nRESET is exposed */ +#define UICR_PSELRESET_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UICR_PSELRESET_PORT_Msk (0x1UL << UICR_PSELRESET_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number of PORT onto which nRESET is exposed */ +#define UICR_PSELRESET_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UICR_PSELRESET_PIN_Msk (0x1FUL << UICR_PSELRESET_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UICR_APPROTECT */ +/* Description: Access port protection */ + +/* Bits 7..0 : Enable or disable Access Port protection. */ +#define UICR_APPROTECT_PALL_Pos (0UL) /*!< Position of PALL field. */ +#define UICR_APPROTECT_PALL_Msk (0xFFUL << UICR_APPROTECT_PALL_Pos) /*!< Bit mask of PALL field. */ +#define UICR_APPROTECT_PALL_Enabled (0x00UL) /*!< Enable */ +#define UICR_APPROTECT_PALL_Disabled (0xFFUL) /*!< Disable */ + +/* Register: UICR_NFCPINS */ +/* Description: Setting of pins dedicated to NFC functionality: NFC antenna or GPIO */ + +/* Bit 0 : Setting of pins dedicated to NFC functionality */ +#define UICR_NFCPINS_PROTECT_Pos (0UL) /*!< Position of PROTECT field. */ +#define UICR_NFCPINS_PROTECT_Msk (0x1UL << UICR_NFCPINS_PROTECT_Pos) /*!< Bit mask of PROTECT field. */ +#define UICR_NFCPINS_PROTECT_Disabled (0UL) /*!< Operation as GPIO pins. Same protection as normal GPIO pins */ +#define UICR_NFCPINS_PROTECT_NFC (1UL) /*!< Operation as NFC antenna pins. Configures the protection for NFC operation */ + +/* Register: UICR_EXTSUPPLY */ +/* Description: Enable external circuitry to be supplied from VDD pin. Applicable in high voltage mode only. */ + +/* Bit 0 : Enable external circuitry to be supplied from VDD pin (output of REG0 stage) */ +#define UICR_EXTSUPPLY_EXTSUPPLY_Pos (0UL) /*!< Position of EXTSUPPLY field. */ +#define UICR_EXTSUPPLY_EXTSUPPLY_Msk (0x1UL << UICR_EXTSUPPLY_EXTSUPPLY_Pos) /*!< Bit mask of EXTSUPPLY field. */ +#define UICR_EXTSUPPLY_EXTSUPPLY_Disabled (0UL) /*!< No current can be drawn from the VDD pin */ +#define UICR_EXTSUPPLY_EXTSUPPLY_Enabled (1UL) /*!< It is allowed to supply external circuitry from the VDD pin */ + +/* Register: UICR_REGOUT0 */ +/* Description: GPIO reference voltage / external output supply voltage in high voltage mode */ + +/* Bits 2..0 : Output voltage from of REG0 regulator stage. The maximum output voltage from this stage is given as VDDH - VEXDIF. */ +#define UICR_REGOUT0_VOUT_Pos (0UL) /*!< Position of VOUT field. */ +#define UICR_REGOUT0_VOUT_Msk (0x7UL << UICR_REGOUT0_VOUT_Pos) /*!< Bit mask of VOUT field. */ +#define UICR_REGOUT0_VOUT_1V8 (0UL) /*!< 1.8 V */ +#define UICR_REGOUT0_VOUT_2V1 (1UL) /*!< 2.1 V */ +#define UICR_REGOUT0_VOUT_2V4 (2UL) /*!< 2.4 V */ +#define UICR_REGOUT0_VOUT_2V7 (3UL) /*!< 2.7 V */ +#define UICR_REGOUT0_VOUT_3V0 (4UL) /*!< 3.0 V */ +#define UICR_REGOUT0_VOUT_3V3 (5UL) /*!< 3.3 V */ +#define UICR_REGOUT0_VOUT_DEFAULT (7UL) /*!< Default voltage: 1.8 V */ + + +/* Peripheral: USBD */ +/* Description: Universal Serial Bus device */ + +/* Register: USBD_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 4 : Shortcut between ENDEPOUT[0] event and EP0RCVOUT task */ +#define USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Pos (4UL) /*!< Position of ENDEPOUT0_EP0RCVOUT field. */ +#define USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Msk (0x1UL << USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Pos) /*!< Bit mask of ENDEPOUT0_EP0RCVOUT field. */ +#define USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Disabled (0UL) /*!< Disable shortcut */ +#define USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between ENDEPOUT[0] event and EP0STATUS task */ +#define USBD_SHORTS_ENDEPOUT0_EP0STATUS_Pos (3UL) /*!< Position of ENDEPOUT0_EP0STATUS field. */ +#define USBD_SHORTS_ENDEPOUT0_EP0STATUS_Msk (0x1UL << USBD_SHORTS_ENDEPOUT0_EP0STATUS_Pos) /*!< Bit mask of ENDEPOUT0_EP0STATUS field. */ +#define USBD_SHORTS_ENDEPOUT0_EP0STATUS_Disabled (0UL) /*!< Disable shortcut */ +#define USBD_SHORTS_ENDEPOUT0_EP0STATUS_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 2 : Shortcut between EP0DATADONE event and EP0STATUS task */ +#define USBD_SHORTS_EP0DATADONE_EP0STATUS_Pos (2UL) /*!< Position of EP0DATADONE_EP0STATUS field. */ +#define USBD_SHORTS_EP0DATADONE_EP0STATUS_Msk (0x1UL << USBD_SHORTS_EP0DATADONE_EP0STATUS_Pos) /*!< Bit mask of EP0DATADONE_EP0STATUS field. */ +#define USBD_SHORTS_EP0DATADONE_EP0STATUS_Disabled (0UL) /*!< Disable shortcut */ +#define USBD_SHORTS_EP0DATADONE_EP0STATUS_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between EP0DATADONE event and STARTEPOUT[0] task */ +#define USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Pos (1UL) /*!< Position of EP0DATADONE_STARTEPOUT0 field. */ +#define USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Msk (0x1UL << USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Pos) /*!< Bit mask of EP0DATADONE_STARTEPOUT0 field. */ +#define USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Disabled (0UL) /*!< Disable shortcut */ +#define USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between EP0DATADONE event and STARTEPIN[0] task */ +#define USBD_SHORTS_EP0DATADONE_STARTEPIN0_Pos (0UL) /*!< Position of EP0DATADONE_STARTEPIN0 field. */ +#define USBD_SHORTS_EP0DATADONE_STARTEPIN0_Msk (0x1UL << USBD_SHORTS_EP0DATADONE_STARTEPIN0_Pos) /*!< Bit mask of EP0DATADONE_STARTEPIN0 field. */ +#define USBD_SHORTS_EP0DATADONE_STARTEPIN0_Disabled (0UL) /*!< Disable shortcut */ +#define USBD_SHORTS_EP0DATADONE_STARTEPIN0_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: USBD_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 25 : Enable or disable interrupt for ACCESSFAULT event */ +#define USBD_INTEN_ACCESSFAULT_Pos (25UL) /*!< Position of ACCESSFAULT field. */ +#define USBD_INTEN_ACCESSFAULT_Msk (0x1UL << USBD_INTEN_ACCESSFAULT_Pos) /*!< Bit mask of ACCESSFAULT field. */ +#define USBD_INTEN_ACCESSFAULT_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ACCESSFAULT_Enabled (1UL) /*!< Enable */ + +/* Bit 24 : Enable or disable interrupt for EPDATA event */ +#define USBD_INTEN_EPDATA_Pos (24UL) /*!< Position of EPDATA field. */ +#define USBD_INTEN_EPDATA_Msk (0x1UL << USBD_INTEN_EPDATA_Pos) /*!< Bit mask of EPDATA field. */ +#define USBD_INTEN_EPDATA_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_EPDATA_Enabled (1UL) /*!< Enable */ + +/* Bit 23 : Enable or disable interrupt for EP0SETUP event */ +#define USBD_INTEN_EP0SETUP_Pos (23UL) /*!< Position of EP0SETUP field. */ +#define USBD_INTEN_EP0SETUP_Msk (0x1UL << USBD_INTEN_EP0SETUP_Pos) /*!< Bit mask of EP0SETUP field. */ +#define USBD_INTEN_EP0SETUP_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_EP0SETUP_Enabled (1UL) /*!< Enable */ + +/* Bit 22 : Enable or disable interrupt for USBEVENT event */ +#define USBD_INTEN_USBEVENT_Pos (22UL) /*!< Position of USBEVENT field. */ +#define USBD_INTEN_USBEVENT_Msk (0x1UL << USBD_INTEN_USBEVENT_Pos) /*!< Bit mask of USBEVENT field. */ +#define USBD_INTEN_USBEVENT_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_USBEVENT_Enabled (1UL) /*!< Enable */ + +/* Bit 21 : Enable or disable interrupt for SOF event */ +#define USBD_INTEN_SOF_Pos (21UL) /*!< Position of SOF field. */ +#define USBD_INTEN_SOF_Msk (0x1UL << USBD_INTEN_SOF_Pos) /*!< Bit mask of SOF field. */ +#define USBD_INTEN_SOF_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_SOF_Enabled (1UL) /*!< Enable */ + +/* Bit 20 : Enable or disable interrupt for ENDISOOUT event */ +#define USBD_INTEN_ENDISOOUT_Pos (20UL) /*!< Position of ENDISOOUT field. */ +#define USBD_INTEN_ENDISOOUT_Msk (0x1UL << USBD_INTEN_ENDISOOUT_Pos) /*!< Bit mask of ENDISOOUT field. */ +#define USBD_INTEN_ENDISOOUT_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDISOOUT_Enabled (1UL) /*!< Enable */ + +/* Bit 19 : Enable or disable interrupt for ENDEPOUT[7] event */ +#define USBD_INTEN_ENDEPOUT7_Pos (19UL) /*!< Position of ENDEPOUT7 field. */ +#define USBD_INTEN_ENDEPOUT7_Msk (0x1UL << USBD_INTEN_ENDEPOUT7_Pos) /*!< Bit mask of ENDEPOUT7 field. */ +#define USBD_INTEN_ENDEPOUT7_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT7_Enabled (1UL) /*!< Enable */ + +/* Bit 18 : Enable or disable interrupt for ENDEPOUT[6] event */ +#define USBD_INTEN_ENDEPOUT6_Pos (18UL) /*!< Position of ENDEPOUT6 field. */ +#define USBD_INTEN_ENDEPOUT6_Msk (0x1UL << USBD_INTEN_ENDEPOUT6_Pos) /*!< Bit mask of ENDEPOUT6 field. */ +#define USBD_INTEN_ENDEPOUT6_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT6_Enabled (1UL) /*!< Enable */ + +/* Bit 17 : Enable or disable interrupt for ENDEPOUT[5] event */ +#define USBD_INTEN_ENDEPOUT5_Pos (17UL) /*!< Position of ENDEPOUT5 field. */ +#define USBD_INTEN_ENDEPOUT5_Msk (0x1UL << USBD_INTEN_ENDEPOUT5_Pos) /*!< Bit mask of ENDEPOUT5 field. */ +#define USBD_INTEN_ENDEPOUT5_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT5_Enabled (1UL) /*!< Enable */ + +/* Bit 16 : Enable or disable interrupt for ENDEPOUT[4] event */ +#define USBD_INTEN_ENDEPOUT4_Pos (16UL) /*!< Position of ENDEPOUT4 field. */ +#define USBD_INTEN_ENDEPOUT4_Msk (0x1UL << USBD_INTEN_ENDEPOUT4_Pos) /*!< Bit mask of ENDEPOUT4 field. */ +#define USBD_INTEN_ENDEPOUT4_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT4_Enabled (1UL) /*!< Enable */ + +/* Bit 15 : Enable or disable interrupt for ENDEPOUT[3] event */ +#define USBD_INTEN_ENDEPOUT3_Pos (15UL) /*!< Position of ENDEPOUT3 field. */ +#define USBD_INTEN_ENDEPOUT3_Msk (0x1UL << USBD_INTEN_ENDEPOUT3_Pos) /*!< Bit mask of ENDEPOUT3 field. */ +#define USBD_INTEN_ENDEPOUT3_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT3_Enabled (1UL) /*!< Enable */ + +/* Bit 14 : Enable or disable interrupt for ENDEPOUT[2] event */ +#define USBD_INTEN_ENDEPOUT2_Pos (14UL) /*!< Position of ENDEPOUT2 field. */ +#define USBD_INTEN_ENDEPOUT2_Msk (0x1UL << USBD_INTEN_ENDEPOUT2_Pos) /*!< Bit mask of ENDEPOUT2 field. */ +#define USBD_INTEN_ENDEPOUT2_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT2_Enabled (1UL) /*!< Enable */ + +/* Bit 13 : Enable or disable interrupt for ENDEPOUT[1] event */ +#define USBD_INTEN_ENDEPOUT1_Pos (13UL) /*!< Position of ENDEPOUT1 field. */ +#define USBD_INTEN_ENDEPOUT1_Msk (0x1UL << USBD_INTEN_ENDEPOUT1_Pos) /*!< Bit mask of ENDEPOUT1 field. */ +#define USBD_INTEN_ENDEPOUT1_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT1_Enabled (1UL) /*!< Enable */ + +/* Bit 12 : Enable or disable interrupt for ENDEPOUT[0] event */ +#define USBD_INTEN_ENDEPOUT0_Pos (12UL) /*!< Position of ENDEPOUT0 field. */ +#define USBD_INTEN_ENDEPOUT0_Msk (0x1UL << USBD_INTEN_ENDEPOUT0_Pos) /*!< Bit mask of ENDEPOUT0 field. */ +#define USBD_INTEN_ENDEPOUT0_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT0_Enabled (1UL) /*!< Enable */ + +/* Bit 11 : Enable or disable interrupt for ENDISOIN event */ +#define USBD_INTEN_ENDISOIN_Pos (11UL) /*!< Position of ENDISOIN field. */ +#define USBD_INTEN_ENDISOIN_Msk (0x1UL << USBD_INTEN_ENDISOIN_Pos) /*!< Bit mask of ENDISOIN field. */ +#define USBD_INTEN_ENDISOIN_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDISOIN_Enabled (1UL) /*!< Enable */ + +/* Bit 10 : Enable or disable interrupt for EP0DATADONE event */ +#define USBD_INTEN_EP0DATADONE_Pos (10UL) /*!< Position of EP0DATADONE field. */ +#define USBD_INTEN_EP0DATADONE_Msk (0x1UL << USBD_INTEN_EP0DATADONE_Pos) /*!< Bit mask of EP0DATADONE field. */ +#define USBD_INTEN_EP0DATADONE_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_EP0DATADONE_Enabled (1UL) /*!< Enable */ + +/* Bit 9 : Enable or disable interrupt for ENDEPIN[7] event */ +#define USBD_INTEN_ENDEPIN7_Pos (9UL) /*!< Position of ENDEPIN7 field. */ +#define USBD_INTEN_ENDEPIN7_Msk (0x1UL << USBD_INTEN_ENDEPIN7_Pos) /*!< Bit mask of ENDEPIN7 field. */ +#define USBD_INTEN_ENDEPIN7_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN7_Enabled (1UL) /*!< Enable */ + +/* Bit 8 : Enable or disable interrupt for ENDEPIN[6] event */ +#define USBD_INTEN_ENDEPIN6_Pos (8UL) /*!< Position of ENDEPIN6 field. */ +#define USBD_INTEN_ENDEPIN6_Msk (0x1UL << USBD_INTEN_ENDEPIN6_Pos) /*!< Bit mask of ENDEPIN6 field. */ +#define USBD_INTEN_ENDEPIN6_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN6_Enabled (1UL) /*!< Enable */ + +/* Bit 7 : Enable or disable interrupt for ENDEPIN[5] event */ +#define USBD_INTEN_ENDEPIN5_Pos (7UL) /*!< Position of ENDEPIN5 field. */ +#define USBD_INTEN_ENDEPIN5_Msk (0x1UL << USBD_INTEN_ENDEPIN5_Pos) /*!< Bit mask of ENDEPIN5 field. */ +#define USBD_INTEN_ENDEPIN5_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN5_Enabled (1UL) /*!< Enable */ + +/* Bit 6 : Enable or disable interrupt for ENDEPIN[4] event */ +#define USBD_INTEN_ENDEPIN4_Pos (6UL) /*!< Position of ENDEPIN4 field. */ +#define USBD_INTEN_ENDEPIN4_Msk (0x1UL << USBD_INTEN_ENDEPIN4_Pos) /*!< Bit mask of ENDEPIN4 field. */ +#define USBD_INTEN_ENDEPIN4_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN4_Enabled (1UL) /*!< Enable */ + +/* Bit 5 : Enable or disable interrupt for ENDEPIN[3] event */ +#define USBD_INTEN_ENDEPIN3_Pos (5UL) /*!< Position of ENDEPIN3 field. */ +#define USBD_INTEN_ENDEPIN3_Msk (0x1UL << USBD_INTEN_ENDEPIN3_Pos) /*!< Bit mask of ENDEPIN3 field. */ +#define USBD_INTEN_ENDEPIN3_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN3_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable interrupt for ENDEPIN[2] event */ +#define USBD_INTEN_ENDEPIN2_Pos (4UL) /*!< Position of ENDEPIN2 field. */ +#define USBD_INTEN_ENDEPIN2_Msk (0x1UL << USBD_INTEN_ENDEPIN2_Pos) /*!< Bit mask of ENDEPIN2 field. */ +#define USBD_INTEN_ENDEPIN2_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN2_Enabled (1UL) /*!< Enable */ + +/* Bit 3 : Enable or disable interrupt for ENDEPIN[1] event */ +#define USBD_INTEN_ENDEPIN1_Pos (3UL) /*!< Position of ENDEPIN1 field. */ +#define USBD_INTEN_ENDEPIN1_Msk (0x1UL << USBD_INTEN_ENDEPIN1_Pos) /*!< Bit mask of ENDEPIN1 field. */ +#define USBD_INTEN_ENDEPIN1_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN1_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for ENDEPIN[0] event */ +#define USBD_INTEN_ENDEPIN0_Pos (2UL) /*!< Position of ENDEPIN0 field. */ +#define USBD_INTEN_ENDEPIN0_Msk (0x1UL << USBD_INTEN_ENDEPIN0_Pos) /*!< Bit mask of ENDEPIN0 field. */ +#define USBD_INTEN_ENDEPIN0_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN0_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for STARTED event */ +#define USBD_INTEN_STARTED_Pos (1UL) /*!< Position of STARTED field. */ +#define USBD_INTEN_STARTED_Msk (0x1UL << USBD_INTEN_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define USBD_INTEN_STARTED_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_STARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable interrupt for USBRESET event */ +#define USBD_INTEN_USBRESET_Pos (0UL) /*!< Position of USBRESET field. */ +#define USBD_INTEN_USBRESET_Msk (0x1UL << USBD_INTEN_USBRESET_Pos) /*!< Bit mask of USBRESET field. */ +#define USBD_INTEN_USBRESET_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_USBRESET_Enabled (1UL) /*!< Enable */ + +/* Register: USBD_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 25 : Write '1' to Enable interrupt for ACCESSFAULT event */ +#define USBD_INTENSET_ACCESSFAULT_Pos (25UL) /*!< Position of ACCESSFAULT field. */ +#define USBD_INTENSET_ACCESSFAULT_Msk (0x1UL << USBD_INTENSET_ACCESSFAULT_Pos) /*!< Bit mask of ACCESSFAULT field. */ +#define USBD_INTENSET_ACCESSFAULT_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ACCESSFAULT_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ACCESSFAULT_Set (1UL) /*!< Enable */ + +/* Bit 24 : Write '1' to Enable interrupt for EPDATA event */ +#define USBD_INTENSET_EPDATA_Pos (24UL) /*!< Position of EPDATA field. */ +#define USBD_INTENSET_EPDATA_Msk (0x1UL << USBD_INTENSET_EPDATA_Pos) /*!< Bit mask of EPDATA field. */ +#define USBD_INTENSET_EPDATA_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_EPDATA_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_EPDATA_Set (1UL) /*!< Enable */ + +/* Bit 23 : Write '1' to Enable interrupt for EP0SETUP event */ +#define USBD_INTENSET_EP0SETUP_Pos (23UL) /*!< Position of EP0SETUP field. */ +#define USBD_INTENSET_EP0SETUP_Msk (0x1UL << USBD_INTENSET_EP0SETUP_Pos) /*!< Bit mask of EP0SETUP field. */ +#define USBD_INTENSET_EP0SETUP_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_EP0SETUP_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_EP0SETUP_Set (1UL) /*!< Enable */ + +/* Bit 22 : Write '1' to Enable interrupt for USBEVENT event */ +#define USBD_INTENSET_USBEVENT_Pos (22UL) /*!< Position of USBEVENT field. */ +#define USBD_INTENSET_USBEVENT_Msk (0x1UL << USBD_INTENSET_USBEVENT_Pos) /*!< Bit mask of USBEVENT field. */ +#define USBD_INTENSET_USBEVENT_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_USBEVENT_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_USBEVENT_Set (1UL) /*!< Enable */ + +/* Bit 21 : Write '1' to Enable interrupt for SOF event */ +#define USBD_INTENSET_SOF_Pos (21UL) /*!< Position of SOF field. */ +#define USBD_INTENSET_SOF_Msk (0x1UL << USBD_INTENSET_SOF_Pos) /*!< Bit mask of SOF field. */ +#define USBD_INTENSET_SOF_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_SOF_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_SOF_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for ENDISOOUT event */ +#define USBD_INTENSET_ENDISOOUT_Pos (20UL) /*!< Position of ENDISOOUT field. */ +#define USBD_INTENSET_ENDISOOUT_Msk (0x1UL << USBD_INTENSET_ENDISOOUT_Pos) /*!< Bit mask of ENDISOOUT field. */ +#define USBD_INTENSET_ENDISOOUT_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDISOOUT_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDISOOUT_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for ENDEPOUT[7] event */ +#define USBD_INTENSET_ENDEPOUT7_Pos (19UL) /*!< Position of ENDEPOUT7 field. */ +#define USBD_INTENSET_ENDEPOUT7_Msk (0x1UL << USBD_INTENSET_ENDEPOUT7_Pos) /*!< Bit mask of ENDEPOUT7 field. */ +#define USBD_INTENSET_ENDEPOUT7_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT7_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT7_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for ENDEPOUT[6] event */ +#define USBD_INTENSET_ENDEPOUT6_Pos (18UL) /*!< Position of ENDEPOUT6 field. */ +#define USBD_INTENSET_ENDEPOUT6_Msk (0x1UL << USBD_INTENSET_ENDEPOUT6_Pos) /*!< Bit mask of ENDEPOUT6 field. */ +#define USBD_INTENSET_ENDEPOUT6_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT6_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT6_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable interrupt for ENDEPOUT[5] event */ +#define USBD_INTENSET_ENDEPOUT5_Pos (17UL) /*!< Position of ENDEPOUT5 field. */ +#define USBD_INTENSET_ENDEPOUT5_Msk (0x1UL << USBD_INTENSET_ENDEPOUT5_Pos) /*!< Bit mask of ENDEPOUT5 field. */ +#define USBD_INTENSET_ENDEPOUT5_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT5_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT5_Set (1UL) /*!< Enable */ + +/* Bit 16 : Write '1' to Enable interrupt for ENDEPOUT[4] event */ +#define USBD_INTENSET_ENDEPOUT4_Pos (16UL) /*!< Position of ENDEPOUT4 field. */ +#define USBD_INTENSET_ENDEPOUT4_Msk (0x1UL << USBD_INTENSET_ENDEPOUT4_Pos) /*!< Bit mask of ENDEPOUT4 field. */ +#define USBD_INTENSET_ENDEPOUT4_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT4_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT4_Set (1UL) /*!< Enable */ + +/* Bit 15 : Write '1' to Enable interrupt for ENDEPOUT[3] event */ +#define USBD_INTENSET_ENDEPOUT3_Pos (15UL) /*!< Position of ENDEPOUT3 field. */ +#define USBD_INTENSET_ENDEPOUT3_Msk (0x1UL << USBD_INTENSET_ENDEPOUT3_Pos) /*!< Bit mask of ENDEPOUT3 field. */ +#define USBD_INTENSET_ENDEPOUT3_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT3_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT3_Set (1UL) /*!< Enable */ + +/* Bit 14 : Write '1' to Enable interrupt for ENDEPOUT[2] event */ +#define USBD_INTENSET_ENDEPOUT2_Pos (14UL) /*!< Position of ENDEPOUT2 field. */ +#define USBD_INTENSET_ENDEPOUT2_Msk (0x1UL << USBD_INTENSET_ENDEPOUT2_Pos) /*!< Bit mask of ENDEPOUT2 field. */ +#define USBD_INTENSET_ENDEPOUT2_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT2_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT2_Set (1UL) /*!< Enable */ + +/* Bit 13 : Write '1' to Enable interrupt for ENDEPOUT[1] event */ +#define USBD_INTENSET_ENDEPOUT1_Pos (13UL) /*!< Position of ENDEPOUT1 field. */ +#define USBD_INTENSET_ENDEPOUT1_Msk (0x1UL << USBD_INTENSET_ENDEPOUT1_Pos) /*!< Bit mask of ENDEPOUT1 field. */ +#define USBD_INTENSET_ENDEPOUT1_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT1_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT1_Set (1UL) /*!< Enable */ + +/* Bit 12 : Write '1' to Enable interrupt for ENDEPOUT[0] event */ +#define USBD_INTENSET_ENDEPOUT0_Pos (12UL) /*!< Position of ENDEPOUT0 field. */ +#define USBD_INTENSET_ENDEPOUT0_Msk (0x1UL << USBD_INTENSET_ENDEPOUT0_Pos) /*!< Bit mask of ENDEPOUT0 field. */ +#define USBD_INTENSET_ENDEPOUT0_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT0_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT0_Set (1UL) /*!< Enable */ + +/* Bit 11 : Write '1' to Enable interrupt for ENDISOIN event */ +#define USBD_INTENSET_ENDISOIN_Pos (11UL) /*!< Position of ENDISOIN field. */ +#define USBD_INTENSET_ENDISOIN_Msk (0x1UL << USBD_INTENSET_ENDISOIN_Pos) /*!< Bit mask of ENDISOIN field. */ +#define USBD_INTENSET_ENDISOIN_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDISOIN_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDISOIN_Set (1UL) /*!< Enable */ + +/* Bit 10 : Write '1' to Enable interrupt for EP0DATADONE event */ +#define USBD_INTENSET_EP0DATADONE_Pos (10UL) /*!< Position of EP0DATADONE field. */ +#define USBD_INTENSET_EP0DATADONE_Msk (0x1UL << USBD_INTENSET_EP0DATADONE_Pos) /*!< Bit mask of EP0DATADONE field. */ +#define USBD_INTENSET_EP0DATADONE_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_EP0DATADONE_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_EP0DATADONE_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ENDEPIN[7] event */ +#define USBD_INTENSET_ENDEPIN7_Pos (9UL) /*!< Position of ENDEPIN7 field. */ +#define USBD_INTENSET_ENDEPIN7_Msk (0x1UL << USBD_INTENSET_ENDEPIN7_Pos) /*!< Bit mask of ENDEPIN7 field. */ +#define USBD_INTENSET_ENDEPIN7_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN7_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN7_Set (1UL) /*!< Enable */ + +/* Bit 8 : Write '1' to Enable interrupt for ENDEPIN[6] event */ +#define USBD_INTENSET_ENDEPIN6_Pos (8UL) /*!< Position of ENDEPIN6 field. */ +#define USBD_INTENSET_ENDEPIN6_Msk (0x1UL << USBD_INTENSET_ENDEPIN6_Pos) /*!< Bit mask of ENDEPIN6 field. */ +#define USBD_INTENSET_ENDEPIN6_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN6_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN6_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for ENDEPIN[5] event */ +#define USBD_INTENSET_ENDEPIN5_Pos (7UL) /*!< Position of ENDEPIN5 field. */ +#define USBD_INTENSET_ENDEPIN5_Msk (0x1UL << USBD_INTENSET_ENDEPIN5_Pos) /*!< Bit mask of ENDEPIN5 field. */ +#define USBD_INTENSET_ENDEPIN5_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN5_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN5_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for ENDEPIN[4] event */ +#define USBD_INTENSET_ENDEPIN4_Pos (6UL) /*!< Position of ENDEPIN4 field. */ +#define USBD_INTENSET_ENDEPIN4_Msk (0x1UL << USBD_INTENSET_ENDEPIN4_Pos) /*!< Bit mask of ENDEPIN4 field. */ +#define USBD_INTENSET_ENDEPIN4_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN4_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN4_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for ENDEPIN[3] event */ +#define USBD_INTENSET_ENDEPIN3_Pos (5UL) /*!< Position of ENDEPIN3 field. */ +#define USBD_INTENSET_ENDEPIN3_Msk (0x1UL << USBD_INTENSET_ENDEPIN3_Pos) /*!< Bit mask of ENDEPIN3 field. */ +#define USBD_INTENSET_ENDEPIN3_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN3_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN3_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for ENDEPIN[2] event */ +#define USBD_INTENSET_ENDEPIN2_Pos (4UL) /*!< Position of ENDEPIN2 field. */ +#define USBD_INTENSET_ENDEPIN2_Msk (0x1UL << USBD_INTENSET_ENDEPIN2_Pos) /*!< Bit mask of ENDEPIN2 field. */ +#define USBD_INTENSET_ENDEPIN2_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN2_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN2_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for ENDEPIN[1] event */ +#define USBD_INTENSET_ENDEPIN1_Pos (3UL) /*!< Position of ENDEPIN1 field. */ +#define USBD_INTENSET_ENDEPIN1_Msk (0x1UL << USBD_INTENSET_ENDEPIN1_Pos) /*!< Bit mask of ENDEPIN1 field. */ +#define USBD_INTENSET_ENDEPIN1_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN1_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN1_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for ENDEPIN[0] event */ +#define USBD_INTENSET_ENDEPIN0_Pos (2UL) /*!< Position of ENDEPIN0 field. */ +#define USBD_INTENSET_ENDEPIN0_Msk (0x1UL << USBD_INTENSET_ENDEPIN0_Pos) /*!< Bit mask of ENDEPIN0 field. */ +#define USBD_INTENSET_ENDEPIN0_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN0_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN0_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STARTED event */ +#define USBD_INTENSET_STARTED_Pos (1UL) /*!< Position of STARTED field. */ +#define USBD_INTENSET_STARTED_Msk (0x1UL << USBD_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define USBD_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_STARTED_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for USBRESET event */ +#define USBD_INTENSET_USBRESET_Pos (0UL) /*!< Position of USBRESET field. */ +#define USBD_INTENSET_USBRESET_Msk (0x1UL << USBD_INTENSET_USBRESET_Pos) /*!< Bit mask of USBRESET field. */ +#define USBD_INTENSET_USBRESET_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_USBRESET_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_USBRESET_Set (1UL) /*!< Enable */ + +/* Register: USBD_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 25 : Write '1' to Disable interrupt for ACCESSFAULT event */ +#define USBD_INTENCLR_ACCESSFAULT_Pos (25UL) /*!< Position of ACCESSFAULT field. */ +#define USBD_INTENCLR_ACCESSFAULT_Msk (0x1UL << USBD_INTENCLR_ACCESSFAULT_Pos) /*!< Bit mask of ACCESSFAULT field. */ +#define USBD_INTENCLR_ACCESSFAULT_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ACCESSFAULT_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ACCESSFAULT_Clear (1UL) /*!< Disable */ + +/* Bit 24 : Write '1' to Disable interrupt for EPDATA event */ +#define USBD_INTENCLR_EPDATA_Pos (24UL) /*!< Position of EPDATA field. */ +#define USBD_INTENCLR_EPDATA_Msk (0x1UL << USBD_INTENCLR_EPDATA_Pos) /*!< Bit mask of EPDATA field. */ +#define USBD_INTENCLR_EPDATA_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_EPDATA_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_EPDATA_Clear (1UL) /*!< Disable */ + +/* Bit 23 : Write '1' to Disable interrupt for EP0SETUP event */ +#define USBD_INTENCLR_EP0SETUP_Pos (23UL) /*!< Position of EP0SETUP field. */ +#define USBD_INTENCLR_EP0SETUP_Msk (0x1UL << USBD_INTENCLR_EP0SETUP_Pos) /*!< Bit mask of EP0SETUP field. */ +#define USBD_INTENCLR_EP0SETUP_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_EP0SETUP_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_EP0SETUP_Clear (1UL) /*!< Disable */ + +/* Bit 22 : Write '1' to Disable interrupt for USBEVENT event */ +#define USBD_INTENCLR_USBEVENT_Pos (22UL) /*!< Position of USBEVENT field. */ +#define USBD_INTENCLR_USBEVENT_Msk (0x1UL << USBD_INTENCLR_USBEVENT_Pos) /*!< Bit mask of USBEVENT field. */ +#define USBD_INTENCLR_USBEVENT_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_USBEVENT_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_USBEVENT_Clear (1UL) /*!< Disable */ + +/* Bit 21 : Write '1' to Disable interrupt for SOF event */ +#define USBD_INTENCLR_SOF_Pos (21UL) /*!< Position of SOF field. */ +#define USBD_INTENCLR_SOF_Msk (0x1UL << USBD_INTENCLR_SOF_Pos) /*!< Bit mask of SOF field. */ +#define USBD_INTENCLR_SOF_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_SOF_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_SOF_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for ENDISOOUT event */ +#define USBD_INTENCLR_ENDISOOUT_Pos (20UL) /*!< Position of ENDISOOUT field. */ +#define USBD_INTENCLR_ENDISOOUT_Msk (0x1UL << USBD_INTENCLR_ENDISOOUT_Pos) /*!< Bit mask of ENDISOOUT field. */ +#define USBD_INTENCLR_ENDISOOUT_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDISOOUT_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDISOOUT_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for ENDEPOUT[7] event */ +#define USBD_INTENCLR_ENDEPOUT7_Pos (19UL) /*!< Position of ENDEPOUT7 field. */ +#define USBD_INTENCLR_ENDEPOUT7_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT7_Pos) /*!< Bit mask of ENDEPOUT7 field. */ +#define USBD_INTENCLR_ENDEPOUT7_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT7_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT7_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for ENDEPOUT[6] event */ +#define USBD_INTENCLR_ENDEPOUT6_Pos (18UL) /*!< Position of ENDEPOUT6 field. */ +#define USBD_INTENCLR_ENDEPOUT6_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT6_Pos) /*!< Bit mask of ENDEPOUT6 field. */ +#define USBD_INTENCLR_ENDEPOUT6_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT6_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT6_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable interrupt for ENDEPOUT[5] event */ +#define USBD_INTENCLR_ENDEPOUT5_Pos (17UL) /*!< Position of ENDEPOUT5 field. */ +#define USBD_INTENCLR_ENDEPOUT5_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT5_Pos) /*!< Bit mask of ENDEPOUT5 field. */ +#define USBD_INTENCLR_ENDEPOUT5_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT5_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT5_Clear (1UL) /*!< Disable */ + +/* Bit 16 : Write '1' to Disable interrupt for ENDEPOUT[4] event */ +#define USBD_INTENCLR_ENDEPOUT4_Pos (16UL) /*!< Position of ENDEPOUT4 field. */ +#define USBD_INTENCLR_ENDEPOUT4_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT4_Pos) /*!< Bit mask of ENDEPOUT4 field. */ +#define USBD_INTENCLR_ENDEPOUT4_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT4_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT4_Clear (1UL) /*!< Disable */ + +/* Bit 15 : Write '1' to Disable interrupt for ENDEPOUT[3] event */ +#define USBD_INTENCLR_ENDEPOUT3_Pos (15UL) /*!< Position of ENDEPOUT3 field. */ +#define USBD_INTENCLR_ENDEPOUT3_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT3_Pos) /*!< Bit mask of ENDEPOUT3 field. */ +#define USBD_INTENCLR_ENDEPOUT3_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT3_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT3_Clear (1UL) /*!< Disable */ + +/* Bit 14 : Write '1' to Disable interrupt for ENDEPOUT[2] event */ +#define USBD_INTENCLR_ENDEPOUT2_Pos (14UL) /*!< Position of ENDEPOUT2 field. */ +#define USBD_INTENCLR_ENDEPOUT2_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT2_Pos) /*!< Bit mask of ENDEPOUT2 field. */ +#define USBD_INTENCLR_ENDEPOUT2_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT2_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT2_Clear (1UL) /*!< Disable */ + +/* Bit 13 : Write '1' to Disable interrupt for ENDEPOUT[1] event */ +#define USBD_INTENCLR_ENDEPOUT1_Pos (13UL) /*!< Position of ENDEPOUT1 field. */ +#define USBD_INTENCLR_ENDEPOUT1_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT1_Pos) /*!< Bit mask of ENDEPOUT1 field. */ +#define USBD_INTENCLR_ENDEPOUT1_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT1_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT1_Clear (1UL) /*!< Disable */ + +/* Bit 12 : Write '1' to Disable interrupt for ENDEPOUT[0] event */ +#define USBD_INTENCLR_ENDEPOUT0_Pos (12UL) /*!< Position of ENDEPOUT0 field. */ +#define USBD_INTENCLR_ENDEPOUT0_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT0_Pos) /*!< Bit mask of ENDEPOUT0 field. */ +#define USBD_INTENCLR_ENDEPOUT0_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT0_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT0_Clear (1UL) /*!< Disable */ + +/* Bit 11 : Write '1' to Disable interrupt for ENDISOIN event */ +#define USBD_INTENCLR_ENDISOIN_Pos (11UL) /*!< Position of ENDISOIN field. */ +#define USBD_INTENCLR_ENDISOIN_Msk (0x1UL << USBD_INTENCLR_ENDISOIN_Pos) /*!< Bit mask of ENDISOIN field. */ +#define USBD_INTENCLR_ENDISOIN_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDISOIN_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDISOIN_Clear (1UL) /*!< Disable */ + +/* Bit 10 : Write '1' to Disable interrupt for EP0DATADONE event */ +#define USBD_INTENCLR_EP0DATADONE_Pos (10UL) /*!< Position of EP0DATADONE field. */ +#define USBD_INTENCLR_EP0DATADONE_Msk (0x1UL << USBD_INTENCLR_EP0DATADONE_Pos) /*!< Bit mask of EP0DATADONE field. */ +#define USBD_INTENCLR_EP0DATADONE_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_EP0DATADONE_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_EP0DATADONE_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ENDEPIN[7] event */ +#define USBD_INTENCLR_ENDEPIN7_Pos (9UL) /*!< Position of ENDEPIN7 field. */ +#define USBD_INTENCLR_ENDEPIN7_Msk (0x1UL << USBD_INTENCLR_ENDEPIN7_Pos) /*!< Bit mask of ENDEPIN7 field. */ +#define USBD_INTENCLR_ENDEPIN7_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN7_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN7_Clear (1UL) /*!< Disable */ + +/* Bit 8 : Write '1' to Disable interrupt for ENDEPIN[6] event */ +#define USBD_INTENCLR_ENDEPIN6_Pos (8UL) /*!< Position of ENDEPIN6 field. */ +#define USBD_INTENCLR_ENDEPIN6_Msk (0x1UL << USBD_INTENCLR_ENDEPIN6_Pos) /*!< Bit mask of ENDEPIN6 field. */ +#define USBD_INTENCLR_ENDEPIN6_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN6_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN6_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for ENDEPIN[5] event */ +#define USBD_INTENCLR_ENDEPIN5_Pos (7UL) /*!< Position of ENDEPIN5 field. */ +#define USBD_INTENCLR_ENDEPIN5_Msk (0x1UL << USBD_INTENCLR_ENDEPIN5_Pos) /*!< Bit mask of ENDEPIN5 field. */ +#define USBD_INTENCLR_ENDEPIN5_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN5_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN5_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for ENDEPIN[4] event */ +#define USBD_INTENCLR_ENDEPIN4_Pos (6UL) /*!< Position of ENDEPIN4 field. */ +#define USBD_INTENCLR_ENDEPIN4_Msk (0x1UL << USBD_INTENCLR_ENDEPIN4_Pos) /*!< Bit mask of ENDEPIN4 field. */ +#define USBD_INTENCLR_ENDEPIN4_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN4_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN4_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for ENDEPIN[3] event */ +#define USBD_INTENCLR_ENDEPIN3_Pos (5UL) /*!< Position of ENDEPIN3 field. */ +#define USBD_INTENCLR_ENDEPIN3_Msk (0x1UL << USBD_INTENCLR_ENDEPIN3_Pos) /*!< Bit mask of ENDEPIN3 field. */ +#define USBD_INTENCLR_ENDEPIN3_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN3_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN3_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for ENDEPIN[2] event */ +#define USBD_INTENCLR_ENDEPIN2_Pos (4UL) /*!< Position of ENDEPIN2 field. */ +#define USBD_INTENCLR_ENDEPIN2_Msk (0x1UL << USBD_INTENCLR_ENDEPIN2_Pos) /*!< Bit mask of ENDEPIN2 field. */ +#define USBD_INTENCLR_ENDEPIN2_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN2_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN2_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for ENDEPIN[1] event */ +#define USBD_INTENCLR_ENDEPIN1_Pos (3UL) /*!< Position of ENDEPIN1 field. */ +#define USBD_INTENCLR_ENDEPIN1_Msk (0x1UL << USBD_INTENCLR_ENDEPIN1_Pos) /*!< Bit mask of ENDEPIN1 field. */ +#define USBD_INTENCLR_ENDEPIN1_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN1_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN1_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for ENDEPIN[0] event */ +#define USBD_INTENCLR_ENDEPIN0_Pos (2UL) /*!< Position of ENDEPIN0 field. */ +#define USBD_INTENCLR_ENDEPIN0_Msk (0x1UL << USBD_INTENCLR_ENDEPIN0_Pos) /*!< Bit mask of ENDEPIN0 field. */ +#define USBD_INTENCLR_ENDEPIN0_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN0_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN0_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STARTED event */ +#define USBD_INTENCLR_STARTED_Pos (1UL) /*!< Position of STARTED field. */ +#define USBD_INTENCLR_STARTED_Msk (0x1UL << USBD_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define USBD_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_STARTED_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for USBRESET event */ +#define USBD_INTENCLR_USBRESET_Pos (0UL) /*!< Position of USBRESET field. */ +#define USBD_INTENCLR_USBRESET_Msk (0x1UL << USBD_INTENCLR_USBRESET_Pos) /*!< Bit mask of USBRESET field. */ +#define USBD_INTENCLR_USBRESET_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_USBRESET_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_USBRESET_Clear (1UL) /*!< Disable */ + +/* Register: USBD_EVENTCAUSE */ +/* Description: Details on event that caused the USBEVENT event */ + +/* Bit 11 : Wrapper has re-initialized SFRs to the proper values. MAC is ready for normal operation. Write '1' to clear. */ +#define USBD_EVENTCAUSE_READY_Pos (11UL) /*!< Position of READY field. */ +#define USBD_EVENTCAUSE_READY_Msk (0x1UL << USBD_EVENTCAUSE_READY_Pos) /*!< Bit mask of READY field. */ +#define USBD_EVENTCAUSE_READY_NotDetected (0UL) /*!< USBEVENT was not issued due to USBD peripheral ready */ +#define USBD_EVENTCAUSE_READY_Ready (1UL) /*!< USBD peripheral is ready */ + +/* Bit 9 : Signals that a RESUME condition (K state or activity restart) has been detected on the USB lines. Write '1' to clear. */ +#define USBD_EVENTCAUSE_RESUME_Pos (9UL) /*!< Position of RESUME field. */ +#define USBD_EVENTCAUSE_RESUME_Msk (0x1UL << USBD_EVENTCAUSE_RESUME_Pos) /*!< Bit mask of RESUME field. */ +#define USBD_EVENTCAUSE_RESUME_NotDetected (0UL) /*!< Resume not detected */ +#define USBD_EVENTCAUSE_RESUME_Detected (1UL) /*!< Resume detected */ + +/* Bit 8 : Signals that the USB lines have been seen idle long enough for the device to enter suspend. Write '1' to clear. */ +#define USBD_EVENTCAUSE_SUSPEND_Pos (8UL) /*!< Position of SUSPEND field. */ +#define USBD_EVENTCAUSE_SUSPEND_Msk (0x1UL << USBD_EVENTCAUSE_SUSPEND_Pos) /*!< Bit mask of SUSPEND field. */ +#define USBD_EVENTCAUSE_SUSPEND_NotDetected (0UL) /*!< Suspend not detected */ +#define USBD_EVENTCAUSE_SUSPEND_Detected (1UL) /*!< Suspend detected */ + +/* Bit 0 : CRC error was detected on isochronous OUT endpoint 8. Write '1' to clear. */ +#define USBD_EVENTCAUSE_ISOOUTCRC_Pos (0UL) /*!< Position of ISOOUTCRC field. */ +#define USBD_EVENTCAUSE_ISOOUTCRC_Msk (0x1UL << USBD_EVENTCAUSE_ISOOUTCRC_Pos) /*!< Bit mask of ISOOUTCRC field. */ +#define USBD_EVENTCAUSE_ISOOUTCRC_NotDetected (0UL) /*!< No error detected */ +#define USBD_EVENTCAUSE_ISOOUTCRC_Detected (1UL) /*!< Error detected */ + +/* Register: USBD_BUSSTATE */ +/* Description: Provides the logic state of the D+ and D- lines */ + +/* Bit 1 : State of the D+ line */ +#define USBD_BUSSTATE_DP_Pos (1UL) /*!< Position of DP field. */ +#define USBD_BUSSTATE_DP_Msk (0x1UL << USBD_BUSSTATE_DP_Pos) /*!< Bit mask of DP field. */ +#define USBD_BUSSTATE_DP_Low (0UL) /*!< Low */ +#define USBD_BUSSTATE_DP_High (1UL) /*!< High */ + +/* Bit 0 : State of the D- line */ +#define USBD_BUSSTATE_DM_Pos (0UL) /*!< Position of DM field. */ +#define USBD_BUSSTATE_DM_Msk (0x1UL << USBD_BUSSTATE_DM_Pos) /*!< Bit mask of DM field. */ +#define USBD_BUSSTATE_DM_Low (0UL) /*!< Low */ +#define USBD_BUSSTATE_DM_High (1UL) /*!< High */ + +/* Register: USBD_HALTED_EPIN */ +/* Description: Description collection[0]: IN endpoint halted status. Can be used as is as response to a GetStatus() request to endpoint. */ + +/* Bits 15..0 : IN endpoint halted status. Can be used as is as response to a GetStatus() request to endpoint. */ +#define USBD_HALTED_EPIN_GETSTATUS_Pos (0UL) /*!< Position of GETSTATUS field. */ +#define USBD_HALTED_EPIN_GETSTATUS_Msk (0xFFFFUL << USBD_HALTED_EPIN_GETSTATUS_Pos) /*!< Bit mask of GETSTATUS field. */ +#define USBD_HALTED_EPIN_GETSTATUS_NotHalted (0UL) /*!< Endpoint is not halted */ +#define USBD_HALTED_EPIN_GETSTATUS_Halted (1UL) /*!< Endpoint is halted */ + +/* Register: USBD_HALTED_EPOUT */ +/* Description: Description collection[0]: OUT endpoint halted status. Can be used as is as response to a GetStatus() request to endpoint. */ + +/* Bits 15..0 : OUT endpoint halted status. Can be used as is as response to a GetStatus() request to endpoint. */ +#define USBD_HALTED_EPOUT_GETSTATUS_Pos (0UL) /*!< Position of GETSTATUS field. */ +#define USBD_HALTED_EPOUT_GETSTATUS_Msk (0xFFFFUL << USBD_HALTED_EPOUT_GETSTATUS_Pos) /*!< Bit mask of GETSTATUS field. */ +#define USBD_HALTED_EPOUT_GETSTATUS_NotHalted (0UL) /*!< Endpoint is not halted */ +#define USBD_HALTED_EPOUT_GETSTATUS_Halted (1UL) /*!< Endpoint is halted */ + +/* Register: USBD_EPSTATUS */ +/* Description: Provides information on which endpoint's EasyDMA registers have been captured */ + +/* Bit 24 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT8_Pos (24UL) /*!< Position of EPOUT8 field. */ +#define USBD_EPSTATUS_EPOUT8_Msk (0x1UL << USBD_EPSTATUS_EPOUT8_Pos) /*!< Bit mask of EPOUT8 field. */ +#define USBD_EPSTATUS_EPOUT8_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT8_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 23 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT7_Pos (23UL) /*!< Position of EPOUT7 field. */ +#define USBD_EPSTATUS_EPOUT7_Msk (0x1UL << USBD_EPSTATUS_EPOUT7_Pos) /*!< Bit mask of EPOUT7 field. */ +#define USBD_EPSTATUS_EPOUT7_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT7_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 22 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT6_Pos (22UL) /*!< Position of EPOUT6 field. */ +#define USBD_EPSTATUS_EPOUT6_Msk (0x1UL << USBD_EPSTATUS_EPOUT6_Pos) /*!< Bit mask of EPOUT6 field. */ +#define USBD_EPSTATUS_EPOUT6_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT6_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 21 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT5_Pos (21UL) /*!< Position of EPOUT5 field. */ +#define USBD_EPSTATUS_EPOUT5_Msk (0x1UL << USBD_EPSTATUS_EPOUT5_Pos) /*!< Bit mask of EPOUT5 field. */ +#define USBD_EPSTATUS_EPOUT5_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT5_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 20 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT4_Pos (20UL) /*!< Position of EPOUT4 field. */ +#define USBD_EPSTATUS_EPOUT4_Msk (0x1UL << USBD_EPSTATUS_EPOUT4_Pos) /*!< Bit mask of EPOUT4 field. */ +#define USBD_EPSTATUS_EPOUT4_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT4_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 19 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT3_Pos (19UL) /*!< Position of EPOUT3 field. */ +#define USBD_EPSTATUS_EPOUT3_Msk (0x1UL << USBD_EPSTATUS_EPOUT3_Pos) /*!< Bit mask of EPOUT3 field. */ +#define USBD_EPSTATUS_EPOUT3_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT3_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 18 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT2_Pos (18UL) /*!< Position of EPOUT2 field. */ +#define USBD_EPSTATUS_EPOUT2_Msk (0x1UL << USBD_EPSTATUS_EPOUT2_Pos) /*!< Bit mask of EPOUT2 field. */ +#define USBD_EPSTATUS_EPOUT2_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT2_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 17 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT1_Pos (17UL) /*!< Position of EPOUT1 field. */ +#define USBD_EPSTATUS_EPOUT1_Msk (0x1UL << USBD_EPSTATUS_EPOUT1_Pos) /*!< Bit mask of EPOUT1 field. */ +#define USBD_EPSTATUS_EPOUT1_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT1_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 16 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT0_Pos (16UL) /*!< Position of EPOUT0 field. */ +#define USBD_EPSTATUS_EPOUT0_Msk (0x1UL << USBD_EPSTATUS_EPOUT0_Pos) /*!< Bit mask of EPOUT0 field. */ +#define USBD_EPSTATUS_EPOUT0_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT0_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 8 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN8_Pos (8UL) /*!< Position of EPIN8 field. */ +#define USBD_EPSTATUS_EPIN8_Msk (0x1UL << USBD_EPSTATUS_EPIN8_Pos) /*!< Bit mask of EPIN8 field. */ +#define USBD_EPSTATUS_EPIN8_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN8_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 7 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN7_Pos (7UL) /*!< Position of EPIN7 field. */ +#define USBD_EPSTATUS_EPIN7_Msk (0x1UL << USBD_EPSTATUS_EPIN7_Pos) /*!< Bit mask of EPIN7 field. */ +#define USBD_EPSTATUS_EPIN7_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN7_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 6 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN6_Pos (6UL) /*!< Position of EPIN6 field. */ +#define USBD_EPSTATUS_EPIN6_Msk (0x1UL << USBD_EPSTATUS_EPIN6_Pos) /*!< Bit mask of EPIN6 field. */ +#define USBD_EPSTATUS_EPIN6_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN6_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 5 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN5_Pos (5UL) /*!< Position of EPIN5 field. */ +#define USBD_EPSTATUS_EPIN5_Msk (0x1UL << USBD_EPSTATUS_EPIN5_Pos) /*!< Bit mask of EPIN5 field. */ +#define USBD_EPSTATUS_EPIN5_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN5_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 4 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN4_Pos (4UL) /*!< Position of EPIN4 field. */ +#define USBD_EPSTATUS_EPIN4_Msk (0x1UL << USBD_EPSTATUS_EPIN4_Pos) /*!< Bit mask of EPIN4 field. */ +#define USBD_EPSTATUS_EPIN4_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN4_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 3 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN3_Pos (3UL) /*!< Position of EPIN3 field. */ +#define USBD_EPSTATUS_EPIN3_Msk (0x1UL << USBD_EPSTATUS_EPIN3_Pos) /*!< Bit mask of EPIN3 field. */ +#define USBD_EPSTATUS_EPIN3_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN3_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 2 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN2_Pos (2UL) /*!< Position of EPIN2 field. */ +#define USBD_EPSTATUS_EPIN2_Msk (0x1UL << USBD_EPSTATUS_EPIN2_Pos) /*!< Bit mask of EPIN2 field. */ +#define USBD_EPSTATUS_EPIN2_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN2_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 1 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN1_Pos (1UL) /*!< Position of EPIN1 field. */ +#define USBD_EPSTATUS_EPIN1_Msk (0x1UL << USBD_EPSTATUS_EPIN1_Pos) /*!< Bit mask of EPIN1 field. */ +#define USBD_EPSTATUS_EPIN1_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN1_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 0 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN0_Pos (0UL) /*!< Position of EPIN0 field. */ +#define USBD_EPSTATUS_EPIN0_Msk (0x1UL << USBD_EPSTATUS_EPIN0_Pos) /*!< Bit mask of EPIN0 field. */ +#define USBD_EPSTATUS_EPIN0_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN0_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Register: USBD_EPDATASTATUS */ +/* Description: Provides information on which endpoint(s) an acknowledged data transfer has occurred (EPDATA event) */ + +/* Bit 23 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT7_Pos (23UL) /*!< Position of EPOUT7 field. */ +#define USBD_EPDATASTATUS_EPOUT7_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT7_Pos) /*!< Bit mask of EPOUT7 field. */ +#define USBD_EPDATASTATUS_EPOUT7_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT7_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 22 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT6_Pos (22UL) /*!< Position of EPOUT6 field. */ +#define USBD_EPDATASTATUS_EPOUT6_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT6_Pos) /*!< Bit mask of EPOUT6 field. */ +#define USBD_EPDATASTATUS_EPOUT6_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT6_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 21 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT5_Pos (21UL) /*!< Position of EPOUT5 field. */ +#define USBD_EPDATASTATUS_EPOUT5_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT5_Pos) /*!< Bit mask of EPOUT5 field. */ +#define USBD_EPDATASTATUS_EPOUT5_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT5_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 20 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT4_Pos (20UL) /*!< Position of EPOUT4 field. */ +#define USBD_EPDATASTATUS_EPOUT4_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT4_Pos) /*!< Bit mask of EPOUT4 field. */ +#define USBD_EPDATASTATUS_EPOUT4_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT4_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 19 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT3_Pos (19UL) /*!< Position of EPOUT3 field. */ +#define USBD_EPDATASTATUS_EPOUT3_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT3_Pos) /*!< Bit mask of EPOUT3 field. */ +#define USBD_EPDATASTATUS_EPOUT3_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT3_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 18 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT2_Pos (18UL) /*!< Position of EPOUT2 field. */ +#define USBD_EPDATASTATUS_EPOUT2_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT2_Pos) /*!< Bit mask of EPOUT2 field. */ +#define USBD_EPDATASTATUS_EPOUT2_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT2_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 17 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT1_Pos (17UL) /*!< Position of EPOUT1 field. */ +#define USBD_EPDATASTATUS_EPOUT1_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT1_Pos) /*!< Bit mask of EPOUT1 field. */ +#define USBD_EPDATASTATUS_EPOUT1_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT1_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 7 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN7_Pos (7UL) /*!< Position of EPIN7 field. */ +#define USBD_EPDATASTATUS_EPIN7_Msk (0x1UL << USBD_EPDATASTATUS_EPIN7_Pos) /*!< Bit mask of EPIN7 field. */ +#define USBD_EPDATASTATUS_EPIN7_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN7_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 6 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN6_Pos (6UL) /*!< Position of EPIN6 field. */ +#define USBD_EPDATASTATUS_EPIN6_Msk (0x1UL << USBD_EPDATASTATUS_EPIN6_Pos) /*!< Bit mask of EPIN6 field. */ +#define USBD_EPDATASTATUS_EPIN6_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN6_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 5 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN5_Pos (5UL) /*!< Position of EPIN5 field. */ +#define USBD_EPDATASTATUS_EPIN5_Msk (0x1UL << USBD_EPDATASTATUS_EPIN5_Pos) /*!< Bit mask of EPIN5 field. */ +#define USBD_EPDATASTATUS_EPIN5_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN5_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 4 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN4_Pos (4UL) /*!< Position of EPIN4 field. */ +#define USBD_EPDATASTATUS_EPIN4_Msk (0x1UL << USBD_EPDATASTATUS_EPIN4_Pos) /*!< Bit mask of EPIN4 field. */ +#define USBD_EPDATASTATUS_EPIN4_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN4_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 3 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN3_Pos (3UL) /*!< Position of EPIN3 field. */ +#define USBD_EPDATASTATUS_EPIN3_Msk (0x1UL << USBD_EPDATASTATUS_EPIN3_Pos) /*!< Bit mask of EPIN3 field. */ +#define USBD_EPDATASTATUS_EPIN3_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN3_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 2 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN2_Pos (2UL) /*!< Position of EPIN2 field. */ +#define USBD_EPDATASTATUS_EPIN2_Msk (0x1UL << USBD_EPDATASTATUS_EPIN2_Pos) /*!< Bit mask of EPIN2 field. */ +#define USBD_EPDATASTATUS_EPIN2_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN2_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 1 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN1_Pos (1UL) /*!< Position of EPIN1 field. */ +#define USBD_EPDATASTATUS_EPIN1_Msk (0x1UL << USBD_EPDATASTATUS_EPIN1_Pos) /*!< Bit mask of EPIN1 field. */ +#define USBD_EPDATASTATUS_EPIN1_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN1_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Register: USBD_USBADDR */ +/* Description: Device USB address */ + +/* Bits 6..0 : Device USB address */ +#define USBD_USBADDR_ADDR_Pos (0UL) /*!< Position of ADDR field. */ +#define USBD_USBADDR_ADDR_Msk (0x7FUL << USBD_USBADDR_ADDR_Pos) /*!< Bit mask of ADDR field. */ + +/* Register: USBD_BMREQUESTTYPE */ +/* Description: SETUP data, byte 0, bmRequestType */ + +/* Bit 7 : Data transfer direction */ +#define USBD_BMREQUESTTYPE_DIRECTION_Pos (7UL) /*!< Position of DIRECTION field. */ +#define USBD_BMREQUESTTYPE_DIRECTION_Msk (0x1UL << USBD_BMREQUESTTYPE_DIRECTION_Pos) /*!< Bit mask of DIRECTION field. */ +#define USBD_BMREQUESTTYPE_DIRECTION_HostToDevice (0UL) /*!< Host-to-device */ +#define USBD_BMREQUESTTYPE_DIRECTION_DeviceToHost (1UL) /*!< Device-to-host */ + +/* Bits 6..5 : Data transfer type */ +#define USBD_BMREQUESTTYPE_TYPE_Pos (5UL) /*!< Position of TYPE field. */ +#define USBD_BMREQUESTTYPE_TYPE_Msk (0x3UL << USBD_BMREQUESTTYPE_TYPE_Pos) /*!< Bit mask of TYPE field. */ +#define USBD_BMREQUESTTYPE_TYPE_Standard (0UL) /*!< Standard */ +#define USBD_BMREQUESTTYPE_TYPE_Class (1UL) /*!< Class */ +#define USBD_BMREQUESTTYPE_TYPE_Vendor (2UL) /*!< Vendor */ + +/* Bits 4..0 : Data transfer type */ +#define USBD_BMREQUESTTYPE_RECIPIENT_Pos (0UL) /*!< Position of RECIPIENT field. */ +#define USBD_BMREQUESTTYPE_RECIPIENT_Msk (0x1FUL << USBD_BMREQUESTTYPE_RECIPIENT_Pos) /*!< Bit mask of RECIPIENT field. */ +#define USBD_BMREQUESTTYPE_RECIPIENT_Device (0UL) /*!< Device */ +#define USBD_BMREQUESTTYPE_RECIPIENT_Interface (1UL) /*!< Interface */ +#define USBD_BMREQUESTTYPE_RECIPIENT_Endpoint (2UL) /*!< Endpoint */ +#define USBD_BMREQUESTTYPE_RECIPIENT_Other (3UL) /*!< Other */ + +/* Register: USBD_BREQUEST */ +/* Description: SETUP data, byte 1, bRequest */ + +/* Bits 7..0 : SETUP data, byte 1, bRequest. Values provides for standard requests only, user must implement Class and Vendor values. */ +#define USBD_BREQUEST_BREQUEST_Pos (0UL) /*!< Position of BREQUEST field. */ +#define USBD_BREQUEST_BREQUEST_Msk (0xFFUL << USBD_BREQUEST_BREQUEST_Pos) /*!< Bit mask of BREQUEST field. */ +#define USBD_BREQUEST_BREQUEST_STD_GET_STATUS (0UL) /*!< Standard request GET_STATUS */ +#define USBD_BREQUEST_BREQUEST_STD_CLEAR_FEATURE (1UL) /*!< Standard request CLEAR_FEATURE */ +#define USBD_BREQUEST_BREQUEST_STD_SET_FEATURE (3UL) /*!< Standard request SET_FEATURE */ +#define USBD_BREQUEST_BREQUEST_STD_SET_ADDRESS (5UL) /*!< Standard request SET_ADDRESS */ +#define USBD_BREQUEST_BREQUEST_STD_GET_DESCRIPTOR (6UL) /*!< Standard request GET_DESCRIPTOR */ +#define USBD_BREQUEST_BREQUEST_STD_SET_DESCRIPTOR (7UL) /*!< Standard request SET_DESCRIPTOR */ +#define USBD_BREQUEST_BREQUEST_STD_GET_CONFIGURATION (8UL) /*!< Standard request GET_CONFIGURATION */ +#define USBD_BREQUEST_BREQUEST_STD_SET_CONFIGURATION (9UL) /*!< Standard request SET_CONFIGURATION */ +#define USBD_BREQUEST_BREQUEST_STD_GET_INTERFACE (10UL) /*!< Standard request GET_INTERFACE */ +#define USBD_BREQUEST_BREQUEST_STD_SET_INTERFACE (11UL) /*!< Standard request SET_INTERFACE */ +#define USBD_BREQUEST_BREQUEST_STD_SYNCH_FRAME (12UL) /*!< Standard request SYNCH_FRAME */ + +/* Register: USBD_WVALUEL */ +/* Description: SETUP data, byte 2, LSB of wValue */ + +/* Bits 7..0 : SETUP data, byte 2, LSB of wValue */ +#define USBD_WVALUEL_WVALUEL_Pos (0UL) /*!< Position of WVALUEL field. */ +#define USBD_WVALUEL_WVALUEL_Msk (0xFFUL << USBD_WVALUEL_WVALUEL_Pos) /*!< Bit mask of WVALUEL field. */ + +/* Register: USBD_WVALUEH */ +/* Description: SETUP data, byte 3, MSB of wValue */ + +/* Bits 7..0 : SETUP data, byte 3, MSB of wValue */ +#define USBD_WVALUEH_WVALUEH_Pos (0UL) /*!< Position of WVALUEH field. */ +#define USBD_WVALUEH_WVALUEH_Msk (0xFFUL << USBD_WVALUEH_WVALUEH_Pos) /*!< Bit mask of WVALUEH field. */ + +/* Register: USBD_WINDEXL */ +/* Description: SETUP data, byte 4, LSB of wIndex */ + +/* Bits 7..0 : SETUP data, byte 4, LSB of wIndex */ +#define USBD_WINDEXL_WINDEXL_Pos (0UL) /*!< Position of WINDEXL field. */ +#define USBD_WINDEXL_WINDEXL_Msk (0xFFUL << USBD_WINDEXL_WINDEXL_Pos) /*!< Bit mask of WINDEXL field. */ + +/* Register: USBD_WINDEXH */ +/* Description: SETUP data, byte 5, MSB of wIndex */ + +/* Bits 7..0 : SETUP data, byte 5, MSB of wIndex */ +#define USBD_WINDEXH_WINDEXH_Pos (0UL) /*!< Position of WINDEXH field. */ +#define USBD_WINDEXH_WINDEXH_Msk (0xFFUL << USBD_WINDEXH_WINDEXH_Pos) /*!< Bit mask of WINDEXH field. */ + +/* Register: USBD_WLENGTHL */ +/* Description: SETUP data, byte 6, LSB of wLength */ + +/* Bits 7..0 : SETUP data, byte 6, LSB of wLength */ +#define USBD_WLENGTHL_WLENGTHL_Pos (0UL) /*!< Position of WLENGTHL field. */ +#define USBD_WLENGTHL_WLENGTHL_Msk (0xFFUL << USBD_WLENGTHL_WLENGTHL_Pos) /*!< Bit mask of WLENGTHL field. */ + +/* Register: USBD_WLENGTHH */ +/* Description: SETUP data, byte 7, MSB of wLength */ + +/* Bits 7..0 : SETUP data, byte 7, MSB of wLength */ +#define USBD_WLENGTHH_WLENGTHH_Pos (0UL) /*!< Position of WLENGTHH field. */ +#define USBD_WLENGTHH_WLENGTHH_Msk (0xFFUL << USBD_WLENGTHH_WLENGTHH_Pos) /*!< Bit mask of WLENGTHH field. */ + +/* Register: USBD_SIZE_EPOUT */ +/* Description: Description collection[0]: Amount of bytes received last in the data stage of this OUT endpoint */ + +/* Bits 6..0 : Amount of bytes received last in the data stage of this OUT endpoint */ +#define USBD_SIZE_EPOUT_SIZE_Pos (0UL) /*!< Position of SIZE field. */ +#define USBD_SIZE_EPOUT_SIZE_Msk (0x7FUL << USBD_SIZE_EPOUT_SIZE_Pos) /*!< Bit mask of SIZE field. */ + +/* Register: USBD_SIZE_ISOOUT */ +/* Description: Amount of bytes received last on this iso OUT data endpoint */ + +/* Bit 16 : Zero-length data packet received */ +#define USBD_SIZE_ISOOUT_ZERO_Pos (16UL) /*!< Position of ZERO field. */ +#define USBD_SIZE_ISOOUT_ZERO_Msk (0x1UL << USBD_SIZE_ISOOUT_ZERO_Pos) /*!< Bit mask of ZERO field. */ +#define USBD_SIZE_ISOOUT_ZERO_Normal (0UL) /*!< No zero-length data received, use value in SIZE */ +#define USBD_SIZE_ISOOUT_ZERO_ZeroData (1UL) /*!< Zero-length data received, ignore value in SIZE */ + +/* Bits 9..0 : Amount of bytes received last on this iso OUT data endpoint */ +#define USBD_SIZE_ISOOUT_SIZE_Pos (0UL) /*!< Position of SIZE field. */ +#define USBD_SIZE_ISOOUT_SIZE_Msk (0x3FFUL << USBD_SIZE_ISOOUT_SIZE_Pos) /*!< Bit mask of SIZE field. */ + +/* Register: USBD_ENABLE */ +/* Description: Enable USB */ + +/* Bit 0 : Enable USB */ +#define USBD_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define USBD_ENABLE_ENABLE_Msk (0x1UL << USBD_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define USBD_ENABLE_ENABLE_Disabled (0UL) /*!< USB peripheral is disabled */ +#define USBD_ENABLE_ENABLE_Enabled (1UL) /*!< USB peripheral is enabled */ + +/* Register: USBD_USBPULLUP */ +/* Description: Control of the USB pull-up */ + +/* Bit 0 : Control of the USB pull-up on the D+ line */ +#define USBD_USBPULLUP_CONNECT_Pos (0UL) /*!< Position of CONNECT field. */ +#define USBD_USBPULLUP_CONNECT_Msk (0x1UL << USBD_USBPULLUP_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define USBD_USBPULLUP_CONNECT_Disabled (0UL) /*!< Pull-up is disconnected */ +#define USBD_USBPULLUP_CONNECT_Enabled (1UL) /*!< Pull-up is connected to D+ */ + +/* Register: USBD_DPDMVALUE */ +/* Description: State at which the DPDMDRIVE task will force D+ and D-. The DPDMNODRIVE task reverts the control of the lines to MAC IP (no forcing). */ + +/* Bits 4..0 : State at which the DPDMDRIVE task will force D+ and D- */ +#define USBD_DPDMVALUE_STATE_Pos (0UL) /*!< Position of STATE field. */ +#define USBD_DPDMVALUE_STATE_Msk (0x1FUL << USBD_DPDMVALUE_STATE_Pos) /*!< Bit mask of STATE field. */ +#define USBD_DPDMVALUE_STATE_Resume (1UL) /*!< D+ forced low, D- forced high (K state) for a timing pre-set in hardware (50 us or 5 ms, depending on bus state) */ +#define USBD_DPDMVALUE_STATE_J (2UL) /*!< D+ forced high, D- forced low (J state) */ +#define USBD_DPDMVALUE_STATE_K (4UL) /*!< D+ forced low, D- forced high (K state) */ + +/* Register: USBD_DTOGGLE */ +/* Description: Data toggle control and status. */ + +/* Bits 9..8 : Data toggle value */ +#define USBD_DTOGGLE_VALUE_Pos (8UL) /*!< Position of VALUE field. */ +#define USBD_DTOGGLE_VALUE_Msk (0x3UL << USBD_DTOGGLE_VALUE_Pos) /*!< Bit mask of VALUE field. */ +#define USBD_DTOGGLE_VALUE_Nop (0UL) /*!< No action on data toggle when writing the register with this value */ +#define USBD_DTOGGLE_VALUE_Data0 (1UL) /*!< Data toggle is DATA0 on endpoint set by EP and IO */ +#define USBD_DTOGGLE_VALUE_Data1 (2UL) /*!< Data toggle is DATA1 on endpoint set by EP and IO */ + +/* Bit 7 : Selects IN or OUT endpoint */ +#define USBD_DTOGGLE_IO_Pos (7UL) /*!< Position of IO field. */ +#define USBD_DTOGGLE_IO_Msk (0x1UL << USBD_DTOGGLE_IO_Pos) /*!< Bit mask of IO field. */ +#define USBD_DTOGGLE_IO_Out (0UL) /*!< Selects OUT endpoint */ +#define USBD_DTOGGLE_IO_In (1UL) /*!< Selects IN endpoint */ + +/* Bits 2..0 : Select bulk endpoint number */ +#define USBD_DTOGGLE_EP_Pos (0UL) /*!< Position of EP field. */ +#define USBD_DTOGGLE_EP_Msk (0x7UL << USBD_DTOGGLE_EP_Pos) /*!< Bit mask of EP field. */ + +/* Register: USBD_EPINEN */ +/* Description: Endpoint IN enable */ + +/* Bit 8 : Enable iso IN endpoint */ +#define USBD_EPINEN_ISOIN_Pos (8UL) /*!< Position of ISOIN field. */ +#define USBD_EPINEN_ISOIN_Msk (0x1UL << USBD_EPINEN_ISOIN_Pos) /*!< Bit mask of ISOIN field. */ +#define USBD_EPINEN_ISOIN_Disable (0UL) /*!< Disable iso IN endpoint 8 */ +#define USBD_EPINEN_ISOIN_Enable (1UL) /*!< Enable iso IN endpoint 8 */ + +/* Bit 7 : Enable IN endpoint 7 */ +#define USBD_EPINEN_IN7_Pos (7UL) /*!< Position of IN7 field. */ +#define USBD_EPINEN_IN7_Msk (0x1UL << USBD_EPINEN_IN7_Pos) /*!< Bit mask of IN7 field. */ +#define USBD_EPINEN_IN7_Disable (0UL) /*!< Disable endpoint IN 7 (no response to IN tokens) */ +#define USBD_EPINEN_IN7_Enable (1UL) /*!< Enable endpoint IN 7 (response to IN tokens) */ + +/* Bit 6 : Enable IN endpoint 6 */ +#define USBD_EPINEN_IN6_Pos (6UL) /*!< Position of IN6 field. */ +#define USBD_EPINEN_IN6_Msk (0x1UL << USBD_EPINEN_IN6_Pos) /*!< Bit mask of IN6 field. */ +#define USBD_EPINEN_IN6_Disable (0UL) /*!< Disable endpoint IN 6 (no response to IN tokens) */ +#define USBD_EPINEN_IN6_Enable (1UL) /*!< Enable endpoint IN 6 (response to IN tokens) */ + +/* Bit 5 : Enable IN endpoint 5 */ +#define USBD_EPINEN_IN5_Pos (5UL) /*!< Position of IN5 field. */ +#define USBD_EPINEN_IN5_Msk (0x1UL << USBD_EPINEN_IN5_Pos) /*!< Bit mask of IN5 field. */ +#define USBD_EPINEN_IN5_Disable (0UL) /*!< Disable endpoint IN 5 (no response to IN tokens) */ +#define USBD_EPINEN_IN5_Enable (1UL) /*!< Enable endpoint IN 5 (response to IN tokens) */ + +/* Bit 4 : Enable IN endpoint 4 */ +#define USBD_EPINEN_IN4_Pos (4UL) /*!< Position of IN4 field. */ +#define USBD_EPINEN_IN4_Msk (0x1UL << USBD_EPINEN_IN4_Pos) /*!< Bit mask of IN4 field. */ +#define USBD_EPINEN_IN4_Disable (0UL) /*!< Disable endpoint IN 4 (no response to IN tokens) */ +#define USBD_EPINEN_IN4_Enable (1UL) /*!< Enable endpoint IN 4 (response to IN tokens) */ + +/* Bit 3 : Enable IN endpoint 3 */ +#define USBD_EPINEN_IN3_Pos (3UL) /*!< Position of IN3 field. */ +#define USBD_EPINEN_IN3_Msk (0x1UL << USBD_EPINEN_IN3_Pos) /*!< Bit mask of IN3 field. */ +#define USBD_EPINEN_IN3_Disable (0UL) /*!< Disable endpoint IN 3 (no response to IN tokens) */ +#define USBD_EPINEN_IN3_Enable (1UL) /*!< Enable endpoint IN 3 (response to IN tokens) */ + +/* Bit 2 : Enable IN endpoint 2 */ +#define USBD_EPINEN_IN2_Pos (2UL) /*!< Position of IN2 field. */ +#define USBD_EPINEN_IN2_Msk (0x1UL << USBD_EPINEN_IN2_Pos) /*!< Bit mask of IN2 field. */ +#define USBD_EPINEN_IN2_Disable (0UL) /*!< Disable endpoint IN 2 (no response to IN tokens) */ +#define USBD_EPINEN_IN2_Enable (1UL) /*!< Enable endpoint IN 2 (response to IN tokens) */ + +/* Bit 1 : Enable IN endpoint 1 */ +#define USBD_EPINEN_IN1_Pos (1UL) /*!< Position of IN1 field. */ +#define USBD_EPINEN_IN1_Msk (0x1UL << USBD_EPINEN_IN1_Pos) /*!< Bit mask of IN1 field. */ +#define USBD_EPINEN_IN1_Disable (0UL) /*!< Disable endpoint IN 1 (no response to IN tokens) */ +#define USBD_EPINEN_IN1_Enable (1UL) /*!< Enable endpoint IN 1 (response to IN tokens) */ + +/* Bit 0 : Enable IN endpoint 0 */ +#define USBD_EPINEN_IN0_Pos (0UL) /*!< Position of IN0 field. */ +#define USBD_EPINEN_IN0_Msk (0x1UL << USBD_EPINEN_IN0_Pos) /*!< Bit mask of IN0 field. */ +#define USBD_EPINEN_IN0_Disable (0UL) /*!< Disable endpoint IN 0 (no response to IN tokens) */ +#define USBD_EPINEN_IN0_Enable (1UL) /*!< Enable endpoint IN 0 (response to IN tokens) */ + +/* Register: USBD_EPOUTEN */ +/* Description: Endpoint OUT enable */ + +/* Bit 8 : Enable iso OUT endpoint 8 */ +#define USBD_EPOUTEN_ISOOUT_Pos (8UL) /*!< Position of ISOOUT field. */ +#define USBD_EPOUTEN_ISOOUT_Msk (0x1UL << USBD_EPOUTEN_ISOOUT_Pos) /*!< Bit mask of ISOOUT field. */ +#define USBD_EPOUTEN_ISOOUT_Disable (0UL) /*!< Disable iso OUT endpoint 8 */ +#define USBD_EPOUTEN_ISOOUT_Enable (1UL) /*!< Enable iso OUT endpoint 8 */ + +/* Bit 7 : Enable OUT endpoint 7 */ +#define USBD_EPOUTEN_OUT7_Pos (7UL) /*!< Position of OUT7 field. */ +#define USBD_EPOUTEN_OUT7_Msk (0x1UL << USBD_EPOUTEN_OUT7_Pos) /*!< Bit mask of OUT7 field. */ +#define USBD_EPOUTEN_OUT7_Disable (0UL) /*!< Disable endpoint OUT 7 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT7_Enable (1UL) /*!< Enable endpoint OUT 7 (response to OUT tokens) */ + +/* Bit 6 : Enable OUT endpoint 6 */ +#define USBD_EPOUTEN_OUT6_Pos (6UL) /*!< Position of OUT6 field. */ +#define USBD_EPOUTEN_OUT6_Msk (0x1UL << USBD_EPOUTEN_OUT6_Pos) /*!< Bit mask of OUT6 field. */ +#define USBD_EPOUTEN_OUT6_Disable (0UL) /*!< Disable endpoint OUT 6 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT6_Enable (1UL) /*!< Enable endpoint OUT 6 (response to OUT tokens) */ + +/* Bit 5 : Enable OUT endpoint 5 */ +#define USBD_EPOUTEN_OUT5_Pos (5UL) /*!< Position of OUT5 field. */ +#define USBD_EPOUTEN_OUT5_Msk (0x1UL << USBD_EPOUTEN_OUT5_Pos) /*!< Bit mask of OUT5 field. */ +#define USBD_EPOUTEN_OUT5_Disable (0UL) /*!< Disable endpoint OUT 5 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT5_Enable (1UL) /*!< Enable endpoint OUT 5 (response to OUT tokens) */ + +/* Bit 4 : Enable OUT endpoint 4 */ +#define USBD_EPOUTEN_OUT4_Pos (4UL) /*!< Position of OUT4 field. */ +#define USBD_EPOUTEN_OUT4_Msk (0x1UL << USBD_EPOUTEN_OUT4_Pos) /*!< Bit mask of OUT4 field. */ +#define USBD_EPOUTEN_OUT4_Disable (0UL) /*!< Disable endpoint OUT 4 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT4_Enable (1UL) /*!< Enable endpoint OUT 4 (response to OUT tokens) */ + +/* Bit 3 : Enable OUT endpoint 3 */ +#define USBD_EPOUTEN_OUT3_Pos (3UL) /*!< Position of OUT3 field. */ +#define USBD_EPOUTEN_OUT3_Msk (0x1UL << USBD_EPOUTEN_OUT3_Pos) /*!< Bit mask of OUT3 field. */ +#define USBD_EPOUTEN_OUT3_Disable (0UL) /*!< Disable endpoint OUT 3 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT3_Enable (1UL) /*!< Enable endpoint OUT 3 (response to OUT tokens) */ + +/* Bit 2 : Enable OUT endpoint 2 */ +#define USBD_EPOUTEN_OUT2_Pos (2UL) /*!< Position of OUT2 field. */ +#define USBD_EPOUTEN_OUT2_Msk (0x1UL << USBD_EPOUTEN_OUT2_Pos) /*!< Bit mask of OUT2 field. */ +#define USBD_EPOUTEN_OUT2_Disable (0UL) /*!< Disable endpoint OUT 2 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT2_Enable (1UL) /*!< Enable endpoint OUT 2 (response to OUT tokens) */ + +/* Bit 1 : Enable OUT endpoint 1 */ +#define USBD_EPOUTEN_OUT1_Pos (1UL) /*!< Position of OUT1 field. */ +#define USBD_EPOUTEN_OUT1_Msk (0x1UL << USBD_EPOUTEN_OUT1_Pos) /*!< Bit mask of OUT1 field. */ +#define USBD_EPOUTEN_OUT1_Disable (0UL) /*!< Disable endpoint OUT 1 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT1_Enable (1UL) /*!< Enable endpoint OUT 1 (response to OUT tokens) */ + +/* Bit 0 : Enable OUT endpoint 0 */ +#define USBD_EPOUTEN_OUT0_Pos (0UL) /*!< Position of OUT0 field. */ +#define USBD_EPOUTEN_OUT0_Msk (0x1UL << USBD_EPOUTEN_OUT0_Pos) /*!< Bit mask of OUT0 field. */ +#define USBD_EPOUTEN_OUT0_Disable (0UL) /*!< Disable endpoint OUT 0 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT0_Enable (1UL) /*!< Enable endpoint OUT 0 (response to OUT tokens) */ + +/* Register: USBD_EPSTALL */ +/* Description: STALL endpoints */ + +/* Bit 8 : Stall selected endpoint */ +#define USBD_EPSTALL_STALL_Pos (8UL) /*!< Position of STALL field. */ +#define USBD_EPSTALL_STALL_Msk (0x1UL << USBD_EPSTALL_STALL_Pos) /*!< Bit mask of STALL field. */ +#define USBD_EPSTALL_STALL_UnStall (0UL) /*!< Don't stall selected endpoint */ +#define USBD_EPSTALL_STALL_Stall (1UL) /*!< Stall selected endpoint */ + +/* Bit 7 : Selects IN or OUT endpoint */ +#define USBD_EPSTALL_IO_Pos (7UL) /*!< Position of IO field. */ +#define USBD_EPSTALL_IO_Msk (0x1UL << USBD_EPSTALL_IO_Pos) /*!< Bit mask of IO field. */ +#define USBD_EPSTALL_IO_Out (0UL) /*!< Selects OUT endpoint */ +#define USBD_EPSTALL_IO_In (1UL) /*!< Selects IN endpoint */ + +/* Bits 2..0 : Select endpoint number */ +#define USBD_EPSTALL_EP_Pos (0UL) /*!< Position of EP field. */ +#define USBD_EPSTALL_EP_Msk (0x7UL << USBD_EPSTALL_EP_Pos) /*!< Bit mask of EP field. */ + +/* Register: USBD_ISOSPLIT */ +/* Description: Controls the split of ISO buffers */ + +/* Bits 15..0 : Controls the split of ISO buffers */ +#define USBD_ISOSPLIT_SPLIT_Pos (0UL) /*!< Position of SPLIT field. */ +#define USBD_ISOSPLIT_SPLIT_Msk (0xFFFFUL << USBD_ISOSPLIT_SPLIT_Pos) /*!< Bit mask of SPLIT field. */ +#define USBD_ISOSPLIT_SPLIT_OneDir (0x0000UL) /*!< Full buffer dedicated to either iso IN or OUT */ +#define USBD_ISOSPLIT_SPLIT_HalfIN (0x0080UL) /*!< Lower half for IN, upper half for OUT */ + +/* Register: USBD_FRAMECNTR */ +/* Description: Returns the current value of the start of frame counter */ + +/* Bits 10..0 : Returns the current value of the start of frame counter */ +#define USBD_FRAMECNTR_FRAMECNTR_Pos (0UL) /*!< Position of FRAMECNTR field. */ +#define USBD_FRAMECNTR_FRAMECNTR_Msk (0x7FFUL << USBD_FRAMECNTR_FRAMECNTR_Pos) /*!< Bit mask of FRAMECNTR field. */ + +/* Register: USBD_ISOINCONFIG */ +/* Description: Controls the response of the ISO IN endpoint to an IN token when no data is ready to be sent */ + +/* Bit 0 : Controls the response of the ISO IN endpoint to an IN token when no data is ready to be sent */ +#define USBD_ISOINCONFIG_RESPONSE_Pos (0UL) /*!< Position of RESPONSE field. */ +#define USBD_ISOINCONFIG_RESPONSE_Msk (0x1UL << USBD_ISOINCONFIG_RESPONSE_Pos) /*!< Bit mask of RESPONSE field. */ +#define USBD_ISOINCONFIG_RESPONSE_NoResp (0UL) /*!< Endpoint does not respond in that case */ +#define USBD_ISOINCONFIG_RESPONSE_ZeroData (1UL) /*!< Endpoint responds with a zero-length data packet in that case */ + +/* Register: USBD_EPIN_PTR */ +/* Description: Description cluster[0]: Data pointer */ + +/* Bits 31..0 : Data pointer. Accepts any address in Data RAM. */ +#define USBD_EPIN_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define USBD_EPIN_PTR_PTR_Msk (0xFFFFFFFFUL << USBD_EPIN_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: USBD_EPIN_MAXCNT */ +/* Description: Description cluster[0]: Maximum number of bytes to transfer */ + +/* Bits 6..0 : Maximum number of bytes to transfer */ +#define USBD_EPIN_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define USBD_EPIN_MAXCNT_MAXCNT_Msk (0x7FUL << USBD_EPIN_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: USBD_EPIN_AMOUNT */ +/* Description: Description cluster[0]: Number of bytes transferred in the last transaction */ + +/* Bits 6..0 : Number of bytes transferred in the last transaction */ +#define USBD_EPIN_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define USBD_EPIN_AMOUNT_AMOUNT_Msk (0x7FUL << USBD_EPIN_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: USBD_ISOIN_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer. Accepts any address in Data RAM. */ +#define USBD_ISOIN_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define USBD_ISOIN_PTR_PTR_Msk (0xFFFFFFFFUL << USBD_ISOIN_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: USBD_ISOIN_MAXCNT */ +/* Description: Maximum number of bytes to transfer */ + +/* Bits 9..0 : Maximum number of bytes to transfer */ +#define USBD_ISOIN_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define USBD_ISOIN_MAXCNT_MAXCNT_Msk (0x3FFUL << USBD_ISOIN_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: USBD_ISOIN_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 9..0 : Number of bytes transferred in the last transaction */ +#define USBD_ISOIN_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define USBD_ISOIN_AMOUNT_AMOUNT_Msk (0x3FFUL << USBD_ISOIN_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: USBD_EPOUT_PTR */ +/* Description: Description cluster[0]: Data pointer */ + +/* Bits 31..0 : Data pointer. Accepts any address in Data RAM. */ +#define USBD_EPOUT_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define USBD_EPOUT_PTR_PTR_Msk (0xFFFFFFFFUL << USBD_EPOUT_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: USBD_EPOUT_MAXCNT */ +/* Description: Description cluster[0]: Maximum number of bytes to transfer */ + +/* Bits 6..0 : Maximum number of bytes to transfer */ +#define USBD_EPOUT_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define USBD_EPOUT_MAXCNT_MAXCNT_Msk (0x7FUL << USBD_EPOUT_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: USBD_EPOUT_AMOUNT */ +/* Description: Description cluster[0]: Number of bytes transferred in the last transaction */ + +/* Bits 6..0 : Number of bytes transferred in the last transaction */ +#define USBD_EPOUT_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define USBD_EPOUT_AMOUNT_AMOUNT_Msk (0x7FUL << USBD_EPOUT_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: USBD_ISOOUT_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer. Accepts any address in Data RAM. */ +#define USBD_ISOOUT_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define USBD_ISOOUT_PTR_PTR_Msk (0xFFFFFFFFUL << USBD_ISOOUT_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: USBD_ISOOUT_MAXCNT */ +/* Description: Maximum number of bytes to transfer */ + +/* Bits 9..0 : Maximum number of bytes to transfer */ +#define USBD_ISOOUT_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define USBD_ISOOUT_MAXCNT_MAXCNT_Msk (0x3FFUL << USBD_ISOOUT_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: USBD_ISOOUT_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 9..0 : Number of bytes transferred in the last transaction */ +#define USBD_ISOOUT_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define USBD_ISOOUT_AMOUNT_AMOUNT_Msk (0x3FFUL << USBD_ISOOUT_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + + +/* Peripheral: WDT */ +/* Description: Watchdog Timer */ + +/* Register: WDT_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 0 : Write '1' to Enable interrupt for TIMEOUT event */ +#define WDT_INTENSET_TIMEOUT_Pos (0UL) /*!< Position of TIMEOUT field. */ +#define WDT_INTENSET_TIMEOUT_Msk (0x1UL << WDT_INTENSET_TIMEOUT_Pos) /*!< Bit mask of TIMEOUT field. */ +#define WDT_INTENSET_TIMEOUT_Disabled (0UL) /*!< Read: Disabled */ +#define WDT_INTENSET_TIMEOUT_Enabled (1UL) /*!< Read: Enabled */ +#define WDT_INTENSET_TIMEOUT_Set (1UL) /*!< Enable */ + +/* Register: WDT_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 0 : Write '1' to Disable interrupt for TIMEOUT event */ +#define WDT_INTENCLR_TIMEOUT_Pos (0UL) /*!< Position of TIMEOUT field. */ +#define WDT_INTENCLR_TIMEOUT_Msk (0x1UL << WDT_INTENCLR_TIMEOUT_Pos) /*!< Bit mask of TIMEOUT field. */ +#define WDT_INTENCLR_TIMEOUT_Disabled (0UL) /*!< Read: Disabled */ +#define WDT_INTENCLR_TIMEOUT_Enabled (1UL) /*!< Read: Enabled */ +#define WDT_INTENCLR_TIMEOUT_Clear (1UL) /*!< Disable */ + +/* Register: WDT_RUNSTATUS */ +/* Description: Run status */ + +/* Bit 0 : Indicates whether or not the watchdog is running */ +#define WDT_RUNSTATUS_RUNSTATUS_Pos (0UL) /*!< Position of RUNSTATUS field. */ +#define WDT_RUNSTATUS_RUNSTATUS_Msk (0x1UL << WDT_RUNSTATUS_RUNSTATUS_Pos) /*!< Bit mask of RUNSTATUS field. */ +#define WDT_RUNSTATUS_RUNSTATUS_NotRunning (0UL) /*!< Watchdog not running */ +#define WDT_RUNSTATUS_RUNSTATUS_Running (1UL) /*!< Watchdog is running */ + +/* Register: WDT_REQSTATUS */ +/* Description: Request status */ + +/* Bit 7 : Request status for RR[7] register */ +#define WDT_REQSTATUS_RR7_Pos (7UL) /*!< Position of RR7 field. */ +#define WDT_REQSTATUS_RR7_Msk (0x1UL << WDT_REQSTATUS_RR7_Pos) /*!< Bit mask of RR7 field. */ +#define WDT_REQSTATUS_RR7_DisabledOrRequested (0UL) /*!< RR[7] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR7_EnabledAndUnrequested (1UL) /*!< RR[7] register is enabled, and are not yet requesting reload */ + +/* Bit 6 : Request status for RR[6] register */ +#define WDT_REQSTATUS_RR6_Pos (6UL) /*!< Position of RR6 field. */ +#define WDT_REQSTATUS_RR6_Msk (0x1UL << WDT_REQSTATUS_RR6_Pos) /*!< Bit mask of RR6 field. */ +#define WDT_REQSTATUS_RR6_DisabledOrRequested (0UL) /*!< RR[6] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR6_EnabledAndUnrequested (1UL) /*!< RR[6] register is enabled, and are not yet requesting reload */ + +/* Bit 5 : Request status for RR[5] register */ +#define WDT_REQSTATUS_RR5_Pos (5UL) /*!< Position of RR5 field. */ +#define WDT_REQSTATUS_RR5_Msk (0x1UL << WDT_REQSTATUS_RR5_Pos) /*!< Bit mask of RR5 field. */ +#define WDT_REQSTATUS_RR5_DisabledOrRequested (0UL) /*!< RR[5] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR5_EnabledAndUnrequested (1UL) /*!< RR[5] register is enabled, and are not yet requesting reload */ + +/* Bit 4 : Request status for RR[4] register */ +#define WDT_REQSTATUS_RR4_Pos (4UL) /*!< Position of RR4 field. */ +#define WDT_REQSTATUS_RR4_Msk (0x1UL << WDT_REQSTATUS_RR4_Pos) /*!< Bit mask of RR4 field. */ +#define WDT_REQSTATUS_RR4_DisabledOrRequested (0UL) /*!< RR[4] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR4_EnabledAndUnrequested (1UL) /*!< RR[4] register is enabled, and are not yet requesting reload */ + +/* Bit 3 : Request status for RR[3] register */ +#define WDT_REQSTATUS_RR3_Pos (3UL) /*!< Position of RR3 field. */ +#define WDT_REQSTATUS_RR3_Msk (0x1UL << WDT_REQSTATUS_RR3_Pos) /*!< Bit mask of RR3 field. */ +#define WDT_REQSTATUS_RR3_DisabledOrRequested (0UL) /*!< RR[3] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR3_EnabledAndUnrequested (1UL) /*!< RR[3] register is enabled, and are not yet requesting reload */ + +/* Bit 2 : Request status for RR[2] register */ +#define WDT_REQSTATUS_RR2_Pos (2UL) /*!< Position of RR2 field. */ +#define WDT_REQSTATUS_RR2_Msk (0x1UL << WDT_REQSTATUS_RR2_Pos) /*!< Bit mask of RR2 field. */ +#define WDT_REQSTATUS_RR2_DisabledOrRequested (0UL) /*!< RR[2] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR2_EnabledAndUnrequested (1UL) /*!< RR[2] register is enabled, and are not yet requesting reload */ + +/* Bit 1 : Request status for RR[1] register */ +#define WDT_REQSTATUS_RR1_Pos (1UL) /*!< Position of RR1 field. */ +#define WDT_REQSTATUS_RR1_Msk (0x1UL << WDT_REQSTATUS_RR1_Pos) /*!< Bit mask of RR1 field. */ +#define WDT_REQSTATUS_RR1_DisabledOrRequested (0UL) /*!< RR[1] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR1_EnabledAndUnrequested (1UL) /*!< RR[1] register is enabled, and are not yet requesting reload */ + +/* Bit 0 : Request status for RR[0] register */ +#define WDT_REQSTATUS_RR0_Pos (0UL) /*!< Position of RR0 field. */ +#define WDT_REQSTATUS_RR0_Msk (0x1UL << WDT_REQSTATUS_RR0_Pos) /*!< Bit mask of RR0 field. */ +#define WDT_REQSTATUS_RR0_DisabledOrRequested (0UL) /*!< RR[0] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR0_EnabledAndUnrequested (1UL) /*!< RR[0] register is enabled, and are not yet requesting reload */ + +/* Register: WDT_CRV */ +/* Description: Counter reload value */ + +/* Bits 31..0 : Counter reload value in number of cycles of the 32.768 kHz clock */ +#define WDT_CRV_CRV_Pos (0UL) /*!< Position of CRV field. */ +#define WDT_CRV_CRV_Msk (0xFFFFFFFFUL << WDT_CRV_CRV_Pos) /*!< Bit mask of CRV field. */ + +/* Register: WDT_RREN */ +/* Description: Enable register for reload request registers */ + +/* Bit 7 : Enable or disable RR[7] register */ +#define WDT_RREN_RR7_Pos (7UL) /*!< Position of RR7 field. */ +#define WDT_RREN_RR7_Msk (0x1UL << WDT_RREN_RR7_Pos) /*!< Bit mask of RR7 field. */ +#define WDT_RREN_RR7_Disabled (0UL) /*!< Disable RR[7] register */ +#define WDT_RREN_RR7_Enabled (1UL) /*!< Enable RR[7] register */ + +/* Bit 6 : Enable or disable RR[6] register */ +#define WDT_RREN_RR6_Pos (6UL) /*!< Position of RR6 field. */ +#define WDT_RREN_RR6_Msk (0x1UL << WDT_RREN_RR6_Pos) /*!< Bit mask of RR6 field. */ +#define WDT_RREN_RR6_Disabled (0UL) /*!< Disable RR[6] register */ +#define WDT_RREN_RR6_Enabled (1UL) /*!< Enable RR[6] register */ + +/* Bit 5 : Enable or disable RR[5] register */ +#define WDT_RREN_RR5_Pos (5UL) /*!< Position of RR5 field. */ +#define WDT_RREN_RR5_Msk (0x1UL << WDT_RREN_RR5_Pos) /*!< Bit mask of RR5 field. */ +#define WDT_RREN_RR5_Disabled (0UL) /*!< Disable RR[5] register */ +#define WDT_RREN_RR5_Enabled (1UL) /*!< Enable RR[5] register */ + +/* Bit 4 : Enable or disable RR[4] register */ +#define WDT_RREN_RR4_Pos (4UL) /*!< Position of RR4 field. */ +#define WDT_RREN_RR4_Msk (0x1UL << WDT_RREN_RR4_Pos) /*!< Bit mask of RR4 field. */ +#define WDT_RREN_RR4_Disabled (0UL) /*!< Disable RR[4] register */ +#define WDT_RREN_RR4_Enabled (1UL) /*!< Enable RR[4] register */ + +/* Bit 3 : Enable or disable RR[3] register */ +#define WDT_RREN_RR3_Pos (3UL) /*!< Position of RR3 field. */ +#define WDT_RREN_RR3_Msk (0x1UL << WDT_RREN_RR3_Pos) /*!< Bit mask of RR3 field. */ +#define WDT_RREN_RR3_Disabled (0UL) /*!< Disable RR[3] register */ +#define WDT_RREN_RR3_Enabled (1UL) /*!< Enable RR[3] register */ + +/* Bit 2 : Enable or disable RR[2] register */ +#define WDT_RREN_RR2_Pos (2UL) /*!< Position of RR2 field. */ +#define WDT_RREN_RR2_Msk (0x1UL << WDT_RREN_RR2_Pos) /*!< Bit mask of RR2 field. */ +#define WDT_RREN_RR2_Disabled (0UL) /*!< Disable RR[2] register */ +#define WDT_RREN_RR2_Enabled (1UL) /*!< Enable RR[2] register */ + +/* Bit 1 : Enable or disable RR[1] register */ +#define WDT_RREN_RR1_Pos (1UL) /*!< Position of RR1 field. */ +#define WDT_RREN_RR1_Msk (0x1UL << WDT_RREN_RR1_Pos) /*!< Bit mask of RR1 field. */ +#define WDT_RREN_RR1_Disabled (0UL) /*!< Disable RR[1] register */ +#define WDT_RREN_RR1_Enabled (1UL) /*!< Enable RR[1] register */ + +/* Bit 0 : Enable or disable RR[0] register */ +#define WDT_RREN_RR0_Pos (0UL) /*!< Position of RR0 field. */ +#define WDT_RREN_RR0_Msk (0x1UL << WDT_RREN_RR0_Pos) /*!< Bit mask of RR0 field. */ +#define WDT_RREN_RR0_Disabled (0UL) /*!< Disable RR[0] register */ +#define WDT_RREN_RR0_Enabled (1UL) /*!< Enable RR[0] register */ + +/* Register: WDT_CONFIG */ +/* Description: Configuration register */ + +/* Bit 3 : Configure the watchdog to either be paused, or kept running, while the CPU is halted by the debugger */ +#define WDT_CONFIG_HALT_Pos (3UL) /*!< Position of HALT field. */ +#define WDT_CONFIG_HALT_Msk (0x1UL << WDT_CONFIG_HALT_Pos) /*!< Bit mask of HALT field. */ +#define WDT_CONFIG_HALT_Pause (0UL) /*!< Pause watchdog while the CPU is halted by the debugger */ +#define WDT_CONFIG_HALT_Run (1UL) /*!< Keep the watchdog running while the CPU is halted by the debugger */ + +/* Bit 0 : Configure the watchdog to either be paused, or kept running, while the CPU is sleeping */ +#define WDT_CONFIG_SLEEP_Pos (0UL) /*!< Position of SLEEP field. */ +#define WDT_CONFIG_SLEEP_Msk (0x1UL << WDT_CONFIG_SLEEP_Pos) /*!< Bit mask of SLEEP field. */ +#define WDT_CONFIG_SLEEP_Pause (0UL) /*!< Pause watchdog while the CPU is sleeping */ +#define WDT_CONFIG_SLEEP_Run (1UL) /*!< Keep the watchdog running while the CPU is sleeping */ + +/* Register: WDT_RR */ +/* Description: Description collection[0]: Reload request 0 */ + +/* Bits 31..0 : Reload request register */ +#define WDT_RR_RR_Pos (0UL) /*!< Position of RR field. */ +#define WDT_RR_RR_Msk (0xFFFFFFFFUL << WDT_RR_RR_Pos) /*!< Bit mask of RR field. */ +#define WDT_RR_RR_Reload (0x6E524635UL) /*!< Value to request a reload of the watchdog timer */ + + +/*lint --flb "Leave library region" */ +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52840_peripherals.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52840_peripherals.h new file mode 100644 index 0000000000000000000000000000000000000000..a77859047a016e02cb6c3398b4aceaec3d6e69d7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52840_peripherals.h @@ -0,0 +1,252 @@ +/* + +Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + +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, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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 Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + +*/ + +#ifndef _NRF52840_PERIPHERALS_H +#define _NRF52840_PERIPHERALS_H + + +/* Floating Point Unit */ +#define FPU_PRESENT +#define FPU_COUNT 1 + +/* Systick timer */ +#define SYSTICK_PRESENT +#define SYSTICK_COUNT 1 + +/* Software Interrupts */ +#define SWI_PRESENT +#define SWI_COUNT 6 + +/* Memory Watch Unit */ +#define MWU_PRESENT +#define MWU_COUNT 1 + +/* GPIO */ +#define GPIO_PRESENT +#define GPIO_COUNT 2 + +#define P0_PIN_NUM 32 +#define P1_PIN_NUM 16 + +/* ACL */ +#define ACL_PRESENT + +#define ACL_REGIONS_COUNT 8 + +/* Radio */ +#define RADIO_PRESENT +#define RADIO_COUNT 1 + +/* Accelerated Address Resolver */ +#define AAR_PRESENT +#define AAR_COUNT 1 + +#define AAR_MAX_IRK_NUM 16 + +/* AES Electronic CodeBook mode encryption */ +#define ECB_PRESENT +#define ECB_COUNT 1 + +/* AES CCM mode encryption */ +#define CCM_PRESENT +#define CCM_COUNT 1 + +/* NFC Tag */ +#define NFCT_PRESENT +#define NFCT_COUNT 1 + +/* Peripheral to Peripheral Interconnect */ +#define PPI_PRESENT +#define PPI_COUNT 1 + +#define PPI_CH_NUM 20 +#define PPI_FIXED_CH_NUM 12 +#define PPI_GROUP_NUM 6 +#define PPI_FEATURE_FORKS_PRESENT + +/* Event Generator Unit */ +#define EGU_PRESENT +#define EGU_COUNT 6 + +#define EGU0_CH_NUM 16 +#define EGU1_CH_NUM 16 +#define EGU2_CH_NUM 16 +#define EGU3_CH_NUM 16 +#define EGU4_CH_NUM 16 +#define EGU5_CH_NUM 16 + +/* Timer/Counter */ +#define TIMER_PRESENT +#define TIMER_COUNT 5 + +#define TIMER0_MAX_SIZE 32 +#define TIMER1_MAX_SIZE 32 +#define TIMER2_MAX_SIZE 32 +#define TIMER3_MAX_SIZE 32 +#define TIMER4_MAX_SIZE 32 + +#define TIMER0_CC_NUM 4 +#define TIMER1_CC_NUM 4 +#define TIMER2_CC_NUM 4 +#define TIMER3_CC_NUM 6 +#define TIMER4_CC_NUM 6 + +/* Real Time Counter */ +#define RTC_PRESENT +#define RTC_COUNT 3 + +#define RTC0_CC_NUM 3 +#define RTC1_CC_NUM 4 +#define RTC2_CC_NUM 4 + +/* RNG */ +#define RNG_PRESENT +#define RNG_COUNT 1 + +/* Watchdog Timer */ +#define WDT_PRESENT +#define WDT_COUNT 1 + +/* Temperature Sensor */ +#define TEMP_PRESENT +#define TEMP_COUNT 1 + +/* Serial Peripheral Interface Master */ +#define SPI_PRESENT +#define SPI_COUNT 3 + +/* Serial Peripheral Interface Master with DMA */ +#define SPIM_PRESENT +#define SPIM_COUNT 4 + +#define SPIM0_MAX_DATARATE 8 +#define SPIM1_MAX_DATARATE 8 +#define SPIM2_MAX_DATARATE 8 +#define SPIM3_MAX_DATARATE 32 + +#define SPIM0_FEATURE_HARDWARE_CSN_PRESENT 0 +#define SPIM1_FEATURE_HARDWARE_CSN_PRESENT 0 +#define SPIM2_FEATURE_HARDWARE_CSN_PRESENT 0 +#define SPIM3_FEATURE_HARDWARE_CSN_PRESENT 1 + +/* Serial Peripheral Interface Slave with DMA*/ +#define SPIS_PRESENT +#define SPIS_COUNT 3 + +/* Two Wire Interface Master */ +#define TWI_PRESENT +#define TWI_COUNT 2 + +/* Two Wire Interface Master with DMA */ +#define TWIM_PRESENT +#define TWIM_COUNT 2 + +/* Two Wire Interface Slave with DMA */ +#define TWIS_PRESENT +#define TWIS_COUNT 2 + +/* Universal Asynchronous Receiver-Transmitter */ +#define UART_PRESENT +#define UART_COUNT 1 + +/* Universal Asynchronous Receiver-Transmitter with DMA */ +#define UARTE_PRESENT +#define UARTE_COUNT 2 + +/* Quadrature Decoder */ +#define QDEC_PRESENT +#define QDEC_COUNT 1 + +/* Successive Approximation Analog to Digital Converter */ +#define SAADC_PRESENT +#define SAADC_COUNT 1 + +/* GPIO Tasks and Events */ +#define GPIOTE_PRESENT +#define GPIOTE_COUNT 1 + +#define GPIOTE_CH_NUM 8 + +#define GPIOTE_FEATURE_SET_PRESENT +#define GPIOTE_FEATURE_CLR_PRESENT + +/* Low Power Comparator */ +#define LPCOMP_PRESENT +#define LPCOMP_COUNT 1 + +#define LPCOMP_REFSEL_RESOLUTION 16 + +#define LPCOMP_FEATURE_HYST_PRESENT + +/* Comparator */ +#define COMP_PRESENT +#define COMP_COUNT 1 + +/* Pulse Width Modulator */ +#define PWM_PRESENT +#define PWM_COUNT 4 + +#define PWM0_CH_NUM 4 +#define PWM1_CH_NUM 4 +#define PWM2_CH_NUM 4 +#define PWM3_CH_NUM 4 + +/* Pulse Density Modulator */ +#define PDM_PRESENT +#define PDM_COUNT 1 + +/* Inter-IC Sound Interface */ +#define I2S_PRESENT +#define I2S_COUNT 1 + +/* Universal Serial Bus Device */ +#define USBD_PRESENT +#define USBD_COUNT 1 + +/* ARM TrustZone Cryptocell 310 */ +#define CRYPTOCELL_PRESENT +#define CRYPTOCELL_COUNT 1 + +/* Quad SPI */ +#define QSPI_PRESENT +#define QSPI_COUNT 1 + +#endif // _NRF52840_PERIPHERALS_H diff --git a/bsp/nrf52832/Libraries/nrf52832/Include/nrf52_bitfields.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52_bitfields.h similarity index 88% rename from bsp/nrf52832/Libraries/nrf52832/Include/nrf52_bitfields.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52_bitfields.h index 7b1efdfc70de2f3f47df1e77683c84bee0d7f0b9..c621f6db8697c2fd780055aa6bd953251a59df14 100644 --- a/bsp/nrf52832/Libraries/nrf52832/Include/nrf52_bitfields.h +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52_bitfields.h @@ -1,32 +1,44 @@ -/* Copyright (c) 2015, Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * * 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. - * - * * Neither the name of Nordic Semiconductor ASA 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. - * - */ +/* + +Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + +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, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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 Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + +*/ + #ifndef __NRF52_BITS_H #define __NRF52_BITS_H @@ -38,21 +50,21 @@ /* Register: AAR_INTENSET */ /* Description: Enable interrupt */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_NOTRESOLVED event */ +/* Bit 2 : Write '1' to Enable interrupt for NOTRESOLVED event */ #define AAR_INTENSET_NOTRESOLVED_Pos (2UL) /*!< Position of NOTRESOLVED field. */ #define AAR_INTENSET_NOTRESOLVED_Msk (0x1UL << AAR_INTENSET_NOTRESOLVED_Pos) /*!< Bit mask of NOTRESOLVED field. */ #define AAR_INTENSET_NOTRESOLVED_Disabled (0UL) /*!< Read: Disabled */ #define AAR_INTENSET_NOTRESOLVED_Enabled (1UL) /*!< Read: Enabled */ #define AAR_INTENSET_NOTRESOLVED_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_RESOLVED event */ +/* Bit 1 : Write '1' to Enable interrupt for RESOLVED event */ #define AAR_INTENSET_RESOLVED_Pos (1UL) /*!< Position of RESOLVED field. */ #define AAR_INTENSET_RESOLVED_Msk (0x1UL << AAR_INTENSET_RESOLVED_Pos) /*!< Bit mask of RESOLVED field. */ #define AAR_INTENSET_RESOLVED_Disabled (0UL) /*!< Read: Disabled */ #define AAR_INTENSET_RESOLVED_Enabled (1UL) /*!< Read: Enabled */ #define AAR_INTENSET_RESOLVED_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_END event */ +/* Bit 0 : Write '1' to Enable interrupt for END event */ #define AAR_INTENSET_END_Pos (0UL) /*!< Position of END field. */ #define AAR_INTENSET_END_Msk (0x1UL << AAR_INTENSET_END_Pos) /*!< Bit mask of END field. */ #define AAR_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ @@ -62,21 +74,21 @@ /* Register: AAR_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_NOTRESOLVED event */ +/* Bit 2 : Write '1' to Disable interrupt for NOTRESOLVED event */ #define AAR_INTENCLR_NOTRESOLVED_Pos (2UL) /*!< Position of NOTRESOLVED field. */ #define AAR_INTENCLR_NOTRESOLVED_Msk (0x1UL << AAR_INTENCLR_NOTRESOLVED_Pos) /*!< Bit mask of NOTRESOLVED field. */ #define AAR_INTENCLR_NOTRESOLVED_Disabled (0UL) /*!< Read: Disabled */ #define AAR_INTENCLR_NOTRESOLVED_Enabled (1UL) /*!< Read: Enabled */ #define AAR_INTENCLR_NOTRESOLVED_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_RESOLVED event */ +/* Bit 1 : Write '1' to Disable interrupt for RESOLVED event */ #define AAR_INTENCLR_RESOLVED_Pos (1UL) /*!< Position of RESOLVED field. */ #define AAR_INTENCLR_RESOLVED_Msk (0x1UL << AAR_INTENCLR_RESOLVED_Pos) /*!< Bit mask of RESOLVED field. */ #define AAR_INTENCLR_RESOLVED_Disabled (0UL) /*!< Read: Disabled */ #define AAR_INTENCLR_RESOLVED_Enabled (1UL) /*!< Read: Enabled */ #define AAR_INTENCLR_RESOLVED_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_END event */ +/* Bit 0 : Write '1' to Disable interrupt for END event */ #define AAR_INTENCLR_END_Pos (0UL) /*!< Position of END field. */ #define AAR_INTENCLR_END_Msk (0x1UL << AAR_INTENCLR_END_Pos) /*!< Bit mask of END field. */ #define AAR_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ @@ -123,7 +135,7 @@ /* Register: AAR_SCRATCHPTR */ /* Description: Pointer to data area used for temporary storage */ -/* Bits 31..0 : Pointer to a "scratch" data area used for temporary storage during resolution.A space of minimum 3 bytes must be reserved. */ +/* Bits 31..0 : Pointer to a scratch data area used for temporary storage during resolution.A space of minimum 3 bytes must be reserved. */ #define AAR_SCRATCHPTR_SCRATCHPTR_Pos (0UL) /*!< Position of SCRATCHPTR field. */ #define AAR_SCRATCHPTR_SCRATCHPTR_Msk (0xFFFFFFFFUL << AAR_SCRATCHPTR_SCRATCHPTR_Pos) /*!< Bit mask of SCRATCHPTR field. */ @@ -522,9 +534,9 @@ #define BPROT_CONFIG1_REGION32_Enabled (1UL) /*!< Protection enabled */ /* Register: BPROT_DISABLEINDEBUG */ -/* Description: Disable protection mechanism in debug mode */ +/* Description: Disable protection mechanism in debug interface mode */ -/* Bit 0 : Disable the protection mechanism for NVM regions while in debug mode. This register will only disable the protection mechanism if the device is in debug mode. */ +/* Bit 0 : Disable the protection mechanism for NVM regions while in debug interface mode. This register will only disable the protection mechanism if the device is in debug interface mode. */ #define BPROT_DISABLEINDEBUG_DISABLEINDEBUG_Pos (0UL) /*!< Position of DISABLEINDEBUG field. */ #define BPROT_DISABLEINDEBUG_DISABLEINDEBUG_Msk (0x1UL << BPROT_DISABLEINDEBUG_DISABLEINDEBUG_Pos) /*!< Bit mask of DISABLEINDEBUG field. */ #define BPROT_DISABLEINDEBUG_DISABLEINDEBUG_Enabled (0UL) /*!< Enable in debug */ @@ -927,7 +939,7 @@ /* Register: CCM_SHORTS */ /* Description: Shortcut register */ -/* Bit 0 : Shortcut between EVENTS_ENDKSGEN event and TASKS_CRYPT task */ +/* Bit 0 : Shortcut between ENDKSGEN event and CRYPT task */ #define CCM_SHORTS_ENDKSGEN_CRYPT_Pos (0UL) /*!< Position of ENDKSGEN_CRYPT field. */ #define CCM_SHORTS_ENDKSGEN_CRYPT_Msk (0x1UL << CCM_SHORTS_ENDKSGEN_CRYPT_Pos) /*!< Bit mask of ENDKSGEN_CRYPT field. */ #define CCM_SHORTS_ENDKSGEN_CRYPT_Disabled (0UL) /*!< Disable shortcut */ @@ -936,21 +948,21 @@ /* Register: CCM_INTENSET */ /* Description: Enable interrupt */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_ERROR event */ +/* Bit 2 : Write '1' to Enable interrupt for ERROR event */ #define CCM_INTENSET_ERROR_Pos (2UL) /*!< Position of ERROR field. */ #define CCM_INTENSET_ERROR_Msk (0x1UL << CCM_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define CCM_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define CCM_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define CCM_INTENSET_ERROR_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_ENDCRYPT event */ +/* Bit 1 : Write '1' to Enable interrupt for ENDCRYPT event */ #define CCM_INTENSET_ENDCRYPT_Pos (1UL) /*!< Position of ENDCRYPT field. */ #define CCM_INTENSET_ENDCRYPT_Msk (0x1UL << CCM_INTENSET_ENDCRYPT_Pos) /*!< Bit mask of ENDCRYPT field. */ #define CCM_INTENSET_ENDCRYPT_Disabled (0UL) /*!< Read: Disabled */ #define CCM_INTENSET_ENDCRYPT_Enabled (1UL) /*!< Read: Enabled */ #define CCM_INTENSET_ENDCRYPT_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_ENDKSGEN event */ +/* Bit 0 : Write '1' to Enable interrupt for ENDKSGEN event */ #define CCM_INTENSET_ENDKSGEN_Pos (0UL) /*!< Position of ENDKSGEN field. */ #define CCM_INTENSET_ENDKSGEN_Msk (0x1UL << CCM_INTENSET_ENDKSGEN_Pos) /*!< Bit mask of ENDKSGEN field. */ #define CCM_INTENSET_ENDKSGEN_Disabled (0UL) /*!< Read: Disabled */ @@ -960,21 +972,21 @@ /* Register: CCM_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_ERROR event */ +/* Bit 2 : Write '1' to Disable interrupt for ERROR event */ #define CCM_INTENCLR_ERROR_Pos (2UL) /*!< Position of ERROR field. */ #define CCM_INTENCLR_ERROR_Msk (0x1UL << CCM_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define CCM_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define CCM_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define CCM_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_ENDCRYPT event */ +/* Bit 1 : Write '1' to Disable interrupt for ENDCRYPT event */ #define CCM_INTENCLR_ENDCRYPT_Pos (1UL) /*!< Position of ENDCRYPT field. */ #define CCM_INTENCLR_ENDCRYPT_Msk (0x1UL << CCM_INTENCLR_ENDCRYPT_Pos) /*!< Bit mask of ENDCRYPT field. */ #define CCM_INTENCLR_ENDCRYPT_Disabled (0UL) /*!< Read: Disabled */ #define CCM_INTENCLR_ENDCRYPT_Enabled (1UL) /*!< Read: Enabled */ #define CCM_INTENCLR_ENDCRYPT_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_ENDKSGEN event */ +/* Bit 0 : Write '1' to Disable interrupt for ENDKSGEN event */ #define CCM_INTENCLR_ENDKSGEN_Pos (0UL) /*!< Position of ENDKSGEN field. */ #define CCM_INTENCLR_ENDKSGEN_Msk (0x1UL << CCM_INTENCLR_ENDKSGEN_Pos) /*!< Bit mask of ENDKSGEN field. */ #define CCM_INTENCLR_ENDKSGEN_Disabled (0UL) /*!< Read: Disabled */ @@ -1044,7 +1056,7 @@ /* Register: CCM_SCRATCHPTR */ /* Description: Pointer to data area used for temporary storage */ -/* Bits 31..0 : Pointer to a "scratch" data area used for temporary storage during key-stream generation, MIC generation and encryption/decryption.The scratch area is used for temporary storage of data during key-stream generation and encryption. A space of minimum 43 bytes must be reserved. */ +/* Bits 31..0 : Pointer to a scratch data area used for temporary storage during key-stream generation, MIC generation and encryption/decryption. */ #define CCM_SCRATCHPTR_SCRATCHPTR_Pos (0UL) /*!< Position of SCRATCHPTR field. */ #define CCM_SCRATCHPTR_SCRATCHPTR_Msk (0xFFFFFFFFUL << CCM_SCRATCHPTR_SCRATCHPTR_Pos) /*!< Bit mask of SCRATCHPTR field. */ @@ -1055,28 +1067,28 @@ /* Register: CLOCK_INTENSET */ /* Description: Enable interrupt */ -/* Bit 4 : Write '1' to Enable interrupt on EVENTS_CTTO event */ +/* Bit 4 : Write '1' to Enable interrupt for CTTO event */ #define CLOCK_INTENSET_CTTO_Pos (4UL) /*!< Position of CTTO field. */ #define CLOCK_INTENSET_CTTO_Msk (0x1UL << CLOCK_INTENSET_CTTO_Pos) /*!< Bit mask of CTTO field. */ #define CLOCK_INTENSET_CTTO_Disabled (0UL) /*!< Read: Disabled */ #define CLOCK_INTENSET_CTTO_Enabled (1UL) /*!< Read: Enabled */ #define CLOCK_INTENSET_CTTO_Set (1UL) /*!< Enable */ -/* Bit 3 : Write '1' to Enable interrupt on EVENTS_DONE event */ +/* Bit 3 : Write '1' to Enable interrupt for DONE event */ #define CLOCK_INTENSET_DONE_Pos (3UL) /*!< Position of DONE field. */ #define CLOCK_INTENSET_DONE_Msk (0x1UL << CLOCK_INTENSET_DONE_Pos) /*!< Bit mask of DONE field. */ #define CLOCK_INTENSET_DONE_Disabled (0UL) /*!< Read: Disabled */ #define CLOCK_INTENSET_DONE_Enabled (1UL) /*!< Read: Enabled */ #define CLOCK_INTENSET_DONE_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_LFCLKSTARTED event */ +/* Bit 1 : Write '1' to Enable interrupt for LFCLKSTARTED event */ #define CLOCK_INTENSET_LFCLKSTARTED_Pos (1UL) /*!< Position of LFCLKSTARTED field. */ #define CLOCK_INTENSET_LFCLKSTARTED_Msk (0x1UL << CLOCK_INTENSET_LFCLKSTARTED_Pos) /*!< Bit mask of LFCLKSTARTED field. */ #define CLOCK_INTENSET_LFCLKSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define CLOCK_INTENSET_LFCLKSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define CLOCK_INTENSET_LFCLKSTARTED_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_HFCLKSTARTED event */ +/* Bit 0 : Write '1' to Enable interrupt for HFCLKSTARTED event */ #define CLOCK_INTENSET_HFCLKSTARTED_Pos (0UL) /*!< Position of HFCLKSTARTED field. */ #define CLOCK_INTENSET_HFCLKSTARTED_Msk (0x1UL << CLOCK_INTENSET_HFCLKSTARTED_Pos) /*!< Bit mask of HFCLKSTARTED field. */ #define CLOCK_INTENSET_HFCLKSTARTED_Disabled (0UL) /*!< Read: Disabled */ @@ -1086,28 +1098,28 @@ /* Register: CLOCK_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 4 : Write '1' to Clear interrupt on EVENTS_CTTO event */ +/* Bit 4 : Write '1' to Disable interrupt for CTTO event */ #define CLOCK_INTENCLR_CTTO_Pos (4UL) /*!< Position of CTTO field. */ #define CLOCK_INTENCLR_CTTO_Msk (0x1UL << CLOCK_INTENCLR_CTTO_Pos) /*!< Bit mask of CTTO field. */ #define CLOCK_INTENCLR_CTTO_Disabled (0UL) /*!< Read: Disabled */ #define CLOCK_INTENCLR_CTTO_Enabled (1UL) /*!< Read: Enabled */ #define CLOCK_INTENCLR_CTTO_Clear (1UL) /*!< Disable */ -/* Bit 3 : Write '1' to Clear interrupt on EVENTS_DONE event */ +/* Bit 3 : Write '1' to Disable interrupt for DONE event */ #define CLOCK_INTENCLR_DONE_Pos (3UL) /*!< Position of DONE field. */ #define CLOCK_INTENCLR_DONE_Msk (0x1UL << CLOCK_INTENCLR_DONE_Pos) /*!< Bit mask of DONE field. */ #define CLOCK_INTENCLR_DONE_Disabled (0UL) /*!< Read: Disabled */ #define CLOCK_INTENCLR_DONE_Enabled (1UL) /*!< Read: Enabled */ #define CLOCK_INTENCLR_DONE_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_LFCLKSTARTED event */ +/* Bit 1 : Write '1' to Disable interrupt for LFCLKSTARTED event */ #define CLOCK_INTENCLR_LFCLKSTARTED_Pos (1UL) /*!< Position of LFCLKSTARTED field. */ #define CLOCK_INTENCLR_LFCLKSTARTED_Msk (0x1UL << CLOCK_INTENCLR_LFCLKSTARTED_Pos) /*!< Bit mask of LFCLKSTARTED field. */ #define CLOCK_INTENCLR_LFCLKSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define CLOCK_INTENCLR_LFCLKSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define CLOCK_INTENCLR_LFCLKSTARTED_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_HFCLKSTARTED event */ +/* Bit 0 : Write '1' to Disable interrupt for HFCLKSTARTED event */ #define CLOCK_INTENCLR_HFCLKSTARTED_Pos (0UL) /*!< Position of HFCLKSTARTED field. */ #define CLOCK_INTENCLR_HFCLKSTARTED_Msk (0x1UL << CLOCK_INTENCLR_HFCLKSTARTED_Pos) /*!< Bit mask of HFCLKSTARTED field. */ #define CLOCK_INTENCLR_HFCLKSTARTED_Disabled (0UL) /*!< Read: Disabled */ @@ -1124,7 +1136,7 @@ #define CLOCK_HFCLKRUN_STATUS_Triggered (1UL) /*!< Task triggered */ /* Register: CLOCK_HFCLKSTAT */ -/* Description: Which HFCLK source is running */ +/* Description: HFCLK status */ /* Bit 16 : HFCLK state */ #define CLOCK_HFCLKSTAT_STATE_Pos (16UL) /*!< Position of STATE field. */ @@ -1132,11 +1144,11 @@ #define CLOCK_HFCLKSTAT_STATE_NotRunning (0UL) /*!< HFCLK not running */ #define CLOCK_HFCLKSTAT_STATE_Running (1UL) /*!< HFCLK running */ -/* Bit 0 : Active clock source */ +/* Bit 0 : Source of HFCLK */ #define CLOCK_HFCLKSTAT_SRC_Pos (0UL) /*!< Position of SRC field. */ #define CLOCK_HFCLKSTAT_SRC_Msk (0x1UL << CLOCK_HFCLKSTAT_SRC_Pos) /*!< Bit mask of SRC field. */ -#define CLOCK_HFCLKSTAT_SRC_RC (0UL) /*!< Internal oscillator (HFINT) */ -#define CLOCK_HFCLKSTAT_SRC_Xtal (1UL) /*!< 32 MHz crystal oscillator (HFXO) */ +#define CLOCK_HFCLKSTAT_SRC_RC (0UL) /*!< 64 MHz internal oscillator (HFINT) */ +#define CLOCK_HFCLKSTAT_SRC_Xtal (1UL) /*!< 64 MHz crystal oscillator (HFXO) */ /* Register: CLOCK_LFCLKRUN */ /* Description: Status indicating that LFCLKSTART task has been triggered */ @@ -1148,7 +1160,7 @@ #define CLOCK_LFCLKRUN_STATUS_Triggered (1UL) /*!< Task triggered */ /* Register: CLOCK_LFCLKSTAT */ -/* Description: Which LFCLK source is running */ +/* Description: LFCLK status */ /* Bit 16 : LFCLK state */ #define CLOCK_LFCLKSTAT_STATE_Pos (16UL) /*!< Position of STATE field. */ @@ -1156,7 +1168,7 @@ #define CLOCK_LFCLKSTAT_STATE_NotRunning (0UL) /*!< LFCLK not running */ #define CLOCK_LFCLKSTAT_STATE_Running (1UL) /*!< LFCLK running */ -/* Bits 1..0 : Active clock source */ +/* Bits 1..0 : Source of LFCLK */ #define CLOCK_LFCLKSTAT_SRC_Pos (0UL) /*!< Position of SRC field. */ #define CLOCK_LFCLKSTAT_SRC_Msk (0x3UL << CLOCK_LFCLKSTAT_SRC_Pos) /*!< Bit mask of SRC field. */ #define CLOCK_LFCLKSTAT_SRC_RC (0UL) /*!< 32.768 kHz RC oscillator */ @@ -1176,6 +1188,18 @@ /* Register: CLOCK_LFCLKSRC */ /* Description: Clock source for the LFCLK */ +/* Bit 17 : Enable or disable external source for LFCLK */ +#define CLOCK_LFCLKSRC_EXTERNAL_Pos (17UL) /*!< Position of EXTERNAL field. */ +#define CLOCK_LFCLKSRC_EXTERNAL_Msk (0x1UL << CLOCK_LFCLKSRC_EXTERNAL_Pos) /*!< Bit mask of EXTERNAL field. */ +#define CLOCK_LFCLKSRC_EXTERNAL_Disabled (0UL) /*!< Disable external source (use with Xtal) */ +#define CLOCK_LFCLKSRC_EXTERNAL_Enabled (1UL) /*!< Enable use of external source instead of Xtal (SRC needs to be set to Xtal) */ + +/* Bit 16 : Enable or disable bypass of LFCLK crystal oscillator with external clock source */ +#define CLOCK_LFCLKSRC_BYPASS_Pos (16UL) /*!< Position of BYPASS field. */ +#define CLOCK_LFCLKSRC_BYPASS_Msk (0x1UL << CLOCK_LFCLKSRC_BYPASS_Pos) /*!< Bit mask of BYPASS field. */ +#define CLOCK_LFCLKSRC_BYPASS_Disabled (0UL) /*!< Disable (use with Xtal or low-swing external source) */ +#define CLOCK_LFCLKSRC_BYPASS_Enabled (1UL) /*!< Enable (use with rail-to-rail external source) */ + /* Bits 1..0 : Clock source */ #define CLOCK_LFCLKSRC_SRC_Pos (0UL) /*!< Position of SRC field. */ #define CLOCK_LFCLKSRC_SRC_Msk (0x3UL << CLOCK_LFCLKSRC_SRC_Pos) /*!< Bit mask of SRC field. */ @@ -1184,7 +1208,7 @@ #define CLOCK_LFCLKSRC_SRC_Synth (2UL) /*!< 32.768 kHz synthesized from HFCLK */ /* Register: CLOCK_CTIV */ -/* Description: Calibration timer interval (retained register, same reset behaviour as RESETREAS) */ +/* Description: Calibration timer interval */ /* Bits 6..0 : Calibration timer interval in multiple of 0.25 seconds. Range: 0.25 seconds to 31.75 seconds. */ #define CLOCK_CTIV_CTIV_Pos (0UL) /*!< Position of CTIV field. */ @@ -1215,31 +1239,31 @@ /* Register: COMP_SHORTS */ /* Description: Shortcut register */ -/* Bit 4 : Shortcut between EVENTS_CROSS event and TASKS_STOP task */ +/* Bit 4 : Shortcut between CROSS event and STOP task */ #define COMP_SHORTS_CROSS_STOP_Pos (4UL) /*!< Position of CROSS_STOP field. */ #define COMP_SHORTS_CROSS_STOP_Msk (0x1UL << COMP_SHORTS_CROSS_STOP_Pos) /*!< Bit mask of CROSS_STOP field. */ #define COMP_SHORTS_CROSS_STOP_Disabled (0UL) /*!< Disable shortcut */ #define COMP_SHORTS_CROSS_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 3 : Shortcut between EVENTS_UP event and TASKS_STOP task */ +/* Bit 3 : Shortcut between UP event and STOP task */ #define COMP_SHORTS_UP_STOP_Pos (3UL) /*!< Position of UP_STOP field. */ #define COMP_SHORTS_UP_STOP_Msk (0x1UL << COMP_SHORTS_UP_STOP_Pos) /*!< Bit mask of UP_STOP field. */ #define COMP_SHORTS_UP_STOP_Disabled (0UL) /*!< Disable shortcut */ #define COMP_SHORTS_UP_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 2 : Shortcut between EVENTS_DOWN event and TASKS_STOP task */ +/* Bit 2 : Shortcut between DOWN event and STOP task */ #define COMP_SHORTS_DOWN_STOP_Pos (2UL) /*!< Position of DOWN_STOP field. */ #define COMP_SHORTS_DOWN_STOP_Msk (0x1UL << COMP_SHORTS_DOWN_STOP_Pos) /*!< Bit mask of DOWN_STOP field. */ #define COMP_SHORTS_DOWN_STOP_Disabled (0UL) /*!< Disable shortcut */ #define COMP_SHORTS_DOWN_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 1 : Shortcut between EVENTS_READY event and TASKS_STOP task */ +/* Bit 1 : Shortcut between READY event and STOP task */ #define COMP_SHORTS_READY_STOP_Pos (1UL) /*!< Position of READY_STOP field. */ #define COMP_SHORTS_READY_STOP_Msk (0x1UL << COMP_SHORTS_READY_STOP_Pos) /*!< Bit mask of READY_STOP field. */ #define COMP_SHORTS_READY_STOP_Disabled (0UL) /*!< Disable shortcut */ #define COMP_SHORTS_READY_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 0 : Shortcut between EVENTS_READY event and TASKS_SAMPLE task */ +/* Bit 0 : Shortcut between READY event and SAMPLE task */ #define COMP_SHORTS_READY_SAMPLE_Pos (0UL) /*!< Position of READY_SAMPLE field. */ #define COMP_SHORTS_READY_SAMPLE_Msk (0x1UL << COMP_SHORTS_READY_SAMPLE_Pos) /*!< Bit mask of READY_SAMPLE field. */ #define COMP_SHORTS_READY_SAMPLE_Disabled (0UL) /*!< Disable shortcut */ @@ -1248,25 +1272,25 @@ /* Register: COMP_INTEN */ /* Description: Enable or disable interrupt */ -/* Bit 3 : Enable or disable interrupt on EVENTS_CROSS event */ +/* Bit 3 : Enable or disable interrupt for CROSS event */ #define COMP_INTEN_CROSS_Pos (3UL) /*!< Position of CROSS field. */ #define COMP_INTEN_CROSS_Msk (0x1UL << COMP_INTEN_CROSS_Pos) /*!< Bit mask of CROSS field. */ #define COMP_INTEN_CROSS_Disabled (0UL) /*!< Disable */ #define COMP_INTEN_CROSS_Enabled (1UL) /*!< Enable */ -/* Bit 2 : Enable or disable interrupt on EVENTS_UP event */ +/* Bit 2 : Enable or disable interrupt for UP event */ #define COMP_INTEN_UP_Pos (2UL) /*!< Position of UP field. */ #define COMP_INTEN_UP_Msk (0x1UL << COMP_INTEN_UP_Pos) /*!< Bit mask of UP field. */ #define COMP_INTEN_UP_Disabled (0UL) /*!< Disable */ #define COMP_INTEN_UP_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable interrupt on EVENTS_DOWN event */ +/* Bit 1 : Enable or disable interrupt for DOWN event */ #define COMP_INTEN_DOWN_Pos (1UL) /*!< Position of DOWN field. */ #define COMP_INTEN_DOWN_Msk (0x1UL << COMP_INTEN_DOWN_Pos) /*!< Bit mask of DOWN field. */ #define COMP_INTEN_DOWN_Disabled (0UL) /*!< Disable */ #define COMP_INTEN_DOWN_Enabled (1UL) /*!< Enable */ -/* Bit 0 : Enable or disable interrupt on EVENTS_READY event */ +/* Bit 0 : Enable or disable interrupt for READY event */ #define COMP_INTEN_READY_Pos (0UL) /*!< Position of READY field. */ #define COMP_INTEN_READY_Msk (0x1UL << COMP_INTEN_READY_Pos) /*!< Bit mask of READY field. */ #define COMP_INTEN_READY_Disabled (0UL) /*!< Disable */ @@ -1275,28 +1299,28 @@ /* Register: COMP_INTENSET */ /* Description: Enable interrupt */ -/* Bit 3 : Write '1' to Enable interrupt on EVENTS_CROSS event */ +/* Bit 3 : Write '1' to Enable interrupt for CROSS event */ #define COMP_INTENSET_CROSS_Pos (3UL) /*!< Position of CROSS field. */ #define COMP_INTENSET_CROSS_Msk (0x1UL << COMP_INTENSET_CROSS_Pos) /*!< Bit mask of CROSS field. */ #define COMP_INTENSET_CROSS_Disabled (0UL) /*!< Read: Disabled */ #define COMP_INTENSET_CROSS_Enabled (1UL) /*!< Read: Enabled */ #define COMP_INTENSET_CROSS_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_UP event */ +/* Bit 2 : Write '1' to Enable interrupt for UP event */ #define COMP_INTENSET_UP_Pos (2UL) /*!< Position of UP field. */ #define COMP_INTENSET_UP_Msk (0x1UL << COMP_INTENSET_UP_Pos) /*!< Bit mask of UP field. */ #define COMP_INTENSET_UP_Disabled (0UL) /*!< Read: Disabled */ #define COMP_INTENSET_UP_Enabled (1UL) /*!< Read: Enabled */ #define COMP_INTENSET_UP_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_DOWN event */ +/* Bit 1 : Write '1' to Enable interrupt for DOWN event */ #define COMP_INTENSET_DOWN_Pos (1UL) /*!< Position of DOWN field. */ #define COMP_INTENSET_DOWN_Msk (0x1UL << COMP_INTENSET_DOWN_Pos) /*!< Bit mask of DOWN field. */ #define COMP_INTENSET_DOWN_Disabled (0UL) /*!< Read: Disabled */ #define COMP_INTENSET_DOWN_Enabled (1UL) /*!< Read: Enabled */ #define COMP_INTENSET_DOWN_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_READY event */ +/* Bit 0 : Write '1' to Enable interrupt for READY event */ #define COMP_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */ #define COMP_INTENSET_READY_Msk (0x1UL << COMP_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ #define COMP_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ @@ -1306,28 +1330,28 @@ /* Register: COMP_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 3 : Write '1' to Clear interrupt on EVENTS_CROSS event */ +/* Bit 3 : Write '1' to Disable interrupt for CROSS event */ #define COMP_INTENCLR_CROSS_Pos (3UL) /*!< Position of CROSS field. */ #define COMP_INTENCLR_CROSS_Msk (0x1UL << COMP_INTENCLR_CROSS_Pos) /*!< Bit mask of CROSS field. */ #define COMP_INTENCLR_CROSS_Disabled (0UL) /*!< Read: Disabled */ #define COMP_INTENCLR_CROSS_Enabled (1UL) /*!< Read: Enabled */ #define COMP_INTENCLR_CROSS_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_UP event */ +/* Bit 2 : Write '1' to Disable interrupt for UP event */ #define COMP_INTENCLR_UP_Pos (2UL) /*!< Position of UP field. */ #define COMP_INTENCLR_UP_Msk (0x1UL << COMP_INTENCLR_UP_Pos) /*!< Bit mask of UP field. */ #define COMP_INTENCLR_UP_Disabled (0UL) /*!< Read: Disabled */ #define COMP_INTENCLR_UP_Enabled (1UL) /*!< Read: Enabled */ #define COMP_INTENCLR_UP_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_DOWN event */ +/* Bit 1 : Write '1' to Disable interrupt for DOWN event */ #define COMP_INTENCLR_DOWN_Pos (1UL) /*!< Position of DOWN field. */ #define COMP_INTENCLR_DOWN_Msk (0x1UL << COMP_INTENCLR_DOWN_Pos) /*!< Bit mask of DOWN field. */ #define COMP_INTENCLR_DOWN_Disabled (0UL) /*!< Read: Disabled */ #define COMP_INTENCLR_DOWN_Enabled (1UL) /*!< Read: Enabled */ #define COMP_INTENCLR_DOWN_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_READY event */ +/* Bit 0 : Write '1' to Disable interrupt for READY event */ #define COMP_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */ #define COMP_INTENCLR_READY_Msk (0x1UL << COMP_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ #define COMP_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ @@ -1340,8 +1364,8 @@ /* Bit 0 : Result of last compare. Decision point SAMPLE task. */ #define COMP_RESULT_RESULT_Pos (0UL) /*!< Position of RESULT field. */ #define COMP_RESULT_RESULT_Msk (0x1UL << COMP_RESULT_RESULT_Pos) /*!< Bit mask of RESULT field. */ -#define COMP_RESULT_RESULT_Below (0UL) /*!< Input voltage is below the threshold (VIN+ < VIN-) */ -#define COMP_RESULT_RESULT_Above (1UL) /*!< Input voltage is above the threshold (VIN+ > VIN-) */ +#define COMP_RESULT_RESULT_Below (0UL) /*!< Input voltage is below the threshold (VIN+ < VIN-) */ +#define COMP_RESULT_RESULT_Above (1UL) /*!< Input voltage is above the threshold (VIN+ > VIN-) */ /* Register: COMP_ENABLE */ /* Description: COMP enable */ @@ -1373,11 +1397,11 @@ /* Bits 2..0 : Reference select */ #define COMP_REFSEL_REFSEL_Pos (0UL) /*!< Position of REFSEL field. */ #define COMP_REFSEL_REFSEL_Msk (0x7UL << COMP_REFSEL_REFSEL_Pos) /*!< Bit mask of REFSEL field. */ -#define COMP_REFSEL_REFSEL_Int1V2 (0UL) /*!< VREF = internal 1.2 V reference (VDD >= 1.7 V) */ -#define COMP_REFSEL_REFSEL_Int1V8 (1UL) /*!< VREF = internal 1.8 V reference (VDD >= VREF + 0.2 V) */ -#define COMP_REFSEL_REFSEL_Int2V4 (2UL) /*!< VREF = internal 2.4 V reference (VDD >= VREF + 0.2 V) */ +#define COMP_REFSEL_REFSEL_Int1V2 (0UL) /*!< VREF = internal 1.2 V reference (VDD >= 1.7 V) */ +#define COMP_REFSEL_REFSEL_Int1V8 (1UL) /*!< VREF = internal 1.8 V reference (VDD >= VREF + 0.2 V) */ +#define COMP_REFSEL_REFSEL_Int2V4 (2UL) /*!< VREF = internal 2.4 V reference (VDD >= VREF + 0.2 V) */ #define COMP_REFSEL_REFSEL_VDD (4UL) /*!< VREF = VDD */ -#define COMP_REFSEL_REFSEL_ARef (5UL) /*!< VREF = AREF (VDD >= VREF >= AREFMIN) */ +#define COMP_REFSEL_REFSEL_ARef (7UL) /*!< VREF = AREF (VDD >= VREF >= AREFMIN) */ /* Register: COMP_EXTREFSEL */ /* Description: External reference select */ @@ -1391,14 +1415,14 @@ /* Register: COMP_TH */ /* Description: Threshold configuration for hysteresis unit */ -/* Bits 13..8 : VDOWN = (THDOWN+1)/64*VREF */ -#define COMP_TH_THDOWN_Pos (8UL) /*!< Position of THDOWN field. */ -#define COMP_TH_THDOWN_Msk (0x3FUL << COMP_TH_THDOWN_Pos) /*!< Bit mask of THDOWN field. */ - -/* Bits 5..0 : VUP = (THUP+1)/64*VREF */ -#define COMP_TH_THUP_Pos (0UL) /*!< Position of THUP field. */ +/* Bits 13..8 : VUP = (THUP+1)/64*VREF */ +#define COMP_TH_THUP_Pos (8UL) /*!< Position of THUP field. */ #define COMP_TH_THUP_Msk (0x3FUL << COMP_TH_THUP_Pos) /*!< Bit mask of THUP field. */ +/* Bits 5..0 : VDOWN = (THDOWN+1)/64*VREF */ +#define COMP_TH_THDOWN_Pos (0UL) /*!< Position of THDOWN field. */ +#define COMP_TH_THDOWN_Msk (0x3FUL << COMP_TH_THDOWN_Pos) /*!< Bit mask of THDOWN field. */ + /* Register: COMP_MODE */ /* Description: Mode configuration */ @@ -1442,14 +1466,14 @@ /* Register: ECB_INTENSET */ /* Description: Enable interrupt */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_ERRORECB event */ +/* Bit 1 : Write '1' to Enable interrupt for ERRORECB event */ #define ECB_INTENSET_ERRORECB_Pos (1UL) /*!< Position of ERRORECB field. */ #define ECB_INTENSET_ERRORECB_Msk (0x1UL << ECB_INTENSET_ERRORECB_Pos) /*!< Bit mask of ERRORECB field. */ #define ECB_INTENSET_ERRORECB_Disabled (0UL) /*!< Read: Disabled */ #define ECB_INTENSET_ERRORECB_Enabled (1UL) /*!< Read: Enabled */ #define ECB_INTENSET_ERRORECB_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_ENDECB event */ +/* Bit 0 : Write '1' to Enable interrupt for ENDECB event */ #define ECB_INTENSET_ENDECB_Pos (0UL) /*!< Position of ENDECB field. */ #define ECB_INTENSET_ENDECB_Msk (0x1UL << ECB_INTENSET_ENDECB_Pos) /*!< Bit mask of ENDECB field. */ #define ECB_INTENSET_ENDECB_Disabled (0UL) /*!< Read: Disabled */ @@ -1459,14 +1483,14 @@ /* Register: ECB_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_ERRORECB event */ +/* Bit 1 : Write '1' to Disable interrupt for ERRORECB event */ #define ECB_INTENCLR_ERRORECB_Pos (1UL) /*!< Position of ERRORECB field. */ #define ECB_INTENCLR_ERRORECB_Msk (0x1UL << ECB_INTENCLR_ERRORECB_Pos) /*!< Bit mask of ERRORECB field. */ #define ECB_INTENCLR_ERRORECB_Disabled (0UL) /*!< Read: Disabled */ #define ECB_INTENCLR_ERRORECB_Enabled (1UL) /*!< Read: Enabled */ #define ECB_INTENCLR_ERRORECB_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_ENDECB event */ +/* Bit 0 : Write '1' to Disable interrupt for ENDECB event */ #define ECB_INTENCLR_ENDECB_Pos (0UL) /*!< Position of ENDECB field. */ #define ECB_INTENCLR_ENDECB_Msk (0x1UL << ECB_INTENCLR_ENDECB_Pos) /*!< Bit mask of ENDECB field. */ #define ECB_INTENCLR_ENDECB_Disabled (0UL) /*!< Read: Disabled */ @@ -1487,97 +1511,97 @@ /* Register: EGU_INTEN */ /* Description: Enable or disable interrupt */ -/* Bit 15 : Enable or disable interrupt on EVENTS_TRIGGERED[15] event */ +/* Bit 15 : Enable or disable interrupt for TRIGGERED[15] event */ #define EGU_INTEN_TRIGGERED15_Pos (15UL) /*!< Position of TRIGGERED15 field. */ #define EGU_INTEN_TRIGGERED15_Msk (0x1UL << EGU_INTEN_TRIGGERED15_Pos) /*!< Bit mask of TRIGGERED15 field. */ #define EGU_INTEN_TRIGGERED15_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED15_Enabled (1UL) /*!< Enable */ -/* Bit 14 : Enable or disable interrupt on EVENTS_TRIGGERED[14] event */ +/* Bit 14 : Enable or disable interrupt for TRIGGERED[14] event */ #define EGU_INTEN_TRIGGERED14_Pos (14UL) /*!< Position of TRIGGERED14 field. */ #define EGU_INTEN_TRIGGERED14_Msk (0x1UL << EGU_INTEN_TRIGGERED14_Pos) /*!< Bit mask of TRIGGERED14 field. */ #define EGU_INTEN_TRIGGERED14_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED14_Enabled (1UL) /*!< Enable */ -/* Bit 13 : Enable or disable interrupt on EVENTS_TRIGGERED[13] event */ +/* Bit 13 : Enable or disable interrupt for TRIGGERED[13] event */ #define EGU_INTEN_TRIGGERED13_Pos (13UL) /*!< Position of TRIGGERED13 field. */ #define EGU_INTEN_TRIGGERED13_Msk (0x1UL << EGU_INTEN_TRIGGERED13_Pos) /*!< Bit mask of TRIGGERED13 field. */ #define EGU_INTEN_TRIGGERED13_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED13_Enabled (1UL) /*!< Enable */ -/* Bit 12 : Enable or disable interrupt on EVENTS_TRIGGERED[12] event */ +/* Bit 12 : Enable or disable interrupt for TRIGGERED[12] event */ #define EGU_INTEN_TRIGGERED12_Pos (12UL) /*!< Position of TRIGGERED12 field. */ #define EGU_INTEN_TRIGGERED12_Msk (0x1UL << EGU_INTEN_TRIGGERED12_Pos) /*!< Bit mask of TRIGGERED12 field. */ #define EGU_INTEN_TRIGGERED12_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED12_Enabled (1UL) /*!< Enable */ -/* Bit 11 : Enable or disable interrupt on EVENTS_TRIGGERED[11] event */ +/* Bit 11 : Enable or disable interrupt for TRIGGERED[11] event */ #define EGU_INTEN_TRIGGERED11_Pos (11UL) /*!< Position of TRIGGERED11 field. */ #define EGU_INTEN_TRIGGERED11_Msk (0x1UL << EGU_INTEN_TRIGGERED11_Pos) /*!< Bit mask of TRIGGERED11 field. */ #define EGU_INTEN_TRIGGERED11_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED11_Enabled (1UL) /*!< Enable */ -/* Bit 10 : Enable or disable interrupt on EVENTS_TRIGGERED[10] event */ +/* Bit 10 : Enable or disable interrupt for TRIGGERED[10] event */ #define EGU_INTEN_TRIGGERED10_Pos (10UL) /*!< Position of TRIGGERED10 field. */ #define EGU_INTEN_TRIGGERED10_Msk (0x1UL << EGU_INTEN_TRIGGERED10_Pos) /*!< Bit mask of TRIGGERED10 field. */ #define EGU_INTEN_TRIGGERED10_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED10_Enabled (1UL) /*!< Enable */ -/* Bit 9 : Enable or disable interrupt on EVENTS_TRIGGERED[9] event */ +/* Bit 9 : Enable or disable interrupt for TRIGGERED[9] event */ #define EGU_INTEN_TRIGGERED9_Pos (9UL) /*!< Position of TRIGGERED9 field. */ #define EGU_INTEN_TRIGGERED9_Msk (0x1UL << EGU_INTEN_TRIGGERED9_Pos) /*!< Bit mask of TRIGGERED9 field. */ #define EGU_INTEN_TRIGGERED9_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED9_Enabled (1UL) /*!< Enable */ -/* Bit 8 : Enable or disable interrupt on EVENTS_TRIGGERED[8] event */ +/* Bit 8 : Enable or disable interrupt for TRIGGERED[8] event */ #define EGU_INTEN_TRIGGERED8_Pos (8UL) /*!< Position of TRIGGERED8 field. */ #define EGU_INTEN_TRIGGERED8_Msk (0x1UL << EGU_INTEN_TRIGGERED8_Pos) /*!< Bit mask of TRIGGERED8 field. */ #define EGU_INTEN_TRIGGERED8_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED8_Enabled (1UL) /*!< Enable */ -/* Bit 7 : Enable or disable interrupt on EVENTS_TRIGGERED[7] event */ +/* Bit 7 : Enable or disable interrupt for TRIGGERED[7] event */ #define EGU_INTEN_TRIGGERED7_Pos (7UL) /*!< Position of TRIGGERED7 field. */ #define EGU_INTEN_TRIGGERED7_Msk (0x1UL << EGU_INTEN_TRIGGERED7_Pos) /*!< Bit mask of TRIGGERED7 field. */ #define EGU_INTEN_TRIGGERED7_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED7_Enabled (1UL) /*!< Enable */ -/* Bit 6 : Enable or disable interrupt on EVENTS_TRIGGERED[6] event */ +/* Bit 6 : Enable or disable interrupt for TRIGGERED[6] event */ #define EGU_INTEN_TRIGGERED6_Pos (6UL) /*!< Position of TRIGGERED6 field. */ #define EGU_INTEN_TRIGGERED6_Msk (0x1UL << EGU_INTEN_TRIGGERED6_Pos) /*!< Bit mask of TRIGGERED6 field. */ #define EGU_INTEN_TRIGGERED6_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED6_Enabled (1UL) /*!< Enable */ -/* Bit 5 : Enable or disable interrupt on EVENTS_TRIGGERED[5] event */ +/* Bit 5 : Enable or disable interrupt for TRIGGERED[5] event */ #define EGU_INTEN_TRIGGERED5_Pos (5UL) /*!< Position of TRIGGERED5 field. */ #define EGU_INTEN_TRIGGERED5_Msk (0x1UL << EGU_INTEN_TRIGGERED5_Pos) /*!< Bit mask of TRIGGERED5 field. */ #define EGU_INTEN_TRIGGERED5_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED5_Enabled (1UL) /*!< Enable */ -/* Bit 4 : Enable or disable interrupt on EVENTS_TRIGGERED[4] event */ +/* Bit 4 : Enable or disable interrupt for TRIGGERED[4] event */ #define EGU_INTEN_TRIGGERED4_Pos (4UL) /*!< Position of TRIGGERED4 field. */ #define EGU_INTEN_TRIGGERED4_Msk (0x1UL << EGU_INTEN_TRIGGERED4_Pos) /*!< Bit mask of TRIGGERED4 field. */ #define EGU_INTEN_TRIGGERED4_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED4_Enabled (1UL) /*!< Enable */ -/* Bit 3 : Enable or disable interrupt on EVENTS_TRIGGERED[3] event */ +/* Bit 3 : Enable or disable interrupt for TRIGGERED[3] event */ #define EGU_INTEN_TRIGGERED3_Pos (3UL) /*!< Position of TRIGGERED3 field. */ #define EGU_INTEN_TRIGGERED3_Msk (0x1UL << EGU_INTEN_TRIGGERED3_Pos) /*!< Bit mask of TRIGGERED3 field. */ #define EGU_INTEN_TRIGGERED3_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED3_Enabled (1UL) /*!< Enable */ -/* Bit 2 : Enable or disable interrupt on EVENTS_TRIGGERED[2] event */ +/* Bit 2 : Enable or disable interrupt for TRIGGERED[2] event */ #define EGU_INTEN_TRIGGERED2_Pos (2UL) /*!< Position of TRIGGERED2 field. */ #define EGU_INTEN_TRIGGERED2_Msk (0x1UL << EGU_INTEN_TRIGGERED2_Pos) /*!< Bit mask of TRIGGERED2 field. */ #define EGU_INTEN_TRIGGERED2_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED2_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable interrupt on EVENTS_TRIGGERED[1] event */ +/* Bit 1 : Enable or disable interrupt for TRIGGERED[1] event */ #define EGU_INTEN_TRIGGERED1_Pos (1UL) /*!< Position of TRIGGERED1 field. */ #define EGU_INTEN_TRIGGERED1_Msk (0x1UL << EGU_INTEN_TRIGGERED1_Pos) /*!< Bit mask of TRIGGERED1 field. */ #define EGU_INTEN_TRIGGERED1_Disabled (0UL) /*!< Disable */ #define EGU_INTEN_TRIGGERED1_Enabled (1UL) /*!< Enable */ -/* Bit 0 : Enable or disable interrupt on EVENTS_TRIGGERED[0] event */ +/* Bit 0 : Enable or disable interrupt for TRIGGERED[0] event */ #define EGU_INTEN_TRIGGERED0_Pos (0UL) /*!< Position of TRIGGERED0 field. */ #define EGU_INTEN_TRIGGERED0_Msk (0x1UL << EGU_INTEN_TRIGGERED0_Pos) /*!< Bit mask of TRIGGERED0 field. */ #define EGU_INTEN_TRIGGERED0_Disabled (0UL) /*!< Disable */ @@ -1586,112 +1610,112 @@ /* Register: EGU_INTENSET */ /* Description: Enable interrupt */ -/* Bit 15 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[15] event */ +/* Bit 15 : Write '1' to Enable interrupt for TRIGGERED[15] event */ #define EGU_INTENSET_TRIGGERED15_Pos (15UL) /*!< Position of TRIGGERED15 field. */ #define EGU_INTENSET_TRIGGERED15_Msk (0x1UL << EGU_INTENSET_TRIGGERED15_Pos) /*!< Bit mask of TRIGGERED15 field. */ #define EGU_INTENSET_TRIGGERED15_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED15_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED15_Set (1UL) /*!< Enable */ -/* Bit 14 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[14] event */ +/* Bit 14 : Write '1' to Enable interrupt for TRIGGERED[14] event */ #define EGU_INTENSET_TRIGGERED14_Pos (14UL) /*!< Position of TRIGGERED14 field. */ #define EGU_INTENSET_TRIGGERED14_Msk (0x1UL << EGU_INTENSET_TRIGGERED14_Pos) /*!< Bit mask of TRIGGERED14 field. */ #define EGU_INTENSET_TRIGGERED14_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED14_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED14_Set (1UL) /*!< Enable */ -/* Bit 13 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[13] event */ +/* Bit 13 : Write '1' to Enable interrupt for TRIGGERED[13] event */ #define EGU_INTENSET_TRIGGERED13_Pos (13UL) /*!< Position of TRIGGERED13 field. */ #define EGU_INTENSET_TRIGGERED13_Msk (0x1UL << EGU_INTENSET_TRIGGERED13_Pos) /*!< Bit mask of TRIGGERED13 field. */ #define EGU_INTENSET_TRIGGERED13_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED13_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED13_Set (1UL) /*!< Enable */ -/* Bit 12 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[12] event */ +/* Bit 12 : Write '1' to Enable interrupt for TRIGGERED[12] event */ #define EGU_INTENSET_TRIGGERED12_Pos (12UL) /*!< Position of TRIGGERED12 field. */ #define EGU_INTENSET_TRIGGERED12_Msk (0x1UL << EGU_INTENSET_TRIGGERED12_Pos) /*!< Bit mask of TRIGGERED12 field. */ #define EGU_INTENSET_TRIGGERED12_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED12_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED12_Set (1UL) /*!< Enable */ -/* Bit 11 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[11] event */ +/* Bit 11 : Write '1' to Enable interrupt for TRIGGERED[11] event */ #define EGU_INTENSET_TRIGGERED11_Pos (11UL) /*!< Position of TRIGGERED11 field. */ #define EGU_INTENSET_TRIGGERED11_Msk (0x1UL << EGU_INTENSET_TRIGGERED11_Pos) /*!< Bit mask of TRIGGERED11 field. */ #define EGU_INTENSET_TRIGGERED11_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED11_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED11_Set (1UL) /*!< Enable */ -/* Bit 10 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[10] event */ +/* Bit 10 : Write '1' to Enable interrupt for TRIGGERED[10] event */ #define EGU_INTENSET_TRIGGERED10_Pos (10UL) /*!< Position of TRIGGERED10 field. */ #define EGU_INTENSET_TRIGGERED10_Msk (0x1UL << EGU_INTENSET_TRIGGERED10_Pos) /*!< Bit mask of TRIGGERED10 field. */ #define EGU_INTENSET_TRIGGERED10_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED10_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED10_Set (1UL) /*!< Enable */ -/* Bit 9 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[9] event */ +/* Bit 9 : Write '1' to Enable interrupt for TRIGGERED[9] event */ #define EGU_INTENSET_TRIGGERED9_Pos (9UL) /*!< Position of TRIGGERED9 field. */ #define EGU_INTENSET_TRIGGERED9_Msk (0x1UL << EGU_INTENSET_TRIGGERED9_Pos) /*!< Bit mask of TRIGGERED9 field. */ #define EGU_INTENSET_TRIGGERED9_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED9_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED9_Set (1UL) /*!< Enable */ -/* Bit 8 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[8] event */ +/* Bit 8 : Write '1' to Enable interrupt for TRIGGERED[8] event */ #define EGU_INTENSET_TRIGGERED8_Pos (8UL) /*!< Position of TRIGGERED8 field. */ #define EGU_INTENSET_TRIGGERED8_Msk (0x1UL << EGU_INTENSET_TRIGGERED8_Pos) /*!< Bit mask of TRIGGERED8 field. */ #define EGU_INTENSET_TRIGGERED8_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED8_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED8_Set (1UL) /*!< Enable */ -/* Bit 7 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[7] event */ +/* Bit 7 : Write '1' to Enable interrupt for TRIGGERED[7] event */ #define EGU_INTENSET_TRIGGERED7_Pos (7UL) /*!< Position of TRIGGERED7 field. */ #define EGU_INTENSET_TRIGGERED7_Msk (0x1UL << EGU_INTENSET_TRIGGERED7_Pos) /*!< Bit mask of TRIGGERED7 field. */ #define EGU_INTENSET_TRIGGERED7_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED7_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED7_Set (1UL) /*!< Enable */ -/* Bit 6 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[6] event */ +/* Bit 6 : Write '1' to Enable interrupt for TRIGGERED[6] event */ #define EGU_INTENSET_TRIGGERED6_Pos (6UL) /*!< Position of TRIGGERED6 field. */ #define EGU_INTENSET_TRIGGERED6_Msk (0x1UL << EGU_INTENSET_TRIGGERED6_Pos) /*!< Bit mask of TRIGGERED6 field. */ #define EGU_INTENSET_TRIGGERED6_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED6_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED6_Set (1UL) /*!< Enable */ -/* Bit 5 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[5] event */ +/* Bit 5 : Write '1' to Enable interrupt for TRIGGERED[5] event */ #define EGU_INTENSET_TRIGGERED5_Pos (5UL) /*!< Position of TRIGGERED5 field. */ #define EGU_INTENSET_TRIGGERED5_Msk (0x1UL << EGU_INTENSET_TRIGGERED5_Pos) /*!< Bit mask of TRIGGERED5 field. */ #define EGU_INTENSET_TRIGGERED5_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED5_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED5_Set (1UL) /*!< Enable */ -/* Bit 4 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[4] event */ +/* Bit 4 : Write '1' to Enable interrupt for TRIGGERED[4] event */ #define EGU_INTENSET_TRIGGERED4_Pos (4UL) /*!< Position of TRIGGERED4 field. */ #define EGU_INTENSET_TRIGGERED4_Msk (0x1UL << EGU_INTENSET_TRIGGERED4_Pos) /*!< Bit mask of TRIGGERED4 field. */ #define EGU_INTENSET_TRIGGERED4_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED4_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED4_Set (1UL) /*!< Enable */ -/* Bit 3 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[3] event */ +/* Bit 3 : Write '1' to Enable interrupt for TRIGGERED[3] event */ #define EGU_INTENSET_TRIGGERED3_Pos (3UL) /*!< Position of TRIGGERED3 field. */ #define EGU_INTENSET_TRIGGERED3_Msk (0x1UL << EGU_INTENSET_TRIGGERED3_Pos) /*!< Bit mask of TRIGGERED3 field. */ #define EGU_INTENSET_TRIGGERED3_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED3_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED3_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[2] event */ +/* Bit 2 : Write '1' to Enable interrupt for TRIGGERED[2] event */ #define EGU_INTENSET_TRIGGERED2_Pos (2UL) /*!< Position of TRIGGERED2 field. */ #define EGU_INTENSET_TRIGGERED2_Msk (0x1UL << EGU_INTENSET_TRIGGERED2_Pos) /*!< Bit mask of TRIGGERED2 field. */ #define EGU_INTENSET_TRIGGERED2_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED2_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED2_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[1] event */ +/* Bit 1 : Write '1' to Enable interrupt for TRIGGERED[1] event */ #define EGU_INTENSET_TRIGGERED1_Pos (1UL) /*!< Position of TRIGGERED1 field. */ #define EGU_INTENSET_TRIGGERED1_Msk (0x1UL << EGU_INTENSET_TRIGGERED1_Pos) /*!< Bit mask of TRIGGERED1 field. */ #define EGU_INTENSET_TRIGGERED1_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENSET_TRIGGERED1_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENSET_TRIGGERED1_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_TRIGGERED[0] event */ +/* Bit 0 : Write '1' to Enable interrupt for TRIGGERED[0] event */ #define EGU_INTENSET_TRIGGERED0_Pos (0UL) /*!< Position of TRIGGERED0 field. */ #define EGU_INTENSET_TRIGGERED0_Msk (0x1UL << EGU_INTENSET_TRIGGERED0_Pos) /*!< Bit mask of TRIGGERED0 field. */ #define EGU_INTENSET_TRIGGERED0_Disabled (0UL) /*!< Read: Disabled */ @@ -1701,112 +1725,112 @@ /* Register: EGU_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 15 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[15] event */ +/* Bit 15 : Write '1' to Disable interrupt for TRIGGERED[15] event */ #define EGU_INTENCLR_TRIGGERED15_Pos (15UL) /*!< Position of TRIGGERED15 field. */ #define EGU_INTENCLR_TRIGGERED15_Msk (0x1UL << EGU_INTENCLR_TRIGGERED15_Pos) /*!< Bit mask of TRIGGERED15 field. */ #define EGU_INTENCLR_TRIGGERED15_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED15_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED15_Clear (1UL) /*!< Disable */ -/* Bit 14 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[14] event */ +/* Bit 14 : Write '1' to Disable interrupt for TRIGGERED[14] event */ #define EGU_INTENCLR_TRIGGERED14_Pos (14UL) /*!< Position of TRIGGERED14 field. */ #define EGU_INTENCLR_TRIGGERED14_Msk (0x1UL << EGU_INTENCLR_TRIGGERED14_Pos) /*!< Bit mask of TRIGGERED14 field. */ #define EGU_INTENCLR_TRIGGERED14_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED14_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED14_Clear (1UL) /*!< Disable */ -/* Bit 13 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[13] event */ +/* Bit 13 : Write '1' to Disable interrupt for TRIGGERED[13] event */ #define EGU_INTENCLR_TRIGGERED13_Pos (13UL) /*!< Position of TRIGGERED13 field. */ #define EGU_INTENCLR_TRIGGERED13_Msk (0x1UL << EGU_INTENCLR_TRIGGERED13_Pos) /*!< Bit mask of TRIGGERED13 field. */ #define EGU_INTENCLR_TRIGGERED13_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED13_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED13_Clear (1UL) /*!< Disable */ -/* Bit 12 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[12] event */ +/* Bit 12 : Write '1' to Disable interrupt for TRIGGERED[12] event */ #define EGU_INTENCLR_TRIGGERED12_Pos (12UL) /*!< Position of TRIGGERED12 field. */ #define EGU_INTENCLR_TRIGGERED12_Msk (0x1UL << EGU_INTENCLR_TRIGGERED12_Pos) /*!< Bit mask of TRIGGERED12 field. */ #define EGU_INTENCLR_TRIGGERED12_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED12_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED12_Clear (1UL) /*!< Disable */ -/* Bit 11 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[11] event */ +/* Bit 11 : Write '1' to Disable interrupt for TRIGGERED[11] event */ #define EGU_INTENCLR_TRIGGERED11_Pos (11UL) /*!< Position of TRIGGERED11 field. */ #define EGU_INTENCLR_TRIGGERED11_Msk (0x1UL << EGU_INTENCLR_TRIGGERED11_Pos) /*!< Bit mask of TRIGGERED11 field. */ #define EGU_INTENCLR_TRIGGERED11_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED11_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED11_Clear (1UL) /*!< Disable */ -/* Bit 10 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[10] event */ +/* Bit 10 : Write '1' to Disable interrupt for TRIGGERED[10] event */ #define EGU_INTENCLR_TRIGGERED10_Pos (10UL) /*!< Position of TRIGGERED10 field. */ #define EGU_INTENCLR_TRIGGERED10_Msk (0x1UL << EGU_INTENCLR_TRIGGERED10_Pos) /*!< Bit mask of TRIGGERED10 field. */ #define EGU_INTENCLR_TRIGGERED10_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED10_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED10_Clear (1UL) /*!< Disable */ -/* Bit 9 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[9] event */ +/* Bit 9 : Write '1' to Disable interrupt for TRIGGERED[9] event */ #define EGU_INTENCLR_TRIGGERED9_Pos (9UL) /*!< Position of TRIGGERED9 field. */ #define EGU_INTENCLR_TRIGGERED9_Msk (0x1UL << EGU_INTENCLR_TRIGGERED9_Pos) /*!< Bit mask of TRIGGERED9 field. */ #define EGU_INTENCLR_TRIGGERED9_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED9_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED9_Clear (1UL) /*!< Disable */ -/* Bit 8 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[8] event */ +/* Bit 8 : Write '1' to Disable interrupt for TRIGGERED[8] event */ #define EGU_INTENCLR_TRIGGERED8_Pos (8UL) /*!< Position of TRIGGERED8 field. */ #define EGU_INTENCLR_TRIGGERED8_Msk (0x1UL << EGU_INTENCLR_TRIGGERED8_Pos) /*!< Bit mask of TRIGGERED8 field. */ #define EGU_INTENCLR_TRIGGERED8_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED8_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED8_Clear (1UL) /*!< Disable */ -/* Bit 7 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[7] event */ +/* Bit 7 : Write '1' to Disable interrupt for TRIGGERED[7] event */ #define EGU_INTENCLR_TRIGGERED7_Pos (7UL) /*!< Position of TRIGGERED7 field. */ #define EGU_INTENCLR_TRIGGERED7_Msk (0x1UL << EGU_INTENCLR_TRIGGERED7_Pos) /*!< Bit mask of TRIGGERED7 field. */ #define EGU_INTENCLR_TRIGGERED7_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED7_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED7_Clear (1UL) /*!< Disable */ -/* Bit 6 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[6] event */ +/* Bit 6 : Write '1' to Disable interrupt for TRIGGERED[6] event */ #define EGU_INTENCLR_TRIGGERED6_Pos (6UL) /*!< Position of TRIGGERED6 field. */ #define EGU_INTENCLR_TRIGGERED6_Msk (0x1UL << EGU_INTENCLR_TRIGGERED6_Pos) /*!< Bit mask of TRIGGERED6 field. */ #define EGU_INTENCLR_TRIGGERED6_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED6_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED6_Clear (1UL) /*!< Disable */ -/* Bit 5 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[5] event */ +/* Bit 5 : Write '1' to Disable interrupt for TRIGGERED[5] event */ #define EGU_INTENCLR_TRIGGERED5_Pos (5UL) /*!< Position of TRIGGERED5 field. */ #define EGU_INTENCLR_TRIGGERED5_Msk (0x1UL << EGU_INTENCLR_TRIGGERED5_Pos) /*!< Bit mask of TRIGGERED5 field. */ #define EGU_INTENCLR_TRIGGERED5_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED5_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED5_Clear (1UL) /*!< Disable */ -/* Bit 4 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[4] event */ +/* Bit 4 : Write '1' to Disable interrupt for TRIGGERED[4] event */ #define EGU_INTENCLR_TRIGGERED4_Pos (4UL) /*!< Position of TRIGGERED4 field. */ #define EGU_INTENCLR_TRIGGERED4_Msk (0x1UL << EGU_INTENCLR_TRIGGERED4_Pos) /*!< Bit mask of TRIGGERED4 field. */ #define EGU_INTENCLR_TRIGGERED4_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED4_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED4_Clear (1UL) /*!< Disable */ -/* Bit 3 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[3] event */ +/* Bit 3 : Write '1' to Disable interrupt for TRIGGERED[3] event */ #define EGU_INTENCLR_TRIGGERED3_Pos (3UL) /*!< Position of TRIGGERED3 field. */ #define EGU_INTENCLR_TRIGGERED3_Msk (0x1UL << EGU_INTENCLR_TRIGGERED3_Pos) /*!< Bit mask of TRIGGERED3 field. */ #define EGU_INTENCLR_TRIGGERED3_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED3_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED3_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[2] event */ +/* Bit 2 : Write '1' to Disable interrupt for TRIGGERED[2] event */ #define EGU_INTENCLR_TRIGGERED2_Pos (2UL) /*!< Position of TRIGGERED2 field. */ #define EGU_INTENCLR_TRIGGERED2_Msk (0x1UL << EGU_INTENCLR_TRIGGERED2_Pos) /*!< Bit mask of TRIGGERED2 field. */ #define EGU_INTENCLR_TRIGGERED2_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED2_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED2_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[1] event */ +/* Bit 1 : Write '1' to Disable interrupt for TRIGGERED[1] event */ #define EGU_INTENCLR_TRIGGERED1_Pos (1UL) /*!< Position of TRIGGERED1 field. */ #define EGU_INTENCLR_TRIGGERED1_Msk (0x1UL << EGU_INTENCLR_TRIGGERED1_Pos) /*!< Bit mask of TRIGGERED1 field. */ #define EGU_INTENCLR_TRIGGERED1_Disabled (0UL) /*!< Read: Disabled */ #define EGU_INTENCLR_TRIGGERED1_Enabled (1UL) /*!< Read: Enabled */ #define EGU_INTENCLR_TRIGGERED1_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_TRIGGERED[0] event */ +/* Bit 0 : Write '1' to Disable interrupt for TRIGGERED[0] event */ #define EGU_INTENCLR_TRIGGERED0_Pos (0UL) /*!< Position of TRIGGERED0 field. */ #define EGU_INTENCLR_TRIGGERED0_Msk (0x1UL << EGU_INTENCLR_TRIGGERED0_Pos) /*!< Bit mask of TRIGGERED0 field. */ #define EGU_INTENCLR_TRIGGERED0_Disabled (0UL) /*!< Read: Disabled */ @@ -1831,17 +1855,6 @@ #define FICR_CODESIZE_CODESIZE_Pos (0UL) /*!< Position of CODESIZE field. */ #define FICR_CODESIZE_CODESIZE_Msk (0xFFFFFFFFUL << FICR_CODESIZE_CODESIZE_Pos) /*!< Bit mask of CODESIZE field. */ -/* Register: FICR_CONFIGID */ -/* Description: Configuration identifier */ - -/* Bits 31..16 : Deprecated field - Identification number for the FW that is pre-loaded into the chip */ -#define FICR_CONFIGID_FWID_Pos (16UL) /*!< Position of FWID field. */ -#define FICR_CONFIGID_FWID_Msk (0xFFFFUL << FICR_CONFIGID_FWID_Pos) /*!< Bit mask of FWID field. */ - -/* Bits 15..0 : Identification number for the HW */ -#define FICR_CONFIGID_HWID_Pos (0UL) /*!< Position of HWID field. */ -#define FICR_CONFIGID_HWID_Msk (0xFFFFUL << FICR_CONFIGID_HWID_Pos) /*!< Bit mask of HWID field. */ - /* Register: FICR_DEVICEID */ /* Description: Description collection[0]: Device identifier */ @@ -1885,20 +1898,21 @@ /* Bits 31..0 : Part code */ #define FICR_INFO_PART_PART_Pos (0UL) /*!< Position of PART field. */ #define FICR_INFO_PART_PART_Msk (0xFFFFFFFFUL << FICR_INFO_PART_PART_Pos) /*!< Bit mask of PART field. */ -#define FICR_INFO_PART_PART_N51422 (0x51422UL) /*!< nRF51422 */ -#define FICR_INFO_PART_PART_N51822 (0x51822UL) /*!< nRF51822 */ -#define FICR_INFO_PART_PART_N52000 (0x52000UL) /*!< nRF52000 */ +#define FICR_INFO_PART_PART_N52832 (0x52832UL) /*!< nRF52832 */ #define FICR_INFO_PART_PART_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ /* Register: FICR_INFO_VARIANT */ -/* Description: Part variant */ +/* Description: Part Variant, Hardware version and Production configuration */ -/* Bits 31..0 : Part variant */ +/* Bits 31..0 : Part Variant, Hardware version and Production configuration, encoded as ASCII */ #define FICR_INFO_VARIANT_VARIANT_Pos (0UL) /*!< Position of VARIANT field. */ #define FICR_INFO_VARIANT_VARIANT_Msk (0xFFFFFFFFUL << FICR_INFO_VARIANT_VARIANT_Pos) /*!< Bit mask of VARIANT field. */ -#define FICR_INFO_VARIANT_VARIANT_nRF51C (0x1002UL) /*!< nRF51-C */ -#define FICR_INFO_VARIANT_VARIANT_nRF51D (0x1003UL) /*!< nRF51-D */ -#define FICR_INFO_VARIANT_VARIANT_nRF51E (0x1004UL) /*!< nRF51-E */ +#define FICR_INFO_VARIANT_VARIANT_AAAA (0x41414141UL) /*!< AAAA */ +#define FICR_INFO_VARIANT_VARIANT_AAAB (0x41414142UL) /*!< AAAB */ +#define FICR_INFO_VARIANT_VARIANT_AAB0 (0x41414230UL) /*!< AAB0 */ +#define FICR_INFO_VARIANT_VARIANT_AABA (0x41414241UL) /*!< AABA */ +#define FICR_INFO_VARIANT_VARIANT_AABB (0x41414242UL) /*!< AABB */ +#define FICR_INFO_VARIANT_VARIANT_SPA0 (0x53504130UL) /*!< SPA0 */ #define FICR_INFO_VARIANT_VARIANT_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ /* Register: FICR_INFO_PACKAGE */ @@ -1907,11 +1921,9 @@ /* Bits 31..0 : Package option */ #define FICR_INFO_PACKAGE_PACKAGE_Pos (0UL) /*!< Position of PACKAGE field. */ #define FICR_INFO_PACKAGE_PACKAGE_Msk (0xFFFFFFFFUL << FICR_INFO_PACKAGE_PACKAGE_Pos) /*!< Bit mask of PACKAGE field. */ -#define FICR_INFO_PACKAGE_PACKAGE_QFN48 (0x0000UL) /*!< 48-pin QFN with 31 GPIO */ -#define FICR_INFO_PACKAGE_PACKAGE_nRF51CSP56A (0x1000UL) /*!< nRF51x22 CDxx - WLCSP 56 balls */ -#define FICR_INFO_PACKAGE_PACKAGE_nRF51CSP62A (0x1001UL) /*!< nRF51x22 CExx - WLCSP 62 balls */ -#define FICR_INFO_PACKAGE_PACKAGE_nRF51CSP62B (0x1002UL) /*!< nRF51x22 CFxx - WLCSP 62 balls */ -#define FICR_INFO_PACKAGE_PACKAGE_nRF51CSP62C (0x1003UL) /*!< nRF51x22 CTxx - WLCSP 62 balls */ +#define FICR_INFO_PACKAGE_PACKAGE_QF (0x2000UL) /*!< QFxx - 48-pin QFN */ +#define FICR_INFO_PACKAGE_PACKAGE_CH (0x2001UL) /*!< CHxx - 7x8 WLCSP 56 balls */ +#define FICR_INFO_PACKAGE_PACKAGE_CI (0x2002UL) /*!< CIxx - 7x8 WLCSP 56 balls */ #define FICR_INFO_PACKAGE_PACKAGE_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ /* Register: FICR_INFO_RAM */ @@ -1920,9 +1932,9 @@ /* Bits 31..0 : RAM variant */ #define FICR_INFO_RAM_RAM_Pos (0UL) /*!< Position of RAM field. */ #define FICR_INFO_RAM_RAM_Msk (0xFFFFFFFFUL << FICR_INFO_RAM_RAM_Pos) /*!< Bit mask of RAM field. */ -#define FICR_INFO_RAM_RAM_K16 (16UL) /*!< 16 kByte RAM */ -#define FICR_INFO_RAM_RAM_K32 (32UL) /*!< 32 kByte RAM */ -#define FICR_INFO_RAM_RAM_K64 (64UL) /*!< 64 kByte RAM */ +#define FICR_INFO_RAM_RAM_K16 (0x10UL) /*!< 16 kByte RAM */ +#define FICR_INFO_RAM_RAM_K32 (0x20UL) /*!< 32 kByte RAM */ +#define FICR_INFO_RAM_RAM_K64 (0x40UL) /*!< 64 kByte RAM */ #define FICR_INFO_RAM_RAM_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ /* Register: FICR_INFO_FLASH */ @@ -1931,11 +1943,130 @@ /* Bits 31..0 : Flash variant */ #define FICR_INFO_FLASH_FLASH_Pos (0UL) /*!< Position of FLASH field. */ #define FICR_INFO_FLASH_FLASH_Msk (0xFFFFFFFFUL << FICR_INFO_FLASH_FLASH_Pos) /*!< Bit mask of FLASH field. */ -#define FICR_INFO_FLASH_FLASH_K128 (128UL) /*!< 128 kByte FLASH */ -#define FICR_INFO_FLASH_FLASH_K256 (256UL) /*!< 256 kByte FLASH */ -#define FICR_INFO_FLASH_FLASH_K512 (512UL) /*!< 512 kByte FLASH */ +#define FICR_INFO_FLASH_FLASH_K128 (0x80UL) /*!< 128 kByte FLASH */ +#define FICR_INFO_FLASH_FLASH_K256 (0x100UL) /*!< 256 kByte FLASH */ +#define FICR_INFO_FLASH_FLASH_K512 (0x200UL) /*!< 512 kByte FLASH */ #define FICR_INFO_FLASH_FLASH_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ +/* Register: FICR_TEMP_A0 */ +/* Description: Slope definition A0. */ + +/* Bits 11..0 : A (slope definition) register. */ +#define FICR_TEMP_A0_A_Pos (0UL) /*!< Position of A field. */ +#define FICR_TEMP_A0_A_Msk (0xFFFUL << FICR_TEMP_A0_A_Pos) /*!< Bit mask of A field. */ + +/* Register: FICR_TEMP_A1 */ +/* Description: Slope definition A1. */ + +/* Bits 11..0 : A (slope definition) register. */ +#define FICR_TEMP_A1_A_Pos (0UL) /*!< Position of A field. */ +#define FICR_TEMP_A1_A_Msk (0xFFFUL << FICR_TEMP_A1_A_Pos) /*!< Bit mask of A field. */ + +/* Register: FICR_TEMP_A2 */ +/* Description: Slope definition A2. */ + +/* Bits 11..0 : A (slope definition) register. */ +#define FICR_TEMP_A2_A_Pos (0UL) /*!< Position of A field. */ +#define FICR_TEMP_A2_A_Msk (0xFFFUL << FICR_TEMP_A2_A_Pos) /*!< Bit mask of A field. */ + +/* Register: FICR_TEMP_A3 */ +/* Description: Slope definition A3. */ + +/* Bits 11..0 : A (slope definition) register. */ +#define FICR_TEMP_A3_A_Pos (0UL) /*!< Position of A field. */ +#define FICR_TEMP_A3_A_Msk (0xFFFUL << FICR_TEMP_A3_A_Pos) /*!< Bit mask of A field. */ + +/* Register: FICR_TEMP_A4 */ +/* Description: Slope definition A4. */ + +/* Bits 11..0 : A (slope definition) register. */ +#define FICR_TEMP_A4_A_Pos (0UL) /*!< Position of A field. */ +#define FICR_TEMP_A4_A_Msk (0xFFFUL << FICR_TEMP_A4_A_Pos) /*!< Bit mask of A field. */ + +/* Register: FICR_TEMP_A5 */ +/* Description: Slope definition A5. */ + +/* Bits 11..0 : A (slope definition) register. */ +#define FICR_TEMP_A5_A_Pos (0UL) /*!< Position of A field. */ +#define FICR_TEMP_A5_A_Msk (0xFFFUL << FICR_TEMP_A5_A_Pos) /*!< Bit mask of A field. */ + +/* Register: FICR_TEMP_B0 */ +/* Description: y-intercept B0. */ + +/* Bits 13..0 : B (y-intercept) */ +#define FICR_TEMP_B0_B_Pos (0UL) /*!< Position of B field. */ +#define FICR_TEMP_B0_B_Msk (0x3FFFUL << FICR_TEMP_B0_B_Pos) /*!< Bit mask of B field. */ + +/* Register: FICR_TEMP_B1 */ +/* Description: y-intercept B1. */ + +/* Bits 13..0 : B (y-intercept) */ +#define FICR_TEMP_B1_B_Pos (0UL) /*!< Position of B field. */ +#define FICR_TEMP_B1_B_Msk (0x3FFFUL << FICR_TEMP_B1_B_Pos) /*!< Bit mask of B field. */ + +/* Register: FICR_TEMP_B2 */ +/* Description: y-intercept B2. */ + +/* Bits 13..0 : B (y-intercept) */ +#define FICR_TEMP_B2_B_Pos (0UL) /*!< Position of B field. */ +#define FICR_TEMP_B2_B_Msk (0x3FFFUL << FICR_TEMP_B2_B_Pos) /*!< Bit mask of B field. */ + +/* Register: FICR_TEMP_B3 */ +/* Description: y-intercept B3. */ + +/* Bits 13..0 : B (y-intercept) */ +#define FICR_TEMP_B3_B_Pos (0UL) /*!< Position of B field. */ +#define FICR_TEMP_B3_B_Msk (0x3FFFUL << FICR_TEMP_B3_B_Pos) /*!< Bit mask of B field. */ + +/* Register: FICR_TEMP_B4 */ +/* Description: y-intercept B4. */ + +/* Bits 13..0 : B (y-intercept) */ +#define FICR_TEMP_B4_B_Pos (0UL) /*!< Position of B field. */ +#define FICR_TEMP_B4_B_Msk (0x3FFFUL << FICR_TEMP_B4_B_Pos) /*!< Bit mask of B field. */ + +/* Register: FICR_TEMP_B5 */ +/* Description: y-intercept B5. */ + +/* Bits 13..0 : B (y-intercept) */ +#define FICR_TEMP_B5_B_Pos (0UL) /*!< Position of B field. */ +#define FICR_TEMP_B5_B_Msk (0x3FFFUL << FICR_TEMP_B5_B_Pos) /*!< Bit mask of B field. */ + +/* Register: FICR_TEMP_T0 */ +/* Description: Segment end T0. */ + +/* Bits 7..0 : T (segment end)register. */ +#define FICR_TEMP_T0_T_Pos (0UL) /*!< Position of T field. */ +#define FICR_TEMP_T0_T_Msk (0xFFUL << FICR_TEMP_T0_T_Pos) /*!< Bit mask of T field. */ + +/* Register: FICR_TEMP_T1 */ +/* Description: Segment end T1. */ + +/* Bits 7..0 : T (segment end)register. */ +#define FICR_TEMP_T1_T_Pos (0UL) /*!< Position of T field. */ +#define FICR_TEMP_T1_T_Msk (0xFFUL << FICR_TEMP_T1_T_Pos) /*!< Bit mask of T field. */ + +/* Register: FICR_TEMP_T2 */ +/* Description: Segment end T2. */ + +/* Bits 7..0 : T (segment end)register. */ +#define FICR_TEMP_T2_T_Pos (0UL) /*!< Position of T field. */ +#define FICR_TEMP_T2_T_Msk (0xFFUL << FICR_TEMP_T2_T_Pos) /*!< Bit mask of T field. */ + +/* Register: FICR_TEMP_T3 */ +/* Description: Segment end T3. */ + +/* Bits 7..0 : T (segment end)register. */ +#define FICR_TEMP_T3_T_Pos (0UL) /*!< Position of T field. */ +#define FICR_TEMP_T3_T_Msk (0xFFUL << FICR_TEMP_T3_T_Pos) /*!< Bit mask of T field. */ + +/* Register: FICR_TEMP_T4 */ +/* Description: Segment end T4. */ + +/* Bits 7..0 : T (segment end)register. */ +#define FICR_TEMP_T4_T_Pos (0UL) /*!< Position of T field. */ +#define FICR_TEMP_T4_T_Msk (0xFFUL << FICR_TEMP_T4_T_Pos) /*!< Bit mask of T field. */ + /* Register: FICR_NFC_TAGHEADER0 */ /* Description: Default header for NFC Tag. Software can read these values to populate NFCID1_3RD_LAST, NFCID1_2ND_LAST and NFCID1_LAST. */ @@ -2019,63 +2150,63 @@ /* Register: GPIOTE_INTENSET */ /* Description: Enable interrupt */ -/* Bit 31 : Write '1' to Enable interrupt on EVENTS_PORT event */ +/* Bit 31 : Write '1' to Enable interrupt for PORT event */ #define GPIOTE_INTENSET_PORT_Pos (31UL) /*!< Position of PORT field. */ #define GPIOTE_INTENSET_PORT_Msk (0x1UL << GPIOTE_INTENSET_PORT_Pos) /*!< Bit mask of PORT field. */ #define GPIOTE_INTENSET_PORT_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENSET_PORT_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENSET_PORT_Set (1UL) /*!< Enable */ -/* Bit 7 : Write '1' to Enable interrupt on EVENTS_IN[7] event */ +/* Bit 7 : Write '1' to Enable interrupt for IN[7] event */ #define GPIOTE_INTENSET_IN7_Pos (7UL) /*!< Position of IN7 field. */ #define GPIOTE_INTENSET_IN7_Msk (0x1UL << GPIOTE_INTENSET_IN7_Pos) /*!< Bit mask of IN7 field. */ #define GPIOTE_INTENSET_IN7_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENSET_IN7_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENSET_IN7_Set (1UL) /*!< Enable */ -/* Bit 6 : Write '1' to Enable interrupt on EVENTS_IN[6] event */ +/* Bit 6 : Write '1' to Enable interrupt for IN[6] event */ #define GPIOTE_INTENSET_IN6_Pos (6UL) /*!< Position of IN6 field. */ #define GPIOTE_INTENSET_IN6_Msk (0x1UL << GPIOTE_INTENSET_IN6_Pos) /*!< Bit mask of IN6 field. */ #define GPIOTE_INTENSET_IN6_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENSET_IN6_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENSET_IN6_Set (1UL) /*!< Enable */ -/* Bit 5 : Write '1' to Enable interrupt on EVENTS_IN[5] event */ +/* Bit 5 : Write '1' to Enable interrupt for IN[5] event */ #define GPIOTE_INTENSET_IN5_Pos (5UL) /*!< Position of IN5 field. */ #define GPIOTE_INTENSET_IN5_Msk (0x1UL << GPIOTE_INTENSET_IN5_Pos) /*!< Bit mask of IN5 field. */ #define GPIOTE_INTENSET_IN5_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENSET_IN5_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENSET_IN5_Set (1UL) /*!< Enable */ -/* Bit 4 : Write '1' to Enable interrupt on EVENTS_IN[4] event */ +/* Bit 4 : Write '1' to Enable interrupt for IN[4] event */ #define GPIOTE_INTENSET_IN4_Pos (4UL) /*!< Position of IN4 field. */ #define GPIOTE_INTENSET_IN4_Msk (0x1UL << GPIOTE_INTENSET_IN4_Pos) /*!< Bit mask of IN4 field. */ #define GPIOTE_INTENSET_IN4_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENSET_IN4_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENSET_IN4_Set (1UL) /*!< Enable */ -/* Bit 3 : Write '1' to Enable interrupt on EVENTS_IN[3] event */ +/* Bit 3 : Write '1' to Enable interrupt for IN[3] event */ #define GPIOTE_INTENSET_IN3_Pos (3UL) /*!< Position of IN3 field. */ #define GPIOTE_INTENSET_IN3_Msk (0x1UL << GPIOTE_INTENSET_IN3_Pos) /*!< Bit mask of IN3 field. */ #define GPIOTE_INTENSET_IN3_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENSET_IN3_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENSET_IN3_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_IN[2] event */ +/* Bit 2 : Write '1' to Enable interrupt for IN[2] event */ #define GPIOTE_INTENSET_IN2_Pos (2UL) /*!< Position of IN2 field. */ #define GPIOTE_INTENSET_IN2_Msk (0x1UL << GPIOTE_INTENSET_IN2_Pos) /*!< Bit mask of IN2 field. */ #define GPIOTE_INTENSET_IN2_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENSET_IN2_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENSET_IN2_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_IN[1] event */ +/* Bit 1 : Write '1' to Enable interrupt for IN[1] event */ #define GPIOTE_INTENSET_IN1_Pos (1UL) /*!< Position of IN1 field. */ #define GPIOTE_INTENSET_IN1_Msk (0x1UL << GPIOTE_INTENSET_IN1_Pos) /*!< Bit mask of IN1 field. */ #define GPIOTE_INTENSET_IN1_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENSET_IN1_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENSET_IN1_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_IN[0] event */ +/* Bit 0 : Write '1' to Enable interrupt for IN[0] event */ #define GPIOTE_INTENSET_IN0_Pos (0UL) /*!< Position of IN0 field. */ #define GPIOTE_INTENSET_IN0_Msk (0x1UL << GPIOTE_INTENSET_IN0_Pos) /*!< Bit mask of IN0 field. */ #define GPIOTE_INTENSET_IN0_Disabled (0UL) /*!< Read: Disabled */ @@ -2085,63 +2216,63 @@ /* Register: GPIOTE_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 31 : Write '1' to Clear interrupt on EVENTS_PORT event */ +/* Bit 31 : Write '1' to Disable interrupt for PORT event */ #define GPIOTE_INTENCLR_PORT_Pos (31UL) /*!< Position of PORT field. */ #define GPIOTE_INTENCLR_PORT_Msk (0x1UL << GPIOTE_INTENCLR_PORT_Pos) /*!< Bit mask of PORT field. */ #define GPIOTE_INTENCLR_PORT_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENCLR_PORT_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENCLR_PORT_Clear (1UL) /*!< Disable */ -/* Bit 7 : Write '1' to Clear interrupt on EVENTS_IN[7] event */ +/* Bit 7 : Write '1' to Disable interrupt for IN[7] event */ #define GPIOTE_INTENCLR_IN7_Pos (7UL) /*!< Position of IN7 field. */ #define GPIOTE_INTENCLR_IN7_Msk (0x1UL << GPIOTE_INTENCLR_IN7_Pos) /*!< Bit mask of IN7 field. */ #define GPIOTE_INTENCLR_IN7_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENCLR_IN7_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENCLR_IN7_Clear (1UL) /*!< Disable */ -/* Bit 6 : Write '1' to Clear interrupt on EVENTS_IN[6] event */ +/* Bit 6 : Write '1' to Disable interrupt for IN[6] event */ #define GPIOTE_INTENCLR_IN6_Pos (6UL) /*!< Position of IN6 field. */ #define GPIOTE_INTENCLR_IN6_Msk (0x1UL << GPIOTE_INTENCLR_IN6_Pos) /*!< Bit mask of IN6 field. */ #define GPIOTE_INTENCLR_IN6_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENCLR_IN6_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENCLR_IN6_Clear (1UL) /*!< Disable */ -/* Bit 5 : Write '1' to Clear interrupt on EVENTS_IN[5] event */ +/* Bit 5 : Write '1' to Disable interrupt for IN[5] event */ #define GPIOTE_INTENCLR_IN5_Pos (5UL) /*!< Position of IN5 field. */ #define GPIOTE_INTENCLR_IN5_Msk (0x1UL << GPIOTE_INTENCLR_IN5_Pos) /*!< Bit mask of IN5 field. */ #define GPIOTE_INTENCLR_IN5_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENCLR_IN5_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENCLR_IN5_Clear (1UL) /*!< Disable */ -/* Bit 4 : Write '1' to Clear interrupt on EVENTS_IN[4] event */ +/* Bit 4 : Write '1' to Disable interrupt for IN[4] event */ #define GPIOTE_INTENCLR_IN4_Pos (4UL) /*!< Position of IN4 field. */ #define GPIOTE_INTENCLR_IN4_Msk (0x1UL << GPIOTE_INTENCLR_IN4_Pos) /*!< Bit mask of IN4 field. */ #define GPIOTE_INTENCLR_IN4_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENCLR_IN4_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENCLR_IN4_Clear (1UL) /*!< Disable */ -/* Bit 3 : Write '1' to Clear interrupt on EVENTS_IN[3] event */ +/* Bit 3 : Write '1' to Disable interrupt for IN[3] event */ #define GPIOTE_INTENCLR_IN3_Pos (3UL) /*!< Position of IN3 field. */ #define GPIOTE_INTENCLR_IN3_Msk (0x1UL << GPIOTE_INTENCLR_IN3_Pos) /*!< Bit mask of IN3 field. */ #define GPIOTE_INTENCLR_IN3_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENCLR_IN3_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENCLR_IN3_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_IN[2] event */ +/* Bit 2 : Write '1' to Disable interrupt for IN[2] event */ #define GPIOTE_INTENCLR_IN2_Pos (2UL) /*!< Position of IN2 field. */ #define GPIOTE_INTENCLR_IN2_Msk (0x1UL << GPIOTE_INTENCLR_IN2_Pos) /*!< Bit mask of IN2 field. */ #define GPIOTE_INTENCLR_IN2_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENCLR_IN2_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENCLR_IN2_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_IN[1] event */ +/* Bit 1 : Write '1' to Disable interrupt for IN[1] event */ #define GPIOTE_INTENCLR_IN1_Pos (1UL) /*!< Position of IN1 field. */ #define GPIOTE_INTENCLR_IN1_Msk (0x1UL << GPIOTE_INTENCLR_IN1_Pos) /*!< Bit mask of IN1 field. */ #define GPIOTE_INTENCLR_IN1_Disabled (0UL) /*!< Read: Disabled */ #define GPIOTE_INTENCLR_IN1_Enabled (1UL) /*!< Read: Enabled */ #define GPIOTE_INTENCLR_IN1_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_IN[0] event */ +/* Bit 0 : Write '1' to Disable interrupt for IN[0] event */ #define GPIOTE_INTENCLR_IN0_Pos (0UL) /*!< Position of IN0 field. */ #define GPIOTE_INTENCLR_IN0_Msk (0x1UL << GPIOTE_INTENCLR_IN0_Pos) /*!< Bit mask of IN0 field. */ #define GPIOTE_INTENCLR_IN0_Disabled (0UL) /*!< Read: Disabled */ @@ -2183,19 +2314,19 @@ /* Register: I2S_INTEN */ /* Description: Enable or disable interrupt */ -/* Bit 5 : Enable or disable interrupt on EVENTS_TXPTRUPD event */ +/* Bit 5 : Enable or disable interrupt for TXPTRUPD event */ #define I2S_INTEN_TXPTRUPD_Pos (5UL) /*!< Position of TXPTRUPD field. */ #define I2S_INTEN_TXPTRUPD_Msk (0x1UL << I2S_INTEN_TXPTRUPD_Pos) /*!< Bit mask of TXPTRUPD field. */ #define I2S_INTEN_TXPTRUPD_Disabled (0UL) /*!< Disable */ #define I2S_INTEN_TXPTRUPD_Enabled (1UL) /*!< Enable */ -/* Bit 2 : Enable or disable interrupt on EVENTS_STOPPED event */ +/* Bit 2 : Enable or disable interrupt for STOPPED event */ #define I2S_INTEN_STOPPED_Pos (2UL) /*!< Position of STOPPED field. */ #define I2S_INTEN_STOPPED_Msk (0x1UL << I2S_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define I2S_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ #define I2S_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable interrupt on EVENTS_RXPTRUPD event */ +/* Bit 1 : Enable or disable interrupt for RXPTRUPD event */ #define I2S_INTEN_RXPTRUPD_Pos (1UL) /*!< Position of RXPTRUPD field. */ #define I2S_INTEN_RXPTRUPD_Msk (0x1UL << I2S_INTEN_RXPTRUPD_Pos) /*!< Bit mask of RXPTRUPD field. */ #define I2S_INTEN_RXPTRUPD_Disabled (0UL) /*!< Disable */ @@ -2204,21 +2335,21 @@ /* Register: I2S_INTENSET */ /* Description: Enable interrupt */ -/* Bit 5 : Write '1' to Enable interrupt on EVENTS_TXPTRUPD event */ +/* Bit 5 : Write '1' to Enable interrupt for TXPTRUPD event */ #define I2S_INTENSET_TXPTRUPD_Pos (5UL) /*!< Position of TXPTRUPD field. */ #define I2S_INTENSET_TXPTRUPD_Msk (0x1UL << I2S_INTENSET_TXPTRUPD_Pos) /*!< Bit mask of TXPTRUPD field. */ #define I2S_INTENSET_TXPTRUPD_Disabled (0UL) /*!< Read: Disabled */ #define I2S_INTENSET_TXPTRUPD_Enabled (1UL) /*!< Read: Enabled */ #define I2S_INTENSET_TXPTRUPD_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_STOPPED event */ +/* Bit 2 : Write '1' to Enable interrupt for STOPPED event */ #define I2S_INTENSET_STOPPED_Pos (2UL) /*!< Position of STOPPED field. */ #define I2S_INTENSET_STOPPED_Msk (0x1UL << I2S_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define I2S_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ #define I2S_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ #define I2S_INTENSET_STOPPED_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_RXPTRUPD event */ +/* Bit 1 : Write '1' to Enable interrupt for RXPTRUPD event */ #define I2S_INTENSET_RXPTRUPD_Pos (1UL) /*!< Position of RXPTRUPD field. */ #define I2S_INTENSET_RXPTRUPD_Msk (0x1UL << I2S_INTENSET_RXPTRUPD_Pos) /*!< Bit mask of RXPTRUPD field. */ #define I2S_INTENSET_RXPTRUPD_Disabled (0UL) /*!< Read: Disabled */ @@ -2228,21 +2359,21 @@ /* Register: I2S_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 5 : Write '1' to Clear interrupt on EVENTS_TXPTRUPD event */ +/* Bit 5 : Write '1' to Disable interrupt for TXPTRUPD event */ #define I2S_INTENCLR_TXPTRUPD_Pos (5UL) /*!< Position of TXPTRUPD field. */ #define I2S_INTENCLR_TXPTRUPD_Msk (0x1UL << I2S_INTENCLR_TXPTRUPD_Pos) /*!< Bit mask of TXPTRUPD field. */ #define I2S_INTENCLR_TXPTRUPD_Disabled (0UL) /*!< Read: Disabled */ #define I2S_INTENCLR_TXPTRUPD_Enabled (1UL) /*!< Read: Enabled */ #define I2S_INTENCLR_TXPTRUPD_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_STOPPED event */ +/* Bit 2 : Write '1' to Disable interrupt for STOPPED event */ #define I2S_INTENCLR_STOPPED_Pos (2UL) /*!< Position of STOPPED field. */ #define I2S_INTENCLR_STOPPED_Msk (0x1UL << I2S_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define I2S_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ #define I2S_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ #define I2S_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_RXPTRUPD event */ +/* Bit 1 : Write '1' to Disable interrupt for RXPTRUPD event */ #define I2S_INTENCLR_RXPTRUPD_Pos (1UL) /*!< Position of RXPTRUPD field. */ #define I2S_INTENCLR_RXPTRUPD_Msk (0x1UL << I2S_INTENCLR_RXPTRUPD_Pos) /*!< Bit mask of RXPTRUPD field. */ #define I2S_INTENCLR_RXPTRUPD_Disabled (0UL) /*!< Read: Disabled */ @@ -2250,22 +2381,22 @@ #define I2S_INTENCLR_RXPTRUPD_Clear (1UL) /*!< Disable */ /* Register: I2S_ENABLE */ -/* Description: Enable I2S module. */ +/* Description: Enable I2S module. */ -/* Bit 0 : Enable I2S module. */ +/* Bit 0 : Enable I2S module. */ #define I2S_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ #define I2S_ENABLE_ENABLE_Msk (0x1UL << I2S_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ -#define I2S_ENABLE_ENABLE_DISABLE (0UL) /*!< Disabl */ -#define I2S_ENABLE_ENABLE_ENABLE (1UL) /*!< Enable */ +#define I2S_ENABLE_ENABLE_Disabled (0UL) /*!< Disable */ +#define I2S_ENABLE_ENABLE_Enabled (1UL) /*!< Enable */ /* Register: I2S_CONFIG_MODE */ -/* Description: I2S mode. */ +/* Description: I2S mode. */ -/* Bit 0 : I2S mode. */ +/* Bit 0 : I2S mode. */ #define I2S_CONFIG_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */ #define I2S_CONFIG_MODE_MODE_Msk (0x1UL << I2S_CONFIG_MODE_MODE_Pos) /*!< Bit mask of MODE field. */ -#define I2S_CONFIG_MODE_MODE_MASTER (0UL) /*!< Master mode. SCK and LRCK generated from internal master clcok (MCK) and output on pins defined by PSEL.xxx. */ -#define I2S_CONFIG_MODE_MODE_SLAVE (1UL) /*!< Slave mode. SCK and LRCK generated by external master and received on pins defined by PSEL.xxx */ +#define I2S_CONFIG_MODE_MODE_Master (0UL) /*!< Master mode. SCK and LRCK generated from internal master clcok (MCK) and output on pins defined by PSEL.xxx. */ +#define I2S_CONFIG_MODE_MODE_Slave (1UL) /*!< Slave mode. SCK and LRCK generated by external master and received on pins defined by PSEL.xxx */ /* Register: I2S_CONFIG_RXEN */ /* Description: Reception (RX) enable. */ @@ -2273,8 +2404,8 @@ /* Bit 0 : Reception (RX) enable. */ #define I2S_CONFIG_RXEN_RXEN_Pos (0UL) /*!< Position of RXEN field. */ #define I2S_CONFIG_RXEN_RXEN_Msk (0x1UL << I2S_CONFIG_RXEN_RXEN_Pos) /*!< Bit mask of RXEN field. */ -#define I2S_CONFIG_RXEN_RXEN_DISABLE (0UL) /*!< Reception disabled and now data will be written to the RXD.PTR address. */ -#define I2S_CONFIG_RXEN_RXEN_ENABLE (1UL) /*!< Reception enabled. */ +#define I2S_CONFIG_RXEN_RXEN_Disabled (0UL) /*!< Reception disabled and now data will be written to the RXD.PTR address. */ +#define I2S_CONFIG_RXEN_RXEN_Enabled (1UL) /*!< Reception enabled. */ /* Register: I2S_CONFIG_TXEN */ /* Description: Transmission (TX) enable. */ @@ -2282,8 +2413,8 @@ /* Bit 0 : Transmission (TX) enable. */ #define I2S_CONFIG_TXEN_TXEN_Pos (0UL) /*!< Position of TXEN field. */ #define I2S_CONFIG_TXEN_TXEN_Msk (0x1UL << I2S_CONFIG_TXEN_TXEN_Pos) /*!< Bit mask of TXEN field. */ -#define I2S_CONFIG_TXEN_TXEN_DISABLE (0UL) /*!< Transmission disabled and now data will be read from the RXD.TXD address. */ -#define I2S_CONFIG_TXEN_TXEN_ENABLE (1UL) /*!< Transmission enabled. */ +#define I2S_CONFIG_TXEN_TXEN_Disabled (0UL) /*!< Transmission disabled and now data will be read from the RXD.TXD address. */ +#define I2S_CONFIG_TXEN_TXEN_Enabled (1UL) /*!< Transmission enabled. */ /* Register: I2S_CONFIG_MCKEN */ /* Description: Master clock generator enable. */ @@ -2291,8 +2422,8 @@ /* Bit 0 : Master clock generator enable. */ #define I2S_CONFIG_MCKEN_MCKEN_Pos (0UL) /*!< Position of MCKEN field. */ #define I2S_CONFIG_MCKEN_MCKEN_Msk (0x1UL << I2S_CONFIG_MCKEN_MCKEN_Pos) /*!< Bit mask of MCKEN field. */ -#define I2S_CONFIG_MCKEN_MCKEN_DISABLE (0UL) /*!< Master clock generator disabled and PSEL.MCK not connected(available as GPIO). */ -#define I2S_CONFIG_MCKEN_MCKEN_ENABLE (1UL) /*!< Master clock generator running and MCK output on PSEL.MCK. */ +#define I2S_CONFIG_MCKEN_MCKEN_Disabled (0UL) /*!< Master clock generator disabled and PSEL.MCK not connected(available as GPIO). */ +#define I2S_CONFIG_MCKEN_MCKEN_Enabled (1UL) /*!< Master clock generator running and MCK output on PSEL.MCK. */ /* Register: I2S_CONFIG_MCKFREQ */ /* Description: Master clock generator frequency. */ @@ -2303,7 +2434,9 @@ #define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV125 (0x020C0000UL) /*!< 32 MHz / 125 = 0.256 MHz */ #define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV63 (0x04100000UL) /*!< 32 MHz / 63 = 0.5079365 MHz */ #define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV42 (0x06000000UL) /*!< 32 MHz / 42 = 0.7619048 MHz */ -#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31 (0x08200000UL) /*!< 32 MHz / 31 = 1.0322581 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV32 (0x08000000UL) /*!< 32 MHz / 32 = 1.0 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31 (0x08400000UL) /*!< 32 MHz / 31 = 1.0322581 MHz */ +#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV30 (0x08800000UL) /*!< 32 MHz / 30 = 1.0666667 MHz */ #define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV23 (0x0B000000UL) /*!< 32 MHz / 23 = 1.3913043 MHz */ #define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV21 (0x0C000000UL) /*!< 32 MHz / 21 = 1.5238095 */ #define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16 (0x10000000UL) /*!< 32 MHz / 16 = 2.0 MHz */ @@ -2326,7 +2459,7 @@ #define I2S_CONFIG_RATIO_RATIO_32X (0UL) /*!< LRCK = MCK / 32 */ #define I2S_CONFIG_RATIO_RATIO_48X (1UL) /*!< LRCK = MCK / 48 */ #define I2S_CONFIG_RATIO_RATIO_64X (2UL) /*!< LRCK = MCK / 64 */ -#define I2S_CONFIG_RATIO_RATIO_96X (3UL) /*!< LRCK = MCK / 96x */ +#define I2S_CONFIG_RATIO_RATIO_96X (3UL) /*!< LRCK = MCK / 96 */ #define I2S_CONFIG_RATIO_RATIO_128X (4UL) /*!< LRCK = MCK / 128 */ #define I2S_CONFIG_RATIO_RATIO_192X (5UL) /*!< LRCK = MCK / 192 */ #define I2S_CONFIG_RATIO_RATIO_256X (6UL) /*!< LRCK = MCK / 256 */ @@ -2339,9 +2472,9 @@ /* Bits 1..0 : Sample width. */ #define I2S_CONFIG_SWIDTH_SWIDTH_Pos (0UL) /*!< Position of SWIDTH field. */ #define I2S_CONFIG_SWIDTH_SWIDTH_Msk (0x3UL << I2S_CONFIG_SWIDTH_SWIDTH_Pos) /*!< Bit mask of SWIDTH field. */ -#define I2S_CONFIG_SWIDTH_SWIDTH_8BIT (0UL) /*!< 8 bit. */ -#define I2S_CONFIG_SWIDTH_SWIDTH_16BIT (1UL) /*!< 16 bit. */ -#define I2S_CONFIG_SWIDTH_SWIDTH_24BIT (2UL) /*!< 24 bit. */ +#define I2S_CONFIG_SWIDTH_SWIDTH_8Bit (0UL) /*!< 8 bit. */ +#define I2S_CONFIG_SWIDTH_SWIDTH_16Bit (1UL) /*!< 16 bit. */ +#define I2S_CONFIG_SWIDTH_SWIDTH_24Bit (2UL) /*!< 24 bit. */ /* Register: I2S_CONFIG_ALIGN */ /* Description: Alignment of sample within a frame. */ @@ -2349,8 +2482,8 @@ /* Bit 0 : Alignment of sample within a frame. */ #define I2S_CONFIG_ALIGN_ALIGN_Pos (0UL) /*!< Position of ALIGN field. */ #define I2S_CONFIG_ALIGN_ALIGN_Msk (0x1UL << I2S_CONFIG_ALIGN_ALIGN_Pos) /*!< Bit mask of ALIGN field. */ -#define I2S_CONFIG_ALIGN_ALIGN_LEFT (0UL) /*!< Left-aligned. */ -#define I2S_CONFIG_ALIGN_ALIGN_RIGHT (1UL) /*!< Right-aligned. */ +#define I2S_CONFIG_ALIGN_ALIGN_Left (0UL) /*!< Left-aligned. */ +#define I2S_CONFIG_ALIGN_ALIGN_Right (1UL) /*!< Right-aligned. */ /* Register: I2S_CONFIG_FORMAT */ /* Description: Frame format. */ @@ -2358,8 +2491,8 @@ /* Bit 0 : Frame format. */ #define I2S_CONFIG_FORMAT_FORMAT_Pos (0UL) /*!< Position of FORMAT field. */ #define I2S_CONFIG_FORMAT_FORMAT_Msk (0x1UL << I2S_CONFIG_FORMAT_FORMAT_Pos) /*!< Bit mask of FORMAT field. */ -#define I2S_CONFIG_FORMAT_FORMAT_I2S (0UL) /*!< Original I2S format. */ -#define I2S_CONFIG_FORMAT_FORMAT_DSP (1UL) /*!< Alternate (DSP) format. */ +#define I2S_CONFIG_FORMAT_FORMAT_I2S (0UL) /*!< Original I2S format. */ +#define I2S_CONFIG_FORMAT_FORMAT_Aligned (1UL) /*!< Alternate (left- or right-aligned) format. */ /* Register: I2S_CONFIG_CHANNELS */ /* Description: Enable channels. */ @@ -2367,9 +2500,9 @@ /* Bits 1..0 : Enable channels. */ #define I2S_CONFIG_CHANNELS_CHANNELS_Pos (0UL) /*!< Position of CHANNELS field. */ #define I2S_CONFIG_CHANNELS_CHANNELS_Msk (0x3UL << I2S_CONFIG_CHANNELS_CHANNELS_Pos) /*!< Bit mask of CHANNELS field. */ -#define I2S_CONFIG_CHANNELS_CHANNELS_STEREO (0UL) /*!< Stereo. */ -#define I2S_CONFIG_CHANNELS_CHANNELS_LEFT (1UL) /*!< Left only. */ -#define I2S_CONFIG_CHANNELS_CHANNELS_RIGHT (2UL) /*!< Right only. */ +#define I2S_CONFIG_CHANNELS_CHANNELS_Stereo (0UL) /*!< Stereo. */ +#define I2S_CONFIG_CHANNELS_CHANNELS_Left (1UL) /*!< Left only. */ +#define I2S_CONFIG_CHANNELS_CHANNELS_Right (2UL) /*!< Right only. */ /* Register: I2S_RXD_PTR */ /* Description: Receive buffer RAM start address. */ @@ -2464,31 +2597,31 @@ /* Register: LPCOMP_SHORTS */ /* Description: Shortcut register */ -/* Bit 4 : Shortcut between EVENTS_CROSS event and TASKS_STOP task */ +/* Bit 4 : Shortcut between CROSS event and STOP task */ #define LPCOMP_SHORTS_CROSS_STOP_Pos (4UL) /*!< Position of CROSS_STOP field. */ #define LPCOMP_SHORTS_CROSS_STOP_Msk (0x1UL << LPCOMP_SHORTS_CROSS_STOP_Pos) /*!< Bit mask of CROSS_STOP field. */ #define LPCOMP_SHORTS_CROSS_STOP_Disabled (0UL) /*!< Disable shortcut */ #define LPCOMP_SHORTS_CROSS_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 3 : Shortcut between EVENTS_UP event and TASKS_STOP task */ +/* Bit 3 : Shortcut between UP event and STOP task */ #define LPCOMP_SHORTS_UP_STOP_Pos (3UL) /*!< Position of UP_STOP field. */ #define LPCOMP_SHORTS_UP_STOP_Msk (0x1UL << LPCOMP_SHORTS_UP_STOP_Pos) /*!< Bit mask of UP_STOP field. */ #define LPCOMP_SHORTS_UP_STOP_Disabled (0UL) /*!< Disable shortcut */ #define LPCOMP_SHORTS_UP_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 2 : Shortcut between EVENTS_DOWN event and TASKS_STOP task */ +/* Bit 2 : Shortcut between DOWN event and STOP task */ #define LPCOMP_SHORTS_DOWN_STOP_Pos (2UL) /*!< Position of DOWN_STOP field. */ #define LPCOMP_SHORTS_DOWN_STOP_Msk (0x1UL << LPCOMP_SHORTS_DOWN_STOP_Pos) /*!< Bit mask of DOWN_STOP field. */ #define LPCOMP_SHORTS_DOWN_STOP_Disabled (0UL) /*!< Disable shortcut */ #define LPCOMP_SHORTS_DOWN_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 1 : Shortcut between EVENTS_READY event and TASKS_STOP task */ +/* Bit 1 : Shortcut between READY event and STOP task */ #define LPCOMP_SHORTS_READY_STOP_Pos (1UL) /*!< Position of READY_STOP field. */ #define LPCOMP_SHORTS_READY_STOP_Msk (0x1UL << LPCOMP_SHORTS_READY_STOP_Pos) /*!< Bit mask of READY_STOP field. */ #define LPCOMP_SHORTS_READY_STOP_Disabled (0UL) /*!< Disable shortcut */ #define LPCOMP_SHORTS_READY_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 0 : Shortcut between EVENTS_READY event and TASKS_SAMPLE task */ +/* Bit 0 : Shortcut between READY event and SAMPLE task */ #define LPCOMP_SHORTS_READY_SAMPLE_Pos (0UL) /*!< Position of READY_SAMPLE field. */ #define LPCOMP_SHORTS_READY_SAMPLE_Msk (0x1UL << LPCOMP_SHORTS_READY_SAMPLE_Pos) /*!< Bit mask of READY_SAMPLE field. */ #define LPCOMP_SHORTS_READY_SAMPLE_Disabled (0UL) /*!< Disable shortcut */ @@ -2497,28 +2630,28 @@ /* Register: LPCOMP_INTENSET */ /* Description: Enable interrupt */ -/* Bit 3 : Write '1' to Enable interrupt on EVENTS_CROSS event */ +/* Bit 3 : Write '1' to Enable interrupt for CROSS event */ #define LPCOMP_INTENSET_CROSS_Pos (3UL) /*!< Position of CROSS field. */ #define LPCOMP_INTENSET_CROSS_Msk (0x1UL << LPCOMP_INTENSET_CROSS_Pos) /*!< Bit mask of CROSS field. */ #define LPCOMP_INTENSET_CROSS_Disabled (0UL) /*!< Read: Disabled */ #define LPCOMP_INTENSET_CROSS_Enabled (1UL) /*!< Read: Enabled */ #define LPCOMP_INTENSET_CROSS_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_UP event */ +/* Bit 2 : Write '1' to Enable interrupt for UP event */ #define LPCOMP_INTENSET_UP_Pos (2UL) /*!< Position of UP field. */ #define LPCOMP_INTENSET_UP_Msk (0x1UL << LPCOMP_INTENSET_UP_Pos) /*!< Bit mask of UP field. */ #define LPCOMP_INTENSET_UP_Disabled (0UL) /*!< Read: Disabled */ #define LPCOMP_INTENSET_UP_Enabled (1UL) /*!< Read: Enabled */ #define LPCOMP_INTENSET_UP_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_DOWN event */ +/* Bit 1 : Write '1' to Enable interrupt for DOWN event */ #define LPCOMP_INTENSET_DOWN_Pos (1UL) /*!< Position of DOWN field. */ #define LPCOMP_INTENSET_DOWN_Msk (0x1UL << LPCOMP_INTENSET_DOWN_Pos) /*!< Bit mask of DOWN field. */ #define LPCOMP_INTENSET_DOWN_Disabled (0UL) /*!< Read: Disabled */ #define LPCOMP_INTENSET_DOWN_Enabled (1UL) /*!< Read: Enabled */ #define LPCOMP_INTENSET_DOWN_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_READY event */ +/* Bit 0 : Write '1' to Enable interrupt for READY event */ #define LPCOMP_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */ #define LPCOMP_INTENSET_READY_Msk (0x1UL << LPCOMP_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ #define LPCOMP_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ @@ -2528,28 +2661,28 @@ /* Register: LPCOMP_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 3 : Write '1' to Clear interrupt on EVENTS_CROSS event */ +/* Bit 3 : Write '1' to Disable interrupt for CROSS event */ #define LPCOMP_INTENCLR_CROSS_Pos (3UL) /*!< Position of CROSS field. */ #define LPCOMP_INTENCLR_CROSS_Msk (0x1UL << LPCOMP_INTENCLR_CROSS_Pos) /*!< Bit mask of CROSS field. */ #define LPCOMP_INTENCLR_CROSS_Disabled (0UL) /*!< Read: Disabled */ #define LPCOMP_INTENCLR_CROSS_Enabled (1UL) /*!< Read: Enabled */ #define LPCOMP_INTENCLR_CROSS_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_UP event */ +/* Bit 2 : Write '1' to Disable interrupt for UP event */ #define LPCOMP_INTENCLR_UP_Pos (2UL) /*!< Position of UP field. */ #define LPCOMP_INTENCLR_UP_Msk (0x1UL << LPCOMP_INTENCLR_UP_Pos) /*!< Bit mask of UP field. */ #define LPCOMP_INTENCLR_UP_Disabled (0UL) /*!< Read: Disabled */ #define LPCOMP_INTENCLR_UP_Enabled (1UL) /*!< Read: Enabled */ #define LPCOMP_INTENCLR_UP_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_DOWN event */ +/* Bit 1 : Write '1' to Disable interrupt for DOWN event */ #define LPCOMP_INTENCLR_DOWN_Pos (1UL) /*!< Position of DOWN field. */ #define LPCOMP_INTENCLR_DOWN_Msk (0x1UL << LPCOMP_INTENCLR_DOWN_Pos) /*!< Bit mask of DOWN field. */ #define LPCOMP_INTENCLR_DOWN_Disabled (0UL) /*!< Read: Disabled */ #define LPCOMP_INTENCLR_DOWN_Enabled (1UL) /*!< Read: Enabled */ #define LPCOMP_INTENCLR_DOWN_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_READY event */ +/* Bit 0 : Write '1' to Disable interrupt for READY event */ #define LPCOMP_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */ #define LPCOMP_INTENCLR_READY_Msk (0x1UL << LPCOMP_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ #define LPCOMP_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ @@ -2562,8 +2695,8 @@ /* Bit 0 : Result of last compare. Decision point SAMPLE task. */ #define LPCOMP_RESULT_RESULT_Pos (0UL) /*!< Position of RESULT field. */ #define LPCOMP_RESULT_RESULT_Msk (0x1UL << LPCOMP_RESULT_RESULT_Pos) /*!< Bit mask of RESULT field. */ -#define LPCOMP_RESULT_RESULT_Bellow (0UL) /*!< Input voltage is below the reference threshold (VIN+ < VIN-). */ -#define LPCOMP_RESULT_RESULT_Above (1UL) /*!< Input voltage is above the reference threshold (VIN+ > VIN-). */ +#define LPCOMP_RESULT_RESULT_Below (0UL) /*!< Input voltage is below the reference threshold (VIN+ < VIN-). */ +#define LPCOMP_RESULT_RESULT_Above (1UL) /*!< Input voltage is above the reference threshold (VIN+ > VIN-). */ /* Register: LPCOMP_ENABLE */ /* Description: Enable LPCOMP */ @@ -2647,73 +2780,73 @@ /* Register: MWU_INTEN */ /* Description: Enable or disable interrupt */ -/* Bit 27 : Enable or disable interrupt on EVENTS_PREGION[1].RA event */ +/* Bit 27 : Enable or disable interrupt for PREGION[1].RA event */ #define MWU_INTEN_PREGION1RA_Pos (27UL) /*!< Position of PREGION1RA field. */ #define MWU_INTEN_PREGION1RA_Msk (0x1UL << MWU_INTEN_PREGION1RA_Pos) /*!< Bit mask of PREGION1RA field. */ #define MWU_INTEN_PREGION1RA_Disabled (0UL) /*!< Disable */ #define MWU_INTEN_PREGION1RA_Enabled (1UL) /*!< Enable */ -/* Bit 26 : Enable or disable interrupt on EVENTS_PREGION[1].WA event */ +/* Bit 26 : Enable or disable interrupt for PREGION[1].WA event */ #define MWU_INTEN_PREGION1WA_Pos (26UL) /*!< Position of PREGION1WA field. */ #define MWU_INTEN_PREGION1WA_Msk (0x1UL << MWU_INTEN_PREGION1WA_Pos) /*!< Bit mask of PREGION1WA field. */ #define MWU_INTEN_PREGION1WA_Disabled (0UL) /*!< Disable */ #define MWU_INTEN_PREGION1WA_Enabled (1UL) /*!< Enable */ -/* Bit 25 : Enable or disable interrupt on EVENTS_PREGION[0].RA event */ +/* Bit 25 : Enable or disable interrupt for PREGION[0].RA event */ #define MWU_INTEN_PREGION0RA_Pos (25UL) /*!< Position of PREGION0RA field. */ #define MWU_INTEN_PREGION0RA_Msk (0x1UL << MWU_INTEN_PREGION0RA_Pos) /*!< Bit mask of PREGION0RA field. */ #define MWU_INTEN_PREGION0RA_Disabled (0UL) /*!< Disable */ #define MWU_INTEN_PREGION0RA_Enabled (1UL) /*!< Enable */ -/* Bit 24 : Enable or disable interrupt on EVENTS_PREGION[0].WA event */ +/* Bit 24 : Enable or disable interrupt for PREGION[0].WA event */ #define MWU_INTEN_PREGION0WA_Pos (24UL) /*!< Position of PREGION0WA field. */ #define MWU_INTEN_PREGION0WA_Msk (0x1UL << MWU_INTEN_PREGION0WA_Pos) /*!< Bit mask of PREGION0WA field. */ #define MWU_INTEN_PREGION0WA_Disabled (0UL) /*!< Disable */ #define MWU_INTEN_PREGION0WA_Enabled (1UL) /*!< Enable */ -/* Bit 7 : Enable or disable interrupt on EVENTS_REGION[3].RA event */ +/* Bit 7 : Enable or disable interrupt for REGION[3].RA event */ #define MWU_INTEN_REGION3RA_Pos (7UL) /*!< Position of REGION3RA field. */ #define MWU_INTEN_REGION3RA_Msk (0x1UL << MWU_INTEN_REGION3RA_Pos) /*!< Bit mask of REGION3RA field. */ #define MWU_INTEN_REGION3RA_Disabled (0UL) /*!< Disable */ #define MWU_INTEN_REGION3RA_Enabled (1UL) /*!< Enable */ -/* Bit 6 : Enable or disable interrupt on EVENTS_REGION[3].WA event */ +/* Bit 6 : Enable or disable interrupt for REGION[3].WA event */ #define MWU_INTEN_REGION3WA_Pos (6UL) /*!< Position of REGION3WA field. */ #define MWU_INTEN_REGION3WA_Msk (0x1UL << MWU_INTEN_REGION3WA_Pos) /*!< Bit mask of REGION3WA field. */ #define MWU_INTEN_REGION3WA_Disabled (0UL) /*!< Disable */ #define MWU_INTEN_REGION3WA_Enabled (1UL) /*!< Enable */ -/* Bit 5 : Enable or disable interrupt on EVENTS_REGION[2].RA event */ +/* Bit 5 : Enable or disable interrupt for REGION[2].RA event */ #define MWU_INTEN_REGION2RA_Pos (5UL) /*!< Position of REGION2RA field. */ #define MWU_INTEN_REGION2RA_Msk (0x1UL << MWU_INTEN_REGION2RA_Pos) /*!< Bit mask of REGION2RA field. */ #define MWU_INTEN_REGION2RA_Disabled (0UL) /*!< Disable */ #define MWU_INTEN_REGION2RA_Enabled (1UL) /*!< Enable */ -/* Bit 4 : Enable or disable interrupt on EVENTS_REGION[2].WA event */ +/* Bit 4 : Enable or disable interrupt for REGION[2].WA event */ #define MWU_INTEN_REGION2WA_Pos (4UL) /*!< Position of REGION2WA field. */ #define MWU_INTEN_REGION2WA_Msk (0x1UL << MWU_INTEN_REGION2WA_Pos) /*!< Bit mask of REGION2WA field. */ #define MWU_INTEN_REGION2WA_Disabled (0UL) /*!< Disable */ #define MWU_INTEN_REGION2WA_Enabled (1UL) /*!< Enable */ -/* Bit 3 : Enable or disable interrupt on EVENTS_REGION[1].RA event */ +/* Bit 3 : Enable or disable interrupt for REGION[1].RA event */ #define MWU_INTEN_REGION1RA_Pos (3UL) /*!< Position of REGION1RA field. */ #define MWU_INTEN_REGION1RA_Msk (0x1UL << MWU_INTEN_REGION1RA_Pos) /*!< Bit mask of REGION1RA field. */ #define MWU_INTEN_REGION1RA_Disabled (0UL) /*!< Disable */ #define MWU_INTEN_REGION1RA_Enabled (1UL) /*!< Enable */ -/* Bit 2 : Enable or disable interrupt on EVENTS_REGION[1].WA event */ +/* Bit 2 : Enable or disable interrupt for REGION[1].WA event */ #define MWU_INTEN_REGION1WA_Pos (2UL) /*!< Position of REGION1WA field. */ #define MWU_INTEN_REGION1WA_Msk (0x1UL << MWU_INTEN_REGION1WA_Pos) /*!< Bit mask of REGION1WA field. */ #define MWU_INTEN_REGION1WA_Disabled (0UL) /*!< Disable */ #define MWU_INTEN_REGION1WA_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable interrupt on EVENTS_REGION[0].RA event */ +/* Bit 1 : Enable or disable interrupt for REGION[0].RA event */ #define MWU_INTEN_REGION0RA_Pos (1UL) /*!< Position of REGION0RA field. */ #define MWU_INTEN_REGION0RA_Msk (0x1UL << MWU_INTEN_REGION0RA_Pos) /*!< Bit mask of REGION0RA field. */ #define MWU_INTEN_REGION0RA_Disabled (0UL) /*!< Disable */ #define MWU_INTEN_REGION0RA_Enabled (1UL) /*!< Enable */ -/* Bit 0 : Enable or disable interrupt on EVENTS_REGION[0].WA event */ +/* Bit 0 : Enable or disable interrupt for REGION[0].WA event */ #define MWU_INTEN_REGION0WA_Pos (0UL) /*!< Position of REGION0WA field. */ #define MWU_INTEN_REGION0WA_Msk (0x1UL << MWU_INTEN_REGION0WA_Pos) /*!< Bit mask of REGION0WA field. */ #define MWU_INTEN_REGION0WA_Disabled (0UL) /*!< Disable */ @@ -2722,84 +2855,84 @@ /* Register: MWU_INTENSET */ /* Description: Enable interrupt */ -/* Bit 27 : Write '1' to Enable interrupt on EVENTS_PREGION[1].RA event */ +/* Bit 27 : Write '1' to Enable interrupt for PREGION[1].RA event */ #define MWU_INTENSET_PREGION1RA_Pos (27UL) /*!< Position of PREGION1RA field. */ #define MWU_INTENSET_PREGION1RA_Msk (0x1UL << MWU_INTENSET_PREGION1RA_Pos) /*!< Bit mask of PREGION1RA field. */ #define MWU_INTENSET_PREGION1RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENSET_PREGION1RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENSET_PREGION1RA_Set (1UL) /*!< Enable */ -/* Bit 26 : Write '1' to Enable interrupt on EVENTS_PREGION[1].WA event */ +/* Bit 26 : Write '1' to Enable interrupt for PREGION[1].WA event */ #define MWU_INTENSET_PREGION1WA_Pos (26UL) /*!< Position of PREGION1WA field. */ #define MWU_INTENSET_PREGION1WA_Msk (0x1UL << MWU_INTENSET_PREGION1WA_Pos) /*!< Bit mask of PREGION1WA field. */ #define MWU_INTENSET_PREGION1WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENSET_PREGION1WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENSET_PREGION1WA_Set (1UL) /*!< Enable */ -/* Bit 25 : Write '1' to Enable interrupt on EVENTS_PREGION[0].RA event */ +/* Bit 25 : Write '1' to Enable interrupt for PREGION[0].RA event */ #define MWU_INTENSET_PREGION0RA_Pos (25UL) /*!< Position of PREGION0RA field. */ #define MWU_INTENSET_PREGION0RA_Msk (0x1UL << MWU_INTENSET_PREGION0RA_Pos) /*!< Bit mask of PREGION0RA field. */ #define MWU_INTENSET_PREGION0RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENSET_PREGION0RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENSET_PREGION0RA_Set (1UL) /*!< Enable */ -/* Bit 24 : Write '1' to Enable interrupt on EVENTS_PREGION[0].WA event */ +/* Bit 24 : Write '1' to Enable interrupt for PREGION[0].WA event */ #define MWU_INTENSET_PREGION0WA_Pos (24UL) /*!< Position of PREGION0WA field. */ #define MWU_INTENSET_PREGION0WA_Msk (0x1UL << MWU_INTENSET_PREGION0WA_Pos) /*!< Bit mask of PREGION0WA field. */ #define MWU_INTENSET_PREGION0WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENSET_PREGION0WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENSET_PREGION0WA_Set (1UL) /*!< Enable */ -/* Bit 7 : Write '1' to Enable interrupt on EVENTS_REGION[3].RA event */ +/* Bit 7 : Write '1' to Enable interrupt for REGION[3].RA event */ #define MWU_INTENSET_REGION3RA_Pos (7UL) /*!< Position of REGION3RA field. */ #define MWU_INTENSET_REGION3RA_Msk (0x1UL << MWU_INTENSET_REGION3RA_Pos) /*!< Bit mask of REGION3RA field. */ #define MWU_INTENSET_REGION3RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENSET_REGION3RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENSET_REGION3RA_Set (1UL) /*!< Enable */ -/* Bit 6 : Write '1' to Enable interrupt on EVENTS_REGION[3].WA event */ +/* Bit 6 : Write '1' to Enable interrupt for REGION[3].WA event */ #define MWU_INTENSET_REGION3WA_Pos (6UL) /*!< Position of REGION3WA field. */ #define MWU_INTENSET_REGION3WA_Msk (0x1UL << MWU_INTENSET_REGION3WA_Pos) /*!< Bit mask of REGION3WA field. */ #define MWU_INTENSET_REGION3WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENSET_REGION3WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENSET_REGION3WA_Set (1UL) /*!< Enable */ -/* Bit 5 : Write '1' to Enable interrupt on EVENTS_REGION[2].RA event */ +/* Bit 5 : Write '1' to Enable interrupt for REGION[2].RA event */ #define MWU_INTENSET_REGION2RA_Pos (5UL) /*!< Position of REGION2RA field. */ #define MWU_INTENSET_REGION2RA_Msk (0x1UL << MWU_INTENSET_REGION2RA_Pos) /*!< Bit mask of REGION2RA field. */ #define MWU_INTENSET_REGION2RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENSET_REGION2RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENSET_REGION2RA_Set (1UL) /*!< Enable */ -/* Bit 4 : Write '1' to Enable interrupt on EVENTS_REGION[2].WA event */ +/* Bit 4 : Write '1' to Enable interrupt for REGION[2].WA event */ #define MWU_INTENSET_REGION2WA_Pos (4UL) /*!< Position of REGION2WA field. */ #define MWU_INTENSET_REGION2WA_Msk (0x1UL << MWU_INTENSET_REGION2WA_Pos) /*!< Bit mask of REGION2WA field. */ #define MWU_INTENSET_REGION2WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENSET_REGION2WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENSET_REGION2WA_Set (1UL) /*!< Enable */ -/* Bit 3 : Write '1' to Enable interrupt on EVENTS_REGION[1].RA event */ +/* Bit 3 : Write '1' to Enable interrupt for REGION[1].RA event */ #define MWU_INTENSET_REGION1RA_Pos (3UL) /*!< Position of REGION1RA field. */ #define MWU_INTENSET_REGION1RA_Msk (0x1UL << MWU_INTENSET_REGION1RA_Pos) /*!< Bit mask of REGION1RA field. */ #define MWU_INTENSET_REGION1RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENSET_REGION1RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENSET_REGION1RA_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_REGION[1].WA event */ +/* Bit 2 : Write '1' to Enable interrupt for REGION[1].WA event */ #define MWU_INTENSET_REGION1WA_Pos (2UL) /*!< Position of REGION1WA field. */ #define MWU_INTENSET_REGION1WA_Msk (0x1UL << MWU_INTENSET_REGION1WA_Pos) /*!< Bit mask of REGION1WA field. */ #define MWU_INTENSET_REGION1WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENSET_REGION1WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENSET_REGION1WA_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_REGION[0].RA event */ +/* Bit 1 : Write '1' to Enable interrupt for REGION[0].RA event */ #define MWU_INTENSET_REGION0RA_Pos (1UL) /*!< Position of REGION0RA field. */ #define MWU_INTENSET_REGION0RA_Msk (0x1UL << MWU_INTENSET_REGION0RA_Pos) /*!< Bit mask of REGION0RA field. */ #define MWU_INTENSET_REGION0RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENSET_REGION0RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENSET_REGION0RA_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_REGION[0].WA event */ +/* Bit 0 : Write '1' to Enable interrupt for REGION[0].WA event */ #define MWU_INTENSET_REGION0WA_Pos (0UL) /*!< Position of REGION0WA field. */ #define MWU_INTENSET_REGION0WA_Msk (0x1UL << MWU_INTENSET_REGION0WA_Pos) /*!< Bit mask of REGION0WA field. */ #define MWU_INTENSET_REGION0WA_Disabled (0UL) /*!< Read: Disabled */ @@ -2809,84 +2942,84 @@ /* Register: MWU_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 27 : Write '1' to Clear interrupt on EVENTS_PREGION[1].RA event */ +/* Bit 27 : Write '1' to Disable interrupt for PREGION[1].RA event */ #define MWU_INTENCLR_PREGION1RA_Pos (27UL) /*!< Position of PREGION1RA field. */ #define MWU_INTENCLR_PREGION1RA_Msk (0x1UL << MWU_INTENCLR_PREGION1RA_Pos) /*!< Bit mask of PREGION1RA field. */ #define MWU_INTENCLR_PREGION1RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENCLR_PREGION1RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENCLR_PREGION1RA_Clear (1UL) /*!< Disable */ -/* Bit 26 : Write '1' to Clear interrupt on EVENTS_PREGION[1].WA event */ +/* Bit 26 : Write '1' to Disable interrupt for PREGION[1].WA event */ #define MWU_INTENCLR_PREGION1WA_Pos (26UL) /*!< Position of PREGION1WA field. */ #define MWU_INTENCLR_PREGION1WA_Msk (0x1UL << MWU_INTENCLR_PREGION1WA_Pos) /*!< Bit mask of PREGION1WA field. */ #define MWU_INTENCLR_PREGION1WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENCLR_PREGION1WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENCLR_PREGION1WA_Clear (1UL) /*!< Disable */ -/* Bit 25 : Write '1' to Clear interrupt on EVENTS_PREGION[0].RA event */ +/* Bit 25 : Write '1' to Disable interrupt for PREGION[0].RA event */ #define MWU_INTENCLR_PREGION0RA_Pos (25UL) /*!< Position of PREGION0RA field. */ #define MWU_INTENCLR_PREGION0RA_Msk (0x1UL << MWU_INTENCLR_PREGION0RA_Pos) /*!< Bit mask of PREGION0RA field. */ #define MWU_INTENCLR_PREGION0RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENCLR_PREGION0RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENCLR_PREGION0RA_Clear (1UL) /*!< Disable */ -/* Bit 24 : Write '1' to Clear interrupt on EVENTS_PREGION[0].WA event */ +/* Bit 24 : Write '1' to Disable interrupt for PREGION[0].WA event */ #define MWU_INTENCLR_PREGION0WA_Pos (24UL) /*!< Position of PREGION0WA field. */ #define MWU_INTENCLR_PREGION0WA_Msk (0x1UL << MWU_INTENCLR_PREGION0WA_Pos) /*!< Bit mask of PREGION0WA field. */ #define MWU_INTENCLR_PREGION0WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENCLR_PREGION0WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENCLR_PREGION0WA_Clear (1UL) /*!< Disable */ -/* Bit 7 : Write '1' to Clear interrupt on EVENTS_REGION[3].RA event */ +/* Bit 7 : Write '1' to Disable interrupt for REGION[3].RA event */ #define MWU_INTENCLR_REGION3RA_Pos (7UL) /*!< Position of REGION3RA field. */ #define MWU_INTENCLR_REGION3RA_Msk (0x1UL << MWU_INTENCLR_REGION3RA_Pos) /*!< Bit mask of REGION3RA field. */ #define MWU_INTENCLR_REGION3RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENCLR_REGION3RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENCLR_REGION3RA_Clear (1UL) /*!< Disable */ -/* Bit 6 : Write '1' to Clear interrupt on EVENTS_REGION[3].WA event */ +/* Bit 6 : Write '1' to Disable interrupt for REGION[3].WA event */ #define MWU_INTENCLR_REGION3WA_Pos (6UL) /*!< Position of REGION3WA field. */ #define MWU_INTENCLR_REGION3WA_Msk (0x1UL << MWU_INTENCLR_REGION3WA_Pos) /*!< Bit mask of REGION3WA field. */ #define MWU_INTENCLR_REGION3WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENCLR_REGION3WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENCLR_REGION3WA_Clear (1UL) /*!< Disable */ -/* Bit 5 : Write '1' to Clear interrupt on EVENTS_REGION[2].RA event */ +/* Bit 5 : Write '1' to Disable interrupt for REGION[2].RA event */ #define MWU_INTENCLR_REGION2RA_Pos (5UL) /*!< Position of REGION2RA field. */ #define MWU_INTENCLR_REGION2RA_Msk (0x1UL << MWU_INTENCLR_REGION2RA_Pos) /*!< Bit mask of REGION2RA field. */ #define MWU_INTENCLR_REGION2RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENCLR_REGION2RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENCLR_REGION2RA_Clear (1UL) /*!< Disable */ -/* Bit 4 : Write '1' to Clear interrupt on EVENTS_REGION[2].WA event */ +/* Bit 4 : Write '1' to Disable interrupt for REGION[2].WA event */ #define MWU_INTENCLR_REGION2WA_Pos (4UL) /*!< Position of REGION2WA field. */ #define MWU_INTENCLR_REGION2WA_Msk (0x1UL << MWU_INTENCLR_REGION2WA_Pos) /*!< Bit mask of REGION2WA field. */ #define MWU_INTENCLR_REGION2WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENCLR_REGION2WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENCLR_REGION2WA_Clear (1UL) /*!< Disable */ -/* Bit 3 : Write '1' to Clear interrupt on EVENTS_REGION[1].RA event */ +/* Bit 3 : Write '1' to Disable interrupt for REGION[1].RA event */ #define MWU_INTENCLR_REGION1RA_Pos (3UL) /*!< Position of REGION1RA field. */ #define MWU_INTENCLR_REGION1RA_Msk (0x1UL << MWU_INTENCLR_REGION1RA_Pos) /*!< Bit mask of REGION1RA field. */ #define MWU_INTENCLR_REGION1RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENCLR_REGION1RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENCLR_REGION1RA_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_REGION[1].WA event */ +/* Bit 2 : Write '1' to Disable interrupt for REGION[1].WA event */ #define MWU_INTENCLR_REGION1WA_Pos (2UL) /*!< Position of REGION1WA field. */ #define MWU_INTENCLR_REGION1WA_Msk (0x1UL << MWU_INTENCLR_REGION1WA_Pos) /*!< Bit mask of REGION1WA field. */ #define MWU_INTENCLR_REGION1WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENCLR_REGION1WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENCLR_REGION1WA_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_REGION[0].RA event */ +/* Bit 1 : Write '1' to Disable interrupt for REGION[0].RA event */ #define MWU_INTENCLR_REGION0RA_Pos (1UL) /*!< Position of REGION0RA field. */ #define MWU_INTENCLR_REGION0RA_Msk (0x1UL << MWU_INTENCLR_REGION0RA_Pos) /*!< Bit mask of REGION0RA field. */ #define MWU_INTENCLR_REGION0RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_INTENCLR_REGION0RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_INTENCLR_REGION0RA_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_REGION[0].WA event */ +/* Bit 0 : Write '1' to Disable interrupt for REGION[0].WA event */ #define MWU_INTENCLR_REGION0WA_Pos (0UL) /*!< Position of REGION0WA field. */ #define MWU_INTENCLR_REGION0WA_Msk (0x1UL << MWU_INTENCLR_REGION0WA_Pos) /*!< Bit mask of REGION0WA field. */ #define MWU_INTENCLR_REGION0WA_Disabled (0UL) /*!< Read: Disabled */ @@ -2896,73 +3029,73 @@ /* Register: MWU_NMIEN */ /* Description: Enable or disable non-maskable interrupt */ -/* Bit 27 : Enable or disable non-maskable interrupt on EVENTS_PREGION[1].RA event */ +/* Bit 27 : Enable or disable non-maskable interrupt for PREGION[1].RA event */ #define MWU_NMIEN_PREGION1RA_Pos (27UL) /*!< Position of PREGION1RA field. */ #define MWU_NMIEN_PREGION1RA_Msk (0x1UL << MWU_NMIEN_PREGION1RA_Pos) /*!< Bit mask of PREGION1RA field. */ #define MWU_NMIEN_PREGION1RA_Disabled (0UL) /*!< Disable */ #define MWU_NMIEN_PREGION1RA_Enabled (1UL) /*!< Enable */ -/* Bit 26 : Enable or disable non-maskable interrupt on EVENTS_PREGION[1].WA event */ +/* Bit 26 : Enable or disable non-maskable interrupt for PREGION[1].WA event */ #define MWU_NMIEN_PREGION1WA_Pos (26UL) /*!< Position of PREGION1WA field. */ #define MWU_NMIEN_PREGION1WA_Msk (0x1UL << MWU_NMIEN_PREGION1WA_Pos) /*!< Bit mask of PREGION1WA field. */ #define MWU_NMIEN_PREGION1WA_Disabled (0UL) /*!< Disable */ #define MWU_NMIEN_PREGION1WA_Enabled (1UL) /*!< Enable */ -/* Bit 25 : Enable or disable non-maskable interrupt on EVENTS_PREGION[0].RA event */ +/* Bit 25 : Enable or disable non-maskable interrupt for PREGION[0].RA event */ #define MWU_NMIEN_PREGION0RA_Pos (25UL) /*!< Position of PREGION0RA field. */ #define MWU_NMIEN_PREGION0RA_Msk (0x1UL << MWU_NMIEN_PREGION0RA_Pos) /*!< Bit mask of PREGION0RA field. */ #define MWU_NMIEN_PREGION0RA_Disabled (0UL) /*!< Disable */ #define MWU_NMIEN_PREGION0RA_Enabled (1UL) /*!< Enable */ -/* Bit 24 : Enable or disable non-maskable interrupt on EVENTS_PREGION[0].WA event */ +/* Bit 24 : Enable or disable non-maskable interrupt for PREGION[0].WA event */ #define MWU_NMIEN_PREGION0WA_Pos (24UL) /*!< Position of PREGION0WA field. */ #define MWU_NMIEN_PREGION0WA_Msk (0x1UL << MWU_NMIEN_PREGION0WA_Pos) /*!< Bit mask of PREGION0WA field. */ #define MWU_NMIEN_PREGION0WA_Disabled (0UL) /*!< Disable */ #define MWU_NMIEN_PREGION0WA_Enabled (1UL) /*!< Enable */ -/* Bit 7 : Enable or disable non-maskable interrupt on EVENTS_REGION[3].RA event */ +/* Bit 7 : Enable or disable non-maskable interrupt for REGION[3].RA event */ #define MWU_NMIEN_REGION3RA_Pos (7UL) /*!< Position of REGION3RA field. */ #define MWU_NMIEN_REGION3RA_Msk (0x1UL << MWU_NMIEN_REGION3RA_Pos) /*!< Bit mask of REGION3RA field. */ #define MWU_NMIEN_REGION3RA_Disabled (0UL) /*!< Disable */ #define MWU_NMIEN_REGION3RA_Enabled (1UL) /*!< Enable */ -/* Bit 6 : Enable or disable non-maskable interrupt on EVENTS_REGION[3].WA event */ +/* Bit 6 : Enable or disable non-maskable interrupt for REGION[3].WA event */ #define MWU_NMIEN_REGION3WA_Pos (6UL) /*!< Position of REGION3WA field. */ #define MWU_NMIEN_REGION3WA_Msk (0x1UL << MWU_NMIEN_REGION3WA_Pos) /*!< Bit mask of REGION3WA field. */ #define MWU_NMIEN_REGION3WA_Disabled (0UL) /*!< Disable */ #define MWU_NMIEN_REGION3WA_Enabled (1UL) /*!< Enable */ -/* Bit 5 : Enable or disable non-maskable interrupt on EVENTS_REGION[2].RA event */ +/* Bit 5 : Enable or disable non-maskable interrupt for REGION[2].RA event */ #define MWU_NMIEN_REGION2RA_Pos (5UL) /*!< Position of REGION2RA field. */ #define MWU_NMIEN_REGION2RA_Msk (0x1UL << MWU_NMIEN_REGION2RA_Pos) /*!< Bit mask of REGION2RA field. */ #define MWU_NMIEN_REGION2RA_Disabled (0UL) /*!< Disable */ #define MWU_NMIEN_REGION2RA_Enabled (1UL) /*!< Enable */ -/* Bit 4 : Enable or disable non-maskable interrupt on EVENTS_REGION[2].WA event */ +/* Bit 4 : Enable or disable non-maskable interrupt for REGION[2].WA event */ #define MWU_NMIEN_REGION2WA_Pos (4UL) /*!< Position of REGION2WA field. */ #define MWU_NMIEN_REGION2WA_Msk (0x1UL << MWU_NMIEN_REGION2WA_Pos) /*!< Bit mask of REGION2WA field. */ #define MWU_NMIEN_REGION2WA_Disabled (0UL) /*!< Disable */ #define MWU_NMIEN_REGION2WA_Enabled (1UL) /*!< Enable */ -/* Bit 3 : Enable or disable non-maskable interrupt on EVENTS_REGION[1].RA event */ +/* Bit 3 : Enable or disable non-maskable interrupt for REGION[1].RA event */ #define MWU_NMIEN_REGION1RA_Pos (3UL) /*!< Position of REGION1RA field. */ #define MWU_NMIEN_REGION1RA_Msk (0x1UL << MWU_NMIEN_REGION1RA_Pos) /*!< Bit mask of REGION1RA field. */ #define MWU_NMIEN_REGION1RA_Disabled (0UL) /*!< Disable */ #define MWU_NMIEN_REGION1RA_Enabled (1UL) /*!< Enable */ -/* Bit 2 : Enable or disable non-maskable interrupt on EVENTS_REGION[1].WA event */ +/* Bit 2 : Enable or disable non-maskable interrupt for REGION[1].WA event */ #define MWU_NMIEN_REGION1WA_Pos (2UL) /*!< Position of REGION1WA field. */ #define MWU_NMIEN_REGION1WA_Msk (0x1UL << MWU_NMIEN_REGION1WA_Pos) /*!< Bit mask of REGION1WA field. */ #define MWU_NMIEN_REGION1WA_Disabled (0UL) /*!< Disable */ #define MWU_NMIEN_REGION1WA_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable non-maskable interrupt on EVENTS_REGION[0].RA event */ +/* Bit 1 : Enable or disable non-maskable interrupt for REGION[0].RA event */ #define MWU_NMIEN_REGION0RA_Pos (1UL) /*!< Position of REGION0RA field. */ #define MWU_NMIEN_REGION0RA_Msk (0x1UL << MWU_NMIEN_REGION0RA_Pos) /*!< Bit mask of REGION0RA field. */ #define MWU_NMIEN_REGION0RA_Disabled (0UL) /*!< Disable */ #define MWU_NMIEN_REGION0RA_Enabled (1UL) /*!< Enable */ -/* Bit 0 : Enable or disable non-maskable interrupt on EVENTS_REGION[0].WA event */ +/* Bit 0 : Enable or disable non-maskable interrupt for REGION[0].WA event */ #define MWU_NMIEN_REGION0WA_Pos (0UL) /*!< Position of REGION0WA field. */ #define MWU_NMIEN_REGION0WA_Msk (0x1UL << MWU_NMIEN_REGION0WA_Pos) /*!< Bit mask of REGION0WA field. */ #define MWU_NMIEN_REGION0WA_Disabled (0UL) /*!< Disable */ @@ -2971,84 +3104,84 @@ /* Register: MWU_NMIENSET */ /* Description: Enable non-maskable interrupt */ -/* Bit 27 : Write '1' to Enable non-maskable interrupt on EVENTS_PREGION[1].RA event */ +/* Bit 27 : Write '1' to Enable non-maskable interrupt for PREGION[1].RA event */ #define MWU_NMIENSET_PREGION1RA_Pos (27UL) /*!< Position of PREGION1RA field. */ #define MWU_NMIENSET_PREGION1RA_Msk (0x1UL << MWU_NMIENSET_PREGION1RA_Pos) /*!< Bit mask of PREGION1RA field. */ #define MWU_NMIENSET_PREGION1RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENSET_PREGION1RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENSET_PREGION1RA_Set (1UL) /*!< Enable */ -/* Bit 26 : Write '1' to Enable non-maskable interrupt on EVENTS_PREGION[1].WA event */ +/* Bit 26 : Write '1' to Enable non-maskable interrupt for PREGION[1].WA event */ #define MWU_NMIENSET_PREGION1WA_Pos (26UL) /*!< Position of PREGION1WA field. */ #define MWU_NMIENSET_PREGION1WA_Msk (0x1UL << MWU_NMIENSET_PREGION1WA_Pos) /*!< Bit mask of PREGION1WA field. */ #define MWU_NMIENSET_PREGION1WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENSET_PREGION1WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENSET_PREGION1WA_Set (1UL) /*!< Enable */ -/* Bit 25 : Write '1' to Enable non-maskable interrupt on EVENTS_PREGION[0].RA event */ +/* Bit 25 : Write '1' to Enable non-maskable interrupt for PREGION[0].RA event */ #define MWU_NMIENSET_PREGION0RA_Pos (25UL) /*!< Position of PREGION0RA field. */ #define MWU_NMIENSET_PREGION0RA_Msk (0x1UL << MWU_NMIENSET_PREGION0RA_Pos) /*!< Bit mask of PREGION0RA field. */ #define MWU_NMIENSET_PREGION0RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENSET_PREGION0RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENSET_PREGION0RA_Set (1UL) /*!< Enable */ -/* Bit 24 : Write '1' to Enable non-maskable interrupt on EVENTS_PREGION[0].WA event */ +/* Bit 24 : Write '1' to Enable non-maskable interrupt for PREGION[0].WA event */ #define MWU_NMIENSET_PREGION0WA_Pos (24UL) /*!< Position of PREGION0WA field. */ #define MWU_NMIENSET_PREGION0WA_Msk (0x1UL << MWU_NMIENSET_PREGION0WA_Pos) /*!< Bit mask of PREGION0WA field. */ #define MWU_NMIENSET_PREGION0WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENSET_PREGION0WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENSET_PREGION0WA_Set (1UL) /*!< Enable */ -/* Bit 7 : Write '1' to Enable non-maskable interrupt on EVENTS_REGION[3].RA event */ +/* Bit 7 : Write '1' to Enable non-maskable interrupt for REGION[3].RA event */ #define MWU_NMIENSET_REGION3RA_Pos (7UL) /*!< Position of REGION3RA field. */ #define MWU_NMIENSET_REGION3RA_Msk (0x1UL << MWU_NMIENSET_REGION3RA_Pos) /*!< Bit mask of REGION3RA field. */ #define MWU_NMIENSET_REGION3RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENSET_REGION3RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENSET_REGION3RA_Set (1UL) /*!< Enable */ -/* Bit 6 : Write '1' to Enable non-maskable interrupt on EVENTS_REGION[3].WA event */ +/* Bit 6 : Write '1' to Enable non-maskable interrupt for REGION[3].WA event */ #define MWU_NMIENSET_REGION3WA_Pos (6UL) /*!< Position of REGION3WA field. */ #define MWU_NMIENSET_REGION3WA_Msk (0x1UL << MWU_NMIENSET_REGION3WA_Pos) /*!< Bit mask of REGION3WA field. */ #define MWU_NMIENSET_REGION3WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENSET_REGION3WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENSET_REGION3WA_Set (1UL) /*!< Enable */ -/* Bit 5 : Write '1' to Enable non-maskable interrupt on EVENTS_REGION[2].RA event */ +/* Bit 5 : Write '1' to Enable non-maskable interrupt for REGION[2].RA event */ #define MWU_NMIENSET_REGION2RA_Pos (5UL) /*!< Position of REGION2RA field. */ #define MWU_NMIENSET_REGION2RA_Msk (0x1UL << MWU_NMIENSET_REGION2RA_Pos) /*!< Bit mask of REGION2RA field. */ #define MWU_NMIENSET_REGION2RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENSET_REGION2RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENSET_REGION2RA_Set (1UL) /*!< Enable */ -/* Bit 4 : Write '1' to Enable non-maskable interrupt on EVENTS_REGION[2].WA event */ +/* Bit 4 : Write '1' to Enable non-maskable interrupt for REGION[2].WA event */ #define MWU_NMIENSET_REGION2WA_Pos (4UL) /*!< Position of REGION2WA field. */ #define MWU_NMIENSET_REGION2WA_Msk (0x1UL << MWU_NMIENSET_REGION2WA_Pos) /*!< Bit mask of REGION2WA field. */ #define MWU_NMIENSET_REGION2WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENSET_REGION2WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENSET_REGION2WA_Set (1UL) /*!< Enable */ -/* Bit 3 : Write '1' to Enable non-maskable interrupt on EVENTS_REGION[1].RA event */ +/* Bit 3 : Write '1' to Enable non-maskable interrupt for REGION[1].RA event */ #define MWU_NMIENSET_REGION1RA_Pos (3UL) /*!< Position of REGION1RA field. */ #define MWU_NMIENSET_REGION1RA_Msk (0x1UL << MWU_NMIENSET_REGION1RA_Pos) /*!< Bit mask of REGION1RA field. */ #define MWU_NMIENSET_REGION1RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENSET_REGION1RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENSET_REGION1RA_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable non-maskable interrupt on EVENTS_REGION[1].WA event */ +/* Bit 2 : Write '1' to Enable non-maskable interrupt for REGION[1].WA event */ #define MWU_NMIENSET_REGION1WA_Pos (2UL) /*!< Position of REGION1WA field. */ #define MWU_NMIENSET_REGION1WA_Msk (0x1UL << MWU_NMIENSET_REGION1WA_Pos) /*!< Bit mask of REGION1WA field. */ #define MWU_NMIENSET_REGION1WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENSET_REGION1WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENSET_REGION1WA_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable non-maskable interrupt on EVENTS_REGION[0].RA event */ +/* Bit 1 : Write '1' to Enable non-maskable interrupt for REGION[0].RA event */ #define MWU_NMIENSET_REGION0RA_Pos (1UL) /*!< Position of REGION0RA field. */ #define MWU_NMIENSET_REGION0RA_Msk (0x1UL << MWU_NMIENSET_REGION0RA_Pos) /*!< Bit mask of REGION0RA field. */ #define MWU_NMIENSET_REGION0RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENSET_REGION0RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENSET_REGION0RA_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable non-maskable interrupt on EVENTS_REGION[0].WA event */ +/* Bit 0 : Write '1' to Enable non-maskable interrupt for REGION[0].WA event */ #define MWU_NMIENSET_REGION0WA_Pos (0UL) /*!< Position of REGION0WA field. */ #define MWU_NMIENSET_REGION0WA_Msk (0x1UL << MWU_NMIENSET_REGION0WA_Pos) /*!< Bit mask of REGION0WA field. */ #define MWU_NMIENSET_REGION0WA_Disabled (0UL) /*!< Read: Disabled */ @@ -3058,84 +3191,84 @@ /* Register: MWU_NMIENCLR */ /* Description: Disable non-maskable interrupt */ -/* Bit 27 : Write '1' to Clear non-maskable interrupt on EVENTS_PREGION[1].RA event */ +/* Bit 27 : Write '1' to Disable non-maskable interrupt for PREGION[1].RA event */ #define MWU_NMIENCLR_PREGION1RA_Pos (27UL) /*!< Position of PREGION1RA field. */ #define MWU_NMIENCLR_PREGION1RA_Msk (0x1UL << MWU_NMIENCLR_PREGION1RA_Pos) /*!< Bit mask of PREGION1RA field. */ #define MWU_NMIENCLR_PREGION1RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENCLR_PREGION1RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENCLR_PREGION1RA_Clear (1UL) /*!< Disable */ -/* Bit 26 : Write '1' to Clear non-maskable interrupt on EVENTS_PREGION[1].WA event */ +/* Bit 26 : Write '1' to Disable non-maskable interrupt for PREGION[1].WA event */ #define MWU_NMIENCLR_PREGION1WA_Pos (26UL) /*!< Position of PREGION1WA field. */ #define MWU_NMIENCLR_PREGION1WA_Msk (0x1UL << MWU_NMIENCLR_PREGION1WA_Pos) /*!< Bit mask of PREGION1WA field. */ #define MWU_NMIENCLR_PREGION1WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENCLR_PREGION1WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENCLR_PREGION1WA_Clear (1UL) /*!< Disable */ -/* Bit 25 : Write '1' to Clear non-maskable interrupt on EVENTS_PREGION[0].RA event */ +/* Bit 25 : Write '1' to Disable non-maskable interrupt for PREGION[0].RA event */ #define MWU_NMIENCLR_PREGION0RA_Pos (25UL) /*!< Position of PREGION0RA field. */ #define MWU_NMIENCLR_PREGION0RA_Msk (0x1UL << MWU_NMIENCLR_PREGION0RA_Pos) /*!< Bit mask of PREGION0RA field. */ #define MWU_NMIENCLR_PREGION0RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENCLR_PREGION0RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENCLR_PREGION0RA_Clear (1UL) /*!< Disable */ -/* Bit 24 : Write '1' to Clear non-maskable interrupt on EVENTS_PREGION[0].WA event */ +/* Bit 24 : Write '1' to Disable non-maskable interrupt for PREGION[0].WA event */ #define MWU_NMIENCLR_PREGION0WA_Pos (24UL) /*!< Position of PREGION0WA field. */ #define MWU_NMIENCLR_PREGION0WA_Msk (0x1UL << MWU_NMIENCLR_PREGION0WA_Pos) /*!< Bit mask of PREGION0WA field. */ #define MWU_NMIENCLR_PREGION0WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENCLR_PREGION0WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENCLR_PREGION0WA_Clear (1UL) /*!< Disable */ -/* Bit 7 : Write '1' to Clear non-maskable interrupt on EVENTS_REGION[3].RA event */ +/* Bit 7 : Write '1' to Disable non-maskable interrupt for REGION[3].RA event */ #define MWU_NMIENCLR_REGION3RA_Pos (7UL) /*!< Position of REGION3RA field. */ #define MWU_NMIENCLR_REGION3RA_Msk (0x1UL << MWU_NMIENCLR_REGION3RA_Pos) /*!< Bit mask of REGION3RA field. */ #define MWU_NMIENCLR_REGION3RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENCLR_REGION3RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENCLR_REGION3RA_Clear (1UL) /*!< Disable */ -/* Bit 6 : Write '1' to Clear non-maskable interrupt on EVENTS_REGION[3].WA event */ +/* Bit 6 : Write '1' to Disable non-maskable interrupt for REGION[3].WA event */ #define MWU_NMIENCLR_REGION3WA_Pos (6UL) /*!< Position of REGION3WA field. */ #define MWU_NMIENCLR_REGION3WA_Msk (0x1UL << MWU_NMIENCLR_REGION3WA_Pos) /*!< Bit mask of REGION3WA field. */ #define MWU_NMIENCLR_REGION3WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENCLR_REGION3WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENCLR_REGION3WA_Clear (1UL) /*!< Disable */ -/* Bit 5 : Write '1' to Clear non-maskable interrupt on EVENTS_REGION[2].RA event */ +/* Bit 5 : Write '1' to Disable non-maskable interrupt for REGION[2].RA event */ #define MWU_NMIENCLR_REGION2RA_Pos (5UL) /*!< Position of REGION2RA field. */ #define MWU_NMIENCLR_REGION2RA_Msk (0x1UL << MWU_NMIENCLR_REGION2RA_Pos) /*!< Bit mask of REGION2RA field. */ #define MWU_NMIENCLR_REGION2RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENCLR_REGION2RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENCLR_REGION2RA_Clear (1UL) /*!< Disable */ -/* Bit 4 : Write '1' to Clear non-maskable interrupt on EVENTS_REGION[2].WA event */ +/* Bit 4 : Write '1' to Disable non-maskable interrupt for REGION[2].WA event */ #define MWU_NMIENCLR_REGION2WA_Pos (4UL) /*!< Position of REGION2WA field. */ #define MWU_NMIENCLR_REGION2WA_Msk (0x1UL << MWU_NMIENCLR_REGION2WA_Pos) /*!< Bit mask of REGION2WA field. */ #define MWU_NMIENCLR_REGION2WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENCLR_REGION2WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENCLR_REGION2WA_Clear (1UL) /*!< Disable */ -/* Bit 3 : Write '1' to Clear non-maskable interrupt on EVENTS_REGION[1].RA event */ +/* Bit 3 : Write '1' to Disable non-maskable interrupt for REGION[1].RA event */ #define MWU_NMIENCLR_REGION1RA_Pos (3UL) /*!< Position of REGION1RA field. */ #define MWU_NMIENCLR_REGION1RA_Msk (0x1UL << MWU_NMIENCLR_REGION1RA_Pos) /*!< Bit mask of REGION1RA field. */ #define MWU_NMIENCLR_REGION1RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENCLR_REGION1RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENCLR_REGION1RA_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear non-maskable interrupt on EVENTS_REGION[1].WA event */ +/* Bit 2 : Write '1' to Disable non-maskable interrupt for REGION[1].WA event */ #define MWU_NMIENCLR_REGION1WA_Pos (2UL) /*!< Position of REGION1WA field. */ #define MWU_NMIENCLR_REGION1WA_Msk (0x1UL << MWU_NMIENCLR_REGION1WA_Pos) /*!< Bit mask of REGION1WA field. */ #define MWU_NMIENCLR_REGION1WA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENCLR_REGION1WA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENCLR_REGION1WA_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear non-maskable interrupt on EVENTS_REGION[0].RA event */ +/* Bit 1 : Write '1' to Disable non-maskable interrupt for REGION[0].RA event */ #define MWU_NMIENCLR_REGION0RA_Pos (1UL) /*!< Position of REGION0RA field. */ #define MWU_NMIENCLR_REGION0RA_Msk (0x1UL << MWU_NMIENCLR_REGION0RA_Pos) /*!< Bit mask of REGION0RA field. */ #define MWU_NMIENCLR_REGION0RA_Disabled (0UL) /*!< Read: Disabled */ #define MWU_NMIENCLR_REGION0RA_Enabled (1UL) /*!< Read: Enabled */ #define MWU_NMIENCLR_REGION0RA_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear non-maskable interrupt on EVENTS_REGION[0].WA event */ +/* Bit 0 : Write '1' to Disable non-maskable interrupt for REGION[0].WA event */ #define MWU_NMIENCLR_REGION0WA_Pos (0UL) /*!< Position of REGION0WA field. */ #define MWU_NMIENCLR_REGION0WA_Msk (0x1UL << MWU_NMIENCLR_REGION0WA_Pos) /*!< Bit mask of REGION0WA field. */ #define MWU_NMIENCLR_REGION0WA_Disabled (0UL) /*!< Read: Disabled */ @@ -3143,390 +3276,390 @@ #define MWU_NMIENCLR_REGION0WA_Clear (1UL) /*!< Disable */ /* Register: MWU_PERREGION_SUBSTATWA */ -/* Description: Description cluster[0]: Source of interrupt in region 0, write access detected while corresponding subregion was enabled for watching */ +/* Description: Description cluster[0]: Source of event/interrupt in region 0, write access detected while corresponding subregion was enabled for watching */ -/* Bit 31 : Sub region 31 in region 0 (write '1' to clear) */ +/* Bit 31 : Subregion 31 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR31_Pos (31UL) /*!< Position of SR31 field. */ #define MWU_PERREGION_SUBSTATWA_SR31_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR31_Pos) /*!< Bit mask of SR31 field. */ #define MWU_PERREGION_SUBSTATWA_SR31_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR31_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 30 : Sub region 30 in region 0 (write '1' to clear) */ +/* Bit 30 : Subregion 30 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR30_Pos (30UL) /*!< Position of SR30 field. */ #define MWU_PERREGION_SUBSTATWA_SR30_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR30_Pos) /*!< Bit mask of SR30 field. */ #define MWU_PERREGION_SUBSTATWA_SR30_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR30_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 29 : Sub region 29 in region 0 (write '1' to clear) */ +/* Bit 29 : Subregion 29 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR29_Pos (29UL) /*!< Position of SR29 field. */ #define MWU_PERREGION_SUBSTATWA_SR29_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR29_Pos) /*!< Bit mask of SR29 field. */ #define MWU_PERREGION_SUBSTATWA_SR29_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR29_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 28 : Sub region 28 in region 0 (write '1' to clear) */ +/* Bit 28 : Subregion 28 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR28_Pos (28UL) /*!< Position of SR28 field. */ #define MWU_PERREGION_SUBSTATWA_SR28_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR28_Pos) /*!< Bit mask of SR28 field. */ #define MWU_PERREGION_SUBSTATWA_SR28_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR28_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 27 : Sub region 27 in region 0 (write '1' to clear) */ +/* Bit 27 : Subregion 27 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR27_Pos (27UL) /*!< Position of SR27 field. */ #define MWU_PERREGION_SUBSTATWA_SR27_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR27_Pos) /*!< Bit mask of SR27 field. */ #define MWU_PERREGION_SUBSTATWA_SR27_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR27_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 26 : Sub region 26 in region 0 (write '1' to clear) */ +/* Bit 26 : Subregion 26 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR26_Pos (26UL) /*!< Position of SR26 field. */ #define MWU_PERREGION_SUBSTATWA_SR26_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR26_Pos) /*!< Bit mask of SR26 field. */ #define MWU_PERREGION_SUBSTATWA_SR26_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR26_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 25 : Sub region 25 in region 0 (write '1' to clear) */ +/* Bit 25 : Subregion 25 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR25_Pos (25UL) /*!< Position of SR25 field. */ #define MWU_PERREGION_SUBSTATWA_SR25_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR25_Pos) /*!< Bit mask of SR25 field. */ #define MWU_PERREGION_SUBSTATWA_SR25_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR25_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 24 : Sub region 24 in region 0 (write '1' to clear) */ +/* Bit 24 : Subregion 24 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR24_Pos (24UL) /*!< Position of SR24 field. */ #define MWU_PERREGION_SUBSTATWA_SR24_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR24_Pos) /*!< Bit mask of SR24 field. */ #define MWU_PERREGION_SUBSTATWA_SR24_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR24_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 23 : Sub region 23 in region 0 (write '1' to clear) */ +/* Bit 23 : Subregion 23 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR23_Pos (23UL) /*!< Position of SR23 field. */ #define MWU_PERREGION_SUBSTATWA_SR23_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR23_Pos) /*!< Bit mask of SR23 field. */ #define MWU_PERREGION_SUBSTATWA_SR23_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR23_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 22 : Sub region 22 in region 0 (write '1' to clear) */ +/* Bit 22 : Subregion 22 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR22_Pos (22UL) /*!< Position of SR22 field. */ #define MWU_PERREGION_SUBSTATWA_SR22_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR22_Pos) /*!< Bit mask of SR22 field. */ #define MWU_PERREGION_SUBSTATWA_SR22_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR22_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 21 : Sub region 21 in region 0 (write '1' to clear) */ +/* Bit 21 : Subregion 21 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR21_Pos (21UL) /*!< Position of SR21 field. */ #define MWU_PERREGION_SUBSTATWA_SR21_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR21_Pos) /*!< Bit mask of SR21 field. */ #define MWU_PERREGION_SUBSTATWA_SR21_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR21_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 20 : Sub region 20 in region 0 (write '1' to clear) */ +/* Bit 20 : Subregion 20 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR20_Pos (20UL) /*!< Position of SR20 field. */ #define MWU_PERREGION_SUBSTATWA_SR20_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR20_Pos) /*!< Bit mask of SR20 field. */ #define MWU_PERREGION_SUBSTATWA_SR20_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR20_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 19 : Sub region 19 in region 0 (write '1' to clear) */ +/* Bit 19 : Subregion 19 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR19_Pos (19UL) /*!< Position of SR19 field. */ #define MWU_PERREGION_SUBSTATWA_SR19_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR19_Pos) /*!< Bit mask of SR19 field. */ #define MWU_PERREGION_SUBSTATWA_SR19_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR19_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 18 : Sub region 18 in region 0 (write '1' to clear) */ +/* Bit 18 : Subregion 18 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR18_Pos (18UL) /*!< Position of SR18 field. */ #define MWU_PERREGION_SUBSTATWA_SR18_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR18_Pos) /*!< Bit mask of SR18 field. */ #define MWU_PERREGION_SUBSTATWA_SR18_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR18_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 17 : Sub region 17 in region 0 (write '1' to clear) */ +/* Bit 17 : Subregion 17 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR17_Pos (17UL) /*!< Position of SR17 field. */ #define MWU_PERREGION_SUBSTATWA_SR17_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR17_Pos) /*!< Bit mask of SR17 field. */ #define MWU_PERREGION_SUBSTATWA_SR17_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR17_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 16 : Sub region 16 in region 0 (write '1' to clear) */ +/* Bit 16 : Subregion 16 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR16_Pos (16UL) /*!< Position of SR16 field. */ #define MWU_PERREGION_SUBSTATWA_SR16_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR16_Pos) /*!< Bit mask of SR16 field. */ #define MWU_PERREGION_SUBSTATWA_SR16_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR16_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 15 : Sub region 15 in region 0 (write '1' to clear) */ +/* Bit 15 : Subregion 15 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR15_Pos (15UL) /*!< Position of SR15 field. */ #define MWU_PERREGION_SUBSTATWA_SR15_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR15_Pos) /*!< Bit mask of SR15 field. */ #define MWU_PERREGION_SUBSTATWA_SR15_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR15_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 14 : Sub region 14 in region 0 (write '1' to clear) */ +/* Bit 14 : Subregion 14 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR14_Pos (14UL) /*!< Position of SR14 field. */ #define MWU_PERREGION_SUBSTATWA_SR14_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR14_Pos) /*!< Bit mask of SR14 field. */ #define MWU_PERREGION_SUBSTATWA_SR14_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR14_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 13 : Sub region 13 in region 0 (write '1' to clear) */ +/* Bit 13 : Subregion 13 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR13_Pos (13UL) /*!< Position of SR13 field. */ #define MWU_PERREGION_SUBSTATWA_SR13_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR13_Pos) /*!< Bit mask of SR13 field. */ #define MWU_PERREGION_SUBSTATWA_SR13_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR13_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 12 : Sub region 12 in region 0 (write '1' to clear) */ +/* Bit 12 : Subregion 12 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR12_Pos (12UL) /*!< Position of SR12 field. */ #define MWU_PERREGION_SUBSTATWA_SR12_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR12_Pos) /*!< Bit mask of SR12 field. */ #define MWU_PERREGION_SUBSTATWA_SR12_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR12_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 11 : Sub region 11 in region 0 (write '1' to clear) */ +/* Bit 11 : Subregion 11 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR11_Pos (11UL) /*!< Position of SR11 field. */ #define MWU_PERREGION_SUBSTATWA_SR11_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR11_Pos) /*!< Bit mask of SR11 field. */ #define MWU_PERREGION_SUBSTATWA_SR11_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR11_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 10 : Sub region 10 in region 0 (write '1' to clear) */ +/* Bit 10 : Subregion 10 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR10_Pos (10UL) /*!< Position of SR10 field. */ #define MWU_PERREGION_SUBSTATWA_SR10_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR10_Pos) /*!< Bit mask of SR10 field. */ #define MWU_PERREGION_SUBSTATWA_SR10_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR10_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 9 : Sub region 9 in region 0 (write '1' to clear) */ +/* Bit 9 : Subregion 9 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR9_Pos (9UL) /*!< Position of SR9 field. */ #define MWU_PERREGION_SUBSTATWA_SR9_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR9_Pos) /*!< Bit mask of SR9 field. */ #define MWU_PERREGION_SUBSTATWA_SR9_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR9_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 8 : Sub region 8 in region 0 (write '1' to clear) */ +/* Bit 8 : Subregion 8 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR8_Pos (8UL) /*!< Position of SR8 field. */ #define MWU_PERREGION_SUBSTATWA_SR8_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR8_Pos) /*!< Bit mask of SR8 field. */ #define MWU_PERREGION_SUBSTATWA_SR8_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR8_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 7 : Sub region 7 in region 0 (write '1' to clear) */ +/* Bit 7 : Subregion 7 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR7_Pos (7UL) /*!< Position of SR7 field. */ #define MWU_PERREGION_SUBSTATWA_SR7_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR7_Pos) /*!< Bit mask of SR7 field. */ #define MWU_PERREGION_SUBSTATWA_SR7_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR7_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 6 : Sub region 6 in region 0 (write '1' to clear) */ +/* Bit 6 : Subregion 6 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR6_Pos (6UL) /*!< Position of SR6 field. */ #define MWU_PERREGION_SUBSTATWA_SR6_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR6_Pos) /*!< Bit mask of SR6 field. */ #define MWU_PERREGION_SUBSTATWA_SR6_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR6_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 5 : Sub region 5 in region 0 (write '1' to clear) */ +/* Bit 5 : Subregion 5 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR5_Pos (5UL) /*!< Position of SR5 field. */ #define MWU_PERREGION_SUBSTATWA_SR5_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR5_Pos) /*!< Bit mask of SR5 field. */ #define MWU_PERREGION_SUBSTATWA_SR5_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR5_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 4 : Sub region 4 in region 0 (write '1' to clear) */ +/* Bit 4 : Subregion 4 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR4_Pos (4UL) /*!< Position of SR4 field. */ #define MWU_PERREGION_SUBSTATWA_SR4_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR4_Pos) /*!< Bit mask of SR4 field. */ #define MWU_PERREGION_SUBSTATWA_SR4_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR4_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 3 : Sub region 3 in region 0 (write '1' to clear) */ +/* Bit 3 : Subregion 3 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR3_Pos (3UL) /*!< Position of SR3 field. */ #define MWU_PERREGION_SUBSTATWA_SR3_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR3_Pos) /*!< Bit mask of SR3 field. */ #define MWU_PERREGION_SUBSTATWA_SR3_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR3_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 2 : Sub region 2 in region 0 (write '1' to clear) */ +/* Bit 2 : Subregion 2 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR2_Pos (2UL) /*!< Position of SR2 field. */ #define MWU_PERREGION_SUBSTATWA_SR2_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR2_Pos) /*!< Bit mask of SR2 field. */ #define MWU_PERREGION_SUBSTATWA_SR2_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR2_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 1 : Sub region 1 in region 0 (write '1' to clear) */ +/* Bit 1 : Subregion 1 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR1_Pos (1UL) /*!< Position of SR1 field. */ #define MWU_PERREGION_SUBSTATWA_SR1_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR1_Pos) /*!< Bit mask of SR1 field. */ #define MWU_PERREGION_SUBSTATWA_SR1_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR1_Access (1UL) /*!< Write access(es) occurred in this subregion */ -/* Bit 0 : Sub region 0 in region 0 (write '1' to clear) */ +/* Bit 0 : Subregion 0 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATWA_SR0_Pos (0UL) /*!< Position of SR0 field. */ #define MWU_PERREGION_SUBSTATWA_SR0_Msk (0x1UL << MWU_PERREGION_SUBSTATWA_SR0_Pos) /*!< Bit mask of SR0 field. */ #define MWU_PERREGION_SUBSTATWA_SR0_NoAccess (0UL) /*!< No write access occurred in this subregion */ #define MWU_PERREGION_SUBSTATWA_SR0_Access (1UL) /*!< Write access(es) occurred in this subregion */ /* Register: MWU_PERREGION_SUBSTATRA */ -/* Description: Description cluster[0]: Source of interrupt in region 0, read access detected while corresponding subregion was enabled for watching */ +/* Description: Description cluster[0]: Source of event/interrupt in region 0, read access detected while corresponding subregion was enabled for watching */ -/* Bit 31 : Sub region 31 in region 0 (write '1' to clear) */ +/* Bit 31 : Subregion 31 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR31_Pos (31UL) /*!< Position of SR31 field. */ #define MWU_PERREGION_SUBSTATRA_SR31_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR31_Pos) /*!< Bit mask of SR31 field. */ #define MWU_PERREGION_SUBSTATRA_SR31_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR31_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 30 : Sub region 30 in region 0 (write '1' to clear) */ +/* Bit 30 : Subregion 30 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR30_Pos (30UL) /*!< Position of SR30 field. */ #define MWU_PERREGION_SUBSTATRA_SR30_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR30_Pos) /*!< Bit mask of SR30 field. */ #define MWU_PERREGION_SUBSTATRA_SR30_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR30_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 29 : Sub region 29 in region 0 (write '1' to clear) */ +/* Bit 29 : Subregion 29 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR29_Pos (29UL) /*!< Position of SR29 field. */ #define MWU_PERREGION_SUBSTATRA_SR29_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR29_Pos) /*!< Bit mask of SR29 field. */ #define MWU_PERREGION_SUBSTATRA_SR29_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR29_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 28 : Sub region 28 in region 0 (write '1' to clear) */ +/* Bit 28 : Subregion 28 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR28_Pos (28UL) /*!< Position of SR28 field. */ #define MWU_PERREGION_SUBSTATRA_SR28_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR28_Pos) /*!< Bit mask of SR28 field. */ #define MWU_PERREGION_SUBSTATRA_SR28_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR28_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 27 : Sub region 27 in region 0 (write '1' to clear) */ +/* Bit 27 : Subregion 27 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR27_Pos (27UL) /*!< Position of SR27 field. */ #define MWU_PERREGION_SUBSTATRA_SR27_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR27_Pos) /*!< Bit mask of SR27 field. */ #define MWU_PERREGION_SUBSTATRA_SR27_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR27_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 26 : Sub region 26 in region 0 (write '1' to clear) */ +/* Bit 26 : Subregion 26 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR26_Pos (26UL) /*!< Position of SR26 field. */ #define MWU_PERREGION_SUBSTATRA_SR26_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR26_Pos) /*!< Bit mask of SR26 field. */ #define MWU_PERREGION_SUBSTATRA_SR26_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR26_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 25 : Sub region 25 in region 0 (write '1' to clear) */ +/* Bit 25 : Subregion 25 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR25_Pos (25UL) /*!< Position of SR25 field. */ #define MWU_PERREGION_SUBSTATRA_SR25_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR25_Pos) /*!< Bit mask of SR25 field. */ #define MWU_PERREGION_SUBSTATRA_SR25_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR25_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 24 : Sub region 24 in region 0 (write '1' to clear) */ +/* Bit 24 : Subregion 24 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR24_Pos (24UL) /*!< Position of SR24 field. */ #define MWU_PERREGION_SUBSTATRA_SR24_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR24_Pos) /*!< Bit mask of SR24 field. */ #define MWU_PERREGION_SUBSTATRA_SR24_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR24_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 23 : Sub region 23 in region 0 (write '1' to clear) */ +/* Bit 23 : Subregion 23 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR23_Pos (23UL) /*!< Position of SR23 field. */ #define MWU_PERREGION_SUBSTATRA_SR23_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR23_Pos) /*!< Bit mask of SR23 field. */ #define MWU_PERREGION_SUBSTATRA_SR23_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR23_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 22 : Sub region 22 in region 0 (write '1' to clear) */ +/* Bit 22 : Subregion 22 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR22_Pos (22UL) /*!< Position of SR22 field. */ #define MWU_PERREGION_SUBSTATRA_SR22_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR22_Pos) /*!< Bit mask of SR22 field. */ #define MWU_PERREGION_SUBSTATRA_SR22_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR22_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 21 : Sub region 21 in region 0 (write '1' to clear) */ +/* Bit 21 : Subregion 21 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR21_Pos (21UL) /*!< Position of SR21 field. */ #define MWU_PERREGION_SUBSTATRA_SR21_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR21_Pos) /*!< Bit mask of SR21 field. */ #define MWU_PERREGION_SUBSTATRA_SR21_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR21_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 20 : Sub region 20 in region 0 (write '1' to clear) */ +/* Bit 20 : Subregion 20 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR20_Pos (20UL) /*!< Position of SR20 field. */ #define MWU_PERREGION_SUBSTATRA_SR20_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR20_Pos) /*!< Bit mask of SR20 field. */ #define MWU_PERREGION_SUBSTATRA_SR20_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR20_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 19 : Sub region 19 in region 0 (write '1' to clear) */ +/* Bit 19 : Subregion 19 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR19_Pos (19UL) /*!< Position of SR19 field. */ #define MWU_PERREGION_SUBSTATRA_SR19_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR19_Pos) /*!< Bit mask of SR19 field. */ #define MWU_PERREGION_SUBSTATRA_SR19_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR19_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 18 : Sub region 18 in region 0 (write '1' to clear) */ +/* Bit 18 : Subregion 18 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR18_Pos (18UL) /*!< Position of SR18 field. */ #define MWU_PERREGION_SUBSTATRA_SR18_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR18_Pos) /*!< Bit mask of SR18 field. */ #define MWU_PERREGION_SUBSTATRA_SR18_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR18_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 17 : Sub region 17 in region 0 (write '1' to clear) */ +/* Bit 17 : Subregion 17 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR17_Pos (17UL) /*!< Position of SR17 field. */ #define MWU_PERREGION_SUBSTATRA_SR17_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR17_Pos) /*!< Bit mask of SR17 field. */ #define MWU_PERREGION_SUBSTATRA_SR17_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR17_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 16 : Sub region 16 in region 0 (write '1' to clear) */ +/* Bit 16 : Subregion 16 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR16_Pos (16UL) /*!< Position of SR16 field. */ #define MWU_PERREGION_SUBSTATRA_SR16_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR16_Pos) /*!< Bit mask of SR16 field. */ #define MWU_PERREGION_SUBSTATRA_SR16_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR16_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 15 : Sub region 15 in region 0 (write '1' to clear) */ +/* Bit 15 : Subregion 15 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR15_Pos (15UL) /*!< Position of SR15 field. */ #define MWU_PERREGION_SUBSTATRA_SR15_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR15_Pos) /*!< Bit mask of SR15 field. */ #define MWU_PERREGION_SUBSTATRA_SR15_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR15_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 14 : Sub region 14 in region 0 (write '1' to clear) */ +/* Bit 14 : Subregion 14 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR14_Pos (14UL) /*!< Position of SR14 field. */ #define MWU_PERREGION_SUBSTATRA_SR14_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR14_Pos) /*!< Bit mask of SR14 field. */ #define MWU_PERREGION_SUBSTATRA_SR14_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR14_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 13 : Sub region 13 in region 0 (write '1' to clear) */ +/* Bit 13 : Subregion 13 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR13_Pos (13UL) /*!< Position of SR13 field. */ #define MWU_PERREGION_SUBSTATRA_SR13_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR13_Pos) /*!< Bit mask of SR13 field. */ #define MWU_PERREGION_SUBSTATRA_SR13_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR13_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 12 : Sub region 12 in region 0 (write '1' to clear) */ +/* Bit 12 : Subregion 12 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR12_Pos (12UL) /*!< Position of SR12 field. */ #define MWU_PERREGION_SUBSTATRA_SR12_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR12_Pos) /*!< Bit mask of SR12 field. */ #define MWU_PERREGION_SUBSTATRA_SR12_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR12_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 11 : Sub region 11 in region 0 (write '1' to clear) */ +/* Bit 11 : Subregion 11 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR11_Pos (11UL) /*!< Position of SR11 field. */ #define MWU_PERREGION_SUBSTATRA_SR11_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR11_Pos) /*!< Bit mask of SR11 field. */ #define MWU_PERREGION_SUBSTATRA_SR11_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR11_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 10 : Sub region 10 in region 0 (write '1' to clear) */ +/* Bit 10 : Subregion 10 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR10_Pos (10UL) /*!< Position of SR10 field. */ #define MWU_PERREGION_SUBSTATRA_SR10_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR10_Pos) /*!< Bit mask of SR10 field. */ #define MWU_PERREGION_SUBSTATRA_SR10_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR10_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 9 : Sub region 9 in region 0 (write '1' to clear) */ +/* Bit 9 : Subregion 9 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR9_Pos (9UL) /*!< Position of SR9 field. */ #define MWU_PERREGION_SUBSTATRA_SR9_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR9_Pos) /*!< Bit mask of SR9 field. */ #define MWU_PERREGION_SUBSTATRA_SR9_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR9_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 8 : Sub region 8 in region 0 (write '1' to clear) */ +/* Bit 8 : Subregion 8 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR8_Pos (8UL) /*!< Position of SR8 field. */ #define MWU_PERREGION_SUBSTATRA_SR8_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR8_Pos) /*!< Bit mask of SR8 field. */ #define MWU_PERREGION_SUBSTATRA_SR8_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR8_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 7 : Sub region 7 in region 0 (write '1' to clear) */ +/* Bit 7 : Subregion 7 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR7_Pos (7UL) /*!< Position of SR7 field. */ #define MWU_PERREGION_SUBSTATRA_SR7_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR7_Pos) /*!< Bit mask of SR7 field. */ #define MWU_PERREGION_SUBSTATRA_SR7_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR7_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 6 : Sub region 6 in region 0 (write '1' to clear) */ +/* Bit 6 : Subregion 6 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR6_Pos (6UL) /*!< Position of SR6 field. */ #define MWU_PERREGION_SUBSTATRA_SR6_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR6_Pos) /*!< Bit mask of SR6 field. */ #define MWU_PERREGION_SUBSTATRA_SR6_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR6_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 5 : Sub region 5 in region 0 (write '1' to clear) */ +/* Bit 5 : Subregion 5 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR5_Pos (5UL) /*!< Position of SR5 field. */ #define MWU_PERREGION_SUBSTATRA_SR5_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR5_Pos) /*!< Bit mask of SR5 field. */ #define MWU_PERREGION_SUBSTATRA_SR5_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR5_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 4 : Sub region 4 in region 0 (write '1' to clear) */ +/* Bit 4 : Subregion 4 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR4_Pos (4UL) /*!< Position of SR4 field. */ #define MWU_PERREGION_SUBSTATRA_SR4_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR4_Pos) /*!< Bit mask of SR4 field. */ #define MWU_PERREGION_SUBSTATRA_SR4_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR4_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 3 : Sub region 3 in region 0 (write '1' to clear) */ +/* Bit 3 : Subregion 3 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR3_Pos (3UL) /*!< Position of SR3 field. */ #define MWU_PERREGION_SUBSTATRA_SR3_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR3_Pos) /*!< Bit mask of SR3 field. */ #define MWU_PERREGION_SUBSTATRA_SR3_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR3_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 2 : Sub region 2 in region 0 (write '1' to clear) */ +/* Bit 2 : Subregion 2 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR2_Pos (2UL) /*!< Position of SR2 field. */ #define MWU_PERREGION_SUBSTATRA_SR2_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR2_Pos) /*!< Bit mask of SR2 field. */ #define MWU_PERREGION_SUBSTATRA_SR2_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR2_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 1 : Sub region 1 in region 0 (write '1' to clear) */ +/* Bit 1 : Subregion 1 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR1_Pos (1UL) /*!< Position of SR1 field. */ #define MWU_PERREGION_SUBSTATRA_SR1_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR1_Pos) /*!< Bit mask of SR1 field. */ #define MWU_PERREGION_SUBSTATRA_SR1_NoAccess (0UL) /*!< No read access occurred in this subregion */ #define MWU_PERREGION_SUBSTATRA_SR1_Access (1UL) /*!< Read access(es) occurred in this subregion */ -/* Bit 0 : Sub region 0 in region 0 (write '1' to clear) */ +/* Bit 0 : Subregion 0 in region 0 (write '1' to clear) */ #define MWU_PERREGION_SUBSTATRA_SR0_Pos (0UL) /*!< Position of SR0 field. */ #define MWU_PERREGION_SUBSTATRA_SR0_Msk (0x1UL << MWU_PERREGION_SUBSTATRA_SR0_Pos) /*!< Bit mask of SR0 field. */ #define MWU_PERREGION_SUBSTATRA_SR0_NoAccess (0UL) /*!< No read access occurred in this subregion */ @@ -3791,10 +3924,9 @@ /* Register: MWU_REGION_END */ /* Description: Description cluster[0]: End address of region 0 */ -/* Bits 31..0 : End address of region. Value 0 has a special meaning, see below. */ +/* Bits 31..0 : End address of region. */ #define MWU_REGION_END_END_Pos (0UL) /*!< Position of END field. */ #define MWU_REGION_END_END_Msk (0xFFFFFFFFUL << MWU_REGION_END_END_Pos) /*!< Bit mask of END field. */ -#define MWU_REGION_END_END_OneByte (0UL) /*!< Region is 1 byte long (End address = Start address) */ /* Register: MWU_PREGION_START */ /* Description: Description cluster[0]: Reserved for future use */ @@ -3811,7 +3943,7 @@ #define MWU_PREGION_END_END_Msk (0xFFFFFFFFUL << MWU_PREGION_END_END_Pos) /*!< Bit mask of END field. */ /* Register: MWU_PREGION_SUBS */ -/* Description: Description cluster[0]: Sub regions of region 0 */ +/* Description: Description cluster[0]: Subregions of region 0 */ /* Bit 31 : Include or exclude subregion 31 in region */ #define MWU_PREGION_SUBS_SR31_Pos (31UL) /*!< Position of SR31 field. */ @@ -4012,13 +4144,13 @@ /* Register: NFCT_SHORTS */ /* Description: Shortcut register */ -/* Bit 1 : Shortcut between EVENTS_FIELDLOST event and TASKS_SENSE task */ +/* Bit 1 : Shortcut between FIELDLOST event and SENSE task */ #define NFCT_SHORTS_FIELDLOST_SENSE_Pos (1UL) /*!< Position of FIELDLOST_SENSE field. */ #define NFCT_SHORTS_FIELDLOST_SENSE_Msk (0x1UL << NFCT_SHORTS_FIELDLOST_SENSE_Pos) /*!< Bit mask of FIELDLOST_SENSE field. */ #define NFCT_SHORTS_FIELDLOST_SENSE_Disabled (0UL) /*!< Disable shortcut */ #define NFCT_SHORTS_FIELDLOST_SENSE_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 0 : Shortcut between EVENTS_FIELDDETECTED event and TASKS_ACTIVATE task */ +/* Bit 0 : Shortcut between FIELDDETECTED event and ACTIVATE task */ #define NFCT_SHORTS_FIELDDETECTED_ACTIVATE_Pos (0UL) /*!< Position of FIELDDETECTED_ACTIVATE field. */ #define NFCT_SHORTS_FIELDDETECTED_ACTIVATE_Msk (0x1UL << NFCT_SHORTS_FIELDDETECTED_ACTIVATE_Pos) /*!< Bit mask of FIELDDETECTED_ACTIVATE field. */ #define NFCT_SHORTS_FIELDDETECTED_ACTIVATE_Disabled (0UL) /*!< Disable shortcut */ @@ -4027,91 +4159,91 @@ /* Register: NFCT_INTEN */ /* Description: Enable or disable interrupt */ -/* Bit 20 : Enable or disable interrupt on EVENTS_STARTED event */ +/* Bit 20 : Enable or disable interrupt for STARTED event */ #define NFCT_INTEN_STARTED_Pos (20UL) /*!< Position of STARTED field. */ #define NFCT_INTEN_STARTED_Msk (0x1UL << NFCT_INTEN_STARTED_Pos) /*!< Bit mask of STARTED field. */ #define NFCT_INTEN_STARTED_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_STARTED_Enabled (1UL) /*!< Enable */ -/* Bit 19 : Enable or disable interrupt on EVENTS_SELECTED event */ +/* Bit 19 : Enable or disable interrupt for SELECTED event */ #define NFCT_INTEN_SELECTED_Pos (19UL) /*!< Position of SELECTED field. */ #define NFCT_INTEN_SELECTED_Msk (0x1UL << NFCT_INTEN_SELECTED_Pos) /*!< Bit mask of SELECTED field. */ #define NFCT_INTEN_SELECTED_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_SELECTED_Enabled (1UL) /*!< Enable */ -/* Bit 18 : Enable or disable interrupt on EVENTS_COLLISION event */ +/* Bit 18 : Enable or disable interrupt for COLLISION event */ #define NFCT_INTEN_COLLISION_Pos (18UL) /*!< Position of COLLISION field. */ #define NFCT_INTEN_COLLISION_Msk (0x1UL << NFCT_INTEN_COLLISION_Pos) /*!< Bit mask of COLLISION field. */ #define NFCT_INTEN_COLLISION_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_COLLISION_Enabled (1UL) /*!< Enable */ -/* Bit 14 : Enable or disable interrupt on EVENTS_AUTOCOLRESSTARTED event */ +/* Bit 14 : Enable or disable interrupt for AUTOCOLRESSTARTED event */ #define NFCT_INTEN_AUTOCOLRESSTARTED_Pos (14UL) /*!< Position of AUTOCOLRESSTARTED field. */ #define NFCT_INTEN_AUTOCOLRESSTARTED_Msk (0x1UL << NFCT_INTEN_AUTOCOLRESSTARTED_Pos) /*!< Bit mask of AUTOCOLRESSTARTED field. */ #define NFCT_INTEN_AUTOCOLRESSTARTED_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_AUTOCOLRESSTARTED_Enabled (1UL) /*!< Enable */ -/* Bit 12 : Enable or disable interrupt on EVENTS_ENDTX event */ +/* Bit 12 : Enable or disable interrupt for ENDTX event */ #define NFCT_INTEN_ENDTX_Pos (12UL) /*!< Position of ENDTX field. */ #define NFCT_INTEN_ENDTX_Msk (0x1UL << NFCT_INTEN_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ #define NFCT_INTEN_ENDTX_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_ENDTX_Enabled (1UL) /*!< Enable */ -/* Bit 11 : Enable or disable interrupt on EVENTS_ENDRX event */ +/* Bit 11 : Enable or disable interrupt for ENDRX event */ #define NFCT_INTEN_ENDRX_Pos (11UL) /*!< Position of ENDRX field. */ #define NFCT_INTEN_ENDRX_Msk (0x1UL << NFCT_INTEN_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ #define NFCT_INTEN_ENDRX_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_ENDRX_Enabled (1UL) /*!< Enable */ -/* Bit 10 : Enable or disable interrupt on EVENTS_RXERROR event */ +/* Bit 10 : Enable or disable interrupt for RXERROR event */ #define NFCT_INTEN_RXERROR_Pos (10UL) /*!< Position of RXERROR field. */ #define NFCT_INTEN_RXERROR_Msk (0x1UL << NFCT_INTEN_RXERROR_Pos) /*!< Bit mask of RXERROR field. */ #define NFCT_INTEN_RXERROR_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_RXERROR_Enabled (1UL) /*!< Enable */ -/* Bit 7 : Enable or disable interrupt on EVENTS_ERROR event */ +/* Bit 7 : Enable or disable interrupt for ERROR event */ #define NFCT_INTEN_ERROR_Pos (7UL) /*!< Position of ERROR field. */ #define NFCT_INTEN_ERROR_Msk (0x1UL << NFCT_INTEN_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define NFCT_INTEN_ERROR_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_ERROR_Enabled (1UL) /*!< Enable */ -/* Bit 6 : Enable or disable interrupt on EVENTS_RXFRAMEEND event */ +/* Bit 6 : Enable or disable interrupt for RXFRAMEEND event */ #define NFCT_INTEN_RXFRAMEEND_Pos (6UL) /*!< Position of RXFRAMEEND field. */ #define NFCT_INTEN_RXFRAMEEND_Msk (0x1UL << NFCT_INTEN_RXFRAMEEND_Pos) /*!< Bit mask of RXFRAMEEND field. */ #define NFCT_INTEN_RXFRAMEEND_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_RXFRAMEEND_Enabled (1UL) /*!< Enable */ -/* Bit 5 : Enable or disable interrupt on EVENTS_RXFRAMESTART event */ +/* Bit 5 : Enable or disable interrupt for RXFRAMESTART event */ #define NFCT_INTEN_RXFRAMESTART_Pos (5UL) /*!< Position of RXFRAMESTART field. */ #define NFCT_INTEN_RXFRAMESTART_Msk (0x1UL << NFCT_INTEN_RXFRAMESTART_Pos) /*!< Bit mask of RXFRAMESTART field. */ #define NFCT_INTEN_RXFRAMESTART_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_RXFRAMESTART_Enabled (1UL) /*!< Enable */ -/* Bit 4 : Enable or disable interrupt on EVENTS_TXFRAMEEND event */ +/* Bit 4 : Enable or disable interrupt for TXFRAMEEND event */ #define NFCT_INTEN_TXFRAMEEND_Pos (4UL) /*!< Position of TXFRAMEEND field. */ #define NFCT_INTEN_TXFRAMEEND_Msk (0x1UL << NFCT_INTEN_TXFRAMEEND_Pos) /*!< Bit mask of TXFRAMEEND field. */ #define NFCT_INTEN_TXFRAMEEND_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_TXFRAMEEND_Enabled (1UL) /*!< Enable */ -/* Bit 3 : Enable or disable interrupt on EVENTS_TXFRAMESTART event */ +/* Bit 3 : Enable or disable interrupt for TXFRAMESTART event */ #define NFCT_INTEN_TXFRAMESTART_Pos (3UL) /*!< Position of TXFRAMESTART field. */ #define NFCT_INTEN_TXFRAMESTART_Msk (0x1UL << NFCT_INTEN_TXFRAMESTART_Pos) /*!< Bit mask of TXFRAMESTART field. */ #define NFCT_INTEN_TXFRAMESTART_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_TXFRAMESTART_Enabled (1UL) /*!< Enable */ -/* Bit 2 : Enable or disable interrupt on EVENTS_FIELDLOST event */ +/* Bit 2 : Enable or disable interrupt for FIELDLOST event */ #define NFCT_INTEN_FIELDLOST_Pos (2UL) /*!< Position of FIELDLOST field. */ #define NFCT_INTEN_FIELDLOST_Msk (0x1UL << NFCT_INTEN_FIELDLOST_Pos) /*!< Bit mask of FIELDLOST field. */ #define NFCT_INTEN_FIELDLOST_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_FIELDLOST_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable interrupt on EVENTS_FIELDDETECTED event */ +/* Bit 1 : Enable or disable interrupt for FIELDDETECTED event */ #define NFCT_INTEN_FIELDDETECTED_Pos (1UL) /*!< Position of FIELDDETECTED field. */ #define NFCT_INTEN_FIELDDETECTED_Msk (0x1UL << NFCT_INTEN_FIELDDETECTED_Pos) /*!< Bit mask of FIELDDETECTED field. */ #define NFCT_INTEN_FIELDDETECTED_Disabled (0UL) /*!< Disable */ #define NFCT_INTEN_FIELDDETECTED_Enabled (1UL) /*!< Enable */ -/* Bit 0 : Enable or disable interrupt on EVENTS_READY event */ +/* Bit 0 : Enable or disable interrupt for READY event */ #define NFCT_INTEN_READY_Pos (0UL) /*!< Position of READY field. */ #define NFCT_INTEN_READY_Msk (0x1UL << NFCT_INTEN_READY_Pos) /*!< Bit mask of READY field. */ #define NFCT_INTEN_READY_Disabled (0UL) /*!< Disable */ @@ -4120,105 +4252,105 @@ /* Register: NFCT_INTENSET */ /* Description: Enable interrupt */ -/* Bit 20 : Write '1' to Enable interrupt on EVENTS_STARTED event */ +/* Bit 20 : Write '1' to Enable interrupt for STARTED event */ #define NFCT_INTENSET_STARTED_Pos (20UL) /*!< Position of STARTED field. */ #define NFCT_INTENSET_STARTED_Msk (0x1UL << NFCT_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ #define NFCT_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_STARTED_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_STARTED_Set (1UL) /*!< Enable */ -/* Bit 19 : Write '1' to Enable interrupt on EVENTS_SELECTED event */ +/* Bit 19 : Write '1' to Enable interrupt for SELECTED event */ #define NFCT_INTENSET_SELECTED_Pos (19UL) /*!< Position of SELECTED field. */ #define NFCT_INTENSET_SELECTED_Msk (0x1UL << NFCT_INTENSET_SELECTED_Pos) /*!< Bit mask of SELECTED field. */ #define NFCT_INTENSET_SELECTED_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_SELECTED_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_SELECTED_Set (1UL) /*!< Enable */ -/* Bit 18 : Write '1' to Enable interrupt on EVENTS_COLLISION event */ +/* Bit 18 : Write '1' to Enable interrupt for COLLISION event */ #define NFCT_INTENSET_COLLISION_Pos (18UL) /*!< Position of COLLISION field. */ #define NFCT_INTENSET_COLLISION_Msk (0x1UL << NFCT_INTENSET_COLLISION_Pos) /*!< Bit mask of COLLISION field. */ #define NFCT_INTENSET_COLLISION_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_COLLISION_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_COLLISION_Set (1UL) /*!< Enable */ -/* Bit 14 : Write '1' to Enable interrupt on EVENTS_AUTOCOLRESSTARTED event */ +/* Bit 14 : Write '1' to Enable interrupt for AUTOCOLRESSTARTED event */ #define NFCT_INTENSET_AUTOCOLRESSTARTED_Pos (14UL) /*!< Position of AUTOCOLRESSTARTED field. */ #define NFCT_INTENSET_AUTOCOLRESSTARTED_Msk (0x1UL << NFCT_INTENSET_AUTOCOLRESSTARTED_Pos) /*!< Bit mask of AUTOCOLRESSTARTED field. */ #define NFCT_INTENSET_AUTOCOLRESSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_AUTOCOLRESSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_AUTOCOLRESSTARTED_Set (1UL) /*!< Enable */ -/* Bit 12 : Write '1' to Enable interrupt on EVENTS_ENDTX event */ +/* Bit 12 : Write '1' to Enable interrupt for ENDTX event */ #define NFCT_INTENSET_ENDTX_Pos (12UL) /*!< Position of ENDTX field. */ #define NFCT_INTENSET_ENDTX_Msk (0x1UL << NFCT_INTENSET_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ #define NFCT_INTENSET_ENDTX_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_ENDTX_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_ENDTX_Set (1UL) /*!< Enable */ -/* Bit 11 : Write '1' to Enable interrupt on EVENTS_ENDRX event */ +/* Bit 11 : Write '1' to Enable interrupt for ENDRX event */ #define NFCT_INTENSET_ENDRX_Pos (11UL) /*!< Position of ENDRX field. */ #define NFCT_INTENSET_ENDRX_Msk (0x1UL << NFCT_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ #define NFCT_INTENSET_ENDRX_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_ENDRX_Set (1UL) /*!< Enable */ -/* Bit 10 : Write '1' to Enable interrupt on EVENTS_RXERROR event */ +/* Bit 10 : Write '1' to Enable interrupt for RXERROR event */ #define NFCT_INTENSET_RXERROR_Pos (10UL) /*!< Position of RXERROR field. */ #define NFCT_INTENSET_RXERROR_Msk (0x1UL << NFCT_INTENSET_RXERROR_Pos) /*!< Bit mask of RXERROR field. */ #define NFCT_INTENSET_RXERROR_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_RXERROR_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_RXERROR_Set (1UL) /*!< Enable */ -/* Bit 7 : Write '1' to Enable interrupt on EVENTS_ERROR event */ +/* Bit 7 : Write '1' to Enable interrupt for ERROR event */ #define NFCT_INTENSET_ERROR_Pos (7UL) /*!< Position of ERROR field. */ #define NFCT_INTENSET_ERROR_Msk (0x1UL << NFCT_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define NFCT_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_ERROR_Set (1UL) /*!< Enable */ -/* Bit 6 : Write '1' to Enable interrupt on EVENTS_RXFRAMEEND event */ +/* Bit 6 : Write '1' to Enable interrupt for RXFRAMEEND event */ #define NFCT_INTENSET_RXFRAMEEND_Pos (6UL) /*!< Position of RXFRAMEEND field. */ #define NFCT_INTENSET_RXFRAMEEND_Msk (0x1UL << NFCT_INTENSET_RXFRAMEEND_Pos) /*!< Bit mask of RXFRAMEEND field. */ #define NFCT_INTENSET_RXFRAMEEND_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_RXFRAMEEND_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_RXFRAMEEND_Set (1UL) /*!< Enable */ -/* Bit 5 : Write '1' to Enable interrupt on EVENTS_RXFRAMESTART event */ +/* Bit 5 : Write '1' to Enable interrupt for RXFRAMESTART event */ #define NFCT_INTENSET_RXFRAMESTART_Pos (5UL) /*!< Position of RXFRAMESTART field. */ #define NFCT_INTENSET_RXFRAMESTART_Msk (0x1UL << NFCT_INTENSET_RXFRAMESTART_Pos) /*!< Bit mask of RXFRAMESTART field. */ #define NFCT_INTENSET_RXFRAMESTART_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_RXFRAMESTART_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_RXFRAMESTART_Set (1UL) /*!< Enable */ -/* Bit 4 : Write '1' to Enable interrupt on EVENTS_TXFRAMEEND event */ +/* Bit 4 : Write '1' to Enable interrupt for TXFRAMEEND event */ #define NFCT_INTENSET_TXFRAMEEND_Pos (4UL) /*!< Position of TXFRAMEEND field. */ #define NFCT_INTENSET_TXFRAMEEND_Msk (0x1UL << NFCT_INTENSET_TXFRAMEEND_Pos) /*!< Bit mask of TXFRAMEEND field. */ #define NFCT_INTENSET_TXFRAMEEND_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_TXFRAMEEND_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_TXFRAMEEND_Set (1UL) /*!< Enable */ -/* Bit 3 : Write '1' to Enable interrupt on EVENTS_TXFRAMESTART event */ +/* Bit 3 : Write '1' to Enable interrupt for TXFRAMESTART event */ #define NFCT_INTENSET_TXFRAMESTART_Pos (3UL) /*!< Position of TXFRAMESTART field. */ #define NFCT_INTENSET_TXFRAMESTART_Msk (0x1UL << NFCT_INTENSET_TXFRAMESTART_Pos) /*!< Bit mask of TXFRAMESTART field. */ #define NFCT_INTENSET_TXFRAMESTART_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_TXFRAMESTART_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_TXFRAMESTART_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_FIELDLOST event */ +/* Bit 2 : Write '1' to Enable interrupt for FIELDLOST event */ #define NFCT_INTENSET_FIELDLOST_Pos (2UL) /*!< Position of FIELDLOST field. */ #define NFCT_INTENSET_FIELDLOST_Msk (0x1UL << NFCT_INTENSET_FIELDLOST_Pos) /*!< Bit mask of FIELDLOST field. */ #define NFCT_INTENSET_FIELDLOST_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_FIELDLOST_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_FIELDLOST_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_FIELDDETECTED event */ +/* Bit 1 : Write '1' to Enable interrupt for FIELDDETECTED event */ #define NFCT_INTENSET_FIELDDETECTED_Pos (1UL) /*!< Position of FIELDDETECTED field. */ #define NFCT_INTENSET_FIELDDETECTED_Msk (0x1UL << NFCT_INTENSET_FIELDDETECTED_Pos) /*!< Bit mask of FIELDDETECTED field. */ #define NFCT_INTENSET_FIELDDETECTED_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENSET_FIELDDETECTED_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENSET_FIELDDETECTED_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_READY event */ +/* Bit 0 : Write '1' to Enable interrupt for READY event */ #define NFCT_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */ #define NFCT_INTENSET_READY_Msk (0x1UL << NFCT_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ #define NFCT_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ @@ -4228,105 +4360,105 @@ /* Register: NFCT_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 20 : Write '1' to Clear interrupt on EVENTS_STARTED event */ +/* Bit 20 : Write '1' to Disable interrupt for STARTED event */ #define NFCT_INTENCLR_STARTED_Pos (20UL) /*!< Position of STARTED field. */ #define NFCT_INTENCLR_STARTED_Msk (0x1UL << NFCT_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ #define NFCT_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_STARTED_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_STARTED_Clear (1UL) /*!< Disable */ -/* Bit 19 : Write '1' to Clear interrupt on EVENTS_SELECTED event */ +/* Bit 19 : Write '1' to Disable interrupt for SELECTED event */ #define NFCT_INTENCLR_SELECTED_Pos (19UL) /*!< Position of SELECTED field. */ #define NFCT_INTENCLR_SELECTED_Msk (0x1UL << NFCT_INTENCLR_SELECTED_Pos) /*!< Bit mask of SELECTED field. */ #define NFCT_INTENCLR_SELECTED_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_SELECTED_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_SELECTED_Clear (1UL) /*!< Disable */ -/* Bit 18 : Write '1' to Clear interrupt on EVENTS_COLLISION event */ +/* Bit 18 : Write '1' to Disable interrupt for COLLISION event */ #define NFCT_INTENCLR_COLLISION_Pos (18UL) /*!< Position of COLLISION field. */ #define NFCT_INTENCLR_COLLISION_Msk (0x1UL << NFCT_INTENCLR_COLLISION_Pos) /*!< Bit mask of COLLISION field. */ #define NFCT_INTENCLR_COLLISION_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_COLLISION_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_COLLISION_Clear (1UL) /*!< Disable */ -/* Bit 14 : Write '1' to Clear interrupt on EVENTS_AUTOCOLRESSTARTED event */ +/* Bit 14 : Write '1' to Disable interrupt for AUTOCOLRESSTARTED event */ #define NFCT_INTENCLR_AUTOCOLRESSTARTED_Pos (14UL) /*!< Position of AUTOCOLRESSTARTED field. */ #define NFCT_INTENCLR_AUTOCOLRESSTARTED_Msk (0x1UL << NFCT_INTENCLR_AUTOCOLRESSTARTED_Pos) /*!< Bit mask of AUTOCOLRESSTARTED field. */ #define NFCT_INTENCLR_AUTOCOLRESSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_AUTOCOLRESSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_AUTOCOLRESSTARTED_Clear (1UL) /*!< Disable */ -/* Bit 12 : Write '1' to Clear interrupt on EVENTS_ENDTX event */ +/* Bit 12 : Write '1' to Disable interrupt for ENDTX event */ #define NFCT_INTENCLR_ENDTX_Pos (12UL) /*!< Position of ENDTX field. */ #define NFCT_INTENCLR_ENDTX_Msk (0x1UL << NFCT_INTENCLR_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ #define NFCT_INTENCLR_ENDTX_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_ENDTX_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_ENDTX_Clear (1UL) /*!< Disable */ -/* Bit 11 : Write '1' to Clear interrupt on EVENTS_ENDRX event */ +/* Bit 11 : Write '1' to Disable interrupt for ENDRX event */ #define NFCT_INTENCLR_ENDRX_Pos (11UL) /*!< Position of ENDRX field. */ #define NFCT_INTENCLR_ENDRX_Msk (0x1UL << NFCT_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ #define NFCT_INTENCLR_ENDRX_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_ENDRX_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_ENDRX_Clear (1UL) /*!< Disable */ -/* Bit 10 : Write '1' to Clear interrupt on EVENTS_RXERROR event */ +/* Bit 10 : Write '1' to Disable interrupt for RXERROR event */ #define NFCT_INTENCLR_RXERROR_Pos (10UL) /*!< Position of RXERROR field. */ #define NFCT_INTENCLR_RXERROR_Msk (0x1UL << NFCT_INTENCLR_RXERROR_Pos) /*!< Bit mask of RXERROR field. */ #define NFCT_INTENCLR_RXERROR_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_RXERROR_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_RXERROR_Clear (1UL) /*!< Disable */ -/* Bit 7 : Write '1' to Clear interrupt on EVENTS_ERROR event */ +/* Bit 7 : Write '1' to Disable interrupt for ERROR event */ #define NFCT_INTENCLR_ERROR_Pos (7UL) /*!< Position of ERROR field. */ #define NFCT_INTENCLR_ERROR_Msk (0x1UL << NFCT_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define NFCT_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ -/* Bit 6 : Write '1' to Clear interrupt on EVENTS_RXFRAMEEND event */ +/* Bit 6 : Write '1' to Disable interrupt for RXFRAMEEND event */ #define NFCT_INTENCLR_RXFRAMEEND_Pos (6UL) /*!< Position of RXFRAMEEND field. */ #define NFCT_INTENCLR_RXFRAMEEND_Msk (0x1UL << NFCT_INTENCLR_RXFRAMEEND_Pos) /*!< Bit mask of RXFRAMEEND field. */ #define NFCT_INTENCLR_RXFRAMEEND_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_RXFRAMEEND_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_RXFRAMEEND_Clear (1UL) /*!< Disable */ -/* Bit 5 : Write '1' to Clear interrupt on EVENTS_RXFRAMESTART event */ +/* Bit 5 : Write '1' to Disable interrupt for RXFRAMESTART event */ #define NFCT_INTENCLR_RXFRAMESTART_Pos (5UL) /*!< Position of RXFRAMESTART field. */ #define NFCT_INTENCLR_RXFRAMESTART_Msk (0x1UL << NFCT_INTENCLR_RXFRAMESTART_Pos) /*!< Bit mask of RXFRAMESTART field. */ #define NFCT_INTENCLR_RXFRAMESTART_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_RXFRAMESTART_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_RXFRAMESTART_Clear (1UL) /*!< Disable */ -/* Bit 4 : Write '1' to Clear interrupt on EVENTS_TXFRAMEEND event */ +/* Bit 4 : Write '1' to Disable interrupt for TXFRAMEEND event */ #define NFCT_INTENCLR_TXFRAMEEND_Pos (4UL) /*!< Position of TXFRAMEEND field. */ #define NFCT_INTENCLR_TXFRAMEEND_Msk (0x1UL << NFCT_INTENCLR_TXFRAMEEND_Pos) /*!< Bit mask of TXFRAMEEND field. */ #define NFCT_INTENCLR_TXFRAMEEND_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_TXFRAMEEND_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_TXFRAMEEND_Clear (1UL) /*!< Disable */ -/* Bit 3 : Write '1' to Clear interrupt on EVENTS_TXFRAMESTART event */ +/* Bit 3 : Write '1' to Disable interrupt for TXFRAMESTART event */ #define NFCT_INTENCLR_TXFRAMESTART_Pos (3UL) /*!< Position of TXFRAMESTART field. */ #define NFCT_INTENCLR_TXFRAMESTART_Msk (0x1UL << NFCT_INTENCLR_TXFRAMESTART_Pos) /*!< Bit mask of TXFRAMESTART field. */ #define NFCT_INTENCLR_TXFRAMESTART_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_TXFRAMESTART_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_TXFRAMESTART_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_FIELDLOST event */ +/* Bit 2 : Write '1' to Disable interrupt for FIELDLOST event */ #define NFCT_INTENCLR_FIELDLOST_Pos (2UL) /*!< Position of FIELDLOST field. */ #define NFCT_INTENCLR_FIELDLOST_Msk (0x1UL << NFCT_INTENCLR_FIELDLOST_Pos) /*!< Bit mask of FIELDLOST field. */ #define NFCT_INTENCLR_FIELDLOST_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_FIELDLOST_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_FIELDLOST_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_FIELDDETECTED event */ +/* Bit 1 : Write '1' to Disable interrupt for FIELDDETECTED event */ #define NFCT_INTENCLR_FIELDDETECTED_Pos (1UL) /*!< Position of FIELDDETECTED field. */ #define NFCT_INTENCLR_FIELDDETECTED_Msk (0x1UL << NFCT_INTENCLR_FIELDDETECTED_Pos) /*!< Bit mask of FIELDDETECTED field. */ #define NFCT_INTENCLR_FIELDDETECTED_Disabled (0UL) /*!< Read: Disabled */ #define NFCT_INTENCLR_FIELDDETECTED_Enabled (1UL) /*!< Read: Enabled */ #define NFCT_INTENCLR_FIELDDETECTED_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_READY event */ +/* Bit 0 : Write '1' to Disable interrupt for READY event */ #define NFCT_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */ #define NFCT_INTENCLR_READY_Msk (0x1UL << NFCT_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ #define NFCT_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ @@ -4336,10 +4468,6 @@ /* Register: NFCT_ERRORSTATUS */ /* Description: NFC Error Status register */ -/* Bit 6 : No valid End of Frame detected */ -#define NFCT_ERRORSTATUS_EOFERROR_Pos (6UL) /*!< Position of EOFERROR field. */ -#define NFCT_ERRORSTATUS_EOFERROR_Msk (0x1UL << NFCT_ERRORSTATUS_EOFERROR_Pos) /*!< Bit mask of EOFERROR field. */ - /* Bit 3 : Field level is too low at min load resistance */ #define NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Pos (3UL) /*!< Position of NFCFIELDTOOWEAK field. */ #define NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Msk (0x1UL << NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Pos) /*!< Bit mask of NFCFIELDTOOWEAK field. */ @@ -4348,10 +4476,6 @@ #define NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Pos (2UL) /*!< Position of NFCFIELDTOOSTRONG field. */ #define NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Msk (0x1UL << NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Pos) /*!< Bit mask of NFCFIELDTOOSTRONG field. */ -/* Bit 1 : The received pulse does not match a valid NFC-A symbol */ -#define NFCT_ERRORSTATUS_INVALIDNFCSYMBOL_Pos (1UL) /*!< Position of INVALIDNFCSYMBOL field. */ -#define NFCT_ERRORSTATUS_INVALIDNFCSYMBOL_Msk (0x1UL << NFCT_ERRORSTATUS_INVALIDNFCSYMBOL_Pos) /*!< Bit mask of INVALIDNFCSYMBOL field. */ - /* Bit 0 : No STARTTX task triggered before expiration of the time set in FRAMEDELAYMAX */ #define NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Pos (0UL) /*!< Position of FRAMEDELAYTIMEOUT field. */ #define NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk (0x1UL << NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Pos) /*!< Bit mask of FRAMEDELAYTIMEOUT field. */ @@ -4393,7 +4517,7 @@ #define NFCT_FIELDPRESENT_LOCKDETECT_NotLocked (0UL) /*!< Not locked to field */ #define NFCT_FIELDPRESENT_LOCKDETECT_Locked (1UL) /*!< Locked to field */ -/* Bit 0 : Indicates the presence or not of a valid field. Linked to the FIELDDETECTED and FIELDLOST events. */ +/* Bit 0 : Indicates the presence or not of a valid field. Available only in the activated state. */ #define NFCT_FIELDPRESENT_FIELDPRESENT_Pos (0UL) /*!< Position of FIELDPRESENT field. */ #define NFCT_FIELDPRESENT_FIELDPRESENT_Msk (0x1UL << NFCT_FIELDPRESENT_FIELDPRESENT_Pos) /*!< Bit mask of FIELDPRESENT field. */ #define NFCT_FIELDPRESENT_FIELDPRESENT_NoField (0UL) /*!< No valid field detected */ @@ -4472,7 +4596,7 @@ #define NFCT_TXD_AMOUNT_TXDATABYTES_Pos (3UL) /*!< Position of TXDATABYTES field. */ #define NFCT_TXD_AMOUNT_TXDATABYTES_Msk (0x1FFUL << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) /*!< Bit mask of TXDATABYTES field. */ -/* Bits 2..0 : Number of bits in the last or first byte read from RAM that shall be included in the frame (excluding parity bit). The DISCARDMODE field in FRAMECONFIG.TX selects if unused bits is discarded at the start or at the end of a frame. A value of 0 bytes and 0 bits is invalid. */ +/* Bits 2..0 : Number of bits in the last or first byte read from RAM that shall be included in the frame (excluding parity bit). */ #define NFCT_TXD_AMOUNT_TXDATABITS_Pos (0UL) /*!< Position of TXDATABITS field. */ #define NFCT_TXD_AMOUNT_TXDATABITS_Msk (0x7UL << NFCT_TXD_AMOUNT_TXDATABITS_Pos) /*!< Bit mask of TXDATABITS field. */ @@ -4504,7 +4628,7 @@ #define NFCT_RXD_AMOUNT_RXDATABYTES_Pos (3UL) /*!< Position of RXDATABYTES field. */ #define NFCT_RXD_AMOUNT_RXDATABYTES_Msk (0x1FFUL << NFCT_RXD_AMOUNT_RXDATABYTES_Pos) /*!< Bit mask of RXDATABYTES field. */ -/* Bits 2..0 : Number of bits in the last byte in the frame, if less than 8 (including CRC, but excluding parity and SoF/EoF framing) */ +/* Bits 2..0 : Number of bits in the last byte in the frame, if less than 8 (including CRC, but excluding parity and SoF/EoF framing). */ #define NFCT_RXD_AMOUNT_RXDATABITS_Pos (0UL) /*!< Position of RXDATABITS field. */ #define NFCT_RXD_AMOUNT_RXDATABITS_Msk (0x7UL << NFCT_RXD_AMOUNT_RXDATABITS_Pos) /*!< Bit mask of RXDATABITS field. */ @@ -4557,21 +4681,6 @@ #define NFCT_NFCID1_3RD_LAST_NFCID1_S_Pos (0UL) /*!< Position of NFCID1_S field. */ #define NFCT_NFCID1_3RD_LAST_NFCID1_S_Msk (0xFFUL << NFCT_NFCID1_3RD_LAST_NFCID1_S_Pos) /*!< Bit mask of NFCID1_S field. */ -/* Register: NFCT_AUTOCOLRESCONFIG */ -/* Description: Controls the Auto collision resolution function. This setting must be done before the NFCT peripheral is enabled. */ - -/* Bit 1 : Enables/disables Auto collision resolution short frame (any frames less than 7 bits) noise filter */ -#define NFCT_AUTOCOLRESCONFIG_FILTER_Pos (1UL) /*!< Position of FILTER field. */ -#define NFCT_AUTOCOLRESCONFIG_FILTER_Msk (0x1UL << NFCT_AUTOCOLRESCONFIG_FILTER_Pos) /*!< Bit mask of FILTER field. */ -#define NFCT_AUTOCOLRESCONFIG_FILTER_Off (0UL) /*!< Auto collision resolution short frame noise filter disabled */ -#define NFCT_AUTOCOLRESCONFIG_FILTER_On (1UL) /*!< Auto collision resolution ignores any frames less than 7 bits */ - -/* Bit 0 : Enables/disables Auto collision resolution */ -#define NFCT_AUTOCOLRESCONFIG_MODE_Pos (0UL) /*!< Position of MODE field. */ -#define NFCT_AUTOCOLRESCONFIG_MODE_Msk (0x1UL << NFCT_AUTOCOLRESCONFIG_MODE_Pos) /*!< Bit mask of MODE field. */ -#define NFCT_AUTOCOLRESCONFIG_MODE_Enabled (0UL) /*!< Auto collision resolution enabled */ -#define NFCT_AUTOCOLRESCONFIG_MODE_Disabled (1UL) /*!< Auto collision resolution disabled */ - /* Register: NFCT_SENSRES */ /* Description: NFC-A SENS_RES auto-response settings */ @@ -4727,193 +4836,193 @@ /* Register: GPIO_OUT */ /* Description: Write GPIO port */ -/* Bit 31 : P0.31 pin */ +/* Bit 31 : Pin 31 */ #define GPIO_OUT_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ #define GPIO_OUT_PIN31_Msk (0x1UL << GPIO_OUT_PIN31_Pos) /*!< Bit mask of PIN31 field. */ #define GPIO_OUT_PIN31_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN31_High (1UL) /*!< Pin driver is high */ -/* Bit 30 : P0.30 pin */ +/* Bit 30 : Pin 30 */ #define GPIO_OUT_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ #define GPIO_OUT_PIN30_Msk (0x1UL << GPIO_OUT_PIN30_Pos) /*!< Bit mask of PIN30 field. */ #define GPIO_OUT_PIN30_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN30_High (1UL) /*!< Pin driver is high */ -/* Bit 29 : P0.29 pin */ +/* Bit 29 : Pin 29 */ #define GPIO_OUT_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ #define GPIO_OUT_PIN29_Msk (0x1UL << GPIO_OUT_PIN29_Pos) /*!< Bit mask of PIN29 field. */ #define GPIO_OUT_PIN29_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN29_High (1UL) /*!< Pin driver is high */ -/* Bit 28 : P0.28 pin */ +/* Bit 28 : Pin 28 */ #define GPIO_OUT_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ #define GPIO_OUT_PIN28_Msk (0x1UL << GPIO_OUT_PIN28_Pos) /*!< Bit mask of PIN28 field. */ #define GPIO_OUT_PIN28_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN28_High (1UL) /*!< Pin driver is high */ -/* Bit 27 : P0.27 pin */ +/* Bit 27 : Pin 27 */ #define GPIO_OUT_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ #define GPIO_OUT_PIN27_Msk (0x1UL << GPIO_OUT_PIN27_Pos) /*!< Bit mask of PIN27 field. */ #define GPIO_OUT_PIN27_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN27_High (1UL) /*!< Pin driver is high */ -/* Bit 26 : P0.26 pin */ +/* Bit 26 : Pin 26 */ #define GPIO_OUT_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ #define GPIO_OUT_PIN26_Msk (0x1UL << GPIO_OUT_PIN26_Pos) /*!< Bit mask of PIN26 field. */ #define GPIO_OUT_PIN26_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN26_High (1UL) /*!< Pin driver is high */ -/* Bit 25 : P0.25 pin */ +/* Bit 25 : Pin 25 */ #define GPIO_OUT_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ #define GPIO_OUT_PIN25_Msk (0x1UL << GPIO_OUT_PIN25_Pos) /*!< Bit mask of PIN25 field. */ #define GPIO_OUT_PIN25_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN25_High (1UL) /*!< Pin driver is high */ -/* Bit 24 : P0.24 pin */ +/* Bit 24 : Pin 24 */ #define GPIO_OUT_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ #define GPIO_OUT_PIN24_Msk (0x1UL << GPIO_OUT_PIN24_Pos) /*!< Bit mask of PIN24 field. */ #define GPIO_OUT_PIN24_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN24_High (1UL) /*!< Pin driver is high */ -/* Bit 23 : P0.23 pin */ +/* Bit 23 : Pin 23 */ #define GPIO_OUT_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ #define GPIO_OUT_PIN23_Msk (0x1UL << GPIO_OUT_PIN23_Pos) /*!< Bit mask of PIN23 field. */ #define GPIO_OUT_PIN23_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN23_High (1UL) /*!< Pin driver is high */ -/* Bit 22 : P0.22 pin */ +/* Bit 22 : Pin 22 */ #define GPIO_OUT_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ #define GPIO_OUT_PIN22_Msk (0x1UL << GPIO_OUT_PIN22_Pos) /*!< Bit mask of PIN22 field. */ #define GPIO_OUT_PIN22_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN22_High (1UL) /*!< Pin driver is high */ -/* Bit 21 : P0.21 pin */ +/* Bit 21 : Pin 21 */ #define GPIO_OUT_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ #define GPIO_OUT_PIN21_Msk (0x1UL << GPIO_OUT_PIN21_Pos) /*!< Bit mask of PIN21 field. */ #define GPIO_OUT_PIN21_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN21_High (1UL) /*!< Pin driver is high */ -/* Bit 20 : P0.20 pin */ +/* Bit 20 : Pin 20 */ #define GPIO_OUT_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ #define GPIO_OUT_PIN20_Msk (0x1UL << GPIO_OUT_PIN20_Pos) /*!< Bit mask of PIN20 field. */ #define GPIO_OUT_PIN20_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN20_High (1UL) /*!< Pin driver is high */ -/* Bit 19 : P0.19 pin */ +/* Bit 19 : Pin 19 */ #define GPIO_OUT_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ #define GPIO_OUT_PIN19_Msk (0x1UL << GPIO_OUT_PIN19_Pos) /*!< Bit mask of PIN19 field. */ #define GPIO_OUT_PIN19_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN19_High (1UL) /*!< Pin driver is high */ -/* Bit 18 : P0.18 pin */ +/* Bit 18 : Pin 18 */ #define GPIO_OUT_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ #define GPIO_OUT_PIN18_Msk (0x1UL << GPIO_OUT_PIN18_Pos) /*!< Bit mask of PIN18 field. */ #define GPIO_OUT_PIN18_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN18_High (1UL) /*!< Pin driver is high */ -/* Bit 17 : P0.17 pin */ +/* Bit 17 : Pin 17 */ #define GPIO_OUT_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ #define GPIO_OUT_PIN17_Msk (0x1UL << GPIO_OUT_PIN17_Pos) /*!< Bit mask of PIN17 field. */ #define GPIO_OUT_PIN17_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN17_High (1UL) /*!< Pin driver is high */ -/* Bit 16 : P0.16 pin */ +/* Bit 16 : Pin 16 */ #define GPIO_OUT_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ #define GPIO_OUT_PIN16_Msk (0x1UL << GPIO_OUT_PIN16_Pos) /*!< Bit mask of PIN16 field. */ #define GPIO_OUT_PIN16_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN16_High (1UL) /*!< Pin driver is high */ -/* Bit 15 : P0.15 pin */ +/* Bit 15 : Pin 15 */ #define GPIO_OUT_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ #define GPIO_OUT_PIN15_Msk (0x1UL << GPIO_OUT_PIN15_Pos) /*!< Bit mask of PIN15 field. */ #define GPIO_OUT_PIN15_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN15_High (1UL) /*!< Pin driver is high */ -/* Bit 14 : P0.14 pin */ +/* Bit 14 : Pin 14 */ #define GPIO_OUT_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ #define GPIO_OUT_PIN14_Msk (0x1UL << GPIO_OUT_PIN14_Pos) /*!< Bit mask of PIN14 field. */ #define GPIO_OUT_PIN14_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN14_High (1UL) /*!< Pin driver is high */ -/* Bit 13 : P0.13 pin */ +/* Bit 13 : Pin 13 */ #define GPIO_OUT_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ #define GPIO_OUT_PIN13_Msk (0x1UL << GPIO_OUT_PIN13_Pos) /*!< Bit mask of PIN13 field. */ #define GPIO_OUT_PIN13_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN13_High (1UL) /*!< Pin driver is high */ -/* Bit 12 : P0.12 pin */ +/* Bit 12 : Pin 12 */ #define GPIO_OUT_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ #define GPIO_OUT_PIN12_Msk (0x1UL << GPIO_OUT_PIN12_Pos) /*!< Bit mask of PIN12 field. */ #define GPIO_OUT_PIN12_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN12_High (1UL) /*!< Pin driver is high */ -/* Bit 11 : P0.11 pin */ +/* Bit 11 : Pin 11 */ #define GPIO_OUT_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ #define GPIO_OUT_PIN11_Msk (0x1UL << GPIO_OUT_PIN11_Pos) /*!< Bit mask of PIN11 field. */ #define GPIO_OUT_PIN11_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN11_High (1UL) /*!< Pin driver is high */ -/* Bit 10 : P0.10 pin */ +/* Bit 10 : Pin 10 */ #define GPIO_OUT_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ #define GPIO_OUT_PIN10_Msk (0x1UL << GPIO_OUT_PIN10_Pos) /*!< Bit mask of PIN10 field. */ #define GPIO_OUT_PIN10_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN10_High (1UL) /*!< Pin driver is high */ -/* Bit 9 : P0.9 pin */ +/* Bit 9 : Pin 9 */ #define GPIO_OUT_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ #define GPIO_OUT_PIN9_Msk (0x1UL << GPIO_OUT_PIN9_Pos) /*!< Bit mask of PIN9 field. */ #define GPIO_OUT_PIN9_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN9_High (1UL) /*!< Pin driver is high */ -/* Bit 8 : P0.8 pin */ +/* Bit 8 : Pin 8 */ #define GPIO_OUT_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ #define GPIO_OUT_PIN8_Msk (0x1UL << GPIO_OUT_PIN8_Pos) /*!< Bit mask of PIN8 field. */ #define GPIO_OUT_PIN8_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN8_High (1UL) /*!< Pin driver is high */ -/* Bit 7 : P0.7 pin */ +/* Bit 7 : Pin 7 */ #define GPIO_OUT_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ #define GPIO_OUT_PIN7_Msk (0x1UL << GPIO_OUT_PIN7_Pos) /*!< Bit mask of PIN7 field. */ #define GPIO_OUT_PIN7_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN7_High (1UL) /*!< Pin driver is high */ -/* Bit 6 : P0.6 pin */ +/* Bit 6 : Pin 6 */ #define GPIO_OUT_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ #define GPIO_OUT_PIN6_Msk (0x1UL << GPIO_OUT_PIN6_Pos) /*!< Bit mask of PIN6 field. */ #define GPIO_OUT_PIN6_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN6_High (1UL) /*!< Pin driver is high */ -/* Bit 5 : P0.5 pin */ +/* Bit 5 : Pin 5 */ #define GPIO_OUT_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ #define GPIO_OUT_PIN5_Msk (0x1UL << GPIO_OUT_PIN5_Pos) /*!< Bit mask of PIN5 field. */ #define GPIO_OUT_PIN5_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN5_High (1UL) /*!< Pin driver is high */ -/* Bit 4 : P0.4 pin */ +/* Bit 4 : Pin 4 */ #define GPIO_OUT_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ #define GPIO_OUT_PIN4_Msk (0x1UL << GPIO_OUT_PIN4_Pos) /*!< Bit mask of PIN4 field. */ #define GPIO_OUT_PIN4_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN4_High (1UL) /*!< Pin driver is high */ -/* Bit 3 : P0.3 pin */ +/* Bit 3 : Pin 3 */ #define GPIO_OUT_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ #define GPIO_OUT_PIN3_Msk (0x1UL << GPIO_OUT_PIN3_Pos) /*!< Bit mask of PIN3 field. */ #define GPIO_OUT_PIN3_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN3_High (1UL) /*!< Pin driver is high */ -/* Bit 2 : P0.2 pin */ +/* Bit 2 : Pin 2 */ #define GPIO_OUT_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ #define GPIO_OUT_PIN2_Msk (0x1UL << GPIO_OUT_PIN2_Pos) /*!< Bit mask of PIN2 field. */ #define GPIO_OUT_PIN2_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN2_High (1UL) /*!< Pin driver is high */ -/* Bit 1 : P0.1 pin */ +/* Bit 1 : Pin 1 */ #define GPIO_OUT_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ #define GPIO_OUT_PIN1_Msk (0x1UL << GPIO_OUT_PIN1_Pos) /*!< Bit mask of PIN1 field. */ #define GPIO_OUT_PIN1_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN1_High (1UL) /*!< Pin driver is high */ -/* Bit 0 : P0.0 pin */ +/* Bit 0 : Pin 0 */ #define GPIO_OUT_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ #define GPIO_OUT_PIN0_Msk (0x1UL << GPIO_OUT_PIN0_Pos) /*!< Bit mask of PIN0 field. */ #define GPIO_OUT_PIN0_Low (0UL) /*!< Pin driver is low */ @@ -4922,224 +5031,224 @@ /* Register: GPIO_OUTSET */ /* Description: Set individual bits in GPIO port */ -/* Bit 31 : P0.31 pin */ +/* Bit 31 : Pin 31 */ #define GPIO_OUTSET_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ #define GPIO_OUTSET_PIN31_Msk (0x1UL << GPIO_OUTSET_PIN31_Pos) /*!< Bit mask of PIN31 field. */ #define GPIO_OUTSET_PIN31_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN31_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN31_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 30 : P0.30 pin */ +/* Bit 30 : Pin 30 */ #define GPIO_OUTSET_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ #define GPIO_OUTSET_PIN30_Msk (0x1UL << GPIO_OUTSET_PIN30_Pos) /*!< Bit mask of PIN30 field. */ #define GPIO_OUTSET_PIN30_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN30_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN30_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 29 : P0.29 pin */ +/* Bit 29 : Pin 29 */ #define GPIO_OUTSET_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ #define GPIO_OUTSET_PIN29_Msk (0x1UL << GPIO_OUTSET_PIN29_Pos) /*!< Bit mask of PIN29 field. */ #define GPIO_OUTSET_PIN29_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN29_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN29_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 28 : P0.28 pin */ +/* Bit 28 : Pin 28 */ #define GPIO_OUTSET_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ #define GPIO_OUTSET_PIN28_Msk (0x1UL << GPIO_OUTSET_PIN28_Pos) /*!< Bit mask of PIN28 field. */ #define GPIO_OUTSET_PIN28_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN28_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN28_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 27 : P0.27 pin */ +/* Bit 27 : Pin 27 */ #define GPIO_OUTSET_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ #define GPIO_OUTSET_PIN27_Msk (0x1UL << GPIO_OUTSET_PIN27_Pos) /*!< Bit mask of PIN27 field. */ #define GPIO_OUTSET_PIN27_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN27_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN27_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 26 : P0.26 pin */ +/* Bit 26 : Pin 26 */ #define GPIO_OUTSET_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ #define GPIO_OUTSET_PIN26_Msk (0x1UL << GPIO_OUTSET_PIN26_Pos) /*!< Bit mask of PIN26 field. */ #define GPIO_OUTSET_PIN26_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN26_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN26_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 25 : P0.25 pin */ +/* Bit 25 : Pin 25 */ #define GPIO_OUTSET_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ #define GPIO_OUTSET_PIN25_Msk (0x1UL << GPIO_OUTSET_PIN25_Pos) /*!< Bit mask of PIN25 field. */ #define GPIO_OUTSET_PIN25_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN25_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN25_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 24 : P0.24 pin */ +/* Bit 24 : Pin 24 */ #define GPIO_OUTSET_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ #define GPIO_OUTSET_PIN24_Msk (0x1UL << GPIO_OUTSET_PIN24_Pos) /*!< Bit mask of PIN24 field. */ #define GPIO_OUTSET_PIN24_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN24_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN24_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 23 : P0.23 pin */ +/* Bit 23 : Pin 23 */ #define GPIO_OUTSET_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ #define GPIO_OUTSET_PIN23_Msk (0x1UL << GPIO_OUTSET_PIN23_Pos) /*!< Bit mask of PIN23 field. */ #define GPIO_OUTSET_PIN23_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN23_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN23_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 22 : P0.22 pin */ +/* Bit 22 : Pin 22 */ #define GPIO_OUTSET_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ #define GPIO_OUTSET_PIN22_Msk (0x1UL << GPIO_OUTSET_PIN22_Pos) /*!< Bit mask of PIN22 field. */ #define GPIO_OUTSET_PIN22_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN22_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN22_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 21 : P0.21 pin */ +/* Bit 21 : Pin 21 */ #define GPIO_OUTSET_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ #define GPIO_OUTSET_PIN21_Msk (0x1UL << GPIO_OUTSET_PIN21_Pos) /*!< Bit mask of PIN21 field. */ #define GPIO_OUTSET_PIN21_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN21_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN21_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 20 : P0.20 pin */ +/* Bit 20 : Pin 20 */ #define GPIO_OUTSET_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ #define GPIO_OUTSET_PIN20_Msk (0x1UL << GPIO_OUTSET_PIN20_Pos) /*!< Bit mask of PIN20 field. */ #define GPIO_OUTSET_PIN20_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN20_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN20_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 19 : P0.19 pin */ +/* Bit 19 : Pin 19 */ #define GPIO_OUTSET_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ #define GPIO_OUTSET_PIN19_Msk (0x1UL << GPIO_OUTSET_PIN19_Pos) /*!< Bit mask of PIN19 field. */ #define GPIO_OUTSET_PIN19_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN19_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN19_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 18 : P0.18 pin */ +/* Bit 18 : Pin 18 */ #define GPIO_OUTSET_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ #define GPIO_OUTSET_PIN18_Msk (0x1UL << GPIO_OUTSET_PIN18_Pos) /*!< Bit mask of PIN18 field. */ #define GPIO_OUTSET_PIN18_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN18_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN18_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 17 : P0.17 pin */ +/* Bit 17 : Pin 17 */ #define GPIO_OUTSET_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ #define GPIO_OUTSET_PIN17_Msk (0x1UL << GPIO_OUTSET_PIN17_Pos) /*!< Bit mask of PIN17 field. */ #define GPIO_OUTSET_PIN17_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN17_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN17_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 16 : P0.16 pin */ +/* Bit 16 : Pin 16 */ #define GPIO_OUTSET_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ #define GPIO_OUTSET_PIN16_Msk (0x1UL << GPIO_OUTSET_PIN16_Pos) /*!< Bit mask of PIN16 field. */ #define GPIO_OUTSET_PIN16_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN16_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN16_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 15 : P0.15 pin */ +/* Bit 15 : Pin 15 */ #define GPIO_OUTSET_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ #define GPIO_OUTSET_PIN15_Msk (0x1UL << GPIO_OUTSET_PIN15_Pos) /*!< Bit mask of PIN15 field. */ #define GPIO_OUTSET_PIN15_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN15_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN15_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 14 : P0.14 pin */ +/* Bit 14 : Pin 14 */ #define GPIO_OUTSET_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ #define GPIO_OUTSET_PIN14_Msk (0x1UL << GPIO_OUTSET_PIN14_Pos) /*!< Bit mask of PIN14 field. */ #define GPIO_OUTSET_PIN14_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN14_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN14_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 13 : P0.13 pin */ +/* Bit 13 : Pin 13 */ #define GPIO_OUTSET_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ #define GPIO_OUTSET_PIN13_Msk (0x1UL << GPIO_OUTSET_PIN13_Pos) /*!< Bit mask of PIN13 field. */ #define GPIO_OUTSET_PIN13_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN13_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN13_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 12 : P0.12 pin */ +/* Bit 12 : Pin 12 */ #define GPIO_OUTSET_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ #define GPIO_OUTSET_PIN12_Msk (0x1UL << GPIO_OUTSET_PIN12_Pos) /*!< Bit mask of PIN12 field. */ #define GPIO_OUTSET_PIN12_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN12_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN12_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 11 : P0.11 pin */ +/* Bit 11 : Pin 11 */ #define GPIO_OUTSET_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ #define GPIO_OUTSET_PIN11_Msk (0x1UL << GPIO_OUTSET_PIN11_Pos) /*!< Bit mask of PIN11 field. */ #define GPIO_OUTSET_PIN11_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN11_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN11_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 10 : P0.10 pin */ +/* Bit 10 : Pin 10 */ #define GPIO_OUTSET_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ #define GPIO_OUTSET_PIN10_Msk (0x1UL << GPIO_OUTSET_PIN10_Pos) /*!< Bit mask of PIN10 field. */ #define GPIO_OUTSET_PIN10_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN10_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN10_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 9 : P0.9 pin */ +/* Bit 9 : Pin 9 */ #define GPIO_OUTSET_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ #define GPIO_OUTSET_PIN9_Msk (0x1UL << GPIO_OUTSET_PIN9_Pos) /*!< Bit mask of PIN9 field. */ #define GPIO_OUTSET_PIN9_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN9_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN9_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 8 : P0.8 pin */ +/* Bit 8 : Pin 8 */ #define GPIO_OUTSET_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ #define GPIO_OUTSET_PIN8_Msk (0x1UL << GPIO_OUTSET_PIN8_Pos) /*!< Bit mask of PIN8 field. */ #define GPIO_OUTSET_PIN8_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN8_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN8_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 7 : P0.7 pin */ +/* Bit 7 : Pin 7 */ #define GPIO_OUTSET_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ #define GPIO_OUTSET_PIN7_Msk (0x1UL << GPIO_OUTSET_PIN7_Pos) /*!< Bit mask of PIN7 field. */ #define GPIO_OUTSET_PIN7_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN7_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN7_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 6 : P0.6 pin */ +/* Bit 6 : Pin 6 */ #define GPIO_OUTSET_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ #define GPIO_OUTSET_PIN6_Msk (0x1UL << GPIO_OUTSET_PIN6_Pos) /*!< Bit mask of PIN6 field. */ #define GPIO_OUTSET_PIN6_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN6_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN6_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 5 : P0.5 pin */ +/* Bit 5 : Pin 5 */ #define GPIO_OUTSET_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ #define GPIO_OUTSET_PIN5_Msk (0x1UL << GPIO_OUTSET_PIN5_Pos) /*!< Bit mask of PIN5 field. */ #define GPIO_OUTSET_PIN5_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN5_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN5_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 4 : P0.4 pin */ +/* Bit 4 : Pin 4 */ #define GPIO_OUTSET_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ #define GPIO_OUTSET_PIN4_Msk (0x1UL << GPIO_OUTSET_PIN4_Pos) /*!< Bit mask of PIN4 field. */ #define GPIO_OUTSET_PIN4_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN4_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN4_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 3 : P0.3 pin */ +/* Bit 3 : Pin 3 */ #define GPIO_OUTSET_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ #define GPIO_OUTSET_PIN3_Msk (0x1UL << GPIO_OUTSET_PIN3_Pos) /*!< Bit mask of PIN3 field. */ #define GPIO_OUTSET_PIN3_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN3_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN3_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 2 : P0.2 pin */ +/* Bit 2 : Pin 2 */ #define GPIO_OUTSET_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ #define GPIO_OUTSET_PIN2_Msk (0x1UL << GPIO_OUTSET_PIN2_Pos) /*!< Bit mask of PIN2 field. */ #define GPIO_OUTSET_PIN2_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN2_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN2_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 1 : P0.1 pin */ +/* Bit 1 : Pin 1 */ #define GPIO_OUTSET_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ #define GPIO_OUTSET_PIN1_Msk (0x1UL << GPIO_OUTSET_PIN1_Pos) /*!< Bit mask of PIN1 field. */ #define GPIO_OUTSET_PIN1_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN1_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN1_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 0 : P0.0 pin */ +/* Bit 0 : Pin 0 */ #define GPIO_OUTSET_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ #define GPIO_OUTSET_PIN0_Msk (0x1UL << GPIO_OUTSET_PIN0_Pos) /*!< Bit mask of PIN0 field. */ #define GPIO_OUTSET_PIN0_Low (0UL) /*!< Read: pin driver is low */ @@ -5149,224 +5258,224 @@ /* Register: GPIO_OUTCLR */ /* Description: Clear individual bits in GPIO port */ -/* Bit 31 : P0.31 pin */ +/* Bit 31 : Pin 31 */ #define GPIO_OUTCLR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ #define GPIO_OUTCLR_PIN31_Msk (0x1UL << GPIO_OUTCLR_PIN31_Pos) /*!< Bit mask of PIN31 field. */ #define GPIO_OUTCLR_PIN31_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN31_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN31_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 30 : P0.30 pin */ +/* Bit 30 : Pin 30 */ #define GPIO_OUTCLR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ #define GPIO_OUTCLR_PIN30_Msk (0x1UL << GPIO_OUTCLR_PIN30_Pos) /*!< Bit mask of PIN30 field. */ #define GPIO_OUTCLR_PIN30_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN30_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN30_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 29 : P0.29 pin */ +/* Bit 29 : Pin 29 */ #define GPIO_OUTCLR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ #define GPIO_OUTCLR_PIN29_Msk (0x1UL << GPIO_OUTCLR_PIN29_Pos) /*!< Bit mask of PIN29 field. */ #define GPIO_OUTCLR_PIN29_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN29_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN29_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 28 : P0.28 pin */ +/* Bit 28 : Pin 28 */ #define GPIO_OUTCLR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ #define GPIO_OUTCLR_PIN28_Msk (0x1UL << GPIO_OUTCLR_PIN28_Pos) /*!< Bit mask of PIN28 field. */ #define GPIO_OUTCLR_PIN28_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN28_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN28_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 27 : P0.27 pin */ +/* Bit 27 : Pin 27 */ #define GPIO_OUTCLR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ #define GPIO_OUTCLR_PIN27_Msk (0x1UL << GPIO_OUTCLR_PIN27_Pos) /*!< Bit mask of PIN27 field. */ #define GPIO_OUTCLR_PIN27_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN27_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN27_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 26 : P0.26 pin */ +/* Bit 26 : Pin 26 */ #define GPIO_OUTCLR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ #define GPIO_OUTCLR_PIN26_Msk (0x1UL << GPIO_OUTCLR_PIN26_Pos) /*!< Bit mask of PIN26 field. */ #define GPIO_OUTCLR_PIN26_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN26_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN26_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 25 : P0.25 pin */ +/* Bit 25 : Pin 25 */ #define GPIO_OUTCLR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ #define GPIO_OUTCLR_PIN25_Msk (0x1UL << GPIO_OUTCLR_PIN25_Pos) /*!< Bit mask of PIN25 field. */ #define GPIO_OUTCLR_PIN25_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN25_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN25_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 24 : P0.24 pin */ +/* Bit 24 : Pin 24 */ #define GPIO_OUTCLR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ #define GPIO_OUTCLR_PIN24_Msk (0x1UL << GPIO_OUTCLR_PIN24_Pos) /*!< Bit mask of PIN24 field. */ #define GPIO_OUTCLR_PIN24_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN24_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN24_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 23 : P0.23 pin */ +/* Bit 23 : Pin 23 */ #define GPIO_OUTCLR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ #define GPIO_OUTCLR_PIN23_Msk (0x1UL << GPIO_OUTCLR_PIN23_Pos) /*!< Bit mask of PIN23 field. */ #define GPIO_OUTCLR_PIN23_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN23_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN23_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 22 : P0.22 pin */ +/* Bit 22 : Pin 22 */ #define GPIO_OUTCLR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ #define GPIO_OUTCLR_PIN22_Msk (0x1UL << GPIO_OUTCLR_PIN22_Pos) /*!< Bit mask of PIN22 field. */ #define GPIO_OUTCLR_PIN22_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN22_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN22_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 21 : P0.21 pin */ +/* Bit 21 : Pin 21 */ #define GPIO_OUTCLR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ #define GPIO_OUTCLR_PIN21_Msk (0x1UL << GPIO_OUTCLR_PIN21_Pos) /*!< Bit mask of PIN21 field. */ #define GPIO_OUTCLR_PIN21_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN21_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN21_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 20 : P0.20 pin */ +/* Bit 20 : Pin 20 */ #define GPIO_OUTCLR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ #define GPIO_OUTCLR_PIN20_Msk (0x1UL << GPIO_OUTCLR_PIN20_Pos) /*!< Bit mask of PIN20 field. */ #define GPIO_OUTCLR_PIN20_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN20_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN20_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 19 : P0.19 pin */ +/* Bit 19 : Pin 19 */ #define GPIO_OUTCLR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ #define GPIO_OUTCLR_PIN19_Msk (0x1UL << GPIO_OUTCLR_PIN19_Pos) /*!< Bit mask of PIN19 field. */ #define GPIO_OUTCLR_PIN19_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN19_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN19_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 18 : P0.18 pin */ +/* Bit 18 : Pin 18 */ #define GPIO_OUTCLR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ #define GPIO_OUTCLR_PIN18_Msk (0x1UL << GPIO_OUTCLR_PIN18_Pos) /*!< Bit mask of PIN18 field. */ #define GPIO_OUTCLR_PIN18_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN18_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN18_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 17 : P0.17 pin */ +/* Bit 17 : Pin 17 */ #define GPIO_OUTCLR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ #define GPIO_OUTCLR_PIN17_Msk (0x1UL << GPIO_OUTCLR_PIN17_Pos) /*!< Bit mask of PIN17 field. */ #define GPIO_OUTCLR_PIN17_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN17_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN17_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 16 : P0.16 pin */ +/* Bit 16 : Pin 16 */ #define GPIO_OUTCLR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ #define GPIO_OUTCLR_PIN16_Msk (0x1UL << GPIO_OUTCLR_PIN16_Pos) /*!< Bit mask of PIN16 field. */ #define GPIO_OUTCLR_PIN16_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN16_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN16_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 15 : P0.15 pin */ +/* Bit 15 : Pin 15 */ #define GPIO_OUTCLR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ #define GPIO_OUTCLR_PIN15_Msk (0x1UL << GPIO_OUTCLR_PIN15_Pos) /*!< Bit mask of PIN15 field. */ #define GPIO_OUTCLR_PIN15_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN15_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN15_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 14 : P0.14 pin */ +/* Bit 14 : Pin 14 */ #define GPIO_OUTCLR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ #define GPIO_OUTCLR_PIN14_Msk (0x1UL << GPIO_OUTCLR_PIN14_Pos) /*!< Bit mask of PIN14 field. */ #define GPIO_OUTCLR_PIN14_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN14_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN14_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 13 : P0.13 pin */ +/* Bit 13 : Pin 13 */ #define GPIO_OUTCLR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ #define GPIO_OUTCLR_PIN13_Msk (0x1UL << GPIO_OUTCLR_PIN13_Pos) /*!< Bit mask of PIN13 field. */ #define GPIO_OUTCLR_PIN13_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN13_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN13_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 12 : P0.12 pin */ +/* Bit 12 : Pin 12 */ #define GPIO_OUTCLR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ #define GPIO_OUTCLR_PIN12_Msk (0x1UL << GPIO_OUTCLR_PIN12_Pos) /*!< Bit mask of PIN12 field. */ #define GPIO_OUTCLR_PIN12_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN12_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN12_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 11 : P0.11 pin */ +/* Bit 11 : Pin 11 */ #define GPIO_OUTCLR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ #define GPIO_OUTCLR_PIN11_Msk (0x1UL << GPIO_OUTCLR_PIN11_Pos) /*!< Bit mask of PIN11 field. */ #define GPIO_OUTCLR_PIN11_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN11_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN11_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 10 : P0.10 pin */ +/* Bit 10 : Pin 10 */ #define GPIO_OUTCLR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ #define GPIO_OUTCLR_PIN10_Msk (0x1UL << GPIO_OUTCLR_PIN10_Pos) /*!< Bit mask of PIN10 field. */ #define GPIO_OUTCLR_PIN10_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN10_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN10_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 9 : P0.9 pin */ +/* Bit 9 : Pin 9 */ #define GPIO_OUTCLR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ #define GPIO_OUTCLR_PIN9_Msk (0x1UL << GPIO_OUTCLR_PIN9_Pos) /*!< Bit mask of PIN9 field. */ #define GPIO_OUTCLR_PIN9_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN9_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN9_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 8 : P0.8 pin */ +/* Bit 8 : Pin 8 */ #define GPIO_OUTCLR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ #define GPIO_OUTCLR_PIN8_Msk (0x1UL << GPIO_OUTCLR_PIN8_Pos) /*!< Bit mask of PIN8 field. */ #define GPIO_OUTCLR_PIN8_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN8_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN8_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 7 : P0.7 pin */ +/* Bit 7 : Pin 7 */ #define GPIO_OUTCLR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ #define GPIO_OUTCLR_PIN7_Msk (0x1UL << GPIO_OUTCLR_PIN7_Pos) /*!< Bit mask of PIN7 field. */ #define GPIO_OUTCLR_PIN7_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN7_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN7_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 6 : P0.6 pin */ +/* Bit 6 : Pin 6 */ #define GPIO_OUTCLR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ #define GPIO_OUTCLR_PIN6_Msk (0x1UL << GPIO_OUTCLR_PIN6_Pos) /*!< Bit mask of PIN6 field. */ #define GPIO_OUTCLR_PIN6_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN6_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN6_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 5 : P0.5 pin */ +/* Bit 5 : Pin 5 */ #define GPIO_OUTCLR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ #define GPIO_OUTCLR_PIN5_Msk (0x1UL << GPIO_OUTCLR_PIN5_Pos) /*!< Bit mask of PIN5 field. */ #define GPIO_OUTCLR_PIN5_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN5_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN5_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 4 : P0.4 pin */ +/* Bit 4 : Pin 4 */ #define GPIO_OUTCLR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ #define GPIO_OUTCLR_PIN4_Msk (0x1UL << GPIO_OUTCLR_PIN4_Pos) /*!< Bit mask of PIN4 field. */ #define GPIO_OUTCLR_PIN4_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN4_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN4_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 3 : P0.3 pin */ +/* Bit 3 : Pin 3 */ #define GPIO_OUTCLR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ #define GPIO_OUTCLR_PIN3_Msk (0x1UL << GPIO_OUTCLR_PIN3_Pos) /*!< Bit mask of PIN3 field. */ #define GPIO_OUTCLR_PIN3_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN3_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN3_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 2 : P0.2 pin */ +/* Bit 2 : Pin 2 */ #define GPIO_OUTCLR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ #define GPIO_OUTCLR_PIN2_Msk (0x1UL << GPIO_OUTCLR_PIN2_Pos) /*!< Bit mask of PIN2 field. */ #define GPIO_OUTCLR_PIN2_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN2_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN2_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 1 : P0.1 pin */ +/* Bit 1 : Pin 1 */ #define GPIO_OUTCLR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ #define GPIO_OUTCLR_PIN1_Msk (0x1UL << GPIO_OUTCLR_PIN1_Pos) /*!< Bit mask of PIN1 field. */ #define GPIO_OUTCLR_PIN1_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN1_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN1_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 0 : P0.0 pin */ +/* Bit 0 : Pin 0 */ #define GPIO_OUTCLR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ #define GPIO_OUTCLR_PIN0_Msk (0x1UL << GPIO_OUTCLR_PIN0_Pos) /*!< Bit mask of PIN0 field. */ #define GPIO_OUTCLR_PIN0_Low (0UL) /*!< Read: pin driver is low */ @@ -5376,193 +5485,193 @@ /* Register: GPIO_IN */ /* Description: Read GPIO port */ -/* Bit 31 : P0.31 pin */ +/* Bit 31 : Pin 31 */ #define GPIO_IN_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ #define GPIO_IN_PIN31_Msk (0x1UL << GPIO_IN_PIN31_Pos) /*!< Bit mask of PIN31 field. */ #define GPIO_IN_PIN31_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN31_High (1UL) /*!< Pin input is high */ -/* Bit 30 : P0.30 pin */ +/* Bit 30 : Pin 30 */ #define GPIO_IN_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ #define GPIO_IN_PIN30_Msk (0x1UL << GPIO_IN_PIN30_Pos) /*!< Bit mask of PIN30 field. */ #define GPIO_IN_PIN30_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN30_High (1UL) /*!< Pin input is high */ -/* Bit 29 : P0.29 pin */ +/* Bit 29 : Pin 29 */ #define GPIO_IN_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ #define GPIO_IN_PIN29_Msk (0x1UL << GPIO_IN_PIN29_Pos) /*!< Bit mask of PIN29 field. */ #define GPIO_IN_PIN29_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN29_High (1UL) /*!< Pin input is high */ -/* Bit 28 : P0.28 pin */ +/* Bit 28 : Pin 28 */ #define GPIO_IN_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ #define GPIO_IN_PIN28_Msk (0x1UL << GPIO_IN_PIN28_Pos) /*!< Bit mask of PIN28 field. */ #define GPIO_IN_PIN28_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN28_High (1UL) /*!< Pin input is high */ -/* Bit 27 : P0.27 pin */ +/* Bit 27 : Pin 27 */ #define GPIO_IN_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ #define GPIO_IN_PIN27_Msk (0x1UL << GPIO_IN_PIN27_Pos) /*!< Bit mask of PIN27 field. */ #define GPIO_IN_PIN27_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN27_High (1UL) /*!< Pin input is high */ -/* Bit 26 : P0.26 pin */ +/* Bit 26 : Pin 26 */ #define GPIO_IN_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ #define GPIO_IN_PIN26_Msk (0x1UL << GPIO_IN_PIN26_Pos) /*!< Bit mask of PIN26 field. */ #define GPIO_IN_PIN26_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN26_High (1UL) /*!< Pin input is high */ -/* Bit 25 : P0.25 pin */ +/* Bit 25 : Pin 25 */ #define GPIO_IN_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ #define GPIO_IN_PIN25_Msk (0x1UL << GPIO_IN_PIN25_Pos) /*!< Bit mask of PIN25 field. */ #define GPIO_IN_PIN25_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN25_High (1UL) /*!< Pin input is high */ -/* Bit 24 : P0.24 pin */ +/* Bit 24 : Pin 24 */ #define GPIO_IN_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ #define GPIO_IN_PIN24_Msk (0x1UL << GPIO_IN_PIN24_Pos) /*!< Bit mask of PIN24 field. */ #define GPIO_IN_PIN24_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN24_High (1UL) /*!< Pin input is high */ -/* Bit 23 : P0.23 pin */ +/* Bit 23 : Pin 23 */ #define GPIO_IN_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ #define GPIO_IN_PIN23_Msk (0x1UL << GPIO_IN_PIN23_Pos) /*!< Bit mask of PIN23 field. */ #define GPIO_IN_PIN23_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN23_High (1UL) /*!< Pin input is high */ -/* Bit 22 : P0.22 pin */ +/* Bit 22 : Pin 22 */ #define GPIO_IN_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ #define GPIO_IN_PIN22_Msk (0x1UL << GPIO_IN_PIN22_Pos) /*!< Bit mask of PIN22 field. */ #define GPIO_IN_PIN22_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN22_High (1UL) /*!< Pin input is high */ -/* Bit 21 : P0.21 pin */ +/* Bit 21 : Pin 21 */ #define GPIO_IN_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ #define GPIO_IN_PIN21_Msk (0x1UL << GPIO_IN_PIN21_Pos) /*!< Bit mask of PIN21 field. */ #define GPIO_IN_PIN21_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN21_High (1UL) /*!< Pin input is high */ -/* Bit 20 : P0.20 pin */ +/* Bit 20 : Pin 20 */ #define GPIO_IN_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ #define GPIO_IN_PIN20_Msk (0x1UL << GPIO_IN_PIN20_Pos) /*!< Bit mask of PIN20 field. */ #define GPIO_IN_PIN20_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN20_High (1UL) /*!< Pin input is high */ -/* Bit 19 : P0.19 pin */ +/* Bit 19 : Pin 19 */ #define GPIO_IN_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ #define GPIO_IN_PIN19_Msk (0x1UL << GPIO_IN_PIN19_Pos) /*!< Bit mask of PIN19 field. */ #define GPIO_IN_PIN19_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN19_High (1UL) /*!< Pin input is high */ -/* Bit 18 : P0.18 pin */ +/* Bit 18 : Pin 18 */ #define GPIO_IN_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ #define GPIO_IN_PIN18_Msk (0x1UL << GPIO_IN_PIN18_Pos) /*!< Bit mask of PIN18 field. */ #define GPIO_IN_PIN18_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN18_High (1UL) /*!< Pin input is high */ -/* Bit 17 : P0.17 pin */ +/* Bit 17 : Pin 17 */ #define GPIO_IN_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ #define GPIO_IN_PIN17_Msk (0x1UL << GPIO_IN_PIN17_Pos) /*!< Bit mask of PIN17 field. */ #define GPIO_IN_PIN17_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN17_High (1UL) /*!< Pin input is high */ -/* Bit 16 : P0.16 pin */ +/* Bit 16 : Pin 16 */ #define GPIO_IN_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ #define GPIO_IN_PIN16_Msk (0x1UL << GPIO_IN_PIN16_Pos) /*!< Bit mask of PIN16 field. */ #define GPIO_IN_PIN16_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN16_High (1UL) /*!< Pin input is high */ -/* Bit 15 : P0.15 pin */ +/* Bit 15 : Pin 15 */ #define GPIO_IN_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ #define GPIO_IN_PIN15_Msk (0x1UL << GPIO_IN_PIN15_Pos) /*!< Bit mask of PIN15 field. */ #define GPIO_IN_PIN15_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN15_High (1UL) /*!< Pin input is high */ -/* Bit 14 : P0.14 pin */ +/* Bit 14 : Pin 14 */ #define GPIO_IN_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ #define GPIO_IN_PIN14_Msk (0x1UL << GPIO_IN_PIN14_Pos) /*!< Bit mask of PIN14 field. */ #define GPIO_IN_PIN14_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN14_High (1UL) /*!< Pin input is high */ -/* Bit 13 : P0.13 pin */ +/* Bit 13 : Pin 13 */ #define GPIO_IN_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ #define GPIO_IN_PIN13_Msk (0x1UL << GPIO_IN_PIN13_Pos) /*!< Bit mask of PIN13 field. */ #define GPIO_IN_PIN13_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN13_High (1UL) /*!< Pin input is high */ -/* Bit 12 : P0.12 pin */ +/* Bit 12 : Pin 12 */ #define GPIO_IN_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ #define GPIO_IN_PIN12_Msk (0x1UL << GPIO_IN_PIN12_Pos) /*!< Bit mask of PIN12 field. */ #define GPIO_IN_PIN12_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN12_High (1UL) /*!< Pin input is high */ -/* Bit 11 : P0.11 pin */ +/* Bit 11 : Pin 11 */ #define GPIO_IN_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ #define GPIO_IN_PIN11_Msk (0x1UL << GPIO_IN_PIN11_Pos) /*!< Bit mask of PIN11 field. */ #define GPIO_IN_PIN11_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN11_High (1UL) /*!< Pin input is high */ -/* Bit 10 : P0.10 pin */ +/* Bit 10 : Pin 10 */ #define GPIO_IN_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ #define GPIO_IN_PIN10_Msk (0x1UL << GPIO_IN_PIN10_Pos) /*!< Bit mask of PIN10 field. */ #define GPIO_IN_PIN10_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN10_High (1UL) /*!< Pin input is high */ -/* Bit 9 : P0.9 pin */ +/* Bit 9 : Pin 9 */ #define GPIO_IN_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ #define GPIO_IN_PIN9_Msk (0x1UL << GPIO_IN_PIN9_Pos) /*!< Bit mask of PIN9 field. */ #define GPIO_IN_PIN9_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN9_High (1UL) /*!< Pin input is high */ -/* Bit 8 : P0.8 pin */ +/* Bit 8 : Pin 8 */ #define GPIO_IN_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ #define GPIO_IN_PIN8_Msk (0x1UL << GPIO_IN_PIN8_Pos) /*!< Bit mask of PIN8 field. */ #define GPIO_IN_PIN8_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN8_High (1UL) /*!< Pin input is high */ -/* Bit 7 : P0.7 pin */ +/* Bit 7 : Pin 7 */ #define GPIO_IN_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ #define GPIO_IN_PIN7_Msk (0x1UL << GPIO_IN_PIN7_Pos) /*!< Bit mask of PIN7 field. */ #define GPIO_IN_PIN7_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN7_High (1UL) /*!< Pin input is high */ -/* Bit 6 : P0.6 pin */ +/* Bit 6 : Pin 6 */ #define GPIO_IN_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ #define GPIO_IN_PIN6_Msk (0x1UL << GPIO_IN_PIN6_Pos) /*!< Bit mask of PIN6 field. */ #define GPIO_IN_PIN6_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN6_High (1UL) /*!< Pin input is high */ -/* Bit 5 : P0.5 pin */ +/* Bit 5 : Pin 5 */ #define GPIO_IN_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ #define GPIO_IN_PIN5_Msk (0x1UL << GPIO_IN_PIN5_Pos) /*!< Bit mask of PIN5 field. */ #define GPIO_IN_PIN5_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN5_High (1UL) /*!< Pin input is high */ -/* Bit 4 : P0.4 pin */ +/* Bit 4 : Pin 4 */ #define GPIO_IN_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ #define GPIO_IN_PIN4_Msk (0x1UL << GPIO_IN_PIN4_Pos) /*!< Bit mask of PIN4 field. */ #define GPIO_IN_PIN4_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN4_High (1UL) /*!< Pin input is high */ -/* Bit 3 : P0.3 pin */ +/* Bit 3 : Pin 3 */ #define GPIO_IN_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ #define GPIO_IN_PIN3_Msk (0x1UL << GPIO_IN_PIN3_Pos) /*!< Bit mask of PIN3 field. */ #define GPIO_IN_PIN3_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN3_High (1UL) /*!< Pin input is high */ -/* Bit 2 : P0.2 pin */ +/* Bit 2 : Pin 2 */ #define GPIO_IN_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ #define GPIO_IN_PIN2_Msk (0x1UL << GPIO_IN_PIN2_Pos) /*!< Bit mask of PIN2 field. */ #define GPIO_IN_PIN2_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN2_High (1UL) /*!< Pin input is high */ -/* Bit 1 : P0.1 pin */ +/* Bit 1 : Pin 1 */ #define GPIO_IN_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ #define GPIO_IN_PIN1_Msk (0x1UL << GPIO_IN_PIN1_Pos) /*!< Bit mask of PIN1 field. */ #define GPIO_IN_PIN1_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN1_High (1UL) /*!< Pin input is high */ -/* Bit 0 : P0.0 pin */ +/* Bit 0 : Pin 0 */ #define GPIO_IN_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ #define GPIO_IN_PIN0_Msk (0x1UL << GPIO_IN_PIN0_Pos) /*!< Bit mask of PIN0 field. */ #define GPIO_IN_PIN0_Low (0UL) /*!< Pin input is low */ @@ -5571,193 +5680,193 @@ /* Register: GPIO_DIR */ /* Description: Direction of GPIO pins */ -/* Bit 31 : P0.31 pin */ +/* Bit 31 : Pin 31 */ #define GPIO_DIR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ #define GPIO_DIR_PIN31_Msk (0x1UL << GPIO_DIR_PIN31_Pos) /*!< Bit mask of PIN31 field. */ #define GPIO_DIR_PIN31_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN31_Output (1UL) /*!< Pin set as output */ -/* Bit 30 : P0.30 pin */ +/* Bit 30 : Pin 30 */ #define GPIO_DIR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ #define GPIO_DIR_PIN30_Msk (0x1UL << GPIO_DIR_PIN30_Pos) /*!< Bit mask of PIN30 field. */ #define GPIO_DIR_PIN30_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN30_Output (1UL) /*!< Pin set as output */ -/* Bit 29 : P0.29 pin */ +/* Bit 29 : Pin 29 */ #define GPIO_DIR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ #define GPIO_DIR_PIN29_Msk (0x1UL << GPIO_DIR_PIN29_Pos) /*!< Bit mask of PIN29 field. */ #define GPIO_DIR_PIN29_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN29_Output (1UL) /*!< Pin set as output */ -/* Bit 28 : P0.28 pin */ +/* Bit 28 : Pin 28 */ #define GPIO_DIR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ #define GPIO_DIR_PIN28_Msk (0x1UL << GPIO_DIR_PIN28_Pos) /*!< Bit mask of PIN28 field. */ #define GPIO_DIR_PIN28_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN28_Output (1UL) /*!< Pin set as output */ -/* Bit 27 : P0.27 pin */ +/* Bit 27 : Pin 27 */ #define GPIO_DIR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ #define GPIO_DIR_PIN27_Msk (0x1UL << GPIO_DIR_PIN27_Pos) /*!< Bit mask of PIN27 field. */ #define GPIO_DIR_PIN27_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN27_Output (1UL) /*!< Pin set as output */ -/* Bit 26 : P0.26 pin */ +/* Bit 26 : Pin 26 */ #define GPIO_DIR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ #define GPIO_DIR_PIN26_Msk (0x1UL << GPIO_DIR_PIN26_Pos) /*!< Bit mask of PIN26 field. */ #define GPIO_DIR_PIN26_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN26_Output (1UL) /*!< Pin set as output */ -/* Bit 25 : P0.25 pin */ +/* Bit 25 : Pin 25 */ #define GPIO_DIR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ #define GPIO_DIR_PIN25_Msk (0x1UL << GPIO_DIR_PIN25_Pos) /*!< Bit mask of PIN25 field. */ #define GPIO_DIR_PIN25_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN25_Output (1UL) /*!< Pin set as output */ -/* Bit 24 : P0.24 pin */ +/* Bit 24 : Pin 24 */ #define GPIO_DIR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ #define GPIO_DIR_PIN24_Msk (0x1UL << GPIO_DIR_PIN24_Pos) /*!< Bit mask of PIN24 field. */ #define GPIO_DIR_PIN24_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN24_Output (1UL) /*!< Pin set as output */ -/* Bit 23 : P0.23 pin */ +/* Bit 23 : Pin 23 */ #define GPIO_DIR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ #define GPIO_DIR_PIN23_Msk (0x1UL << GPIO_DIR_PIN23_Pos) /*!< Bit mask of PIN23 field. */ #define GPIO_DIR_PIN23_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN23_Output (1UL) /*!< Pin set as output */ -/* Bit 22 : P0.22 pin */ +/* Bit 22 : Pin 22 */ #define GPIO_DIR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ #define GPIO_DIR_PIN22_Msk (0x1UL << GPIO_DIR_PIN22_Pos) /*!< Bit mask of PIN22 field. */ #define GPIO_DIR_PIN22_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN22_Output (1UL) /*!< Pin set as output */ -/* Bit 21 : P0.21 pin */ +/* Bit 21 : Pin 21 */ #define GPIO_DIR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ #define GPIO_DIR_PIN21_Msk (0x1UL << GPIO_DIR_PIN21_Pos) /*!< Bit mask of PIN21 field. */ #define GPIO_DIR_PIN21_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN21_Output (1UL) /*!< Pin set as output */ -/* Bit 20 : P0.20 pin */ +/* Bit 20 : Pin 20 */ #define GPIO_DIR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ #define GPIO_DIR_PIN20_Msk (0x1UL << GPIO_DIR_PIN20_Pos) /*!< Bit mask of PIN20 field. */ #define GPIO_DIR_PIN20_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN20_Output (1UL) /*!< Pin set as output */ -/* Bit 19 : P0.19 pin */ +/* Bit 19 : Pin 19 */ #define GPIO_DIR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ #define GPIO_DIR_PIN19_Msk (0x1UL << GPIO_DIR_PIN19_Pos) /*!< Bit mask of PIN19 field. */ #define GPIO_DIR_PIN19_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN19_Output (1UL) /*!< Pin set as output */ -/* Bit 18 : P0.18 pin */ +/* Bit 18 : Pin 18 */ #define GPIO_DIR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ #define GPIO_DIR_PIN18_Msk (0x1UL << GPIO_DIR_PIN18_Pos) /*!< Bit mask of PIN18 field. */ #define GPIO_DIR_PIN18_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN18_Output (1UL) /*!< Pin set as output */ -/* Bit 17 : P0.17 pin */ +/* Bit 17 : Pin 17 */ #define GPIO_DIR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ #define GPIO_DIR_PIN17_Msk (0x1UL << GPIO_DIR_PIN17_Pos) /*!< Bit mask of PIN17 field. */ #define GPIO_DIR_PIN17_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN17_Output (1UL) /*!< Pin set as output */ -/* Bit 16 : P0.16 pin */ +/* Bit 16 : Pin 16 */ #define GPIO_DIR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ #define GPIO_DIR_PIN16_Msk (0x1UL << GPIO_DIR_PIN16_Pos) /*!< Bit mask of PIN16 field. */ #define GPIO_DIR_PIN16_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN16_Output (1UL) /*!< Pin set as output */ -/* Bit 15 : P0.15 pin */ +/* Bit 15 : Pin 15 */ #define GPIO_DIR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ #define GPIO_DIR_PIN15_Msk (0x1UL << GPIO_DIR_PIN15_Pos) /*!< Bit mask of PIN15 field. */ #define GPIO_DIR_PIN15_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN15_Output (1UL) /*!< Pin set as output */ -/* Bit 14 : P0.14 pin */ +/* Bit 14 : Pin 14 */ #define GPIO_DIR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ #define GPIO_DIR_PIN14_Msk (0x1UL << GPIO_DIR_PIN14_Pos) /*!< Bit mask of PIN14 field. */ #define GPIO_DIR_PIN14_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN14_Output (1UL) /*!< Pin set as output */ -/* Bit 13 : P0.13 pin */ +/* Bit 13 : Pin 13 */ #define GPIO_DIR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ #define GPIO_DIR_PIN13_Msk (0x1UL << GPIO_DIR_PIN13_Pos) /*!< Bit mask of PIN13 field. */ #define GPIO_DIR_PIN13_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN13_Output (1UL) /*!< Pin set as output */ -/* Bit 12 : P0.12 pin */ +/* Bit 12 : Pin 12 */ #define GPIO_DIR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ #define GPIO_DIR_PIN12_Msk (0x1UL << GPIO_DIR_PIN12_Pos) /*!< Bit mask of PIN12 field. */ #define GPIO_DIR_PIN12_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN12_Output (1UL) /*!< Pin set as output */ -/* Bit 11 : P0.11 pin */ +/* Bit 11 : Pin 11 */ #define GPIO_DIR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ #define GPIO_DIR_PIN11_Msk (0x1UL << GPIO_DIR_PIN11_Pos) /*!< Bit mask of PIN11 field. */ #define GPIO_DIR_PIN11_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN11_Output (1UL) /*!< Pin set as output */ -/* Bit 10 : P0.10 pin */ +/* Bit 10 : Pin 10 */ #define GPIO_DIR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ #define GPIO_DIR_PIN10_Msk (0x1UL << GPIO_DIR_PIN10_Pos) /*!< Bit mask of PIN10 field. */ #define GPIO_DIR_PIN10_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN10_Output (1UL) /*!< Pin set as output */ -/* Bit 9 : P0.9 pin */ +/* Bit 9 : Pin 9 */ #define GPIO_DIR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ #define GPIO_DIR_PIN9_Msk (0x1UL << GPIO_DIR_PIN9_Pos) /*!< Bit mask of PIN9 field. */ #define GPIO_DIR_PIN9_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN9_Output (1UL) /*!< Pin set as output */ -/* Bit 8 : P0.8 pin */ +/* Bit 8 : Pin 8 */ #define GPIO_DIR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ #define GPIO_DIR_PIN8_Msk (0x1UL << GPIO_DIR_PIN8_Pos) /*!< Bit mask of PIN8 field. */ #define GPIO_DIR_PIN8_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN8_Output (1UL) /*!< Pin set as output */ -/* Bit 7 : P0.7 pin */ +/* Bit 7 : Pin 7 */ #define GPIO_DIR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ #define GPIO_DIR_PIN7_Msk (0x1UL << GPIO_DIR_PIN7_Pos) /*!< Bit mask of PIN7 field. */ #define GPIO_DIR_PIN7_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN7_Output (1UL) /*!< Pin set as output */ -/* Bit 6 : P0.6 pin */ +/* Bit 6 : Pin 6 */ #define GPIO_DIR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ #define GPIO_DIR_PIN6_Msk (0x1UL << GPIO_DIR_PIN6_Pos) /*!< Bit mask of PIN6 field. */ #define GPIO_DIR_PIN6_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN6_Output (1UL) /*!< Pin set as output */ -/* Bit 5 : P0.5 pin */ +/* Bit 5 : Pin 5 */ #define GPIO_DIR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ #define GPIO_DIR_PIN5_Msk (0x1UL << GPIO_DIR_PIN5_Pos) /*!< Bit mask of PIN5 field. */ #define GPIO_DIR_PIN5_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN5_Output (1UL) /*!< Pin set as output */ -/* Bit 4 : P0.4 pin */ +/* Bit 4 : Pin 4 */ #define GPIO_DIR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ #define GPIO_DIR_PIN4_Msk (0x1UL << GPIO_DIR_PIN4_Pos) /*!< Bit mask of PIN4 field. */ #define GPIO_DIR_PIN4_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN4_Output (1UL) /*!< Pin set as output */ -/* Bit 3 : P0.3 pin */ +/* Bit 3 : Pin 3 */ #define GPIO_DIR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ #define GPIO_DIR_PIN3_Msk (0x1UL << GPIO_DIR_PIN3_Pos) /*!< Bit mask of PIN3 field. */ #define GPIO_DIR_PIN3_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN3_Output (1UL) /*!< Pin set as output */ -/* Bit 2 : P0.2 pin */ +/* Bit 2 : Pin 2 */ #define GPIO_DIR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ #define GPIO_DIR_PIN2_Msk (0x1UL << GPIO_DIR_PIN2_Pos) /*!< Bit mask of PIN2 field. */ #define GPIO_DIR_PIN2_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN2_Output (1UL) /*!< Pin set as output */ -/* Bit 1 : P0.1 pin */ +/* Bit 1 : Pin 1 */ #define GPIO_DIR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ #define GPIO_DIR_PIN1_Msk (0x1UL << GPIO_DIR_PIN1_Pos) /*!< Bit mask of PIN1 field. */ #define GPIO_DIR_PIN1_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN1_Output (1UL) /*!< Pin set as output */ -/* Bit 0 : P0.0 pin */ +/* Bit 0 : Pin 0 */ #define GPIO_DIR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ #define GPIO_DIR_PIN0_Msk (0x1UL << GPIO_DIR_PIN0_Pos) /*!< Bit mask of PIN0 field. */ #define GPIO_DIR_PIN0_Input (0UL) /*!< Pin set as input */ @@ -6218,11 +6327,199 @@ #define GPIO_DIRCLR_PIN0_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ /* Register: GPIO_LATCH */ -/* Description: Latch indicating which GPIO pins have met the criteria set in PIN_CNF[n].SENSE register */ - -/* Bits 31..0 : Register holding a '1' for each GPIO pins which has met the criteria set in PIN_CNF[n].SENSE */ -#define GPIO_LATCH_LATCH_Pos (0UL) /*!< Position of LATCH field. */ -#define GPIO_LATCH_LATCH_Msk (0xFFFFFFFFUL << GPIO_LATCH_LATCH_Pos) /*!< Bit mask of LATCH field. */ +/* Description: Latch register indicating what GPIO pins that have met the criteria set in the PIN_CNF[n].SENSE registers */ + +/* Bit 31 : Status on whether PIN31 has met criteria set in PIN_CNF31.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_LATCH_PIN31_Msk (0x1UL << GPIO_LATCH_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_LATCH_PIN31_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN31_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 30 : Status on whether PIN30 has met criteria set in PIN_CNF30.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_LATCH_PIN30_Msk (0x1UL << GPIO_LATCH_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_LATCH_PIN30_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN30_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 29 : Status on whether PIN29 has met criteria set in PIN_CNF29.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_LATCH_PIN29_Msk (0x1UL << GPIO_LATCH_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_LATCH_PIN29_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN29_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 28 : Status on whether PIN28 has met criteria set in PIN_CNF28.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_LATCH_PIN28_Msk (0x1UL << GPIO_LATCH_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_LATCH_PIN28_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN28_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 27 : Status on whether PIN27 has met criteria set in PIN_CNF27.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_LATCH_PIN27_Msk (0x1UL << GPIO_LATCH_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_LATCH_PIN27_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN27_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 26 : Status on whether PIN26 has met criteria set in PIN_CNF26.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_LATCH_PIN26_Msk (0x1UL << GPIO_LATCH_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_LATCH_PIN26_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN26_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 25 : Status on whether PIN25 has met criteria set in PIN_CNF25.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_LATCH_PIN25_Msk (0x1UL << GPIO_LATCH_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_LATCH_PIN25_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN25_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 24 : Status on whether PIN24 has met criteria set in PIN_CNF24.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_LATCH_PIN24_Msk (0x1UL << GPIO_LATCH_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_LATCH_PIN24_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN24_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 23 : Status on whether PIN23 has met criteria set in PIN_CNF23.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_LATCH_PIN23_Msk (0x1UL << GPIO_LATCH_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_LATCH_PIN23_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN23_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 22 : Status on whether PIN22 has met criteria set in PIN_CNF22.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_LATCH_PIN22_Msk (0x1UL << GPIO_LATCH_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_LATCH_PIN22_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN22_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 21 : Status on whether PIN21 has met criteria set in PIN_CNF21.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_LATCH_PIN21_Msk (0x1UL << GPIO_LATCH_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_LATCH_PIN21_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN21_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 20 : Status on whether PIN20 has met criteria set in PIN_CNF20.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_LATCH_PIN20_Msk (0x1UL << GPIO_LATCH_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_LATCH_PIN20_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN20_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 19 : Status on whether PIN19 has met criteria set in PIN_CNF19.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_LATCH_PIN19_Msk (0x1UL << GPIO_LATCH_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_LATCH_PIN19_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN19_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 18 : Status on whether PIN18 has met criteria set in PIN_CNF18.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_LATCH_PIN18_Msk (0x1UL << GPIO_LATCH_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_LATCH_PIN18_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN18_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 17 : Status on whether PIN17 has met criteria set in PIN_CNF17.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_LATCH_PIN17_Msk (0x1UL << GPIO_LATCH_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_LATCH_PIN17_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN17_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 16 : Status on whether PIN16 has met criteria set in PIN_CNF16.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_LATCH_PIN16_Msk (0x1UL << GPIO_LATCH_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_LATCH_PIN16_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN16_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 15 : Status on whether PIN15 has met criteria set in PIN_CNF15.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_LATCH_PIN15_Msk (0x1UL << GPIO_LATCH_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_LATCH_PIN15_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN15_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 14 : Status on whether PIN14 has met criteria set in PIN_CNF14.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_LATCH_PIN14_Msk (0x1UL << GPIO_LATCH_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_LATCH_PIN14_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN14_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 13 : Status on whether PIN13 has met criteria set in PIN_CNF13.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_LATCH_PIN13_Msk (0x1UL << GPIO_LATCH_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_LATCH_PIN13_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN13_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 12 : Status on whether PIN12 has met criteria set in PIN_CNF12.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_LATCH_PIN12_Msk (0x1UL << GPIO_LATCH_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_LATCH_PIN12_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN12_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 11 : Status on whether PIN11 has met criteria set in PIN_CNF11.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_LATCH_PIN11_Msk (0x1UL << GPIO_LATCH_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_LATCH_PIN11_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN11_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 10 : Status on whether PIN10 has met criteria set in PIN_CNF10.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_LATCH_PIN10_Msk (0x1UL << GPIO_LATCH_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_LATCH_PIN10_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN10_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 9 : Status on whether PIN9 has met criteria set in PIN_CNF9.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_LATCH_PIN9_Msk (0x1UL << GPIO_LATCH_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_LATCH_PIN9_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN9_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 8 : Status on whether PIN8 has met criteria set in PIN_CNF8.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_LATCH_PIN8_Msk (0x1UL << GPIO_LATCH_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_LATCH_PIN8_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN8_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 7 : Status on whether PIN7 has met criteria set in PIN_CNF7.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_LATCH_PIN7_Msk (0x1UL << GPIO_LATCH_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_LATCH_PIN7_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN7_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 6 : Status on whether PIN6 has met criteria set in PIN_CNF6.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_LATCH_PIN6_Msk (0x1UL << GPIO_LATCH_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_LATCH_PIN6_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN6_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 5 : Status on whether PIN5 has met criteria set in PIN_CNF5.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_LATCH_PIN5_Msk (0x1UL << GPIO_LATCH_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_LATCH_PIN5_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN5_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 4 : Status on whether PIN4 has met criteria set in PIN_CNF4.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_LATCH_PIN4_Msk (0x1UL << GPIO_LATCH_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_LATCH_PIN4_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN4_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 3 : Status on whether PIN3 has met criteria set in PIN_CNF3.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_LATCH_PIN3_Msk (0x1UL << GPIO_LATCH_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_LATCH_PIN3_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN3_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 2 : Status on whether PIN2 has met criteria set in PIN_CNF2.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_LATCH_PIN2_Msk (0x1UL << GPIO_LATCH_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_LATCH_PIN2_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN2_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 1 : Status on whether PIN1 has met criteria set in PIN_CNF1.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_LATCH_PIN1_Msk (0x1UL << GPIO_LATCH_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_LATCH_PIN1_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN1_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 0 : Status on whether PIN0 has met criteria set in PIN_CNF0.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_LATCH_PIN0_Msk (0x1UL << GPIO_LATCH_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_LATCH_PIN0_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN0_Latched (1UL) /*!< Criteria has been met */ /* Register: GPIO_DETECTMODE */ /* Description: Select between default DETECT signal behaviour and LDETECT mode */ @@ -6230,8 +6527,8 @@ /* Bit 0 : Select between default DETECT signal behaviour and LDETECT mode */ #define GPIO_DETECTMODE_DETECTMODE_Pos (0UL) /*!< Position of DETECTMODE field. */ #define GPIO_DETECTMODE_DETECTMODE_Msk (0x1UL << GPIO_DETECTMODE_DETECTMODE_Pos) /*!< Bit mask of DETECTMODE field. */ -#define GPIO_DETECTMODE_DETECTMODE_Default (0UL) /*!< Use default behaviour */ -#define GPIO_DETECTMODE_DETECTMODE_LDETECT (1UL) /*!< Use LDETECT behaviour */ +#define GPIO_DETECTMODE_DETECTMODE_Default (0UL) /*!< DETECT directly connected to PIN DETECT signals */ +#define GPIO_DETECTMODE_DETECTMODE_LDETECT (1UL) /*!< Use the latched LDETECT behaviour */ /* Register: GPIO_PIN_CNF */ /* Description: Description collection[0]: Configuration of GPIO pins */ @@ -6250,10 +6547,10 @@ #define GPIO_PIN_CNF_DRIVE_H0S1 (1UL) /*!< High drive '0', standard '1' */ #define GPIO_PIN_CNF_DRIVE_S0H1 (2UL) /*!< Standard '0', high drive '1' */ #define GPIO_PIN_CNF_DRIVE_H0H1 (3UL) /*!< High drive '0', high 'drive '1'' */ -#define GPIO_PIN_CNF_DRIVE_D0S1 (4UL) /*!< Disconnect '0' standard '1' */ -#define GPIO_PIN_CNF_DRIVE_D0H1 (5UL) /*!< Disconnect '0', high drive '1' */ -#define GPIO_PIN_CNF_DRIVE_S0D1 (6UL) /*!< Standard '0'. disconnect '1' */ -#define GPIO_PIN_CNF_DRIVE_H0D1 (7UL) /*!< High drive '0', disconnect '1' */ +#define GPIO_PIN_CNF_DRIVE_D0S1 (4UL) /*!< Disconnect '0' standard '1' (normally used for wired-or connections) */ +#define GPIO_PIN_CNF_DRIVE_D0H1 (5UL) /*!< Disconnect '0', high drive '1' (normally used for wired-or connections) */ +#define GPIO_PIN_CNF_DRIVE_S0D1 (6UL) /*!< Standard '0'. disconnect '1' (normally used for wired-and connections) */ +#define GPIO_PIN_CNF_DRIVE_H0D1 (7UL) /*!< High drive '0', disconnect '1' (normally used for wired-and connections) */ /* Bits 3..2 : Pull configuration */ #define GPIO_PIN_CNF_PULL_Pos (2UL) /*!< Position of PULL field. */ @@ -6268,7 +6565,7 @@ #define GPIO_PIN_CNF_INPUT_Connect (0UL) /*!< Connect input buffer */ #define GPIO_PIN_CNF_INPUT_Disconnect (1UL) /*!< Disconnect input buffer */ -/* Bit 0 : Pin direction */ +/* Bit 0 : Pin direction. Same physical register as DIR register */ #define GPIO_PIN_CNF_DIR_Pos (0UL) /*!< Position of DIR field. */ #define GPIO_PIN_CNF_DIR_Msk (0x1UL << GPIO_PIN_CNF_DIR_Pos) /*!< Bit mask of DIR field. */ #define GPIO_PIN_CNF_DIR_Input (0UL) /*!< Configure pin as an input pin */ @@ -6281,19 +6578,19 @@ /* Register: PDM_INTEN */ /* Description: Enable or disable interrupt */ -/* Bit 2 : Enable or disable interrupt on EVENTS_END event */ +/* Bit 2 : Enable or disable interrupt for END event */ #define PDM_INTEN_END_Pos (2UL) /*!< Position of END field. */ #define PDM_INTEN_END_Msk (0x1UL << PDM_INTEN_END_Pos) /*!< Bit mask of END field. */ #define PDM_INTEN_END_Disabled (0UL) /*!< Disable */ #define PDM_INTEN_END_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Enable or disable interrupt for STOPPED event */ #define PDM_INTEN_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define PDM_INTEN_STOPPED_Msk (0x1UL << PDM_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define PDM_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ #define PDM_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ -/* Bit 0 : Enable or disable interrupt on EVENTS_STARTED event */ +/* Bit 0 : Enable or disable interrupt for STARTED event */ #define PDM_INTEN_STARTED_Pos (0UL) /*!< Position of STARTED field. */ #define PDM_INTEN_STARTED_Msk (0x1UL << PDM_INTEN_STARTED_Pos) /*!< Bit mask of STARTED field. */ #define PDM_INTEN_STARTED_Disabled (0UL) /*!< Disable */ @@ -6302,21 +6599,21 @@ /* Register: PDM_INTENSET */ /* Description: Enable interrupt */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_END event */ +/* Bit 2 : Write '1' to Enable interrupt for END event */ #define PDM_INTENSET_END_Pos (2UL) /*!< Position of END field. */ #define PDM_INTENSET_END_Msk (0x1UL << PDM_INTENSET_END_Pos) /*!< Bit mask of END field. */ #define PDM_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ #define PDM_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ #define PDM_INTENSET_END_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ #define PDM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define PDM_INTENSET_STOPPED_Msk (0x1UL << PDM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define PDM_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ #define PDM_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ #define PDM_INTENSET_STOPPED_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_STARTED event */ +/* Bit 0 : Write '1' to Enable interrupt for STARTED event */ #define PDM_INTENSET_STARTED_Pos (0UL) /*!< Position of STARTED field. */ #define PDM_INTENSET_STARTED_Msk (0x1UL << PDM_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ #define PDM_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ @@ -6326,21 +6623,21 @@ /* Register: PDM_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_END event */ +/* Bit 2 : Write '1' to Disable interrupt for END event */ #define PDM_INTENCLR_END_Pos (2UL) /*!< Position of END field. */ #define PDM_INTENCLR_END_Msk (0x1UL << PDM_INTENCLR_END_Pos) /*!< Bit mask of END field. */ #define PDM_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ #define PDM_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ #define PDM_INTENCLR_END_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ #define PDM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define PDM_INTENCLR_STOPPED_Msk (0x1UL << PDM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define PDM_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ #define PDM_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ #define PDM_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_STARTED event */ +/* Bit 0 : Write '1' to Disable interrupt for STARTED event */ #define PDM_INTENCLR_STARTED_Pos (0UL) /*!< Position of STARTED field. */ #define PDM_INTENCLR_STARTED_Msk (0x1UL << PDM_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ #define PDM_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ @@ -6350,7 +6647,7 @@ /* Register: PDM_ENABLE */ /* Description: PDM module enable register */ -/* Bit 0 : Enable or disable PDM reception */ +/* Bit 0 : Enable or disable PDM module */ #define PDM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ #define PDM_ENABLE_ENABLE_Msk (0x1UL << PDM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ #define PDM_ENABLE_ENABLE_Disabled (0UL) /*!< Disable */ @@ -6362,9 +6659,9 @@ /* Bits 31..0 : PDM_CLK frequency */ #define PDM_PDMCLKCTRL_FREQ_Pos (0UL) /*!< Position of FREQ field. */ #define PDM_PDMCLKCTRL_FREQ_Msk (0xFFFFFFFFUL << PDM_PDMCLKCTRL_FREQ_Pos) /*!< Bit mask of FREQ field. */ -#define PDM_PDMCLKCTRL_FREQ_1000K (0x08000000UL) /*!< PDM_CLK = 1.000 MHz */ -#define PDM_PDMCLKCTRL_FREQ_1024K (0x08400000UL) /*!< PDM_CLK = 1.024 MHz */ -#define PDM_PDMCLKCTRL_FREQ_1067K (0x08800000UL) /*!< PDM_CLK = 1.067 MHz */ +#define PDM_PDMCLKCTRL_FREQ_1000K (0x08000000UL) /*!< PDM_CLK = 32 MHz / 32 = 1.000 MHz */ +#define PDM_PDMCLKCTRL_FREQ_Default (0x08400000UL) /*!< PDM_CLK = 32 MHz / 31 = 1.032 MHz */ +#define PDM_PDMCLKCTRL_FREQ_1067K (0x08800000UL) /*!< PDM_CLK = 32 MHz / 30 = 1.067 MHz */ /* Register: PDM_MODE */ /* Description: Defines the routing of the connected PDM microphones' signals */ @@ -6376,15 +6673,15 @@ #define PDM_MODE_EDGE_LeftRising (1UL) /*!< Left (or mono) is sampled on rising edge of PDM_CLK */ /* Bit 0 : Mono or stereo operation */ -#define PDM_MODE_MONO_Pos (0UL) /*!< Position of MONO field. */ -#define PDM_MODE_MONO_Msk (0x1UL << PDM_MODE_MONO_Pos) /*!< Bit mask of MONO field. */ -#define PDM_MODE_MONO_Stereo (0UL) /*!< Sample and store one pair (Left + Right) of 16bit samples per RAM word R=[31:16]; L=[15:0] */ -#define PDM_MODE_MONO_Mono (1UL) /*!< Sample and store two successive Left samples (16 bit each) per RAM word L1=[31:16]; L0=[15:0] */ +#define PDM_MODE_OPERATION_Pos (0UL) /*!< Position of OPERATION field. */ +#define PDM_MODE_OPERATION_Msk (0x1UL << PDM_MODE_OPERATION_Pos) /*!< Bit mask of OPERATION field. */ +#define PDM_MODE_OPERATION_Stereo (0UL) /*!< Sample and store one pair (Left + Right) of 16bit samples per RAM word R=[31:16]; L=[15:0] */ +#define PDM_MODE_OPERATION_Mono (1UL) /*!< Sample and store two successive Left samples (16 bit each) per RAM word L1=[31:16]; L0=[15:0] */ /* Register: PDM_GAINL */ /* Description: Left output gain adjustment */ -/* Bits 6..0 : Left output gain adjustment, in 0.5 dB steps, around the requirement that 0dB gain adjustment corresponds to 2500 RMS output samples (16-bit) with 1 kHz 90dBA signal into a -26dBFS sensitivity PDM microphone. 0x00 -20 dB gain 0x01 -19.5 dB gain (...) 0x27 -0.5 dB gain 0x28 0 dB gain 0x29 +0.5 dB gain (...) 0x4F +19.5 dB gain 0x50 +20 dB gain */ +/* Bits 6..0 : Left output gain adjustment, in 0.5 dB steps, around the default module gain (see electrical parameters) 0x00 -20 dB gain adjust 0x01 -19.5 dB gain adjust (...) 0x27 -0.5 dB gain adjust 0x28 0 dB gain adjust 0x29 +0.5 dB gain adjust (...) 0x4F +19.5 dB gain adjust 0x50 +20 dB gain adjust */ #define PDM_GAINL_GAINL_Pos (0UL) /*!< Position of GAINL field. */ #define PDM_GAINL_GAINL_Msk (0x7FUL << PDM_GAINL_GAINL_Pos) /*!< Bit mask of GAINL field. */ #define PDM_GAINL_GAINL_MinGain (0x00UL) /*!< -20dB gain adjustment (minimum) */ @@ -6394,7 +6691,7 @@ /* Register: PDM_GAINR */ /* Description: Right output gain adjustment */ -/* Bits 7..0 : Right output gain adjustment, in 0.5 dB steps, around the requirement that 0dB gain adjustment corresponds to 2500 RMS output samples (16-bit) with 1 kHz 90dBA signal into a -26dBFS sensitivity PDM microphone. (same encoding as GAINL) */ +/* Bits 7..0 : Right output gain adjustment, in 0.5 dB steps, around the default module gain (see electrical parameters) */ #define PDM_GAINR_GAINR_Pos (0UL) /*!< Position of GAINR field. */ #define PDM_GAINR_GAINR_Msk (0xFFUL << PDM_GAINR_GAINR_Pos) /*!< Bit mask of GAINR field. */ #define PDM_GAINR_GAINR_MinGain (0x00UL) /*!< -20dB gain adjustment (minimum) */ @@ -6437,7 +6734,7 @@ /* Register: PDM_SAMPLE_MAXCNT */ /* Description: Number of samples to allocate memory for in EasyDMA mode */ -/* Bits 14..0 : Length of DMA RAM allocation in number of samples. Number of RAM word allocated depends on MODE.CHANNELS. */ +/* Bits 14..0 : Length of DMA RAM allocation in number of samples */ #define PDM_SAMPLE_MAXCNT_BUFFSIZE_Pos (0UL) /*!< Position of BUFFSIZE field. */ #define PDM_SAMPLE_MAXCNT_BUFFSIZE_Msk (0x7FFFUL << PDM_SAMPLE_MAXCNT_BUFFSIZE_Pos) /*!< Bit mask of BUFFSIZE field. */ @@ -6448,21 +6745,21 @@ /* Register: POWER_INTENSET */ /* Description: Enable interrupt */ -/* Bit 6 : Write '1' to Enable interrupt on EVENTS_SLEEPEXIT event */ +/* Bit 6 : Write '1' to Enable interrupt for SLEEPEXIT event */ #define POWER_INTENSET_SLEEPEXIT_Pos (6UL) /*!< Position of SLEEPEXIT field. */ #define POWER_INTENSET_SLEEPEXIT_Msk (0x1UL << POWER_INTENSET_SLEEPEXIT_Pos) /*!< Bit mask of SLEEPEXIT field. */ #define POWER_INTENSET_SLEEPEXIT_Disabled (0UL) /*!< Read: Disabled */ #define POWER_INTENSET_SLEEPEXIT_Enabled (1UL) /*!< Read: Enabled */ #define POWER_INTENSET_SLEEPEXIT_Set (1UL) /*!< Enable */ -/* Bit 5 : Write '1' to Enable interrupt on EVENTS_SLEEPENTER event */ +/* Bit 5 : Write '1' to Enable interrupt for SLEEPENTER event */ #define POWER_INTENSET_SLEEPENTER_Pos (5UL) /*!< Position of SLEEPENTER field. */ #define POWER_INTENSET_SLEEPENTER_Msk (0x1UL << POWER_INTENSET_SLEEPENTER_Pos) /*!< Bit mask of SLEEPENTER field. */ #define POWER_INTENSET_SLEEPENTER_Disabled (0UL) /*!< Read: Disabled */ #define POWER_INTENSET_SLEEPENTER_Enabled (1UL) /*!< Read: Enabled */ #define POWER_INTENSET_SLEEPENTER_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_POFWARN event */ +/* Bit 2 : Write '1' to Enable interrupt for POFWARN event */ #define POWER_INTENSET_POFWARN_Pos (2UL) /*!< Position of POFWARN field. */ #define POWER_INTENSET_POFWARN_Msk (0x1UL << POWER_INTENSET_POFWARN_Pos) /*!< Bit mask of POFWARN field. */ #define POWER_INTENSET_POFWARN_Disabled (0UL) /*!< Read: Disabled */ @@ -6472,21 +6769,21 @@ /* Register: POWER_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 6 : Write '1' to Clear interrupt on EVENTS_SLEEPEXIT event */ +/* Bit 6 : Write '1' to Disable interrupt for SLEEPEXIT event */ #define POWER_INTENCLR_SLEEPEXIT_Pos (6UL) /*!< Position of SLEEPEXIT field. */ #define POWER_INTENCLR_SLEEPEXIT_Msk (0x1UL << POWER_INTENCLR_SLEEPEXIT_Pos) /*!< Bit mask of SLEEPEXIT field. */ #define POWER_INTENCLR_SLEEPEXIT_Disabled (0UL) /*!< Read: Disabled */ #define POWER_INTENCLR_SLEEPEXIT_Enabled (1UL) /*!< Read: Enabled */ #define POWER_INTENCLR_SLEEPEXIT_Clear (1UL) /*!< Disable */ -/* Bit 5 : Write '1' to Clear interrupt on EVENTS_SLEEPENTER event */ +/* Bit 5 : Write '1' to Disable interrupt for SLEEPENTER event */ #define POWER_INTENCLR_SLEEPENTER_Pos (5UL) /*!< Position of SLEEPENTER field. */ #define POWER_INTENCLR_SLEEPENTER_Msk (0x1UL << POWER_INTENCLR_SLEEPENTER_Pos) /*!< Bit mask of SLEEPENTER field. */ #define POWER_INTENCLR_SLEEPENTER_Disabled (0UL) /*!< Read: Disabled */ #define POWER_INTENCLR_SLEEPENTER_Enabled (1UL) /*!< Read: Enabled */ #define POWER_INTENCLR_SLEEPENTER_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_POFWARN event */ +/* Bit 2 : Write '1' to Disable interrupt for POFWARN event */ #define POWER_INTENCLR_POFWARN_Pos (2UL) /*!< Position of POFWARN field. */ #define POWER_INTENCLR_POFWARN_Msk (0x1UL << POWER_INTENCLR_POFWARN_Pos) /*!< Bit mask of POFWARN field. */ #define POWER_INTENCLR_POFWARN_Disabled (0UL) /*!< Read: Disabled */ @@ -6526,7 +6823,7 @@ #define POWER_RESETREAS_LOCKUP_NotDetected (0UL) /*!< Not detected */ #define POWER_RESETREAS_LOCKUP_Detected (1UL) /*!< Detected */ -/* Bit 2 : Reset from AIRCR.SYSRESETREQ detected */ +/* Bit 2 : Reset from soft reset detected */ #define POWER_RESETREAS_SREQ_Pos (2UL) /*!< Position of SREQ field. */ #define POWER_RESETREAS_SREQ_Msk (0x1UL << POWER_RESETREAS_SREQ_Pos) /*!< Bit mask of SREQ field. */ #define POWER_RESETREAS_SREQ_NotDetected (0UL) /*!< Not detected */ @@ -6585,12 +6882,16 @@ /* Bits 4..1 : Power failure comparator threshold setting */ #define POWER_POFCON_THRESHOLD_Pos (1UL) /*!< Position of THRESHOLD field. */ #define POWER_POFCON_THRESHOLD_Msk (0xFUL << POWER_POFCON_THRESHOLD_Pos) /*!< Bit mask of THRESHOLD field. */ +#define POWER_POFCON_THRESHOLD_V17 (4UL) /*!< Set threshold to 1.7 V */ +#define POWER_POFCON_THRESHOLD_V18 (5UL) /*!< Set threshold to 1.8 V */ #define POWER_POFCON_THRESHOLD_V19 (6UL) /*!< Set threshold to 1.9 V */ #define POWER_POFCON_THRESHOLD_V20 (7UL) /*!< Set threshold to 2.0 V */ #define POWER_POFCON_THRESHOLD_V21 (8UL) /*!< Set threshold to 2.1 V */ #define POWER_POFCON_THRESHOLD_V22 (9UL) /*!< Set threshold to 2.2 V */ #define POWER_POFCON_THRESHOLD_V23 (10UL) /*!< Set threshold to 2.3 V */ #define POWER_POFCON_THRESHOLD_V24 (11UL) /*!< Set threshold to 2.4 V */ +#define POWER_POFCON_THRESHOLD_V25 (12UL) /*!< Set threshold to 2.5 V */ +#define POWER_POFCON_THRESHOLD_V26 (13UL) /*!< Set threshold to 2.6 V */ #define POWER_POFCON_THRESHOLD_V27 (14UL) /*!< Set threshold to 2.7 V */ #define POWER_POFCON_THRESHOLD_V28 (15UL) /*!< Set threshold to 2.8 V */ @@ -6680,25 +6981,25 @@ /* Register: POWER_RAM_POWER */ /* Description: Description cluster[0]: RAM0 power control register */ -/* Bit 17 : Keep retention on RAM section S1 when RAM section is switched off */ +/* Bit 17 : Keep retention on RAM section S1 when RAM section is in OFF */ #define POWER_RAM_POWER_S1RETENTION_Pos (17UL) /*!< Position of S1RETENTION field. */ #define POWER_RAM_POWER_S1RETENTION_Msk (0x1UL << POWER_RAM_POWER_S1RETENTION_Pos) /*!< Bit mask of S1RETENTION field. */ #define POWER_RAM_POWER_S1RETENTION_Off (0UL) /*!< Off */ #define POWER_RAM_POWER_S1RETENTION_On (1UL) /*!< On */ -/* Bit 16 : Keep retention on RAM section S0 when RAM section is switched off */ +/* Bit 16 : Keep retention on RAM section S0 when RAM section is in OFF */ #define POWER_RAM_POWER_S0RETENTION_Pos (16UL) /*!< Position of S0RETENTION field. */ #define POWER_RAM_POWER_S0RETENTION_Msk (0x1UL << POWER_RAM_POWER_S0RETENTION_Pos) /*!< Bit mask of S0RETENTION field. */ #define POWER_RAM_POWER_S0RETENTION_Off (0UL) /*!< Off */ #define POWER_RAM_POWER_S0RETENTION_On (1UL) /*!< On */ -/* Bit 1 : Keep RAM section S1 of RAMm on or off in System ON mode */ +/* Bit 1 : Keep RAM section S1 ON or OFF in System ON mode. */ #define POWER_RAM_POWER_S1POWER_Pos (1UL) /*!< Position of S1POWER field. */ #define POWER_RAM_POWER_S1POWER_Msk (0x1UL << POWER_RAM_POWER_S1POWER_Pos) /*!< Bit mask of S1POWER field. */ #define POWER_RAM_POWER_S1POWER_Off (0UL) /*!< Off */ #define POWER_RAM_POWER_S1POWER_On (1UL) /*!< On */ -/* Bit 0 : Keep RAM section S0 of RAMm on or off in System ON mode */ +/* Bit 0 : Keep RAM section S0 ON or OFF in System ON mode. */ #define POWER_RAM_POWER_S0POWER_Pos (0UL) /*!< Position of S0POWER field. */ #define POWER_RAM_POWER_S0POWER_Msk (0x1UL << POWER_RAM_POWER_S0POWER_Pos) /*!< Bit mask of S0POWER field. */ #define POWER_RAM_POWER_S0POWER_Off (0UL) /*!< Off */ @@ -6717,12 +7018,12 @@ #define POWER_RAM_POWERSET_S0RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S0RETENTION_Pos) /*!< Bit mask of S0RETENTION field. */ #define POWER_RAM_POWERSET_S0RETENTION_On (1UL) /*!< On */ -/* Bit 1 : Keep RAM section S1 of RAMm on or off in System ON mode */ +/* Bit 1 : Keep RAM section S1 of RAM0 on or off in System ON mode */ #define POWER_RAM_POWERSET_S1POWER_Pos (1UL) /*!< Position of S1POWER field. */ #define POWER_RAM_POWERSET_S1POWER_Msk (0x1UL << POWER_RAM_POWERSET_S1POWER_Pos) /*!< Bit mask of S1POWER field. */ #define POWER_RAM_POWERSET_S1POWER_On (1UL) /*!< On */ -/* Bit 0 : Keep RAM section S0 of RAMm on or off in System ON mode */ +/* Bit 0 : Keep RAM section S0 of RAM0 on or off in System ON mode */ #define POWER_RAM_POWERSET_S0POWER_Pos (0UL) /*!< Position of S0POWER field. */ #define POWER_RAM_POWERSET_S0POWER_Msk (0x1UL << POWER_RAM_POWERSET_S0POWER_Pos) /*!< Bit mask of S0POWER field. */ #define POWER_RAM_POWERSET_S0POWER_On (1UL) /*!< On */ @@ -6740,12 +7041,12 @@ #define POWER_RAM_POWERCLR_S0RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S0RETENTION_Pos) /*!< Bit mask of S0RETENTION field. */ #define POWER_RAM_POWERCLR_S0RETENTION_Off (1UL) /*!< Off */ -/* Bit 1 : Keep RAM section S1 of RAMm on or off in System ON mode */ +/* Bit 1 : Keep RAM section S1 of RAM0 on or off in System ON mode */ #define POWER_RAM_POWERCLR_S1POWER_Pos (1UL) /*!< Position of S1POWER field. */ #define POWER_RAM_POWERCLR_S1POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S1POWER_Pos) /*!< Bit mask of S1POWER field. */ #define POWER_RAM_POWERCLR_S1POWER_Off (1UL) /*!< Off */ -/* Bit 0 : Keep RAM section S0 of RAMm on or off in System ON mode */ +/* Bit 0 : Keep RAM section S0 of RAM0 on or off in System ON mode */ #define POWER_RAM_POWERCLR_S0POWER_Pos (0UL) /*!< Position of S0POWER field. */ #define POWER_RAM_POWERCLR_S0POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S0POWER_Pos) /*!< Bit mask of S0POWER field. */ #define POWER_RAM_POWERCLR_S0POWER_Off (1UL) /*!< Off */ @@ -7626,31 +7927,31 @@ /* Register: PWM_SHORTS */ /* Description: Shortcut register */ -/* Bit 4 : Shortcut between EVENTS_LOOPSDONE event and TASKS_STOP task */ +/* Bit 4 : Shortcut between LOOPSDONE event and STOP task */ #define PWM_SHORTS_LOOPSDONE_STOP_Pos (4UL) /*!< Position of LOOPSDONE_STOP field. */ #define PWM_SHORTS_LOOPSDONE_STOP_Msk (0x1UL << PWM_SHORTS_LOOPSDONE_STOP_Pos) /*!< Bit mask of LOOPSDONE_STOP field. */ #define PWM_SHORTS_LOOPSDONE_STOP_Disabled (0UL) /*!< Disable shortcut */ #define PWM_SHORTS_LOOPSDONE_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 3 : Shortcut between EVENTS_LOOPSDONE event and TASKS_SEQSTART[1] task */ +/* Bit 3 : Shortcut between LOOPSDONE event and SEQSTART[1] task */ #define PWM_SHORTS_LOOPSDONE_SEQSTART1_Pos (3UL) /*!< Position of LOOPSDONE_SEQSTART1 field. */ #define PWM_SHORTS_LOOPSDONE_SEQSTART1_Msk (0x1UL << PWM_SHORTS_LOOPSDONE_SEQSTART1_Pos) /*!< Bit mask of LOOPSDONE_SEQSTART1 field. */ #define PWM_SHORTS_LOOPSDONE_SEQSTART1_Disabled (0UL) /*!< Disable shortcut */ #define PWM_SHORTS_LOOPSDONE_SEQSTART1_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 2 : Shortcut between EVENTS_LOOPSDONE event and TASKS_SEQSTART[0] task */ +/* Bit 2 : Shortcut between LOOPSDONE event and SEQSTART[0] task */ #define PWM_SHORTS_LOOPSDONE_SEQSTART0_Pos (2UL) /*!< Position of LOOPSDONE_SEQSTART0 field. */ #define PWM_SHORTS_LOOPSDONE_SEQSTART0_Msk (0x1UL << PWM_SHORTS_LOOPSDONE_SEQSTART0_Pos) /*!< Bit mask of LOOPSDONE_SEQSTART0 field. */ #define PWM_SHORTS_LOOPSDONE_SEQSTART0_Disabled (0UL) /*!< Disable shortcut */ #define PWM_SHORTS_LOOPSDONE_SEQSTART0_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 1 : Shortcut between EVENTS_SEQEND[1] event and TASKS_STOP task */ +/* Bit 1 : Shortcut between SEQEND[1] event and STOP task */ #define PWM_SHORTS_SEQEND1_STOP_Pos (1UL) /*!< Position of SEQEND1_STOP field. */ #define PWM_SHORTS_SEQEND1_STOP_Msk (0x1UL << PWM_SHORTS_SEQEND1_STOP_Pos) /*!< Bit mask of SEQEND1_STOP field. */ #define PWM_SHORTS_SEQEND1_STOP_Disabled (0UL) /*!< Disable shortcut */ #define PWM_SHORTS_SEQEND1_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 0 : Shortcut between EVENTS_SEQEND[0] event and TASKS_STOP task */ +/* Bit 0 : Shortcut between SEQEND[0] event and STOP task */ #define PWM_SHORTS_SEQEND0_STOP_Pos (0UL) /*!< Position of SEQEND0_STOP field. */ #define PWM_SHORTS_SEQEND0_STOP_Msk (0x1UL << PWM_SHORTS_SEQEND0_STOP_Pos) /*!< Bit mask of SEQEND0_STOP field. */ #define PWM_SHORTS_SEQEND0_STOP_Disabled (0UL) /*!< Disable shortcut */ @@ -7659,43 +7960,43 @@ /* Register: PWM_INTEN */ /* Description: Enable or disable interrupt */ -/* Bit 7 : Enable or disable interrupt on EVENTS_LOOPSDONE event */ +/* Bit 7 : Enable or disable interrupt for LOOPSDONE event */ #define PWM_INTEN_LOOPSDONE_Pos (7UL) /*!< Position of LOOPSDONE field. */ #define PWM_INTEN_LOOPSDONE_Msk (0x1UL << PWM_INTEN_LOOPSDONE_Pos) /*!< Bit mask of LOOPSDONE field. */ #define PWM_INTEN_LOOPSDONE_Disabled (0UL) /*!< Disable */ #define PWM_INTEN_LOOPSDONE_Enabled (1UL) /*!< Enable */ -/* Bit 6 : Enable or disable interrupt on EVENTS_PWMPERIODEND event */ +/* Bit 6 : Enable or disable interrupt for PWMPERIODEND event */ #define PWM_INTEN_PWMPERIODEND_Pos (6UL) /*!< Position of PWMPERIODEND field. */ #define PWM_INTEN_PWMPERIODEND_Msk (0x1UL << PWM_INTEN_PWMPERIODEND_Pos) /*!< Bit mask of PWMPERIODEND field. */ #define PWM_INTEN_PWMPERIODEND_Disabled (0UL) /*!< Disable */ #define PWM_INTEN_PWMPERIODEND_Enabled (1UL) /*!< Enable */ -/* Bit 5 : Enable or disable interrupt on EVENTS_SEQEND[1] event */ +/* Bit 5 : Enable or disable interrupt for SEQEND[1] event */ #define PWM_INTEN_SEQEND1_Pos (5UL) /*!< Position of SEQEND1 field. */ #define PWM_INTEN_SEQEND1_Msk (0x1UL << PWM_INTEN_SEQEND1_Pos) /*!< Bit mask of SEQEND1 field. */ #define PWM_INTEN_SEQEND1_Disabled (0UL) /*!< Disable */ #define PWM_INTEN_SEQEND1_Enabled (1UL) /*!< Enable */ -/* Bit 4 : Enable or disable interrupt on EVENTS_SEQEND[0] event */ +/* Bit 4 : Enable or disable interrupt for SEQEND[0] event */ #define PWM_INTEN_SEQEND0_Pos (4UL) /*!< Position of SEQEND0 field. */ #define PWM_INTEN_SEQEND0_Msk (0x1UL << PWM_INTEN_SEQEND0_Pos) /*!< Bit mask of SEQEND0 field. */ #define PWM_INTEN_SEQEND0_Disabled (0UL) /*!< Disable */ #define PWM_INTEN_SEQEND0_Enabled (1UL) /*!< Enable */ -/* Bit 3 : Enable or disable interrupt on EVENTS_SEQSTARTED[1] event */ +/* Bit 3 : Enable or disable interrupt for SEQSTARTED[1] event */ #define PWM_INTEN_SEQSTARTED1_Pos (3UL) /*!< Position of SEQSTARTED1 field. */ #define PWM_INTEN_SEQSTARTED1_Msk (0x1UL << PWM_INTEN_SEQSTARTED1_Pos) /*!< Bit mask of SEQSTARTED1 field. */ #define PWM_INTEN_SEQSTARTED1_Disabled (0UL) /*!< Disable */ #define PWM_INTEN_SEQSTARTED1_Enabled (1UL) /*!< Enable */ -/* Bit 2 : Enable or disable interrupt on EVENTS_SEQSTARTED[0] event */ +/* Bit 2 : Enable or disable interrupt for SEQSTARTED[0] event */ #define PWM_INTEN_SEQSTARTED0_Pos (2UL) /*!< Position of SEQSTARTED0 field. */ #define PWM_INTEN_SEQSTARTED0_Msk (0x1UL << PWM_INTEN_SEQSTARTED0_Pos) /*!< Bit mask of SEQSTARTED0 field. */ #define PWM_INTEN_SEQSTARTED0_Disabled (0UL) /*!< Disable */ #define PWM_INTEN_SEQSTARTED0_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Enable or disable interrupt for STOPPED event */ #define PWM_INTEN_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define PWM_INTEN_STOPPED_Msk (0x1UL << PWM_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define PWM_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ @@ -7704,49 +8005,49 @@ /* Register: PWM_INTENSET */ /* Description: Enable interrupt */ -/* Bit 7 : Write '1' to Enable interrupt on EVENTS_LOOPSDONE event */ +/* Bit 7 : Write '1' to Enable interrupt for LOOPSDONE event */ #define PWM_INTENSET_LOOPSDONE_Pos (7UL) /*!< Position of LOOPSDONE field. */ #define PWM_INTENSET_LOOPSDONE_Msk (0x1UL << PWM_INTENSET_LOOPSDONE_Pos) /*!< Bit mask of LOOPSDONE field. */ #define PWM_INTENSET_LOOPSDONE_Disabled (0UL) /*!< Read: Disabled */ #define PWM_INTENSET_LOOPSDONE_Enabled (1UL) /*!< Read: Enabled */ #define PWM_INTENSET_LOOPSDONE_Set (1UL) /*!< Enable */ -/* Bit 6 : Write '1' to Enable interrupt on EVENTS_PWMPERIODEND event */ +/* Bit 6 : Write '1' to Enable interrupt for PWMPERIODEND event */ #define PWM_INTENSET_PWMPERIODEND_Pos (6UL) /*!< Position of PWMPERIODEND field. */ #define PWM_INTENSET_PWMPERIODEND_Msk (0x1UL << PWM_INTENSET_PWMPERIODEND_Pos) /*!< Bit mask of PWMPERIODEND field. */ #define PWM_INTENSET_PWMPERIODEND_Disabled (0UL) /*!< Read: Disabled */ #define PWM_INTENSET_PWMPERIODEND_Enabled (1UL) /*!< Read: Enabled */ #define PWM_INTENSET_PWMPERIODEND_Set (1UL) /*!< Enable */ -/* Bit 5 : Write '1' to Enable interrupt on EVENTS_SEQEND[1] event */ +/* Bit 5 : Write '1' to Enable interrupt for SEQEND[1] event */ #define PWM_INTENSET_SEQEND1_Pos (5UL) /*!< Position of SEQEND1 field. */ #define PWM_INTENSET_SEQEND1_Msk (0x1UL << PWM_INTENSET_SEQEND1_Pos) /*!< Bit mask of SEQEND1 field. */ #define PWM_INTENSET_SEQEND1_Disabled (0UL) /*!< Read: Disabled */ #define PWM_INTENSET_SEQEND1_Enabled (1UL) /*!< Read: Enabled */ #define PWM_INTENSET_SEQEND1_Set (1UL) /*!< Enable */ -/* Bit 4 : Write '1' to Enable interrupt on EVENTS_SEQEND[0] event */ +/* Bit 4 : Write '1' to Enable interrupt for SEQEND[0] event */ #define PWM_INTENSET_SEQEND0_Pos (4UL) /*!< Position of SEQEND0 field. */ #define PWM_INTENSET_SEQEND0_Msk (0x1UL << PWM_INTENSET_SEQEND0_Pos) /*!< Bit mask of SEQEND0 field. */ #define PWM_INTENSET_SEQEND0_Disabled (0UL) /*!< Read: Disabled */ #define PWM_INTENSET_SEQEND0_Enabled (1UL) /*!< Read: Enabled */ #define PWM_INTENSET_SEQEND0_Set (1UL) /*!< Enable */ -/* Bit 3 : Write '1' to Enable interrupt on EVENTS_SEQSTARTED[1] event */ +/* Bit 3 : Write '1' to Enable interrupt for SEQSTARTED[1] event */ #define PWM_INTENSET_SEQSTARTED1_Pos (3UL) /*!< Position of SEQSTARTED1 field. */ #define PWM_INTENSET_SEQSTARTED1_Msk (0x1UL << PWM_INTENSET_SEQSTARTED1_Pos) /*!< Bit mask of SEQSTARTED1 field. */ #define PWM_INTENSET_SEQSTARTED1_Disabled (0UL) /*!< Read: Disabled */ #define PWM_INTENSET_SEQSTARTED1_Enabled (1UL) /*!< Read: Enabled */ #define PWM_INTENSET_SEQSTARTED1_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_SEQSTARTED[0] event */ +/* Bit 2 : Write '1' to Enable interrupt for SEQSTARTED[0] event */ #define PWM_INTENSET_SEQSTARTED0_Pos (2UL) /*!< Position of SEQSTARTED0 field. */ #define PWM_INTENSET_SEQSTARTED0_Msk (0x1UL << PWM_INTENSET_SEQSTARTED0_Pos) /*!< Bit mask of SEQSTARTED0 field. */ #define PWM_INTENSET_SEQSTARTED0_Disabled (0UL) /*!< Read: Disabled */ #define PWM_INTENSET_SEQSTARTED0_Enabled (1UL) /*!< Read: Enabled */ #define PWM_INTENSET_SEQSTARTED0_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ #define PWM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define PWM_INTENSET_STOPPED_Msk (0x1UL << PWM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define PWM_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ @@ -7756,49 +8057,49 @@ /* Register: PWM_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 7 : Write '1' to Clear interrupt on EVENTS_LOOPSDONE event */ +/* Bit 7 : Write '1' to Disable interrupt for LOOPSDONE event */ #define PWM_INTENCLR_LOOPSDONE_Pos (7UL) /*!< Position of LOOPSDONE field. */ #define PWM_INTENCLR_LOOPSDONE_Msk (0x1UL << PWM_INTENCLR_LOOPSDONE_Pos) /*!< Bit mask of LOOPSDONE field. */ #define PWM_INTENCLR_LOOPSDONE_Disabled (0UL) /*!< Read: Disabled */ #define PWM_INTENCLR_LOOPSDONE_Enabled (1UL) /*!< Read: Enabled */ #define PWM_INTENCLR_LOOPSDONE_Clear (1UL) /*!< Disable */ -/* Bit 6 : Write '1' to Clear interrupt on EVENTS_PWMPERIODEND event */ +/* Bit 6 : Write '1' to Disable interrupt for PWMPERIODEND event */ #define PWM_INTENCLR_PWMPERIODEND_Pos (6UL) /*!< Position of PWMPERIODEND field. */ #define PWM_INTENCLR_PWMPERIODEND_Msk (0x1UL << PWM_INTENCLR_PWMPERIODEND_Pos) /*!< Bit mask of PWMPERIODEND field. */ #define PWM_INTENCLR_PWMPERIODEND_Disabled (0UL) /*!< Read: Disabled */ #define PWM_INTENCLR_PWMPERIODEND_Enabled (1UL) /*!< Read: Enabled */ #define PWM_INTENCLR_PWMPERIODEND_Clear (1UL) /*!< Disable */ -/* Bit 5 : Write '1' to Clear interrupt on EVENTS_SEQEND[1] event */ +/* Bit 5 : Write '1' to Disable interrupt for SEQEND[1] event */ #define PWM_INTENCLR_SEQEND1_Pos (5UL) /*!< Position of SEQEND1 field. */ #define PWM_INTENCLR_SEQEND1_Msk (0x1UL << PWM_INTENCLR_SEQEND1_Pos) /*!< Bit mask of SEQEND1 field. */ #define PWM_INTENCLR_SEQEND1_Disabled (0UL) /*!< Read: Disabled */ #define PWM_INTENCLR_SEQEND1_Enabled (1UL) /*!< Read: Enabled */ #define PWM_INTENCLR_SEQEND1_Clear (1UL) /*!< Disable */ -/* Bit 4 : Write '1' to Clear interrupt on EVENTS_SEQEND[0] event */ +/* Bit 4 : Write '1' to Disable interrupt for SEQEND[0] event */ #define PWM_INTENCLR_SEQEND0_Pos (4UL) /*!< Position of SEQEND0 field. */ #define PWM_INTENCLR_SEQEND0_Msk (0x1UL << PWM_INTENCLR_SEQEND0_Pos) /*!< Bit mask of SEQEND0 field. */ #define PWM_INTENCLR_SEQEND0_Disabled (0UL) /*!< Read: Disabled */ #define PWM_INTENCLR_SEQEND0_Enabled (1UL) /*!< Read: Enabled */ #define PWM_INTENCLR_SEQEND0_Clear (1UL) /*!< Disable */ -/* Bit 3 : Write '1' to Clear interrupt on EVENTS_SEQSTARTED[1] event */ +/* Bit 3 : Write '1' to Disable interrupt for SEQSTARTED[1] event */ #define PWM_INTENCLR_SEQSTARTED1_Pos (3UL) /*!< Position of SEQSTARTED1 field. */ #define PWM_INTENCLR_SEQSTARTED1_Msk (0x1UL << PWM_INTENCLR_SEQSTARTED1_Pos) /*!< Bit mask of SEQSTARTED1 field. */ #define PWM_INTENCLR_SEQSTARTED1_Disabled (0UL) /*!< Read: Disabled */ #define PWM_INTENCLR_SEQSTARTED1_Enabled (1UL) /*!< Read: Enabled */ #define PWM_INTENCLR_SEQSTARTED1_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_SEQSTARTED[0] event */ +/* Bit 2 : Write '1' to Disable interrupt for SEQSTARTED[0] event */ #define PWM_INTENCLR_SEQSTARTED0_Pos (2UL) /*!< Position of SEQSTARTED0 field. */ #define PWM_INTENCLR_SEQSTARTED0_Msk (0x1UL << PWM_INTENCLR_SEQSTARTED0_Pos) /*!< Bit mask of SEQSTARTED0 field. */ #define PWM_INTENCLR_SEQSTARTED0_Disabled (0UL) /*!< Read: Disabled */ #define PWM_INTENCLR_SEQSTARTED0_Enabled (1UL) /*!< Read: Enabled */ #define PWM_INTENCLR_SEQSTARTED0_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ #define PWM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define PWM_INTENCLR_STOPPED_Msk (0x1UL << PWM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define PWM_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ @@ -7871,24 +8172,24 @@ #define PWM_LOOP_CNT_Disabled (0UL) /*!< Looping disabled (stop at the end of the sequence) */ /* Register: PWM_SEQ_PTR */ -/* Description: Description cluster[0]: Beginning address in Data RAM of sequence A */ +/* Description: Description cluster[0]: Beginning address in Data RAM of this sequence */ -/* Bits 31..0 : Beginning address in Data RAM of sequence A */ +/* Bits 31..0 : Beginning address in Data RAM of this sequence */ #define PWM_SEQ_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ #define PWM_SEQ_PTR_PTR_Msk (0xFFFFFFFFUL << PWM_SEQ_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ /* Register: PWM_SEQ_CNT */ -/* Description: Description cluster[0]: Amount of values (duty cycles) in sequence A */ +/* Description: Description cluster[0]: Amount of values (duty cycles) in this sequence */ -/* Bits 14..0 : Amount of values (duty cycles) in sequence A */ +/* Bits 14..0 : Amount of values (duty cycles) in this sequence */ #define PWM_SEQ_CNT_CNT_Pos (0UL) /*!< Position of CNT field. */ #define PWM_SEQ_CNT_CNT_Msk (0x7FFFUL << PWM_SEQ_CNT_CNT_Pos) /*!< Bit mask of CNT field. */ -#define PWM_SEQ_CNT_CNT_Disabled (0UL) /*!< Sequence is disabled */ +#define PWM_SEQ_CNT_CNT_Disabled (0UL) /*!< Sequence is disabled, and shall not be started as it is empty */ /* Register: PWM_SEQ_REFRESH */ -/* Description: Description cluster[0]: Amount of additional PWM periods between samples loaded to compare register (load every CNT+1 PWM periods) */ +/* Description: Description cluster[0]: Amount of additional PWM periods between samples loaded into compare register */ -/* Bits 23..0 : Amount of additional PWM periods between samples loaded to compare register (load every CNT+1 PWM periods) */ +/* Bits 23..0 : Amount of additional PWM periods between samples loaded into compare register (load every REFRESH.CNT+1 PWM periods) */ #define PWM_SEQ_REFRESH_CNT_Pos (0UL) /*!< Position of CNT field. */ #define PWM_SEQ_REFRESH_CNT_Msk (0xFFFFFFUL << PWM_SEQ_REFRESH_CNT_Pos) /*!< Bit mask of CNT field. */ #define PWM_SEQ_REFRESH_CNT_Continuous (0UL) /*!< Update every PWM period */ @@ -7920,43 +8221,43 @@ /* Register: QDEC_SHORTS */ /* Description: Shortcut register */ -/* Bit 6 : Shortcut between EVENTS_SAMPLERDY event and TASKS_READCLRACC task */ +/* Bit 6 : Shortcut between SAMPLERDY event and READCLRACC task */ #define QDEC_SHORTS_SAMPLERDY_READCLRACC_Pos (6UL) /*!< Position of SAMPLERDY_READCLRACC field. */ #define QDEC_SHORTS_SAMPLERDY_READCLRACC_Msk (0x1UL << QDEC_SHORTS_SAMPLERDY_READCLRACC_Pos) /*!< Bit mask of SAMPLERDY_READCLRACC field. */ #define QDEC_SHORTS_SAMPLERDY_READCLRACC_Disabled (0UL) /*!< Disable shortcut */ #define QDEC_SHORTS_SAMPLERDY_READCLRACC_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 5 : Shortcut between EVENTS_DBLRDY event and TASKS_STOP task */ +/* Bit 5 : Shortcut between DBLRDY event and STOP task */ #define QDEC_SHORTS_DBLRDY_STOP_Pos (5UL) /*!< Position of DBLRDY_STOP field. */ #define QDEC_SHORTS_DBLRDY_STOP_Msk (0x1UL << QDEC_SHORTS_DBLRDY_STOP_Pos) /*!< Bit mask of DBLRDY_STOP field. */ #define QDEC_SHORTS_DBLRDY_STOP_Disabled (0UL) /*!< Disable shortcut */ #define QDEC_SHORTS_DBLRDY_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 4 : Shortcut between EVENTS_DBLRDY event and TASKS_RDCLRDBL task */ +/* Bit 4 : Shortcut between DBLRDY event and RDCLRDBL task */ #define QDEC_SHORTS_DBLRDY_RDCLRDBL_Pos (4UL) /*!< Position of DBLRDY_RDCLRDBL field. */ #define QDEC_SHORTS_DBLRDY_RDCLRDBL_Msk (0x1UL << QDEC_SHORTS_DBLRDY_RDCLRDBL_Pos) /*!< Bit mask of DBLRDY_RDCLRDBL field. */ #define QDEC_SHORTS_DBLRDY_RDCLRDBL_Disabled (0UL) /*!< Disable shortcut */ #define QDEC_SHORTS_DBLRDY_RDCLRDBL_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 3 : Shortcut between EVENTS_REPORTRDY event and TASKS_STOP task */ +/* Bit 3 : Shortcut between REPORTRDY event and STOP task */ #define QDEC_SHORTS_REPORTRDY_STOP_Pos (3UL) /*!< Position of REPORTRDY_STOP field. */ #define QDEC_SHORTS_REPORTRDY_STOP_Msk (0x1UL << QDEC_SHORTS_REPORTRDY_STOP_Pos) /*!< Bit mask of REPORTRDY_STOP field. */ #define QDEC_SHORTS_REPORTRDY_STOP_Disabled (0UL) /*!< Disable shortcut */ #define QDEC_SHORTS_REPORTRDY_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 2 : Shortcut between EVENTS_REPORTRDY event and TASKS_RDCLRACC task */ +/* Bit 2 : Shortcut between REPORTRDY event and RDCLRACC task */ #define QDEC_SHORTS_REPORTRDY_RDCLRACC_Pos (2UL) /*!< Position of REPORTRDY_RDCLRACC field. */ #define QDEC_SHORTS_REPORTRDY_RDCLRACC_Msk (0x1UL << QDEC_SHORTS_REPORTRDY_RDCLRACC_Pos) /*!< Bit mask of REPORTRDY_RDCLRACC field. */ #define QDEC_SHORTS_REPORTRDY_RDCLRACC_Disabled (0UL) /*!< Disable shortcut */ #define QDEC_SHORTS_REPORTRDY_RDCLRACC_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 1 : Shortcut between EVENTS_SAMPLERDY event and TASKS_STOP task */ +/* Bit 1 : Shortcut between SAMPLERDY event and STOP task */ #define QDEC_SHORTS_SAMPLERDY_STOP_Pos (1UL) /*!< Position of SAMPLERDY_STOP field. */ #define QDEC_SHORTS_SAMPLERDY_STOP_Msk (0x1UL << QDEC_SHORTS_SAMPLERDY_STOP_Pos) /*!< Bit mask of SAMPLERDY_STOP field. */ #define QDEC_SHORTS_SAMPLERDY_STOP_Disabled (0UL) /*!< Disable shortcut */ #define QDEC_SHORTS_SAMPLERDY_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 0 : Shortcut between EVENTS_REPORTRDY event and TASKS_READCLRACC task */ +/* Bit 0 : Shortcut between REPORTRDY event and READCLRACC task */ #define QDEC_SHORTS_REPORTRDY_READCLRACC_Pos (0UL) /*!< Position of REPORTRDY_READCLRACC field. */ #define QDEC_SHORTS_REPORTRDY_READCLRACC_Msk (0x1UL << QDEC_SHORTS_REPORTRDY_READCLRACC_Pos) /*!< Bit mask of REPORTRDY_READCLRACC field. */ #define QDEC_SHORTS_REPORTRDY_READCLRACC_Disabled (0UL) /*!< Disable shortcut */ @@ -7965,35 +8266,35 @@ /* Register: QDEC_INTENSET */ /* Description: Enable interrupt */ -/* Bit 4 : Write '1' to Enable interrupt on EVENTS_STOPPED event */ +/* Bit 4 : Write '1' to Enable interrupt for STOPPED event */ #define QDEC_INTENSET_STOPPED_Pos (4UL) /*!< Position of STOPPED field. */ #define QDEC_INTENSET_STOPPED_Msk (0x1UL << QDEC_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define QDEC_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ #define QDEC_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ #define QDEC_INTENSET_STOPPED_Set (1UL) /*!< Enable */ -/* Bit 3 : Write '1' to Enable interrupt on EVENTS_DBLRDY event */ +/* Bit 3 : Write '1' to Enable interrupt for DBLRDY event */ #define QDEC_INTENSET_DBLRDY_Pos (3UL) /*!< Position of DBLRDY field. */ #define QDEC_INTENSET_DBLRDY_Msk (0x1UL << QDEC_INTENSET_DBLRDY_Pos) /*!< Bit mask of DBLRDY field. */ #define QDEC_INTENSET_DBLRDY_Disabled (0UL) /*!< Read: Disabled */ #define QDEC_INTENSET_DBLRDY_Enabled (1UL) /*!< Read: Enabled */ #define QDEC_INTENSET_DBLRDY_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_ACCOF event */ +/* Bit 2 : Write '1' to Enable interrupt for ACCOF event */ #define QDEC_INTENSET_ACCOF_Pos (2UL) /*!< Position of ACCOF field. */ #define QDEC_INTENSET_ACCOF_Msk (0x1UL << QDEC_INTENSET_ACCOF_Pos) /*!< Bit mask of ACCOF field. */ #define QDEC_INTENSET_ACCOF_Disabled (0UL) /*!< Read: Disabled */ #define QDEC_INTENSET_ACCOF_Enabled (1UL) /*!< Read: Enabled */ #define QDEC_INTENSET_ACCOF_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_REPORTRDY event */ +/* Bit 1 : Write '1' to Enable interrupt for REPORTRDY event */ #define QDEC_INTENSET_REPORTRDY_Pos (1UL) /*!< Position of REPORTRDY field. */ #define QDEC_INTENSET_REPORTRDY_Msk (0x1UL << QDEC_INTENSET_REPORTRDY_Pos) /*!< Bit mask of REPORTRDY field. */ #define QDEC_INTENSET_REPORTRDY_Disabled (0UL) /*!< Read: Disabled */ #define QDEC_INTENSET_REPORTRDY_Enabled (1UL) /*!< Read: Enabled */ #define QDEC_INTENSET_REPORTRDY_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_SAMPLERDY event */ +/* Bit 0 : Write '1' to Enable interrupt for SAMPLERDY event */ #define QDEC_INTENSET_SAMPLERDY_Pos (0UL) /*!< Position of SAMPLERDY field. */ #define QDEC_INTENSET_SAMPLERDY_Msk (0x1UL << QDEC_INTENSET_SAMPLERDY_Pos) /*!< Bit mask of SAMPLERDY field. */ #define QDEC_INTENSET_SAMPLERDY_Disabled (0UL) /*!< Read: Disabled */ @@ -8003,35 +8304,35 @@ /* Register: QDEC_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 4 : Write '1' to Clear interrupt on EVENTS_STOPPED event */ +/* Bit 4 : Write '1' to Disable interrupt for STOPPED event */ #define QDEC_INTENCLR_STOPPED_Pos (4UL) /*!< Position of STOPPED field. */ #define QDEC_INTENCLR_STOPPED_Msk (0x1UL << QDEC_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define QDEC_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ #define QDEC_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ #define QDEC_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ -/* Bit 3 : Write '1' to Clear interrupt on EVENTS_DBLRDY event */ +/* Bit 3 : Write '1' to Disable interrupt for DBLRDY event */ #define QDEC_INTENCLR_DBLRDY_Pos (3UL) /*!< Position of DBLRDY field. */ #define QDEC_INTENCLR_DBLRDY_Msk (0x1UL << QDEC_INTENCLR_DBLRDY_Pos) /*!< Bit mask of DBLRDY field. */ #define QDEC_INTENCLR_DBLRDY_Disabled (0UL) /*!< Read: Disabled */ #define QDEC_INTENCLR_DBLRDY_Enabled (1UL) /*!< Read: Enabled */ #define QDEC_INTENCLR_DBLRDY_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_ACCOF event */ +/* Bit 2 : Write '1' to Disable interrupt for ACCOF event */ #define QDEC_INTENCLR_ACCOF_Pos (2UL) /*!< Position of ACCOF field. */ #define QDEC_INTENCLR_ACCOF_Msk (0x1UL << QDEC_INTENCLR_ACCOF_Pos) /*!< Bit mask of ACCOF field. */ #define QDEC_INTENCLR_ACCOF_Disabled (0UL) /*!< Read: Disabled */ #define QDEC_INTENCLR_ACCOF_Enabled (1UL) /*!< Read: Enabled */ #define QDEC_INTENCLR_ACCOF_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_REPORTRDY event */ +/* Bit 1 : Write '1' to Disable interrupt for REPORTRDY event */ #define QDEC_INTENCLR_REPORTRDY_Pos (1UL) /*!< Position of REPORTRDY field. */ #define QDEC_INTENCLR_REPORTRDY_Msk (0x1UL << QDEC_INTENCLR_REPORTRDY_Pos) /*!< Bit mask of REPORTRDY field. */ #define QDEC_INTENCLR_REPORTRDY_Disabled (0UL) /*!< Read: Disabled */ #define QDEC_INTENCLR_REPORTRDY_Enabled (1UL) /*!< Read: Enabled */ #define QDEC_INTENCLR_REPORTRDY_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_SAMPLERDY event */ +/* Bit 0 : Write '1' to Disable interrupt for SAMPLERDY event */ #define QDEC_INTENCLR_SAMPLERDY_Pos (0UL) /*!< Position of SAMPLERDY field. */ #define QDEC_INTENCLR_SAMPLERDY_Msk (0x1UL << QDEC_INTENCLR_SAMPLERDY_Pos) /*!< Bit mask of SAMPLERDY field. */ #define QDEC_INTENCLR_SAMPLERDY_Disabled (0UL) /*!< Read: Disabled */ @@ -8187,49 +8488,49 @@ /* Register: RADIO_SHORTS */ /* Description: Shortcut register */ -/* Bit 8 : Shortcut between EVENTS_DISABLED event and TASKS_RSSISTOP task */ +/* Bit 8 : Shortcut between DISABLED event and RSSISTOP task */ #define RADIO_SHORTS_DISABLED_RSSISTOP_Pos (8UL) /*!< Position of DISABLED_RSSISTOP field. */ #define RADIO_SHORTS_DISABLED_RSSISTOP_Msk (0x1UL << RADIO_SHORTS_DISABLED_RSSISTOP_Pos) /*!< Bit mask of DISABLED_RSSISTOP field. */ #define RADIO_SHORTS_DISABLED_RSSISTOP_Disabled (0UL) /*!< Disable shortcut */ #define RADIO_SHORTS_DISABLED_RSSISTOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 6 : Shortcut between EVENTS_ADDRESS event and TASKS_BCSTART task */ +/* Bit 6 : Shortcut between ADDRESS event and BCSTART task */ #define RADIO_SHORTS_ADDRESS_BCSTART_Pos (6UL) /*!< Position of ADDRESS_BCSTART field. */ #define RADIO_SHORTS_ADDRESS_BCSTART_Msk (0x1UL << RADIO_SHORTS_ADDRESS_BCSTART_Pos) /*!< Bit mask of ADDRESS_BCSTART field. */ #define RADIO_SHORTS_ADDRESS_BCSTART_Disabled (0UL) /*!< Disable shortcut */ #define RADIO_SHORTS_ADDRESS_BCSTART_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 5 : Shortcut between EVENTS_END event and TASKS_START task */ +/* Bit 5 : Shortcut between END event and START task */ #define RADIO_SHORTS_END_START_Pos (5UL) /*!< Position of END_START field. */ #define RADIO_SHORTS_END_START_Msk (0x1UL << RADIO_SHORTS_END_START_Pos) /*!< Bit mask of END_START field. */ #define RADIO_SHORTS_END_START_Disabled (0UL) /*!< Disable shortcut */ #define RADIO_SHORTS_END_START_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 4 : Shortcut between EVENTS_ADDRESS event and TASKS_RSSISTART task */ +/* Bit 4 : Shortcut between ADDRESS event and RSSISTART task */ #define RADIO_SHORTS_ADDRESS_RSSISTART_Pos (4UL) /*!< Position of ADDRESS_RSSISTART field. */ #define RADIO_SHORTS_ADDRESS_RSSISTART_Msk (0x1UL << RADIO_SHORTS_ADDRESS_RSSISTART_Pos) /*!< Bit mask of ADDRESS_RSSISTART field. */ #define RADIO_SHORTS_ADDRESS_RSSISTART_Disabled (0UL) /*!< Disable shortcut */ #define RADIO_SHORTS_ADDRESS_RSSISTART_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 3 : Shortcut between EVENTS_DISABLED event and TASKS_RXEN task */ +/* Bit 3 : Shortcut between DISABLED event and RXEN task */ #define RADIO_SHORTS_DISABLED_RXEN_Pos (3UL) /*!< Position of DISABLED_RXEN field. */ #define RADIO_SHORTS_DISABLED_RXEN_Msk (0x1UL << RADIO_SHORTS_DISABLED_RXEN_Pos) /*!< Bit mask of DISABLED_RXEN field. */ #define RADIO_SHORTS_DISABLED_RXEN_Disabled (0UL) /*!< Disable shortcut */ #define RADIO_SHORTS_DISABLED_RXEN_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 2 : Shortcut between EVENTS_DISABLED event and TASKS_TXEN task */ +/* Bit 2 : Shortcut between DISABLED event and TXEN task */ #define RADIO_SHORTS_DISABLED_TXEN_Pos (2UL) /*!< Position of DISABLED_TXEN field. */ #define RADIO_SHORTS_DISABLED_TXEN_Msk (0x1UL << RADIO_SHORTS_DISABLED_TXEN_Pos) /*!< Bit mask of DISABLED_TXEN field. */ #define RADIO_SHORTS_DISABLED_TXEN_Disabled (0UL) /*!< Disable shortcut */ #define RADIO_SHORTS_DISABLED_TXEN_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 1 : Shortcut between EVENTS_END event and TASKS_DISABLE task */ +/* Bit 1 : Shortcut between END event and DISABLE task */ #define RADIO_SHORTS_END_DISABLE_Pos (1UL) /*!< Position of END_DISABLE field. */ #define RADIO_SHORTS_END_DISABLE_Msk (0x1UL << RADIO_SHORTS_END_DISABLE_Pos) /*!< Bit mask of END_DISABLE field. */ #define RADIO_SHORTS_END_DISABLE_Disabled (0UL) /*!< Disable shortcut */ #define RADIO_SHORTS_END_DISABLE_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 0 : Shortcut between EVENTS_READY event and TASKS_START task */ +/* Bit 0 : Shortcut between READY event and START task */ #define RADIO_SHORTS_READY_START_Pos (0UL) /*!< Position of READY_START field. */ #define RADIO_SHORTS_READY_START_Msk (0x1UL << RADIO_SHORTS_READY_START_Pos) /*!< Bit mask of READY_START field. */ #define RADIO_SHORTS_READY_START_Disabled (0UL) /*!< Disable shortcut */ @@ -8238,77 +8539,77 @@ /* Register: RADIO_INTENSET */ /* Description: Enable interrupt */ -/* Bit 13 : Write '1' to Enable interrupt on EVENTS_CRCERROR event */ +/* Bit 13 : Write '1' to Enable interrupt for CRCERROR event */ #define RADIO_INTENSET_CRCERROR_Pos (13UL) /*!< Position of CRCERROR field. */ #define RADIO_INTENSET_CRCERROR_Msk (0x1UL << RADIO_INTENSET_CRCERROR_Pos) /*!< Bit mask of CRCERROR field. */ #define RADIO_INTENSET_CRCERROR_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENSET_CRCERROR_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENSET_CRCERROR_Set (1UL) /*!< Enable */ -/* Bit 12 : Write '1' to Enable interrupt on EVENTS_CRCOK event */ +/* Bit 12 : Write '1' to Enable interrupt for CRCOK event */ #define RADIO_INTENSET_CRCOK_Pos (12UL) /*!< Position of CRCOK field. */ #define RADIO_INTENSET_CRCOK_Msk (0x1UL << RADIO_INTENSET_CRCOK_Pos) /*!< Bit mask of CRCOK field. */ #define RADIO_INTENSET_CRCOK_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENSET_CRCOK_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENSET_CRCOK_Set (1UL) /*!< Enable */ -/* Bit 10 : Write '1' to Enable interrupt on EVENTS_BCMATCH event */ +/* Bit 10 : Write '1' to Enable interrupt for BCMATCH event */ #define RADIO_INTENSET_BCMATCH_Pos (10UL) /*!< Position of BCMATCH field. */ #define RADIO_INTENSET_BCMATCH_Msk (0x1UL << RADIO_INTENSET_BCMATCH_Pos) /*!< Bit mask of BCMATCH field. */ #define RADIO_INTENSET_BCMATCH_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENSET_BCMATCH_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENSET_BCMATCH_Set (1UL) /*!< Enable */ -/* Bit 7 : Write '1' to Enable interrupt on EVENTS_RSSIEND event */ +/* Bit 7 : Write '1' to Enable interrupt for RSSIEND event */ #define RADIO_INTENSET_RSSIEND_Pos (7UL) /*!< Position of RSSIEND field. */ #define RADIO_INTENSET_RSSIEND_Msk (0x1UL << RADIO_INTENSET_RSSIEND_Pos) /*!< Bit mask of RSSIEND field. */ #define RADIO_INTENSET_RSSIEND_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENSET_RSSIEND_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENSET_RSSIEND_Set (1UL) /*!< Enable */ -/* Bit 6 : Write '1' to Enable interrupt on EVENTS_DEVMISS event */ +/* Bit 6 : Write '1' to Enable interrupt for DEVMISS event */ #define RADIO_INTENSET_DEVMISS_Pos (6UL) /*!< Position of DEVMISS field. */ #define RADIO_INTENSET_DEVMISS_Msk (0x1UL << RADIO_INTENSET_DEVMISS_Pos) /*!< Bit mask of DEVMISS field. */ #define RADIO_INTENSET_DEVMISS_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENSET_DEVMISS_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENSET_DEVMISS_Set (1UL) /*!< Enable */ -/* Bit 5 : Write '1' to Enable interrupt on EVENTS_DEVMATCH event */ +/* Bit 5 : Write '1' to Enable interrupt for DEVMATCH event */ #define RADIO_INTENSET_DEVMATCH_Pos (5UL) /*!< Position of DEVMATCH field. */ #define RADIO_INTENSET_DEVMATCH_Msk (0x1UL << RADIO_INTENSET_DEVMATCH_Pos) /*!< Bit mask of DEVMATCH field. */ #define RADIO_INTENSET_DEVMATCH_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENSET_DEVMATCH_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENSET_DEVMATCH_Set (1UL) /*!< Enable */ -/* Bit 4 : Write '1' to Enable interrupt on EVENTS_DISABLED event */ +/* Bit 4 : Write '1' to Enable interrupt for DISABLED event */ #define RADIO_INTENSET_DISABLED_Pos (4UL) /*!< Position of DISABLED field. */ #define RADIO_INTENSET_DISABLED_Msk (0x1UL << RADIO_INTENSET_DISABLED_Pos) /*!< Bit mask of DISABLED field. */ #define RADIO_INTENSET_DISABLED_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENSET_DISABLED_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENSET_DISABLED_Set (1UL) /*!< Enable */ -/* Bit 3 : Write '1' to Enable interrupt on EVENTS_END event */ +/* Bit 3 : Write '1' to Enable interrupt for END event */ #define RADIO_INTENSET_END_Pos (3UL) /*!< Position of END field. */ #define RADIO_INTENSET_END_Msk (0x1UL << RADIO_INTENSET_END_Pos) /*!< Bit mask of END field. */ #define RADIO_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENSET_END_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_PAYLOAD event */ +/* Bit 2 : Write '1' to Enable interrupt for PAYLOAD event */ #define RADIO_INTENSET_PAYLOAD_Pos (2UL) /*!< Position of PAYLOAD field. */ #define RADIO_INTENSET_PAYLOAD_Msk (0x1UL << RADIO_INTENSET_PAYLOAD_Pos) /*!< Bit mask of PAYLOAD field. */ #define RADIO_INTENSET_PAYLOAD_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENSET_PAYLOAD_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENSET_PAYLOAD_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_ADDRESS event */ +/* Bit 1 : Write '1' to Enable interrupt for ADDRESS event */ #define RADIO_INTENSET_ADDRESS_Pos (1UL) /*!< Position of ADDRESS field. */ #define RADIO_INTENSET_ADDRESS_Msk (0x1UL << RADIO_INTENSET_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */ #define RADIO_INTENSET_ADDRESS_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENSET_ADDRESS_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENSET_ADDRESS_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_READY event */ +/* Bit 0 : Write '1' to Enable interrupt for READY event */ #define RADIO_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */ #define RADIO_INTENSET_READY_Msk (0x1UL << RADIO_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ #define RADIO_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ @@ -8318,77 +8619,77 @@ /* Register: RADIO_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 13 : Write '1' to Clear interrupt on EVENTS_CRCERROR event */ +/* Bit 13 : Write '1' to Disable interrupt for CRCERROR event */ #define RADIO_INTENCLR_CRCERROR_Pos (13UL) /*!< Position of CRCERROR field. */ #define RADIO_INTENCLR_CRCERROR_Msk (0x1UL << RADIO_INTENCLR_CRCERROR_Pos) /*!< Bit mask of CRCERROR field. */ #define RADIO_INTENCLR_CRCERROR_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENCLR_CRCERROR_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENCLR_CRCERROR_Clear (1UL) /*!< Disable */ -/* Bit 12 : Write '1' to Clear interrupt on EVENTS_CRCOK event */ +/* Bit 12 : Write '1' to Disable interrupt for CRCOK event */ #define RADIO_INTENCLR_CRCOK_Pos (12UL) /*!< Position of CRCOK field. */ #define RADIO_INTENCLR_CRCOK_Msk (0x1UL << RADIO_INTENCLR_CRCOK_Pos) /*!< Bit mask of CRCOK field. */ #define RADIO_INTENCLR_CRCOK_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENCLR_CRCOK_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENCLR_CRCOK_Clear (1UL) /*!< Disable */ -/* Bit 10 : Write '1' to Clear interrupt on EVENTS_BCMATCH event */ +/* Bit 10 : Write '1' to Disable interrupt for BCMATCH event */ #define RADIO_INTENCLR_BCMATCH_Pos (10UL) /*!< Position of BCMATCH field. */ #define RADIO_INTENCLR_BCMATCH_Msk (0x1UL << RADIO_INTENCLR_BCMATCH_Pos) /*!< Bit mask of BCMATCH field. */ #define RADIO_INTENCLR_BCMATCH_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENCLR_BCMATCH_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENCLR_BCMATCH_Clear (1UL) /*!< Disable */ -/* Bit 7 : Write '1' to Clear interrupt on EVENTS_RSSIEND event */ +/* Bit 7 : Write '1' to Disable interrupt for RSSIEND event */ #define RADIO_INTENCLR_RSSIEND_Pos (7UL) /*!< Position of RSSIEND field. */ #define RADIO_INTENCLR_RSSIEND_Msk (0x1UL << RADIO_INTENCLR_RSSIEND_Pos) /*!< Bit mask of RSSIEND field. */ #define RADIO_INTENCLR_RSSIEND_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENCLR_RSSIEND_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENCLR_RSSIEND_Clear (1UL) /*!< Disable */ -/* Bit 6 : Write '1' to Clear interrupt on EVENTS_DEVMISS event */ +/* Bit 6 : Write '1' to Disable interrupt for DEVMISS event */ #define RADIO_INTENCLR_DEVMISS_Pos (6UL) /*!< Position of DEVMISS field. */ #define RADIO_INTENCLR_DEVMISS_Msk (0x1UL << RADIO_INTENCLR_DEVMISS_Pos) /*!< Bit mask of DEVMISS field. */ #define RADIO_INTENCLR_DEVMISS_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENCLR_DEVMISS_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENCLR_DEVMISS_Clear (1UL) /*!< Disable */ -/* Bit 5 : Write '1' to Clear interrupt on EVENTS_DEVMATCH event */ +/* Bit 5 : Write '1' to Disable interrupt for DEVMATCH event */ #define RADIO_INTENCLR_DEVMATCH_Pos (5UL) /*!< Position of DEVMATCH field. */ #define RADIO_INTENCLR_DEVMATCH_Msk (0x1UL << RADIO_INTENCLR_DEVMATCH_Pos) /*!< Bit mask of DEVMATCH field. */ #define RADIO_INTENCLR_DEVMATCH_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENCLR_DEVMATCH_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENCLR_DEVMATCH_Clear (1UL) /*!< Disable */ -/* Bit 4 : Write '1' to Clear interrupt on EVENTS_DISABLED event */ +/* Bit 4 : Write '1' to Disable interrupt for DISABLED event */ #define RADIO_INTENCLR_DISABLED_Pos (4UL) /*!< Position of DISABLED field. */ #define RADIO_INTENCLR_DISABLED_Msk (0x1UL << RADIO_INTENCLR_DISABLED_Pos) /*!< Bit mask of DISABLED field. */ #define RADIO_INTENCLR_DISABLED_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENCLR_DISABLED_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENCLR_DISABLED_Clear (1UL) /*!< Disable */ -/* Bit 3 : Write '1' to Clear interrupt on EVENTS_END event */ +/* Bit 3 : Write '1' to Disable interrupt for END event */ #define RADIO_INTENCLR_END_Pos (3UL) /*!< Position of END field. */ #define RADIO_INTENCLR_END_Msk (0x1UL << RADIO_INTENCLR_END_Pos) /*!< Bit mask of END field. */ #define RADIO_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENCLR_END_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_PAYLOAD event */ +/* Bit 2 : Write '1' to Disable interrupt for PAYLOAD event */ #define RADIO_INTENCLR_PAYLOAD_Pos (2UL) /*!< Position of PAYLOAD field. */ #define RADIO_INTENCLR_PAYLOAD_Msk (0x1UL << RADIO_INTENCLR_PAYLOAD_Pos) /*!< Bit mask of PAYLOAD field. */ #define RADIO_INTENCLR_PAYLOAD_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENCLR_PAYLOAD_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENCLR_PAYLOAD_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_ADDRESS event */ +/* Bit 1 : Write '1' to Disable interrupt for ADDRESS event */ #define RADIO_INTENCLR_ADDRESS_Pos (1UL) /*!< Position of ADDRESS field. */ #define RADIO_INTENCLR_ADDRESS_Msk (0x1UL << RADIO_INTENCLR_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */ #define RADIO_INTENCLR_ADDRESS_Disabled (0UL) /*!< Read: Disabled */ #define RADIO_INTENCLR_ADDRESS_Enabled (1UL) /*!< Read: Enabled */ #define RADIO_INTENCLR_ADDRESS_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_READY event */ +/* Bit 0 : Write '1' to Disable interrupt for READY event */ #define RADIO_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */ #define RADIO_INTENCLR_READY_Msk (0x1UL << RADIO_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ #define RADIO_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ @@ -8435,6 +8736,12 @@ /* Register: RADIO_FREQUENCY */ /* Description: Frequency */ +/* Bit 8 : Channel map selection. */ +#define RADIO_FREQUENCY_MAP_Pos (8UL) /*!< Position of MAP field. */ +#define RADIO_FREQUENCY_MAP_Msk (0x1UL << RADIO_FREQUENCY_MAP_Pos) /*!< Bit mask of MAP field. */ +#define RADIO_FREQUENCY_MAP_Default (0UL) /*!< Channel map between 2400 MHZ .. 2500 MHz */ +#define RADIO_FREQUENCY_MAP_Low (1UL) /*!< Channel map between 2360 MHZ .. 2460 MHz */ + /* Bits 6..0 : Radio channel frequency */ #define RADIO_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */ #define RADIO_FREQUENCY_FREQUENCY_Msk (0x7FUL << RADIO_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */ @@ -8466,11 +8773,12 @@ #define RADIO_MODE_MODE_Nrf_2Mbit (1UL) /*!< 2 Mbit/s Nordic proprietary radio mode */ #define RADIO_MODE_MODE_Nrf_250Kbit (2UL) /*!< Deprecated enumerator - 250 kbit/s Nordic proprietary radio mode */ #define RADIO_MODE_MODE_Ble_1Mbit (3UL) /*!< 1 Mbit/s Bluetooth Low Energy */ +#define RADIO_MODE_MODE_Ble_2Mbit (4UL) /*!< 2 Mbit/s Bluetooth Low Energy */ /* Register: RADIO_PCNF0 */ /* Description: Packet configuration register 0 */ -/* Bit 24 : Length of preamble on air. Decision point: "RADIO.TASKS_START" task */ +/* Bit 24 : Length of preamble on air. Decision point: TASKS_START task */ #define RADIO_PCNF0_PLEN_Pos (24UL) /*!< Position of PLEN field. */ #define RADIO_PCNF0_PLEN_Msk (0x1UL << RADIO_PCNF0_PLEN_Pos) /*!< Bit mask of PLEN field. */ #define RADIO_PCNF0_PLEN_8bit (0UL) /*!< 8-bit preamble */ @@ -8479,7 +8787,7 @@ /* Bit 20 : Include or exclude S1 field in RAM */ #define RADIO_PCNF0_S1INCL_Pos (20UL) /*!< Position of S1INCL field. */ #define RADIO_PCNF0_S1INCL_Msk (0x1UL << RADIO_PCNF0_S1INCL_Pos) /*!< Bit mask of S1INCL field. */ -#define RADIO_PCNF0_S1INCL_Automatic (0UL) /*!< Include S1 field in RAM only if S1LEN > 0 */ +#define RADIO_PCNF0_S1INCL_Automatic (0UL) /*!< Include S1 field in RAM only if S1LEN > 0 */ #define RADIO_PCNF0_S1INCL_Include (1UL) /*!< Always include S1 field in RAM independent of S1LEN */ /* Bits 19..16 : Length on air of S1 field in number of bits. */ @@ -8816,8 +9124,8 @@ /* Bit 0 : Radio ramp-up time */ #define RADIO_MODECNF0_RU_Pos (0UL) /*!< Position of RU field. */ #define RADIO_MODECNF0_RU_Msk (0x1UL << RADIO_MODECNF0_RU_Pos) /*!< Bit mask of RU field. */ -#define RADIO_MODECNF0_RU_Default (0UL) /*!< Default ramp-up time, compatible with nRF51 */ -#define RADIO_MODECNF0_RU_Fast (1UL) /*!< Fast ramp-up, see product specification for more information */ +#define RADIO_MODECNF0_RU_Default (0UL) /*!< Default ramp-up time (tRXEN), compatible with firmware written for nRF51 */ +#define RADIO_MODECNF0_RU_Fast (1UL) /*!< Fast ramp-up (tRXEN,FAST), see electrical specification for more information */ /* Register: RADIO_POWER */ /* Description: Peripheral power control */ @@ -8835,7 +9143,7 @@ /* Register: RNG_SHORTS */ /* Description: Shortcut register */ -/* Bit 0 : Shortcut between EVENTS_VALRDY event and TASKS_STOP task */ +/* Bit 0 : Shortcut between VALRDY event and STOP task */ #define RNG_SHORTS_VALRDY_STOP_Pos (0UL) /*!< Position of VALRDY_STOP field. */ #define RNG_SHORTS_VALRDY_STOP_Msk (0x1UL << RNG_SHORTS_VALRDY_STOP_Pos) /*!< Bit mask of VALRDY_STOP field. */ #define RNG_SHORTS_VALRDY_STOP_Disabled (0UL) /*!< Disable shortcut */ @@ -8844,7 +9152,7 @@ /* Register: RNG_INTENSET */ /* Description: Enable interrupt */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_VALRDY event */ +/* Bit 0 : Write '1' to Enable interrupt for VALRDY event */ #define RNG_INTENSET_VALRDY_Pos (0UL) /*!< Position of VALRDY field. */ #define RNG_INTENSET_VALRDY_Msk (0x1UL << RNG_INTENSET_VALRDY_Pos) /*!< Bit mask of VALRDY field. */ #define RNG_INTENSET_VALRDY_Disabled (0UL) /*!< Read: Disabled */ @@ -8854,7 +9162,7 @@ /* Register: RNG_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_VALRDY event */ +/* Bit 0 : Write '1' to Disable interrupt for VALRDY event */ #define RNG_INTENCLR_VALRDY_Pos (0UL) /*!< Position of VALRDY field. */ #define RNG_INTENCLR_VALRDY_Msk (0x1UL << RNG_INTENCLR_VALRDY_Pos) /*!< Bit mask of VALRDY field. */ #define RNG_INTENCLR_VALRDY_Disabled (0UL) /*!< Read: Disabled */ @@ -8884,42 +9192,42 @@ /* Register: RTC_INTENSET */ /* Description: Enable interrupt */ -/* Bit 19 : Write '1' to Enable interrupt on EVENTS_COMPARE[3] event */ +/* Bit 19 : Write '1' to Enable interrupt for COMPARE[3] event */ #define RTC_INTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ #define RTC_INTENSET_COMPARE3_Msk (0x1UL << RTC_INTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ #define RTC_INTENSET_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ #define RTC_INTENSET_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ #define RTC_INTENSET_COMPARE3_Set (1UL) /*!< Enable */ -/* Bit 18 : Write '1' to Enable interrupt on EVENTS_COMPARE[2] event */ +/* Bit 18 : Write '1' to Enable interrupt for COMPARE[2] event */ #define RTC_INTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ #define RTC_INTENSET_COMPARE2_Msk (0x1UL << RTC_INTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ #define RTC_INTENSET_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ #define RTC_INTENSET_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ #define RTC_INTENSET_COMPARE2_Set (1UL) /*!< Enable */ -/* Bit 17 : Write '1' to Enable interrupt on EVENTS_COMPARE[1] event */ +/* Bit 17 : Write '1' to Enable interrupt for COMPARE[1] event */ #define RTC_INTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ #define RTC_INTENSET_COMPARE1_Msk (0x1UL << RTC_INTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ #define RTC_INTENSET_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ #define RTC_INTENSET_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ #define RTC_INTENSET_COMPARE1_Set (1UL) /*!< Enable */ -/* Bit 16 : Write '1' to Enable interrupt on EVENTS_COMPARE[0] event */ +/* Bit 16 : Write '1' to Enable interrupt for COMPARE[0] event */ #define RTC_INTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ #define RTC_INTENSET_COMPARE0_Msk (0x1UL << RTC_INTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ #define RTC_INTENSET_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ #define RTC_INTENSET_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ #define RTC_INTENSET_COMPARE0_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_OVRFLW event */ +/* Bit 1 : Write '1' to Enable interrupt for OVRFLW event */ #define RTC_INTENSET_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ #define RTC_INTENSET_OVRFLW_Msk (0x1UL << RTC_INTENSET_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ #define RTC_INTENSET_OVRFLW_Disabled (0UL) /*!< Read: Disabled */ #define RTC_INTENSET_OVRFLW_Enabled (1UL) /*!< Read: Enabled */ #define RTC_INTENSET_OVRFLW_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_TICK event */ +/* Bit 0 : Write '1' to Enable interrupt for TICK event */ #define RTC_INTENSET_TICK_Pos (0UL) /*!< Position of TICK field. */ #define RTC_INTENSET_TICK_Msk (0x1UL << RTC_INTENSET_TICK_Pos) /*!< Bit mask of TICK field. */ #define RTC_INTENSET_TICK_Disabled (0UL) /*!< Read: Disabled */ @@ -8929,42 +9237,42 @@ /* Register: RTC_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 19 : Write '1' to Clear interrupt on EVENTS_COMPARE[3] event */ +/* Bit 19 : Write '1' to Disable interrupt for COMPARE[3] event */ #define RTC_INTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ #define RTC_INTENCLR_COMPARE3_Msk (0x1UL << RTC_INTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ #define RTC_INTENCLR_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ #define RTC_INTENCLR_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ #define RTC_INTENCLR_COMPARE3_Clear (1UL) /*!< Disable */ -/* Bit 18 : Write '1' to Clear interrupt on EVENTS_COMPARE[2] event */ +/* Bit 18 : Write '1' to Disable interrupt for COMPARE[2] event */ #define RTC_INTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ #define RTC_INTENCLR_COMPARE2_Msk (0x1UL << RTC_INTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ #define RTC_INTENCLR_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ #define RTC_INTENCLR_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ #define RTC_INTENCLR_COMPARE2_Clear (1UL) /*!< Disable */ -/* Bit 17 : Write '1' to Clear interrupt on EVENTS_COMPARE[1] event */ +/* Bit 17 : Write '1' to Disable interrupt for COMPARE[1] event */ #define RTC_INTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ #define RTC_INTENCLR_COMPARE1_Msk (0x1UL << RTC_INTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ #define RTC_INTENCLR_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ #define RTC_INTENCLR_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ #define RTC_INTENCLR_COMPARE1_Clear (1UL) /*!< Disable */ -/* Bit 16 : Write '1' to Clear interrupt on EVENTS_COMPARE[0] event */ +/* Bit 16 : Write '1' to Disable interrupt for COMPARE[0] event */ #define RTC_INTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ #define RTC_INTENCLR_COMPARE0_Msk (0x1UL << RTC_INTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ #define RTC_INTENCLR_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ #define RTC_INTENCLR_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ #define RTC_INTENCLR_COMPARE0_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_OVRFLW event */ +/* Bit 1 : Write '1' to Disable interrupt for OVRFLW event */ #define RTC_INTENCLR_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ #define RTC_INTENCLR_OVRFLW_Msk (0x1UL << RTC_INTENCLR_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ #define RTC_INTENCLR_OVRFLW_Disabled (0UL) /*!< Read: Disabled */ #define RTC_INTENCLR_OVRFLW_Enabled (1UL) /*!< Read: Enabled */ #define RTC_INTENCLR_OVRFLW_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_TICK event */ +/* Bit 0 : Write '1' to Disable interrupt for TICK event */ #define RTC_INTENCLR_TICK_Pos (0UL) /*!< Position of TICK field. */ #define RTC_INTENCLR_TICK_Msk (0x1UL << RTC_INTENCLR_TICK_Pos) /*!< Bit mask of TICK field. */ #define RTC_INTENCLR_TICK_Disabled (0UL) /*!< Read: Disabled */ @@ -8974,37 +9282,37 @@ /* Register: RTC_EVTEN */ /* Description: Enable or disable event routing */ -/* Bit 19 : Enable or disable event routing on EVENTS_COMPARE[3] event */ +/* Bit 19 : Enable or disable event routing for COMPARE[3] event */ #define RTC_EVTEN_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ #define RTC_EVTEN_COMPARE3_Msk (0x1UL << RTC_EVTEN_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ #define RTC_EVTEN_COMPARE3_Disabled (0UL) /*!< Disable */ #define RTC_EVTEN_COMPARE3_Enabled (1UL) /*!< Enable */ -/* Bit 18 : Enable or disable event routing on EVENTS_COMPARE[2] event */ +/* Bit 18 : Enable or disable event routing for COMPARE[2] event */ #define RTC_EVTEN_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ #define RTC_EVTEN_COMPARE2_Msk (0x1UL << RTC_EVTEN_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ #define RTC_EVTEN_COMPARE2_Disabled (0UL) /*!< Disable */ #define RTC_EVTEN_COMPARE2_Enabled (1UL) /*!< Enable */ -/* Bit 17 : Enable or disable event routing on EVENTS_COMPARE[1] event */ +/* Bit 17 : Enable or disable event routing for COMPARE[1] event */ #define RTC_EVTEN_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ #define RTC_EVTEN_COMPARE1_Msk (0x1UL << RTC_EVTEN_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ #define RTC_EVTEN_COMPARE1_Disabled (0UL) /*!< Disable */ #define RTC_EVTEN_COMPARE1_Enabled (1UL) /*!< Enable */ -/* Bit 16 : Enable or disable event routing on EVENTS_COMPARE[0] event */ +/* Bit 16 : Enable or disable event routing for COMPARE[0] event */ #define RTC_EVTEN_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ #define RTC_EVTEN_COMPARE0_Msk (0x1UL << RTC_EVTEN_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ #define RTC_EVTEN_COMPARE0_Disabled (0UL) /*!< Disable */ #define RTC_EVTEN_COMPARE0_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable event routing on EVENTS_OVRFLW event */ +/* Bit 1 : Enable or disable event routing for OVRFLW event */ #define RTC_EVTEN_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ #define RTC_EVTEN_OVRFLW_Msk (0x1UL << RTC_EVTEN_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ #define RTC_EVTEN_OVRFLW_Disabled (0UL) /*!< Disable */ #define RTC_EVTEN_OVRFLW_Enabled (1UL) /*!< Enable */ -/* Bit 0 : Enable or disable event routing on EVENTS_TICK event */ +/* Bit 0 : Enable or disable event routing for TICK event */ #define RTC_EVTEN_TICK_Pos (0UL) /*!< Position of TICK field. */ #define RTC_EVTEN_TICK_Msk (0x1UL << RTC_EVTEN_TICK_Pos) /*!< Bit mask of TICK field. */ #define RTC_EVTEN_TICK_Disabled (0UL) /*!< Disable */ @@ -9013,42 +9321,42 @@ /* Register: RTC_EVTENSET */ /* Description: Enable event routing */ -/* Bit 19 : Write '1' to Enable event routing on EVENTS_COMPARE[3] event */ +/* Bit 19 : Write '1' to Enable event routing for COMPARE[3] event */ #define RTC_EVTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ #define RTC_EVTENSET_COMPARE3_Msk (0x1UL << RTC_EVTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ #define RTC_EVTENSET_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ #define RTC_EVTENSET_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ #define RTC_EVTENSET_COMPARE3_Set (1UL) /*!< Enable */ -/* Bit 18 : Write '1' to Enable event routing on EVENTS_COMPARE[2] event */ +/* Bit 18 : Write '1' to Enable event routing for COMPARE[2] event */ #define RTC_EVTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ #define RTC_EVTENSET_COMPARE2_Msk (0x1UL << RTC_EVTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ #define RTC_EVTENSET_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ #define RTC_EVTENSET_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ #define RTC_EVTENSET_COMPARE2_Set (1UL) /*!< Enable */ -/* Bit 17 : Write '1' to Enable event routing on EVENTS_COMPARE[1] event */ +/* Bit 17 : Write '1' to Enable event routing for COMPARE[1] event */ #define RTC_EVTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ #define RTC_EVTENSET_COMPARE1_Msk (0x1UL << RTC_EVTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ #define RTC_EVTENSET_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ #define RTC_EVTENSET_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ #define RTC_EVTENSET_COMPARE1_Set (1UL) /*!< Enable */ -/* Bit 16 : Write '1' to Enable event routing on EVENTS_COMPARE[0] event */ +/* Bit 16 : Write '1' to Enable event routing for COMPARE[0] event */ #define RTC_EVTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ #define RTC_EVTENSET_COMPARE0_Msk (0x1UL << RTC_EVTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ #define RTC_EVTENSET_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ #define RTC_EVTENSET_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ #define RTC_EVTENSET_COMPARE0_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable event routing on EVENTS_OVRFLW event */ +/* Bit 1 : Write '1' to Enable event routing for OVRFLW event */ #define RTC_EVTENSET_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ #define RTC_EVTENSET_OVRFLW_Msk (0x1UL << RTC_EVTENSET_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ #define RTC_EVTENSET_OVRFLW_Disabled (0UL) /*!< Read: Disabled */ #define RTC_EVTENSET_OVRFLW_Enabled (1UL) /*!< Read: Enabled */ #define RTC_EVTENSET_OVRFLW_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable event routing on EVENTS_TICK event */ +/* Bit 0 : Write '1' to Enable event routing for TICK event */ #define RTC_EVTENSET_TICK_Pos (0UL) /*!< Position of TICK field. */ #define RTC_EVTENSET_TICK_Msk (0x1UL << RTC_EVTENSET_TICK_Pos) /*!< Bit mask of TICK field. */ #define RTC_EVTENSET_TICK_Disabled (0UL) /*!< Read: Disabled */ @@ -9058,42 +9366,42 @@ /* Register: RTC_EVTENCLR */ /* Description: Disable event routing */ -/* Bit 19 : Write '1' to Clear event routing on EVENTS_COMPARE[3] event */ +/* Bit 19 : Write '1' to Disable event routing for COMPARE[3] event */ #define RTC_EVTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ #define RTC_EVTENCLR_COMPARE3_Msk (0x1UL << RTC_EVTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ #define RTC_EVTENCLR_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ #define RTC_EVTENCLR_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ #define RTC_EVTENCLR_COMPARE3_Clear (1UL) /*!< Disable */ -/* Bit 18 : Write '1' to Clear event routing on EVENTS_COMPARE[2] event */ +/* Bit 18 : Write '1' to Disable event routing for COMPARE[2] event */ #define RTC_EVTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ #define RTC_EVTENCLR_COMPARE2_Msk (0x1UL << RTC_EVTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ #define RTC_EVTENCLR_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ #define RTC_EVTENCLR_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ #define RTC_EVTENCLR_COMPARE2_Clear (1UL) /*!< Disable */ -/* Bit 17 : Write '1' to Clear event routing on EVENTS_COMPARE[1] event */ +/* Bit 17 : Write '1' to Disable event routing for COMPARE[1] event */ #define RTC_EVTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ #define RTC_EVTENCLR_COMPARE1_Msk (0x1UL << RTC_EVTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ #define RTC_EVTENCLR_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ #define RTC_EVTENCLR_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ #define RTC_EVTENCLR_COMPARE1_Clear (1UL) /*!< Disable */ -/* Bit 16 : Write '1' to Clear event routing on EVENTS_COMPARE[0] event */ +/* Bit 16 : Write '1' to Disable event routing for COMPARE[0] event */ #define RTC_EVTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ #define RTC_EVTENCLR_COMPARE0_Msk (0x1UL << RTC_EVTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ #define RTC_EVTENCLR_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ #define RTC_EVTENCLR_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ #define RTC_EVTENCLR_COMPARE0_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear event routing on EVENTS_OVRFLW event */ +/* Bit 1 : Write '1' to Disable event routing for OVRFLW event */ #define RTC_EVTENCLR_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ #define RTC_EVTENCLR_OVRFLW_Msk (0x1UL << RTC_EVTENCLR_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ #define RTC_EVTENCLR_OVRFLW_Disabled (0UL) /*!< Read: Disabled */ #define RTC_EVTENCLR_OVRFLW_Enabled (1UL) /*!< Read: Enabled */ #define RTC_EVTENCLR_OVRFLW_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear event routing on EVENTS_TICK event */ +/* Bit 0 : Write '1' to Disable event routing for TICK event */ #define RTC_EVTENCLR_TICK_Pos (0UL) /*!< Position of TICK field. */ #define RTC_EVTENCLR_TICK_Msk (0x1UL << RTC_EVTENCLR_TICK_Pos) /*!< Bit mask of TICK field. */ #define RTC_EVTENCLR_TICK_Disabled (0UL) /*!< Read: Disabled */ @@ -9128,133 +9436,133 @@ /* Register: SAADC_INTEN */ /* Description: Enable or disable interrupt */ -/* Bit 21 : Enable or disable interrupt on EVENTS_CH[7].LIMITL event */ +/* Bit 21 : Enable or disable interrupt for CH[7].LIMITL event */ #define SAADC_INTEN_CH7LIMITL_Pos (21UL) /*!< Position of CH7LIMITL field. */ #define SAADC_INTEN_CH7LIMITL_Msk (0x1UL << SAADC_INTEN_CH7LIMITL_Pos) /*!< Bit mask of CH7LIMITL field. */ #define SAADC_INTEN_CH7LIMITL_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH7LIMITL_Enabled (1UL) /*!< Enable */ -/* Bit 20 : Enable or disable interrupt on EVENTS_CH[7].LIMITH event */ +/* Bit 20 : Enable or disable interrupt for CH[7].LIMITH event */ #define SAADC_INTEN_CH7LIMITH_Pos (20UL) /*!< Position of CH7LIMITH field. */ #define SAADC_INTEN_CH7LIMITH_Msk (0x1UL << SAADC_INTEN_CH7LIMITH_Pos) /*!< Bit mask of CH7LIMITH field. */ #define SAADC_INTEN_CH7LIMITH_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH7LIMITH_Enabled (1UL) /*!< Enable */ -/* Bit 19 : Enable or disable interrupt on EVENTS_CH[6].LIMITL event */ +/* Bit 19 : Enable or disable interrupt for CH[6].LIMITL event */ #define SAADC_INTEN_CH6LIMITL_Pos (19UL) /*!< Position of CH6LIMITL field. */ #define SAADC_INTEN_CH6LIMITL_Msk (0x1UL << SAADC_INTEN_CH6LIMITL_Pos) /*!< Bit mask of CH6LIMITL field. */ #define SAADC_INTEN_CH6LIMITL_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH6LIMITL_Enabled (1UL) /*!< Enable */ -/* Bit 18 : Enable or disable interrupt on EVENTS_CH[6].LIMITH event */ +/* Bit 18 : Enable or disable interrupt for CH[6].LIMITH event */ #define SAADC_INTEN_CH6LIMITH_Pos (18UL) /*!< Position of CH6LIMITH field. */ #define SAADC_INTEN_CH6LIMITH_Msk (0x1UL << SAADC_INTEN_CH6LIMITH_Pos) /*!< Bit mask of CH6LIMITH field. */ #define SAADC_INTEN_CH6LIMITH_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH6LIMITH_Enabled (1UL) /*!< Enable */ -/* Bit 17 : Enable or disable interrupt on EVENTS_CH[5].LIMITL event */ +/* Bit 17 : Enable or disable interrupt for CH[5].LIMITL event */ #define SAADC_INTEN_CH5LIMITL_Pos (17UL) /*!< Position of CH5LIMITL field. */ #define SAADC_INTEN_CH5LIMITL_Msk (0x1UL << SAADC_INTEN_CH5LIMITL_Pos) /*!< Bit mask of CH5LIMITL field. */ #define SAADC_INTEN_CH5LIMITL_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH5LIMITL_Enabled (1UL) /*!< Enable */ -/* Bit 16 : Enable or disable interrupt on EVENTS_CH[5].LIMITH event */ +/* Bit 16 : Enable or disable interrupt for CH[5].LIMITH event */ #define SAADC_INTEN_CH5LIMITH_Pos (16UL) /*!< Position of CH5LIMITH field. */ #define SAADC_INTEN_CH5LIMITH_Msk (0x1UL << SAADC_INTEN_CH5LIMITH_Pos) /*!< Bit mask of CH5LIMITH field. */ #define SAADC_INTEN_CH5LIMITH_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH5LIMITH_Enabled (1UL) /*!< Enable */ -/* Bit 15 : Enable or disable interrupt on EVENTS_CH[4].LIMITL event */ +/* Bit 15 : Enable or disable interrupt for CH[4].LIMITL event */ #define SAADC_INTEN_CH4LIMITL_Pos (15UL) /*!< Position of CH4LIMITL field. */ #define SAADC_INTEN_CH4LIMITL_Msk (0x1UL << SAADC_INTEN_CH4LIMITL_Pos) /*!< Bit mask of CH4LIMITL field. */ #define SAADC_INTEN_CH4LIMITL_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH4LIMITL_Enabled (1UL) /*!< Enable */ -/* Bit 14 : Enable or disable interrupt on EVENTS_CH[4].LIMITH event */ +/* Bit 14 : Enable or disable interrupt for CH[4].LIMITH event */ #define SAADC_INTEN_CH4LIMITH_Pos (14UL) /*!< Position of CH4LIMITH field. */ #define SAADC_INTEN_CH4LIMITH_Msk (0x1UL << SAADC_INTEN_CH4LIMITH_Pos) /*!< Bit mask of CH4LIMITH field. */ #define SAADC_INTEN_CH4LIMITH_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH4LIMITH_Enabled (1UL) /*!< Enable */ -/* Bit 13 : Enable or disable interrupt on EVENTS_CH[3].LIMITL event */ +/* Bit 13 : Enable or disable interrupt for CH[3].LIMITL event */ #define SAADC_INTEN_CH3LIMITL_Pos (13UL) /*!< Position of CH3LIMITL field. */ #define SAADC_INTEN_CH3LIMITL_Msk (0x1UL << SAADC_INTEN_CH3LIMITL_Pos) /*!< Bit mask of CH3LIMITL field. */ #define SAADC_INTEN_CH3LIMITL_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH3LIMITL_Enabled (1UL) /*!< Enable */ -/* Bit 12 : Enable or disable interrupt on EVENTS_CH[3].LIMITH event */ +/* Bit 12 : Enable or disable interrupt for CH[3].LIMITH event */ #define SAADC_INTEN_CH3LIMITH_Pos (12UL) /*!< Position of CH3LIMITH field. */ #define SAADC_INTEN_CH3LIMITH_Msk (0x1UL << SAADC_INTEN_CH3LIMITH_Pos) /*!< Bit mask of CH3LIMITH field. */ #define SAADC_INTEN_CH3LIMITH_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH3LIMITH_Enabled (1UL) /*!< Enable */ -/* Bit 11 : Enable or disable interrupt on EVENTS_CH[2].LIMITL event */ +/* Bit 11 : Enable or disable interrupt for CH[2].LIMITL event */ #define SAADC_INTEN_CH2LIMITL_Pos (11UL) /*!< Position of CH2LIMITL field. */ #define SAADC_INTEN_CH2LIMITL_Msk (0x1UL << SAADC_INTEN_CH2LIMITL_Pos) /*!< Bit mask of CH2LIMITL field. */ #define SAADC_INTEN_CH2LIMITL_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH2LIMITL_Enabled (1UL) /*!< Enable */ -/* Bit 10 : Enable or disable interrupt on EVENTS_CH[2].LIMITH event */ +/* Bit 10 : Enable or disable interrupt for CH[2].LIMITH event */ #define SAADC_INTEN_CH2LIMITH_Pos (10UL) /*!< Position of CH2LIMITH field. */ #define SAADC_INTEN_CH2LIMITH_Msk (0x1UL << SAADC_INTEN_CH2LIMITH_Pos) /*!< Bit mask of CH2LIMITH field. */ #define SAADC_INTEN_CH2LIMITH_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH2LIMITH_Enabled (1UL) /*!< Enable */ -/* Bit 9 : Enable or disable interrupt on EVENTS_CH[1].LIMITL event */ +/* Bit 9 : Enable or disable interrupt for CH[1].LIMITL event */ #define SAADC_INTEN_CH1LIMITL_Pos (9UL) /*!< Position of CH1LIMITL field. */ #define SAADC_INTEN_CH1LIMITL_Msk (0x1UL << SAADC_INTEN_CH1LIMITL_Pos) /*!< Bit mask of CH1LIMITL field. */ #define SAADC_INTEN_CH1LIMITL_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH1LIMITL_Enabled (1UL) /*!< Enable */ -/* Bit 8 : Enable or disable interrupt on EVENTS_CH[1].LIMITH event */ +/* Bit 8 : Enable or disable interrupt for CH[1].LIMITH event */ #define SAADC_INTEN_CH1LIMITH_Pos (8UL) /*!< Position of CH1LIMITH field. */ #define SAADC_INTEN_CH1LIMITH_Msk (0x1UL << SAADC_INTEN_CH1LIMITH_Pos) /*!< Bit mask of CH1LIMITH field. */ #define SAADC_INTEN_CH1LIMITH_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH1LIMITH_Enabled (1UL) /*!< Enable */ -/* Bit 7 : Enable or disable interrupt on EVENTS_CH[0].LIMITL event */ +/* Bit 7 : Enable or disable interrupt for CH[0].LIMITL event */ #define SAADC_INTEN_CH0LIMITL_Pos (7UL) /*!< Position of CH0LIMITL field. */ #define SAADC_INTEN_CH0LIMITL_Msk (0x1UL << SAADC_INTEN_CH0LIMITL_Pos) /*!< Bit mask of CH0LIMITL field. */ #define SAADC_INTEN_CH0LIMITL_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH0LIMITL_Enabled (1UL) /*!< Enable */ -/* Bit 6 : Enable or disable interrupt on EVENTS_CH[0].LIMITH event */ +/* Bit 6 : Enable or disable interrupt for CH[0].LIMITH event */ #define SAADC_INTEN_CH0LIMITH_Pos (6UL) /*!< Position of CH0LIMITH field. */ #define SAADC_INTEN_CH0LIMITH_Msk (0x1UL << SAADC_INTEN_CH0LIMITH_Pos) /*!< Bit mask of CH0LIMITH field. */ #define SAADC_INTEN_CH0LIMITH_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CH0LIMITH_Enabled (1UL) /*!< Enable */ -/* Bit 5 : Enable or disable interrupt on EVENTS_STOPPED event */ +/* Bit 5 : Enable or disable interrupt for STOPPED event */ #define SAADC_INTEN_STOPPED_Pos (5UL) /*!< Position of STOPPED field. */ #define SAADC_INTEN_STOPPED_Msk (0x1UL << SAADC_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define SAADC_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ -/* Bit 4 : Enable or disable interrupt on EVENTS_CALIBRATEDONE event */ +/* Bit 4 : Enable or disable interrupt for CALIBRATEDONE event */ #define SAADC_INTEN_CALIBRATEDONE_Pos (4UL) /*!< Position of CALIBRATEDONE field. */ #define SAADC_INTEN_CALIBRATEDONE_Msk (0x1UL << SAADC_INTEN_CALIBRATEDONE_Pos) /*!< Bit mask of CALIBRATEDONE field. */ #define SAADC_INTEN_CALIBRATEDONE_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_CALIBRATEDONE_Enabled (1UL) /*!< Enable */ -/* Bit 3 : Enable or disable interrupt on EVENTS_RESULTDONE event */ +/* Bit 3 : Enable or disable interrupt for RESULTDONE event */ #define SAADC_INTEN_RESULTDONE_Pos (3UL) /*!< Position of RESULTDONE field. */ #define SAADC_INTEN_RESULTDONE_Msk (0x1UL << SAADC_INTEN_RESULTDONE_Pos) /*!< Bit mask of RESULTDONE field. */ #define SAADC_INTEN_RESULTDONE_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_RESULTDONE_Enabled (1UL) /*!< Enable */ -/* Bit 2 : Enable or disable interrupt on EVENTS_DONE event */ +/* Bit 2 : Enable or disable interrupt for DONE event */ #define SAADC_INTEN_DONE_Pos (2UL) /*!< Position of DONE field. */ #define SAADC_INTEN_DONE_Msk (0x1UL << SAADC_INTEN_DONE_Pos) /*!< Bit mask of DONE field. */ #define SAADC_INTEN_DONE_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_DONE_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable interrupt on EVENTS_END event */ +/* Bit 1 : Enable or disable interrupt for END event */ #define SAADC_INTEN_END_Pos (1UL) /*!< Position of END field. */ #define SAADC_INTEN_END_Msk (0x1UL << SAADC_INTEN_END_Pos) /*!< Bit mask of END field. */ #define SAADC_INTEN_END_Disabled (0UL) /*!< Disable */ #define SAADC_INTEN_END_Enabled (1UL) /*!< Enable */ -/* Bit 0 : Enable or disable interrupt on EVENTS_STARTED event */ +/* Bit 0 : Enable or disable interrupt for STARTED event */ #define SAADC_INTEN_STARTED_Pos (0UL) /*!< Position of STARTED field. */ #define SAADC_INTEN_STARTED_Msk (0x1UL << SAADC_INTEN_STARTED_Pos) /*!< Bit mask of STARTED field. */ #define SAADC_INTEN_STARTED_Disabled (0UL) /*!< Disable */ @@ -9263,154 +9571,154 @@ /* Register: SAADC_INTENSET */ /* Description: Enable interrupt */ -/* Bit 21 : Write '1' to Enable interrupt on EVENTS_CH[7].LIMITL event */ +/* Bit 21 : Write '1' to Enable interrupt for CH[7].LIMITL event */ #define SAADC_INTENSET_CH7LIMITL_Pos (21UL) /*!< Position of CH7LIMITL field. */ #define SAADC_INTENSET_CH7LIMITL_Msk (0x1UL << SAADC_INTENSET_CH7LIMITL_Pos) /*!< Bit mask of CH7LIMITL field. */ #define SAADC_INTENSET_CH7LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH7LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH7LIMITL_Set (1UL) /*!< Enable */ -/* Bit 20 : Write '1' to Enable interrupt on EVENTS_CH[7].LIMITH event */ +/* Bit 20 : Write '1' to Enable interrupt for CH[7].LIMITH event */ #define SAADC_INTENSET_CH7LIMITH_Pos (20UL) /*!< Position of CH7LIMITH field. */ #define SAADC_INTENSET_CH7LIMITH_Msk (0x1UL << SAADC_INTENSET_CH7LIMITH_Pos) /*!< Bit mask of CH7LIMITH field. */ #define SAADC_INTENSET_CH7LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH7LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH7LIMITH_Set (1UL) /*!< Enable */ -/* Bit 19 : Write '1' to Enable interrupt on EVENTS_CH[6].LIMITL event */ +/* Bit 19 : Write '1' to Enable interrupt for CH[6].LIMITL event */ #define SAADC_INTENSET_CH6LIMITL_Pos (19UL) /*!< Position of CH6LIMITL field. */ #define SAADC_INTENSET_CH6LIMITL_Msk (0x1UL << SAADC_INTENSET_CH6LIMITL_Pos) /*!< Bit mask of CH6LIMITL field. */ #define SAADC_INTENSET_CH6LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH6LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH6LIMITL_Set (1UL) /*!< Enable */ -/* Bit 18 : Write '1' to Enable interrupt on EVENTS_CH[6].LIMITH event */ +/* Bit 18 : Write '1' to Enable interrupt for CH[6].LIMITH event */ #define SAADC_INTENSET_CH6LIMITH_Pos (18UL) /*!< Position of CH6LIMITH field. */ #define SAADC_INTENSET_CH6LIMITH_Msk (0x1UL << SAADC_INTENSET_CH6LIMITH_Pos) /*!< Bit mask of CH6LIMITH field. */ #define SAADC_INTENSET_CH6LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH6LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH6LIMITH_Set (1UL) /*!< Enable */ -/* Bit 17 : Write '1' to Enable interrupt on EVENTS_CH[5].LIMITL event */ +/* Bit 17 : Write '1' to Enable interrupt for CH[5].LIMITL event */ #define SAADC_INTENSET_CH5LIMITL_Pos (17UL) /*!< Position of CH5LIMITL field. */ #define SAADC_INTENSET_CH5LIMITL_Msk (0x1UL << SAADC_INTENSET_CH5LIMITL_Pos) /*!< Bit mask of CH5LIMITL field. */ #define SAADC_INTENSET_CH5LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH5LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH5LIMITL_Set (1UL) /*!< Enable */ -/* Bit 16 : Write '1' to Enable interrupt on EVENTS_CH[5].LIMITH event */ +/* Bit 16 : Write '1' to Enable interrupt for CH[5].LIMITH event */ #define SAADC_INTENSET_CH5LIMITH_Pos (16UL) /*!< Position of CH5LIMITH field. */ #define SAADC_INTENSET_CH5LIMITH_Msk (0x1UL << SAADC_INTENSET_CH5LIMITH_Pos) /*!< Bit mask of CH5LIMITH field. */ #define SAADC_INTENSET_CH5LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH5LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH5LIMITH_Set (1UL) /*!< Enable */ -/* Bit 15 : Write '1' to Enable interrupt on EVENTS_CH[4].LIMITL event */ +/* Bit 15 : Write '1' to Enable interrupt for CH[4].LIMITL event */ #define SAADC_INTENSET_CH4LIMITL_Pos (15UL) /*!< Position of CH4LIMITL field. */ #define SAADC_INTENSET_CH4LIMITL_Msk (0x1UL << SAADC_INTENSET_CH4LIMITL_Pos) /*!< Bit mask of CH4LIMITL field. */ #define SAADC_INTENSET_CH4LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH4LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH4LIMITL_Set (1UL) /*!< Enable */ -/* Bit 14 : Write '1' to Enable interrupt on EVENTS_CH[4].LIMITH event */ +/* Bit 14 : Write '1' to Enable interrupt for CH[4].LIMITH event */ #define SAADC_INTENSET_CH4LIMITH_Pos (14UL) /*!< Position of CH4LIMITH field. */ #define SAADC_INTENSET_CH4LIMITH_Msk (0x1UL << SAADC_INTENSET_CH4LIMITH_Pos) /*!< Bit mask of CH4LIMITH field. */ #define SAADC_INTENSET_CH4LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH4LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH4LIMITH_Set (1UL) /*!< Enable */ -/* Bit 13 : Write '1' to Enable interrupt on EVENTS_CH[3].LIMITL event */ +/* Bit 13 : Write '1' to Enable interrupt for CH[3].LIMITL event */ #define SAADC_INTENSET_CH3LIMITL_Pos (13UL) /*!< Position of CH3LIMITL field. */ #define SAADC_INTENSET_CH3LIMITL_Msk (0x1UL << SAADC_INTENSET_CH3LIMITL_Pos) /*!< Bit mask of CH3LIMITL field. */ #define SAADC_INTENSET_CH3LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH3LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH3LIMITL_Set (1UL) /*!< Enable */ -/* Bit 12 : Write '1' to Enable interrupt on EVENTS_CH[3].LIMITH event */ +/* Bit 12 : Write '1' to Enable interrupt for CH[3].LIMITH event */ #define SAADC_INTENSET_CH3LIMITH_Pos (12UL) /*!< Position of CH3LIMITH field. */ #define SAADC_INTENSET_CH3LIMITH_Msk (0x1UL << SAADC_INTENSET_CH3LIMITH_Pos) /*!< Bit mask of CH3LIMITH field. */ #define SAADC_INTENSET_CH3LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH3LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH3LIMITH_Set (1UL) /*!< Enable */ -/* Bit 11 : Write '1' to Enable interrupt on EVENTS_CH[2].LIMITL event */ +/* Bit 11 : Write '1' to Enable interrupt for CH[2].LIMITL event */ #define SAADC_INTENSET_CH2LIMITL_Pos (11UL) /*!< Position of CH2LIMITL field. */ #define SAADC_INTENSET_CH2LIMITL_Msk (0x1UL << SAADC_INTENSET_CH2LIMITL_Pos) /*!< Bit mask of CH2LIMITL field. */ #define SAADC_INTENSET_CH2LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH2LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH2LIMITL_Set (1UL) /*!< Enable */ -/* Bit 10 : Write '1' to Enable interrupt on EVENTS_CH[2].LIMITH event */ +/* Bit 10 : Write '1' to Enable interrupt for CH[2].LIMITH event */ #define SAADC_INTENSET_CH2LIMITH_Pos (10UL) /*!< Position of CH2LIMITH field. */ #define SAADC_INTENSET_CH2LIMITH_Msk (0x1UL << SAADC_INTENSET_CH2LIMITH_Pos) /*!< Bit mask of CH2LIMITH field. */ #define SAADC_INTENSET_CH2LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH2LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH2LIMITH_Set (1UL) /*!< Enable */ -/* Bit 9 : Write '1' to Enable interrupt on EVENTS_CH[1].LIMITL event */ +/* Bit 9 : Write '1' to Enable interrupt for CH[1].LIMITL event */ #define SAADC_INTENSET_CH1LIMITL_Pos (9UL) /*!< Position of CH1LIMITL field. */ #define SAADC_INTENSET_CH1LIMITL_Msk (0x1UL << SAADC_INTENSET_CH1LIMITL_Pos) /*!< Bit mask of CH1LIMITL field. */ #define SAADC_INTENSET_CH1LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH1LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH1LIMITL_Set (1UL) /*!< Enable */ -/* Bit 8 : Write '1' to Enable interrupt on EVENTS_CH[1].LIMITH event */ +/* Bit 8 : Write '1' to Enable interrupt for CH[1].LIMITH event */ #define SAADC_INTENSET_CH1LIMITH_Pos (8UL) /*!< Position of CH1LIMITH field. */ #define SAADC_INTENSET_CH1LIMITH_Msk (0x1UL << SAADC_INTENSET_CH1LIMITH_Pos) /*!< Bit mask of CH1LIMITH field. */ #define SAADC_INTENSET_CH1LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH1LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH1LIMITH_Set (1UL) /*!< Enable */ -/* Bit 7 : Write '1' to Enable interrupt on EVENTS_CH[0].LIMITL event */ +/* Bit 7 : Write '1' to Enable interrupt for CH[0].LIMITL event */ #define SAADC_INTENSET_CH0LIMITL_Pos (7UL) /*!< Position of CH0LIMITL field. */ #define SAADC_INTENSET_CH0LIMITL_Msk (0x1UL << SAADC_INTENSET_CH0LIMITL_Pos) /*!< Bit mask of CH0LIMITL field. */ #define SAADC_INTENSET_CH0LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH0LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH0LIMITL_Set (1UL) /*!< Enable */ -/* Bit 6 : Write '1' to Enable interrupt on EVENTS_CH[0].LIMITH event */ +/* Bit 6 : Write '1' to Enable interrupt for CH[0].LIMITH event */ #define SAADC_INTENSET_CH0LIMITH_Pos (6UL) /*!< Position of CH0LIMITH field. */ #define SAADC_INTENSET_CH0LIMITH_Msk (0x1UL << SAADC_INTENSET_CH0LIMITH_Pos) /*!< Bit mask of CH0LIMITH field. */ #define SAADC_INTENSET_CH0LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CH0LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CH0LIMITH_Set (1UL) /*!< Enable */ -/* Bit 5 : Write '1' to Enable interrupt on EVENTS_STOPPED event */ +/* Bit 5 : Write '1' to Enable interrupt for STOPPED event */ #define SAADC_INTENSET_STOPPED_Pos (5UL) /*!< Position of STOPPED field. */ #define SAADC_INTENSET_STOPPED_Msk (0x1UL << SAADC_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define SAADC_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_STOPPED_Set (1UL) /*!< Enable */ -/* Bit 4 : Write '1' to Enable interrupt on EVENTS_CALIBRATEDONE event */ +/* Bit 4 : Write '1' to Enable interrupt for CALIBRATEDONE event */ #define SAADC_INTENSET_CALIBRATEDONE_Pos (4UL) /*!< Position of CALIBRATEDONE field. */ #define SAADC_INTENSET_CALIBRATEDONE_Msk (0x1UL << SAADC_INTENSET_CALIBRATEDONE_Pos) /*!< Bit mask of CALIBRATEDONE field. */ #define SAADC_INTENSET_CALIBRATEDONE_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_CALIBRATEDONE_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_CALIBRATEDONE_Set (1UL) /*!< Enable */ -/* Bit 3 : Write '1' to Enable interrupt on EVENTS_RESULTDONE event */ +/* Bit 3 : Write '1' to Enable interrupt for RESULTDONE event */ #define SAADC_INTENSET_RESULTDONE_Pos (3UL) /*!< Position of RESULTDONE field. */ #define SAADC_INTENSET_RESULTDONE_Msk (0x1UL << SAADC_INTENSET_RESULTDONE_Pos) /*!< Bit mask of RESULTDONE field. */ #define SAADC_INTENSET_RESULTDONE_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_RESULTDONE_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_RESULTDONE_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_DONE event */ +/* Bit 2 : Write '1' to Enable interrupt for DONE event */ #define SAADC_INTENSET_DONE_Pos (2UL) /*!< Position of DONE field. */ #define SAADC_INTENSET_DONE_Msk (0x1UL << SAADC_INTENSET_DONE_Pos) /*!< Bit mask of DONE field. */ #define SAADC_INTENSET_DONE_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_DONE_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_DONE_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_END event */ +/* Bit 1 : Write '1' to Enable interrupt for END event */ #define SAADC_INTENSET_END_Pos (1UL) /*!< Position of END field. */ #define SAADC_INTENSET_END_Msk (0x1UL << SAADC_INTENSET_END_Pos) /*!< Bit mask of END field. */ #define SAADC_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENSET_END_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_STARTED event */ +/* Bit 0 : Write '1' to Enable interrupt for STARTED event */ #define SAADC_INTENSET_STARTED_Pos (0UL) /*!< Position of STARTED field. */ #define SAADC_INTENSET_STARTED_Msk (0x1UL << SAADC_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ #define SAADC_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ @@ -9420,154 +9728,154 @@ /* Register: SAADC_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 21 : Write '1' to Clear interrupt on EVENTS_CH[7].LIMITL event */ +/* Bit 21 : Write '1' to Disable interrupt for CH[7].LIMITL event */ #define SAADC_INTENCLR_CH7LIMITL_Pos (21UL) /*!< Position of CH7LIMITL field. */ #define SAADC_INTENCLR_CH7LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH7LIMITL_Pos) /*!< Bit mask of CH7LIMITL field. */ #define SAADC_INTENCLR_CH7LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH7LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH7LIMITL_Clear (1UL) /*!< Disable */ -/* Bit 20 : Write '1' to Clear interrupt on EVENTS_CH[7].LIMITH event */ +/* Bit 20 : Write '1' to Disable interrupt for CH[7].LIMITH event */ #define SAADC_INTENCLR_CH7LIMITH_Pos (20UL) /*!< Position of CH7LIMITH field. */ #define SAADC_INTENCLR_CH7LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH7LIMITH_Pos) /*!< Bit mask of CH7LIMITH field. */ #define SAADC_INTENCLR_CH7LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH7LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH7LIMITH_Clear (1UL) /*!< Disable */ -/* Bit 19 : Write '1' to Clear interrupt on EVENTS_CH[6].LIMITL event */ +/* Bit 19 : Write '1' to Disable interrupt for CH[6].LIMITL event */ #define SAADC_INTENCLR_CH6LIMITL_Pos (19UL) /*!< Position of CH6LIMITL field. */ #define SAADC_INTENCLR_CH6LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH6LIMITL_Pos) /*!< Bit mask of CH6LIMITL field. */ #define SAADC_INTENCLR_CH6LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH6LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH6LIMITL_Clear (1UL) /*!< Disable */ -/* Bit 18 : Write '1' to Clear interrupt on EVENTS_CH[6].LIMITH event */ +/* Bit 18 : Write '1' to Disable interrupt for CH[6].LIMITH event */ #define SAADC_INTENCLR_CH6LIMITH_Pos (18UL) /*!< Position of CH6LIMITH field. */ #define SAADC_INTENCLR_CH6LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH6LIMITH_Pos) /*!< Bit mask of CH6LIMITH field. */ #define SAADC_INTENCLR_CH6LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH6LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH6LIMITH_Clear (1UL) /*!< Disable */ -/* Bit 17 : Write '1' to Clear interrupt on EVENTS_CH[5].LIMITL event */ +/* Bit 17 : Write '1' to Disable interrupt for CH[5].LIMITL event */ #define SAADC_INTENCLR_CH5LIMITL_Pos (17UL) /*!< Position of CH5LIMITL field. */ #define SAADC_INTENCLR_CH5LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH5LIMITL_Pos) /*!< Bit mask of CH5LIMITL field. */ #define SAADC_INTENCLR_CH5LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH5LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH5LIMITL_Clear (1UL) /*!< Disable */ -/* Bit 16 : Write '1' to Clear interrupt on EVENTS_CH[5].LIMITH event */ +/* Bit 16 : Write '1' to Disable interrupt for CH[5].LIMITH event */ #define SAADC_INTENCLR_CH5LIMITH_Pos (16UL) /*!< Position of CH5LIMITH field. */ #define SAADC_INTENCLR_CH5LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH5LIMITH_Pos) /*!< Bit mask of CH5LIMITH field. */ #define SAADC_INTENCLR_CH5LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH5LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH5LIMITH_Clear (1UL) /*!< Disable */ -/* Bit 15 : Write '1' to Clear interrupt on EVENTS_CH[4].LIMITL event */ +/* Bit 15 : Write '1' to Disable interrupt for CH[4].LIMITL event */ #define SAADC_INTENCLR_CH4LIMITL_Pos (15UL) /*!< Position of CH4LIMITL field. */ #define SAADC_INTENCLR_CH4LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH4LIMITL_Pos) /*!< Bit mask of CH4LIMITL field. */ #define SAADC_INTENCLR_CH4LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH4LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH4LIMITL_Clear (1UL) /*!< Disable */ -/* Bit 14 : Write '1' to Clear interrupt on EVENTS_CH[4].LIMITH event */ +/* Bit 14 : Write '1' to Disable interrupt for CH[4].LIMITH event */ #define SAADC_INTENCLR_CH4LIMITH_Pos (14UL) /*!< Position of CH4LIMITH field. */ #define SAADC_INTENCLR_CH4LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH4LIMITH_Pos) /*!< Bit mask of CH4LIMITH field. */ #define SAADC_INTENCLR_CH4LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH4LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH4LIMITH_Clear (1UL) /*!< Disable */ -/* Bit 13 : Write '1' to Clear interrupt on EVENTS_CH[3].LIMITL event */ +/* Bit 13 : Write '1' to Disable interrupt for CH[3].LIMITL event */ #define SAADC_INTENCLR_CH3LIMITL_Pos (13UL) /*!< Position of CH3LIMITL field. */ #define SAADC_INTENCLR_CH3LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH3LIMITL_Pos) /*!< Bit mask of CH3LIMITL field. */ #define SAADC_INTENCLR_CH3LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH3LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH3LIMITL_Clear (1UL) /*!< Disable */ -/* Bit 12 : Write '1' to Clear interrupt on EVENTS_CH[3].LIMITH event */ +/* Bit 12 : Write '1' to Disable interrupt for CH[3].LIMITH event */ #define SAADC_INTENCLR_CH3LIMITH_Pos (12UL) /*!< Position of CH3LIMITH field. */ #define SAADC_INTENCLR_CH3LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH3LIMITH_Pos) /*!< Bit mask of CH3LIMITH field. */ #define SAADC_INTENCLR_CH3LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH3LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH3LIMITH_Clear (1UL) /*!< Disable */ -/* Bit 11 : Write '1' to Clear interrupt on EVENTS_CH[2].LIMITL event */ +/* Bit 11 : Write '1' to Disable interrupt for CH[2].LIMITL event */ #define SAADC_INTENCLR_CH2LIMITL_Pos (11UL) /*!< Position of CH2LIMITL field. */ #define SAADC_INTENCLR_CH2LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH2LIMITL_Pos) /*!< Bit mask of CH2LIMITL field. */ #define SAADC_INTENCLR_CH2LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH2LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH2LIMITL_Clear (1UL) /*!< Disable */ -/* Bit 10 : Write '1' to Clear interrupt on EVENTS_CH[2].LIMITH event */ +/* Bit 10 : Write '1' to Disable interrupt for CH[2].LIMITH event */ #define SAADC_INTENCLR_CH2LIMITH_Pos (10UL) /*!< Position of CH2LIMITH field. */ #define SAADC_INTENCLR_CH2LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH2LIMITH_Pos) /*!< Bit mask of CH2LIMITH field. */ #define SAADC_INTENCLR_CH2LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH2LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH2LIMITH_Clear (1UL) /*!< Disable */ -/* Bit 9 : Write '1' to Clear interrupt on EVENTS_CH[1].LIMITL event */ +/* Bit 9 : Write '1' to Disable interrupt for CH[1].LIMITL event */ #define SAADC_INTENCLR_CH1LIMITL_Pos (9UL) /*!< Position of CH1LIMITL field. */ #define SAADC_INTENCLR_CH1LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH1LIMITL_Pos) /*!< Bit mask of CH1LIMITL field. */ #define SAADC_INTENCLR_CH1LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH1LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH1LIMITL_Clear (1UL) /*!< Disable */ -/* Bit 8 : Write '1' to Clear interrupt on EVENTS_CH[1].LIMITH event */ +/* Bit 8 : Write '1' to Disable interrupt for CH[1].LIMITH event */ #define SAADC_INTENCLR_CH1LIMITH_Pos (8UL) /*!< Position of CH1LIMITH field. */ #define SAADC_INTENCLR_CH1LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH1LIMITH_Pos) /*!< Bit mask of CH1LIMITH field. */ #define SAADC_INTENCLR_CH1LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH1LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH1LIMITH_Clear (1UL) /*!< Disable */ -/* Bit 7 : Write '1' to Clear interrupt on EVENTS_CH[0].LIMITL event */ +/* Bit 7 : Write '1' to Disable interrupt for CH[0].LIMITL event */ #define SAADC_INTENCLR_CH0LIMITL_Pos (7UL) /*!< Position of CH0LIMITL field. */ #define SAADC_INTENCLR_CH0LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH0LIMITL_Pos) /*!< Bit mask of CH0LIMITL field. */ #define SAADC_INTENCLR_CH0LIMITL_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH0LIMITL_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH0LIMITL_Clear (1UL) /*!< Disable */ -/* Bit 6 : Write '1' to Clear interrupt on EVENTS_CH[0].LIMITH event */ +/* Bit 6 : Write '1' to Disable interrupt for CH[0].LIMITH event */ #define SAADC_INTENCLR_CH0LIMITH_Pos (6UL) /*!< Position of CH0LIMITH field. */ #define SAADC_INTENCLR_CH0LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH0LIMITH_Pos) /*!< Bit mask of CH0LIMITH field. */ #define SAADC_INTENCLR_CH0LIMITH_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CH0LIMITH_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CH0LIMITH_Clear (1UL) /*!< Disable */ -/* Bit 5 : Write '1' to Clear interrupt on EVENTS_STOPPED event */ +/* Bit 5 : Write '1' to Disable interrupt for STOPPED event */ #define SAADC_INTENCLR_STOPPED_Pos (5UL) /*!< Position of STOPPED field. */ #define SAADC_INTENCLR_STOPPED_Msk (0x1UL << SAADC_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define SAADC_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ -/* Bit 4 : Write '1' to Clear interrupt on EVENTS_CALIBRATEDONE event */ +/* Bit 4 : Write '1' to Disable interrupt for CALIBRATEDONE event */ #define SAADC_INTENCLR_CALIBRATEDONE_Pos (4UL) /*!< Position of CALIBRATEDONE field. */ #define SAADC_INTENCLR_CALIBRATEDONE_Msk (0x1UL << SAADC_INTENCLR_CALIBRATEDONE_Pos) /*!< Bit mask of CALIBRATEDONE field. */ #define SAADC_INTENCLR_CALIBRATEDONE_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_CALIBRATEDONE_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_CALIBRATEDONE_Clear (1UL) /*!< Disable */ -/* Bit 3 : Write '1' to Clear interrupt on EVENTS_RESULTDONE event */ +/* Bit 3 : Write '1' to Disable interrupt for RESULTDONE event */ #define SAADC_INTENCLR_RESULTDONE_Pos (3UL) /*!< Position of RESULTDONE field. */ #define SAADC_INTENCLR_RESULTDONE_Msk (0x1UL << SAADC_INTENCLR_RESULTDONE_Pos) /*!< Bit mask of RESULTDONE field. */ #define SAADC_INTENCLR_RESULTDONE_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_RESULTDONE_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_RESULTDONE_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_DONE event */ +/* Bit 2 : Write '1' to Disable interrupt for DONE event */ #define SAADC_INTENCLR_DONE_Pos (2UL) /*!< Position of DONE field. */ #define SAADC_INTENCLR_DONE_Msk (0x1UL << SAADC_INTENCLR_DONE_Pos) /*!< Bit mask of DONE field. */ #define SAADC_INTENCLR_DONE_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_DONE_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_DONE_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_END event */ +/* Bit 1 : Write '1' to Disable interrupt for END event */ #define SAADC_INTENCLR_END_Pos (1UL) /*!< Position of END field. */ #define SAADC_INTENCLR_END_Msk (0x1UL << SAADC_INTENCLR_END_Pos) /*!< Bit mask of END field. */ #define SAADC_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ #define SAADC_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ #define SAADC_INTENCLR_END_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_STARTED event */ +/* Bit 0 : Write '1' to Disable interrupt for STARTED event */ #define SAADC_INTENCLR_STARTED_Pos (0UL) /*!< Position of STARTED field. */ #define SAADC_INTENCLR_STARTED_Msk (0x1UL << SAADC_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ #define SAADC_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ @@ -9629,6 +9937,12 @@ /* Register: SAADC_CH_CONFIG */ /* Description: Description cluster[0]: Input configuration for CH[0] */ +/* Bit 24 : Enable burst mode */ +#define SAADC_CH_CONFIG_BURST_Pos (24UL) /*!< Position of BURST field. */ +#define SAADC_CH_CONFIG_BURST_Msk (0x1UL << SAADC_CH_CONFIG_BURST_Pos) /*!< Bit mask of BURST field. */ +#define SAADC_CH_CONFIG_BURST_Disabled (0UL) /*!< Burst mode is disabled (normal operation) */ +#define SAADC_CH_CONFIG_BURST_Enabled (1UL) /*!< Burst mode is enabled. SAADC takes 2^OVERSAMPLE number of samples as fast as it can, and sends the average to Data RAM. */ + /* Bit 20 : Enable differential mode */ #define SAADC_CH_CONFIG_MODE_Pos (20UL) /*!< Position of MODE field. */ #define SAADC_CH_CONFIG_MODE_Msk (0x1UL << SAADC_CH_CONFIG_MODE_Pos) /*!< Bit mask of MODE field. */ @@ -9740,16 +10054,16 @@ /* Register: SAADC_RESULT_MAXCNT */ /* Description: Maximum number of buffer words to transfer */ -/* Bits 15..0 : Maximum number of buffer words to transfer */ +/* Bits 14..0 : Maximum number of buffer words to transfer */ #define SAADC_RESULT_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ -#define SAADC_RESULT_MAXCNT_MAXCNT_Msk (0xFFFFUL << SAADC_RESULT_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ +#define SAADC_RESULT_MAXCNT_MAXCNT_Msk (0x7FFFUL << SAADC_RESULT_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ /* Register: SAADC_RESULT_AMOUNT */ /* Description: Number of buffer words transferred since last START */ -/* Bits 15..0 : Number of buffer words transferred since last START. This register can be read after an END or STOPPED event. */ +/* Bits 14..0 : Number of buffer words transferred since last START. This register can be read after an END or STOPPED event. */ #define SAADC_RESULT_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ -#define SAADC_RESULT_AMOUNT_AMOUNT_Msk (0xFFFFUL << SAADC_RESULT_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ +#define SAADC_RESULT_AMOUNT_AMOUNT_Msk (0x7FFFUL << SAADC_RESULT_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ /* Peripheral: SPI */ @@ -9758,7 +10072,7 @@ /* Register: SPI_INTENSET */ /* Description: Enable interrupt */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_READY event */ +/* Bit 2 : Write '1' to Enable interrupt for READY event */ #define SPI_INTENSET_READY_Pos (2UL) /*!< Position of READY field. */ #define SPI_INTENSET_READY_Msk (0x1UL << SPI_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ #define SPI_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ @@ -9768,7 +10082,7 @@ /* Register: SPI_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_READY event */ +/* Bit 2 : Write '1' to Disable interrupt for READY event */ #define SPI_INTENCLR_READY_Pos (2UL) /*!< Position of READY field. */ #define SPI_INTENCLR_READY_Msk (0x1UL << SPI_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ #define SPI_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ @@ -9864,7 +10178,7 @@ /* Register: SPIM_SHORTS */ /* Description: Shortcut register */ -/* Bit 17 : Shortcut between EVENTS_END event and TASKS_START task */ +/* Bit 17 : Shortcut between END event and START task */ #define SPIM_SHORTS_END_START_Pos (17UL) /*!< Position of END_START field. */ #define SPIM_SHORTS_END_START_Msk (0x1UL << SPIM_SHORTS_END_START_Pos) /*!< Bit mask of END_START field. */ #define SPIM_SHORTS_END_START_Disabled (0UL) /*!< Disable shortcut */ @@ -9873,35 +10187,35 @@ /* Register: SPIM_INTENSET */ /* Description: Enable interrupt */ -/* Bit 19 : Write '1' to Enable interrupt on EVENTS_STARTED event */ +/* Bit 19 : Write '1' to Enable interrupt for STARTED event */ #define SPIM_INTENSET_STARTED_Pos (19UL) /*!< Position of STARTED field. */ #define SPIM_INTENSET_STARTED_Msk (0x1UL << SPIM_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ #define SPIM_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ #define SPIM_INTENSET_STARTED_Enabled (1UL) /*!< Read: Enabled */ #define SPIM_INTENSET_STARTED_Set (1UL) /*!< Enable */ -/* Bit 8 : Write '1' to Enable interrupt on EVENTS_ENDTX event */ +/* Bit 8 : Write '1' to Enable interrupt for ENDTX event */ #define SPIM_INTENSET_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ #define SPIM_INTENSET_ENDTX_Msk (0x1UL << SPIM_INTENSET_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ #define SPIM_INTENSET_ENDTX_Disabled (0UL) /*!< Read: Disabled */ #define SPIM_INTENSET_ENDTX_Enabled (1UL) /*!< Read: Enabled */ #define SPIM_INTENSET_ENDTX_Set (1UL) /*!< Enable */ -/* Bit 6 : Write '1' to Enable interrupt on EVENTS_END event */ +/* Bit 6 : Write '1' to Enable interrupt for END event */ #define SPIM_INTENSET_END_Pos (6UL) /*!< Position of END field. */ #define SPIM_INTENSET_END_Msk (0x1UL << SPIM_INTENSET_END_Pos) /*!< Bit mask of END field. */ #define SPIM_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ #define SPIM_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ #define SPIM_INTENSET_END_Set (1UL) /*!< Enable */ -/* Bit 4 : Write '1' to Enable interrupt on EVENTS_ENDRX event */ +/* Bit 4 : Write '1' to Enable interrupt for ENDRX event */ #define SPIM_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ #define SPIM_INTENSET_ENDRX_Msk (0x1UL << SPIM_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ #define SPIM_INTENSET_ENDRX_Disabled (0UL) /*!< Read: Disabled */ #define SPIM_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */ #define SPIM_INTENSET_ENDRX_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ #define SPIM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define SPIM_INTENSET_STOPPED_Msk (0x1UL << SPIM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define SPIM_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ @@ -9911,35 +10225,35 @@ /* Register: SPIM_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 19 : Write '1' to Clear interrupt on EVENTS_STARTED event */ +/* Bit 19 : Write '1' to Disable interrupt for STARTED event */ #define SPIM_INTENCLR_STARTED_Pos (19UL) /*!< Position of STARTED field. */ #define SPIM_INTENCLR_STARTED_Msk (0x1UL << SPIM_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ #define SPIM_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ #define SPIM_INTENCLR_STARTED_Enabled (1UL) /*!< Read: Enabled */ #define SPIM_INTENCLR_STARTED_Clear (1UL) /*!< Disable */ -/* Bit 8 : Write '1' to Clear interrupt on EVENTS_ENDTX event */ +/* Bit 8 : Write '1' to Disable interrupt for ENDTX event */ #define SPIM_INTENCLR_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ #define SPIM_INTENCLR_ENDTX_Msk (0x1UL << SPIM_INTENCLR_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ #define SPIM_INTENCLR_ENDTX_Disabled (0UL) /*!< Read: Disabled */ #define SPIM_INTENCLR_ENDTX_Enabled (1UL) /*!< Read: Enabled */ #define SPIM_INTENCLR_ENDTX_Clear (1UL) /*!< Disable */ -/* Bit 6 : Write '1' to Clear interrupt on EVENTS_END event */ +/* Bit 6 : Write '1' to Disable interrupt for END event */ #define SPIM_INTENCLR_END_Pos (6UL) /*!< Position of END field. */ #define SPIM_INTENCLR_END_Msk (0x1UL << SPIM_INTENCLR_END_Pos) /*!< Bit mask of END field. */ #define SPIM_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ #define SPIM_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ #define SPIM_INTENCLR_END_Clear (1UL) /*!< Disable */ -/* Bit 4 : Write '1' to Clear interrupt on EVENTS_ENDRX event */ +/* Bit 4 : Write '1' to Disable interrupt for ENDRX event */ #define SPIM_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ #define SPIM_INTENCLR_ENDRX_Msk (0x1UL << SPIM_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ #define SPIM_INTENCLR_ENDRX_Disabled (0UL) /*!< Read: Disabled */ #define SPIM_INTENCLR_ENDRX_Enabled (1UL) /*!< Read: Enabled */ #define SPIM_INTENCLR_ENDRX_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ #define SPIM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define SPIM_INTENCLR_STOPPED_Msk (0x1UL << SPIM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define SPIM_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ @@ -10016,9 +10330,9 @@ #define SPIM_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIM_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ /* Register: SPIM_RXD_MAXCNT */ -/* Description: Maximum number of buffer words to transfer */ +/* Description: Maximum number of bytes in receive buffer */ -/* Bits 7..0 : Maximum number of buffer words to transfer */ +/* Bits 7..0 : Maximum number of bytes in receive buffer */ #define SPIM_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ #define SPIM_RXD_MAXCNT_MAXCNT_Msk (0xFFUL << SPIM_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ @@ -10046,9 +10360,9 @@ #define SPIM_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIM_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ /* Register: SPIM_TXD_MAXCNT */ -/* Description: Maximum number of buffer words to transfer */ +/* Description: Maximum number of bytes in transmit buffer */ -/* Bits 7..0 : Maximum number of buffer words to transfer */ +/* Bits 7..0 : Maximum number of bytes in transmit buffer */ #define SPIM_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ #define SPIM_TXD_MAXCNT_MAXCNT_Msk (0xFFUL << SPIM_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ @@ -10103,7 +10417,7 @@ /* Register: SPIS_SHORTS */ /* Description: Shortcut register */ -/* Bit 2 : Shortcut between EVENTS_END event and TASKS_ACQUIRE task */ +/* Bit 2 : Shortcut between END event and ACQUIRE task */ #define SPIS_SHORTS_END_ACQUIRE_Pos (2UL) /*!< Position of END_ACQUIRE field. */ #define SPIS_SHORTS_END_ACQUIRE_Msk (0x1UL << SPIS_SHORTS_END_ACQUIRE_Pos) /*!< Bit mask of END_ACQUIRE field. */ #define SPIS_SHORTS_END_ACQUIRE_Disabled (0UL) /*!< Disable shortcut */ @@ -10112,14 +10426,21 @@ /* Register: SPIS_INTENSET */ /* Description: Enable interrupt */ -/* Bit 10 : Write '1' to Enable interrupt on EVENTS_ACQUIRED event */ +/* Bit 10 : Write '1' to Enable interrupt for ACQUIRED event */ #define SPIS_INTENSET_ACQUIRED_Pos (10UL) /*!< Position of ACQUIRED field. */ #define SPIS_INTENSET_ACQUIRED_Msk (0x1UL << SPIS_INTENSET_ACQUIRED_Pos) /*!< Bit mask of ACQUIRED field. */ #define SPIS_INTENSET_ACQUIRED_Disabled (0UL) /*!< Read: Disabled */ #define SPIS_INTENSET_ACQUIRED_Enabled (1UL) /*!< Read: Enabled */ #define SPIS_INTENSET_ACQUIRED_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_END event */ +/* Bit 4 : Write '1' to Enable interrupt for ENDRX event */ +#define SPIS_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define SPIS_INTENSET_ENDRX_Msk (0x1UL << SPIS_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define SPIS_INTENSET_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENSET_ENDRX_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for END event */ #define SPIS_INTENSET_END_Pos (1UL) /*!< Position of END field. */ #define SPIS_INTENSET_END_Msk (0x1UL << SPIS_INTENSET_END_Pos) /*!< Bit mask of END field. */ #define SPIS_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ @@ -10129,14 +10450,21 @@ /* Register: SPIS_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 10 : Write '1' to Clear interrupt on EVENTS_ACQUIRED event */ +/* Bit 10 : Write '1' to Disable interrupt for ACQUIRED event */ #define SPIS_INTENCLR_ACQUIRED_Pos (10UL) /*!< Position of ACQUIRED field. */ #define SPIS_INTENCLR_ACQUIRED_Msk (0x1UL << SPIS_INTENCLR_ACQUIRED_Pos) /*!< Bit mask of ACQUIRED field. */ #define SPIS_INTENCLR_ACQUIRED_Disabled (0UL) /*!< Read: Disabled */ #define SPIS_INTENCLR_ACQUIRED_Enabled (1UL) /*!< Read: Enabled */ #define SPIS_INTENCLR_ACQUIRED_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_END event */ +/* Bit 4 : Write '1' to Disable interrupt for ENDRX event */ +#define SPIS_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define SPIS_INTENCLR_ENDRX_Msk (0x1UL << SPIS_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define SPIS_INTENCLR_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENCLR_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENCLR_ENDRX_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for END event */ #define SPIS_INTENCLR_END_Pos (1UL) /*!< Position of END field. */ #define SPIS_INTENCLR_END_Msk (0x1UL << SPIS_INTENCLR_END_Pos) /*!< Bit mask of END field. */ #define SPIS_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ @@ -10316,7 +10644,7 @@ /* Register: TEMP_INTENSET */ /* Description: Enable interrupt */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_DATARDY event */ +/* Bit 0 : Write '1' to Enable interrupt for DATARDY event */ #define TEMP_INTENSET_DATARDY_Pos (0UL) /*!< Position of DATARDY field. */ #define TEMP_INTENSET_DATARDY_Msk (0x1UL << TEMP_INTENSET_DATARDY_Pos) /*!< Bit mask of DATARDY field. */ #define TEMP_INTENSET_DATARDY_Disabled (0UL) /*!< Read: Disabled */ @@ -10326,7 +10654,7 @@ /* Register: TEMP_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_DATARDY event */ +/* Bit 0 : Write '1' to Disable interrupt for DATARDY event */ #define TEMP_INTENCLR_DATARDY_Pos (0UL) /*!< Position of DATARDY field. */ #define TEMP_INTENCLR_DATARDY_Msk (0x1UL << TEMP_INTENCLR_DATARDY_Pos) /*!< Bit mask of DATARDY field. */ #define TEMP_INTENCLR_DATARDY_Disabled (0UL) /*!< Read: Disabled */ @@ -10334,12 +10662,131 @@ #define TEMP_INTENCLR_DATARDY_Clear (1UL) /*!< Disable */ /* Register: TEMP_TEMP */ -/* Description: Temperature in degC */ +/* Description: Temperature in degC (0.25deg steps) */ -/* Bits 31..0 : Temperature in degC */ +/* Bits 31..0 : Temperature in degC (0.25deg steps) */ #define TEMP_TEMP_TEMP_Pos (0UL) /*!< Position of TEMP field. */ #define TEMP_TEMP_TEMP_Msk (0xFFFFFFFFUL << TEMP_TEMP_TEMP_Pos) /*!< Bit mask of TEMP field. */ +/* Register: TEMP_A0 */ +/* Description: Slope of 1st piece wise linear function */ + +/* Bits 11..0 : Slope of 1st piece wise linear function */ +#define TEMP_A0_A0_Pos (0UL) /*!< Position of A0 field. */ +#define TEMP_A0_A0_Msk (0xFFFUL << TEMP_A0_A0_Pos) /*!< Bit mask of A0 field. */ + +/* Register: TEMP_A1 */ +/* Description: Slope of 2nd piece wise linear function */ + +/* Bits 11..0 : Slope of 2nd piece wise linear function */ +#define TEMP_A1_A1_Pos (0UL) /*!< Position of A1 field. */ +#define TEMP_A1_A1_Msk (0xFFFUL << TEMP_A1_A1_Pos) /*!< Bit mask of A1 field. */ + +/* Register: TEMP_A2 */ +/* Description: Slope of 3rd piece wise linear function */ + +/* Bits 11..0 : Slope of 3rd piece wise linear function */ +#define TEMP_A2_A2_Pos (0UL) /*!< Position of A2 field. */ +#define TEMP_A2_A2_Msk (0xFFFUL << TEMP_A2_A2_Pos) /*!< Bit mask of A2 field. */ + +/* Register: TEMP_A3 */ +/* Description: Slope of 4th piece wise linear function */ + +/* Bits 11..0 : Slope of 4th piece wise linear function */ +#define TEMP_A3_A3_Pos (0UL) /*!< Position of A3 field. */ +#define TEMP_A3_A3_Msk (0xFFFUL << TEMP_A3_A3_Pos) /*!< Bit mask of A3 field. */ + +/* Register: TEMP_A4 */ +/* Description: Slope of 5th piece wise linear function */ + +/* Bits 11..0 : Slope of 5th piece wise linear function */ +#define TEMP_A4_A4_Pos (0UL) /*!< Position of A4 field. */ +#define TEMP_A4_A4_Msk (0xFFFUL << TEMP_A4_A4_Pos) /*!< Bit mask of A4 field. */ + +/* Register: TEMP_A5 */ +/* Description: Slope of 6th piece wise linear function */ + +/* Bits 11..0 : Slope of 6th piece wise linear function */ +#define TEMP_A5_A5_Pos (0UL) /*!< Position of A5 field. */ +#define TEMP_A5_A5_Msk (0xFFFUL << TEMP_A5_A5_Pos) /*!< Bit mask of A5 field. */ + +/* Register: TEMP_B0 */ +/* Description: y-intercept of 1st piece wise linear function */ + +/* Bits 13..0 : y-intercept of 1st piece wise linear function */ +#define TEMP_B0_B0_Pos (0UL) /*!< Position of B0 field. */ +#define TEMP_B0_B0_Msk (0x3FFFUL << TEMP_B0_B0_Pos) /*!< Bit mask of B0 field. */ + +/* Register: TEMP_B1 */ +/* Description: y-intercept of 2nd piece wise linear function */ + +/* Bits 13..0 : y-intercept of 2nd piece wise linear function */ +#define TEMP_B1_B1_Pos (0UL) /*!< Position of B1 field. */ +#define TEMP_B1_B1_Msk (0x3FFFUL << TEMP_B1_B1_Pos) /*!< Bit mask of B1 field. */ + +/* Register: TEMP_B2 */ +/* Description: y-intercept of 3rd piece wise linear function */ + +/* Bits 13..0 : y-intercept of 3rd piece wise linear function */ +#define TEMP_B2_B2_Pos (0UL) /*!< Position of B2 field. */ +#define TEMP_B2_B2_Msk (0x3FFFUL << TEMP_B2_B2_Pos) /*!< Bit mask of B2 field. */ + +/* Register: TEMP_B3 */ +/* Description: y-intercept of 4th piece wise linear function */ + +/* Bits 13..0 : y-intercept of 4th piece wise linear function */ +#define TEMP_B3_B3_Pos (0UL) /*!< Position of B3 field. */ +#define TEMP_B3_B3_Msk (0x3FFFUL << TEMP_B3_B3_Pos) /*!< Bit mask of B3 field. */ + +/* Register: TEMP_B4 */ +/* Description: y-intercept of 5th piece wise linear function */ + +/* Bits 13..0 : y-intercept of 5th piece wise linear function */ +#define TEMP_B4_B4_Pos (0UL) /*!< Position of B4 field. */ +#define TEMP_B4_B4_Msk (0x3FFFUL << TEMP_B4_B4_Pos) /*!< Bit mask of B4 field. */ + +/* Register: TEMP_B5 */ +/* Description: y-intercept of 6th piece wise linear function */ + +/* Bits 13..0 : y-intercept of 6th piece wise linear function */ +#define TEMP_B5_B5_Pos (0UL) /*!< Position of B5 field. */ +#define TEMP_B5_B5_Msk (0x3FFFUL << TEMP_B5_B5_Pos) /*!< Bit mask of B5 field. */ + +/* Register: TEMP_T0 */ +/* Description: End point of 1st piece wise linear function */ + +/* Bits 7..0 : End point of 1st piece wise linear function */ +#define TEMP_T0_T0_Pos (0UL) /*!< Position of T0 field. */ +#define TEMP_T0_T0_Msk (0xFFUL << TEMP_T0_T0_Pos) /*!< Bit mask of T0 field. */ + +/* Register: TEMP_T1 */ +/* Description: End point of 2nd piece wise linear function */ + +/* Bits 7..0 : End point of 2nd piece wise linear function */ +#define TEMP_T1_T1_Pos (0UL) /*!< Position of T1 field. */ +#define TEMP_T1_T1_Msk (0xFFUL << TEMP_T1_T1_Pos) /*!< Bit mask of T1 field. */ + +/* Register: TEMP_T2 */ +/* Description: End point of 3rd piece wise linear function */ + +/* Bits 7..0 : End point of 3rd piece wise linear function */ +#define TEMP_T2_T2_Pos (0UL) /*!< Position of T2 field. */ +#define TEMP_T2_T2_Msk (0xFFUL << TEMP_T2_T2_Pos) /*!< Bit mask of T2 field. */ + +/* Register: TEMP_T3 */ +/* Description: End point of 4th piece wise linear function */ + +/* Bits 7..0 : End point of 4th piece wise linear function */ +#define TEMP_T3_T3_Pos (0UL) /*!< Position of T3 field. */ +#define TEMP_T3_T3_Msk (0xFFUL << TEMP_T3_T3_Pos) /*!< Bit mask of T3 field. */ + +/* Register: TEMP_T4 */ +/* Description: End point of 5th piece wise linear function */ + +/* Bits 7..0 : End point of 5th piece wise linear function */ +#define TEMP_T4_T4_Pos (0UL) /*!< Position of T4 field. */ +#define TEMP_T4_T4_Msk (0xFFUL << TEMP_T4_T4_Pos) /*!< Bit mask of T4 field. */ + /* Peripheral: TIMER */ /* Description: Timer/Counter 0 */ @@ -10347,73 +10794,73 @@ /* Register: TIMER_SHORTS */ /* Description: Shortcut register */ -/* Bit 13 : Shortcut between EVENTS_COMPARE[5] event and TASKS_STOP task */ +/* Bit 13 : Shortcut between COMPARE[5] event and STOP task */ #define TIMER_SHORTS_COMPARE5_STOP_Pos (13UL) /*!< Position of COMPARE5_STOP field. */ #define TIMER_SHORTS_COMPARE5_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE5_STOP_Pos) /*!< Bit mask of COMPARE5_STOP field. */ #define TIMER_SHORTS_COMPARE5_STOP_Disabled (0UL) /*!< Disable shortcut */ #define TIMER_SHORTS_COMPARE5_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 12 : Shortcut between EVENTS_COMPARE[4] event and TASKS_STOP task */ +/* Bit 12 : Shortcut between COMPARE[4] event and STOP task */ #define TIMER_SHORTS_COMPARE4_STOP_Pos (12UL) /*!< Position of COMPARE4_STOP field. */ #define TIMER_SHORTS_COMPARE4_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE4_STOP_Pos) /*!< Bit mask of COMPARE4_STOP field. */ #define TIMER_SHORTS_COMPARE4_STOP_Disabled (0UL) /*!< Disable shortcut */ #define TIMER_SHORTS_COMPARE4_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 11 : Shortcut between EVENTS_COMPARE[3] event and TASKS_STOP task */ +/* Bit 11 : Shortcut between COMPARE[3] event and STOP task */ #define TIMER_SHORTS_COMPARE3_STOP_Pos (11UL) /*!< Position of COMPARE3_STOP field. */ #define TIMER_SHORTS_COMPARE3_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE3_STOP_Pos) /*!< Bit mask of COMPARE3_STOP field. */ #define TIMER_SHORTS_COMPARE3_STOP_Disabled (0UL) /*!< Disable shortcut */ #define TIMER_SHORTS_COMPARE3_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 10 : Shortcut between EVENTS_COMPARE[2] event and TASKS_STOP task */ +/* Bit 10 : Shortcut between COMPARE[2] event and STOP task */ #define TIMER_SHORTS_COMPARE2_STOP_Pos (10UL) /*!< Position of COMPARE2_STOP field. */ #define TIMER_SHORTS_COMPARE2_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE2_STOP_Pos) /*!< Bit mask of COMPARE2_STOP field. */ #define TIMER_SHORTS_COMPARE2_STOP_Disabled (0UL) /*!< Disable shortcut */ #define TIMER_SHORTS_COMPARE2_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 9 : Shortcut between EVENTS_COMPARE[1] event and TASKS_STOP task */ +/* Bit 9 : Shortcut between COMPARE[1] event and STOP task */ #define TIMER_SHORTS_COMPARE1_STOP_Pos (9UL) /*!< Position of COMPARE1_STOP field. */ #define TIMER_SHORTS_COMPARE1_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE1_STOP_Pos) /*!< Bit mask of COMPARE1_STOP field. */ #define TIMER_SHORTS_COMPARE1_STOP_Disabled (0UL) /*!< Disable shortcut */ #define TIMER_SHORTS_COMPARE1_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 8 : Shortcut between EVENTS_COMPARE[0] event and TASKS_STOP task */ +/* Bit 8 : Shortcut between COMPARE[0] event and STOP task */ #define TIMER_SHORTS_COMPARE0_STOP_Pos (8UL) /*!< Position of COMPARE0_STOP field. */ #define TIMER_SHORTS_COMPARE0_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE0_STOP_Pos) /*!< Bit mask of COMPARE0_STOP field. */ #define TIMER_SHORTS_COMPARE0_STOP_Disabled (0UL) /*!< Disable shortcut */ #define TIMER_SHORTS_COMPARE0_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 5 : Shortcut between EVENTS_COMPARE[5] event and TASKS_CLEAR task */ +/* Bit 5 : Shortcut between COMPARE[5] event and CLEAR task */ #define TIMER_SHORTS_COMPARE5_CLEAR_Pos (5UL) /*!< Position of COMPARE5_CLEAR field. */ #define TIMER_SHORTS_COMPARE5_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE5_CLEAR_Pos) /*!< Bit mask of COMPARE5_CLEAR field. */ #define TIMER_SHORTS_COMPARE5_CLEAR_Disabled (0UL) /*!< Disable shortcut */ #define TIMER_SHORTS_COMPARE5_CLEAR_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 4 : Shortcut between EVENTS_COMPARE[4] event and TASKS_CLEAR task */ +/* Bit 4 : Shortcut between COMPARE[4] event and CLEAR task */ #define TIMER_SHORTS_COMPARE4_CLEAR_Pos (4UL) /*!< Position of COMPARE4_CLEAR field. */ #define TIMER_SHORTS_COMPARE4_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE4_CLEAR_Pos) /*!< Bit mask of COMPARE4_CLEAR field. */ #define TIMER_SHORTS_COMPARE4_CLEAR_Disabled (0UL) /*!< Disable shortcut */ #define TIMER_SHORTS_COMPARE4_CLEAR_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 3 : Shortcut between EVENTS_COMPARE[3] event and TASKS_CLEAR task */ +/* Bit 3 : Shortcut between COMPARE[3] event and CLEAR task */ #define TIMER_SHORTS_COMPARE3_CLEAR_Pos (3UL) /*!< Position of COMPARE3_CLEAR field. */ #define TIMER_SHORTS_COMPARE3_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE3_CLEAR_Pos) /*!< Bit mask of COMPARE3_CLEAR field. */ #define TIMER_SHORTS_COMPARE3_CLEAR_Disabled (0UL) /*!< Disable shortcut */ #define TIMER_SHORTS_COMPARE3_CLEAR_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 2 : Shortcut between EVENTS_COMPARE[2] event and TASKS_CLEAR task */ +/* Bit 2 : Shortcut between COMPARE[2] event and CLEAR task */ #define TIMER_SHORTS_COMPARE2_CLEAR_Pos (2UL) /*!< Position of COMPARE2_CLEAR field. */ #define TIMER_SHORTS_COMPARE2_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE2_CLEAR_Pos) /*!< Bit mask of COMPARE2_CLEAR field. */ #define TIMER_SHORTS_COMPARE2_CLEAR_Disabled (0UL) /*!< Disable shortcut */ #define TIMER_SHORTS_COMPARE2_CLEAR_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 1 : Shortcut between EVENTS_COMPARE[1] event and TASKS_CLEAR task */ +/* Bit 1 : Shortcut between COMPARE[1] event and CLEAR task */ #define TIMER_SHORTS_COMPARE1_CLEAR_Pos (1UL) /*!< Position of COMPARE1_CLEAR field. */ #define TIMER_SHORTS_COMPARE1_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE1_CLEAR_Pos) /*!< Bit mask of COMPARE1_CLEAR field. */ #define TIMER_SHORTS_COMPARE1_CLEAR_Disabled (0UL) /*!< Disable shortcut */ #define TIMER_SHORTS_COMPARE1_CLEAR_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 0 : Shortcut between EVENTS_COMPARE[0] event and TASKS_CLEAR task */ +/* Bit 0 : Shortcut between COMPARE[0] event and CLEAR task */ #define TIMER_SHORTS_COMPARE0_CLEAR_Pos (0UL) /*!< Position of COMPARE0_CLEAR field. */ #define TIMER_SHORTS_COMPARE0_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE0_CLEAR_Pos) /*!< Bit mask of COMPARE0_CLEAR field. */ #define TIMER_SHORTS_COMPARE0_CLEAR_Disabled (0UL) /*!< Disable shortcut */ @@ -10422,42 +10869,42 @@ /* Register: TIMER_INTENSET */ /* Description: Enable interrupt */ -/* Bit 21 : Write '1' to Enable interrupt on EVENTS_COMPARE[5] event */ +/* Bit 21 : Write '1' to Enable interrupt for COMPARE[5] event */ #define TIMER_INTENSET_COMPARE5_Pos (21UL) /*!< Position of COMPARE5 field. */ #define TIMER_INTENSET_COMPARE5_Msk (0x1UL << TIMER_INTENSET_COMPARE5_Pos) /*!< Bit mask of COMPARE5 field. */ #define TIMER_INTENSET_COMPARE5_Disabled (0UL) /*!< Read: Disabled */ #define TIMER_INTENSET_COMPARE5_Enabled (1UL) /*!< Read: Enabled */ #define TIMER_INTENSET_COMPARE5_Set (1UL) /*!< Enable */ -/* Bit 20 : Write '1' to Enable interrupt on EVENTS_COMPARE[4] event */ +/* Bit 20 : Write '1' to Enable interrupt for COMPARE[4] event */ #define TIMER_INTENSET_COMPARE4_Pos (20UL) /*!< Position of COMPARE4 field. */ #define TIMER_INTENSET_COMPARE4_Msk (0x1UL << TIMER_INTENSET_COMPARE4_Pos) /*!< Bit mask of COMPARE4 field. */ #define TIMER_INTENSET_COMPARE4_Disabled (0UL) /*!< Read: Disabled */ #define TIMER_INTENSET_COMPARE4_Enabled (1UL) /*!< Read: Enabled */ #define TIMER_INTENSET_COMPARE4_Set (1UL) /*!< Enable */ -/* Bit 19 : Write '1' to Enable interrupt on EVENTS_COMPARE[3] event */ +/* Bit 19 : Write '1' to Enable interrupt for COMPARE[3] event */ #define TIMER_INTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ #define TIMER_INTENSET_COMPARE3_Msk (0x1UL << TIMER_INTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ #define TIMER_INTENSET_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ #define TIMER_INTENSET_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ #define TIMER_INTENSET_COMPARE3_Set (1UL) /*!< Enable */ -/* Bit 18 : Write '1' to Enable interrupt on EVENTS_COMPARE[2] event */ +/* Bit 18 : Write '1' to Enable interrupt for COMPARE[2] event */ #define TIMER_INTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ #define TIMER_INTENSET_COMPARE2_Msk (0x1UL << TIMER_INTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ #define TIMER_INTENSET_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ #define TIMER_INTENSET_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ #define TIMER_INTENSET_COMPARE2_Set (1UL) /*!< Enable */ -/* Bit 17 : Write '1' to Enable interrupt on EVENTS_COMPARE[1] event */ +/* Bit 17 : Write '1' to Enable interrupt for COMPARE[1] event */ #define TIMER_INTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ #define TIMER_INTENSET_COMPARE1_Msk (0x1UL << TIMER_INTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ #define TIMER_INTENSET_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ #define TIMER_INTENSET_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ #define TIMER_INTENSET_COMPARE1_Set (1UL) /*!< Enable */ -/* Bit 16 : Write '1' to Enable interrupt on EVENTS_COMPARE[0] event */ +/* Bit 16 : Write '1' to Enable interrupt for COMPARE[0] event */ #define TIMER_INTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ #define TIMER_INTENSET_COMPARE0_Msk (0x1UL << TIMER_INTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ #define TIMER_INTENSET_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ @@ -10467,42 +10914,42 @@ /* Register: TIMER_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 21 : Write '1' to Clear interrupt on EVENTS_COMPARE[5] event */ +/* Bit 21 : Write '1' to Disable interrupt for COMPARE[5] event */ #define TIMER_INTENCLR_COMPARE5_Pos (21UL) /*!< Position of COMPARE5 field. */ #define TIMER_INTENCLR_COMPARE5_Msk (0x1UL << TIMER_INTENCLR_COMPARE5_Pos) /*!< Bit mask of COMPARE5 field. */ #define TIMER_INTENCLR_COMPARE5_Disabled (0UL) /*!< Read: Disabled */ #define TIMER_INTENCLR_COMPARE5_Enabled (1UL) /*!< Read: Enabled */ #define TIMER_INTENCLR_COMPARE5_Clear (1UL) /*!< Disable */ -/* Bit 20 : Write '1' to Clear interrupt on EVENTS_COMPARE[4] event */ +/* Bit 20 : Write '1' to Disable interrupt for COMPARE[4] event */ #define TIMER_INTENCLR_COMPARE4_Pos (20UL) /*!< Position of COMPARE4 field. */ #define TIMER_INTENCLR_COMPARE4_Msk (0x1UL << TIMER_INTENCLR_COMPARE4_Pos) /*!< Bit mask of COMPARE4 field. */ #define TIMER_INTENCLR_COMPARE4_Disabled (0UL) /*!< Read: Disabled */ #define TIMER_INTENCLR_COMPARE4_Enabled (1UL) /*!< Read: Enabled */ #define TIMER_INTENCLR_COMPARE4_Clear (1UL) /*!< Disable */ -/* Bit 19 : Write '1' to Clear interrupt on EVENTS_COMPARE[3] event */ +/* Bit 19 : Write '1' to Disable interrupt for COMPARE[3] event */ #define TIMER_INTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ #define TIMER_INTENCLR_COMPARE3_Msk (0x1UL << TIMER_INTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ #define TIMER_INTENCLR_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ #define TIMER_INTENCLR_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ #define TIMER_INTENCLR_COMPARE3_Clear (1UL) /*!< Disable */ -/* Bit 18 : Write '1' to Clear interrupt on EVENTS_COMPARE[2] event */ +/* Bit 18 : Write '1' to Disable interrupt for COMPARE[2] event */ #define TIMER_INTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ #define TIMER_INTENCLR_COMPARE2_Msk (0x1UL << TIMER_INTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ #define TIMER_INTENCLR_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ #define TIMER_INTENCLR_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ #define TIMER_INTENCLR_COMPARE2_Clear (1UL) /*!< Disable */ -/* Bit 17 : Write '1' to Clear interrupt on EVENTS_COMPARE[1] event */ +/* Bit 17 : Write '1' to Disable interrupt for COMPARE[1] event */ #define TIMER_INTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ #define TIMER_INTENCLR_COMPARE1_Msk (0x1UL << TIMER_INTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ #define TIMER_INTENCLR_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ #define TIMER_INTENCLR_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ #define TIMER_INTENCLR_COMPARE1_Clear (1UL) /*!< Disable */ -/* Bit 16 : Write '1' to Clear interrupt on EVENTS_COMPARE[0] event */ +/* Bit 16 : Write '1' to Disable interrupt for COMPARE[0] event */ #define TIMER_INTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ #define TIMER_INTENCLR_COMPARE0_Msk (0x1UL << TIMER_INTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ #define TIMER_INTENCLR_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ @@ -10516,7 +10963,7 @@ #define TIMER_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */ #define TIMER_MODE_MODE_Msk (0x3UL << TIMER_MODE_MODE_Pos) /*!< Bit mask of MODE field. */ #define TIMER_MODE_MODE_Timer (0UL) /*!< Select Timer mode */ -#define TIMER_MODE_MODE_Counter (1UL) /*!< Select Counter mode */ +#define TIMER_MODE_MODE_Counter (1UL) /*!< Deprecated enumerator - Select Counter mode */ #define TIMER_MODE_MODE_LowPowerCounter (2UL) /*!< Select Low Power Counter mode */ /* Register: TIMER_BITMODE */ @@ -10551,13 +10998,13 @@ /* Register: TWI_SHORTS */ /* Description: Shortcut register */ -/* Bit 1 : Shortcut between EVENTS_BB event and TASKS_STOP task */ +/* Bit 1 : Shortcut between BB event and STOP task */ #define TWI_SHORTS_BB_STOP_Pos (1UL) /*!< Position of BB_STOP field. */ #define TWI_SHORTS_BB_STOP_Msk (0x1UL << TWI_SHORTS_BB_STOP_Pos) /*!< Bit mask of BB_STOP field. */ #define TWI_SHORTS_BB_STOP_Disabled (0UL) /*!< Disable shortcut */ #define TWI_SHORTS_BB_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 0 : Shortcut between EVENTS_BB event and TASKS_SUSPEND task */ +/* Bit 0 : Shortcut between BB event and SUSPEND task */ #define TWI_SHORTS_BB_SUSPEND_Pos (0UL) /*!< Position of BB_SUSPEND field. */ #define TWI_SHORTS_BB_SUSPEND_Msk (0x1UL << TWI_SHORTS_BB_SUSPEND_Pos) /*!< Bit mask of BB_SUSPEND field. */ #define TWI_SHORTS_BB_SUSPEND_Disabled (0UL) /*!< Disable shortcut */ @@ -10566,42 +11013,42 @@ /* Register: TWI_INTENSET */ /* Description: Enable interrupt */ -/* Bit 18 : Write '1' to Enable interrupt on EVENTS_SUSPENDED event */ +/* Bit 18 : Write '1' to Enable interrupt for SUSPENDED event */ #define TWI_INTENSET_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ #define TWI_INTENSET_SUSPENDED_Msk (0x1UL << TWI_INTENSET_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ #define TWI_INTENSET_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ #define TWI_INTENSET_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ #define TWI_INTENSET_SUSPENDED_Set (1UL) /*!< Enable */ -/* Bit 14 : Write '1' to Enable interrupt on EVENTS_BB event */ +/* Bit 14 : Write '1' to Enable interrupt for BB event */ #define TWI_INTENSET_BB_Pos (14UL) /*!< Position of BB field. */ #define TWI_INTENSET_BB_Msk (0x1UL << TWI_INTENSET_BB_Pos) /*!< Bit mask of BB field. */ #define TWI_INTENSET_BB_Disabled (0UL) /*!< Read: Disabled */ #define TWI_INTENSET_BB_Enabled (1UL) /*!< Read: Enabled */ #define TWI_INTENSET_BB_Set (1UL) /*!< Enable */ -/* Bit 9 : Write '1' to Enable interrupt on EVENTS_ERROR event */ +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ #define TWI_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define TWI_INTENSET_ERROR_Msk (0x1UL << TWI_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define TWI_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define TWI_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define TWI_INTENSET_ERROR_Set (1UL) /*!< Enable */ -/* Bit 7 : Write '1' to Enable interrupt on EVENTS_TXDSENT event */ +/* Bit 7 : Write '1' to Enable interrupt for TXDSENT event */ #define TWI_INTENSET_TXDSENT_Pos (7UL) /*!< Position of TXDSENT field. */ #define TWI_INTENSET_TXDSENT_Msk (0x1UL << TWI_INTENSET_TXDSENT_Pos) /*!< Bit mask of TXDSENT field. */ #define TWI_INTENSET_TXDSENT_Disabled (0UL) /*!< Read: Disabled */ #define TWI_INTENSET_TXDSENT_Enabled (1UL) /*!< Read: Enabled */ #define TWI_INTENSET_TXDSENT_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_RXDREADY event */ +/* Bit 2 : Write '1' to Enable interrupt for RXDREADY event */ #define TWI_INTENSET_RXDREADY_Pos (2UL) /*!< Position of RXDREADY field. */ #define TWI_INTENSET_RXDREADY_Msk (0x1UL << TWI_INTENSET_RXDREADY_Pos) /*!< Bit mask of RXDREADY field. */ #define TWI_INTENSET_RXDREADY_Disabled (0UL) /*!< Read: Disabled */ #define TWI_INTENSET_RXDREADY_Enabled (1UL) /*!< Read: Enabled */ #define TWI_INTENSET_RXDREADY_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ #define TWI_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define TWI_INTENSET_STOPPED_Msk (0x1UL << TWI_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define TWI_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ @@ -10611,42 +11058,42 @@ /* Register: TWI_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 18 : Write '1' to Clear interrupt on EVENTS_SUSPENDED event */ +/* Bit 18 : Write '1' to Disable interrupt for SUSPENDED event */ #define TWI_INTENCLR_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ #define TWI_INTENCLR_SUSPENDED_Msk (0x1UL << TWI_INTENCLR_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ #define TWI_INTENCLR_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ #define TWI_INTENCLR_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ #define TWI_INTENCLR_SUSPENDED_Clear (1UL) /*!< Disable */ -/* Bit 14 : Write '1' to Clear interrupt on EVENTS_BB event */ +/* Bit 14 : Write '1' to Disable interrupt for BB event */ #define TWI_INTENCLR_BB_Pos (14UL) /*!< Position of BB field. */ #define TWI_INTENCLR_BB_Msk (0x1UL << TWI_INTENCLR_BB_Pos) /*!< Bit mask of BB field. */ #define TWI_INTENCLR_BB_Disabled (0UL) /*!< Read: Disabled */ #define TWI_INTENCLR_BB_Enabled (1UL) /*!< Read: Enabled */ #define TWI_INTENCLR_BB_Clear (1UL) /*!< Disable */ -/* Bit 9 : Write '1' to Clear interrupt on EVENTS_ERROR event */ +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ #define TWI_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define TWI_INTENCLR_ERROR_Msk (0x1UL << TWI_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define TWI_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define TWI_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define TWI_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ -/* Bit 7 : Write '1' to Clear interrupt on EVENTS_TXDSENT event */ +/* Bit 7 : Write '1' to Disable interrupt for TXDSENT event */ #define TWI_INTENCLR_TXDSENT_Pos (7UL) /*!< Position of TXDSENT field. */ #define TWI_INTENCLR_TXDSENT_Msk (0x1UL << TWI_INTENCLR_TXDSENT_Pos) /*!< Bit mask of TXDSENT field. */ #define TWI_INTENCLR_TXDSENT_Disabled (0UL) /*!< Read: Disabled */ #define TWI_INTENCLR_TXDSENT_Enabled (1UL) /*!< Read: Enabled */ #define TWI_INTENCLR_TXDSENT_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_RXDREADY event */ +/* Bit 2 : Write '1' to Disable interrupt for RXDREADY event */ #define TWI_INTENCLR_RXDREADY_Pos (2UL) /*!< Position of RXDREADY field. */ #define TWI_INTENCLR_RXDREADY_Msk (0x1UL << TWI_INTENCLR_RXDREADY_Pos) /*!< Bit mask of RXDREADY field. */ #define TWI_INTENCLR_RXDREADY_Disabled (0UL) /*!< Read: Disabled */ #define TWI_INTENCLR_RXDREADY_Enabled (1UL) /*!< Read: Enabled */ #define TWI_INTENCLR_RXDREADY_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ #define TWI_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define TWI_INTENCLR_STOPPED_Msk (0x1UL << TWI_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define TWI_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ @@ -10661,18 +11108,21 @@ #define TWI_ERRORSRC_DNACK_Msk (0x1UL << TWI_ERRORSRC_DNACK_Pos) /*!< Bit mask of DNACK field. */ #define TWI_ERRORSRC_DNACK_NotPresent (0UL) /*!< Read: error not present */ #define TWI_ERRORSRC_DNACK_Present (1UL) /*!< Read: error present */ +#define TWI_ERRORSRC_DNACK_Clear (1UL) /*!< Write: clear error on writing '1' */ /* Bit 1 : NACK received after sending the address (write '1' to clear) */ #define TWI_ERRORSRC_ANACK_Pos (1UL) /*!< Position of ANACK field. */ #define TWI_ERRORSRC_ANACK_Msk (0x1UL << TWI_ERRORSRC_ANACK_Pos) /*!< Bit mask of ANACK field. */ #define TWI_ERRORSRC_ANACK_NotPresent (0UL) /*!< Read: error not present */ #define TWI_ERRORSRC_ANACK_Present (1UL) /*!< Read: error present */ +#define TWI_ERRORSRC_ANACK_Clear (1UL) /*!< Write: clear error on writing '1' */ /* Bit 0 : Overrun error */ #define TWI_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */ #define TWI_ERRORSRC_OVERRUN_Msk (0x1UL << TWI_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ #define TWI_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Read: no overrun occured */ #define TWI_ERRORSRC_OVERRUN_Present (1UL) /*!< Read: overrun occured */ +#define TWI_ERRORSRC_OVERRUN_Clear (1UL) /*!< Write: clear error on writing '1' */ /* Register: TWI_ENABLE */ /* Description: Enable TWI */ @@ -10737,31 +11187,31 @@ /* Register: TWIM_SHORTS */ /* Description: Shortcut register */ -/* Bit 12 : Shortcut between EVENTS_LASTRX event and TASKS_STOP task */ +/* Bit 12 : Shortcut between LASTRX event and STOP task */ #define TWIM_SHORTS_LASTRX_STOP_Pos (12UL) /*!< Position of LASTRX_STOP field. */ #define TWIM_SHORTS_LASTRX_STOP_Msk (0x1UL << TWIM_SHORTS_LASTRX_STOP_Pos) /*!< Bit mask of LASTRX_STOP field. */ #define TWIM_SHORTS_LASTRX_STOP_Disabled (0UL) /*!< Disable shortcut */ #define TWIM_SHORTS_LASTRX_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 10 : Shortcut between EVENTS_LASTRX event and TASKS_STARTTX task */ +/* Bit 10 : Shortcut between LASTRX event and STARTTX task */ #define TWIM_SHORTS_LASTRX_STARTTX_Pos (10UL) /*!< Position of LASTRX_STARTTX field. */ #define TWIM_SHORTS_LASTRX_STARTTX_Msk (0x1UL << TWIM_SHORTS_LASTRX_STARTTX_Pos) /*!< Bit mask of LASTRX_STARTTX field. */ #define TWIM_SHORTS_LASTRX_STARTTX_Disabled (0UL) /*!< Disable shortcut */ #define TWIM_SHORTS_LASTRX_STARTTX_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 9 : Shortcut between EVENTS_LASTTX event and TASKS_STOP task */ +/* Bit 9 : Shortcut between LASTTX event and STOP task */ #define TWIM_SHORTS_LASTTX_STOP_Pos (9UL) /*!< Position of LASTTX_STOP field. */ #define TWIM_SHORTS_LASTTX_STOP_Msk (0x1UL << TWIM_SHORTS_LASTTX_STOP_Pos) /*!< Bit mask of LASTTX_STOP field. */ #define TWIM_SHORTS_LASTTX_STOP_Disabled (0UL) /*!< Disable shortcut */ #define TWIM_SHORTS_LASTTX_STOP_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 8 : Shortcut between EVENTS_LASTTX event and TASKS_SUSPEND task */ +/* Bit 8 : Shortcut between LASTTX event and SUSPEND task */ #define TWIM_SHORTS_LASTTX_SUSPEND_Pos (8UL) /*!< Position of LASTTX_SUSPEND field. */ #define TWIM_SHORTS_LASTTX_SUSPEND_Msk (0x1UL << TWIM_SHORTS_LASTTX_SUSPEND_Pos) /*!< Bit mask of LASTTX_SUSPEND field. */ #define TWIM_SHORTS_LASTTX_SUSPEND_Disabled (0UL) /*!< Disable shortcut */ #define TWIM_SHORTS_LASTTX_SUSPEND_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 7 : Shortcut between EVENTS_LASTTX event and TASKS_STARTRX task */ +/* Bit 7 : Shortcut between LASTTX event and STARTRX task */ #define TWIM_SHORTS_LASTTX_STARTRX_Pos (7UL) /*!< Position of LASTTX_STARTRX field. */ #define TWIM_SHORTS_LASTTX_STARTRX_Msk (0x1UL << TWIM_SHORTS_LASTTX_STARTRX_Pos) /*!< Bit mask of LASTTX_STARTRX field. */ #define TWIM_SHORTS_LASTTX_STARTRX_Disabled (0UL) /*!< Disable shortcut */ @@ -10770,37 +11220,43 @@ /* Register: TWIM_INTEN */ /* Description: Enable or disable interrupt */ -/* Bit 24 : Enable or disable interrupt on EVENTS_LASTTX event */ +/* Bit 24 : Enable or disable interrupt for LASTTX event */ #define TWIM_INTEN_LASTTX_Pos (24UL) /*!< Position of LASTTX field. */ #define TWIM_INTEN_LASTTX_Msk (0x1UL << TWIM_INTEN_LASTTX_Pos) /*!< Bit mask of LASTTX field. */ #define TWIM_INTEN_LASTTX_Disabled (0UL) /*!< Disable */ #define TWIM_INTEN_LASTTX_Enabled (1UL) /*!< Enable */ -/* Bit 23 : Enable or disable interrupt on EVENTS_LASTRX event */ +/* Bit 23 : Enable or disable interrupt for LASTRX event */ #define TWIM_INTEN_LASTRX_Pos (23UL) /*!< Position of LASTRX field. */ #define TWIM_INTEN_LASTRX_Msk (0x1UL << TWIM_INTEN_LASTRX_Pos) /*!< Bit mask of LASTRX field. */ #define TWIM_INTEN_LASTRX_Disabled (0UL) /*!< Disable */ #define TWIM_INTEN_LASTRX_Enabled (1UL) /*!< Enable */ -/* Bit 20 : Enable or disable interrupt on EVENTS_TXSTARTED event */ +/* Bit 20 : Enable or disable interrupt for TXSTARTED event */ #define TWIM_INTEN_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ #define TWIM_INTEN_TXSTARTED_Msk (0x1UL << TWIM_INTEN_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ #define TWIM_INTEN_TXSTARTED_Disabled (0UL) /*!< Disable */ #define TWIM_INTEN_TXSTARTED_Enabled (1UL) /*!< Enable */ -/* Bit 19 : Enable or disable interrupt on EVENTS_RXSTARTED event */ +/* Bit 19 : Enable or disable interrupt for RXSTARTED event */ #define TWIM_INTEN_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ #define TWIM_INTEN_RXSTARTED_Msk (0x1UL << TWIM_INTEN_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ #define TWIM_INTEN_RXSTARTED_Disabled (0UL) /*!< Disable */ #define TWIM_INTEN_RXSTARTED_Enabled (1UL) /*!< Enable */ -/* Bit 9 : Enable or disable interrupt on EVENTS_ERROR event */ +/* Bit 18 : Enable or disable interrupt for SUSPENDED event */ +#define TWIM_INTEN_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWIM_INTEN_SUSPENDED_Msk (0x1UL << TWIM_INTEN_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWIM_INTEN_SUSPENDED_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_SUSPENDED_Enabled (1UL) /*!< Enable */ + +/* Bit 9 : Enable or disable interrupt for ERROR event */ #define TWIM_INTEN_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define TWIM_INTEN_ERROR_Msk (0x1UL << TWIM_INTEN_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define TWIM_INTEN_ERROR_Disabled (0UL) /*!< Disable */ #define TWIM_INTEN_ERROR_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Enable or disable interrupt for STOPPED event */ #define TWIM_INTEN_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define TWIM_INTEN_STOPPED_Msk (0x1UL << TWIM_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define TWIM_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ @@ -10809,42 +11265,49 @@ /* Register: TWIM_INTENSET */ /* Description: Enable interrupt */ -/* Bit 24 : Write '1' to Enable interrupt on EVENTS_LASTTX event */ +/* Bit 24 : Write '1' to Enable interrupt for LASTTX event */ #define TWIM_INTENSET_LASTTX_Pos (24UL) /*!< Position of LASTTX field. */ #define TWIM_INTENSET_LASTTX_Msk (0x1UL << TWIM_INTENSET_LASTTX_Pos) /*!< Bit mask of LASTTX field. */ #define TWIM_INTENSET_LASTTX_Disabled (0UL) /*!< Read: Disabled */ #define TWIM_INTENSET_LASTTX_Enabled (1UL) /*!< Read: Enabled */ #define TWIM_INTENSET_LASTTX_Set (1UL) /*!< Enable */ -/* Bit 23 : Write '1' to Enable interrupt on EVENTS_LASTRX event */ +/* Bit 23 : Write '1' to Enable interrupt for LASTRX event */ #define TWIM_INTENSET_LASTRX_Pos (23UL) /*!< Position of LASTRX field. */ #define TWIM_INTENSET_LASTRX_Msk (0x1UL << TWIM_INTENSET_LASTRX_Pos) /*!< Bit mask of LASTRX field. */ #define TWIM_INTENSET_LASTRX_Disabled (0UL) /*!< Read: Disabled */ #define TWIM_INTENSET_LASTRX_Enabled (1UL) /*!< Read: Enabled */ #define TWIM_INTENSET_LASTRX_Set (1UL) /*!< Enable */ -/* Bit 20 : Write '1' to Enable interrupt on EVENTS_TXSTARTED event */ +/* Bit 20 : Write '1' to Enable interrupt for TXSTARTED event */ #define TWIM_INTENSET_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ #define TWIM_INTENSET_TXSTARTED_Msk (0x1UL << TWIM_INTENSET_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ #define TWIM_INTENSET_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define TWIM_INTENSET_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define TWIM_INTENSET_TXSTARTED_Set (1UL) /*!< Enable */ -/* Bit 19 : Write '1' to Enable interrupt on EVENTS_RXSTARTED event */ +/* Bit 19 : Write '1' to Enable interrupt for RXSTARTED event */ #define TWIM_INTENSET_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ #define TWIM_INTENSET_RXSTARTED_Msk (0x1UL << TWIM_INTENSET_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ #define TWIM_INTENSET_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define TWIM_INTENSET_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define TWIM_INTENSET_RXSTARTED_Set (1UL) /*!< Enable */ -/* Bit 9 : Write '1' to Enable interrupt on EVENTS_ERROR event */ +/* Bit 18 : Write '1' to Enable interrupt for SUSPENDED event */ +#define TWIM_INTENSET_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWIM_INTENSET_SUSPENDED_Msk (0x1UL << TWIM_INTENSET_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWIM_INTENSET_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_SUSPENDED_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ #define TWIM_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define TWIM_INTENSET_ERROR_Msk (0x1UL << TWIM_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define TWIM_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define TWIM_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define TWIM_INTENSET_ERROR_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ #define TWIM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define TWIM_INTENSET_STOPPED_Msk (0x1UL << TWIM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define TWIM_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ @@ -10854,42 +11317,49 @@ /* Register: TWIM_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 24 : Write '1' to Clear interrupt on EVENTS_LASTTX event */ +/* Bit 24 : Write '1' to Disable interrupt for LASTTX event */ #define TWIM_INTENCLR_LASTTX_Pos (24UL) /*!< Position of LASTTX field. */ #define TWIM_INTENCLR_LASTTX_Msk (0x1UL << TWIM_INTENCLR_LASTTX_Pos) /*!< Bit mask of LASTTX field. */ #define TWIM_INTENCLR_LASTTX_Disabled (0UL) /*!< Read: Disabled */ #define TWIM_INTENCLR_LASTTX_Enabled (1UL) /*!< Read: Enabled */ #define TWIM_INTENCLR_LASTTX_Clear (1UL) /*!< Disable */ -/* Bit 23 : Write '1' to Clear interrupt on EVENTS_LASTRX event */ +/* Bit 23 : Write '1' to Disable interrupt for LASTRX event */ #define TWIM_INTENCLR_LASTRX_Pos (23UL) /*!< Position of LASTRX field. */ #define TWIM_INTENCLR_LASTRX_Msk (0x1UL << TWIM_INTENCLR_LASTRX_Pos) /*!< Bit mask of LASTRX field. */ #define TWIM_INTENCLR_LASTRX_Disabled (0UL) /*!< Read: Disabled */ #define TWIM_INTENCLR_LASTRX_Enabled (1UL) /*!< Read: Enabled */ #define TWIM_INTENCLR_LASTRX_Clear (1UL) /*!< Disable */ -/* Bit 20 : Write '1' to Clear interrupt on EVENTS_TXSTARTED event */ +/* Bit 20 : Write '1' to Disable interrupt for TXSTARTED event */ #define TWIM_INTENCLR_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ #define TWIM_INTENCLR_TXSTARTED_Msk (0x1UL << TWIM_INTENCLR_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ #define TWIM_INTENCLR_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define TWIM_INTENCLR_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define TWIM_INTENCLR_TXSTARTED_Clear (1UL) /*!< Disable */ -/* Bit 19 : Write '1' to Clear interrupt on EVENTS_RXSTARTED event */ +/* Bit 19 : Write '1' to Disable interrupt for RXSTARTED event */ #define TWIM_INTENCLR_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ #define TWIM_INTENCLR_RXSTARTED_Msk (0x1UL << TWIM_INTENCLR_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ #define TWIM_INTENCLR_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define TWIM_INTENCLR_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define TWIM_INTENCLR_RXSTARTED_Clear (1UL) /*!< Disable */ -/* Bit 9 : Write '1' to Clear interrupt on EVENTS_ERROR event */ +/* Bit 18 : Write '1' to Disable interrupt for SUSPENDED event */ +#define TWIM_INTENCLR_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWIM_INTENCLR_SUSPENDED_Msk (0x1UL << TWIM_INTENCLR_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWIM_INTENCLR_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_SUSPENDED_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ #define TWIM_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define TWIM_INTENCLR_ERROR_Msk (0x1UL << TWIM_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define TWIM_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define TWIM_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define TWIM_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ #define TWIM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define TWIM_INTENCLR_STOPPED_Msk (0x1UL << TWIM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define TWIM_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ @@ -10911,6 +11381,12 @@ #define TWIM_ERRORSRC_ANACK_NotReceived (0UL) /*!< Error did not occur */ #define TWIM_ERRORSRC_ANACK_Received (1UL) /*!< Error occurred */ +/* Bit 0 : Overrun error */ +#define TWIM_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */ +#define TWIM_ERRORSRC_OVERRUN_Msk (0x1UL << TWIM_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ +#define TWIM_ERRORSRC_OVERRUN_NotReceived (0UL) /*!< Error did not occur */ +#define TWIM_ERRORSRC_OVERRUN_Received (1UL) /*!< Error occurred */ + /* Register: TWIM_ENABLE */ /* Description: Enable TWIM */ @@ -10964,9 +11440,9 @@ #define TWIM_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << TWIM_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ /* Register: TWIM_RXD_MAXCNT */ -/* Description: Maximum number of buffer words to transfer */ +/* Description: Maximum number of bytes in receive buffer */ -/* Bits 7..0 : Maximum number of buffer words to transfer */ +/* Bits 7..0 : Maximum number of bytes in receive buffer */ #define TWIM_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ #define TWIM_RXD_MAXCNT_MAXCNT_Msk (0xFFUL << TWIM_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ @@ -10994,9 +11470,9 @@ #define TWIM_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << TWIM_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ /* Register: TWIM_TXD_MAXCNT */ -/* Description: Maximum number of buffer words to transfer */ +/* Description: Maximum number of bytes in transmit buffer */ -/* Bits 7..0 : Maximum number of buffer words to transfer */ +/* Bits 7..0 : Maximum number of bytes in transmit buffer */ #define TWIM_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ #define TWIM_TXD_MAXCNT_MAXCNT_Msk (0xFFUL << TWIM_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ @@ -11030,13 +11506,13 @@ /* Register: TWIS_SHORTS */ /* Description: Shortcut register */ -/* Bit 14 : Shortcut between EVENTS_READ event and TASKS_SUSPEND task */ +/* Bit 14 : Shortcut between READ event and SUSPEND task */ #define TWIS_SHORTS_READ_SUSPEND_Pos (14UL) /*!< Position of READ_SUSPEND field. */ #define TWIS_SHORTS_READ_SUSPEND_Msk (0x1UL << TWIS_SHORTS_READ_SUSPEND_Pos) /*!< Bit mask of READ_SUSPEND field. */ #define TWIS_SHORTS_READ_SUSPEND_Disabled (0UL) /*!< Disable shortcut */ #define TWIS_SHORTS_READ_SUSPEND_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 13 : Shortcut between EVENTS_WRITE event and TASKS_SUSPEND task */ +/* Bit 13 : Shortcut between WRITE event and SUSPEND task */ #define TWIS_SHORTS_WRITE_SUSPEND_Pos (13UL) /*!< Position of WRITE_SUSPEND field. */ #define TWIS_SHORTS_WRITE_SUSPEND_Msk (0x1UL << TWIS_SHORTS_WRITE_SUSPEND_Pos) /*!< Bit mask of WRITE_SUSPEND field. */ #define TWIS_SHORTS_WRITE_SUSPEND_Disabled (0UL) /*!< Disable shortcut */ @@ -11045,37 +11521,37 @@ /* Register: TWIS_INTEN */ /* Description: Enable or disable interrupt */ -/* Bit 26 : Enable or disable interrupt on EVENTS_READ event */ +/* Bit 26 : Enable or disable interrupt for READ event */ #define TWIS_INTEN_READ_Pos (26UL) /*!< Position of READ field. */ #define TWIS_INTEN_READ_Msk (0x1UL << TWIS_INTEN_READ_Pos) /*!< Bit mask of READ field. */ #define TWIS_INTEN_READ_Disabled (0UL) /*!< Disable */ #define TWIS_INTEN_READ_Enabled (1UL) /*!< Enable */ -/* Bit 25 : Enable or disable interrupt on EVENTS_WRITE event */ +/* Bit 25 : Enable or disable interrupt for WRITE event */ #define TWIS_INTEN_WRITE_Pos (25UL) /*!< Position of WRITE field. */ #define TWIS_INTEN_WRITE_Msk (0x1UL << TWIS_INTEN_WRITE_Pos) /*!< Bit mask of WRITE field. */ #define TWIS_INTEN_WRITE_Disabled (0UL) /*!< Disable */ #define TWIS_INTEN_WRITE_Enabled (1UL) /*!< Enable */ -/* Bit 20 : Enable or disable interrupt on EVENTS_TXSTARTED event */ +/* Bit 20 : Enable or disable interrupt for TXSTARTED event */ #define TWIS_INTEN_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ #define TWIS_INTEN_TXSTARTED_Msk (0x1UL << TWIS_INTEN_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ #define TWIS_INTEN_TXSTARTED_Disabled (0UL) /*!< Disable */ #define TWIS_INTEN_TXSTARTED_Enabled (1UL) /*!< Enable */ -/* Bit 19 : Enable or disable interrupt on EVENTS_RXSTARTED event */ +/* Bit 19 : Enable or disable interrupt for RXSTARTED event */ #define TWIS_INTEN_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ #define TWIS_INTEN_RXSTARTED_Msk (0x1UL << TWIS_INTEN_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ #define TWIS_INTEN_RXSTARTED_Disabled (0UL) /*!< Disable */ #define TWIS_INTEN_RXSTARTED_Enabled (1UL) /*!< Enable */ -/* Bit 9 : Enable or disable interrupt on EVENTS_ERROR event */ +/* Bit 9 : Enable or disable interrupt for ERROR event */ #define TWIS_INTEN_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define TWIS_INTEN_ERROR_Msk (0x1UL << TWIS_INTEN_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define TWIS_INTEN_ERROR_Disabled (0UL) /*!< Disable */ #define TWIS_INTEN_ERROR_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Enable or disable interrupt for STOPPED event */ #define TWIS_INTEN_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define TWIS_INTEN_STOPPED_Msk (0x1UL << TWIS_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define TWIS_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ @@ -11084,42 +11560,42 @@ /* Register: TWIS_INTENSET */ /* Description: Enable interrupt */ -/* Bit 26 : Write '1' to Enable interrupt on EVENTS_READ event */ +/* Bit 26 : Write '1' to Enable interrupt for READ event */ #define TWIS_INTENSET_READ_Pos (26UL) /*!< Position of READ field. */ #define TWIS_INTENSET_READ_Msk (0x1UL << TWIS_INTENSET_READ_Pos) /*!< Bit mask of READ field. */ #define TWIS_INTENSET_READ_Disabled (0UL) /*!< Read: Disabled */ #define TWIS_INTENSET_READ_Enabled (1UL) /*!< Read: Enabled */ #define TWIS_INTENSET_READ_Set (1UL) /*!< Enable */ -/* Bit 25 : Write '1' to Enable interrupt on EVENTS_WRITE event */ +/* Bit 25 : Write '1' to Enable interrupt for WRITE event */ #define TWIS_INTENSET_WRITE_Pos (25UL) /*!< Position of WRITE field. */ #define TWIS_INTENSET_WRITE_Msk (0x1UL << TWIS_INTENSET_WRITE_Pos) /*!< Bit mask of WRITE field. */ #define TWIS_INTENSET_WRITE_Disabled (0UL) /*!< Read: Disabled */ #define TWIS_INTENSET_WRITE_Enabled (1UL) /*!< Read: Enabled */ #define TWIS_INTENSET_WRITE_Set (1UL) /*!< Enable */ -/* Bit 20 : Write '1' to Enable interrupt on EVENTS_TXSTARTED event */ +/* Bit 20 : Write '1' to Enable interrupt for TXSTARTED event */ #define TWIS_INTENSET_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ #define TWIS_INTENSET_TXSTARTED_Msk (0x1UL << TWIS_INTENSET_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ #define TWIS_INTENSET_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define TWIS_INTENSET_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define TWIS_INTENSET_TXSTARTED_Set (1UL) /*!< Enable */ -/* Bit 19 : Write '1' to Enable interrupt on EVENTS_RXSTARTED event */ +/* Bit 19 : Write '1' to Enable interrupt for RXSTARTED event */ #define TWIS_INTENSET_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ #define TWIS_INTENSET_RXSTARTED_Msk (0x1UL << TWIS_INTENSET_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ #define TWIS_INTENSET_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define TWIS_INTENSET_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define TWIS_INTENSET_RXSTARTED_Set (1UL) /*!< Enable */ -/* Bit 9 : Write '1' to Enable interrupt on EVENTS_ERROR event */ +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ #define TWIS_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define TWIS_INTENSET_ERROR_Msk (0x1UL << TWIS_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define TWIS_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define TWIS_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define TWIS_INTENSET_ERROR_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ #define TWIS_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define TWIS_INTENSET_STOPPED_Msk (0x1UL << TWIS_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define TWIS_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ @@ -11129,42 +11605,42 @@ /* Register: TWIS_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 26 : Write '1' to Clear interrupt on EVENTS_READ event */ +/* Bit 26 : Write '1' to Disable interrupt for READ event */ #define TWIS_INTENCLR_READ_Pos (26UL) /*!< Position of READ field. */ #define TWIS_INTENCLR_READ_Msk (0x1UL << TWIS_INTENCLR_READ_Pos) /*!< Bit mask of READ field. */ #define TWIS_INTENCLR_READ_Disabled (0UL) /*!< Read: Disabled */ #define TWIS_INTENCLR_READ_Enabled (1UL) /*!< Read: Enabled */ #define TWIS_INTENCLR_READ_Clear (1UL) /*!< Disable */ -/* Bit 25 : Write '1' to Clear interrupt on EVENTS_WRITE event */ +/* Bit 25 : Write '1' to Disable interrupt for WRITE event */ #define TWIS_INTENCLR_WRITE_Pos (25UL) /*!< Position of WRITE field. */ #define TWIS_INTENCLR_WRITE_Msk (0x1UL << TWIS_INTENCLR_WRITE_Pos) /*!< Bit mask of WRITE field. */ #define TWIS_INTENCLR_WRITE_Disabled (0UL) /*!< Read: Disabled */ #define TWIS_INTENCLR_WRITE_Enabled (1UL) /*!< Read: Enabled */ #define TWIS_INTENCLR_WRITE_Clear (1UL) /*!< Disable */ -/* Bit 20 : Write '1' to Clear interrupt on EVENTS_TXSTARTED event */ +/* Bit 20 : Write '1' to Disable interrupt for TXSTARTED event */ #define TWIS_INTENCLR_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ #define TWIS_INTENCLR_TXSTARTED_Msk (0x1UL << TWIS_INTENCLR_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ #define TWIS_INTENCLR_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define TWIS_INTENCLR_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define TWIS_INTENCLR_TXSTARTED_Clear (1UL) /*!< Disable */ -/* Bit 19 : Write '1' to Clear interrupt on EVENTS_RXSTARTED event */ +/* Bit 19 : Write '1' to Disable interrupt for RXSTARTED event */ #define TWIS_INTENCLR_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ #define TWIS_INTENCLR_RXSTARTED_Msk (0x1UL << TWIS_INTENCLR_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ #define TWIS_INTENCLR_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define TWIS_INTENCLR_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define TWIS_INTENCLR_RXSTARTED_Clear (1UL) /*!< Disable */ -/* Bit 9 : Write '1' to Clear interrupt on EVENTS_ERROR event */ +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ #define TWIS_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define TWIS_INTENCLR_ERROR_Msk (0x1UL << TWIS_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define TWIS_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define TWIS_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define TWIS_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_STOPPED event */ +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ #define TWIS_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ #define TWIS_INTENCLR_STOPPED_Msk (0x1UL << TWIS_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ #define TWIS_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ @@ -11312,13 +11788,13 @@ /* Register: UART_SHORTS */ /* Description: Shortcut register */ -/* Bit 4 : Shortcut between EVENTS_NCTS event and TASKS_STOPRX task */ +/* Bit 4 : Shortcut between NCTS event and STOPRX task */ #define UART_SHORTS_NCTS_STOPRX_Pos (4UL) /*!< Position of NCTS_STOPRX field. */ #define UART_SHORTS_NCTS_STOPRX_Msk (0x1UL << UART_SHORTS_NCTS_STOPRX_Pos) /*!< Bit mask of NCTS_STOPRX field. */ #define UART_SHORTS_NCTS_STOPRX_Disabled (0UL) /*!< Disable shortcut */ #define UART_SHORTS_NCTS_STOPRX_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 3 : Shortcut between EVENTS_CTS event and TASKS_STARTRX task */ +/* Bit 3 : Shortcut between CTS event and STARTRX task */ #define UART_SHORTS_CTS_STARTRX_Pos (3UL) /*!< Position of CTS_STARTRX field. */ #define UART_SHORTS_CTS_STARTRX_Msk (0x1UL << UART_SHORTS_CTS_STARTRX_Pos) /*!< Bit mask of CTS_STARTRX field. */ #define UART_SHORTS_CTS_STARTRX_Disabled (0UL) /*!< Disable shortcut */ @@ -11327,42 +11803,42 @@ /* Register: UART_INTENSET */ /* Description: Enable interrupt */ -/* Bit 17 : Write '1' to Enable interrupt on EVENTS_RXTO event */ +/* Bit 17 : Write '1' to Enable interrupt for RXTO event */ #define UART_INTENSET_RXTO_Pos (17UL) /*!< Position of RXTO field. */ #define UART_INTENSET_RXTO_Msk (0x1UL << UART_INTENSET_RXTO_Pos) /*!< Bit mask of RXTO field. */ #define UART_INTENSET_RXTO_Disabled (0UL) /*!< Read: Disabled */ #define UART_INTENSET_RXTO_Enabled (1UL) /*!< Read: Enabled */ #define UART_INTENSET_RXTO_Set (1UL) /*!< Enable */ -/* Bit 9 : Write '1' to Enable interrupt on EVENTS_ERROR event */ +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ #define UART_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define UART_INTENSET_ERROR_Msk (0x1UL << UART_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define UART_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define UART_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define UART_INTENSET_ERROR_Set (1UL) /*!< Enable */ -/* Bit 7 : Write '1' to Enable interrupt on EVENTS_TXDRDY event */ +/* Bit 7 : Write '1' to Enable interrupt for TXDRDY event */ #define UART_INTENSET_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ #define UART_INTENSET_TXDRDY_Msk (0x1UL << UART_INTENSET_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ #define UART_INTENSET_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ #define UART_INTENSET_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ #define UART_INTENSET_TXDRDY_Set (1UL) /*!< Enable */ -/* Bit 2 : Write '1' to Enable interrupt on EVENTS_RXDRDY event */ +/* Bit 2 : Write '1' to Enable interrupt for RXDRDY event */ #define UART_INTENSET_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ #define UART_INTENSET_RXDRDY_Msk (0x1UL << UART_INTENSET_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ #define UART_INTENSET_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ #define UART_INTENSET_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ #define UART_INTENSET_RXDRDY_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_NCTS event */ +/* Bit 1 : Write '1' to Enable interrupt for NCTS event */ #define UART_INTENSET_NCTS_Pos (1UL) /*!< Position of NCTS field. */ #define UART_INTENSET_NCTS_Msk (0x1UL << UART_INTENSET_NCTS_Pos) /*!< Bit mask of NCTS field. */ #define UART_INTENSET_NCTS_Disabled (0UL) /*!< Read: Disabled */ #define UART_INTENSET_NCTS_Enabled (1UL) /*!< Read: Enabled */ #define UART_INTENSET_NCTS_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_CTS event */ +/* Bit 0 : Write '1' to Enable interrupt for CTS event */ #define UART_INTENSET_CTS_Pos (0UL) /*!< Position of CTS field. */ #define UART_INTENSET_CTS_Msk (0x1UL << UART_INTENSET_CTS_Pos) /*!< Bit mask of CTS field. */ #define UART_INTENSET_CTS_Disabled (0UL) /*!< Read: Disabled */ @@ -11372,42 +11848,42 @@ /* Register: UART_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 17 : Write '1' to Clear interrupt on EVENTS_RXTO event */ +/* Bit 17 : Write '1' to Disable interrupt for RXTO event */ #define UART_INTENCLR_RXTO_Pos (17UL) /*!< Position of RXTO field. */ #define UART_INTENCLR_RXTO_Msk (0x1UL << UART_INTENCLR_RXTO_Pos) /*!< Bit mask of RXTO field. */ #define UART_INTENCLR_RXTO_Disabled (0UL) /*!< Read: Disabled */ #define UART_INTENCLR_RXTO_Enabled (1UL) /*!< Read: Enabled */ #define UART_INTENCLR_RXTO_Clear (1UL) /*!< Disable */ -/* Bit 9 : Write '1' to Clear interrupt on EVENTS_ERROR event */ +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ #define UART_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define UART_INTENCLR_ERROR_Msk (0x1UL << UART_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define UART_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define UART_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define UART_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ -/* Bit 7 : Write '1' to Clear interrupt on EVENTS_TXDRDY event */ +/* Bit 7 : Write '1' to Disable interrupt for TXDRDY event */ #define UART_INTENCLR_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ #define UART_INTENCLR_TXDRDY_Msk (0x1UL << UART_INTENCLR_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ #define UART_INTENCLR_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ #define UART_INTENCLR_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ #define UART_INTENCLR_TXDRDY_Clear (1UL) /*!< Disable */ -/* Bit 2 : Write '1' to Clear interrupt on EVENTS_RXDRDY event */ +/* Bit 2 : Write '1' to Disable interrupt for RXDRDY event */ #define UART_INTENCLR_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ #define UART_INTENCLR_RXDRDY_Msk (0x1UL << UART_INTENCLR_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ #define UART_INTENCLR_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ #define UART_INTENCLR_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ #define UART_INTENCLR_RXDRDY_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_NCTS event */ +/* Bit 1 : Write '1' to Disable interrupt for NCTS event */ #define UART_INTENCLR_NCTS_Pos (1UL) /*!< Position of NCTS field. */ #define UART_INTENCLR_NCTS_Msk (0x1UL << UART_INTENCLR_NCTS_Pos) /*!< Bit mask of NCTS field. */ #define UART_INTENCLR_NCTS_Disabled (0UL) /*!< Read: Disabled */ #define UART_INTENCLR_NCTS_Enabled (1UL) /*!< Read: Enabled */ #define UART_INTENCLR_NCTS_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_CTS event */ +/* Bit 0 : Write '1' to Disable interrupt for CTS event */ #define UART_INTENCLR_CTS_Pos (0UL) /*!< Position of CTS field. */ #define UART_INTENCLR_CTS_Msk (0x1UL << UART_INTENCLR_CTS_Pos) /*!< Bit mask of CTS field. */ #define UART_INTENCLR_CTS_Disabled (0UL) /*!< Read: Disabled */ @@ -11499,7 +11975,7 @@ /* Register: UART_BAUDRATE */ /* Description: Baud rate */ -/* Bits 31..0 : Baud-rate */ +/* Bits 31..0 : Baud rate */ #define UART_BAUDRATE_BAUDRATE_Pos (0UL) /*!< Position of BAUDRATE field. */ #define UART_BAUDRATE_BAUDRATE_Msk (0xFFFFFFFFUL << UART_BAUDRATE_BAUDRATE_Pos) /*!< Bit mask of BAUDRATE field. */ #define UART_BAUDRATE_BAUDRATE_Baud1200 (0x0004F000UL) /*!< 1200 baud (actual rate: 1205) */ @@ -11509,7 +11985,9 @@ #define UART_BAUDRATE_BAUDRATE_Baud14400 (0x003B0000UL) /*!< 14400 baud (actual rate: 14414) */ #define UART_BAUDRATE_BAUDRATE_Baud19200 (0x004EA000UL) /*!< 19200 baud (actual rate: 19208) */ #define UART_BAUDRATE_BAUDRATE_Baud28800 (0x0075F000UL) /*!< 28800 baud (actual rate: 28829) */ +#define UART_BAUDRATE_BAUDRATE_Baud31250 (0x00800000UL) /*!< 31250 baud */ #define UART_BAUDRATE_BAUDRATE_Baud38400 (0x009D5000UL) /*!< 38400 baud (actual rate: 38462) */ +#define UART_BAUDRATE_BAUDRATE_Baud56000 (0x00E50000UL) /*!< 56000 baud (actual rate: 55944) */ #define UART_BAUDRATE_BAUDRATE_Baud57600 (0x00EBF000UL) /*!< 57600 baud (actual rate: 57762) */ #define UART_BAUDRATE_BAUDRATE_Baud76800 (0x013A9000UL) /*!< 76800 baud (actual rate: 76923) */ #define UART_BAUDRATE_BAUDRATE_Baud115200 (0x01D7E000UL) /*!< 115200 baud (actual rate: 115942) */ @@ -11541,13 +12019,13 @@ /* Register: UARTE_SHORTS */ /* Description: Shortcut register */ -/* Bit 6 : Shortcut between EVENTS_ENDRX event and TASKS_STOPRX task */ +/* Bit 6 : Shortcut between ENDRX event and STOPRX task */ #define UARTE_SHORTS_ENDRX_STOPRX_Pos (6UL) /*!< Position of ENDRX_STOPRX field. */ #define UARTE_SHORTS_ENDRX_STOPRX_Msk (0x1UL << UARTE_SHORTS_ENDRX_STOPRX_Pos) /*!< Bit mask of ENDRX_STOPRX field. */ #define UARTE_SHORTS_ENDRX_STOPRX_Disabled (0UL) /*!< Disable shortcut */ #define UARTE_SHORTS_ENDRX_STOPRX_Enabled (1UL) /*!< Enable shortcut */ -/* Bit 5 : Shortcut between EVENTS_ENDRX event and TASKS_STARTRX task */ +/* Bit 5 : Shortcut between ENDRX event and STARTRX task */ #define UARTE_SHORTS_ENDRX_STARTRX_Pos (5UL) /*!< Position of ENDRX_STARTRX field. */ #define UARTE_SHORTS_ENDRX_STARTRX_Msk (0x1UL << UARTE_SHORTS_ENDRX_STARTRX_Pos) /*!< Bit mask of ENDRX_STARTRX field. */ #define UARTE_SHORTS_ENDRX_STARTRX_Disabled (0UL) /*!< Disable shortcut */ @@ -11556,55 +12034,67 @@ /* Register: UARTE_INTEN */ /* Description: Enable or disable interrupt */ -/* Bit 22 : Enable or disable interrupt on EVENTS_TXSTOPPED event */ +/* Bit 22 : Enable or disable interrupt for TXSTOPPED event */ #define UARTE_INTEN_TXSTOPPED_Pos (22UL) /*!< Position of TXSTOPPED field. */ #define UARTE_INTEN_TXSTOPPED_Msk (0x1UL << UARTE_INTEN_TXSTOPPED_Pos) /*!< Bit mask of TXSTOPPED field. */ #define UARTE_INTEN_TXSTOPPED_Disabled (0UL) /*!< Disable */ #define UARTE_INTEN_TXSTOPPED_Enabled (1UL) /*!< Enable */ -/* Bit 20 : Enable or disable interrupt on EVENTS_TXSTARTED event */ +/* Bit 20 : Enable or disable interrupt for TXSTARTED event */ #define UARTE_INTEN_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ #define UARTE_INTEN_TXSTARTED_Msk (0x1UL << UARTE_INTEN_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ #define UARTE_INTEN_TXSTARTED_Disabled (0UL) /*!< Disable */ #define UARTE_INTEN_TXSTARTED_Enabled (1UL) /*!< Enable */ -/* Bit 19 : Enable or disable interrupt on EVENTS_RXSTARTED event */ +/* Bit 19 : Enable or disable interrupt for RXSTARTED event */ #define UARTE_INTEN_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ #define UARTE_INTEN_RXSTARTED_Msk (0x1UL << UARTE_INTEN_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ #define UARTE_INTEN_RXSTARTED_Disabled (0UL) /*!< Disable */ #define UARTE_INTEN_RXSTARTED_Enabled (1UL) /*!< Enable */ -/* Bit 17 : Enable or disable interrupt on EVENTS_RXTO event */ +/* Bit 17 : Enable or disable interrupt for RXTO event */ #define UARTE_INTEN_RXTO_Pos (17UL) /*!< Position of RXTO field. */ #define UARTE_INTEN_RXTO_Msk (0x1UL << UARTE_INTEN_RXTO_Pos) /*!< Bit mask of RXTO field. */ #define UARTE_INTEN_RXTO_Disabled (0UL) /*!< Disable */ #define UARTE_INTEN_RXTO_Enabled (1UL) /*!< Enable */ -/* Bit 9 : Enable or disable interrupt on EVENTS_ERROR event */ +/* Bit 9 : Enable or disable interrupt for ERROR event */ #define UARTE_INTEN_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define UARTE_INTEN_ERROR_Msk (0x1UL << UARTE_INTEN_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define UARTE_INTEN_ERROR_Disabled (0UL) /*!< Disable */ #define UARTE_INTEN_ERROR_Enabled (1UL) /*!< Enable */ -/* Bit 8 : Enable or disable interrupt on EVENTS_ENDTX event */ +/* Bit 8 : Enable or disable interrupt for ENDTX event */ #define UARTE_INTEN_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ #define UARTE_INTEN_ENDTX_Msk (0x1UL << UARTE_INTEN_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ #define UARTE_INTEN_ENDTX_Disabled (0UL) /*!< Disable */ #define UARTE_INTEN_ENDTX_Enabled (1UL) /*!< Enable */ -/* Bit 4 : Enable or disable interrupt on EVENTS_ENDRX event */ +/* Bit 7 : Enable or disable interrupt for TXDRDY event */ +#define UARTE_INTEN_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UARTE_INTEN_TXDRDY_Msk (0x1UL << UARTE_INTEN_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UARTE_INTEN_TXDRDY_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_TXDRDY_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable interrupt for ENDRX event */ #define UARTE_INTEN_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ #define UARTE_INTEN_ENDRX_Msk (0x1UL << UARTE_INTEN_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ #define UARTE_INTEN_ENDRX_Disabled (0UL) /*!< Disable */ #define UARTE_INTEN_ENDRX_Enabled (1UL) /*!< Enable */ -/* Bit 1 : Enable or disable interrupt on EVENTS_NCTS event */ +/* Bit 2 : Enable or disable interrupt for RXDRDY event */ +#define UARTE_INTEN_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UARTE_INTEN_RXDRDY_Msk (0x1UL << UARTE_INTEN_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UARTE_INTEN_RXDRDY_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_RXDRDY_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for NCTS event */ #define UARTE_INTEN_NCTS_Pos (1UL) /*!< Position of NCTS field. */ #define UARTE_INTEN_NCTS_Msk (0x1UL << UARTE_INTEN_NCTS_Pos) /*!< Bit mask of NCTS field. */ #define UARTE_INTEN_NCTS_Disabled (0UL) /*!< Disable */ #define UARTE_INTEN_NCTS_Enabled (1UL) /*!< Enable */ -/* Bit 0 : Enable or disable interrupt on EVENTS_CTS event */ +/* Bit 0 : Enable or disable interrupt for CTS event */ #define UARTE_INTEN_CTS_Pos (0UL) /*!< Position of CTS field. */ #define UARTE_INTEN_CTS_Msk (0x1UL << UARTE_INTEN_CTS_Pos) /*!< Bit mask of CTS field. */ #define UARTE_INTEN_CTS_Disabled (0UL) /*!< Disable */ @@ -11613,63 +12103,77 @@ /* Register: UARTE_INTENSET */ /* Description: Enable interrupt */ -/* Bit 22 : Write '1' to Enable interrupt on EVENTS_TXSTOPPED event */ +/* Bit 22 : Write '1' to Enable interrupt for TXSTOPPED event */ #define UARTE_INTENSET_TXSTOPPED_Pos (22UL) /*!< Position of TXSTOPPED field. */ #define UARTE_INTENSET_TXSTOPPED_Msk (0x1UL << UARTE_INTENSET_TXSTOPPED_Pos) /*!< Bit mask of TXSTOPPED field. */ #define UARTE_INTENSET_TXSTOPPED_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENSET_TXSTOPPED_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENSET_TXSTOPPED_Set (1UL) /*!< Enable */ -/* Bit 20 : Write '1' to Enable interrupt on EVENTS_TXSTARTED event */ +/* Bit 20 : Write '1' to Enable interrupt for TXSTARTED event */ #define UARTE_INTENSET_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ #define UARTE_INTENSET_TXSTARTED_Msk (0x1UL << UARTE_INTENSET_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ #define UARTE_INTENSET_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENSET_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENSET_TXSTARTED_Set (1UL) /*!< Enable */ -/* Bit 19 : Write '1' to Enable interrupt on EVENTS_RXSTARTED event */ +/* Bit 19 : Write '1' to Enable interrupt for RXSTARTED event */ #define UARTE_INTENSET_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ #define UARTE_INTENSET_RXSTARTED_Msk (0x1UL << UARTE_INTENSET_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ #define UARTE_INTENSET_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENSET_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENSET_RXSTARTED_Set (1UL) /*!< Enable */ -/* Bit 17 : Write '1' to Enable interrupt on EVENTS_RXTO event */ +/* Bit 17 : Write '1' to Enable interrupt for RXTO event */ #define UARTE_INTENSET_RXTO_Pos (17UL) /*!< Position of RXTO field. */ #define UARTE_INTENSET_RXTO_Msk (0x1UL << UARTE_INTENSET_RXTO_Pos) /*!< Bit mask of RXTO field. */ #define UARTE_INTENSET_RXTO_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENSET_RXTO_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENSET_RXTO_Set (1UL) /*!< Enable */ -/* Bit 9 : Write '1' to Enable interrupt on EVENTS_ERROR event */ +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ #define UARTE_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define UARTE_INTENSET_ERROR_Msk (0x1UL << UARTE_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define UARTE_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENSET_ERROR_Set (1UL) /*!< Enable */ -/* Bit 8 : Write '1' to Enable interrupt on EVENTS_ENDTX event */ +/* Bit 8 : Write '1' to Enable interrupt for ENDTX event */ #define UARTE_INTENSET_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ #define UARTE_INTENSET_ENDTX_Msk (0x1UL << UARTE_INTENSET_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ #define UARTE_INTENSET_ENDTX_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENSET_ENDTX_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENSET_ENDTX_Set (1UL) /*!< Enable */ -/* Bit 4 : Write '1' to Enable interrupt on EVENTS_ENDRX event */ +/* Bit 7 : Write '1' to Enable interrupt for TXDRDY event */ +#define UARTE_INTENSET_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UARTE_INTENSET_TXDRDY_Msk (0x1UL << UARTE_INTENSET_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UARTE_INTENSET_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_TXDRDY_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for ENDRX event */ #define UARTE_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ #define UARTE_INTENSET_ENDRX_Msk (0x1UL << UARTE_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ #define UARTE_INTENSET_ENDRX_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENSET_ENDRX_Set (1UL) /*!< Enable */ -/* Bit 1 : Write '1' to Enable interrupt on EVENTS_NCTS event */ +/* Bit 2 : Write '1' to Enable interrupt for RXDRDY event */ +#define UARTE_INTENSET_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UARTE_INTENSET_RXDRDY_Msk (0x1UL << UARTE_INTENSET_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UARTE_INTENSET_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_RXDRDY_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for NCTS event */ #define UARTE_INTENSET_NCTS_Pos (1UL) /*!< Position of NCTS field. */ #define UARTE_INTENSET_NCTS_Msk (0x1UL << UARTE_INTENSET_NCTS_Pos) /*!< Bit mask of NCTS field. */ #define UARTE_INTENSET_NCTS_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENSET_NCTS_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENSET_NCTS_Set (1UL) /*!< Enable */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_CTS event */ +/* Bit 0 : Write '1' to Enable interrupt for CTS event */ #define UARTE_INTENSET_CTS_Pos (0UL) /*!< Position of CTS field. */ #define UARTE_INTENSET_CTS_Msk (0x1UL << UARTE_INTENSET_CTS_Pos) /*!< Bit mask of CTS field. */ #define UARTE_INTENSET_CTS_Disabled (0UL) /*!< Read: Disabled */ @@ -11679,63 +12183,77 @@ /* Register: UARTE_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 22 : Write '1' to Clear interrupt on EVENTS_TXSTOPPED event */ +/* Bit 22 : Write '1' to Disable interrupt for TXSTOPPED event */ #define UARTE_INTENCLR_TXSTOPPED_Pos (22UL) /*!< Position of TXSTOPPED field. */ #define UARTE_INTENCLR_TXSTOPPED_Msk (0x1UL << UARTE_INTENCLR_TXSTOPPED_Pos) /*!< Bit mask of TXSTOPPED field. */ #define UARTE_INTENCLR_TXSTOPPED_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENCLR_TXSTOPPED_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENCLR_TXSTOPPED_Clear (1UL) /*!< Disable */ -/* Bit 20 : Write '1' to Clear interrupt on EVENTS_TXSTARTED event */ +/* Bit 20 : Write '1' to Disable interrupt for TXSTARTED event */ #define UARTE_INTENCLR_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ #define UARTE_INTENCLR_TXSTARTED_Msk (0x1UL << UARTE_INTENCLR_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ #define UARTE_INTENCLR_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENCLR_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENCLR_TXSTARTED_Clear (1UL) /*!< Disable */ -/* Bit 19 : Write '1' to Clear interrupt on EVENTS_RXSTARTED event */ +/* Bit 19 : Write '1' to Disable interrupt for RXSTARTED event */ #define UARTE_INTENCLR_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ #define UARTE_INTENCLR_RXSTARTED_Msk (0x1UL << UARTE_INTENCLR_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ #define UARTE_INTENCLR_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENCLR_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENCLR_RXSTARTED_Clear (1UL) /*!< Disable */ -/* Bit 17 : Write '1' to Clear interrupt on EVENTS_RXTO event */ +/* Bit 17 : Write '1' to Disable interrupt for RXTO event */ #define UARTE_INTENCLR_RXTO_Pos (17UL) /*!< Position of RXTO field. */ #define UARTE_INTENCLR_RXTO_Msk (0x1UL << UARTE_INTENCLR_RXTO_Pos) /*!< Bit mask of RXTO field. */ #define UARTE_INTENCLR_RXTO_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENCLR_RXTO_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENCLR_RXTO_Clear (1UL) /*!< Disable */ -/* Bit 9 : Write '1' to Clear interrupt on EVENTS_ERROR event */ +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ #define UARTE_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define UARTE_INTENCLR_ERROR_Msk (0x1UL << UARTE_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ #define UARTE_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ -/* Bit 8 : Write '1' to Clear interrupt on EVENTS_ENDTX event */ +/* Bit 8 : Write '1' to Disable interrupt for ENDTX event */ #define UARTE_INTENCLR_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ #define UARTE_INTENCLR_ENDTX_Msk (0x1UL << UARTE_INTENCLR_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ #define UARTE_INTENCLR_ENDTX_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENCLR_ENDTX_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENCLR_ENDTX_Clear (1UL) /*!< Disable */ -/* Bit 4 : Write '1' to Clear interrupt on EVENTS_ENDRX event */ +/* Bit 7 : Write '1' to Disable interrupt for TXDRDY event */ +#define UARTE_INTENCLR_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UARTE_INTENCLR_TXDRDY_Msk (0x1UL << UARTE_INTENCLR_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UARTE_INTENCLR_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_TXDRDY_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for ENDRX event */ #define UARTE_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ #define UARTE_INTENCLR_ENDRX_Msk (0x1UL << UARTE_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ #define UARTE_INTENCLR_ENDRX_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENCLR_ENDRX_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENCLR_ENDRX_Clear (1UL) /*!< Disable */ -/* Bit 1 : Write '1' to Clear interrupt on EVENTS_NCTS event */ +/* Bit 2 : Write '1' to Disable interrupt for RXDRDY event */ +#define UARTE_INTENCLR_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UARTE_INTENCLR_RXDRDY_Msk (0x1UL << UARTE_INTENCLR_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UARTE_INTENCLR_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_RXDRDY_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for NCTS event */ #define UARTE_INTENCLR_NCTS_Pos (1UL) /*!< Position of NCTS field. */ #define UARTE_INTENCLR_NCTS_Msk (0x1UL << UARTE_INTENCLR_NCTS_Pos) /*!< Bit mask of NCTS field. */ #define UARTE_INTENCLR_NCTS_Disabled (0UL) /*!< Read: Disabled */ #define UARTE_INTENCLR_NCTS_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENCLR_NCTS_Clear (1UL) /*!< Disable */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_CTS event */ +/* Bit 0 : Write '1' to Disable interrupt for CTS event */ #define UARTE_INTENCLR_CTS_Pos (0UL) /*!< Position of CTS field. */ #define UARTE_INTENCLR_CTS_Msk (0x1UL << UARTE_INTENCLR_CTS_Pos) /*!< Bit mask of CTS field. */ #define UARTE_INTENCLR_CTS_Disabled (0UL) /*!< Read: Disabled */ @@ -11831,9 +12349,9 @@ #define UARTE_PSEL_RXD_PIN_Msk (0x1FUL << UARTE_PSEL_RXD_PIN_Pos) /*!< Bit mask of PIN field. */ /* Register: UARTE_BAUDRATE */ -/* Description: Baud rate */ +/* Description: Baud rate. Accuracy depends on the HFCLK source selected. */ -/* Bits 31..0 : Baud-rate */ +/* Bits 31..0 : Baud rate */ #define UARTE_BAUDRATE_BAUDRATE_Pos (0UL) /*!< Position of BAUDRATE field. */ #define UARTE_BAUDRATE_BAUDRATE_Msk (0xFFFFFFFFUL << UARTE_BAUDRATE_BAUDRATE_Pos) /*!< Bit mask of BAUDRATE field. */ #define UARTE_BAUDRATE_BAUDRATE_Baud1200 (0x0004F000UL) /*!< 1200 baud (actual rate: 1205) */ @@ -11843,7 +12361,9 @@ #define UARTE_BAUDRATE_BAUDRATE_Baud14400 (0x003AF000UL) /*!< 14400 baud (actual rate: 14401) */ #define UARTE_BAUDRATE_BAUDRATE_Baud19200 (0x004EA000UL) /*!< 19200 baud (actual rate: 19208) */ #define UARTE_BAUDRATE_BAUDRATE_Baud28800 (0x0075C000UL) /*!< 28800 baud (actual rate: 28777) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud31250 (0x00800000UL) /*!< 31250 baud */ #define UARTE_BAUDRATE_BAUDRATE_Baud38400 (0x009D0000UL) /*!< 38400 baud (actual rate: 38369) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud56000 (0x00E50000UL) /*!< 56000 baud (actual rate: 55944) */ #define UARTE_BAUDRATE_BAUDRATE_Baud57600 (0x00EB0000UL) /*!< 57600 baud (actual rate: 57554) */ #define UARTE_BAUDRATE_BAUDRATE_Baud76800 (0x013A9000UL) /*!< 76800 baud (actual rate: 76923) */ #define UARTE_BAUDRATE_BAUDRATE_Baud115200 (0x01D60000UL) /*!< 115200 baud (actual rate: 115108) */ @@ -11861,9 +12381,9 @@ #define UARTE_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << UARTE_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ /* Register: UARTE_RXD_MAXCNT */ -/* Description: Maximum number of bytes in buffer */ +/* Description: Maximum number of bytes in receive buffer */ -/* Bits 7..0 : Maximum number of bytes in buffer */ +/* Bits 7..0 : Maximum number of bytes in receive buffer */ #define UARTE_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ #define UARTE_RXD_MAXCNT_MAXCNT_Msk (0xFFUL << UARTE_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ @@ -11882,9 +12402,9 @@ #define UARTE_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << UARTE_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ /* Register: UARTE_TXD_MAXCNT */ -/* Description: Maximum number of bytes in buffer */ +/* Description: Maximum number of bytes in transmit buffer */ -/* Bits 7..0 : Maximum number of bytes in buffer */ +/* Bits 7..0 : Maximum number of bytes in transmit buffer */ #define UARTE_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ #define UARTE_TXD_MAXCNT_MAXCNT_Msk (0xFFUL << UARTE_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ @@ -11949,9 +12469,9 @@ #define UICR_PSELRESET_PIN_Msk (0x1FUL << UICR_PSELRESET_PIN_Pos) /*!< Bit mask of PIN field. */ /* Register: UICR_APPROTECT */ -/* Description: Access port protection */ +/* Description: Access Port protection */ -/* Bits 7..0 : Blocks debugger read/write access to all CPU registers and memory mapped addresses except for the Control Access Port registers. */ +/* Bits 7..0 : Enable or disable Access Port protection. Any other value than 0xFF being written to this field will enable protection. */ #define UICR_APPROTECT_PALL_Pos (0UL) /*!< Position of PALL field. */ #define UICR_APPROTECT_PALL_Msk (0xFFUL << UICR_APPROTECT_PALL_Pos) /*!< Bit mask of PALL field. */ #define UICR_APPROTECT_PALL_Enabled (0x00UL) /*!< Enable */ @@ -11973,7 +12493,7 @@ /* Register: WDT_INTENSET */ /* Description: Enable interrupt */ -/* Bit 0 : Write '1' to Enable interrupt on EVENTS_TIMEOUT event */ +/* Bit 0 : Write '1' to Enable interrupt for TIMEOUT event */ #define WDT_INTENSET_TIMEOUT_Pos (0UL) /*!< Position of TIMEOUT field. */ #define WDT_INTENSET_TIMEOUT_Msk (0x1UL << WDT_INTENSET_TIMEOUT_Pos) /*!< Bit mask of TIMEOUT field. */ #define WDT_INTENSET_TIMEOUT_Disabled (0UL) /*!< Read: Disabled */ @@ -11983,7 +12503,7 @@ /* Register: WDT_INTENCLR */ /* Description: Disable interrupt */ -/* Bit 0 : Write '1' to Clear interrupt on EVENTS_TIMEOUT event */ +/* Bit 0 : Write '1' to Disable interrupt for TIMEOUT event */ #define WDT_INTENCLR_TIMEOUT_Pos (0UL) /*!< Position of TIMEOUT field. */ #define WDT_INTENCLR_TIMEOUT_Msk (0x1UL << WDT_INTENCLR_TIMEOUT_Pos) /*!< Bit mask of TIMEOUT field. */ #define WDT_INTENCLR_TIMEOUT_Disabled (0UL) /*!< Read: Disabled */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52_name_change.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52_name_change.h new file mode 100644 index 0000000000000000000000000000000000000000..92106dbf87643199846733ae07746c611afb7332 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52_name_change.h @@ -0,0 +1,81 @@ +/* + +Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + +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, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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 Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + +*/ + +#ifndef NRF52_NAME_CHANGE_H +#define NRF52_NAME_CHANGE_H + +/*lint ++flb "Enter library region */ + +/* This file is given to prevent your SW from not compiling with the updates made to nrf52.h and + * nrf52_bitfields.h. The macros defined in this file were available previously. Do not use these + * macros on purpose. Use the ones defined in nrf52.h and nrf52_bitfields.h instead. + */ + +/* I2S */ +/* Several enumerations changed case. Adding old macros to keep compilation compatibility. */ +#define I2S_ENABLE_ENABLE_DISABLE I2S_ENABLE_ENABLE_Disabled +#define I2S_ENABLE_ENABLE_ENABLE I2S_ENABLE_ENABLE_Enabled +#define I2S_CONFIG_MODE_MODE_MASTER I2S_CONFIG_MODE_MODE_Master +#define I2S_CONFIG_MODE_MODE_SLAVE I2S_CONFIG_MODE_MODE_Slave +#define I2S_CONFIG_RXEN_RXEN_DISABLE I2S_CONFIG_RXEN_RXEN_Disabled +#define I2S_CONFIG_RXEN_RXEN_ENABLE I2S_CONFIG_RXEN_RXEN_Enabled +#define I2S_CONFIG_TXEN_TXEN_DISABLE I2S_CONFIG_TXEN_TXEN_Disabled +#define I2S_CONFIG_TXEN_TXEN_ENABLE I2S_CONFIG_TXEN_TXEN_Enabled +#define I2S_CONFIG_MCKEN_MCKEN_DISABLE I2S_CONFIG_MCKEN_MCKEN_Disabled +#define I2S_CONFIG_MCKEN_MCKEN_ENABLE I2S_CONFIG_MCKEN_MCKEN_Enabled +#define I2S_CONFIG_SWIDTH_SWIDTH_8BIT I2S_CONFIG_SWIDTH_SWIDTH_8Bit +#define I2S_CONFIG_SWIDTH_SWIDTH_16BIT I2S_CONFIG_SWIDTH_SWIDTH_16Bit +#define I2S_CONFIG_SWIDTH_SWIDTH_24BIT I2S_CONFIG_SWIDTH_SWIDTH_24Bit +#define I2S_CONFIG_ALIGN_ALIGN_LEFT I2S_CONFIG_ALIGN_ALIGN_Left +#define I2S_CONFIG_ALIGN_ALIGN_RIGHT I2S_CONFIG_ALIGN_ALIGN_Right +#define I2S_CONFIG_FORMAT_FORMAT_ALIGNED I2S_CONFIG_FORMAT_FORMAT_Aligned +#define I2S_CONFIG_CHANNELS_CHANNELS_STEREO I2S_CONFIG_CHANNELS_CHANNELS_Stereo +#define I2S_CONFIG_CHANNELS_CHANNELS_LEFT I2S_CONFIG_CHANNELS_CHANNELS_Left +#define I2S_CONFIG_CHANNELS_CHANNELS_RIGHT I2S_CONFIG_CHANNELS_CHANNELS_Right + +/* LPCOMP */ +/* Corrected typo in RESULT register. */ +#define LPCOMP_RESULT_RESULT_Bellow LPCOMP_RESULT_RESULT_Below + +/*lint --flb "Leave library region" */ + +#endif /* NRF52_NAME_CHANGE_H */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52_to_nrf52840.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52_to_nrf52840.h new file mode 100644 index 0000000000000000000000000000000000000000..6f3887e440c330e5fbbd1117c6c32057f8d14be8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/device/nrf52_to_nrf52840.h @@ -0,0 +1,99 @@ +/* + +Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + +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, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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 Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + +*/ + +#ifndef NRF52_TO_NRF52840_H +#define NRF52_TO_NRF52840_H + +/*lint ++flb "Enter library region */ + +/* This file is given to prevent your SW from not compiling with the name changes between nRF51 or nRF52832 and nRF52840 devices. + * It redefines the old nRF51 or nRF52832 names into the new ones as long as the functionality is still supported. If the + * functionality is gone, there old names are not defined, so compilation will fail. Note that also includes macros + * from the nrf52_namechange.h file. */ + +/* Differences between latest nRF52 headers and nRF52840 headers. */ + +/* UART */ +/* The registers PSELRTS, PSELTXD, PSELCTS, PSELRXD were restructured into a struct. */ +#define PSELRTS PSEL.RTS +#define PSELTXD PSEL.TXD +#define PSELCTS PSEL.CTS +#define PSELRXD PSEL.RXD + +/* TWI */ +/* The registers PSELSCL, PSELSDA were restructured into a struct. */ +#define PSELSCL PSEL.SCL +#define PSELSDA PSEL.SDA + + +/* From nrf52_name_change.h. Several macros changed in different versions of nRF52 headers. By defining the following, any code written for any version of nRF52 headers will still compile. */ + +/* I2S */ +/* Several enumerations changed case. Adding old macros to keep compilation compatibility. */ +#define I2S_ENABLE_ENABLE_DISABLE I2S_ENABLE_ENABLE_Disabled +#define I2S_ENABLE_ENABLE_ENABLE I2S_ENABLE_ENABLE_Enabled +#define I2S_CONFIG_MODE_MODE_MASTER I2S_CONFIG_MODE_MODE_Master +#define I2S_CONFIG_MODE_MODE_SLAVE I2S_CONFIG_MODE_MODE_Slave +#define I2S_CONFIG_RXEN_RXEN_DISABLE I2S_CONFIG_RXEN_RXEN_Disabled +#define I2S_CONFIG_RXEN_RXEN_ENABLE I2S_CONFIG_RXEN_RXEN_Enabled +#define I2S_CONFIG_TXEN_TXEN_DISABLE I2S_CONFIG_TXEN_TXEN_Disabled +#define I2S_CONFIG_TXEN_TXEN_ENABLE I2S_CONFIG_TXEN_TXEN_Enabled +#define I2S_CONFIG_MCKEN_MCKEN_DISABLE I2S_CONFIG_MCKEN_MCKEN_Disabled +#define I2S_CONFIG_MCKEN_MCKEN_ENABLE I2S_CONFIG_MCKEN_MCKEN_Enabled +#define I2S_CONFIG_SWIDTH_SWIDTH_8BIT I2S_CONFIG_SWIDTH_SWIDTH_8Bit +#define I2S_CONFIG_SWIDTH_SWIDTH_16BIT I2S_CONFIG_SWIDTH_SWIDTH_16Bit +#define I2S_CONFIG_SWIDTH_SWIDTH_24BIT I2S_CONFIG_SWIDTH_SWIDTH_24Bit +#define I2S_CONFIG_ALIGN_ALIGN_LEFT I2S_CONFIG_ALIGN_ALIGN_Left +#define I2S_CONFIG_ALIGN_ALIGN_RIGHT I2S_CONFIG_ALIGN_ALIGN_Right +#define I2S_CONFIG_FORMAT_FORMAT_ALIGNED I2S_CONFIG_FORMAT_FORMAT_Aligned +#define I2S_CONFIG_CHANNELS_CHANNELS_STEREO I2S_CONFIG_CHANNELS_CHANNELS_Stereo +#define I2S_CONFIG_CHANNELS_CHANNELS_LEFT I2S_CONFIG_CHANNELS_CHANNELS_Left +#define I2S_CONFIG_CHANNELS_CHANNELS_RIGHT I2S_CONFIG_CHANNELS_CHANNELS_Right + +/* LPCOMP */ +/* Corrected typo in RESULT register. */ +#define LPCOMP_RESULT_RESULT_Bellow LPCOMP_RESULT_RESULT_Below + + +/*lint --flb "Leave library region" */ + +#endif /* NRF51_TO_NRF52840_H */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/adns2080/adns2080.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/adns2080/adns2080.c new file mode 100644 index 0000000000000000000000000000000000000000..a6b8c15764ef1d1100a7b5793f2146db94e85b95 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/adns2080/adns2080.c @@ -0,0 +1,358 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include + +#include "adns2080.h" +#include "sdio.h" + +/*lint ++flb "Enter library region" */ + +#define ADNS2080_PRODUCT_ID (0x2AU) /*!< ADNS2080 product id */ +#define ADNS2080_RESET_NUMBER (0x5AU) /*!< ADNS2080 reset code */ + +/* ADNS2080 register addresses */ +#define REG_PROD_ID (0x00U) /*!< Product ID. Default value : 0x2A */ +#define REG_REV_ID (0x01U) /*!< Revision ID. Default value : 0x00 */ +#define REG_MOTION_ST (0x02U) /*!< Motion Status. Default value : 0x00 */ +#define REG_DELTA_X (0x03U) /*!< Lower byte of Delta_X. Default value : 0x00 */ +#define REG_DELTA_Y (0x04U) /*!< Lower byte of Delta_Y. Default value : 0x00 */ +#define REG_SQUAL (0x05U) /*!< Squal Quality. Default value : 0x00 */ +#define REG_SHUT_HI (0x06U) /*!< Shutter Open Time (Upper 8-bit). Default value : 0x00 */ +#define REG_SHUT_LO (0x07U) /*!< Shutter Open Time (Lower 8-bit). Default value : 0x64 */ +#define REG_PIX_MAX (0x08U) /*!< Maximum Pixel Value. Default value : 0xD0 */ +#define REG_PIX_ACCUM (0x09U) /*!< Average Pixel Value. Default value : 0x80 */ +#define REG_PIX_MIN (0x0AU) /*!< Minimum Pixel Value. Default value : 0x00 */ +#define REG_PIX_GRAB (0x0BU) /*!< Pixel Grabber. Default value : 0x00 */ +#define REG_DELTA_XY_HIGH (0x0CU) /*!< Upper 4 bits of Delta X and Y displacement. Default value : 0x00 */ +#define REG_MOUSE_CTRL (0x0DU) /*!< Mouse Control. Default value : 0x01 */ +#define REG_RUN_DOWNSHIFT (0x0EU) /*!< Run to Rest1 Time. Default value : 0x08 */ +#define REG_REST1_PERIOD (0x0FU) /*!< Rest1 Period. Default value : 0x01 */ +#define REG_REST1_DOWNSHIFT (0x10U) /*!< Rest1 to Rest2 Time. Default value : 0x1f */ +#define REG_REST2_PERIOD (0x11U) /*!< Rest2 Period. Default value : 0x09 */ +#define REG_REST2_DOWNSHIFT (0x12U) /*!< Rest2 to Rest3 Time. Default value : 0x2f */ +#define REG_REST3_PERIOD (0x13U) /*!< Rest3 Period. Default value : 0x31 */ +#define REG_PERFORMANCE (0x22U) /*!< Performance. Default value : 0x00 */ +#define REG_RESET (0x3aU) /*!< Reset. Default value : 0x00 */ +#define REG_NOT_REV_ID (0x3fU) /*!< Inverted Revision ID. Default value : 0xff */ +#define REG_LED_CTRL (0x40U) /*!< LED Control. Default value : 0x00 */ +#define REG_MOTION_CTRL (0x41U) /*!< Motion Control. Default value : 0x40 */ +#define REG_BURST_READ_FIRST (0x42U) /*!< Burst Read Starting Register. Default value : 0x03 */ +#define REG_BURST_READ_LAST (0x44U) /*!< Burst Read Ending Register. Default value : 0x09 */ +#define REG_REST_MODE_CONFIG (0x45U) /*!< Rest Mode Confi guration. Default value : 0x00 */ +#define REG_MOTION_BURST (0x63U) /*!< Burst Read. Default value : 0x00 */ + +/* ADNS2080 register bits */ +#define REG_MOUSE_CTRL_POWERDOWN (0x02U) /*!< Mouse control register powerdown bit */ +#define REG_MOTION_CTRL_MOT_A (0x80U) /*!< Motion control register polarity bit */ +#define REG_MOTION_CTRL_MOT_S (0x40U) /*!< Motion control register edge sensitivity bit */ +#define REG_MOUSE_CTRL_RES_EN (0x40U) /*!< Mouse control register resolution enable bit */ +#define REG_MOUSE_CTRL_BIT_REPORTING (0x80U) /*!< Mouse control register "number of motion bits" bit*/ + +void adns2080_movement_read(int16_t * deltaX, int16_t * deltaY) +{ + uint8_t delta_x; /*!< Stores REG_DELTA_X contents */ + uint8_t delta_y; /*!< Stores REG_DELTA_Y contents */ + uint8_t delta_xy_high; /*!< Stores REG_DELTA_XY contents which contains upper 4 bits for both delta_x and delta_y when 12 bit mode is used */ + uint8_t delta_x_high; /*!< Stores delta_x 4 MSB bits */ + uint8_t delta_y_high; /*!< Stores delta_y 4 MSB bits */ + + uint16_t u16_deltaX; /*!< This is used to buffer the result and will be cast later to int16_t */ + uint16_t u16_deltaY; /*!< This is used to buffer the result and will be cast later to int16_t */ + + delta_x = sdio_read_byte(REG_DELTA_X); + delta_y = sdio_read_byte(REG_DELTA_Y); + + if (adns2080_motion_bits_read() == ADNS2080_MOTION_BITS_12) + { + // In 12 bit mode the upper 4 bits are stored in a separate register + // where first 4 upper bits are for delta_x and lower 4 bits for delta_y. + delta_xy_high = sdio_read_byte(REG_DELTA_XY_HIGH); + + delta_x_high = ((delta_xy_high & 0xF0) >> 4); + delta_y_high = (delta_xy_high & 0x0F); + + // Check if MSB is 1. If it is, this is a negative number and we have + // to fill the upper unused bits with 1s. + if (delta_x_high & 0x08) + { + u16_deltaX = 0xF000; + } + else + { + u16_deltaX = 0x0000; + } + + // Check if MSB is 1. If it is, this is a negative number and we have + // to fill the upper unused bits with 1s. + if (delta_y_high & 0x08) + { + u16_deltaY = 0xF000; + } + else + { + u16_deltaY = 0x0000; + } + + u16_deltaX |= (delta_x_high << 4) | delta_x; + u16_deltaY |= (delta_y_high << 4) | delta_y; + } + else // Only 8 bits is used for motion data + { + // Check if MSB is 1. If it is, this is a negative number and we have + // to fill the upper unused bits with 1s. + if (delta_x & 0x80) + { + u16_deltaX = 0xFF00; + } + else + { + u16_deltaX = 0x0000; + } + + // Check if MSB is 1. If it is, this is a negative number and we have + // to fill the upper unused bits with 1s. + if (delta_y & 0x80) + { + u16_deltaY = 0xFF00; + } + else + { + u16_deltaY = 0x0000; + } + + u16_deltaX |= delta_x; + u16_deltaY |= delta_y; + } + + *deltaX = (int16_t)u16_deltaX; + *deltaY = (int16_t)u16_deltaY; +} + +adns2080_motion_bits_t adns2080_motion_bits_read(void) +{ + /* Read the most significant bit */ + return (adns2080_motion_bits_t)((sdio_read_byte(REG_MOUSE_CTRL) >> 7) & 0x01); +} + +bool adns2080_is_motion_detected(void) +{ + return ((sdio_read_byte(REG_MOTION_ST) & 0x80) != 0); +} + +uint8_t adns2080_product_id_read(void) +{ + return sdio_read_byte(REG_PROD_ID); +} + +uint8_t adns2080_revision_id_read(void) +{ + return sdio_read_byte(REG_REV_ID); +} + +adns2080_status_t adns2080_init(void) +{ + sdio_init(); + adns2080_reset(); + + if (adns2080_product_id_read() != ADNS2080_PRODUCT_ID) + { + return ADNS2080_CHIP_NOT_DETECTED; + } + + sdio_write_byte(REG_BURST_READ_FIRST, REG_DELTA_X); + sdio_write_byte(REG_BURST_READ_LAST, REG_DELTA_Y); + + return ADNS2080_OK; +} + +void adns2080_reset(void) +{ + sdio_write_byte(REG_RESET, ADNS2080_RESET_NUMBER); +} + +void adns2080_powerdown(void) +{ + sdio_write_byte(REG_MOUSE_CTRL, REG_MOUSE_CTRL_POWERDOWN); +} + +void adns2080_wakeup(void) +{ + adns2080_reset(); +} + +adns2080_status_t adns2080_motion_interrupt_set(motion_output_polarity_t polarity, motion_output_sensitivity_t sensitivity) +{ + uint8_t databyte = 0; + adns2080_status_t status = ADNS2080_OK; + + switch (polarity) + { + case ADNS2080_MOTION_OUTPUT_POLARITY_LOW: + databyte = 0; // Clear REG_MOTION_CTRL_MOT_A bit + break; + + case ADNS2080_MOTION_OUTPUT_POLARITY_HIGH: + databyte = REG_MOTION_CTRL_MOT_A; + break; + + default: + status = ADNS2080_INVALID_PARAMETER; + break; + } + + switch (sensitivity) + { + case ADNS2080_MOTION_OUTPUT_SENSITIVITY_LEVEL: + databyte &= ~(REG_MOTION_CTRL_MOT_S); + break; + + case ADNS2080_MOTION_OUTPUT_SENSITIVITY_EDGE: + databyte |= (REG_MOTION_CTRL_MOT_S); + break; + + default: + status = ADNS2080_INVALID_PARAMETER; + break; + } + + if (status == ADNS2080_OK) + { + sdio_write_byte(REG_MOTION_CTRL, databyte); + } + + return status; +} + +adns2080_status_t adns2080_resolution_set(adns2080_resolution_t resolution) +{ + uint8_t databyte = sdio_read_byte(REG_MOUSE_CTRL); + adns2080_status_t status = ADNS2080_OK; + + // Enable resolution settings on REG_MOUSE_CTRL [4:2] + databyte |= (REG_MOUSE_CTRL_RES_EN); + + switch (resolution) + { + case ADNS2080_RESOLUTION_250DPI: + case ADNS2080_RESOLUTION_500DPI: + case ADNS2080_RESOLUTION_1000DPI: + case ADNS2080_RESOLUTION_1250DPI: + case ADNS2080_RESOLUTION_1500DPI: + case ADNS2080_RESOLUTION_1750DPI: + case ADNS2080_RESOLUTION_2000DPI: + // Clear resolution bits [4:2] + databyte &= ~(0x1C); // 0b00011100; + // Set resolution bits + databyte |= (uint8_t)((uint8_t)resolution << 2); + break; + + default: + status = ADNS2080_INVALID_PARAMETER; + break; + } + + if (status == ADNS2080_OK) + { + sdio_write_byte(REG_MOUSE_CTRL, databyte); + } + + return status; +} + +adns2080_status_t adns2080_motion_bits_set(adns2080_motion_bits_t motion_bits) +{ + uint8_t databyte = sdio_read_byte(REG_MOUSE_CTRL); + adns2080_status_t status = ADNS2080_OK; + + switch (motion_bits) + { + case ADNS2080_MOTION_BITS_8: + databyte &= ~(REG_MOUSE_CTRL_BIT_REPORTING); + break; + + case ADNS2080_MOTION_BITS_12: + databyte |= (REG_MOUSE_CTRL_BIT_REPORTING); + break; + + default: + status = ADNS2080_INVALID_PARAMETER; + break; + } + + if (status == ADNS2080_OK) + { + sdio_write_byte(REG_MOUSE_CTRL, databyte); + } + + return status; +} + +void adns2080_rest_periods_set(uint8_t rest1_period, uint8_t rest2_period, uint8_t rest3_period) +{ + adns2080_mode_t current_mode = adns2080_force_mode_read(); + adns2080_force_mode_set(ADNS2080_MODE_RUN1); + sdio_write_byte(REG_REST1_PERIOD, rest1_period); + sdio_write_byte(REG_REST2_PERIOD, rest2_period); + sdio_write_byte(REG_REST3_PERIOD, rest3_period); + adns2080_force_mode_set(current_mode); +} + +void adns2080_downshift_times_set(uint8_t run_to_rest1_mode_time, uint8_t rest1_to_rest2_mode_time, uint8_t rest2_to_rest3_mode_time) +{ + adns2080_mode_t current_mode = adns2080_force_mode_read(); + adns2080_force_mode_set(ADNS2080_MODE_RUN1); + sdio_write_byte(REG_RUN_DOWNSHIFT, run_to_rest1_mode_time); + sdio_write_byte(REG_REST1_DOWNSHIFT, rest1_to_rest2_mode_time); + sdio_write_byte(REG_REST2_DOWNSHIFT, rest2_to_rest3_mode_time); + adns2080_force_mode_set(current_mode); +} + +adns2080_mode_t adns2080_force_mode_read(void) +{ + return (adns2080_mode_t)((sdio_read_byte(REG_PERFORMANCE) >> 4) & 0x07); +} + +void adns2080_force_mode_set(adns2080_mode_t mode) +{ + sdio_write_byte(REG_PERFORMANCE, (uint8_t)((uint8_t)mode << 4)); +} + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/adns2080/adns2080.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/adns2080/adns2080.h new file mode 100644 index 0000000000000000000000000000000000000000..9117f6fc99267e40f30d02df385749c1a7a4127d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/adns2080/adns2080.h @@ -0,0 +1,317 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ADNS2080_H +#define ADNS2080_H + +/*lint ++flb "Enter library region" */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file +* @brief ADNS2080 mouse sensor driver +* +* @defgroup nrf_drivers_adns2080 ADNS2080 driver +* @{ +* @ingroup ext_drivers +* @brief ADNS2080 mouse sensor driver. +*/ + +/** + * Describes return values for @ref adns2080_init. + */ +typedef enum +{ + ADNS2080_OK, /*!< Operation was succesful */ + ADNS2080_SERIAL_COMM_FAILURE, /*!< Serial communication failed */ + ADNS2080_CHIP_NOT_DETECTED, /*!< Product/Revision ID was not what was expected */ + ADNS2080_INVALID_PARAMETER /*!< Given parameters were not valid */ +} adns2080_status_t; + +/** + * ADNS2080 motion output pin polarity values. + */ +typedef enum +{ + ADNS2080_MOTION_OUTPUT_POLARITY_LOW = 0, /*!< Motion output polarity active low */ + ADNS2080_MOTION_OUTPUT_POLARITY_HIGH = 1 /*!< Motion output polarity active high */ +} motion_output_polarity_t; + +/** + * Motion output pin configuration. + */ +typedef enum +{ + ADNS2080_MOTION_OUTPUT_SENSITIVITY_LEVEL = 0, /*!< Motion output pin will be driven low/high (depending on the polarity setting) as long as there is motion data in DELTA registers */ + ADNS2080_MOTION_OUTPUT_SENSITIVITY_EDGE = 1 /*!< Motion output pin will be driven low/high (depending on the polarity setting) for 380 ns when motion is detected during rest modes */ +} motion_output_sensitivity_t; + +/** + * Mouse sensor resolution values. + */ +typedef enum +{ + ADNS2080_RESOLUTION_250DPI = 1, /*!< 250 dpi resolution */ + ADNS2080_RESOLUTION_500DPI = 2, /*!< 500 dpi resolution */ + ADNS2080_RESOLUTION_1000DPI = 0, /*!< 1000 dpi resolution */ + ADNS2080_RESOLUTION_1250DPI = 3, /*!< 1250 dpi resolution */ + ADNS2080_RESOLUTION_1500DPI = 4, /*!< 1500 dpi resolution */ + ADNS2080_RESOLUTION_1750DPI = 5, /*!< 1750 dpi resolution */ + ADNS2080_RESOLUTION_2000DPI = 6 /*!< 2000 dpi resolution */ +} adns2080_resolution_t; + +/** + * Mouse sensor forced mode options. + */ +typedef enum +{ + ADNS2080_MODE_NORMAL = 0, /*!< Normal operation mode */ + ADNS2080_MODE_REST1 = 1, /*!< Rest1 operation mode */ + ADNS2080_MODE_REST2 = 2, /*!< Rest2 operation mode */ + ADNS2080_MODE_REST3 = 3, /*!< Rest3 operation mode */ + ADNS2080_MODE_RUN1 = 4, /*!< Run1 operation mode */ + ADNS2080_MODE_RUN2 = 5, /*!< Run2 operation mode */ + ADNS2080_MODE_IDLE = 6 /*!< Idle operation mode */ +} adns2080_mode_t; + +/** + * Mouse sensor motion reporting bits. + */ +typedef enum +{ + ADNS2080_MOTION_BITS_8 = 0, /*!< Motion reporting uses 8 bits */ + ADNS2080_MOTION_BITS_12 = 1 /*!< Motion reporting uses 12 bits */ +} adns2080_motion_bits_t; + +/** + * @brief Function for initializing the mouse sensor chip. + * + * Valid mouse sensor information will be available 50 milliseconds after this + * function finishes. + * + * @return + * @retval ADNS2080_OK Mouse sensor was initialized succesfully. + * @retval ADNS2080_SERIAL_COMM_FAILURE Serial communications failure. + * @retval ADNS2080_CHIP_NOT_DETECTED Could not find revision 0 ADNS2080 chip. + */ +adns2080_status_t adns2080_init(void); + +/** + * @brief Function for resetting the mouse sensor chip. + * + * Valid mouse sensor information will be available 50 milliseconds after this + * function finishes. + * All register settings will be lost and need to be reloaded. + * + */ +void adns2080_reset(void); + +/** + * @brief Function for reading mouse sensor product ID. + * + * Chip is expected to be initialized before calling this function. + * Returned product ID should always be 0x2A. + * + * @return Product ID. + */ +uint8_t adns2080_product_id_read(void); + +/** + * @brief Function for reading mouse sensor revision ID. + * + * Chip is expected to be initialized before calling this function. + * + * @return Product ID. + */ +uint8_t adns2080_revision_id_read(void); // also note there is "not rev id" register + +/** + * @brief Function for powering down the mouse sensor. + * + * Chip is expected to be initialized before calling this function. + * Serial port should not be accessed during the power down. To exit the power + * down mode, @ref adns2080_wakeup must be called. + * + */ +void adns2080_powerdown(void); + +/** + * @brief Function for waking up the mouse sensor. + * + * After wakeup, all mouse sensor settings must be reloaded. Valid mouse sensor + * information will be available 55 milliseconds after this function finishes. + */ +void adns2080_wakeup(void); + +/** + * @brief Function for configuring the MOTION interrupt output pin. + * + * When motion is detected by the mouse sensor, the chip has a MOTION pin + * indicating there is motion data in DELTA_X and DELTA_Y registers. This + * function configures the polarity and sensitivity of that pin. + * + * Chip is expected to be initialized before calling this function. + * + * @param polarity MOTION output pin is either active LOW (default) or active HIGH + * @param sensitivity Level or Edge (default) sensitive + * @return + * @retval ADNS2080_OK Operation succeeded. + * @retval ADNS2080_INVALID_PARAMETER One of the parameters was not within valid range. + */ +adns2080_status_t adns2080_motion_interrupt_set(motion_output_polarity_t polarity, motion_output_sensitivity_t sensitivity); + +/** + * @brief Function for setting mouse sensor resolution. + * + * Chip is expected to be initialized before calling this function. + * + * @param resolution Desired resolution. + * @return + * @retval ADNS2080_OK Operation succeeded. + * @retval ADNS2080_INVALID_PARAMETER One of the parameters was not within valid range. + */ +adns2080_status_t adns2080_resolution_set(adns2080_resolution_t resolution); + +/** + * @brief Function for setting number of bits used for mouse sensor motion reporting. + * + * Chip is expected to be initialized before calling this function. + * + * @param motion_bits Desired number of bits. + * @return + * @retval ADNS2080_OK Operation succeeded. + * @retval ADNS2080_INVALID_PARAMETER One of the parameters was not within valid range. + */ +adns2080_status_t adns2080_motion_bits_set(adns2080_motion_bits_t motion_bits); + +/** + * @brief Function for reading number of bits used for mouse sensor motion reporting. + * + * Chip is expected to be initialized before calling this function. + * + * @return motion_bits Number of bits. + */ +adns2080_motion_bits_t adns2080_motion_bits_read(void); + +/** + * @brief Function for reading X- and Y-axis movement (in counts) since last report. + * + * Absolute value is determined by resolution. + * Chip is expected to be initialized before calling this function. + * + * @param p_delta_x Location to store X-axis movement + * @param p_delta_y Location to store Y-axis movement + */ +void adns2080_movement_read(int16_t *p_delta_x, int16_t *p_delta_y); + +/** + * @brief Function for checking if motion has been detected since last call. + * + * Chip is expected to be initialized before calling this function. + * + * @return + * @retval true, if movement has been detected + * @retval false, if no movement has been detected + */ +bool adns2080_is_motion_detected(void); + +/** + * @brief Function for setting mouse sensor Rest1, Rest2 and Rest3 mode motion detection time period. + * + * Allowed range for the periods is 0x01 to 0xFD. + * Resulting period is derived from the following equation : + * Period = (Rest period + 1) * 10 milliseconds + * Chip is expected to be initialized before calling this function. + * + * @param rest1_period Rest1 period + * @param rest2_period Rest2 period + * @param rest3_period Rest3 period + */ +void adns2080_rest_periods_set(uint8_t rest1_period, uint8_t rest2_period, uint8_t rest3_period); + +/** + * @brief Function for setting mouse sensor mode downshift time periods. + * + * Allowed range for run_to_rest1_mode_time period is 0x00 to 0xFF. + * Allowed range for rest1_to_rest2_mode_time period is 0x01 to 0xFF. + * Allowed range for rest2_to_rest3_mode_time period is 0x01 to 0xFF. + * + * Chip is expected to be initialized before calling this function. + * + * @param run_to_rest1_mode_time Run mode to Rest1 mode downshift time period (Time = run_to_rest1_mode_time * 8 * 4) + * @param rest1_to_rest2_mode_time Rest1 mode to Rest2 mode downshift time period (Time = rest1_to_rest2_mode_time * rest1_period * 16) + * @param rest2_to_rest3_mode_time Rest2 mode to Rest3 mode downshift time period (Time = rest2_to_rest3_mode_time * rest2_period * 128) + */ +void adns2080_downshift_times_set(uint8_t run_to_rest1_mode_time, uint8_t rest1_to_rest2_mode_time, uint8_t rest2_to_rest3_mode_time); + +/** + * @brief Function for forcing mouse sensor to a certain operating mode. + * + * Chip is expected to be initialized before calling this function. + * Normal operation will not continue until this function is called with ADNS2080_MODE_NORMAL parameter. + * + * @param mode Mode to force the sensor to. + */ +void adns2080_force_mode_set(adns2080_mode_t mode); + +/** + * @brief Function for reading the current forced operating mode. + * + * Chip is expected to be initialized before calling this function. + * + * @return Mode the sensor is forced to. + */ +adns2080_mode_t adns2080_force_mode_read(void); + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/cherry8x16/cherry8x16.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/cherry8x16/cherry8x16.c new file mode 100644 index 0000000000000000000000000000000000000000..9c4387cc11c10e536a4a8fb34ff1888ec0ea5184 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/cherry8x16/cherry8x16.c @@ -0,0 +1,474 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include + +#include "cherry8x16.h" +#include "nrf.h" + +#define CHERRY8x16_NUM_OF_COLUMNS 16 // !< Number of columns in the keyboard matrix +#define CHERRY8x16_NUM_OF_ROWS 8 // !< Number of rows in the keyboard matrix + +#define MODIFIER_HID_START 0xE0 +#define MODIFIER_HID_END 0xE7 +static uint8_t m_currently_pressed_keys[CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS]; //!< Array holding currently pressed keys. Filled up from index 0. Values are +static uint8_t m_transmitted_keys[CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS]; //!< Array holding the keys that have already been transmitted. +static uint8_t m_num_of_currently_pressed_keys; //!< Number of keys in m_currently_pressed_keys +static uint8_t m_number_of_transmitted_keys; //!< Number of keys in m_transmitted_keys + +static uint8_t m_key_packet[KEY_PACKET_SIZE]; //!< Stores last created key packet. One byte is used for modifier keys, one for OEMs. Key values are USB HID keycodes. + +static const uint8_t volatile * m_row_port; //!< Pointer to location where row IO can be read +static uint16_t volatile * m_column_port; //!< Pointer to location where column IO can be written +static const uint8_t * matrix_lookup; //!< Pointer to the key lookup matrix in use + +/** Table containing the mapping between the key matrix and the HID Usage codes for each key. */ +static const uint8_t default_matrix_lookup[CHERRY8x16_NUM_OF_COLUMNS * CHERRY8x16_NUM_OF_ROWS] = +{ + 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE1, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xE2, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x29, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x3F, 0x40, + 0x1E, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x24, 0x25, + 0x4F, 0x43, 0x47, 0x53, 0x46, 0x48, 0x42, 0x41, + 0x51, 0x2D, 0x2E, 0x2A, 0x00, 0x4A, 0x27, 0x26, + 0x52, 0x13, 0x2F, 0x30, 0x00, 0x4B, 0x12, 0x0C, + 0x50, 0x33, 0x34, 0x32, 0x28, 0x4E, 0x0F, 0x0E, + 0x2C, 0x38, 0x4C, 0x49, 0x65, 0x4D, 0x37, 0x36, + 0x35, 0x05, 0x19, 0x06, 0x1B, 0x1D, 0x11, 0x10, + 0x39, 0x0A, 0x09, 0x07, 0x16, 0x04, 0x0B, 0x0D, + 0x2B, 0x17, 0x15, 0x08, 0x1A, 0x14, 0x1C, 0x18 +}; + +static bool cherry8x16_have_keys_changed(const uint8_t * state_now, + uint8_t number_of_now_pressed_keys, + const uint8_t * state_before, + uint8_t number_of_before_pressed_keys); +static bool cherry8x16_keymatrix_read(uint8_t * pressed_keys, uint8_t * number_of_pressed_keys); +static void cherry8x16_keypacket_addkey(uint8_t key); +static void cherry8x16_keypacket_create(uint8_t * key_packet, uint8_t key_packet_size); +static void cherry8x16_remap_fn_keys(uint8_t * keys, uint8_t number_of_keys); +static uint8_t cherry8x16_row_read(void); + +cherry8x16_status_t cherry8x16_init(const uint8_t volatile * row_port, + uint16_t * column_port, + const uint8_t * key_lookup_matrix) +{ + cherry8x16_status_t status = CHERRY8x16_OK; + + if (row_port == 0 || column_port == 0) + { + status = CHERRY8x16_INVALID_PARAMETER; + } + else + { + m_row_port = row_port; + m_column_port = column_port; + + *m_column_port = 0x0000; + if (*m_row_port != 0x00) + { + status = CHERRY8x16_NOT_DETECTED; + } + else + { + m_num_of_currently_pressed_keys = 0; + m_number_of_transmitted_keys = 0; + + for (uint_fast8_t i = CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS; i--;) + { + m_currently_pressed_keys[i] = 0; + m_transmitted_keys[i] = 0; + } + } + + if (key_lookup_matrix == CHERRY8x16_DEFAULT_KEY_LOOKUP_MATRIX) + { + matrix_lookup = default_matrix_lookup; + } + else + { + matrix_lookup = key_lookup_matrix; + } + } + + return status; +} + +bool cherry8x16_new_packet(const uint8_t ** p_key_packet, uint8_t * p_key_packet_size) +{ + bool new_packet_prepared; + + // Save currently pressed keys + for (uint_fast8_t i = CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS; i--; ) + { + m_transmitted_keys[i] = m_currently_pressed_keys[i]; + } + m_number_of_transmitted_keys = m_num_of_currently_pressed_keys; + + // Create a new packet if key states have changed and there are no keys blocking each other (ghosting/phantom keys) + if (cherry8x16_keymatrix_read(m_currently_pressed_keys, &m_num_of_currently_pressed_keys)) + { + if (cherry8x16_have_keys_changed(m_currently_pressed_keys, m_num_of_currently_pressed_keys, + m_transmitted_keys, m_number_of_transmitted_keys)) + { + cherry8x16_keypacket_create(&m_key_packet[0], KEY_PACKET_SIZE); + *p_key_packet = &m_key_packet[0]; + *p_key_packet_size = KEY_PACKET_SIZE; + new_packet_prepared = true; + } + else + { + // The same keys are still pressed, no need to create a new packet + new_packet_prepared = false; + } + } + else + { + // Ghosting detected. Don't create a packet. + new_packet_prepared = false; + } + + return new_packet_prepared; +} + + +/** + * @brief Function for reading and returning keyboard matrix row state. + * + * @return uint8_t Row state + */ +static uint8_t cherry8x16_row_read(void) +{ + return *m_row_port; +} + + +/** + * @brief Function for reading the keyboard matrix state and stores the pressed keys to an array. + * + * This function resolves keys from the matrix and finds their corresponding HID usage codes + * If there are any ghost key conditions the packet will be discarded + * @param pressed_keys Array holding pressed keys. Must be at least CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS in size. + * @param number_of_pressed_keys Pointer to variable where number of pressed keys will be stored. + * @return + * @retval true If no keys were blocking each other. + * @retval false If some keys were blocking each other o rno key is pressed. + */ +static bool cherry8x16_keymatrix_read(uint8_t * pressed_keys, uint8_t * number_of_pressed_keys) +{ + uint_fast8_t row_state[CHERRY8x16_NUM_OF_COLUMNS]; + uint_fast8_t blocking_mask = 0; + + *number_of_pressed_keys = 0; + + for (uint_fast8_t column = CHERRY8x16_NUM_OF_COLUMNS; column--;) + { + // drive column under test + *m_column_port = (uint16_t)(1UL << column); + row_state[column] = cherry8x16_row_read(); + + // Check if any keys are pressed + if (row_state[column] != 0) + { + uint_fast8_t detected_keypresses_on_column = 0; + + // Loop through rows, check for active rows and add pressed keys to the array + for (uint_fast8_t row = CHERRY8x16_NUM_OF_ROWS; row--;) + { + if (row_state[column] & (1U << row)) + { + if (*number_of_pressed_keys < CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS) + { + *pressed_keys = matrix_lookup[column * CHERRY8x16_NUM_OF_ROWS + row]; + pressed_keys++; + (*number_of_pressed_keys)++; + } + detected_keypresses_on_column++; + } + } + + if (detected_keypresses_on_column > 1) + { + if (blocking_mask & row_state[column]) + { + // Cannot determine reliably all pressed keys, two or more keys are blocking each other. + return false; + } + } + blocking_mask |= row_state[column]; + } + } + + return true; +} + + +/** + * @brief Function for remapping the keypad, F11 and F12 keys in case when Fn key is pressed. + * + * @param keys Array holding pressed keys. + * @param number_of_keys Number of elements if 'keys' array. + */ +static void cherry8x16_remap_fn_keys(uint8_t * keys, uint8_t number_of_keys) +{ + + /*lint -e845 -save // A zero has been given as right argument to operator '<<'" */ + /*lint -e778 -save // Constant expression evaluates to zero */ + +#define MODIFIER_LEFT_CONTROL_HID 0xE0 +#define MODIFER_RIGHT_CONTROL_HID 0xE4 + // Check if Fn key is pressed along with any other modifier key (only usage now is Fn + Left_Ctrl = Right Ctrl) + // So we modify the modifier byte if Fn + Left_Ctrl is pressed, HID for left_Ctrl = 0xE0 + if ( keys[0] & (1UL << (MODIFIER_LEFT_CONTROL_HID - MODIFIER_HID_START)) ) + { + keys[0] &= ~(1UL << (MODIFIER_LEFT_CONTROL_HID - MODIFIER_HID_START)); + keys[0] |= (1UL << (MODIFER_RIGHT_CONTROL_HID - MODIFIER_HID_START)); + } + + /*lint -restore */ + /*lint -restore */ + + for (uint_fast8_t i = 2; i < number_of_keys; i++) + { + switch (keys[i]) + { + case 0x10: // 'M' + keys[i] = 0x62; // Keypad 0 + break; + + case 0x37: // '>' + keys[i] = 0x63; // Keypad . + break; + + case 0x38: // '/' + keys[i] = 0x54; // Keypad / + break; + + case 0x0D: // 'J' + keys[i] = 0x59; // Keypad 1 + break; + + case 0x0E: // 'K' + keys[i] = 0x5A; // Keypad 2 + break; + + case 0x0F: // 'L' + keys[i] = 0x5B; // Keypad 3 + break; + + case 0x33: // '' + keys[i] = 0x57; // Keypad + + break; + + case 0x28: // 'Enter' + keys[i] = 0x58; // Keypad enter + break; + + case 0x18: // 'U' + keys[i] = 0x5C; // Keypad 4 + break; + + case 0x0C: // 'I' + keys[i] = 0x5D; // Keypad 5 + break; + + case 0x12: // 'O' + keys[i] = 0x5E; // Keypad 6 + break; + + case 0x13: // 'P' + keys[i] = 0x56; // Keypad - + break; + + case 0x24: // '7' + keys[i] = 0x5F; // Keypad 7 + break; + + case 0x25: // '8' + keys[i] = 0x60; // Keypad 8 + break; + + case 0x26: // '9' + keys[i] = 0x61; // Keypad 9 + break; + + case 0x27: // '0' + keys[i] = 0x55; // Keypad * + break; + + case 0x3A: // 'F1' + keys[i] = 0x44; // 'F11' + break; + + case 0x3B: // 'F2' + keys[i] = 0x45; // 'F12' + break; + + default: + break; + } + } +} + + +/** + * @brief Function for determining whether the keyboard matrix state has changed compared to the state before. + * + * @param state_now List of pressed keys in current state + * @param number_of_now_pressed_keys Number of pressed keys in current state + * @param state_before List of pressed keys in previous state + * @param number_of_before_pressed_keys Number of pressed keys in previous state + * @return + * @retval true If keyboard matrix is different compared to state before. + * @retval false If keyboard matrix is the same compared to state before. + */ +static bool cherry8x16_have_keys_changed(const uint8_t * state_now, + uint8_t number_of_now_pressed_keys, + const uint8_t * state_before, + uint8_t number_of_before_pressed_keys) +{ + if (number_of_now_pressed_keys != number_of_before_pressed_keys) + { + return true; + } + else + { + for (uint_fast8_t i = number_of_now_pressed_keys; i--;) + { + if (state_now[i] != state_before[i]) + { + return true; + } + } + } + return false; +} + +/** + * @brief Function for adding a key to the key packet. + * + * If key is found to be in the packet, it will not be added twice. + * Attempts to add more keys than the buffer capacity allows will be silently ignored. + * + * @param key Key to add + */ +static void cherry8x16_keypacket_addkey(uint8_t key) +{ + for (uint_fast8_t i = KEY_PACKET_KEY_INDEX; i < KEY_PACKET_SIZE; i++) + { + if (m_key_packet[i] == key) + { + return; + } + } + + for (uint_fast8_t i = KEY_PACKET_KEY_INDEX; i < KEY_PACKET_SIZE; i++) + { + if (m_key_packet[i] == KEY_PACKET_NO_KEY) + { + m_key_packet[i] = key; + return; + } + } +} + +/** + * @brief Function for creating a new key packet. + * + * This function uses @ref m_currently_pressed_keys to determine pressed keys. + * Priority is given to those keys that were found in the previous packet. + * All modifier keys can be found in all packets. + * If Fn key is detected to be pressed, some keys are remapped to different functions. + * + * @param key_packet Pointer to location where packet contents will be put + * @param key_packet_size Key packet size in bytes + */ +static void cherry8x16_keypacket_create(uint8_t * key_packet, uint8_t key_packet_size) +{ + // Clear key_packet contents + for (uint_fast8_t i = KEY_PACKET_KEY_INDEX; i < key_packet_size; i++) + { + key_packet[i] = KEY_PACKET_NO_KEY; + } + key_packet[KEY_PACKET_MODIFIER_KEY_INDEX] = 0; + key_packet[KEY_PACKET_RESERVED_INDEX] = 0; + + // Give priority to keys that were already pressed when we transmitted them the last time. + for (uint_fast8_t i = 0; i < m_number_of_transmitted_keys; i++) + { + for (uint_fast8_t j = 0; j < m_num_of_currently_pressed_keys; j++) + { + if (m_transmitted_keys[i] == m_currently_pressed_keys[j]) + { + cherry8x16_keypacket_addkey(m_currently_pressed_keys[j]); + break; + } + } + } + + bool fn_key_is_set = false; + + // Detect if Fn is pressed, detect modifier keys, and add rest of the keys to the packet + for (uint_fast8_t i = 0; i < m_num_of_currently_pressed_keys; i++) + { + if (m_currently_pressed_keys[i] == 0xFF) // Pressing Fn key changes function of certain keys and it must handled by the firmware + { + fn_key_is_set = true; + } + // Modifier HID usage codes are from 0xE0 to 0xE7 + else if (m_currently_pressed_keys[i] >= MODIFIER_HID_START && m_currently_pressed_keys[i] <= MODIFIER_HID_END) // Detect and set modifier keys + { + key_packet[KEY_PACKET_MODIFIER_KEY_INDEX] |= (uint8_t)(1U << (m_currently_pressed_keys[i] - MODIFIER_HID_START)); + } + else if (m_currently_pressed_keys[i] != 0) + { + cherry8x16_keypacket_addkey(m_currently_pressed_keys[i]); + } + } + + if (fn_key_is_set) + { + cherry8x16_remap_fn_keys(&key_packet[0], KEY_PACKET_MAX_KEYS); + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/cherry8x16/cherry8x16.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/cherry8x16/cherry8x16.h new file mode 100644 index 0000000000000000000000000000000000000000..52486a6629cbd122d89108e1004998397320000f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/cherry8x16/cherry8x16.h @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef CHERRY8x16_H +#define CHERRY8x16_H + +/*lint ++flb "Enter library region" */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file +* @brief Cherry 8x16 keyboard matrix driver +* +* +* @defgroup nrf_drivers_cherry8x16 Cherry 8x16 keyboard matrix driver +* @{ +* @ingroup ext_drivers +* @brief Cherry 8x16 keyboard matrix driver. +*/ + +#define CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS 6 //!< Maximum number of pressed keys kept in buffers +#define CHERRY8x16_DEFAULT_KEY_LOOKUP_MATRIX (const uint8_t*)0 //!< If passed to @ref cherry8x16_init, default lookup matrix will be used + +#define KEY_PACKET_MODIFIER_KEY_INDEX (0) //!< Index in the key packet where modifier keys such as ALT and Control are stored +#define KEY_PACKET_RESERVED_INDEX (1) //!< Index in the key packet where OEMs can store information +#define KEY_PACKET_KEY_INDEX (2) //!< Start index in the key packet where pressed keys are stored +#define KEY_PACKET_MAX_KEYS (6) //!< Maximum number of keys that can be stored into the key packet +#define KEY_PACKET_SIZE (KEY_PACKET_KEY_INDEX + KEY_PACKET_MAX_KEYS) //!< Total size of the key packet in bytes +#define KEY_PACKET_NO_KEY (0) //!< Value to be stored to key index to indicate no key is pressed + + +/** + * Describes return values for: + * @ref cherry8x16_init + */ +typedef enum +{ + CHERRY8x16_OK, /*!< Operation was succesful. */ + CHERRY8x16_NOT_DETECTED, /*!< Product/Revision ID was not what was expected */ + CHERRY8x16_INVALID_PARAMETER /*!< Given parameters were not valid */ +} cherry8x16_status_t; + +/** + * @brief Function for initializing the driver. + * + * @note Before calling this function, setup row_port as IO inputs with pulldowns enabled and column_port as IO outputs. + * + * @param row_port Pointer to GPIO port address that is used as key matrix row input. + * @param column_port Pointer to GPIO port address that is used as key matrix column output. + * @param key_lookup_matrix If NULL, use a default key lookup matrix. Otherwise pointer to a 128 (8x16) element array containing HID keycodes. + * @return + * @retval CHERRY8X16_OK Peripheral was initialized succesfully. + * @retval CHERRY8X16_NOT_DETECTED Could not detect the peripheral. + */ +cherry8x16_status_t cherry8x16_init(const uint8_t volatile * row_port, uint16_t * column_port, const uint8_t * key_lookup_matrix); + +/** + * @brief Function for creating a new key packet if new data is available and key ghosting is not detected. + * + * @param p_key_packet Array that will hold the created key packet. Previously created packet will be discarded. + * @param p_key_packet_size Key packet size in bytes. + * @return + * @retval true If new packet was created. + * @retval false If packet was not created. + */ +bool cherry8x16_new_packet(const uint8_t ** p_key_packet, uint8_t *p_key_packet_size); + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/ds1624/ds1624.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/ds1624/ds1624.c new file mode 100644 index 0000000000000000000000000000000000000000..306024d3b68da00d53e1e25fa2fad9585f6c0e50 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/ds1624/ds1624.c @@ -0,0 +1,154 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ds1624.h" +#include "twi_master.h" +#include "nrf_delay.h" + +/*lint ++flb "Enter library region" */ + +#define DS1634_BASE_ADDRESS 0x90 //!< 4 MSBs of the DS1624 TWI address + +#define DS1624_ONESHOT_MODE 0x01 //!< Bit in configuration register for 1-shot mode +#define DS1624_CONVERSION_DONE 0x80 //!< Bit in configuration register to indicate completed temperature conversion + +static uint8_t m_device_address; //!< Device address in bits [7:1] + +const uint8_t command_access_memory = 0x17; //!< Reads or writes to 256-byte EEPROM memory +const uint8_t command_access_config = 0xAC; //!< Reads or writes configuration data to configuration register +const uint8_t command_read_temp = 0xAA; //!< Reads last converted temperature value from temperature register +const uint8_t command_start_convert_temp = 0xEE; //!< Initiates temperature conversion. +const uint8_t command_stop_convert_temp = 0x22; //!< Halts temperature conversion. + +/** + * @brief Function for reading the current configuration of the sensor. + * + * @return uint8_t Zero if communication with the sensor failed. Contents (always non-zero) of configuration register (@ref DS1624_ONESHOT_MODE and @ref DS1624_CONVERSION_DONE) if communication succeeded. + */ +static uint8_t ds1624_config_read(void) +{ + uint8_t config = 0; + + // Write: command protocol + if (twi_master_transfer(m_device_address, (uint8_t*)&command_access_config, 1, TWI_DONT_ISSUE_STOP)) + { + if (twi_master_transfer(m_device_address | TWI_READ_BIT, &config, 1, TWI_ISSUE_STOP)) // Read: current configuration + { + // Read succeeded, configuration stored to variable "config" + } + else + { + // Read failed + config = 0; + } + } + + return config; +} + +bool ds1624_init(uint8_t device_address) +{ + bool transfer_succeeded = true; + m_device_address = DS1634_BASE_ADDRESS + (uint8_t)(device_address << 1); + + uint8_t config = ds1624_config_read(); + + if (config != 0) + { + // Configure DS1624 for 1SHOT mode if not done so already. + if (!(config & DS1624_ONESHOT_MODE)) + { + uint8_t data_buffer[2]; + + data_buffer[0] = command_access_config; + data_buffer[1] = DS1624_ONESHOT_MODE; + + transfer_succeeded &= twi_master_transfer(m_device_address, data_buffer, 2, TWI_ISSUE_STOP); + } + } + else + { + transfer_succeeded = false; + } + + return transfer_succeeded; +} + +bool ds1624_start_temp_conversion(void) +{ + return twi_master_transfer(m_device_address, (uint8_t*)&command_start_convert_temp, 1, TWI_ISSUE_STOP); +} + +bool ds1624_is_temp_conversion_done(void) +{ + uint8_t config = ds1624_config_read(); + + if (config & DS1624_CONVERSION_DONE) + { + return true; + } + else + { + return false; + } +} + +bool ds1624_temp_read(int8_t * temperature_in_celcius, int8_t * temperature_fraction) +{ + bool transfer_succeeded = false; + + // Write: Begin read temperature command + if (twi_master_transfer(m_device_address, (uint8_t*)&command_read_temp, 1, TWI_DONT_ISSUE_STOP)) + { + uint8_t data_buffer[2]; + + // Read: 2 temperature bytes to data_buffer + if (twi_master_transfer(m_device_address | TWI_READ_BIT, data_buffer, 2, TWI_ISSUE_STOP)) + { + *temperature_in_celcius = (int8_t)data_buffer[0]; + *temperature_fraction = (int8_t)data_buffer[1]; + + transfer_succeeded = true; + } + } + + return transfer_succeeded; +} + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/ds1624/ds1624.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/ds1624/ds1624.h new file mode 100644 index 0000000000000000000000000000000000000000..bb368a610c3e4ab1a950b4be1d186c2c71c5e95f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/ds1624/ds1624.h @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef DS1624_H +#define DS1624_H + +/*lint ++flb "Enter library region" */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file +* @brief DS1624 digital temperature sensor driver. +* +* +* @defgroup nrf_drivers_ds1624 DS1624 digital temperature sensor driver +* @{ +* @ingroup ext_drivers +* @brief DS1624 digital temperature sensor driver. +*/ + +/** + * @brief Function for initializing DS1624 temperature sensor to 1-shot mode. + * + * @note Before calling this function, you must initialize twi_master first. + * + * @param device_address Bits [2:0] for the device address. All other bits must be zero. + * @return + * @retval true If communication succeeded with the device. + * @retval false If communication failed with the device. + */ +bool ds1624_init(uint8_t device_address); + +/** + * @brief Function for reading temperature from the sensor. + * + * @param temperature_in_celcius Memory location to store temperature in full celcius degrees. + * @param temperature_fraction Memory location to store temperature's fraction part in 0.03125 celcius degree increments. + * @return + * @retval true Temperature was successfully read + * @retval false Temperature reading failed or conversion was not yet complete + */ +bool ds1624_temp_read(int8_t *temperature_in_celcius, int8_t *temperature_fraction); + +/** + * @brief Function for starting temperature conversion. Valid data will be available 400 - 1000 milliseconds after exiting this function. + * + * @return + * @retval true Temperature conversion started. + * @retval false Temperature converion failed to start. +*/ +bool ds1624_start_temp_conversion(void); + +/** + * @brief Function for checking if temperature conversion is done. + * + * @return + * @retval true Temperature conversion done. + * @retval false Temperature converion still in progress. +*/ +bool ds1624_is_temp_conversion_done(void); + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/ili9341/ili9341.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/ili9341/ili9341.c new file mode 100644 index 0000000000000000000000000000000000000000..6e834d45bda77302f50db7a90e5295155227b418 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/ili9341/ili9341.c @@ -0,0 +1,397 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" + +#if NRF_MODULE_ENABLED(ILI9341) + +#include "nrf_lcd.h" +#include "nrf_drv_spi.h" +#include "nrf_delay.h" +#include "nrf_gpio.h" +#include "boards.h" + +// Set of commands described in ILI9341 datasheet. +#define ILI9341_NOP 0x00 +#define ILI9341_SWRESET 0x01 +#define ILI9341_RDDID 0x04 +#define ILI9341_RDDST 0x09 + +#define ILI9341_SLPIN 0x10 +#define ILI9341_SLPOUT 0x11 +#define ILI9341_PTLON 0x12 +#define ILI9341_NORON 0x13 + +#define ILI9341_RDMODE 0x0A +#define ILI9341_RDMADCTL 0x0B +#define ILI9341_RDPIXFMT 0x0C +#define ILI9341_RDIMGFMT 0x0D +#define ILI9341_RDSELFDIAG 0x0F + +#define ILI9341_INVOFF 0x20 +#define ILI9341_INVON 0x21 +#define ILI9341_GAMMASET 0x26 +#define ILI9341_DISPOFF 0x28 +#define ILI9341_DISPON 0x29 + +#define ILI9341_CASET 0x2A +#define ILI9341_PASET 0x2B +#define ILI9341_RAMWR 0x2C +#define ILI9341_RAMRD 0x2E + +#define ILI9341_PTLAR 0x30 +#define ILI9341_MADCTL 0x36 +#define ILI9341_PIXFMT 0x3A + +#define ILI9341_FRMCTR1 0xB1 +#define ILI9341_FRMCTR2 0xB2 +#define ILI9341_FRMCTR3 0xB3 +#define ILI9341_INVCTR 0xB4 +#define ILI9341_DFUNCTR 0xB6 + +#define ILI9341_PWCTR1 0xC0 +#define ILI9341_PWCTR2 0xC1 +#define ILI9341_PWCTR3 0xC2 +#define ILI9341_PWCTR4 0xC3 +#define ILI9341_PWCTR5 0xC4 +#define ILI9341_VMCTR1 0xC5 +#define ILI9341_VMCTR2 0xC7 +#define ILI9341_PWCTRSEQ 0xCB +#define ILI9341_PWCTRA 0xCD +#define ILI9341_PWCTRB 0xCF + +#define ILI9341_RDID1 0xDA +#define ILI9341_RDID2 0xDB +#define ILI9341_RDID3 0xDC +#define ILI9341_RDID4 0xDD + +#define ILI9341_GMCTRP1 0xE0 +#define ILI9341_GMCTRN1 0xE1 +#define ILI9341_DGMCTR1 0xE2 +#define ILI9341_DGMCTR2 0xE3 +#define ILI9341_TIMCTRA 0xE8 +#define ILI9341_TIMCTRB 0xEA + +#define ILI9341_ENGMCTR 0xF2 +#define ILI9341_INCTR 0xF6 +#define ILI9341_PUMP 0xF7 + +#define ILI9341_MADCTL_MY 0x80 +#define ILI9341_MADCTL_MX 0x40 +#define ILI9341_MADCTL_MV 0x20 +#define ILI9341_MADCTL_ML 0x10 +#define ILI9341_MADCTL_RGB 0x00 +#define ILI9341_MADCTL_BGR 0x08 +#define ILI9341_MADCTL_MH 0x04 + +static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(ILI9341_SPI_INSTANCE); + +static inline void spi_write(const void * data, size_t size) +{ + APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, data, size, NULL, 0)); +} + +static inline void write_command(uint8_t c) +{ + nrf_gpio_pin_clear(ILI9341_DC_PIN); + spi_write(&c, sizeof(c)); +} + +static inline void write_data(uint8_t c) +{ + nrf_gpio_pin_set(ILI9341_DC_PIN); + spi_write(&c, sizeof(c)); +} + +static void set_addr_window(uint16_t x_0, uint16_t y_0, uint16_t x_1, uint16_t y_1) +{ + ASSERT(x_0 < x_1); + ASSERT(y_0 < y_1); + + write_command(ILI9341_CASET); + write_data(x_0 >> 8); + write_data(x_0); + write_data(x_1 >> 8); + write_data(x_1); + write_command(ILI9341_PASET); + write_data(y_0 >> 8); + write_data(y_0); + write_data(y_1 >> 8); + write_data(y_1); + write_command(ILI9341_RAMWR); +} + +static void command_list(void) +{ + write_command(ILI9341_PWCTRB); + write_data(0x00); + write_data(0XC1); + write_data(0X30); + + write_command(ILI9341_TIMCTRA); + write_data(0x85); + write_data(0x00); + write_data(0x78); + + write_command(ILI9341_PWCTRSEQ); + write_data(0x39); + write_data(0x2C); + write_data(0x00); + write_data(0x34); + write_data(0x02); + + write_command(ILI9341_PUMP); + write_data(0x20); + + write_command(ILI9341_TIMCTRB); + write_data(0x00); + write_data(0x00); + + write_command(ILI9341_PWCTR1); + write_data(0x23); + + write_command(ILI9341_PWCTR2); + write_data(0x10); + + write_command(ILI9341_VMCTR1); + write_data(0x3e); + write_data(0x28); + + write_command(ILI9341_VMCTR2); + write_data(0x86); + + write_command(ILI9341_MADCTL); + write_data(0x48); + + write_command(ILI9341_PIXFMT); + write_data(0x55); + + write_command(ILI9341_FRMCTR1); + write_data(0x00); + write_data(0x18); + + write_command(ILI9341_DFUNCTR); + write_data(0x08); + write_data(0x82); + write_data(0x27); + + write_command(ILI9341_ENGMCTR); + write_data(0x00); + + write_command(ILI9341_GAMMASET); + write_data(0x01); + + write_command(ILI9341_GMCTRP1); + write_data(0x0F); + write_data(0x31); + write_data(0x2B); + write_data(0x0C); + write_data(0x0E); + write_data(0x08); + write_data(0x4E); + write_data(0xF1); + write_data(0x37); + write_data(0x07); + write_data(0x10); + write_data(0x03); + write_data(0x0E); + write_data(0x09); + write_data(0x00); + + write_command(ILI9341_GMCTRN1); + write_data(0x00); + write_data(0x0E); + write_data(0x14); + write_data(0x03); + write_data(0x11); + write_data(0x07); + write_data(0x31); + write_data(0xC1); + write_data(0x48); + write_data(0x08); + write_data(0x0F); + write_data(0x0C); + write_data(0x31); + write_data(0x36); + write_data(0x0F); + + write_command(ILI9341_SLPOUT); + nrf_delay_ms(120); + write_command(ILI9341_DISPON); +} + +static ret_code_t hardware_init(void) +{ + ret_code_t err_code; + + nrf_gpio_cfg_output(ILI9341_DC_PIN); + + nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; + + spi_config.sck_pin = ILI9341_SCK_PIN; + spi_config.miso_pin = ILI9341_MISO_PIN; + spi_config.mosi_pin = ILI9341_MOSI_PIN; + spi_config.ss_pin = ILI9341_SS_PIN; + + err_code = nrf_drv_spi_init(&spi, &spi_config, NULL, NULL); + return err_code; +} + +static ret_code_t ili9341_init(void) +{ + ret_code_t err_code; + + err_code = hardware_init(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + command_list(); + + return err_code; +} + +static void ili9341_uninit(void) +{ + nrf_drv_spi_uninit(&spi); +} + +static void ili9341_pixel_draw(uint16_t x, uint16_t y, uint32_t color) +{ + set_addr_window(x, y, x, y); + + const uint8_t data[2] = {color >> 8, color}; + + nrf_gpio_pin_set(ILI9341_DC_PIN); + + spi_write(data, sizeof(data)); + + nrf_gpio_pin_clear(ILI9341_DC_PIN); +} + +static void ili9341_rect_draw(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color) +{ + set_addr_window(x, y, x + width - 1, y + height - 1); + + const uint8_t data[2] = {color >> 8, color}; + + nrf_gpio_pin_set(ILI9341_DC_PIN); + + // Duff's device algorithm for optimizing loop. + uint32_t i = (height * width + 7) / 8; + +/*lint -save -e525 -e616 -e646 */ + switch ((height * width) % 8) { + case 0: + do { + spi_write(data, sizeof(data)); + case 7: + spi_write(data, sizeof(data)); + case 6: + spi_write(data, sizeof(data)); + case 5: + spi_write(data, sizeof(data)); + case 4: + spi_write(data, sizeof(data)); + case 3: + spi_write(data, sizeof(data)); + case 2: + spi_write(data, sizeof(data)); + case 1: + spi_write(data, sizeof(data)); + } while (--i > 0); + default: + break; + } +/*lint -restore */ + + nrf_gpio_pin_clear(ILI9341_DC_PIN); +} + +static void ili9341_dummy_display(void) +{ + /* No implementation needed. */ +} + +static void ili9341_rotation_set(nrf_lcd_rotation_t rotation) +{ + write_command(ILI9341_MADCTL); + switch (rotation) { + case NRF_LCD_ROTATE_0: + write_data(ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR); + break; + case NRF_LCD_ROTATE_90: + write_data(ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR); + break; + case NRF_LCD_ROTATE_180: + write_data(ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR); + break; + case NRF_LCD_ROTATE_270: + write_data(ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR); + break; + default: + break; + } +} + +static void ili9341_display_invert(bool invert) +{ + write_command(invert ? ILI9341_INVON : ILI9341_INVOFF); +} + +static lcd_cb_t ili9341_cb = { + .height = ILI9341_HEIGHT, + .width = ILI9341_WIDTH +}; + + +const nrf_lcd_t nrf_lcd_ili9341 = { + .lcd_init = ili9341_init, + .lcd_uninit = ili9341_uninit, + .lcd_pixel_draw = ili9341_pixel_draw, + .lcd_rect_draw = ili9341_rect_draw, + .lcd_display = ili9341_dummy_display, + .lcd_rotation_set = ili9341_rotation_set, + .lcd_display_invert = ili9341_display_invert, + .p_lcd_cb = &ili9341_cb +}; + +#endif // NRF_MODULE_ENABLED(ILI9341) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/max9850/max9850.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/max9850/max9850.c new file mode 100644 index 0000000000000000000000000000000000000000..152e83d356b7f1b01d2bd6896586d7bd4b9b7080 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/max9850/max9850.c @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "max9850.h" + +#include + +ret_code_t max9850_init(max9850_config_t const * p_max9850) +{ + ret_code_t ret = NRF_SUCCESS; + + ret = nrf_drv_twi_init(&p_max9850->twi, &p_max9850->twi_cfg, NULL, NULL); + if (ret != NRF_SUCCESS) + { + return ret; + } + + nrf_drv_twi_enable(&p_max9850->twi); + + /*Probe device*/ + uint8_t rx[] = {0}; + ret = nrf_drv_twi_rx(&p_max9850->twi, p_max9850->twi_addr, rx, sizeof(rx)); + if (ret != NRF_SUCCESS) + { + return ret; + } + + uint8_t regs[sizeof(max9850_regmap_t) + 1]; + + regs[0] = 0x00; + memcpy(regs + 1, &p_max9850->regmap, sizeof(max9850_regmap_t)); + + /*Write configuration*/ + return nrf_drv_twi_tx(&p_max9850->twi, p_max9850->twi_addr, regs, sizeof(regs), false); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/max9850/max9850.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/max9850/max9850.h new file mode 100644 index 0000000000000000000000000000000000000000..a460c0a11443a9764e8fc98d301f7f515d523793 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/max9850/max9850.h @@ -0,0 +1,130 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAX9850_H__ +#define MAX9850_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "nrf_drv_twi.h" + +/** + * @brief Default MAX9850 TWI configuration + * + * @param scl_pin SCL pin number + * @param sda_pin SDA pin number + */ +#define MAX9850_DEFAULT_TWI_CONFIG(scl_pin, sda_pin) { \ + .scl = scl_pin, \ + .sda = sda_pin, \ + .frequency = NRF_TWI_FREQ_100K, \ + .interrupt_priority = APP_IRQ_PRIORITY_HIGH, \ + .clear_bus_init = false, \ + .hold_bus_uninit = false \ +} + +/** + * @brief Internal MAX9850 register map + * */ +typedef struct { + uint8_t status_a; //!< Status register A (R) + uint8_t status_b; //!< Status register B (R) + uint8_t volume; //!< Volume control (RW) + uint8_t general_purpose; //!< General purpose register (RW) + uint8_t interrupt_enable; //!< Interrupt enable (RW) + uint8_t enable; //!< Enable register (RW) + uint8_t clock; //!< Clock control (RW) + uint8_t charge_pump; //!< Charge pump (RW) + uint8_t lrclk_msb; //!< LRCLK MSB register (RW) + uint8_t lrclk_lsb; //!< LRCLK LSB register (RW) + uint8_t digital_audio; //!< Digital audio (RW) +} max9850_regmap_t; + +/** + * @brief MAX9850 register map after reset + * */ +#define MAX9850_DEFAULT_REGMAP() { \ + .status_a = 0, \ + .status_b = 0, \ + .volume = 0x0C, \ + .general_purpose = 0, \ + .interrupt_enable = 0, \ + .enable = 0, \ + .clock = 0, \ + .charge_pump = 0, \ + .lrclk_msb = 0, \ + .lrclk_lsb = 0, \ + .digital_audio = 0, \ +} + +/** + * @brief Helper macro for creating MAX9850 TWI address + * */ +#define MAX9850_TWI_ADDR(v) (0x10 + (v)) + + +/** + * @brief MAX9850 configuration + * */ +typedef struct { + nrf_drv_twi_t twi; //!< TWI instance + nrf_drv_twi_config_t twi_cfg; //!< TWI configuration + max9850_regmap_t regmap; //!< MAX9850 register map + uint8_t twi_addr; //!< MAX9850 TWI address +} max9850_config_t; + +/** + * @brief Initializes MAX9850 IC + * + * @param p_max9850 MAX9850 configuration + * + * @return Standard error code + * */ +ret_code_t max9850_init(max9850_config_t const * p_max9850); + + +#ifdef __cplusplus +} +#endif + +#endif /* MAX9850_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/mcp4725/mcp4725.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/mcp4725/mcp4725.c new file mode 100644 index 0000000000000000000000000000000000000000..d0fb318842a360ad52edb82eb693e089b501ec9b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/mcp4725/mcp4725.c @@ -0,0 +1,156 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "mcp4725.h" +#include "nrf_drv_twi.h" +#include "nrf_delay.h" +#include "boards.h" +#include "app_util_platform.h" + +/*lint ++flb "Enter library region" */ +#define MCP4725_BASE_ADDRESS 0x60 //!< MCP4725 base address + +#define MCP4725_DAC_ADDRESS 0x40 //!< MCP4725 write-to-dac register +#define MCP4725_EEPROM_ADDRESS 0x60 //!< MCP4725 write-to-eeprom register + +#define RDY_BIT_POS 0x07 //!< Position of RDY bit + +/* TWI instance. */ +static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID_USED); + +/* Twi transfer indicators. */ +volatile bool m_xfer_done = false; +volatile bool m_read_done = false; + +/** + * @brief TWI events handler. + */ +static void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context) +{ + switch (p_event->type) + { + case NRF_DRV_TWI_EVT_DONE: + if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX) + { + m_xfer_done = true; + } + if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX) + { + m_read_done = true; + } + break; + default: + break; + } +} + +/** + * @brief TWI initialization. + * + * @param[in] p_pins_config Pointer to structere holding pins numbers to be used by TWI. + */ +static ret_code_t twi_init(mcp4725_pins_config_t const * p_pins_config) +{ + ret_code_t err_code; + + const nrf_drv_twi_config_t twi_mcp4725_config = { + .scl = p_pins_config->scl_pin, + .sda = p_pins_config->sda_pin, + .frequency = NRF_TWI_FREQ_100K, + .interrupt_priority = APP_IRQ_PRIORITY_HIGH, + .clear_bus_init = false + }; + + err_code = nrf_drv_twi_init(&m_twi, &twi_mcp4725_config, twi_handler, NULL); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + nrf_drv_twi_enable(&m_twi); + return NRF_SUCCESS; +} + +ret_code_t mcp4725_setup(mcp4725_pins_config_t const * p_pins_config) +{ + ret_code_t err_code = twi_init(p_pins_config); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + return NRF_SUCCESS; +} + +ret_code_t mcp4725_set_voltage(uint16_t val, bool write_eeprom) +{ + /* Shift parameter val to get 2 8-bits values. */ + uint8_t reg[3] = {write_eeprom ? MCP4725_EEPROM_ADDRESS : MCP4725_DAC_ADDRESS, + (val>>4), (val<<4)}; + + m_xfer_done = false; + + ret_code_t err_code = nrf_drv_twi_tx(&m_twi, MCP4725_BASE_ADDRESS, reg, sizeof(reg), false); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + while (m_xfer_done == false); + + return NRF_SUCCESS; +} + +bool mcp4725_is_busy(void) +{ + uint8_t busy; + m_read_done = false; + + ret_code_t err_code = nrf_drv_twi_rx(&m_twi, MCP4725_BASE_ADDRESS, &busy, sizeof(busy)); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + while (m_read_done == false); + + return (bool)(!(busy >> RDY_BIT_POS)); +} + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/mcp4725/mcp4725.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/mcp4725/mcp4725.h new file mode 100644 index 0000000000000000000000000000000000000000..8a7ca79ef758e16e32b07db804ed5a1d2b175e0b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/mcp4725/mcp4725.h @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MCP4725_H +#define MCP4725_H + +/*lint ++flb "Enter library region" */ + +#include +#include +#include "app_util_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file +* @brief MCP4725 digital DAC driver. +* +* +* @defgroup mcp4725 MCP4725 digital DAC driver +* @{ +* @ingroup ext_drivers +* @brief MCP4725 digital DAC driver. +*/ + +typedef struct +{ + uint8_t scl_pin; + uint8_t sda_pin; +}mcp4725_pins_config_t; + +/** + * @brief Function for setting up the driver. + * + * @param[in] p_pins_config Pointer to structere holding pins numbers to be used by TWI. + * + * @return Values returned by @ref nrf_drv_twi_init. + */ +ret_code_t mcp4725_setup(mcp4725_pins_config_t const * p_pins_config); + + +/** + * @brief Function for setting new value to DAC. + * + * @param[in] val 12-bit value. Base on it voltage is set (Vout = (val/4095) * Vcc). + * @param[in] write_eeprom Defines if value will be written to DAC only or to EEPROM memmory also. + * + * @return Values returned by @ref nrf_drv_twi_tx. + */ +ret_code_t mcp4725_set_voltage(uint16_t val, bool write_eeprom); + +/** + * @brief Function for checking if DAC is busy saving data in EEPROM. + * + * @retval true If DAC is busy. + * @retval false If Dac is not busy. + */ +bool mcp4725_is_busy(void); + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + +#endif //MCP4725_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/mpu6050/mpu6050.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/mpu6050/mpu6050.c new file mode 100644 index 0000000000000000000000000000000000000000..7846736fea4646b3247115ae82f05f006c2ed570 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/mpu6050/mpu6050.c @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include + +#include "twi_master.h" +#include "mpu6050.h" + +/*lint ++flb "Enter library region" */ + +#define ADDRESS_WHO_AM_I (0x75U) // !< WHO_AM_I register identifies the device. Expected value is 0x68. +#define ADDRESS_SIGNAL_PATH_RESET (0x68U) // !< + +static const uint8_t expected_who_am_i = 0x68U; // !< Expected value to get from WHO_AM_I register. +static uint8_t m_device_address; // !< Device address in bits [7:1] + +bool mpu6050_init(uint8_t device_address) +{ + bool transfer_succeeded = true; + + m_device_address = (uint8_t)(device_address << 1); + + // Do a reset on signal paths + uint8_t reset_value = 0x04U | 0x02U | 0x01U; // Resets gyro, accelerometer and temperature sensor signal paths. + transfer_succeeded &= mpu6050_register_write(ADDRESS_SIGNAL_PATH_RESET, reset_value); + + // Read and verify product ID + transfer_succeeded &= mpu6050_verify_product_id(); + + return transfer_succeeded; +} + +bool mpu6050_verify_product_id(void) +{ + uint8_t who_am_i; + + if (mpu6050_register_read(ADDRESS_WHO_AM_I, &who_am_i, 1)) + { + if (who_am_i != expected_who_am_i) + { + return false; + } + else + { + return true; + } + } + else + { + return false; + } +} + +bool mpu6050_register_write(uint8_t register_address, uint8_t value) +{ + uint8_t w2_data[2]; + + w2_data[0] = register_address; + w2_data[1] = value; + return twi_master_transfer(m_device_address, w2_data, 2, TWI_ISSUE_STOP); +} + +bool mpu6050_register_read(uint8_t register_address, uint8_t * destination, uint8_t number_of_bytes) +{ + bool transfer_succeeded; + transfer_succeeded = twi_master_transfer(m_device_address, ®ister_address, 1, TWI_DONT_ISSUE_STOP); + transfer_succeeded &= twi_master_transfer(m_device_address|TWI_READ_BIT, destination, number_of_bytes, TWI_ISSUE_STOP); + return transfer_succeeded; +} + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/mpu6050/mpu6050.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/mpu6050/mpu6050.h new file mode 100644 index 0000000000000000000000000000000000000000..fb3bfc32030bebc24a37328276b83bd0a4a3f635 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/mpu6050/mpu6050.h @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MPU6050_H +#define MPU6050_H + +/*lint ++flb "Enter library region" */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file +* @brief MPU6050 gyro/accelerometer driver. +* +* +* @defgroup nrf_drivers_mpu6050 MPU6050 gyro/accelerometer driver +* @{ +* @ingroup ext_drivers +* @brief MPU6050 gyro/accelerometer driver. +*/ + +/** + * @brief Function for initializing MPU6050 and verifies it's on the bus. + * + * @param device_address Device TWI address in bits [6:0]. + * @return + * @retval true MPU6050 found on the bus and ready for operation. + * @retval false MPU6050 not found on the bus or communication failure. + */ +bool mpu6050_init(uint8_t device_address); + +/** + @brief Function for writing a MPU6050 register contents over TWI. + @param[in] register_address Register address to start writing to + @param[in] value Value to write to register + @retval true Register write succeeded + @retval false Register write failed +*/ +bool mpu6050_register_write(uint8_t register_address, const uint8_t value); + +/** + @brief Function for reading MPU6050 register contents over TWI. + Reads one or more consecutive registers. + @param[in] register_address Register address to start reading from + @param[in] number_of_bytes Number of bytes to read + @param[out] destination Pointer to a data buffer where read data will be stored + @retval true Register read succeeded + @retval false Register read failed +*/ +bool mpu6050_register_read(uint8_t register_address, uint8_t *destination, uint8_t number_of_bytes); + +/** + @brief Function for reading and verifying MPU6050 product ID. + @retval true Product ID is what was expected + @retval false Product ID was not what was expected +*/ +bool mpu6050_verify_product_id(void); + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ + + +#ifdef __cplusplus +} +#endif + +#endif /* MPU6050_H */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/nrf6350/nrf6350.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/nrf6350/nrf6350.c new file mode 100644 index 0000000000000000000000000000000000000000..0999c5ed51e209e66005d2bcc50409523e9ee968 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/nrf6350/nrf6350.c @@ -0,0 +1,305 @@ +/** + * Copyright (c) 2008 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf6350.h" +#include "nrf_delay.h" +#include "twi_master.h" + +/*lint ++flb "Enter library region" */ + +#define DDRAM_ADR 0x80 //!< Write to DDRAM AC +#define DDRAM_WR 0x40 //!< Write to DDRAM +#define FUNC_SET 0x00 //!< Enter LCD Function settings +#define LCD_ADDR 0x3E //!< LCD display adr +#define JS_ADDR 0x3F //!< Joystick adr + +#define X 0 //!< X direction in pos 0 of joystick array +#define Y 1 //!< Y direction in pos 1 of joystick array + + +//static void nrf6350_nrf6350_lcd_set_instruction(uint8_t instr); + +#define BUF_LEN 32 //!< LCD data buffer length +static uint8_t data_buffer[BUF_LEN]; //!< LCD data buffer +static uint8_t empty_str[18] = {DDRAM_WR, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}; //!< Blank line + + +static bool nrf6350_lcd_set_instruction(uint8_t instr) +{ + nrf_delay_us(10000); + data_buffer[0] = FUNC_SET; + data_buffer[1] = instr; + return twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP); +} + +bool nrf6350_lcd_clear(void) +{ + nrf_delay_us(10000); + data_buffer[0] = FUNC_SET; + data_buffer[1] = (uint8_t)(DDRAM_ADR + LCD_UPPER_LINE); + if (!twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP)) + return false; + if (!twi_master_transfer(LCD_ADDR << 1, empty_str, 18, TWI_ISSUE_STOP)) + { + return false; + } + data_buffer[1] = DDRAM_ADR + LCD_LOWER_LINE; + if (!twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP)) + return false; + if (!twi_master_transfer(LCD_ADDR << 1, empty_str, 18, TWI_ISSUE_STOP)) + return false; + return true; +} + +bool nrf6350_lcd_set_contrast(uint8_t contrast) +{ + nrf_delay_us(10000); + data_buffer[0] = FUNC_SET; + data_buffer[1] = 0x70 | contrast; + return twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP); +} + +bool nrf6350_lcd_on(void) +{ + nrf_delay_us(10000); + data_buffer[0] = FUNC_SET; + data_buffer[1] = 0x0C; + return twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP); +} + +bool nrf6350_lcd_off(void) +{ + nrf_delay_us(10000); + data_buffer[0] = FUNC_SET; + data_buffer[1] = 0x08; + return twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP); +} + +bool nrf6350_lcd_init(void) +{ + if (!twi_master_init()) + { + return false; + } + + // Sometimes the first command doesn't get through, so we'll try + // sending non-important "wake up" command first and don't care if it fails. + (void)nrf6350_lcd_wake_up(); + + if (!nrf6350_lcd_set_instruction(0x38)) // Function set. + return false; + if (!nrf6350_lcd_set_instruction(0x39)) // Choose two-line mode. + return false; + if (!nrf6350_lcd_set_instruction(0x14)) // Internal OSC frequency. + return false; + if (!nrf6350_lcd_set_contrast(LCD_CONTRAST_HIGH)) // Contrast set (low byte). + return false; + if (!nrf6350_lcd_set_instruction(0x5F)) // Power/ICON control/. + return false; + if (!nrf6350_lcd_set_instruction(0x6A)) // Follower control. + return false; + nrf_delay_us(200000); // Need to wait 200ms here according to datasheet. + if (!nrf6350_lcd_on()) // Display ON. + return false; + if (!nrf6350_lcd_clear()) // Clear display. + return false; + return nrf6350_lcd_set_instruction(0x06); // Entry mode set. +} + +bool nrf6350_lcd_write_string(const char *p_text, uint8_t size, uint8_t line, uint8_t pos) +{ + uint8_t i; + + data_buffer[0] = FUNC_SET; + data_buffer[1] = DDRAM_ADR + (pos + line); + if (!twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP)) + return false; + if (!twi_master_transfer(LCD_ADDR << 1, empty_str, 18 - pos, TWI_ISSUE_STOP)) + return false; + data_buffer[0] = FUNC_SET; + data_buffer[1] = DDRAM_ADR + (pos + line); + if (!twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP)) + return false; + data_buffer[0] = DDRAM_WR; + for (i=0;iTXD = *data++; + NRF_TWI1->TASKS_STARTTX = 1; + + /** @snippet [TWI HW master write] */ + while (true) + { + while (NRF_TWI1->EVENTS_TXDSENT == 0 && (--timeout)) + { + // Do nothing. + } + + if (timeout == 0) + { + NRF_TWI1->EVENTS_STOPPED = 0; + NRF_TWI1->TASKS_STOP = 1; + + /* Wait until stop sequence is sent */ + while (NRF_TWI1->EVENTS_STOPPED == 0) + { + // Do nothing. + } + + /* Timeout before receiving event*/ + return false; + } + + NRF_TWI1->EVENTS_TXDSENT = 0; + if (--data_length == 0) + { + break; + } + + NRF_TWI1->TXD = *data++; + } + /** @snippet [TWI HW master write] */ + + if (issue_stop_condition) + { + NRF_TWI1->EVENTS_STOPPED = 0; + NRF_TWI1->TASKS_STOP = 1; + + /* Wait until stop sequence is sent */ + while (NRF_TWI1->EVENTS_STOPPED == 0) + { + // Do nothing. + } + } + return true; +} + +/** @brief Function for transfer by twi_master. + */ +bool nrf6350_lcd_wake_up(void) +{ + uint8_t address = (LCD_ADDR << 1); + uint8_t dummy_data[] = {0, 0, 0, 0}; + uint8_t dummy_data_length = 4; + bool issue_stop_condition = 0; + bool transfer_succeeded = false; + + NRF_TWI1->ADDRESS = (address >> 1); + + transfer_succeeded = nrf6350_lcd_write_without_recovery(dummy_data, + dummy_data_length, + issue_stop_condition); + + NRF_TWI1->EVENTS_ERROR = 0; + + return transfer_succeeded; +} + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/nrf6350/nrf6350.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/nrf6350/nrf6350.h new file mode 100644 index 0000000000000000000000000000000000000000..93c3b221049f22fe52a8308f75ca4cb35a117317 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/nrf6350/nrf6350.h @@ -0,0 +1,154 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF6350_H_ +#define NRF6350_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define LCD_LLEN 16 //!< LCD Line length + +#define JS_BUTTON_NONE 0x00 //!< Joystick not touched +#define JS_BUTTON_LEFT 0x01 //!< joystick pulled left +#define JS_BUTTON_PUSH 0x02 //!< joystick pushed +#define JS_BUTTON_DOWN 0x04 //!< joystick pulled down +#define JS_BUTTON_UP 0x08 //!< joystick pulled up +#define JS_BUTTON_RIGHT 0x10 //!< joystick pulled right +#define LCD_UPPER_LINE 0x00 //!< LCD upper line +#define LCD_LOWER_LINE 0x40 //!< LCD lower line +#define LCD_CONTRAST_LOW 0x00 //!< LCD Low contrast +#define LCD_CONTRAST_MEDIUM 0x02 //!< LCD Medium contrast +#define LCD_CONTRAST_HIGH 0x08 //!< LCD High contrast + + +/** + * @brief Function for initializing the LCD display prior to writing. + * @return + * @retval true Operation succeeded + * @retval false Operation failed + */ +bool nrf6350_lcd_init(void); + +/** + * @brief Function for writing a text string on the LCD-display. + * + * @param p_text A pointer to the text string to be written + * @param size Size of the text string to be written + * @param line The line the text should be written to + * @param pos The start position of the text on the line + * @return + * @retval true Write succeeded + * @retval false Write failed + */ +bool nrf6350_lcd_write_string(const char *p_text, uint8_t size, uint8_t line, uint8_t pos); + +/** + * @brief Function for clearing the contents of the LCD-display. + * + * @return + * @retval true Operation succeeded + * @retval false Operation failed + */ +bool nrf6350_lcd_clear(void); + +/** + * @brief Function for adjusting the contrast of the LCD-display, select between + * LCD_CONTRAST_LOW, LCD_CONTRAST_MEDIUM and LCD_CONTRAST_HIGH. + * + * @param contrast The desired contrast of the lcd display + * @return + * @retval true Operation succeeded + * @retval false Operation failed + */ +bool nrf6350_lcd_set_contrast(uint8_t contrast); + +/** + * @brief Function for turning ON the LCD-display. + * + * @return + * @retval true Operation succeeded + * @retval false Operation failed + */ +bool nrf6350_lcd_on(void); + +/** + * @brief Function for turning OFF the LCD-display. + * + * @return + * @retval true Operation succeeded + * @retval false Operation failed + */ +bool nrf6350_lcd_off(void); + +/** + * @brief Function for getting the position of the joystick. + * + * @param val pointer to a 2 byte array where the X,Y position is stored + * @return + * @retval true Operation succeeded + * @retval false Operation failed + */ +bool nrf6350_js_get_value(int8_t *val); + +/** + * @brief Function for getting the status of the joystick. + * + * @param js_state pointer to a uint8_t that receives the status of the joystick + * @return + * @retval true Operation succeeded + * @retval false Operation failed + */ +bool nrf6350_js_get_status(uint8_t *js_state); + +/** @brief Function for transferring data over TWI bus. Used the first time you want to communicate nRF6350 to bypass a fail. + */ +bool nrf6350_lcd_wake_up(void); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF6350_H_ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/st7735/st7735.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/st7735/st7735.c new file mode 100644 index 0000000000000000000000000000000000000000..8a45a2bce45a6dc13b63aa245da305e97ad07ca4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/st7735/st7735.c @@ -0,0 +1,474 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" + +#if NRF_MODULE_ENABLED(ST7735) + +#include "nrf_lcd.h" +#include "nrf_drv_spi.h" +#include "nrf_delay.h" +#include "nrf_gpio.h" +#include "boards.h" + +// Set of commands described in ST7735 data sheet. +#define ST7735_NOP 0x00 +#define ST7735_SWRESET 0x01 +#define ST7735_RDDID 0x04 +#define ST7735_RDDST 0x09 + +#define ST7735_SLPIN 0x10 +#define ST7735_SLPOUT 0x11 +#define ST7735_PTLON 0x12 +#define ST7735_NORON 0x13 + +#define ST7735_INVOFF 0x20 +#define ST7735_INVON 0x21 +#define ST7735_DISPOFF 0x28 +#define ST7735_DISPON 0x29 +#define ST7735_CASET 0x2A +#define ST7735_RASET 0x2B +#define ST7735_RAMWR 0x2C +#define ST7735_RAMRD 0x2E + +#define ST7735_PTLAR 0x30 +#define ST7735_COLMOD 0x3A +#define ST7735_MADCTL 0x36 + +#define ST7735_FRMCTR1 0xB1 +#define ST7735_FRMCTR2 0xB2 +#define ST7735_FRMCTR3 0xB3 +#define ST7735_INVCTR 0xB4 +#define ST7735_DISSET5 0xB6 + +#define ST7735_PWCTR1 0xC0 +#define ST7735_PWCTR2 0xC1 +#define ST7735_PWCTR3 0xC2 +#define ST7735_PWCTR4 0xC3 +#define ST7735_PWCTR5 0xC4 +#define ST7735_VMCTR1 0xC5 + +#define ST7735_RDID1 0xDA +#define ST7735_RDID2 0xDB +#define ST7735_RDID3 0xDC +#define ST7735_RDID4 0xDD + +#define ST7735_PWCTR6 0xFC + +#define ST7735_GMCTRP1 0xE0 +#define ST7735_GMCTRN1 0xE1 + +#define ST7735_MADCTL_MY 0x80 +#define ST7735_MADCTL_MX 0x40 +#define ST7735_MADCTL_MV 0x20 +#define ST7735_MADCTL_ML 0x10 +#define ST7735_MADCTL_RGB 0x00 +#define ST7735_MADCTL_BGR 0x08 +#define ST7735_MADCTL_MH 0x04 +/* @} */ + +#define RGB2BGR(x) (x << 11) | (x & 0x07E0) | (x >> 11) + +static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(ST7735_SPI_INSTANCE); /**< SPI instance. */ + +/** + * @brief Structure holding ST7735 controller basic parameters. + */ +typedef struct +{ + uint8_t tab_color; /**< Color of tab attached to the used screen. */ +}st7735_t; + +/** + * @brief Enumerator with TFT tab colors. + */ +typedef enum{ + INITR_GREENTAB = 0, /**< Green tab. */ + INITR_REDTAB, /**< Red tab. */ + INITR_BLACKTAB, /**< Black tab. */ + INITR_144GREENTAB /**< Green tab, 1.44" display. */ +}st7735_tab_t; + +static st7735_t m_st7735; + +static inline void spi_write(const void * data, size_t size) +{ + APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, data, size, NULL, 0)); +} + +static inline void write_command(uint8_t c) +{ + nrf_gpio_pin_clear(ST7735_DC_PIN); + spi_write(&c, sizeof(c)); +} + +static inline void write_data(uint8_t c) +{ + nrf_gpio_pin_set(ST7735_DC_PIN); + spi_write(&c, sizeof(c)); +} + +static void set_addr_window(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) +{ + ASSERT(x0 < x1); + ASSERT(y0 < y1); + + write_command(ST7735_CASET); + write_data(0x00); // For a 128x160 display, it is always 0. + write_data(x0); + write_data(0x00); // For a 128x160 display, it is always 0. + write_data(x1); + write_command(ST7735_RASET); + write_data(0x00); // For a 128x160 display, it is always 0. + write_data(y0); + write_data(0x00); // For a 128x160 display, it is always 0. + write_data(y1); + write_command(ST7735_RAMWR); +} + +static void command_list(void) +{ + write_command(ST7735_SWRESET); + nrf_delay_ms(150); + write_command(ST7735_SLPOUT); + nrf_delay_ms(500); + + write_command(ST7735_FRMCTR1); + write_data(0x01); + write_data(0x2C); + write_data(0x2D); + write_command(ST7735_FRMCTR2); + write_data(0x01); + write_data(0x2C); + write_data(0x2D); + write_command(ST7735_FRMCTR3); + write_data(0x01); + write_data(0x2C); + write_data(0x2D); + write_data(0x01); + write_data(0x2C); + write_data(0x2D); + + write_command(ST7735_INVCTR); + write_data(0x07); + + write_command(ST7735_PWCTR1); + write_data(0xA2); + write_data(0x02); + write_data(0x84); + write_command(ST7735_PWCTR2); + write_data(0xC5); + write_command(ST7735_PWCTR3); + write_data(0x0A); + write_data(0x00); + write_command(ST7735_PWCTR3); + write_data(0x8A); + write_data(0x2A); + write_command(ST7735_PWCTR5); + write_data(0x8A); + write_data(0xEE); + write_data(0x0E); + + write_command(ST7735_INVOFF); + write_command(ST7735_MADCTL); + write_data(0xC8); + + write_command(ST7735_COLMOD); + write_data(0x05); + + if (m_st7735.tab_color == INITR_GREENTAB) + { + write_command(ST7735_CASET); + write_data(0x00); + write_data(0x02); + write_data(0x00); + write_data(0x81); + write_command(ST7735_RASET); + write_data(0x00); + write_data(0x01); + write_data(0x00); + write_data(0xA0); + } + else if (m_st7735.tab_color == INITR_144GREENTAB) + { + write_command(ST7735_CASET); + write_data(0x00); + write_data(0x00); + write_data(0x00); + write_data(0x7F); + write_command(ST7735_RASET); + write_data(0x00); + write_data(0x00); + write_data(0x00); + write_data(0x7F); + } + else if (m_st7735.tab_color == INITR_REDTAB) + { + write_command(ST7735_CASET); + write_data(0x00); + write_data(0x00); + write_data(0x00); + write_data(0x7F); + write_command(ST7735_RASET); + write_data(0x00); + write_data(0x00); + write_data(0x00); + write_data(0x9F); + } + + write_command(ST7735_GMCTRP1); + write_data(0x02); + write_data(0x1c); + write_data(0x07); + write_data(0x12); + write_data(0x37); + write_data(0x32); + write_data(0x29); + write_data(0x2d); + write_data(0x29); + write_data(0x25); + write_data(0x2b); + write_data(0x39); + write_data(0x00); + write_data(0x01); + write_data(0x03); + write_data(0x10); + write_command(ST7735_GMCTRN1); + write_data(0x03); + write_data(0x1d); + write_data(0x07); + write_data(0x06); + write_data(0x2e); + write_data(0x2c); + write_data(0x29); + write_data(0x2d); + write_data(0x2e); + write_data(0x2e); + write_data(0x37); + write_data(0x3f); + write_data(0x00); + write_data(0x00); + write_data(0x02); + write_data(0x10); + + write_command(ST7735_NORON); + nrf_delay_ms(10); + write_command(ST7735_DISPON); + nrf_delay_ms(100); + + if (m_st7735.tab_color == INITR_BLACKTAB) + { + write_command(ST7735_MADCTL); + write_data(0xC0); + } +} + + +static ret_code_t hardware_init(void) +{ + ret_code_t err_code; + + nrf_gpio_cfg_output(ST7735_DC_PIN); + + nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; + + spi_config.sck_pin = ST7735_SCK_PIN; + spi_config.miso_pin = ST7735_MISO_PIN; + spi_config.mosi_pin = ST7735_MOSI_PIN; + spi_config.ss_pin = ST7735_SS_PIN; + + err_code = nrf_drv_spi_init(&spi, &spi_config, NULL, NULL); + return err_code; +} + +static ret_code_t st7735_init(void) +{ + ret_code_t err_code; + + m_st7735.tab_color = ST7735_TAB_COLOR; + + err_code = hardware_init(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + command_list(); + + return err_code; +} + +static void st7735_uninit(void) +{ + nrf_drv_spi_uninit(&spi); +} + +static void st7735_pixel_draw(uint16_t x, uint16_t y, uint32_t color) +{ + set_addr_window(x, y, x, y); + + color = RGB2BGR(color); + + const uint8_t data[2] = {color >> 8, color}; + + nrf_gpio_pin_set(ST7735_DC_PIN); + + spi_write(data, sizeof(data)); + + nrf_gpio_pin_clear(ST7735_DC_PIN); +} + +static void st7735_rect_draw(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color) +{ + set_addr_window(x, y, x + width - 1, y + height - 1); + + color = RGB2BGR(color); + + const uint8_t data[2] = {color >> 8, color}; + + nrf_gpio_pin_set(ST7735_DC_PIN); + + // Duff's device algorithm for optimizing loop. + uint32_t i = (height * width + 7) / 8; + +/*lint -save -e525 -e616 -e646 */ + switch ((height * width) % 8) { + case 0: + do { + spi_write(data, sizeof(data)); + case 7: + spi_write(data, sizeof(data)); + case 6: + spi_write(data, sizeof(data)); + case 5: + spi_write(data, sizeof(data)); + case 4: + spi_write(data, sizeof(data)); + case 3: + spi_write(data, sizeof(data)); + case 2: + spi_write(data, sizeof(data)); + case 1: + spi_write(data, sizeof(data)); + } while (--i > 0); + default: + break; + } +/*lint -restore */ + nrf_gpio_pin_clear(ST7735_DC_PIN); +} + +static void st7735_dummy_display(void) +{ + /* No implementation needed. */ +} + +static void st7735_rotation_set(nrf_lcd_rotation_t rotation) +{ + write_command(ST7735_MADCTL); + switch (rotation) { + case NRF_LCD_ROTATE_0: + if (m_st7735.tab_color == INITR_BLACKTAB) + { + write_data(ST7735_MADCTL_MX | ST7735_MADCTL_MY | ST7735_MADCTL_RGB); + } + else + { + write_data(ST7735_MADCTL_MX | ST7735_MADCTL_MY | ST7735_MADCTL_BGR); + } + break; + case NRF_LCD_ROTATE_90: + if (m_st7735.tab_color == INITR_BLACKTAB) + { + write_data(ST7735_MADCTL_MY | ST7735_MADCTL_MV | ST7735_MADCTL_RGB); + } + else + { + write_data(ST7735_MADCTL_MY | ST7735_MADCTL_MV | ST7735_MADCTL_BGR); + } + break; + case NRF_LCD_ROTATE_180: + if (m_st7735.tab_color == INITR_BLACKTAB) + { + write_data(ST7735_MADCTL_RGB); + } + else + { + write_data(ST7735_MADCTL_BGR); + } + break; + case NRF_LCD_ROTATE_270: + if (m_st7735.tab_color == INITR_BLACKTAB) + { + write_data(ST7735_MADCTL_MX | ST7735_MADCTL_MV | ST7735_MADCTL_RGB); + } + else + { + write_data(ST7735_MADCTL_MX | ST7735_MADCTL_MV | ST7735_MADCTL_BGR); + } + break; + default: + break; + } +} + + +static void st7735_display_invert(bool invert) +{ + write_command(invert ? ST7735_INVON : ST7735_INVOFF); +} + +static lcd_cb_t st7735_cb = { + .height = ST7735_HEIGHT, + .width = ST7735_WIDTH +}; + +const nrf_lcd_t nrf_lcd_st7735 = { + .lcd_init = st7735_init, + .lcd_uninit = st7735_uninit, + .lcd_pixel_draw = st7735_pixel_draw, + .lcd_rect_draw = st7735_rect_draw, + .lcd_display = st7735_dummy_display, + .lcd_rotation_set = st7735_rotation_set, + .lcd_display_invert = st7735_display_invert, + .p_lcd_cb = &st7735_cb +}; + +#endif // NRF_MODULE_ENABLED(ST7735) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c new file mode 100644 index 0000000000000000000000000000000000000000..3769ea50dfe4461144448c7bacf806c856e32faa --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include + +#include "twi_master.h" +#include "synaptics_touchpad.h" + +/*lint ++flb "Enter library region" */ + +#define PRODUCT_ID_BYTES 10U //!< Number of bytes to expect to be in product ID + +static uint8_t m_device_address; // !< Device address in bits [7:1] +static const uint8_t expected_product_id[PRODUCT_ID_BYTES] = {'T', 'M', '1', '9', '4', '4', '-', '0', '0', '2'}; //!< Product ID expected to get from product ID query + +bool touchpad_init(uint8_t device_address) +{ + bool transfer_succeeded = true; + + m_device_address = (uint8_t)(device_address << 1); + + // Do a soft reset + uint8_t reset_command = 0x01; + transfer_succeeded &= touchpad_write_register(TOUCHPAD_RESET, reset_command); + + // Page select 0 + uint8_t page_to_select = 0x00; + transfer_succeeded &= touchpad_write_register(TOUCHPAD_PAGESELECT, page_to_select); + + // Read and verify product ID + transfer_succeeded &= touchpad_product_id_verify(); + + return transfer_succeeded; +} + + +bool touchpad_product_id_verify(void) +{ + bool transfer_succeeded = true; + uint8_t product_id[PRODUCT_ID_BYTES]; + transfer_succeeded &= touchpad_product_id_read(product_id, PRODUCT_ID_BYTES); + + for (uint8_t i = 0; i < 10; i++) + { + if (product_id[i] != expected_product_id[i]) + { + transfer_succeeded = false; + } + } + + return transfer_succeeded; +} + +bool touchpad_reset(void) +{ + uint8_t w2_data[2] = {TOUCHPAD_COMMAND, 0x01}; + + return twi_master_transfer(m_device_address, w2_data, 2, TWI_ISSUE_STOP); +} + +bool touchpad_interrupt_status_read(uint8_t *interrupt_status) +{ + return touchpad_read_register(TOUCHPAD_INT_STATUS, interrupt_status); +} + +bool touchpad_set_sleep_mode(TouchpadSleepMode_t mode) +{ + return touchpad_write_register(TOUCHPAD_CONTROL, (uint8_t)mode); +} + +bool touchpad_read_register(uint8_t register_address, uint8_t *value) +{ + bool transfer_succeeded = true; + transfer_succeeded &= twi_master_transfer(m_device_address, ®ister_address, 1, TWI_DONT_ISSUE_STOP); + if (transfer_succeeded) + { + transfer_succeeded &= twi_master_transfer(m_device_address | TWI_READ_BIT, value, 1, TWI_ISSUE_STOP); + } + return transfer_succeeded; +} + +bool touchpad_write_register(uint8_t register_address, const uint8_t value) +{ + uint8_t w2_data[2]; + + w2_data[0] = register_address; + w2_data[1] = value; + return twi_master_transfer(m_device_address, w2_data, 2, TWI_ISSUE_STOP); +} + +bool touchpad_product_id_read(uint8_t * product_id, uint8_t product_id_bytes) +{ + uint8_t w2_data[1]; + bool transfer_succeeded = true; + + w2_data[0] = TOUCHPAD_PRODUCT_ID; + transfer_succeeded &= twi_master_transfer(m_device_address, w2_data, 1, TWI_DONT_ISSUE_STOP); + if (transfer_succeeded) + { + transfer_succeeded &= twi_master_transfer(m_device_address | TWI_READ_BIT, product_id, product_id_bytes, TWI_ISSUE_STOP); + } + return transfer_succeeded; +} + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h new file mode 100644 index 0000000000000000000000000000000000000000..1f3d3ea1dd420505ca2f1c2bec342f9a02b5efd5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYNAPTICS_TOUCHPAD_H +#define SYNAPTICS_TOUCHPAD_H + +/*lint ++flb "Enter library region" */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file +* @brief Synaptics Touchpad driver +* +* +* @defgroup nrf_drivers_synaptics_touchpad Synaptics Touchpad driver +* @{ +* @ingroup ext_drivers +* @brief Synaptics Touchpad driver. +*/ + +/** + Touchpad register addresses. +*/ +#define TOUCHPAD_INT_STATUS 0x14 //!< Interrupt status register +#define TOUCHPAD_BUTTON_STATUS 0x41 //!< Button status register +#define TOUCHPAD_FINGER0_REL 0x30 //!< First register in finger delta block +#define TOUCHPAD_GESTURE_FLAGS 0x3A //!< Gesture flags 0 +#define TOUCHPAD_SCROLL 0x3F //!< Scroll zone X / horizontal multifinger scroll +#define TOUCHPAD_CONTROL 0x42 //!< Device control register +#define TOUCHPAD_COMMAND 0x8F //!< Device command register + +#define TOUCHPAD_RESET 0x54 //!< Address of reset +#define TOUCHPAD_PAGESELECT 0xFF //!< Address of page select (can be found in every page at the same address) +#define TOUCHPAD_PRODUCT_ID 0xA2 //!< Address of product ID string + +/** + Operational states +*/ +typedef enum +{ + SleepmodeNormal = 0x00, //!< Normal operation + SleepmodeSensorSleep = 0x01 //!< Low power operation +} TouchpadSleepMode_t; + +/** + @brief Function for Touchpad initialization. + @param device_address TWI address of the device in bits [6:0] + @retval true Touchpad was successfully identified and initialized + @retval false Unexpected product ID or communication failure +*/ +bool touchpad_init(uint8_t device_address); + +/** + @brief Function for attempting to soft-reset the device. + @retval true Reset succeeded + @retval false Reset failed +*/ +bool touchpad_reset(void); + +/** + @brief Function for reading the interrupt status register of the device. This clears all interrupts. + @param interrupt_status Address to store interrupt status to. + @retval true Register contents read successfully to interrupt_status + @retval false Reading failed +*/ +bool touchpad_interrupt_status_read(uint8_t *interrupt_status); + +/** + @brief Function for sleep mode configuration. + @note In low power mode the touchpad do not generate interrupts from touch sensing. + @param[in] mode Operational mode + @retval true Sleep mode set successfully + @retval false Sleep mode setting failed +*/ +bool touchpad_set_sleep_mode(TouchpadSleepMode_t mode); + +/** + @brief Function for reading a touchpad register contents over TWI. + @param[in] register_address Register address + @param[out] value Pointer to a data buffer where read data will be stored + @retval true Register read succeeded + @retval false Register read failed +*/ +bool touchpad_read_register(uint8_t register_address, uint8_t *value); + +/** + @brief Function for writing a touchpad register contents over TWI. + @param[in] register_address Register address + @param[in] value Value to write to register + @retval true Register write succeeded + @retval false Register write failed +*/ +bool touchpad_write_register(uint8_t register_address, uint8_t value); + +/** + @brief Function for writing touchpad register contents over TWI. + Writes one or more consecutive registers. + @param[out] product_id Pointer to a address to store product ID. Memory must be allocated for product_id_bytes number of bytes. + @param[in] product_id_bytes Number of bytes to read + @retval true Product ID read succeeded + @retval false Product ID read failed +*/ +bool touchpad_product_id_read(uint8_t *product_id, uint8_t product_id_bytes); + +/** + @brief Function for reading and verifying touchpad's product ID. + @retval true Product ID is what was expected + @retval false Product ID was not what was expected +*/ +bool touchpad_product_id_verify(void); + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __TOUCHPAD_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/uda1380/uda1380.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/uda1380/uda1380.c new file mode 100644 index 0000000000000000000000000000000000000000..3b67d1346e97e4169d3178832c416c3c90419a03 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/uda1380/uda1380.c @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "uda1380.h" +#include + +ret_code_t uda1380_init(uda1380_iface_t const * p_iface, + uda1380_reg_t const * p_reg_config, + size_t reg_size) +{ + ret_code_t ret = NRF_SUCCESS; + + ret = nrf_drv_twi_init(&p_iface->twi, &p_iface->twi_cfg, NULL, NULL); + if (ret != NRF_SUCCESS) + { + return ret; + } + + nrf_drv_twi_enable(&p_iface->twi); + + /*Probe device*/ + uint8_t rx[] = {0}; + ret = nrf_drv_twi_rx(&p_iface->twi, p_iface->twi_addr, rx, sizeof(rx)); + if (ret != NRF_SUCCESS) + { + return ret; + } + + for (size_t i = 0; i < reg_size; ++i) + { + uint8_t p_dat[sizeof(uda1380_reg_t)]; + memcpy(p_dat, &p_reg_config[i], sizeof(uda1380_reg_t)); + ret = nrf_drv_twi_tx(&p_iface->twi, p_iface->twi_addr, p_dat, sizeof(uda1380_reg_t), false); + if (ret != NRF_SUCCESS) + { + break; + } + } + + return ret; +} + + +ret_code_t uda1380_enable(uda1380_iface_t const * p_iface) +{ + ret_code_t ret = NRF_SUCCESS; + + static const uda1380_reg_t enable[] = { + UDA1380_REG_INIT(UDA1380_REG_PWR, 0xA500), + UDA1380_REG_INIT(UDA1380_REG_CLK, 0x0332), + }; + + for (size_t i = 0; i < ARRAY_SIZE(enable); ++i) + { + uint8_t p_dat[sizeof(uda1380_reg_t)]; + memcpy(p_dat, &enable[i], sizeof(uda1380_reg_t)); + ret = nrf_drv_twi_tx(&p_iface->twi, p_iface->twi_addr, p_dat, sizeof(uda1380_reg_t), false); + if (ret != NRF_SUCCESS) + { + break; + } + } + + return ret; +} + + +ret_code_t uda1380_disable(uda1380_iface_t const * p_iface) +{ + ret_code_t ret = NRF_SUCCESS; + + static const uda1380_reg_t disable[] = { + UDA1380_REG_INIT(UDA1380_REG_PWR, 0x0000), + UDA1380_REG_INIT(UDA1380_REG_CLK, 0x0000), + }; + + for (size_t i = 0; i < ARRAY_SIZE(disable); ++i) + { + const uint8_t * p_dat = (const uint8_t *)&disable[i]; + ret = nrf_drv_twi_tx(&p_iface->twi, p_iface->twi_addr, p_dat, sizeof(uda1380_reg_t), false); + if (ret != NRF_SUCCESS) + { + break; + } + } + + return ret; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/uda1380/uda1380.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/uda1380/uda1380.h new file mode 100644 index 0000000000000000000000000000000000000000..59fb61eaae25b50811e67e467faaad942d5d0053 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_ext/uda1380/uda1380.h @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef UDA1380_H__ +#define UDA1380_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "nrf_drv_twi.h" + + +#define UDA1380_REG_CLK 0x00 +#define UDA1380_REG_I2S 0x01 +#define UDA1380_REG_PWR 0x02 +#define UDA1380_REG_AMIX 0x03 +#define UDA1380_REG_HPA 0x04 + +#define UDA1380_REG_VOL 0x10 +#define UDA1380_REG_MIX_VOL 0x11 +#define UDA1380_REG_PPROC 0x12 +#define UDA1380_REG_DEEMP 0x13 +#define UDA1380_REG_MIXER 0x14 + +#define UDA1380_REG_RESET 0x7F + + +/** + * @brief Default UDA1380 TWI configuration + * + * @param scl_pin SCL pin number + * @param sda_pin SDA pin number + */ +#define UDA1380_DEFAULT_TWI_CONFIG(scl_pin, sda_pin) { \ + .scl = scl_pin, \ + .sda = sda_pin, \ + .frequency = NRF_TWI_FREQ_100K, \ + .interrupt_priority = APP_IRQ_PRIORITY_HIGH, \ + .clear_bus_init = false, \ + .hold_bus_uninit = false \ +} + +/** + * @brief UDA1380 register descriptor + * */ +typedef struct { + uint8_t addr; //!< Internal register address + uint8_t val[2]; //!< Internal register value +} uda1380_reg_t; + +#define UDA1380_REG_INIT(address, value) { \ + .addr = address, \ + .val = {(value) / 256, (value) & 0xFF}, \ +} + +/** + * @brief UDA1380 TWI bus address*/ +#define UDA1380_TWI_ADDRESS (0x18) + +/** + * @brief UDA1380 interface + * */ +typedef struct { + nrf_drv_twi_t twi; //!< TWI instance + nrf_drv_twi_config_t twi_cfg; //!< TWI configuration + uint8_t twi_addr; //!< UDA1380 TWI address +} uda1380_iface_t; + + +/** + * @brief Initializes UDA1380 codec IC + * + * @param p_iface Communication interface + * @param p_reg_config Configuration registers + * @param reg_size Number of configuration registers + * + * @return Standard error code + * */ +ret_code_t uda1380_init(uda1380_iface_t const * p_iface, + uda1380_reg_t const * p_reg_config, + size_t reg_size); + +/** + * @brief Enable UDA1380 codec + * + * @return Standard error code + * */ +ret_code_t uda1380_enable(uda1380_iface_t const * p_iface); + + +/** + * @brief Disable UDA1380 codec + * + * @return Standard error code + * */ +ret_code_t uda1380_disable(uda1380_iface_t const * p_iface); + +#ifdef __cplusplus +} +#endif + +#endif /* UDA1380_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/ble_flash/ble_flash.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/ble_flash/ble_flash.c new file mode 100644 index 0000000000000000000000000000000000000000..25368adaee7658b7e4af39c645459955560b99dc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/ble_flash/ble_flash.c @@ -0,0 +1,313 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_flash.h" +#include +#include +#include +#include "nrf_soc.h" +#include "nordic_common.h" +#include "nrf_error.h" +#include "nrf.h" +#include "app_util.h" + + +static volatile bool m_radio_active = false; /**< TRUE if radio is active (or about to become active), FALSE otherwise. */ + + +uint16_t ble_flash_crc16_compute(uint8_t * p_data, uint16_t size, uint16_t * p_crc) +{ + uint16_t i; + uint16_t crc = (p_crc == NULL) ? 0xffff : *p_crc; + + for (i = 0; i < size; i++) + { + crc = (unsigned char)(crc >> 8) | (crc << 8); + crc ^= p_data[i]; + crc ^= (unsigned char)(crc & 0xff) >> 4; + crc ^= (crc << 8) << 4; + crc ^= ((crc & 0xff) << 4) << 1; + } + return crc; +} + + +/**@brief Function for erasing a page in flash. + * + * @param[in] p_page Pointer to first word in page to be erased. + */ +static void flash_page_erase(uint32_t * p_page) +{ + // Turn on flash erase enable and wait until the NVMC is ready. + NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos); + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + // Do nothing. + } + + // Erase page. + NRF_NVMC->ERASEPAGE = (uint32_t)p_page; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + // Do nothing. + } + + // Turn off flash erase enable and wait until the NVMC is ready. + NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos); + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + // Do nothing + } +} + + +/**@brief Function for writing one word to flash. Unprotected write, which can interfere with radio communication. + * + * @details This function DOES NOT use the m_radio_active variable, but will force the write even + * when the radio is active. To be used only from @ref ble_flash_page_write. + * + * @note Flash location to be written must have been erased previously. + * + * @param[in] p_address Pointer to flash location to be written. + * @param[in] value Value to write to flash. + */ +static void flash_word_unprotected_write(uint32_t * p_address, uint32_t value) +{ + // Turn on flash write enable and wait until the NVMC is ready. + NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos); + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + // Do nothing. + } + *p_address = value; + + // Wait flash write to finish + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + // Do nothing. + } + + // Turn off flash write enable and wait until the NVMC is ready. + NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos); + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + // Do nothing. + } +} + + +/**@brief Function for writing one word to flash. + * + * @note Flash location to be written must have been erased previously. + * + * @param[in] p_address Pointer to flash location to be written. + * @param[in] value Value to write to flash. + */ +static void flash_word_write(uint32_t * p_address, uint32_t value) +{ + // If radio is active, wait for it to become inactive. + while (m_radio_active) + { + // Do nothing (just wait for radio to become inactive). + (void) sd_app_evt_wait(); + } + + // Turn on flash write enable and wait until the NVMC is ready. + NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos); + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + // Do nothing. + } + + *p_address = value; + // Wait flash write to finish + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + // Do nothing. + } + // Turn off flash write enable and wait until the NVMC is ready. + NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos); + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + // Do nothing + } +} + + +uint32_t ble_flash_word_write(uint32_t * p_address, uint32_t value) +{ + flash_word_write(p_address, value); + return NRF_SUCCESS; +} + + +uint32_t ble_flash_block_write(uint32_t * p_address, uint32_t * p_in_array, uint16_t word_count) +{ + uint16_t i; + + for (i = 0; i < word_count; i++) + { + flash_word_write(p_address, p_in_array[i]); + p_address++; + } + + return NRF_SUCCESS; +} + + +uint32_t ble_flash_page_erase(uint8_t page_num) +{ + uint32_t * p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num); + flash_page_erase(p_page); + + return NRF_SUCCESS; +} + + +uint32_t ble_flash_page_write(uint8_t page_num, uint32_t * p_in_array, uint8_t word_count) +{ + int i; + uint32_t * p_page; + uint32_t * p_curr_addr; + uint16_t in_data_crc; + uint16_t flash_crc; + uint32_t flash_header; + + p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num); + p_curr_addr = p_page; + + // Calculate CRC of the data to write. + in_data_crc = ble_flash_crc16_compute((uint8_t *)p_in_array, + word_count * sizeof(uint32_t), + NULL); + + // Compare the calculated to the one in flash. + flash_header = *p_curr_addr; + flash_crc = (uint16_t)flash_header; + + if (flash_crc == in_data_crc) + { + // Data is the same as the data already stored in flash, return without modifying flash. + return NRF_SUCCESS; + } + + // Erase flash page + flash_page_erase(p_page); + + // Reserve space for magic number (for detecting if flash content is valid). + p_curr_addr++; + + // Reserve space for saving word_count. + p_curr_addr++; + + // Write data + for (i = 0; i < word_count; i++) + { + flash_word_unprotected_write(p_curr_addr, p_in_array[i]); + p_curr_addr++; + } + + // Write number of elements. + flash_word_write(p_page + 1, (uint32_t)(word_count)); + + // Write magic number and CRC to indicate that flash content is valid. + flash_header = BLE_FLASH_MAGIC_NUMBER | (uint32_t)in_data_crc; + flash_word_write(p_page, flash_header); + + return NRF_SUCCESS; +} + + +uint32_t ble_flash_page_read(uint8_t page_num, uint32_t * p_out_array, uint8_t * p_word_count) +{ + int byte_count; + uint32_t * p_page; + uint32_t * p_curr_addr; + uint32_t flash_header; + uint32_t calc_header; + uint16_t calc_crc; + uint32_t tmp; + + p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num); + p_curr_addr = p_page; + + // Check if block is valid + flash_header = *p_curr_addr; + tmp = flash_header & 0xFFFF0000; + if (tmp != BLE_FLASH_MAGIC_NUMBER) + { + *p_word_count = 0; + return NRF_ERROR_NOT_FOUND; + } + p_curr_addr++; + + // Read number of elements + *p_word_count = (uint8_t)(*(p_curr_addr)); + p_curr_addr++; + + // Read data + byte_count = (*p_word_count) * sizeof(uint32_t); + memcpy(p_out_array, p_curr_addr, byte_count); + + // Check CRC + calc_crc = ble_flash_crc16_compute((uint8_t *)p_out_array, + (*p_word_count) * sizeof(uint32_t), + NULL); + calc_header = BLE_FLASH_MAGIC_NUMBER | (uint32_t)calc_crc; + + if (calc_header != flash_header) + { + return NRF_ERROR_NOT_FOUND; + } + + return NRF_SUCCESS; +} + + +uint32_t ble_flash_page_addr(uint8_t page_num, uint32_t ** pp_page_addr) +{ + *pp_page_addr = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num); + return NRF_SUCCESS; +} + + +void ble_flash_on_radio_active_evt(bool radio_active) +{ + m_radio_active = radio_active; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/ble_flash/ble_flash.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/ble_flash/ble_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..8fffeb62a7c3cebc24b4b112a9b6a00b9d0ee31a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/ble_flash/ble_flash.h @@ -0,0 +1,178 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_flash_module Flash Manager + * @{ + * @ingroup ble_sdk_lib + * @brief Module for accessing flash memory. + * + * @details It contains functions for reading, writing and erasing one page in flash. + * + * The module uses the first 32 bits of the flash page to write a magic number in order to + * determine if the page has been written or not. + * + * @note Be careful not to use a page number in the SoftDevice area (which currently occupies the + * range 0 to 127), or in your application space! In both cases, this would end up + * with a hard fault. + */ + +#ifndef BLE_FLASH_H__ +#define BLE_FLASH_H__ + +#include +#include +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_FLASH_PAGE_SIZE ((uint16_t)NRF_FICR->CODEPAGESIZE) /**< Size of one flash page. */ +#define BLE_FLASH_MAGIC_NUMBER 0x45DE0000 /**< Magic value to identify if flash contains valid data. */ +#define BLE_FLASH_EMPTY_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */ + + +/**@brief Macro for getting the end of the flash available for application. + * + * @details The result flash page number indicates the end boundary of the flash available + * to the application. If a bootloader is used, the end will be the start of the + * bootloader region. Otherwise, the end will be the size of the flash. + */ +#define BLE_FLASH_PAGE_END \ + ((NRF_UICR->NRFFW[0] != BLE_FLASH_EMPTY_MASK) \ + ? (NRF_UICR->NRFFW[0] / BLE_FLASH_PAGE_SIZE) \ + : NRF_FICR->CODESIZE) + +/**@brief Function for erasing the specified flash page, and then writes the given data to this page. + * + * @warning This operation blocks the CPU. DO NOT use while in a connection! + * + * @param[in] page_num Page number to update. + * @param[in] p_in_array Pointer to a RAM area containing the elements to write in flash. + * This area has to be 32 bits aligned. + * @param[in] word_count Number of 32 bits words to write in flash. + * + * @return NRF_SUCCESS on successful flash write, otherwise an error code. + */ +uint32_t ble_flash_page_write(uint8_t page_num, uint32_t * p_in_array, uint8_t word_count); + +/**@brief Function for reading data from flash to RAM. + * + * @param[in] page_num Page number to read. + * @param[out] p_out_array Pointer to a RAM area where the found data will be written. + * This area has to be 32 bits aligned. + * @param[out] p_word_count Number of 32 bits words read. + * + * @return NRF_SUCCESS on successful upload, NRF_ERROR_NOT_FOUND if no valid data has been found + * in flash (first 32 bits not equal to the MAGIC_NUMBER + CRC). + */ +uint32_t ble_flash_page_read(uint8_t page_num, uint32_t * p_out_array, uint8_t * p_word_count); + +/**@brief Function for erasing a flash page. + * + * @note This operation blocks the CPU, so it should not be done while the radio is running! + * + * @param[in] page_num Page number to erase. + * + * @return NRF_SUCCESS on success, an error_code otherwise. + */ +uint32_t ble_flash_page_erase(uint8_t page_num); + +/**@brief Function for writing one word to flash. + * + * @note Flash location to be written must have been erased previously. + * + * @param[in] p_address Pointer to flash location to be written. + * @param[in] value Value to write to flash. + * + * @return NRF_SUCCESS. + */ +uint32_t ble_flash_word_write(uint32_t * p_address, uint32_t value); + +/**@brief Function for writing a data block to flash. + * + * @note Flash locations to be written must have been erased previously. + * + * @param[in] p_address Pointer to start of flash location to be written. + * @param[in] p_in_array Pointer to start of flash block to be written. + * @param[in] word_count Number of words to be written. + * + * @return NRF_SUCCESS. + */ +uint32_t ble_flash_block_write(uint32_t * p_address, uint32_t * p_in_array, uint16_t word_count); + +/**@brief Function for computing pointer to start of specified flash page. + * + * @param[in] page_num Page number. + * @param[out] pp_page_addr Pointer to start of flash page. + * + * @return NRF_SUCCESS. + */ +uint32_t ble_flash_page_addr(uint8_t page_num, uint32_t ** pp_page_addr); + +/**@brief Function for calculating a 16 bit CRC using the CRC-16-CCITT scheme. + * + * @param[in] p_data Pointer to data on which the CRC is to be calculated. + * @param[in] size Number of bytes on which the CRC is to be calculated. + * @param[in] p_crc Initial CRC value (if NULL, a preset value is used as the initial value). + * + * @return Calculated CRC. + */ +uint16_t ble_flash_crc16_compute(uint8_t * p_data, uint16_t size, uint16_t * p_crc); + +/**@brief Function for handling flashing module Radio Notification event. + * + * @note For flash writing to work safely while in a connection or while advertising, this function + * MUST be called from the Radio Notification module's event handler (see + * @ref ble_radio_notification for details). + * + * @param[in] radio_active TRUE if radio is active (or about to become active), FALSE otherwise. + */ +void ble_flash_on_radio_active_evt(bool radio_active); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_FLASH_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/clock/nrf_drv_clock.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/clock/nrf_drv_clock.c new file mode 100644 index 0000000000000000000000000000000000000000..dfc017bdd83b873df07c622356b81832f7f1c091 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/clock/nrf_drv_clock.c @@ -0,0 +1,599 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(CLOCK) + +#include "nrf_drv_clock.h" +#include "nrf_error.h" +#include "app_util_platform.h" +#ifdef SOFTDEVICE_PRESENT +#include "softdevice_handler.h" +#include "nrf_sdm.h" +#include "nrf_soc.h" +#endif + +#define NRF_LOG_MODULE_NAME "CLOCK" + +#if CLOCK_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL CLOCK_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR CLOCK_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR CLOCK_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_CLOCK_EVENT_HFCLKSTARTED ? "NRF_CLOCK_EVENT_HFCLKSTARTED" : \ + (event == NRF_CLOCK_EVENT_LFCLKSTARTED ? "NRF_CLOCK_EVENT_LFCLKSTARTED" : \ + (event == NRF_CLOCK_EVENT_DONE ? "NRF_CLOCK_EVENT_DONE" : \ + (event == NRF_CLOCK_EVENT_CTTO ? "NRF_CLOCK_EVENT_CTTO" : "UNKNOWN EVENT")))) +#else //CLOCK_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //CLOCK_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +/* Validate configuration */ +INTERRUPT_PRIORITY_VALIDATION(CLOCK_CONFIG_IRQ_PRIORITY); + +/*lint -save -e652 */ +#define NRF_CLOCK_LFCLK_RC CLOCK_LFCLKSRC_SRC_RC +#define NRF_CLOCK_LFCLK_Xtal CLOCK_LFCLKSRC_SRC_Xtal +#define NRF_CLOCK_LFCLK_Synth CLOCK_LFCLKSRC_SRC_Synth +/*lint -restore */ + +#if (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LFCLK_RC) && !defined(SOFTDEVICE_PRESENT) +#define CALIBRATION_SUPPORT 1 +#else +#define CALIBRATION_SUPPORT 0 +#endif +typedef enum +{ + CAL_STATE_IDLE, + CAL_STATE_CT, + CAL_STATE_HFCLK_REQ, + CAL_STATE_CAL, + CAL_STATE_ABORT, +} nrf_drv_clock_cal_state_t; + +/**@brief CLOCK control block. */ +typedef struct +{ + bool module_initialized; /*< Indicate the state of module */ + volatile bool hfclk_on; /*< High-frequency clock state. */ + volatile bool lfclk_on; /*< Low-frequency clock state. */ + volatile uint32_t hfclk_requests; /*< High-frequency clock request counter. */ + volatile nrf_drv_clock_handler_item_t * p_hf_head; + volatile uint32_t lfclk_requests; /*< Low-frequency clock request counter. */ + volatile nrf_drv_clock_handler_item_t * p_lf_head; +#if CALIBRATION_SUPPORT + nrf_drv_clock_handler_item_t cal_hfclk_started_handler_item; + nrf_drv_clock_event_handler_t cal_done_handler; + volatile nrf_drv_clock_cal_state_t cal_state; +#endif // CALIBRATION_SUPPORT +} nrf_drv_clock_cb_t; + +static nrf_drv_clock_cb_t m_clock_cb; + + +/**@brief Function for starting LFCLK. This function will return immediately without waiting for start. + */ +static void lfclk_start(void) +{ + nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); + nrf_clock_int_enable(NRF_CLOCK_INT_LF_STARTED_MASK); + nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART); +} + +/**@brief Function for stopping LFCLK and calibration (if it was set up). + */ +static void lfclk_stop(void) +{ +#if CALIBRATION_SUPPORT + (void)nrf_drv_clock_calibration_abort(); +#endif + +#ifdef SOFTDEVICE_PRESENT + // If LFCLK is requested to stop while SD is still enabled, + // it indicates an error in the application. + // Enabling SD should increment the LFCLK request. + ASSERT(!softdevice_handler_is_enabled()); +#endif // SOFTDEVICE_PRESENT + + nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTOP); + while (nrf_clock_lf_is_running()) + {} + m_clock_cb.lfclk_on = false; +} + +static void hfclk_start(void) +{ +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + (void)sd_clock_hfclk_request(); + return; + } +#endif // SOFTDEVICE_PRESENT + + nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); + nrf_clock_int_enable(NRF_CLOCK_INT_HF_STARTED_MASK); + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART); +} + +static void hfclk_stop(void) +{ +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + (void)sd_clock_hfclk_release(); + return; + } +#endif // SOFTDEVICE_PRESENT + + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); + while (nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY)) + {} + m_clock_cb.hfclk_on = false; +} + +bool nrf_drv_clock_init_check(void) +{ + return m_clock_cb.module_initialized; +} + +ret_code_t nrf_drv_clock_init(void) +{ + ret_code_t err_code = NRF_SUCCESS; + if (m_clock_cb.module_initialized) + { + err_code = NRF_ERROR_MODULE_ALREADY_INITIALIZED; + } + else + { + m_clock_cb.p_hf_head = NULL; + m_clock_cb.hfclk_requests = 0; + m_clock_cb.p_lf_head = NULL; + m_clock_cb.lfclk_requests = 0; + nrf_drv_common_power_clock_irq_init(); +#ifdef SOFTDEVICE_PRESENT + if (!softdevice_handler_is_enabled()) +#endif + { + nrf_clock_lf_src_set((nrf_clock_lfclk_t)CLOCK_CONFIG_LF_SRC); + } + +#if CALIBRATION_SUPPORT + m_clock_cb.cal_state = CAL_STATE_IDLE; +#endif + + m_clock_cb.module_initialized = true; + } + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +void nrf_drv_clock_uninit(void) +{ + ASSERT(m_clock_cb.module_initialized); + nrf_drv_common_clock_irq_disable(); + nrf_clock_int_disable(0xFFFFFFFF); + + lfclk_stop(); + hfclk_stop(); + m_clock_cb.module_initialized = false; + NRF_LOG_INFO("Uninitialized.\r\n"); +} + +static void item_enqueue(nrf_drv_clock_handler_item_t ** p_head, + nrf_drv_clock_handler_item_t * p_item) +{ + nrf_drv_clock_handler_item_t * p_next = *p_head; + while(p_next) + { + if(p_next == p_item) + { + return; + } + p_next = p_next->p_next; + } + + p_item->p_next = (*p_head ? *p_head : NULL); + *p_head = p_item; +} + +static nrf_drv_clock_handler_item_t * item_dequeue(nrf_drv_clock_handler_item_t ** p_head) +{ + nrf_drv_clock_handler_item_t * p_item = *p_head; + if (p_item) + { + *p_head = p_item->p_next; + } + return p_item; +} + +void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item) +{ + ASSERT(m_clock_cb.module_initialized); + + if (m_clock_cb.lfclk_on) + { + if (p_handler_item) + { + p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_LFCLK_STARTED); + } + CRITICAL_REGION_ENTER(); + ++(m_clock_cb.lfclk_requests); + CRITICAL_REGION_EXIT(); + } + else + { + CRITICAL_REGION_ENTER(); + if (p_handler_item) + { + item_enqueue((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_lf_head, + p_handler_item); + } + if (m_clock_cb.lfclk_requests == 0) + { + lfclk_start(); + } + ++(m_clock_cb.lfclk_requests); + CRITICAL_REGION_EXIT(); + } + + ASSERT(m_clock_cb.lfclk_requests > 0); +} + +void nrf_drv_clock_lfclk_release(void) +{ + ASSERT(m_clock_cb.module_initialized); + ASSERT(m_clock_cb.lfclk_requests > 0); + + CRITICAL_REGION_ENTER(); + --(m_clock_cb.lfclk_requests); + if (m_clock_cb.lfclk_requests == 0) + { + lfclk_stop(); + } + CRITICAL_REGION_EXIT(); +} + +bool nrf_drv_clock_lfclk_is_running(void) +{ + ASSERT(m_clock_cb.module_initialized); + +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + return true; + } +#endif // SOFTDEVICE_PRESENT + + return nrf_clock_lf_is_running(); +} + +void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t * p_handler_item) +{ + ASSERT(m_clock_cb.module_initialized); + + if (m_clock_cb.hfclk_on) + { + if (p_handler_item) + { + p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_HFCLK_STARTED); + } + CRITICAL_REGION_ENTER(); + ++(m_clock_cb.hfclk_requests); + CRITICAL_REGION_EXIT(); + } + else + { + CRITICAL_REGION_ENTER(); + if (p_handler_item) + { + item_enqueue((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_hf_head, + p_handler_item); + } + if (m_clock_cb.hfclk_requests == 0) + { + hfclk_start(); + } + ++(m_clock_cb.hfclk_requests); + CRITICAL_REGION_EXIT(); + } + + ASSERT(m_clock_cb.hfclk_requests > 0); +} + +void nrf_drv_clock_hfclk_release(void) +{ + ASSERT(m_clock_cb.module_initialized); + ASSERT(m_clock_cb.hfclk_requests > 0); + + CRITICAL_REGION_ENTER(); + --(m_clock_cb.hfclk_requests); + if (m_clock_cb.hfclk_requests == 0) + { + hfclk_stop(); + } + CRITICAL_REGION_EXIT(); +} + +bool nrf_drv_clock_hfclk_is_running(void) +{ + ASSERT(m_clock_cb.module_initialized); + +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + uint32_t is_running; + UNUSED_VARIABLE(sd_clock_hfclk_is_running(&is_running)); + return (is_running ? true : false); + } +#endif // SOFTDEVICE_PRESENT + + return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY); +} + +#if CALIBRATION_SUPPORT +static void clock_calibration_hf_started(nrf_drv_clock_evt_type_t event) +{ + if (m_clock_cb.cal_state == CAL_STATE_ABORT) + { + nrf_drv_clock_hfclk_release(); + m_clock_cb.cal_state = CAL_STATE_IDLE; + if (m_clock_cb.cal_done_handler) + { + m_clock_cb.cal_done_handler(NRF_DRV_CLOCK_EVT_CAL_ABORTED); + } + } + else + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE); + nrf_clock_int_enable(NRF_CLOCK_INT_DONE_MASK); + m_clock_cb.cal_state = CAL_STATE_CAL; + nrf_clock_task_trigger(NRF_CLOCK_TASK_CAL); + } +} +#endif // CALIBRATION_SUPPORT + +ret_code_t nrf_drv_clock_calibration_start(uint8_t interval, nrf_drv_clock_event_handler_t handler) +{ + ret_code_t err_code = NRF_SUCCESS; +#if CALIBRATION_SUPPORT + ASSERT(m_clock_cb.cal_state == CAL_STATE_IDLE); + if (m_clock_cb.lfclk_on == false) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else if (m_clock_cb.cal_state == CAL_STATE_IDLE) + { + m_clock_cb.cal_done_handler = handler; + m_clock_cb.cal_hfclk_started_handler_item.event_handler = clock_calibration_hf_started; + if (interval == 0) + { + m_clock_cb.cal_state = CAL_STATE_HFCLK_REQ; + nrf_drv_clock_hfclk_request(&m_clock_cb.cal_hfclk_started_handler_item); + } + else + { + m_clock_cb.cal_state = CAL_STATE_CT; + nrf_clock_cal_timer_timeout_set(interval); + nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO); + nrf_clock_int_enable(NRF_CLOCK_INT_CTTO_MASK); + nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTART); + } + } + else + { + err_code = NRF_ERROR_BUSY; + } + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +#else + err_code = NRF_ERROR_FORBIDDEN; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +#endif // CALIBRATION_SUPPORT +} + +ret_code_t nrf_drv_clock_calibration_abort(void) +{ + ret_code_t err_code = NRF_SUCCESS; +#if CALIBRATION_SUPPORT + CRITICAL_REGION_ENTER(); + switch (m_clock_cb.cal_state) + { + case CAL_STATE_CT: + nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK); + nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTOP); + m_clock_cb.cal_state = CAL_STATE_IDLE; + if (m_clock_cb.cal_done_handler) + { + m_clock_cb.cal_done_handler(NRF_DRV_CLOCK_EVT_CAL_ABORTED); + } + break; + case CAL_STATE_HFCLK_REQ: + /* fall through. */ + case CAL_STATE_CAL: + m_clock_cb.cal_state = CAL_STATE_ABORT; + break; + default: + break; + } + CRITICAL_REGION_EXIT(); + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +#else + err_code = NRF_ERROR_FORBIDDEN; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +#endif // CALIBRATION_SUPPORT +} + +ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating) +{ + ret_code_t err_code = NRF_SUCCESS; +#if CALIBRATION_SUPPORT + ASSERT(m_clock_cb.module_initialized); + *p_is_calibrating = (m_clock_cb.cal_state != CAL_STATE_IDLE); + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +#else + err_code = NRF_ERROR_FORBIDDEN; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +#endif // CALIBRATION_SUPPORT +} + +__STATIC_INLINE void clock_clk_started_notify(nrf_drv_clock_evt_type_t evt_type) +{ + nrf_drv_clock_handler_item_t **p_head; + if (evt_type == NRF_DRV_CLOCK_EVT_HFCLK_STARTED) + { + p_head = (nrf_drv_clock_handler_item_t **)&m_clock_cb.p_hf_head; + } + else + { + p_head = (nrf_drv_clock_handler_item_t **)&m_clock_cb.p_lf_head; + } + + while (1) + { + nrf_drv_clock_handler_item_t * p_item = item_dequeue(p_head); + if (!p_item) + { + break; + } + + p_item->event_handler(evt_type); + } +} + +#if NRF_DRV_COMMON_POWER_CLOCK_ISR +void nrf_drv_clock_onIRQ(void) +#else +void POWER_CLOCK_IRQHandler(void) +#endif +{ + if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED)) + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_CLOCK_EVENT_HFCLKSTARTED)); + nrf_clock_int_disable(NRF_CLOCK_INT_HF_STARTED_MASK); + m_clock_cb.hfclk_on = true; + clock_clk_started_notify(NRF_DRV_CLOCK_EVT_HFCLK_STARTED); + } + if (nrf_clock_event_check(NRF_CLOCK_EVENT_LFCLKSTARTED)) + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_CLOCK_EVENT_LFCLKSTARTED)); + nrf_clock_int_disable(NRF_CLOCK_INT_LF_STARTED_MASK); + m_clock_cb.lfclk_on = true; + clock_clk_started_notify(NRF_DRV_CLOCK_EVT_LFCLK_STARTED); + } +#if CALIBRATION_SUPPORT + if (nrf_clock_event_check(NRF_CLOCK_EVENT_CTTO)) + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_CLOCK_EVENT_CTTO)); + nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK); + nrf_drv_clock_hfclk_request(&m_clock_cb.cal_hfclk_started_handler_item); + } + + if (nrf_clock_event_check(NRF_CLOCK_EVENT_DONE)) + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_CLOCK_EVENT_DONE)); + nrf_clock_int_disable(NRF_CLOCK_INT_DONE_MASK); + nrf_drv_clock_hfclk_release(); + bool aborted = (m_clock_cb.cal_state == CAL_STATE_ABORT); + m_clock_cb.cal_state = CAL_STATE_IDLE; + if (m_clock_cb.cal_done_handler) + { + m_clock_cb.cal_done_handler(aborted ? + NRF_DRV_CLOCK_EVT_CAL_ABORTED : NRF_DRV_CLOCK_EVT_CAL_DONE); + } + } +#endif // CALIBRATION_SUPPORT +} + +#ifdef SOFTDEVICE_PRESENT + +void nrf_drv_clock_on_soc_event(uint32_t evt_id) +{ + if (evt_id == NRF_EVT_HFCLKSTARTED) + { + clock_clk_started_notify(NRF_DRV_CLOCK_EVT_HFCLK_STARTED); + } +} + +void nrf_drv_clock_on_sd_enable(void) +{ + CRITICAL_REGION_ENTER(); + /* Make sure that nrf_drv_clock module is initialized */ + if (!m_clock_cb.module_initialized) + { + (void)nrf_drv_clock_init(); + } + /* SD is one of the LFCLK requesters, but it will enable it by itself. */ + ++(m_clock_cb.lfclk_requests); + m_clock_cb.lfclk_on = true; + CRITICAL_REGION_EXIT(); +} + +void nrf_drv_clock_on_sd_disable(void) +{ + /* Reinit interrupts */ + ASSERT(m_clock_cb.module_initialized); + nrf_drv_common_irq_enable(POWER_CLOCK_IRQn, CLOCK_CONFIG_IRQ_PRIORITY); + + /* SD leaves LFCLK enabled - disable it if it is no longer required. */ + nrf_drv_clock_lfclk_release(); +} + +#endif // SOFTDEVICE_PRESENT + +#undef NRF_CLOCK_LFCLK_RC +#undef NRF_CLOCK_LFCLK_Xtal +#undef NRF_CLOCK_LFCLK_Synth + +#endif // NRF_MODULE_ENABLED(CLOCK) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/clock/nrf_drv_clock.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/clock/nrf_drv_clock.h new file mode 100644 index 0000000000000000000000000000000000000000..ba9520d72961cbb63b26db3863fdaa4f0084f7b5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/clock/nrf_drv_clock.h @@ -0,0 +1,314 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_DRV_CLOCK_H__ +#define NRF_DRV_CLOCK_H__ + +#include +#include +#include "sdk_errors.h" +#include "nrf_assert.h" +#include "nrf_clock.h" +#include "sdk_config.h" +#include "nrf_drv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * + * @addtogroup nrf_clock Clock HAL and driver + * @ingroup nrf_drivers + * @brief Clock APIs. + * @details The clock HAL provides basic APIs for accessing the registers of the clock. + * The clock driver provides APIs on a higher level. + * + * @defgroup nrf_drv_clock Clock driver + * @{ + * @ingroup nrf_clock + * @brief Driver for managing the low-frequency clock (LFCLK) and the high-frequency clock (HFCLK). + */ + +/** + * @brief Clock events. + */ +typedef enum +{ + NRF_DRV_CLOCK_EVT_HFCLK_STARTED, ///< HFCLK has been started. + NRF_DRV_CLOCK_EVT_LFCLK_STARTED, ///< LFCLK has been started. + NRF_DRV_CLOCK_EVT_CAL_DONE, ///< Calibration is done. + NRF_DRV_CLOCK_EVT_CAL_ABORTED, ///< Calibration has been aborted. +} nrf_drv_clock_evt_type_t; + +/** + * @brief Clock event handler. + * + * @param[in] event Event. + */ +typedef void (*nrf_drv_clock_event_handler_t)(nrf_drv_clock_evt_type_t event); + +// Forward declaration of the nrf_drv_clock_handler_item_t type. +typedef struct nrf_drv_clock_handler_item_s nrf_drv_clock_handler_item_t; + +struct nrf_drv_clock_handler_item_s +{ + nrf_drv_clock_handler_item_t * p_next; ///< A pointer to the next handler that should be called when the clock is started. + nrf_drv_clock_event_handler_t event_handler; ///< Function to be called when the clock is started. +}; + +/** + * @brief Function for checking if driver is already initialized + * + * This function is used to check whatever common POWER_CLOCK common interrupt + * should be disabled or not if @ref nrf_drv_power tries to disable the interrupt. + * + * @retval true Driver is initialized + * @retval false Driver is uninitialized + */ +bool nrf_drv_clock_init_check(void); + +/** + * @brief Function for initializing the nrf_drv_clock module. + * + * After initialization, the module is in power off state (clocks are not requested). + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED If the driver was already initialized. + */ +ret_code_t nrf_drv_clock_init(void); + +/** + * @brief Function for uninitializing the clock module. + * + */ +void nrf_drv_clock_uninit(void); + +/** + * @brief Function for requesting the LFCLK. + * + * The low-frequency clock can be requested by different modules + * or contexts. The driver ensures that the clock will be started only when it is requested + * the first time. If the clock is not ready but it was already started, the handler item that is + * provided as an input parameter is added to the list of handlers that will be notified + * when the clock is started. If the clock is already enabled, user callback is called from the + * current context. + * + * The first request will start the selected LFCLK source. If an event handler is + * provided, it will be called once the LFCLK is started. If the LFCLK was already started at this + * time, the event handler will be called from the context of this function. Additionally, + * the @ref nrf_drv_clock_lfclk_is_running function can be polled to check if the clock has started. + * + * @note When a SoftDevice is enabled, the LFCLK is always running and the driver cannot control it. + * + * @note The handler item provided by the user cannot be an automatic variable. + * + * @param[in] p_handler_item A pointer to the event handler structure. + */ +void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item); + +/** + * @brief Function for releasing the LFCLK. + * + * If there are no more requests, the LFCLK source will be stopped. + * + * @note When a SoftDevice is enabled, the LFCLK is always running. + */ +void nrf_drv_clock_lfclk_release(void); + +/** + * @brief Function for checking the LFCLK state. + * + * @retval true If the LFCLK is running. + * @retval false If the LFCLK is not running. + */ +bool nrf_drv_clock_lfclk_is_running(void); + +/** + * @brief Function for requesting the high-accuracy source HFCLK. + * + * The high-accuracy source + * can be requested by different modules or contexts. The driver ensures that the high-accuracy + * clock will be started only when it is requested the first time. If the clock is not ready + * but it was already started, the handler item that is provided as an input parameter is added + * to the list of handlers that will be notified when the clock is started. + * + * If an event handler is provided, it will be called once the clock is started. If the clock was already + * started at this time, the event handler will be called from the context of this function. Additionally, + * the @ref nrf_drv_clock_hfclk_is_running function can be polled to check if the clock has started. + * + * @note If a SoftDevice is running, the clock is managed by the SoftDevice and all requests are handled by + * the SoftDevice. This function cannot be called from all interrupt priority levels in that case. + * @note The handler item provided by the user cannot be an automatic variable. + * + * @param[in] p_handler_item A pointer to the event handler structure. + */ +void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t * p_handler_item); + +/** + * @brief Function for releasing the high-accuracy source HFCLK. + * + * If there are no more requests, the high-accuracy source will be released. + */ +void nrf_drv_clock_hfclk_release(void); + +/** + * @brief Function for checking the HFCLK state. + * + * @retval true If the HFCLK is running (for \nRFXX XTAL source). + * @retval false If the HFCLK is not running. + */ +bool nrf_drv_clock_hfclk_is_running(void); + +/** + * @brief Function for starting a single calibration process. + * + * This function can also delay the start of calibration by a user-specified value. The delay will use + * a low-power timer that is part of the CLOCK module. @ref nrf_drv_clock_is_calibrating can be called to + * check if calibration is still in progress. If a handler is provided, the user can be notified when + * calibration is completed. The ext calibration can be started from the handler context. + * + * The calibration process consists of three phases: + * - Delay (optional) + * - Requesting the high-accuracy HFCLK + * - Hardware-supported calibration + * + * @param[in] delay Time after which the calibration will be started (in 0.25 s units). + * @param[in] handler NULL or user function to be called when calibration is completed or aborted. + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator. + * @retval NRF_ERROR_INVALID_STATE If the low-frequency clock is off. + * @retval NRF_ERROR_BUSY If calibration is in progress. + */ +ret_code_t nrf_drv_clock_calibration_start(uint8_t delay, nrf_drv_clock_event_handler_t handler); + +/** + * @brief Function for aborting calibration. + * + * This function aborts on-going calibration. If calibration was started, it cannot be stopped. If a handler + * was provided by @ref nrf_drv_clock_calibration_start, this handler will be called once + * aborted calibration is completed. @ref nrf_drv_clock_is_calibrating can also be used to check + * if the system is calibrating. + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator. + */ +ret_code_t nrf_drv_clock_calibration_abort(void); + +/** + * @brief Function for checking if calibration is in progress. + * + * This function indicates that the system is + * in calibration if it is in any of the calibration process phases (see @ref nrf_drv_clock_calibration_start). + * + * @param[out] p_is_calibrating True if calibration is in progress, false if not. + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator. + */ +ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating); + +/**@brief Function for returning a requested task address for the clock driver module. + * + * @param[in] task One of the peripheral tasks. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_clock_ppi_task_addr(nrf_clock_task_t task); + +/**@brief Function for returning a requested event address for the clock driver module. + * + * @param[in] event One of the peripheral events. + * + * @return Event address. + */ +__STATIC_INLINE uint32_t nrf_drv_clock_ppi_event_addr(nrf_clock_event_t event); + + +#ifdef SOFTDEVICE_PRESENT +/** + * @brief Function called by the SoftDevice handler if an @ref nrf_soc event is received from the SoftDevice. + * + * @param[in] evt_id One of NRF_SOC_EVTS values. + */ +void nrf_drv_clock_on_soc_event(uint32_t evt_id); + +/** + * @brief Function called by the SoftDevice handler when the SoftDevice has been enabled. + * + * This function is called just after the SoftDevice has been properly enabled. + * Its main purpose is to mark that LFCLK has been requested by SD. + */ +void nrf_drv_clock_on_sd_enable(void); + +/** + * @brief Function called by the SoftDevice handler when the SoftDevice has been disabled. + * + * This function is called just after the SoftDevice has been properly disabled. + * It has two purposes: + * 1. Releases the LFCLK from the SD. + * 2. Reinitializes an interrupt after the SD releases POWER_CLOCK_IRQ. + */ +void nrf_drv_clock_on_sd_disable(void); + +#endif +/** + *@} + **/ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION +__STATIC_INLINE uint32_t nrf_drv_clock_ppi_task_addr(nrf_clock_task_t task) +{ + return nrf_clock_task_address_get(task); +} + +__STATIC_INLINE uint32_t nrf_drv_clock_ppi_event_addr(nrf_clock_event_t event) +{ + return nrf_clock_event_address_get(event); +} +#endif //SUPPRESS_INLINE_IMPLEMENTATION + +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_CLOCK_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/common/nrf_drv_common.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/common/nrf_drv_common.c new file mode 100644 index 0000000000000000000000000000000000000000..e11706b9bb85f699c10c2378ea56913f5aef6068 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/common/nrf_drv_common.c @@ -0,0 +1,296 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "nrf_drv_common.h" +#include "nrf_assert.h" +#include "app_util_platform.h" +#include "nrf_peripherals.h" + +#if NRF_DRV_COMMON_POWER_CLOCK_ISR +#include "nrf_drv_power.h" +#include "nrf_drv_clock.h" +#endif +#ifdef SOFTDEVICE_PRESENT +#include "nrf_soc.h" +#endif + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +#define NRF_LOG_MODULE_NAME "COMMON" + +#if COMMON_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL COMMON_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR COMMON_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR COMMON_CONFIG_DEBUG_COLOR +#else //COMMON_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //COMMON_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +typedef struct { + nrf_drv_irq_handler_t handler; + bool acquired; +} shared_resource_t; + +// SPIM0, SPIS0, SPI0, TWIM0, TWIS0, TWI0 +#if (NRF_MODULE_ENABLED(SPI0) || NRF_MODULE_ENABLED(SPIS0) || NRF_MODULE_ENABLED(TWI0) || NRF_MODULE_ENABLED(TWIS0)) + #define SERIAL_BOX_0_IN_USE + // [this checking may need a different form in unit tests, hence macro] + #ifndef IS_SERIAL_BOX_0 + #define IS_SERIAL_BOX_0(p_per_base) (p_per_base == NRF_SPI0) + #endif + + static shared_resource_t m_serial_box_0 = { .acquired = false }; + void SPI0_TWI0_IRQHandler(void) + { + ASSERT(m_serial_box_0.handler); + m_serial_box_0.handler(); + } +#endif // (NRF_MODULE_ENABLED(SPI0) || NRF_MODULE_ENABLED(SPIS0) || NRF_MODULE_ENABLED(TWI0) || NRF_MODULE_ENABLED(TWIS0)) + +// SPIM1, SPIS1, SPI1, TWIM1, TWIS1, TWI1 +#if (NRF_MODULE_ENABLED(SPI1) || NRF_MODULE_ENABLED(SPIS1) || NRF_MODULE_ENABLED(TWI1) || NRF_MODULE_ENABLED(TWIS1)) + #define SERIAL_BOX_1_IN_USE + // [this checking may need a different form in unit tests, hence macro] + #ifndef IS_SERIAL_BOX_1 + #define IS_SERIAL_BOX_1(p_per_base) (p_per_base == NRF_SPI1) + #endif + + static shared_resource_t m_serial_box_1 = { .acquired = false }; +#ifdef TWIM_PRESENT + void SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler(void) +#else + void SPI1_TWI1_IRQHandler(void) +#endif + { + ASSERT(m_serial_box_1.handler); + m_serial_box_1.handler(); + } +#endif // (NRF_MODULE_ENABLED(SPI1) || NRF_MODULE_ENABLED(SPIS1) || NRF_MODULE_ENABLED(TWI1) || NRF_MODULE_ENABLED(TWIS1)) + +// SPIM2, SPIS2, SPI2 +#if (NRF_MODULE_ENABLED(SPI2) || NRF_MODULE_ENABLED(SPIS2)) + #define SERIAL_BOX_2_IN_USE + // [this checking may need a different form in unit tests, hence macro] + #ifndef IS_SERIAL_BOX_2 + #define IS_SERIAL_BOX_2(p_per_base) (p_per_base == NRF_SPI2) + #endif + + static shared_resource_t m_serial_box_2 = { .acquired = false }; + void SPIM2_SPIS2_SPI2_IRQHandler(void) + { + ASSERT(m_serial_box_2.handler); + m_serial_box_2.handler(); + } +#endif // (NRF_MODULE_ENABLED(SPI2) || NRF_MODULE_ENABLED(SPIS2)) + +// COMP, LPCOMP +#if (NRF_MODULE_ENABLED(COMP) || NRF_MODULE_ENABLED(LPCOMP)) + #define COMP_LPCOMP_IN_USE + + #ifndef IS_COMP_LPCOMP + #define IS_COMP_LPCOMP(p_per_base) ((p_per_base) == NRF_LPCOMP) + #endif + + static shared_resource_t m_comp_lpcomp = { .acquired = false }; + void LPCOMP_IRQHandler(void) + { + ASSERT(m_comp_lpcomp.handler); + m_comp_lpcomp.handler(); + } +#endif // (NRF_MODULE_ENABLED(COMP) || NRF_MODULE_ENABLED(LPCOMP)) + +#if defined(SERIAL_BOX_0_IN_USE) || \ + defined(SERIAL_BOX_1_IN_USE) || \ + defined(SERIAL_BOX_2_IN_USE) || \ + defined(COMP_LPCOMP_IN_USE) +static ret_code_t acquire_shared_resource(shared_resource_t * p_resource, + nrf_drv_irq_handler_t handler) +{ + ret_code_t err_code; + + bool busy = false; + + CRITICAL_REGION_ENTER(); + if (p_resource->acquired) + { + busy = true; + } + else + { + p_resource->acquired = true; + } + CRITICAL_REGION_EXIT(); + + if (busy) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + p_resource->handler = handler; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} +#endif + +ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base, + nrf_drv_irq_handler_t handler) +{ +#ifdef SERIAL_BOX_0_IN_USE + if (IS_SERIAL_BOX_0(p_per_base)) + { + return acquire_shared_resource(&m_serial_box_0, handler); + } +#endif + +#ifdef SERIAL_BOX_1_IN_USE + if (IS_SERIAL_BOX_1(p_per_base)) + { + return acquire_shared_resource(&m_serial_box_1, handler); + } +#endif + +#ifdef SERIAL_BOX_2_IN_USE + if (IS_SERIAL_BOX_2(p_per_base)) + { + return acquire_shared_resource(&m_serial_box_2, handler); + } +#endif + +#ifdef COMP_LPCOMP_IN_USE + if (IS_COMP_LPCOMP(p_per_base)) + { + return acquire_shared_resource(&m_comp_lpcomp, handler); + } +#endif + ret_code_t err_code; + + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +void nrf_drv_common_per_res_release(void const * p_per_base) +{ +#ifdef SERIAL_BOX_0_IN_USE + if (IS_SERIAL_BOX_0(p_per_base)) + { + m_serial_box_0.acquired = false; + } + else +#endif + +#ifdef SERIAL_BOX_1_IN_USE + if (IS_SERIAL_BOX_1(p_per_base)) + { + m_serial_box_1.acquired = false; + } + else +#endif + +#ifdef SERIAL_BOX_2_IN_USE + if (IS_SERIAL_BOX_2(p_per_base)) + { + m_serial_box_2.acquired = false; + } + else +#endif + +#ifdef COMP_LPCOMP_IN_USE + if (IS_COMP_LPCOMP(p_per_base)) + { + m_comp_lpcomp.acquired = false; + } + else +#endif + + {} +} + +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +#if NRF_MODULE_ENABLED(POWER) +void nrf_drv_common_power_irq_disable(void) +{ +#if NRF_DRV_COMMON_POWER_CLOCK_ISR + if(!nrf_drv_clock_init_check()) +#endif + { + nrf_drv_common_irq_disable(POWER_CLOCK_IRQn); + } +} +#endif + +#if NRF_MODULE_ENABLED(CLOCK) +void nrf_drv_common_clock_irq_disable(void) +{ +#if NRF_DRV_COMMON_POWER_CLOCK_ISR + if(!nrf_drv_power_init_check()) +#endif + { + nrf_drv_common_irq_disable(POWER_CLOCK_IRQn); + } +} +#endif + +#if NRF_DRV_COMMON_POWER_CLOCK_ISR +void POWER_CLOCK_IRQHandler(void) +{ + extern void nrf_drv_clock_onIRQ(void); + extern void nrf_drv_power_onIRQ(void); + + nrf_drv_clock_onIRQ(); + nrf_drv_power_onIRQ(); +} +#endif // NRF_DRV_COMMON_POWER_CLOCK_ISR + + +void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority) +{ + INTERRUPT_PRIORITY_ASSERT(priority); + + NVIC_SetPriority(IRQn, priority); + NVIC_ClearPendingIRQ(IRQn); + NVIC_EnableIRQ(IRQn); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/common/nrf_drv_common.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/common/nrf_drv_common.h new file mode 100644 index 0000000000000000000000000000000000000000..ef0e24a1b347bf49fa159142ea0a6a2279705fcd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/common/nrf_drv_common.h @@ -0,0 +1,357 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_DRV_COMMON_H__ +#define NRF_DRV_COMMON_H__ + +#include +#include +#include "nrf.h" +#include "sdk_errors.h" +#include "sdk_common.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NRF51 +#ifdef SOFTDEVICE_PRESENT +#define INTERRUPT_PRIORITY_IS_VALID(pri) (((pri) == 1) || ((pri) == 3)) +#else +#define INTERRUPT_PRIORITY_IS_VALID(pri) ((pri) < 4) +#endif //SOFTDEVICE_PRESENT +#else +#ifdef SOFTDEVICE_PRESENT +#define INTERRUPT_PRIORITY_IS_VALID(pri) ((((pri) > 1) && ((pri) < 4)) || (((pri) > 5) && ((pri) < 8))) +#else +#define INTERRUPT_PRIORITY_IS_VALID(pri) ((pri) < 8) +#endif //SOFTDEVICE_PRESENT +#endif //NRF52 + +#define INTERRUPT_PRIORITY_VALIDATION(pri) STATIC_ASSERT(INTERRUPT_PRIORITY_IS_VALID((pri))) +#define INTERRUPT_PRIORITY_ASSERT(pri) ASSERT(INTERRUPT_PRIORITY_IS_VALID((pri))) + +/** + * @defgroup nrf_drv_common Peripheral drivers common module + * @{ + * @ingroup nrf_drivers + */ + +/** + * @brief Offset of event registers in every peripheral instance. + * + * This is the offset where event registers start in every peripheral. + */ +#define NRF_DRV_COMMON_EVREGS_OFFSET 0x100U + +/** + * @brief The flag that is set when POWER_CLOCK ISR is implemented in common module + * + * This flag means that the function POWER_CLOCK_IRQHandler is implemented in + * nrf_drv_common.c file. In the @c clock and @c power modules functions + * nrf_drv_clock_onIRQ nrf_drv_power_onIRQ should be implemented + * and they would be called from common implementation. + * + * None of the checking is done here. + * The implementation functions in @c clock and @c power are required to handle + * correctly the case when they are called without any event bit set. + */ +#define NRF_DRV_COMMON_POWER_CLOCK_ISR (NRF_MODULE_ENABLED(CLOCK) && NRF_MODULE_ENABLED(POWER)) + +/** + * @brief Driver state. + */ +typedef enum +{ + NRF_DRV_STATE_UNINITIALIZED, /**< Uninitialized. */ + NRF_DRV_STATE_INITIALIZED, /**< Initialized but powered off. */ + NRF_DRV_STATE_POWERED_ON +} nrf_drv_state_t; + +/** + * @brief Driver power state selection. + */ +typedef enum +{ + NRF_DRV_PWR_CTRL_ON, /**< Power on request. */ + NRF_DRV_PWR_CTRL_OFF /**< Power off request. */ +} nrf_drv_pwr_ctrl_t; + +/** + * @brief IRQ handler type. + */ +typedef void (*nrf_drv_irq_handler_t)(void); + + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +/** + * @brief Function for acquiring shared peripheral resources associated with + * the specified peripheral. + * + * Certain resources and registers are shared among peripherals that have + * the same ID (for example: SPI0, SPIM0, SPIS0, TWI0, TWIM0, and TWIS0). + * Only one of them can be utilized at a given time. This function reserves + * proper resources to be used by the specified peripheral. + * If PERIPHERAL_RESOURCE_SHARING_ENABLED is set to a non-zero value, IRQ + * handlers for peripherals that are sharing resources with others are + * implemented by the nrf_drv_common module instead of individual drivers. + * The drivers must then specify their interrupt handling routines and + * register them by using this function. + * + * @param[in] p_per_base Requested peripheral base pointer. + * @param[in] handler Interrupt handler to register. May be NULL + * if interrupts are not used for the peripheral. + * + * @retval NRF_SUCCESS If resources were acquired successfully. + * @retval NRF_ERROR_BUSY If resources were already acquired. + * @retval NRF_ERROR_INVALID_PARAM If the specified peripheral is not enabled + * or the peripheral does not share resources + * with other peripherals. + */ +ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base, + nrf_drv_irq_handler_t handler); + +/** + * @brief Function for releasing shared resources reserved previously by + * @ref nrf_drv_common_per_res_acquire() for the specified peripheral. + * + * @param[in] p_per_base Requested peripheral base pointer. + */ +void nrf_drv_common_per_res_release(void const * p_per_base); + +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + + +/** + * @brief Function sets priority and enables NVIC interrupt + * + * @note Function checks if correct priority is used when softdevice is present + * + * @param[in] IRQn Interrupt id + * @param[in] priority Interrupt priority + */ +void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority); + +#if NRF_MODULE_ENABLED(POWER) +/** + * @brief Disable power IRQ + * + * Power and clock peripheral uses the same IRQ. + * This function disables POWER_CLOCK IRQ only if CLOCK driver + * is uninitialized. + * + * @sa nrf_drv_common_power_clock_irq_init + */ +void nrf_drv_common_power_irq_disable(void); +#endif + +#if NRF_MODULE_ENABLED(CLOCK) +/** + * @brief Disable clock IRQ + * + * Power and clock peripheral uses the same IRQ. + * This function disables POWER_CLOCK IRQ only if POWER driver + * is uninitialized. + * + * @sa nrf_drv_common_power_clock_irq_init + */ +void nrf_drv_common_clock_irq_disable(void); +#endif + +/** + * @brief Check if interrupt is enabled + * + * Function that checks if selected interrupt is enabled. + * + * @param[in] IRQn Interrupt id + * + * @retval true Selected IRQ is enabled. + * @retval false Selected IRQ is disabled. + */ +__STATIC_INLINE bool nrf_drv_common_irq_enable_check(IRQn_Type IRQn); + +/** + * @brief Function disables NVIC interrupt + * + * @param[in] IRQn Interrupt id + */ +__STATIC_INLINE void nrf_drv_common_irq_disable(IRQn_Type IRQn); + +/** + * @brief Convert bit position to event code + * + * Function for converting the bit position in INTEN register to event code + * that is equivalent to the offset of the event register from the beginning + * of peripheral instance. + * + * For example the result of this function can be casted directly to + * the types like @ref nrf_twis_event_t or @ref nrf_rng_event_t + * + * @param bit Bit position in INTEN register + * @return Event code to be casted to the right enum type or to be used in functions like + * @ref nrf_rng_event_get + * + * @sa nrf_drv_event_to_bitpos + */ +__STATIC_INLINE uint32_t nrf_drv_bitpos_to_event(uint32_t bit); + +/** + * @brief Convert event code to bit position + * + * This function can be used to get bit position in INTEN register from event code. + * + * @param event Event code that may be casted from enum values from types like + * @ref nrf_twis_event_t or @ref nrf_rng_event_t + * @return Bit position in INTEN register that corresponds to the given code. + * + * @sa nrf_drv_bitpos_to_event + */ +__STATIC_INLINE uint32_t nrf_drv_event_to_bitpos(uint32_t event); + +/** + * @brief Get interrupt number connected with given instance + * + * Function returns interrupt number for a given instance of any peripheral. + * @param[in] pinst Pointer to peripheral registry + * @return Interrupt number + */ +__STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst); + +#if NRF_MODULE_ENABLED(CLOCK) || NRF_MODULE_ENABLED(POWER) +/** + * @brief Enable and setup power clock IRQ + * + * This function would be called from @ref nrf_drv_clock and @ref nrf_drv_power + * to enable related interrupt. + * This function avoids multiple interrupt configuration. + * + * @note + * This function is aviable only if @ref nrf_drv_clock or @ref nrf_drv_power + * module is enabled. + * + * @note + * If both @ref nrf_drv_clock and @ref nrf_drv_power modules are enabled, + * during the compilation the check is made that + * @ref CLOCK_CONFIG_IRQ_PRIORITY equals @ref POWER_CONFIG_IRQ_PRIORITY. + * + * @sa nrf_drv_common_power_irq_disable + * @sa nrf_drv_common_clock_irq_disable + */ +__STATIC_INLINE void nrf_drv_common_power_clock_irq_init(void); +#endif + +/** + * @brief Check if given object is in RAM + * + * Function for analyzing if given location is placed in RAM. + * This function is used to determine if we have address that can be supported by EasyDMA. + * @param[in] ptr Pointer to the object + * @retval true Object is located in RAM + * @retval false Object is not located in RAM + */ +__STATIC_INLINE bool nrf_drv_is_in_RAM(void const * const ptr); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE bool nrf_drv_common_irq_enable_check(IRQn_Type IRQn) +{ + return 0 != (NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & + (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); +} + +__STATIC_INLINE void nrf_drv_common_irq_disable(IRQn_Type IRQn) +{ + NVIC_DisableIRQ(IRQn); +} + +__STATIC_INLINE uint32_t nrf_drv_bitpos_to_event(uint32_t bit) +{ + return NRF_DRV_COMMON_EVREGS_OFFSET + bit * sizeof(uint32_t); +} + +__STATIC_INLINE uint32_t nrf_drv_event_to_bitpos(uint32_t event) +{ + return (event - NRF_DRV_COMMON_EVREGS_OFFSET) / sizeof(uint32_t); +} + +__STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst) +{ + uint8_t ret = (uint8_t)((uint32_t)pinst>>12U); + return (IRQn_Type) ret; +} + +#if NRF_MODULE_ENABLED(CLOCK) || NRF_MODULE_ENABLED(POWER) +__STATIC_INLINE void nrf_drv_common_power_clock_irq_init(void) +{ + if(!nrf_drv_common_irq_enable_check(POWER_CLOCK_IRQn)) + { + nrf_drv_common_irq_enable( + POWER_CLOCK_IRQn, +#if NRF_DRV_COMMON_POWER_CLOCK_ISR + #if CLOCK_CONFIG_IRQ_PRIORITY != POWER_CONFIG_IRQ_PRIORITY + #error CLOCK_CONFIG_IRQ_PRIORITY and POWER_CONFIG_IRQ_PRIORITY have to be the same. + #endif + CLOCK_CONFIG_IRQ_PRIORITY +#elif NRF_MODULE_ENABLED(CLOCK) + CLOCK_CONFIG_IRQ_PRIORITY +#elif NRF_MODULE_ENABLED(POWER) + POWER_CONFIG_IRQ_PRIORITY +#endif + ); + } +} +#endif + +__STATIC_INLINE bool nrf_drv_is_in_RAM(void const * const ptr) +{ + return ((((uintptr_t)ptr) & 0xE0000000u) == 0x20000000u); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_COMMON_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/comp/nrf_drv_comp.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/comp/nrf_drv_comp.c new file mode 100644 index 0000000000000000000000000000000000000000..bb026ca52178e842d209c0d8b089b914881b8f11 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/comp/nrf_drv_comp.c @@ -0,0 +1,237 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(COMP) +#include "nrf_drv_comp.h" + +#include "nrf_assert.h" +#include "nrf_error.h" +#include "nrf_soc.h" +#include "nrf_drv_common.h" +#include "app_util_platform.h" +#include +#include +#include + +#define NRF_LOG_MODULE_NAME "COMP" + +#if COMP_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL COMP_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR COMP_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR COMP_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_COMP_EVENT_READY ? "NRF_COMP_EVENT_READY" : \ + (event == NRF_COMP_EVENT_DOWN ? "NRF_COMP_EVENT_DOWN" : \ + (event == NRF_COMP_EVENT_UP ? "NRF_COMP_EVENT_UP" : \ + (event == NRF_COMP_EVENT_CROSS ? "NRF_COMP_EVENT_CROSS" : "UNKNOWN ERROR")))) +#else //COMP_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //COMP_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + + +static comp_events_handler_t m_comp_events_handler = NULL; +static nrf_drv_state_t m_state = NRF_DRV_STATE_UNINITIALIZED; + +static const nrf_drv_comp_config_t m_default_config = NRF_DRV_COMP_DEFAULT_CONFIG(NRF_COMP_INPUT_0); + +static void comp_execute_handler(nrf_comp_event_t event, uint32_t event_mask) +{ + if ( nrf_comp_event_check(event) && nrf_comp_int_enable_check(event_mask) ) + { + nrf_comp_event_clear(event); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(event)); + + m_comp_events_handler(event); + } +} + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + #define IRQ_HANDLER_NAME irq_handler_for_comp + #define IRQ_HANDLER static void IRQ_HANDLER_NAME(void) + + IRQ_HANDLER; +#else + #define IRQ_HANDLER void COMP_LPCOMP_IRQHandler(void) +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +IRQ_HANDLER +{ + comp_execute_handler(NRF_COMP_EVENT_READY, COMP_INTENSET_READY_Msk); + comp_execute_handler(NRF_COMP_EVENT_DOWN, COMP_INTENSET_DOWN_Msk); + comp_execute_handler(NRF_COMP_EVENT_UP, COMP_INTENSET_UP_Msk); + comp_execute_handler(NRF_COMP_EVENT_CROSS, COMP_INTENSET_CROSS_Msk); +} + + +ret_code_t nrf_drv_comp_init(const nrf_drv_comp_config_t * p_config, + comp_events_handler_t event_handler) +{ + ret_code_t err_code; + + if (m_state != NRF_DRV_STATE_UNINITIALIZED) + { // COMP driver is already initialized + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + if (p_config == NULL) + { + p_config = &m_default_config; + } + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + if (nrf_drv_common_per_res_acquire(NRF_COMP, IRQ_HANDLER_NAME) != NRF_SUCCESS) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } +#endif + + nrf_comp_task_trigger(NRF_COMP_TASK_STOP); + nrf_comp_enable(); + + // Clear events to be sure there are no leftovers. + nrf_comp_event_clear(NRF_COMP_EVENT_READY); + nrf_comp_event_clear(NRF_COMP_EVENT_DOWN); + nrf_comp_event_clear(NRF_COMP_EVENT_UP); + nrf_comp_event_clear(NRF_COMP_EVENT_CROSS); + + nrf_comp_ref_set(p_config->reference); + + //If external source is chosen, write to appropriate register. + if (p_config->reference == COMP_REFSEL_REFSEL_ARef) + { + nrf_comp_ext_ref_set(p_config->ext_ref); + } + + nrf_comp_th_set(p_config->threshold); + nrf_comp_main_mode_set(p_config->main_mode); + nrf_comp_speed_mode_set(p_config->speed_mode); + nrf_comp_hysteresis_set(p_config->hyst); + nrf_comp_isource_set(p_config->isource); + nrf_comp_shorts_disable(NRF_DRV_COMP_SHORT_STOP_AFTER_CROSS_EVT | NRF_DRV_COMP_SHORT_STOP_AFTER_UP_EVT | + NRF_DRV_COMP_SHORT_STOP_AFTER_DOWN_EVT); + nrf_comp_int_disable(COMP_INTENCLR_CROSS_Msk | COMP_INTENCLR_UP_Msk | + COMP_INTENCLR_DOWN_Msk | COMP_INTENCLR_READY_Msk); + + if (event_handler) + { + m_comp_events_handler = event_handler; + } + else + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + nrf_comp_input_select(p_config->input); + + nrf_drv_common_irq_enable(COMP_LPCOMP_IRQn, p_config->interrupt_priority); + + m_state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_comp_uninit(void) +{ + ASSERT(m_state != NRF_DRV_STATE_UNINITIALIZED); + nrf_drv_common_irq_disable(COMP_LPCOMP_IRQn); + nrf_comp_disable(); +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + nrf_drv_common_per_res_release(NRF_COMP); +#endif + m_state = NRF_DRV_STATE_UNINITIALIZED; + m_comp_events_handler = NULL; + NRF_LOG_INFO("Uninitialized.\r\n"); +} + +void nrf_drv_comp_pin_select(nrf_comp_input_t psel) +{ + bool comp_enable_state = nrf_comp_enable_check(); + nrf_comp_task_trigger(NRF_COMP_TASK_STOP); + if (m_state == NRF_DRV_STATE_POWERED_ON) + { + m_state = NRF_DRV_STATE_INITIALIZED; + } + nrf_comp_disable(); + nrf_comp_input_select(psel); + if (comp_enable_state == true) + { + nrf_comp_enable(); + } +} + +void nrf_drv_comp_start(uint32_t comp_int_mask, uint32_t comp_shorts_mask) +{ + ASSERT(m_state == NRF_DRV_STATE_INITIALIZED); + nrf_comp_int_enable(comp_int_mask); + nrf_comp_shorts_enable(comp_shorts_mask); + nrf_comp_task_trigger(NRF_COMP_TASK_START); + m_state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Enabled.\r\n"); +} + +void nrf_drv_comp_stop(void) +{ + ASSERT(m_state == NRF_DRV_STATE_POWERED_ON); + nrf_comp_shorts_disable(UINT32_MAX); + nrf_comp_int_disable(UINT32_MAX); + nrf_comp_task_trigger(NRF_COMP_TASK_STOP); + m_state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Disabled.\r\n"); +} + +uint32_t nrf_drv_comp_sample() +{ + ASSERT(m_state == NRF_DRV_STATE_POWERED_ON); + nrf_comp_task_trigger(NRF_COMP_TASK_SAMPLE); + return nrf_comp_result_get(); +} +#endif //NRF_MODULE_ENABLED(COMP) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/comp/nrf_drv_comp.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/comp/nrf_drv_comp.h new file mode 100644 index 0000000000000000000000000000000000000000..5905a81076dd3b49769fc98f1f2f3d239c7e5fad --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/comp/nrf_drv_comp.h @@ -0,0 +1,243 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_DRV_COMP_H__ +#define NRF_DRV_COMP_H__ + +#include "sdk_config.h" +#include "nrf_comp.h" +#include "sdk_errors.h" +#include "nrf_drv_common.h" +#include "app_util_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup nrf_comp COMP HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52 Comparator (COMP) APIs. + * @details The COMP HAL provides basic APIs for accessing the registers of Comparator. + * The COMP driver provides APIs on a higher level. + * + * @defgroup nrf_drv_comp COMP driver + * @{ + * @ingroup nrf_comp + * @brief @tagAPI52 Comparator (COMP) driver. + */ + +/** + * @brief Macro to convert the threshold voltage to an integer value (needed by the COMP_TH register). + * + * @param[in] vol Voltage to be changed to COMP_TH register value. This value must not be smaller than + * reference voltage divided by 64. + * @param[in] ref Reference voltage. + */ +#define VOLTAGE_THRESHOLD_TO_INT(vol, ref) (uint8_t)(((vol) > ((ref) / 64)) ? (ROUNDED_DIV((vol) * 64,(ref)) - 1) : 0) + +/**@brief COMP event handler function type. + * @param[in] event COMP event. + */ +typedef void (* comp_events_handler_t)(nrf_comp_event_t event); + +/** + * @enum nrf_drv_comp_short_mask_t + * @brief COMP shortcut masks. + */ +typedef enum +{ + NRF_DRV_COMP_SHORT_STOP_AFTER_CROSS_EVT = COMP_SHORTS_CROSS_STOP_Msk, /*!< Shortcut between the CROSS event and the STOP task. */ + NRF_DRV_COMP_SHORT_STOP_AFTER_UP_EVT = COMP_SHORTS_UP_STOP_Msk, /*!< Shortcut between the UP event and the STOP task. */ + NRF_DRV_COMP_SHORT_STOP_AFTER_DOWN_EVT = COMP_SHORTS_DOWN_STOP_Msk /*!< Shortcut between the DOWN event and the STOP task. */ +}nrf_drv_comp_short_mask_t; + +/** + * @enum nrf_drv_comp_evt_en_mask_t + * @brief COMP events masks. + */ +typedef enum +{ + NRF_DRV_COMP_EVT_EN_CROSS_MASK = COMP_INTENSET_CROSS_Msk, /*!< CROSS event (generated after VIN+ == VIN-). */ + NRF_DRV_COMP_EVT_EN_UP_MASK = COMP_INTENSET_UP_Msk, /*!< UP event (generated when VIN+ crosses VIN- while increasing). */ + NRF_DRV_COMP_EVT_EN_DOWN_MASK = COMP_INTENSET_DOWN_Msk, /*!< DOWN event (generated when VIN+ crosses VIN- while decreasing). */ + NRF_DRV_COMP_EVT_EN_READY_MASK = COMP_INTENSET_READY_Msk /*!< READY event (generated when the module is ready). */ +}nrf_drv_comp_evt_en_mask_t; + +/**@brief COMP configuration. + */ +typedef struct +{ + nrf_comp_ref_t reference; /**< Reference selection. */ + nrf_comp_ext_ref_t ext_ref; /**< External analog reference selection. */ + nrf_comp_main_mode_t main_mode; /**< Main operation mode. */ + nrf_comp_th_t threshold; /**< Structure holding THDOWN and THUP values needed by the COMP_TH register. */ + nrf_comp_sp_mode_t speed_mode; /**< Speed and power mode. */ + nrf_comp_hyst_t hyst; /**< Comparator hysteresis.*/ + nrf_isource_t isource; /**< Current source selected on analog input. */ + nrf_comp_input_t input; /**< Input to be monitored. */ + uint8_t interrupt_priority; /**< Interrupt priority. */ +} nrf_drv_comp_config_t; + +/** @brief COMP threshold default configuration. */ +#define COMP_CONFIG_TH \ +{ \ + .th_down = VOLTAGE_THRESHOLD_TO_INT(0.5, 1.8), \ + .th_up = VOLTAGE_THRESHOLD_TO_INT(1.5, 1.8) \ +} + +/** @brief COMP driver default configuration including the COMP HAL configuration. */ +#define NRF_DRV_COMP_DEFAULT_CONFIG(INPUT) \ +{ \ + .reference = (nrf_comp_ref_t)COMP_CONFIG_REF, \ + .main_mode = (nrf_comp_main_mode_t)COMP_CONFIG_MAIN_MODE, \ + .threshold = COMP_CONFIG_TH, \ + .speed_mode = (nrf_comp_sp_mode_t)COMP_CONFIG_SPEED_MODE, \ + .hyst = (nrf_comp_hyst_t)COMP_CONFIG_HYST, \ + .isource = (nrf_isource_t)COMP_CONFIG_ISOURCE, \ + .input = (nrf_comp_input_t)INPUT, \ + .interrupt_priority = COMP_CONFIG_IRQ_PRIORITY \ +} + +/** + * @brief Function for initializing the COMP driver. + * + * This function initializes the COMP driver, but does not enable the peripheral or any interrupts. + * To start the driver, call the function @ref nrf_drv_comp_start() after initialization. + * + * If no configuration structure is provided, the driver is initialized with the default settings. + * + * @param[in] p_config Initial configuration. If NULL, the default configuration is used. + * @param[in] event_handler Handler function. + * + * @retval NRF_ERROR_INVALID_PARAM If the configuration is invalid. + * @retval NRF_ERROR_INVALID_STATE If the driver has already been initialized. + * @retval NRF_ERROR_BUSY If the LPCOMP driver is initialized. + */ +ret_code_t nrf_drv_comp_init(const nrf_drv_comp_config_t * p_config, + comp_events_handler_t event_handler); + + +/** + * @brief Function for uninitializing the COMP driver. + * + * This function uninitializes the COMP driver. The COMP peripheral and + * its interrupts are disabled, and local variables are cleaned. After this call, you must + * initialize the driver again by calling nrf_drv_comp_init() if you want to use it. + * + * @sa nrf_drv_comp_stop() + */ +void nrf_drv_comp_uninit(void); + +/** + * @brief Function for setting the analog input. + * + * @param[in] psel COMP analog pin selection. + */ +void nrf_drv_comp_pin_select(nrf_comp_input_t psel); + +/** + * @brief Function for starting the COMP peripheral and interrupts. + * + * Before calling this function, the driver must be initialized. This function + * enables the COMP peripheral and its interrupts. + * + * @param[in] comp_evt_en_mask Mask of events to be enabled. This parameter should be built as + * 'or' of elements from @ref nrf_drv_comp_evt_en_mask_t. + * @param[in] comp_shorts_mask Mask of shorts to be enabled. This parameter should be built as + * 'or' of elements from @ref nrf_drv_comp_short_mask_t. + * + * @sa nrf_drv_comp_init() + * + */ +void nrf_drv_comp_start(uint32_t comp_evt_en_mask, uint32_t comp_shorts_mask); + +/**@brief Function for stopping the COMP peripheral. + * + * Before calling this function, the driver must be enabled. This function disables the COMP + * peripheral and its interrupts. + * + * @sa nrf_drv_comp_uninit() + * + */ +void nrf_drv_comp_stop(void); + +/** + * @brief Function for copying the current state of the comparator result to the RESULT register. + * + * @retval 0 If the input voltage is below the threshold (VIN+ < VIN-). + * @retval 1 If the input voltage is above the threshold (VIN+ > VIN-). + */ +uint32_t nrf_drv_comp_sample(void); + +/** + * @brief Function for getting the task address. + * + * Before calling this function, the driver must be enabled. + * + * @param[in] comp_task COMP task. + * + * @return Address of the given COMP task. + */ +__STATIC_INLINE uint32_t nrf_drv_comp_task_address_get(nrf_comp_task_t comp_task) +{ + return (uint32_t)nrf_comp_task_address_get(comp_task); +} + +/** + * @brief Function for getting the event address. + * + * @param[in] comp_event COMP event. + * + * @return Address of the given COMP event. + */ +__STATIC_INLINE uint32_t nrf_drv_comp_event_address_get(nrf_comp_event_t comp_event) +{ + return (uint32_t)nrf_comp_event_address_get(comp_event); +} + +/** + *@} + **/ + + +#ifdef __cplusplus +} +#endif +#endif /* NRF_DRV_COMP_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/delay/nrf_delay.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/delay/nrf_delay.h new file mode 100644 index 0000000000000000000000000000000000000000..11f214af52cdabcb6a0dae2c57d4d00a176b01a8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/delay/nrf_delay.h @@ -0,0 +1,268 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef _NRF_DELAY_H +#define _NRF_DELAY_H + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CLOCK_FREQ_16MHz (16000000UL) + +#ifdef NRF52_SERIES + #define CPU_FREQ_64MHz +#endif + +/** + * @brief Function for delaying execution for number of microseconds. + * + * @note NRF52 has instruction cache and because of that delay is not precise. + * + * @param number_of_us + * + */ +/*lint --e{438, 522, 40, 10, 563} "Variable not used" "Function lacks side-effects" */ +__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us); + + +/** + * @brief Function for delaying execution for number of miliseconds. + * + * @note NRF52 has instruction cache and because of that delay is not precise. + * + * @note Function internally calls @ref nrf_delay_us so the maximum delay is the + * same as in case of @ref nrf_delay_us, approx. 71 minutes. + * + * @param number_of_ms + * + */ + +/*lint --e{438, 522, 40, 10, 563} "Variable not used" "Function lacks side-effects" */ +__STATIC_INLINE void nrf_delay_ms(uint32_t number_of_ms); + +#if defined ( __CC_ARM ) +__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us) +{ + if(!number_of_us) + return; +__asm + { +loop: + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + CMP SystemCoreClock, CLOCK_FREQ_16MHz + BEQ cond + NOP +#ifdef CPU_FREQ_64MHz + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP +#endif //CPU_FREQ_64MHz +cond: + SUBS number_of_us,number_of_us, #1 + BNE loop + } +} + +#elif defined ( _WIN32 ) || defined ( __unix ) || defined( __APPLE__ ) + + +#ifndef CUSTOM_NRF_DELAY_US +__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us) +{} +#endif + +#elif defined ( __GNUC__ ) || ( __ICCARM__ ) + +__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us) +{ + const uint32_t clock16MHz = CLOCK_FREQ_16MHz; + if (number_of_us) + { +__ASM volatile ( +#if ( defined(__GNUC__) && (__CORTEX_M == (0x00U) ) ) + ".syntax unified\n" +#endif +"1:\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " CMP %[SystemCoreClock],%[clock16MHz]\n" + " BEQ.n 2f\n" + " NOP\n" +#ifdef CPU_FREQ_64MHz + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" +#endif //CPU_FREQ_64MHz +"2:\n" + " SUBS %0, %0, #1\n" + " BNE.n 1b\n" +#if __CORTEX_M == (0x00U) +#ifdef __GNUC__ + ".syntax divided\n" +#endif + :"+l" (number_of_us) : +#else + :"+r" (number_of_us) : +#endif + [SystemCoreClock] "r" (SystemCoreClock), + [clock16MHz] "r" (clock16MHz) + ); +#ifdef __ICCARM__ + __DMB(); +#endif + } +} +#endif + +__STATIC_INLINE void nrf_delay_ms(uint32_t number_of_ms) +{ + nrf_delay_us(1000*number_of_ms); +} + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/gpiote/nrf_drv_gpiote.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/gpiote/nrf_drv_gpiote.c new file mode 100644 index 0000000000000000000000000000000000000000..37604b9a6a0ede1f48842ecefd0bc9a3112b7944 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/gpiote/nrf_drv_gpiote.c @@ -0,0 +1,808 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(GPIOTE) +#include "nrf_drv_gpiote.h" +#include "nrf_drv_common.h" +#include "app_util_platform.h" +#include "nrf_assert.h" +#include "nrf_bitmask.h" +#include + +#define NRF_LOG_MODULE_NAME "GPIOTE" + +#if GPIOTE_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL GPIOTE_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR GPIOTE_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR GPIOTE_CONFIG_DEBUG_COLOR +#else // GPIOTE_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // GPIOTE_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +/* Validate configuration */ +INTERRUPT_PRIORITY_VALIDATION(GPIOTE_CONFIG_IRQ_PRIORITY); + +#define FORBIDDEN_HANDLER_ADDRESS ((nrf_drv_gpiote_evt_handler_t)UINT32_MAX) +#define PIN_NOT_USED (-1) +#define PIN_USED (-2) +#define NO_CHANNELS (-1) +#define SENSE_FIELD_POS (6) +#define SENSE_FIELD_MASK (0xC0) + +/** + * @brief Macro for converting task-event index to an address of an event register. + * + * Macro utilizes the fact that registers are grouped together in ascending order. + */ +#define TE_IDX_TO_EVENT_ADDR(idx) (nrf_gpiote_events_t)((uint32_t)NRF_GPIOTE_EVENTS_IN_0 + \ + (sizeof(uint32_t) * (idx))) + +/** + * @brief Macro for converting task-event index of OUT task to an address of a task register. + * + * Macro utilizes the fact that registers are grouped together in ascending order. + */ +#define TE_OUT_IDX_TO_TASK_ADDR(idx) (nrf_gpiote_tasks_t)((uint32_t)NRF_GPIOTE_TASKS_OUT_0 + \ + (sizeof(uint32_t) * (idx))) + +#if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__SDK_DOXYGEN__) +/** + * @brief Macro for converting task-event index of SET task to an address of a task register. + * + * Macro utilizes the fact that registers are grouped together in ascending order. + */ +#define TE_SET_IDX_TO_TASK_ADDR(idx) (nrf_gpiote_tasks_t)((uint32_t)NRF_GPIOTE_TASKS_SET_0 + \ + (sizeof(uint32_t) * (idx))) + +#endif // defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__SDK_DOXYGEN__) + +#if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__SDK_DOXYGEN__) +/** + * @brief Macro for converting task-event index of CLR task to an address of a task register. + * + * Macro utilizes the fact that registers are grouped together in ascending order. + */ +#define TE_CLR_IDX_TO_TASK_ADDR(idx) (nrf_gpiote_tasks_t)((uint32_t)NRF_GPIOTE_TASKS_CLR_0 + \ + (sizeof(uint32_t) * (idx))) + +#endif // defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__SDK_DOXYGEN__) + +/*lint -save -e661*/ +typedef struct +{ + nrf_drv_gpiote_evt_handler_t handlers[GPIOTE_CH_NUM + GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS]; + int8_t pin_assignments[NUMBER_OF_PINS]; + int8_t port_handlers_pins[GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS]; + nrf_drv_state_t state; +} gpiote_control_block_t; + +static gpiote_control_block_t m_cb; + +__STATIC_INLINE bool pin_in_use(uint32_t pin) +{ + return (m_cb.pin_assignments[pin] != PIN_NOT_USED); +} + + +__STATIC_INLINE bool pin_in_use_as_non_task_out(uint32_t pin) +{ + return (m_cb.pin_assignments[pin] == PIN_USED); +} + + +__STATIC_INLINE bool pin_in_use_by_te(uint32_t pin) +{ + return (m_cb.pin_assignments[pin] >= 0 && m_cb.pin_assignments[pin] < + GPIOTE_CH_NUM) ? true : false; +} + + +__STATIC_INLINE bool pin_in_use_by_port(uint32_t pin) +{ + return (m_cb.pin_assignments[pin] >= GPIOTE_CH_NUM); +} + + +__STATIC_INLINE bool pin_in_use_by_gpiote(uint32_t pin) +{ + return (m_cb.pin_assignments[pin] >= 0); +} + + +__STATIC_INLINE void pin_in_use_by_te_set(uint32_t pin, + uint32_t channel_id, + nrf_drv_gpiote_evt_handler_t handler, + bool is_channel) +{ + m_cb.pin_assignments[pin] = channel_id; + m_cb.handlers[channel_id] = handler; + if (!is_channel) + { + m_cb.port_handlers_pins[channel_id - GPIOTE_CH_NUM] = (int8_t)pin; + } +} + + +__STATIC_INLINE void pin_in_use_set(uint32_t pin) +{ + m_cb.pin_assignments[pin] = PIN_USED; +} + + +__STATIC_INLINE void pin_in_use_clear(uint32_t pin) +{ + m_cb.pin_assignments[pin] = PIN_NOT_USED; +} + + +__STATIC_INLINE int8_t channel_port_get(uint32_t pin) +{ + return m_cb.pin_assignments[pin]; +} + + +__STATIC_INLINE nrf_drv_gpiote_evt_handler_t channel_handler_get(uint32_t channel) +{ + return m_cb.handlers[channel]; +} + + +static int8_t channel_port_alloc(uint32_t pin, nrf_drv_gpiote_evt_handler_t handler, bool channel) +{ + int8_t channel_id = NO_CHANNELS; + uint32_t i; + + uint32_t start_idx = channel ? 0 : GPIOTE_CH_NUM; + uint32_t end_idx = + channel ? GPIOTE_CH_NUM : (GPIOTE_CH_NUM + GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS); + + // critical section + + for (i = start_idx; i < end_idx; i++) + { + if (m_cb.handlers[i] == FORBIDDEN_HANDLER_ADDRESS) + { + pin_in_use_by_te_set(pin, i, handler, channel); + channel_id = i; + break; + } + } + // critical section + return channel_id; +} + + +static void channel_free(uint8_t channel_id) +{ + m_cb.handlers[channel_id] = FORBIDDEN_HANDLER_ADDRESS; + if (channel_id >= GPIOTE_CH_NUM) + { + m_cb.port_handlers_pins[channel_id - GPIOTE_CH_NUM] = (int8_t)PIN_NOT_USED; + } +} + + +ret_code_t nrf_drv_gpiote_init(void) +{ + ret_code_t err_code; + + if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + uint8_t i; + + for (i = 0; i < NUMBER_OF_PINS; i++) + { + pin_in_use_clear(i); + } + + for (i = 0; i < (GPIOTE_CH_NUM + GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS); i++) + { + channel_free(i); + } + + nrf_drv_common_irq_enable(GPIOTE_IRQn, GPIOTE_CONFIG_IRQ_PRIORITY); + nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT); + nrf_gpiote_int_enable(GPIOTE_INTENSET_PORT_Msk); + m_cb.state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +bool nrf_drv_gpiote_is_init(void) +{ + return (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) ? true : false; +} + + +void nrf_drv_gpiote_uninit(void) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + uint32_t i; + + for (i = 0; i < NUMBER_OF_PINS; i++) + { + if (pin_in_use_as_non_task_out(i)) + { + nrf_drv_gpiote_out_uninit(i); + } + else if ( pin_in_use_by_gpiote(i)) + { + /* Disable gpiote_in is having the same effect on out pin as gpiote_out_uninit on + * so it can be called on all pins used by GPIOTE. + */ + nrf_drv_gpiote_in_uninit(i); + } + } + m_cb.state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Uninitialized.\r\n"); +} + + +ret_code_t nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin, + nrf_drv_gpiote_out_config_t const * p_config) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(m_cb.state == NRF_DRV_STATE_INITIALIZED); + ASSERT(p_config); + + ret_code_t err_code = NRF_SUCCESS; + + if (pin_in_use(pin)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else + { + if (p_config->task_pin) + { + int8_t channel = channel_port_alloc(pin, NULL, true); + + if (channel != NO_CHANNELS) + { + nrf_gpiote_task_configure(channel, pin, p_config->action, p_config->init_state); + } + else + { + err_code = NRF_ERROR_NO_MEM; + } + } + else + { + pin_in_use_set(pin); + } + + if (err_code == NRF_SUCCESS) + { + if (p_config->init_state == NRF_GPIOTE_INITIAL_VALUE_HIGH) + { + nrf_gpio_pin_set(pin); + } + else + { + nrf_gpio_pin_clear(pin); + } + + nrf_gpio_cfg_output(pin); + } + } + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_gpiote_out_uninit(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use(pin)); + + if (pin_in_use_by_te(pin)) + { + channel_free((uint8_t)channel_port_get(pin)); + nrf_gpiote_te_default(channel_port_get(pin)); + } + pin_in_use_clear(pin); + + nrf_gpio_cfg_default(pin); +} + + +void nrf_drv_gpiote_out_set(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use(pin)); + ASSERT(!pin_in_use_by_te(pin)) + + nrf_gpio_pin_set(pin); +} + + +void nrf_drv_gpiote_out_clear(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use(pin)); + ASSERT(!pin_in_use_by_te(pin)) + + nrf_gpio_pin_clear(pin); +} + + +void nrf_drv_gpiote_out_toggle(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use(pin)); + ASSERT(!pin_in_use_by_te(pin)) + + nrf_gpio_pin_toggle(pin); +} + + +void nrf_drv_gpiote_out_task_enable(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use(pin)); + ASSERT(pin_in_use_by_te(pin)) + + nrf_gpiote_task_enable(m_cb.pin_assignments[pin]); +} + + +void nrf_drv_gpiote_out_task_disable(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use(pin)); + ASSERT(pin_in_use_by_te(pin)) + + nrf_gpiote_task_disable(m_cb.pin_assignments[pin]); +} + + +uint32_t nrf_drv_gpiote_out_task_addr_get(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use_by_te(pin)); + + nrf_gpiote_tasks_t task = TE_OUT_IDX_TO_TASK_ADDR(channel_port_get(pin)); + return nrf_gpiote_task_addr_get(task); +} + + +#if defined(GPIOTE_FEATURE_SET_PRESENT) +uint32_t nrf_drv_gpiote_set_task_addr_get(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use_by_te(pin)); + + nrf_gpiote_tasks_t task = TE_SET_IDX_TO_TASK_ADDR(channel_port_get(pin)); + return nrf_gpiote_task_addr_get(task); +} + + +#endif // defined(GPIOTE_FEATURE_SET_PRESENT) + +#if defined(GPIOTE_FEATURE_CLR_PRESENT) +uint32_t nrf_drv_gpiote_clr_task_addr_get(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use_by_te(pin)); + + nrf_gpiote_tasks_t task = TE_CLR_IDX_TO_TASK_ADDR(channel_port_get(pin)); + return nrf_gpiote_task_addr_get(task); +} + + +#endif // defined(GPIOTE_FEATURE_CLR_PRESENT) + +void nrf_drv_gpiote_out_task_force(nrf_drv_gpiote_pin_t pin, uint8_t state) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use(pin)); + ASSERT(pin_in_use_by_te(pin)); + + nrf_gpiote_outinit_t init_val = + state ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW; + nrf_gpiote_task_force(m_cb.pin_assignments[pin], init_val); +} + + +void nrf_drv_gpiote_out_task_trigger(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use(pin)); + ASSERT(pin_in_use_by_te(pin)); + + nrf_gpiote_tasks_t task = TE_OUT_IDX_TO_TASK_ADDR(channel_port_get(pin)); + nrf_gpiote_task_set(task); +} + + +#if defined(GPIOTE_FEATURE_SET_PRESENT) +void nrf_drv_gpiote_set_task_trigger(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use(pin)); + ASSERT(pin_in_use_by_te(pin)); + + nrf_gpiote_tasks_t task = TE_SET_IDX_TO_TASK_ADDR(channel_port_get(pin)); + nrf_gpiote_task_set(task); +} + + +#endif // defined(GPIOTE_FEATURE_SET_PRESENT) + +#if defined(GPIOTE_FEATURE_CLR_PRESENT) +void nrf_drv_gpiote_clr_task_trigger(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use(pin)); + ASSERT(pin_in_use_by_te(pin)); + + nrf_gpiote_tasks_t task = TE_CLR_IDX_TO_TASK_ADDR(channel_port_get(pin)); + nrf_gpiote_task_set(task); +} + + +#endif // defined(GPIOTE_FEATURE_CLR_PRESENT) + +ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin, + nrf_drv_gpiote_in_config_t const * p_config, + nrf_drv_gpiote_evt_handler_t evt_handler) +{ + ASSERT(pin < NUMBER_OF_PINS); + ret_code_t err_code = NRF_SUCCESS; + + /* Only one GPIOTE channel can be assigned to one physical pin. */ + if (pin_in_use_by_gpiote(pin)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else + { + int8_t channel = channel_port_alloc(pin, evt_handler, p_config->hi_accuracy); + if (channel != NO_CHANNELS) + { + if (p_config->is_watcher) + { + nrf_gpio_cfg_watcher(pin); + } + else + { + nrf_gpio_cfg_input(pin, p_config->pull); + } + + if (p_config->hi_accuracy) + { + nrf_gpiote_event_configure(channel, pin, p_config->sense); + } + else + { + m_cb.port_handlers_pins[channel - + GPIOTE_CH_NUM] |= (p_config->sense) << SENSE_FIELD_POS; + } + } + else + { + err_code = NRF_ERROR_NO_MEM; + } + } + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_gpiote_in_event_enable(nrf_drv_gpiote_pin_t pin, bool int_enable) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use_by_gpiote(pin)); + if (pin_in_use_by_port(pin)) + { + uint8_t pin_and_sense = + m_cb.port_handlers_pins[channel_port_get(pin) - GPIOTE_CH_NUM]; + nrf_gpiote_polarity_t polarity = + (nrf_gpiote_polarity_t)(pin_and_sense >> SENSE_FIELD_POS); + nrf_gpio_pin_sense_t sense; + if (polarity == NRF_GPIOTE_POLARITY_TOGGLE) + { + /* read current pin state and set for next sense to oposit */ + sense = (nrf_gpio_pin_read(pin)) ? + NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH; + } + else + { + sense = (polarity == NRF_GPIOTE_POLARITY_LOTOHI) ? + NRF_GPIO_PIN_SENSE_HIGH : NRF_GPIO_PIN_SENSE_LOW; + } + nrf_gpio_cfg_sense_set(pin, sense); + } + else if (pin_in_use_by_te(pin)) + { + int32_t channel = (int32_t)channel_port_get(pin); + nrf_gpiote_events_t event = TE_IDX_TO_EVENT_ADDR(channel); + + nrf_gpiote_event_enable(channel); + + nrf_gpiote_event_clear(event); + if (int_enable) + { + nrf_drv_gpiote_evt_handler_t handler = channel_handler_get(channel_port_get(pin)); + // Enable the interrupt only if event handler was provided. + if (handler) + { + nrf_gpiote_int_enable(1 << channel); + } + } + } +} + + +void nrf_drv_gpiote_in_event_disable(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use_by_gpiote(pin)); + if (pin_in_use_by_port(pin)) + { + nrf_gpio_cfg_sense_set(pin, NRF_GPIO_PIN_NOSENSE); + } + else if (pin_in_use_by_te(pin)) + { + int32_t channel = (int32_t)channel_port_get(pin); + nrf_gpiote_event_disable(channel); + nrf_gpiote_int_disable(1 << channel); + } +} + + +void nrf_drv_gpiote_in_uninit(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use_by_gpiote(pin)); + nrf_drv_gpiote_in_event_disable(pin); + if (pin_in_use_by_te(pin)) + { + nrf_gpiote_te_default(channel_port_get(pin)); + } + nrf_gpio_cfg_default(pin); + channel_free((uint8_t)channel_port_get(pin)); + pin_in_use_clear(pin); +} + + +bool nrf_drv_gpiote_in_is_set(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + return nrf_gpio_pin_read(pin) ? true : false; +} + + +uint32_t nrf_drv_gpiote_in_event_addr_get(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use_by_port(pin) || pin_in_use_by_te(pin)); + + nrf_gpiote_events_t event = NRF_GPIOTE_EVENTS_PORT; + + if (pin_in_use_by_te(pin)) + { + event = TE_IDX_TO_EVENT_ADDR(channel_port_get(pin)); + } + return nrf_gpiote_event_addr_get(event); +} + + +void GPIOTE_IRQHandler(void) +{ + uint32_t status = 0; + uint32_t input[GPIO_COUNT] = {0}; + + /* collect status of all GPIOTE pin events. Processing is done once all are collected and cleared.*/ + uint32_t i; + nrf_gpiote_events_t event = NRF_GPIOTE_EVENTS_IN_0; + uint32_t mask = (uint32_t)NRF_GPIOTE_INT_IN0_MASK; + + for (i = 0; i < GPIOTE_CH_NUM; i++) + { + if (nrf_gpiote_event_is_set(event) && nrf_gpiote_int_is_enabled(mask)) + { + nrf_gpiote_event_clear(event); + status |= mask; + } + mask <<= 1; + /* Incrementing to next event, utilizing the fact that events are grouped together + * in ascending order. */ + event = (nrf_gpiote_events_t)((uint32_t)event + sizeof(uint32_t)); + } + + /* collect PORT status event, if event is set read pins state. Processing is postponed to the + * end of interrupt. */ + if (nrf_gpiote_event_is_set(NRF_GPIOTE_EVENTS_PORT)) + { + nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT); + status |= (uint32_t)NRF_GPIOTE_INT_PORT_MASK; + nrf_gpio_ports_read(0, GPIO_COUNT, input); + } + + /* Process pin events. */ + if (status & NRF_GPIOTE_INT_IN_MASK) + { + mask = (uint32_t)NRF_GPIOTE_INT_IN0_MASK; + + for (i = 0; i < GPIOTE_CH_NUM; i++) + { + if (mask & status) + { + nrf_drv_gpiote_pin_t pin = nrf_gpiote_event_pin_get(i); + NRF_LOG_DEBUG("Event in number: %d.\r\n", i); + nrf_gpiote_polarity_t polarity = nrf_gpiote_event_polarity_get(i); + nrf_drv_gpiote_evt_handler_t handler = channel_handler_get(i); + NRF_LOG_DEBUG("Pin: %d, polarity: %d.\r\n", pin, polarity); + if (handler) + { + handler(pin, polarity); + } + } + mask <<= 1; + } + } + + if (status & (uint32_t)NRF_GPIOTE_INT_PORT_MASK) + { + /* Process port event. */ + uint32_t port_idx; + uint8_t repeat = 0; + uint32_t toggle_mask[GPIO_COUNT] = {0}; + uint32_t pins_to_check[GPIO_COUNT]; + + // Faster way of doing memset because in interrupt context. + for (port_idx = 0; port_idx < GPIO_COUNT; port_idx++) + { + pins_to_check[port_idx] = 0xFFFFFFFF; + } + + do + { + repeat = 0; + + for (i = 0; i < GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS; i++) + { + uint8_t pin_and_sense = m_cb.port_handlers_pins[i]; + nrf_drv_gpiote_pin_t pin = (pin_and_sense & ~SENSE_FIELD_MASK); + + if ((m_cb.port_handlers_pins[i] != PIN_NOT_USED) + && nrf_bitmask_bit_is_set(pin, pins_to_check)) + { + nrf_gpiote_polarity_t polarity = + (nrf_gpiote_polarity_t)((pin_and_sense & + SENSE_FIELD_MASK) >> SENSE_FIELD_POS); + nrf_drv_gpiote_evt_handler_t handler = + channel_handler_get(channel_port_get(pin)); + if (handler || (polarity == NRF_GPIOTE_POLARITY_TOGGLE)) + { + if (polarity == NRF_GPIOTE_POLARITY_TOGGLE) + { + nrf_bitmask_bit_set(pin, toggle_mask); + } + nrf_gpio_pin_sense_t sense = nrf_gpio_pin_sense_get(pin); + uint32_t pin_state = nrf_bitmask_bit_is_set(pin, input); + if ((pin_state && (sense == NRF_GPIO_PIN_SENSE_HIGH)) || + (!pin_state && (sense == NRF_GPIO_PIN_SENSE_LOW)) ) + { + NRF_LOG_DEBUG("PORT event for pin: %d, polarity: %d.\r\n", pin, + polarity); + if (polarity == NRF_GPIOTE_POLARITY_TOGGLE) + { + nrf_gpio_pin_sense_t next_sense = + (sense == NRF_GPIO_PIN_SENSE_HIGH) ? + NRF_GPIO_PIN_SENSE_LOW : + NRF_GPIO_PIN_SENSE_HIGH; + nrf_gpio_cfg_sense_set(pin, next_sense); + ++repeat; + + } + if (handler) + { + handler(pin, polarity); + } + } + } + } + } + + if (repeat) + { + // When one of the pins in low-accuracy and toggle mode becomes active, + // it's sense mode is inverted to clear the internal SENSE signal. + // State of any other enabled low-accuracy input in toggle mode must be checked + // explicitly, because it does not trigger the interrput when SENSE signal is active. + // For more information about SENSE functionality, refer to Product Specification. + + uint32_t new_input[GPIO_COUNT]; + bool input_unchanged = true; + nrf_gpio_ports_read(0, GPIO_COUNT, new_input); + + // Faster way of doing memcmp because in interrupt context. + for (port_idx = 0; port_idx < GPIO_COUNT; port_idx++) + { + if (new_input[port_idx] != input[port_idx]) + { + input_unchanged = false; + break; + } + } + + if (input_unchanged) + { + // No change. + repeat = 0; + } + else + { + // Faster way of doing memcpy because in interrupt context. + for (port_idx = 0; port_idx < GPIO_COUNT; port_idx++) + { + input[port_idx] = new_input[port_idx]; + pins_to_check[port_idx] = toggle_mask[port_idx]; + } + } + } + } + while (repeat); + } +} + + +/*lint -restore*/ +#endif // NRF_MODULE_ENABLED(GPIOTE) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/gpiote/nrf_drv_gpiote.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/gpiote/nrf_drv_gpiote.h new file mode 100644 index 0000000000000000000000000000000000000000..6c5f627b8ce7a274c6b13415ce0a9220cd516a1b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/gpiote/nrf_drv_gpiote.h @@ -0,0 +1,385 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_DRV_GPIOTE__ +#define NRF_DRV_GPIOTE__ + +/** + * @addtogroup nrf_gpiote GPIOTE abstraction and driver + * @ingroup nrf_drivers + * @brief GPIOTE APIs. + * @defgroup nrf_drv_gpiote GPIOTE driver + * @{ + * @ingroup nrf_gpiote + * @brief GPIOTE driver for managing input and output pins. + */ + +#include "nrf_gpiote.h" +#include "nrf_gpio.h" +#include "sdk_errors.h" +#include +#include +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Input pin configuration. */ +typedef struct +{ + nrf_gpiote_polarity_t sense; /**< Transition that triggers interrupt. */ + nrf_gpio_pin_pull_t pull; /**< Pulling mode. */ + bool is_watcher; /**< True when the input pin is tracking an output pin. */ + bool hi_accuracy;/**< True when high accuracy (IN_EVENT) is used. */ +} nrf_drv_gpiote_in_config_t; + +/**@brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect low-to-high transition. + * @details Set hi_accu to true to use IN_EVENT. */ +#define GPIOTE_CONFIG_IN_SENSE_LOTOHI(hi_accu) \ + { \ + .is_watcher = false, \ + .hi_accuracy = hi_accu, \ + .pull = NRF_GPIO_PIN_NOPULL, \ + .sense = NRF_GPIOTE_POLARITY_LOTOHI, \ + } + +/**@brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect high-to-low transition. + * @details Set hi_accu to true to use IN_EVENT. */ +#define GPIOTE_CONFIG_IN_SENSE_HITOLO(hi_accu) \ + { \ + .is_watcher = false, \ + .hi_accuracy = hi_accu, \ + .pull = NRF_GPIO_PIN_NOPULL, \ + .sense = NRF_GPIOTE_POLARITY_HITOLO, \ + } + +/**@brief Macro for configuring a pin to use a GPIO IN or PORT EVENT to detect any change on the pin. + * @details Set hi_accu to true to use IN_EVENT.*/ +#define GPIOTE_CONFIG_IN_SENSE_TOGGLE(hi_accu) \ + { \ + .is_watcher = false, \ + .hi_accuracy = hi_accu, \ + .pull = NRF_GPIO_PIN_NOPULL, \ + .sense = NRF_GPIOTE_POLARITY_TOGGLE, \ + } + +/**@brief Output pin configuration. */ +typedef struct +{ + nrf_gpiote_polarity_t action; /**< Configuration of the pin task. */ + nrf_gpiote_outinit_t init_state; /**< Initial state of the output pin. */ + bool task_pin; /**< True if the pin is controlled by a GPIOTE task. */ +} nrf_drv_gpiote_out_config_t; + +/**@brief Macro for configuring a pin to use as output. GPIOTE is not used for the pin. */ +#define GPIOTE_CONFIG_OUT_SIMPLE(init_high) \ + { \ + .init_state = init_high ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW, \ + .task_pin = false, \ + } + +/**@brief Macro for configuring a pin to use the GPIO OUT TASK to change the state from high to low. + * @details The task will clear the pin. Therefore, the pin is set initially. */ +#define GPIOTE_CONFIG_OUT_TASK_LOW \ + { \ + .init_state = NRF_GPIOTE_INITIAL_VALUE_HIGH, \ + .task_pin = true, \ + .action = NRF_GPIOTE_POLARITY_HITOLO, \ + } + +/**@brief Macro for configuring a pin to use the GPIO OUT TASK to change the state from low to high. + * @details The task will set the pin. Therefore, the pin is cleared initially. */ +#define GPIOTE_CONFIG_OUT_TASK_HIGH \ + { \ + .init_state = NRF_GPIOTE_INITIAL_VALUE_LOW, \ + .task_pin = true, \ + .action = NRF_GPIOTE_POLARITY_LOTOHI, \ + } + +/**@brief Macro for configuring a pin to use the GPIO OUT TASK to toggle the pin state. + * @details The initial pin state must be provided. */ +#define GPIOTE_CONFIG_OUT_TASK_TOGGLE(init_high) \ + { \ + .init_state = init_high ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW, \ + .task_pin = true, \ + .action = NRF_GPIOTE_POLARITY_TOGGLE, \ + } + +/** @brief Pin. */ +typedef uint32_t nrf_drv_gpiote_pin_t; + +/** + * @brief Pin event handler prototype. + * @param pin Pin that triggered this event. + * @param action Action that lead to triggering this event. + */ +typedef void (*nrf_drv_gpiote_evt_handler_t)(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action); + +/** + * @brief Function for initializing the GPIOTE module. + * + * @details Only static configuration is supported to prevent the shared + * resource being customized by the initiator. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver was already initialized. + */ +ret_code_t nrf_drv_gpiote_init(void); + +/** + * @brief Function for checking if the GPIOTE module is initialized. + * + * @details The GPIOTE module is a shared module. Therefore, you should check if + * the module is already initialized and skip initialization if it is. + * + * @retval true If the module is already initialized. + * @retval false If the module is not initialized. + */ +bool nrf_drv_gpiote_is_init(void); + +/** + * @brief Function for uninitializing the GPIOTE module. + */ +void nrf_drv_gpiote_uninit(void); + +/** + * @brief Function for initializing a GPIOTE output pin. + * @details The output pin can be controlled by the CPU or by PPI. The initial + * configuration specifies which mode is used. If PPI mode is used, the driver + * attempts to allocate one of the available GPIOTE channels. If no channel is + * available, an error is returned. + * + * @param[in] pin Pin. + * @param[in] p_config Initial configuration. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver is not initialized or the pin is already used. + * @retval NRF_ERROR_NO_MEM If no GPIOTE channel is available. + */ +ret_code_t nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin, + nrf_drv_gpiote_out_config_t const * p_config); + +/** + * @brief Function for uninitializing a GPIOTE output pin. + * @details The driver frees the GPIOTE channel if the output pin was using one. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_out_uninit(nrf_drv_gpiote_pin_t pin); + +/** + * @brief Function for setting a GPIOTE output pin. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_out_set(nrf_drv_gpiote_pin_t pin); + +/** + * @brief Function for clearing a GPIOTE output pin. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_out_clear(nrf_drv_gpiote_pin_t pin); + +/** + * @brief Function for toggling a GPIOTE output pin. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_out_toggle(nrf_drv_gpiote_pin_t pin); + +/** + * @brief Function for enabling a GPIOTE output pin task. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_out_task_enable(nrf_drv_gpiote_pin_t pin); + +/** + * @brief Function for disabling a GPIOTE output pin task. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_out_task_disable(nrf_drv_gpiote_pin_t pin); + +/** + * @brief Function for getting the address of a configurable GPIOTE task. + * + * @param[in] pin Pin. + * + * @return Address of OUT task. + */ +uint32_t nrf_drv_gpiote_out_task_addr_get(nrf_drv_gpiote_pin_t pin); + +#if defined(GPIOTE_FEATURE_SET_PRESENT) +/** + * @brief Function for getting the address of a configurable GPIOTE task. + * + * @param[in] pin Pin. + * + * @return Address of SET task. + */ +uint32_t nrf_drv_gpiote_set_task_addr_get(nrf_drv_gpiote_pin_t pin); +#endif // defined(GPIOTE_FEATURE_SET_PRESENT) + +#if defined(GPIOTE_FEATURE_CLR_PRESENT) +/** + * @brief Function for getting the address of a configurable GPIOTE task. + * + * @param[in] pin Pin. + * + * @return Address of CLR task. + */ +uint32_t nrf_drv_gpiote_clr_task_addr_get(nrf_drv_gpiote_pin_t pin); +#endif // defined(GPIOTE_FEATURE_CLR_PRESENT) + +/** + * @brief Function for initializing a GPIOTE input pin. + * @details The input pin can act in two ways: + * - lower accuracy but low power (high frequency clock not needed) + * - higher accuracy (high frequency clock required) + * + * The initial configuration specifies which mode is used. + * If high-accuracy mode is used, the driver attempts to allocate one + * of the available GPIOTE channels. If no channel is + * available, an error is returned. + * In low accuracy mode SENSE feature is used. In this case only one active pin + * can be detected at a time. It can be worked around by setting all of the used + * low accuracy pins to toggle mode. + * For more information about SENSE functionality, refer to Product Specification. + * + * @param[in] pin Pin. + * @param[in] p_config Initial configuration. + * @param[in] evt_handler User function to be called when the configured transition occurs. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver is not initialized or the pin is already used. + * @retval NRF_ERROR_NO_MEM If no GPIOTE channel is available. + */ +ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin, + nrf_drv_gpiote_in_config_t const * p_config, + nrf_drv_gpiote_evt_handler_t evt_handler); + +/** + * @brief Function for uninitializing a GPIOTE input pin. + * @details The driver frees the GPIOTE channel if the input pin was using one. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_in_uninit(nrf_drv_gpiote_pin_t pin); + +/** + * @brief Function for enabling sensing of a GPIOTE input pin. + * + * @details If the input pin is configured as high-accuracy pin, the function + * enables an IN_EVENT. Otherwise, the function enables the GPIO sense mechanism. + * Note that a PORT event is shared between multiple pins, therefore the + * interrupt is always enabled. + * + * @param[in] pin Pin. + * @param[in] int_enable True to enable the interrupt. Always valid for a high-accuracy pin. + */ +void nrf_drv_gpiote_in_event_enable(nrf_drv_gpiote_pin_t pin, bool int_enable); + +/** + * @brief Function for disabling a GPIOTE input pin. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_in_event_disable(nrf_drv_gpiote_pin_t pin); + +/** + * @brief Function for checking if a GPIOTE input pin is set. + * + * @param[in] pin Pin. + * @retval true If the input pin is set. + * @retval false If the input pin is not set. + */ +bool nrf_drv_gpiote_in_is_set(nrf_drv_gpiote_pin_t pin); + +/** + * @brief Function for getting the address of a GPIOTE input pin event. + * @details If the pin is configured to use low-accuracy mode, the address of the PORT event is returned. + * + * @param[in] pin Pin. + */ +uint32_t nrf_drv_gpiote_in_event_addr_get(nrf_drv_gpiote_pin_t pin); + +/** + * @brief Function for forcing a specific state on the pin configured as task. + * + * @param[in] pin Pin. + * @param[in] state Pin state. + */ +void nrf_drv_gpiote_out_task_force(nrf_drv_gpiote_pin_t pin, uint8_t state); + +/** + * @brief Function for triggering the task OUT manually. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_out_task_trigger(nrf_drv_gpiote_pin_t pin); + +#ifdef NRF52_SERIES +/** + * @brief Function for triggering the task SET manually. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_set_task_trigger(nrf_drv_gpiote_pin_t pin); + +/** + * @brief Function for triggering the task CLR manually. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_clr_task_trigger(nrf_drv_gpiote_pin_t pin); +#endif + +/** + *@} + **/ + + +#ifdef __cplusplus +} +#endif + +#endif //NRF_DRV_GPIOTE__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_clock.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_clock.h new file mode 100644 index 0000000000000000000000000000000000000000..50a7271a9db1de3a7b172afe7f9b6e4861aee5e9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_clock.h @@ -0,0 +1,401 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CLOCK_H__ +#define NRF_CLOCK_H__ + +#include +#include + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_clock_hal Clock HAL + * @{ + * @ingroup nrf_clock + * @brief Hardware access layer for managing the low-frequency clock (LFCLK) and the high-frequency clock (HFCLK). + */ + +#define NRF_CLOCK_TASK_TRIGGER (1UL) +#define NRF_CLOCK_EVENT_CLEAR (0UL) + +/** + * @brief Low-frequency clock sources. + * @details Used by LFCLKSRC, LFCLKSTAT, and LFCLKSRCCOPY registers. + */ +typedef enum +{ + NRF_CLOCK_LFCLK_RC = CLOCK_LFCLKSRC_SRC_RC, /**< Internal 32 kHz RC oscillator. */ + NRF_CLOCK_LFCLK_Xtal = CLOCK_LFCLKSRC_SRC_Xtal, /**< External 32 kHz crystal. */ + NRF_CLOCK_LFCLK_Synth = CLOCK_LFCLKSRC_SRC_Synth /**< Internal 32 kHz synthesizer from HFCLK system clock. */ +} nrf_clock_lfclk_t; + +/** + * @brief High-frequency clock sources. + */ +typedef enum +{ + NRF_CLOCK_HFCLK_LOW_ACCURACY = CLOCK_HFCLKSTAT_SRC_RC, /**< Internal 16 MHz RC oscillator. */ + NRF_CLOCK_HFCLK_HIGH_ACCURACY = CLOCK_HFCLKSTAT_SRC_Xtal /**< External 16 MHz/32 MHz crystal oscillator. */ +} nrf_clock_hfclk_t; + +/** + * @brief Trigger status of task LFCLKSTART/HFCLKSTART. + * @details Used by LFCLKRUN and HFCLKRUN registers. + */ +typedef enum +{ + NRF_CLOCK_START_TASK_NOT_TRIGGERED = CLOCK_LFCLKRUN_STATUS_NotTriggered, /**< Task LFCLKSTART/HFCLKSTART has not been triggered. */ + NRF_CLOCK_START_TASK_TRIGGERED = CLOCK_LFCLKRUN_STATUS_Triggered /**< Task LFCLKSTART/HFCLKSTART has been triggered. */ +} nrf_clock_start_task_status_t; + +/** + * @brief Interrupts. + */ +typedef enum +{ + NRF_CLOCK_INT_HF_STARTED_MASK = CLOCK_INTENSET_HFCLKSTARTED_Msk, /**< Interrupt on HFCLKSTARTED event. */ + NRF_CLOCK_INT_LF_STARTED_MASK = CLOCK_INTENSET_LFCLKSTARTED_Msk, /**< Interrupt on LFCLKSTARTED event. */ + NRF_CLOCK_INT_DONE_MASK = CLOCK_INTENSET_DONE_Msk, /**< Interrupt on DONE event. */ + NRF_CLOCK_INT_CTTO_MASK = CLOCK_INTENSET_CTTO_Msk /**< Interrupt on CTTO event. */ +} nrf_clock_int_mask_t; + +/** + * @brief Tasks. + * + * @details The NRF_CLOCK_TASK_LFCLKSTOP task cannot be set when the low-frequency clock is not running. + * The NRF_CLOCK_TASK_HFCLKSTOP task cannot be set when the high-frequency clock is not running. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_CLOCK_TASK_HFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTART), /**< Start HFCLK clock source.*/ + NRF_CLOCK_TASK_HFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_HFCLKSTOP), /**< Stop HFCLK clock source.*/ + NRF_CLOCK_TASK_LFCLKSTART = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTART), /**< Start LFCLK clock source.*/ + NRF_CLOCK_TASK_LFCLKSTOP = offsetof(NRF_CLOCK_Type, TASKS_LFCLKSTOP), /**< Stop LFCLK clock source.*/ + NRF_CLOCK_TASK_CAL = offsetof(NRF_CLOCK_Type, TASKS_CAL), /**< Start calibration of LFCLK RC oscillator.*/ + NRF_CLOCK_TASK_CTSTART = offsetof(NRF_CLOCK_Type, TASKS_CTSTART), /**< Start calibration timer.*/ + NRF_CLOCK_TASK_CTSTOP = offsetof(NRF_CLOCK_Type, TASKS_CTSTOP) /**< Stop calibration timer.*/ +} nrf_clock_task_t; /*lint -restore */ + +/** + * @brief Events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_CLOCK_EVENT_HFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_HFCLKSTARTED), /**< HFCLK oscillator started.*/ + NRF_CLOCK_EVENT_LFCLKSTARTED = offsetof(NRF_CLOCK_Type, EVENTS_LFCLKSTARTED), /**< LFCLK oscillator started.*/ + NRF_CLOCK_EVENT_DONE = offsetof(NRF_CLOCK_Type, EVENTS_DONE), /**< Calibration of LFCLK RC oscillator completed.*/ + NRF_CLOCK_EVENT_CTTO = offsetof(NRF_CLOCK_Type, EVENTS_CTTO) /**< Calibration timer time-out.*/ +} nrf_clock_event_t; /*lint -restore */ + +/** + * @brief Function for enabling a specific interrupt. + * + * @param[in] int_mask Interrupt. + */ +__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask); + +/** + * @brief Function for disabling a specific interrupt. + * + * @param[in] int_mask Interrupt. + */ +__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask); + +/** + * @brief Function for retrieving the state of a specific interrupt. + * + * @param[in] int_mask Interrupt. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask); + +/** + * @brief Function for retrieving the address of a specific task. + * @details This function can be used by the PPI module. + * + * @param[in] task Task. + * + * @return Address of the requested task register. + */ +__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task); + +/** + * @brief Function for setting a specific task. + * + * @param[in] task Task. + */ +__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task); + +/** + * @brief Function for retrieving the address of a specific event. + * @details This function can be used by the PPI module. + * + * @param[in] event Event. + * + * @return Address of the requested event register. + */ +__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event); + +/** + * @brief Function for clearing a specific event. + * + * @param[in] event Event. + */ +__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event); + +/** + * @brief Function for retrieving the state of a specific event. + * + * @param[in] event Event. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event); + +/** + * @brief Function for changing the low-frequency clock source. + * @details This function cannot be called when the low-frequency clock is running. + * + * @param[in] source New low-frequency clock source. + * + */ +__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source); + +/** + * @brief Function for retrieving the selected source for the low-frequency clock. + * + * @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is the selected source for the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is the selected source for the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is the selected source for the low-frequency clock. + */ +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void); + +/** + * @brief Function for retrieving the active source of the low-frequency clock. + * + * @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is the active source of the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is the active source of the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is the active source of the low-frequency clock. + */ +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(void); + +/** + * @brief Function for retrieving the clock source for the LFCLK clock when the task LKCLKSTART is triggered. + * + * @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is running and generating the LFCLK clock. + * @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is running and generating the LFCLK clock. + * @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is running and generating the LFCLK clock. + */ +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(void); + +/** + * @brief Function for retrieving the state of the LFCLK clock. + * + * @retval false If the LFCLK clock is not running. + * @retval true If the LFCLK clock is running. + */ +__STATIC_INLINE bool nrf_clock_lf_is_running(void); + +/** + * @brief Function for retrieving the trigger status of the task LFCLKSTART. + * + * @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED If the task LFCLKSTART has not been triggered. + * @retval NRF_CLOCK_START_TASK_TRIGGERED If the task LFCLKSTART has been triggered. + */ +__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void); + +/** + * @brief Function for retrieving the active source of the high-frequency clock. + * + * @retval NRF_CLOCK_HFCLK_LOW_ACCURACY If the internal 16 MHz RC oscillator is the active source of the high-frequency clock. + * @retval NRF_CLOCK_HFCLK_HIGH_ACCURACY If an external 16 MHz/32 MHz crystal oscillator is the active source of the high-frequency clock. + */ +__STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void); + +/** + * @brief Function for retrieving the state of the HFCLK clock. + * + * @param[in] clk_src Clock source to be checked. + * + * @retval false If the HFCLK clock is not running. + * @retval true If the HFCLK clock is running. + */ +__STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src); + +/** + * @brief Function for retrieving the trigger status of the task HFCLKSTART. + * + * @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED If the task HFCLKSTART has not been triggered. + * @retval NRF_CLOCK_START_TASK_TRIGGERED If the task HFCLKSTART has been triggered. + */ +__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void); + +/** + * @brief Function for changing the calibration timer interval. + * + * @param[in] interval New calibration timer interval in 0.25 s resolution (range: 0.25 seconds to 31.75 seconds). + */ +__STATIC_INLINE void nrf_clock_cal_timer_timeout_set(uint32_t interval); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask) +{ + NRF_CLOCK->INTENSET = int_mask; +} + +__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask) +{ + NRF_CLOCK->INTENCLR = int_mask; +} + +__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask) +{ + return (bool)(NRF_CLOCK->INTENCLR & int_mask); +} + +__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task) +{ + return ((uint32_t )NRF_CLOCK + task); +} + +__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + task)) = NRF_CLOCK_TASK_TRIGGER; +} + +__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event) +{ + return ((uint32_t)NRF_CLOCK + event); +} + +__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)) = NRF_CLOCK_EVENT_CLEAR; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event) +{ + return (bool)*((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)); +} + +__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source) +{ + NRF_CLOCK->LFCLKSRC = + (uint32_t)((source << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); +} + +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void) +{ + return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSRC & + CLOCK_LFCLKSRC_SRC_Msk) >> CLOCK_LFCLKSRC_SRC_Pos); +} + +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(void) +{ + return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSTAT & + CLOCK_LFCLKSTAT_SRC_Msk) >> CLOCK_LFCLKSTAT_SRC_Pos); +} + +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(void) +{ + return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSRCCOPY & + CLOCK_LFCLKSRCCOPY_SRC_Msk) >> CLOCK_LFCLKSRCCOPY_SRC_Pos); +} + +__STATIC_INLINE bool nrf_clock_lf_is_running(void) +{ + return ((NRF_CLOCK->LFCLKSTAT & + CLOCK_LFCLKSTAT_STATE_Msk) >> CLOCK_LFCLKSTAT_STATE_Pos); +} + +__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void) +{ + return (nrf_clock_start_task_status_t)((NRF_CLOCK->LFCLKRUN & + CLOCK_LFCLKRUN_STATUS_Msk) >> + CLOCK_LFCLKRUN_STATUS_Pos); +} + +__STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void) +{ + return (nrf_clock_hfclk_t)((NRF_CLOCK->HFCLKSTAT & + CLOCK_HFCLKSTAT_SRC_Msk) >> CLOCK_HFCLKSTAT_SRC_Pos); +} + +__STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src) +{ + return (NRF_CLOCK->HFCLKSTAT & (CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk)) == + (CLOCK_HFCLKSTAT_STATE_Msk | (clk_src << CLOCK_HFCLKSTAT_SRC_Pos)); +} + +__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void) +{ + return (nrf_clock_start_task_status_t)((NRF_CLOCK->HFCLKRUN & + CLOCK_HFCLKRUN_STATUS_Msk) >> + CLOCK_HFCLKRUN_STATUS_Pos); +} + +__STATIC_INLINE void nrf_clock_cal_timer_timeout_set(uint32_t interval) +{ + NRF_CLOCK->CTIV = ((interval << CLOCK_CTIV_CTIV_Pos) & CLOCK_CTIV_CTIV_Msk); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_CLOCK_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_comp.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_comp.h new file mode 100644 index 0000000000000000000000000000000000000000..97be9db28cd7dafc31120ef8034d1e11c73c3b4c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_comp.h @@ -0,0 +1,509 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief COMP HAL API. + */ + +#ifndef NRF_COMP_H_ +#define NRF_COMP_H_ + +/** + * @defgroup nrf_comp_hal COMP HAL + * @{ + * @ingroup nrf_comp + * @brief @tagAPI52 Hardware access layer for managing the Comparator (COMP). + */ + +#include "nrf.h" + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @enum nrf_comp_input_t + * @brief COMP analog pin selection. + */ +typedef enum +{ + NRF_COMP_INPUT_0 = COMP_PSEL_PSEL_AnalogInput0, /*!< AIN0 selected as analog input. */ + NRF_COMP_INPUT_1 = COMP_PSEL_PSEL_AnalogInput1, /*!< AIN1 selected as analog input. */ + NRF_COMP_INPUT_2 = COMP_PSEL_PSEL_AnalogInput2, /*!< AIN2 selected as analog input. */ + NRF_COMP_INPUT_3 = COMP_PSEL_PSEL_AnalogInput3, /*!< AIN3 selected as analog input. */ + NRF_COMP_INPUT_4 = COMP_PSEL_PSEL_AnalogInput4, /*!< AIN4 selected as analog input. */ + NRF_COMP_INPUT_5 = COMP_PSEL_PSEL_AnalogInput5, /*!< AIN5 selected as analog input. */ + NRF_COMP_INPUT_6 = COMP_PSEL_PSEL_AnalogInput6, /*!< AIN6 selected as analog input. */ + NRF_COMP_INPUT_7 = COMP_PSEL_PSEL_AnalogInput7 /*!< AIN7 selected as analog input. */ +}nrf_comp_input_t; + +/** + * @enum nrf_comp_ref_t + * @brief COMP reference selection. + */ +typedef enum +{ + NRF_COMP_REF_Int1V2 = COMP_REFSEL_REFSEL_Int1V2, /*!< VREF = internal 1.2 V reference (VDD >= 1.7 V). */ + NRF_COMP_REF_Int1V8 = COMP_REFSEL_REFSEL_Int1V8, /*!< VREF = internal 1.8 V reference (VDD >= VREF + 0.2 V). */ + NRF_COMP_REF_Int2V4 = COMP_REFSEL_REFSEL_Int2V4, /*!< VREF = internal 2.4 V reference (VDD >= VREF + 0.2 V). */ + NRF_COMP_REF_VDD = COMP_REFSEL_REFSEL_VDD, /*!< VREF = VDD. */ + NRF_COMP_REF_ARef = COMP_REFSEL_REFSEL_ARef /*!< VREF = AREF (VDD >= VREF >= AREFMIN). */ +}nrf_comp_ref_t; + +/** + * @enum nrf_comp_ext_ref_t + * @brief COMP external analog reference selection. + */ +typedef enum +{ + NRF_COMP_EXT_REF_0 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference0, /*!< Use AIN0 as external analog reference. */ + NRF_COMP_EXT_REF_1 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference1 /*!< Use AIN1 as external analog reference. */ +}nrf_comp_ext_ref_t; + +/** + * @brief COMP THDOWN and THUP values that are used to calculate the threshold voltages VDOWN and VUP. + */ +typedef struct +{ + uint8_t th_down; /*!< THDOWN value. */ + uint8_t th_up; /*!< THUP value. */ +}nrf_comp_th_t; + +/** + * @enum nrf_comp_main_mode_t + * @brief COMP main operation mode. + */ +typedef enum +{ + NRF_COMP_MAIN_MODE_SE = COMP_MODE_MAIN_SE, /*!< Single ended mode. */ + NRF_COMP_MAIN_MODE_Diff = COMP_MODE_MAIN_Diff /*!< Differential mode. */ +}nrf_comp_main_mode_t; + +/** + * @enum nrf_comp_sp_mode_t + * @brief COMP speed and power mode. + */ +typedef enum +{ + NRF_COMP_SP_MODE_Low = COMP_MODE_SP_Low, /*!< Low power mode. */ + NRF_COMP_SP_MODE_Normal = COMP_MODE_SP_Normal, /*!< Normal mode. */ + NRF_COMP_SP_MODE_High = COMP_MODE_SP_High /*!< High speed mode. */ +}nrf_comp_sp_mode_t; + +/** + * @enum nrf_comp_hyst_t + * @brief COMP comparator hysteresis. + */ +typedef enum +{ + NRF_COMP_HYST_NoHyst = COMP_HYST_HYST_NoHyst, /*!< Comparator hysteresis disabled. */ + NRF_COMP_HYST_50mV = COMP_HYST_HYST_Hyst50mV /*!< Comparator hysteresis enabled. */ +}nrf_comp_hyst_t; + +/** + * @brief COMP current source selection on analog input. + */ +typedef enum +{ + NRF_COMP_ISOURCE_Off = COMP_ISOURCE_ISOURCE_Off, /*!< Current source disabled. */ + NRF_COMP_ISOURCE_Ien2uA5 = COMP_ISOURCE_ISOURCE_Ien2mA5, /*!< Current source enabled (+/- 2.5 uA). */ + NRF_COMP_ISOURCE_Ien5uA = COMP_ISOURCE_ISOURCE_Ien5mA, /*!< Current source enabled (+/- 5 uA). */ + NRF_COMP_ISOURCE_Ien10uA = COMP_ISOURCE_ISOURCE_Ien10mA /*!< Current source enabled (+/- 10 uA). */ +}nrf_isource_t; + +/** + * @enum nrf_comp_task_t + * @brief COMP tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_COMP_TASK_START = offsetof(NRF_COMP_Type, TASKS_START), /*!< COMP start sampling task. */ + NRF_COMP_TASK_STOP = offsetof(NRF_COMP_Type, TASKS_STOP), /*!< COMP stop sampling task. */ + NRF_COMP_TASK_SAMPLE = offsetof(NRF_COMP_Type, TASKS_SAMPLE) /*!< Sample comparator value. */ + /*lint -restore*/ +}nrf_comp_task_t; + +/** + * @enum nrf_comp_event_t + * @brief COMP events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_COMP_EVENT_READY = offsetof(NRF_COMP_Type, EVENTS_READY), /*!< COMP is ready and output is valid. */ + NRF_COMP_EVENT_DOWN = offsetof(NRF_COMP_Type, EVENTS_DOWN), /*!< Input voltage crossed the threshold going down. */ + NRF_COMP_EVENT_UP = offsetof(NRF_COMP_Type, EVENTS_UP), /*!< Input voltage crossed the threshold going up. */ + NRF_COMP_EVENT_CROSS = offsetof(NRF_COMP_Type, EVENTS_CROSS) /*!< Input voltage crossed the threshold in any direction. */ + /*lint -restore*/ +}nrf_comp_event_t; + +/** + * @brief COMP reference configuration. + */ +typedef struct +{ + nrf_comp_ref_t reference; /*!< COMP reference selection. */ + nrf_comp_ext_ref_t external; /*!< COMP external analog reference selection. */ +}nrf_comp_ref_conf_t; + + +/** + * @brief Function for enabling the COMP peripheral. + */ +__STATIC_INLINE void nrf_comp_enable(void); + + +/** + * @brief Function for disabling the COMP peripheral. + */ + +__STATIC_INLINE void nrf_comp_disable(void); + +/** + * @brief Function for checking if the COMP peripheral is enabled. + * + * @retval true If the COMP peripheral is enabled. + * @retval false If the COMP peripheral is not enabled. + */ +__STATIC_INLINE bool nrf_comp_enable_check(void); + +/** + * @brief Function for setting the reference source. + * + * @param[in] reference COMP reference selection. + */ +__STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference); + + +/** + * @brief Function for setting the external analog reference source. + * + * @param[in] ext_ref COMP external analog reference selection. + */ +__STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref); + + +/** + * @brief Function for setting threshold voltages. + * + * @param[in] threshold COMP VDOWN and VUP thresholds. + */ +__STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold); + + +/** + * @brief Function for setting the main mode. + * + * @param[in] main_mode COMP main operation mode. + */ +__STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode); + + +/** + * @brief Function for setting the speed mode. + * + * @param[in] speed_mode COMP speed and power mode. + */ +__STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode); + + +/** + * @brief Function for setting the hysteresis. + * + * @param[in] hyst COMP comparator hysteresis. + */ +__STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst); + + +/** + * @brief Function for setting the current source on the analog input. + * + * @param[in] isource COMP current source selection on analog input. + */ +__STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource); + + +/** + * @brief Function for selecting the active input of the COMP. + * + * @param[in] input Input to be selected. + */ +__STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input); + + +/** + * @brief Function for getting the last COMP compare result. + * + * @return The last compare result. If 0, then VIN+ < VIN-. If 1, then VIN+ > VIN-. + * + * @note If VIN+ == VIN-, the return value depends on the previous result. + */ +__STATIC_INLINE uint32_t nrf_comp_result_get(void); + + +/** + * @brief Function for enabling interrupts from COMP. + * + * @param[in] comp_int_mask Mask of interrupts to be enabled. + * + * @sa nrf_comp_int_enable_check() + */ +__STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask); + +/** + * @brief Function for disabling interrupts from COMP. + * + * @param[in] comp_int_mask Mask of interrupts to be disabled. + * + * @sa nrf_comp_int_enable_check() + */ +__STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask); + + +/** + * @brief Function for getting the enabled interrupts of COMP. + * + * @param[in] comp_int_mask Mask of interrupts to be checked. + * + * @retval true If any interrupts of the specified mask are enabled. + */ +__STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask); + + + +/** + * @brief Function for getting the address of a specific COMP task register. + * + * @param[in] comp_task COMP task. + * + * @return Address of the specified COMP task. + */ +__STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task); + + +/** + * @brief Function for getting the address of a specific COMP event register. + * + * @param[in] comp_event COMP event. + * + * @return Address of the specified COMP event. + */ +__STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event); + + +/** + * @brief Function for setting COMP shorts. + * + * @param[in] comp_short_mask COMP shorts by mask. + * + */ +__STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask); + + +/** + * @brief Function for clearing COMP shorts by mask. + * + * @param[in] comp_short_mask COMP shorts to be cleared. + * + */ +__STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask); + + +/** + * @brief Function for setting a specific COMP task. + * + * @param[in] comp_task COMP task to be set. + * + */ +__STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task); + + +/** + * @brief Function for clearing a specific COMP event. + * + * @param[in] comp_event COMP event to be cleared. + * + */ +__STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event); + + +/** + * @brief Function for getting the state of a specific COMP event. + * + * @retval true If the specified COMP event is active. + * + */ +__STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_comp_enable(void) +{ + NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Enabled << COMP_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_comp_disable(void) +{ + NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Disabled << COMP_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE bool nrf_comp_enable_check(void) +{ + return ((NRF_COMP->ENABLE) & COMP_ENABLE_ENABLE_Enabled); +} + +__STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference) +{ + NRF_COMP->REFSEL = (reference << COMP_REFSEL_REFSEL_Pos); +} + +__STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref) +{ + NRF_COMP->EXTREFSEL = (ext_ref << COMP_EXTREFSEL_EXTREFSEL_Pos); +} + +__STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold) +{ + NRF_COMP->TH = + ((threshold.th_down << COMP_TH_THDOWN_Pos) & COMP_TH_THDOWN_Msk) | + ((threshold.th_up << COMP_TH_THUP_Pos) & COMP_TH_THUP_Msk); +} + +__STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode) +{ + NRF_COMP->MODE |= (main_mode << COMP_MODE_MAIN_Pos); +} + +__STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode) +{ + NRF_COMP->MODE |= (speed_mode << COMP_MODE_SP_Pos); +} + +__STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst) +{ + NRF_COMP->HYST = (hyst << COMP_HYST_HYST_Pos) & COMP_HYST_HYST_Msk; +} + +__STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource) +{ + NRF_COMP->ISOURCE = (isource << COMP_ISOURCE_ISOURCE_Pos) & COMP_ISOURCE_ISOURCE_Msk; +} + +__STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input) +{ + NRF_COMP->PSEL = ((uint32_t)input << COMP_PSEL_PSEL_Pos); +} + +__STATIC_INLINE uint32_t nrf_comp_result_get(void) +{ + return (uint32_t)NRF_COMP->RESULT; +} + +__STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask) +{ + NRF_COMP->INTENSET = comp_int_mask; +} + +__STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask) +{ + NRF_COMP->INTENCLR = comp_int_mask; +} + +__STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask) +{ + return (NRF_COMP->INTENSET & comp_int_mask); // when read this register will return the value of INTEN. +} + +__STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task) +{ + return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_task); +} + +__STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event) +{ + return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_event); +} + +__STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask) +{ + NRF_COMP->SHORTS |= comp_short_mask; +} + +__STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask) +{ + NRF_COMP->SHORTS &= ~comp_short_mask; +} + +__STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_task) ) = 1; +} + +__STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_COMP + (uint32_t)comp_event) ) = 0; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event) +{ + return (bool) (*(volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_event)); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +/** + *@} + **/ + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_COMP_H_ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_ecb.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_ecb.c new file mode 100644 index 0000000000000000000000000000000000000000..d8c96d4ce87a26d6dc9f6cdd01ceb8e0128a42fc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_ecb.c @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief Implementation of AES ECB driver + */ + + +//lint -e438 + +#include +#include +#include +#include "nrf.h" +#include "nrf_ecb.h" + +static uint8_t ecb_data[48]; ///< ECB data structure for RNG peripheral to access. +static uint8_t* ecb_key; ///< Key: Starts at ecb_data +static uint8_t* ecb_cleartext; ///< Cleartext: Starts at ecb_data + 16 bytes. +static uint8_t* ecb_ciphertext; ///< Ciphertext: Starts at ecb_data + 32 bytes. + +bool nrf_ecb_init(void) +{ + ecb_key = ecb_data; + ecb_cleartext = ecb_data + 16; + ecb_ciphertext = ecb_data + 32; + + NRF_ECB->ECBDATAPTR = (uint32_t)ecb_data; + return true; +} + + +bool nrf_ecb_crypt(uint8_t * dest_buf, const uint8_t * src_buf) +{ + uint32_t counter = 0x1000000; + if (src_buf != ecb_cleartext) + { + memcpy(ecb_cleartext,src_buf,16); + } + NRF_ECB->EVENTS_ENDECB = 0; + NRF_ECB->TASKS_STARTECB = 1; + while (NRF_ECB->EVENTS_ENDECB == 0) + { + counter--; + if (counter == 0) + { + return false; + } + } + NRF_ECB->EVENTS_ENDECB = 0; + if (dest_buf != ecb_ciphertext) + { + memcpy(dest_buf,ecb_ciphertext,16); + } + return true; +} + +void nrf_ecb_set_key(const uint8_t * key) +{ + memcpy(ecb_key,key,16); +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_ecb.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_ecb.h new file mode 100644 index 0000000000000000000000000000000000000000..b9bf4fb0a8772eeca4d0b5119706a25f894eadea --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_ecb.h @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief ECB driver API. + */ + +#ifndef NRF_ECB_H__ +#define NRF_ECB_H__ + +/** + * @defgroup nrf_ecb AES ECB encryption + * @{ + * @ingroup nrf_drivers + * @brief Driver for the AES Electronic Code Book (ECB) peripheral. + * + * To encrypt data, the peripheral must first be powered on + * using @ref nrf_ecb_init. Next, the key must be set using @ref nrf_ecb_set_key. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Function for initializing and powering on the ECB peripheral. + * + * This function allocates memory for the ECBDATAPTR. + * @retval true If initialization was successful. + * @retval false If powering on failed. + */ +bool nrf_ecb_init(void); + +/** + * @brief Function for encrypting 16-byte data using current key. + * + * This function avoids unnecessary copying of data if the parameters point to the + * correct locations in the ECB data structure. + * + * @param dst Result of encryption, 16 bytes will be written. + * @param src Source with 16-byte data to be encrypted. + * + * @retval true If the encryption operation completed. + * @retval false If the encryption operation did not complete. + */ +bool nrf_ecb_crypt(uint8_t * dst, const uint8_t * src); + +/** + * @brief Function for setting the key to be used for encryption. + * + * @param key Pointer to the key. 16 bytes will be read. + */ +void nrf_ecb_set_key(const uint8_t * key); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_ECB_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_egu.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_egu.h new file mode 100644 index 0000000000000000000000000000000000000000..ea7fbe90188851b4ad44d3dc1460704e3b582230 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_egu.h @@ -0,0 +1,352 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_EGU_H__ +#define NRF_EGU_H__ + +/** +* @defgroup nrf_egu EGU (Event Generator Unit) abstraction +* @{ +* @ingroup nrf_drivers +* @brief @tagAPI52 EGU (Event Generator Unit) module functions. +* +*/ + +#include +#include +#include +#include "nrf_assert.h" +#include "nrf.h" +#include "nrf_peripherals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @enum nrf_egu_task_t + * @brief EGU tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_EGU_TASK_TRIGGER0 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[0]), /**< Trigger 0 for triggering the corresponding TRIGGERED[0] event. */ + NRF_EGU_TASK_TRIGGER1 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[1]), /**< Trigger 1 for triggering the corresponding TRIGGERED[1] event. */ + NRF_EGU_TASK_TRIGGER2 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[2]), /**< Trigger 2 for triggering the corresponding TRIGGERED[2] event. */ + NRF_EGU_TASK_TRIGGER3 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[3]), /**< Trigger 3 for triggering the corresponding TRIGGERED[3] event. */ + NRF_EGU_TASK_TRIGGER4 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[4]), /**< Trigger 4 for triggering the corresponding TRIGGERED[4] event. */ + NRF_EGU_TASK_TRIGGER5 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[5]), /**< Trigger 5 for triggering the corresponding TRIGGERED[5] event. */ + NRF_EGU_TASK_TRIGGER6 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[6]), /**< Trigger 6 for triggering the corresponding TRIGGERED[6] event. */ + NRF_EGU_TASK_TRIGGER7 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[7]), /**< Trigger 7 for triggering the corresponding TRIGGERED[7] event. */ + NRF_EGU_TASK_TRIGGER8 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[8]), /**< Trigger 8 for triggering the corresponding TRIGGERED[8] event. */ + NRF_EGU_TASK_TRIGGER9 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[9]), /**< Trigger 9 for triggering the corresponding TRIGGERED[9] event. */ + NRF_EGU_TASK_TRIGGER10 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[10]), /**< Trigger 10 for triggering the corresponding TRIGGERED[10] event. */ + NRF_EGU_TASK_TRIGGER11 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[11]), /**< Trigger 11 for triggering the corresponding TRIGGERED[11] event. */ + NRF_EGU_TASK_TRIGGER12 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[12]), /**< Trigger 12 for triggering the corresponding TRIGGERED[12] event. */ + NRF_EGU_TASK_TRIGGER13 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[13]), /**< Trigger 13 for triggering the corresponding TRIGGERED[13] event. */ + NRF_EGU_TASK_TRIGGER14 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[14]), /**< Trigger 14 for triggering the corresponding TRIGGERED[14] event. */ + NRF_EGU_TASK_TRIGGER15 = offsetof(NRF_EGU_Type, TASKS_TRIGGER[15]) /**< Trigger 15 for triggering the corresponding TRIGGERED[15] event. */ + /*lint -restore*/ +} nrf_egu_task_t; + + +/** + * @enum nrf_egu_event_t + * @brief EGU events. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_EGU_EVENT_TRIGGERED0 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[0]), /**< Event number 0 generated by triggering the corresponding TRIGGER[0] task. */ + NRF_EGU_EVENT_TRIGGERED1 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[1]), /**< Event number 1 generated by triggering the corresponding TRIGGER[1] task. */ + NRF_EGU_EVENT_TRIGGERED2 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[2]), /**< Event number 2 generated by triggering the corresponding TRIGGER[2] task. */ + NRF_EGU_EVENT_TRIGGERED3 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[3]), /**< Event number 3 generated by triggering the corresponding TRIGGER[3] task. */ + NRF_EGU_EVENT_TRIGGERED4 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[4]), /**< Event number 4 generated by triggering the corresponding TRIGGER[4] task. */ + NRF_EGU_EVENT_TRIGGERED5 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[5]), /**< Event number 5 generated by triggering the corresponding TRIGGER[5] task. */ + NRF_EGU_EVENT_TRIGGERED6 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[6]), /**< Event number 6 generated by triggering the corresponding TRIGGER[6] task. */ + NRF_EGU_EVENT_TRIGGERED7 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[7]), /**< Event number 7 generated by triggering the corresponding TRIGGER[7] task. */ + NRF_EGU_EVENT_TRIGGERED8 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[8]), /**< Event number 8 generated by triggering the corresponding TRIGGER[8] task. */ + NRF_EGU_EVENT_TRIGGERED9 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[9]), /**< Event number 9 generated by triggering the corresponding TRIGGER[9] task. */ + NRF_EGU_EVENT_TRIGGERED10 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[10]), /**< Event number 10 generated by triggering the corresponding TRIGGER[10] task. */ + NRF_EGU_EVENT_TRIGGERED11 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[11]), /**< Event number 11 generated by triggering the corresponding TRIGGER[11] task. */ + NRF_EGU_EVENT_TRIGGERED12 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[12]), /**< Event number 12 generated by triggering the corresponding TRIGGER[12] task. */ + NRF_EGU_EVENT_TRIGGERED13 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[13]), /**< Event number 13 generated by triggering the corresponding TRIGGER[13] task. */ + NRF_EGU_EVENT_TRIGGERED14 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[14]), /**< Event number 14 generated by triggering the corresponding TRIGGER[14] task. */ + NRF_EGU_EVENT_TRIGGERED15 = offsetof(NRF_EGU_Type, EVENTS_TRIGGERED[15]) /**< Event number 15 generated by triggering the corresponding TRIGGER[15] task. */ + /*lint -restore*/ +} nrf_egu_event_t; + + +/** + * @enum nrf_egu_int_mask_t + * @brief EGU interrupts. + */ +typedef enum +{ + NRF_EGU_INT_TRIGGERED0 = EGU_INTENSET_TRIGGERED0_Msk, /**< Interrupt on EVENTS_TRIGGERED[0] event. */ + NRF_EGU_INT_TRIGGERED1 = EGU_INTENSET_TRIGGERED1_Msk, /**< Interrupt on EVENTS_TRIGGERED[1] event. */ + NRF_EGU_INT_TRIGGERED2 = EGU_INTENSET_TRIGGERED2_Msk, /**< Interrupt on EVENTS_TRIGGERED[2] event. */ + NRF_EGU_INT_TRIGGERED3 = EGU_INTENSET_TRIGGERED3_Msk, /**< Interrupt on EVENTS_TRIGGERED[3] event. */ + NRF_EGU_INT_TRIGGERED4 = EGU_INTENSET_TRIGGERED4_Msk, /**< Interrupt on EVENTS_TRIGGERED[4] event. */ + NRF_EGU_INT_TRIGGERED5 = EGU_INTENSET_TRIGGERED5_Msk, /**< Interrupt on EVENTS_TRIGGERED[5] event. */ + NRF_EGU_INT_TRIGGERED6 = EGU_INTENSET_TRIGGERED6_Msk, /**< Interrupt on EVENTS_TRIGGERED[6] event. */ + NRF_EGU_INT_TRIGGERED7 = EGU_INTENSET_TRIGGERED7_Msk, /**< Interrupt on EVENTS_TRIGGERED[7] event. */ + NRF_EGU_INT_TRIGGERED8 = EGU_INTENSET_TRIGGERED8_Msk, /**< Interrupt on EVENTS_TRIGGERED[8] event. */ + NRF_EGU_INT_TRIGGERED9 = EGU_INTENSET_TRIGGERED9_Msk, /**< Interrupt on EVENTS_TRIGGERED[9] event. */ + NRF_EGU_INT_TRIGGERED10 = EGU_INTENSET_TRIGGERED10_Msk, /**< Interrupt on EVENTS_TRIGGERED[10] event. */ + NRF_EGU_INT_TRIGGERED11 = EGU_INTENSET_TRIGGERED11_Msk, /**< Interrupt on EVENTS_TRIGGERED[11] event. */ + NRF_EGU_INT_TRIGGERED12 = EGU_INTENSET_TRIGGERED12_Msk, /**< Interrupt on EVENTS_TRIGGERED[12] event. */ + NRF_EGU_INT_TRIGGERED13 = EGU_INTENSET_TRIGGERED13_Msk, /**< Interrupt on EVENTS_TRIGGERED[13] event. */ + NRF_EGU_INT_TRIGGERED14 = EGU_INTENSET_TRIGGERED14_Msk, /**< Interrupt on EVENTS_TRIGGERED[14] event. */ + NRF_EGU_INT_TRIGGERED15 = EGU_INTENSET_TRIGGERED15_Msk, /**< Interrupt on EVENTS_TRIGGERED[15] event. */ + NRF_EGU_INT_ALL = 0xFFFFuL +} nrf_egu_int_mask_t; + +/**@brief Function for getting max channel number of given EGU. + * + * @param NRF_EGUx EGU instance. + * + * @returns number of available channels. + */ +__STATIC_INLINE uint32_t nrf_egu_channel_count(NRF_EGU_Type * NRF_EGUx) +{ + if (NRF_EGUx == NRF_EGU0){ + return EGU0_CH_NUM; + } + if (NRF_EGUx == NRF_EGU1){ + return EGU1_CH_NUM; + } + if (NRF_EGUx == NRF_EGU2){ + return EGU2_CH_NUM; + } + if (NRF_EGUx == NRF_EGU3){ + return EGU3_CH_NUM; + } + if (NRF_EGUx == NRF_EGU4){ + return EGU4_CH_NUM; + } + if (NRF_EGUx == NRF_EGU5){ + return EGU5_CH_NUM; + } + return 0; +} + +/** + * @brief Function for triggering a specific EGU task. + * + * @param NRF_EGUx EGU instance. + * @param egu_task EGU task. + */ +__STATIC_INLINE void nrf_egu_task_trigger(NRF_EGU_Type * NRF_EGUx, nrf_egu_task_t egu_task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task)) = 0x1UL; +} + + +/** + * @brief Function for returning the address of a specific EGU task register. + * + * @param NRF_EGUx EGU instance. + * @param egu_task EGU task. + */ +__STATIC_INLINE uint32_t * nrf_egu_task_address_get(NRF_EGU_Type * NRF_EGUx, + nrf_egu_task_t egu_task) +{ + return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_task); +} + + +/** + * @brief Function for returning the address of a specific EGU TRIGGER task register. + * + * @param NRF_EGUx EGU instance. + * @param channel Channel number. + */ +__STATIC_INLINE uint32_t * nrf_egu_task_trigger_address_get(NRF_EGU_Type * NRF_EGUx, + uint8_t channel) +{ + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); + return (uint32_t*)&NRF_EGUx->TASKS_TRIGGER[channel]; +} + + +/** + * @brief Function for returning the specific EGU TRIGGER task. + * + * @param NRF_EGUx EGU instance. + * @param channel Channel number. + */ +__STATIC_INLINE nrf_egu_task_t nrf_egu_task_trigger_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel) +{ + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); + return (nrf_egu_task_t)((uint32_t) NRF_EGU_TASK_TRIGGER0 + (channel * sizeof(uint32_t))); +} + + +/** + * @brief Function for returning the state of a specific EGU event. + * + * @param NRF_EGUx EGU instance. + * @param egu_event EGU event to check. + */ +__STATIC_INLINE bool nrf_egu_event_check(NRF_EGU_Type * NRF_EGUx, + nrf_egu_event_t egu_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event); +} + + +/** + * @brief Function for clearing a specific EGU event. + * + * @param NRF_EGUx EGU instance. + * @param egu_event EGU event to clear. + */ +__STATIC_INLINE void nrf_egu_event_clear(NRF_EGU_Type * NRF_EGUx, + nrf_egu_event_t egu_event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)); + (void)dummy; +#endif +} + + +/** + * @brief Function for returning the address of a specific EGU event register. + * + * @param NRF_EGUx EGU instance. + * @param egu_event EGU event. + */ +__STATIC_INLINE uint32_t * nrf_egu_event_address_get(NRF_EGU_Type * NRF_EGUx, + nrf_egu_event_t egu_event) +{ + return (uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event); +} + + +/** + * @brief Function for returning the address of a specific EGU TRIGGERED event register. + * + * @param NRF_EGUx EGU instance. + * @param channel Channel number. + */ +__STATIC_INLINE uint32_t * nrf_egu_event_triggered_address_get(NRF_EGU_Type * NRF_EGUx, + uint8_t channel) +{ + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); + return (uint32_t*)&NRF_EGUx->EVENTS_TRIGGERED[channel]; +} + + +/** + * @brief Function for returning the specific EGU TRIGGERED event. + * + * @param NRF_EGUx EGU instance. + * @param channel Channel number. + */ +__STATIC_INLINE nrf_egu_event_t nrf_egu_event_triggered_get(NRF_EGU_Type * NRF_EGUx, + uint8_t channel) +{ + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); + return (nrf_egu_event_t)((uint32_t) NRF_EGU_EVENT_TRIGGERED0 + (channel * sizeof(uint32_t))); +} + + +/** + * @brief Function for enabling one or more specific EGU interrupts. + * + * @param NRF_EGUx EGU instance. + * @param egu_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_egu_int_enable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask) +{ + NRF_EGUx->INTENSET = egu_int_mask; +} + + +/** + * @brief Function for retrieving the state of one or more EGU interrupts. + * + * @param NRF_EGUx EGU instance. + * @param egu_int_mask Interrupts to check. + * + * @retval true If all of the specified interrupts are enabled. + * @retval false If at least one of the specified interrupts is disabled. + */ +__STATIC_INLINE bool nrf_egu_int_enable_check(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask) +{ + return (bool)(NRF_EGUx->INTENSET & egu_int_mask); +} + + +/** + * @brief Function for disabling one or more specific EGU interrupts. + * + * @param NRF_EGUx EGU instance. + * @param egu_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_egu_int_disable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_int_mask) +{ + NRF_EGUx->INTENCLR = egu_int_mask; +} + +/** + * @brief Function for retrieving one or more specific EGU interrupts. + * + * @param NRF_EGUx EGU instance. + * @param channel Channel number. + * + * @returns EGU interrupt mask. + */ +__STATIC_INLINE nrf_egu_int_mask_t nrf_egu_int_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel) +{ + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); + return (nrf_egu_int_mask_t)((uint32_t) (EGU_INTENSET_TRIGGERED0_Msk << channel)); +} + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_gpio.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..ccd408c0ad7fa8a68a314a29694f06978ea01994 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_gpio.h @@ -0,0 +1,795 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_GPIO_H__ +#define NRF_GPIO_H__ + +#include "nrf.h" +#include "nrf_peripherals.h" +#include "nrf_assert.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_gpio GPIO abstraction + * @{ + * @ingroup nrf_drivers + * @brief GPIO pin abstraction and port abstraction for reading and writing byte-wise to GPIO ports. + */ + +#if (GPIO_COUNT == 1) +#define NUMBER_OF_PINS (P0_PIN_NUM) +#define GPIO_REG_LIST {NRF_GPIO} +#elif (GPIO_COUNT == 2) +#define NUMBER_OF_PINS (P0_PIN_NUM + P1_PIN_NUM) +#define GPIO_REG_LIST {NRF_P0, NRF_P1} +#else +#error "Not supported." +#endif + + +/** + * @brief Macro for mapping port and pin numbers to values understandable for nrf_gpio functions. + */ +#define NRF_GPIO_PIN_MAP(port, pin) ((port << 5) | (pin & 0x1F)) + +/** + * @brief Pin direction definitions. + */ +typedef enum +{ + NRF_GPIO_PIN_DIR_INPUT = GPIO_PIN_CNF_DIR_Input, ///< Input. + NRF_GPIO_PIN_DIR_OUTPUT = GPIO_PIN_CNF_DIR_Output ///< Output. +} nrf_gpio_pin_dir_t; + +/** + * @brief Connection of input buffer. + */ +typedef enum +{ + NRF_GPIO_PIN_INPUT_CONNECT = GPIO_PIN_CNF_INPUT_Connect, ///< Connect input buffer. + NRF_GPIO_PIN_INPUT_DISCONNECT = GPIO_PIN_CNF_INPUT_Disconnect ///< Disconnect input buffer. +} nrf_gpio_pin_input_t; + +/** + * @brief Enumerator used for selecting the pin to be pulled down or up at the time of pin configuration. + */ +typedef enum +{ + NRF_GPIO_PIN_NOPULL = GPIO_PIN_CNF_PULL_Disabled, ///< Pin pull-up resistor disabled. + NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown, ///< Pin pull-down resistor enabled. + NRF_GPIO_PIN_PULLUP = GPIO_PIN_CNF_PULL_Pullup, ///< Pin pull-up resistor enabled. +} nrf_gpio_pin_pull_t; + +/** + * @brief Enumerator used for selecting output drive mode. + */ +typedef enum +{ + NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< !< Standard '0', standard '1'. + NRF_GPIO_PIN_H0S1 = GPIO_PIN_CNF_DRIVE_H0S1, ///< !< High-drive '0', standard '1'. + NRF_GPIO_PIN_S0H1 = GPIO_PIN_CNF_DRIVE_S0H1, ///< !< Standard '0', high-drive '1'. + NRF_GPIO_PIN_H0H1 = GPIO_PIN_CNF_DRIVE_H0H1, ///< !< High drive '0', high-drive '1'. + NRF_GPIO_PIN_D0S1 = GPIO_PIN_CNF_DRIVE_D0S1, ///< !< Disconnect '0' standard '1'. + NRF_GPIO_PIN_D0H1 = GPIO_PIN_CNF_DRIVE_D0H1, ///< !< Disconnect '0', high-drive '1'. + NRF_GPIO_PIN_S0D1 = GPIO_PIN_CNF_DRIVE_S0D1, ///< !< Standard '0', disconnect '1'. + NRF_GPIO_PIN_H0D1 = GPIO_PIN_CNF_DRIVE_H0D1, ///< !< High-drive '0', disconnect '1'. +} nrf_gpio_pin_drive_t; + +/** + * @brief Enumerator used for selecting the pin to sense high or low level on the pin input. + */ +typedef enum +{ + NRF_GPIO_PIN_NOSENSE = GPIO_PIN_CNF_SENSE_Disabled, ///< Pin sense level disabled. + NRF_GPIO_PIN_SENSE_LOW = GPIO_PIN_CNF_SENSE_Low, ///< Pin sense low level. + NRF_GPIO_PIN_SENSE_HIGH = GPIO_PIN_CNF_SENSE_High, ///< Pin sense high level. +} nrf_gpio_pin_sense_t; + + +#if (__LINT__ != 1) + +/** + * @brief Function for configuring the GPIO pin range as output pins with normal drive strength. + * This function can be used to configure pin range as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). + * + * @param pin_range_start Specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30). + * + * @param pin_range_end Specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30). + * + * @note For configuring only one pin as output, use @ref nrf_gpio_cfg_output. + * Sense capability on the pin is disabled and input is disconnected from the buffer as the pins are configured as output. + */ +__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end); + +/** + * @brief Function for configuring the GPIO pin range as input pins with given initial value set, hiding inner details. + * This function can be used to configure pin range as simple input. + * + * @param pin_range_start Specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30). + * + * @param pin_range_end Specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30). + * + * @param pull_config State of the pin range pull resistor (no pull, pulled down, or pulled high). + * + * @note For configuring only one pin as input, use @ref nrf_gpio_cfg_input. + * Sense capability on the pin is disabled and input is connected to buffer so that the GPIO->IN register is readable. + */ +__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, + uint32_t pin_range_end, + nrf_gpio_pin_pull_t pull_config); + +/** + * @brief Pin configuration function. + * + * The main pin configuration function. + * This function allows to set any aspect in PIN_CNF register. + * @param pin_number Specifies the pin number. + * @param dir Pin direction. + * @param input Connect or disconnect the input buffer. + * @param pull Pull configuration. + * @param drive Drive configuration. + * @param sense Pin sensing mechanism. + */ +__STATIC_INLINE void nrf_gpio_cfg( + uint32_t pin_number, + nrf_gpio_pin_dir_t dir, + nrf_gpio_pin_input_t input, + nrf_gpio_pin_pull_t pull, + nrf_gpio_pin_drive_t drive, + nrf_gpio_pin_sense_t sense); + +/** + * @brief Function for configuring the given GPIO pin number as output, hiding inner details. + * This function can be used to configure a pin as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). + * + * @param pin_number Specifies the pin number. + * + * @note Sense capability on the pin is disabled and input is disconnected from the buffer as the pins are configured as output. + */ +__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number); + +/** + * @brief Function for configuring the given GPIO pin number as input, hiding inner details. + * This function can be used to configure a pin as simple input. + * + * @param pin_number Specifies the pin number. + * @param pull_config State of the pin range pull resistor (no pull, pulled down, or pulled high). + * + * @note Sense capability on the pin is disabled and input is connected to buffer so that the GPIO->IN register is readable. + */ +__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config); + +/** + * @brief Function for resetting pin configuration to its default state. + * + * @param pin_number Specifies the pin number. + */ +__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number); + +/** + * @brief Function for configuring the given GPIO pin number as a watcher. Only input is connected. + * + * @param pin_number Specifies the pin number. + * + */ +__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number); + +/** + * @brief Function for disconnecting input for the given GPIO. + * + * @param pin_number Specifies the pin number. + * + */ +__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number); + +/** + * @brief Function for configuring the given GPIO pin number as input, hiding inner details. + * This function can be used to configure pin range as simple input. + * Sense capability on the pin is configurable and input is connected to buffer so that the GPIO->IN register is readable. + * + * @param pin_number Specifies the pin number. + * @param pull_config State of the pin pull resistor (no pull, pulled down, or pulled high). + * @param sense_config Sense level of the pin (no sense, sense low, or sense high). + */ +__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, + nrf_gpio_pin_pull_t pull_config, + nrf_gpio_pin_sense_t sense_config); + +/** + * @brief Function for configuring sense level for the given GPIO. + * + * @param pin_number Specifies the pin number. + * @param sense_config Sense configuration. + * + */ +__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config); + +/** + * @brief Function for setting the direction for a GPIO pin. + * + * @param pin_number Specifies the pin number for which to set the direction. + * + * @param direction Specifies the direction. + */ +__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction); + +/** + * @brief Function for setting a GPIO pin. + * + * Note that the pin must be configured as an output for this function to have any effect. + * + * @param pin_number Specifies the pin number to set. + */ +__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number); + +/** + * @brief Function for clearing a GPIO pin. + * + * Note that the pin must be configured as an output for this + * function to have any effect. + * + * @param pin_number Specifies the pin number to clear. + */ +__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number); + +/** + * @brief Function for toggling a GPIO pin. + * + * Note that the pin must be configured as an output for this + * function to have any effect. + * + * @param pin_number Specifies the pin number to toggle. + */ +__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number); + +/** + * @brief Function for writing a value to a GPIO pin. + * + * Note that the pin must be configured as an output for this + * function to have any effect. + * + * @param pin_number Specifies the pin number to write. + * + * @param value Specifies the value to be written to the pin. + * @arg 0 Clears the pin. + * @arg >=1 Sets the pin. + */ +__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value); + +/** + * @brief Function for reading the input level of a GPIO pin. + * + * Note that the pin must have input connected for the value + * returned from this function to be valid. + * + * @param pin_number Specifies the pin number to read. + * + * @return 0 if the pin input level is low. Positive value if the pin is high. + */ +__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number); + +/** + * @brief Function for reading the output level of a GPIO pin. + * + * @param pin_number Specifies the pin number to read. + * + * @return 0 if the pin output level is low. Positive value if pin output is high. + */ +__STATIC_INLINE uint32_t nrf_gpio_pin_out_read(uint32_t pin_number); + +/** + * @brief Function for reading the sense configuration of a GPIO pin. + * + * @param pin_number Specifies the pin number to read. + * + * @retval Sense configuration. + */ +__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number); + +/** + * @brief Function for setting output direction on selected pins on a given port. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param out_mask Mask specifying the pins to set as output. + * + */ +__STATIC_INLINE void nrf_gpio_port_dir_output_set(NRF_GPIO_Type * p_reg, uint32_t out_mask); + +/** + * @brief Function for setting input direction on selected pins on a given port. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param in_mask Mask specifying the pins to set as input. + * + */ +__STATIC_INLINE void nrf_gpio_port_dir_input_set(NRF_GPIO_Type * p_reg, uint32_t in_mask); + +/** + * @brief Function for writing the direction configuration of GPIO pins in a given port. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param dir_mask Mask specifying the direction of pins. Bit set means that the given pin is configured as output. + * + */ +__STATIC_INLINE void nrf_gpio_port_dir_write(NRF_GPIO_Type * p_reg, uint32_t dir_mask); + +/** + * @brief Function for reading the direction configuration of a GPIO port. + * + * @param p_reg Pointer to the peripheral registers structure. + * + * @retval Pin configuration of the current direction settings. Bit set means that the given pin is configured as output. + */ +__STATIC_INLINE uint32_t nrf_gpio_port_dir_read(NRF_GPIO_Type const * p_reg); + +/** + * @brief Function for reading the input signals of GPIO pins on a given port. + * + * @param p_reg Pointer to the peripheral registers structure. + * + * @retval Port input values. + */ +__STATIC_INLINE uint32_t nrf_gpio_port_in_read(NRF_GPIO_Type const * p_reg); + +/** + * @brief Function for reading the output signals of GPIO pins of a given port. + * + * @param p_reg Pointer to the peripheral registers structure. + * + * @retval Port output values. + */ +__STATIC_INLINE uint32_t nrf_gpio_port_out_read(NRF_GPIO_Type const * p_reg); + +/** + * @brief Function for writing the GPIO pins output on a given port. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param value Output port mask. + * + */ +__STATIC_INLINE void nrf_gpio_port_out_write(NRF_GPIO_Type * p_reg, uint32_t value); + +/** + * @brief Function for setting high level on selected GPIO pins of a given port. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param set_mask Mask with pins to set as logical high level. + * + */ +__STATIC_INLINE void nrf_gpio_port_out_set(NRF_GPIO_Type * p_reg, uint32_t set_mask); + +/** + * @brief Function for setting low level on selected GPIO pins of a given port. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param clr_mask Mask with pins to set as logical low level. + * + */ +__STATIC_INLINE void nrf_gpio_port_out_clear(NRF_GPIO_Type * p_reg, uint32_t clr_mask); + +/** + * @brief Function for reading pins state of multiple consecutive ports. + * + * @param start_port Index of the first port to read. + * @param length Number of ports to read. + * @param p_masks Pointer to output array where port states will be stored. + */ +__STATIC_INLINE void nrf_gpio_ports_read(uint32_t start_port, uint32_t length, uint32_t * p_masks); + +#ifdef GPIO_DETECTMODE_DETECTMODE_LDETECT +/** + * @brief Function for reading latch state of multiple consecutive ports. + * + * @param start_port Index of the first port to read. + * @param length Number of ports to read. + * @param p_masks Pointer to output array where latch states will be stored. + */ +__STATIC_INLINE void nrf_gpio_latches_read(uint32_t start_port, uint32_t length, + uint32_t * p_masks); + +/** + * @brief Function for reading latch state of single pin. + * + * @param pin_number Pin number. + * @return 0 if latch is not set. Positive value otherwise. + * + */ +__STATIC_INLINE uint32_t nrf_gpio_pin_latch_get(uint32_t pin_number); + +/** + * @brief Function for clearing latch state of a single pin. + * + * @param pin_number Pin number. + * + */ +__STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t pin_number); +#endif + + +#endif // #ifndef (__LINT__ != 1) + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +/** + * @brief Function for extracting port and relative pin number from absolute pin number. + * + * @param[inout] Pointer to absolute pin number which is overriden by relative to port pin number. + * + * @return Pointer to port register set. + * + */ +__STATIC_INLINE NRF_GPIO_Type * nrf_gpio_pin_port_decode(uint32_t * p_pin) +{ + ASSERT(*p_pin < NUMBER_OF_PINS); +#if (GPIO_COUNT == 1) + // The oldest definition case + return NRF_GPIO; +#else + if (*p_pin < P0_PIN_NUM) + { + return NRF_P0; + } + else + { + *p_pin = *p_pin & (P0_PIN_NUM - 1); + return NRF_P1; + } +#endif +} + + +__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end) +{ + /*lint -e{845} // A zero has been given as right argument to operator '|'" */ + for (; pin_range_start <= pin_range_end; pin_range_start++) + { + nrf_gpio_cfg_output(pin_range_start); + } +} + + +__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, + uint32_t pin_range_end, + nrf_gpio_pin_pull_t pull_config) +{ + /*lint -e{845} // A zero has been given as right argument to operator '|'" */ + for (; pin_range_start <= pin_range_end; pin_range_start++) + { + nrf_gpio_cfg_input(pin_range_start, pull_config); + } +} + + +__STATIC_INLINE void nrf_gpio_cfg( + uint32_t pin_number, + nrf_gpio_pin_dir_t dir, + nrf_gpio_pin_input_t input, + nrf_gpio_pin_pull_t pull, + nrf_gpio_pin_drive_t drive, + nrf_gpio_pin_sense_t sense) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + reg->PIN_CNF[pin_number] = ((uint32_t)dir << GPIO_PIN_CNF_DIR_Pos) + | ((uint32_t)input << GPIO_PIN_CNF_INPUT_Pos) + | ((uint32_t)pull << GPIO_PIN_CNF_PULL_Pos) + | ((uint32_t)drive << GPIO_PIN_CNF_DRIVE_Pos) + | ((uint32_t)sense << GPIO_PIN_CNF_SENSE_Pos); +} + + +__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number) +{ + nrf_gpio_cfg( + pin_number, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); +} + + +__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config) +{ + nrf_gpio_cfg( + pin_number, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + pull_config, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); +} + + +__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number) +{ + nrf_gpio_cfg( + pin_number, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); +} + + +__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + /*lint -e{845} // A zero has been given as right argument to operator '|'" */ + uint32_t cnf = reg->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk; + + reg->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); +} + + +__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + /*lint -e{845} // A zero has been given as right argument to operator '|'" */ + uint32_t cnf = reg->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk; + + reg->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); +} + + +__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, + nrf_gpio_pin_pull_t pull_config, + nrf_gpio_pin_sense_t sense_config) +{ + nrf_gpio_cfg( + pin_number, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + pull_config, + NRF_GPIO_PIN_S0S1, + sense_config); +} + + +__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + /*lint -e{845} // A zero has been given as right argument to operator '|'" */ + reg->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_SENSE_Msk; + reg->PIN_CNF[pin_number] |= (sense_config << GPIO_PIN_CNF_SENSE_Pos); +} + + +__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction) +{ + if (direction == NRF_GPIO_PIN_DIR_INPUT) + { + nrf_gpio_cfg( + pin_number, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); + } + else + { + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + reg->DIRSET = (1UL << pin_number); + } +} + + +__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + nrf_gpio_port_out_set(reg, 1UL << pin_number); +} + + +__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + nrf_gpio_port_out_clear(reg, 1UL << pin_number); +} + + +__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + uint32_t pins_state = reg->OUT; + + reg->OUTSET = (~pins_state & (1UL << pin_number)); + reg->OUTCLR = (pins_state & (1UL << pin_number)); +} + + +__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value) +{ + if (value == 0) + { + nrf_gpio_pin_clear(pin_number); + } + else + { + nrf_gpio_pin_set(pin_number); + } +} + + +__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + return ((nrf_gpio_port_in_read(reg) >> pin_number) & 1UL); +} + + +__STATIC_INLINE uint32_t nrf_gpio_pin_out_read(uint32_t pin_number) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + return ((nrf_gpio_port_out_read(reg) >> pin_number) & 1UL); +} + + +__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + return (nrf_gpio_pin_sense_t)((reg->PIN_CNF[pin_number] & + GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos); +} + + +__STATIC_INLINE void nrf_gpio_port_dir_output_set(NRF_GPIO_Type * p_reg, uint32_t out_mask) +{ + p_reg->DIRSET = out_mask; +} + + +__STATIC_INLINE void nrf_gpio_port_dir_input_set(NRF_GPIO_Type * p_reg, uint32_t in_mask) +{ + p_reg->DIRCLR = in_mask; +} + + +__STATIC_INLINE void nrf_gpio_port_dir_write(NRF_GPIO_Type * p_reg, uint32_t value) +{ + p_reg->DIR = value; +} + + +__STATIC_INLINE uint32_t nrf_gpio_port_dir_read(NRF_GPIO_Type const * p_reg) +{ + return p_reg->DIR; +} + + +__STATIC_INLINE uint32_t nrf_gpio_port_in_read(NRF_GPIO_Type const * p_reg) +{ + return p_reg->IN; +} + + +__STATIC_INLINE uint32_t nrf_gpio_port_out_read(NRF_GPIO_Type const * p_reg) +{ + return p_reg->OUT; +} + + +__STATIC_INLINE void nrf_gpio_port_out_write(NRF_GPIO_Type * p_reg, uint32_t value) +{ + p_reg->OUT = value; +} + + +__STATIC_INLINE void nrf_gpio_port_out_set(NRF_GPIO_Type * p_reg, uint32_t set_mask) +{ + p_reg->OUTSET = set_mask; +} + + +__STATIC_INLINE void nrf_gpio_port_out_clear(NRF_GPIO_Type * p_reg, uint32_t clr_mask) +{ + p_reg->OUTCLR = clr_mask; +} + + +__STATIC_INLINE void nrf_gpio_ports_read(uint32_t start_port, uint32_t length, uint32_t * p_masks) +{ + NRF_GPIO_Type * gpio_regs[GPIO_COUNT] = GPIO_REG_LIST; + + ASSERT(start_port + length <= GPIO_COUNT); + uint32_t i; + + for (i = start_port; i < (start_port + length); i++) + { + *p_masks = nrf_gpio_port_in_read(gpio_regs[i]); + p_masks++; + } +} + + +#ifdef GPIO_DETECTMODE_DETECTMODE_LDETECT +__STATIC_INLINE void nrf_gpio_latches_read(uint32_t start_port, uint32_t length, uint32_t * p_masks) +{ + NRF_GPIO_Type * gpio_regs[GPIO_COUNT] = GPIO_REG_LIST; + uint32_t i; + + for (i = start_port; i < (start_port + length); i++) + { + *p_masks = gpio_regs[i]->LATCH; + p_masks++; + } +} + + +__STATIC_INLINE uint32_t nrf_gpio_pin_latch_get(uint32_t pin_number) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + return (reg->LATCH & (1 << pin_number)) ? 1 : 0; +} + + +__STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t pin_number) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + reg->LATCH = (1 << pin_number); +} + + +#endif +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_gpiote.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_gpiote.h new file mode 100644 index 0000000000000000000000000000000000000000..df9bd35ce6e7f90c110477bda409f3e77bd6a8a4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_gpiote.h @@ -0,0 +1,430 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_GPIOTE_H__ +#define NRF_GPIOTE_H__ + +#include "nrf_peripherals.h" +#include "nrf.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef GPIOTE_CONFIG_PORT_Msk +#define GPIOTE_CONFIG_PORT_PIN_Msk (GPIOTE_CONFIG_PORT_Msk | GPIOTE_CONFIG_PSEL_Msk) +#else +#define GPIOTE_CONFIG_PORT_PIN_Msk GPIOTE_CONFIG_PSEL_Msk +#endif +/** +* @defgroup nrf_gpiote_abs GPIOTE abstraction +* @{ +* @ingroup nrf_gpiote +* @brief GPIOTE abstraction for configuration of channels. +*/ + + /** + * @enum nrf_gpiote_polarity_t + * @brief Polarity for the GPIOTE channel. + */ +typedef enum +{ + NRF_GPIOTE_POLARITY_LOTOHI = GPIOTE_CONFIG_POLARITY_LoToHi, ///< Low to high. + NRF_GPIOTE_POLARITY_HITOLO = GPIOTE_CONFIG_POLARITY_HiToLo, ///< High to low. + NRF_GPIOTE_POLARITY_TOGGLE = GPIOTE_CONFIG_POLARITY_Toggle ///< Toggle. +} nrf_gpiote_polarity_t; + + + /** + * @enum nrf_gpiote_outinit_t + * @brief Initial output value for the GPIOTE channel. + */ +typedef enum +{ + NRF_GPIOTE_INITIAL_VALUE_LOW = GPIOTE_CONFIG_OUTINIT_Low, ///< Low to high. + NRF_GPIOTE_INITIAL_VALUE_HIGH = GPIOTE_CONFIG_OUTINIT_High ///< High to low. +} nrf_gpiote_outinit_t; + +/** + * @brief Tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_GPIOTE_TASKS_OUT_0 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[0]), /**< Out task 0.*/ + NRF_GPIOTE_TASKS_OUT_1 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[1]), /**< Out task 1.*/ + NRF_GPIOTE_TASKS_OUT_2 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[2]), /**< Out task 2.*/ + NRF_GPIOTE_TASKS_OUT_3 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[3]), /**< Out task 3.*/ +#if (GPIOTE_CH_NUM > 4) || defined(__SDK_DOXYGEN__) + NRF_GPIOTE_TASKS_OUT_4 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[4]), /**< Out task 4.*/ + NRF_GPIOTE_TASKS_OUT_5 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[5]), /**< Out task 5.*/ + NRF_GPIOTE_TASKS_OUT_6 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[6]), /**< Out task 6.*/ + NRF_GPIOTE_TASKS_OUT_7 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[7]), /**< Out task 7.*/ +#endif +#if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__SDK_DOXYGEN__) + NRF_GPIOTE_TASKS_SET_0 = offsetof(NRF_GPIOTE_Type, TASKS_SET[0]), /**< Set task 0.*/ + NRF_GPIOTE_TASKS_SET_1 = offsetof(NRF_GPIOTE_Type, TASKS_SET[1]), /**< Set task 1.*/ + NRF_GPIOTE_TASKS_SET_2 = offsetof(NRF_GPIOTE_Type, TASKS_SET[2]), /**< Set task 2.*/ + NRF_GPIOTE_TASKS_SET_3 = offsetof(NRF_GPIOTE_Type, TASKS_SET[3]), /**< Set task 3.*/ + NRF_GPIOTE_TASKS_SET_4 = offsetof(NRF_GPIOTE_Type, TASKS_SET[4]), /**< Set task 4.*/ + NRF_GPIOTE_TASKS_SET_5 = offsetof(NRF_GPIOTE_Type, TASKS_SET[5]), /**< Set task 5.*/ + NRF_GPIOTE_TASKS_SET_6 = offsetof(NRF_GPIOTE_Type, TASKS_SET[6]), /**< Set task 6.*/ + NRF_GPIOTE_TASKS_SET_7 = offsetof(NRF_GPIOTE_Type, TASKS_SET[7]), /**< Set task 7.*/ +#endif +#if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__SDK_DOXYGEN__) + NRF_GPIOTE_TASKS_CLR_0 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[0]), /**< Clear task 0.*/ + NRF_GPIOTE_TASKS_CLR_1 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[1]), /**< Clear task 1.*/ + NRF_GPIOTE_TASKS_CLR_2 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[2]), /**< Clear task 2.*/ + NRF_GPIOTE_TASKS_CLR_3 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[3]), /**< Clear task 3.*/ + NRF_GPIOTE_TASKS_CLR_4 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[4]), /**< Clear task 4.*/ + NRF_GPIOTE_TASKS_CLR_5 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[5]), /**< Clear task 5.*/ + NRF_GPIOTE_TASKS_CLR_6 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[6]), /**< Clear task 6.*/ + NRF_GPIOTE_TASKS_CLR_7 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[7]), /**< Clear task 7.*/ +#endif + /*lint -restore*/ +} nrf_gpiote_tasks_t; + +/** + * @brief Events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_GPIOTE_EVENTS_IN_0 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[0]), /**< In event 0.*/ + NRF_GPIOTE_EVENTS_IN_1 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[1]), /**< In event 1.*/ + NRF_GPIOTE_EVENTS_IN_2 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[2]), /**< In event 2.*/ + NRF_GPIOTE_EVENTS_IN_3 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[3]), /**< In event 3.*/ +#if (GPIOTE_CH_NUM > 4) || defined(__SDK_DOXYGEN__) + NRF_GPIOTE_EVENTS_IN_4 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[4]), /**< In event 4.*/ + NRF_GPIOTE_EVENTS_IN_5 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[5]), /**< In event 5.*/ + NRF_GPIOTE_EVENTS_IN_6 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[6]), /**< In event 6.*/ + NRF_GPIOTE_EVENTS_IN_7 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[7]), /**< In event 7.*/ +#endif + NRF_GPIOTE_EVENTS_PORT = offsetof(NRF_GPIOTE_Type, EVENTS_PORT), /**< Port event.*/ + /*lint -restore*/ +} nrf_gpiote_events_t; + +/** + * @enum nrf_gpiote_int_t + * @brief GPIOTE interrupts. + */ +typedef enum +{ + NRF_GPIOTE_INT_IN0_MASK = GPIOTE_INTENSET_IN0_Msk, /**< GPIOTE interrupt from IN0. */ + NRF_GPIOTE_INT_IN1_MASK = GPIOTE_INTENSET_IN1_Msk, /**< GPIOTE interrupt from IN1. */ + NRF_GPIOTE_INT_IN2_MASK = GPIOTE_INTENSET_IN2_Msk, /**< GPIOTE interrupt from IN2. */ + NRF_GPIOTE_INT_IN3_MASK = GPIOTE_INTENSET_IN3_Msk, /**< GPIOTE interrupt from IN3. */ +#if (GPIOTE_CH_NUM > 4) || defined(__SDK_DOXYGEN__) + NRF_GPIOTE_INT_IN4_MASK = GPIOTE_INTENSET_IN4_Msk, /**< GPIOTE interrupt from IN4. */ + NRF_GPIOTE_INT_IN5_MASK = GPIOTE_INTENSET_IN5_Msk, /**< GPIOTE interrupt from IN5. */ + NRF_GPIOTE_INT_IN6_MASK = GPIOTE_INTENSET_IN6_Msk, /**< GPIOTE interrupt from IN6. */ + NRF_GPIOTE_INT_IN7_MASK = GPIOTE_INTENSET_IN7_Msk, /**< GPIOTE interrupt from IN7. */ +#endif + NRF_GPIOTE_INT_PORT_MASK = (int)GPIOTE_INTENSET_PORT_Msk, /**< GPIOTE interrupt from PORT event. */ +} nrf_gpiote_int_t; + +#define NRF_GPIOTE_INT_IN_MASK (NRF_GPIOTE_INT_IN0_MASK | NRF_GPIOTE_INT_IN1_MASK |\ + NRF_GPIOTE_INT_IN2_MASK | NRF_GPIOTE_INT_IN3_MASK) +#if (GPIOTE_CH_NUM > 4) +#undef NRF_GPIOTE_INT_IN_MASK +#define NRF_GPIOTE_INT_IN_MASK (NRF_GPIOTE_INT_IN0_MASK | NRF_GPIOTE_INT_IN1_MASK |\ + NRF_GPIOTE_INT_IN2_MASK | NRF_GPIOTE_INT_IN3_MASK |\ + NRF_GPIOTE_INT_IN4_MASK | NRF_GPIOTE_INT_IN5_MASK |\ + NRF_GPIOTE_INT_IN6_MASK | NRF_GPIOTE_INT_IN7_MASK) +#endif + +/** + * @brief Function for activating a specific GPIOTE task. + * + * @param[in] task Task. + */ +__STATIC_INLINE void nrf_gpiote_task_set(nrf_gpiote_tasks_t task); + +/** + * @brief Function for getting the address of a specific GPIOTE task. + * + * @param[in] task Task. + * + * @returns Address. + */ +__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task); + +/** + * @brief Function for getting the state of a specific GPIOTE event. + * + * @param[in] event Event. + */ +__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event); + +/** + * @brief Function for clearing a specific GPIOTE event. + * + * @param[in] event Event. + */ +__STATIC_INLINE void nrf_gpiote_event_clear(nrf_gpiote_events_t event); + +/** + * @brief Function for getting the address of a specific GPIOTE event. + * + * @param[in] event Event. + * + * @return Address + */ +__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event); + +/**@brief Function for enabling interrupts. + * + * @param[in] mask Interrupt mask to be enabled. + */ +__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask); + +/**@brief Function for disabling interrupts. + * + * @param[in] mask Interrupt mask to be disabled. + */ +__STATIC_INLINE void nrf_gpiote_int_disable(uint32_t mask); + +/**@brief Function for checking if interrupts are enabled. + * + * @param[in] mask Mask of interrupt flags to check. + * + * @return Mask with enabled interrupts. + */ +__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask); + +/**@brief Function for enabling a GPIOTE event. + * + * @param[in] idx Task-Event index. + */ +__STATIC_INLINE void nrf_gpiote_event_enable(uint32_t idx); + +/**@brief Function for disabling a GPIOTE event. + * + * @param[in] idx Task-Event index. + */ +__STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx); + +/**@brief Function for configuring a GPIOTE event. + * + * @param[in] idx Task-Event index. + * @param[in] pin Pin associated with event. + * @param[in] polarity Transition that should generate an event. + */ +__STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin, + nrf_gpiote_polarity_t polarity); + +/**@brief Function for getting the pin associated with a GPIOTE event. + * + * @param[in] idx Task-Event index. + * + * @return Pin number. + */ +__STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx); + +/**@brief Function for getting the polarity associated with a GPIOTE event. + * + * @param[in] idx Task-Event index. + * + * @return Polarity. + */ +__STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx); + +/**@brief Function for enabling a GPIOTE task. + * + * @param[in] idx Task-Event index. + */ +__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx); + +/**@brief Function for disabling a GPIOTE task. + * + * @param[in] idx Task-Event index. + */ +__STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx); + +/**@brief Function for configuring a GPIOTE task. + * @note Function is not configuring mode field so task is disabled after this function is called. + * + * @param[in] idx Task-Event index. + * @param[in] pin Pin associated with event. + * @param[in] polarity Transition that should generate an event. + * @param[in] init_val Initial value of the pin. + */ +__STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin, + nrf_gpiote_polarity_t polarity, + nrf_gpiote_outinit_t init_val); + +/**@brief Function for forcing a specific state on the pin connected to GPIOTE. + * + * @param[in] idx Task-Event index. + * @param[in] init_val Pin state. + */ +__STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val); + +/**@brief Function for resetting a GPIOTE task event configuration to the default state. + * + * @param[in] idx Task-Event index. + */ +__STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION +__STATIC_INLINE void nrf_gpiote_task_set(nrf_gpiote_tasks_t task) +{ + *(__IO uint32_t *)((uint32_t)NRF_GPIOTE + task) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task) +{ + return ((uint32_t)NRF_GPIOTE + task); +} + +__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event) +{ + return (*(uint32_t *)nrf_gpiote_event_addr_get(event) == 0x1UL) ? true : false; +} + +__STATIC_INLINE void nrf_gpiote_event_clear(nrf_gpiote_events_t event) +{ + *(uint32_t *)nrf_gpiote_event_addr_get(event) = 0; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)nrf_gpiote_event_addr_get(event)); + (void)dummy; +#endif +} + +__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event) +{ + return ((uint32_t)NRF_GPIOTE + event); +} + +__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask) +{ + NRF_GPIOTE->INTENSET = mask; +} + +__STATIC_INLINE void nrf_gpiote_int_disable(uint32_t mask) +{ + NRF_GPIOTE->INTENCLR = mask; +} + +__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask) +{ + return (NRF_GPIOTE->INTENSET & mask); +} + +__STATIC_INLINE void nrf_gpiote_event_enable(uint32_t idx) +{ + NRF_GPIOTE->CONFIG[idx] |= GPIOTE_CONFIG_MODE_Event; +} + +__STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx) +{ + NRF_GPIOTE->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Event; +} + +__STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin, nrf_gpiote_polarity_t polarity) +{ + NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PORT_PIN_Msk | GPIOTE_CONFIG_POLARITY_Msk); + NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_Msk) | + ((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk); +} + +__STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx) +{ + return ((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_PORT_PIN_Msk) >> GPIOTE_CONFIG_PSEL_Pos); +} + +__STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx) +{ + return (nrf_gpiote_polarity_t)((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_POLARITY_Msk) >> GPIOTE_CONFIG_POLARITY_Pos); +} + +__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx) +{ + uint32_t final_config = NRF_GPIOTE->CONFIG[idx] | GPIOTE_CONFIG_MODE_Task; +#ifdef NRF51 + /* Workaround for the OUTINIT PAN. When nrf_gpiote_task_config() is called a glitch happens + on the GPIO if the GPIO in question is already assigned to GPIOTE and the pin is in the + correct state in GPIOTE but not in the OUT register. */ + /* Configure channel to not existing, not connected to the pin, and configure as a tasks that will set it to proper level */ + NRF_GPIOTE->CONFIG[idx] = final_config | (((31) << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_Msk); + __NOP(); + __NOP(); + __NOP(); +#endif + NRF_GPIOTE->CONFIG[idx] = final_config; +} + +__STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx) +{ + NRF_GPIOTE->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Task; +} + +__STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin, + nrf_gpiote_polarity_t polarity, + nrf_gpiote_outinit_t init_val) +{ + NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PORT_PIN_Msk | + GPIOTE_CONFIG_POLARITY_Msk | + GPIOTE_CONFIG_OUTINIT_Msk); + + NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_Msk) | + ((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk) | + ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk); +} + +__STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val) +{ + NRF_GPIOTE->CONFIG[idx] = (NRF_GPIOTE->CONFIG[idx] & ~GPIOTE_CONFIG_OUTINIT_Msk) + | ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk); +} + +__STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx) +{ + NRF_GPIOTE->CONFIG[idx] = 0; +} +#endif //SUPPRESS_INLINE_IMPLEMENTATION +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_i2s.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_i2s.h new file mode 100644 index 0000000000000000000000000000000000000000..d5485572b5a48a01b3d61a9afd00583c75773cfc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_i2s.h @@ -0,0 +1,563 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @defgroup nrf_i2s_hal I2S HAL + * @{ + * @ingroup nrf_i2s + * + * @brief @tagAPI52 Hardware access layer for managing the Inter-IC Sound (I2S) peripheral. + */ + +#ifndef NRF_I2S_H__ +#define NRF_I2S_H__ + +#include +#include +#include + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief This value can be provided as a parameter for the @ref nrf_i2s_pins_set + * function call to specify that a given I2S signal (SDOUT, SDIN, or MCK) + * shall not be connected to a physical pin. + */ +#define NRF_I2S_PIN_NOT_CONNECTED 0xFFFFFFFF + + +/** + * @brief I2S tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_I2S_TASK_START = offsetof(NRF_I2S_Type, TASKS_START), ///< Starts continuous I2S transfer. Also starts the MCK generator if this is enabled. + NRF_I2S_TASK_STOP = offsetof(NRF_I2S_Type, TASKS_STOP) ///< Stops I2S transfer. Also stops the MCK generator. + /*lint -restore*/ +} nrf_i2s_task_t; + +/** + * @brief I2S events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_I2S_EVENT_RXPTRUPD = offsetof(NRF_I2S_Type, EVENTS_RXPTRUPD), ///< The RXD.PTR register has been copied to internal double-buffers. + NRF_I2S_EVENT_TXPTRUPD = offsetof(NRF_I2S_Type, EVENTS_TXPTRUPD), ///< The TXD.PTR register has been copied to internal double-buffers. + NRF_I2S_EVENT_STOPPED = offsetof(NRF_I2S_Type, EVENTS_STOPPED) ///< I2S transfer stopped. + /*lint -restore*/ +} nrf_i2s_event_t; + +/** + * @brief I2S interrupts. + */ +typedef enum +{ + NRF_I2S_INT_RXPTRUPD_MASK = I2S_INTENSET_RXPTRUPD_Msk, ///< Interrupt on RXPTRUPD event. + NRF_I2S_INT_TXPTRUPD_MASK = I2S_INTENSET_TXPTRUPD_Msk, ///< Interrupt on TXPTRUPD event. + NRF_I2S_INT_STOPPED_MASK = I2S_INTENSET_STOPPED_Msk ///< Interrupt on STOPPED event. +} nrf_i2s_int_mask_t; + +/** + * @brief I2S modes of operation. + */ +typedef enum +{ + NRF_I2S_MODE_MASTER = I2S_CONFIG_MODE_MODE_Master, ///< Master mode. + NRF_I2S_MODE_SLAVE = I2S_CONFIG_MODE_MODE_Slave ///< Slave mode. +} nrf_i2s_mode_t; + +/** + * @brief I2S master clock generator settings. + */ +typedef enum +{ + NRF_I2S_MCK_DISABLED = 0, ///< MCK disabled. + // [conversion to 'int' needed to prevent compilers from complaining + // that the provided value (0x80000000UL) is out of range of "int"] + NRF_I2S_MCK_32MDIV2 = (int)I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2, ///< 32 MHz / 2 = 16.0 MHz. + NRF_I2S_MCK_32MDIV3 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV3, ///< 32 MHz / 3 = 10.6666667 MHz. + NRF_I2S_MCK_32MDIV4 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV4, ///< 32 MHz / 4 = 8.0 MHz. + NRF_I2S_MCK_32MDIV5 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV5, ///< 32 MHz / 5 = 6.4 MHz. + NRF_I2S_MCK_32MDIV6 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV6, ///< 32 MHz / 6 = 5.3333333 MHz. + NRF_I2S_MCK_32MDIV8 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8, ///< 32 MHz / 8 = 4.0 MHz. + NRF_I2S_MCK_32MDIV10 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV10, ///< 32 MHz / 10 = 3.2 MHz. + NRF_I2S_MCK_32MDIV11 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV11, ///< 32 MHz / 11 = 2.9090909 MHz. + NRF_I2S_MCK_32MDIV15 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV15, ///< 32 MHz / 15 = 2.1333333 MHz. + NRF_I2S_MCK_32MDIV16 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16, ///< 32 MHz / 16 = 2.0 MHz. + NRF_I2S_MCK_32MDIV21 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV21, ///< 32 MHz / 21 = 1.5238095 MHz. + NRF_I2S_MCK_32MDIV23 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV23, ///< 32 MHz / 23 = 1.3913043 MHz. + NRF_I2S_MCK_32MDIV31 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31, ///< 32 MHz / 31 = 1.0322581 MHz. + NRF_I2S_MCK_32MDIV42 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV42, ///< 32 MHz / 42 = 0.7619048 MHz. + NRF_I2S_MCK_32MDIV63 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV63, ///< 32 MHz / 63 = 0.5079365 MHz. + NRF_I2S_MCK_32MDIV125 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV125 ///< 32 MHz / 125 = 0.256 MHz. +} nrf_i2s_mck_t; + +/** + * @brief I2S MCK/LRCK ratios. + */ +typedef enum +{ + NRF_I2S_RATIO_32X = I2S_CONFIG_RATIO_RATIO_32X, ///< LRCK = MCK / 32. + NRF_I2S_RATIO_48X = I2S_CONFIG_RATIO_RATIO_48X, ///< LRCK = MCK / 48. + NRF_I2S_RATIO_64X = I2S_CONFIG_RATIO_RATIO_64X, ///< LRCK = MCK / 64. + NRF_I2S_RATIO_96X = I2S_CONFIG_RATIO_RATIO_96X, ///< LRCK = MCK / 96. + NRF_I2S_RATIO_128X = I2S_CONFIG_RATIO_RATIO_128X, ///< LRCK = MCK / 128. + NRF_I2S_RATIO_192X = I2S_CONFIG_RATIO_RATIO_192X, ///< LRCK = MCK / 192. + NRF_I2S_RATIO_256X = I2S_CONFIG_RATIO_RATIO_256X, ///< LRCK = MCK / 256. + NRF_I2S_RATIO_384X = I2S_CONFIG_RATIO_RATIO_384X, ///< LRCK = MCK / 384. + NRF_I2S_RATIO_512X = I2S_CONFIG_RATIO_RATIO_512X ///< LRCK = MCK / 512. +} nrf_i2s_ratio_t; + +/** + * @brief I2S sample widths. + */ +typedef enum +{ + NRF_I2S_SWIDTH_8BIT = I2S_CONFIG_SWIDTH_SWIDTH_8Bit, ///< 8 bit. + NRF_I2S_SWIDTH_16BIT = I2S_CONFIG_SWIDTH_SWIDTH_16Bit, ///< 16 bit. + NRF_I2S_SWIDTH_24BIT = I2S_CONFIG_SWIDTH_SWIDTH_24Bit ///< 24 bit. +} nrf_i2s_swidth_t; + +/** + * @brief I2S alignments of sample within a frame. + */ +typedef enum +{ + NRF_I2S_ALIGN_LEFT = I2S_CONFIG_ALIGN_ALIGN_Left, ///< Left-aligned. + NRF_I2S_ALIGN_RIGHT = I2S_CONFIG_ALIGN_ALIGN_Right ///< Right-aligned. +} nrf_i2s_align_t; + +/** + * @brief I2S frame formats. + */ +typedef enum +{ + NRF_I2S_FORMAT_I2S = I2S_CONFIG_FORMAT_FORMAT_I2S, ///< Original I2S format. + NRF_I2S_FORMAT_ALIGNED = I2S_CONFIG_FORMAT_FORMAT_Aligned ///< Alternate (left- or right-aligned) format. +} nrf_i2s_format_t; + +/** + * @brief I2S enabled channels. + */ +typedef enum +{ + NRF_I2S_CHANNELS_STEREO = I2S_CONFIG_CHANNELS_CHANNELS_Stereo, ///< Stereo. + NRF_I2S_CHANNELS_LEFT = I2S_CONFIG_CHANNELS_CHANNELS_Left, ///< Left only. + NRF_I2S_CHANNELS_RIGHT = I2S_CONFIG_CHANNELS_CHANNELS_Right ///< Right only. +} nrf_i2s_channels_t; + + +/** + * @brief Function for activating a specific I2S task. + * + * @param[in] p_i2s I2S instance. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_i2s, + nrf_i2s_task_t task); + +/** + * @brief Function for getting the address of a specific I2S task register. + * + * @param[in] p_i2s I2S instance. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t nrf_i2s_task_address_get(NRF_I2S_Type const * p_i2s, + nrf_i2s_task_t task); + +/** + * @brief Function for clearing a specific I2S event. + * + * @param[in] p_i2s I2S instance. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_i2s_event_clear(NRF_I2S_Type * p_i2s, + nrf_i2s_event_t event); + +/** + * @brief Function for checking the state of a specific I2S event. + * + * @param[in] p_i2s I2S instance. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_i2s_event_check(NRF_I2S_Type const * p_i2s, + nrf_i2s_event_t event); + +/** + * @brief Function for getting the address of a specific I2S event register. + * + * @param[in] p_i2s I2S instance. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t nrf_i2s_event_address_get(NRF_I2S_Type const * p_i2s, + nrf_i2s_event_t event); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_i2s I2S instance. + * @param[in] mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_i2s_int_enable(NRF_I2S_Type * p_i2s, uint32_t mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_i2s I2S instance. + * @param[in] mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_i2s_int_disable(NRF_I2S_Type * p_i2s, uint32_t mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_i2s I2S instance. + * @param[in] i2s_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_i2s_int_enable_check(NRF_I2S_Type const * p_i2s, + nrf_i2s_int_mask_t i2s_int); + +/** + * @brief Function for enabling the I2S peripheral. + * + * @param[in] p_i2s I2S instance. + */ +__STATIC_INLINE void nrf_i2s_enable(NRF_I2S_Type * p_i2s); + +/** + * @brief Function for disabling the I2S peripheral. + * + * @param[in] p_i2s I2S instance. + */ +__STATIC_INLINE void nrf_i2s_disable(NRF_I2S_Type * p_i2s); + +/** + * @brief Function for configuring I2S pins. + * + * Usage of the SDOUT, SDIN, and MCK signals is optional. + * If a given signal is not needed, pass the @ref NRF_I2S_PIN_NOT_CONNECTED + * value instead of its pin number. + * + * @param[in] p_i2s I2S instance. + * @param[in] sck_pin SCK pin number. + * @param[in] lrck_pin LRCK pin number. + * @param[in] mck_pin MCK pin number. + * @param[in] sdout_pin SDOUT pin number. + * @param[in] sdin_pin SDIN pin number. + */ +__STATIC_INLINE void nrf_i2s_pins_set(NRF_I2S_Type * p_i2s, + uint32_t sck_pin, + uint32_t lrck_pin, + uint32_t mck_pin, + uint32_t sdout_pin, + uint32_t sdin_pin); + +/** + * @brief Function for setting the I2S peripheral configuration. + * + * @param[in] p_i2s I2S instance. + * @param[in] mode Mode of operation (master or slave). + * @param[in] format I2S frame format. + * @param[in] alignment Alignment of sample within a frame. + * @param[in] sample_width Sample width. + * @param[in] channels Enabled channels. + * @param[in] mck_setup Master clock generator setup. + * @param[in] ratio MCK/LRCK ratio. + * + * @retval true If the configuration has been set successfully. + * @retval false If the requested configuration is not allowed. + */ +__STATIC_INLINE bool nrf_i2s_configure(NRF_I2S_Type * p_i2s, + nrf_i2s_mode_t mode, + nrf_i2s_format_t format, + nrf_i2s_align_t alignment, + nrf_i2s_swidth_t sample_width, + nrf_i2s_channels_t channels, + nrf_i2s_mck_t mck_setup, + nrf_i2s_ratio_t ratio); + +/** + * @brief Function for setting up the I2S transfer. + * + * This function sets up the RX and TX buffers and enables reception and/or + * transmission accordingly. If the transfer in a given direction is not + * required, pass NULL instead of the pointer to the corresponding buffer. + * + * @param[in] p_i2s I2S instance. + * @param[in] size Size of the buffers (in 32-bit words). + * @param[in] p_rx_buffer Pointer to the receive buffer. + * Pass NULL to disable reception. + * @param[in] p_tx_buffer Pointer to the transmit buffer. + * Pass NULL to disable transmission. + */ +__STATIC_INLINE void nrf_i2s_transfer_set(NRF_I2S_Type * p_i2s, + uint16_t size, + uint32_t * p_rx_buffer, + uint32_t const * p_tx_buffer); + +/** + * @brief Function for setting the pointer to the receive buffer. + * + * @note The size of the buffer can be set only by calling + * @ref nrf_i2s_transfer_set. + * + * @param[in] p_i2s I2S instance. + * @param[in] p_buffer Pointer to the receive buffer. + */ +__STATIC_INLINE void nrf_i2s_rx_buffer_set(NRF_I2S_Type * p_i2s, + uint32_t * p_buffer); + +/** + * @brief Function for getting the pointer to the receive buffer. + * + * @param[in] p_i2s I2S instance. + * + * @return Pointer to the receive buffer. + */ +__STATIC_INLINE uint32_t * nrf_i2s_rx_buffer_get(NRF_I2S_Type const * p_i2s); + +/** + * @brief Function for setting the pointer to the transmit buffer. + * + * @note The size of the buffer can be set only by calling + * @ref nrf_i2s_transfer_set. + * + * @param[in] p_i2s I2S instance. + * @param[in] p_buffer Pointer to the transmit buffer. + */ +__STATIC_INLINE void nrf_i2s_tx_buffer_set(NRF_I2S_Type * p_i2s, + uint32_t const * p_buffer); + +/** + * @brief Function for getting the pointer to the transmit buffer. + * + * @param[in] p_i2s I2S instance. + * + * @return Pointer to the transmit buffer. + */ +__STATIC_INLINE uint32_t * nrf_i2s_tx_buffer_get(NRF_I2S_Type const * p_i2s); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_i2s, + nrf_i2s_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_i2s_task_address_get(NRF_I2S_Type const * p_i2s, + nrf_i2s_task_t task) +{ + return ((uint32_t)p_i2s + (uint32_t)task); +} + +__STATIC_INLINE void nrf_i2s_event_clear(NRF_I2S_Type * p_i2s, + nrf_i2s_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_i2s_event_check(NRF_I2S_Type const * p_i2s, + nrf_i2s_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event); +} + +__STATIC_INLINE uint32_t nrf_i2s_event_address_get(NRF_I2S_Type const * p_i2s, + nrf_i2s_event_t event) +{ + return ((uint32_t)p_i2s + (uint32_t)event); +} + +__STATIC_INLINE void nrf_i2s_int_enable(NRF_I2S_Type * p_i2s, uint32_t mask) +{ + p_i2s->INTENSET = mask; +} + +__STATIC_INLINE void nrf_i2s_int_disable(NRF_I2S_Type * p_i2s, uint32_t mask) +{ + p_i2s->INTENCLR = mask; +} + +__STATIC_INLINE bool nrf_i2s_int_enable_check(NRF_I2S_Type const * p_i2s, + nrf_i2s_int_mask_t i2s_int) +{ + return (bool)(p_i2s->INTENSET & i2s_int); +} + +__STATIC_INLINE void nrf_i2s_enable(NRF_I2S_Type * p_i2s) +{ + p_i2s->ENABLE = (I2S_ENABLE_ENABLE_Enabled << I2S_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_i2s_disable(NRF_I2S_Type * p_i2s) +{ + p_i2s->ENABLE = (I2S_ENABLE_ENABLE_Disabled << I2S_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_i2s_pins_set(NRF_I2S_Type * p_i2s, + uint32_t sck_pin, + uint32_t lrck_pin, + uint32_t mck_pin, + uint32_t sdout_pin, + uint32_t sdin_pin) +{ + p_i2s->PSEL.SCK = sck_pin; + p_i2s->PSEL.LRCK = lrck_pin; + p_i2s->PSEL.MCK = mck_pin; + p_i2s->PSEL.SDOUT = sdout_pin; + p_i2s->PSEL.SDIN = sdin_pin; +} + +__STATIC_INLINE bool nrf_i2s_configure(NRF_I2S_Type * p_i2s, + nrf_i2s_mode_t mode, + nrf_i2s_format_t format, + nrf_i2s_align_t alignment, + nrf_i2s_swidth_t sample_width, + nrf_i2s_channels_t channels, + nrf_i2s_mck_t mck_setup, + nrf_i2s_ratio_t ratio) +{ + if (mode == NRF_I2S_MODE_MASTER) + { + // The MCK/LRCK ratio shall be a multiple of 2 * sample width. + if (((sample_width == NRF_I2S_SWIDTH_16BIT) && + (ratio == NRF_I2S_RATIO_48X)) + || + ((sample_width == NRF_I2S_SWIDTH_24BIT) && + ((ratio == NRF_I2S_RATIO_32X) || + (ratio == NRF_I2S_RATIO_64X) || + (ratio == NRF_I2S_RATIO_128X) || + (ratio == NRF_I2S_RATIO_256X) || + (ratio == NRF_I2S_RATIO_512X)))) + { + return false; + } + } + + p_i2s->CONFIG.MODE = mode; + p_i2s->CONFIG.FORMAT = format; + p_i2s->CONFIG.ALIGN = alignment; + p_i2s->CONFIG.SWIDTH = sample_width; + p_i2s->CONFIG.CHANNELS = channels; + p_i2s->CONFIG.RATIO = ratio; + + if (mck_setup == NRF_I2S_MCK_DISABLED) + { + p_i2s->CONFIG.MCKEN = + (I2S_CONFIG_MCKEN_MCKEN_Disabled << I2S_CONFIG_MCKEN_MCKEN_Pos); + } + else + { + p_i2s->CONFIG.MCKFREQ = mck_setup; + p_i2s->CONFIG.MCKEN = + (I2S_CONFIG_MCKEN_MCKEN_Enabled << I2S_CONFIG_MCKEN_MCKEN_Pos); + } + + return true; +} + +__STATIC_INLINE void nrf_i2s_transfer_set(NRF_I2S_Type * p_i2s, + uint16_t size, + uint32_t * p_buffer_rx, + uint32_t const * p_buffer_tx) +{ + p_i2s->RXTXD.MAXCNT = size; + + nrf_i2s_rx_buffer_set(p_i2s, p_buffer_rx); + p_i2s->CONFIG.RXEN = (p_buffer_rx != NULL) ? 1 : 0; + + nrf_i2s_tx_buffer_set(p_i2s, p_buffer_tx); + p_i2s->CONFIG.TXEN = (p_buffer_tx != NULL) ? 1 : 0; +} + +__STATIC_INLINE void nrf_i2s_rx_buffer_set(NRF_I2S_Type * p_i2s, + uint32_t * p_buffer) +{ + p_i2s->RXD.PTR = (uint32_t)p_buffer; +} + +__STATIC_INLINE uint32_t * nrf_i2s_rx_buffer_get(NRF_I2S_Type const * p_i2s) +{ + return (uint32_t *)(p_i2s->RXD.PTR); +} + +__STATIC_INLINE void nrf_i2s_tx_buffer_set(NRF_I2S_Type * p_i2s, + uint32_t const * p_buffer) +{ + p_i2s->TXD.PTR = (uint32_t)p_buffer; +} + +__STATIC_INLINE uint32_t * nrf_i2s_tx_buffer_get(NRF_I2S_Type const * p_i2s) +{ + return (uint32_t *)(p_i2s->TXD.PTR); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_I2S_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_lpcomp.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_lpcomp.h new file mode 100644 index 0000000000000000000000000000000000000000..4e241a9779dfeacea8a53c84f4a931c9b8f071a3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_lpcomp.h @@ -0,0 +1,425 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief LPCOMP HAL API. + */ + +#ifndef NRF_LPCOMP_H_ +#define NRF_LPCOMP_H_ + +/** + * @defgroup nrf_lpcomp_hal LPCOMP HAL + * @{ + * @ingroup nrf_lpcomp + * @brief Hardware access layer for managing the Low Power Comparator (LPCOMP). + */ + +#include "nrf.h" +#include "nrf_peripherals.h" + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @enum nrf_lpcomp_ref_t + * @brief LPCOMP reference selection. + */ +typedef enum +{ +#if (LPCOMP_REFSEL_RESOLUTION == 8) || defined(__SDK_DOXYGEN__) + NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_SupplyOneEighthPrescaling, /**< Use supply with a 1/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_SupplyTwoEighthsPrescaling, /**< Use supply with a 2/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_SupplyThreeEighthsPrescaling, /**< Use supply with a 3/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_4_8 = LPCOMP_REFSEL_REFSEL_SupplyFourEighthsPrescaling, /**< Use supply with a 4/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_SupplyFiveEighthsPrescaling, /**< Use supply with a 5/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_SupplySixEighthsPrescaling, /**< Use supply with a 6/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_SupplySevenEighthsPrescaling, /**< Use supply with a 7/8 prescaler as reference. */ +#elif (LPCOMP_REFSEL_RESOLUTION == 16) || defined(__SDK_DOXYGEN__) + NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_Ref1_8Vdd, /**< Use supply with a 1/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_Ref2_8Vdd, /**< Use supply with a 2/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_Ref3_8Vdd, /**< Use supply with a 3/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_4_8 = LPCOMP_REFSEL_REFSEL_Ref4_8Vdd, /**< Use supply with a 4/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_Ref5_8Vdd, /**< Use supply with a 5/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_Ref6_8Vdd, /**< Use supply with a 6/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_Ref7_8Vdd, /**< Use supply with a 7/8 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_1_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 1/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_3_16 = LPCOMP_REFSEL_REFSEL_Ref3_16Vdd, /**< Use supply with a 3/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_5_16 = LPCOMP_REFSEL_REFSEL_Ref5_16Vdd, /**< Use supply with a 5/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_7_16 = LPCOMP_REFSEL_REFSEL_Ref7_16Vdd, /**< Use supply with a 7/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_9_16 = LPCOMP_REFSEL_REFSEL_Ref9_16Vdd, /**< Use supply with a 9/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_11_16 = LPCOMP_REFSEL_REFSEL_Ref11_16Vdd, /**< Use supply with a 11/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_13_16 = LPCOMP_REFSEL_REFSEL_Ref13_16Vdd, /**< Use supply with a 13/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_15_16 = LPCOMP_REFSEL_REFSEL_Ref15_16Vdd, /**< Use supply with a 15/16 prescaler as reference. */ +#endif + NRF_LPCOMP_REF_EXT_REF0 = LPCOMP_REFSEL_REFSEL_ARef | + (LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference0 << 16), /**< External reference 0. */ + NRF_LPCOMP_CONFIG_REF_EXT_REF1 = LPCOMP_REFSEL_REFSEL_ARef | + (LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference1 << 16), /**< External reference 1. */ +} nrf_lpcomp_ref_t; + +/** + * @enum nrf_lpcomp_input_t + * @brief LPCOMP input selection. + */ +typedef enum +{ + NRF_LPCOMP_INPUT_0 = LPCOMP_PSEL_PSEL_AnalogInput0, /**< Input 0. */ + NRF_LPCOMP_INPUT_1 = LPCOMP_PSEL_PSEL_AnalogInput1, /**< Input 1. */ + NRF_LPCOMP_INPUT_2 = LPCOMP_PSEL_PSEL_AnalogInput2, /**< Input 2. */ + NRF_LPCOMP_INPUT_3 = LPCOMP_PSEL_PSEL_AnalogInput3, /**< Input 3. */ + NRF_LPCOMP_INPUT_4 = LPCOMP_PSEL_PSEL_AnalogInput4, /**< Input 4. */ + NRF_LPCOMP_INPUT_5 = LPCOMP_PSEL_PSEL_AnalogInput5, /**< Input 5. */ + NRF_LPCOMP_INPUT_6 = LPCOMP_PSEL_PSEL_AnalogInput6, /**< Input 6. */ + NRF_LPCOMP_INPUT_7 = LPCOMP_PSEL_PSEL_AnalogInput7 /**< Input 7. */ +} nrf_lpcomp_input_t; + +/** + * @enum nrf_lpcomp_detect_t + * @brief LPCOMP detection type selection. + */ +typedef enum +{ + NRF_LPCOMP_DETECT_CROSS = LPCOMP_ANADETECT_ANADETECT_Cross, /**< Generate ANADETEC on crossing, both upwards and downwards crossing. */ + NRF_LPCOMP_DETECT_UP = LPCOMP_ANADETECT_ANADETECT_Up, /**< Generate ANADETEC on upwards crossing only. */ + NRF_LPCOMP_DETECT_DOWN = LPCOMP_ANADETECT_ANADETECT_Down /**< Generate ANADETEC on downwards crossing only. */ +} nrf_lpcomp_detect_t; + +/** + * @enum nrf_lpcomp_task_t + * @brief LPCOMP tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_LPCOMP_TASK_START = offsetof(NRF_LPCOMP_Type, TASKS_START), /**< LPCOMP start sampling task. */ + NRF_LPCOMP_TASK_STOP = offsetof(NRF_LPCOMP_Type, TASKS_STOP), /**< LPCOMP stop sampling task. */ + NRF_LPCOMP_TASK_SAMPLE = offsetof(NRF_LPCOMP_Type, TASKS_SAMPLE) /**< Sample comparator value. */ +} nrf_lpcomp_task_t; /*lint -restore*/ + + +/** + * @enum nrf_lpcomp_event_t + * @brief LPCOMP events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_LPCOMP_EVENT_READY = offsetof(NRF_LPCOMP_Type, EVENTS_READY), /**< LPCOMP is ready and output is valid. */ + NRF_LPCOMP_EVENT_DOWN = offsetof(NRF_LPCOMP_Type, EVENTS_DOWN), /**< Input voltage crossed the threshold going down. */ + NRF_LPCOMP_EVENT_UP = offsetof(NRF_LPCOMP_Type, EVENTS_UP), /**< Input voltage crossed the threshold going up. */ + NRF_LPCOMP_EVENT_CROSS = offsetof(NRF_LPCOMP_Type, EVENTS_CROSS) /**< Input voltage crossed the threshold in any direction. */ +} nrf_lpcomp_event_t; /*lint -restore*/ + +/** + * @enum nrf_lpcomp_short_mask_t + * @brief LPCOMP shorts masks. + */ +typedef enum +{ + NRF_LPCOMP_SHORT_CROSS_STOP_MASK = LPCOMP_SHORTS_CROSS_STOP_Msk, /*!< Short between CROSS event and STOP task. */ + NRF_LPCOMP_SHORT_UP_STOP_MASK = LPCOMP_SHORTS_UP_STOP_Msk, /*!< Short between UP event and STOP task. */ + NRF_LPCOMP_SHORT_DOWN_STOP_MASK = LPCOMP_SHORTS_DOWN_STOP_Msk, /*!< Short between DOWN event and STOP task. */ + NRF_LPCOMP_SHORT_READY_STOP_MASK = LPCOMP_SHORTS_READY_STOP_Msk, /*!< Short between READY event and STOP task. */ + NRF_LPCOMP_SHORT_READY_SAMPLE_MASK = LPCOMP_SHORTS_READY_SAMPLE_Msk /*!< Short between READY event and SAMPLE task. */ +} nrf_lpcomp_short_mask_t; + +#ifdef LPCOMP_FEATURE_HYST_PRESENT +/** + * @enum nrf_lpcomp_hysteresis_t + * @brief LPCOMP hysteresis. + */ +typedef enum +{ + NRF_LPCOMP_HYST_NOHYST = LPCOMP_HYST_HYST_NoHyst, /**< Comparator hysteresis disabled. */ + NRF_LPCOMP_HYST_50mV = LPCOMP_HYST_HYST_Hyst50mV /**< Comparator hysteresis enabled (typ. 50 mV). */ +}nrf_lpcomp_hysteresis_t; +#endif // LPCOMP_FEATURE_HYST_PRESENT + +/** @brief LPCOMP configuration. */ +typedef struct +{ + nrf_lpcomp_ref_t reference; /**< LPCOMP reference. */ + nrf_lpcomp_detect_t detection; /**< LPCOMP detection type. */ +#ifdef LPCOMP_FEATURE_HYST_PRESENT + nrf_lpcomp_hysteresis_t hyst; /**< LPCOMP hysteresis. */ +#endif // LPCOMP_FEATURE_HYST_PRESENT +} nrf_lpcomp_config_t; + +/** Default LPCOMP configuration. */ +#define NRF_LPCOMP_CONFIG_DEFAULT { NRF_LPCOMP_REF_SUPPLY_FOUR_EIGHT, NRF_LPCOMP_DETECT_DOWN } + +/** + * @brief Function for configuring LPCOMP. + * + * This function powers on LPCOMP and configures it. LPCOMP is in DISABLE state after configuration, + * so it must be enabled before using it. All shorts are inactive, events are cleared, and LPCOMP is stopped. + * + * @param[in] p_config Configuration. + */ +__STATIC_INLINE void nrf_lpcomp_configure(const nrf_lpcomp_config_t * p_config) +{ + NRF_LPCOMP->TASKS_STOP = 1; + NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos; + NRF_LPCOMP->REFSEL = + (p_config->reference << LPCOMP_REFSEL_REFSEL_Pos) & LPCOMP_REFSEL_REFSEL_Msk; + + //If external source is choosen extract analog reference index. + if ((p_config->reference & LPCOMP_REFSEL_REFSEL_ARef)==LPCOMP_REFSEL_REFSEL_ARef) + { + uint32_t extref = p_config->reference >> 16; + NRF_LPCOMP->EXTREFSEL = (extref << LPCOMP_EXTREFSEL_EXTREFSEL_Pos) & LPCOMP_EXTREFSEL_EXTREFSEL_Msk; + } + + NRF_LPCOMP->ANADETECT = + (p_config->detection << LPCOMP_ANADETECT_ANADETECT_Pos) & LPCOMP_ANADETECT_ANADETECT_Msk; +#ifdef LPCOMP_FEATURE_HYST_PRESENT + NRF_LPCOMP->HYST = ((p_config->hyst) << LPCOMP_HYST_HYST_Pos) & LPCOMP_HYST_HYST_Msk; +#endif //LPCOMP_FEATURE_HYST_PRESENT + NRF_LPCOMP->SHORTS = 0; + NRF_LPCOMP->INTENCLR = LPCOMP_INTENCLR_CROSS_Msk | LPCOMP_INTENCLR_UP_Msk | + LPCOMP_INTENCLR_DOWN_Msk | LPCOMP_INTENCLR_READY_Msk; +} + + +/** + * @brief Function for selecting the LPCOMP input. + * + * This function selects the active input of LPCOMP. + * + * @param[in] input Input to be selected. + */ +__STATIC_INLINE void nrf_lpcomp_input_select(nrf_lpcomp_input_t input) +{ + uint32_t lpcomp_enable_state = NRF_LPCOMP->ENABLE; + + NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos; + NRF_LPCOMP->PSEL = + ((uint32_t)input << LPCOMP_PSEL_PSEL_Pos) | (NRF_LPCOMP->PSEL & ~LPCOMP_PSEL_PSEL_Msk); + NRF_LPCOMP->ENABLE = lpcomp_enable_state; +} + + +/** + * @brief Function for enabling the Low Power Comparator. + * + * This function enables LPCOMP. + * + */ +__STATIC_INLINE void nrf_lpcomp_enable(void) +{ + NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Enabled << LPCOMP_ENABLE_ENABLE_Pos; + NRF_LPCOMP->EVENTS_READY = 0; + NRF_LPCOMP->EVENTS_DOWN = 0; + NRF_LPCOMP->EVENTS_UP = 0; + NRF_LPCOMP->EVENTS_CROSS = 0; +} + + +/** + * @brief Function for disabling the Low Power Comparator. + * + * This function disables LPCOMP. + * + */ +__STATIC_INLINE void nrf_lpcomp_disable(void) +{ + NRF_LPCOMP->ENABLE = LPCOMP_ENABLE_ENABLE_Disabled << LPCOMP_ENABLE_ENABLE_Pos; +} + + +/** + * @brief Function for getting the last LPCOMP compare result. + * + * @return The last compare result. If 0 then VIN+ < VIN-, if 1 then the opposite. + */ +__STATIC_INLINE uint32_t nrf_lpcomp_result_get(void) +{ + return (uint32_t)NRF_LPCOMP->RESULT; +} + + +/** + * @brief Function for enabling interrupts from LPCOMP. + * + * @param[in] lpcomp_int_mask Mask of interrupts to be enabled. + * + * @sa nrf_lpcomp_int_disable() + * @sa nrf_lpcomp_int_enable_check() + */ +__STATIC_INLINE void nrf_lpcomp_int_enable(uint32_t lpcomp_int_mask) +{ + NRF_LPCOMP->INTENSET = lpcomp_int_mask; +} + + +/** + * @brief Function for disabling interrupts from LPCOMP. + * + * @param[in] lpcomp_int_mask Mask of interrupts to be disabled. + * + * @sa nrf_lpcomp_int_enable() + * @sa nrf_lpcomp_int_enable_check() + */ +__STATIC_INLINE void nrf_lpcomp_int_disable(uint32_t lpcomp_int_mask) +{ + NRF_LPCOMP->INTENCLR = lpcomp_int_mask; +} + + +/** + * @brief Function for getting the enabled interrupts of LPCOMP. + * + * @param[in] lpcomp_int_mask Mask of interrupts to be checked. + * + * @retval true If any of interrupts of the specified mask are enabled. + * + * @sa nrf_lpcomp_int_enable() + * @sa nrf_lpcomp_int_disable() + */ +__STATIC_INLINE bool nrf_lpcomp_int_enable_check(uint32_t lpcomp_int_mask) +{ + return (NRF_LPCOMP->INTENSET & lpcomp_int_mask); // when read this register will return the value of INTEN. +} + + +/** + * @brief Function for getting the address of a specific LPCOMP task register. + * + * @param[in] lpcomp_task LPCOMP task. + * + * @return The address of the specified LPCOMP task. + */ +__STATIC_INLINE uint32_t * nrf_lpcomp_task_address_get(nrf_lpcomp_task_t lpcomp_task) +{ + return (uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_task); +} + + +/** + * @brief Function for getting the address of a specific LPCOMP event register. + * + * @param[in] lpcomp_event LPCOMP event. + * + * @return The address of the specified LPCOMP event. + */ +__STATIC_INLINE uint32_t * nrf_lpcomp_event_address_get(nrf_lpcomp_event_t lpcomp_event) +{ + return (uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_event); +} + + +/** + * @brief Function for setting LPCOMP shorts. + * + * @param[in] lpcomp_short_mask LPCOMP shorts by mask. + * + */ +__STATIC_INLINE void nrf_lpcomp_shorts_enable(uint32_t lpcomp_short_mask) +{ + NRF_LPCOMP->SHORTS |= lpcomp_short_mask; +} + + +/** + * @brief Function for clearing LPCOMP shorts by mask. + * + * @param[in] lpcomp_short_mask LPCOMP shorts to be cleared. + * + */ +__STATIC_INLINE void nrf_lpcomp_shorts_disable(uint32_t lpcomp_short_mask) +{ + NRF_LPCOMP->SHORTS &= ~lpcomp_short_mask; +} + + +/** + * @brief Function for setting a specific LPCOMP task. + * + * @param[in] lpcomp_task LPCOMP task to be set. + * + */ +__STATIC_INLINE void nrf_lpcomp_task_trigger(nrf_lpcomp_task_t lpcomp_task) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_task) ) = 1; +} + + +/** + * @brief Function for clearing a specific LPCOMP event. + * + * @param[in] lpcomp_event LPCOMP event to be cleared. + * + */ +__STATIC_INLINE void nrf_lpcomp_event_clear(nrf_lpcomp_event_t lpcomp_event) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_event) ) = 0; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_event)); + (void)dummy; +#endif +} + + +/** + * @brief Function for getting the state of a specific LPCOMP event. + * + * @retval true If the specified LPCOMP event is active. + * + */ +__STATIC_INLINE bool nrf_lpcomp_event_check(nrf_lpcomp_event_t lpcomp_event) +{ + return (bool) (*(volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_event)); +} + + +/** + *@} + **/ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_LPCOMP_H_ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_nvmc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_nvmc.c new file mode 100644 index 0000000000000000000000000000000000000000..5eb5f684be89a6eb44decdc852b91afb03974a4f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_nvmc.c @@ -0,0 +1,143 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + *@file + *@brief NMVC driver implementation + */ + +#include +#include "nrf.h" +#include "nrf_nvmc.h" + + +void nrf_nvmc_page_erase(uint32_t address) +{ + // Enable erase. + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + // Erase the page + NRF_NVMC->ERASEPAGE = address; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } +} + + +void nrf_nvmc_write_byte(uint32_t address, uint8_t value) +{ + uint32_t byte_shift = address & (uint32_t)0x03; + uint32_t address32 = address & ~byte_shift; // Address to the word this byte is in. + uint32_t value32 = (*(uint32_t*)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3))); + value32 = value32 + ((uint32_t)value << (byte_shift << 3)); + + // Enable write. + NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos); + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + *(uint32_t*)address32 = value32; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos); + { + } +} + +void nrf_nvmc_write_word(uint32_t address, uint32_t value) +{ + // Enable write. + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){ + } + + *(uint32_t*)address = value; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){ + } + + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } +} + +void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes) +{ + uint32_t i; + for (i=0;iCONFIG = NVMC_CONFIG_WEN_Wen; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + for (i=0;iREADY == NVMC_READY_READY_Busy) + { + } + } + + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } +} + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_nvmc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_nvmc.h new file mode 100644 index 0000000000000000000000000000000000000000..2c4e047d26399c9b77c29a3c903ff02c335c987f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_nvmc.h @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief NMVC driver API. + */ + +#ifndef NRF_NVMC_H__ +#define NRF_NVMC_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup nrf_nvmc Non-volatile memory controller + * @{ + * @ingroup nrf_drivers + * @brief Driver for the NVMC peripheral. + * + * This driver allows writing to the non-volatile memory (NVM) regions + * of the chip. In order to write to NVM the controller must be powered + * on and the relevant page must be erased. + * + */ + + +/** + * @brief Erase a page in flash. This is required before writing to any + * address in the page. + * + * @param address Start address of the page. + */ +void nrf_nvmc_page_erase(uint32_t address); + + +/** + * @brief Write a single byte to flash. + * + * The function reads the word containing the byte, and then + * rewrites the entire word. + * + * @param address Address to write to. + * @param value Value to write. + */ +void nrf_nvmc_write_byte(uint32_t address , uint8_t value); + + +/** + * @brief Write a 32-bit word to flash. + * @param address Address to write to. + * @param value Value to write. + */ +void nrf_nvmc_write_word(uint32_t address, uint32_t value); + + +/** + * @brief Write consecutive bytes to flash. + * + * @param address Address to write to. + * @param src Pointer to data to copy from. + * @param num_bytes Number of bytes in src to write. + */ +void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes); + + +/** + * @brief Write consecutive words to flash. + * + * @param address Address to write to. + * @param src Pointer to data to copy from. + * @param num_words Number of bytes in src to write. + */ +void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words); + + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_NVMC_H__ +/** @} */ + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_pdm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_pdm.h new file mode 100644 index 0000000000000000000000000000000000000000..7937d756870c1d00686b0080b9f2647588931649 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_pdm.h @@ -0,0 +1,396 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_PDM_H_ +#define NRF_PDM_H_ + +/** + * @defgroup nrf_pdm_hal PDM HAL + * @{ + * @ingroup nrf_pdm + * + * @brief @tagAPI52 Hardware abstraction layer for accessing the pulse density modulation (PDM) peripheral. + */ + +#include +#include +#include "nrf.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define NRF_PDM_GAIN_MINIMUM 0x00 +#define NRF_PDM_GAIN_DEFAULT 0x28 +#define NRF_PDM_GAIN_MAXIMUM 0x50 + +typedef uint8_t nrf_pdm_gain_t; + + +/** + * @brief PDM tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_PDM_TASK_START = offsetof(NRF_PDM_Type, TASKS_START), ///< Starts continuous PDM transfer. + NRF_PDM_TASK_STOP = offsetof(NRF_PDM_Type, TASKS_STOP) ///< Stops PDM transfer. +} nrf_pdm_task_t; + + +/** + * @brief PDM events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_PDM_EVENT_STARTED = offsetof(NRF_PDM_Type, EVENTS_STARTED), ///< PDM transfer has started. + NRF_PDM_EVENT_STOPPED = offsetof(NRF_PDM_Type, EVENTS_STOPPED), ///< PDM transfer has finished. + NRF_PDM_EVENT_END = offsetof(NRF_PDM_Type, EVENTS_END) ///< The PDM has written the last sample specified by SAMPLE.MAXCNT (or the last sample after a STOP task has been received) to Data RAM. +} nrf_pdm_event_t; + + +/** + * @brief PDM interrupt masks. + */ +typedef enum +{ + NRF_PDM_INT_STARTED = PDM_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event. + NRF_PDM_INT_STOPPED = PDM_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event. + NRF_PDM_INT_END = PDM_INTENSET_END_Msk ///< Interrupt on EVENTS_END event. +} nrf_pdm_int_mask_t; + +/** + * @brief PDM clock frequency. + */ +typedef enum +{ + NRF_PDM_FREQ_1000K = PDM_PDMCLKCTRL_FREQ_1000K, ///< PDM_CLK = 1.000 MHz. + NRF_PDM_FREQ_1032K = PDM_PDMCLKCTRL_FREQ_Default, ///< PDM_CLK = 1.032 MHz. + NRF_PDM_FREQ_1067K = PDM_PDMCLKCTRL_FREQ_1067K ///< PDM_CLK = 1.067 MHz. +} nrf_pdm_freq_t; + + +/** + * @brief PDM operation mode. + */ +typedef enum +{ + NRF_PDM_MODE_STEREO = PDM_MODE_OPERATION_Stereo, ///< Sample and store one pair (Left + Right) of 16-bit samples per RAM word. + NRF_PDM_MODE_MONO = PDM_MODE_OPERATION_Mono ///< Sample and store two successive Left samples (16 bit each) per RAM word. +} nrf_pdm_mode_t; + + +/** + * @brief PDM sampling mode. + */ +typedef enum +{ + NRF_PDM_EDGE_LEFTFALLING = PDM_MODE_EDGE_LeftFalling, ///< Left (or mono) is sampled on falling edge of PDM_CLK. + NRF_PDM_EDGE_LEFTRISING = PDM_MODE_EDGE_LeftRising ///< Left (or mono) is sampled on rising edge of PDM_CLK. +} nrf_pdm_edge_t; + + +/** + * @brief Function for triggering a PDM task. + * + * @param[in] pdm_task PDM task. + */ +__STATIC_INLINE void nrf_pdm_task_trigger(nrf_pdm_task_t pdm_task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_task)) = 0x1UL; +} + + +/** + * @brief Function for getting the address of a PDM task register. + * + * @param[in] pdm_task PDM task. + * + * @return Address of the specified PDM task. + */ +__STATIC_INLINE uint32_t nrf_pdm_task_address_get(nrf_pdm_task_t pdm_task) +{ + return (uint32_t)((uint8_t *)NRF_PDM + (uint32_t)pdm_task); +} + + +/** + * @brief Function for getting the state of a PDM event. + * + * @param[in] pdm_event PDM event. + * + * @return State of the specified PDM event. + */ +__STATIC_INLINE bool nrf_pdm_event_check(nrf_pdm_event_t pdm_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event); +} + + +/** + * @brief Function for clearing a PDM event. + * + * @param[in] pdm_event PDM event. + */ +__STATIC_INLINE void nrf_pdm_event_clear(nrf_pdm_event_t pdm_event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event)); + (void)dummy; +#endif +} + + +/** + * @brief Function for getting the address of a PDM event register. + * + * @param[in] pdm_event PDM event. + * + * @return Address of the specified PDM event. + */ +__STATIC_INLINE volatile uint32_t * nrf_pdm_event_address_get(nrf_pdm_event_t pdm_event) +{ + return (volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event); +} + + +/** + * @brief Function for enabling PDM interrupts. + * + * @param[in] pdm_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_pdm_int_enable(uint32_t pdm_int_mask) +{ + NRF_PDM->INTENSET = pdm_int_mask; +} + + +/** + * @brief Function for retrieving the state of PDM interrupts. + * + * @param[in] pdm_int_mask Interrupts to check. + * + * @retval true If all specified interrupts are enabled. + * @retval false If at least one of the given interrupts is not enabled. + */ +__STATIC_INLINE bool nrf_pdm_int_enable_check(uint32_t pdm_int_mask) +{ + return (bool)(NRF_PDM->INTENSET & pdm_int_mask); +} + + +/** + * @brief Function for disabling interrupts. + * + * @param pdm_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_pdm_int_disable(uint32_t pdm_int_mask) +{ + NRF_PDM->INTENCLR = pdm_int_mask; +} + + +/** + * @brief Function for enabling the PDM peripheral. + * + * The PDM peripheral must be enabled before use. + */ +__STATIC_INLINE void nrf_pdm_enable(void) +{ + NRF_PDM->ENABLE = (PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos); +} + + +/** + * @brief Function for disabling the PDM peripheral. + */ +__STATIC_INLINE void nrf_pdm_disable(void) +{ + NRF_PDM->ENABLE = (PDM_ENABLE_ENABLE_Disabled << PDM_ENABLE_ENABLE_Pos); +} + + +/** + * @brief Function for checking if the PDM peripheral is enabled. + * + * @retval true If the PDM peripheral is enabled. + * @retval false If the PDM peripheral is not enabled. + */ +__STATIC_INLINE bool nrf_pdm_enable_check(void) +{ + return (NRF_PDM->ENABLE == (PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos)); +} + + +/** + * @brief Function for setting the PDM operation mode. + * + * @param[in] pdm_mode PDM operation mode. + * @param[in] pdm_edge PDM sampling mode. + */ +__STATIC_INLINE void nrf_pdm_mode_set(nrf_pdm_mode_t pdm_mode, nrf_pdm_edge_t pdm_edge) +{ + NRF_PDM->MODE = ((pdm_mode << PDM_MODE_OPERATION_Pos) & PDM_MODE_OPERATION_Msk) + | ((pdm_edge << PDM_MODE_EDGE_Pos) & PDM_MODE_EDGE_Msk); +} + + +/** + * @brief Function for getting the PDM operation mode. + * + * @param[out] p_pdm_mode PDM operation mode. + * @param[out] p_pdm_edge PDM sampling mode. + */ +__STATIC_INLINE void nrf_pdm_mode_get(nrf_pdm_mode_t * p_pdm_mode, nrf_pdm_edge_t * p_pdm_edge) +{ + uint32_t mode = NRF_PDM->MODE; + *p_pdm_mode = (nrf_pdm_mode_t)((mode & PDM_MODE_OPERATION_Msk ) >> PDM_MODE_OPERATION_Pos); + *p_pdm_edge = (nrf_pdm_edge_t)((mode & PDM_MODE_EDGE_Msk ) >> PDM_MODE_EDGE_Pos); +} + + +/** + * @brief Function for setting the PDM clock frequency. + * + * @param[in] pdm_freq PDM clock frequency. + */ +__STATIC_INLINE void nrf_pdm_clock_set(nrf_pdm_freq_t pdm_freq) +{ + NRF_PDM->PDMCLKCTRL = ((pdm_freq << PDM_PDMCLKCTRL_FREQ_Pos) & PDM_PDMCLKCTRL_FREQ_Msk); +} + + +/** + * @brief Function for getting the PDM clock frequency. + */ +__STATIC_INLINE nrf_pdm_freq_t nrf_pdm_clock_get(void) +{ + return (nrf_pdm_freq_t) ((NRF_PDM->PDMCLKCTRL << PDM_PDMCLKCTRL_FREQ_Pos) & PDM_PDMCLKCTRL_FREQ_Msk); +} + + +/** + * @brief Function for setting up the PDM pins. + * + * @param[in] psel_clk CLK pin number. + * @param[in] psel_din DIN pin number. + */ +__STATIC_INLINE void nrf_pdm_psel_connect(uint32_t psel_clk, uint32_t psel_din) +{ + NRF_PDM->PSEL.CLK = psel_clk; + NRF_PDM->PSEL.DIN = psel_din; +} + +/** + * @brief Function for disconnecting the PDM pins. + */ +__STATIC_INLINE void nrf_pdm_psel_disconnect() +{ + NRF_PDM->PSEL.CLK = ((PDM_PSEL_CLK_CONNECT_Disconnected << PDM_PSEL_CLK_CONNECT_Pos) + & PDM_PSEL_CLK_CONNECT_Msk); + NRF_PDM->PSEL.DIN = ((PDM_PSEL_DIN_CONNECT_Disconnected << PDM_PSEL_DIN_CONNECT_Pos) + & PDM_PSEL_DIN_CONNECT_Msk); +} + + +/** + * @brief Function for setting the PDM gain. + * + * @param[in] gain_l Left channel gain. + * @param[in] gain_r Right channel gain. + */ +__STATIC_INLINE void nrf_pdm_gain_set(nrf_pdm_gain_t gain_l, nrf_pdm_gain_t gain_r) +{ + NRF_PDM->GAINL = gain_l; + NRF_PDM->GAINR = gain_r; +} + + +/** + * @brief Function for getting the PDM gain. + * + * @param[out] p_gain_l Left channel gain. + * @param[out] p_gain_r Right channel gain. + */ +__STATIC_INLINE void nrf_pdm_gain_get(nrf_pdm_gain_t * p_gain_l, nrf_pdm_gain_t * p_gain_r) +{ + *p_gain_l = NRF_PDM->GAINL; + *p_gain_r = NRF_PDM->GAINR; +} + + +/** + * @brief Function for setting the PDM sample buffer. + * + * @param[in] p_buffer Pointer to the RAM address where samples should be written with EasyDMA. + * @param[in] num Number of samples to allocate memory for in EasyDMA mode. + * + * The amount of allocated RAM depends on the operation mode. + * - For stereo mode: N 32-bit words. + * - For mono mode: Ceil(N/2) 32-bit words. + */ +__STATIC_INLINE void nrf_pdm_buffer_set(uint32_t * p_buffer, uint32_t num) +{ + NRF_PDM->SAMPLE.PTR = (uint32_t)p_buffer; + NRF_PDM->SAMPLE.MAXCNT = num; +} + +/** + * @brief Function for getting the current PDM sample buffer address. + * + * @return Pointer to the current sample buffer. + */ +__STATIC_INLINE uint32_t * nrf_pdm_buffer_get() +{ + return (uint32_t *)NRF_PDM->SAMPLE.PTR; +} + + +/** + *@} + **/ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_PDM_H_ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_peripherals.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_peripherals.h new file mode 100644 index 0000000000000000000000000000000000000000..6c953b660a36fe3ce8feac342696aaaad2ba0be2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_peripherals.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_PERIPHERALS_H +#define NRF_PERIPHERALS_H + +/*lint ++flb "Enter library region */ + +#ifdef NRF51422 +#include "nrf51422_peripherals.h" +#endif + +#ifdef NRF51802 +#include "nrf51802_peripherals.h" +#endif + +#ifdef NRF51822 +#include "nrf51822_peripherals.h" +#endif + +#ifdef NRF52832_XXAA +#include "nrf52832_peripherals.h" +#endif + +#ifdef NRF52840_XXAA +#include "nrf52840_peripherals.h" +#endif + + +/*lint --flb "Leave library region" */ + +#endif /* NRF_PERIPHERALS_H */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_power.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_power.h new file mode 100644 index 0000000000000000000000000000000000000000..cb4da92345327ac2dd5104eb606131e90b65a328 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_power.h @@ -0,0 +1,1050 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef NRF_POWER_H__ +#define NRF_POWER_H__ + +/** + * @ingroup nrf_power + * @defgroup nrf_power_hal POWER HAL + * @{ + * + * Hardware access layer for (POWER) peripheral. + */ +#include "nrf.h" +#include "sdk_config.h" +#include "nordic_common.h" +#include "nrf_assert.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name The implemented functionality + * @{ + * + * Macros that defines functionality that is implemented into POWER peripheral. + */ +#if defined(POWER_INTENSET_SLEEPENTER_Msk) || defined(__SDK_DOXYGEN__) +/** + * @brief The fact that sleep events are present + * + * In some MCUs there is possibility to process sleep entering and exiting + * events. + */ +#define NRF_POWER_HAS_SLEEPEVT 1 +#else +#define NRF_POWER_HAS_SLEEPEVT 0 +#endif + +#if defined(POWER_RAM_POWER_S0POWER_Msk) || defined(__SDK_DOXYGEN__) +/** + * @brief The fact that RAMPOWER registers are present + * + * After nRF51, new way to manage RAM power was implemented. + * Special registers, one for every RAM block that makes it possible to + * power ON or OFF RAM segments and turn ON and OFF RAM retention in system OFF + * state. + */ +#define NRF_POWER_HAS_RAMPOWER_REGS 1 +#else +#define NRF_POWER_HAS_RAMPOWER_REGS 0 +#endif + +#if defined(POWER_POFCON_THRESHOLDVDDH_Msk) || defined(__SDK_DOXYGEN__) +/** + * @brief Auxiliary definition to mark the fact that VDDH is present + * + * This definition can be used in a code to decide if the part with VDDH + * related settings should be implemented. + */ +#define NRF_POWER_HAS_VDDH 1 +#else +#define NRF_POWER_HAS_VDDH 0 +#endif + +#if defined(POWER_USBREGSTATUS_VBUSDETECT_Msk) || defined(__SDK_DOXYGEN__) +/** + * @brief The fact that power module manages USB regulator + * + * In devices that have USB, power peripheral manages also connection + * detection and USB power regulator, that converts 5 V to 3.3 V + * used by USBD peripheral. + */ +#define NRF_POWER_HAS_USBREG 1 +#else +#define NRF_POWER_HAS_USBREG 0 +#endif +/** @} */ + +/* ------------------------------------------------------------------------------------------------ + * Begin of automatically generated part + * ------------------------------------------------------------------------------------------------ + */ + +/** + * @brief POWER tasks + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_POWER_TASK_CONSTLAT = offsetof(NRF_POWER_Type, TASKS_CONSTLAT), /**< Enable constant latency mode */ + NRF_POWER_TASK_LOWPWR = offsetof(NRF_POWER_Type, TASKS_LOWPWR ), /**< Enable low power mode (variable latency) */ +}nrf_power_task_t; /*lint -restore */ + +/** + * @brief POWER events + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_POWER_EVENT_POFWARN = offsetof(NRF_POWER_Type, EVENTS_POFWARN ), /**< Power failure warning */ +#if NRF_POWER_HAS_SLEEPEVT + NRF_POWER_EVENT_SLEEPENTER = offsetof(NRF_POWER_Type, EVENTS_SLEEPENTER ), /**< CPU entered WFI/WFE sleep */ + NRF_POWER_EVENT_SLEEPEXIT = offsetof(NRF_POWER_Type, EVENTS_SLEEPEXIT ), /**< CPU exited WFI/WFE sleep */ +#endif +#if NRF_POWER_HAS_USBREG + NRF_POWER_EVENT_USBDETECTED = offsetof(NRF_POWER_Type, EVENTS_USBDETECTED), /**< Voltage supply detected on VBUS */ + NRF_POWER_EVENT_USBREMOVED = offsetof(NRF_POWER_Type, EVENTS_USBREMOVED ), /**< Voltage supply removed from VBUS */ + NRF_POWER_EVENT_USBPWRRDY = offsetof(NRF_POWER_Type, EVENTS_USBPWRRDY ), /**< USB 3.3 V supply ready */ +#endif +}nrf_power_event_t; /*lint -restore */ + +/** + * @brief POWER interrupts + */ +typedef enum +{ + NRF_POWER_INT_POFWARN_MASK = POWER_INTENSET_POFWARN_Msk , /**< Write '1' to Enable interrupt for POFWARN event */ +#if NRF_POWER_HAS_SLEEPEVT + NRF_POWER_INT_SLEEPENTER_MASK = POWER_INTENSET_SLEEPENTER_Msk , /**< Write '1' to Enable interrupt for SLEEPENTER event */ + NRF_POWER_INT_SLEEPEXIT_MASK = POWER_INTENSET_SLEEPEXIT_Msk , /**< Write '1' to Enable interrupt for SLEEPEXIT event */ +#endif +#if NRF_POWER_HAS_USBREG + NRF_POWER_INT_USBDETECTED_MASK = POWER_INTENSET_USBDETECTED_Msk, /**< Write '1' to Enable interrupt for USBDETECTED event */ + NRF_POWER_INT_USBREMOVED_MASK = POWER_INTENSET_USBREMOVED_Msk , /**< Write '1' to Enable interrupt for USBREMOVED event */ + NRF_POWER_INT_USBPWRRDY_MASK = POWER_INTENSET_USBPWRRDY_Msk , /**< Write '1' to Enable interrupt for USBPWRRDY event */ +#endif +}nrf_power_int_mask_t; + +/** + * @brief Function for activating a specific POWER task. + * + * @param task Task. + */ +__STATIC_INLINE void nrf_power_task_trigger(nrf_power_task_t task); + +/** + * @brief Function for returning the address of a specific POWER task register. + * + * @param task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_power_task_address_get(nrf_power_task_t task); + +/** + * @brief Function for clearing a specific event. + * + * @param event Event. + */ +__STATIC_INLINE void nrf_power_event_clear(nrf_power_event_t event); + +/** + * @brief Function for returning the state of a specific event. + * + * @param event Event. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_power_event_check(nrf_power_event_t event); + +/** + * @brief Function for getting and clearing the state of specific event + * + * This function checks the state of the event and clears it. + * + * @param event Event. + * + * @retval true If the event was set. + * @retval false If the event was not set. + */ +__STATIC_INLINE bool nrf_power_event_get_and_clear(nrf_power_event_t event); + +/** + * @brief Function for returning the address of a specific POWER event register. + * + * @param event Event. + * + * @return Address. + */ +__STATIC_INLINE uint32_t nrf_power_event_address_get(nrf_power_event_t event); + +/** + * @brief Function for enabling selected interrupts. + * + * @param int_mask Interrupts mask. + */ +__STATIC_INLINE void nrf_power_int_enable(uint32_t int_mask); + +/** + * @brief Function for retrieving the state of selected interrupts. + * + * @param int_mask Interrupts mask. + * + * @retval true If any of selected interrupts is enabled. + * @retval false If none of selected interrupts is enabled. + */ +__STATIC_INLINE bool nrf_power_int_enable_check(uint32_t int_mask); + +/** + * @brief Function for retrieving the information about enabled interrupts. + * + * @return The flags of enabled interrupts. + */ +__STATIC_INLINE uint32_t nrf_power_int_enable_get(void); + +/** + * @brief Function for disabling selected interrupts. + * + * @param int_mask Interrupts mask. + */ +__STATIC_INLINE void nrf_power_int_disable(uint32_t int_mask); + + +/** @} */ /* End of nrf_power_hal */ + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +/* ------------------------------------------------------------------------------------------------ + * Internal functions + */ + +/** + * @internal + * @brief Internal function for getting task/event register address + * + * @oaram offset Offset of the register from the instance beginning + * + * @attention offset has to be modulo 4 value. In other case we can get hardware fault. + * @return Pointer to the register + */ +__STATIC_INLINE volatile uint32_t * nrf_power_regptr_get(uint32_t offset) +{ + return (volatile uint32_t *)(((uint8_t *)NRF_POWER) + (uint32_t)offset); +} + +/** + * @internal + * @brief Internal function for getting task/event register address - constant version + * + * @oaram offset Offset of the register from the instance beginning + * + * @attention offset has to be modulo 4 value. In other case we can get hardware fault. + * @return Pointer to the register + */ +__STATIC_INLINE volatile const uint32_t * nrf_power_regptr_get_c( + uint32_t offset) +{ + return (volatile const uint32_t *)(((uint8_t *)NRF_POWER) + + (uint32_t)offset); +} + +/* ------------------------------------------------------------------------------------------------ + * Interface functions definitions + */ + +void nrf_power_task_trigger(nrf_power_task_t task) +{ + *(nrf_power_regptr_get((uint32_t)task)) = 1UL; +} + +uint32_t nrf_power_task_address_get(nrf_power_task_t task) +{ + return (uint32_t)nrf_power_regptr_get_c((uint32_t)task); +} + +void nrf_power_event_clear(nrf_power_event_t event) +{ + *(nrf_power_regptr_get((uint32_t)event)) = 0UL; +} + +bool nrf_power_event_check(nrf_power_event_t event) +{ + return (bool)*nrf_power_regptr_get_c((uint32_t)event); +} + +bool nrf_power_event_get_and_clear(nrf_power_event_t event) +{ + bool ret = nrf_power_event_check(event); + if(ret) + { + nrf_power_event_clear(event); + } + return ret; +} + +uint32_t nrf_power_event_address_get(nrf_power_event_t event) +{ + return (uint32_t)nrf_power_regptr_get_c((uint32_t)event); +} + +void nrf_power_int_enable(uint32_t int_mask) +{ + NRF_POWER->INTENSET = int_mask; +} + +bool nrf_power_int_enable_check(uint32_t int_mask) +{ + return !!(NRF_POWER->INTENSET & int_mask); +} + +uint32_t nrf_power_int_enable_get(void) +{ + return NRF_POWER->INTENSET; +} + +void nrf_power_int_disable(uint32_t int_mask) +{ + NRF_POWER->INTENCLR = int_mask; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +/* ------------------------------------------------------------------------------------------------ + * End of automatically generated part + * ------------------------------------------------------------------------------------------------ + */ +/** + * @ingroup nrf_power_hal + * @{ + */ + +/** + * @brief Reset reason + */ +typedef enum +{ + NRF_POWER_RESETREAS_RESETPIN_MASK = POWER_RESETREAS_RESETPIN_Msk, /*!< Bit mask of RESETPIN field. *///!< NRF_POWER_RESETREAS_RESETPIN_MASK + NRF_POWER_RESETREAS_DOG_MASK = POWER_RESETREAS_DOG_Msk , /*!< Bit mask of DOG field. */ //!< NRF_POWER_RESETREAS_DOG_MASK + NRF_POWER_RESETREAS_SREQ_MASK = POWER_RESETREAS_SREQ_Msk , /*!< Bit mask of SREQ field. */ //!< NRF_POWER_RESETREAS_SREQ_MASK + NRF_POWER_RESETREAS_LOCKUP_MASK = POWER_RESETREAS_LOCKUP_Msk , /*!< Bit mask of LOCKUP field. */ //!< NRF_POWER_RESETREAS_LOCKUP_MASK + NRF_POWER_RESETREAS_OFF_MASK = POWER_RESETREAS_OFF_Msk , /*!< Bit mask of OFF field. */ //!< NRF_POWER_RESETREAS_OFF_MASK + NRF_POWER_RESETREAS_LPCOMP_MASK = POWER_RESETREAS_LPCOMP_Msk , /*!< Bit mask of LPCOMP field. */ //!< NRF_POWER_RESETREAS_LPCOMP_MASK + NRF_POWER_RESETREAS_DIF_MASK = POWER_RESETREAS_DIF_Msk , /*!< Bit mask of DIF field. */ //!< NRF_POWER_RESETREAS_DIF_MASK +#if defined(POWER_RESETREAS_NFC_Msk) || defined(__SDK_DOXYGEN__) + NRF_POWER_RESETREAS_NFC_MASK = POWER_RESETREAS_NFC_Msk , /*!< Bit mask of NFC field. */ +#endif +#if defined(POWER_RESETREAS_VBUS_Msk) || defined(__SDK_DOXYGEN__) + NRF_POWER_RESETREAS_VBUS_MASK = POWER_RESETREAS_VBUS_Msk , /*!< Bit mask of VBUS field. */ +#endif +}nrf_power_resetreas_mask_t; + +#if NRF_POWER_HAS_USBREG +/** + * @brief USBREGSTATUS register bit masks + * + * @sa nrf_power_usbregstatus_get + */ +typedef enum +{ + NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK = POWER_USBREGSTATUS_VBUSDETECT_Msk, /**< USB detected or removed */ + NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK = POWER_USBREGSTATUS_OUTPUTRDY_Msk /**< USB 3.3 V supply ready */ +}nrf_power_usbregstatus_mask_t; +#endif + +/** + * @brief RAM blocks numbers + * + * @sa nrf_power_ramblock_mask_t + * @note + * Ram blocks has to been used in nrf51. + * In new CPU ram is divided into segments and this functionality is depreciated. + * For the newer MCU see the PS for mapping between internal RAM and RAM blocks, + * because this mapping is not 1:1, and functions related to old style blocks + * should not be used. + */ +typedef enum +{ + NRF_POWER_RAMBLOCK0 = POWER_RAMSTATUS_RAMBLOCK0_Pos, + NRF_POWER_RAMBLOCK1 = POWER_RAMSTATUS_RAMBLOCK1_Pos, + NRF_POWER_RAMBLOCK2 = POWER_RAMSTATUS_RAMBLOCK2_Pos, + NRF_POWER_RAMBLOCK3 = POWER_RAMSTATUS_RAMBLOCK3_Pos +}nrf_power_ramblock_t; + +/** + * @brief RAM blocks masks + * + * @sa nrf_power_ramblock_t + */ +typedef enum +{ + NRF_POWER_RAMBLOCK0_MASK = POWER_RAMSTATUS_RAMBLOCK0_Msk, + NRF_POWER_RAMBLOCK1_MASK = POWER_RAMSTATUS_RAMBLOCK1_Msk, + NRF_POWER_RAMBLOCK2_MASK = POWER_RAMSTATUS_RAMBLOCK2_Msk, + NRF_POWER_RAMBLOCK3_MASK = POWER_RAMSTATUS_RAMBLOCK3_Msk +}nrf_power_ramblock_mask_t; + +/** + * @brief RAM power state position of the bits + * + * @sa nrf_power_onoffram_mask_t + */ +typedef enum +{ + NRF_POWER_ONRAM0, /**< Keep RAM block 0 on or off in system ON Mode */ + NRF_POWER_OFFRAM0, /**< Keep retention on RAM block 0 when RAM block is switched off */ + NRF_POWER_ONRAM1, /**< Keep RAM block 1 on or off in system ON Mode */ + NRF_POWER_OFFRAM1, /**< Keep retention on RAM block 1 when RAM block is switched off */ + NRF_POWER_ONRAM2, /**< Keep RAM block 2 on or off in system ON Mode */ + NRF_POWER_OFFRAM2, /**< Keep retention on RAM block 2 when RAM block is switched off */ + NRF_POWER_ONRAM3, /**< Keep RAM block 3 on or off in system ON Mode */ + NRF_POWER_OFFRAM3, /**< Keep retention on RAM block 3 when RAM block is switched off */ +}nrf_power_onoffram_t; + +/** + * @brief RAM power state bit masks + * + * @sa nrf_power_onoffram_t + */ +typedef enum +{ + NRF_POWER_ONRAM0_MASK = 1U << NRF_POWER_ONRAM0, /**< Keep RAM block 0 on or off in system ON Mode */ + NRF_POWER_OFFRAM0_MASK = 1U << NRF_POWER_OFFRAM0, /**< Keep retention on RAM block 0 when RAM block is switched off */ + NRF_POWER_ONRAM1_MASK = 1U << NRF_POWER_ONRAM1, /**< Keep RAM block 1 on or off in system ON Mode */ + NRF_POWER_OFFRAM1_MASK = 1U << NRF_POWER_OFFRAM1, /**< Keep retention on RAM block 1 when RAM block is switched off */ + NRF_POWER_ONRAM2_MASK = 1U << NRF_POWER_ONRAM2, /**< Keep RAM block 2 on or off in system ON Mode */ + NRF_POWER_OFFRAM2_MASK = 1U << NRF_POWER_OFFRAM2, /**< Keep retention on RAM block 2 when RAM block is switched off */ + NRF_POWER_ONRAM3_MASK = 1U << NRF_POWER_ONRAM3, /**< Keep RAM block 3 on or off in system ON Mode */ + NRF_POWER_OFFRAM3_MASK = 1U << NRF_POWER_OFFRAM3, /**< Keep retention on RAM block 3 when RAM block is switched off */ +}nrf_power_onoffram_mask_t; + +/** + * @brief Power failure comparator thresholds + */ +typedef enum +{ + NRF_POWER_POFTHR_V21 = POWER_POFCON_THRESHOLD_V21, /**< Set threshold to 2.1 V */ + NRF_POWER_POFTHR_V23 = POWER_POFCON_THRESHOLD_V23, /**< Set threshold to 2.3 V */ + NRF_POWER_POFTHR_V25 = POWER_POFCON_THRESHOLD_V25, /**< Set threshold to 2.5 V */ + NRF_POWER_POFTHR_V27 = POWER_POFCON_THRESHOLD_V27, /**< Set threshold to 2.7 V */ +#if defined(POWER_POFCON_THRESHOLD_V17) || defined(__SDK_DOXYGEN__) + NRF_POWER_POFTHR_V17 = POWER_POFCON_THRESHOLD_V17, /**< Set threshold to 1.7 V */ + NRF_POWER_POFTHR_V18 = POWER_POFCON_THRESHOLD_V18, /**< Set threshold to 1.8 V */ + NRF_POWER_POFTHR_V19 = POWER_POFCON_THRESHOLD_V19, /**< Set threshold to 1.9 V */ + NRF_POWER_POFTHR_V20 = POWER_POFCON_THRESHOLD_V20, /**< Set threshold to 2.0 V */ + NRF_POWER_POFTHR_V22 = POWER_POFCON_THRESHOLD_V22, /**< Set threshold to 2.2 V */ + NRF_POWER_POFTHR_V24 = POWER_POFCON_THRESHOLD_V24, /**< Set threshold to 2.4 V */ + NRF_POWER_POFTHR_V26 = POWER_POFCON_THRESHOLD_V26, /**< Set threshold to 2.6 V */ + NRF_POWER_POFTHR_V28 = POWER_POFCON_THRESHOLD_V28, /**< Set threshold to 2.8 V */ +#endif +}nrf_power_pof_thr_t; + +#if NRF_POWER_HAS_VDDH +/** + * @brief Power failure comparator thresholds for VDDH + */ +typedef enum +{ + NRF_POWER_POFTHRVDDH_V27 = POWER_POFCON_THRESHOLDVDDH_V27, /**< Set threshold to 2.7 V */ + NRF_POWER_POFTHRVDDH_V28 = POWER_POFCON_THRESHOLDVDDH_V28, /**< Set threshold to 2.8 V */ + NRF_POWER_POFTHRVDDH_V29 = POWER_POFCON_THRESHOLDVDDH_V29, /**< Set threshold to 2.9 V */ + NRF_POWER_POFTHRVDDH_V30 = POWER_POFCON_THRESHOLDVDDH_V30, /**< Set threshold to 3.0 V */ + NRF_POWER_POFTHRVDDH_V31 = POWER_POFCON_THRESHOLDVDDH_V31, /**< Set threshold to 3.1 V */ + NRF_POWER_POFTHRVDDH_V32 = POWER_POFCON_THRESHOLDVDDH_V32, /**< Set threshold to 3.2 V */ + NRF_POWER_POFTHRVDDH_V33 = POWER_POFCON_THRESHOLDVDDH_V33, /**< Set threshold to 3.3 V */ + NRF_POWER_POFTHRVDDH_V34 = POWER_POFCON_THRESHOLDVDDH_V34, /**< Set threshold to 3.4 V */ + NRF_POWER_POFTHRVDDH_V35 = POWER_POFCON_THRESHOLDVDDH_V35, /**< Set threshold to 3.5 V */ + NRF_POWER_POFTHRVDDH_V36 = POWER_POFCON_THRESHOLDVDDH_V36, /**< Set threshold to 3.6 V */ + NRF_POWER_POFTHRVDDH_V37 = POWER_POFCON_THRESHOLDVDDH_V37, /**< Set threshold to 3.7 V */ + NRF_POWER_POFTHRVDDH_V38 = POWER_POFCON_THRESHOLDVDDH_V38, /**< Set threshold to 3.8 V */ + NRF_POWER_POFTHRVDDH_V39 = POWER_POFCON_THRESHOLDVDDH_V39, /**< Set threshold to 3.9 V */ + NRF_POWER_POFTHRVDDH_V40 = POWER_POFCON_THRESHOLDVDDH_V40, /**< Set threshold to 4.0 V */ + NRF_POWER_POFTHRVDDH_V41 = POWER_POFCON_THRESHOLDVDDH_V41, /**< Set threshold to 4.1 V */ + NRF_POWER_POFTHRVDDH_V42 = POWER_POFCON_THRESHOLDVDDH_V42, /**< Set threshold to 4.2 V */ +}nrf_power_pof_thrvddh_t; + +/** + * @brief Main regulator status + */ +typedef enum +{ + NRF_POWER_MAINREGSTATUS_NORMAL = POWER_MAINREGSTATUS_MAINREGSTATUS_Normal, /**< Normal voltage mode. Voltage supplied on VDD. */ + NRF_POWER_MAINREGSTATUS_HIGH = POWER_MAINREGSTATUS_MAINREGSTATUS_High /**< High voltage mode. Voltage supplied on VDDH. */ +}nrf_power_mainregstatus_t; + +#endif /* NRF_POWER_HAS_VDDH */ + +#if NRF_POWER_HAS_RAMPOWER_REGS +/** + * @brief Bit positions for RAMPOWER register + * + * All possible bits described, even if they are not used in selected MCU. + */ +typedef enum +{ + /** Keep RAM section S0 ON in System ON mode */ + NRF_POWER_RAMPOWER_S0POWER = POWER_RAM_POWER_S0POWER_Pos, + NRF_POWER_RAMPOWER_S1POWER, /**< Keep RAM section S1 ON in System ON mode */ + NRF_POWER_RAMPOWER_S2POWER, /**< Keep RAM section S2 ON in System ON mode */ + NRF_POWER_RAMPOWER_S3POWER, /**< Keep RAM section S3 ON in System ON mode */ + NRF_POWER_RAMPOWER_S4POWER, /**< Keep RAM section S4 ON in System ON mode */ + NRF_POWER_RAMPOWER_S5POWER, /**< Keep RAM section S5 ON in System ON mode */ + NRF_POWER_RAMPOWER_S6POWER, /**< Keep RAM section S6 ON in System ON mode */ + NRF_POWER_RAMPOWER_S7POWER, /**< Keep RAM section S7 ON in System ON mode */ + NRF_POWER_RAMPOWER_S8POWER, /**< Keep RAM section S8 ON in System ON mode */ + NRF_POWER_RAMPOWER_S9POWER, /**< Keep RAM section S9 ON in System ON mode */ + NRF_POWER_RAMPOWER_S10POWER, /**< Keep RAM section S10 ON in System ON mode */ + NRF_POWER_RAMPOWER_S11POWER, /**< Keep RAM section S11 ON in System ON mode */ + NRF_POWER_RAMPOWER_S12POWER, /**< Keep RAM section S12 ON in System ON mode */ + NRF_POWER_RAMPOWER_S13POWER, /**< Keep RAM section S13 ON in System ON mode */ + NRF_POWER_RAMPOWER_S14POWER, /**< Keep RAM section S14 ON in System ON mode */ + NRF_POWER_RAMPOWER_S15POWER, /**< Keep RAM section S15 ON in System ON mode */ + + /** Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S0RETENTION = POWER_RAM_POWER_S0RETENTION_Pos, + NRF_POWER_RAMPOWER_S1RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S2RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S3RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S4RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S5RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S6RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S7RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S8RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S9RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S10RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S11RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S12RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S13RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S14RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S15RETENTION, /**< Keep section retention in OFF mode when section is OFF */ +}nrf_power_rampower_t; + +#if defined ( __CC_ARM ) +#pragma push +#pragma diag_suppress 66 +#endif +/** + * @brief Bit masks for RAMPOWER register + * + * All possible bits described, even if they are not used in selected MCU. + */ +typedef enum +{ + NRF_POWER_RAMPOWER_S0POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S0POWER , + NRF_POWER_RAMPOWER_S1POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S1POWER , + NRF_POWER_RAMPOWER_S2POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S2POWER , + NRF_POWER_RAMPOWER_S3POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S3POWER , + NRF_POWER_RAMPOWER_S4POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S4POWER , + NRF_POWER_RAMPOWER_S5POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S5POWER , + NRF_POWER_RAMPOWER_S7POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S7POWER , + NRF_POWER_RAMPOWER_S8POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S8POWER , + NRF_POWER_RAMPOWER_S9POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S9POWER , + NRF_POWER_RAMPOWER_S10POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S10POWER, + NRF_POWER_RAMPOWER_S11POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S11POWER, + NRF_POWER_RAMPOWER_S12POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S12POWER, + NRF_POWER_RAMPOWER_S13POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S13POWER, + NRF_POWER_RAMPOWER_S14POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S14POWER, + NRF_POWER_RAMPOWER_S15POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S15POWER, + + NRF_POWER_RAMPOWER_S0RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S0RETENTION , + NRF_POWER_RAMPOWER_S1RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S1RETENTION , + NRF_POWER_RAMPOWER_S2RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S2RETENTION , + NRF_POWER_RAMPOWER_S3RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S3RETENTION , + NRF_POWER_RAMPOWER_S4RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S4RETENTION , + NRF_POWER_RAMPOWER_S5RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S5RETENTION , + NRF_POWER_RAMPOWER_S7RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S7RETENTION , + NRF_POWER_RAMPOWER_S8RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S8RETENTION , + NRF_POWER_RAMPOWER_S9RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S9RETENTION , + NRF_POWER_RAMPOWER_S10RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S10RETENTION, + NRF_POWER_RAMPOWER_S11RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S11RETENTION, + NRF_POWER_RAMPOWER_S12RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S12RETENTION, + NRF_POWER_RAMPOWER_S13RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S13RETENTION, + NRF_POWER_RAMPOWER_S14RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S14RETENTION, + NRF_POWER_RAMPOWER_S15RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S15RETENTION, +}nrf_power_rampower_mask_t; +#if defined ( __CC_ARM ) +#pragma pop +#endif +#endif /* NRF_POWER_HAS_RAMPOWER_REGS */ + + +/** + * @brief Get reset reason mask + * + * Function returns the reset reason. + * Unless cleared, the RESETREAS register is cumulative. + * A field is cleared by writing '1' to it (see @ref nrf_power_resetreas_clear). + * If none of the reset sources are flagged, + * this indicates that the chip was reset from the on-chip reset generator, + * which indicates a power-on-reset or a brown out reset. + * + * @return The mask of reset reasons constructed with @ref nrf_power_resetreas_mask_t. + */ +__STATIC_INLINE uint32_t nrf_power_resetreas_get(void); + +/** + * @brief Clear selected reset reason field + * + * Function clears selected reset reason fields. + * + * @param[in] mask The mask constructed from @ref nrf_power_resetreas_mask_t enumerator values. + * @sa nrf_power_resetreas_get + */ +__STATIC_INLINE void nrf_power_resetreas_clear(uint32_t mask); + +/** + * @brief Get RAMSTATUS register + * + * Returns the masks of RAM blocks that are powered ON. + * + * @return Value with bits sets according to masks in @ref nrf_power_ramblock_mask_t. + */ +__STATIC_INLINE uint32_t nrf_power_ramstatus_get(void); + +/** + * @brief Go to system OFF + * + * This function puts the CPU into system off mode. + * The only way to wake up the CPU is by reset. + * + * @note This function never returns. + */ +__STATIC_INLINE void nrf_power_system_off(void); + +/** + * @brief Set power failure comparator configuration + * + * Sets power failure comparator threshold and enable/disable flag. + * + * @param enabled Set to true if power failure comparator should be enabled. + * @param thr Set the voltage threshold value. + * + * @note + * If VDDH settings is present in the device, this function would + * clear it settings (set to the lowest voltage). + * Use @ref nrf_power_pofcon_vddh_set function to set new value. + */ +__STATIC_INLINE void nrf_power_pofcon_set(bool enabled, nrf_power_pof_thr_t thr); + +/** + * @brief Get power failure comparator configuration + * + * Get power failure comparator threshold and enable bit. + * + * @param[out] p_enabled Function would set this boolean variable to true + * if power failure comparator is enabled. + * The pointer can be NULL if we do not need this information. + * @return Threshold setting for power failure comparator + */ +__STATIC_INLINE nrf_power_pof_thr_t nrf_power_pofcon_get(bool * p_enabled); + +#if NRF_POWER_HAS_VDDH +/** + * @brief Set VDDH power failure comparator threshold + * + * @param thr Threshold to be set + */ +__STATIC_INLINE void nrf_power_pofcon_vddh_set(nrf_power_pof_thrvddh_t thr); + +/** + * @brief Get VDDH power failure comparator threshold + * + * @return VDDH threshold currently configured + */ +__STATIC_INLINE nrf_power_pof_thrvddh_t nrf_power_pofcon_vddh_get(void); +#endif + +/** + * @brief Set general purpose retention register + * + * @param val Value to be set in the register + */ +__STATIC_INLINE void nrf_power_gpregret_set(uint8_t val); + +/** + * @brief Get general purpose retention register + * + * @return The value from the register + */ +__STATIC_INLINE uint8_t nrf_power_gpregret_get(void); + +#if defined(POWER_GPREGRET2_GPREGRET_Msk) || defined(__SDK_DOXYGEN__) +/** + * @brief Set general purpose retention register 2 + * + * @param val Value to be set in the register + * @note This register is not available in nrf51 MCU family + */ +__STATIC_INLINE void nrf_power_gpregret2_set(uint8_t val); + +/** + * @brief Get general purpose retention register 2 + * + * @return The value from the register + * @note This register is not available in all MCUs. + */ +__STATIC_INLINE uint8_t nrf_power_gpregret2_get(void); +#endif + +/** + * @brief Enable or disable DCDC converter + * + * @param enable Set true to enable or false to disable DCDC converter. + * + * @note + * If the device consist of high voltage power input (VDDH) this setting + * would relate to the converter on low voltage side (1.3 V output). + */ +__STATIC_INLINE void nrf_power_dcdcen_set(bool enable); + +/** + * @brief Get the state of DCDC converter + * + * @retval true Converter is enabled + * @retval false Converter is disabled + * + * @note + * If the device consist of high voltage power input (VDDH) this setting + * would relate to the converter on low voltage side (1.3 V output). + */ +__STATIC_INLINE bool nrf_power_dcdcen_get(void); + +#if NRF_POWER_HAS_RAMPOWER_REGS +/** + * @brief Turn ON sections in selected RAM block. + * + * This function turns ON sections in block and also block retention. + * + * @sa nrf_power_rampower_mask_t + * @sa nrf_power_rampower_mask_off + * + * @param block RAM block index. + * @param section_mask Mask of the sections created by merging + * @ref nrf_power_rampower_mask_t flags. + */ +__STATIC_INLINE void nrf_power_rampower_mask_on(uint8_t block, uint32_t section_mask); + +/** + * @brief Turn ON sections in selected RAM block. + * + * This function turns OFF sections in block and also block retention. + * + * @sa nrf_power_rampower_mask_t + * @sa nrf_power_rampower_mask_off + * + * @param block RAM block index. + * @param section_mask Mask of the sections created by merging + * @ref nrf_power_rampower_mask_t flags. + */ +__STATIC_INLINE void nrf_power_rampower_mask_off(uint8_t block, uint32_t section_mask); + +/** + * @brief Get the mask of ON and retention sections in selected RAM block. + * + * @param block RAM block index. + * @return Mask of sections state composed from @ref nrf_power_rampower_mask_t flags. + */ +__STATIC_INLINE uint32_t nrf_power_rampower_mask_get(uint8_t block); +#endif /* NRF_POWER_HAS_RAMPOWER_REGS */ + +#if NRF_POWER_HAS_VDDH +/** + * @brief Enable of disable DCDC converter on VDDH + * + * @param enable Set true to enable or false to disable DCDC converter. + */ +__STATIC_INLINE void nrf_power_dcdcen_vddh_set(bool enable); + +/** + * @brief Get the state of DCDC converter on VDDH + * + * @retval true Converter is enabled + * @retval false Converter is disabled + */ +__STATIC_INLINE bool nrf_power_dcdcen_vddh_get(void); + +/** + * @brief Get main supply status + * + * @return Current main supply status + */ +__STATIC_INLINE nrf_power_mainregstatus_t nrf_power_mainregstatus_get(void); +#endif /* NRF_POWER_HAS_VDDH */ + +#if NRF_POWER_HAS_USBREG +/** + * + * @return Get the whole USBREGSTATUS register + * + * @return The USBREGSTATUS register value. + * Use @ref nrf_power_usbregstatus_mask_t values for bit masking. + * + * @sa nrf_power_usbregstatus_vbusdet_get + * @sa nrf_power_usbregstatus_outrdy_get + */ +__STATIC_INLINE uint32_t nrf_power_usbregstatus_get(void); + +/** + * @brief VBUS input detection status + * + * USBDETECTED and USBREMOVED events are derived from this information + * + * @retval false VBUS voltage below valid threshold + * @retval true VBUS voltage above valid threshold + * + * @sa nrf_power_usbregstatus_get + */ +__STATIC_INLINE bool nrf_power_usbregstatus_vbusdet_get(void); + +/** + * @brief USB supply output settling time elapsed + * + * @retval false USBREG output settling time not elapsed + * @retval true USBREG output settling time elapsed + * (same information as USBPWRRDY event) + * + * @sa nrf_power_usbregstatus_get + */ +__STATIC_INLINE bool nrf_power_usbregstatus_outrdy_get(void); +#endif /* NRF_POWER_HAS_USBREG */ + +/** @} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t nrf_power_resetreas_get(void) +{ + return NRF_POWER->RESETREAS; +} + +__STATIC_INLINE void nrf_power_resetreas_clear(uint32_t mask) +{ + NRF_POWER->RESETREAS = mask; +} + +__STATIC_INLINE uint32_t nrf_power_ramstatus_get(void) +{ + return NRF_POWER->RAMSTATUS; +} + +__STATIC_INLINE void nrf_power_system_off(void) +{ + NRF_POWER->SYSTEMOFF = POWER_SYSTEMOFF_SYSTEMOFF_Enter; + /* Solution for simulated System OFF in debug mode. + * Also, because dead loop is placed here, we do not need to implement + * any barriers here. */ + while(true) + { + /* Intentionally empty - we would be here only in debug mode */ + } +} + +__STATIC_INLINE void nrf_power_pofcon_set(bool enabled, nrf_power_pof_thr_t thr) +{ + ASSERT(thr == (thr & (POWER_POFCON_THRESHOLD_Msk >> POWER_POFCON_THRESHOLD_Pos))); +#if NRF_POWER_HAS_VDDH + uint32_t pofcon = NRF_POWER->POFCON; + pofcon &= ~(POWER_POFCON_THRESHOLD_Msk | POWER_POFCON_POF_Msk); + pofcon |= +#else /* NRF_POWER_HAS_VDDH */ + NRF_POWER->POFCON = +#endif + (((uint32_t)thr) << POWER_POFCON_THRESHOLD_Pos) | + (enabled ? + (POWER_POFCON_POF_Enabled << POWER_POFCON_POF_Pos) + : + (POWER_POFCON_POF_Disabled << POWER_POFCON_POF_Pos)); +#if NRF_POWER_HAS_VDDH + NRF_POWER->POFCON = pofcon; +#endif +} + +__STATIC_INLINE nrf_power_pof_thr_t nrf_power_pofcon_get(bool * p_enabled) +{ + uint32_t pofcon = NRF_POWER->POFCON; + if(NULL != p_enabled) + { + (*p_enabled) = ((pofcon & POWER_POFCON_POF_Msk) >> POWER_POFCON_POF_Pos) + == POWER_POFCON_POF_Enabled; + } + return (nrf_power_pof_thr_t)((pofcon & POWER_POFCON_THRESHOLD_Msk) >> + POWER_POFCON_THRESHOLD_Pos); +} + +#if NRF_POWER_HAS_VDDH +__STATIC_INLINE void nrf_power_pofcon_vddh_set(nrf_power_pof_thrvddh_t thr) +{ + ASSERT(thr == (thr & (POWER_POFCON_THRESHOLDVDDH_Msk >> POWER_POFCON_THRESHOLDVDDH_Pos))); + uint32_t pofcon = NRF_POWER->POFCON; + pofcon &= ~POWER_POFCON_THRESHOLDVDDH_Msk; + pofcon |= (((uint32_t)thr) << POWER_POFCON_THRESHOLDVDDH_Pos); + NRF_POWER->POFCON = pofcon; +} + +__STATIC_INLINE nrf_power_pof_thrvddh_t nrf_power_pofcon_vddh_get(void) +{ + return (nrf_power_pof_thrvddh_t)((NRF_POWER->POFCON & + POWER_POFCON_THRESHOLDVDDH_Msk) >> POWER_POFCON_THRESHOLDVDDH_Pos); +} +#endif /* NRF_POWER_HAS_VDDH */ + +__STATIC_INLINE void nrf_power_gpregret_set(uint8_t val) +{ + NRF_POWER->GPREGRET = val; +} + +__STATIC_INLINE uint8_t nrf_power_gpregret_get(void) +{ + return NRF_POWER->GPREGRET; +} + +#if defined(POWER_GPREGRET2_GPREGRET_Msk) || defined(__SDK_DOXYGEN__) +void nrf_power_gpregret2_set(uint8_t val) +{ + NRF_POWER->GPREGRET2 = val; +} + +__STATIC_INLINE uint8_t nrf_power_gpregret2_get(void) +{ + return NRF_POWER->GPREGRET2; +} +#endif + +__STATIC_INLINE void nrf_power_dcdcen_set(bool enable) +{ +#if NRF_POWER_HAS_VDDH + NRF_POWER->DCDCEN = (enable ? + POWER_DCDCEN_DCDCEN_Enabled : POWER_DCDCEN_DCDCEN_Disabled) << + POWER_DCDCEN_DCDCEN_Pos; +#else + NRF_POWER->DCDCEN = (enable ? + POWER_DCDCEN_DCDCEN_Enabled : POWER_DCDCEN_DCDCEN_Disabled) << + POWER_DCDCEN_DCDCEN_Pos; +#endif +} + +__STATIC_INLINE bool nrf_power_dcdcen_get(void) +{ +#if NRF_POWER_HAS_VDDH + return (NRF_POWER->DCDCEN & POWER_DCDCEN_DCDCEN_Msk) + == + (POWER_DCDCEN_DCDCEN_Enabled << POWER_DCDCEN_DCDCEN_Pos); +#else + return (NRF_POWER->DCDCEN & POWER_DCDCEN_DCDCEN_Msk) + == + (POWER_DCDCEN_DCDCEN_Enabled << POWER_DCDCEN_DCDCEN_Pos); +#endif +} + +#if NRF_POWER_HAS_RAMPOWER_REGS +__STATIC_INLINE void nrf_power_rampower_mask_on(uint8_t block, uint32_t section_mask) +{ + ASSERT(block < ARRAY_SIZE(NRF_POWER->RAM)); + NRF_POWER->RAM[block].POWERSET = section_mask; +} + +__STATIC_INLINE void nrf_power_rampower_mask_off(uint8_t block, uint32_t section_mask) +{ + ASSERT(block < ARRAY_SIZE(NRF_POWER->RAM)); + NRF_POWER->RAM[block].POWERCLR = section_mask; +} + +__STATIC_INLINE uint32_t nrf_power_rampower_mask_get(uint8_t block) +{ + ASSERT(block < ARRAY_SIZE(NRF_POWER->RAM)); + return NRF_POWER->RAM[block].POWER; +} +#endif /* NRF_POWER_HAS_RAMPOWER_REGS */ + +#if NRF_POWER_HAS_VDDH +__STATIC_INLINE void nrf_power_dcdcen_vddh_set(bool enable) +{ + NRF_POWER->DCDCEN0 = (enable ? + POWER_DCDCEN0_DCDCEN_Enabled : POWER_DCDCEN0_DCDCEN_Disabled) << + POWER_DCDCEN0_DCDCEN_Pos; +} + +bool nrf_power_dcdcen_vddh_get(void) +{ + return (NRF_POWER->DCDCEN0 & POWER_DCDCEN0_DCDCEN_Msk) + == + (POWER_DCDCEN0_DCDCEN_Enabled << POWER_DCDCEN0_DCDCEN_Pos); +} + +nrf_power_mainregstatus_t nrf_power_mainregstatus_get(void) +{ + return (nrf_power_mainregstatus_t)(((NRF_POWER->MAINREGSTATUS) & + POWER_MAINREGSTATUS_MAINREGSTATUS_Msk) >> + POWER_MAINREGSTATUS_MAINREGSTATUS_Pos); +} +#endif /* NRF_POWER_HAS_VDDH */ + +#if NRF_POWER_HAS_USBREG +__STATIC_INLINE uint32_t nrf_power_usbregstatus_get(void) +{ + return NRF_POWER->USBREGSTATUS; +} + +__STATIC_INLINE bool nrf_power_usbregstatus_vbusdet_get(void) +{ + return (nrf_power_usbregstatus_get() & + NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK) != 0; +} + +__STATIC_INLINE bool nrf_power_usbregstatus_outrdy_get(void) +{ + return (nrf_power_usbregstatus_get() & + NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK) != 0; +} +#endif /* NRF_POWER_HAS_USBREG */ + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_POWER_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_ppi.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_ppi.h new file mode 100644 index 0000000000000000000000000000000000000000..945fedc2d8ad98dd37faaa72a35ec68f2d754ee8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_ppi.h @@ -0,0 +1,439 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_PPI_H__ +#define NRF_PPI_H__ + +#include +#include "nrf.h" +#include "nrf_peripherals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_ppi_hal PPI HAL + * @{ + * @ingroup nrf_ppi + * @brief Hardware access layer for setting up Programmable Peripheral Interconnect (PPI) channels. + */ + +#define NRF_PPI_TASK_SET (1UL) + +/** + * @enum nrf_ppi_channel_t + * @brief PPI channels. + */ +typedef enum +{ + NRF_PPI_CHANNEL0 = PPI_CHEN_CH0_Pos, /**< Channel 0. */ + NRF_PPI_CHANNEL1 = PPI_CHEN_CH1_Pos, /**< Channel 1. */ + NRF_PPI_CHANNEL2 = PPI_CHEN_CH2_Pos, /**< Channel 2. */ + NRF_PPI_CHANNEL3 = PPI_CHEN_CH3_Pos, /**< Channel 3. */ + NRF_PPI_CHANNEL4 = PPI_CHEN_CH4_Pos, /**< Channel 4. */ + NRF_PPI_CHANNEL5 = PPI_CHEN_CH5_Pos, /**< Channel 5. */ + NRF_PPI_CHANNEL6 = PPI_CHEN_CH6_Pos, /**< Channel 6. */ + NRF_PPI_CHANNEL7 = PPI_CHEN_CH7_Pos, /**< Channel 7. */ + NRF_PPI_CHANNEL8 = PPI_CHEN_CH8_Pos, /**< Channel 8. */ + NRF_PPI_CHANNEL9 = PPI_CHEN_CH9_Pos, /**< Channel 9. */ + NRF_PPI_CHANNEL10 = PPI_CHEN_CH10_Pos, /**< Channel 10. */ + NRF_PPI_CHANNEL11 = PPI_CHEN_CH11_Pos, /**< Channel 11. */ + NRF_PPI_CHANNEL12 = PPI_CHEN_CH12_Pos, /**< Channel 12. */ + NRF_PPI_CHANNEL13 = PPI_CHEN_CH13_Pos, /**< Channel 13. */ + NRF_PPI_CHANNEL14 = PPI_CHEN_CH14_Pos, /**< Channel 14. */ + NRF_PPI_CHANNEL15 = PPI_CHEN_CH15_Pos, /**< Channel 15. */ +#if (PPI_CH_NUM > 16) || defined(__SDK_DOXYGEN__) + NRF_PPI_CHANNEL16 = PPI_CHEN_CH16_Pos, /**< Channel 16. */ + NRF_PPI_CHANNEL17 = PPI_CHEN_CH17_Pos, /**< Channel 17. */ + NRF_PPI_CHANNEL18 = PPI_CHEN_CH18_Pos, /**< Channel 18. */ + NRF_PPI_CHANNEL19 = PPI_CHEN_CH19_Pos, /**< Channel 19. */ +#endif + NRF_PPI_CHANNEL20 = PPI_CHEN_CH20_Pos, /**< Channel 20. */ + NRF_PPI_CHANNEL21 = PPI_CHEN_CH21_Pos, /**< Channel 21. */ + NRF_PPI_CHANNEL22 = PPI_CHEN_CH22_Pos, /**< Channel 22. */ + NRF_PPI_CHANNEL23 = PPI_CHEN_CH23_Pos, /**< Channel 23. */ + NRF_PPI_CHANNEL24 = PPI_CHEN_CH24_Pos, /**< Channel 24. */ + NRF_PPI_CHANNEL25 = PPI_CHEN_CH25_Pos, /**< Channel 25. */ + NRF_PPI_CHANNEL26 = PPI_CHEN_CH26_Pos, /**< Channel 26. */ + NRF_PPI_CHANNEL27 = PPI_CHEN_CH27_Pos, /**< Channel 27. */ + NRF_PPI_CHANNEL28 = PPI_CHEN_CH28_Pos, /**< Channel 28. */ + NRF_PPI_CHANNEL29 = PPI_CHEN_CH29_Pos, /**< Channel 29. */ + NRF_PPI_CHANNEL30 = PPI_CHEN_CH30_Pos, /**< Channel 30. */ + NRF_PPI_CHANNEL31 = PPI_CHEN_CH31_Pos /**< Channel 31. */ +} nrf_ppi_channel_t; + +/** + * @enum nrf_ppi_channel_group_t + * @brief PPI channel groups. + */ +typedef enum +{ + NRF_PPI_CHANNEL_GROUP0 = 0, /**< Channel group 0. */ + NRF_PPI_CHANNEL_GROUP1 = 1, /**< Channel group 1. */ + NRF_PPI_CHANNEL_GROUP2 = 2, /**< Channel group 2. */ + NRF_PPI_CHANNEL_GROUP3 = 3, /**< Channel group 3. */ +#if (PPI_GROUP_NUM > 4) || defined(__SDK_DOXYGEN__) + NRF_PPI_CHANNEL_GROUP4 = 4, /**< Channel group 4. */ + NRF_PPI_CHANNEL_GROUP5 = 5 /**< Channel group 5. */ +#endif +} nrf_ppi_channel_group_t; + +/** + * @enum nrf_ppi_channel_include_t + * @brief Definition of which PPI channels belong to a group. + */ +typedef enum +{ + NRF_PPI_CHANNEL_EXCLUDE = PPI_CHG_CH0_Excluded, /**< Channel excluded from a group. */ + NRF_PPI_CHANNEL_INCLUDE = PPI_CHG_CH0_Included /**< Channel included in a group. */ +} nrf_ppi_channel_include_t; + +/** + * @enum nrf_ppi_channel_enable_t + * @brief Definition if a PPI channel is enabled. + */ +typedef enum +{ + NRF_PPI_CHANNEL_DISABLED = PPI_CHEN_CH0_Disabled, /**< Channel disabled. */ + NRF_PPI_CHANNEL_ENABLED = PPI_CHEN_CH0_Enabled /**< Channel enabled. */ +} nrf_ppi_channel_enable_t; + +/** + * @enum nrf_ppi_task_t + * @brief PPI tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_PPI_TASK_CHG0_EN = offsetof(NRF_PPI_Type, TASKS_CHG[0].EN), /**< Task for enabling channel group 0 */ + NRF_PPI_TASK_CHG0_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[0].DIS), /**< Task for disabling channel group 0 */ + NRF_PPI_TASK_CHG1_EN = offsetof(NRF_PPI_Type, TASKS_CHG[1].EN), /**< Task for enabling channel group 1 */ + NRF_PPI_TASK_CHG1_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[1].DIS), /**< Task for disabling channel group 1 */ + NRF_PPI_TASK_CHG2_EN = offsetof(NRF_PPI_Type, TASKS_CHG[2].EN), /**< Task for enabling channel group 2 */ + NRF_PPI_TASK_CHG2_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[2].DIS), /**< Task for disabling channel group 2 */ + NRF_PPI_TASK_CHG3_EN = offsetof(NRF_PPI_Type, TASKS_CHG[3].EN), /**< Task for enabling channel group 3 */ + NRF_PPI_TASK_CHG3_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[3].DIS), /**< Task for disabling channel group 3 */ +#if (PPI_GROUP_NUM > 4) || defined(__SDK_DOXYGEN__) + NRF_PPI_TASK_CHG4_EN = offsetof(NRF_PPI_Type, TASKS_CHG[4].EN), /**< Task for enabling channel group 4 */ + NRF_PPI_TASK_CHG4_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[4].DIS), /**< Task for disabling channel group 4 */ + NRF_PPI_TASK_CHG5_EN = offsetof(NRF_PPI_Type, TASKS_CHG[5].EN), /**< Task for enabling channel group 5 */ + NRF_PPI_TASK_CHG5_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[5].DIS) /**< Task for disabling channel group 5 */ +#endif + /*lint -restore*/ +} nrf_ppi_task_t; + +/** + * @brief Function for enabling a given PPI channel. + * + * @details This function enables only one channel. + * + * @param[in] channel Channel to enable. + * + * */ +__STATIC_INLINE void nrf_ppi_channel_enable(nrf_ppi_channel_t channel) +{ + NRF_PPI->CHENSET = PPI_CHENSET_CH0_Set << ((uint32_t) channel); +} + + +/** + * @brief Function for disabling a given PPI channel. + * + * @details This function disables only one channel. + * + * @param[in] channel Channel to disable. + */ +__STATIC_INLINE void nrf_ppi_channel_disable(nrf_ppi_channel_t channel) +{ + NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Clear << ((uint32_t) channel); +} + + +/** + * @brief Function for checking if a given PPI channel is enabled. + * + * @details This function checks only one channel. + * + * @param[in] channel Channel to check. + * + * @retval NRF_PPI_CHANNEL_ENABLED If the channel is enabled. + * @retval NRF_PPI_CHANNEL_DISABLED If the channel is not enabled. + * + */ +__STATIC_INLINE nrf_ppi_channel_enable_t nrf_ppi_channel_enable_get(nrf_ppi_channel_t channel) +{ + if (NRF_PPI->CHEN & (PPI_CHEN_CH0_Msk << ((uint32_t) channel))) + { + return NRF_PPI_CHANNEL_ENABLED; + } + else + { + return NRF_PPI_CHANNEL_DISABLED; + } +} + + +/** + * @brief Function for disabling all PPI channels. + */ +__STATIC_INLINE void nrf_ppi_channel_disable_all(void) +{ + NRF_PPI->CHENCLR = ((uint32_t)0xFFFFFFFFuL); +} + +/** + * @brief Function for disabling multiple PPI channels. + * + * @param[in] mask Channel mask. + */ +__STATIC_INLINE void nrf_ppi_channels_disable(uint32_t mask) +{ + NRF_PPI->CHENCLR = mask; +} + +/** + * @brief Function for setting up event and task endpoints for a given PPI channel. + * + * @param[in] eep Event register address. + * + * @param[in] tep Task register address. + * + * @param[in] channel Channel to which the given endpoints are assigned. + */ +__STATIC_INLINE void nrf_ppi_channel_endpoint_setup(nrf_ppi_channel_t channel, + uint32_t eep, + uint32_t tep) +{ + NRF_PPI->CH[(uint32_t) channel].EEP = eep; + NRF_PPI->CH[(uint32_t) channel].TEP = tep; +} + +#if defined(PPI_FEATURE_FORKS_PRESENT) || defined(__SDK_DOXYGEN__) +/** + * @brief Function for setting up task endpoint for a given PPI fork. + * + * @param[in] fork_tep Task register address. + * + * @param[in] channel Channel to which the given fork endpoint is assigned. + */ +__STATIC_INLINE void nrf_ppi_fork_endpoint_setup(nrf_ppi_channel_t channel, + uint32_t fork_tep) +{ + NRF_PPI->FORK[(uint32_t) channel].TEP = fork_tep; +} + +/** + * @brief Function for setting up event and task endpoints for a given PPI channel and fork. + * + * @param[in] eep Event register address. + * + * @param[in] tep Task register address. + * + * @param[in] fork_tep Fork task register address (register value). + * + * @param[in] channel Channel to which the given endpoints are assigned. + */ +__STATIC_INLINE void nrf_ppi_channel_and_fork_endpoint_setup(nrf_ppi_channel_t channel, + uint32_t eep, + uint32_t tep, + uint32_t fork_tep) +{ + nrf_ppi_channel_endpoint_setup(channel, eep, tep); + nrf_ppi_fork_endpoint_setup(channel, fork_tep); +} +#endif + +/** + * @brief Function for including a PPI channel in a channel group. + * + * @details This function adds only one channel to the group. + * + * @param[in] channel Channel to be included in the group. + * + * @param[in] channel_group Channel group. + * + */ +__STATIC_INLINE void nrf_ppi_channel_include_in_group(nrf_ppi_channel_t channel, + nrf_ppi_channel_group_t channel_group) +{ + NRF_PPI->CHG[(uint32_t) channel_group] = + NRF_PPI->CHG[(uint32_t) channel_group] | (PPI_CHG_CH0_Included << ((uint32_t) channel)); +} + +/** + * @brief Function for including multiple PPI channels in a channel group. + * + * @details This function adds all specified channels to the group. + * + * @param[in] channel_mask Channels to be included in the group. + * + * @param[in] channel_group Channel group. + * + */ +__STATIC_INLINE void nrf_ppi_channels_include_in_group(uint32_t channel_mask, + nrf_ppi_channel_group_t channel_group) +{ + NRF_PPI->CHG[(uint32_t) channel_group] = + NRF_PPI->CHG[(uint32_t) channel_group] | (channel_mask); +} + + +/** + * @brief Function for removing a PPI channel from a channel group. + * + * @details This function removes only one channel from the group. + * + * @param[in] channel Channel to be removed from the group. + * + * @param[in] channel_group Channel group. + */ +__STATIC_INLINE void nrf_ppi_channel_remove_from_group(nrf_ppi_channel_t channel, + nrf_ppi_channel_group_t channel_group) +{ + NRF_PPI->CHG[(uint32_t) channel_group] = + NRF_PPI->CHG[(uint32_t) channel_group] & ~(PPI_CHG_CH0_Included << ((uint32_t) channel)); +} + +/** + * @brief Function for removing multiple PPI channels from a channel group. + * + * @details This function removes all specified channels from the group. + * + * @param[in] channel_mask Channels to be removed from the group. + * + * @param[in] channel_group Channel group. + */ +__STATIC_INLINE void nrf_ppi_channels_remove_from_group(uint32_t channel_mask, + nrf_ppi_channel_group_t channel_group) +{ + NRF_PPI->CHG[(uint32_t) channel_group] = + NRF_PPI->CHG[(uint32_t) channel_group] & ~(channel_mask); +} + + +/** + * @brief Function for removing all PPI channels from a channel group. + * + * @param[in] group Channel group. + * + */ +__STATIC_INLINE void nrf_ppi_channel_group_clear(nrf_ppi_channel_group_t group) +{ + NRF_PPI->CHG[(uint32_t) group] = 0; +} + + +/** + * @brief Function for enabling a channel group. + * + * @param[in] group Channel group. + * + */ +__STATIC_INLINE void nrf_ppi_group_enable(nrf_ppi_channel_group_t group) +{ + NRF_PPI->TASKS_CHG[(uint32_t) group].EN = NRF_PPI_TASK_SET; +} + + +/** + * @brief Function for disabling a channel group. + * + * @param[in] group Channel group. + * + */ +__STATIC_INLINE void nrf_ppi_group_disable(nrf_ppi_channel_group_t group) +{ + NRF_PPI->TASKS_CHG[(uint32_t) group].DIS = NRF_PPI_TASK_SET; +} + + +/** + * @brief Function for setting a PPI task. + * + * @param[in] ppi_task PPI task to set. + */ +__STATIC_INLINE void nrf_ppi_task_trigger(nrf_ppi_task_t ppi_task) +{ + *((volatile uint32_t *) ((uint8_t *) NRF_PPI_BASE + (uint32_t) ppi_task)) = NRF_PPI_TASK_SET; +} + + +/** + * @brief Function for returning the address of a specific PPI task register. + * + * @param[in] ppi_task PPI task. + */ +__STATIC_INLINE uint32_t * nrf_ppi_task_address_get(nrf_ppi_task_t ppi_task) +{ + return (uint32_t *) ((uint8_t *) NRF_PPI_BASE + (uint32_t) ppi_task); +} + +/** + * @brief Function for returning the PPI enable task address of a specific group. + * + * @param[in] group PPI group. + */ +__STATIC_INLINE uint32_t * nrf_ppi_task_group_enable_address_get(nrf_ppi_channel_group_t group) +{ + return (uint32_t *) &NRF_PPI->TASKS_CHG[(uint32_t) group].EN; +} + +/** + * @brief Function for returning the PPI disable task address of a specific group. + * + * @param[in] group PPI group. + */ +__STATIC_INLINE uint32_t * nrf_ppi_task_group_disable_address_get(nrf_ppi_channel_group_t group) +{ + return (uint32_t *) &NRF_PPI->TASKS_CHG[(uint32_t) group].DIS; +} + + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_PPI_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_pwm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..710f307e27d70b4e456946cd3fa8f3b2cd16f60f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_pwm.h @@ -0,0 +1,701 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @defgroup nrf_pwm_hal PWM HAL + * @{ + * @ingroup nrf_pwm + * + * @brief @tagAPI52 Hardware access layer for managing the Pulse Width Modulation (PWM) + * peripheral. + */ + +#ifndef NRF_PWM_H__ +#define NRF_PWM_H__ + +#include +#include +#include + +#include "nrf.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief This value can be provided as a parameter for the @ref nrf_pwm_pins_set + * function call to specify that a given output channel shall not be + * connected to a physical pin. + */ +#define NRF_PWM_PIN_NOT_CONNECTED 0xFFFFFFFF + +/** + * @brief Number of channels in each Pointer to the peripheral registers structure. + */ +#define NRF_PWM_CHANNEL_COUNT 4 + + +/** + * @brief PWM tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_PWM_TASK_STOP = offsetof(NRF_PWM_Type, TASKS_STOP), ///< Stops PWM pulse generation on all channels at the end of the current PWM period, and stops the sequence playback. + NRF_PWM_TASK_SEQSTART0 = offsetof(NRF_PWM_Type, TASKS_SEQSTART[0]), ///< Starts playback of sequence 0. + NRF_PWM_TASK_SEQSTART1 = offsetof(NRF_PWM_Type, TASKS_SEQSTART[1]), ///< Starts playback of sequence 1. + NRF_PWM_TASK_NEXTSTEP = offsetof(NRF_PWM_Type, TASKS_NEXTSTEP) ///< Steps by one value in the current sequence if the decoder is set to @ref NRF_PWM_STEP_TRIGGERED mode. + /*lint -restore*/ +} nrf_pwm_task_t; + +/** + * @brief PWM events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_PWM_EVENT_STOPPED = offsetof(NRF_PWM_Type, EVENTS_STOPPED), ///< Response to STOP task, emitted when PWM pulses are no longer generated. + NRF_PWM_EVENT_SEQSTARTED0 = offsetof(NRF_PWM_Type, EVENTS_SEQSTARTED[0]), ///< First PWM period started on sequence 0. + NRF_PWM_EVENT_SEQSTARTED1 = offsetof(NRF_PWM_Type, EVENTS_SEQSTARTED[1]), ///< First PWM period started on sequence 1. + NRF_PWM_EVENT_SEQEND0 = offsetof(NRF_PWM_Type, EVENTS_SEQEND[0]), ///< Emitted at the end of every sequence 0 when its last value has been read from RAM. + NRF_PWM_EVENT_SEQEND1 = offsetof(NRF_PWM_Type, EVENTS_SEQEND[1]), ///< Emitted at the end of every sequence 1 when its last value has been read from RAM. + NRF_PWM_EVENT_PWMPERIODEND = offsetof(NRF_PWM_Type, EVENTS_PWMPERIODEND), ///< Emitted at the end of each PWM period. + NRF_PWM_EVENT_LOOPSDONE = offsetof(NRF_PWM_Type, EVENTS_LOOPSDONE) ///< Concatenated sequences have been played the requested number of times. + /*lint -restore*/ +} nrf_pwm_event_t; + +/** + * @brief PWM interrupts. + */ +typedef enum +{ + NRF_PWM_INT_STOPPED_MASK = PWM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event. + NRF_PWM_INT_SEQSTARTED0_MASK = PWM_INTENSET_SEQSTARTED0_Msk, ///< Interrupt on SEQSTARTED[0] event. + NRF_PWM_INT_SEQSTARTED1_MASK = PWM_INTENSET_SEQSTARTED1_Msk, ///< Interrupt on SEQSTARTED[1] event. + NRF_PWM_INT_SEQEND0_MASK = PWM_INTENSET_SEQEND0_Msk, ///< Interrupt on SEQEND[0] event. + NRF_PWM_INT_SEQEND1_MASK = PWM_INTENSET_SEQEND1_Msk, ///< Interrupt on SEQEND[1] event. + NRF_PWM_INT_PWMPERIODEND_MASK = PWM_INTENSET_PWMPERIODEND_Msk, ///< Interrupt on PWMPERIODEND event. + NRF_PWM_INT_LOOPSDONE_MASK = PWM_INTENSET_LOOPSDONE_Msk ///< Interrupt on LOOPSDONE event. +} nrf_pwm_int_mask_t; + +/** + * @brief PWM shortcuts. + */ +typedef enum +{ + NRF_PWM_SHORT_SEQEND0_STOP_MASK = PWM_SHORTS_SEQEND0_STOP_Msk, ///< Shortcut between SEQEND[0] event and STOP task. + NRF_PWM_SHORT_SEQEND1_STOP_MASK = PWM_SHORTS_SEQEND1_STOP_Msk, ///< Shortcut between SEQEND[1] event and STOP task. + NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK = PWM_SHORTS_LOOPSDONE_SEQSTART0_Msk, ///< Shortcut between LOOPSDONE event and SEQSTART[0] task. + NRF_PWM_SHORT_LOOPSDONE_SEQSTART1_MASK = PWM_SHORTS_LOOPSDONE_SEQSTART1_Msk, ///< Shortcut between LOOPSDONE event and SEQSTART[1] task. + NRF_PWM_SHORT_LOOPSDONE_STOP_MASK = PWM_SHORTS_LOOPSDONE_STOP_Msk ///< Shortcut between LOOPSDONE event and STOP task. +} nrf_pwm_short_mask_t; + +/** + * @brief PWM modes of operation. + */ +typedef enum +{ + NRF_PWM_MODE_UP = PWM_MODE_UPDOWN_Up, ///< Up counter (edge-aligned PWM duty cycle). + NRF_PWM_MODE_UP_AND_DOWN = PWM_MODE_UPDOWN_UpAndDown, ///< Up and down counter (center-aligned PWM duty cycle). +} nrf_pwm_mode_t; + +/** + * @brief PWM base clock frequencies. + */ +typedef enum +{ + NRF_PWM_CLK_16MHz = PWM_PRESCALER_PRESCALER_DIV_1, ///< 16 MHz / 1 = 16 MHz. + NRF_PWM_CLK_8MHz = PWM_PRESCALER_PRESCALER_DIV_2, ///< 16 MHz / 2 = 8 MHz. + NRF_PWM_CLK_4MHz = PWM_PRESCALER_PRESCALER_DIV_4, ///< 16 MHz / 4 = 4 MHz. + NRF_PWM_CLK_2MHz = PWM_PRESCALER_PRESCALER_DIV_8, ///< 16 MHz / 8 = 2 MHz. + NRF_PWM_CLK_1MHz = PWM_PRESCALER_PRESCALER_DIV_16, ///< 16 MHz / 16 = 1 MHz. + NRF_PWM_CLK_500kHz = PWM_PRESCALER_PRESCALER_DIV_32, ///< 16 MHz / 32 = 500 kHz. + NRF_PWM_CLK_250kHz = PWM_PRESCALER_PRESCALER_DIV_64, ///< 16 MHz / 64 = 250 kHz. + NRF_PWM_CLK_125kHz = PWM_PRESCALER_PRESCALER_DIV_128 ///< 16 MHz / 128 = 125 kHz. +} nrf_pwm_clk_t; + +/** + * @brief PWM decoder load modes. + * + * The selected mode determines how the sequence data is read from RAM and + * spread to the compare registers. + */ +typedef enum +{ + NRF_PWM_LOAD_COMMON = PWM_DECODER_LOAD_Common, ///< 1st half word (16-bit) used in all PWM channels (0-3). + NRF_PWM_LOAD_GROUPED = PWM_DECODER_LOAD_Grouped, ///< 1st half word (16-bit) used in channels 0 and 1; 2nd word in channels 2 and 3. + NRF_PWM_LOAD_INDIVIDUAL = PWM_DECODER_LOAD_Individual, ///< 1st half word (16-bit) used in channel 0; 2nd in channel 1; 3rd in channel 2; 4th in channel 3. + NRF_PWM_LOAD_WAVE_FORM = PWM_DECODER_LOAD_WaveForm ///< 1st half word (16-bit) used in channel 0; 2nd in channel 1; ... ; 4th as the top value for the pulse generator counter. +} nrf_pwm_dec_load_t; + +/** + * @brief PWM decoder next step modes. + * + * The selected mode determines when the next value from the active sequence + * is loaded. + */ +typedef enum +{ + NRF_PWM_STEP_AUTO = PWM_DECODER_MODE_RefreshCount, ///< Automatically after the current value is played and repeated the requested number of times. + NRF_PWM_STEP_TRIGGERED = PWM_DECODER_MODE_NextStep ///< When the @ref NRF_PWM_TASK_NEXTSTEP task is triggered. +} nrf_pwm_dec_step_t; + + +/** + * @brief Type used for defining duty cycle values for a sequence + * loaded in @ref NRF_PWM_LOAD_COMMON mode. + */ +typedef uint16_t nrf_pwm_values_common_t; + +/** + * @brief Structure for defining duty cycle values for a sequence + * loaded in @ref NRF_PWM_LOAD_GROUPED mode. + */ +typedef struct { + uint16_t group_0; ///< Duty cycle value for group 0 (channels 0 and 1). + uint16_t group_1; ///< Duty cycle value for group 1 (channels 2 and 3). +} nrf_pwm_values_grouped_t; + +/** + * @brief Structure for defining duty cycle values for a sequence + * loaded in @ref NRF_PWM_LOAD_INDIVIDUAL mode. + */ +typedef struct +{ + uint16_t channel_0; ///< Duty cycle value for channel 0. + uint16_t channel_1; ///< Duty cycle value for channel 1. + uint16_t channel_2; ///< Duty cycle value for channel 2. + uint16_t channel_3; ///< Duty cycle value for channel 3. +} nrf_pwm_values_individual_t; + +/** + * @brief Structure for defining duty cycle values for a sequence + * loaded in @ref NRF_PWM_LOAD_WAVE_FORM mode. + */ +typedef struct { + uint16_t channel_0; ///< Duty cycle value for channel 0. + uint16_t channel_1; ///< Duty cycle value for channel 1. + uint16_t channel_2; ///< Duty cycle value for channel 2. + uint16_t counter_top; ///< Top value for the pulse generator counter. +} nrf_pwm_values_wave_form_t; + +/** + * @brief Union grouping pointers to arrays of duty cycle values applicable to + * various loading modes. + */ +typedef union { + nrf_pwm_values_common_t const * p_common; ///< Pointer to be used in @ref NRF_PWM_LOAD_COMMON mode. + nrf_pwm_values_grouped_t const * p_grouped; ///< Pointer to be used in @ref NRF_PWM_LOAD_GROUPED mode. + nrf_pwm_values_individual_t const * p_individual; ///< Pointer to be used in @ref NRF_PWM_LOAD_INDIVIDUAL mode. + nrf_pwm_values_wave_form_t const * p_wave_form; ///< Pointer to be used in @ref NRF_PWM_LOAD_WAVE_FORM mode. + uint16_t const * p_raw; ///< Pointer providing raw access to the values. +} nrf_pwm_values_t; + +/** + * @brief Structure for defining a sequence of PWM duty cycles. + * + * When the sequence is set (by a call to @ref nrf_pwm_sequence_set), the + * provided duty cycle values are not copied. The @p values pointer is stored + * in the peripheral's internal register, and the values are loaded from RAM + * during the sequence playback. Therefore, you must ensure that the values + * do not change before and during the sequence playback (for example, + * the values cannot be placed in a local variable that is allocated on stack). + * If the sequence is played in a loop and the values should be updated + * before the next iteration, it is safe to modify them when the corresponding + * event signaling the end of sequence occurs (@ref NRF_PWM_EVENT_SEQEND0 + * or @ref NRF_PWM_EVENT_SEQEND1, respectively). + * + * @note The @p repeats and @p end_delay values (which are written to the + * SEQ[n].REFRESH and SEQ[n].ENDDELAY registers in the peripheral, + * respectively) are ignored at the end of a complex sequence + * playback, indicated by the LOOPSDONE event. + * See the @linkProductSpecification52 for more information. + */ +typedef struct +{ + nrf_pwm_values_t values; ///< Pointer to an array with duty cycle values. This array must be in Data RAM. + /**< This field is defined as an union of pointers + * to provide a convenient way to define duty + * cycle values in various loading modes + * (see @ref nrf_pwm_dec_load_t). + * In each value, the most significant bit (15) + * determines the polarity of the output and the + * others (14-0) compose the 15-bit value to be + * compared with the pulse generator counter. */ + uint16_t length; ///< Number of 16-bit values in the array pointed by @p values. + uint32_t repeats; ///< Number of times that each duty cycle should be repeated (after being played once). Ignored in @ref NRF_PWM_STEP_TRIGGERED mode. + uint32_t end_delay; ///< Additional time (in PWM periods) that the last duty cycle is to be kept after the sequence is played. Ignored in @ref NRF_PWM_STEP_TRIGGERED mode. +} nrf_pwm_sequence_t; + +/** + * @brief Helper macro for calculating the number of 16-bit values in specified + * array of duty cycle values. + */ +#define NRF_PWM_VALUES_LENGTH(array) (sizeof(array) / sizeof(uint16_t)) + + +/** + * @brief Function for activating a specific PWM task. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_pwm_task_trigger(NRF_PWM_Type * p_reg, + nrf_pwm_task_t task); + +/** + * @brief Function for getting the address of a specific PWM task register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t nrf_pwm_task_address_get(NRF_PWM_Type const * p_reg, + nrf_pwm_task_t task); + +/** + * @brief Function for clearing a specific PWM event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_pwm_event_clear(NRF_PWM_Type * p_reg, + nrf_pwm_event_t event); + +/** + * @brief Function for checking the state of a specific PWM event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_pwm_event_check(NRF_PWM_Type const * p_reg, + nrf_pwm_event_t event); + +/** + * @brief Function for getting the address of a specific PWM event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t nrf_pwm_event_address_get(NRF_PWM_Type const * p_reg, + nrf_pwm_event_t event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_pwm_shorts_enable(NRF_PWM_Type * p_reg, + uint32_t pwm_shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_pwm_shorts_disable(NRF_PWM_Type * p_reg, + uint32_t pwm_shorts_mask); + +/** + * @brief Function for setting the configuration of PWM shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_shorts_mask Shortcuts configuration to set. + */ +__STATIC_INLINE void nrf_pwm_shorts_set(NRF_PWM_Type * p_reg, + uint32_t pwm_shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_pwm_int_enable(NRF_PWM_Type * p_reg, + uint32_t pwm_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_pwm_int_disable(NRF_PWM_Type * p_reg, + uint32_t pwm_int_mask); + +/** + * @brief Function for setting the configuration of PWM interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_int_mask Interrupts configuration to set. + */ +__STATIC_INLINE void nrf_pwm_int_set(NRF_PWM_Type * p_reg, + uint32_t pwm_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_pwm_int_enable_check(NRF_PWM_Type const * p_reg, + nrf_pwm_int_mask_t pwm_int); + +/** + * @brief Function for enabling the PWM peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_pwm_enable(NRF_PWM_Type * p_reg); + +/** + * @brief Function for disabling the PWM peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_pwm_disable(NRF_PWM_Type * p_reg); + +/** + * @brief Function for assigning pins to PWM output channels. + * + * Usage of all PWM output channels is optional. If a given channel is not + * needed, pass the @ref NRF_PWM_PIN_NOT_CONNECTED value instead of its pin + * number. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] out_pins Array with pin numbers for individual PWM output channels. + */ +__STATIC_INLINE void nrf_pwm_pins_set(NRF_PWM_Type * p_reg, + uint32_t out_pins[NRF_PWM_CHANNEL_COUNT]); + +/** + * @brief Function for configuring the PWM peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] base_clock Base clock frequency. + * @param[in] mode Operating mode of the pulse generator counter. + * @param[in] top_value Value up to which the pulse generator counter counts. + */ +__STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_reg, + nrf_pwm_clk_t base_clock, + nrf_pwm_mode_t mode, + uint16_t top_value); + +/** + * @brief Function for defining a sequence of PWM duty cycles. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] p_seq Pointer to the sequence definition. + */ +__STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + nrf_pwm_sequence_t const * p_seq); + +/** + * @brief Function for modifying the pointer to the duty cycle values + * in the specified sequence. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] p_values Pointer to an array with duty cycle values. + */ +__STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint16_t const * p_values); + +/** + * @brief Function for modifying the total number of duty cycle values + * in the specified sequence. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] length Number of duty cycle values. + */ +__STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint16_t length); + +/** + * @brief Function for modifying the additional number of PWM periods spent + * on each duty cycle value in the specified sequence. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] refresh Number of additional PWM periods for each duty cycle value. + */ +__STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint32_t refresh); + +/** + * @brief Function for modifying the additional time added after the sequence + * is played. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] end_delay Number of PWM periods added at the end of the sequence. + */ +__STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint32_t end_delay); + +/** + * @brief Function for setting the mode of loading sequence data from RAM + * and advancing the sequence. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] dec_load Mode of loading sequence data from RAM. + * @param[in] dec_step Mode of advancing the active sequence. + */ +__STATIC_INLINE void nrf_pwm_decoder_set(NRF_PWM_Type * p_reg, + nrf_pwm_dec_load_t dec_load, + nrf_pwm_dec_step_t dec_step); + +/** + * @brief Function for setting the number of times the sequence playback + * should be performed. + * + * This function applies to two-sequence playback (concatenated sequence 0 and 1). + * A single sequence can be played back only once. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] loop_count Number of times to perform the sequence playback. + */ +__STATIC_INLINE void nrf_pwm_loop_set(NRF_PWM_Type * p_reg, + uint16_t loop_count); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_pwm_task_trigger(NRF_PWM_Type * p_reg, + nrf_pwm_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_pwm_task_address_get(NRF_PWM_Type const * p_reg, + nrf_pwm_task_t task) +{ + return ((uint32_t)p_reg + (uint32_t)task); +} + +__STATIC_INLINE void nrf_pwm_event_clear(NRF_PWM_Type * p_reg, + nrf_pwm_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_pwm_event_check(NRF_PWM_Type const * p_reg, + nrf_pwm_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE uint32_t nrf_pwm_event_address_get(NRF_PWM_Type const * p_reg, + nrf_pwm_event_t event) +{ + return ((uint32_t)p_reg + (uint32_t)event); +} + +__STATIC_INLINE void nrf_pwm_shorts_enable(NRF_PWM_Type * p_reg, + uint32_t pwm_shorts_mask) +{ + p_reg->SHORTS |= pwm_shorts_mask; +} + +__STATIC_INLINE void nrf_pwm_shorts_disable(NRF_PWM_Type * p_reg, + uint32_t pwm_shorts_mask) +{ + p_reg->SHORTS &= ~(pwm_shorts_mask); +} + +__STATIC_INLINE void nrf_pwm_shorts_set(NRF_PWM_Type * p_reg, + uint32_t pwm_shorts_mask) +{ + p_reg->SHORTS = pwm_shorts_mask; +} + +__STATIC_INLINE void nrf_pwm_int_enable(NRF_PWM_Type * p_reg, + uint32_t pwm_int_mask) +{ + p_reg->INTENSET = pwm_int_mask; +} + +__STATIC_INLINE void nrf_pwm_int_disable(NRF_PWM_Type * p_reg, + uint32_t pwm_int_mask) +{ + p_reg->INTENCLR = pwm_int_mask; +} + +__STATIC_INLINE void nrf_pwm_int_set(NRF_PWM_Type * p_reg, + uint32_t pwm_int_mask) +{ + p_reg->INTEN = pwm_int_mask; +} + +__STATIC_INLINE bool nrf_pwm_int_enable_check(NRF_PWM_Type const * p_reg, + nrf_pwm_int_mask_t pwm_int) +{ + return (bool)(p_reg->INTENSET & pwm_int); +} + +__STATIC_INLINE void nrf_pwm_enable(NRF_PWM_Type * p_reg) +{ + p_reg->ENABLE = (PWM_ENABLE_ENABLE_Enabled << PWM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_pwm_disable(NRF_PWM_Type * p_reg) +{ + p_reg->ENABLE = (PWM_ENABLE_ENABLE_Disabled << PWM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_pwm_pins_set(NRF_PWM_Type * p_reg, + uint32_t out_pins[NRF_PWM_CHANNEL_COUNT]) +{ + uint8_t i; + for (i = 0; i < NRF_PWM_CHANNEL_COUNT; ++i) + { + p_reg->PSEL.OUT[i] = out_pins[i]; + } +} + +__STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_reg, + nrf_pwm_clk_t base_clock, + nrf_pwm_mode_t mode, + uint16_t top_value) +{ + ASSERT(top_value <= PWM_COUNTERTOP_COUNTERTOP_Msk); + + p_reg->PRESCALER = base_clock; + p_reg->MODE = mode; + p_reg->COUNTERTOP = top_value; +} + +__STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + nrf_pwm_sequence_t const * p_seq) +{ + ASSERT(p_seq != NULL); + + nrf_pwm_seq_ptr_set( p_reg, seq_id, p_seq->values.p_raw); + nrf_pwm_seq_cnt_set( p_reg, seq_id, p_seq->length); + nrf_pwm_seq_refresh_set( p_reg, seq_id, p_seq->repeats); + nrf_pwm_seq_end_delay_set(p_reg, seq_id, p_seq->end_delay); +} + +__STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint16_t const * p_values) +{ + ASSERT(seq_id <= 1); + ASSERT(p_values != NULL); + p_reg->SEQ[seq_id].PTR = (uint32_t)p_values; +} + +__STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint16_t length) +{ + ASSERT(seq_id <= 1); + ASSERT(length != 0); + ASSERT(length <= PWM_SEQ_CNT_CNT_Msk); + p_reg->SEQ[seq_id].CNT = length; +} + +__STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint32_t refresh) +{ + ASSERT(seq_id <= 1); + ASSERT(refresh <= PWM_SEQ_REFRESH_CNT_Msk); + p_reg->SEQ[seq_id].REFRESH = refresh; +} + +__STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint32_t end_delay) +{ + ASSERT(seq_id <= 1); + ASSERT(end_delay <= PWM_SEQ_ENDDELAY_CNT_Msk); + p_reg->SEQ[seq_id].ENDDELAY = end_delay; +} + +__STATIC_INLINE void nrf_pwm_decoder_set(NRF_PWM_Type * p_reg, + nrf_pwm_dec_load_t dec_load, + nrf_pwm_dec_step_t dec_step) +{ + p_reg->DECODER = ((uint32_t)dec_load << PWM_DECODER_LOAD_Pos) | + ((uint32_t)dec_step << PWM_DECODER_MODE_Pos); +} + +__STATIC_INLINE void nrf_pwm_loop_set(NRF_PWM_Type * p_reg, + uint16_t loop_count) +{ + p_reg->LOOP = loop_count; +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_PWM_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_qdec.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_qdec.h new file mode 100644 index 0000000000000000000000000000000000000000..e6a0fccbfefcba8ccc3b33f1086c7d91356b428c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_qdec.h @@ -0,0 +1,504 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_QDEC_H__ +#define NRF_QDEC_H__ + +#include +#include "nrf_error.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*lint ++flb "Enter library region" */ + +/** + * @defgroup nrf_qdec_hal QDEC HAL + * @{ + * @ingroup nrf_qdec + * @brief Hardware access layer for accessing the quadrature decoder (QDEC) peripheral. + */ + +/** + * @enum nrf_qdec_task_t + * @brief QDEC tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_QDEC_TASK_START = offsetof(NRF_QDEC_Type, TASKS_START), /**< Starting the quadrature decoder. */ + NRF_QDEC_TASK_STOP = offsetof(NRF_QDEC_Type, TASKS_STOP), /**< Stopping the quadrature decoder. */ + NRF_QDEC_TASK_READCLRACC = offsetof(NRF_QDEC_Type, TASKS_READCLRACC) /**< Reading and clearing ACC and ACCDBL registers. */ +} nrf_qdec_task_t; + +/** + * @enum nrf_qdec_event_t + * @brief QDEC events. + */ +typedef enum +{ + NRF_QDEC_EVENT_SAMPLERDY = offsetof(NRF_QDEC_Type, EVENTS_SAMPLERDY), /**< Event generated for every new sample. */ + NRF_QDEC_EVENT_REPORTRDY = offsetof(NRF_QDEC_Type, EVENTS_REPORTRDY), /**< Event generated for every new report. */ + NRF_QDEC_EVENT_ACCOF = offsetof(NRF_QDEC_Type, EVENTS_ACCOF) /**< Event generated for every accumulator overflow. */ +} nrf_qdec_event_t; /*lint -restore */ + +/** + * @enum nrf_qdec_short_mask_t + * @brief QDEC shortcuts. + */ +typedef enum +{ + NRF_QDEC_SHORT_REPORTRDY_READCLRACC_MASK = QDEC_SHORTS_REPORTRDY_READCLRACC_Msk, /**< Shortcut between REPORTRDY event and READCLRACC task. */ + NRF_QDEC_SHORT_SAMPLERDY_STOP_MASK = QDEC_SHORTS_SAMPLERDY_STOP_Msk /**< Shortcut between SAMPLERDY event and STOP task. */ +} nrf_qdec_short_mask_t; + +/** + * @enum nrf_qdec_int_mask_t + * @brief QDEC interrupts. + */ +typedef enum +{ + NRF_QDEC_INT_SAMPLERDY_MASK = QDEC_INTENSET_SAMPLERDY_Msk, /**< Mask for enabling or disabling an interrupt on SAMPLERDY event. */ + NRF_QDEC_INT_REPORTRDY_MASK = QDEC_INTENSET_REPORTRDY_Msk, /**< Mask for enabling or disabling an interrupt on REPORTRDY event. */ + NRF_QDEC_INT_ACCOF_MASK = QDEC_INTENSET_ACCOF_Msk /**< Mask for enabling or disabling an interrupt on ACCOF event. */ +} nrf_qdec_int_mask_t; + +/** + * @enum nrf_qdec_enable_t + * @brief States of the enable bit. + */ +typedef enum +{ + NRF_QDEC_DISABLE = QDEC_ENABLE_ENABLE_Disabled, /**< Mask for disabling the QDEC periperal. When disabled, the QDEC decoder pins are not active. */ + NRF_QDEC_ENABLE = QDEC_ENABLE_ENABLE_Enabled /**< Mask for enabling the QDEC periperal. When enabled, the QDEC pins are active. */ +} nrf_qdec_enable_t; + + +/** + * @enum nrf_qdec_dbfen_t + * @brief States of the debounce filter enable bit. + */ +typedef enum +{ + NRF_QDEC_DBFEN_DISABLE = QDEC_DBFEN_DBFEN_Disabled, /**< Mask for disabling the debounce filter. */ + NRF_QDEC_DBFEN_ENABLE = QDEC_DBFEN_DBFEN_Enabled /**< Mask for enabling the debounce filter. */ +} nrf_qdec_dbfen_t; + +/** + * @enum nrf_qdec_ledpol_t + * @brief Active LED polarity. + */ +typedef enum +{ + NRF_QDEC_LEPOL_ACTIVE_LOW = QDEC_LEDPOL_LEDPOL_ActiveLow, /**< QDEC LED active on output pin low. */ + NRF_QDEC_LEPOL_ACTIVE_HIGH = QDEC_LEDPOL_LEDPOL_ActiveHigh /**< QDEC LED active on output pin high. */ +} nrf_qdec_ledpol_t; + + +/** + * @enum nrf_qdec_sampleper_t + * @brief Available sampling periods. + */ +typedef enum +{ + NRF_QDEC_SAMPLEPER_128us = QDEC_SAMPLEPER_SAMPLEPER_128us, /**< QDEC sampling period 128 microseconds. */ + NRF_QDEC_SAMPLEPER_256us = QDEC_SAMPLEPER_SAMPLEPER_256us, /**< QDEC sampling period 256 microseconds. */ + NRF_QDEC_SAMPLEPER_512us = QDEC_SAMPLEPER_SAMPLEPER_512us, /**< QDEC sampling period 512 microseconds. */ + NRF_QDEC_SAMPLEPER_1024us = QDEC_SAMPLEPER_SAMPLEPER_1024us, /**< QDEC sampling period 1024 microseconds. */ + NRF_QDEC_SAMPLEPER_2048us = QDEC_SAMPLEPER_SAMPLEPER_2048us, /**< QDEC sampling period 2048 microseconds. */ + NRF_QDEC_SAMPLEPER_4096us = QDEC_SAMPLEPER_SAMPLEPER_4096us, /**< QDEC sampling period 4096 microseconds. */ + NRF_QDEC_SAMPLEPER_8192us = QDEC_SAMPLEPER_SAMPLEPER_8192us, /**< QDEC sampling period 8192 microseconds. */ + NRF_QDEC_SAMPLEPER_16384us = QDEC_SAMPLEPER_SAMPLEPER_16384us /**< QDEC sampling period 16384 microseconds. */ +} nrf_qdec_sampleper_t; + +/** + * @enum nrf_qdec_reportper_t + * @brief Available report periods. + */ +typedef enum +{ + NRF_QDEC_REPORTPER_10 = QDEC_REPORTPER_REPORTPER_10Smpl, /**< QDEC report period 10 samples. */ + NRF_QDEC_REPORTPER_40 = QDEC_REPORTPER_REPORTPER_40Smpl, /**< QDEC report period 40 samples. */ + NRF_QDEC_REPORTPER_80 = QDEC_REPORTPER_REPORTPER_80Smpl, /**< QDEC report period 80 samples. */ + NRF_QDEC_REPORTPER_120 = QDEC_REPORTPER_REPORTPER_120Smpl, /**< QDEC report period 120 samples. */ + NRF_QDEC_REPORTPER_160 = QDEC_REPORTPER_REPORTPER_160Smpl, /**< QDEC report period 160 samples. */ + NRF_QDEC_REPORTPER_200 = QDEC_REPORTPER_REPORTPER_200Smpl, /**< QDEC report period 200 samples. */ + NRF_QDEC_REPORTPER_240 = QDEC_REPORTPER_REPORTPER_240Smpl, /**< QDEC report period 240 samples. */ + NRF_QDEC_REPORTPER_280 = QDEC_REPORTPER_REPORTPER_280Smpl, /**< QDEC report period 280 samples. */ + NRF_QDEC_REPORTPER_DISABLED /**< QDEC reporting disabled. */ +} nrf_qdec_reportper_t; + +/** + * @brief Function for enabling QDEC. + */ +__STATIC_INLINE void nrf_qdec_enable(void) +{ + NRF_QDEC->ENABLE = NRF_QDEC_ENABLE; +} + + +/** + * @brief Function for disabling QDEC. + */ +__STATIC_INLINE void nrf_qdec_disable(void) +{ + NRF_QDEC->ENABLE = NRF_QDEC_DISABLE; +} + + +/** + * @brief Function for returning the enable state of QDEC. + * @return State of the register. + */ +__STATIC_INLINE uint32_t nrf_qdec_enable_get(void) +{ + return NRF_QDEC->ENABLE; +} + + +/** + * @brief Function for enabling QDEC interrupts by mask. + * @param[in] qdec_int_mask Sources of the interrupts to enable. + */ +__STATIC_INLINE void nrf_qdec_int_enable(uint32_t qdec_int_mask) +{ + NRF_QDEC->INTENSET = qdec_int_mask; // writing 0 has no effect +} + + +/** + * @brief Function for disabling QDEC interrupts by mask. + * @param[in] qdec_int_mask Sources of the interrupts to disable. + * + */ +__STATIC_INLINE void nrf_qdec_int_disable(uint32_t qdec_int_mask) +{ + NRF_QDEC->INTENCLR = qdec_int_mask; // writing 0 has no effect +} + + +/** + * @brief Function for getting the enabled interrupts of the QDEC. + */ +__STATIC_INLINE uint32_t nrf_qdec_int_enable_check(nrf_qdec_int_mask_t qdec_int_mask) +{ + return NRF_QDEC->INTENSET & qdec_int_mask; // when read this register will return the value of INTEN. +} + + +/** + * @brief Function for enabling the debouncing filter of the QED. + */ +__STATIC_INLINE void nrf_qdec_dbfen_enable(void) +{ + NRF_QDEC->DBFEN = NRF_QDEC_DBFEN_ENABLE; +} + + +/** + * @brief Function for disabling the debouncing filter of the QED. + */ +__STATIC_INLINE void nrf_qdec_dbfen_disable(void) +{ + NRF_QDEC->DBFEN = NRF_QDEC_DBFEN_DISABLE; +} + + +/** + * @brief Function for getting the state of the QDEC's debouncing filter. + * @retval NRF_QDEC_DBFEN_DISABLE If the debouncing filter is disabled. + * @retval NRF_QDEC_DBFEN_ENABLE If the debouncing filter is enabled. + */ +__STATIC_INLINE uint32_t nrf_qdec_dbfen_get(void) +{ + return NRF_QDEC->DBFEN; +} + + +/** + * @brief Function for assigning QDEC pins. + * @param[in] psela Pin number. + * @param[in] pselb Pin number. + * @param[in] pselled Pin number. + */ +__STATIC_INLINE void nrf_qdec_pio_assign( uint32_t psela, uint32_t pselb, uint32_t pselled) +{ + NRF_QDEC->PSELA = psela; + NRF_QDEC->PSELB = pselb; + NRF_QDEC->PSELLED = pselled; + +} + +/** + * @brief Function for setting a specific QDEC task. + * @param[in] qdec_task QDEC task to be set. + */ +__STATIC_INLINE void nrf_qdec_task_trigger(nrf_qdec_task_t qdec_task) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_task) ) = 1; +} + + +/** + * @brief Function for retrieving the address of a QDEC task register. + * @param[in] qdec_task QDEC task. + */ +__STATIC_INLINE uint32_t * nrf_qdec_task_address_get(nrf_qdec_task_t qdec_task) +{ + return (uint32_t *)( (uint8_t *)NRF_QDEC + qdec_task); +} + + +/** + * @brief Function for clearing a specific QDEC event. + * @param[in] qdec_event QDEC event to clear. + */ +__STATIC_INLINE void nrf_qdec_event_clear(nrf_qdec_event_t qdec_event) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event) ) = 0; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_QDEC + qdec_event)); + (void)dummy; +#endif +} + + +/** + * @brief Function for retrieving the state of a specific QDEC event. + * @return State of the QDEC event. + */ +__STATIC_INLINE uint32_t nrf_qdec_event_check(nrf_qdec_event_t qdec_event) +{ + return *(volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event); +} + + +/** + * @brief Function for retrieving the address of a specific QDEC event register. + * @param[in] qdec_event QDEC event. + * @return Address of the specified QDEC event. + */ +__STATIC_INLINE uint32_t * nrf_qdec_event_address_get(nrf_qdec_event_t qdec_event) +{ + return (uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event); +} + + +/** + * @brief Function for setting QDEC shortcuts. + * @param[in] qdec_short_mask QDEC shortcut by mask. + */ +__STATIC_INLINE void nrf_qdec_shorts_enable(uint32_t qdec_short_mask) +{ + NRF_QDEC->SHORTS |= qdec_short_mask; +} + + +/** + * @brief Function for clearing shortcuts of the QDEC by mask. + * @param[in] qdec_short_mask QDEC shortcute to be cleared. + */ +__STATIC_INLINE void nrf_qdec_shorts_disable(uint32_t qdec_short_mask) +{ + NRF_QDEC->SHORTS &= ~qdec_short_mask; +} + + +/** + * @brief Function for retrieving the value of QDEC's SAMPLEPER register. + * @return Value of the SAMPLEPER register. + */ +__STATIC_INLINE int32_t nrf_qdec_sampleper_reg_get(void) +{ + return NRF_QDEC->SAMPLEPER; +} + + +/** + * @brief Function for converting the value of QDEC's SAMPLE PERIOD to microseconds. + * @retval sampling period in microseconds. + */ +__STATIC_INLINE uint32_t nrf_qdec_sampleper_to_value(uint32_t sampleper) +{ + return (1 << (7 + sampleper)); +} + +/** + * @brief Function for setting the value of QDEC's SAMPLEPER register. + * @param[in] sample_per Sampling period. + */ +__STATIC_INLINE void nrf_qdec_sampleper_set(nrf_qdec_sampleper_t sample_per) +{ + NRF_QDEC->SAMPLEPER = sample_per; +} + + +/** + * @brief Function for retrieving the value of QDEC's SAMPLE register. + * @return Value of the SAMPLE register. + */ +__STATIC_INLINE int32_t nrf_qdec_sample_get(void) +{ + return NRF_QDEC->SAMPLE; +} + + +/** + * @brief Function for retrieving the value of QDEC's ACC register. + * @return Value of the ACC register. + */ +__STATIC_INLINE int32_t nrf_qdec_acc_get(void) +{ + return NRF_QDEC->ACC; +} + + +/** + * @brief Function for retrieving the value of QDEC's ACCREAD register. + * @return Value of the ACCREAD register. + */ +__STATIC_INLINE int32_t nrf_qdec_accread_get(void) +{ + return NRF_QDEC->ACCREAD; +} + + +/** + * @brief Function for retrieving the value of QDEC's ACCDBL register. + * @return Value of the ACCDBL register. + */ +__STATIC_INLINE uint32_t nrf_qdec_accdbl_get(void) +{ + return NRF_QDEC->ACCDBL; +} + + +/** + * @brief Function for retrieving the value of QDEC's ACCDBLREAD register. + * @return Value of the ACCDBLREAD register. + */ +__STATIC_INLINE uint32_t nrf_qdec_accdblread_get(void) +{ + return NRF_QDEC->ACCDBLREAD; +} + + +/** + * @brief Function for setting how long the LED is switched on before sampling. + * @param[in] time_us Time (in microseconds) how long the LED is switched on before sampling. + */ +__STATIC_INLINE void nrf_qdec_ledpre_set(uint32_t time_us) +{ + NRF_QDEC->LEDPRE = time_us; +} + + +/** + * @brief Function for retrieving how long the LED is switched on before sampling. + * @retval time_us Time (in microseconds) how long the LED is switched on before sampling. + */ +__STATIC_INLINE uint32_t nrf_qdec_ledpre_get(void) +{ + return NRF_QDEC->LEDPRE; +} + + +/** + * @brief Function for setting the report period (in samples). + * @param[in] reportper Number of samples. + */ +__STATIC_INLINE void nrf_qdec_reportper_set(nrf_qdec_reportper_t reportper) +{ + NRF_QDEC->REPORTPER = reportper; +} + + +/** + * @brief Function for retrieving the report period. + * @retval reportper Number of samples as encoded in the register. + */ +__STATIC_INLINE uint32_t nrf_qdec_reportper_reg_get(void) +{ + return NRF_QDEC->REPORTPER; +} + + +/** + * @brief Function for retrieving the value of QDEC's SAMPLEPER register. + * @param [in] reportper Reportper to be converted to amount of samples per report. + + */ +__STATIC_INLINE uint32_t nrf_qdec_reportper_to_value(uint32_t reportper) +{ + return (reportper == NRF_QDEC_REPORTPER_10) ? 10 : reportper * 40; +} + + +/** + * @brief Function for setting the active level for the LED. + * @param[in] pol Active level for the LED. + */ +__STATIC_INLINE void nrf_qdec_ledpol_set(nrf_qdec_ledpol_t pol) +{ + NRF_QDEC->LEDPOL = pol; +} + + +/** + * @brief Function for retrieving the active level for the LED. + * @return Active level for the LED. + */ +__STATIC_INLINE uint32_t nrf_qdec_ledpol_get(void) +{ + return NRF_QDEC->LEDPOL; +} + + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_qspi.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_qspi.h new file mode 100644 index 0000000000000000000000000000000000000000..72b2d7237a6772a27984361eedb8a082fac1f077 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_qspi.h @@ -0,0 +1,765 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @defgroup nrf_qspi_hal QSPI HAL + * @{ + * @ingroup nrf_qspi + * + * @brief Hardware access layer for accessing the QSPI peripheral. + */ + +#ifndef NRF_QSPI_H__ +#define NRF_QSPI_H__ + +#include +#include +#include "boards.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief This value can be used as a parameter for the @ref nrf_qspi_pins_set + * function to specify that a given QSPI signal (SCK, CSN, IO0, IO1, IO2, or IO3) + * will not be connected to a physical pin. + */ +#define NRF_QSPI_PIN_NOT_CONNECTED 0xFF + +/** + * @brief Macro for setting proper values to pin registers. + */ + +#define NRF_QSPI_PIN_VAL(pin) (pin) == NRF_QSPI_PIN_NOT_CONNECTED ? 0xFFFFFFFF : (pin) + +/** + * @brief QSPI tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_QSPI_TASK_ACTIVATE = offsetof(NRF_QSPI_Type, TASKS_ACTIVATE), /**< Activate the QSPI interface. */ + NRF_QSPI_TASK_READSTART = offsetof(NRF_QSPI_Type, TASKS_READSTART), /**< Start transfer from external flash memory to internal RAM. */ + NRF_QSPI_TASK_WRITESTART = offsetof(NRF_QSPI_Type, TASKS_WRITESTART), /**< Start transfer from internal RAM to external flash memory. */ + NRF_QSPI_TASK_ERASESTART = offsetof(NRF_QSPI_Type, TASKS_ERASESTART), /**< Start external flash memory erase operation. */ + /*lint -restore*/ +} nrf_qspi_task_t; + +/** + * @brief QSPI events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_QSPI_EVENT_READY = offsetof(NRF_QSPI_Type, EVENTS_READY) /**< QSPI peripheral is ready after it executes any task. */ + /*lint -restore*/ +} nrf_qspi_event_t; + +/** + * @brief QSPI interrupts. + */ +typedef enum +{ + NRF_QSPI_INT_READY_MASK = QSPI_INTENSET_READY_Msk /**< Interrupt on READY event. */ +} nrf_qspi_int_mask_t; + +/** + * @brief QSPI frequency divider values. + */ +typedef enum +{ + NRF_QSPI_FREQ_32MDIV1, /**< 32.0 MHz. */ + NRF_QSPI_FREQ_32MDIV2, /**< 16.0 MHz. */ + NRF_QSPI_FREQ_32MDIV3, /**< 10.6 MHz. */ + NRF_QSPI_FREQ_32MDIV4, /**< 8.00 MHz. */ + NRF_QSPI_FREQ_32MDIV5, /**< 6.40 MHz. */ + NRF_QSPI_FREQ_32MDIV6, /**< 5.33 MHz. */ + NRF_QSPI_FREQ_32MDIV7, /**< 4.57 MHz. */ + NRF_QSPI_FREQ_32MDIV8, /**< 4.00 MHz. */ + NRF_QSPI_FREQ_32MDIV9, /**< 3.55 MHz. */ + NRF_QSPI_FREQ_32MDIV10, /**< 3.20 MHz. */ + NRF_QSPI_FREQ_32MDIV11, /**< 2.90 MHz. */ + NRF_QSPI_FREQ_32MDIV12, /**< 2.66 MHz. */ + NRF_QSPI_FREQ_32MDIV13, /**< 2.46 MHz. */ + NRF_QSPI_FREQ_32MDIV14, /**< 2.29 MHz. */ + NRF_QSPI_FREQ_32MDIV15, /**< 2.13 MHz. */ + NRF_QSPI_FREQ_32MDIV16, /**< 2.00 MHz. */ +} nrf_qspi_frequency_t; + +/** + * @brief Interface configuration for a read operation. + */ +typedef enum +{ + NRF_QSPI_READOC_FASTREAD = QSPI_IFCONFIG0_READOC_FASTREAD, /**< Single data line SPI. FAST_READ (opcode 0x0B). */ + NRF_QSPI_READOC_READ2O = QSPI_IFCONFIG0_READOC_READ2O, /**< Dual data line SPI. READ2O (opcode 0x3B). */ + NRF_QSPI_READOC_READ2IO = QSPI_IFCONFIG0_READOC_READ2IO, /**< Dual data line SPI. READ2IO (opcode 0xBB). */ + NRF_QSPI_READOC_READ4O = QSPI_IFCONFIG0_READOC_READ4O, /**< Quad data line SPI. READ4O (opcode 0x6B). */ + NRF_QSPI_READOC_READ4IO = QSPI_IFCONFIG0_READOC_READ4IO /**< Quad data line SPI. READ4IO (opcode 0xEB). */ +} nrf_qspi_readoc_t; + +/** + * @brief Interface configuration for a write operation. + */ +typedef enum +{ + NRF_QSPI_WRITEOC_PP = QSPI_IFCONFIG0_WRITEOC_PP, /**< Single data line SPI. PP (opcode 0x02). */ + NRF_QSPI_WRITEOC_PP2O = QSPI_IFCONFIG0_WRITEOC_PP2O, /**< Dual data line SPI. PP2O (opcode 0xA2). */ + NRF_QSPI_WRITEOC_PP4O = QSPI_IFCONFIG0_WRITEOC_PP4O, /**< Quad data line SPI. PP4O (opcode 0x32). */ + NRF_QSPI_WRITEOC_PP4IO = QSPI_IFCONFIG0_WRITEOC_PP4IO, /**< Quad data line SPI. READ4O (opcode 0x38). */ +} nrf_qspi_writeoc_t; + +/** + * @brief Interface configuration for addressing mode. + */ +typedef enum +{ + NRF_QSPI_ADDRMODE_24BIT = QSPI_IFCONFIG0_ADDRMODE_24BIT, /**< 24-bit addressing. */ + NRF_QSPI_ADDRMODE_32BIT = QSPI_IFCONFIG0_ADDRMODE_32BIT /**< 32-bit addressing. */ +} nrf_qspi_addrmode_t; + +/** + * @brief QSPI SPI mode. Polarization and phase configuration. + */ +typedef enum +{ + NRF_QSPI_MODE_0 = QSPI_IFCONFIG1_SPIMODE_MODE0, /**< Mode 0 (CPOL=0, CPHA=0). */ + NRF_QSPI_MODE_1 = QSPI_IFCONFIG1_SPIMODE_MODE3 /**< Mode 1 (CPOL=1, CPHA=1). */ +} nrf_qspi_spi_mode_t; + +/** + * @brief Addressing configuration mode. + */ +typedef enum +{ + NRF_QSPI_ADDRCONF_MODE_NOINSTR = QSPI_ADDRCONF_MODE_NoInstr, /**< Do not send any instruction. */ + NRF_QSPI_ADDRCONF_MODE_OPCODE = QSPI_ADDRCONF_MODE_Opcode, /**< Send opcode. */ + NRF_QSPI_ADDRCONF_MODE_OPBYTE0 = QSPI_ADDRCONF_MODE_OpByte0, /**< Send opcode, byte0. */ + NRF_QSPI_ADDRCONF_MODE_ALL = QSPI_ADDRCONF_MODE_All /**< Send opcode, byte0, byte1. */ +} nrf_qspi_addrconfig_mode_t; + +/** + * @brief Erasing data length. + */ +typedef enum +{ + NRF_QSPI_ERASE_LEN_4KB = QSPI_ERASE_LEN_LEN_4KB, /**< Erase 4 kB block (flash command 0x20). */ + NRF_QSPI_ERASE_LEN_64KB = QSPI_ERASE_LEN_LEN_64KB, /**< Erase 64 kB block (flash command 0xD8). */ + NRF_QSPI_ERASE_LEN_ALL = QSPI_ERASE_LEN_LEN_All /**< Erase all (flash command 0xC7). */ +} nrf_qspi_erase_len_t; + +/** + * @brief Custom instruction length. + */ +typedef enum +{ + NRF_QSPI_CINSTR_LEN_1B = QSPI_CINSTRCONF_LENGTH_1B, /**< Send opcode only. */ + NRF_QSPI_CINSTR_LEN_2B = QSPI_CINSTRCONF_LENGTH_2B, /**< Send opcode, CINSTRDAT0.BYTE0. */ + NRF_QSPI_CINSTR_LEN_3B = QSPI_CINSTRCONF_LENGTH_3B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE1. */ + NRF_QSPI_CINSTR_LEN_4B = QSPI_CINSTRCONF_LENGTH_4B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE2. */ + NRF_QSPI_CINSTR_LEN_5B = QSPI_CINSTRCONF_LENGTH_5B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE3. */ + NRF_QSPI_CINSTR_LEN_6B = QSPI_CINSTRCONF_LENGTH_6B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE4. */ + NRF_QSPI_CINSTR_LEN_7B = QSPI_CINSTRCONF_LENGTH_7B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE5. */ + NRF_QSPI_CINSTR_LEN_8B = QSPI_CINSTRCONF_LENGTH_8B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE6. */ + NRF_QSPI_CINSTR_LEN_9B = QSPI_CINSTRCONF_LENGTH_9B /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE7. */ +} nrf_qspi_cinstr_len_t; + +/** + * @brief Pins configuration. + */ +typedef struct +{ + uint8_t sck_pin; /**< SCK pin number. */ + uint8_t csn_pin; /**< Chip select pin number. */ + uint8_t io0_pin; /**< IO0/MOSI pin number. */ + uint8_t io1_pin; /**< IO1/MISO pin number. */ + uint8_t io2_pin; /**< IO2 pin number (optional). + * Set to @ref NRF_QSPI_PIN_NOT_CONNECTED if this signal is not needed. + */ + uint8_t io3_pin; /**< IO3 pin number (optional). + * Set to @ref NRF_QSPI_PIN_NOT_CONNECTED if this signal is not needed. + */ +} nrf_qspi_pins_t; + +/** + * @brief Custom instruction configuration. + */ +typedef struct +{ + uint8_t opcode; /**< Opcode used in custom instruction transmission. */ + nrf_qspi_cinstr_len_t length; /**< Length of the custom instruction data. */ + bool io2_level; /**< I/O line level during transmission. */ + bool io3_level; /**< I/O line level during transmission. */ + bool wipwait; /**< Wait if a Wait in Progress bit is set in the memory status byte. */ + bool wren; /**< Send write enable before instruction. */ +} nrf_qspi_cinstr_conf_t; + +/** + * @brief Addressing mode register configuration. See @ref nrf_qspi_addrconfig_set + */ +typedef struct +{ + uint8_t opcode; /**< Opcode used to enter proper addressing mode. */ + uint8_t byte0; /**< Byte following the opcode. */ + uint8_t byte1; /**< Byte following byte0. */ + nrf_qspi_addrconfig_mode_t mode; /**< Extended addresing mode. */ + bool wipwait; /**< Enable/disable waiting for complete operation execution. */ + bool wren; /**< Send write enable before instruction. */ +} nrf_qspi_addrconfig_conf_t; + +/** + * @brief Structure with QSPI protocol interface configuration. + */ +typedef struct +{ + nrf_qspi_readoc_t readoc; /**< Read operation code. */ + nrf_qspi_writeoc_t writeoc; /**< Write operation code. */ + nrf_qspi_addrmode_t addrmode; /**< Addresing mode (24-bit or 32-bit). */ + bool dpmconfig; /**< Enable the Deep Power-down Mode (DPM) feature. */ +} nrf_qspi_prot_conf_t; + +/** + * @brief QSPI physical interface configuration. + */ +typedef struct +{ + uint8_t sck_delay; /**< tSHSL, tWHSL, and tSHWL in number of 16 MHz periods (62.5ns). */ + bool dpmen; /**< Enable the DPM feature. */ + nrf_qspi_spi_mode_t spi_mode; /**< SPI phase and polarization. */ + nrf_qspi_frequency_t sck_freq; /**< SCK frequency given as enum @ref nrf_qspi_frequency_t. */ +} nrf_qspi_phy_conf_t; + +/** + * @brief Function for activating a specific QSPI task. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_qspi_task_trigger(NRF_QSPI_Type * p_reg, nrf_qspi_task_t task); + +/** + * @brief Function for getting the address of a specific QSPI task register. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t nrf_qspi_task_address_get(NRF_QSPI_Type const * p_reg, + nrf_qspi_task_t task); + +/** + * @brief Function for clearing a specific QSPI event. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] qspi_event Event to clear. + */ +__STATIC_INLINE void nrf_qspi_event_clear(NRF_QSPI_Type * p_reg, nrf_qspi_event_t qspi_event); + +/** + * @brief Function for checking the state of a specific SPI event. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] qspi_event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_qspi_event_check(NRF_QSPI_Type const * p_reg, nrf_qspi_event_t qspi_event); + +/** + * @brief Function for getting the address of a specific QSPI event register. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] qspi_event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t * nrf_qspi_event_address_get(NRF_QSPI_Type const * p_reg, + nrf_qspi_event_t qspi_event); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] qspi_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_qspi_int_enable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] qspi_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_qspi_int_disable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] qspi_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_qspi_int_enable_check(NRF_QSPI_Type const * p_reg, + nrf_qspi_int_mask_t qspi_int); + +/** + * @brief Function for enabling the QSPI peripheral. + * + * @param[in] p_reg Pointer to the peripheral register structure. + */ +__STATIC_INLINE void nrf_qspi_enable(NRF_QSPI_Type * p_reg); + +/** + * @brief Function for disabling the QSPI peripheral. + * + * @param[in] p_reg Pointer to the peripheral register structure. + */ +__STATIC_INLINE void nrf_qspi_disable(NRF_QSPI_Type * p_reg); + +/** + * @brief Function for configuring QSPI pins. + * + * If a given signal is not needed, pass the @ref NRF_QSPI_PIN_NOT_CONNECTED + * value instead of its pin number. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] p_pins Pointer to the pins configuration structure. See @ref nrf_qspi_pins_t. + */ +__STATIC_INLINE void nrf_qspi_pins_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_pins_t * p_pins); + +/** + * @brief Function for setting the QSPI IFCONFIG0 register. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] p_config Pointer to the QSPI protocol interface configuration structure. See @ref nrf_qspi_prot_conf_t. + */ +__STATIC_INLINE void nrf_qspi_ifconfig0_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_prot_conf_t * p_config); + +/** + * @brief Function for setting the QSPI IFCONFIG1 register. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] p_config Pointer to the QSPI physical interface configuration structure. See @ref nrf_qspi_phy_conf_t. + */ +__STATIC_INLINE void nrf_qspi_ifconfig1_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_phy_conf_t * p_config); + +/** + * @brief Function for setting the QSPI ADDRCONF register. + * + * Function must be executed before sending task NRF_QSPI_TASK_ACTIVATE. Data stored in the structure + * is sent during the start of the peripheral. Remember that the reset instruction can set + * addressing mode to default in the memory device. If memory reset is necessary before configuring + * the addressing mode, use custom instruction feature instead of this function. + * Case with reset: Enable the peripheral without setting ADDRCONF register, send reset instructions + * using a custom instruction feature (reset enable and then reset), set proper addressing mode + * using the custom instruction feature. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] p_config Pointer to the addressing mode configuration structure. See @ref nrf_qspi_addrconfig_conf_t. +*/ +__STATIC_INLINE void nrf_qspi_addrconfig_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_addrconfig_conf_t * p_config); + +/** + * @brief Function for setting write data into the peripheral register (without starting the process). + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] p_buffer Pointer to the writing buffer. + * @param[in] length Lenght of the writing data. + * @param[in] dest_addr Address in memory to write to. + */ +__STATIC_INLINE void nrf_qspi_write_buffer_set(NRF_QSPI_Type * p_reg, + void const * p_buffer, + uint32_t length, + uint32_t dest_addr); + +/** + * @brief Function for setting read data into the peripheral register (without starting the process). + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[out] p_buffer Pointer to the reading buffer. + * @param[in] length Length of the read data. + * @param[in] src_addr Address in memory to read from. + */ +__STATIC_INLINE void nrf_qspi_read_buffer_set(NRF_QSPI_Type * p_reg, + void * p_buffer, + uint32_t length, + uint32_t src_addr); + +/** + * @brief Function for setting erase data into the peripheral register (without starting the process). + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] erase_addr Start address to erase. Address must have padding set to 4 bytes. + * @param[in] len Size of erasing area. + */ +__STATIC_INLINE void nrf_qspi_erase_ptr_set(NRF_QSPI_Type * p_reg, + uint32_t erase_addr, + nrf_qspi_erase_len_t len); + +/** + * @brief Function for getting the peripheral status register. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * + * @return Peripheral status register. + */ +__STATIC_INLINE uint32_t nrf_qspi_status_reg_get(NRF_QSPI_Type const * p_reg); + +/** + * @brief Function for getting the device status register stored in the peripheral status register. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * + * @return Device status register (lower byte). + */ +__STATIC_INLINE uint8_t nrf_qspi_sreg_get(NRF_QSPI_Type const * p_reg); + +/** + * @brief Function for checking if the peripheral is busy or not. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * + * @retval true If QSPI is busy. + * @retval false If QSPI is ready. + */ +__STATIC_INLINE bool nrf_qspi_busy_check(NRF_QSPI_Type const * p_reg); + +/** + * @brief Function for setting registers sending with custom instruction transmission. + * + * This function can be ommited when using NRF_QSPI_CINSTR_LEN_1B as the length argument + * (sending only opcode without data). + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] length Length of the custom instruction data. + * @param[in] p_tx_data Pointer to the data to send with the custom instruction. + */ +__STATIC_INLINE void nrf_qspi_cinstrdata_set(NRF_QSPI_Type * p_reg, + nrf_qspi_cinstr_len_t length, + void const * p_tx_data); + +/** + * @brief Function for getting data from register after custom instruction transmission. + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] length Length of the custom instruction data. + * @param[in] p_rx_data Pointer to the reading buffer. + */ +__STATIC_INLINE void nrf_qspi_cinstrdata_get(NRF_QSPI_Type const * p_reg, + nrf_qspi_cinstr_len_t length, + void * p_rx_data); + +/** + * @brief Function for sending custom instruction to external memory. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] p_config Pointer to the custom instruction configuration structure. See @ref nrf_qspi_cinstr_conf_t. + */ + +__STATIC_INLINE void nrf_qspi_cinstr_transfer_start(NRF_QSPI_Type * p_reg, + const nrf_qspi_cinstr_conf_t * p_config); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_qspi_task_trigger(NRF_QSPI_Type * p_reg, nrf_qspi_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_qspi_task_address_get(NRF_QSPI_Type const * p_reg, + nrf_qspi_task_t task) +{ + return ((uint32_t)p_reg + (uint32_t)task); +} + +__STATIC_INLINE void nrf_qspi_event_clear(NRF_QSPI_Type * p_reg, nrf_qspi_event_t qspi_event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)qspi_event)) = 0x0UL; +} + +__STATIC_INLINE bool nrf_qspi_event_check(NRF_QSPI_Type const * p_reg, nrf_qspi_event_t qspi_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)qspi_event); +} + +__STATIC_INLINE uint32_t * nrf_qspi_event_address_get(NRF_QSPI_Type const * p_reg, + nrf_qspi_event_t qspi_event) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)qspi_event); +} + +__STATIC_INLINE void nrf_qspi_int_enable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask) +{ + p_reg->INTENSET = qspi_int_mask; +} + +__STATIC_INLINE void nrf_qspi_int_disable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask) +{ + p_reg->INTENCLR = qspi_int_mask; +} + +__STATIC_INLINE bool nrf_qspi_int_enable_check(NRF_QSPI_Type const * p_reg, + nrf_qspi_int_mask_t qspi_int) +{ + return (bool)(p_reg->INTENSET & qspi_int); +} + +__STATIC_INLINE void nrf_qspi_enable(NRF_QSPI_Type * p_reg) +{ + p_reg->ENABLE = (QSPI_ENABLE_ENABLE_Enabled << QSPI_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_qspi_disable(NRF_QSPI_Type * p_reg) +{ + p_reg->ENABLE = (QSPI_ENABLE_ENABLE_Disabled << QSPI_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_qspi_pins_set(NRF_QSPI_Type * p_reg, const nrf_qspi_pins_t * p_pins) +{ + p_reg->PSEL.SCK = NRF_QSPI_PIN_VAL(p_pins->sck_pin); + p_reg->PSEL.CSN = NRF_QSPI_PIN_VAL(p_pins->csn_pin); + p_reg->PSEL.IO0 = NRF_QSPI_PIN_VAL(p_pins->io0_pin); + p_reg->PSEL.IO1 = NRF_QSPI_PIN_VAL(p_pins->io1_pin); + p_reg->PSEL.IO2 = NRF_QSPI_PIN_VAL(p_pins->io2_pin); + p_reg->PSEL.IO3 = NRF_QSPI_PIN_VAL(p_pins->io3_pin); +} + +__STATIC_INLINE void nrf_qspi_ifconfig0_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_prot_conf_t * p_config) +{ + uint32_t config = p_config->readoc; + config |= ((uint32_t)p_config->writeoc) << QSPI_IFCONFIG0_WRITEOC_Pos; + config |= ((uint32_t)p_config->addrmode) << QSPI_IFCONFIG0_ADDRMODE_Pos; + config |= (p_config->dpmconfig ? 1U : 0U ) << QSPI_IFCONFIG0_DPMENABLE_Pos; + + p_reg->IFCONFIG0 = config; +} + +__STATIC_INLINE void nrf_qspi_ifconfig1_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_phy_conf_t * p_config) +{ + // IFCONFIG1 mask for reserved fields in the register. + uint32_t config = p_reg->IFCONFIG1 & 0x00FFFF00; + config |= p_config->sck_delay; + config |= (p_config->dpmen ? 1U : 0U) << QSPI_IFCONFIG1_DPMEN_Pos; + config |= ((uint32_t)(p_config->spi_mode)) << QSPI_IFCONFIG1_SPIMODE_Pos; + config |= ((uint32_t)(p_config->sck_freq)) << QSPI_IFCONFIG1_SCKFREQ_Pos; + + p_reg->IFCONFIG1 = config; +} + +__STATIC_INLINE void nrf_qspi_addrconfig_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_addrconfig_conf_t * p_config) +{ + uint32_t config = p_config->opcode; + config |= ((uint32_t)p_config->byte0) << QSPI_ADDRCONF_BYTE0_Pos; + config |= ((uint32_t)p_config->byte1) << QSPI_ADDRCONF_BYTE1_Pos; + config |= ((uint32_t)(p_config->mode)) << QSPI_ADDRCONF_MODE_Pos; + config |= (p_config->wipwait ? 1U : 0U) << QSPI_ADDRCONF_WIPWAIT_Pos; + config |= (p_config->wren ? 1U : 0U) << QSPI_ADDRCONF_WREN_Pos; + + p_reg->ADDRCONF = config; +} + +__STATIC_INLINE void nrf_qspi_write_buffer_set(NRF_QSPI_Type * p_reg, + void const * p_buffer, + uint32_t length, + uint32_t dest_addr) +{ + p_reg->WRITE.DST = dest_addr; + p_reg->WRITE.SRC = (uint32_t) p_buffer; + p_reg->WRITE.CNT = length; +} + +__STATIC_INLINE void nrf_qspi_read_buffer_set(NRF_QSPI_Type * p_reg, + void * p_buffer, + uint32_t length, + uint32_t src_addr) +{ + p_reg->READ.SRC = src_addr; + p_reg->READ.DST = (uint32_t) p_buffer; + p_reg->READ.CNT = length; +} + +__STATIC_INLINE void nrf_qspi_erase_ptr_set(NRF_QSPI_Type * p_reg, + uint32_t erase_addr, + nrf_qspi_erase_len_t len) +{ + p_reg->ERASE.PTR = erase_addr; + p_reg->ERASE.LEN = len; +} + +__STATIC_INLINE uint32_t nrf_qspi_status_reg_get(NRF_QSPI_Type const * p_reg) +{ + return p_reg->STATUS; +} + +__STATIC_INLINE uint8_t nrf_qspi_sreg_get(NRF_QSPI_Type const * p_reg) +{ + return (uint8_t)(p_reg->STATUS & QSPI_STATUS_SREG_Msk) >> QSPI_STATUS_SREG_Pos; +} + +__STATIC_INLINE bool nrf_qspi_busy_check(NRF_QSPI_Type const * p_reg) +{ + return ((p_reg->STATUS & QSPI_STATUS_READY_Msk) >> + QSPI_STATUS_READY_Pos) == QSPI_STATUS_READY_BUSY; +} + +__STATIC_INLINE void nrf_qspi_cinstrdata_set(NRF_QSPI_Type * p_reg, + nrf_qspi_cinstr_len_t length, + void const * p_tx_data) +{ + uint32_t reg = 0; + uint8_t const *p_tx_data_8 = (uint8_t const *) p_tx_data; + + // Load custom instruction. + switch (length) + { + case NRF_QSPI_CINSTR_LEN_9B: + reg |= ((uint32_t)p_tx_data_8[7]) << QSPI_CINSTRDAT1_BYTE7_Pos; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_8B: + reg |= ((uint32_t)p_tx_data_8[6]) << QSPI_CINSTRDAT1_BYTE6_Pos; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_7B: + reg |= ((uint32_t)p_tx_data_8[5]) << QSPI_CINSTRDAT1_BYTE5_Pos; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_6B: + reg |= ((uint32_t)p_tx_data_8[4]); + p_reg->CINSTRDAT1 = reg; + reg = 0; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_5B: + reg |= ((uint32_t)p_tx_data_8[3]) << QSPI_CINSTRDAT0_BYTE3_Pos; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_4B: + reg |= ((uint32_t)p_tx_data_8[2]) << QSPI_CINSTRDAT0_BYTE2_Pos; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_3B: + reg |= ((uint32_t)p_tx_data_8[1]) << QSPI_CINSTRDAT0_BYTE1_Pos; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_2B: + reg |= ((uint32_t)p_tx_data_8[0]); + p_reg->CINSTRDAT0 = reg; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_1B: + /* Send only opcode. Case to avoid compiler warnings. */ + break; + default: + break; + } +} + +__STATIC_INLINE void nrf_qspi_cinstrdata_get(NRF_QSPI_Type const * p_reg, + nrf_qspi_cinstr_len_t length, + void * p_rx_data) +{ + uint8_t *p_rx_data_8 = (uint8_t *) p_rx_data; + + uint32_t reg = p_reg->CINSTRDAT1; + switch (length) + { + case NRF_QSPI_CINSTR_LEN_9B: + p_rx_data_8[7] = (uint8_t)(reg >> QSPI_CINSTRDAT1_BYTE7_Pos); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_8B: + p_rx_data_8[6] = (uint8_t)(reg >> QSPI_CINSTRDAT1_BYTE6_Pos); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_7B: + p_rx_data_8[5] = (uint8_t)(reg >> QSPI_CINSTRDAT1_BYTE5_Pos); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_6B: + p_rx_data_8[4] = (uint8_t)(reg); + /* fall-through */ + default: + break; + } + + reg = p_reg->CINSTRDAT0; + switch (length) + { + case NRF_QSPI_CINSTR_LEN_5B: + p_rx_data_8[3] = (uint8_t)(reg >> QSPI_CINSTRDAT0_BYTE3_Pos); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_4B: + p_rx_data_8[2] = (uint8_t)(reg >> QSPI_CINSTRDAT0_BYTE2_Pos); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_3B: + p_rx_data_8[1] = (uint8_t)(reg >> QSPI_CINSTRDAT0_BYTE1_Pos); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_2B: + p_rx_data_8[0] = (uint8_t)(reg); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_1B: + /* Send only opcode. Case to avoid compiler warnings. */ + break; + default: + break; + } +} + +__STATIC_INLINE void nrf_qspi_cinstr_transfer_start(NRF_QSPI_Type * p_reg, + const nrf_qspi_cinstr_conf_t * p_config) +{ + p_reg->CINSTRCONF = (((uint32_t)p_config->opcode << QSPI_CINSTRCONF_OPCODE_Pos) | + ((uint32_t)p_config->length << QSPI_CINSTRCONF_LENGTH_Pos) | + ((uint32_t)p_config->io2_level << QSPI_CINSTRCONF_LIO2_Pos) | + ((uint32_t)p_config->io3_level << QSPI_CINSTRCONF_LIO3_Pos) | + ((uint32_t)p_config->wipwait << QSPI_CINSTRCONF_WIPWAIT_Pos) | + ((uint32_t)p_config->wren << QSPI_CINSTRCONF_WREN_Pos)); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +#ifdef __cplusplus +} +#endif + +#endif // NRF_QSPI_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_rng.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_rng.h new file mode 100644 index 0000000000000000000000000000000000000000..9ebf81748a1302bdf97a8cc09ff1fe5f6d5fa14b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_rng.h @@ -0,0 +1,282 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief RNG HAL API. + */ + +#ifndef NRF_RNG_H__ +#define NRF_RNG_H__ +/** + * @defgroup nrf_rng_hal RNG HAL + * @{ + * @ingroup nrf_rng + * @brief Hardware access layer for managing the random number generator (RNG). + */ + +#include +#include +#include +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_RNG_TASK_SET (1UL) +#define NRF_RNG_EVENT_CLEAR (0UL) +/** + * @enum nrf_rng_task_t + * @brief RNG tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_RNG_TASK_START = offsetof(NRF_RNG_Type, TASKS_START), /**< Start the random number generator. */ + NRF_RNG_TASK_STOP = offsetof(NRF_RNG_Type, TASKS_STOP) /**< Stop the random number generator. */ +} nrf_rng_task_t; /*lint -restore */ + +/** + * @enum nrf_rng_event_t + * @brief RNG events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_RNG_EVENT_VALRDY = offsetof(NRF_RNG_Type, EVENTS_VALRDY) /**< New random number generated event. */ +} nrf_rng_event_t; /*lint -restore */ + +/** + * @enum nrf_rng_int_mask_t + * @brief RNG interrupts. + */ +typedef enum +{ + NRF_RNG_INT_VALRDY_MASK = RNG_INTENSET_VALRDY_Msk /**< Mask for enabling or disabling an interrupt on VALRDY event. */ +} nrf_rng_int_mask_t; + +/** + * @enum nrf_rng_short_mask_t + * @brief Types of RNG shortcuts. + */ +typedef enum +{ + NRF_RNG_SHORT_VALRDY_STOP_MASK = RNG_SHORTS_VALRDY_STOP_Msk /**< Mask for setting shortcut between EVENT_VALRDY and TASK_STOP. */ +} nrf_rng_short_mask_t; + +/** + * @brief Function for enabling interrupts. + * + * @param[in] rng_int_mask Mask of interrupts. + */ +__STATIC_INLINE void nrf_rng_int_enable(uint32_t rng_int_mask); + +/** + * @brief Function for disabling interrupts. + * + * @param[in] rng_int_mask Mask of interrupts. + */ +__STATIC_INLINE void nrf_rng_int_disable(uint32_t rng_int_mask); + +/** + * @brief Function for getting the state of a specific interrupt. + * + * @param[in] rng_int_mask Interrupt. + * + * @retval true If the interrupt is not enabled. + * @retval false If the interrupt is enabled. + */ +__STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t rng_int_mask); + +/** + * @brief Function for getting the address of a specific task. + * + * This function can be used by the PPI module. + * + * @param[in] rng_task Task. + */ +__STATIC_INLINE uint32_t * nrf_rng_task_address_get(nrf_rng_task_t rng_task); + +/** + * @brief Function for setting a specific task. + * + * @param[in] rng_task Task. + */ +__STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task); + +/** + * @brief Function for getting address of a specific event. + * + * This function can be used by the PPI module. + * + * @param[in] rng_event Event. + */ +__STATIC_INLINE uint32_t * nrf_rng_event_address_get(nrf_rng_event_t rng_event); + +/** + * @brief Function for clearing a specific event. + * + * @param[in] rng_event Event. + */ +__STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event); + +/** + * @brief Function for getting the state of a specific event. + * + * @param[in] rng_event Event. + * + * @retval true If the event is not set. + * @retval false If the event is set. + */ +__STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event); + +/** + * @brief Function for setting shortcuts. + * + * @param[in] rng_short_mask Mask of shortcuts. + * + */ +__STATIC_INLINE void nrf_rng_shorts_enable(uint32_t rng_short_mask); + +/** + * @brief Function for clearing shortcuts. + * + * @param[in] rng_short_mask Mask of shortcuts. + * + */ +__STATIC_INLINE void nrf_rng_shorts_disable(uint32_t rng_short_mask); + +/** + * @brief Function for getting the previously generated random value. + * + * @return Previously generated random value. + */ +__STATIC_INLINE uint8_t nrf_rng_random_value_get(void); + +/** + * @brief Function for enabling digital error correction. + */ +__STATIC_INLINE void nrf_rng_error_correction_enable(void); + +/** + * @brief Function for disabling digital error correction. + */ +__STATIC_INLINE void nrf_rng_error_correction_disable(void); + +/** + *@} + **/ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_rng_int_enable(uint32_t rng_int_mask) +{ + NRF_RNG->INTENSET = rng_int_mask; +} + +__STATIC_INLINE void nrf_rng_int_disable(uint32_t rng_int_mask) +{ + NRF_RNG->INTENCLR = rng_int_mask; +} + +__STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t rng_int_mask) +{ + return (bool)(NRF_RNG->INTENCLR & rng_int_mask); +} + +__STATIC_INLINE uint32_t * nrf_rng_task_address_get(nrf_rng_task_t rng_task) +{ + return (uint32_t *)((uint8_t *)NRF_RNG + rng_task); +} + +__STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_task)) = NRF_RNG_TASK_SET; +} + +__STATIC_INLINE uint32_t * nrf_rng_event_address_get(nrf_rng_event_t rng_event) +{ + return (uint32_t *)((uint8_t *)NRF_RNG + rng_event); +} + +__STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)) = NRF_RNG_EVENT_CLEAR; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event) +{ + return (bool) * ((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)); +} + +__STATIC_INLINE void nrf_rng_shorts_enable(uint32_t rng_short_mask) +{ + NRF_RNG->SHORTS |= rng_short_mask; +} + +__STATIC_INLINE void nrf_rng_shorts_disable(uint32_t rng_short_mask) +{ + NRF_RNG->SHORTS &= ~rng_short_mask; +} + +__STATIC_INLINE uint8_t nrf_rng_random_value_get(void) +{ + return (uint8_t)(NRF_RNG->VALUE & RNG_VALUE_VALUE_Msk); +} + +__STATIC_INLINE void nrf_rng_error_correction_enable(void) +{ + NRF_RNG->CONFIG |= RNG_CONFIG_DERCEN_Msk; +} + +__STATIC_INLINE void nrf_rng_error_correction_disable(void) +{ + NRF_RNG->CONFIG &= ~RNG_CONFIG_DERCEN_Msk; +} + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_RNG_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_rtc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..bca028f12bba2812dc0e8a46a4b1df30b62757b7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_rtc.h @@ -0,0 +1,343 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief RTC HAL API. + */ + +#ifndef NRF_RTC_H +#define NRF_RTC_H + +/** + * @defgroup nrf_rtc_hal RTC HAL + * @{ + * @ingroup nrf_rtc + * @brief Hardware access layer for managing the real time counter (RTC). + */ + +#include +#include +#include +#include "nrf.h" +#include "nrf_assert.h" +#include "nrf_peripherals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Macro for getting the number of compare channels available + * in a given RTC instance. + */ + +#define NRF_RTC_CC_CHANNEL_COUNT(id) CONCAT_3(RTC, id, _CC_NUM) + +#define RTC_INPUT_FREQ 32768 /**< Input frequency of the RTC instance. */ + +/** + * @brief Macro for converting expected frequency to prescaler setting. + */ +#define RTC_FREQ_TO_PRESCALER(FREQ) (uint16_t)((RTC_INPUT_FREQ / (FREQ)) - 1) + +/**< Macro for wrapping values to RTC capacity. */ +#define RTC_WRAP(val) (val & RTC_COUNTER_COUNTER_Msk) + +#define RTC_CHANNEL_INT_MASK(ch) ((uint32_t)NRF_RTC_INT_COMPARE0_MASK << ch) +#define RTC_CHANNEL_EVENT_ADDR(ch) (nrf_rtc_event_t)(NRF_RTC_EVENT_COMPARE_0 + ch * sizeof(uint32_t)) +/** + * @enum nrf_rtc_task_t + * @brief RTC tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_RTC_TASK_START = offsetof(NRF_RTC_Type,TASKS_START), /**< Start. */ + NRF_RTC_TASK_STOP = offsetof(NRF_RTC_Type,TASKS_STOP), /**< Stop. */ + NRF_RTC_TASK_CLEAR = offsetof(NRF_RTC_Type,TASKS_CLEAR), /**< Clear. */ + NRF_RTC_TASK_TRIGGER_OVERFLOW = offsetof(NRF_RTC_Type,TASKS_TRIGOVRFLW),/**< Trigger overflow. */ + /*lint -restore*/ +} nrf_rtc_task_t; + +/** + * @enum nrf_rtc_event_t + * @brief RTC events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_RTC_EVENT_TICK = offsetof(NRF_RTC_Type,EVENTS_TICK), /**< Tick event. */ + NRF_RTC_EVENT_OVERFLOW = offsetof(NRF_RTC_Type,EVENTS_OVRFLW), /**< Overflow event. */ + NRF_RTC_EVENT_COMPARE_0 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[0]), /**< Compare 0 event. */ + NRF_RTC_EVENT_COMPARE_1 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[1]), /**< Compare 1 event. */ + NRF_RTC_EVENT_COMPARE_2 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[2]), /**< Compare 2 event. */ + NRF_RTC_EVENT_COMPARE_3 = offsetof(NRF_RTC_Type,EVENTS_COMPARE[3]) /**< Compare 3 event. */ + /*lint -restore*/ +} nrf_rtc_event_t; + +/** + * @enum nrf_rtc_int_t + * @brief RTC interrupts. + */ +typedef enum +{ + NRF_RTC_INT_TICK_MASK = RTC_INTENSET_TICK_Msk, /**< RTC interrupt from tick event. */ + NRF_RTC_INT_OVERFLOW_MASK = RTC_INTENSET_OVRFLW_Msk, /**< RTC interrupt from overflow event. */ + NRF_RTC_INT_COMPARE0_MASK = RTC_INTENSET_COMPARE0_Msk, /**< RTC interrupt from compare event on channel 0. */ + NRF_RTC_INT_COMPARE1_MASK = RTC_INTENSET_COMPARE1_Msk, /**< RTC interrupt from compare event on channel 1. */ + NRF_RTC_INT_COMPARE2_MASK = RTC_INTENSET_COMPARE2_Msk, /**< RTC interrupt from compare event on channel 2. */ + NRF_RTC_INT_COMPARE3_MASK = RTC_INTENSET_COMPARE3_Msk /**< RTC interrupt from compare event on channel 3. */ +} nrf_rtc_int_t; + +/**@brief Function for setting a compare value for a channel. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] ch Channel. + * @param[in] cc_val Compare value to set. + */ +__STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_rtc, uint32_t ch, uint32_t cc_val); + +/**@brief Function for returning the compare value for a channel. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] ch Channel. + * + * @return COMPARE[ch] value. + */ +__STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_rtc, uint32_t ch); + +/**@brief Function for enabling interrupts. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] mask Interrupt mask to be enabled. + */ +__STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_rtc, uint32_t mask); + +/**@brief Function for disabling interrupts. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] mask Interrupt mask to be disabled. + */ +__STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_rtc, uint32_t mask); + +/**@brief Function for checking if interrupts are enabled. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] mask Mask of interrupt flags to check. + * + * @return Mask with enabled interrupts. + */ +__STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_rtc, uint32_t mask); + +/**@brief Function for returning the status of currently enabled interrupts. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * + * @return Value in INTEN register. + */ +__STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_rtc); + +/**@brief Function for checking if an event is pending. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] event Address of the event. + * + * @return Mask of pending events. + */ +__STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event); + +/**@brief Function for clearing an event. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event); + +/**@brief Function for returning a counter value. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * + * @return Counter value. + */ +__STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_rtc); + +/**@brief Function for setting a prescaler value. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] val Value to set the prescaler to. + */ +__STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_rtc, uint32_t val); + +/**@brief Function for returning the address of an event. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] event Requested event. + * + * @return Address of the requested event register. + */ +__STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event); + +/**@brief Function for returning the address of a task. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] task Requested task. + * + * @return Address of the requested task register. + */ +__STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task); + +/**@brief Function for starting a task. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] task Requested task. + */ +__STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task); + +/**@brief Function for enabling events. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] mask Mask of event flags to enable. + */ +__STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_rtc, uint32_t mask); + +/**@brief Function for disabling an event. + * + * @param[in] p_rtc Pointer to the peripheral registers structure. + * @param[in] event Requested event. + */ +__STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_rtc, uint32_t event); + +/** + *@} + **/ + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_rtc, uint32_t ch, uint32_t cc_val) +{ + p_rtc->CC[ch] = cc_val; +} + +__STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_rtc, uint32_t ch) +{ + return p_rtc->CC[ch]; +} + +__STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_rtc, uint32_t mask) +{ + p_rtc->INTENSET = mask; +} + +__STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_rtc, uint32_t mask) +{ + p_rtc->INTENCLR = mask; +} + +__STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_rtc, uint32_t mask) +{ + return (p_rtc->INTENSET & mask); +} + +__STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_rtc) +{ + return p_rtc->INTENSET; +} + +__STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event) +{ + return *(volatile uint32_t *)((uint8_t *)p_rtc + (uint32_t)event); +} + +__STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_rtc + (uint32_t)event)) = 0; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_rtc + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_rtc) +{ + return p_rtc->COUNTER; +} + +__STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_rtc, uint32_t val) +{ + ASSERT(val <= (RTC_PRESCALER_PRESCALER_Msk >> RTC_PRESCALER_PRESCALER_Pos)); + p_rtc->PRESCALER = val; +} +__STATIC_INLINE uint32_t rtc_prescaler_get(NRF_RTC_Type * p_rtc) +{ + return p_rtc->PRESCALER; +} + +__STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event) +{ + return (uint32_t)p_rtc + event; +} + +__STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task) +{ + return (uint32_t)p_rtc + task; +} + +__STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task) +{ + *(__IO uint32_t *)((uint32_t)p_rtc + task) = 1; +} + +__STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_rtc, uint32_t mask) +{ + p_rtc->EVTENSET = mask; +} +__STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_rtc, uint32_t mask) +{ + p_rtc->EVTENCLR = mask; +} +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_RTC_H */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_saadc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_saadc.c new file mode 100644 index 0000000000000000000000000000000000000000..c028eaa49e7c9078b4f4719f6c1b1b47fe778974 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_saadc.c @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief SAADC HAL implementation + */ +#include "sdk_config.h" +#if SAADC_ENABLED +#include "nrf_saadc.h" + +void nrf_saadc_channel_init(uint8_t channel, nrf_saadc_channel_config_t const * const config) +{ + NRF_SAADC->CH[channel].CONFIG = + ((config->resistor_p << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk) + | ((config->resistor_n << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk) + | ((config->gain << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk) + | ((config->reference << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk) + | ((config->acq_time << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk) + | ((config->mode << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk) + | ((config->burst << SAADC_CH_CONFIG_BURST_Pos) & SAADC_CH_CONFIG_BURST_Msk); + nrf_saadc_channel_input_set(channel, config->pin_p, config->pin_n); + return; +} +#endif //SAADC_ENABLED + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_saadc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_saadc.h new file mode 100644 index 0000000000000000000000000000000000000000..73eb8128b186ef8ef3f00e6b8f364efbb457f014 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_saadc.h @@ -0,0 +1,609 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SAADC_H_ +#define NRF_SAADC_H_ + +/** + * @defgroup nrf_saadc_hal SAADC HAL + * @{ + * @ingroup nrf_saadc + * + * @brief @tagAPI52 Hardware access layer for accessing the SAADC peripheral. + */ + +#include +#include +#include "nrf.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_SAADC_CHANNEL_COUNT 8 + +/** + * @brief Resolution of the analog-to-digital converter. + */ +typedef enum +{ + NRF_SAADC_RESOLUTION_8BIT = SAADC_RESOLUTION_VAL_8bit, ///< 8 bit resolution. + NRF_SAADC_RESOLUTION_10BIT = SAADC_RESOLUTION_VAL_10bit, ///< 10 bit resolution. + NRF_SAADC_RESOLUTION_12BIT = SAADC_RESOLUTION_VAL_12bit, ///< 12 bit resolution. + NRF_SAADC_RESOLUTION_14BIT = SAADC_RESOLUTION_VAL_14bit ///< 14 bit resolution. +} nrf_saadc_resolution_t; + + +/** + * @brief Input selection for the analog-to-digital converter. + */ +typedef enum +{ + NRF_SAADC_INPUT_DISABLED = SAADC_CH_PSELP_PSELP_NC, ///< Not connected. + NRF_SAADC_INPUT_AIN0 = SAADC_CH_PSELP_PSELP_AnalogInput0, ///< Analog input 0 (AIN0). + NRF_SAADC_INPUT_AIN1 = SAADC_CH_PSELP_PSELP_AnalogInput1, ///< Analog input 1 (AIN1). + NRF_SAADC_INPUT_AIN2 = SAADC_CH_PSELP_PSELP_AnalogInput2, ///< Analog input 2 (AIN2). + NRF_SAADC_INPUT_AIN3 = SAADC_CH_PSELP_PSELP_AnalogInput3, ///< Analog input 3 (AIN3). + NRF_SAADC_INPUT_AIN4 = SAADC_CH_PSELP_PSELP_AnalogInput4, ///< Analog input 4 (AIN4). + NRF_SAADC_INPUT_AIN5 = SAADC_CH_PSELP_PSELP_AnalogInput5, ///< Analog input 5 (AIN5). + NRF_SAADC_INPUT_AIN6 = SAADC_CH_PSELP_PSELP_AnalogInput6, ///< Analog input 6 (AIN6). + NRF_SAADC_INPUT_AIN7 = SAADC_CH_PSELP_PSELP_AnalogInput7, ///< Analog input 7 (AIN7). + NRF_SAADC_INPUT_VDD = SAADC_CH_PSELP_PSELP_VDD ///< VDD as input. +} nrf_saadc_input_t; + + +/** + * @brief Analog-to-digital converter oversampling mode. + */ +typedef enum +{ + NRF_SAADC_OVERSAMPLE_DISABLED = SAADC_OVERSAMPLE_OVERSAMPLE_Bypass, ///< No oversampling. + NRF_SAADC_OVERSAMPLE_2X = SAADC_OVERSAMPLE_OVERSAMPLE_Over2x, ///< Oversample 2x. + NRF_SAADC_OVERSAMPLE_4X = SAADC_OVERSAMPLE_OVERSAMPLE_Over4x, ///< Oversample 4x. + NRF_SAADC_OVERSAMPLE_8X = SAADC_OVERSAMPLE_OVERSAMPLE_Over8x, ///< Oversample 8x. + NRF_SAADC_OVERSAMPLE_16X = SAADC_OVERSAMPLE_OVERSAMPLE_Over16x, ///< Oversample 16x. + NRF_SAADC_OVERSAMPLE_32X = SAADC_OVERSAMPLE_OVERSAMPLE_Over32x, ///< Oversample 32x. + NRF_SAADC_OVERSAMPLE_64X = SAADC_OVERSAMPLE_OVERSAMPLE_Over64x, ///< Oversample 64x. + NRF_SAADC_OVERSAMPLE_128X = SAADC_OVERSAMPLE_OVERSAMPLE_Over128x, ///< Oversample 128x. + NRF_SAADC_OVERSAMPLE_256X = SAADC_OVERSAMPLE_OVERSAMPLE_Over256x ///< Oversample 256x. +} nrf_saadc_oversample_t; + + +/** + * @brief Analog-to-digital converter channel resistor control. + */ +typedef enum +{ + NRF_SAADC_RESISTOR_DISABLED = SAADC_CH_CONFIG_RESP_Bypass, ///< Bypass resistor ladder. + NRF_SAADC_RESISTOR_PULLDOWN = SAADC_CH_CONFIG_RESP_Pulldown, ///< Pull-down to GND. + NRF_SAADC_RESISTOR_PULLUP = SAADC_CH_CONFIG_RESP_Pullup, ///< Pull-up to VDD. + NRF_SAADC_RESISTOR_VDD1_2 = SAADC_CH_CONFIG_RESP_VDD1_2 ///< Set input at VDD/2. +} nrf_saadc_resistor_t; + + +/** + * @brief Gain factor of the analog-to-digital converter input. + */ +typedef enum +{ + NRF_SAADC_GAIN1_6 = SAADC_CH_CONFIG_GAIN_Gain1_6, ///< Gain factor 1/6. + NRF_SAADC_GAIN1_5 = SAADC_CH_CONFIG_GAIN_Gain1_5, ///< Gain factor 1/5. + NRF_SAADC_GAIN1_4 = SAADC_CH_CONFIG_GAIN_Gain1_4, ///< Gain factor 1/4. + NRF_SAADC_GAIN1_3 = SAADC_CH_CONFIG_GAIN_Gain1_3, ///< Gain factor 1/3. + NRF_SAADC_GAIN1_2 = SAADC_CH_CONFIG_GAIN_Gain1_2, ///< Gain factor 1/2. + NRF_SAADC_GAIN1 = SAADC_CH_CONFIG_GAIN_Gain1, ///< Gain factor 1. + NRF_SAADC_GAIN2 = SAADC_CH_CONFIG_GAIN_Gain2, ///< Gain factor 2. + NRF_SAADC_GAIN4 = SAADC_CH_CONFIG_GAIN_Gain4, ///< Gain factor 4. +} nrf_saadc_gain_t; + + +/** + * @brief Reference selection for the analog-to-digital converter. + */ +typedef enum +{ + NRF_SAADC_REFERENCE_INTERNAL = SAADC_CH_CONFIG_REFSEL_Internal, ///< Internal reference (0.6 V). + NRF_SAADC_REFERENCE_VDD4 = SAADC_CH_CONFIG_REFSEL_VDD1_4 ///< VDD/4 as reference. +} nrf_saadc_reference_t; + + +/** + * @brief Analog-to-digital converter acquisition time. + */ +typedef enum +{ + NRF_SAADC_ACQTIME_3US = SAADC_CH_CONFIG_TACQ_3us, ///< 3 us. + NRF_SAADC_ACQTIME_5US = SAADC_CH_CONFIG_TACQ_5us, ///< 5 us. + NRF_SAADC_ACQTIME_10US = SAADC_CH_CONFIG_TACQ_10us, ///< 10 us. + NRF_SAADC_ACQTIME_15US = SAADC_CH_CONFIG_TACQ_15us, ///< 15 us. + NRF_SAADC_ACQTIME_20US = SAADC_CH_CONFIG_TACQ_20us, ///< 20 us. + NRF_SAADC_ACQTIME_40US = SAADC_CH_CONFIG_TACQ_40us ///< 40 us. +} nrf_saadc_acqtime_t; + + +/** + * @brief Analog-to-digital converter channel mode. + */ +typedef enum +{ + NRF_SAADC_MODE_SINGLE_ENDED = SAADC_CH_CONFIG_MODE_SE, ///< Single ended, PSELN will be ignored, negative input to ADC shorted to GND. + NRF_SAADC_MODE_DIFFERENTIAL = SAADC_CH_CONFIG_MODE_Diff ///< Differential mode. +} nrf_saadc_mode_t; + + +/** + * @brief Analog-to-digital converter channel burst mode. + */ +typedef enum +{ + NRF_SAADC_BURST_DISABLED = SAADC_CH_CONFIG_BURST_Disabled, ///< Burst mode is disabled (normal operation). + NRF_SAADC_BURST_ENABLED = SAADC_CH_CONFIG_BURST_Enabled ///< Burst mode is enabled. SAADC takes 2^OVERSAMPLE number of samples as fast as it can, and sends the average to Data RAM. +} nrf_saadc_burst_t; + + +/** + * @brief Analog-to-digital converter tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_SAADC_TASK_START = offsetof(NRF_SAADC_Type, TASKS_START), ///< Start the ADC and prepare the result buffer in RAM. + NRF_SAADC_TASK_SAMPLE = offsetof(NRF_SAADC_Type, TASKS_SAMPLE), ///< Take one ADC sample. If scan is enabled, all channels are sampled. + NRF_SAADC_TASK_STOP = offsetof(NRF_SAADC_Type, TASKS_STOP), ///< Stop the ADC and terminate any on-going conversion. + NRF_SAADC_TASK_CALIBRATEOFFSET = offsetof(NRF_SAADC_Type, TASKS_CALIBRATEOFFSET), ///< Starts offset auto-calibration. +} nrf_saadc_task_t; + + +/** + * @brief Analog-to-digital converter events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_SAADC_EVENT_STARTED = offsetof(NRF_SAADC_Type, EVENTS_STARTED), ///< The ADC has started. + NRF_SAADC_EVENT_END = offsetof(NRF_SAADC_Type, EVENTS_END), ///< The ADC has filled up the result buffer. + NRF_SAADC_EVENT_DONE = offsetof(NRF_SAADC_Type, EVENTS_DONE), ///< A conversion task has been completed. + NRF_SAADC_EVENT_RESULTDONE = offsetof(NRF_SAADC_Type, EVENTS_RESULTDONE), ///< A result is ready to get transferred to RAM. + NRF_SAADC_EVENT_CALIBRATEDONE = offsetof(NRF_SAADC_Type, EVENTS_CALIBRATEDONE), ///< Calibration is complete. + NRF_SAADC_EVENT_STOPPED = offsetof(NRF_SAADC_Type, EVENTS_STOPPED), ///< The ADC has stopped. + NRF_SAADC_EVENT_CH0_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITH), ///< Last result is equal or above CH[0].LIMIT.HIGH. + NRF_SAADC_EVENT_CH0_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITL), ///< Last result is equal or below CH[0].LIMIT.LOW. + NRF_SAADC_EVENT_CH1_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[1].LIMITH), ///< Last result is equal or above CH[1].LIMIT.HIGH. + NRF_SAADC_EVENT_CH1_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[1].LIMITL), ///< Last result is equal or below CH[1].LIMIT.LOW. + NRF_SAADC_EVENT_CH2_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[2].LIMITH), ///< Last result is equal or above CH[2].LIMIT.HIGH. + NRF_SAADC_EVENT_CH2_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[2].LIMITL), ///< Last result is equal or below CH[2].LIMIT.LOW. + NRF_SAADC_EVENT_CH3_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[3].LIMITH), ///< Last result is equal or above CH[3].LIMIT.HIGH. + NRF_SAADC_EVENT_CH3_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[3].LIMITL), ///< Last result is equal or below CH[3].LIMIT.LOW. + NRF_SAADC_EVENT_CH4_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[4].LIMITH), ///< Last result is equal or above CH[4].LIMIT.HIGH. + NRF_SAADC_EVENT_CH4_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[4].LIMITL), ///< Last result is equal or below CH[4].LIMIT.LOW. + NRF_SAADC_EVENT_CH5_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[5].LIMITH), ///< Last result is equal or above CH[5].LIMIT.HIGH. + NRF_SAADC_EVENT_CH5_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[5].LIMITL), ///< Last result is equal or below CH[5].LIMIT.LOW. + NRF_SAADC_EVENT_CH6_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[6].LIMITH), ///< Last result is equal or above CH[6].LIMIT.HIGH. + NRF_SAADC_EVENT_CH6_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[6].LIMITL), ///< Last result is equal or below CH[6].LIMIT.LOW. + NRF_SAADC_EVENT_CH7_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[7].LIMITH), ///< Last result is equal or above CH[7].LIMIT.HIGH. + NRF_SAADC_EVENT_CH7_LIMITL = offsetof(NRF_SAADC_Type, EVENTS_CH[7].LIMITL) ///< Last result is equal or below CH[7].LIMIT.LOW. +} nrf_saadc_event_t; + + +/** + * @brief Analog-to-digital converter interrupt masks. + */ +typedef enum +{ + NRF_SAADC_INT_STARTED = SAADC_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event. + NRF_SAADC_INT_END = SAADC_INTENSET_END_Msk, ///< Interrupt on EVENTS_END event. + NRF_SAADC_INT_DONE = SAADC_INTENSET_DONE_Msk, ///< Interrupt on EVENTS_DONE event. + NRF_SAADC_INT_RESULTDONE = SAADC_INTENSET_RESULTDONE_Msk, ///< Interrupt on EVENTS_RESULTDONE event. + NRF_SAADC_INT_CALIBRATEDONE = SAADC_INTENSET_CALIBRATEDONE_Msk, ///< Interrupt on EVENTS_CALIBRATEDONE event. + NRF_SAADC_INT_STOPPED = SAADC_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event. + NRF_SAADC_INT_CH0LIMITH = SAADC_INTENSET_CH0LIMITH_Msk, ///< Interrupt on EVENTS_CH[0].LIMITH event. + NRF_SAADC_INT_CH0LIMITL = SAADC_INTENSET_CH0LIMITL_Msk, ///< Interrupt on EVENTS_CH[0].LIMITL event. + NRF_SAADC_INT_CH1LIMITH = SAADC_INTENSET_CH1LIMITH_Msk, ///< Interrupt on EVENTS_CH[1].LIMITH event. + NRF_SAADC_INT_CH1LIMITL = SAADC_INTENSET_CH1LIMITL_Msk, ///< Interrupt on EVENTS_CH[1].LIMITL event. + NRF_SAADC_INT_CH2LIMITH = SAADC_INTENSET_CH2LIMITH_Msk, ///< Interrupt on EVENTS_CH[2].LIMITH event. + NRF_SAADC_INT_CH2LIMITL = SAADC_INTENSET_CH2LIMITL_Msk, ///< Interrupt on EVENTS_CH[2].LIMITL event. + NRF_SAADC_INT_CH3LIMITH = SAADC_INTENSET_CH3LIMITH_Msk, ///< Interrupt on EVENTS_CH[3].LIMITH event. + NRF_SAADC_INT_CH3LIMITL = SAADC_INTENSET_CH3LIMITL_Msk, ///< Interrupt on EVENTS_CH[3].LIMITL event. + NRF_SAADC_INT_CH4LIMITH = SAADC_INTENSET_CH4LIMITH_Msk, ///< Interrupt on EVENTS_CH[4].LIMITH event. + NRF_SAADC_INT_CH4LIMITL = SAADC_INTENSET_CH4LIMITL_Msk, ///< Interrupt on EVENTS_CH[4].LIMITL event. + NRF_SAADC_INT_CH5LIMITH = SAADC_INTENSET_CH5LIMITH_Msk, ///< Interrupt on EVENTS_CH[5].LIMITH event. + NRF_SAADC_INT_CH5LIMITL = SAADC_INTENSET_CH5LIMITL_Msk, ///< Interrupt on EVENTS_CH[5].LIMITL event. + NRF_SAADC_INT_CH6LIMITH = SAADC_INTENSET_CH6LIMITH_Msk, ///< Interrupt on EVENTS_CH[6].LIMITH event. + NRF_SAADC_INT_CH6LIMITL = SAADC_INTENSET_CH6LIMITL_Msk, ///< Interrupt on EVENTS_CH[6].LIMITL event. + NRF_SAADC_INT_CH7LIMITH = SAADC_INTENSET_CH7LIMITH_Msk, ///< Interrupt on EVENTS_CH[7].LIMITH event. + NRF_SAADC_INT_CH7LIMITL = SAADC_INTENSET_CH7LIMITL_Msk, ///< Interrupt on EVENTS_CH[7].LIMITL event. + NRF_SAADC_INT_ALL = 0x7FFFFFFFUL ///< Mask of all interrupts. +} nrf_saadc_int_mask_t; + + +/** + * @brief Analog-to-digital converter value limit type. + */ +typedef enum +{ + NRF_SAADC_LIMIT_LOW = 0, + NRF_SAADC_LIMIT_HIGH = 1 +} nrf_saadc_limit_t; + + +typedef int16_t nrf_saadc_value_t; ///< Type of a single ADC conversion result. + + +/** + * @brief Analog-to-digital converter configuration structure. + */ +typedef struct +{ + nrf_saadc_resolution_t resolution; + nrf_saadc_oversample_t oversample; + nrf_saadc_value_t * buffer; + uint32_t buffer_size; +} nrf_saadc_config_t; + + +/** + * @brief Analog-to-digital converter channel configuration structure. + */ +typedef struct +{ + nrf_saadc_resistor_t resistor_p; + nrf_saadc_resistor_t resistor_n; + nrf_saadc_gain_t gain; + nrf_saadc_reference_t reference; + nrf_saadc_acqtime_t acq_time; + nrf_saadc_mode_t mode; + nrf_saadc_burst_t burst; + nrf_saadc_input_t pin_p; + nrf_saadc_input_t pin_n; +} nrf_saadc_channel_config_t; + + +/** + * @brief Function for triggering a specific SAADC task. + * + * @param[in] saadc_task SAADC task. + */ +__STATIC_INLINE void nrf_saadc_task_trigger(nrf_saadc_task_t saadc_task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_task)) = 0x1UL; +} + + +/** + * @brief Function for getting the address of a specific SAADC task register. + * + * @param[in] saadc_task SAADC task. + * + * @return Address of the specified SAADC task. + */ +__STATIC_INLINE uint32_t nrf_saadc_task_address_get(nrf_saadc_task_t saadc_task) +{ + return (uint32_t)((uint8_t *)NRF_SAADC + (uint32_t)saadc_task); +} + + +/** + * @brief Function for getting the state of a specific SAADC event. + * + * @param[in] saadc_event SAADC event. + * + * @return State of the specified SAADC event. + */ +__STATIC_INLINE bool nrf_saadc_event_check(nrf_saadc_event_t saadc_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event); +} + + +/** + * @brief Function for clearing the specific SAADC event. + * + * @param[in] saadc_event SAADC event. + */ +__STATIC_INLINE void nrf_saadc_event_clear(nrf_saadc_event_t saadc_event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event)); + (void)dummy; +#endif +} + + +/** + * @brief Function for getting the address of a specific SAADC event register. + * + * @param[in] saadc_event SAADC event. + * + * @return Address of the specified SAADC event. + */ +__STATIC_INLINE uint32_t nrf_saadc_event_address_get(nrf_saadc_event_t saadc_event) +{ + return (uint32_t )((uint8_t *)NRF_SAADC + (uint32_t)saadc_event); +} + + +/** + * @brief Function for getting the address of a specific SAADC limit event register. + * + * @param[in] channel Channel number. + * @param[in] limit_type Low limit or high limit. + * + * @return Address of the specified SAADC limit event. + */ +__STATIC_INLINE volatile uint32_t * nrf_saadc_event_limit_address_get(uint8_t channel, nrf_saadc_limit_t limit_type) +{ + ASSERT(channel < NRF_SAADC_CHANNEL_COUNT); + if (limit_type == NRF_SAADC_LIMIT_HIGH) + { + return &NRF_SAADC->EVENTS_CH[channel].LIMITH; + } + else + { + return &NRF_SAADC->EVENTS_CH[channel].LIMITL; + } +} + + +/** + * @brief Function for getting the SAADC channel monitoring limit events. + * + * @param[in] channel Channel number. + * @param[in] limit_type Low limit or high limit. + */ +__STATIC_INLINE nrf_saadc_event_t nrf_saadc_event_limit_get(uint8_t channel, nrf_saadc_limit_t limit_type) +{ + if (limit_type == NRF_SAADC_LIMIT_HIGH) + { + return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITH + + (uint32_t) (NRF_SAADC_EVENT_CH1_LIMITH - NRF_SAADC_EVENT_CH0_LIMITH) + * (uint32_t) channel ); + } + else + { + return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITL + + (uint32_t) (NRF_SAADC_EVENT_CH1_LIMITL - NRF_SAADC_EVENT_CH0_LIMITL) + * (uint32_t) channel ); + } +} + + +/** + * @brief Function for configuring the input pins for a specific SAADC channel. + * + * @param[in] channel Channel number. + * @param[in] pselp Positive input. + * @param[in] pseln Negative input. Set to NRF_SAADC_INPUT_DISABLED in single ended mode. + */ +__STATIC_INLINE void nrf_saadc_channel_input_set(uint8_t channel, + nrf_saadc_input_t pselp, + nrf_saadc_input_t pseln) +{ + NRF_SAADC->CH[channel].PSELN = pseln; + NRF_SAADC->CH[channel].PSELP = pselp; +} + + +/** + * @brief Function for setting the SAADC channel monitoring limits. + * + * @param[in] channel Channel number. + * @param[in] low Low limit. + * @param[in] high High limit. + */ +__STATIC_INLINE void nrf_saadc_channel_limits_set(uint8_t channel, int16_t low, int16_t high) +{ + NRF_SAADC->CH[channel].LIMIT = ( + (((uint32_t) low << SAADC_CH_LIMIT_LOW_Pos) & SAADC_CH_LIMIT_LOW_Msk) + | (((uint32_t) high << SAADC_CH_LIMIT_HIGH_Pos) & SAADC_CH_LIMIT_HIGH_Msk)); +} + + +/** + * @brief Function for enabling specified SAADC interrupts. + * + * @param[in] saadc_int_mask Interrupt(s) to enable. + */ +__STATIC_INLINE void nrf_saadc_int_enable(uint32_t saadc_int_mask) +{ + NRF_SAADC->INTENSET = saadc_int_mask; +} + + +/** + * @brief Function for retrieving the state of specified SAADC interrupts. + * + * @param[in] saadc_int_mask Interrupt(s) to check. + * + * @retval true If all specified interrupts are enabled. + * @retval false If at least one of the given interrupts is not enabled. + */ +__STATIC_INLINE bool nrf_saadc_int_enable_check(uint32_t saadc_int_mask) +{ + return (bool)(NRF_SAADC->INTENSET & saadc_int_mask); +} + + +/** + * @brief Function for disabling specified interrupts. + * + * @param saadc_int_mask Interrupt(s) to disable. + */ +__STATIC_INLINE void nrf_saadc_int_disable(uint32_t saadc_int_mask) +{ + NRF_SAADC->INTENCLR = saadc_int_mask; +} + + +/** + * @brief Function for generating masks for SAADC channel limit interrupts. + * + * @param[in] channel SAADC channel number. + * @param[in] limit_type Limit type. + * + * @returns Interrupt mask. + */ +__STATIC_INLINE uint32_t nrf_saadc_limit_int_get(uint8_t channel, nrf_saadc_limit_t limit_type) +{ + ASSERT(channel < NRF_SAADC_CHANNEL_COUNT); + uint32_t mask = (limit_type == NRF_SAADC_LIMIT_LOW) ? NRF_SAADC_INT_CH0LIMITL : NRF_SAADC_INT_CH0LIMITH; + return mask << (channel * 2); +} + + +/** + * @brief Function for checking whether the SAADC is busy. + * + * This function checks whether the analog-to-digital converter is busy with a conversion. + * + * @retval true If the SAADC is busy. + * @retval false If the SAADC is not busy. + */ +__STATIC_INLINE bool nrf_saadc_busy_check(void) +{ + //return ((NRF_SAADC->STATUS & SAADC_STATUS_STATUS_Msk) == SAADC_STATUS_STATUS_Msk); + //simplified for performance + return NRF_SAADC->STATUS; +} + + +/** + * @brief Function for enabling the SAADC. + * + * The analog-to-digital converter must be enabled before use. + */ +__STATIC_INLINE void nrf_saadc_enable(void) +{ + NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Enabled << SAADC_ENABLE_ENABLE_Pos); +} + + +/** + * @brief Function for disabling the SAADC. + */ +__STATIC_INLINE void nrf_saadc_disable(void) +{ + NRF_SAADC->ENABLE = (SAADC_ENABLE_ENABLE_Disabled << SAADC_ENABLE_ENABLE_Pos); +} + + +/** + * @brief Function for checking if the SAADC is enabled. + * + * @retval true If the SAADC is enabled. + * @retval false If the SAADC is not enabled. + */ +__STATIC_INLINE bool nrf_saadc_enable_check(void) +{ + //simplified for performance + return NRF_SAADC->ENABLE; +} + + +/** + * @brief Function for initializing the SAADC result buffer. + * + * @param[in] buffer Pointer to the result buffer. + * @param[in] num Size of buffer in words. + */ +__STATIC_INLINE void nrf_saadc_buffer_init(nrf_saadc_value_t * buffer, uint32_t num) +{ + NRF_SAADC->RESULT.PTR = (uint32_t)buffer; + NRF_SAADC->RESULT.MAXCNT = num; +} + +/** + * @brief Function for getting the number of buffer words transferred since last START operation. + * + * @returns Number of words transferred. + */ +__STATIC_INLINE uint16_t nrf_saadc_amount_get(void) +{ + return NRF_SAADC->RESULT.AMOUNT; +} + + +/** + * @brief Function for setting the SAADC sample resolution. + * + * @param[in] resolution Bit resolution. + */ +__STATIC_INLINE void nrf_saadc_resolution_set(nrf_saadc_resolution_t resolution) +{ + NRF_SAADC->RESOLUTION = resolution; +} + + +/** + * @brief Function for configuring the oversampling feature. + * + * @param[in] oversample Oversampling mode. + */ +__STATIC_INLINE void nrf_saadc_oversample_set(nrf_saadc_oversample_t oversample) +{ + NRF_SAADC->OVERSAMPLE = oversample; +} + +/** + * @brief Function for getting the oversampling feature configuration. + * + * @return Oversampling configuration. + */ +__STATIC_INLINE nrf_saadc_oversample_t nrf_saadc_oversample_get(void) +{ + return (nrf_saadc_oversample_t)NRF_SAADC->OVERSAMPLE; +} + +/** + * @brief Function for initializing the SAADC channel. + * + * @param[in] channel Channel number. + * @param[in] config Pointer to the channel configuration structure. + */ +void nrf_saadc_channel_init(uint8_t channel, nrf_saadc_channel_config_t const * const config); + +/** + *@} + **/ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SAADC_H_ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_spi.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..5d4d20d723143ac03a7685ed977559375c75662d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_spi.h @@ -0,0 +1,374 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @defgroup nrf_spi_hal SPI HAL + * @{ + * @ingroup nrf_spi + * + * @brief Hardware access layer for accessing the SPI peripheral. + */ + +#ifndef NRF_SPI_H__ +#define NRF_SPI_H__ + +#include +#include +#include + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief This value can be used as a parameter for the @ref nrf_spi_pins_set + * function to specify that a given SPI signal (SCK, MOSI, or MISO) + * shall not be connected to a physical pin. + */ +#define NRF_SPI_PIN_NOT_CONNECTED 0xFFFFFFFF + + +/** + * @brief SPI events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_SPI_EVENT_READY = offsetof(NRF_SPI_Type, EVENTS_READY) ///< TXD byte sent and RXD byte received. + /*lint -restore*/ +} nrf_spi_event_t; + +/** + * @brief SPI interrupts. + */ +typedef enum +{ + NRF_SPI_INT_READY_MASK = SPI_INTENSET_READY_Msk ///< Interrupt on READY event. +} nrf_spi_int_mask_t; + +/** + * @brief SPI data rates. + */ +typedef enum +{ + NRF_SPI_FREQ_125K = SPI_FREQUENCY_FREQUENCY_K125, ///< 125 kbps. + NRF_SPI_FREQ_250K = SPI_FREQUENCY_FREQUENCY_K250, ///< 250 kbps. + NRF_SPI_FREQ_500K = SPI_FREQUENCY_FREQUENCY_K500, ///< 500 kbps. + NRF_SPI_FREQ_1M = SPI_FREQUENCY_FREQUENCY_M1, ///< 1 Mbps. + NRF_SPI_FREQ_2M = SPI_FREQUENCY_FREQUENCY_M2, ///< 2 Mbps. + NRF_SPI_FREQ_4M = SPI_FREQUENCY_FREQUENCY_M4, ///< 4 Mbps. + // [conversion to 'int' needed to prevent compilers from complaining + // that the provided value (0x80000000UL) is out of range of "int"] + NRF_SPI_FREQ_8M = (int)SPI_FREQUENCY_FREQUENCY_M8 ///< 8 Mbps. +} nrf_spi_frequency_t; + +/** + * @brief SPI modes. + */ +typedef enum +{ + NRF_SPI_MODE_0, ///< SCK active high, sample on leading edge of clock. + NRF_SPI_MODE_1, ///< SCK active high, sample on trailing edge of clock. + NRF_SPI_MODE_2, ///< SCK active low, sample on leading edge of clock. + NRF_SPI_MODE_3 ///< SCK active low, sample on trailing edge of clock. +} nrf_spi_mode_t; + +/** + * @brief SPI bit orders. + */ +typedef enum +{ + NRF_SPI_BIT_ORDER_MSB_FIRST = SPI_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first. + NRF_SPI_BIT_ORDER_LSB_FIRST = SPI_CONFIG_ORDER_LsbFirst ///< Least significant bit shifted out first. +} nrf_spi_bit_order_t; + + +/** + * @brief Function for clearing a specific SPI event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spi_event Event to clear. + */ +__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_reg, + nrf_spi_event_t spi_event); + +/** + * @brief Function for checking the state of a specific SPI event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spi_event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_reg, + nrf_spi_event_t spi_event); + +/** + * @brief Function for getting the address of a specific SPI event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spi_event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_reg, + nrf_spi_event_t spi_event); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spi_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_reg, + uint32_t spi_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spi_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_reg, + uint32_t spi_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spi_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_reg, + nrf_spi_int_mask_t spi_int); + +/** + * @brief Function for enabling the SPI peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_reg); + +/** + * @brief Function for disabling the SPI peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_reg); + +/** + * @brief Function for configuring SPI pins. + * + * If a given signal is not needed, pass the @ref NRF_SPI_PIN_NOT_CONNECTED + * value instead of its pin number. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] sck_pin SCK pin number. + * @param[in] mosi_pin MOSI pin number. + * @param[in] miso_pin MISO pin number. + */ +__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_reg, + uint32_t sck_pin, + uint32_t mosi_pin, + uint32_t miso_pin); + +/** + * @brief Function for writing data to the SPI transmitter register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] data TX data to send. + */ +__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_reg, uint8_t data); + +/** + * @brief Function for reading data from the SPI receiver register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return RX data received. + */ +__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_reg); + +/** + * @brief Function for setting the SPI master data rate. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] frequency SPI frequency. + */ +__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_reg, + nrf_spi_frequency_t frequency); + +/** + * @brief Function for setting the SPI configuration. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spi_mode SPI mode. + * @param[in] spi_bit_order SPI bit order. + */ +__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_reg, + nrf_spi_mode_t spi_mode, + nrf_spi_bit_order_t spi_bit_order); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_reg, + nrf_spi_event_t spi_event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spi_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spi_event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_reg, + nrf_spi_event_t spi_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spi_event); +} + +__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_reg, + nrf_spi_event_t spi_event) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)spi_event); +} + +__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_reg, + uint32_t spi_int_mask) +{ + p_reg->INTENSET = spi_int_mask; +} + +__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_reg, + uint32_t spi_int_mask) +{ + p_reg->INTENCLR = spi_int_mask; +} + +__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_reg, + nrf_spi_int_mask_t spi_int) +{ + return (bool)(p_reg->INTENSET & spi_int); +} + +__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_reg) +{ + p_reg->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_reg) +{ + p_reg->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_reg, + uint32_t sck_pin, + uint32_t mosi_pin, + uint32_t miso_pin) +{ + p_reg->PSELSCK = sck_pin; + p_reg->PSELMOSI = mosi_pin; + p_reg->PSELMISO = miso_pin; +} + +__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_reg, uint8_t data) +{ + p_reg->TXD = data; +} + +__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_reg) +{ + return p_reg->RXD; +} + +__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_reg, + nrf_spi_frequency_t frequency) +{ + p_reg->FREQUENCY = frequency; +} + +__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_reg, + nrf_spi_mode_t spi_mode, + nrf_spi_bit_order_t spi_bit_order) +{ + uint32_t config = (spi_bit_order == NRF_SPI_BIT_ORDER_MSB_FIRST ? + SPI_CONFIG_ORDER_MsbFirst : SPI_CONFIG_ORDER_LsbFirst); + switch (spi_mode) + { + default: + case NRF_SPI_MODE_0: + config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos) | + (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos); + break; + + case NRF_SPI_MODE_1: + config |= (SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos) | + (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos); + break; + + case NRF_SPI_MODE_2: + config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos) | + (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos); + break; + + case NRF_SPI_MODE_3: + config |= (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos) | + (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos); + break; + } + p_reg->CONFIG = config; +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SPI_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_spim.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_spim.h new file mode 100644 index 0000000000000000000000000000000000000000..f23ef0e3a4b3ed91dc1cfa6ee282610f6dfdc2ee --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_spim.h @@ -0,0 +1,551 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @defgroup nrf_spim_hal SPIM HAL + * @{ + * @ingroup nrf_spi + * + * @brief Hardware access layer for accessing the SPIM peripheral. + */ + +#ifndef NRF_SPIM_H__ +#define NRF_SPIM_H__ + +#include +#include +#include + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief This value can be used as a parameter for the @ref nrf_spim_pins_set + * function to specify that a given SPI signal (SCK, MOSI, or MISO) + * shall not be connected to a physical pin. + */ +#define NRF_SPIM_PIN_NOT_CONNECTED 0xFFFFFFFF + + +/** + * @brief SPIM tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_SPIM_TASK_START = offsetof(NRF_SPIM_Type, TASKS_START), ///< Start SPI transaction. + NRF_SPIM_TASK_STOP = offsetof(NRF_SPIM_Type, TASKS_STOP), ///< Stop SPI transaction. + NRF_SPIM_TASK_SUSPEND = offsetof(NRF_SPIM_Type, TASKS_SUSPEND), ///< Suspend SPI transaction. + NRF_SPIM_TASK_RESUME = offsetof(NRF_SPIM_Type, TASKS_RESUME) ///< Resume SPI transaction. + /*lint -restore*/ +} nrf_spim_task_t; + +/** + * @brief SPIM events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_SPIM_EVENT_STOPPED = offsetof(NRF_SPIM_Type, EVENTS_STOPPED), ///< SPI transaction has stopped. + NRF_SPIM_EVENT_ENDRX = offsetof(NRF_SPIM_Type, EVENTS_ENDRX), ///< End of RXD buffer reached. + NRF_SPIM_EVENT_END = offsetof(NRF_SPIM_Type, EVENTS_END), ///< End of RXD buffer and TXD buffer reached. + NRF_SPIM_EVENT_ENDTX = offsetof(NRF_SPIM_Type, EVENTS_ENDTX), ///< End of TXD buffer reached. + NRF_SPIM_EVENT_STARTED = offsetof(NRF_SPIM_Type, EVENTS_STARTED) ///< Transaction started. + /*lint -restore*/ +} nrf_spim_event_t; + +/** + * @brief SPIM shortcuts. + */ +typedef enum +{ + NRF_SPIM_SHORT_END_START_MASK = SPIM_SHORTS_END_START_Msk ///< Shortcut between END event and START task. +} nrf_spim_short_mask_t; + +/** + * @brief SPIM interrupts. + */ +typedef enum +{ + NRF_SPIM_INT_STOPPED_MASK = SPIM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event. + NRF_SPIM_INT_ENDRX_MASK = SPIM_INTENSET_ENDRX_Msk, ///< Interrupt on ENDRX event. + NRF_SPIM_INT_END_MASK = SPIM_INTENSET_END_Msk, ///< Interrupt on END event. + NRF_SPIM_INT_ENDTX_MASK = SPIM_INTENSET_ENDTX_Msk, ///< Interrupt on ENDTX event. + NRF_SPIM_INT_STARTED_MASK = SPIM_INTENSET_STARTED_Msk ///< Interrupt on STARTED event. +} nrf_spim_int_mask_t; + +/** + * @brief SPI master data rates. + */ +typedef enum +{ + NRF_SPIM_FREQ_125K = SPIM_FREQUENCY_FREQUENCY_K125, ///< 125 kbps. + NRF_SPIM_FREQ_250K = SPIM_FREQUENCY_FREQUENCY_K250, ///< 250 kbps. + NRF_SPIM_FREQ_500K = SPIM_FREQUENCY_FREQUENCY_K500, ///< 500 kbps. + NRF_SPIM_FREQ_1M = SPIM_FREQUENCY_FREQUENCY_M1, ///< 1 Mbps. + NRF_SPIM_FREQ_2M = SPIM_FREQUENCY_FREQUENCY_M2, ///< 2 Mbps. + NRF_SPIM_FREQ_4M = SPIM_FREQUENCY_FREQUENCY_M4, ///< 4 Mbps. + // [conversion to 'int' needed to prevent compilers from complaining + // that the provided value (0x80000000UL) is out of range of "int"] + NRF_SPIM_FREQ_8M = (int)SPIM_FREQUENCY_FREQUENCY_M8 ///< 8 Mbps. +} nrf_spim_frequency_t; + +/** + * @brief SPI modes. + */ +typedef enum +{ + NRF_SPIM_MODE_0, ///< SCK active high, sample on leading edge of clock. + NRF_SPIM_MODE_1, ///< SCK active high, sample on trailing edge of clock. + NRF_SPIM_MODE_2, ///< SCK active low, sample on leading edge of clock. + NRF_SPIM_MODE_3 ///< SCK active low, sample on trailing edge of clock. +} nrf_spim_mode_t; + +/** + * @brief SPI bit orders. + */ +typedef enum +{ + NRF_SPIM_BIT_ORDER_MSB_FIRST = SPIM_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first. + NRF_SPIM_BIT_ORDER_LSB_FIRST = SPIM_CONFIG_ORDER_LsbFirst ///< Least significant bit shifted out first. +} nrf_spim_bit_order_t; + + +/** + * @brief Function for activating a specific SPIM task. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spim_task Task to activate. + */ +__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_reg, + nrf_spim_task_t spim_task); + +/** + * @brief Function for getting the address of a specific SPIM task register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spim_task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_reg, + nrf_spim_task_t spim_task); + +/** + * @brief Function for clearing a specific SPIM event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spim_event Event to clear. + */ +__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_reg, + nrf_spim_event_t spim_event); + +/** + * @brief Function for checking the state of a specific SPIM event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spim_event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_reg, + nrf_spim_event_t spim_event); + +/** + * @brief Function for getting the address of a specific SPIM event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spim_event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_reg, + nrf_spim_event_t spim_event); +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spim_shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_reg, + uint32_t spim_shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spim_shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_reg, + uint32_t spim_shorts_mask); + +/** + * @brief Function for getting shorts setting. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_reg); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spim_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_reg, + uint32_t spim_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spim_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_reg, + uint32_t spim_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spim_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_reg, + nrf_spim_int_mask_t spim_int); + +/** + * @brief Function for enabling the SPIM peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_reg); + +/** + * @brief Function for disabling the SPIM peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_reg); + +/** + * @brief Function for configuring SPIM pins. + * + * If a given signal is not needed, pass the @ref NRF_SPIM_PIN_NOT_CONNECTED + * value instead of its pin number. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] sck_pin SCK pin number. + * @param[in] mosi_pin MOSI pin number. + * @param[in] miso_pin MISO pin number. + */ +__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_reg, + uint32_t sck_pin, + uint32_t mosi_pin, + uint32_t miso_pin); + +/** + * @brief Function for setting the SPI master data rate. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] frequency SPI frequency. + */ +__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_reg, + nrf_spim_frequency_t frequency); + +/** + * @brief Function for setting the transmit buffer. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] p_buffer Pointer to the buffer with data to send. + * @param[in] length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_reg, + uint8_t const * p_buffer, + uint8_t length); + +/** + * @brief Function for setting the receive buffer. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] p_buffer Pointer to the buffer for received data. + * @param[in] length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_reg, + uint8_t * p_buffer, + uint8_t length); + +/** + * @brief Function for setting the SPI configuration. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spi_mode SPI mode. + * @param[in] spi_bit_order SPI bit order. + */ +__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_reg, + nrf_spim_mode_t spi_mode, + nrf_spim_bit_order_t spi_bit_order); + +/** + * @brief Function for setting the over-read character. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] orc Over-read character that is clocked out in case of + * an over-read of the TXD buffer. + */ +__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_reg, + uint8_t orc); + +/** + * @brief Function for enabling the TX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_reg); + +/** + * @brief Function for disabling the TX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_reg); + +/** + * @brief Function for enabling the RX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_reg); + +/** + * @brief Function for disabling the RX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_reg); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_reg, + nrf_spim_task_t spim_task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_reg, + nrf_spim_task_t spim_task) +{ + return (uint32_t)((uint8_t *)p_reg + (uint32_t)spim_task); +} + +__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_reg, + nrf_spim_event_t spim_event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_reg, + nrf_spim_event_t spim_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_event); +} + +__STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_reg, + nrf_spim_event_t spim_event) +{ + return (uint32_t)((uint8_t *)p_reg + (uint32_t)spim_event); +} + +__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_reg, + uint32_t spim_shorts_mask) +{ + p_reg->SHORTS |= spim_shorts_mask; +} + +__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_reg, + uint32_t spim_shorts_mask) +{ + p_reg->SHORTS &= ~(spim_shorts_mask); +} + +__STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_reg) +{ + return p_reg->SHORTS; +} + +__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_reg, + uint32_t spim_int_mask) +{ + p_reg->INTENSET = spim_int_mask; +} + +__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_reg, + uint32_t spim_int_mask) +{ + p_reg->INTENCLR = spim_int_mask; +} + +__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_reg, + nrf_spim_int_mask_t spim_int) +{ + return (bool)(p_reg->INTENSET & spim_int); +} + +__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_reg) +{ + p_reg->ENABLE = (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_reg) +{ + p_reg->ENABLE = (SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_reg, + uint32_t sck_pin, + uint32_t mosi_pin, + uint32_t miso_pin) +{ + p_reg->PSEL.SCK = sck_pin; + p_reg->PSEL.MOSI = mosi_pin; + p_reg->PSEL.MISO = miso_pin; +} + +__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_reg, + nrf_spim_frequency_t frequency) +{ + p_reg->FREQUENCY = frequency; +} + +__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_reg, + uint8_t const * p_buffer, + uint8_t length) +{ + p_reg->TXD.PTR = (uint32_t)p_buffer; + p_reg->TXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_reg, + uint8_t * p_buffer, + uint8_t length) +{ + p_reg->RXD.PTR = (uint32_t)p_buffer; + p_reg->RXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_reg, + nrf_spim_mode_t spi_mode, + nrf_spim_bit_order_t spi_bit_order) +{ + uint32_t config = (spi_bit_order == NRF_SPIM_BIT_ORDER_MSB_FIRST ? + SPIM_CONFIG_ORDER_MsbFirst : SPIM_CONFIG_ORDER_LsbFirst); + switch (spi_mode) + { + default: + case NRF_SPIM_MODE_0: + config |= (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) | + (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos); + break; + + case NRF_SPIM_MODE_1: + config |= (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) | + (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos); + break; + + case NRF_SPIM_MODE_2: + config |= (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) | + (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos); + break; + + case NRF_SPIM_MODE_3: + config |= (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) | + (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos); + break; + } + p_reg->CONFIG = config; +} + +__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_reg, + uint8_t orc) +{ + p_reg->ORC = orc; +} + + +__STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_reg) +{ + p_reg->TXD.LIST = 1; +} + +__STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_reg) +{ + p_reg->TXD.LIST = 0; +} + +__STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_reg) +{ + p_reg->RXD.LIST = 1; +} + +__STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_reg) +{ + p_reg->RXD.LIST = 0; +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SPIM_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_spis.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_spis.h new file mode 100644 index 0000000000000000000000000000000000000000..68746ad38203ab1fdfaca04bf93cd0fdd3eef6b5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_spis.h @@ -0,0 +1,553 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @defgroup nrf_spis_hal SPIS HAL + * @{ + * @ingroup nrf_spis + * + * @brief Hardware access layer for accessing the SPIS peripheral. + */ + +#ifndef NRF_SPIS_H__ +#define NRF_SPIS_H__ + +#include +#include +#include + +#include "nrf.h" +#include "nrf_peripherals.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief This value can be used as a parameter for the @ref nrf_spis_pins_set + * function to specify that a given SPI signal (SCK, MOSI, or MISO) + * shall not be connected to a physical pin. + */ +#define NRF_SPIS_PIN_NOT_CONNECTED 0xFFFFFFFF + + +/** + * @brief SPIS tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_SPIS_TASK_ACQUIRE = offsetof(NRF_SPIS_Type, TASKS_ACQUIRE), ///< Acquire SPI semaphore. + NRF_SPIS_TASK_RELEASE = offsetof(NRF_SPIS_Type, TASKS_RELEASE), ///< Release SPI semaphore, enabling the SPI slave to acquire it. + /*lint -restore*/ +} nrf_spis_task_t; + +/** + * @brief SPIS events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_SPIS_EVENT_END = offsetof(NRF_SPIS_Type, EVENTS_END), ///< Granted transaction completed. + NRF_SPIS_EVENT_ACQUIRED = offsetof(NRF_SPIS_Type, EVENTS_ACQUIRED) ///< Semaphore acquired. + /*lint -restore*/ +} nrf_spis_event_t; + +/** + * @brief SPIS shortcuts. + */ +typedef enum +{ + NRF_SPIS_SHORT_END_ACQUIRE = SPIS_SHORTS_END_ACQUIRE_Msk ///< Shortcut between END event and ACQUIRE task. +} nrf_spis_short_mask_t; + +/** + * @brief SPIS interrupts. + */ +typedef enum +{ + NRF_SPIS_INT_END_MASK = SPIS_INTENSET_END_Msk, ///< Interrupt on END event. + NRF_SPIS_INT_ACQUIRED_MASK = SPIS_INTENSET_ACQUIRED_Msk ///< Interrupt on ACQUIRED event. +} nrf_spis_int_mask_t; + +/** + * @brief SPI modes. + */ +typedef enum +{ + NRF_SPIS_MODE_0, ///< SCK active high, sample on leading edge of clock. + NRF_SPIS_MODE_1, ///< SCK active high, sample on trailing edge of clock. + NRF_SPIS_MODE_2, ///< SCK active low, sample on leading edge of clock. + NRF_SPIS_MODE_3 ///< SCK active low, sample on trailing edge of clock. +} nrf_spis_mode_t; + +/** + * @brief SPI bit orders. + */ +typedef enum +{ + NRF_SPIS_BIT_ORDER_MSB_FIRST = SPIS_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first. + NRF_SPIS_BIT_ORDER_LSB_FIRST = SPIS_CONFIG_ORDER_LsbFirst ///< Least significant bit shifted out first. +} nrf_spis_bit_order_t; + +/** + * @brief SPI semaphore status. + */ +typedef enum +{ + NRF_SPIS_SEMSTAT_FREE = 0, ///< Semaphore is free. + NRF_SPIS_SEMSTAT_CPU = 1, ///< Semaphore is assigned to the CPU. + NRF_SPIS_SEMSTAT_SPIS = 2, ///< Semaphore is assigned to the SPI slave. + NRF_SPIS_SEMSTAT_CPUPENDING = 3 ///< Semaphore is assigned to the SPI, but a handover to the CPU is pending. +} nrf_spis_semstat_t; + +/** + * @brief SPIS status. + */ +typedef enum +{ + NRF_SPIS_STATUS_OVERREAD = SPIS_STATUS_OVERREAD_Msk, ///< TX buffer over-read detected and prevented. + NRF_SPIS_STATUS_OVERFLOW = SPIS_STATUS_OVERFLOW_Msk ///< RX buffer overflow detected and prevented. +} nrf_spis_status_mask_t; + +/** + * @brief Function for activating a specific SPIS task. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spis_task Task to activate. + */ +__STATIC_INLINE void nrf_spis_task_trigger(NRF_SPIS_Type * p_reg, + nrf_spis_task_t spis_task); + +/** + * @brief Function for getting the address of a specific SPIS task register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spis_task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t nrf_spis_task_address_get(NRF_SPIS_Type const * p_reg, + nrf_spis_task_t spis_task); + +/** + * @brief Function for clearing a specific SPIS event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spis_event Event to clear. + */ +__STATIC_INLINE void nrf_spis_event_clear(NRF_SPIS_Type * p_reg, + nrf_spis_event_t spis_event); + +/** + * @brief Function for checking the state of a specific SPIS event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spis_event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_spis_event_check(NRF_SPIS_Type const * p_reg, + nrf_spis_event_t spis_event); + +/** + * @brief Function for getting the address of a specific SPIS event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spis_event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t nrf_spis_event_address_get(NRF_SPIS_Type const * p_reg, + nrf_spis_event_t spis_event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spis_shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_spis_shorts_enable(NRF_SPIS_Type * p_reg, + uint32_t spis_shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spis_shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_spis_shorts_disable(NRF_SPIS_Type * p_reg, + uint32_t spis_shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spis_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_spis_int_enable(NRF_SPIS_Type * p_reg, + uint32_t spis_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spis_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_spis_int_disable(NRF_SPIS_Type * p_reg, + uint32_t spis_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spis_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_spis_int_enable_check(NRF_SPIS_Type const * p_reg, + nrf_spis_int_mask_t spis_int); + +/** + * @brief Function for enabling the SPIS peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spis_enable(NRF_SPIS_Type * p_reg); + +/** + * @brief Function for disabling the SPIS peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spis_disable(NRF_SPIS_Type * p_reg); + +/** + * @brief Function for retrieving the SPIS semaphore status. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @returns Current semaphore status. + */ +__STATIC_INLINE nrf_spis_semstat_t nrf_spis_semaphore_status_get(NRF_SPIS_Type * p_reg); + +/** + * @brief Function for retrieving the SPIS status. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @returns Current SPIS status. + */ +__STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_reg); + +/** + * @brief Function for configuring SPIS pins. + * + * If a given signal is not needed, pass the @ref NRF_SPIS_PIN_NOT_CONNECTED + * value instead of its pin number. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] sck_pin SCK pin number. + * @param[in] mosi_pin MOSI pin number. + * @param[in] miso_pin MISO pin number. + * @param[in] csn_pin CSN pin number. + */ +__STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_reg, + uint32_t sck_pin, + uint32_t mosi_pin, + uint32_t miso_pin, + uint32_t csn_pin); + +/** + * @brief Function for setting the transmit buffer. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] p_buffer Pointer to the buffer that contains the data to send. + * @param[in] length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_spis_tx_buffer_set(NRF_SPIS_Type * p_reg, + uint8_t const * p_buffer, + uint8_t length); + +/** + * @brief Function for setting the receive buffer. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] p_buffer Pointer to the buffer for received data. + * @param[in] length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_reg, + uint8_t * p_buffer, + uint8_t length); + +/** + * @brief Function for getting the number of bytes transmitted + * in the last granted transaction. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @returns Number of bytes transmitted. + */ +__STATIC_INLINE uint8_t nrf_spis_tx_amount_get(NRF_SPIS_Type const * p_reg); + +/** + * @brief Function for getting the number of bytes received + * in the last granted transaction. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @returns Number of bytes received. + */ +__STATIC_INLINE uint8_t nrf_spis_rx_amount_get(NRF_SPIS_Type const * p_reg); + +/** + * @brief Function for setting the SPI configuration. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] spi_mode SPI mode. + * @param[in] spi_bit_order SPI bit order. + */ +__STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_reg, + nrf_spis_mode_t spi_mode, + nrf_spis_bit_order_t spi_bit_order); + +/** + * @brief Function for setting the default character. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] def Default character that is clocked out in case of + * an overflow of the RXD buffer. + */ +__STATIC_INLINE void nrf_spis_def_set(NRF_SPIS_Type * p_reg, + uint8_t def); + +/** + * @brief Function for setting the over-read character. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] orc Over-read character that is clocked out in case of + * an over-read of the TXD buffer. + */ +__STATIC_INLINE void nrf_spis_orc_set(NRF_SPIS_Type * p_reg, + uint8_t orc); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_spis_task_trigger(NRF_SPIS_Type * p_reg, + nrf_spis_task_t spis_task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spis_task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_spis_task_address_get(NRF_SPIS_Type const * p_reg, + nrf_spis_task_t spis_task) +{ + return (uint32_t)p_reg + (uint32_t)spis_task; +} + +__STATIC_INLINE void nrf_spis_event_clear(NRF_SPIS_Type * p_reg, + nrf_spis_event_t spis_event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spis_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spis_event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_spis_event_check(NRF_SPIS_Type const * p_reg, + nrf_spis_event_t spis_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spis_event); +} + +__STATIC_INLINE uint32_t nrf_spis_event_address_get(NRF_SPIS_Type const * p_reg, + nrf_spis_event_t spis_event) +{ + return (uint32_t)p_reg + (uint32_t)spis_event; +} + +__STATIC_INLINE void nrf_spis_shorts_enable(NRF_SPIS_Type * p_reg, + uint32_t spis_shorts_mask) +{ + p_reg->SHORTS |= spis_shorts_mask; +} + +__STATIC_INLINE void nrf_spis_shorts_disable(NRF_SPIS_Type * p_reg, + uint32_t spis_shorts_mask) +{ + p_reg->SHORTS &= ~(spis_shorts_mask); +} + +__STATIC_INLINE void nrf_spis_int_enable(NRF_SPIS_Type * p_reg, + uint32_t spis_int_mask) +{ + p_reg->INTENSET = spis_int_mask; +} + +__STATIC_INLINE void nrf_spis_int_disable(NRF_SPIS_Type * p_reg, + uint32_t spis_int_mask) +{ + p_reg->INTENCLR = spis_int_mask; +} + +__STATIC_INLINE bool nrf_spis_int_enable_check(NRF_SPIS_Type const * p_reg, + nrf_spis_int_mask_t spis_int) +{ + return (bool)(p_reg->INTENSET & spis_int); +} + +__STATIC_INLINE void nrf_spis_enable(NRF_SPIS_Type * p_reg) +{ + p_reg->ENABLE = (SPIS_ENABLE_ENABLE_Enabled << SPIS_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_spis_disable(NRF_SPIS_Type * p_reg) +{ + p_reg->ENABLE = (SPIS_ENABLE_ENABLE_Disabled << SPIS_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE nrf_spis_semstat_t nrf_spis_semaphore_status_get(NRF_SPIS_Type * p_reg) +{ + return (nrf_spis_semstat_t) ((p_reg->SEMSTAT & SPIS_SEMSTAT_SEMSTAT_Msk) + >> SPIS_SEMSTAT_SEMSTAT_Pos); +} + +__STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_reg) +{ + return (nrf_spis_status_mask_t) p_reg->STATUS; +} + +__STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_reg, + uint32_t sck_pin, + uint32_t mosi_pin, + uint32_t miso_pin, + uint32_t csn_pin) +{ + p_reg->PSELSCK = sck_pin; + p_reg->PSELMOSI = mosi_pin; + p_reg->PSELMISO = miso_pin; + p_reg->PSELCSN = csn_pin; +} + +__STATIC_INLINE void nrf_spis_tx_buffer_set(NRF_SPIS_Type * p_reg, + uint8_t const * p_buffer, + uint8_t length) +{ + p_reg->TXDPTR = (uint32_t)p_buffer; + p_reg->MAXTX = length; +} + +__STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_reg, + uint8_t * p_buffer, + uint8_t length) +{ + p_reg->RXDPTR = (uint32_t)p_buffer; + p_reg->MAXRX = length; +} + +__STATIC_INLINE uint8_t nrf_spis_tx_amount_get(NRF_SPIS_Type const * p_reg) +{ + return (uint8_t) p_reg->AMOUNTTX; +} + +__STATIC_INLINE uint8_t nrf_spis_rx_amount_get(NRF_SPIS_Type const * p_reg) +{ + return (uint8_t) p_reg->AMOUNTRX; +} + +__STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_reg, + nrf_spis_mode_t spi_mode, + nrf_spis_bit_order_t spi_bit_order) +{ + uint32_t config = (spi_bit_order == NRF_SPIS_BIT_ORDER_MSB_FIRST ? + SPIS_CONFIG_ORDER_MsbFirst : SPIS_CONFIG_ORDER_LsbFirst); + + switch (spi_mode) + { + default: + case NRF_SPIS_MODE_0: + config |= (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) | + (SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos); + break; + + case NRF_SPIS_MODE_1: + config |= (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) | + (SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos); + break; + + case NRF_SPIS_MODE_2: + config |= (SPIS_CONFIG_CPOL_ActiveLow << SPIS_CONFIG_CPOL_Pos) | + (SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos); + break; + + case NRF_SPIS_MODE_3: + config |= (SPIS_CONFIG_CPOL_ActiveLow << SPIS_CONFIG_CPOL_Pos) | + (SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos); + break; + } + p_reg->CONFIG = config; +} + +__STATIC_INLINE void nrf_spis_orc_set(NRF_SPIS_Type * p_reg, + uint8_t orc) +{ + p_reg->ORC = orc; +} + +__STATIC_INLINE void nrf_spis_def_set(NRF_SPIS_Type * p_reg, + uint8_t def) +{ + p_reg->DEF = def; +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SPIS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_systick.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_systick.h new file mode 100644 index 0000000000000000000000000000000000000000..26fbf37e33a42dff2429f224b4713887c58d3e6f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_systick.h @@ -0,0 +1,184 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SYSTICK_H__ +#define NRF_SYSTICK_H__ + +#include "nrf.h" +#include +#include +#include + +/** + * @defgroup nrf_systick_hal SYSTICK HAL + * @{ + * @ingroup nrf_systick + * + * @brief Hardware access layer for accessing the SYSTICK peripheral. + * + * SYSTICK is ARM peripheral, not Nordic design. + * It means that it has no Nordic-typical interface with Tasks and Events. + * + * Its usage is limited here to implement simple delays. + * Also keep in mind that this timer would be stopped when CPU is sleeping + * (WFE/WFI instruction is successfully executed). + */ + +/** + * @brief Mask of usable bits in the SysTick value + */ +#define NRF_SYSTICK_VAL_MASK SysTick_VAL_CURRENT_Msk + +/** + * @brief Flags used by SysTick configuration. + * + * @sa nrf_systick_csr_set + * @sa nrf_systick_csr_get + */ +typedef enum { + NRF_SYSTICK_CSR_COUNTFLAG_MASK = SysTick_CTRL_COUNTFLAG_Msk, /**< Status flag: Returns 1 if timer counted to 0 since the last read of this register. */ + + NRF_SYSTICK_CSR_CLKSOURCE_MASK = SysTick_CTRL_CLKSOURCE_Msk, /**< Configuration bit: Select the SysTick clock source. */ + NRF_SYSTICK_CSR_CLKSOURCE_REF = 0U << SysTick_CTRL_CLKSOURCE_Pos, /**< Configuration value: Select reference clock. */ + NRF_SYSTICK_CSR_CLKSOURCE_CPU = 1U << SysTick_CTRL_CLKSOURCE_Pos, /**< Configuration value: Select CPU clock. */ + + NRF_SYSTICK_CSR_TICKINT_MASK = SysTick_CTRL_TICKINT_Msk, /**< Configuration bit: Enables SysTick exception request. */ + NRF_SYSTICK_CSR_TICKINT_ENABLE = 1U << SysTick_CTRL_TICKINT_Pos, /**< Configuration value: Counting down to zero does not assert the SysTick exception request. */ + NRF_SYSTICK_CSR_TICKINT_DISABLE = 0U << SysTick_CTRL_TICKINT_Pos, /**< Configuration value: Counting down to zero to asserts the SysTick exception request. */ + + NRF_SYSTICK_CSR_ENABLE_MASK = SysTick_CTRL_ENABLE_Msk, /**< Configuration bit: Enable the SysTick timer. */ + NRF_SYSTICK_CSR_ENABLE = 1U << SysTick_CTRL_ENABLE_Pos, /**< Configuration value: Counter enabled. */ + NRF_SYSTICK_CSR_DISABLE = 0U << SysTick_CTRL_ENABLE_Pos /**< Configuration value: Counter disabled. */ +} nrf_systick_csr_flags_t; + +/** + * @brief Get Configuration and Status Register + * + * @return Values composed by @ref nrf_systick_csr_flags_t. + * @note The @ref NRF_SYSTICK_CSR_COUNTFLAG_MASK value is cleared when CSR register is read. + */ +__STATIC_INLINE uint32_t nrf_systick_csr_get(void); + +/** + * @brief Set Configuration and Status Register + * + * @param[in] val The value composed from @ref nrf_systick_csr_flags_t. + */ +__STATIC_INLINE void nrf_systick_csr_set(uint32_t val); + +/** + * @brief Get the current reload value. + * + * @return The reload register value. + */ +__STATIC_INLINE uint32_t nrf_systick_load_get(void); + +/** + * @brief Configure the reload value. + * + * @param[in] val The value to set in the reload register. + */ +__STATIC_INLINE void nrf_systick_load_set(uint32_t val); + +/** + * @brief Read the SysTick current value + * + * @return The current SysTick value + * @sa NRF_SYSTICK_VAL_MASK + */ +__STATIC_INLINE uint32_t nrf_systick_val_get(void); + +/** + * @brief Clear the SysTick current value + * + * @note The SysTick does not allow setting current value. + * Any write to VAL register would clear the timer. + */ +__STATIC_INLINE void nrf_systick_val_clear(void); + +/** + * @brief Read the calibration register + * + * @return The calibration register value + */ +__STATIC_INLINE uint32_t nrf_systick_calib_get(void); + + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t nrf_systick_csr_get(void) +{ + return SysTick->CTRL; +} + +__STATIC_INLINE void nrf_systick_csr_set(uint32_t val) +{ + SysTick->CTRL = val; +} + +__STATIC_INLINE uint32_t nrf_systick_load_get(void) +{ + return SysTick->LOAD; +} + +__STATIC_INLINE void nrf_systick_load_set(uint32_t val) +{ + SysTick->LOAD = val; +} + +__STATIC_INLINE uint32_t nrf_systick_val_get(void) +{ + return SysTick->VAL; +} + +__STATIC_INLINE void nrf_systick_val_clear(void) +{ + SysTick->VAL = 0; +} + +__STATIC_INLINE uint32_t nrf_systick_calib_get(void) +{ + return SysTick->CALIB; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +/** @} */ +#endif /* NRF_SYSTICK_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_temp.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_temp.h new file mode 100644 index 0000000000000000000000000000000000000000..415a3e74e27d3649bf5c7a180e6e8365e64d65cb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_temp.h @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_TEMP_H__ +#define NRF_TEMP_H__ + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @defgroup nrf_temperature TEMP (temperature) abstraction +* @{ +* @ingroup nrf_drivers temperature_example +* @brief Temperature module init and read functions. +* +*/ + +/**@cond NO_DOXYGEN */ +#define MASK_SIGN (0x00000200UL) +#define MASK_SIGN_EXTENSION (0xFFFFFC00UL) + +/** + * @brief Function for preparing the temp module for temperature measurement. + * + * This function initializes the TEMP module and writes to the hidden configuration register. + */ +static __INLINE void nrf_temp_init(void) +{ + /**@note Workaround for PAN_028 rev2.0A anomaly 31 - TEMP: Temperature offset value has to be manually loaded to the TEMP module */ + *(uint32_t *) 0x4000C504 = 0; +} + +/** + * @brief Function for reading temperature measurement. + * + * The function reads the 10 bit 2's complement value and transforms it to a 32 bit 2's complement value. + */ +static __INLINE int32_t nrf_temp_read(void) +{ + /**@note Workaround for PAN_028 rev2.0A anomaly 28 - TEMP: Negative measured values are not represented correctly */ + return ((NRF_TEMP->TEMP & MASK_SIGN) != 0) ? (NRF_TEMP->TEMP | MASK_SIGN_EXTENSION) : (NRF_TEMP->TEMP); +} +/**@endcond */ + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_timer.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..d089d01b35be2f841c8083d6393304f37ed47924 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_timer.h @@ -0,0 +1,630 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @defgroup nrf_timer_hal Timer HAL + * @{ + * @ingroup nrf_timer + * + * @brief Hardware access layer for accessing the timer peripheral. + */ + +#ifndef NRF_TIMER_H__ +#define NRF_TIMER_H__ + +#include +#include +#include + +#include "nrf_peripherals.h" +#include "nrf.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Macro for validating the correctness of the BIT_WIDTH setting. + */ + +#define TIMER_MAX_SIZE(id) CONCAT_3(TIMER, id, _MAX_SIZE) + +#define TIMER_BIT_WIDTH_MAX(id, bit_width) \ + (TIMER_MAX_SIZE(id) == 8 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) : \ + (TIMER_MAX_SIZE(id) == 16 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_16) : \ + (TIMER_MAX_SIZE(id) == 24 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_16) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_24) : \ + (TIMER_MAX_SIZE(id) == 32 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_16) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_24) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_32) : \ + false)))) + +#if TIMER_COUNT > 3 +#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \ + ((p_reg == NRF_TIMER0) && (TIMER_BIT_WIDTH_MAX(0, bit_width))) \ + || ((p_reg == NRF_TIMER1) && (TIMER_BIT_WIDTH_MAX(1, bit_width))) \ + || ((p_reg == NRF_TIMER2) && (TIMER_BIT_WIDTH_MAX(2, bit_width))) \ + || ((p_reg == NRF_TIMER3) && (TIMER_BIT_WIDTH_MAX(3, bit_width))) \ + || ((p_reg == NRF_TIMER4) && (TIMER_BIT_WIDTH_MAX(4, bit_width))) ) + +#else +#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \ + ((p_reg == NRF_TIMER0) && TIMER_BIT_WIDTH_MAX(0, bit_width)) \ + || ((p_reg == NRF_TIMER1) && TIMER_BIT_WIDTH_MAX(1, bit_width)) \ + || ((p_reg == NRF_TIMER2) && TIMER_BIT_WIDTH_MAX(2, bit_width)) ) + +#endif + +/** + * @brief Macro for getting the number of capture/compare channels available + * in a given timer instance. + */ +#define NRF_TIMER_CC_CHANNEL_COUNT(id) CONCAT_3(TIMER, id, _CC_NUM) + +/** + * @brief Timer tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_TIMER_TASK_START = offsetof(NRF_TIMER_Type, TASKS_START), ///< Task for starting the timer. + NRF_TIMER_TASK_STOP = offsetof(NRF_TIMER_Type, TASKS_STOP), ///< Task for stopping the timer. + NRF_TIMER_TASK_COUNT = offsetof(NRF_TIMER_Type, TASKS_COUNT), ///< Task for incrementing the timer (in counter mode). + NRF_TIMER_TASK_CLEAR = offsetof(NRF_TIMER_Type, TASKS_CLEAR), ///< Task for resetting the timer value. + NRF_TIMER_TASK_SHUTDOWN = offsetof(NRF_TIMER_Type, TASKS_SHUTDOWN), ///< Task for powering off the timer. + NRF_TIMER_TASK_CAPTURE0 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[0]), ///< Task for capturing the timer value on channel 0. + NRF_TIMER_TASK_CAPTURE1 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[1]), ///< Task for capturing the timer value on channel 1. + NRF_TIMER_TASK_CAPTURE2 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[2]), ///< Task for capturing the timer value on channel 2. + NRF_TIMER_TASK_CAPTURE3 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[3]), ///< Task for capturing the timer value on channel 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_TASK_CAPTURE4 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[4]), ///< Task for capturing the timer value on channel 4. + NRF_TIMER_TASK_CAPTURE5 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[5]), ///< Task for capturing the timer value on channel 5. +#endif + /*lint -restore*/ +} nrf_timer_task_t; + +/** + * @brief Timer events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TIMER_EVENT_COMPARE0 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[0]), ///< Event from compare channel 0. + NRF_TIMER_EVENT_COMPARE1 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[1]), ///< Event from compare channel 1. + NRF_TIMER_EVENT_COMPARE2 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[2]), ///< Event from compare channel 2. + NRF_TIMER_EVENT_COMPARE3 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[3]), ///< Event from compare channel 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_EVENT_COMPARE4 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[4]), ///< Event from compare channel 4. + NRF_TIMER_EVENT_COMPARE5 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[5]), ///< Event from compare channel 5. +#endif + /*lint -restore*/ +} nrf_timer_event_t; + +/** + * @brief Types of timer shortcuts. + */ +typedef enum +{ + NRF_TIMER_SHORT_COMPARE0_STOP_MASK = TIMER_SHORTS_COMPARE0_STOP_Msk, ///< Shortcut for stopping the timer based on compare 0. + NRF_TIMER_SHORT_COMPARE1_STOP_MASK = TIMER_SHORTS_COMPARE1_STOP_Msk, ///< Shortcut for stopping the timer based on compare 1. + NRF_TIMER_SHORT_COMPARE2_STOP_MASK = TIMER_SHORTS_COMPARE2_STOP_Msk, ///< Shortcut for stopping the timer based on compare 2. + NRF_TIMER_SHORT_COMPARE3_STOP_MASK = TIMER_SHORTS_COMPARE3_STOP_Msk, ///< Shortcut for stopping the timer based on compare 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_SHORT_COMPARE4_STOP_MASK = TIMER_SHORTS_COMPARE4_STOP_Msk, ///< Shortcut for stopping the timer based on compare 4. + NRF_TIMER_SHORT_COMPARE5_STOP_MASK = TIMER_SHORTS_COMPARE5_STOP_Msk, ///< Shortcut for stopping the timer based on compare 5. +#endif + NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK = TIMER_SHORTS_COMPARE0_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 0. + NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK = TIMER_SHORTS_COMPARE1_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 1. + NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK = TIMER_SHORTS_COMPARE2_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 2. + NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK = TIMER_SHORTS_COMPARE3_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK = TIMER_SHORTS_COMPARE4_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 4. + NRF_TIMER_SHORT_COMPARE5_CLEAR_MASK = TIMER_SHORTS_COMPARE5_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 5. +#endif +} nrf_timer_short_mask_t; + +/** + * @brief Timer modes. + */ +typedef enum +{ + NRF_TIMER_MODE_TIMER = TIMER_MODE_MODE_Timer, ///< Timer mode: timer. + NRF_TIMER_MODE_COUNTER = TIMER_MODE_MODE_Counter, ///< Timer mode: counter. +#if defined(TIMER_MODE_MODE_LowPowerCounter) || defined(__SDK_DOXYGEN__) + NRF_TIMER_MODE_LOW_POWER_COUNTER = TIMER_MODE_MODE_LowPowerCounter, ///< Timer mode: low-power counter. +#endif +} nrf_timer_mode_t; + +/** + * @brief Timer bit width. + */ +typedef enum +{ + NRF_TIMER_BIT_WIDTH_8 = TIMER_BITMODE_BITMODE_08Bit, ///< Timer bit width 8 bit. + NRF_TIMER_BIT_WIDTH_16 = TIMER_BITMODE_BITMODE_16Bit, ///< Timer bit width 16 bit. + NRF_TIMER_BIT_WIDTH_24 = TIMER_BITMODE_BITMODE_24Bit, ///< Timer bit width 24 bit. + NRF_TIMER_BIT_WIDTH_32 = TIMER_BITMODE_BITMODE_32Bit ///< Timer bit width 32 bit. +} nrf_timer_bit_width_t; + +/** + * @brief Timer prescalers. + */ +typedef enum +{ + NRF_TIMER_FREQ_16MHz = 0, ///< Timer frequency 16 MHz. + NRF_TIMER_FREQ_8MHz, ///< Timer frequency 8 MHz. + NRF_TIMER_FREQ_4MHz, ///< Timer frequency 4 MHz. + NRF_TIMER_FREQ_2MHz, ///< Timer frequency 2 MHz. + NRF_TIMER_FREQ_1MHz, ///< Timer frequency 1 MHz. + NRF_TIMER_FREQ_500kHz, ///< Timer frequency 500 kHz. + NRF_TIMER_FREQ_250kHz, ///< Timer frequency 250 kHz. + NRF_TIMER_FREQ_125kHz, ///< Timer frequency 125 kHz. + NRF_TIMER_FREQ_62500Hz, ///< Timer frequency 62500 Hz. + NRF_TIMER_FREQ_31250Hz ///< Timer frequency 31250 Hz. +} nrf_timer_frequency_t; + +/** + * @brief Timer capture/compare channels. + */ +typedef enum +{ + NRF_TIMER_CC_CHANNEL0 = 0, ///< Timer capture/compare channel 0. + NRF_TIMER_CC_CHANNEL1, ///< Timer capture/compare channel 1. + NRF_TIMER_CC_CHANNEL2, ///< Timer capture/compare channel 2. + NRF_TIMER_CC_CHANNEL3, ///< Timer capture/compare channel 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_CC_CHANNEL4, ///< Timer capture/compare channel 4. + NRF_TIMER_CC_CHANNEL5, ///< Timer capture/compare channel 5. +#endif +} nrf_timer_cc_channel_t; + +/** + * @brief Timer interrupts. + */ +typedef enum +{ + NRF_TIMER_INT_COMPARE0_MASK = TIMER_INTENSET_COMPARE0_Msk, ///< Timer interrupt from compare event on channel 0. + NRF_TIMER_INT_COMPARE1_MASK = TIMER_INTENSET_COMPARE1_Msk, ///< Timer interrupt from compare event on channel 1. + NRF_TIMER_INT_COMPARE2_MASK = TIMER_INTENSET_COMPARE2_Msk, ///< Timer interrupt from compare event on channel 2. + NRF_TIMER_INT_COMPARE3_MASK = TIMER_INTENSET_COMPARE3_Msk, ///< Timer interrupt from compare event on channel 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_INT_COMPARE4_MASK = TIMER_INTENSET_COMPARE4_Msk, ///< Timer interrupt from compare event on channel 4. + NRF_TIMER_INT_COMPARE5_MASK = TIMER_INTENSET_COMPARE5_Msk, ///< Timer interrupt from compare event on channel 5. +#endif +} nrf_timer_int_mask_t; + + +/** + * @brief Function for activating a specific timer task. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg, + nrf_timer_task_t task); + +/** + * @brief Function for getting the address of a specific timer task register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg, + nrf_timer_task_t task); + +/** + * @brief Function for clearing a specific timer event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event); + +/** + * @brief Function for checking the state of a specific timer event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event); + +/** + * @brief Function for getting the address of a specific timer event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg, + uint32_t timer_shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg, + uint32_t timer_shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg, + uint32_t timer_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg, + uint32_t timer_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg, + uint32_t timer_int); + +/** + * @brief Function for setting the timer mode. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] mode Timer mode. + */ +__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg, + nrf_timer_mode_t mode); + +/** + * @brief Function for retrieving the timer mode. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Timer mode. + */ +__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg); + +/** + * @brief Function for setting the timer bit width. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] bit_width Timer bit width. + */ +__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg, + nrf_timer_bit_width_t bit_width); + +/** + * @brief Function for retrieving the timer bit width. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Timer bit width. + */ +__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg); + +/** + * @brief Function for setting the timer frequency. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] frequency Timer frequency. + */ +__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg, + nrf_timer_frequency_t frequency); + +/** + * @brief Function for retrieving the timer frequency. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Timer frequency. + */ +__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg); + +/** + * @brief Function for writing the capture/compare register for a specified channel. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] cc_channel Requested capture/compare channel. + * @param[in] cc_value Value to write to the capture/compare register. + */ +__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg, + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value); + +/** + * @brief Function for retrieving the capture/compare value for a specified channel. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] cc_channel Requested capture/compare channel. + * + * @return Value from the requested capture/compare register. + */ +__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg, + nrf_timer_cc_channel_t cc_channel); + +/** + * @brief Function for getting a specific timer capture task. + * + * @param[in] channel Capture channel. + * + * @return Capture task. + */ +__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel); + +/** + * @brief Function for getting a specific timer compare event. + * + * @param[in] channel Compare channel. + * + * @return Compare event. + */ +__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel); + +/** + * @brief Function for getting a specific timer compare interrupt. + * + * @param[in] channel Compare channel. + * + * @return Compare interrupt. + */ +__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel); + +/** + * @brief Function for calculating the number of timer ticks for a given time + * (in microseconds) and timer frequency. + * + * @param[in] time_us Time in microseconds. + * @param[in] frequency Timer frequency. + * + * @return Number of timer ticks. + */ +__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us, + nrf_timer_frequency_t frequency); + +/** + * @brief Function for calculating the number of timer ticks for a given time + * (in milliseconds) and timer frequency. + * + * @param[in] time_ms Time in milliseconds. + * @param[in] frequency Timer frequency. + * + * @return Number of timer ticks. + */ +__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms, + nrf_timer_frequency_t frequency); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg, + nrf_timer_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg, + nrf_timer_task_t task) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task); +} + +__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg, + uint32_t timer_shorts_mask) +{ + p_reg->SHORTS |= timer_shorts_mask; +} + +__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg, + uint32_t timer_shorts_mask) +{ + p_reg->SHORTS &= ~(timer_shorts_mask); +} + +__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg, + uint32_t timer_int_mask) +{ + p_reg->INTENSET = timer_int_mask; +} + +__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg, + uint32_t timer_int_mask) +{ + p_reg->INTENCLR = timer_int_mask; +} + +__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg, + uint32_t timer_int) +{ + return (bool)(p_reg->INTENSET & timer_int); +} + +__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg, + nrf_timer_mode_t mode) +{ + p_reg->MODE = (p_reg->MODE & ~TIMER_MODE_MODE_Msk) | + ((mode << TIMER_MODE_MODE_Pos) & TIMER_MODE_MODE_Msk); +} + +__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg) +{ + return (nrf_timer_mode_t)(p_reg->MODE); +} + +__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg, + nrf_timer_bit_width_t bit_width) +{ + p_reg->BITMODE = (p_reg->BITMODE & ~TIMER_BITMODE_BITMODE_Msk) | + ((bit_width << TIMER_BITMODE_BITMODE_Pos) & + TIMER_BITMODE_BITMODE_Msk); +} + +__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg) +{ + return (nrf_timer_bit_width_t)(p_reg->BITMODE); +} + +__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg, + nrf_timer_frequency_t frequency) +{ + p_reg->PRESCALER = (p_reg->PRESCALER & ~TIMER_PRESCALER_PRESCALER_Msk) | + ((frequency << TIMER_PRESCALER_PRESCALER_Pos) & + TIMER_PRESCALER_PRESCALER_Msk); +} + +__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg) +{ + return (nrf_timer_frequency_t)(p_reg->PRESCALER); +} + +__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg, + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value) +{ + p_reg->CC[cc_channel] = cc_value; +} + +__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg, + nrf_timer_cc_channel_t cc_channel) +{ + return (uint32_t)p_reg->CC[cc_channel]; +} + +__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel) +{ + return (nrf_timer_task_t) + ((uint32_t)NRF_TIMER_TASK_CAPTURE0 + (channel * sizeof(uint32_t))); +} + +__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel) +{ + return (nrf_timer_event_t) + ((uint32_t)NRF_TIMER_EVENT_COMPARE0 + (channel * sizeof(uint32_t))); +} + +__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel) +{ + return (nrf_timer_int_mask_t) + ((uint32_t)NRF_TIMER_INT_COMPARE0_MASK << channel); +} + +__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us, + nrf_timer_frequency_t frequency) +{ + // The "frequency" parameter here is actually the prescaler value, and the + // timer runs at the following frequency: f = 16 MHz / 2^prescaler. + uint32_t prescaler = (uint32_t)frequency; + ASSERT(time_us <= (UINT32_MAX / 16UL)); + return ((time_us * 16UL) >> prescaler); +} + +__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms, + nrf_timer_frequency_t frequency) +{ + // The "frequency" parameter here is actually the prescaler value, and the + // timer runs at the following frequency: f = 16000 kHz / 2^prescaler. + uint32_t prescaler = (uint32_t)frequency; + ASSERT(time_ms <= (UINT32_MAX / 16000UL)); + return ((time_ms * 16000UL) >> prescaler); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_TIMER_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_twi.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_twi.h new file mode 100644 index 0000000000000000000000000000000000000000..5e80272bec4f720da46ba9e03e7b1d7db0c122dd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_twi.h @@ -0,0 +1,452 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_TWI_H__ +#define NRF_TWI_H__ + +/** + * @defgroup nrf_twi_hal TWI HAL + * @{ + * @ingroup nrf_twi + * + * @brief Hardware access layer for managing the TWI peripheral. + */ + +#include +#include +#include + +#include "nrf_peripherals.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief TWI tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWI_TASK_STARTRX = offsetof(NRF_TWI_Type, TASKS_STARTRX), ///< Start TWI receive sequence. + NRF_TWI_TASK_STARTTX = offsetof(NRF_TWI_Type, TASKS_STARTTX), ///< Start TWI transmit sequence. + NRF_TWI_TASK_STOP = offsetof(NRF_TWI_Type, TASKS_STOP), ///< Stop TWI transaction. + NRF_TWI_TASK_SUSPEND = offsetof(NRF_TWI_Type, TASKS_SUSPEND), ///< Suspend TWI transaction. + NRF_TWI_TASK_RESUME = offsetof(NRF_TWI_Type, TASKS_RESUME) ///< Resume TWI transaction. + /*lint -restore*/ +} nrf_twi_task_t; + +/** + * @brief TWI events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWI_EVENT_STOPPED = offsetof(NRF_TWI_Type, EVENTS_STOPPED), ///< TWI stopped. + NRF_TWI_EVENT_RXDREADY = offsetof(NRF_TWI_Type, EVENTS_RXDREADY), ///< TWI RXD byte received. + NRF_TWI_EVENT_TXDSENT = offsetof(NRF_TWI_Type, EVENTS_TXDSENT), ///< TWI TXD byte sent. + NRF_TWI_EVENT_ERROR = offsetof(NRF_TWI_Type, EVENTS_ERROR), ///< TWI error. + NRF_TWI_EVENT_BB = offsetof(NRF_TWI_Type, EVENTS_BB), ///< TWI byte boundary, generated before each byte that is sent or received. + NRF_TWI_EVENT_SUSPENDED = offsetof(NRF_TWI_Type, EVENTS_SUSPENDED) ///< TWI entered the suspended state. + /*lint -restore*/ +} nrf_twi_event_t; + +/** + * @brief TWI shortcuts. + */ +typedef enum +{ + NRF_TWI_SHORT_BB_SUSPEND_MASK = TWI_SHORTS_BB_SUSPEND_Msk, ///< Shortcut between BB event and SUSPEND task. + NRF_TWI_SHORT_BB_STOP_MASK = TWI_SHORTS_BB_STOP_Msk, ///< Shortcut between BB event and STOP task. +} nrf_twi_short_mask_t; + +/** + * @brief TWI interrupts. + */ +typedef enum +{ + NRF_TWI_INT_STOPPED_MASK = TWI_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event. + NRF_TWI_INT_RXDREADY_MASK = TWI_INTENSET_RXDREADY_Msk, ///< Interrupt on RXDREADY event. + NRF_TWI_INT_TXDSENT_MASK = TWI_INTENSET_TXDSENT_Msk, ///< Interrupt on TXDSENT event. + NRF_TWI_INT_ERROR_MASK = TWI_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event. + NRF_TWI_INT_BB_MASK = TWI_INTENSET_BB_Msk, ///< Interrupt on BB event. + NRF_TWI_INT_SUSPENDED_MASK = TWI_INTENSET_SUSPENDED_Msk ///< Interrupt on SUSPENDED event. +} nrf_twi_int_mask_t; + +/** + * @brief TWI error source. + */ +typedef enum +{ + NRF_TWI_ERROR_ADDRESS_NACK = TWI_ERRORSRC_ANACK_Msk, ///< NACK received after sending the address. + NRF_TWI_ERROR_DATA_NACK = TWI_ERRORSRC_DNACK_Msk, ///< NACK received after sending a data byte. + NRF_TWI_ERROR_OVERRUN = TWI_ERRORSRC_OVERRUN_Msk ///< Overrun error. + /**< A new byte was received before the previous byte was read + * from the RXD register (previous data is lost). */ +} nrf_twi_error_t; + +/** + * @brief TWI master clock frequency. + */ +typedef enum +{ + NRF_TWI_FREQ_100K = TWI_FREQUENCY_FREQUENCY_K100, ///< 100 kbps. + NRF_TWI_FREQ_250K = TWI_FREQUENCY_FREQUENCY_K250, ///< 250 kbps. + NRF_TWI_FREQ_400K = TWI_FREQUENCY_FREQUENCY_K400 ///< 400 kbps. +} nrf_twi_frequency_t; + + +/** + * @brief Function for activating a specific TWI task. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_reg, + nrf_twi_task_t task); + +/** + * @brief Function for getting the address of a specific TWI task register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_reg, + nrf_twi_task_t task); + +/** + * @brief Function for clearing a specific TWI event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_reg, + nrf_twi_event_t event); + +/** + * @brief Function for checking the state of a specific event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_reg, + nrf_twi_event_t event); + +/** + * @brief Function for getting the address of a specific TWI event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_reg, + nrf_twi_event_t event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_reg, + uint32_t shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_reg, + uint32_t shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_reg, + uint32_t int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_reg, + uint32_t int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] int_mask Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_reg, + nrf_twi_int_mask_t int_mask); + +/** + * @brief Function for enabling the TWI peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_reg); + +/** + * @brief Function for disabling the TWI peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_reg); + +/** + * @brief Function for configuring TWI pins. + * + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] scl_pin SCL pin number. + * @param[in] sda_pin SDA pin number. + */ +__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_reg, + uint32_t scl_pin, + uint32_t sda_pin); + +/** + * @brief Function for setting the TWI master clock frequency. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] frequency TWI frequency. + */ +__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_reg, + nrf_twi_frequency_t frequency); + +/** + * @brief Function for checking the TWI error source. + * + * The error flags are cleared after reading. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Mask with error source flags. + */ +__STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_reg); + +/** + * @brief Function for setting the address to be used in TWI transfers. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] address Address to be used in transfers. + */ +__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_reg, uint8_t address); + +/** + * @brief Function for reading data received by TWI. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Received data. + */ +__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_reg); + +/** + * @brief Function for writing data to be transmitted by TWI. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] data Data to be transmitted. + */ +__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_reg, uint8_t data); + +__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_reg, + uint32_t shorts_mask); + +/** + * @} + */ + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_reg, + nrf_twi_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_reg, + nrf_twi_task_t task) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task); +} + +__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_reg, + nrf_twi_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_reg, + nrf_twi_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_reg, + nrf_twi_event_t event) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_reg, + uint32_t shorts_mask) +{ + p_reg->SHORTS |= shorts_mask; +} + +__STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_reg, + uint32_t shorts_mask) +{ + p_reg->SHORTS &= ~(shorts_mask); +} + +__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_reg, + uint32_t int_mask) +{ + p_reg->INTENSET = int_mask; +} + +__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_reg, + uint32_t int_mask) +{ + p_reg->INTENCLR = int_mask; +} + +__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_reg, + nrf_twi_int_mask_t int_mask) +{ + return (bool)(p_reg->INTENSET & int_mask); +} + +__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_reg) +{ + p_reg->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_reg) +{ + p_reg->ENABLE = (TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_reg, + uint32_t scl_pin, + uint32_t sda_pin) +{ +#if defined(TWI_PSEL_SCL_CONNECT_Pos) + p_reg->PSEL.SCL = scl_pin; +#else + p_reg->PSELSCL = scl_pin; +#endif + +#if defined(TWI_PSEL_SDA_CONNECT_Pos) + p_reg->PSEL.SDA = sda_pin; +#else + p_reg->PSELSDA = sda_pin; +#endif +} + +__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_reg, + nrf_twi_frequency_t frequency) +{ + p_reg->FREQUENCY = frequency; +} + +__STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_reg) +{ + uint32_t error_source = p_reg->ERRORSRC; + + // [error flags are cleared by writing '1' on their position] + p_reg->ERRORSRC = error_source; + + return error_source; +} + +__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_reg, uint8_t address) +{ + p_reg->ADDRESS = address; +} + +__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_reg) +{ + return (uint8_t)p_reg->RXD; +} + +__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_reg, uint8_t data) +{ + p_reg->TXD = data; +} + +__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_reg, + uint32_t shorts_mask) +{ + p_reg->SHORTS = shorts_mask; +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_TWI_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_twim.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_twim.h new file mode 100644 index 0000000000000000000000000000000000000000..753cd705544eba1741279567d2b243c3f7571d4b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_twim.h @@ -0,0 +1,518 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_TWIM_H__ +#define NRF_TWIM_H__ + +/** + * @defgroup nrf_twim_hal TWIM HAL + * @{ + * @ingroup nrf_twi + * + * @brief Hardware access layer for managing the TWIM peripheral. + */ + +#include +#include +#include + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief TWIM tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWIM_TASK_STARTRX = offsetof(NRF_TWIM_Type, TASKS_STARTRX), ///< Start TWI receive sequence. + NRF_TWIM_TASK_STARTTX = offsetof(NRF_TWIM_Type, TASKS_STARTTX), ///< Start TWI transmit sequence. + NRF_TWIM_TASK_STOP = offsetof(NRF_TWIM_Type, TASKS_STOP), ///< Stop TWI transaction. + NRF_TWIM_TASK_SUSPEND = offsetof(NRF_TWIM_Type, TASKS_SUSPEND), ///< Suspend TWI transaction. + NRF_TWIM_TASK_RESUME = offsetof(NRF_TWIM_Type, TASKS_RESUME) ///< Resume TWI transaction. + /*lint -restore*/ +} nrf_twim_task_t; + +/** + * @brief TWIM events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWIM_EVENT_STOPPED = offsetof(NRF_TWIM_Type, EVENTS_STOPPED), ///< TWI stopped. + NRF_TWIM_EVENT_ERROR = offsetof(NRF_TWIM_Type, EVENTS_ERROR), ///< TWI error. + NRF_TWIM_EVENT_SUSPENDED = 0x148, ///< TWI suspended. + NRF_TWIM_EVENT_RXSTARTED = offsetof(NRF_TWIM_Type, EVENTS_RXSTARTED), ///< Receive sequence started. + NRF_TWIM_EVENT_TXSTARTED = offsetof(NRF_TWIM_Type, EVENTS_TXSTARTED), ///< Transmit sequence started. + NRF_TWIM_EVENT_LASTRX = offsetof(NRF_TWIM_Type, EVENTS_LASTRX), ///< Byte boundary, starting to receive the last byte. + NRF_TWIM_EVENT_LASTTX = offsetof(NRF_TWIM_Type, EVENTS_LASTTX) ///< Byte boundary, starting to transmit the last byte. + /*lint -restore*/ +} nrf_twim_event_t; + +/** + * @brief TWIM shortcuts. + */ +typedef enum +{ + NRF_TWIM_SHORT_LASTTX_STARTRX_MASK = TWIM_SHORTS_LASTTX_STARTRX_Msk, ///< Shortcut between LASTTX event and STARTRX task. + NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK = TWIM_SHORTS_LASTTX_SUSPEND_Msk, ///< Shortcut between LASTTX event and SUSPEND task. + NRF_TWIM_SHORT_LASTTX_STOP_MASK = TWIM_SHORTS_LASTTX_STOP_Msk, ///< Shortcut between LASTTX event and STOP task. + NRF_TWIM_SHORT_LASTRX_STARTTX_MASK = TWIM_SHORTS_LASTRX_STARTTX_Msk, ///< Shortcut between LASTRX event and STARTTX task. + NRF_TWIM_SHORT_LASTRX_STOP_MASK = TWIM_SHORTS_LASTRX_STOP_Msk ///< Shortcut between LASTRX event and STOP task. +} nrf_twim_short_mask_t; + +/** + * @brief TWIM interrupts. + */ +typedef enum +{ + NRF_TWIM_INT_STOPPED_MASK = TWIM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event. + NRF_TWIM_INT_ERROR_MASK = TWIM_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event. + NRF_TWIM_INT_SUSPENDED_MASK = (1 << 18), ///< Interrupt on SUSPENDED event. + NRF_TWIM_INT_RXSTARTED_MASK = TWIM_INTENSET_RXSTARTED_Msk, ///< Interrupt on RXSTARTED event. + NRF_TWIM_INT_TXSTARTED_MASK = TWIM_INTENSET_TXSTARTED_Msk, ///< Interrupt on TXSTARTED event. + NRF_TWIM_INT_LASTRX_MASK = TWIM_INTENSET_LASTRX_Msk, ///< Interrupt on LASTRX event. + NRF_TWIM_INT_LASTTX_MASK = TWIM_INTENSET_LASTTX_Msk ///< Interrupt on LASTTX event. +} nrf_twim_int_mask_t; + +/** + * @brief TWIM master clock frequency. + */ +typedef enum +{ + NRF_TWIM_FREQ_100K = TWIM_FREQUENCY_FREQUENCY_K100, ///< 100 kbps. + NRF_TWIM_FREQ_250K = TWIM_FREQUENCY_FREQUENCY_K250, ///< 250 kbps. + NRF_TWIM_FREQ_400K = TWIM_FREQUENCY_FREQUENCY_K400 ///< 400 kbps. +} nrf_twim_frequency_t; + +/** + * @brief TWIM error source. + */ +typedef enum +{ + NRF_TWIM_ERROR_ADDRESS_NACK = TWIM_ERRORSRC_ANACK_Msk, ///< NACK received after sending the address. + NRF_TWIM_ERROR_DATA_NACK = TWIM_ERRORSRC_DNACK_Msk ///< NACK received after sending a data byte. +} nrf_twim_error_t; + + +/** + * @brief Function for activating a specific TWIM task. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_reg, + nrf_twim_task_t task); + +/** + * @brief Function for getting the address of a specific TWIM task register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t * nrf_twim_task_address_get(NRF_TWIM_Type * p_reg, + nrf_twim_task_t task); + +/** + * @brief Function for clearing a specific TWIM event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_reg, + nrf_twim_event_t event); + +/** + * @brief Function for checking the state of a specific TWIM event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type * p_reg, + nrf_twim_event_t event); + +/** + * @brief Function for getting the address of a specific TWIM event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t * nrf_twim_event_address_get(NRF_TWIM_Type * p_reg, + nrf_twim_event_t event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_reg, + uint32_t shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_reg, + uint32_t shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_reg, + uint32_t int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_reg, + uint32_t int_mask); + +/** + * @brief Function for checking the state of a given interrupt. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] int_mask Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_twim_int_enable_check(NRF_TWIM_Type * p_reg, + nrf_twim_int_mask_t int_mask); + +/** + * @brief Function for enabling the TWIM peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for disabling the TWIM peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for configuring TWI pins. + * + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] scl_pin SCL pin number. + * @param[in] sda_pin SDA pin number. + */ +__STATIC_INLINE void nrf_twim_pins_set(NRF_TWIM_Type * p_reg, + uint32_t scl_pin, + uint32_t sda_pin); + +/** + * @brief Function for setting the TWI master clock frequency. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] frequency TWI frequency. + */ +__STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_reg, + nrf_twim_frequency_t frequency); + +/** + * @brief Function for checking the TWI error source. + * + * The error flags are cleared after reading. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Mask with error source flags. + */ +__STATIC_INLINE uint32_t nrf_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for setting the address to be used in TWI transfers. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] address Address to be used in transfers. + */ +__STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_reg, + uint8_t address); + +/** + * @brief Function for setting the transmit buffer. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] p_buffer Pointer to the buffer with data to send. + * @param[in] length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_reg, + uint8_t const * p_buffer, + uint8_t length); + +/** + * @brief Function for setting the receive buffer. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] p_buffer Pointer to the buffer for received data. + * @param[in] length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_reg, + uint8_t * p_buffer, + uint8_t length); + +__STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_reg, + uint32_t shorts_mask); + +__STATIC_INLINE uint32_t nrf_twim_txd_amount_get(NRF_TWIM_Type * p_reg); + +__STATIC_INLINE uint32_t nrf_twim_rxd_amount_get(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for enabling the TX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for disabling the TX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for enabling the RX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for disabling the RX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_reg); + +/** + * @} + */ + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_reg, + nrf_twim_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t * nrf_twim_task_address_get(NRF_TWIM_Type * p_reg, + nrf_twim_task_t task) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task); +} + +__STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_reg, + nrf_twim_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type * p_reg, + nrf_twim_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE uint32_t * nrf_twim_event_address_get(NRF_TWIM_Type * p_reg, + nrf_twim_event_t event) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_reg, + uint32_t shorts_mask) +{ + p_reg->SHORTS |= shorts_mask; +} + +__STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_reg, + uint32_t shorts_mask) +{ + p_reg->SHORTS &= ~(shorts_mask); +} + +__STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_reg, + uint32_t int_mask) +{ + p_reg->INTENSET = int_mask; +} + +__STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_reg, + uint32_t int_mask) +{ + p_reg->INTENCLR = int_mask; +} + +__STATIC_INLINE bool nrf_twim_int_enable_check(NRF_TWIM_Type * p_reg, + nrf_twim_int_mask_t int_mask) +{ + return (bool)(p_reg->INTENSET & int_mask); +} + +__STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_reg) +{ + p_reg->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_reg) +{ + p_reg->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_twim_pins_set(NRF_TWIM_Type * p_reg, + uint32_t scl_pin, + uint32_t sda_pin) +{ + p_reg->PSEL.SCL = scl_pin; + p_reg->PSEL.SDA = sda_pin; +} + +__STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_reg, + nrf_twim_frequency_t frequency) +{ + p_reg->FREQUENCY = frequency; +} + +__STATIC_INLINE uint32_t nrf_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_reg) +{ + uint32_t error_source = p_reg->ERRORSRC; + + // [error flags are cleared by writing '1' on their position] + p_reg->ERRORSRC = error_source; + + return error_source; +} + +__STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_reg, + uint8_t address) +{ + p_reg->ADDRESS = address; +} + +__STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_reg, + uint8_t const * p_buffer, + uint8_t length) +{ + p_reg->TXD.PTR = (uint32_t)p_buffer; + p_reg->TXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_reg, + uint8_t * p_buffer, + uint8_t length) +{ + p_reg->RXD.PTR = (uint32_t)p_buffer; + p_reg->RXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_reg, + uint32_t shorts_mask) +{ + p_reg->SHORTS = shorts_mask; +} + +__STATIC_INLINE uint32_t nrf_twim_txd_amount_get(NRF_TWIM_Type * p_reg) +{ + return p_reg->TXD.AMOUNT; +} + +__STATIC_INLINE uint32_t nrf_twim_rxd_amount_get(NRF_TWIM_Type * p_reg) +{ + return p_reg->RXD.AMOUNT; +} + +__STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_reg) +{ + p_reg->TXD.LIST = 1; +} + +__STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_reg) +{ + p_reg->TXD.LIST = 0; +} + +__STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_reg) +{ + p_reg->RXD.LIST = 1; +} + +__STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_reg) +{ + p_reg->RXD.LIST = 0; +} +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_TWIM_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_twis.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_twis.h new file mode 100644 index 0000000000000000000000000000000000000000..3cd56d6ce66edcdd00a5de9d3a95af224a5321b4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_twis.h @@ -0,0 +1,706 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @ingroup nrf_twis + * @defgroup nrf_twis_hal TWIS HAL + * @{ + * + * @brief @tagAPI52 Hardware access layer for Two Wire Interface Slave with EasyDMA + * (TWIS) peripheral. + */ +#ifndef NRF_TWIS_H__ +#define NRF_TWIS_H__ + +#include "nrf.h" +#include "sdk_config.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief TWIS tasks + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWIS_TASK_STOP = offsetof(NRF_TWIS_Type, TASKS_STOP), /**< Stop TWIS transaction */ + NRF_TWIS_TASK_SUSPEND = offsetof(NRF_TWIS_Type, TASKS_SUSPEND), /**< Suspend TWIS transaction */ + NRF_TWIS_TASK_RESUME = offsetof(NRF_TWIS_Type, TASKS_RESUME), /**< Resume TWIS transaction */ + NRF_TWIS_TASK_PREPARERX = offsetof(NRF_TWIS_Type, TASKS_PREPARERX), /**< Prepare the TWIS slave to respond to a write command */ + NRF_TWIS_TASK_PREPARETX = offsetof(NRF_TWIS_Type, TASKS_PREPARETX) /**< Prepare the TWIS slave to respond to a read command */ + /*lint -restore*/ +} nrf_twis_task_t; + +/** + * @brief TWIS events + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWIS_EVENT_STOPPED = offsetof(NRF_TWIS_Type, EVENTS_STOPPED), /**< TWIS stopped */ + NRF_TWIS_EVENT_ERROR = offsetof(NRF_TWIS_Type, EVENTS_ERROR), /**< TWIS error */ + NRF_TWIS_EVENT_RXSTARTED = offsetof(NRF_TWIS_Type, EVENTS_RXSTARTED), /**< Receive sequence started */ + NRF_TWIS_EVENT_TXSTARTED = offsetof(NRF_TWIS_Type, EVENTS_TXSTARTED), /**< Transmit sequence started */ + NRF_TWIS_EVENT_WRITE = offsetof(NRF_TWIS_Type, EVENTS_WRITE), /**< Write command received */ + NRF_TWIS_EVENT_READ = offsetof(NRF_TWIS_Type, EVENTS_READ) /**< Read command received */ + /*lint -restore*/ +} nrf_twis_event_t; + +/** + * @brief TWIS shortcuts + */ +typedef enum +{ + NRF_TWIS_SHORT_WRITE_SUSPEND_MASK = TWIS_SHORTS_WRITE_SUSPEND_Msk, /**< Shortcut between WRITE event and SUSPEND task */ + NRF_TWIS_SHORT_READ_SUSPEND_MASK = TWIS_SHORTS_READ_SUSPEND_Msk, /**< Shortcut between READ event and SUSPEND task */ +} nrf_twis_short_mask_t; + +/** + * @brief TWIS interrupts + */ +typedef enum +{ + NRF_TWIS_INT_STOPPED_MASK = TWIS_INTEN_STOPPED_Msk, /**< Interrupt on STOPPED event */ + NRF_TWIS_INT_ERROR_MASK = TWIS_INTEN_ERROR_Msk, /**< Interrupt on ERROR event */ + NRF_TWIS_INT_RXSTARTED_MASK = TWIS_INTEN_RXSTARTED_Msk, /**< Interrupt on RXSTARTED event */ + NRF_TWIS_INT_TXSTARTED_MASK = TWIS_INTEN_TXSTARTED_Msk, /**< Interrupt on TXSTARTED event */ + NRF_TWIS_INT_WRITE_MASK = TWIS_INTEN_WRITE_Msk, /**< Interrupt on WRITE event */ + NRF_TWIS_INT_READ_MASK = TWIS_INTEN_READ_Msk, /**< Interrupt on READ event */ +} nrf_twis_int_mask_t; + +/** + * @brief TWIS error source + */ +typedef enum +{ + NRF_TWIS_ERROR_OVERFLOW = TWIS_ERRORSRC_OVERFLOW_Msk, /**< RX buffer overflow detected, and prevented */ + NRF_TWIS_ERROR_DATA_NACK = TWIS_ERRORSRC_DNACK_Msk, /**< NACK sent after receiving a data byte */ + NRF_TWIS_ERROR_OVERREAD = TWIS_ERRORSRC_OVERREAD_Msk /**< TX buffer over-read detected, and prevented */ +} nrf_twis_error_t; + +/** + * @brief TWIS address matching configuration + */ +typedef enum +{ + NRF_TWIS_CONFIG_ADDRESS0_MASK = TWIS_CONFIG_ADDRESS0_Msk, /**< Enable or disable address matching on ADDRESS[0] */ + NRF_TWIS_CONFIG_ADDRESS1_MASK = TWIS_CONFIG_ADDRESS1_Msk, /**< Enable or disable address matching on ADDRESS[1] */ + NRF_TWIS_CONFIG_ADDRESS01_MASK = TWIS_CONFIG_ADDRESS0_Msk | TWIS_CONFIG_ADDRESS1_Msk /**< Enable both address matching */ +} nrf_twis_config_addr_mask_t; + +/** + * @brief Variable type to hold amount of data for EasyDMA + * + * Variable of the minimum size that can hold the amount of data to transfer. + * + * @note + * Defined to make it simple to change if EasyDMA would be updated to support more data in + * the future devices to. + */ +typedef uint8_t nrf_twis_amount_t; + +/** + * @brief Smallest variable type to hold TWI address + * + * Variable of the minimum size that can hold single TWI address. + * + * @note + * Defined to make it simple to change if new TWI would support for example + * 10 bit addressing mode. + */ +typedef uint8_t nrf_twis_address_t; + + +/** + * @brief Function for activating a specific TWIS task. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param task Task. + */ +__STATIC_INLINE void nrf_twis_task_trigger(NRF_TWIS_Type * const p_reg, nrf_twis_task_t task); + +/** + * @brief Function for returning the address of a specific TWIS task register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_twis_task_address_get( + NRF_TWIS_Type const * const p_reg, + nrf_twis_task_t task); + +/** + * @brief Function for clearing a specific event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param event Event. + */ +__STATIC_INLINE void nrf_twis_event_clear( + NRF_TWIS_Type * const p_reg, + nrf_twis_event_t event); +/** + * @brief Function for returning the state of a specific event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param event Event. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_twis_event_check( + NRF_TWIS_Type const * const p_reg, + nrf_twis_event_t event); + + +/** + * @brief Function for getting and clearing the state of specific event + * + * This function checks the state of the event and clears it. + * @param[in,out] p_reg Pointer to the peripheral registers structure. + * @param event Event. + * + * @retval true If the event was set. + * @retval false If the event was not set. + */ +__STATIC_INLINE bool nrf_twis_event_get_and_clear( + NRF_TWIS_Type * const p_reg, + nrf_twis_event_t event); + + +/** + * @brief Function for returning the address of a specific TWIS event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param event Event. + * + * @return Address. + */ +__STATIC_INLINE uint32_t nrf_twis_event_address_get( + NRF_TWIS_Type const * const p_reg, + nrf_twis_event_t event); + +/** + * @brief Function for setting a shortcut. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param short_mask Shortcuts mask. + */ +__STATIC_INLINE void nrf_twis_shorts_enable(NRF_TWIS_Type * const p_reg, uint32_t short_mask); + +/** + * @brief Function for clearing shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param short_mask Shortcuts mask. + */ +__STATIC_INLINE void nrf_twis_shorts_disable(NRF_TWIS_Type * const p_reg, uint32_t short_mask); + +/** + * @brief Get the shorts mask + * + * Function returns shorts register. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @return Flags of currently enabled shortcuts + */ +__STATIC_INLINE uint32_t nrf_twis_shorts_get(NRF_TWIS_Type * const p_reg); + +/** + * @brief Function for enabling selected interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param int_mask Interrupts mask. + */ +__STATIC_INLINE void nrf_twis_int_enable(NRF_TWIS_Type * const p_reg, uint32_t int_mask); + +/** + * @brief Function for retrieving the state of selected interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param int_mask Interrupts mask. + * + * @retval true If any of selected interrupts is enabled. + * @retval false If none of selected interrupts is enabled. + */ +__STATIC_INLINE bool nrf_twis_int_enable_check(NRF_TWIS_Type const * const p_reg, uint32_t int_mask); + +/** + * @brief Function for disabling selected interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param int_mask Interrupts mask. + */ +__STATIC_INLINE void nrf_twis_int_disable(NRF_TWIS_Type * const p_reg, uint32_t int_mask); + +/** + * @brief Function for retrieving and clearing the TWIS error source. + * + * @attention Error sources are cleared after read. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @return Error source mask with values from @ref nrf_twis_error_t. + */ +__STATIC_INLINE uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * const p_reg); + +/** + * @brief Get information which of addresses matched + * + * Function returns index in the address table + * that points to the address that already matched. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @return Index of matched address + */ +__STATIC_INLINE uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_reg); + +/** + * @brief Function for enabling TWIS. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twis_enable(NRF_TWIS_Type * const p_reg); + +/** + * @brief Function for disabling TWIS. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twis_disable(NRF_TWIS_Type * const p_reg); + +/** + * @brief Function for configuring TWIS pins. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param scl SCL pin number. + * @param sda SDA pin number. + */ +__STATIC_INLINE void nrf_twis_pins_set(NRF_TWIS_Type * const p_reg, uint32_t scl, uint32_t sda); + +/** + * @brief Function for setting the receive buffer. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param p_buf Pointer to the buffer for received data. + * @param length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_twis_rx_buffer_set( + NRF_TWIS_Type * const p_reg, + uint8_t * p_buf, + nrf_twis_amount_t length); + +/** + * @brief Function that prepares TWIS for receiving + * + * This function sets receive buffer and then sets NRF_TWIS_TASK_PREPARERX task. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param p_buf Pointer to the buffer for received data. + * @param length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_twis_rx_prepare( + NRF_TWIS_Type * const p_reg, + uint8_t * p_buf, + nrf_twis_amount_t length); + +/** + * @brief Function for getting number of bytes received in the last transaction. + * + * @param[in] p_reg TWIS instance. + * @return Amount of bytes received. + * */ +__STATIC_INLINE nrf_twis_amount_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * const p_reg); + +/** + * @brief Function for setting the transmit buffer. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param p_buf Pointer to the buffer with data to send. + * @param length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_twis_tx_buffer_set( + NRF_TWIS_Type * const p_reg, + uint8_t const * p_buf, + nrf_twis_amount_t length); + +/** + * @brief Function that prepares TWIS for transmitting + * + * This function sets transmit buffer and then sets NRF_TWIS_TASK_PREPARETX task. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param p_buf Pointer to the buffer with data to send. + * @param length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_twis_tx_prepare( + NRF_TWIS_Type * const p_reg, + uint8_t const * p_buf, + nrf_twis_amount_t length); + +/** + * @brief Function for getting number of bytes transmitted in the last transaction. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @return Amount of bytes transmitted. + */ +__STATIC_INLINE nrf_twis_amount_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * const p_reg); + +/** + * @brief Function for setting slave address + * + * Function sets the selected address for this TWI interface. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param n Index of address to set + * @param addr Addres to set + * @sa nrf_twis_config_address_set + * @sa nrf_twis_config_address_get + */ +__STATIC_INLINE void nrf_twis_address_set( + NRF_TWIS_Type * const p_reg, + uint_fast8_t n, + nrf_twis_address_t addr); + +/** + * @brief Function for retrieving configured slave address + * + * Function gets the selected address for this TWI interface. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param n Index of address to get + */ +__STATIC_INLINE nrf_twis_address_t nrf_twis_address_get( + NRF_TWIS_Type const * const p_reg, + uint_fast8_t n); + +/** + * @brief Function for setting the device address configuration. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param addr_mask Mask of address indexes of what device should answer to. + * + * @sa nrf_twis_address_set + */ +__STATIC_INLINE void nrf_twis_config_address_set( + NRF_TWIS_Type * const p_reg, + nrf_twis_config_addr_mask_t addr_mask); + +/** + * @brief Function for retrieving the device address configuration. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Mask of address indexes of what device should answer to. + */ +__STATIC_INLINE nrf_twis_config_addr_mask_t nrf_twis_config_address_get( + NRF_TWIS_Type const * const p_reg); + +/** + * @brief Function for setting the over-read character. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] orc Over-read character. Character clocked out in case of + * over-read of the TXD buffer. + */ +__STATIC_INLINE void nrf_twis_orc_set( + NRF_TWIS_Type * const p_reg, + uint8_t orc); + +/** + * @brief Function for setting the over-read character. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Over-read character configured for selected instance. + */ +__STATIC_INLINE uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_reg); + + +/** @} */ /* End of nrf_twis_hal */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +/* ------------------------------------------------------------------------------------------------ + * Internal functions + */ + +/** + * @internal + * @brief Internal function for getting task/event register address + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @oaram offset Offset of the register from the instance beginning + * + * @attention offset has to be modulo 4 value. In other case we can get hardware fault. + * @return Pointer to the register + */ +__STATIC_INLINE volatile uint32_t* nrf_twis_getRegPtr(NRF_TWIS_Type * const p_reg, uint32_t offset) +{ + return (volatile uint32_t*)((uint8_t *)p_reg + (uint32_t)offset); +} + +/** + * @internal + * @brief Internal function for getting task/event register address - constant version + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @oaram offset Offset of the register from the instance beginning + * + * @attention offset has to be modulo 4 value. In other case we can get hardware fault. + * @return Pointer to the register + */ +__STATIC_INLINE volatile const uint32_t* nrf_twis_getRegPtr_c(NRF_TWIS_Type const * const p_reg, uint32_t offset) +{ + return (volatile const uint32_t*)((uint8_t *)p_reg + (uint32_t)offset); +} + + +/* ------------------------------------------------------------------------------------------------ + * Interface functions definitions + */ + + +void nrf_twis_task_trigger(NRF_TWIS_Type * const p_reg, nrf_twis_task_t task) +{ + *(nrf_twis_getRegPtr(p_reg, (uint32_t)task)) = 1UL; +} + +uint32_t nrf_twis_task_address_get( + NRF_TWIS_Type const * const p_reg, + nrf_twis_task_t task) +{ + return (uint32_t)nrf_twis_getRegPtr_c(p_reg, (uint32_t)task); +} + +void nrf_twis_event_clear( + NRF_TWIS_Type * const p_reg, + nrf_twis_event_t event) +{ + *(nrf_twis_getRegPtr(p_reg, (uint32_t)event)) = 0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif +} + +bool nrf_twis_event_check( + NRF_TWIS_Type const * const p_reg, + nrf_twis_event_t event) +{ + return (bool)*nrf_twis_getRegPtr_c(p_reg, (uint32_t)event); +} + +bool nrf_twis_event_get_and_clear( + NRF_TWIS_Type * const p_reg, + nrf_twis_event_t event) +{ + bool ret = nrf_twis_event_check(p_reg, event); + if (ret) + { + nrf_twis_event_clear(p_reg, event); + } + return ret; +} + +uint32_t nrf_twis_event_address_get( + NRF_TWIS_Type const * const p_reg, + nrf_twis_event_t event) +{ + return (uint32_t)nrf_twis_getRegPtr_c(p_reg, (uint32_t)event); +} + +void nrf_twis_shorts_enable(NRF_TWIS_Type * const p_reg, uint32_t short_mask) +{ + p_reg->SHORTS |= short_mask; +} + +void nrf_twis_shorts_disable(NRF_TWIS_Type * const p_reg, uint32_t short_mask) +{ + if (~0U == short_mask) + { + /* Optimized version for "disable all" */ + p_reg->SHORTS = 0; + } + else + { + p_reg->SHORTS &= ~short_mask; + } +} + +uint32_t nrf_twis_shorts_get(NRF_TWIS_Type * const p_reg) +{ + return p_reg->SHORTS; +} + +void nrf_twis_int_enable(NRF_TWIS_Type * const p_reg, uint32_t int_mask) +{ + p_reg->INTENSET = int_mask; +} + +bool nrf_twis_int_enable_check(NRF_TWIS_Type const * const p_reg, uint32_t int_mask) +{ + return (bool)(p_reg->INTENSET & int_mask); +} + +void nrf_twis_int_disable(NRF_TWIS_Type * const p_reg, uint32_t int_mask) +{ + p_reg->INTENCLR = int_mask; +} + +uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * const p_reg) +{ + uint32_t ret = p_reg->ERRORSRC; + p_reg->ERRORSRC = ret; + return ret; +} + +uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_reg) +{ + return (uint_fast8_t)p_reg->MATCH; +} + +void nrf_twis_enable(NRF_TWIS_Type * const p_reg) +{ + p_reg->ENABLE = (TWIS_ENABLE_ENABLE_Enabled << TWIS_ENABLE_ENABLE_Pos); +} + +void nrf_twis_disable(NRF_TWIS_Type * const p_reg) +{ + p_reg->ENABLE = (TWIS_ENABLE_ENABLE_Disabled << TWIS_ENABLE_ENABLE_Pos); +} + +void nrf_twis_pins_set(NRF_TWIS_Type * const p_reg, uint32_t scl, uint32_t sda) +{ + p_reg->PSEL.SCL = scl; + p_reg->PSEL.SDA = sda; +} + +void nrf_twis_rx_buffer_set( + NRF_TWIS_Type * const p_reg, + uint8_t * p_buf, + nrf_twis_amount_t length) +{ + p_reg->RXD.PTR = (uint32_t)p_buf; + p_reg->RXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_twis_rx_prepare( + NRF_TWIS_Type * const p_reg, + uint8_t * p_buf, + nrf_twis_amount_t length) +{ + nrf_twis_rx_buffer_set(p_reg, p_buf, length); + nrf_twis_task_trigger(p_reg, NRF_TWIS_TASK_PREPARERX); +} + +nrf_twis_amount_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * const p_reg) +{ + return (nrf_twis_amount_t)p_reg->RXD.AMOUNT; +} + +void nrf_twis_tx_buffer_set( + NRF_TWIS_Type * const p_reg, + uint8_t const * p_buf, + nrf_twis_amount_t length) +{ + p_reg->TXD.PTR = (uint32_t)p_buf; + p_reg->TXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_twis_tx_prepare( + NRF_TWIS_Type * const p_reg, + uint8_t const * p_buf, + nrf_twis_amount_t length) +{ + nrf_twis_tx_buffer_set(p_reg, p_buf, length); + nrf_twis_task_trigger(p_reg, NRF_TWIS_TASK_PREPARETX); +} + +nrf_twis_amount_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * const p_reg) +{ + return (nrf_twis_amount_t)p_reg->TXD.AMOUNT; +} + +void nrf_twis_address_set( + NRF_TWIS_Type * const p_reg, + uint_fast8_t n, + nrf_twis_address_t addr) +{ + p_reg->ADDRESS[n] = addr; +} + +nrf_twis_address_t nrf_twis_address_get( + NRF_TWIS_Type const * const p_reg, + uint_fast8_t n) +{ + return (nrf_twis_address_t)p_reg->ADDRESS[n]; +} +void nrf_twis_config_address_set( + NRF_TWIS_Type * const p_reg, + nrf_twis_config_addr_mask_t addr_mask) +{ + /* This is the only configuration in TWIS - just write it without masking */ + p_reg->CONFIG = addr_mask; +} + +nrf_twis_config_addr_mask_t nrf_twis_config_address_get(NRF_TWIS_Type const * const p_reg) +{ + return (nrf_twis_config_addr_mask_t)(p_reg->CONFIG & TWIS_ADDRESS_ADDRESS_Msk); +} + +void nrf_twis_orc_set( + NRF_TWIS_Type * const p_reg, + uint8_t orc) +{ + p_reg->ORC = orc; +} + +uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_reg) +{ + return (uint8_t)p_reg->ORC; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_TWIS_H__ */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_uart.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..5bb1dcd17c5358d41d2a0c1fb8589b1b447cafc2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_uart.h @@ -0,0 +1,549 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_UART_H__ +#define NRF_UART_H__ + +#include "nrf.h" +#include "nrf_peripherals.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//Temporary defining legacy UART for instance 1 +#define NRF_UART1 (NRF_UART_Type *)NRF_UARTE1 + +/** + * @defgroup nrf_uart_hal UART HAL + * @{ + * @ingroup nrf_uart + * + * @brief Hardware access layer for accessing the UART peripheral. + */ + +#define NRF_UART_PSEL_DISCONNECTED 0xFFFFFFFF + +/** + * @enum nrf_uart_task_t + * @brief UART tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_UART_TASK_STARTRX = offsetof(NRF_UART_Type, TASKS_STARTRX), /**< Task for starting reception. */ + NRF_UART_TASK_STOPRX = offsetof(NRF_UART_Type, TASKS_STOPRX), /**< Task for stopping reception. */ + NRF_UART_TASK_STARTTX = offsetof(NRF_UART_Type, TASKS_STARTTX), /**< Task for starting transmission. */ + NRF_UART_TASK_STOPTX = offsetof(NRF_UART_Type, TASKS_STOPTX), /**< Task for stopping transmission. */ + NRF_UART_TASK_SUSPEND = offsetof(NRF_UART_Type, TASKS_SUSPEND), /**< Task for suspending UART. */ + /*lint -restore*/ +} nrf_uart_task_t; + +/** + * @enum nrf_uart_event_t + * @brief UART events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_UART_EVENT_CTS = offsetof(NRF_UART_Type, EVENTS_CTS), /**< Event from CTS line activation. */ + NRF_UART_EVENT_NCTS = offsetof(NRF_UART_Type, EVENTS_NCTS), /**< Event from CTS line deactivation. */ + NRF_UART_EVENT_RXDRDY = offsetof(NRF_UART_Type, EVENTS_RXDRDY),/**< Event from data ready in RXD. */ + NRF_UART_EVENT_TXDRDY = offsetof(NRF_UART_Type, EVENTS_TXDRDY),/**< Event from data sent from TXD. */ + NRF_UART_EVENT_ERROR = offsetof(NRF_UART_Type, EVENTS_ERROR), /**< Event from error detection. */ + NRF_UART_EVENT_RXTO = offsetof(NRF_UART_Type, EVENTS_RXTO) /**< Event from receiver timeout. */ + /*lint -restore*/ +} nrf_uart_event_t; + +/** + * @enum nrf_uart_int_mask_t + * @brief UART interrupts. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_UART_INT_MASK_CTS = UART_INTENCLR_CTS_Msk, /**< CTS line activation interrupt. */ + NRF_UART_INT_MASK_NCTS = UART_INTENCLR_NCTS_Msk, /**< CTS line deactivation interrupt. */ + NRF_UART_INT_MASK_RXDRDY = UART_INTENCLR_RXDRDY_Msk, /**< Data ready in RXD interrupt. */ + NRF_UART_INT_MASK_TXDRDY = UART_INTENCLR_TXDRDY_Msk, /**< Data sent from TXD interrupt. */ + NRF_UART_INT_MASK_ERROR = UART_INTENCLR_ERROR_Msk, /**< Error detection interrupt. */ + NRF_UART_INT_MASK_RXTO = UART_INTENCLR_RXTO_Msk /**< Receiver timeout interrupt. */ + /*lint -restore*/ +} nrf_uart_int_mask_t; + +/** + * @enum nrf_uart_baudrate_t + * @brief Baudrates supported by UART. + */ +typedef enum +{ +#ifdef UARTE_PRESENT + NRF_UART_BAUDRATE_1200 = UARTE_BAUDRATE_BAUDRATE_Baud1200, /**< 1200 baud. */ + NRF_UART_BAUDRATE_2400 = UARTE_BAUDRATE_BAUDRATE_Baud2400, /**< 2400 baud. */ + NRF_UART_BAUDRATE_4800 = UARTE_BAUDRATE_BAUDRATE_Baud4800, /**< 4800 baud. */ + NRF_UART_BAUDRATE_9600 = UARTE_BAUDRATE_BAUDRATE_Baud9600, /**< 9600 baud. */ + NRF_UART_BAUDRATE_14400 = UARTE_BAUDRATE_BAUDRATE_Baud14400, /**< 14400 baud. */ + NRF_UART_BAUDRATE_19200 = UARTE_BAUDRATE_BAUDRATE_Baud19200, /**< 19200 baud. */ + NRF_UART_BAUDRATE_28800 = UARTE_BAUDRATE_BAUDRATE_Baud28800, /**< 28800 baud. */ + NRF_UART_BAUDRATE_38400 = UARTE_BAUDRATE_BAUDRATE_Baud38400, /**< 38400 baud. */ + NRF_UART_BAUDRATE_57600 = UARTE_BAUDRATE_BAUDRATE_Baud57600, /**< 57600 baud. */ + NRF_UART_BAUDRATE_76800 = UARTE_BAUDRATE_BAUDRATE_Baud76800, /**< 76800 baud. */ + NRF_UART_BAUDRATE_115200 = UARTE_BAUDRATE_BAUDRATE_Baud115200, /**< 115200 baud. */ + NRF_UART_BAUDRATE_230400 = UARTE_BAUDRATE_BAUDRATE_Baud230400, /**< 230400 baud. */ + NRF_UART_BAUDRATE_250000 = UARTE_BAUDRATE_BAUDRATE_Baud250000, /**< 250000 baud. */ + NRF_UART_BAUDRATE_460800 = UARTE_BAUDRATE_BAUDRATE_Baud460800, /**< 460800 baud. */ + NRF_UART_BAUDRATE_921600 = UARTE_BAUDRATE_BAUDRATE_Baud921600, /**< 921600 baud. */ + NRF_UART_BAUDRATE_1000000 = UARTE_BAUDRATE_BAUDRATE_Baud1M, /**< 1000000 baud. */ +#else + NRF_UART_BAUDRATE_1200 = UART_BAUDRATE_BAUDRATE_Baud1200, /**< 1200 baud. */ + NRF_UART_BAUDRATE_2400 = UART_BAUDRATE_BAUDRATE_Baud2400, /**< 2400 baud. */ + NRF_UART_BAUDRATE_4800 = UART_BAUDRATE_BAUDRATE_Baud4800, /**< 4800 baud. */ + NRF_UART_BAUDRATE_9600 = UART_BAUDRATE_BAUDRATE_Baud9600, /**< 9600 baud. */ + NRF_UART_BAUDRATE_14400 = UART_BAUDRATE_BAUDRATE_Baud14400, /**< 14400 baud. */ + NRF_UART_BAUDRATE_19200 = UART_BAUDRATE_BAUDRATE_Baud19200, /**< 19200 baud. */ + NRF_UART_BAUDRATE_28800 = UART_BAUDRATE_BAUDRATE_Baud28800, /**< 28800 baud. */ + NRF_UART_BAUDRATE_38400 = UART_BAUDRATE_BAUDRATE_Baud38400, /**< 38400 baud. */ + NRF_UART_BAUDRATE_57600 = UART_BAUDRATE_BAUDRATE_Baud57600, /**< 57600 baud. */ + NRF_UART_BAUDRATE_76800 = UART_BAUDRATE_BAUDRATE_Baud76800, /**< 76800 baud. */ + NRF_UART_BAUDRATE_115200 = UART_BAUDRATE_BAUDRATE_Baud115200, /**< 115200 baud. */ + NRF_UART_BAUDRATE_230400 = UART_BAUDRATE_BAUDRATE_Baud230400, /**< 230400 baud. */ + NRF_UART_BAUDRATE_250000 = UART_BAUDRATE_BAUDRATE_Baud250000, /**< 250000 baud. */ + NRF_UART_BAUDRATE_460800 = UART_BAUDRATE_BAUDRATE_Baud460800, /**< 460800 baud. */ + NRF_UART_BAUDRATE_921600 = UART_BAUDRATE_BAUDRATE_Baud921600, /**< 921600 baud. */ + NRF_UART_BAUDRATE_1000000 = UART_BAUDRATE_BAUDRATE_Baud1M, /**< 1000000 baud. */ +#endif +} nrf_uart_baudrate_t; + +/** + * @enum nrf_uart_error_mask_t + * @brief Types of UART error masks. + */ +typedef enum +{ + NRF_UART_ERROR_OVERRUN_MASK = UART_ERRORSRC_OVERRUN_Msk, /**< Overrun error. */ + NRF_UART_ERROR_PARITY_MASK = UART_ERRORSRC_PARITY_Msk, /**< Parity error. */ + NRF_UART_ERROR_FRAMING_MASK = UART_ERRORSRC_FRAMING_Msk, /**< Framing error. */ + NRF_UART_ERROR_BREAK_MASK = UART_ERRORSRC_BREAK_Msk, /**< Break error. */ +} nrf_uart_error_mask_t; + +/** + * @enum nrf_uart_parity_t + * @brief Types of UART parity modes. + */ +typedef enum +{ + NRF_UART_PARITY_EXCLUDED = UART_CONFIG_PARITY_Excluded << UART_CONFIG_PARITY_Pos, /**< Parity excluded. */ + NRF_UART_PARITY_INCLUDED = UART_CONFIG_PARITY_Included << UART_CONFIG_PARITY_Pos, /**< Parity included. */ +} nrf_uart_parity_t; + +/** + * @enum nrf_uart_hwfc_t + * @brief Types of UART flow control modes. + */ +typedef enum +{ + NRF_UART_HWFC_DISABLED = UART_CONFIG_HWFC_Disabled, /**< HW flow control disabled. */ + NRF_UART_HWFC_ENABLED = UART_CONFIG_HWFC_Enabled, /**< HW flow control enabled. */ +} nrf_uart_hwfc_t; + +/** + * @brief Function for clearing a specific UART event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event); + +/** + * @brief Function for checking the state of a specific UART event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to check. + * + * @retval True if event is set, False otherwise. + */ +__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_t event); + +/** + * @brief Function for returning the address of a specific UART event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Desired event. + * + * @retval Address of specified event register. + */ +__STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type * p_reg, + nrf_uart_event_t event); + +/** + * @brief Function for enabling a specific interrupt. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param int_mask Mask of interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t int_mask); + +/** + * @brief Function for disabling specific interrupts. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t int_mask); + +/** + * @brief Function for getting error source mask. Function is clearing error source flags after reading. + * + * @param p_reg Pointer to the peripheral registers structure. + * @return Mask with error source flags. + */ +__STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg); + +/** + * @brief Function for enabling UART. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type * p_reg); + +/** + * @brief Function for disabling UART. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg); + +/** + * @brief Function for configuring TX/RX pins. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param pseltxd TXD pin number. + * @param pselrxd RXD pin number. + */ +__STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd); + +/** + * @brief Function for disconnecting TX/RX pins. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg); + +/** + * @brief Function for getting TX pin. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg); + +/** + * @brief Function for getting RX pin. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg); + +/** + * @brief Function for getting RTS pin. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg); + +/** + * @brief Function for getting CTS pin. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg); + + +/** + * @brief Function for configuring flow control pins. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param pselrts RTS pin number. + * @param pselcts CTS pin number. + */ +__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg, + uint32_t pselrts, + uint32_t pselcts); + +/** + * @brief Function for disconnecting flow control pins. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg); + +/** + * @brief Function for reading RX data. + * + * @param p_reg Pointer to the peripheral registers structure. + * @return Received byte. + */ +__STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type * p_reg); + +/** + * @brief Function for setting Tx data. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param txd Byte. + */ +__STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd); + +/** + * @brief Function for starting an UART task. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param task Task. + */ +__STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task); + +/** + * @brief Function for returning the address of a specific task register. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type * p_reg, nrf_uart_task_t task); + +/** + * @brief Function for configuring UART. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param hwfc Hardware flow control. Enabled if true. + * @param parity Parity. Included if true. + */ +__STATIC_INLINE void nrf_uart_configure(NRF_UART_Type * p_reg, + nrf_uart_parity_t parity, + nrf_uart_hwfc_t hwfc); + +/** + * @brief Function for setting UART baudrate. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param baudrate Baudrate. + */ +__STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_baudrate_t baudrate); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION +__STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif + +} + +__STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type * p_reg, + nrf_uart_event_t event) +{ + return (uint32_t)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t int_mask) +{ + p_reg->INTENSET = int_mask; +} + +__STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t int_mask) +{ + return (bool)(p_reg->INTENSET & int_mask); +} + +__STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t int_mask) +{ + p_reg->INTENCLR = int_mask; +} + +__STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg) +{ + uint32_t errsrc_mask = p_reg->ERRORSRC; + p_reg->ERRORSRC = errsrc_mask; + return errsrc_mask; +} + +__STATIC_INLINE void nrf_uart_enable(NRF_UART_Type * p_reg) +{ + p_reg->ENABLE = UART_ENABLE_ENABLE_Enabled; +} + +__STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg) +{ + p_reg->ENABLE = UART_ENABLE_ENABLE_Disabled; +} + +__STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd) +{ +#if defined(UART_PSEL_RXD_CONNECT_Pos) + p_reg->PSEL.RXD = pselrxd; +#else + p_reg->PSELRXD = pselrxd; +#endif +#if defined(UART_PSEL_TXD_CONNECT_Pos) + p_reg->PSEL.TXD = pseltxd; +#else + p_reg->PSELTXD = pseltxd; +#endif +} + +__STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg) +{ + nrf_uart_txrx_pins_set(p_reg, NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED); +} + +__STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg) +{ +#if defined(UART_PSEL_TXD_CONNECT_Pos) + return p_reg->PSEL.TXD; +#else + return p_reg->PSELTXD; +#endif +} + +__STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg) +{ +#if defined(UART_PSEL_RXD_CONNECT_Pos) + return p_reg->PSEL.RXD; +#else + return p_reg->PSELRXD; +#endif +} + +__STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg) +{ +#if defined(UART_PSEL_RTS_CONNECT_Pos) + return p_reg->PSEL.RTS; +#else + return p_reg->PSELRTS; +#endif +} + +__STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg) +{ +#if defined(UART_PSEL_RTS_CONNECT_Pos) + return p_reg->PSEL.CTS; +#else + return p_reg->PSELCTS; +#endif +} + +__STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg, uint32_t pselrts, uint32_t pselcts) +{ +#if defined(UART_PSEL_RTS_CONNECT_Pos) + p_reg->PSEL.RTS = pselrts; +#else + p_reg->PSELRTS = pselrts; +#endif + +#if defined(UART_PSEL_RTS_CONNECT_Pos) + p_reg->PSEL.CTS = pselcts; +#else + p_reg->PSELCTS = pselcts; +#endif +} + +__STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg) +{ + nrf_uart_hwfc_pins_set(p_reg, NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED); +} + +__STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type * p_reg) +{ + return p_reg->RXD; +} + +__STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd) +{ + p_reg->TXD = txd; +} + +__STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type * p_reg, nrf_uart_task_t task) +{ + return (uint32_t)p_reg + (uint32_t)task; +} + +__STATIC_INLINE void nrf_uart_configure(NRF_UART_Type * p_reg, + nrf_uart_parity_t parity, + nrf_uart_hwfc_t hwfc) +{ + p_reg->CONFIG = (uint32_t)parity | (uint32_t)hwfc; +} + +__STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_baudrate_t baudrate) +{ + p_reg->BAUDRATE = baudrate; +} +#endif //SUPPRESS_INLINE_IMPLEMENTATION +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif //NRF_UART_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_uarte.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_uarte.h new file mode 100644 index 0000000000000000000000000000000000000000..c4b6abdcd0b74460206a1371a9a3d15d8be51d63 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_uarte.h @@ -0,0 +1,575 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_UARTE_H__ +#define NRF_UARTE_H__ + +#include "nrf.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_UARTE_PSEL_DISCONNECTED 0xFFFFFFFF + +/** + * @defgroup nrf_uarte_hal UARTE HAL + * @{ + * @ingroup nrf_uart + * + * @brief Hardware access layer for accessing the UARTE peripheral. + */ + +/** + * @enum nrf_uarte_task_t + * @brief UARTE tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_UARTE_TASK_STARTRX = offsetof(NRF_UARTE_Type, TASKS_STARTRX),///< Start UART receiver. + NRF_UARTE_TASK_STOPRX = offsetof(NRF_UARTE_Type, TASKS_STOPRX), ///< Stop UART receiver. + NRF_UARTE_TASK_STARTTX = offsetof(NRF_UARTE_Type, TASKS_STARTTX),///< Start UART transmitter. + NRF_UARTE_TASK_STOPTX = offsetof(NRF_UARTE_Type, TASKS_STOPTX), ///< Stop UART transmitter. + NRF_UARTE_TASK_FLUSHRX = offsetof(NRF_UARTE_Type, TASKS_FLUSHRX) ///< Flush RX FIFO in RX buffer. + /*lint -restore*/ +} nrf_uarte_task_t; + +/** + * @enum nrf_uarte_event_t + * @brief UARTE events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_UARTE_EVENT_CTS = offsetof(NRF_UARTE_Type, EVENTS_CTS), ///< CTS is activated. + NRF_UARTE_EVENT_NCTS = offsetof(NRF_UARTE_Type, EVENTS_NCTS), ///< CTS is deactivated. + NRF_UARTE_EVENT_ENDRX = offsetof(NRF_UARTE_Type, EVENTS_ENDRX), ///< Receive buffer is filled up. + NRF_UARTE_EVENT_ENDTX = offsetof(NRF_UARTE_Type, EVENTS_ENDTX), ///< Last TX byte transmitted. + NRF_UARTE_EVENT_ERROR = offsetof(NRF_UARTE_Type, EVENTS_ERROR), ///< Error detected. + NRF_UARTE_EVENT_RXTO = offsetof(NRF_UARTE_Type, EVENTS_RXTO), ///< Receiver timeout. + NRF_UARTE_EVENT_RXSTARTED = offsetof(NRF_UARTE_Type, EVENTS_RXSTARTED),///< Receiver has started. + NRF_UARTE_EVENT_TXSTARTED = offsetof(NRF_UARTE_Type, EVENTS_TXSTARTED),///< Transmitter has started. + NRF_UARTE_EVENT_TXSTOPPED = offsetof(NRF_UARTE_Type, EVENTS_TXSTOPPED) ///< Transmitted stopped. + /*lint -restore*/ +} nrf_uarte_event_t; + +/** + * @brief Types of UARTE shortcuts. + */ +typedef enum +{ + NRF_UARTE_SHORT_ENDRX_STARTRX = UARTE_SHORTS_ENDRX_STARTRX_Msk,///< Shortcut between ENDRX event and STARTRX task. + NRF_UARTE_SHORT_ENDRX_STOPRX = UARTE_SHORTS_ENDRX_STOPRX_Msk, ///< Shortcut between ENDRX event and STOPRX task. +} nrf_uarte_short_t; + + +/** + * @enum nrf_uarte_int_mask_t + * @brief UARTE interrupts. + */ +typedef enum +{ + NRF_UARTE_INT_CTS_MASK = UARTE_INTENSET_CTS_Msk, ///< Interrupt on CTS event. + NRF_UARTE_INT_NCTSRX_MASK = UARTE_INTENSET_NCTS_Msk, ///< Interrupt on NCTS event. + NRF_UARTE_INT_ENDRX_MASK = UARTE_INTENSET_ENDRX_Msk, ///< Interrupt on ENDRX event. + NRF_UARTE_INT_ENDTX_MASK = UARTE_INTENSET_ENDTX_Msk, ///< Interrupt on ENDTX event. + NRF_UARTE_INT_ERROR_MASK = UARTE_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event. + NRF_UARTE_INT_RXTO_MASK = UARTE_INTENSET_RXTO_Msk, ///< Interrupt on RXTO event. + NRF_UARTE_INT_RXSTARTED_MASK = UARTE_INTENSET_RXSTARTED_Msk,///< Interrupt on RXSTARTED event. + NRF_UARTE_INT_TXSTARTED_MASK = UARTE_INTENSET_TXSTARTED_Msk,///< Interrupt on TXSTARTED event. + NRF_UARTE_INT_TXSTOPPED_MASK = UARTE_INTENSET_TXSTOPPED_Msk ///< Interrupt on TXSTOPPED event. +} nrf_uarte_int_mask_t; + +/** + * @enum nrf_uarte_baudrate_t + * @brief Baudrates supported by UARTE. + */ +typedef enum +{ + NRF_UARTE_BAUDRATE_1200 = UARTE_BAUDRATE_BAUDRATE_Baud1200, ///< 1200 baud. + NRF_UARTE_BAUDRATE_2400 = UARTE_BAUDRATE_BAUDRATE_Baud2400, ///< 2400 baud. + NRF_UARTE_BAUDRATE_4800 = UARTE_BAUDRATE_BAUDRATE_Baud4800, ///< 4800 baud. + NRF_UARTE_BAUDRATE_9600 = UARTE_BAUDRATE_BAUDRATE_Baud9600, ///< 9600 baud. + NRF_UARTE_BAUDRATE_14400 = UARTE_BAUDRATE_BAUDRATE_Baud14400, ///< 14400 baud. + NRF_UARTE_BAUDRATE_19200 = UARTE_BAUDRATE_BAUDRATE_Baud19200, ///< 19200 baud. + NRF_UARTE_BAUDRATE_28800 = UARTE_BAUDRATE_BAUDRATE_Baud28800, ///< 28800 baud. + NRF_UARTE_BAUDRATE_38400 = UARTE_BAUDRATE_BAUDRATE_Baud38400, ///< 38400 baud. + NRF_UARTE_BAUDRATE_57600 = UARTE_BAUDRATE_BAUDRATE_Baud57600, ///< 57600 baud. + NRF_UARTE_BAUDRATE_76800 = UARTE_BAUDRATE_BAUDRATE_Baud76800, ///< 76800 baud. + NRF_UARTE_BAUDRATE_115200 = UARTE_BAUDRATE_BAUDRATE_Baud115200, ///< 115200 baud. + NRF_UARTE_BAUDRATE_230400 = UARTE_BAUDRATE_BAUDRATE_Baud230400, ///< 230400 baud. + NRF_UARTE_BAUDRATE_250000 = UARTE_BAUDRATE_BAUDRATE_Baud250000, ///< 250000 baud. + NRF_UARTE_BAUDRATE_460800 = UARTE_BAUDRATE_BAUDRATE_Baud460800, ///< 460800 baud. + NRF_UARTE_BAUDRATE_921600 = UARTE_BAUDRATE_BAUDRATE_Baud921600, ///< 921600 baud. + NRF_UARTE_BAUDRATE_1000000 = UARTE_BAUDRATE_BAUDRATE_Baud1M, ///< 1000000 baud. +} nrf_uarte_baudrate_t; + +/** + * @enum nrf_uarte_error_mask_t + * @brief Types of UARTE error masks. + */ +typedef enum +{ + NRF_UARTE_ERROR_OVERRUN_MASK = UARTE_ERRORSRC_OVERRUN_Msk, ///< Overrun error. + NRF_UARTE_ERROR_PARITY_MASK = UARTE_ERRORSRC_PARITY_Msk, ///< Parity error. + NRF_UARTE_ERROR_FRAMING_MASK = UARTE_ERRORSRC_FRAMING_Msk, ///< Framing error. + NRF_UARTE_ERROR_BREAK_MASK = UARTE_ERRORSRC_BREAK_Msk, ///< Break error. +} nrf_uarte_error_mask_t; + +/** + * @enum nrf_uarte_parity_t + * @brief Types of UARTE parity modes. + */ +typedef enum +{ + NRF_UARTE_PARITY_EXCLUDED = UARTE_CONFIG_PARITY_Excluded << UARTE_CONFIG_PARITY_Pos, ///< Parity excluded. + NRF_UARTE_PARITY_INCLUDED = UARTE_CONFIG_PARITY_Included << UARTE_CONFIG_PARITY_Pos, ///< Parity included. +} nrf_uarte_parity_t; + +/** + * @enum nrf_uarte_hwfc_t + * @brief Types of UARTE flow control modes. + */ +typedef enum +{ + NRF_UARTE_HWFC_DISABLED = UARTE_CONFIG_HWFC_Disabled << UARTE_CONFIG_HWFC_Pos, ///< HW flow control disabled. + NRF_UARTE_HWFC_ENABLED = UARTE_CONFIG_HWFC_Enabled << UARTE_CONFIG_HWFC_Pos, ///< HW flow control enabled. +} nrf_uarte_hwfc_t; + + +/** + * @brief Function for clearing a specific UARTE event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event); + +/** + * @brief Function for checking the state of a specific UARTE event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to check. + * + * @retval True if event is set, False otherwise. + */ +__STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event); + +/** + * @brief Function for returning the address of a specific UARTE event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Desired event. + * + * @retval Address of specified event register. + */ +__STATIC_INLINE uint32_t nrf_uarte_event_address_get(NRF_UARTE_Type * p_reg, + nrf_uarte_event_t event); + +/** + * @brief Function for enabling UARTE shortcuts. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_uarte_shorts_enable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask); + +/** + * @brief Function for disabling UARTE shortcuts. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_uarte_shorts_disable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask); + +/** + * @brief Function for enabling UARTE interrupts. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param int_mask Mask of interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_uarte_int_enable_check(NRF_UARTE_Type * p_reg, nrf_uarte_int_mask_t int_mask); + +/** + * @brief Function for disabling specific interrupts. + * + * @param p_reg Instance. + * @param int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t int_mask); + +/** + * @brief Function for getting error source mask. Function is clearing error source flags after reading. + * + * @param p_reg Pointer to the peripheral registers structure. + * @return Mask with error source flags. + */ +__STATIC_INLINE uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for enabling UARTE. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_uarte_enable(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for disabling UARTE. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_uarte_disable(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for configuring TX/RX pins. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param pseltxd TXD pin number. + * @param pselrxd RXD pin number. + */ +__STATIC_INLINE void nrf_uarte_txrx_pins_set(NRF_UARTE_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd); + +/** + * @brief Function for disconnecting TX/RX pins. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_uarte_txrx_pins_disconnect(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for getting TX pin. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE uint32_t nrf_uarte_tx_pin_get(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for getting RX pin. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE uint32_t nrf_uarte_rx_pin_get(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for getting RTS pin. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE uint32_t nrf_uarte_rts_pin_get(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for getting CTS pin. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE uint32_t nrf_uarte_cts_pin_get(NRF_UARTE_Type * p_reg); + + +/** + * @brief Function for configuring flow control pins. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param pselrts RTS pin number. + * @param pselcts CTS pin number. + */ +__STATIC_INLINE void nrf_uarte_hwfc_pins_set(NRF_UARTE_Type * p_reg, + uint32_t pselrts, + uint32_t pselcts); + +/** + * @brief Function for disconnecting flow control pins. + * + * @param p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_uarte_hwfc_pins_disconnect(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for starting an UARTE task. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param task Task. + */ +__STATIC_INLINE void nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task); + +/** + * @brief Function for returning the address of a specific task register. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_uarte_task_address_get(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task); + +/** + * @brief Function for configuring UARTE. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param hwfc Hardware flow control. Enabled if true. + * @param parity Parity. Included if true. + */ +__STATIC_INLINE void nrf_uarte_configure(NRF_UARTE_Type * p_reg, + nrf_uarte_parity_t parity, + nrf_uarte_hwfc_t hwfc); + + +/** + * @brief Function for setting UARTE baudrate. + * + * @param p_reg Instance. + * @param baudrate Baudrate. + */ +__STATIC_INLINE void nrf_uarte_baudrate_set(NRF_UARTE_Type * p_reg, nrf_uarte_baudrate_t baudrate); + +/** + * @brief Function for setting the transmit buffer. + * + * @param[in] p_reg Instance. + * @param[in] p_buffer Pointer to the buffer with data to send. + * @param[in] length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_uarte_tx_buffer_set(NRF_UARTE_Type * p_reg, + uint8_t const * p_buffer, + uint8_t length); + +/** + * @brief Function for getting number of bytes transmitted in the last transaction. + * + * @param[in] p_reg Instance. + * + * @retval Amount of bytes transmitted. + */ +__STATIC_INLINE uint32_t nrf_uarte_tx_amount_get(NRF_UARTE_Type * p_reg); + +/** + * @brief Function for setting the receive buffer. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] p_buffer Pointer to the buffer for received data. + * @param[in] length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_uarte_rx_buffer_set(NRF_UARTE_Type * p_reg, + uint8_t * p_buffer, + uint8_t length); + +/** + * @brief Function for getting number of bytes received in the last transaction. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @retval Amount of bytes received. + */ +__STATIC_INLINE uint32_t nrf_uarte_rx_amount_get(NRF_UARTE_Type * p_reg); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION +__STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif + +} + +__STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE uint32_t nrf_uarte_event_address_get(NRF_UARTE_Type * p_reg, + nrf_uarte_event_t event) +{ + return (uint32_t)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE void nrf_uarte_shorts_enable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask) +{ + p_reg->SHORTS |= shorts_mask; +} + +__STATIC_INLINE void nrf_uarte_shorts_disable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask) +{ + p_reg->SHORTS &= ~(shorts_mask); +} + +__STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t int_mask) +{ + p_reg->INTENSET = int_mask; +} + +__STATIC_INLINE bool nrf_uarte_int_enable_check(NRF_UARTE_Type * p_reg, nrf_uarte_int_mask_t int_mask) +{ + return (bool)(p_reg->INTENSET & int_mask); +} + +__STATIC_INLINE void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t int_mask) +{ + p_reg->INTENCLR = int_mask; +} + +__STATIC_INLINE uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg) +{ + uint32_t errsrc_mask = p_reg->ERRORSRC; + p_reg->ERRORSRC = errsrc_mask; + return errsrc_mask; +} + +__STATIC_INLINE void nrf_uarte_enable(NRF_UARTE_Type * p_reg) +{ + p_reg->ENABLE = UARTE_ENABLE_ENABLE_Enabled; +} + +__STATIC_INLINE void nrf_uarte_disable(NRF_UARTE_Type * p_reg) +{ + p_reg->ENABLE = UARTE_ENABLE_ENABLE_Disabled; +} + +__STATIC_INLINE void nrf_uarte_txrx_pins_set(NRF_UARTE_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd) +{ + p_reg->PSEL.TXD = pseltxd; + p_reg->PSEL.RXD = pselrxd; +} + +__STATIC_INLINE void nrf_uarte_txrx_pins_disconnect(NRF_UARTE_Type * p_reg) +{ + nrf_uarte_txrx_pins_set(p_reg, NRF_UARTE_PSEL_DISCONNECTED, NRF_UARTE_PSEL_DISCONNECTED); +} + +__STATIC_INLINE uint32_t nrf_uarte_tx_pin_get(NRF_UARTE_Type * p_reg) +{ + return p_reg->PSEL.TXD; +} + +__STATIC_INLINE uint32_t nrf_uarte_rx_pin_get(NRF_UARTE_Type * p_reg) +{ + return p_reg->PSEL.RXD; +} + +__STATIC_INLINE uint32_t nrf_uarte_rts_pin_get(NRF_UARTE_Type * p_reg) +{ + return p_reg->PSEL.RTS; +} + +__STATIC_INLINE uint32_t nrf_uarte_cts_pin_get(NRF_UARTE_Type * p_reg) +{ + return p_reg->PSEL.CTS; +} + +__STATIC_INLINE void nrf_uarte_hwfc_pins_set(NRF_UARTE_Type * p_reg, uint32_t pselrts, uint32_t pselcts) +{ + p_reg->PSEL.RTS = pselrts; + p_reg->PSEL.CTS = pselcts; +} + +__STATIC_INLINE void nrf_uarte_hwfc_pins_disconnect(NRF_UARTE_Type * p_reg) +{ + nrf_uarte_hwfc_pins_set(p_reg, NRF_UARTE_PSEL_DISCONNECTED, NRF_UARTE_PSEL_DISCONNECTED); +} + +__STATIC_INLINE void nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_uarte_task_address_get(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task) +{ + return (uint32_t)p_reg + (uint32_t)task; +} + +__STATIC_INLINE void nrf_uarte_configure(NRF_UARTE_Type * p_reg, + nrf_uarte_parity_t parity, + nrf_uarte_hwfc_t hwfc) +{ + p_reg->CONFIG = (uint32_t)parity | (uint32_t)hwfc; +} + +__STATIC_INLINE void nrf_uarte_baudrate_set(NRF_UARTE_Type * p_reg, nrf_uarte_baudrate_t baudrate) +{ + p_reg->BAUDRATE = baudrate; +} + +__STATIC_INLINE void nrf_uarte_tx_buffer_set(NRF_UARTE_Type * p_reg, + uint8_t const * p_buffer, + uint8_t length) +{ + p_reg->TXD.PTR = (uint32_t)p_buffer; + p_reg->TXD.MAXCNT = length; +} + +__STATIC_INLINE uint32_t nrf_uarte_tx_amount_get(NRF_UARTE_Type * p_reg) +{ + return p_reg->TXD.AMOUNT; +} + +__STATIC_INLINE void nrf_uarte_rx_buffer_set(NRF_UARTE_Type * p_reg, + uint8_t * p_buffer, + uint8_t length) +{ + p_reg->RXD.PTR = (uint32_t)p_buffer; + p_reg->RXD.MAXCNT = length; +} + +__STATIC_INLINE uint32_t nrf_uarte_rx_amount_get(NRF_UARTE_Type * p_reg) +{ + return p_reg->RXD.AMOUNT; +} +#endif //SUPPRESS_INLINE_IMPLEMENTATION +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif //NRF_UARTE_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_usbd.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_usbd.h new file mode 100644 index 0000000000000000000000000000000000000000..53fd5d717b057834612c167fe71d6cfda03e6a82 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_usbd.h @@ -0,0 +1,1334 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef NRF_USBD_H__ +#define NRF_USBD_H__ + +/** + * @ingroup nrf_drivers + * @defgroup nrf_usbd_hal USBD HAL + * @{ + * + * @brief @tagAPI52840 Hardware access layer for Two Wire Interface Slave with EasyDMA + * (USBD) peripheral. + */ + +#include "nrf_peripherals.h" +#include "nrf.h" +#include "nrf_assert.h" +#include +#include +#include + +/** + * @brief USBD tasks + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_USBD_TASK_STARTEPIN0 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[0] ), /**< Captures the EPIN[0].PTR, EPIN[0].MAXCNT and EPIN[0].CONFIG registers values, and enables control endpoint IN 0 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN1 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[1] ), /**< Captures the EPIN[1].PTR, EPIN[1].MAXCNT and EPIN[1].CONFIG registers values, and enables data endpoint IN 1 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN2 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[2] ), /**< Captures the EPIN[2].PTR, EPIN[2].MAXCNT and EPIN[2].CONFIG registers values, and enables data endpoint IN 2 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN3 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[3] ), /**< Captures the EPIN[3].PTR, EPIN[3].MAXCNT and EPIN[3].CONFIG registers values, and enables data endpoint IN 3 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN4 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[4] ), /**< Captures the EPIN[4].PTR, EPIN[4].MAXCNT and EPIN[4].CONFIG registers values, and enables data endpoint IN 4 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN5 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[5] ), /**< Captures the EPIN[5].PTR, EPIN[5].MAXCNT and EPIN[5].CONFIG registers values, and enables data endpoint IN 5 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN6 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[6] ), /**< Captures the EPIN[6].PTR, EPIN[6].MAXCNT and EPIN[6].CONFIG registers values, and enables data endpoint IN 6 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN7 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[7] ), /**< Captures the EPIN[7].PTR, EPIN[7].MAXCNT and EPIN[7].CONFIG registers values, and enables data endpoint IN 7 to respond to traffic from host */ + NRF_USBD_TASK_STARTISOIN = offsetof(NRF_USBD_Type, TASKS_STARTISOIN ), /**< Captures the ISOIN.PTR, ISOIN.MAXCNT and ISOIN.CONFIG registers values, and enables sending data on iso endpoint 8 */ + NRF_USBD_TASK_STARTEPOUT0 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[0]), /**< Captures the EPOUT[0].PTR, EPOUT[0].MAXCNT and EPOUT[0].CONFIG registers values, and enables control endpoint 0 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT1 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[1]), /**< Captures the EPOUT[1].PTR, EPOUT[1].MAXCNT and EPOUT[1].CONFIG registers values, and enables data endpoint 1 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT2 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[2]), /**< Captures the EPOUT[2].PTR, EPOUT[2].MAXCNT and EPOUT[2].CONFIG registers values, and enables data endpoint 2 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT3 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[3]), /**< Captures the EPOUT[3].PTR, EPOUT[3].MAXCNT and EPOUT[3].CONFIG registers values, and enables data endpoint 3 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT4 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[4]), /**< Captures the EPOUT[4].PTR, EPOUT[4].MAXCNT and EPOUT[4].CONFIG registers values, and enables data endpoint 4 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT5 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[5]), /**< Captures the EPOUT[5].PTR, EPOUT[5].MAXCNT and EPOUT[5].CONFIG registers values, and enables data endpoint 5 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT6 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[6]), /**< Captures the EPOUT[6].PTR, EPOUT[6].MAXCNT and EPOUT[6].CONFIG registers values, and enables data endpoint 6 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT7 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[7]), /**< Captures the EPOUT[7].PTR, EPOUT[7].MAXCNT and EPOUT[7].CONFIG registers values, and enables data endpoint 7 to respond to traffic from host */ + NRF_USBD_TASK_STARTISOOUT = offsetof(NRF_USBD_Type, TASKS_STARTISOOUT ), /**< Captures the ISOOUT.PTR, ISOOUT.MAXCNT and ISOOUT.CONFIG registers values, and enables receiving of data on iso endpoint 8 */ + NRF_USBD_TASK_EP0RCVOUT = offsetof(NRF_USBD_Type, TASKS_EP0RCVOUT ), /**< Allows OUT data stage on control endpoint 0 */ + NRF_USBD_TASK_EP0STATUS = offsetof(NRF_USBD_Type, TASKS_EP0STATUS ), /**< Allows status stage on control endpoint 0 */ + NRF_USBD_TASK_EP0STALL = offsetof(NRF_USBD_Type, TASKS_EP0STALL ), /**< STALLs data and status stage on control endpoint 0 */ + NRF_USBD_TASK_DRIVEDPDM = offsetof(NRF_USBD_Type, TASKS_DPDMDRIVE ), /**< Forces D+ and D-lines to the state defined in the DPDMVALUE register */ + NRF_USBD_TASK_NODRIVEDPDM = offsetof(NRF_USBD_Type, TASKS_DPDMNODRIVE ), /**< Stops forcing D+ and D- lines to any state (USB engine takes control) */ + /*lint -restore*/ +}nrf_usbd_task_t; + +/** + * @brief USBD events + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_USBD_EVENT_USBRESET = offsetof(NRF_USBD_Type, EVENTS_USBRESET ), /**< Signals that a USB reset condition has been detected on the USB lines */ + NRF_USBD_EVENT_STARTED = offsetof(NRF_USBD_Type, EVENTS_STARTED ), /**< Confirms that the EPIN[n].PTR, EPIN[n].MAXCNT, EPIN[n].CONFIG, or EPOUT[n].PTR, EPOUT[n].MAXCNT and EPOUT[n].CONFIG registers have been captured on all endpoints reported in the EPSTATUS register */ + NRF_USBD_EVENT_ENDEPIN0 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[0] ), /**< The whole EPIN[0] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN1 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[1] ), /**< The whole EPIN[1] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN2 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[2] ), /**< The whole EPIN[2] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN3 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[3] ), /**< The whole EPIN[3] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN4 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[4] ), /**< The whole EPIN[4] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN5 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[5] ), /**< The whole EPIN[5] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN6 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[6] ), /**< The whole EPIN[6] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN7 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[7] ), /**< The whole EPIN[7] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_EP0DATADONE = offsetof(NRF_USBD_Type, EVENTS_EP0DATADONE), /**< An acknowledged data transfer has taken place on the control endpoint */ + NRF_USBD_EVENT_ENDISOIN0 = offsetof(NRF_USBD_Type, EVENTS_ENDISOIN ), /**< The whole ISOIN buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT0 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[0]), /**< The whole EPOUT[0] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT1 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[1]), /**< The whole EPOUT[1] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT2 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[2]), /**< The whole EPOUT[2] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT3 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[3]), /**< The whole EPOUT[3] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT4 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[4]), /**< The whole EPOUT[4] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT5 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[5]), /**< The whole EPOUT[5] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT6 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[6]), /**< The whole EPOUT[6] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT7 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[7]), /**< The whole EPOUT[7] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDISOOUT0 = offsetof(NRF_USBD_Type, EVENTS_ENDISOOUT ), /**< The whole ISOOUT buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_SOF = offsetof(NRF_USBD_Type, EVENTS_SOF ), /**< Signals that a SOF (start of frame) condition has been detected on the USB lines */ + NRF_USBD_EVENT_USBEVENT = offsetof(NRF_USBD_Type, EVENTS_USBEVENT ), /**< An event or an error not covered by specific events has occurred, check EVENTCAUSE register to find the cause */ + NRF_USBD_EVENT_EP0SETUP = offsetof(NRF_USBD_Type, EVENTS_EP0SETUP ), /**< A valid SETUP token has been received (and acknowledged) on the control endpoint */ + NRF_USBD_EVENT_DATAEP = offsetof(NRF_USBD_Type, EVENTS_EPDATA ), /**< A data transfer has occurred on a data endpoint, indicated by the EPDATASTATUS register */ + NRF_USBD_EVENT_ACCESSFAULT = offsetof(NRF_USBD_Type, EVENTS_ACCESSFAULT), /**< >Access to an unavailable USB register has been attempted (software or EasyDMA) */ + /*lint -restore*/ +}nrf_usbd_event_t; + +/** + * @brief USBD shorts + */ +typedef enum +{ + NRF_USBD_SHORT_EP0DATADONE_STARTEPIN0_MASK = USBD_SHORTS_EP0DATADONE_STARTEPIN0_Msk , /**< Shortcut between EP0DATADONE event and STARTEPIN0 task */ + NRF_USBD_SHORT_EP0DATADONE_STARTEPOUT0_MASK = USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Msk, /**< Shortcut between EP0DATADONE event and STARTEPOUT0 task */ + NRF_USBD_SHORT_EP0DATADONE_EP0STATUS_MASK = USBD_SHORTS_EP0DATADONE_EP0STATUS_Msk , /**< Shortcut between EP0DATADONE event and EP0STATUS task */ + NRF_USBD_SHORT_ENDEPOUT0_EP0STATUS_MASK = USBD_SHORTS_ENDEPOUT0_EP0STATUS_Msk , /**< Shortcut between ENDEPOUT[0] event and EP0STATUS task */ + NRF_USBD_SHORT_ENDEPOUT0_EP0RCVOUT_MASK = USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Msk , /**< Shortcut between ENDEPOUT[0] event and EP0RCVOUT task */ +}nrf_usbd_short_mask_t; + +/** + * @brief USBD interrupts + */ +typedef enum +{ + NRF_USBD_INT_USBRESET_MASK = USBD_INTEN_USBRESET_Msk , /**< Enable or disable interrupt for USBRESET event */ + NRF_USBD_INT_STARTED_MASK = USBD_INTEN_STARTED_Msk , /**< Enable or disable interrupt for STARTED event */ + NRF_USBD_INT_ENDEPIN0_MASK = USBD_INTEN_ENDEPIN0_Msk , /**< Enable or disable interrupt for ENDEPIN[0] event */ + NRF_USBD_INT_ENDEPIN1_MASK = USBD_INTEN_ENDEPIN1_Msk , /**< Enable or disable interrupt for ENDEPIN[1] event */ + NRF_USBD_INT_ENDEPIN2_MASK = USBD_INTEN_ENDEPIN2_Msk , /**< Enable or disable interrupt for ENDEPIN[2] event */ + NRF_USBD_INT_ENDEPIN3_MASK = USBD_INTEN_ENDEPIN3_Msk , /**< Enable or disable interrupt for ENDEPIN[3] event */ + NRF_USBD_INT_ENDEPIN4_MASK = USBD_INTEN_ENDEPIN4_Msk , /**< Enable or disable interrupt for ENDEPIN[4] event */ + NRF_USBD_INT_ENDEPIN5_MASK = USBD_INTEN_ENDEPIN5_Msk , /**< Enable or disable interrupt for ENDEPIN[5] event */ + NRF_USBD_INT_ENDEPIN6_MASK = USBD_INTEN_ENDEPIN6_Msk , /**< Enable or disable interrupt for ENDEPIN[6] event */ + NRF_USBD_INT_ENDEPIN7_MASK = USBD_INTEN_ENDEPIN7_Msk , /**< Enable or disable interrupt for ENDEPIN[7] event */ + NRF_USBD_INT_EP0DATADONE_MASK = USBD_INTEN_EP0DATADONE_Msk, /**< Enable or disable interrupt for EP0DATADONE event */ + NRF_USBD_INT_ENDISOIN0_MASK = USBD_INTEN_ENDISOIN_Msk , /**< Enable or disable interrupt for ENDISOIN[0] event */ + NRF_USBD_INT_ENDEPOUT0_MASK = USBD_INTEN_ENDEPOUT0_Msk , /**< Enable or disable interrupt for ENDEPOUT[0] event */ + NRF_USBD_INT_ENDEPOUT1_MASK = USBD_INTEN_ENDEPOUT1_Msk , /**< Enable or disable interrupt for ENDEPOUT[1] event */ + NRF_USBD_INT_ENDEPOUT2_MASK = USBD_INTEN_ENDEPOUT2_Msk , /**< Enable or disable interrupt for ENDEPOUT[2] event */ + NRF_USBD_INT_ENDEPOUT3_MASK = USBD_INTEN_ENDEPOUT3_Msk , /**< Enable or disable interrupt for ENDEPOUT[3] event */ + NRF_USBD_INT_ENDEPOUT4_MASK = USBD_INTEN_ENDEPOUT4_Msk , /**< Enable or disable interrupt for ENDEPOUT[4] event */ + NRF_USBD_INT_ENDEPOUT5_MASK = USBD_INTEN_ENDEPOUT5_Msk , /**< Enable or disable interrupt for ENDEPOUT[5] event */ + NRF_USBD_INT_ENDEPOUT6_MASK = USBD_INTEN_ENDEPOUT6_Msk , /**< Enable or disable interrupt for ENDEPOUT[6] event */ + NRF_USBD_INT_ENDEPOUT7_MASK = USBD_INTEN_ENDEPOUT7_Msk , /**< Enable or disable interrupt for ENDEPOUT[7] event */ + NRF_USBD_INT_ENDISOOUT0_MASK = USBD_INTEN_ENDISOOUT_Msk , /**< Enable or disable interrupt for ENDISOOUT[0] event */ + NRF_USBD_INT_SOF_MASK = USBD_INTEN_SOF_Msk , /**< Enable or disable interrupt for SOF event */ + NRF_USBD_INT_USBEVENT_MASK = USBD_INTEN_USBEVENT_Msk , /**< Enable or disable interrupt for USBEVENT event */ + NRF_USBD_INT_EP0SETUP_MASK = USBD_INTEN_EP0SETUP_Msk , /**< Enable or disable interrupt for EP0SETUP event */ + NRF_USBD_INT_DATAEP_MASK = USBD_INTEN_EPDATA_Msk , /**< Enable or disable interrupt for EPDATA event */ + NRF_USBD_INT_ACCESSFAULT_MASK = USBD_INTEN_ACCESSFAULT_Msk, /**< Enable or disable interrupt for ACCESSFAULT event */ +}nrf_usbd_int_mask_t; + + +/** + * @brief Function for activating a specific USBD task. + * + * @param task Task. + */ +__STATIC_INLINE void nrf_usbd_task_trigger(nrf_usbd_task_t task); + +/** + * @brief Function for returning the address of a specific USBD task register. + * + * @param task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_usbd_task_address_get(nrf_usbd_task_t task); + +/** + * @brief Function for clearing a specific event. + * + * @param event Event. + */ +__STATIC_INLINE void nrf_usbd_event_clear(nrf_usbd_event_t event); + +/** + * @brief Function for returning the state of a specific event. + * + * @param event Event. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_usbd_event_check(nrf_usbd_event_t event); + +/** + * @brief Function for getting and clearing the state of specific event + * + * This function checks the state of the event and clears it. + * + * @param event Event. + * + * @retval true If the event was set. + * @retval false If the event was not set. + */ +__STATIC_INLINE bool nrf_usbd_event_get_and_clear(nrf_usbd_event_t event); + +/** + * @brief Function for returning the address of a specific USBD event register. + * + * @param event Event. + * + * @return Address. + */ +__STATIC_INLINE uint32_t nrf_usbd_event_address_get(nrf_usbd_event_t event); + +/** + * @brief Function for setting a shortcut. + * + * @param short_mask Shortcuts mask. + */ +__STATIC_INLINE void nrf_usbd_shorts_enable(uint32_t short_mask); + +/** + * @brief Function for clearing shortcuts. + * + * @param short_mask Shortcuts mask. + */ +__STATIC_INLINE void nrf_usbd_shorts_disable(uint32_t short_mask); + +/** + * @brief Get the shorts mask + * + * Function returns shorts register. + * + * @return Flags of currently enabled shortcuts + */ +__STATIC_INLINE uint32_t nrf_usbd_shorts_get(void); + +/** + * @brief Function for enabling selected interrupts. + * + * @param int_mask Interrupts mask. + */ +__STATIC_INLINE void nrf_usbd_int_enable(uint32_t int_mask); + +/** + * @brief Function for retrieving the state of selected interrupts. + * + * @param int_mask Interrupts mask. + * + * @retval true If any of selected interrupts is enabled. + * @retval false If none of selected interrupts is enabled. + */ +__STATIC_INLINE bool nrf_usbd_int_enable_check(uint32_t int_mask); + +/** + * @brief Function for retrieving the information about enabled interrupts. + * + * @return The flags of enabled interrupts. + */ +__STATIC_INLINE uint32_t nrf_usbd_int_enable_get(void); + +/** + * @brief Function for disabling selected interrupts. + * + * @param int_mask Interrupts mask. + */ +__STATIC_INLINE void nrf_usbd_int_disable(uint32_t int_mask); + + +/** @} */ /* End of nrf_usbd_hal */ + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +/* ------------------------------------------------------------------------------------------------ + * Internal functions + */ + +/** + * @internal + * @brief Internal function for getting task/event register address + * + * @oaram offset Offset of the register from the instance beginning + * + * @attention offset has to be modulo 4 value. In other case we can get hardware fault. + * @return Pointer to the register + */ +__STATIC_INLINE volatile uint32_t* nrf_usbd_getRegPtr(uint32_t offset) +{ + return (volatile uint32_t*)(((uint8_t *)NRF_USBD) + (uint32_t)offset); +} + +/** + * @internal + * @brief Internal function for getting task/event register address - constant version + * + * @oaram offset Offset of the register from the instance beginning + * + * @attention offset has to be modulo 4 value. In other case we can get hardware fault. + * @return Pointer to the register + */ +__STATIC_INLINE volatile const uint32_t* nrf_usbd_getRegPtr_c(uint32_t offset) +{ + return (volatile const uint32_t*)(((uint8_t *)NRF_USBD) + (uint32_t)offset); +} + +/* ------------------------------------------------------------------------------------------------ + * Interface functions definitions + */ + +void nrf_usbd_task_trigger(nrf_usbd_task_t task) +{ + *(nrf_usbd_getRegPtr((uint32_t)task)) = 1UL; + __ISB(); + __DSB(); +} + +uint32_t nrf_usbd_task_address_get(nrf_usbd_task_t task) +{ + return (uint32_t)nrf_usbd_getRegPtr_c((uint32_t)task); +} + +void nrf_usbd_event_clear(nrf_usbd_event_t event) +{ + *(nrf_usbd_getRegPtr((uint32_t)event)) = 0UL; + __ISB(); + __DSB(); +} + +bool nrf_usbd_event_check(nrf_usbd_event_t event) +{ + return (bool)*nrf_usbd_getRegPtr_c((uint32_t)event); +} + +bool nrf_usbd_event_get_and_clear(nrf_usbd_event_t event) +{ + bool ret = nrf_usbd_event_check(event); + if (ret) + { + nrf_usbd_event_clear(event); + } + return ret; +} + +uint32_t nrf_usbd_event_address_get(nrf_usbd_event_t event) +{ + return (uint32_t)nrf_usbd_getRegPtr_c((uint32_t)event); +} + +void nrf_usbd_shorts_enable(uint32_t short_mask) +{ + NRF_USBD->SHORTS |= short_mask; +} + +void nrf_usbd_shorts_disable(uint32_t short_mask) +{ + if (~0U == short_mask) + { + /* Optimized version for "disable all" */ + NRF_USBD->SHORTS = 0; + } + else + { + NRF_USBD->SHORTS &= ~short_mask; + } +} + +uint32_t nrf_usbd_shorts_get(void) +{ + return NRF_USBD->SHORTS; +} + +void nrf_usbd_int_enable(uint32_t int_mask) +{ + NRF_USBD->INTENSET = int_mask; +} + +bool nrf_usbd_int_enable_check(uint32_t int_mask) +{ + return !!(NRF_USBD->INTENSET & int_mask); +} + +uint32_t nrf_usbd_int_enable_get(void) +{ + return NRF_USBD->INTENSET; +} + +void nrf_usbd_int_disable(uint32_t int_mask) +{ + NRF_USBD->INTENCLR = int_mask; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +/* ------------------------------------------------------------------------------------------------ + * End of automatically generated part + * ------------------------------------------------------------------------------------------------ + */ +/** + * @ingroup nrf_usbd_hal + * @{ + */ + +/** + * @brief Frame counter size + * + * The number of counts that can be fitted into frame counter + */ +#define NRF_USBD_FRAMECNTR_SIZE \ + ( (USBD_FRAMECNTR_FRAMECNTR_Msk >> USBD_FRAMECNTR_FRAMECNTR_Pos) + 1UL ) +#ifndef USBD_FRAMECNTR_FRAMECNTR_Msk +#error USBD_FRAMECNTR_FRAMECNTR_Msk should be changed into USBD_FRAMECNTR_FRAMECNTR_Msk +#endif + +/** + * @brief First isochronous endpoint number + * + * The number of the first isochronous endpoint + */ +#define NRF_USBD_EPISO_FIRST 8 + +/** + * @brief Total number of IN endpoints + * + * Total number of IN endpoint (including ISOCHRONOUS). + */ +#define NRF_USBD_EPIN_CNT 9 + +/** + * @brief Total number of OUT endpoints + * + * Total number of OUT endpoint (including ISOCHRONOUS). + */ +#define NRF_USBD_EPOUT_CNT 9 + +/** + * @brief Mask of the direction bit in endpoint number + */ +#define NRF_USBD_EP_DIR_Msk (1U << 7) + +/** + * @brief The value of direction bit for IN endpoint direction + */ +#define NRF_USBD_EP_DIR_IN (1U << 7) + +/** + * @brief The value of direction bit for OUT endpoint direction + */ +#define NRF_USBD_EP_DIR_OUT (0U << 7) + +/** + * @brief Macro for making IN endpoint identifier from endpoint number + * + * Macro that sets direction bit to make IN endpoint + * @param[in] epnr Endpoint number + * @return IN Endpoint identifier + */ +#define NRF_USBD_EPIN(epnr) (((uint8_t)(epnr)) | NRF_USBD_EP_DIR_IN) + +/** + * @brief Macro for making OUT endpoint identifier from endpoint number + * + * Macro that sets direction bit to make OUT endpoint + * @param[in] epnr Endpoint number + * @return OUT Endpoint identifier + */ +#define NRF_USBD_EPOUT(epnr) (((uint8_t)(epnr)) | NRF_USBD_EP_DIR_OUT) + +/** + * @brief Macro for extracting the endpoint number from endpoint identifier + * + * Macro that strips out the information about endpoint direction. + * @param[in] ep Endpoint identifier + * @return Endpoint number + */ +#define NRF_USBD_EP_NR_GET(ep) ((uint8_t)(((uint8_t)(ep)) & 0xFU)) + +/** + * @brief Macro for checking endpoint direction + * + * This macro checks if given endpoint has IN direction + * @param ep Endpoint identifier + * @retval true If the endpoint direction is IN + * @retval false If the endpoint direction is OUT + */ +#define NRF_USBD_EPIN_CHECK(ep) ( (((uint8_t)(ep)) & NRF_USBD_EP_DIR_Msk) == NRF_USBD_EP_DIR_IN ) + +/** + * @brief Macro for checking endpoint direction + * + * This macro checks if given endpoint has OUT direction + * @param ep Endpoint identifier + * @retval true If the endpoint direction is OUT + * @retval false If the endpoint direction is IN + */ +#define NRF_USBD_EPOUT_CHECK(ep) ( (((uint8_t)(ep)) & NRF_USBD_EP_DIR_Msk) == NRF_USBD_EP_DIR_OUT ) + +/** + * @brief Macro for checking if endpoint is isochronous + * + * @param ep It can be endpoint identifier or just endpoint number to check + * @retval true The endpoint is isochronous type + * @retval false The endpoint is bulk of interrupt type + */ +#define NRF_USBD_EPISO_CHECK(ep) (NRF_USBD_EP_NR_GET(ep) >= NRF_USBD_EPISO_FIRST) + +/** + * @brief Macro for checking if given number is valid endpoint number + * + * @param ep Endpoint number to check + * @retval true The endpoint is valid + * @retval false The endpoint is not valid + */ +#define NRF_USBD_EP_VALIDATE(ep) ( \ + (NRF_USBD_EPIN_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPIN_CNT)) \ + || \ + (NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPOUT_CNT)) \ + ) + + +/** + * @brief EVENTCAUSE register bit masks + */ +typedef enum +{ + NRF_USBD_EVENTCAUSE_ISOOUTCRC_MASK = USBD_EVENTCAUSE_ISOOUTCRC_Msk, /**< CRC error was detected on isochronous OUT endpoint 8. */ + NRF_USBD_EVENTCAUSE_SUSPEND_MASK = USBD_EVENTCAUSE_SUSPEND_Msk , /**< Signals that the USB lines have been seen idle long enough for the device to enter suspend. */ + NRF_USBD_EVENTCAUSE_RESUME_MASK = USBD_EVENTCAUSE_RESUME_Msk , /**< Signals that a RESUME condition (K state or activity restart) has been detected on the USB lines. */ + NRF_USBD_EVENTCAUSE_READY_MASK = USBD_EVENTCAUSE_READY_Msk /**< MAC is ready for normal operation, rised few us after USBD enabling */ +}nrf_usbd_eventcause_mask_t; + +/** + * @brief BUSSTATE register bit masks + */ +typedef enum +{ + NRF_USBD_BUSSTATE_DM_MASK = USBD_BUSSTATE_DM_Msk, /**< Negative line mask */ + NRF_USBD_BUSSTATE_DP_MASK = USBD_BUSSTATE_DP_Msk, /**< Positive line mask */ + /** Both lines are low */ + NRF_USBD_BUSSTATE_DPDM_LL = (USBD_BUSSTATE_DM_Low << USBD_BUSSTATE_DM_Pos) | (USBD_BUSSTATE_DP_Low << USBD_BUSSTATE_DP_Pos), + /** Positive line is high, negative line is low */ + NRF_USBD_BUSSTATE_DPDM_HL = (USBD_BUSSTATE_DM_Low << USBD_BUSSTATE_DM_Pos) | (USBD_BUSSTATE_DP_High << USBD_BUSSTATE_DP_Pos), + /** Positive line is low, negative line is high */ + NRF_USBD_BUSSTATE_DPDM_LH = (USBD_BUSSTATE_DM_High << USBD_BUSSTATE_DM_Pos) | (USBD_BUSSTATE_DP_Low << USBD_BUSSTATE_DP_Pos), + /** Both lines are high */ + NRF_USBD_BUSSTATE_DPDM_HH = (USBD_BUSSTATE_DM_High << USBD_BUSSTATE_DM_Pos) | (USBD_BUSSTATE_DP_High << USBD_BUSSTATE_DP_Pos), + /** J state */ + NRF_USBD_BUSSTATE_J = NRF_USBD_BUSSTATE_DPDM_HL, + /** K state */ + NRF_USBD_BUSSTATE_K = NRF_USBD_BUSSTATE_DPDM_LH, + /** Single ended 0 */ + NRF_USBD_BUSSTATE_SE0 = NRF_USBD_BUSSTATE_DPDM_LL, + /** Single ended 1 */ + NRF_USBD_BUSSTATE_SE1 = NRF_USBD_BUSSTATE_DPDM_HH +}nrf_usbd_busstate_t; + +/** + * @brief DPDMVALUE register + */ +typedef enum +{ + /**Generate Resume signal. Signal is generated for 50 us or 5 ms, + * depending on bus state */ + NRF_USBD_DPDMVALUE_RESUME = USBD_DPDMVALUE_STATE_Resume, + /** D+ Forced high, D- forced low (J state) */ + NRF_USBD_DPDMVALUE_J = USBD_DPDMVALUE_STATE_J, + /** D+ Forced low, D- forced high (K state) */ + NRF_USBD_DPMVALUE_K = USBD_DPDMVALUE_STATE_K +}nrf_usbd_dpdmvalue_t; + +/** + * @brief Dtoggle value or operation + */ +typedef enum +{ + NRF_USBD_DTOGGLE_NOP = USBD_DTOGGLE_VALUE_Nop, /**< No operation - do not change current data toggle on selected endpoint */ + NRF_USBD_DTOGGLE_DATA0 = USBD_DTOGGLE_VALUE_Data0,/**< Data toggle is DATA0 on selected endpoint */ + NRF_USBD_DTOGGLE_DATA1 = USBD_DTOGGLE_VALUE_Data1 /**< Data toggle is DATA1 on selected endpoint */ +}nrf_usbd_dtoggle_t; + +/** + * @brief EPSTATUS bit masks + */ +typedef enum +{ + NRF_USBD_EPSTATUS_EPIN0_MASK = USBD_EPSTATUS_EPIN0_Msk, + NRF_USBD_EPSTATUS_EPIN1_MASK = USBD_EPSTATUS_EPIN1_Msk, + NRF_USBD_EPSTATUS_EPIN2_MASK = USBD_EPSTATUS_EPIN2_Msk, + NRF_USBD_EPSTATUS_EPIN3_MASK = USBD_EPSTATUS_EPIN3_Msk, + NRF_USBD_EPSTATUS_EPIN4_MASK = USBD_EPSTATUS_EPIN4_Msk, + NRF_USBD_EPSTATUS_EPIN5_MASK = USBD_EPSTATUS_EPIN5_Msk, + NRF_USBD_EPSTATUS_EPIN6_MASK = USBD_EPSTATUS_EPIN6_Msk, + NRF_USBD_EPSTATUS_EPIN7_MASK = USBD_EPSTATUS_EPIN7_Msk, + + NRF_USBD_EPSTATUS_EPOUT0_MASK = USBD_EPSTATUS_EPOUT0_Msk, + NRF_USBD_EPSTATUS_EPOUT1_MASK = USBD_EPSTATUS_EPOUT1_Msk, + NRF_USBD_EPSTATUS_EPOUT2_MASK = USBD_EPSTATUS_EPOUT2_Msk, + NRF_USBD_EPSTATUS_EPOUT3_MASK = USBD_EPSTATUS_EPOUT3_Msk, + NRF_USBD_EPSTATUS_EPOUT4_MASK = USBD_EPSTATUS_EPOUT4_Msk, + NRF_USBD_EPSTATUS_EPOUT5_MASK = USBD_EPSTATUS_EPOUT5_Msk, + NRF_USBD_EPSTATUS_EPOUT6_MASK = USBD_EPSTATUS_EPOUT6_Msk, + NRF_USBD_EPSTATUS_EPOUT7_MASK = USBD_EPSTATUS_EPOUT7_Msk, +}nrf_usbd_epstatus_mask_t; + +/** + * @brief DATAEPSTATUS bit masks + */ +typedef enum +{ + NRF_USBD_EPDATASTATUS_EPIN1_MASK = USBD_EPDATASTATUS_EPIN1_Msk, + NRF_USBD_EPDATASTATUS_EPIN2_MASK = USBD_EPDATASTATUS_EPIN2_Msk, + NRF_USBD_EPDATASTATUS_EPIN3_MASK = USBD_EPDATASTATUS_EPIN3_Msk, + NRF_USBD_EPDATASTATUS_EPIN4_MASK = USBD_EPDATASTATUS_EPIN4_Msk, + NRF_USBD_EPDATASTATUS_EPIN5_MASK = USBD_EPDATASTATUS_EPIN5_Msk, + NRF_USBD_EPDATASTATUS_EPIN6_MASK = USBD_EPDATASTATUS_EPIN6_Msk, + NRF_USBD_EPDATASTATUS_EPIN7_MASK = USBD_EPDATASTATUS_EPIN7_Msk, + + NRF_USBD_EPDATASTATUS_EPOUT1_MASK = USBD_EPDATASTATUS_EPOUT1_Msk, + NRF_USBD_EPDATASTATUS_EPOUT2_MASK = USBD_EPDATASTATUS_EPOUT2_Msk, + NRF_USBD_EPDATASTATUS_EPOUT3_MASK = USBD_EPDATASTATUS_EPOUT3_Msk, + NRF_USBD_EPDATASTATUS_EPOUT4_MASK = USBD_EPDATASTATUS_EPOUT4_Msk, + NRF_USBD_EPDATASTATUS_EPOUT5_MASK = USBD_EPDATASTATUS_EPOUT5_Msk, + NRF_USBD_EPDATASTATUS_EPOUT6_MASK = USBD_EPDATASTATUS_EPOUT6_Msk, + NRF_USBD_EPDATASTATUS_EPOUT7_MASK = USBD_EPDATASTATUS_EPOUT7_Msk, +}nrf_usbd_dataepstatus_mask_t; + +/** + * @brief ISOSPLIT configurations + */ +typedef enum +{ + NRF_USBD_ISOSPLIT_OneDir = USBD_ISOSPLIT_SPLIT_OneDir, /**< Full buffer dedicated to either iso IN or OUT */ + NRF_USBD_ISOSPLIT_Half = USBD_ISOSPLIT_SPLIT_HalfIN, /**< Buffer divided in half */ + +}nrf_usbd_isosplit_t; + +/** + * @brief Function for enabling USBD + */ +__STATIC_INLINE void nrf_usbd_enable(void); + +/** + * @brief Function for disabling USBD + */ +__STATIC_INLINE void nrf_usbd_disable(void); + +/** + * @brief Function for getting EVENTCAUSE register + * + * @return Flag values defined in @ref nrf_usbd_eventcause_mask_t + */ +__STATIC_INLINE uint32_t nrf_usbd_eventcause_get(void); + +/** + * @brief Function for clearing EVENTCAUSE flags + * + * @param flags Flags defined in @ref nrf_usbd_eventcause_mask_t + */ +__STATIC_INLINE void nrf_usbd_eventcause_clear(uint32_t flags); + +/** + * @brief Function for getting EVENTCAUSE register and clear flags that are set + * + * The safest way to return current EVENTCAUSE register. + * All the flags that are returned would be cleared inside EVENTCAUSE register. + * + * @return Flag values defined in @ref nrf_usbd_eventcause_mask_t + */ +__STATIC_INLINE uint32_t nrf_usbd_eventcause_get_and_clear(void); + +/** + * @brief Function for getting BUSSTATE register value + * + * @return The value of BUSSTATE register + */ +__STATIC_INLINE nrf_usbd_busstate_t nrf_usbd_busstate_get(void); + +/** + * @brief Function for getting HALTEDEPIN register value + * + * @param ep Endpoint number with IN/OUT flag + * + * @return The value of HALTEDEPIN or HALTEDOUT register for selected endpoint + * + * @note + * Use this function for the response for GetStatus() request to endpoint. + * To check if endpoint is stalled in the code use @ref nrf_usbd_ep_is_stall. + */ +__STATIC_INLINE uint32_t nrf_usbd_haltedep(uint8_t ep); + +/** + * @brief Function for checking if selected endpoint is stalled + * + * Function to be used as a syntax sweeter for @ref nrf_usbd_haltedep. + * + * Also as the isochronous endpoint cannot be halted - it returns always false + * if isochronous endpoint is checked. + * + * @param ep Endpoint number with IN/OUT flag + * + * @return The information if the enepoint is halted. + */ +__STATIC_INLINE bool nrf_usbd_ep_is_stall(uint8_t ep); + +/** + * @brief Function for getting EPSTATUS register value + * + * @return Flag values defined in @ref nrf_usbd_epstatus_mask_t + */ +__STATIC_INLINE uint32_t nrf_usbd_epstatus_get(void); + +/** + * @brief Function for clearing EPSTATUS register value + * + * @param flags Flags defined in @ref nrf_usbd_epstatus_mask_t + */ +__STATIC_INLINE void nrf_usbd_epstatus_clear(uint32_t flags); + +/** + * @brief Function for getting and clearing EPSTATUS register value + * + * Function clears all flags in register set before returning its value. + * @return Flag values defined in @ref nrf_usbd_epstatus_mask_t + */ +__STATIC_INLINE uint32_t nrf_usbd_epstatus_get_and_clear(void); + +/** + * @brief Function for getting DATAEPSTATUS register value + * + * @return Flag values defined in @ref nrf_usbd_dataepstatus_mask_t + */ +__STATIC_INLINE uint32_t nrf_usbd_epdatastatus_get(void); + +/** + * @brief Function for clearing DATAEPSTATUS register value + * + * @param flags Flags defined in @ref nrf_usbd_dataepstatus_mask_t + */ +__STATIC_INLINE void nrf_usbd_epdatastatus_clear(uint32_t flags); + +/** + * @brief Function for getting and clearing DATAEPSTATUS register value + * + * Function clears all flags in register set before returning its value. + * @return Flag values defined in @ref nrf_usbd_dataepstatus_mask_t + */ +__STATIC_INLINE uint32_t nrf_usbd_epdatastatus_get_and_clear(void); + +/** + * @name Setup command frame functions + * + * Functions for setup command frame parts access + * @{ + */ + /** + * @brief Function for reading BMREQUESTTYPE - part of SETUP packet + * + * @return the value of BREQUESTTYPE on last received SETUP frame + */ + __STATIC_INLINE uint8_t nrf_usbd_setup_bmrequesttype_get(void); + + /** + * @brief Function for reading BMREQUEST - part of SETUP packet + * + * @return the value of BREQUEST on last received SETUP frame + */ + __STATIC_INLINE uint8_t nrf_usbd_setup_brequest_get(void); + + /** + * @brief Function for reading WVALUE - part of SETUP packet + * + * @return the value of WVALUE on last received SETUP frame + */ + __STATIC_INLINE uint16_t nrf_usbd_setup_wvalue_get(void); + + /** + * @brief Function for reading WINDEX - part of SETUP packet + * + * @return the value of WINDEX on last received SETUP frame + */ + __STATIC_INLINE uint16_t nrf_usbd_setup_windex_get(void); + + /** + * @brief Function for reading WLENGTH - part of SETUP packet + * + * @return the value of WLENGTH on last received SETUP frame + */ + __STATIC_INLINE uint16_t nrf_usbd_setup_wlength_get(void); +/** @} */ + +/** + * @brief Function for getting number of received bytes on selected endpoint + * + * @param ep Endpoint identifier. + * + * @return Number of received bytes. + * + * @note This function may be used on Bulk/Interrupt and Isochronous endpoints. + */ +__STATIC_INLINE size_t nrf_usbd_epout_size_get(uint8_t ep); + +/** + * @brief Function for clearing out endpoint to accept any new incoming traffic + * + * @param ep ep Endpoint identifier. Only OUT Interrupt/Bulk endpoints are accepted. + */ +__STATIC_INLINE void nrf_usbd_epout_clear(uint8_t ep); + +/** + * @brief Function for enabling USB pullup + */ +__STATIC_INLINE void nrf_usbd_pullup_enable(void); + +/** + * @brief Function for disabling USB pullup + */ +__STATIC_INLINE void nrf_usbd_pullup_disable(void); + +/** + * @brief Function for returning current USB pullup state + * + * @retval true USB pullup is enabled + * @retval false USB pullup is disabled + */ +__STATIC_INLINE bool nrf_usbd_pullup_check(void); + +/** + * @brief Function for configuring the value to be forced on the bus on DRIVEDPDM task + * + * Selected state would be forced on the bus when @ref NRF_USBD_TASK_DRIVEDPM is set. + * The state would be removed from the bus on @ref NRF_USBD_TASK_NODRIVEDPM and + * the control would be returned to the USBD peripheral. + * @param val State to be set + */ +__STATIC_INLINE void nrf_usbd_dpdmvalue_set(nrf_usbd_dpdmvalue_t val); + +/** + * @brief Function for setting data toggle + * + * Configuration of current state of data toggling + * @param ep Endpoint number with the information about its direction + * @param op Operation to execute + */ +__STATIC_INLINE void nrf_usbd_dtoggle_set(uint8_t ep, nrf_usbd_dtoggle_t op); + +/** + * @brief Function for getting data toggle + * + * Get the current state of data toggling + * @param ep Endpoint number to return the information about current data toggling + * @retval NRF_USBD_DTOGGLE_DATA0 Data toggle is DATA0 on selected endpoint + * @retval NRF_USBD_DTOGGLE_DATA1 Data toggle is DATA1 on selected endpoint + */ +__STATIC_INLINE nrf_usbd_dtoggle_t nrf_usbd_dtoggle_get(uint8_t ep); + +/** + * @brief Function for checking if endpoint is enabled + * + * @param ep Endpoint id to check + * + * @retval true Endpoint is enabled + * @retval false Endpoint is disabled + */ +__STATIC_INLINE bool nrf_usbd_ep_enable_check(uint8_t ep); + +/** + * @brief Function for enabling selected endpoint + * + * Enabled endpoint responds for the tokens on the USB bus + * + * @param ep Endpoint id to enable + */ +__STATIC_INLINE void nrf_usbd_ep_enable(uint8_t ep); + +/** + * @brief Function for disabling selected endpoint + * + * Disabled endpoint does not respond for the tokens on the USB bus + * + * @param ep Endpoint id to disable + */ +__STATIC_INLINE void nrf_usbd_ep_disable(uint8_t ep); + +/** + * @brief Function for disabling all endpoints + * + * Auxiliary function to simply disable all aviable endpoints. + * It lefts only EP0 IN and OUT enabled. + */ +__STATIC_INLINE void nrf_usbd_ep_all_disable(void); + +/** + * @brief Function for stalling selected endpoint + * + * @param ep Endpoint identifier + * @note This function cannot be called on isochronous endpoint + */ +__STATIC_INLINE void nrf_usbd_ep_stall(uint8_t ep); + +/** + * @brief Function for unstalling selected endpoint + * + * @param ep Endpoint identifier + * @note This function cannot be called on isochronous endpoint + */ +__STATIC_INLINE void nrf_usbd_ep_unstall(uint8_t ep); + +/** + * @brief Function for configuration of isochronous buffer splitting + * + * Configure isochronous buffer splitting between IN and OUT endpoints. + * + * @param split Required configuration + */ +__STATIC_INLINE void nrf_usbd_isosplit_set(nrf_usbd_isosplit_t split); + +/** + * @brief Function for getting the isochronous buffer splitting configuration + * + * Get the current isochronous buffer splitting configuration. + * + * @return Current configuration + */ +__STATIC_INLINE nrf_usbd_isosplit_t nrf_usbd_isosplit_get(void); + +/** + * @brief Function for getting current frame counter + * + * @return Current frame counter + */ +__STATIC_INLINE uint32_t nrf_usbd_framecntr_get(void); + +/** + * @brief Function for configuring EasyDMA channel + * + * Configures EasyDMA for the transfer. + * + * @param ep Endpoint identifier (with direction) + * @param ptr Pointer to the data + * @param maxcnt Number of bytes to transfer + */ +__STATIC_INLINE void nrf_usbd_ep_easydma_set(uint8_t ep, uint32_t ptr, uint32_t maxcnt); + +/** + * @brief Function for getting number of transferred bytes + * + * Get number of transferred bytes in the last transaction + * + * @param ep Endpoint identifier + * + * @return The content of the AMOUNT register + */ +__STATIC_INLINE uint32_t nrf_usbd_ep_amount_get(uint8_t ep); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +void nrf_usbd_enable(void) +{ +#ifdef NRF_FPGA_IMPLEMENTATION + *(volatile uint32_t *)0x400005F4 = 3; + __ISB(); + __DSB(); + *(volatile uint32_t *)0x400005F0 = 3; + __ISB(); + __DSB(); +#endif + + NRF_USBD->ENABLE = USBD_ENABLE_ENABLE_Enabled << USBD_ENABLE_ENABLE_Pos; + __ISB(); + __DSB(); +} + +void nrf_usbd_disable(void) +{ + NRF_USBD->ENABLE = USBD_ENABLE_ENABLE_Disabled << USBD_ENABLE_ENABLE_Pos; + __ISB(); + __DSB(); +} + +uint32_t nrf_usbd_eventcause_get(void) +{ + return NRF_USBD->EVENTCAUSE; +} + +void nrf_usbd_eventcause_clear(uint32_t flags) +{ + NRF_USBD->EVENTCAUSE = flags; + __ISB(); + __DSB(); +} + +uint32_t nrf_usbd_eventcause_get_and_clear(void) +{ + uint32_t ret; + ret = nrf_usbd_eventcause_get(); + nrf_usbd_eventcause_clear(ret); + __ISB(); + __DSB(); + return ret; +} + +nrf_usbd_busstate_t nrf_usbd_busstate_get(void) +{ + return (nrf_usbd_busstate_t)(NRF_USBD->BUSSTATE); +} + +uint32_t nrf_usbd_haltedep(uint8_t ep) +{ + uint8_t epnr = NRF_USBD_EP_NR_GET(ep); + if (NRF_USBD_EPIN_CHECK(ep)) + { + ASSERT(epnr < ARRAY_SIZE(NRF_USBD->HALTED.EPIN)); + return NRF_USBD->HALTED.EPIN[epnr]; + } + else + { + ASSERT(epnr < ARRAY_SIZE(NRF_USBD->HALTED.EPOUT)); + return NRF_USBD->HALTED.EPOUT[epnr]; + } +} + +bool nrf_usbd_ep_is_stall(uint8_t ep) +{ + if (NRF_USBD_EPISO_CHECK(ep)) + return false; + return USBD_HALTED_EPOUT_GETSTATUS_Halted == nrf_usbd_haltedep(ep); +} + +uint32_t nrf_usbd_epstatus_get(void) +{ + return NRF_USBD->EPSTATUS; +} + +void nrf_usbd_epstatus_clear(uint32_t flags) +{ + NRF_USBD->EPSTATUS = flags; + __ISB(); + __DSB(); +} + +uint32_t nrf_usbd_epstatus_get_and_clear(void) +{ + uint32_t ret; + ret = nrf_usbd_epstatus_get(); + nrf_usbd_epstatus_clear(ret); + return ret; +} + +uint32_t nrf_usbd_epdatastatus_get(void) +{ + return NRF_USBD->EPDATASTATUS; +} + +void nrf_usbd_epdatastatus_clear(uint32_t flags) +{ + NRF_USBD->EPDATASTATUS = flags; + __ISB(); + __DSB(); +} + +uint32_t nrf_usbd_epdatastatus_get_and_clear(void) +{ + uint32_t ret; + ret = nrf_usbd_epdatastatus_get(); + nrf_usbd_epdatastatus_clear(ret); + __ISB(); + __DSB(); + return ret; +} + +uint8_t nrf_usbd_setup_bmrequesttype_get(void) +{ + return (uint8_t)(NRF_USBD->BMREQUESTTYPE); +} + +uint8_t nrf_usbd_setup_brequest_get(void) +{ + return (uint8_t)(NRF_USBD->BREQUEST); +} + +uint16_t nrf_usbd_setup_wvalue_get(void) +{ + const uint16_t val = NRF_USBD->WVALUEL; + return (uint16_t)(val | ((NRF_USBD->WVALUEH) << 8)); +} + +uint16_t nrf_usbd_setup_windex_get(void) +{ + const uint16_t val = NRF_USBD->WINDEXL; + return (uint16_t)(val | ((NRF_USBD->WINDEXH) << 8)); +} + +uint16_t nrf_usbd_setup_wlength_get(void) +{ + const uint16_t val = NRF_USBD->WLENGTHL; + return (uint16_t)(val | ((NRF_USBD->WLENGTHH) << 8)); +} + +size_t nrf_usbd_epout_size_get(uint8_t ep) +{ + ASSERT(NRF_USBD_EPOUT_CHECK(ep)); + if (NRF_USBD_EPISO_CHECK(ep)) + { + /* Only single isochronous endpoint supported */ + ASSERT(NRF_USBD_EP_NR_GET(ep) == ARRAY_SIZE(NRF_USBD->SIZE.EPOUT)); + return NRF_USBD->SIZE.ISOOUT; + } + + ASSERT(NRF_USBD_EP_NR_GET(ep) < ARRAY_SIZE(NRF_USBD->SIZE.EPOUT)); + return NRF_USBD->SIZE.EPOUT[NRF_USBD_EP_NR_GET(ep)]; +} + +void nrf_usbd_epout_clear(uint8_t ep) +{ + ASSERT(NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < ARRAY_SIZE(NRF_USBD->SIZE.EPOUT))); + NRF_USBD->SIZE.EPOUT[NRF_USBD_EP_NR_GET(ep)] = 0; + __ISB(); + __DSB(); +} + +void nrf_usbd_pullup_enable(void) +{ + NRF_USBD->USBPULLUP = USBD_USBPULLUP_CONNECT_Enabled << USBD_USBPULLUP_CONNECT_Pos; + __ISB(); + __DSB(); +} + +void nrf_usbd_pullup_disable(void) +{ + NRF_USBD->USBPULLUP = USBD_USBPULLUP_CONNECT_Disabled << USBD_USBPULLUP_CONNECT_Pos; + __ISB(); + __DSB(); +} + +bool nrf_usbd_pullup_check(void) +{ + return NRF_USBD->USBPULLUP == (USBD_USBPULLUP_CONNECT_Enabled << USBD_USBPULLUP_CONNECT_Pos); +} + +void nrf_usbd_dpdmvalue_set(nrf_usbd_dpdmvalue_t val) +{ + NRF_USBD->DPDMVALUE = ((uint32_t)val) << USBD_DPDMVALUE_STATE_Pos; +} + +void nrf_usbd_dtoggle_set(uint8_t ep, nrf_usbd_dtoggle_t op) +{ + NRF_USBD->DTOGGLE = ep | (op << USBD_DTOGGLE_VALUE_Pos); + __ISB(); + __DSB(); +} + +nrf_usbd_dtoggle_t nrf_usbd_dtoggle_get(uint8_t ep) +{ + uint32_t retval; + /* Select the endpoint to read */ + nrf_usbd_dtoggle_set(ep, NRF_USBD_DTOGGLE_NOP); + retval = ((NRF_USBD->DTOGGLE) & USBD_DTOGGLE_VALUE_Msk) >> USBD_DTOGGLE_VALUE_Pos; + return (nrf_usbd_dtoggle_t)retval; +} + +bool nrf_usbd_ep_enable_check(uint8_t ep) +{ + ASSERT(NRF_USBD_EP_VALIDATE(ep)); + uint8_t epnr = NRF_USBD_EP_NR_GET(ep); + + if (NRF_USBD_EPIN_CHECK(ep)) + { + return 0 != (NRF_USBD->EPINEN & (1UL<EPOUTEN & (1UL<EPINEN |= 1UL<EPOUTEN |= 1UL<EPINEN &= ~(1UL<EPOUTEN &= ~(1UL<EPINEN = USBD_EPINEN_IN0_Enable << USBD_EPINEN_IN0_Pos; + NRF_USBD->EPOUTEN = USBD_EPOUTEN_OUT0_Enable << USBD_EPOUTEN_OUT0_Pos; + __ISB(); + __DSB(); +} + +void nrf_usbd_ep_stall(uint8_t ep) +{ + ASSERT(!NRF_USBD_EPISO_CHECK(ep)); + NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_Stall << USBD_EPSTALL_STALL_Pos) | ep; + __ISB(); + __DSB(); +} + +void nrf_usbd_ep_unstall(uint8_t ep) +{ + ASSERT(!NRF_USBD_EPISO_CHECK(ep)); + NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep; + __ISB(); + __DSB(); +} + +void nrf_usbd_isosplit_set(nrf_usbd_isosplit_t split) +{ + NRF_USBD->ISOSPLIT = split << USBD_ISOSPLIT_SPLIT_Pos; +} + +nrf_usbd_isosplit_t nrf_usbd_isosplit_get(void) +{ + return (nrf_usbd_isosplit_t) + (((NRF_USBD->ISOSPLIT) & USBD_ISOSPLIT_SPLIT_Msk) >> USBD_ISOSPLIT_SPLIT_Pos); +} + +uint32_t nrf_usbd_framecntr_get(void) +{ + return NRF_USBD->FRAMECNTR; +} + +void nrf_usbd_ep_easydma_set(uint8_t ep, uint32_t ptr, uint32_t maxcnt) +{ + if (NRF_USBD_EPIN_CHECK(ep)) + { + if (NRF_USBD_EPISO_CHECK(ep)) + { + NRF_USBD->ISOIN.PTR = ptr; + NRF_USBD->ISOIN.MAXCNT = maxcnt; + } + else + { + uint8_t epnr = NRF_USBD_EP_NR_GET(ep); + ASSERT(epnr < ARRAY_SIZE(NRF_USBD->EPIN)); + NRF_USBD->EPIN[epnr].PTR = ptr; + NRF_USBD->EPIN[epnr].MAXCNT = maxcnt; + } + } + else + { + if (NRF_USBD_EPISO_CHECK(ep)) + { + NRF_USBD->ISOOUT.PTR = ptr; + NRF_USBD->ISOOUT.MAXCNT = maxcnt; + } + else + { + uint8_t epnr = NRF_USBD_EP_NR_GET(ep); + ASSERT(epnr < ARRAY_SIZE(NRF_USBD->EPOUT)); + NRF_USBD->EPOUT[epnr].PTR = ptr; + NRF_USBD->EPOUT[epnr].MAXCNT = maxcnt; + } + } +} + +uint32_t nrf_usbd_ep_amount_get(uint8_t ep) +{ + uint32_t ret; + + if (NRF_USBD_EPIN_CHECK(ep)) + { + if (NRF_USBD_EPISO_CHECK(ep)) + { + ret = NRF_USBD->ISOIN.AMOUNT; + } + else + { + uint8_t epnr = NRF_USBD_EP_NR_GET(ep); + ASSERT(epnr < ARRAY_SIZE(NRF_USBD->EPOUT)); + ret = NRF_USBD->EPIN[epnr].AMOUNT; + } + } + else + { + if (NRF_USBD_EPISO_CHECK(ep)) + { + ret = NRF_USBD->ISOOUT.AMOUNT; + } + else + { + uint8_t epnr = NRF_USBD_EP_NR_GET(ep); + ASSERT(epnr < ARRAY_SIZE(NRF_USBD->EPOUT)); + ret = NRF_USBD->EPOUT[epnr].AMOUNT; + } + } + + return ret; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +/** @} */ +#endif /* NRF_USBD_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_wdt.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..d497fc24646200d383b734035dbf8487df4dbe69 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/hal/nrf_wdt.h @@ -0,0 +1,339 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @defgroup nrf_wdt_hal WDT HAL + * @{ + * @ingroup nrf_wdt + * + * @brief Hardware access layer for accessing the watchdog timer (WDT) peripheral. + */ + +#ifndef NRF_WDT_H__ +#define NRF_WDT_H__ + +#include +#include +#include + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_WDT_CHANNEL_NUMBER 0x8UL +#define NRF_WDT_RR_VALUE 0x6E524635UL /* Fixed value, shouldn't be modified.*/ + +#define NRF_WDT_TASK_SET 1UL +#define NRF_WDT_EVENT_CLEAR 0UL + +/** + * @enum nrf_wdt_task_t + * @brief WDT tasks. + */ +typedef enum +{ + /*lint -save -e30 -esym(628,__INTADDR__)*/ + NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */ + /*lint -restore*/ +} nrf_wdt_task_t; + +/** + * @enum nrf_wdt_event_t + * @brief WDT events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */ + /*lint -restore*/ +} nrf_wdt_event_t; + +/** + * @enum nrf_wdt_behaviour_t + * @brief WDT behavior in CPU SLEEP or HALT mode. + */ +typedef enum +{ + NRF_WDT_BEHAVIOUR_RUN_SLEEP = WDT_CONFIG_SLEEP_Msk, /**< WDT will run when CPU is in SLEEP mode. */ + NRF_WDT_BEHAVIOUR_RUN_HALT = WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in HALT mode. */ + NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */ + NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0, /**< WDT will be paused when CPU is in SLEEP or HALT mode. */ +} nrf_wdt_behaviour_t; + +/** + * @enum nrf_wdt_rr_register_t + * @brief WDT reload request registers. + */ +typedef enum +{ + NRF_WDT_RR0 = 0, /**< Reload request register 0. */ + NRF_WDT_RR1, /**< Reload request register 1. */ + NRF_WDT_RR2, /**< Reload request register 2. */ + NRF_WDT_RR3, /**< Reload request register 3. */ + NRF_WDT_RR4, /**< Reload request register 4. */ + NRF_WDT_RR5, /**< Reload request register 5. */ + NRF_WDT_RR6, /**< Reload request register 6. */ + NRF_WDT_RR7 /**< Reload request register 7. */ +} nrf_wdt_rr_register_t; + +/** + * @enum nrf_wdt_int_mask_t + * @brief WDT interrupts. + */ +typedef enum +{ + NRF_WDT_INT_TIMEOUT_MASK = WDT_INTENSET_TIMEOUT_Msk, /**< WDT interrupt from time-out event. */ +} nrf_wdt_int_mask_t; + +/** + * @brief Function for configuring the watchdog behavior when the CPU is sleeping or halted. + * + * @param behaviour Watchdog behavior when CPU is in SLEEP or HALT mode. + */ +__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour) +{ + NRF_WDT->CONFIG = behaviour; +} + + +/** + * @brief Function for starting the watchdog. + * + * @param[in] task Task. + */ +__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_WDT + task)) = NRF_WDT_TASK_SET; +} + + +/** + * @brief Function for clearing the WDT event. + * + * @param[in] event Event. + */ +__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)); + (void)dummy; +#endif +} + + +/** + * @brief Function for retrieving the state of the WDT event. + * + * @param[in] event Event. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event) +{ + return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + event)); +} + + +/** + * @brief Function for enabling a specific interrupt. + * + * @param[in] int_mask Interrupt. + */ +__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask) +{ + NRF_WDT->INTENSET = int_mask; +} + + +/** + * @brief Function for retrieving the state of given interrupt. + * + * @param[in] int_mask Interrupt. + * + * @retval true Interrupt is enabled. + * @retval false Interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask) +{ + return (bool)(NRF_WDT->INTENSET & int_mask); +} + + +/** + * @brief Function for disabling a specific interrupt. + * + * @param[in] int_mask Interrupt. + */ +__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask) +{ + NRF_WDT->INTENCLR = int_mask; +} + + +/** + * @brief Function for returning the address of a specific WDT task register. + * + * @param[in] task Task. + */ +__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task) +{ + return ((uint32_t)NRF_WDT + task); +} + + +/** + * @brief Function for returning the address of a specific WDT event register. + * + * @param[in] event Event. + * + * @retval address of requested event register + */ +__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event) +{ + return ((uint32_t)NRF_WDT + event); +} + + +/** + * @brief Function for retrieving the watchdog status. + * + * @retval true If the watchdog is started. + * @retval false If the watchdog is not started. + */ +__STATIC_INLINE bool nrf_wdt_started(void) +{ + return (bool)(NRF_WDT->RUNSTATUS); +} + + +/** + * @brief Function for retrieving the watchdog reload request status. + * + * @param[in] rr_register Reload request register to check. + * + * @retval true If a reload request is running. + * @retval false If no reload request is running. + */ +__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register) +{ + return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL); +} + + +/** + * @brief Function for setting the watchdog reload value. + * + * @param[in] reload_value Watchdog counter initial value. + */ +__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value) +{ + NRF_WDT->CRV = reload_value; +} + + +/** + * @brief Function for retrieving the watchdog reload value. + * + * @retval Reload value. + */ +__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void) +{ + return (uint32_t)NRF_WDT->CRV; +} + + +/** + * @brief Function for enabling a specific reload request register. + * + * @param[in] rr_register Reload request register to enable. + */ +__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register) +{ + NRF_WDT->RREN |= 0x1UL << rr_register; +} + + +/** + * @brief Function for disabling a specific reload request register. + * + * @param[in] rr_register Reload request register to disable. + */ +__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register) +{ + NRF_WDT->RREN &= ~(0x1UL << rr_register); +} + + +/** + * @brief Function for retrieving the status of a specific reload request register. + * + * @param[in] rr_register Reload request register to check. + * + * @retval true If the reload request register is enabled. + * @retval false If the reload request register is not enabled. + */ +__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register) +{ + return (bool)(NRF_WDT->RREN & (0x1UL << rr_register)); +} + + +/** + * @brief Function for setting a specific reload request register. + * + * @param[in] rr_register Reload request register to set. + */ +__STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_register) +{ + NRF_WDT->RR[rr_register] = NRF_WDT_RR_VALUE; +} + + + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/i2s/nrf_drv_i2s.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/i2s/nrf_drv_i2s.c new file mode 100644 index 0000000000000000000000000000000000000000..2d8966fd9f706676d014c869c438ec0935ced810 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/i2s/nrf_drv_i2s.c @@ -0,0 +1,437 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(I2S) +#include "nrf_drv_i2s.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" +#include "nrf_assert.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "I2S" + +#if I2S_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL I2S_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR I2S_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR I2S_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_I2S_EVENT_RXPTRUPD ? "NRF_I2S_EVENT_RXPTRUPD" : \ + (event == NRF_I2S_EVENT_TXPTRUPD ? "NRF_I2S_EVENT_TXPTRUPD" : \ + (event == NRF_I2S_EVENT_STOPPED ? "NRF_I2S_EVENT_STOPPED" : "UNKNOWN EVENT"))) +#else //I2S_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //I2S_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +#define MODULE_INITIALIZED (m_cb.state == NRF_DRV_STATE_INITIALIZED) /**< Macro designating whether the module has been initialized properly. */ + +// Control block - driver instance local data. +typedef struct +{ + nrf_drv_i2s_data_handler_t handler; + nrf_drv_state_t state; + + bool synchronized_mode : 1; + bool rx_ready : 1; + bool tx_ready : 1; + bool just_started : 1; + uint16_t buffer_half_size; + uint32_t * p_rx_buffer; + uint32_t * p_tx_buffer; +} i2s_control_block_t; +static i2s_control_block_t m_cb; + + +static nrf_drv_i2s_config_t const m_default_config = NRF_DRV_I2S_DEFAULT_CONFIG; + + +static void configure_pins(nrf_drv_i2s_config_t const * p_config) +{ + uint32_t mck_pin, sdout_pin, sdin_pin; + + // Configure pins used by the peripheral: + + // - SCK and LRCK (required) - depending on the mode of operation these + // pins are configured as outputs (in Master mode) or inputs (in Slave + // mode). + if (p_config->mode == NRF_I2S_MODE_MASTER) + { + nrf_gpio_cfg_output(p_config->sck_pin); + nrf_gpio_cfg_output(p_config->lrck_pin); + } + else + { + nrf_gpio_cfg_input(p_config->sck_pin, NRF_GPIO_PIN_NOPULL); + nrf_gpio_cfg_input(p_config->lrck_pin, NRF_GPIO_PIN_NOPULL); + } + + // - MCK (optional) - always output, + if (p_config->mck_pin != NRF_DRV_I2S_PIN_NOT_USED) + { + mck_pin = p_config->mck_pin; + nrf_gpio_cfg_output(mck_pin); + } + else + { + mck_pin = NRF_I2S_PIN_NOT_CONNECTED; + } + + // - SDOUT (optional) - always output, + if (p_config->sdout_pin != NRF_DRV_I2S_PIN_NOT_USED) + { + sdout_pin = p_config->sdout_pin; + nrf_gpio_cfg_output(sdout_pin); + } + else + { + sdout_pin = NRF_I2S_PIN_NOT_CONNECTED; + } + + // - SDIN (optional) - always input. + if (p_config->sdin_pin != NRF_DRV_I2S_PIN_NOT_USED) + { + sdin_pin = p_config->sdin_pin; + nrf_gpio_cfg_input(sdin_pin, NRF_GPIO_PIN_NOPULL); + } + else + { + sdin_pin = NRF_I2S_PIN_NOT_CONNECTED; + } + + nrf_i2s_pins_set(NRF_I2S, p_config->sck_pin, p_config->lrck_pin, + mck_pin, sdout_pin, sdin_pin); +} + + +ret_code_t nrf_drv_i2s_init(nrf_drv_i2s_config_t const * p_config, + nrf_drv_i2s_data_handler_t handler) +{ + ASSERT(handler); + + ret_code_t err_code; + + if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + if (p_config == NULL) + { + p_config = &m_default_config; + } + + if (!nrf_i2s_configure(NRF_I2S, p_config->mode, + p_config->format, + p_config->alignment, + p_config->sample_width, + p_config->channels, + p_config->mck_setup, + p_config->ratio)) + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + configure_pins(p_config); + + m_cb.handler = handler; + + nrf_drv_common_irq_enable(I2S_IRQn, p_config->irq_priority); + + m_cb.state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_i2s_uninit(void) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_drv_i2s_stop(); + + nrf_drv_common_irq_disable(I2S_IRQn); + + m_cb.state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Initialized.\r\n"); +} + + +ret_code_t nrf_drv_i2s_start(uint32_t * p_rx_buffer, + uint32_t * p_tx_buffer, + uint16_t buffer_size, + uint8_t flags) +{ + ASSERT((p_rx_buffer != NULL) || (p_tx_buffer != NULL)); + + uint16_t buffer_half_size = buffer_size / 2; + ASSERT(buffer_half_size != 0); + + VERIFY_MODULE_INITIALIZED(); + + ret_code_t err_code; + + if ((p_rx_buffer != NULL) && !nrf_drv_is_in_RAM(p_rx_buffer)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + if ((p_tx_buffer != NULL) && !nrf_drv_is_in_RAM(p_tx_buffer)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + // Initially we set up the peripheral to use the first half of each buffer, + // then in 'I2S_IRQHandler' we will switch to the second half. + nrf_i2s_transfer_set(NRF_I2S, buffer_half_size, p_rx_buffer, p_tx_buffer); + + m_cb.p_rx_buffer = p_rx_buffer; + m_cb.p_tx_buffer = p_tx_buffer; + m_cb.buffer_half_size = buffer_half_size; + m_cb.just_started = true; + + if ((flags & NRF_DRV_I2S_FLAG_SYNCHRONIZED_MODE) && + // [synchronized mode makes sense only when both RX and TX are enabled] + (m_cb.p_rx_buffer != NULL) && (m_cb.p_tx_buffer != NULL)) + { + m_cb.synchronized_mode = true; + m_cb.rx_ready = false; + m_cb.tx_ready = false; + } + else + { + m_cb.synchronized_mode = false; + } + + nrf_i2s_enable(NRF_I2S); + + m_cb.state = NRF_DRV_STATE_POWERED_ON; + + if (m_cb.p_tx_buffer != NULL) + { + // Get from the application the first portion of data to be sent - we + // need to have it in the transmit buffer before we start the transfer. + // Unless the synchronized mode is active. In this mode we must wait + // with this until the first portion of data is received, so here we + // just make sure that there will be silence on the SDOUT line prior + // to that moment. + if (m_cb.synchronized_mode) + { + memset(m_cb.p_tx_buffer, 0, buffer_size); + } + else + { + m_cb.handler(NULL, m_cb.p_tx_buffer, m_cb.buffer_half_size); + } + } + + nrf_i2s_event_clear(NRF_I2S, NRF_I2S_EVENT_RXPTRUPD); + nrf_i2s_event_clear(NRF_I2S, NRF_I2S_EVENT_TXPTRUPD); + nrf_i2s_int_enable(NRF_I2S, + NRF_I2S_INT_RXPTRUPD_MASK | NRF_I2S_INT_TXPTRUPD_MASK); + nrf_i2s_task_trigger(NRF_I2S, NRF_I2S_TASK_START); + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_i2s_stop(void) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + // First disable interrupts, then trigger the STOP task, so no spurious + // RXPTRUPD and TXPTRUPD events (see FTPAN-55) will be processed. + nrf_i2s_int_disable(NRF_I2S, + NRF_I2S_INT_RXPTRUPD_MASK | NRF_I2S_INT_TXPTRUPD_MASK); + + nrf_i2s_task_trigger(NRF_I2S, NRF_I2S_TASK_STOP); + + nrf_i2s_disable(NRF_I2S); + + m_cb.state = NRF_DRV_STATE_INITIALIZED; + + NRF_LOG_INFO("Disabled."); +} + + +void I2S_IRQHandler(void) +{ + uint32_t * p_data_received = NULL; + uint32_t * p_data_to_send = NULL; + + if (nrf_i2s_event_check(NRF_I2S, NRF_I2S_EVENT_TXPTRUPD)) + { + nrf_i2s_event_clear(NRF_I2S, NRF_I2S_EVENT_TXPTRUPD); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_I2S_EVENT_TXPTRUPD)); + + // If transmission is not enabled, but for some reason the TXPTRUPD + // event has been generated, just ignore it. + if (m_cb.p_tx_buffer != NULL) + { + uint32_t * p_tx_buffer_next; + if (nrf_i2s_tx_buffer_get(NRF_I2S) == m_cb.p_tx_buffer) + { + p_tx_buffer_next = m_cb.p_tx_buffer + m_cb.buffer_half_size; + } + else + { + p_tx_buffer_next = m_cb.p_tx_buffer; + } + nrf_i2s_tx_buffer_set(NRF_I2S, p_tx_buffer_next); + + m_cb.tx_ready = true; + + // Now the part of the buffer that we've configured as "next" should + // be filled by the application with proper data to be sent; + // the peripheral is sending data from the other part of the buffer + // (but it will finish soon...). + p_data_to_send = p_tx_buffer_next; + + } + } + + if (nrf_i2s_event_check(NRF_I2S, NRF_I2S_EVENT_RXPTRUPD)) + { + nrf_i2s_event_clear(NRF_I2S, NRF_I2S_EVENT_RXPTRUPD); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_I2S_EVENT_RXPTRUPD)); + + // If reception is not enabled, but for some reason the RXPTRUPD event + // has been generated, just ignore it. + if (m_cb.p_rx_buffer != NULL) + { + uint32_t * p_rx_buffer_next; + if (nrf_i2s_rx_buffer_get(NRF_I2S) == m_cb.p_rx_buffer) + { + p_rx_buffer_next = m_cb.p_rx_buffer + m_cb.buffer_half_size; + } + else + { + p_rx_buffer_next = m_cb.p_rx_buffer; + } + nrf_i2s_rx_buffer_set(NRF_I2S, p_rx_buffer_next); + + m_cb.rx_ready = true; + + // The RXPTRUPD event is generated for the first time right after + // the transfer is started. Since there is no data received yet at + // this point we only update the buffer pointer (it is done above), + // there is no callback to the application. + // [for synchronized mode this has to be handled differently - + // see below] + if (m_cb.just_started && !m_cb.synchronized_mode) + { + m_cb.just_started = false; + } + else + { + // The RXPTRUPD event indicates that from now on the peripheral + // will be filling the part of the buffer that was pointed at + // the time the event has been generated, hence now we can let + // the application process the data stored in the other part of + // the buffer - the one that we've just set to be filled next. + p_data_received = p_rx_buffer_next; + } + } + } + + // Call the data handler passing received data to the application and/or + // requesting data to be sent. + if (!m_cb.synchronized_mode) + { + if ((p_data_received != NULL) || (p_data_to_send != NULL)) + { + if (p_data_received != NULL) + { + NRF_LOG_DEBUG("Rx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_data_received, + m_cb.buffer_half_size * sizeof(p_data_received)); + } + m_cb.handler(p_data_received, p_data_to_send, + m_cb.buffer_half_size); + if (p_data_to_send != NULL) + { + NRF_LOG_DEBUG("Tx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_data_to_send, + m_cb.buffer_half_size * sizeof(p_data_to_send)); + } + } + } + // In the synchronized mode wait until the events for both RX and TX occur. + // And ignore the initial occurrences of these events, since they only + // indicate that the transfer has started - no data is received yet at + // that moment, so we have got nothing to pass to the application. + else + { + if (m_cb.rx_ready && m_cb.tx_ready) + { + m_cb.rx_ready = false; + m_cb.tx_ready = false; + + if (m_cb.just_started) + { + m_cb.just_started = false; + } + else + { + NRF_LOG_DEBUG("Rx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)nrf_i2s_rx_buffer_get(NRF_I2S), + m_cb.buffer_half_size * sizeof(p_data_to_send)); + m_cb.handler(nrf_i2s_rx_buffer_get(NRF_I2S), + nrf_i2s_tx_buffer_get(NRF_I2S), + m_cb.buffer_half_size); + NRF_LOG_DEBUG("Tx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)nrf_i2s_tx_buffer_get(NRF_I2S), + m_cb.buffer_half_size * sizeof(p_data_to_send)); + } + } + } +} +#endif //NRF_MODULE_ENABLED(I2S) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/i2s/nrf_drv_i2s.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/i2s/nrf_drv_i2s.h new file mode 100644 index 0000000000000000000000000000000000000000..f2c368cc8a86eca1b96ba14e7dc1b37ec9f346bb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/i2s/nrf_drv_i2s.h @@ -0,0 +1,255 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * @addtogroup nrf_i2s I2S HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52 Inter-IC Sound (I2S) interface APIs. + * + * @defgroup nrf_drv_i2s I2S driver + * @{ + * @ingroup nrf_i2s + * @brief @tagAPI52 Inter-IC Sound (I2S) interface driver. + */ + + +#ifndef NRF_DRV_I2S_H__ +#define NRF_DRV_I2S_H__ + +#include "nordic_common.h" +#include "sdk_config.h" +#include "nrf_i2s.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief This value can be provided instead of a pin number for the signals + * SDOUT, SDIN, and MCK to specify that a given signal is not used + * and therefore does not need to be connected to a pin. + */ +#define NRF_DRV_I2S_PIN_NOT_USED 0xFF + +/** + * @brief Flag indicating that calls to the data handler for RX and TX should + * be synchronized, thus always combined into one call. + * + * Use this flag when calling @ref nrf_drv_i2s_start to force a common call + * to the @ref nrf_drv_i2s_data_handler_t "data handler" for RX and TX data. + * This is useful, for example, when received data should be processed and + * then be sent back. Obviously, this flag is only applicable when both + * directions (RX and TX) are enabled. + */ +#define NRF_DRV_I2S_FLAG_SYNCHRONIZED_MODE 0x01 + +/** + * @brief I2S driver configuration structure. + */ +typedef struct +{ + uint8_t sck_pin; ///< SCK pin number. + uint8_t lrck_pin; ///< LRCK pin number. + uint8_t mck_pin; ///< MCK pin number. + /**< Optional. Use @ref NRF_DRV_I2S_PIN_NOT_USED + * if this signal is not needed. */ + uint8_t sdout_pin; ///< SDOUT pin number. + /**< Optional. Use @ref NRF_DRV_I2S_PIN_NOT_USED + * if this signal is not needed. */ + uint8_t sdin_pin; ///< SDIN pin number. + /**< Optional. Use @ref NRF_DRV_I2S_PIN_NOT_USED + * if this signal is not needed. */ + uint8_t irq_priority; ///< Interrupt priority. + + nrf_i2s_mode_t mode; ///< Mode of operation. + nrf_i2s_format_t format; ///< Frame format. + nrf_i2s_align_t alignment; ///< Alignment of sample within a frame. + nrf_i2s_swidth_t sample_width; ///< Sample width. + nrf_i2s_channels_t channels; ///< Enabled channels. + nrf_i2s_mck_t mck_setup; ///< Master clock setup. + nrf_i2s_ratio_t ratio; ///< MCK/LRCK ratio. +} nrf_drv_i2s_config_t; + +/** + * @brief I2S driver default configuration. + */ +#define NRF_DRV_I2S_DEFAULT_CONFIG \ +{ \ + .sck_pin = I2S_CONFIG_SCK_PIN, \ + .lrck_pin = I2S_CONFIG_LRCK_PIN, \ + .mck_pin = I2S_CONFIG_MCK_PIN, \ + .sdout_pin = I2S_CONFIG_SDOUT_PIN, \ + .sdin_pin = I2S_CONFIG_SDIN_PIN, \ + .irq_priority = I2S_CONFIG_IRQ_PRIORITY, \ + .mode = (nrf_i2s_mode_t)I2S_CONFIG_MASTER, \ + .format = (nrf_i2s_format_t)I2S_CONFIG_FORMAT, \ + .alignment = (nrf_i2s_align_t)I2S_CONFIG_ALIGN, \ + .sample_width = (nrf_i2s_swidth_t)I2S_CONFIG_SWIDTH, \ + .channels = (nrf_i2s_channels_t)I2S_CONFIG_CHANNELS, \ + .mck_setup = (nrf_i2s_mck_t)I2S_CONFIG_MCK_SETUP, \ + .ratio = (nrf_i2s_ratio_t)I2S_CONFIG_RATIO, \ +} + +/** + * @brief I2S driver data handler type. + * + * A data handling function of this type must be specified during initialization + * of the driver. The driver will call this function when a new portion of data + * is received or a new portion of data should be prepared for transmission. + * The first case is indicated by a non-NULL value in the @p p_data_received + * parameter (which points to the memory containing the received data). + * Similarly, the second case is indicated by a non-NULL value in the + * @p p_data_to_send parameter (which points to where the data to be transmitted + * should be placed). + * + * @note The two cases mentioned above may be indicated separately or combined + * into one call (depending on the environment in which the driver is + * used). Therefore, both parameters should be checked and handled + * properly in every call. @ref NRF_DRV_I2S_FLAG_SYNCHRONIZED_MODE + * "Synchronized mode" can be used to always combine these indications. + * + * @param[in] p_data_received Pointer to the buffer with received data, + * or NULL if the handler is called to prepare + * transmission only. + * @param[out] p_data_to_send Pointer to the buffer where data to be sent + * should be written, or NULL if the handler is + * called for received data only. + * @param[in] number_of_words Length of data received and/or to be written + * (in 32-bit words). This value is always equal to + * half the size of the buffers set by the call + * to the @ref nrf_drv_i2s_start function. + */ +typedef void (* nrf_drv_i2s_data_handler_t)(uint32_t const * p_data_received, + uint32_t * p_data_to_send, + uint16_t number_of_words); + + +/** + * @brief Function for initializing the I2S driver. + * + * @param[in] p_config Pointer to the structure with initial configuration. + * If NULL, the default configuration is used. + * @param[in] handler Data handler provided by the user. Must not be NULL. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver was already initialized. + * @retval NRF_ERROR_INVALID_PARAM If the requested combination of configuration + * options is not allowed by the I2S peripheral. + */ +ret_code_t nrf_drv_i2s_init(nrf_drv_i2s_config_t const * p_config, + nrf_drv_i2s_data_handler_t handler); + +/** + * @brief Function for uninitializing the I2S driver. + */ +void nrf_drv_i2s_uninit(void); + +/** + * @brief Function for starting the continuous I2S transfer. + * + * The I2S data transfer can be performed in one of three modes: RX (reception) + * only, TX (transmission) only, or in both directions simultaneously. + * The mode is selected by specifying a proper buffer for a given direction + * in the call to this function or by passing NULL instead if this direction + * should be disabled. + * + * The length of the buffer (which is a common value for RX and TX if both + * directions are enabled) is specified in 32-bit words. One 32-bit memory + * word can either contain four 8-bit samples, two 16-bit samples, or one + * right-aligned 24-bit sample sign-extended to a 32-bit value. + * For a detailed memory mapping for different supported configurations, + * see the @linkProductSpecification52. + * + * The provided buffers are logically divided into two parts of equal size. + * One of them is in use by the peripheral (for storing received data or for + * getting data to be transmitted, respectively). The other part is provided + * to the application via a call to the defined @ref nrf_drv_i2s_data_handler_t + * "data handling function", so that the application can process the received + * data or prepare the next portion of data to be sent. The two parts are + * swapped every time @p buffer_size/2 data words are received or transmitted. + * + * Additional options are provided using the @p flags parameter: + * - @ref NRF_DRV_I2S_FLAG_SYNCHRONIZED_MODE - the calls to data handler should + * be done in a synchronized manner (one common call for TX and RX). + * Applicable only when both RX and TX are enabled. + * + * @attention All data exchange is done in the data handler only. In particular, + * no data should be written to the transmit buffer before calling + * this function (a proper call to the data handler to get the first + * portion of data to be sent will be done before the actual transfer + * starts). + * + * @note Peripherals using EasyDMA (like I2S) require the transfer buffers + * to be placed in the Data RAM region. If this condition is not met, + * this function will fail with the error code NRF_ERROR_INVALID_ADDR. + * + * @param[in] p_rx_buffer Pointer to the receive buffer. + * Pass NULL if reception is not required. + * @param[in] p_tx_buffer Pointer to the transmit buffer. + * Pass NULL if transmission is not required. + * @param[in] buffer_size Size of the buffers (in 32-bit words). + * The size must be an even number greater than 0. + * @param[in] flags Transfer options (0 for default settings). + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_STATE If a transfer was already started or + * the driver has not been initialized. + * @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed + * in the Data RAM region. + */ +ret_code_t nrf_drv_i2s_start(uint32_t * p_rx_buffer, + uint32_t * p_tx_buffer, + uint16_t buffer_size, + uint8_t flags); + +/** + * @brief Function for stopping the I2S transfer. + */ +void nrf_drv_i2s_stop(void); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_I2S_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.c new file mode 100644 index 0000000000000000000000000000000000000000..e0df14540bbf2fd3bf45e880d6b966e922393cde --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.c @@ -0,0 +1,205 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(LPCOMP) +#include "nrf_drv_lpcomp.h" +#include "nrf_assert.h" +#include "nrf_error.h" +#include "nrf_soc.h" +#include "nrf_drv_common.h" +#include "app_util_platform.h" +#include +#include +#include + +#define NRF_LOG_MODULE_NAME "LPCOMP" + +#if LPCOMP_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL LPCOMP_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR LPCOMP_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR LPCOMP_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_LPCOMP_EVENT_READY ? "NRF_LPCOMP_EVENT_READY" : \ + (event == NRF_LPCOMP_EVENT_DOWN ? "NRF_LPCOMP_EVENT_DOWN" : \ + (event == NRF_LPCOMP_EVENT_UP ? "NRF_LPCOMP_EVENT_UP" : \ + (event == NRF_LPCOMP_EVENT_CROSS ? "NRF_LPCOMP_EVENT_CROSS" : "UNKNOWN EVENT")))) +#else //LPCOMP_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //LPCOMP_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +static lpcomp_events_handler_t m_lpcomp_events_handler = NULL; +static nrf_drv_state_t m_state = NRF_DRV_STATE_UNINITIALIZED; + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + #define IRQ_HANDLER_NAME irq_handler_for_lpcomp + #define IRQ_HANDLER static void IRQ_HANDLER_NAME(void) + + IRQ_HANDLER; +#else + #define IRQ_HANDLER void LPCOMP_IRQHandler(void) +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +static void lpcomp_execute_handler(nrf_lpcomp_event_t event, uint32_t event_mask) +{ + if ( nrf_lpcomp_event_check(event) && nrf_lpcomp_int_enable_check(event_mask) ) + { + nrf_lpcomp_event_clear(event); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(event)); + + m_lpcomp_events_handler(event); + } +} + + +IRQ_HANDLER +{ + lpcomp_execute_handler(NRF_LPCOMP_EVENT_READY, LPCOMP_INTENSET_READY_Msk); + lpcomp_execute_handler(NRF_LPCOMP_EVENT_DOWN, LPCOMP_INTENSET_DOWN_Msk); + lpcomp_execute_handler(NRF_LPCOMP_EVENT_UP, LPCOMP_INTENSET_UP_Msk); + lpcomp_execute_handler(NRF_LPCOMP_EVENT_CROSS, LPCOMP_INTENSET_CROSS_Msk); +} + + +ret_code_t nrf_drv_lpcomp_init(const nrf_drv_lpcomp_config_t * p_config, + lpcomp_events_handler_t events_handler) +{ + ASSERT(p_config); + ret_code_t err_code; + + if (m_state != NRF_DRV_STATE_UNINITIALIZED) + { // LPCOMP driver is already initialized + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + if (nrf_drv_common_per_res_acquire(NRF_LPCOMP, IRQ_HANDLER_NAME) != NRF_SUCCESS) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } +#endif + + nrf_lpcomp_configure(&(p_config->hal) ); + + if (events_handler) + { + m_lpcomp_events_handler = events_handler; + } + else + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + nrf_lpcomp_input_select(p_config->input); + + switch (p_config->hal.detection) + { + case NRF_LPCOMP_DETECT_UP: + nrf_lpcomp_int_enable(LPCOMP_INTENSET_UP_Msk); + break; + + case NRF_LPCOMP_DETECT_DOWN: + nrf_lpcomp_int_enable(LPCOMP_INTENSET_DOWN_Msk); + break; + + case NRF_LPCOMP_DETECT_CROSS: + nrf_lpcomp_int_enable(LPCOMP_INTENSET_CROSS_Msk); + break; + + default: + break; + } + nrf_lpcomp_shorts_enable(NRF_LPCOMP_SHORT_READY_SAMPLE_MASK); + + nrf_drv_common_irq_enable(LPCOMP_IRQn, p_config->interrupt_priority); + + m_state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_lpcomp_uninit(void) +{ + ASSERT(m_state != NRF_DRV_STATE_UNINITIALIZED); + nrf_drv_common_irq_disable(LPCOMP_IRQn); + nrf_drv_lpcomp_disable(); +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + nrf_drv_common_per_res_release(NRF_LPCOMP); +#endif + m_state = NRF_DRV_STATE_UNINITIALIZED; + m_lpcomp_events_handler = NULL; + NRF_LOG_INFO("Uninitialized.\r\n"); +} + +void nrf_drv_lpcomp_enable(void) +{ + ASSERT(m_state == NRF_DRV_STATE_INITIALIZED); + nrf_lpcomp_enable(); + nrf_lpcomp_task_trigger(NRF_LPCOMP_TASK_START); + m_state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Enabled.\r\n"); +} + +void nrf_drv_lpcomp_disable(void) +{ + ASSERT(m_state == NRF_DRV_STATE_POWERED_ON); + nrf_lpcomp_disable(); + nrf_lpcomp_task_trigger(NRF_LPCOMP_TASK_STOP); + m_state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Disabled.\r\n"); +} + +void nrf_drv_lpcomp_event_handler_register(lpcomp_events_handler_t lpcomp_events_handler) +{ + m_lpcomp_events_handler = lpcomp_events_handler; +} + +#endif //NRF_MODULE_ENABLED(LPCOMP) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.h new file mode 100644 index 0000000000000000000000000000000000000000..7cd185287316448be01719b457cef31796f71797 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.h @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_DRV_LPCOMP_H__ +#define NRF_DRV_LPCOMP_H__ + +#include "nrf_lpcomp.h" +#include "sdk_errors.h" +#include "nrf_drv_common.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup nrf_lpcomp LPCOMP HAL and driver + * @ingroup nrf_drivers + * @brief Low Power Comparator (LPCOMP) APIs. + * @details The LPCOMP HAL provides basic APIs for accessing the registers of Low Power Comparator. + * The LPCOMP driver provides APIs on a higher level. + * + * @defgroup nrf_drv_lpcomp LPCOMP driver + * @{ + * @ingroup nrf_lpcomp + * @brief Low Power Comparator (LPCOMP) driver. + */ + +/**@brief LPCOMP event handler function type. + * @param[in] event LPCOMP event. + */ +typedef void (* lpcomp_events_handler_t)(nrf_lpcomp_event_t event); + +/**@brief LPCOMP configuration. + */ +typedef struct +{ + nrf_lpcomp_config_t hal; /**< LPCOMP HAL configuration. */ + nrf_lpcomp_input_t input; /**< Input to be monitored. */ + uint8_t interrupt_priority; /**< LPCOMP interrupt priority. */ +} nrf_drv_lpcomp_config_t; + +/** @brief LPCOMP driver default configuration including the LPCOMP HAL configuration. */ +#ifdef NRF52_SERIES +#define NRF_DRV_LPCOMP_DEFAULT_CONFIG \ + { \ + .hal = {(nrf_lpcomp_ref_t)LPCOMP_CONFIG_REFERENCE , (nrf_lpcomp_detect_t)LPCOMP_CONFIG_DETECTION, \ + (nrf_lpcomp_hysteresis_t)LPCOMP_CONFIG_HYST}, \ + .input = (nrf_lpcomp_input_t)LPCOMP_CONFIG_INPUT, \ + .interrupt_priority = LPCOMP_CONFIG_IRQ_PRIORITY \ + } +#else +#define NRF_DRV_LPCOMP_DEFAULT_CONFIG \ + { \ + .hal = {(nrf_lpcomp_ref_t)LPCOMP_CONFIG_REFERENCE , (nrf_lpcomp_detect_t)LPCOMP_CONFIG_DETECTION}, \ + .input = (nrf_lpcomp_input_t)LPCOMP_CONFIG_INPUT, \ + .interrupt_priority = LPCOMP_CONFIG_IRQ_PRIORITY \ + } +#endif + +/** + * @brief Function for initializing the LPCOMP driver. + * + * This function initializes the LPCOMP driver, but does not enable the peripheral or any interrupts. + * To start the driver, call the function nrf_drv_lpcomp_enable() after initialization. + * + * If no configuration structure is provided, the driver is initialized with the default settings. + * + * @param[in] p_config Initial configuration. If NULL, the default configuration is used. + * @param[in] events_handler Handler function. + * @retval NRF_ERROR_INVALID_PARAM If the configuration is invalid. + * @retval NRF_ERROR_INVALID_STATE If the driver has already been initialized. + */ +ret_code_t nrf_drv_lpcomp_init(const nrf_drv_lpcomp_config_t * p_config, + lpcomp_events_handler_t events_handler); + + +/** + * @brief Function for uninitializing the LCOMP driver. + * + * This function uninitializes the LPCOMP driver. The LPCOMP peripheral and + * its interrupts are disabled, and local variables are cleaned. After this call, you must + * initialize the driver again by calling nrf_drv_lpcomp_init() if you want to use it. + * + * @sa nrf_drv_lpcomp_disable() + * @sa nrf_drv_lpcomp_init() + */ +void nrf_drv_lpcomp_uninit(void); + +/**@brief Function for enabling the LPCOMP peripheral and interrupts. + * + * Before calling this function, the driver must be initialized. This function + * enables the LPCOMP peripheral and its interrupts. + * + * @sa nrf_drv_lpcomp_disable() + */ +void nrf_drv_lpcomp_enable(void); + +/**@brief Function for disabling the LPCOMP peripheral. + * + * Before calling this function, the driver must be initialized. This function disables the LPCOMP + * peripheral and its interrupts. + * + * @sa nrf_drv_lpcomp_enable() + */ +void nrf_drv_lpcomp_disable(void); + +/** + *@} + **/ + + +#ifdef __cplusplus +} +#endif + + #endif /* NRF_DRV_LPCOMP_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_error.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_error.h new file mode 100644 index 0000000000000000000000000000000000000000..6ae2c9b52ac738b2649efb2b6f6a599706cd22f1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_error.h @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* Header guard */ +#ifndef NRF_ERROR_H__ +#define NRF_ERROR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/// @cond Make doxygen skip this file + +/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions + * @{ */ +#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base +#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base +#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base +#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base +/** @} */ + +#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command +#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing +#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled +#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error +#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation +#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found +#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported +#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter +#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state +#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length +#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags +#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data +#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Data size exceeds limit +#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out +#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer +#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation +#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address +#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_ERROR_H__ + +/// @endcond +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c new file mode 100644 index 0000000000000000000000000000000000000000..45803bf61a8e42bcbee6bd41358a01c19e630f81 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c @@ -0,0 +1,123 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "nrf_soc.h" +#include "nrf_error.h" + +static uint8_t m_in_critical_region = 0; + +uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn) +{ + NVIC_EnableIRQ(IRQn); + return NRF_SUCCESS; +} + +uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn) +{ + NVIC_DisableIRQ(IRQn); + return NRF_SUCCESS; +} + +uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq) +{ + if (p_pending_irq != NULL) + { + *p_pending_irq = NVIC_GetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + return NRF_ERROR_NULL; +} + +uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC_SetPendingIRQ(IRQn); + return NRF_SUCCESS; +} + +uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC_ClearPendingIRQ(IRQn); + return NRF_SUCCESS; +} + +uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + NVIC_SetPriority(IRQn, priority); + return NRF_SUCCESS; +} + +uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority) +{ + if (p_priority != NULL) + { + *p_priority = NVIC_GetPriority(IRQn); + return NRF_SUCCESS; + } + + return NRF_ERROR_NULL; +} + +uint32_t sd_nvic_SystemReset(void) +{ + NVIC_SystemReset(); + return NRF_SUCCESS; +} + +uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region) +{ + __disable_irq(); + + *p_is_nested_critical_region = (m_in_critical_region != 0); + m_in_critical_region++; + + return NRF_SUCCESS; +} + +uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) +{ + m_in_critical_region--; + + if (is_nested_critical_region == 0) + { + m_in_critical_region = 0; + __enable_irq(); + } + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.h new file mode 100644 index 0000000000000000000000000000000000000000..ff4c345e82fb1cf977d2d5524a7958e275ff826a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.h @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SOC_H__ +#define NRF_SOC_H__ + +#include +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Enable External Interrupt. + * @note Corresponds to NVIC_EnableIRQ in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was enabled. + */ +uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn); + +/**@brief Disable External Interrupt. + * @note Corresponds to NVIC_DisableIRQ in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS + * + * @retval ::NRF_SUCCESS The interrupt was disabled. + */ +uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn); + +/**@brief Get Pending Interrupt. + * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. + * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. + * + * @retval ::NRF_SUCCESS The interrupt is available for the application. + */ +uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq); + +/**@brief Set Pending Interrupt. + * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt is set pending. + */ +uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn); + +/**@brief Clear Pending Interrupt. + * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. + */ +uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn); + +/**@brief Set Interrupt Priority. + * @note Corresponds to NVIC_SetPriority in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * @pre{priority is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. + * @param[in] priority A valid IRQ priority for use by the application. + * + * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. + */ +uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority); + +/**@brief Get Interrupt Priority. + * @note Corresponds to NVIC_GetPriority in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. + * @param[out] p_priority Return value from NVIC_GetPriority. + * + * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. + */ +uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority); + +/**@brief System Reset. + * @note Corresponds to NVIC_SystemReset in CMSIS. + * + * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN + */ +uint32_t sd_nvic_SystemReset(void); + +/**@brief Enters critical region. + * + * @post Application interrupts will be disabled. + * @sa sd_nvic_critical_region_exit + * + * @param[out] p_is_nested_critical_region 1: If in a nested critical region. + * 0: Otherwise. + * + * @retval ::NRF_SUCCESS + */ +uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region); + +/**@brief Exit critical region. + * + * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. + * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. + * + * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. + * + * @retval ::NRF_SUCCESS + */ +uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region); + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SOC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c new file mode 100644 index 0000000000000000000000000000000000000000..8b273d74bf53a5bc62f30eeb12c41cbfce4c758a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "nrf_soc.h" +#include "nrf_error.h" + +uint32_t sd_app_evt_wait(void) +{ + __WFE(); + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_soc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_soc.h new file mode 100644 index 0000000000000000000000000000000000000000..3119ada366f4d7061c670d88d7971f95a39874f5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/nrf_soc_nosd/nrf_soc.h @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SOC_H__ +#define NRF_SOC_H__ + +#include +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Waits for an application event. + * + * An application event is either an application interrupt or a pended interrupt when the + * interrupt is disabled. When the interrupt is enabled it will be taken immediately since + * this function will wait in thread mode, then the execution will return in the application's + * main thread. When an interrupt is disabled and gets pended it will return to the application's + * thread main. The application must ensure that the pended flag is cleared using + * ::sd_nvic_ClearPendingIRQ in order to sleep using this function. This is only necessary for + * disabled interrupts, as the interrupt handler will clear the pending flag automatically for + * enabled interrupts. + * + * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M0 + * System Control Register (SCR). @sa CMSIS_SCB + * + * @note If an application interrupt has happened since the last time sd_app_evt_wait was + * called this function will return immediately and not go to sleep. This is to avoid race + * conditions that can occur when a flag is updated in the interrupt handler and processed + * in the main loop. + * + * @post An application interrupt has happened or a interrupt pending flag is set. + * + * @retval ::NRF_SUCCESS + */ +uint32_t sd_app_evt_wait(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SOC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/pdm/nrf_drv_pdm.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/pdm/nrf_drv_pdm.c new file mode 100644 index 0000000000000000000000000000000000000000..4dcf00ae7df3ae1808919b0d7ec5581a619b13ec --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/pdm/nrf_drv_pdm.c @@ -0,0 +1,248 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PDM) +#include "nrf_drv_pdm.h" +#include "nrf_assert.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" + +#define NRF_LOG_MODULE_NAME "PDM" + +#if PDM_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL PDM_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR PDM_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR PDM_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_PDM_EVENT_STARTED ? "NRF_PDM_EVENT_STARTED" : \ + (event == NRF_PDM_EVENT_STOPPED ? "NRF_COMP_EVENT_DOWN" : \ + (event == NRF_PDM_EVENT_END ? "NRF_COMP_EVENT_CROSS" : "UNKNOWN EVENT"))) +#else //PDM_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //PDM_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +/** @brief PDM interface status. */ +typedef enum +{ + NRF_PDM_STATE_IDLE, + NRF_PDM_STATE_RUNNING, + NRF_PDM_STATE_TRANSITION +} nrf_drv_pdm_state_t; + + +/** @brief PDM interface control block.*/ +typedef struct +{ + nrf_drv_state_t drv_state; ///< Driver state. + nrf_drv_pdm_state_t status; ///< Sampling state. + nrf_drv_pdm_event_handler_t event_handler; ///< Event handler function pointer. + uint16_t buffer_length; ///< Length of a single buffer in 16-bit words. + uint32_t * buffers[2]; ///< Sample buffers. +} nrf_drv_pdm_cb_t; + +static nrf_drv_pdm_cb_t m_cb; + + +void PDM_IRQHandler(void) +{ + if (nrf_pdm_event_check(NRF_PDM_EVENT_END)) + { + nrf_pdm_event_clear(NRF_PDM_EVENT_END); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_PDM_EVENT_END)); + + //Buffer is ready to process. + if (nrf_pdm_buffer_get() == m_cb.buffers[0]) + { + NRF_LOG_DEBUG("PDM data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)m_cb.buffers[1], m_cb.buffer_length * sizeof(m_cb.buffers[1])); + m_cb.event_handler(m_cb.buffers[1], m_cb.buffer_length); + } + else + { + NRF_LOG_DEBUG("PDM data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)m_cb.buffers[0], m_cb.buffer_length * sizeof(m_cb.buffers[0])); + m_cb.event_handler(m_cb.buffers[0], m_cb.buffer_length); + } + } + else if (nrf_pdm_event_check(NRF_PDM_EVENT_STARTED)) + { + nrf_pdm_event_clear(NRF_PDM_EVENT_STARTED); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_PDM_EVENT_STARTED)); + m_cb.status = NRF_PDM_STATE_RUNNING; + + //Swap buffer. + if (nrf_pdm_buffer_get() == m_cb.buffers[0]) + { + nrf_pdm_buffer_set(m_cb.buffers[1],m_cb.buffer_length); + } + else + { + nrf_pdm_buffer_set(m_cb.buffers[0],m_cb.buffer_length); + } + } + else if (nrf_pdm_event_check(NRF_PDM_EVENT_STOPPED)) + { + nrf_pdm_event_clear(NRF_PDM_EVENT_STOPPED); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_PDM_EVENT_STOPPED)); + nrf_pdm_disable(); + m_cb.status = NRF_PDM_STATE_IDLE; + } +} + + +ret_code_t nrf_drv_pdm_init(nrf_drv_pdm_config_t const * p_config, + nrf_drv_pdm_event_handler_t event_handler) +{ + ret_code_t err_code; + + if (m_cb.drv_state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + if ((p_config == NULL) + || (event_handler == NULL)) + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + if (p_config->gain_l > NRF_PDM_GAIN_MAXIMUM + || p_config->gain_r > NRF_PDM_GAIN_MAXIMUM + || p_config->buffer_length > NRF_PDM_MAX_BUFFER_SIZE) + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + m_cb.buffers[0] = (uint32_t*)p_config->buffer_a; + m_cb.buffers[1] = (uint32_t*)p_config->buffer_b; + m_cb.buffer_length = p_config->buffer_length; + m_cb.event_handler = event_handler; + m_cb.status = NRF_PDM_STATE_IDLE; + + nrf_pdm_buffer_set(m_cb.buffers[0],m_cb.buffer_length); + nrf_pdm_clock_set(p_config->clock_freq); + nrf_pdm_mode_set(p_config->mode, p_config->edge); + nrf_pdm_gain_set(p_config->gain_l, p_config->gain_r); + + nrf_gpio_cfg_output(p_config->pin_clk); + nrf_gpio_pin_clear(p_config->pin_clk); + nrf_gpio_cfg_input(p_config->pin_din, NRF_GPIO_PIN_NOPULL); + nrf_pdm_psel_connect(p_config->pin_clk, p_config->pin_din); + + m_cb.drv_state = NRF_DRV_STATE_INITIALIZED; + nrf_pdm_int_enable(NRF_PDM_INT_STARTED | NRF_PDM_INT_END | NRF_PDM_INT_STOPPED); + nrf_drv_common_irq_enable(PDM_IRQn, p_config->interrupt_priority); + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_pdm_uninit(void) +{ + nrf_pdm_disable(); + nrf_pdm_psel_disconnect(); + m_cb.drv_state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Uninitialized.\r\n"); +} + + +ret_code_t nrf_drv_pdm_start(void) +{ + ASSERT(m_cb.drv_state != NRF_DRV_STATE_UNINITIALIZED); + ret_code_t err_code; + + if (m_cb.status != NRF_PDM_STATE_IDLE) + { + if (m_cb.status == NRF_PDM_STATE_RUNNING) + { + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + m_cb.status = NRF_PDM_STATE_TRANSITION; + m_cb.drv_state = NRF_DRV_STATE_POWERED_ON; + nrf_pdm_enable(); + nrf_pdm_event_clear(NRF_PDM_EVENT_STARTED); + nrf_pdm_task_trigger(NRF_PDM_TASK_START); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +ret_code_t nrf_drv_pdm_stop(void) +{ + ASSERT(m_cb.drv_state != NRF_DRV_STATE_UNINITIALIZED); + ret_code_t err_code; + + if (m_cb.status != NRF_PDM_STATE_RUNNING) + { + if (m_cb.status == NRF_PDM_STATE_IDLE) + { + nrf_pdm_disable(); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + m_cb.status = NRF_PDM_STATE_TRANSITION; + m_cb.drv_state = NRF_DRV_STATE_INITIALIZED; + nrf_pdm_task_trigger(NRF_PDM_TASK_STOP); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} +#endif //NRF_MODULE_ENABLED(PDM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/pdm/nrf_drv_pdm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/pdm/nrf_drv_pdm.h new file mode 100644 index 0000000000000000000000000000000000000000..7a871f5ec3772cfd72900bd6a861f41ca9e73563 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/pdm/nrf_drv_pdm.h @@ -0,0 +1,203 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 nrf_pdm PDM HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52 Pulse density modulation (PDM) interface APIs. + * + * The PDM HAL provides basic APIs for accessing the registers of the PDM interface peripheral. + * The PDM driver provides APIs on a higher level. + * + * @defgroup nrf_drv_pdm PDM driver + * @{ + * @ingroup nrf_pdm + * + * @brief @tagAPI52 Pulse density modulation (PDM) interface driver. + */ + + +#ifndef NRF_DRV_PDM_H__ +#define NRF_DRV_PDM_H__ + +#include "sdk_config.h" +#include "nrf_pdm.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define NRF_PDM_MAX_BUFFER_SIZE 32768 + + +/** + * @brief PDM interface driver configuration structure. + */ +typedef struct +{ + nrf_pdm_mode_t mode; ///< Interface operation mode. + nrf_pdm_edge_t edge; ///< Sampling mode. + uint8_t pin_clk; ///< CLK pin. + uint8_t pin_din; ///< DIN pin. + nrf_pdm_freq_t clock_freq; ///< Clock frequency. + nrf_pdm_gain_t gain_l; ///< Left channel gain. + nrf_pdm_gain_t gain_r; ///< Right channel gain. + uint8_t interrupt_priority; ///< Interrupt priority. + uint16_t buffer_length; ///< Length of a single buffer (in 16-bit words). + int16_t * buffer_a; ///< Sample buffer A (filled first). + int16_t * buffer_b; ///< Sample buffer B (filled after buffer A). +} nrf_drv_pdm_config_t; + + +/** + * @brief Macro for setting @ref nrf_drv_pdm_config_t to default settings + * in single ended mode. + * + * @param PIN_CLK CLK output pin. + * @param PIN_DIN DIN input pin. + * @param BUFF_A Sample buffer A (filled first). + * @param BUFF_B Sample buffer B (filled after buffer A). + * @param BUFF_LEN Length of a single buffer (in 16-bit words). + */ +#define NRF_DRV_PDM_DEFAULT_CONFIG(PIN_CLK, PIN_DIN, BUFF_A, BUFF_B, BUFF_LEN) \ +{ \ + .mode = (nrf_pdm_mode_t)PDM_CONFIG_MODE, \ + .edge = (nrf_pdm_edge_t)PDM_CONFIG_EDGE, \ + .pin_clk = PIN_CLK, \ + .pin_din = PIN_DIN, \ + .clock_freq = (nrf_pdm_freq_t)PDM_CONFIG_CLOCK_FREQ, \ + .gain_l = NRF_PDM_GAIN_DEFAULT, \ + .gain_r = NRF_PDM_GAIN_DEFAULT, \ + .interrupt_priority = PDM_CONFIG_IRQ_PRIORITY, \ + .buffer_length = BUFF_LEN, \ + .buffer_a = BUFF_A, \ + .buffer_b = BUFF_B \ +} + + +/** + * @brief Handler for PDM interface ready events. + * + * This event handler is called when a buffer is full and ready to be processed. + * + * @param[in] p_buffer Sample buffer pointer. + * @param[in] length Buffer length in 16-bit words. + */ +typedef void (*nrf_drv_pdm_event_handler_t)(uint32_t * buffer, uint16_t length); + + +/** + * @brief Function for initializing the PDM interface. + * + * @param[in] p_config Pointer to a configuration structure. If NULL, the default one is used. + * @param[in] event_handler Event handler provided by the user. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver is already initialized. + * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified. + */ +ret_code_t nrf_drv_pdm_init(nrf_drv_pdm_config_t const * p_config, + nrf_drv_pdm_event_handler_t event_handler); + + +/** + * @brief Function for uninitializing the PDM interface. + * + * This function stops PDM sampling, if it is in progress. + */ +void nrf_drv_pdm_uninit(void); + + +/** + * @brief Function for getting the address of a PDM interface task. + * + * @param[in] task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_pdm_task_address_get(nrf_pdm_task_t task) +{ + return nrf_pdm_task_address_get(task); +} + + +/** + * @brief Function for getting the state of the PDM interface. + * + * @retval TRUE If the PDM interface is enabled. + * @retval FALSE If the PDM interface is disabled. + */ +__STATIC_INLINE bool nrf_drv_pdm_enable_check() +{ + return nrf_pdm_enable_check(); +} + + +/** + * @brief Function for starting PDM sampling. + * + * @retval NRF_SUCCESS If sampling was started successfully or was already in progress. + * @retval NRF_ERROR_BUSY If a previous start/stop operation is in progress. + */ +ret_code_t nrf_drv_pdm_start(void); + + +/** + * @brief Function for stopping PDM sampling. + * + * When this function is called, the PDM interface is stopped after finishing + * the current frame. + * The event handler function might be called once more after calling this function. + * + * @retval NRF_SUCCESS If sampling was stopped successfully or was already stopped before. + * @retval NRF_ERROR_BUSY If a previous start/stop operation is in progress. + */ +ret_code_t nrf_drv_pdm_stop(void); + + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_PDM_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/power/nrf_drv_power.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/power/nrf_drv_power.c new file mode 100644 index 0000000000000000000000000000000000000000..00165d958bfd0b473da7036b5d7eb4a2f05f1603 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/power/nrf_drv_power.c @@ -0,0 +1,447 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(POWER) + +#include "nrf_drv_power.h" +#include "nrf_assert.h" +#include "nordic_common.h" +#include "app_util_platform.h" +#ifdef SOFTDEVICE_PRESENT +#include "softdevice_handler.h" +#include "nrf_sdm.h" +#include "nrf_soc.h" +#endif + +/* Validate configuration */ +INTERRUPT_PRIORITY_VALIDATION(POWER_CONFIG_IRQ_PRIORITY); + +/** + * @internal + * @defgroup nrf_drv_power_internals POWER driver internals + * @ingroup nrf_drv_power + * + * Internal variables, auxiliary macros and functions of POWER driver. + * @{ + */ + +/** + * @brief Default configuration + * + * The structure with default configuration data. + * This structure would be used if configuration pointer given + * to the @ref nrf_drv_power_init is set to NULL. + */ +static const nrf_drv_power_config_t m_drv_power_config_default = +{ + .dcdcen = POWER_CONFIG_DEFAULT_DCDCEN, +#if NRF_POWER_HAS_VDDH + .dcdcenhv = POWER_CONFIG_DEFAULT_DCDCENHV, +#endif +}; + +/** + * @brief The initialization flag + */ +static bool m_initialized; + +/** + * @brief The handler of power fail comparator warning event + */ +static nrf_drv_power_pofwarn_event_handler_t m_pofwarn_handler; + +#if NRF_POWER_HAS_SLEEPEVT +/** + * @brief The handler of sleep event handler + */ +static nrf_drv_power_sleep_event_handler_t m_sleepevt_handler; +#endif + +#if NRF_POWER_HAS_USBREG +/** + * @brief The handler of USB power events + */ +static nrf_drv_power_usb_event_handler_t m_usbevt_handler; +#endif + +/** @} */ + +bool nrf_drv_power_init_check(void) +{ + return m_initialized; +} + +ret_code_t nrf_drv_power_init(nrf_drv_power_config_t const * p_config) +{ + nrf_drv_power_config_t const * p_used_config; + if (m_initialized) + { + return NRF_ERROR_MODULE_ALREADY_INITIALIZED; + } +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + return NRF_ERROR_INVALID_STATE; + } +#endif + + p_used_config = (p_config != NULL) ? + p_config : (&m_drv_power_config_default); +#if NRF_POWER_HAS_VDDH + nrf_power_dcdcen_vddh_set(p_used_config->dcdcenhv); +#endif + nrf_power_dcdcen_set(p_used_config->dcdcen); + + nrf_drv_common_power_clock_irq_init(); + + m_initialized = true; + return NRF_SUCCESS; +} + +void nrf_drv_power_uninit(void) +{ + ASSERT(m_initialized); + nrf_drv_power_pof_uninit(); +#if NRF_POWER_HAS_SLEEPEVT + nrf_drv_power_sleepevt_uninit(); +#endif +#if NRF_POWER_HAS_USBREG + nrf_drv_power_usbevt_uninit(); +#endif + m_initialized = false; +} + +ret_code_t nrf_drv_power_pof_init(nrf_drv_power_pofwarn_config_t const * p_config) +{ + ASSERT(p_config != NULL); + + nrf_drv_power_pof_uninit(); + +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + /* Currently when SD is enabled - the configuration can be changed + * in very limited range. + * It is the SoftDevice limitation. + */ +#if NRF_POWER_HAS_VDDH + if (p_config->thrvddh != nrf_power_pofcon_vddh_get()) + { + /* Cannot change THRVDDH with current SD API */ + return NRF_ERROR_INVALID_STATE; + } +#endif + if (p_config->thr != nrf_power_pofcon_get(NULL)) + { + /* Only limited number of THR values are supported and + * the values taken by SD is different than the one in hardware + */ + uint8_t thr; + switch(p_config->thr) + { + case NRF_POWER_POFTHR_V21: + thr = NRF_POWER_THRESHOLD_V21; + break; + case NRF_POWER_POFTHR_V23: + thr = NRF_POWER_THRESHOLD_V23; + break; + case NRF_POWER_POFTHR_V25: + thr = NRF_POWER_THRESHOLD_V25; + break; + case NRF_POWER_POFTHR_V27: + thr = NRF_POWER_THRESHOLD_V27; + break; + default: + /* Cannot configure */ + return NRF_ERROR_INVALID_STATE; + } + sd_power_pof_threshold_set(thr); + } + } + else +#endif /* SOFTDEVICE_PRESENT */ + { + nrf_power_pofcon_set(true, p_config->thr); +#if NRF_POWER_HAS_VDDH + nrf_power_pofcon_vddh_set(p_config->thrvddh); +#endif + } + + if (p_config->handler != NULL) + { + m_pofwarn_handler = p_config->handler; +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + sd_power_pof_enable(true); + } + else +#endif + { + nrf_power_int_enable(NRF_POWER_INT_POFWARN_MASK); + } + } + return NRF_SUCCESS; +} + +void nrf_drv_power_pof_uninit(void) +{ +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + sd_power_pof_enable(false); + } + else +#endif + { + nrf_power_int_disable(NRF_POWER_INT_POFWARN_MASK); + } + m_pofwarn_handler = NULL; +} + +#if NRF_POWER_HAS_SLEEPEVT +ret_code_t nrf_drv_power_sleepevt_init(nrf_drv_power_sleepevt_config_t const * p_config) +{ + ASSERT(p_config != NULL); + + nrf_drv_power_sleepevt_uninit(); + if (p_config->handler != NULL) + { + uint32_t enmask = 0; + m_sleepevt_handler = p_config->handler; + if (p_config->en_enter) + { + enmask |= NRF_POWER_INT_SLEEPENTER_MASK; + nrf_power_event_clear(NRF_POWER_EVENT_SLEEPENTER); + } + if (p_config->en_exit) + { + enmask |= NRF_POWER_INT_SLEEPEXIT_MASK; + nrf_power_event_clear(NRF_POWER_EVENT_SLEEPEXIT); + } +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + if (enmask != 0) + { + return NRF_ERROR_INVALID_STATE; + } + } + else +#endif + { + nrf_power_int_enable(enmask); + } + } + + return NRF_SUCCESS; +} + +void nrf_drv_power_sleepevt_uninit(void) +{ +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + /* Nothing to do */ + } + else +#endif + { + nrf_power_int_disable( + NRF_POWER_INT_SLEEPENTER_MASK | + NRF_POWER_INT_SLEEPEXIT_MASK); + } + m_sleepevt_handler = NULL; +} +#endif /* NRF_POWER_HAS_SLEEPEVT */ + +#if NRF_POWER_HAS_USBREG +ret_code_t nrf_drv_power_usbevt_init(nrf_drv_power_usbevt_config_t const * p_config) +{ + nrf_drv_power_usbevt_uninit(); + if (p_config->handler != NULL) + { + m_usbevt_handler = p_config->handler; +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + /** @todo Implement USB power events when SD support it */ + return NRF_ERROR_INVALID_STATE; + } + else +#endif + { + nrf_power_int_enable( + NRF_POWER_INT_USBDETECTED_MASK | + NRF_POWER_INT_USBREMOVED_MASK | + NRF_POWER_INT_USBPWRRDY_MASK); + } + } + return NRF_SUCCESS; +} + +void nrf_drv_power_usbevt_uninit(void) +{ +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + /** @todo Implement USB power events when SD support it */ + } + else +#endif + { + nrf_power_int_disable( + NRF_POWER_INT_USBDETECTED_MASK | + NRF_POWER_INT_USBREMOVED_MASK | + NRF_POWER_INT_USBPWRRDY_MASK); + } + m_usbevt_handler = NULL; +} +#endif /* NRF_POWER_HAS_USBREG */ + + +/** + * @ingroup nrf_drv_power_internals + * @brief Interrupt handler + * + * POWER peripheral interrupt handler + */ +#if NRF_DRV_COMMON_POWER_CLOCK_ISR +void nrf_drv_power_onIRQ(void) +#else +void POWER_POWER_IRQHandler(void) +#endif +{ + uint32_t enabled = nrf_power_int_enable_get(); + if ((0 != (enabled & NRF_POWER_INT_POFWARN_MASK)) && + nrf_power_event_get_and_clear(NRF_POWER_EVENT_POFWARN)) + { + /* Cannot be null if event is enabled */ + ASSERT(m_pofwarn_handler != NULL); + m_pofwarn_handler(); + } +#if NRF_POWER_HAS_SLEEPEVT + if ((0 != (enabled & NRF_POWER_INT_SLEEPENTER_MASK)) && + nrf_power_event_get_and_clear(NRF_POWER_EVENT_SLEEPENTER)) + { + /* Cannot be null if event is enabled */ + ASSERT(m_sleepevt_handler != NULL); + m_sleepevt_handler(NRF_DRV_POWER_SLEEP_EVT_ENTER); + } + if ((0 != (enabled & NRF_POWER_INT_SLEEPEXIT_MASK)) && + nrf_power_event_get_and_clear(NRF_POWER_EVENT_SLEEPEXIT)) + { + /* Cannot be null if event is enabled */ + ASSERT(m_sleepevt_handler != NULL); + m_sleepevt_handler(NRF_DRV_POWER_SLEEP_EVT_EXIT); + } +#endif +#if NRF_POWER_HAS_USBREG + if ((0 != (enabled & NRF_POWER_INT_USBDETECTED_MASK)) && + nrf_power_event_get_and_clear(NRF_POWER_EVENT_USBDETECTED)) + { + /* Cannot be null if event is enabled */ + ASSERT(m_usbevt_handler != NULL); + m_usbevt_handler(NRF_DRV_POWER_USB_EVT_DETECTED); + } + if ((0 != (enabled & NRF_POWER_INT_USBREMOVED_MASK)) && + nrf_power_event_get_and_clear(NRF_POWER_EVENT_USBREMOVED)) + { + /* Cannot be null if event is enabled */ + ASSERT(m_usbevt_handler != NULL); + m_usbevt_handler(NRF_DRV_POWER_USB_EVT_REMOVED); + } + if ((0 != (enabled & NRF_POWER_INT_USBPWRRDY_MASK)) && + nrf_power_event_get_and_clear(NRF_POWER_EVENT_USBPWRRDY)) + { + /* Cannot be null if event is enabled */ + ASSERT(m_usbevt_handler != NULL); + m_usbevt_handler(NRF_DRV_POWER_USB_EVT_READY); + } +#endif +} + +#ifdef SOFTDEVICE_PRESENT + +void nrf_drv_power_on_soc_event(uint32_t evt_id) +{ + if (evt_id == NRF_EVT_POWER_FAILURE_WARNING) + { + /* Cannot be null if event is enabled */ + ASSERT(m_pofwarn_handler != NULL); + m_pofwarn_handler(); + } +} + +void nrf_drv_power_on_sd_enable(void) +{ + ASSERT(m_initialized); /* This module has to be enabled first */ + CRITICAL_REGION_ENTER(); + if (m_pofwarn_handler != NULL) + { + sd_power_pof_enable(true); + } + CRITICAL_REGION_EXIT(); +} + +void nrf_drv_power_on_sd_disable(void) +{ + /* Reinit interrupts */ + ASSERT(m_initialized); + nrf_drv_common_irq_enable(POWER_CLOCK_IRQn, CLOCK_CONFIG_IRQ_PRIORITY); + if (m_pofwarn_handler != NULL) + { + nrf_power_int_enable(NRF_POWER_INT_POFWARN_MASK); + } +#if NRF_POWER_HAS_USBREG + if (m_usbevt_handler != NULL) + { + nrf_power_int_enable( + NRF_POWER_INT_USBDETECTED_MASK | + NRF_POWER_INT_USBREMOVED_MASK | + NRF_POWER_INT_USBPWRRDY_MASK); + } +#endif +} + +#endif // SOFTDEVICE_PRESENT + +#endif /* NRF_MODULE_ENABLED(POWER) */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/power/nrf_drv_power.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/power/nrf_drv_power.h new file mode 100644 index 0000000000000000000000000000000000000000..70ac172e17d883c7f48b96fea1f70cf180719c96 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/power/nrf_drv_power.h @@ -0,0 +1,397 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef NRF_DRV_POWER_H__ +#define NRF_DRV_POWER_H__ + +#include +#include +#include "nrf_power.h" +#include "sdk_config.h" +#include "nrf_drv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_power Power HAL and driver + * @ingroup nrf_drivers + * @brief POWER peripheral APIs. + * + * The power peripheral HAL provides basic APIs for accessing + * the registers of the POWER peripheral. + * The POWER driver provides APIs on a higher level. + */ + +/** + * @defgroup nrf_drv_power POWER driver + * @{ + * @ingroup nrf_power + * @brief Driver for managing events and the state of POWER peripheral. + * + */ + +/** + * @brief Power mode possible configurations + */ +typedef enum +{ + NRF_DRV_POWER_MODE_CONSTLAT, /**< Constant latency mode *///!< NRF_DRV_POWER_MODE_CONSTLAT + NRF_DRV_POWER_MODE_LOWPWR /**< Low power mode *///!< NRF_DRV_POWER_MODE_LOWPWR +}nrf_drv_power_mode_t; + +#if NRF_POWER_HAS_SLEEPEVT +/** + * @brief Events from power system + */ +typedef enum +{ + NRF_DRV_POWER_SLEEP_EVT_ENTER, /**< CPU entered WFI/WFE sleep + * + * Keep in mind that if this interrupt is enabled, + * it means that CPU was waken up just after WFI by this interrupt. + */ + NRF_DRV_POWER_SLEEP_EVT_EXIT /**< CPU exited WFI/WFE sleep */ +}nrf_drv_power_sleep_evt_t; +#endif /* NRF_POWER_HAS_SLEEPEVT */ + +#if NRF_POWER_HAS_USBREG +/** + * @brief Events from USB power system + */ +typedef enum +{ + NRF_DRV_POWER_USB_EVT_DETECTED, /**< USB power detected on the connector (plugged in). */ + NRF_DRV_POWER_USB_EVT_REMOVED, /**< USB power removed from the connector. */ + NRF_DRV_POWER_USB_EVT_READY /**< USB power regulator ready. */ +}nrf_drv_power_usb_evt_t; + +/** + * @brief USB power state + * + * The single enumerator that holds all data about current state of USB + * related POWER. + * + * Organized this way that higher power state has higher numeric value + */ +typedef enum +{ + NRF_DRV_POWER_USB_STATE_DISCONNECTED, /**< No power on USB lines detected */ + NRF_DRV_POWER_USB_STATE_CONNECTED, /**< The USB power is detected, but USB power regulator is not ready */ + NRF_DRV_POWER_USB_STATE_READY /**< From the power point of view USB is ready for working */ +}nrf_drv_power_usb_state_t; +#endif /* NRF_POWER_HAS_USBREG */ + +/** + * @name Callback types + * + * Defined types of callback functions + * @{ + */ +/** + * @brief Event handler for power failure warning + */ +typedef void (*nrf_drv_power_pofwarn_event_handler_t)(void); + +#if NRF_POWER_HAS_SLEEPEVT +/** + * @brief Event handler for entering/exiting sleep + * + * @param event Event type + */ +typedef void (*nrf_drv_power_sleep_event_handler_t)(nrf_drv_power_sleep_evt_t event); +#endif + +#if NRF_POWER_HAS_USBREG +/** + * @brief Event handler for USB related power events + * + * @param event Event type + */ +typedef void (*nrf_drv_power_usb_event_handler_t)(nrf_drv_power_usb_evt_t event); +#endif +/** @} */ + +/** + * @brief General power configuration + * + * Parameters required to initialize power driver. + */ +typedef struct +{ + /** + * @brief Enable main DCDC regulator + * + * This bit only informs the driver that elements for DCDC regulator + * are installed and regulator can be used. + * The regulator would be enabled or disabled automatically + * automatically by the hardware, basing on current power requirement. + */ + bool dcdcen:1; + +#if NRF_POWER_HAS_VDDH + /** + * @brief Enable HV DCDC regulator + * + * This bit only informs the driver that elements for DCDC regulator + * are installed and regulator can be used. + * The regulator would be enabled or disabled automatically + * automatically by the hardware, basing on current power requirement. + */ + bool dcdcenhv: 1; +#endif +}nrf_drv_power_config_t; + +/** + * @brief The configuration for power failure comparator + * + * Configuration used to enable and configure power failure comparator + */ +typedef struct +{ + nrf_drv_power_pofwarn_event_handler_t handler; //!< Event handler + nrf_power_pof_thr_t thr; //!< Threshold for power failure detection +#if NRF_POWER_HAS_VDDH + nrf_power_pof_thrvddh_t thrvddh; //!< Threshold for power failure detection on VDDH pin +#endif +}nrf_drv_power_pofwarn_config_t; + +#if NRF_POWER_HAS_SLEEPEVT +/** + * @brief The configuration of sleep event processing + * + * Configuration used to enable and configure sleep event handling + */ +typedef struct +{ + nrf_drv_power_sleep_event_handler_t handler; //!< Event handler + bool en_enter:1; //!< Enable event on sleep entering + bool en_exit :1; //!< Enable event on sleep exiting +}nrf_drv_power_sleepevt_config_t; +#endif + +#if NRF_POWER_HAS_USBREG +/** + * @brief The configuration of USB related power events + * + * Configuration used to enable and configure USB power event handling + */ +typedef struct +{ + nrf_drv_power_usb_event_handler_t handler; //!< Event processing +}nrf_drv_power_usbevt_config_t; +#endif /* NRF_POWER_HAS_USBREG */ + +/** + * @brief Function for checking if driver is already initialized + * + * This function is used to check whatever common POWER_CLOCK common interrupt + * should be disabled or not if @ref nrf_drv_clock tries to disable the interrupt. + * + * @retval true Driver is initialized + * @retval false Driver is uninitialized + * + * @sa nrf_drv_power_uninit + */ +bool nrf_drv_power_init_check(void); + +/** + * @brief Initialize power module driver + * + * Enabled power module driver would process all the interrupts from power system. + * + * @param[in] p_config Driver configuration. Can be NULL - the default configuration + * from @em sdk_config.h file would be used then. + * + * @retval NRF_ERROR_INVALID_STATE Power driver has to be enabled + * before SoftDevice. + * @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED Module is initialized already. + * @retval NRF_SUCCESS Successfully initialized. + */ +ret_code_t nrf_drv_power_init(nrf_drv_power_config_t const * p_config); + +/** + * @brief Unintialize power module driver + * + * Disables all the interrupt handling in the module. + * + * @sa nrf_drv_power_init + */ +void nrf_drv_power_uninit(void); + +/** + * @brief Initialize power failure comparator + * + * Configures and setups the power failure comparator and enables it. + * + * @param[in] p_config Configuration with values and event handler. + * If event handler is set to NULL, interrupt would be disabled. + * + * @retval NRF_ERROR_INVALID_STATE POF is initialized when SD is enabled and + * the configuration differs from the old one and + * is not possible to be set using SD interface. + * @retval NRF_SUCCESS Successfully initialized and configured. + */ +ret_code_t nrf_drv_power_pof_init(nrf_drv_power_pofwarn_config_t const * p_config); + +/** + * @brief Turn off the power failure comparator + * + * Disables and clears the settings of the power failure comparator. + */ +void nrf_drv_power_pof_uninit(void); + +#if NRF_POWER_HAS_SLEEPEVT +/** + * @brief Initialize sleep entering and exiting events processing + * + * Configures and setups the sleep event processing. + * + * @param[in] p_config Configuration with values and event handler. + * + * @sa nrf_drv_power_sleepevt_uninit + * + * @note Sleep events are not available when SoftDevice is enabled. + * @note If sleep event is enabled when SoftDevice is initialized, sleep events + * would be automatically disabled - it is the limitation of the + * SoftDevice itself. + * + * @retval NRF_ERROR_INVALID_STATE This event cannot be initialized + * when SD is enabled. + * @retval NRF_SUCCESS Successfully initialized and configured. + */ +ret_code_t nrf_drv_power_sleepevt_init(nrf_drv_power_sleepevt_config_t const * p_config); + +/** + * @brief Uninitialize sleep entering and exiting events processing + * + * @sa nrf_drv_power_sleepevt_init + */ +void nrf_drv_power_sleepevt_uninit(void); +#endif /* NRF_POWER_HAS_SLEEPEVT */ + +#if NRF_POWER_HAS_USBREG +/** + * @brief Initialize USB power event processing + * + * Configures and setups the USB power event processing. + * + * @param[in] p_config Configuration with values and event handler. + * + * @sa nrf_drv_power_usbevt_uninit + * + * @retval NRF_ERROR_INVALID_STATE This event cannot be initialized + * when SD is enabled and SD does not support + * USB power events. + * @retval NRF_SUCCESS Successfully initialized and configured. + */ +ret_code_t nrf_drv_power_usbevt_init(nrf_drv_power_usbevt_config_t const * p_config); + +/** + * @brief Uninitalize USB power event processing + * + * @sa nrf_drv_power_usbevt_init + */ +void nrf_drv_power_usbevt_uninit(void); + +/** + * @brief Get the status of USB power + * + * @return Current USB power status + */ +__STATIC_INLINE nrf_drv_power_usb_state_t nrf_drv_power_usbstatus_get(void); + +#endif /* NRF_POWER_HAS_USBREG */ + +#ifdef SOFTDEVICE_PRESENT +/** + * @brief Function called by the SoftDevice handler if an @ref nrf_soc event is received from the SoftDevice. + * + * @param[in] evt_id One of NRF_SOC_EVTS values. + */ +void nrf_drv_power_on_soc_event(uint32_t evt_id); + +/** + * @brief Function called by the SoftDevice handler when the SoftDevice has been enabled. + * + * This function is called just after the SoftDevice has been properly enabled. + * Its main purpose is to reenable required interrupts and connect them to SD events. + */ +void nrf_drv_power_on_sd_enable(void); + +/** + * @brief Function called by the SoftDevice handler when the SoftDevice has been disabled. + * + * This function is called just after the SoftDevice has been properly disabled. + * Its main purpose is to reenable required interrupts. + */ +void nrf_drv_power_on_sd_disable(void); + +#endif /* SOFTDEVICE_PRESENT */ + +/** @} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +#if NRF_POWER_HAS_USBREG +__STATIC_INLINE nrf_drv_power_usb_state_t nrf_drv_power_usbstatus_get(void) +{ + uint32_t status = nrf_power_usbregstatus_get(); + if(0 == (status & NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK)) + { + return NRF_DRV_POWER_USB_STATE_DISCONNECTED; + } + if(0 == (status & NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK)) + { + return NRF_DRV_POWER_USB_STATE_CONNECTED; + } + return NRF_DRV_POWER_USB_STATE_READY; +} +#endif /* NRF_POWER_HAS_USBREG */ + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_DRV_POWER_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/ppi/nrf_drv_ppi.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/ppi/nrf_drv_ppi.c new file mode 100644 index 0000000000000000000000000000000000000000..fb625b026195b405d8b9db6b0b8c7817287ecff0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/ppi/nrf_drv_ppi.c @@ -0,0 +1,540 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PPI) +#include + +#include "nrf.h" +#include "nrf_drv_ppi.h" +#include "nrf_drv_common.h" +#include "nrf_ppi.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "PPI" + +#if PPI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL PPI_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR PPI_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR PPI_CONFIG_DEBUG_COLOR +#else //PPI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //PPI_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +static nrf_drv_state_t m_drv_state; /**< Driver state */ +static uint32_t m_channels_allocated; /**< Bitmap representing channels availability. 1 when a channel is allocated, 0 otherwise. */ +static uint8_t m_groups_allocated; /**< Bitmap representing groups availability. 1 when a group is allocated, 0 otherwise.*/ + + +/**@brief Compute a group mask (needed for driver internals, not used for NRF_PPI registers). + * @param[in] group Group number to transform to a mask. + * @retval Group mask. + */ +__STATIC_INLINE uint32_t group_to_mask(nrf_ppi_channel_group_t group) +{ + return (1uL << (uint32_t) group); +} + + +/**@brief Check whether a channel is a programmable channel and can be used by an application. + * @param[in] channel Channel to check. + * @retval true The channel is a programmable application channel. + * false The channel is used by a SoftDevice or is preprogrammed. + */ +__STATIC_INLINE bool is_programmable_app_channel(nrf_ppi_channel_t channel) +{ + return ((NRF_PPI_PROG_APP_CHANNELS_MASK & nrf_drv_ppi_channel_to_mask(channel)) != 0); +} + + +/**@brief Check whether a channels can be used by an application. + * @param[in] channel Channel mask to check. + * @retval true All specified channels can be used by an application. + * false At least one specified channel is used by a SoftDevice. + */ +__STATIC_INLINE bool are_app_channels(uint32_t channel_mask) +{ + //lint -e(587) + return ((~(NRF_PPI_ALL_APP_CHANNELS_MASK) & channel_mask) == 0); +} + + +/**@brief Check whether a channel can be used by an application. + * @param[in] channel Channel to check. + * @retval true The channel can be used by an application. + * false The channel is used by a SoftDevice. + */ +__STATIC_INLINE bool is_app_channel(nrf_ppi_channel_t channel) +{ + return are_app_channels(nrf_drv_ppi_channel_to_mask(channel)); +} + + +/**@brief Check whether a channel group can be used by an application. + * @param[in] group Group to check. + * @retval true The group is an application group. + * false The group is not an application group (this group either does not exist or + * it is used by a SoftDevice). + */ +__STATIC_INLINE bool is_app_group(nrf_ppi_channel_group_t group) +{ + return ((NRF_PPI_ALL_APP_GROUPS_MASK & group_to_mask(group)) != 0); +} + + +/**@brief Check whether a channel is allocated. + * @param[in] channel_num Channel number to check. + * @retval true The channel is allocated. + * false The channel is not allocated. + */ +__STATIC_INLINE bool is_allocated_channel(nrf_ppi_channel_t channel) +{ + return ((m_channels_allocated & nrf_drv_ppi_channel_to_mask(channel)) != 0); +} + + +/**@brief Set channel allocated indication. + * @param[in] channel_num Specifies the channel to set the "allocated" indication. + */ +__STATIC_INLINE void channel_allocated_set(nrf_ppi_channel_t channel) +{ + m_channels_allocated |= nrf_drv_ppi_channel_to_mask(channel); +} + + +/**@brief Clear channel allocated indication. + * @param[in] channel_num Specifies the channel to clear the "allocated" indication. + */ +__STATIC_INLINE void channel_allocated_clr(nrf_ppi_channel_t channel) +{ + m_channels_allocated &= ~nrf_drv_ppi_channel_to_mask(channel); +} + + +/**@brief Clear all allocated channels. + */ +__STATIC_INLINE void channel_allocated_clr_all(void) +{ + m_channels_allocated &= ~NRF_PPI_ALL_APP_CHANNELS_MASK; +} + + +/**@brief Check whether a group is allocated. + * @param[in] group_num Group number to check. + * @retval true The group is allocated. + * false The group is not allocated. + */ +__STATIC_INLINE bool is_allocated_group(nrf_ppi_channel_group_t group) +{ + return ((m_groups_allocated & group_to_mask(group)) != 0); +} + + +/**@brief Set group allocated indication. + * @param[in] group_num Specifies the group to set the "allocated" indication. + */ +__STATIC_INLINE void group_allocated_set(nrf_ppi_channel_group_t group) +{ + m_groups_allocated |= group_to_mask(group); +} + + +/**@brief Clear group allocated indication. + * @param[in] group_num Specifies the group to clear the "allocated" indication. + */ +__STATIC_INLINE void group_allocated_clr(nrf_ppi_channel_group_t group) +{ + m_groups_allocated &= ~group_to_mask(group); +} + + +/**@brief Clear all allocated groups. + */ +__STATIC_INLINE void group_allocated_clr_all() +{ + m_groups_allocated &= ~NRF_PPI_ALL_APP_GROUPS_MASK; +} + + +uint32_t nrf_drv_ppi_init(void) +{ + uint32_t err_code; + + if (m_drv_state == NRF_DRV_STATE_UNINITIALIZED) + { + m_drv_state = NRF_DRV_STATE_INITIALIZED; + err_code = NRF_SUCCESS; + } + else + { + + err_code = NRF_ERROR_MODULE_ALREADY_INITIALIZED; + } + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +uint32_t nrf_drv_ppi_uninit(void) +{ + ret_code_t err_code = NRF_SUCCESS; + uint32_t mask = NRF_PPI_ALL_APP_GROUPS_MASK; + nrf_ppi_channel_group_t group; + + if (m_drv_state == NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + m_drv_state = NRF_DRV_STATE_UNINITIALIZED; + + // Disable all channels and groups + nrf_ppi_channels_disable(NRF_PPI_ALL_APP_CHANNELS_MASK); + + for (group = NRF_PPI_CHANNEL_GROUP0; mask != 0; mask &= ~group_to_mask(group), group++) + { + if (mask & group_to_mask(group)) + { + nrf_ppi_channel_group_clear(group); + } + } + channel_allocated_clr_all(); + group_allocated_clr_all(); + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +uint32_t nrf_drv_ppi_channel_alloc(nrf_ppi_channel_t * p_channel) +{ + uint32_t err_code = NRF_SUCCESS; + nrf_ppi_channel_t channel; + uint32_t mask = 0; + + err_code = NRF_ERROR_NO_MEM; + + mask = NRF_PPI_PROG_APP_CHANNELS_MASK; + for (channel = NRF_PPI_CHANNEL0; mask != 0; mask &= ~nrf_drv_ppi_channel_to_mask(channel), channel++) + { + CRITICAL_REGION_ENTER(); + if ((mask & nrf_drv_ppi_channel_to_mask(channel)) && (!is_allocated_channel(channel))) + { + channel_allocated_set(channel); + *p_channel = channel; + err_code = NRF_SUCCESS; + } + CRITICAL_REGION_EXIT(); + if (err_code == NRF_SUCCESS) + { + NRF_LOG_INFO("Allocated channel: %d.\r\n", channel); + break; + } + } + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +uint32_t nrf_drv_ppi_channel_free(nrf_ppi_channel_t channel) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (!is_programmable_app_channel(channel)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else + { + // First disable this channel + nrf_ppi_channel_disable(channel); + CRITICAL_REGION_ENTER(); + channel_allocated_clr(channel); + CRITICAL_REGION_EXIT(); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +uint32_t nrf_drv_ppi_channel_assign(nrf_ppi_channel_t channel, uint32_t eep, uint32_t tep) +{ + VERIFY_PARAM_NOT_NULL((uint32_t *)eep); + VERIFY_PARAM_NOT_NULL((uint32_t *)tep); + + ret_code_t err_code = NRF_SUCCESS; + + if (!is_programmable_app_channel(channel)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else if (!is_allocated_channel(channel)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else + { + nrf_ppi_channel_endpoint_setup(channel, eep, tep); + NRF_LOG_INFO("Assigned channel: %d, event end point: %x, task end point: %x.\r\n", channel, eep, tep); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +uint32_t nrf_drv_ppi_channel_fork_assign(nrf_ppi_channel_t channel, uint32_t fork_tep) +{ + ret_code_t err_code = NRF_SUCCESS; +#ifdef PPI_FEATURE_FORKS_PRESENT + if (!is_programmable_app_channel(channel)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else if (!is_allocated_channel(channel)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else + { + nrf_ppi_fork_endpoint_setup(channel, fork_tep); + NRF_LOG_INFO("Fork assigned channel: %d, task end point: %d.\r\n", channel, fork_tep); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +#else + err_code = NRF_ERROR_NOT_SUPPORTED; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +#endif +} + +uint32_t nrf_drv_ppi_channel_enable(nrf_ppi_channel_t channel) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (!is_app_channel(channel)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else if (is_programmable_app_channel(channel) && !is_allocated_channel(channel)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else + { + nrf_ppi_channel_enable(channel); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +uint32_t nrf_drv_ppi_channel_disable(nrf_ppi_channel_t channel) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (!is_app_channel(channel)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else if (is_programmable_app_channel(channel) && !is_allocated_channel(channel)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else + { + nrf_ppi_channel_disable(channel); + err_code = NRF_SUCCESS; + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +uint32_t nrf_drv_ppi_group_alloc(nrf_ppi_channel_group_t * p_group) +{ + uint32_t err_code; + uint32_t mask = 0; + nrf_ppi_channel_group_t group; + + err_code = NRF_ERROR_NO_MEM; + + mask = NRF_PPI_ALL_APP_GROUPS_MASK; + for (group = NRF_PPI_CHANNEL_GROUP0; mask != 0; mask &= ~group_to_mask(group), group++) + { + CRITICAL_REGION_ENTER(); + if ((mask & group_to_mask(group)) && (!is_allocated_group(group))) + { + group_allocated_set(group); + *p_group = group; + err_code = NRF_SUCCESS; + } + CRITICAL_REGION_EXIT(); + if (err_code == NRF_SUCCESS) + { + NRF_LOG_INFO("Allocated group: %d.\r\n", group); + break; + } + } + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +uint32_t nrf_drv_ppi_group_free(nrf_ppi_channel_group_t group) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (!is_app_group(group)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + if (!is_allocated_group(group)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else + { + nrf_ppi_group_disable(group); + CRITICAL_REGION_ENTER(); + group_allocated_clr(group); + CRITICAL_REGION_EXIT(); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +uint32_t nrf_drv_ppi_group_enable(nrf_ppi_channel_group_t group) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (!is_app_group(group)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else if (!is_allocated_group(group)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else + { + nrf_ppi_group_enable(group); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +uint32_t nrf_drv_ppi_group_disable(nrf_ppi_channel_group_t group) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (!is_app_group(group)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else + { + nrf_ppi_group_disable(group); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +uint32_t nrf_drv_ppi_channels_remove_from_group(uint32_t channel_mask, + nrf_ppi_channel_group_t group) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (!is_app_group(group)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else if (!is_allocated_group(group)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else if (!are_app_channels(channel_mask)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else + { + CRITICAL_REGION_ENTER(); + nrf_ppi_channels_remove_from_group(channel_mask, group); + CRITICAL_REGION_EXIT(); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +uint32_t nrf_drv_ppi_channels_include_in_group(uint32_t channel_mask, + nrf_ppi_channel_group_t group) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (!is_app_group(group)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else if (!is_allocated_group(group)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else if (!are_app_channels(channel_mask)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else + { + CRITICAL_REGION_ENTER(); + nrf_ppi_channels_include_in_group(channel_mask, group); + CRITICAL_REGION_EXIT(); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} +#endif //NRF_MODULE_ENABLED(PPI) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/ppi/nrf_drv_ppi.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/ppi/nrf_drv_ppi.h new file mode 100644 index 0000000000000000000000000000000000000000..91fdf96a363743eeac2149cdc1b360e868165353 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/ppi/nrf_drv_ppi.h @@ -0,0 +1,316 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_DRV_PPI_H +#define NRF_DRV_PPI_H + +/*lint ++flb "Enter library region" */ +#include "sdk_errors.h" +#include "nrf_ppi.h" +#include +#include + +/** @file + * + * @addtogroup nrf_ppi PPI HAL and driver + * @ingroup nrf_drivers + * @brief Programmable Peripheral Interconnect (PPI) APIs. + * + * @details The PPI HAL provides basic APIs for accessing the registers of the PPI. + * The PPI driver provides APIs on a higher level. + * + * @defgroup nrf_drv_ppi PPI driver + * @{ + * @ingroup nrf_ppi + * + * @brief Programmable Peripheral Interconnect (PPI) driver. + */ + +#include "sdk_resources.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if PPI_CH_NUM > 16 +#define NRF_PPI_ALL_APP_CHANNELS_MASK ((uint32_t)0xFFFFFFFFuL & ~(NRF_PPI_CHANNELS_USED)) /**< All PPI channels available to the application. */ +#define NRF_PPI_PROG_APP_CHANNELS_MASK ((uint32_t)0x000FFFFFuL & ~(NRF_PPI_CHANNELS_USED)) /**< Programmable PPI channels available to the application. */ +#else +#define NRF_PPI_ALL_APP_CHANNELS_MASK ((uint32_t)0xFFF0FFFFuL & ~(NRF_PPI_CHANNELS_USED)) /**< All PPI channels available to the application. */ +#define NRF_PPI_PROG_APP_CHANNELS_MASK ((uint32_t)0x0000FFFFuL & ~(NRF_PPI_CHANNELS_USED)) /**< Programmable PPI channels available to the application. */ +#endif + +#define NRF_PPI_ALL_APP_GROUPS_MASK (((1uL << PPI_GROUP_NUM) - 1) & ~(NRF_PPI_GROUPS_USED)) /**< All PPI groups available to the application. */ + + +/**@brief Function for initializing PPI module. + * + * @retval NRF_SUCCESS If the module was successfully initialized. + * @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED If the module has already been initialized. + */ +uint32_t nrf_drv_ppi_init(void); + +/**@brief Function for uninitializing the PPI module. + * + * This function also disables all channels and clears the channel groups. + * + * @retval NRF_SUCCESS If the module was successfully uninitialized. + * @retval NRF_ERROR_INVALID_STATE If the module has not been initialized yet. + * @retval NRF_ERROR_INTERNAL If the channels or groups could not be disabled. + */ +uint32_t nrf_drv_ppi_uninit(void); + +/**@brief Function for allocating a PPI channel. + * @details This function allocates the first unused PPI channel. + * + * @param[out] p_channel Pointer to the PPI channel that has been allocated. + * + * @retval NRF_SUCCESS If the channel was successfully allocated. + * @retval NRF_ERROR_NO_MEM If there is no available channel to be used. + */ +uint32_t nrf_drv_ppi_channel_alloc(nrf_ppi_channel_t * p_channel); + +/**@brief Function for freeing a PPI channel. + * @details This function also disables the chosen channel. + * + * @param[in] channel PPI channel to be freed. + * + * @retval NRF_SUCCESS If the channel was successfully freed. + * @retval NRF_ERROR_INVALID_PARAM If the channel is not user-configurable. + */ +uint32_t nrf_drv_ppi_channel_free(nrf_ppi_channel_t channel); + +/**@brief Function for assigning task and event endpoints to the PPI channel. + * + * @param[in] channel PPI channel to be assigned endpoints. + * + * @param[in] eep Event endpoint address. + * + * @param[in] tep Task endpoint address. + * + * @retval NRF_SUCCESS If the channel was successfully assigned. + * @retval NRF_ERROR_INVALID_STATE If the channel is not allocated for the user. + * @retval NRF_ERROR_INVALID_PARAM If the channel is not user-configurable. + */ +uint32_t nrf_drv_ppi_channel_assign(nrf_ppi_channel_t channel, uint32_t eep, uint32_t tep); + +/**@brief Function for assigning or clearing fork endpoint to the PPI channel. + * + * @param[in] channel PPI channel to be assigned endpoints. + * + * @param[in] fork_tep Fork task endpoint address or 0 to clear. + * + * @retval NRF_SUCCESS If the channel was successfully assigned. + * @retval NRF_ERROR_INVALID_STATE If the channel is not allocated for the user. + * @retval NRF_ERROR_INVALID_PARAM If the channel is not user-configurable. + * @retval NRF_ERROR_NOT_SUPPORTED If function is not supported. + */ +uint32_t nrf_drv_ppi_channel_fork_assign(nrf_ppi_channel_t channel, uint32_t fork_tep); + +/**@brief Function for enabling a PPI channel. + * + * @param[in] channel PPI channel to be enabled. + * + * @retval NRF_SUCCESS If the channel was successfully enabled. + * @retval NRF_ERROR_INVALID_STATE If the user-configurable channel is not allocated. + * @retval NRF_ERROR_INVALID_PARAM If the channel cannot be enabled by the user. + */ +uint32_t nrf_drv_ppi_channel_enable(nrf_ppi_channel_t channel); + +/**@brief Function for disabling a PPI channel. + * + * @param[in] channel PPI channel to be disabled. + * + * @retval NRF_SUCCESS If the channel was successfully disabled. + * @retval NRF_ERROR_INVALID_STATE If the user-configurable channel is not allocated. + * @retval NRF_ERROR_INVALID_PARAM If the channel cannot be disabled by the user. + */ +uint32_t nrf_drv_ppi_channel_disable(nrf_ppi_channel_t channel); + +/**@brief Function for allocating a PPI channel group. + * @details This function allocates the first unused PPI group. + * + * @param[out] p_group Pointer to the PPI channel group that has been allocated. + * + * @retval NRF_SUCCESS If the channel group was successfully allocated. + * @retval NRF_ERROR_NO_MEM If there is no available channel group to be used. + */ +uint32_t nrf_drv_ppi_group_alloc(nrf_ppi_channel_group_t * p_group); + +/**@brief Function for freeing a PPI channel group. + * @details This function also disables the chosen group. + * + * @param[in] group PPI channel group to be freed. + * + * @retval NRF_SUCCESS If the channel group was successfully freed. + * @retval NRF_ERROR_INVALID_PARAM If the channel group is not user-configurable. + */ +uint32_t nrf_drv_ppi_group_free(nrf_ppi_channel_group_t group); + +/**@brief Compute a channel mask for NRF_PPI registers. + * + * @param[in] channel Channel number to transform to a mask. + * + * @retval Channel mask. + */ +__STATIC_INLINE uint32_t nrf_drv_ppi_channel_to_mask(nrf_ppi_channel_t channel) +{ + return (1uL << (uint32_t) channel); +} + +/**@brief Function for including multiple PPI channels in a channel group. + * + * @param[in] channel_mask PPI channels to be added. + * @param[in] group Channel group in which to include the channels. + * + * @retval NRF_SUCCESS If the channels was successfully included. + */ +uint32_t nrf_drv_ppi_channels_include_in_group(uint32_t channel_mask, + nrf_ppi_channel_group_t group); + +/**@brief Function for including a PPI channel in a channel group. + * + * @param[in] channel PPI channel to be added. + * @param[in] group Channel group in which to include the channel. + * + * @retval NRF_SUCCESS If the channel was successfully included. + */ +__STATIC_INLINE uint32_t nrf_drv_ppi_channel_include_in_group(nrf_ppi_channel_t channel, + nrf_ppi_channel_group_t group) +{ + return nrf_drv_ppi_channels_include_in_group(nrf_drv_ppi_channel_to_mask(channel), group); +} + +/**@brief Function for removing multiple PPI channels from a channel group. + * + * @param[in] channel_mask PPI channels to be removed. + * @param[in] group Channel group from which to remove the channels. + * + * @retval NRF_SUCCESS If the channel was successfully removed. + */ +uint32_t nrf_drv_ppi_channels_remove_from_group(uint32_t channel_mask, + nrf_ppi_channel_group_t group); + +/**@brief Function for removing a PPI channel from a channel group. + * + * @param[in] channel PPI channel to be removed. + * @param[in] group Channel group from which to remove the channel. + * + * @retval NRF_SUCCESS If the channel was successfully removed. + */ +__STATIC_INLINE uint32_t nrf_drv_ppi_channel_remove_from_group(nrf_ppi_channel_t channel, + nrf_ppi_channel_group_t group) +{ + return nrf_drv_ppi_channels_remove_from_group(nrf_drv_ppi_channel_to_mask(channel), group); +} + +/**@brief Function for clearing a PPI channel group. + * + * @param[in] group Channel group to be cleared. + * + * @retval NRF_SUCCESS If the group was successfully cleared. + */ +__STATIC_INLINE uint32_t nrf_drv_ppi_group_clear(nrf_ppi_channel_group_t group) +{ + return nrf_drv_ppi_channels_remove_from_group(NRF_PPI_ALL_APP_CHANNELS_MASK, group); +} + +/**@brief Function for enabling a PPI channel group. + * + * @param[in] group Channel group to be enabled. + * + * @retval NRF_SUCCESS If the group was successfully enabled. + */ +uint32_t nrf_drv_ppi_group_enable(nrf_ppi_channel_group_t group); + +/**@brief Function for disabling a PPI channel group. + * + * @param[in] group Channel group to be disabled. + * + * @retval NRF_SUCCESS If the group was successfully disabled. + */ +uint32_t nrf_drv_ppi_group_disable(nrf_ppi_channel_group_t group); + +/** + * @brief Function for getting the address of a PPI task. + * + * @param[in] task Task. + * + * @retval Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_ppi_task_addr_get(nrf_ppi_task_t task) +{ + return (uint32_t) nrf_ppi_task_address_get(task); +} + +/** + * @brief Function for getting the address of a PPI group enable task. + * + * @param[in] group PPI channel group + * + * @retval Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_ppi_task_addr_group_enable_get(nrf_ppi_channel_group_t group) +{ + return (uint32_t) nrf_ppi_task_group_enable_address_get(group); +} + +/** + * @brief Function for getting the address of a PPI group enable task. + * + * @param[in] group PPI channel group + * + * @retval Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_ppi_task_addr_group_disable_get(nrf_ppi_channel_group_t group) +{ + return (uint32_t) nrf_ppi_task_group_disable_address_get(group); +} + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_PPI_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/pwm/nrf_drv_pwm.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/pwm/nrf_drv_pwm.c new file mode 100644 index 0000000000000000000000000000000000000000..581ff607c2afa3ab25ff9e9b6a63b5d4fcb1c79d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/pwm/nrf_drv_pwm.c @@ -0,0 +1,516 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PWM) +#define ENABLED_PWM_COUNT (PWM0_ENABLED+PWM1_ENABLED+PWM2_ENABLED) +#if ENABLED_PWM_COUNT +#include +#include "nrf_drv_pwm.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "PWM" + +#if PWM_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL PWM_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR PWM_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR PWM_CONFIG_DEBUG_COLOR +#else //PWM_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //PWM_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +#if NRF_MODULE_ENABLED(PWM_NRF52_ANOMALY_109_WORKAROUND) +// The workaround uses interrupts to wake up the CPU and ensure it is active +// when PWM is about to start a DMA transfer. For initial transfer, done when +// a playback is started via PPI, a specific EGU instance is used to generate +// an interrupt. During the playback, the PWM interrupt triggered on SEQEND +// event of a preceding sequence is used to protect the transfer done for +// the next sequence to be played. +#include "nrf_egu.h" +#define USE_DMA_ISSUE_WORKAROUND +#endif +#if defined(USE_DMA_ISSUE_WORKAROUND) +#define EGU_IRQn(i) EGU_IRQn_(i) +#define EGU_IRQn_(i) SWI##i##_EGU##i##_IRQn +#define EGU_IRQHandler(i) EGU_IRQHandler_(i) +#define EGU_IRQHandler_(i) SWI##i##_EGU##i##_IRQHandler +#define DMA_ISSUE_EGU_IDX PWM_NRF52_ANOMALY_109_EGU_INSTANCE +#define DMA_ISSUE_EGU CONCAT_2(NRF_EGU, DMA_ISSUE_EGU_IDX) +#define DMA_ISSUE_EGU_IRQn EGU_IRQn(DMA_ISSUE_EGU_IDX) +#define DMA_ISSUE_EGU_IRQHandler EGU_IRQHandler(DMA_ISSUE_EGU_IDX) +#endif + +// Control block - driver instance local data. +typedef struct +{ +#if defined(USE_DMA_ISSUE_WORKAROUND) + uint32_t starting_task_address; +#endif + nrf_drv_pwm_handler_t handler; + nrf_drv_state_t volatile state; + uint8_t flags; +} pwm_control_block_t; +static pwm_control_block_t m_cb[ENABLED_PWM_COUNT]; + +static void configure_pins(nrf_drv_pwm_t const * const p_instance, + nrf_drv_pwm_config_t const * p_config) +{ + uint32_t out_pins[NRF_PWM_CHANNEL_COUNT]; + uint8_t i; + + for (i = 0; i < NRF_PWM_CHANNEL_COUNT; ++i) + { + uint8_t output_pin = p_config->output_pins[i]; + if (output_pin != NRF_DRV_PWM_PIN_NOT_USED) + { + bool inverted = output_pin & NRF_DRV_PWM_PIN_INVERTED; + out_pins[i] = output_pin & ~NRF_DRV_PWM_PIN_INVERTED; + + if (inverted) + { + nrf_gpio_pin_set(out_pins[i]); + } + else + { + nrf_gpio_pin_clear(out_pins[i]); + } + + nrf_gpio_cfg_output(out_pins[i]); + } + else + { + out_pins[i] = NRF_PWM_PIN_NOT_CONNECTED; + } + } + + nrf_pwm_pins_set(p_instance->p_registers, out_pins); +} + + +ret_code_t nrf_drv_pwm_init(nrf_drv_pwm_t const * const p_instance, + nrf_drv_pwm_config_t const * p_config, + nrf_drv_pwm_handler_t handler) +{ + ASSERT(p_config); + + ret_code_t err_code; + + pwm_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + p_cb->handler = handler; + + configure_pins(p_instance, p_config); + + nrf_pwm_enable(p_instance->p_registers); + nrf_pwm_configure(p_instance->p_registers, + p_config->base_clock, p_config->count_mode, p_config->top_value); + nrf_pwm_decoder_set(p_instance->p_registers, + p_config->load_mode, p_config->step_mode); + + nrf_pwm_shorts_set(p_instance->p_registers, 0); + nrf_pwm_int_set(p_instance->p_registers, 0); + nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_LOOPSDONE); + nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_SEQEND0); + nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_SEQEND1); + nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_STOPPED); + + // The workaround for nRF52 Anomaly 109 "protects" DMA transfers by handling + // interrupts generated on SEQEND0 and SEQEND1 events (this ensures that + // the 64 MHz clock is ready when data for the next sequence to be played + // is read). Therefore, the PWM interrupt must be enabled even if the event + // handler is not used. +#if defined(USE_DMA_ISSUE_WORKAROUND) + nrf_drv_common_irq_enable(DMA_ISSUE_EGU_IRQn, p_config->irq_priority); +#else + if (p_cb->handler) +#endif + { + nrf_drv_common_irq_enable(nrf_drv_get_IRQn(p_instance->p_registers), + p_config->irq_priority); + } + + p_cb->state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_pwm_uninit(nrf_drv_pwm_t const * const p_instance) +{ + pwm_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_drv_common_irq_disable(nrf_drv_get_IRQn(p_instance->p_registers)); +#if defined(USE_DMA_ISSUE_WORKAROUND) + nrf_drv_common_irq_disable(DMA_ISSUE_EGU_IRQn); +#endif + + nrf_pwm_disable(p_instance->p_registers); + + p_cb->state = NRF_DRV_STATE_UNINITIALIZED; +} + + +static uint32_t start_playback(nrf_drv_pwm_t const * const p_instance, + pwm_control_block_t * p_cb, + uint8_t flags, + nrf_pwm_task_t starting_task) +{ + p_cb->state = NRF_DRV_STATE_POWERED_ON; + p_cb->flags = flags; + + if (p_cb->handler) + { + // The notification about finished playback is by default enabled, + // but this can be suppressed. + // The notification that the peripheral has stopped is always enabled. + uint32_t int_mask = NRF_PWM_INT_LOOPSDONE_MASK | + NRF_PWM_INT_STOPPED_MASK; + + // The workaround for nRF52 Anomaly 109 "protects" DMA transfers by + // handling interrupts generated on SEQEND0 and SEQEND1 events (see + // 'nrf_drv_pwm_init'), hence these events must be always enabled + // to generate interrupts. + // However, the user handler is called for them only when requested + // (see 'irq_handler'). +#if defined(USE_DMA_ISSUE_WORKAROUND) + int_mask |= NRF_PWM_INT_SEQEND0_MASK | NRF_PWM_INT_SEQEND1_MASK; +#else + if (flags & NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0) + { + int_mask |= NRF_PWM_INT_SEQEND0_MASK; + } + if (flags & NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1) + { + int_mask |= NRF_PWM_INT_SEQEND1_MASK; + } +#endif + if (flags & NRF_DRV_PWM_FLAG_NO_EVT_FINISHED) + { + int_mask &= ~NRF_PWM_INT_LOOPSDONE_MASK; + } + + nrf_pwm_int_set(p_instance->p_registers, int_mask); + } +#if defined(USE_DMA_ISSUE_WORKAROUND) + else + { + nrf_pwm_int_set(p_instance->p_registers, + NRF_PWM_INT_SEQEND0_MASK | NRF_PWM_INT_SEQEND1_MASK); + } +#endif + + nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_STOPPED); + + if (flags & NRF_DRV_PWM_FLAG_START_VIA_TASK) + { + uint32_t starting_task_address = + nrf_pwm_task_address_get(p_instance->p_registers, starting_task); + +#if defined(USE_DMA_ISSUE_WORKAROUND) + // To "protect" the initial DMA transfer it is required to start + // the PWM by triggering the proper task from EGU interrupt handler, + // it is not safe to do it directly via PPI. + p_cb->starting_task_address = starting_task_address; + nrf_egu_int_enable(DMA_ISSUE_EGU, + nrf_egu_int_get(DMA_ISSUE_EGU, p_instance->drv_inst_idx)); + return (uint32_t)nrf_egu_task_trigger_address_get(DMA_ISSUE_EGU, + p_instance->drv_inst_idx); +#else + return starting_task_address; +#endif + } + + nrf_pwm_task_trigger(p_instance->p_registers, starting_task); + return 0; +} + + +uint32_t nrf_drv_pwm_simple_playback(nrf_drv_pwm_t const * const p_instance, + nrf_pwm_sequence_t const * p_sequence, + uint16_t playback_count, + uint32_t flags) +{ + pwm_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(playback_count > 0); + ASSERT(nrf_drv_is_in_RAM(p_sequence->values.p_raw)); + + // To take advantage of the looping mechanism, we need to use both sequences + // (single sequence can be played back only once). + nrf_pwm_sequence_set(p_instance->p_registers, 0, p_sequence); + nrf_pwm_sequence_set(p_instance->p_registers, 1, p_sequence); + bool odd = (playback_count & 1); + nrf_pwm_loop_set(p_instance->p_registers, + (playback_count / 2) + (odd ? 1 : 0)); + + uint32_t shorts_mask; + if (flags & NRF_DRV_PWM_FLAG_STOP) + { + shorts_mask = NRF_PWM_SHORT_LOOPSDONE_STOP_MASK; + } + else if (flags & NRF_DRV_PWM_FLAG_LOOP) + { + shorts_mask = odd ? NRF_PWM_SHORT_LOOPSDONE_SEQSTART1_MASK + : NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK; + } + else + { + shorts_mask = 0; + } + nrf_pwm_shorts_set(p_instance->p_registers, shorts_mask); + + NRF_LOG_INFO("Function: %s, sequence length: %d.\r\n", (uint32_t)__func__, + p_sequence->length * sizeof(p_sequence->values)); + NRF_LOG_DEBUG("Sequence data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_sequence->values.p_raw, + p_sequence->length * sizeof(p_sequence->values)); + return start_playback(p_instance, p_cb, flags, + odd ? NRF_PWM_TASK_SEQSTART1 : NRF_PWM_TASK_SEQSTART0); +} + + +uint32_t nrf_drv_pwm_complex_playback(nrf_drv_pwm_t const * const p_instance, + nrf_pwm_sequence_t const * p_sequence_0, + nrf_pwm_sequence_t const * p_sequence_1, + uint16_t playback_count, + uint32_t flags) +{ + pwm_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(playback_count > 0); + ASSERT(nrf_drv_is_in_RAM(p_sequence_0->values.p_raw)); + ASSERT(nrf_drv_is_in_RAM(p_sequence_1->values.p_raw)); + + nrf_pwm_sequence_set(p_instance->p_registers, 0, p_sequence_0); + nrf_pwm_sequence_set(p_instance->p_registers, 1, p_sequence_1); + nrf_pwm_loop_set(p_instance->p_registers, playback_count); + + uint32_t shorts_mask; + if (flags & NRF_DRV_PWM_FLAG_STOP) + { + shorts_mask = NRF_PWM_SHORT_LOOPSDONE_STOP_MASK; + } + else if (flags & NRF_DRV_PWM_FLAG_LOOP) + { + shorts_mask = NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK; + } + else + { + shorts_mask = 0; + } + nrf_pwm_shorts_set(p_instance->p_registers, shorts_mask); + + NRF_LOG_INFO("Function: %s, sequence 0 length: %d.\r\n", (uint32_t)__func__, + p_sequence_0->length * sizeof(p_sequence_0->values)); + NRF_LOG_INFO("Function: %s, sequence 1 length: %d.\r\n", (uint32_t)__func__, + p_sequence_1->length * sizeof(p_sequence_1->values)); + NRF_LOG_DEBUG("Sequence 0 data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_sequence_0->values.p_raw, + p_sequence_0->length * sizeof(p_sequence_0->values)); + NRF_LOG_DEBUG("Sequence 1 data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_sequence_1->values.p_raw, + p_sequence_1->length * sizeof(p_sequence_1->values)); + return start_playback(p_instance, p_cb, flags, NRF_PWM_TASK_SEQSTART0); +} + + +bool nrf_drv_pwm_stop(nrf_drv_pwm_t const * const p_instance, + bool wait_until_stopped) +{ + ASSERT(m_cb[p_instance->drv_inst_idx].state != NRF_DRV_STATE_UNINITIALIZED); + + bool ret_val = false; + + if (nrf_drv_pwm_is_stopped(p_instance)) + { + ret_val = true; + } + else + { + nrf_pwm_task_trigger(p_instance->p_registers, NRF_PWM_TASK_STOP); + + do { + if (nrf_drv_pwm_is_stopped(p_instance)) + { + ret_val = true; + break; + } + } while (wait_until_stopped); + } + + NRF_LOG_INFO("%s returned %d.\r\n", (uint32_t)__func__, ret_val); + return ret_val; +} + + +bool nrf_drv_pwm_is_stopped(nrf_drv_pwm_t const * const p_instance) +{ + pwm_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + bool ret_val = false; + + // If the event handler is used (interrupts are enabled), the state will + // be changed in interrupt handler when the STOPPED event occurs. + if (p_cb->state != NRF_DRV_STATE_POWERED_ON) + { + ret_val = true; + } + // If interrupts are disabled, we must check the STOPPED event here. + if (nrf_pwm_event_check(p_instance->p_registers, NRF_PWM_EVENT_STOPPED)) + { + p_cb->state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Disabled.\r\n"); + ret_val = true; + } + + NRF_LOG_INFO("%s returned %d.\r\n", (uint32_t)__func__, ret_val); + return ret_val; +} + + +static void irq_handler(NRF_PWM_Type * p_pwm, pwm_control_block_t * p_cb) +{ + // The user handler is called for SEQEND0 and SEQEND1 events only when the + // user asks for it (by setting proper flags when starting the playback). + if (nrf_pwm_event_check(p_pwm, NRF_PWM_EVENT_SEQEND0)) + { + nrf_pwm_event_clear(p_pwm, NRF_PWM_EVENT_SEQEND0); + if ((p_cb->flags & NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0) && p_cb->handler) + { + p_cb->handler(NRF_DRV_PWM_EVT_END_SEQ0); + } + } + if (nrf_pwm_event_check(p_pwm, NRF_PWM_EVENT_SEQEND1)) + { + nrf_pwm_event_clear(p_pwm, NRF_PWM_EVENT_SEQEND1); + if ((p_cb->flags & NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1) && p_cb->handler) + { + p_cb->handler(NRF_DRV_PWM_EVT_END_SEQ1); + } + } + // For LOOPSDONE the handler is called by default, but the user can disable + // this (via flags). + if (nrf_pwm_event_check(p_pwm, NRF_PWM_EVENT_LOOPSDONE)) + { + nrf_pwm_event_clear(p_pwm, NRF_PWM_EVENT_LOOPSDONE); + if (!(p_cb->flags & NRF_DRV_PWM_FLAG_NO_EVT_FINISHED) && p_cb->handler) + { + p_cb->handler(NRF_DRV_PWM_EVT_FINISHED); + } + } + + // The STOPPED event is always propagated to the user handler. + if (nrf_pwm_event_check(p_pwm, NRF_PWM_EVENT_STOPPED)) + { + nrf_pwm_event_clear(p_pwm, NRF_PWM_EVENT_STOPPED); + + p_cb->state = NRF_DRV_STATE_INITIALIZED; + if (p_cb->handler) + { + p_cb->handler(NRF_DRV_PWM_EVT_STOPPED); + } + } +} + + +#if defined(USE_DMA_ISSUE_WORKAROUND) +// See 'start_playback' why this is needed. +void DMA_ISSUE_EGU_IRQHandler(void) +{ + int i; + for (i = 0; i < ENABLED_PWM_COUNT; ++i) + { + volatile uint32_t * p_event_reg = + nrf_egu_event_triggered_address_get(DMA_ISSUE_EGU, i); + if (*p_event_reg) + { + *p_event_reg = 0; + *(volatile uint32_t *)(m_cb[i].starting_task_address) = 1; + } + } +} +#endif + + +#if NRF_MODULE_ENABLED(PWM0) +void PWM0_IRQHandler(void) +{ + irq_handler(NRF_PWM0, &m_cb[PWM0_INSTANCE_INDEX]); +} +#endif + +#if NRF_MODULE_ENABLED(PWM1) +void PWM1_IRQHandler(void) +{ + irq_handler(NRF_PWM1, &m_cb[PWM1_INSTANCE_INDEX]); +} +#endif + +#if NRF_MODULE_ENABLED(PWM2) +void PWM2_IRQHandler(void) +{ + irq_handler(NRF_PWM2, &m_cb[PWM2_INSTANCE_INDEX]); +} +#endif + +#if PWM3_ENABLED +void PWM3_IRQHandler(void) +{ + irq_handler(NRF_PWM3, &m_cb[PWM3_INSTANCE_INDEX]); +} +#endif +#endif //ENABLED_PWM_COUNT +#endif //NRF_MODULE_ENABLED(PWM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/pwm/nrf_drv_pwm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/pwm/nrf_drv_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..8fbd88208745dffdd5c90a552bb17011f2c11af4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/pwm/nrf_drv_pwm.h @@ -0,0 +1,512 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * @addtogroup nrf_pwm PWM HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52 Pulse Width Modulation (PWM) module APIs. + * + * @defgroup nrf_drv_pwm PWM driver + * @{ + * @ingroup nrf_pwm + * @brief @tagAPI52 Pulse Width Modulation (PWM) module driver. + */ + + +#ifndef NRF_DRV_PWM_H__ +#define NRF_DRV_PWM_H__ + +#include "nordic_common.h" +#include "sdk_config.h" +#include "nrf_pwm.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PWM0_ENABLED +#define PWM0_ENABLED 0 +#endif +#ifndef PWM1_ENABLED +#define PWM1_ENABLED 0 +#endif +#ifndef PWM2_ENABLED +#define PWM2_ENABLED 0 +#endif +#ifndef PWM3_ENABLED +#define PWM3_ENABLED 0 +#endif +/** + * @brief PWM driver instance data structure. + */ +typedef struct +{ + NRF_PWM_Type * p_registers; ///< Pointer to the structure with PWM peripheral instance registers. + uint8_t drv_inst_idx; ///< Driver instance index. +} nrf_drv_pwm_t; + +#define PWM0_INSTANCE_INDEX 0 +#define PWM1_INSTANCE_INDEX PWM0_INSTANCE_INDEX+PWM0_ENABLED +#define PWM2_INSTANCE_INDEX PWM1_INSTANCE_INDEX+PWM1_ENABLED +#define PWM3_INSTANCE_INDEX PWM2_INSTANCE_INDEX+PWM2_ENABLED + +/** + * @brief Macro for creating a PWM driver instance. + */ +#define NRF_DRV_PWM_INSTANCE(id) \ +{ \ + .p_registers = CONCAT_2(NRF_PWM, id), \ + .drv_inst_idx = CONCAT_3(PWM, id, _INSTANCE_INDEX), \ +} + + +/** + * @brief This value can be provided instead of a pin number for any channel + * to specify that its output is not used and therefore does not need + * to be connected to a pin. + */ +#define NRF_DRV_PWM_PIN_NOT_USED 0xFF + +/** + * @brief This value can be added to a pin number to inverse its polarity + * (set idle state = 1). + */ +#define NRF_DRV_PWM_PIN_INVERTED 0x80 + +/** + * @brief PWM driver configuration structure. + */ +typedef struct +{ + uint8_t output_pins[NRF_PWM_CHANNEL_COUNT]; ///< Pin numbers for individual output channels (optional). + /**< Use @ref NRF_DRV_PWM_PIN_NOT_USED + * if a given output channel is not needed. */ + uint8_t irq_priority; ///< Interrupt priority. + nrf_pwm_clk_t base_clock; ///< Base clock frequency. + nrf_pwm_mode_t count_mode; ///< Operating mode of the pulse generator counter. + uint16_t top_value; ///< Value up to which the pulse generator counter counts. + nrf_pwm_dec_load_t load_mode; ///< Mode of loading sequence data from RAM. + nrf_pwm_dec_step_t step_mode; ///< Mode of advancing the active sequence. +} nrf_drv_pwm_config_t; + +/** + * @brief PWM driver default configuration. + */ +#define NRF_DRV_PWM_DEFAULT_CONFIG \ +{ \ + .output_pins = {PWM_DEFAULT_CONFIG_OUT0_PIN, \ + PWM_DEFAULT_CONFIG_OUT1_PIN, \ + PWM_DEFAULT_CONFIG_OUT2_PIN, \ + PWM_DEFAULT_CONFIG_OUT3_PIN }, \ + .irq_priority = PWM_DEFAULT_CONFIG_IRQ_PRIORITY, \ + .base_clock = (nrf_pwm_clk_t)PWM_DEFAULT_CONFIG_BASE_CLOCK, \ + .count_mode = (nrf_pwm_mode_t)PWM_DEFAULT_CONFIG_COUNT_MODE, \ + .top_value = PWM_DEFAULT_CONFIG_TOP_VALUE, \ + .load_mode = (nrf_pwm_dec_load_t)PWM_DEFAULT_CONFIG_LOAD_MODE, \ + .step_mode = (nrf_pwm_dec_step_t)PWM_DEFAULT_CONFIG_STEP_MODE, \ +} + + +/** + * @brief PWM flags providing additional playback options. + */ +typedef enum +{ + NRF_DRV_PWM_FLAG_STOP = 0x01, /**< When the requested playback is finished, + the peripheral should be stopped. + @note The STOP task is triggered when + the last value of the final sequence is + loaded from RAM, and the peripheral stops + at the end of the current PWM period. + For sequences with configured repeating + of duty cycle values, this might result in + less than the requested number of repeats + of the last value. */ + NRF_DRV_PWM_FLAG_LOOP = 0x02, /**< When the requested playback is finished, + it should be started from the beginning. + This flag is ignored if used together + with @ref NRF_DRV_PWM_FLAG_STOP. + @note The playback restart is done via a + shortcut configured in the PWM peripheral. + This shortcut triggers the proper starting + task when the final value of previous + playback is read from RAM and applied to + the pulse generator counter. + When this mechanism is used together with + the @ref NRF_PWM_STEP_TRIGGERED mode, + the playback restart will occur right + after switching to the final value (this + final value will be played only once). */ + NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0 = 0x04, /**< The event handler should be + called when the last value + from sequence 0 is loaded. */ + NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1 = 0x08, /**< The event handler should be + called when the last value + from sequence 1 is loaded. */ + NRF_DRV_PWM_FLAG_NO_EVT_FINISHED = 0x10, /**< The playback finished event + (enabled by default) should be + suppressed. */ + NRF_DRV_PWM_FLAG_START_VIA_TASK = 0x80, /**< The playback should not be + started directly by the called + function. Instead, the function + should only prepare it and + return the address of the task + to be triggered to start the + playback. */ +} nrf_drv_pwm_flag_t; + + +/** + * @brief PWM driver event type. + */ +typedef enum +{ + NRF_DRV_PWM_EVT_FINISHED, ///< Sequence playback finished. + NRF_DRV_PWM_EVT_END_SEQ0, /**< End of sequence 0 reached. Its data can be + safely modified now. */ + NRF_DRV_PWM_EVT_END_SEQ1, /**< End of sequence 1 reached. Its data can be + safely modified now. */ + NRF_DRV_PWM_EVT_STOPPED, ///< The PWM peripheral has been stopped. +} nrf_drv_pwm_evt_type_t; + +/** + * @brief PWM driver event handler type. + */ +typedef void (* nrf_drv_pwm_handler_t)(nrf_drv_pwm_evt_type_t event_type); + + +/** + * @brief Function for initializing the PWM driver. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_config Pointer to the structure with initial configuration. + * If NULL, the default configuration is used. + * @param[in] handler Event handler provided by the user. If NULL is passed + * instead, event notifications are not done and PWM + * interrupts are disabled. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver was already initialized. + */ +ret_code_t nrf_drv_pwm_init(nrf_drv_pwm_t const * const p_instance, + nrf_drv_pwm_config_t const * p_config, + nrf_drv_pwm_handler_t handler); + +/** + * @brief Function for uninitializing the PWM driver. + * + * If any sequence playback is in progress, it is stopped immediately. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_pwm_uninit(nrf_drv_pwm_t const * const p_instance); + +/** + * @brief Function for starting a single sequence playback. + * + * To take advantage of the looping mechanism in the PWM peripheral, both + * sequences must be used (single sequence can be played back only once by + * the peripheral). Therefore, the provided sequence is internally set and + * played back as both sequence 0 and sequence 1. Consequently, if end of + * sequence notifications are required, events for both sequences should be + * used (that means that both the @ref NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0 flag + * and the @ref NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1 flag should be specified and + * the @ref NRF_DRV_PWM_EVT_END_SEQ0 event and the @ref NRF_DRV_PWM_EVT_END_SEQ1 + * event should be handled in the same way). + * + * Use the @ref NRF_DRV_PWM_FLAG_START_VIA_TASK flag if you want the playback + * to be only prepared by this function, and you want to start it later by + * triggering a task (using PPI for instance). The function will then return + * the address of the task to be triggered. + * + * @note The array containing the duty cycle values for the specified sequence + * must be in RAM and cannot be allocated on stack. + * For detailed information, see @ref nrf_pwm_sequence_t. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_sequence Sequence to be played back. + * @param[in] playback_count Number of playbacks to be performed (must not be 0). + * @param[in] flags Additional options. Pass any combination of + * @ref nrf_drv_pwm_flag_t "playback flags", or 0 + * for default settings. + * + * @return Address of the task to be triggered to start the playback if the @ref + * NRF_DRV_PWM_FLAG_START_VIA_TASK flag was used, 0 otherwise. + */ +uint32_t nrf_drv_pwm_simple_playback(nrf_drv_pwm_t const * const p_instance, + nrf_pwm_sequence_t const * p_sequence, + uint16_t playback_count, + uint32_t flags); + +/** + * @brief Function for starting a two-sequence playback. + * + * Use the @ref NRF_DRV_PWM_FLAG_START_VIA_TASK flag if you want the playback + * to be only prepared by this function, and you want to start it later by + * triggering a task (using PPI for instance). The function will then return + * the address of the task to be triggered. + * + * @note The array containing the duty cycle values for the specified sequence + * must be in RAM and cannot be allocated on stack. + * For detailed information, see @ref nrf_pwm_sequence_t. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_sequence_0 First sequence to be played back. + * @param[in] p_sequence_1 Second sequence to be played back. + * @param[in] playback_count Number of playbacks to be performed (must not be 0). + * @param[in] flags Additional options. Pass any combination of + * @ref nrf_drv_pwm_flag_t "playback flags", or 0 + * for default settings. + * + * @return Address of the task to be triggered to start the playback if the @ref + * NRF_DRV_PWM_FLAG_START_VIA_TASK flag was used, 0 otherwise. + */ +uint32_t nrf_drv_pwm_complex_playback(nrf_drv_pwm_t const * const p_instance, + nrf_pwm_sequence_t const * p_sequence_0, + nrf_pwm_sequence_t const * p_sequence_1, + uint16_t playback_count, + uint32_t flags); + +/** + * @brief Function for advancing the active sequence. + * + * This function only applies to @ref NRF_PWM_STEP_TRIGGERED mode. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +__STATIC_INLINE void nrf_drv_pwm_step(nrf_drv_pwm_t const * const p_instance); + +/** + * @brief Function for stopping the sequence playback. + * + * The playback is stopped at the end of the current PWM period. + * This means that if the active sequence is configured to repeat each duty + * cycle value for a certain number of PWM periods, the last played value + * might appear on the output less times than requested. + * + * @note This function can be instructed to wait until the playback is stopped + * (by setting @p wait_until_stopped to true). Note that, depending on + * the length of the PMW period, this might take a significant amount of + * time. Alternatively, the @ref nrf_drv_pwm_is_stopped function can be + * used to poll the status, or the @ref NRF_DRV_PWM_EVT_STOPPED event can + * be used to get the notification when the playback is stopped, provided + * the event handler is defined. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] wait_until_stopped If true, the function will not return until + * the playback is stopped. + * + * @retval true If the PWM peripheral is stopped. + * @retval false If the PWM peripheral is not stopped. + */ +bool nrf_drv_pwm_stop(nrf_drv_pwm_t const * const p_instance, + bool wait_until_stopped); + +/** + * @brief Function for checking the status of the PWM peripheral. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true If the PWM peripheral is stopped. + * @retval false If the PWM peripheral is not stopped. + */ +bool nrf_drv_pwm_is_stopped(nrf_drv_pwm_t const * const p_instance); + +/** + * @brief Function for updating the sequence data during playback. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] p_sequence Pointer to the new sequence definition. + */ +__STATIC_INLINE void nrf_drv_pwm_sequence_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + nrf_pwm_sequence_t const * p_sequence); + +/** + * @brief Function for updating the pointer to the duty cycle values + * in the specified sequence during playback. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] values New pointer to the duty cycle values. + */ +__STATIC_INLINE void nrf_drv_pwm_sequence_values_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + nrf_pwm_values_t values); + +/** + * @brief Function for updating the number of duty cycle values + * in the specified sequence during playback. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] length New number of the duty cycle values. + */ +__STATIC_INLINE void nrf_drv_pwm_sequence_length_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + uint16_t length); + +/** + * @brief Function for updating the number of repeats for duty cycle values + * in specified sequence during playback. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] repeats New number of repeats. + */ +__STATIC_INLINE void nrf_drv_pwm_sequence_repeats_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + uint32_t repeats); + +/** + * @brief Function for updating the additional delay after the specified + * sequence during playback. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] end_delay New end delay value (in PWM periods). + */ +__STATIC_INLINE void nrf_drv_pwm_sequence_end_delay_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + uint32_t end_delay); + +/** + * @brief Function for returning the address of a specified PWM task that can + * be used in PPI module. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] task Requested task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_pwm_task_address_get( + nrf_drv_pwm_t const * const p_instance, + nrf_pwm_task_t task); + +/**@brief Function for returning the address of a specified PWM event that can + * be used in PPI module. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] event Requested event. + * + * @return Event address. + */ +__STATIC_INLINE uint32_t nrf_drv_pwm_event_address_get( + nrf_drv_pwm_t const * const p_instance, + nrf_pwm_event_t event); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_drv_pwm_step(nrf_drv_pwm_t const * const p_instance) +{ + nrf_pwm_task_trigger(p_instance->p_registers, NRF_PWM_TASK_NEXTSTEP); +} + +__STATIC_INLINE void nrf_drv_pwm_sequence_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + nrf_pwm_sequence_t const * p_sequence) +{ + nrf_pwm_sequence_set(p_instance->p_registers, seq_id, p_sequence); +} + +__STATIC_INLINE void nrf_drv_pwm_sequence_values_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + nrf_pwm_values_t values) +{ + nrf_pwm_seq_ptr_set(p_instance->p_registers, seq_id, values.p_raw); +} + +__STATIC_INLINE void nrf_drv_pwm_sequence_length_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + uint16_t length) +{ + nrf_pwm_seq_cnt_set(p_instance->p_registers, seq_id, length); +} + +__STATIC_INLINE void nrf_drv_pwm_sequence_repeats_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + uint32_t repeats) +{ + nrf_pwm_seq_refresh_set(p_instance->p_registers, seq_id, repeats); +} + +__STATIC_INLINE void nrf_drv_pwm_sequence_end_delay_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + uint32_t end_delay) +{ + nrf_pwm_seq_end_delay_set(p_instance->p_registers, seq_id, end_delay); +} + +__STATIC_INLINE uint32_t nrf_drv_pwm_task_address_get( + nrf_drv_pwm_t const * const p_instance, + nrf_pwm_task_t task) +{ + return nrf_pwm_task_address_get(p_instance->p_registers, task); +} + +__STATIC_INLINE uint32_t nrf_drv_pwm_event_address_get( + nrf_drv_pwm_t const * const p_instance, + nrf_pwm_event_t event) +{ + return nrf_pwm_event_address_get(p_instance->p_registers, event); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_PWM_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/qdec/nrf_drv_qdec.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/qdec/nrf_drv_qdec.c new file mode 100644 index 0000000000000000000000000000000000000000..cdd3fc52e9ff55ad0674d9b259dab1b561f50a88 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/qdec/nrf_drv_qdec.c @@ -0,0 +1,234 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(QDEC) +#include +#include + +#include "nrf.h" +#include "nrf_gpio.h" +#include "nrf_error.h" +#include "nrf_assert.h" +#include "nrf_drv_common.h" +#include "nrf_drv_qdec.h" +#include "app_util_platform.h" +#include "nrf_assert.h" + +#define NRF_LOG_MODULE_NAME "QDEC" + +#if QDEC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL QDEC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR QDEC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR QDEC_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_QDEC_EVENT_SAMPLERDY ? "NRF_QDEC_EVENT_SAMPLERDY" : \ + (event == NRF_QDEC_EVENT_REPORTRDY ? "NRF_QDEC_EVENT_REPORTRDY" : \ + (event == NRF_QDEC_EVENT_ACCOF ? "NRF_QDEC_EVENT_ACCOF" : "UNKNOWN EVENT"))) +#else //QDEC_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //QDEC_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +static qdec_event_handler_t m_qdec_event_handler = NULL; +static const nrf_drv_qdec_config_t m_default_config = NRF_DRV_QDEC_DEFAULT_CONFIG; +static nrf_drv_state_t m_state = NRF_DRV_STATE_UNINITIALIZED; + +void QDEC_IRQHandler(void) +{ + nrf_drv_qdec_event_t event; + if ( nrf_qdec_event_check(NRF_QDEC_EVENT_SAMPLERDY) && + nrf_qdec_int_enable_check(NRF_QDEC_INT_SAMPLERDY_MASK) ) + { + nrf_qdec_event_clear(NRF_QDEC_EVENT_SAMPLERDY); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_QDEC_EVENT_SAMPLERDY)); + + event.type = NRF_QDEC_EVENT_SAMPLERDY; + event.data.sample.value = (int8_t)nrf_qdec_sample_get(); + m_qdec_event_handler(event); + } + + if ( nrf_qdec_event_check(NRF_QDEC_EVENT_REPORTRDY) && + nrf_qdec_int_enable_check(NRF_QDEC_INT_REPORTRDY_MASK) ) + { + nrf_qdec_event_clear(NRF_QDEC_EVENT_REPORTRDY); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_QDEC_INT_REPORTRDY_MASK)); + + event.type = NRF_QDEC_EVENT_REPORTRDY; + + event.data.report.acc = (int16_t)nrf_qdec_accread_get(); + event.data.report.accdbl = (uint16_t)nrf_qdec_accdblread_get(); + m_qdec_event_handler(event); + } + + if ( nrf_qdec_event_check(NRF_QDEC_EVENT_ACCOF) && + nrf_qdec_int_enable_check(NRF_QDEC_INT_ACCOF_MASK) ) + { + nrf_qdec_event_clear(NRF_QDEC_EVENT_ACCOF); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_QDEC_EVENT_ACCOF)); + + event.type = NRF_QDEC_EVENT_ACCOF; + m_qdec_event_handler(event); + } +} + + +ret_code_t nrf_drv_qdec_init(const nrf_drv_qdec_config_t * p_config, + qdec_event_handler_t event_handler) +{ + ret_code_t err_code; + + if (m_state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + if (p_config == NULL) + { + p_config = &m_default_config; + } + + if (event_handler) + { + m_qdec_event_handler = event_handler; + } + else + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + nrf_qdec_sampleper_set(p_config->sampleper); + nrf_gpio_cfg_input(p_config->pselled, NRF_GPIO_PIN_NOPULL); + nrf_gpio_cfg_input(p_config->psela, NRF_GPIO_PIN_NOPULL); + nrf_gpio_cfg_input(p_config->pselb, NRF_GPIO_PIN_NOPULL); + nrf_qdec_pio_assign( p_config->psela, p_config->pselb, p_config->pselled); + nrf_qdec_ledpre_set(p_config->ledpre); + nrf_qdec_ledpol_set(p_config->ledpol); + nrf_qdec_shorts_enable(NRF_QDEC_SHORT_REPORTRDY_READCLRACC_MASK); + + if (p_config->dbfen) + { + nrf_qdec_dbfen_enable(); + } + else + { + nrf_qdec_dbfen_disable(); + } + + uint32_t int_mask = NRF_QDEC_INT_ACCOF_MASK; + + if (p_config->reportper != NRF_QDEC_REPORTPER_DISABLED) + { + nrf_qdec_reportper_set(p_config->reportper); + int_mask |= NRF_QDEC_INT_REPORTRDY_MASK; + } + + if (p_config->sample_inten) + { + int_mask |= NRF_QDEC_INT_SAMPLERDY_MASK; + } + + nrf_qdec_int_enable(int_mask); + nrf_drv_common_irq_enable(QDEC_IRQn, p_config->interrupt_priority); + + m_state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +void nrf_drv_qdec_uninit(void) +{ + ASSERT(m_state != NRF_DRV_STATE_UNINITIALIZED); + nrf_drv_qdec_disable(); + nrf_drv_common_irq_disable(QDEC_IRQn); + m_state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Uninitialized.\r\n"); +} + +void nrf_drv_qdec_enable(void) +{ + ASSERT(m_state == NRF_DRV_STATE_INITIALIZED); + nrf_qdec_enable(); + nrf_qdec_task_trigger(NRF_QDEC_TASK_START); + m_state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Enabled.\r\n"); +} + +void nrf_drv_qdec_disable(void) +{ + ASSERT(m_state == NRF_DRV_STATE_POWERED_ON); + nrf_qdec_task_trigger(NRF_QDEC_TASK_STOP); + nrf_qdec_disable(); + m_state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Disabled.\r\n"); +} + +void nrf_drv_qdec_accumulators_read(int16_t * p_acc, int16_t * p_accdbl) +{ + ASSERT(m_state == NRF_DRV_STATE_POWERED_ON); + nrf_qdec_task_trigger(NRF_QDEC_TASK_READCLRACC); + + *p_acc = (int16_t)nrf_qdec_accread_get(); + *p_accdbl = (int16_t)nrf_qdec_accdblread_get(); + + NRF_LOG_DEBUG("Accumulators data, ACC register:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_acc, sizeof(p_acc)); + NRF_LOG_DEBUG("Accumulators data, ACCDBL register:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_accdbl, sizeof(p_accdbl)); +} + +void nrf_drv_qdec_task_address_get(nrf_qdec_task_t task, uint32_t * p_task) +{ + *p_task = (uint32_t)nrf_qdec_task_address_get(task); +} + +void nrf_drv_qdec_event_address_get(nrf_qdec_event_t event, uint32_t * p_event) +{ + *p_event = (uint32_t)nrf_qdec_event_address_get(event); +} + +#endif //NRF_MODULE_ENABLED(QDEC) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/qdec/nrf_drv_qdec.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/qdec/nrf_drv_qdec.h new file mode 100644 index 0000000000000000000000000000000000000000..8327d287b173166063e18d32b20db95852e61231 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/qdec/nrf_drv_qdec.h @@ -0,0 +1,185 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_DRV_QDEC_H__ +#define NRF_DRV_QDEC_H__ + +#include "nrf_qdec.h" +#include "sdk_config.h" +#include "sdk_errors.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup nrf_qdec QDEC HAL and driver + * @ingroup nrf_drivers + * @brief Quadrature decoder (QDEC) APIs. + * @details The QDEC HAL provides basic APIs for accessing the registers of the QDEC. + * The QDEC driver provides APIs on a higher level. + * + * @defgroup nrf_drv_qdec QDEC driver + * @{ + * @ingroup nrf_qdec + * @brief Quadrature decoder (QDEC) driver. + */ + +/**@brief QDEC configuration structure.*/ +typedef struct +{ + nrf_qdec_reportper_t reportper; /**< Report period in samples. */ + nrf_qdec_sampleper_t sampleper; /**< Sampling period in microseconds. */ + uint32_t psela; /**< Pin number for A input. */ + uint32_t pselb; /**< Pin number for B input. */ + uint32_t pselled; /**< Pin number for LED output. */ + uint32_t ledpre; /**< Time (in microseconds) how long LED is switched on before sampling. */ + nrf_qdec_ledpol_t ledpol; /**< Active LED polarity. */ + bool dbfen; /**< State of debouncing filter. */ + bool sample_inten; /**< Enabling sample ready interrupt. */ + uint8_t interrupt_priority; /**< QDEC interrupt priority. */ +} nrf_drv_qdec_config_t; + +/**@brief QDEC default configuration. */ +#define NRF_DRV_QDEC_DEFAULT_CONFIG \ + { \ + .reportper = (nrf_qdec_reportper_t)QDEC_CONFIG_REPORTPER, \ + .sampleper = (nrf_qdec_sampleper_t)QDEC_CONFIG_SAMPLEPER, \ + .psela = QDEC_CONFIG_PIO_A, \ + .pselb = QDEC_CONFIG_PIO_B, \ + .pselled = QDEC_CONFIG_PIO_LED, \ + .ledpre = QDEC_CONFIG_LEDPRE, \ + .ledpol = (nrf_qdec_ledpol_t)QDEC_CONFIG_LEDPOL, \ + .interrupt_priority = QDEC_CONFIG_IRQ_PRIORITY, \ + .dbfen = QDEC_CONFIG_DBFEN, \ + .sample_inten = QDEC_CONFIG_SAMPLE_INTEN \ + } + +/**@brief QDEC sample event data.*/ +typedef struct +{ + int8_t value; /**< Sample value. */ +} nrf_drv_qdec_sample_data_evt_t; + +/**@brief QDEC report event data.*/ +typedef struct +{ + int16_t acc; /**< Accumulated transitions. */ + uint16_t accdbl; /**< Accumulated double transitions. */ +} nrf_drv_qdec_report_data_evt_t; + +/**@brief QDEC event handler structure. */ +typedef struct +{ + nrf_qdec_event_t type; + union + { + nrf_drv_qdec_sample_data_evt_t sample; /**< Sample event data. */ + nrf_drv_qdec_report_data_evt_t report; /**< Report event data. */ + } data; +} nrf_drv_qdec_event_t; + +/**@brief QDEC event handler. + * @param[in] event QDEC event structure. + */ +typedef void (*qdec_event_handler_t)(nrf_drv_qdec_event_t event); + +/**@brief Function for initializing QDEC. + * + * @param[in] p_config Pointer to configuration parameters. + * @param[in] event_handler Event handler function. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were supplied. + * @retval NRF_ERROR_INVALID_STATE If QDEC was already initialized. + */ +ret_code_t nrf_drv_qdec_init(nrf_drv_qdec_config_t const * p_config, + qdec_event_handler_t event_handler); + +/**@brief Function for uninitializing QDEC. + * @note Function asserts if module is uninitialized. + */ +void nrf_drv_qdec_uninit(void); + +/**@brief Function for enabling QDEC. + * @note Function asserts if module is uninitialized or enabled. + */ +void nrf_drv_qdec_enable(void); + +/**@brief Function for disabling QDEC. + * @note Function asserts if module is uninitialized or disabled. + */ +void nrf_drv_qdec_disable(void); + +/**@brief Function for reading accumulated transitions QDEC. + * @note Function asserts if module is not enabled. + * @note Accumulators are cleared after reading. + * + * @param[out] p_acc Pointer to store accumulated transitions. + * @param[out] p_accdbl Pointer to store accumulated double transitions. + */ +void nrf_drv_qdec_accumulators_read(int16_t * p_acc, int16_t * p_accdbl); + +/** + * @brief Function for returning the address of a specific timer task. + * + * @param[in] task QDEC task. + * @param[out] p_task Task address. + */ +void nrf_drv_qdec_task_address_get(nrf_qdec_task_t task, uint32_t * p_task); + +/** + * @brief Function for returning the address of a specific timer event. + * + * @param[in] event QDEC event. + * @param[out] p_event Event address. + */ +void nrf_drv_qdec_event_address_get(nrf_qdec_event_t event, uint32_t * p_event); + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_DRV_QDEC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/qspi/nrf_drv_qspi.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/qspi/nrf_drv_qspi.c new file mode 100644 index 0000000000000000000000000000000000000000..54cbb24de5b36920657c44cd0268767adc18cf3d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/qspi/nrf_drv_qspi.c @@ -0,0 +1,300 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" + +#if QSPI_ENABLED + +#include "nrf_drv_qspi.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" +#include "nrf_assert.h" + +/** + * @brief Command byte used to read status register. + * + */ +#define QSPI_STD_CMD_RDSR 0x05 + +/** + * @brief Byte used to mask status register and retrieve the write-in-progess bit. + * + */ +#define QSPI_MEM_STATUSREG_WIP_Pos 0x01 + +#define QSPI_WAIT_READY() do { \ + while (!nrf_qspi_event_check(NRF_QSPI, NRF_QSPI_EVENT_READY)); \ + } while(0) + +/** + * @brief Control block - driver instance local data. + * + */ +typedef struct +{ + nrf_drv_qspi_handler_t handler; /**< Handler. */ + nrf_drv_state_t state; /**< Driver state. */ + volatile bool interrupt_driven; /**< Information if the current operation is performed and is interrupt-driven. */ + void * p_context; /**< Driver context used in interrupt. */ +} qspi_control_block_t; + +static qspi_control_block_t m_cb; + +static ret_code_t qspi_task_perform(nrf_qspi_task_t task) +{ + // Wait for peripheral + if (m_cb.interrupt_driven) + { + return NRF_ERROR_BUSY; + } + + nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY); + + if (m_cb.handler) + { + m_cb.interrupt_driven = true; + nrf_qspi_int_enable(NRF_QSPI, NRF_QSPI_INT_READY_MASK); + } + + nrf_qspi_task_trigger(NRF_QSPI, task); + + if (m_cb.handler == NULL) + { + QSPI_WAIT_READY(); + } + return NRF_SUCCESS; +} + +static bool qspi_pins_configure(nrf_qspi_pins_t const * p_config) +{ + // Check if the user set meaningful values to struct fields. If not, return false. + if ((p_config->sck_pin == NRF_QSPI_PIN_NOT_CONNECTED) || + (p_config->csn_pin == NRF_QSPI_PIN_NOT_CONNECTED) || + (p_config->io0_pin == NRF_QSPI_PIN_NOT_CONNECTED) || + (p_config->io1_pin == NRF_QSPI_PIN_NOT_CONNECTED)) + { + return false; + } + + nrf_qspi_pins_set(NRF_QSPI, p_config); + + return true; +} + +ret_code_t nrf_drv_qspi_init(nrf_drv_qspi_config_t const * p_config, + nrf_drv_qspi_handler_t handler, + void * p_context) +{ + if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + + if (!qspi_pins_configure(&p_config->pins)) + { + return NRF_ERROR_INVALID_PARAM; + } + + nrf_qspi_ifconfig0_set(NRF_QSPI, &p_config->prot_if); + nrf_qspi_ifconfig1_set(NRF_QSPI, &p_config->phy_if); + + m_cb.interrupt_driven = false; + m_cb.handler = handler; + m_cb.p_context = p_context; + + /* QSPI interrupt is disabled because the device should be enabled in polling mode (wait for activate + task event ready)*/ + nrf_qspi_int_disable(NRF_QSPI, NRF_QSPI_INT_READY_MASK); + + if (handler) + { + nrf_drv_common_irq_enable(QSPI_IRQn, p_config->irq_priority); + } + + m_cb.state = NRF_DRV_STATE_INITIALIZED; + + nrf_qspi_enable(NRF_QSPI); + + nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY); + nrf_qspi_task_trigger(NRF_QSPI, NRF_QSPI_TASK_ACTIVATE); + + // Waiting for the peripheral to activate + QSPI_WAIT_READY(); + + return NRF_SUCCESS; +} + +ret_code_t nrf_drv_qspi_cinstr_xfer(nrf_qspi_cinstr_conf_t const * p_config, + void const * p_tx_buffer, + void * p_rx_buffer) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + if (m_cb.interrupt_driven) + { + return NRF_ERROR_BUSY; + } + + nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY); + /* In some cases, only opcode should be sent. To prevent execution, set function code is + * surrounded by an if. + */ + if (p_tx_buffer) + { + nrf_qspi_cinstrdata_set(NRF_QSPI, p_config->length, p_tx_buffer); + } + nrf_qspi_int_disable(NRF_QSPI, NRF_QSPI_INT_READY_MASK); + + nrf_qspi_cinstr_transfer_start(NRF_QSPI, p_config); + + QSPI_WAIT_READY(); + nrf_qspi_int_enable(NRF_QSPI, NRF_QSPI_INT_READY_MASK); + + if (p_rx_buffer) + { + nrf_qspi_cinstrdata_get(NRF_QSPI, p_config->length, p_rx_buffer); + } + + return NRF_SUCCESS; +} + +ret_code_t nrf_drv_qspi_cinstr_quick_send(uint8_t opcode, + nrf_qspi_cinstr_len_t length, + void const * p_tx_buffer) +{ + nrf_qspi_cinstr_conf_t config = NRF_DRV_QSPI_DEFAULT_CINSTR(opcode, length); + return nrf_drv_qspi_cinstr_xfer(&config, p_tx_buffer, NULL); +} + +ret_code_t nrf_drv_qspi_mem_busy_check(void) +{ + ret_code_t ret_code; + uint8_t status_value = 0; + + nrf_qspi_cinstr_conf_t config = NRF_DRV_QSPI_DEFAULT_CINSTR(QSPI_STD_CMD_RDSR, + NRF_QSPI_CINSTR_LEN_2B); + + ret_code = nrf_drv_qspi_cinstr_xfer(&config, &status_value, &status_value); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + if ((status_value & QSPI_MEM_STATUSREG_WIP_Pos) != 0x00) + { + return NRF_ERROR_BUSY; + } + + return NRF_SUCCESS; +} + +void nrf_drv_qspi_uninit(void) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_qspi_int_disable(NRF_QSPI, NRF_QSPI_INT_READY_MASK); + + nrf_qspi_disable(NRF_QSPI); + + nrf_drv_common_irq_disable(QSPI_IRQn); + + nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY); + + m_cb.state = NRF_DRV_STATE_UNINITIALIZED; +} + +ret_code_t nrf_drv_qspi_write(void const * p_tx_buffer, + size_t tx_buffer_length, + uint32_t dst_address) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_tx_buffer != NULL); + + if (!nrf_drv_is_in_RAM(p_tx_buffer)) + { + return NRF_ERROR_INVALID_ADDR; + } + + nrf_qspi_write_buffer_set(NRF_QSPI, p_tx_buffer, tx_buffer_length, dst_address); + return qspi_task_perform(NRF_QSPI_TASK_WRITESTART); + +} + +ret_code_t nrf_drv_qspi_read(void * p_rx_buffer, + size_t rx_buffer_length, + uint32_t src_address) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_rx_buffer != NULL); + + if (!nrf_drv_is_in_RAM(p_rx_buffer)) + { + return NRF_ERROR_INVALID_ADDR; + } + + nrf_qspi_read_buffer_set(NRF_QSPI, p_rx_buffer, rx_buffer_length, src_address); + return qspi_task_perform(NRF_QSPI_TASK_READSTART); +} + +ret_code_t nrf_drv_qspi_erase(nrf_qspi_erase_len_t length, + uint32_t start_address) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + nrf_qspi_erase_ptr_set(NRF_QSPI, start_address, length); + return qspi_task_perform(NRF_QSPI_TASK_ERASESTART); +} + +ret_code_t nrf_drv_qspi_chip_erase(void) +{ + return nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_ALL, 0); +} + +void QSPI_IRQHandler(void) +{ + // Catch Event ready interrupts + if (nrf_qspi_event_check(NRF_QSPI, NRF_QSPI_EVENT_READY)) + { + m_cb.interrupt_driven = false; + nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY); + m_cb.handler(NRF_DRV_QSPI_EVENT_DONE, m_cb.p_context); + } +} + +#endif // QSPI_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/qspi/nrf_drv_qspi.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/qspi/nrf_drv_qspi.h new file mode 100644 index 0000000000000000000000000000000000000000..35ce036bcd5632adac094e68ae9d7aed908e827f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/qspi/nrf_drv_qspi.h @@ -0,0 +1,311 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * @addtogroup nrf_qspi QSPI HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52840 Quad serial peripheral interface (QSPI) APIs. + * + * @defgroup nrf_drv_qspi QSPI driver + * @{ + * @ingroup nrf_qspi + * @brief @tagAPI52840 Quad serial peripheral interface (QSPI) driver. + */ + +#ifndef NRF_DRV_QSPI_H__ +#define NRF_DRV_QSPI_H__ + +#include "nordic_common.h" +#include "sdk_config.h" +#include "nrf_qspi.h" +#include "sdk_errors.h" +#include "boards.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief QSPI driver instance configuration structure. + */ +typedef struct +{ + nrf_qspi_pins_t pins; /**< Pins configuration structure. */ + nrf_qspi_prot_conf_t prot_if; /**< Protocol layer interface configuration structure. */ + nrf_qspi_phy_conf_t phy_if; /**< Physical layer interface configuration structure. */ + uint8_t irq_priority; /**< Interrupt priority. */ +} nrf_drv_qspi_config_t; + +#if QSPI_PIN_SCK == NRF_QSPI_PIN_NOT_CONNECTED + #undef QSPI_PIN_SCK + #define QSPI_PIN_SCK BSP_QSPI_SCK_PIN +#endif +#if QSPI_PIN_CSN == NRF_QSPI_PIN_NOT_CONNECTED + #undef QSPI_PIN_CSN + #define QSPI_PIN_CSN BSP_QSPI_CSN_PIN +#endif +#if QSPI_PIN_IO0 == NRF_QSPI_PIN_NOT_CONNECTED + #undef QSPI_PIN_IO0 + #define QSPI_PIN_IO0 BSP_QSPI_IO0_PIN +#endif +#if QSPI_PIN_IO1 == NRF_QSPI_PIN_NOT_CONNECTED + #undef QSPI_PIN_IO1 + #define QSPI_PIN_IO1 BSP_QSPI_IO1_PIN +#endif +#if QSPI_PIN_IO2 == NRF_QSPI_PIN_NOT_CONNECTED + #undef QSPI_PIN_IO2 + #define QSPI_PIN_IO2 BSP_QSPI_IO2_PIN +#endif +#if QSPI_PIN_IO3 == NRF_QSPI_PIN_NOT_CONNECTED + #undef QSPI_PIN_IO3 + #define QSPI_PIN_IO3 BSP_QSPI_IO3_PIN +#endif +/** + * @brief QSPI instance default configuration. + */ +#define NRF_DRV_QSPI_DEFAULT_CONFIG \ +{ \ + .pins = { \ + .sck_pin = QSPI_PIN_SCK, \ + .csn_pin = QSPI_PIN_CSN, \ + .io0_pin = QSPI_PIN_IO0, \ + .io1_pin = QSPI_PIN_IO1, \ + .io2_pin = QSPI_PIN_IO2, \ + .io3_pin = QSPI_PIN_IO3, \ + }, \ + .irq_priority = (uint8_t)QSPI_CONFIG_IRQ_PRIORITY, \ + .prot_if = { \ + .readoc = (nrf_qspi_readoc_t) QSPI_CONFIG_READOC, \ + .writeoc = (nrf_qspi_writeoc_t) QSPI_CONFIG_WRITEOC, \ + .addrmode = (nrf_qspi_addrmode_t) QSPI_CONFIG_ADDRMODE, \ + .dpmconfig = false, \ + }, \ + .phy_if = { \ + .sck_freq = (nrf_qspi_frequency_t) QSPI_CONFIG_FREQUENCY, \ + .sck_delay = (uint8_t) QSPI_CONFIG_SCK_DELAY, \ + .spi_mode = (nrf_qspi_spi_mode_t) QSPI_CONFIG_MODE, \ + .dpmen = false \ + } \ +} + + +/** + * @brief QSPI custom instruction helper with default configuration. + */ +#define NRF_DRV_QSPI_DEFAULT_CINSTR(opc, len) \ +{ \ + .opcode = (opc), \ + .length = (len), \ + .io2_level = false, \ + .io3_level = false, \ + .wipwait = false, \ + .wren = false \ +} + +/** + * @brief QSPI master driver event types, passed to the handler routine provided + * during initialization. + */ +typedef enum +{ + NRF_DRV_QSPI_EVENT_DONE, /**< Transfer done. */ +} nrf_drv_qspi_evt_t; + +/** + * @brief QSPI driver event handler type. + */ +typedef void (*nrf_drv_qspi_handler_t)(nrf_drv_qspi_evt_t event, void * p_context); + +/** + * @brief Function for initializing the QSPI driver instance. + * + * @param[in] p_config Pointer to the structure with the initial configuration. + * @param[in] handler Event handler provided by the user. If NULL, transfers + * will be performed in blocking mode. + * @param[in] p_context Pointer to context. Use in interrupt handler. + * + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver was already initialized. + * @retval NRF_ERROR_INVALID_PARAM If the pin configuration was incorrect. + */ +ret_code_t nrf_drv_qspi_init(nrf_drv_qspi_config_t const * p_config, + nrf_drv_qspi_handler_t handler, + void * p_context); + +/** + * @brief Function for uninitializing the QSPI driver instance. + */ +void nrf_drv_qspi_uninit(void); + +/** + * @brief Function for reading data from QSPI memory. + * + * Write, read, and erase operations check memory device busy state before starting the operation. + * If the memory is busy, the resulting action depends on the mode in which the read operation is used: + * - blocking mode (without handler) - a delay occurs until the last operation still runs and + * until operation data is still being read. + * - interrupt mode (with handler) - event emission occurs after the last operation + * and reading of data are finished. + * + * @param[out] p_rx_buffer Pointer to the receive buffer. + * @param[in] rx_buffer_length Size of the data to read. + * @param[in] src_address Address in memory to read from. + * + * @retval NRF_SUCCESS If the operation was successful (blocking mode) or operation + * was commissioned (handler mode). + * @retval NRF_ERROR_BUSY If the driver currently handles another operation. + * @retval NRF_ERROR_INVALID_ADDR If the provided buffer is not placed in the Data RAM region. + */ +ret_code_t nrf_drv_qspi_read(void * p_rx_buffer, + size_t rx_buffer_length, + uint32_t src_address); + +/** + * @brief Function for writing data to QSPI memory. + * + * Write, read, and erase operations check memory device busy state before starting the operation. + * If the memory is busy, the resulting action depends on the mode in which the write operation is used: + * - blocking mode (without handler) - a delay occurs until the last operation still runs and + * until operation data is still being sent. + * - interrupt mode (with handler) - event emission occurs after the last operation + * and sending of operation data are finished. + * To manually control operation execution in the memory device, use @ref nrf_drv_qspi_mem_busy_check + * after executing the write function. + * Remember that an incoming event signalizes only that data was sent to the memory device and the periheral + * before the write operation checked if memory was busy. + * + * @param[in] p_tx_buffer Pointer to the writing buffer. + * @param[in] tx_buffer_length Size of the data to write. + * @param[in] dst_address Address in memory to write to. + * + * @retval NRF_SUCCESS If the operation was successful (blocking mode) or operation + * was commissioned (handler mode). + * @retval NRF_ERROR_BUSY If the driver currently handles other operation. + * @retval NRF_ERROR_INVALID_ADDR If the provided buffer is not placed in the Data RAM region. + */ +ret_code_t nrf_drv_qspi_write(void const * p_tx_buffer, + size_t tx_buffer_length, + uint32_t dst_address); + +/** + * @brief Function for starting erasing of one memory block - 4KB, 64KB, or the whole chip. + * + * Write, read, and erase operations check memory device busy state before starting the operation. + * If the memory is busy, the resulting action depends on the mode in which the erase operation is used: + * - blocking mode (without handler) - a delay occurs until the last operation still runs and + * until operation data is still being sent. + * - interrupt mode (with handler) - event emission occurs after the last operation + * and sending of operation data are finished. + * To manually control operation execution in the memory device, use @ref nrf_drv_qspi_mem_busy_check + * after executing the erase function. + * Remember that an incoming event signalizes only that data was sent to the memory device and the periheral + * before the erase operation checked if memory was busy. + * + * @param[in] length Size of data to erase. See @ref nrf_qspi_erase_len_t. + * @param[in] start_address Memory address to start erasing. If chip erase is performed, address + * field is ommited. + * + * @retval NRF_SUCCESS If the operation was successful (blocking mode) or operation + * was commissioned (handler mode). + * @retval NRF_ERROR_BUSY If the driver currently handles another operation. + */ +ret_code_t nrf_drv_qspi_erase(nrf_qspi_erase_len_t length, + uint32_t start_address); + +/** + * @brief Function for starting an erase operation of the whole chip. + * + * @retval NRF_SUCCESS If the operation was successful (blocking mode) or operation + * was commissioned (handler mode). + * @retval NRF_ERROR_BUSY If the driver currently handles another operation. + */ +ret_code_t nrf_drv_qspi_chip_erase(void); + +/** + * @brief Function for getting the current driver status and status byte of memory device with + * testing WIP (write in progress) bit. + * + * @retval NRF_SUCCESS If the driver and memory are ready to handle a new operation. + * @retval NRF_ERROR_BUSY If the driver or memory currently handle another operation. + */ +ret_code_t nrf_drv_qspi_mem_busy_check(void); + +/** + * @brief Function for sending operation code, sending data, and receiving data from the memory device. + * + * Use this function to transfer configuration data to memory and to receive data from memory. + * Pointers can be addresses from flash memory. + * This function is a synchronous function and should be used only if necessary. + * See more: @ref hardware_driver_qspi. + * + * @param[in] p_config Pointer to the structure with opcode and transfer configuration. + * @param[in] p_tx_buffer Pointer to the array with data to send. Can be NULL if only opcode is transmitted. + * @param[out] p_rx_buffer Pointer to the array for data to receive. Can be NULL if there is nothing to receive. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_BUSY If the driver currently handles other operation. + */ +ret_code_t nrf_drv_qspi_cinstr_xfer(nrf_qspi_cinstr_conf_t const * p_config, + void const * p_tx_buffer, + void * p_rx_buffer); +/** + * @brief Function for sending operation code and data to the memory device with simpler configuration. + * + * Use this function to transfer configuration data to memory and to receive data from memory. + * This function is a synchronous function and should be used only if necessary. + * + * @param[in] opcode Operation code. Sending first. + * @param[in] length Length of the data to send and opcode. See @ref nrf_qspi_cinstr_len_t. + * @param[in] p_tx_buffer Pointer to input data array. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_BUSY If the driver currently handles another operation. + */ +ret_code_t nrf_drv_qspi_cinstr_quick_send(uint8_t opcode, + nrf_qspi_cinstr_len_t length, + void const * p_tx_buffer); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_QSPI_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/radio_config/radio_config.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/radio_config/radio_config.c new file mode 100644 index 0000000000000000000000000000000000000000..5f529a7db7ed1bbc8c6d596aa04ab04f84c8e16b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/radio_config/radio_config.c @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file +* @addtogroup nrf_dev_radio_rx_example_main nrf_dev_radio_tx_example_main +* @{ +*/ + +#include "radio_config.h" +#include "nrf_delay.h" + +/* These are set to zero as ShockBurst packets don't have corresponding fields. */ +#define PACKET_S1_FIELD_SIZE (0UL) /**< Packet S1 field size in bits. */ +#define PACKET_S0_FIELD_SIZE (0UL) /**< Packet S0 field size in bits. */ +#define PACKET_LENGTH_FIELD_SIZE (0UL) /**< Packet length field size in bits. */ + +/** + * @brief Function for swapping/mirroring bits in a byte. + * + *@verbatim + * output_bit_7 = input_bit_0 + * output_bit_6 = input_bit_1 + * : + * output_bit_0 = input_bit_7 + *@endverbatim + * + * @param[in] inp is the input byte to be swapped. + * + * @return + * Returns the swapped/mirrored input byte. + */ +static uint32_t swap_bits(uint32_t inp); + +/** + * @brief Function for swapping bits in a 32 bit word for each byte individually. + * + * The bits are swapped as follows: + * @verbatim + * output[31:24] = input[24:31] + * output[23:16] = input[16:23] + * output[15:8] = input[8:15] + * output[7:0] = input[0:7] + * @endverbatim + * @param[in] input is the input word to be swapped. + * + * @return + * Returns the swapped input byte. + */ +static uint32_t bytewise_bitswap(uint32_t inp); + +static uint32_t swap_bits(uint32_t inp) +{ + uint32_t i; + uint32_t retval = 0; + + inp = (inp & 0x000000FFUL); + + for (i = 0; i < 8; i++) + { + retval |= ((inp >> i) & 0x01) << (7 - i); + } + + return retval; +} + + +static uint32_t bytewise_bitswap(uint32_t inp) +{ + return (swap_bits(inp >> 24) << 24) + | (swap_bits(inp >> 16) << 16) + | (swap_bits(inp >> 8) << 8) + | (swap_bits(inp)); +} + + +/** + * @brief Function for configuring the radio to operate in ShockBurst compatible mode. + * + * To configure the application running on nRF24L series devices: + * + * @verbatim + * uint8_t tx_address[5] = { 0xC0, 0x01, 0x23, 0x45, 0x67 }; + * hal_nrf_set_rf_channel(7); + * hal_nrf_set_address_width(HAL_NRF_AW_5BYTES); + * hal_nrf_set_address(HAL_NRF_TX, tx_address); + * hal_nrf_set_address(HAL_NRF_PIPE0, tx_address); + * hal_nrf_open_pipe(0, false); + * hal_nrf_set_datarate(HAL_NRF_1MBPS); + * hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT); + * hal_nrf_setup_dynamic_payload(0xFF); + * hal_nrf_enable_dynamic_payload(false); + * @endverbatim + * + * When transmitting packets with hal_nrf_write_tx_payload(const uint8_t *tx_pload, uint8_t length), + * match the length with PACKET_STATIC_LENGTH. + * hal_nrf_write_tx_payload(payload, PACKET_STATIC_LENGTH); + * +*/ +void radio_configure() +{ + // Radio config + NRF_RADIO->TXPOWER = (RADIO_TXPOWER_TXPOWER_0dBm << RADIO_TXPOWER_TXPOWER_Pos); + NRF_RADIO->FREQUENCY = 7UL; // Frequency bin 7, 2407MHz + NRF_RADIO->MODE = (RADIO_MODE_MODE_Nrf_1Mbit << RADIO_MODE_MODE_Pos); + + // Radio address config + NRF_RADIO->PREFIX0 = + ((uint32_t)swap_bits(0xC3) << 24) // Prefix byte of address 3 converted to nRF24L series format + | ((uint32_t)swap_bits(0xC2) << 16) // Prefix byte of address 2 converted to nRF24L series format + | ((uint32_t)swap_bits(0xC1) << 8) // Prefix byte of address 1 converted to nRF24L series format + | ((uint32_t)swap_bits(0xC0) << 0); // Prefix byte of address 0 converted to nRF24L series format + + NRF_RADIO->PREFIX1 = + ((uint32_t)swap_bits(0xC7) << 24) // Prefix byte of address 7 converted to nRF24L series format + | ((uint32_t)swap_bits(0xC6) << 16) // Prefix byte of address 6 converted to nRF24L series format + | ((uint32_t)swap_bits(0xC4) << 0); // Prefix byte of address 4 converted to nRF24L series format + + NRF_RADIO->BASE0 = bytewise_bitswap(0x01234567UL); // Base address for prefix 0 converted to nRF24L series format + NRF_RADIO->BASE1 = bytewise_bitswap(0x89ABCDEFUL); // Base address for prefix 1-7 converted to nRF24L series format + + NRF_RADIO->TXADDRESS = 0x00UL; // Set device address 0 to use when transmitting + NRF_RADIO->RXADDRESSES = 0x01UL; // Enable device address 0 to use to select which addresses to receive + + // Packet configuration + NRF_RADIO->PCNF0 = (PACKET_S1_FIELD_SIZE << RADIO_PCNF0_S1LEN_Pos) | + (PACKET_S0_FIELD_SIZE << RADIO_PCNF0_S0LEN_Pos) | + (PACKET_LENGTH_FIELD_SIZE << RADIO_PCNF0_LFLEN_Pos); //lint !e845 "The right argument to operator '|' is certain to be 0" + + // Packet configuration + NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | + (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | + (PACKET_BASE_ADDRESS_LENGTH << RADIO_PCNF1_BALEN_Pos) | + (PACKET_STATIC_LENGTH << RADIO_PCNF1_STATLEN_Pos) | + (PACKET_PAYLOAD_MAXSIZE << RADIO_PCNF1_MAXLEN_Pos); //lint !e845 "The right argument to operator '|' is certain to be 0" + + // CRC Config + NRF_RADIO->CRCCNF = (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos); // Number of checksum bits + if ((NRF_RADIO->CRCCNF & RADIO_CRCCNF_LEN_Msk) == (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos)) + { + NRF_RADIO->CRCINIT = 0xFFFFUL; // Initial value + NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16 + x^12^x^5 + 1 + } + else if ((NRF_RADIO->CRCCNF & RADIO_CRCCNF_LEN_Msk) == (RADIO_CRCCNF_LEN_One << RADIO_CRCCNF_LEN_Pos)) + { + NRF_RADIO->CRCINIT = 0xFFUL; // Initial value + NRF_RADIO->CRCPOLY = 0x107UL; // CRC poly: x^8 + x^2^x^1 + 1 + } +} + +/** + * @} + */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/radio_config/radio_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/radio_config/radio_config.h new file mode 100644 index 0000000000000000000000000000000000000000..2b4cacd106f0cc5e7818bee6ab86c0c5b197d2a5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/radio_config/radio_config.h @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef RADIO_CONFIG_H +#define RADIO_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define PACKET_BASE_ADDRESS_LENGTH (4UL) //!< Packet base address length field size in bytes +#define PACKET_STATIC_LENGTH (1UL) //!< Packet static length in bytes +#define PACKET_PAYLOAD_MAXSIZE (PACKET_STATIC_LENGTH) //!< Packet payload maximum size in bytes + +void radio_configure(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/rng/nrf_drv_rng.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/rng/nrf_drv_rng.c new file mode 100644 index 0000000000000000000000000000000000000000..db95e23dffd1df61e6ccc1d896067e0fabeae43a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/rng/nrf_drv_rng.c @@ -0,0 +1,298 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(RNG) + +#include +#include +#include "nrf_drv_rng.h" +#include "nrf_drv_common.h" +#include "nordic_common.h" +#include "nrf_assert.h" +#include "nrf_queue.h" + +#ifdef SOFTDEVICE_PRESENT + #include "softdevice_handler.h" + #include "nrf_soc.h" + #include "app_util_platform.h" +#endif // SOFTDEVICE_PRESENT + +#define NRF_LOG_MODULE_NAME "RNG" + +#if RNG_CONFIG_LOG_ENABLED + #define NRF_LOG_LEVEL RNG_CONFIG_LOG_LEVEL + #define NRF_LOG_INFO_COLOR RNG_CONFIG_INFO_COLOR + #define NRF_LOG_DEBUG_COLOR RNG_CONFIG_DEBUG_COLOR +#else //RNG_CONFIG_LOG_ENABLED + #define NRF_LOG_LEVEL 0 +#endif //RNG_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +/* Validate configuration */ +INTERRUPT_PRIORITY_VALIDATION(RNG_CONFIG_IRQ_PRIORITY); + +typedef struct +{ + nrf_drv_state_t state; + nrf_drv_rng_config_t config; +} nrf_drv_rng_cb_t; + +static nrf_drv_rng_cb_t m_rng_cb; +NRF_QUEUE_DEF(uint8_t, m_rand_pool, RNG_CONFIG_POOL_SIZE, NRF_QUEUE_MODE_OVERFLOW); +static const nrf_drv_rng_config_t m_default_config = NRF_DRV_RNG_DEFAULT_CONFIG; + +#ifdef SOFTDEVICE_PRESENT + #define SD_RAND_POOL_SIZE (32) + STATIC_ASSERT(RNG_CONFIG_POOL_SIZE == SD_RAND_POOL_SIZE); + + #define NRF_DRV_RNG_LOCK() CRITICAL_REGION_ENTER() + #define NRF_DRV_RNG_RELEASE() CRITICAL_REGION_EXIT() + #define NRF_DRV_RNG_SD_IS_ENABLED() softdevice_handler_is_enabled() +#else + #define NRF_DRV_RNG_LOCK() do { } while (0) + #define NRF_DRV_RNG_RELEASE() do { } while (0) + #define NRF_DRV_RNG_SD_IS_ENABLED() false +#endif // SOFTDEVICE_PRESENT + +/** + * @brief Function for starting generation. + */ +static void nrf_drv_rng_start(void) +{ + ASSERT(!NRF_DRV_RNG_SD_IS_ENABLED()); + + nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); + nrf_rng_int_enable(NRF_RNG_INT_VALRDY_MASK); + nrf_rng_task_trigger(NRF_RNG_TASK_START); +} + +/** + * @brief Function for stoping generation. + */ +static void nrf_drv_rng_stop(void) +{ + ASSERT(!NRF_DRV_RNG_SD_IS_ENABLED()); + + nrf_rng_int_disable(NRF_RNG_INT_VALRDY_MASK); + nrf_rng_task_trigger(NRF_RNG_TASK_STOP); +} + +/** + * @brief Function for setting up RNG hardware. + */ +static void nrf_drv_rng_setup(void) +{ + ASSERT(!NRF_DRV_RNG_SD_IS_ENABLED()); + + if (m_rng_cb.config.error_correction) + { + nrf_rng_error_correction_enable(); + } + nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK); + nrf_drv_common_irq_enable(RNG_IRQn, m_rng_cb.config.interrupt_priority); +} + +ret_code_t nrf_drv_rng_init(nrf_drv_rng_config_t const * p_config) +{ + if (m_rng_cb.state != NRF_DRV_STATE_UNINITIALIZED) + { + return NRF_ERROR_MODULE_ALREADY_INITIALIZED; + } + + if (p_config == NULL) + { + p_config = &m_default_config; + } + m_rng_cb.config = *p_config; + + NRF_DRV_RNG_LOCK(); + + if (!NRF_DRV_RNG_SD_IS_ENABLED()) + { + nrf_drv_rng_setup(); + nrf_drv_rng_start(); + } + + NRF_DRV_RNG_RELEASE(); + + m_rng_cb.state = NRF_DRV_STATE_INITIALIZED; + + return NRF_SUCCESS; +} + +void nrf_drv_rng_uninit(void) +{ + ASSERT(m_rng_cb.state == NRF_DRV_STATE_INITIALIZED); + + NRF_DRV_RNG_LOCK(); + + if (!NRF_DRV_RNG_SD_IS_ENABLED()) + { + nrf_drv_rng_stop(); + nrf_drv_common_irq_disable(RNG_IRQn); + } + + NRF_DRV_RNG_RELEASE(); + + nrf_queue_reset(&m_rand_pool); + m_rng_cb.state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Uninitialized.\r\n"); +} + +void nrf_drv_rng_bytes_available(uint8_t * p_bytes_available) +{ + ASSERT(m_rng_cb.state == NRF_DRV_STATE_INITIALIZED); + +#ifdef SOFTDEVICE_PRESENT + if (NRF_DRV_RNG_SD_IS_ENABLED()) + { + if (NRF_SUCCESS == sd_rand_application_bytes_available_get(p_bytes_available)) + { + return; + } + } +#endif // SOFTDEVICE_PRESENT + + *p_bytes_available = nrf_queue_utilization_get(&m_rand_pool); + + NRF_LOG_INFO("Function: %s, available bytes: %d.\r\n", (uint32_t)__func__, *p_bytes_available); +} + +ret_code_t nrf_drv_rng_rand(uint8_t * p_buff, uint8_t length) +{ + ret_code_t err_code = NRF_SUCCESS; + ASSERT(m_rng_cb.state == NRF_DRV_STATE_INITIALIZED); + +#ifdef SOFTDEVICE_PRESENT + do { + bool sd_is_enabled; + NRF_DRV_RNG_LOCK(); + sd_is_enabled = NRF_DRV_RNG_SD_IS_ENABLED(); + if (!sd_is_enabled) +#endif // SOFTDEVICE_PRESENT + { + err_code = nrf_queue_read(&m_rand_pool, p_buff, (uint32_t)length); + nrf_drv_rng_start(); + } +#ifdef SOFTDEVICE_PRESENT + NRF_DRV_RNG_RELEASE(); + + if (sd_is_enabled) + { + err_code = sd_rand_application_vector_get(p_buff, length); + if (err_code == NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES) + { + err_code = NRF_ERROR_NOT_FOUND; + } + } + } while (err_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED); +#endif // SOFTDEVICE_PRESENT + ASSERT((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND)); + +#if defined(RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED) && (RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED != 0) + NRF_LOG_DEBUG("Rand buffer data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_buff, length); +#endif // RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + + return err_code; +} + +void nrf_drv_rng_block_rand(uint8_t * p_buff, uint32_t length) +{ + ASSERT(m_rng_cb.state == NRF_DRV_STATE_INITIALIZED); + + while (length) + { + uint32_t len = MIN(length, RNG_CONFIG_POOL_SIZE); + ret_code_t err_code; + + do { + err_code = nrf_drv_rng_rand(p_buff, len); + } while(err_code != NRF_SUCCESS); + + length -= len; + p_buff += len; + } + + NRF_LOG_DEBUG("Rand buffer data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_buff, length); +} + +#ifdef SOFTDEVICE_PRESENT +void nrf_drv_rng_on_sd_disable(void) +{ + NRF_DRV_RNG_LOCK(); + if (m_rng_cb.state == NRF_DRV_STATE_INITIALIZED) + { + nrf_drv_rng_setup(); + nrf_drv_rng_start(); + } + NRF_DRV_RNG_RELEASE(); +} +#endif // SOFTDEVICE_PRESENT + +void RNG_IRQHandler(void) +{ + NRF_DRV_RNG_LOCK(); + if ( + !NRF_DRV_RNG_SD_IS_ENABLED() && + nrf_rng_event_get(NRF_RNG_EVENT_VALRDY) && + nrf_rng_int_get(NRF_RNG_INT_VALRDY_MASK)) + { + nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); + + uint8_t new_value = nrf_rng_random_value_get(); + UNUSED_RETURN_VALUE(nrf_queue_push(&m_rand_pool, &new_value)); + + if (nrf_queue_is_full(&m_rand_pool)) + { + nrf_drv_rng_stop(); + } + + NRF_LOG_DEBUG("Event: NRF_RNG_EVENT_VALRDY.\r\n"); + } + NRF_DRV_RNG_RELEASE(); +} + +#endif // NRF_MODULE_ENABLED(RNG) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/rng/nrf_drv_rng.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/rng/nrf_drv_rng.h new file mode 100644 index 0000000000000000000000000000000000000000..902a05da4670aaae383ef2658ca5801d908b7f61 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/rng/nrf_drv_rng.h @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_DRV_RNG_H__ +#define NRF_DRV_RNG_H__ + +#include +#include + +#include "nrf_rng.h" +#include "sdk_errors.h" +#include "sdk_config.h" +#include "nrf_drv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup nrf_rng RNG HAL and driver + * @ingroup nrf_drivers + * @brief Random number generator (RNG) APIs. + * @details The RNG HAL provides basic APIs for accessing the registers of the random number + * generator. The RNG driver provides APIs on a higher level. + * + * @defgroup nrf_drv_rng RNG driver + * @{ + * @ingroup nrf_rng + * @brief Driver for managing the random number generator (RNG). + */ + +/**@brief Struct for RNG configuration. */ +typedef struct +{ + bool error_correction : 1; /**< Error correction flag. */ + uint8_t interrupt_priority; /**< interrupt priority */ +} nrf_drv_rng_config_t; + +/**@brief RNG default configuration. */ +#define NRF_DRV_RNG_DEFAULT_CONFIG \ + { \ + .error_correction = RNG_CONFIG_ERROR_CORRECTION, \ + .interrupt_priority = RNG_CONFIG_IRQ_PRIORITY, \ + } + +/** + * @brief Function for initializing the nrf_drv_rng module. + * + * @param[in] p_config Initial configuration. Default configuration used if NULL. + * + * @retval NRF_SUCCESS Driver was successfully initialized. + * @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED Driver was already initialized. + */ +ret_code_t nrf_drv_rng_init(nrf_drv_rng_config_t const * p_config); + +/** + * @brief Function for uninitializing the nrf_drv_rng module. + */ +void nrf_drv_rng_uninit(void); + +/** + * @brief Function for getting the number of currently available random bytes. + * + * @param[out] p_bytes_available The number of bytes currently available in the pool. + */ +void nrf_drv_rng_bytes_available(uint8_t * p_bytes_available); + +/** + * @brief Function for getting the vector of random numbers. + * + * @param[out] p_buff Pointer to uint8_t buffer for storing the bytes. + * @param[in] length Number of bytes to take from the pool and place in p_buff. + * + * @retval NRF_SUCCESS If the requested bytes were written to p_buff. + * @retval NRF_ERROR_NOT_FOUND If no bytes were written to the buffer because there were + * not enough bytes available in the pool. + */ +ret_code_t nrf_drv_rng_rand(uint8_t * p_buff, uint8_t length); + +/** + * @brief Blocking function for getting an arbitrary array of random numbers. + * + * @note This function may execute for a substantial amount of time depending on the length + * of the buffer required and on the state of the current internal pool of random numbers. + * + * @param[out] p_buff Pointer to uint8_t buffer for storing the bytes. + * @param[in] length Number of bytes place in p_buff. + */ +void nrf_drv_rng_block_rand(uint8_t * p_buff, uint32_t length); + +#ifdef SOFTDEVICE_PRESENT +/** + * @brief Function called by the SoftDevice handler when the SoftDevice has been disabled. + * + * This function is called just after the SoftDevice has been properly disabled. + * It has two purposes: + * 1. Reinitializes RNG hardware. + * 2. Trigger new random numbers generation. + */ +void nrf_drv_rng_on_sd_disable(void); + +#endif +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_RNG_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/rtc/nrf_drv_rtc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/rtc/nrf_drv_rtc.c new file mode 100644 index 0000000000000000000000000000000000000000..bac31ac909876b66988f8577501e87818c34cc5c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/rtc/nrf_drv_rtc.c @@ -0,0 +1,356 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(RTC) +#define ENABLED_RTC_COUNT (RTC0_ENABLED+RTC1_ENABLED+RTC2_ENABLED) +#if ENABLED_RTC_COUNT + +#include "nrf_drv_rtc.h" +#include "nrf_rtc.h" +#include "nrf_assert.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "RTC" + +#if RTC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL RTC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR RTC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR RTC_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_RTC_EVENT_TICK ? "NRF_RTC_EVENT_TICK" : \ + (event == NRF_RTC_EVENT_OVERFLOW ? "NRF_RTC_EVENT_OVERFLOW" : \ + (event == NRF_RTC_EVENT_COMPARE_0 ? "NRF_RTC_EVENT_COMPARE_0" : \ + (event == NRF_RTC_EVENT_COMPARE_1 ? "NRF_RTC_EVENT_COMPARE_1" : \ + (event == NRF_RTC_EVENT_COMPARE_2 ? "NRF_RTC_EVENT_COMPARE_2" : \ + (event == NRF_RTC_EVENT_COMPARE_3 ? "NRF_RTC_EVENT_COMPARE_3" : "UNKNOWN EVENT") +#else //RTC_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //RTC_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +/**@brief RTC driver instance control block structure. */ +typedef struct +{ + nrf_drv_state_t state; /**< Instance state. */ + bool reliable; /**< Reliable mode flag. */ + uint8_t tick_latency; /**< Maximum length of interrupt handler in ticks (max 7.7 ms). */ +} nrf_drv_rtc_cb_t; + +// User callbacks local storage. +static nrf_drv_rtc_handler_t m_handlers[ENABLED_RTC_COUNT]; +static nrf_drv_rtc_cb_t m_cb[ENABLED_RTC_COUNT]; + +ret_code_t nrf_drv_rtc_init(nrf_drv_rtc_t const * const p_instance, + nrf_drv_rtc_config_t const * p_config, + nrf_drv_rtc_handler_t handler) +{ + ASSERT(p_config); + + ret_code_t err_code; + + if (handler) + { + m_handlers[p_instance->instance_id] = handler; + } + else + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + if (m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + nrf_drv_common_irq_enable(p_instance->irq, p_config->interrupt_priority); + nrf_rtc_prescaler_set(p_instance->p_reg, p_config->prescaler); + m_cb[p_instance->instance_id].reliable = p_config->reliable; + m_cb[p_instance->instance_id].tick_latency = p_config->tick_latency; + m_cb[p_instance->instance_id].state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +void nrf_drv_rtc_uninit(nrf_drv_rtc_t const * const p_instance) +{ + uint32_t mask = NRF_RTC_INT_TICK_MASK | + NRF_RTC_INT_OVERFLOW_MASK | + NRF_RTC_INT_COMPARE0_MASK | + NRF_RTC_INT_COMPARE1_MASK | + NRF_RTC_INT_COMPARE2_MASK | + NRF_RTC_INT_COMPARE3_MASK; + ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_drv_common_irq_disable(p_instance->irq); + + nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_STOP); + nrf_rtc_event_disable(p_instance->p_reg, mask); + nrf_rtc_int_disable(p_instance->p_reg, mask); + + m_cb[p_instance->instance_id].state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Uninitialized.\r\n"); +} + +void nrf_drv_rtc_enable(nrf_drv_rtc_t const * const p_instance) +{ + ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_INITIALIZED); + + nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_START); + m_cb[p_instance->instance_id].state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Enabled.\r\n"); +} + +void nrf_drv_rtc_disable(nrf_drv_rtc_t const * const p_instance) +{ + ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_STOP); + m_cb[p_instance->instance_id].state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Disabled.\r\n"); +} + +ret_code_t nrf_drv_rtc_cc_disable(nrf_drv_rtc_t const * const p_instance, uint32_t channel) +{ + ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(channelcc_channel_count); + + ret_code_t err_code; + uint32_t int_mask = RTC_CHANNEL_INT_MASK(channel); + nrf_rtc_event_t event = RTC_CHANNEL_EVENT_ADDR(channel); + + nrf_rtc_event_disable(p_instance->p_reg,int_mask); + if (nrf_rtc_int_is_enabled(p_instance->p_reg,int_mask)) + { + nrf_rtc_int_disable(p_instance->p_reg,int_mask); + if (nrf_rtc_event_pending(p_instance->p_reg,event)) + { + nrf_rtc_event_clear(p_instance->p_reg,event); + err_code = NRF_ERROR_TIMEOUT; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + } + NRF_LOG_INFO("RTC id: %d, channel disabled: %d.\r\n", p_instance->instance_id, channel); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +ret_code_t nrf_drv_rtc_cc_set(nrf_drv_rtc_t const * const p_instance, + uint32_t channel, + uint32_t val, + bool enable_irq) +{ + ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(channelcc_channel_count); + + ret_code_t err_code; + uint32_t int_mask = RTC_CHANNEL_INT_MASK(channel); + nrf_rtc_event_t event = RTC_CHANNEL_EVENT_ADDR(channel); + + nrf_rtc_event_disable(p_instance->p_reg, int_mask); + nrf_rtc_int_disable(p_instance->p_reg, int_mask); + + val = RTC_WRAP(val); + if (m_cb[p_instance->instance_id].reliable) + { + nrf_rtc_cc_set(p_instance->p_reg,channel,val); + uint32_t cnt = nrf_rtc_counter_get(p_instance->p_reg); + int32_t diff = cnt - val; + if (cnt < val) + { + diff += RTC_COUNTER_COUNTER_Msk; + } + if (diff < m_cb[p_instance->instance_id].tick_latency) + { + err_code = NRF_ERROR_TIMEOUT; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + } + else + { + nrf_rtc_cc_set(p_instance->p_reg,channel,val); + } + + if (enable_irq) + { + nrf_rtc_event_clear(p_instance->p_reg,event); + nrf_rtc_int_enable(p_instance->p_reg, int_mask); + } + nrf_rtc_event_enable(p_instance->p_reg,int_mask); + + NRF_LOG_INFO("RTC id: %d, channel enabled: %d, compare value: %d.\r\n", p_instance->instance_id, channel, val); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +void nrf_drv_rtc_tick_enable(nrf_drv_rtc_t const * const p_instance, bool enable_irq) +{ + nrf_rtc_event_t event = NRF_RTC_EVENT_TICK; + uint32_t mask = NRF_RTC_INT_TICK_MASK; + + nrf_rtc_event_clear(p_instance->p_reg, event); + nrf_rtc_event_enable(p_instance->p_reg, mask); + if (enable_irq) + { + nrf_rtc_int_enable(p_instance->p_reg, mask); + } + NRF_LOG_INFO("Tick events enabled.\r\n"); +} + +void nrf_drv_rtc_tick_disable(nrf_drv_rtc_t const * const p_instance) +{ + uint32_t mask = NRF_RTC_INT_TICK_MASK; + + nrf_rtc_event_disable(p_instance->p_reg, mask); + nrf_rtc_int_disable(p_instance->p_reg, mask); + NRF_LOG_INFO("Tick events disabled.\r\n"); +} + +void nrf_drv_rtc_overflow_enable(nrf_drv_rtc_t const * const p_instance, bool enable_irq) +{ + nrf_rtc_event_t event = NRF_RTC_EVENT_OVERFLOW; + uint32_t mask = NRF_RTC_INT_OVERFLOW_MASK; + + nrf_rtc_event_clear(p_instance->p_reg, event); + nrf_rtc_event_enable(p_instance->p_reg, mask); + if (enable_irq) + { + nrf_rtc_int_enable(p_instance->p_reg, mask); + } +} +void nrf_drv_rtc_overflow_disable(nrf_drv_rtc_t const * const p_instance) +{ + uint32_t mask = NRF_RTC_INT_OVERFLOW_MASK; + nrf_rtc_event_disable(p_instance->p_reg, mask); + nrf_rtc_int_disable(p_instance->p_reg, mask); +} + +uint32_t nrf_drv_rtc_max_ticks_get(nrf_drv_rtc_t const * const p_instance) +{ + uint32_t ticks; + if (m_cb[p_instance->instance_id].reliable) + { + ticks = RTC_COUNTER_COUNTER_Msk - m_cb[p_instance->instance_id].tick_latency; + } + else + { + ticks = RTC_COUNTER_COUNTER_Msk; + } + return ticks; +} + +/**@brief Generic function for handling RTC interrupt + * + * @param[in] p_reg Pointer to instance register structure. + * @param[in] instance_id Index of instance. + */ +__STATIC_INLINE void nrf_drv_rtc_int_handler(NRF_RTC_Type * p_reg, + uint32_t instance_id, + uint32_t channel_count) +{ + uint32_t i; + uint32_t int_mask = (uint32_t)NRF_RTC_INT_COMPARE0_MASK; + nrf_rtc_event_t event = NRF_RTC_EVENT_COMPARE_0; + + for (i = 0; i < channel_count; i++) + { + if (nrf_rtc_int_is_enabled(p_reg,int_mask) && nrf_rtc_event_pending(p_reg,event)) + { + nrf_rtc_event_disable(p_reg,int_mask); + nrf_rtc_int_disable(p_reg,int_mask); + nrf_rtc_event_clear(p_reg,event); + NRF_LOG_DEBUG("Event: %s, instance id: %d.\r\n", + (uint32_t)EVT_TO_STR(event), (uint32_t)instance_id); + m_handlers[instance_id]((nrf_drv_rtc_int_type_t)i); + } + int_mask <<= 1; + event = (nrf_rtc_event_t)((uint32_t)event + sizeof(uint32_t)); + } + event = NRF_RTC_EVENT_TICK; + if (nrf_rtc_int_is_enabled(p_reg,NRF_RTC_INT_TICK_MASK) && + nrf_rtc_event_pending(p_reg, event)) + { + nrf_rtc_event_clear(p_reg, event); + NRF_LOG_DEBUG("Event: %s, instance id: %d.\r\n", (uint32_t)EVT_TO_STR(event), instance_id); + m_handlers[instance_id](NRF_DRV_RTC_INT_TICK); + } + + event = NRF_RTC_EVENT_OVERFLOW; + if (nrf_rtc_int_is_enabled(p_reg,NRF_RTC_INT_OVERFLOW_MASK) && + nrf_rtc_event_pending(p_reg, event)) + { + nrf_rtc_event_clear(p_reg,event); + NRF_LOG_DEBUG("Event: %s, instance id: %d.\r\n", (uint32_t)EVT_TO_STR(event), instance_id); + m_handlers[instance_id](NRF_DRV_RTC_INT_OVERFLOW); + } +} + +#if NRF_MODULE_ENABLED(RTC0) +void RTC0_IRQHandler(void) +{ + nrf_drv_rtc_int_handler(NRF_RTC0,RTC0_INSTANCE_INDEX, NRF_RTC_CC_CHANNEL_COUNT(0)); +} +#endif + +#if NRF_MODULE_ENABLED(RTC1) +void RTC1_IRQHandler(void) +{ + nrf_drv_rtc_int_handler(NRF_RTC1,RTC1_INSTANCE_INDEX, NRF_RTC_CC_CHANNEL_COUNT(1)); +} +#endif + +#if NRF_MODULE_ENABLED(RTC2) +void RTC2_IRQHandler(void) +{ + nrf_drv_rtc_int_handler(NRF_RTC2,RTC2_INSTANCE_INDEX, NRF_RTC_CC_CHANNEL_COUNT(2)); +} +#endif +#endif //ENABLED_RTC_COUNT +#endif //NRF_MODULE_ENABLED(RTC) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/rtc/nrf_drv_rtc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/rtc/nrf_drv_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..be783e667248fe178b36c6e439960b4316817bea --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/rtc/nrf_drv_rtc.h @@ -0,0 +1,365 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_DRV_RTC_H +#define NRF_DRV_RTC_H + + +#include "sdk_config.h" +#include "nordic_common.h" +#include "nrf_drv_common.h" +#include "nrf_rtc.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup nrf_rtc RTC HAL and driver + * @ingroup nrf_drivers + * @brief Real timer counter (RTC) APIs. + * @details The RTC HAL provides basic APIs for accessing the registers of the real time counter (RTC). + * The RTC driver provides APIs on a higher level. + * + * @defgroup nrf_drv_rtc RTC driver + * @{ + * @ingroup nrf_rtc + * @brief Real timer counter (RTC) driver. + */ + +/**@brief Macro to convert microseconds into ticks. */ +#define RTC_US_TO_TICKS(us,freq) ((us * freq) / 1000000) + +/** + * @enum nrf_drv_rtc_int_type_t + * @brief RTC driver interrupt types. + */ +typedef enum +{ + NRF_DRV_RTC_INT_COMPARE0 = 0, /**< Interrupt from COMPARE0 event. */ + NRF_DRV_RTC_INT_COMPARE1 = 1, /**< Interrupt from COMPARE1 event. */ + NRF_DRV_RTC_INT_COMPARE2 = 2, /**< Interrupt from COMPARE2 event. */ + NRF_DRV_RTC_INT_COMPARE3 = 3, /**< Interrupt from COMPARE3 event. */ + NRF_DRV_RTC_INT_TICK = 4, /**< Interrupt from TICK event. */ + NRF_DRV_RTC_INT_OVERFLOW = 5 /**< Interrupt from OVERFLOW event. */ +} nrf_drv_rtc_int_type_t; + +/**@brief RTC driver instance structure. */ +typedef struct +{ + NRF_RTC_Type * p_reg; /**< Pointer to instance register set. */ + IRQn_Type irq; /**< Instance IRQ ID. */ + uint8_t instance_id; /**< Instance index. */ + uint8_t cc_channel_count; /**< Number of capture/compare channels. */ +} nrf_drv_rtc_t; + +#define RTC0_INSTANCE_INDEX 0 +#define RTC1_INSTANCE_INDEX RTC0_INSTANCE_INDEX+RTC0_ENABLED +#define RTC2_INSTANCE_INDEX RTC1_INSTANCE_INDEX+RTC1_ENABLED + +/**@brief Macro for creating RTC driver instance.*/ +#define NRF_DRV_RTC_INSTANCE(id) \ +{ \ + .p_reg = CONCAT_2(NRF_RTC, id), \ + .irq = CONCAT_3(RTC, id, _IRQn), \ + .instance_id = CONCAT_3(RTC, id, _INSTANCE_INDEX),\ + .cc_channel_count = NRF_RTC_CC_CHANNEL_COUNT(id), \ +} + +/**@brief RTC driver instance configuration structure. */ +typedef struct +{ + uint16_t prescaler; /**< Prescaler. */ + uint8_t interrupt_priority; /**< Interrupt priority. */ + uint8_t tick_latency; /**< Maximum length of interrupt handler in ticks (max 7.7 ms). */ + bool reliable; /**< Reliable mode flag. */ +} nrf_drv_rtc_config_t; + +/**@brief RTC instance default configuration. */ +#define NRF_DRV_RTC_DEFAULT_CONFIG \ +{ \ + .prescaler = RTC_FREQ_TO_PRESCALER(RTC_DEFAULT_CONFIG_FREQUENCY), \ + .interrupt_priority = RTC_DEFAULT_CONFIG_IRQ_PRIORITY, \ + .reliable = RTC_DEFAULT_CONFIG_RELIABLE, \ + .tick_latency = RTC_US_TO_TICKS(NRF_MAXIMUM_LATENCY_US, RTC_DEFAULT_CONFIG_FREQUENCY), \ +} + +/**@brief RTC driver instance handler type. */ +typedef void (*nrf_drv_rtc_handler_t)(nrf_drv_rtc_int_type_t int_type); + +/**@brief Function for initializing the RTC driver instance. + * + * After initialization, the instance is in power off state. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_config Initial configuration. Default configuration used if NULL. + * @param[in] handler User's event handler. + * + * @retval NRF_SUCCESS If successfully initialized. + * @retval NRF_ERROR_INVALID_PARAM If no handler was provided. + * @retval NRF_ERROR_INVALID_STATE If the instance is already initialized. + */ +ret_code_t nrf_drv_rtc_init(nrf_drv_rtc_t const * const p_instance, + nrf_drv_rtc_config_t const * p_config, + nrf_drv_rtc_handler_t handler); + +/**@brief Function for uninitializing the RTC driver instance. + * + * After uninitialization, the instance is in idle state. The hardware should return to the state + * before initialization. The function asserts if the instance is in idle state. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_rtc_uninit(nrf_drv_rtc_t const * const p_instance); + +/**@brief Function for enabling the RTC driver instance. + * + * @note Function asserts if instance is enabled. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_rtc_enable(nrf_drv_rtc_t const * const p_instance); + +/**@brief Function for disabling the RTC driver instance. + * + * @note Function asserts if instance is disabled. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_rtc_disable(nrf_drv_rtc_t const * const p_instance); + +/**@brief Function for setting a compare channel. + * + * The function asserts if the instance is not initialized or if the channel parameter is + * wrong. The function powers on the instance if the instance was in power off state. + * + * The driver is not entering a critical section when configuring RTC, which means that it can be + * preempted for a certain amount of time. When the driver was preempted and the value to be set + * is short in time, there is a risk that the driver sets a compare value that is + * behind. If RTCn_CONFIG_RELIABLE is 1 for the given instance, the Reliable mode handles that case. + * However, to detect if the requested value is behind, this mode makes the following assumptions: + * - The maximum preemption time in ticks (8 - bit value) is known and is less than 7.7 ms + * (for prescaler = 0, RTC frequency 32 kHz). + * - The requested absolute compare value is not bigger than (0x00FFFFFF) - tick_latency. It is + * the user's responsibility to ensure that. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] channel One of the instance's channels. + * @param[in] val Absolute value to be set in the compare register. + * @param[in] enable_irq True to enable the interrupt. False to disable the interrupt. + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_TIMEOUT If the compare was not set because the request value is behind the current counter + * value. This error can only be reported if RTCn_CONFIG_RELIABLE = 1. + */ +ret_code_t nrf_drv_rtc_cc_set(nrf_drv_rtc_t const * const p_instance, + uint32_t channel, + uint32_t val, + bool enable_irq); + +/**@brief Function for disabling a channel. + * + * This function disables channel events and channel interrupts. The function asserts if the instance is not + * initialized or if the channel parameter is wrong. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] channel One of the instance's channels. + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_TIMEOUT If an interrupt was pending on the requested channel. + */ +ret_code_t nrf_drv_rtc_cc_disable(nrf_drv_rtc_t const * const p_instance, uint32_t channel); + +/**@brief Function for enabling tick. + * + * This function enables the tick event and optionally the interrupt. The function asserts if the instance is not + * powered on. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] enable_irq True to enable the interrupt. False to disable the interrupt. + */ +void nrf_drv_rtc_tick_enable(nrf_drv_rtc_t const * const p_instance, bool enable_irq); + +/**@brief Function for disabling tick. + * + * This function disables the tick event and interrupt. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_rtc_tick_disable(nrf_drv_rtc_t const * const p_instance); + +/**@brief Function for enabling overflow. + * + * This function enables the overflow event and optionally the interrupt. The function asserts if the instance is + * not powered on. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] enable_irq True to enable the interrupt. False to disable the interrupt. + */ +void nrf_drv_rtc_overflow_enable(nrf_drv_rtc_t const * const p_instance, bool enable_irq); + +/**@brief Function for disabling overflow. + * + * This function disables the overflow event and interrupt. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_rtc_overflow_disable(nrf_drv_rtc_t const * const p_instance); + +/**@brief Function for getting the maximum relative ticks value that can be set in the compare channel. + * + * When a SoftDevice is used, it occupies the highest level interrupt, so that the application code can be + * interrupted at any moment for a certain period of time. If Reliable mode is enabled, the provided + * maximum latency is taken into account and the return value is smaller than the RTC counter + * resolution. If Reliable mode is disabled, the return value equals the counter resolution. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval ticks Maximum ticks value. + */ +uint32_t nrf_drv_rtc_max_ticks_get(nrf_drv_rtc_t const * const p_instance); + +/**@brief Function for disabling all instance interrupts. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_mask Pointer to the location where the mask is filled. + */ +__STATIC_INLINE void nrf_drv_rtc_int_disable(nrf_drv_rtc_t const * const p_instance, + uint32_t * p_mask); + +/**@brief Function for enabling instance interrupts. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] mask Mask of interrupts to enable. + */ +__STATIC_INLINE void nrf_drv_rtc_int_enable(nrf_drv_rtc_t const * const p_instance, uint32_t mask); + +/**@brief Function for retrieving the current counter value. + * + * This function asserts if the instance is not powered on or if p_val is NULL. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval value Counter value. + */ +__STATIC_INLINE uint32_t nrf_drv_rtc_counter_get(nrf_drv_rtc_t const * const p_instance); + +/**@brief Function for clearing the counter value. + * + * This function asserts if the instance is not powered on. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +__STATIC_INLINE void nrf_drv_rtc_counter_clear(nrf_drv_rtc_t const * const p_instance); + +/**@brief Function for returning a requested task address for the RTC driver instance. + * + * This function asserts if the output pointer is NULL. The task address can be used by the PPI module. + * + * @param[in] p_instance Pointer to the instance. + * @param[in] task One of the peripheral tasks. + * + * @retval Address of task register. + */ +__STATIC_INLINE uint32_t nrf_drv_rtc_task_address_get(nrf_drv_rtc_t const * const p_instance, + nrf_rtc_task_t task); + +/**@brief Function for returning a requested event address for the RTC driver instance. + * + * This function asserts if the output pointer is NULL. The event address can be used by the PPI module. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] event One of the peripheral events. + * + * @retval Address of event register. + */ +__STATIC_INLINE uint32_t nrf_drv_rtc_event_address_get(nrf_drv_rtc_t const * const p_instance, + nrf_rtc_event_t event); +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_drv_rtc_int_disable(nrf_drv_rtc_t const * const p_instance, + uint32_t * p_mask) +{ + *p_mask = nrf_rtc_int_get(p_instance->p_reg); + nrf_rtc_int_disable(p_instance->p_reg, NRF_RTC_INT_TICK_MASK | + NRF_RTC_INT_OVERFLOW_MASK | + NRF_RTC_INT_COMPARE0_MASK | + NRF_RTC_INT_COMPARE1_MASK | + NRF_RTC_INT_COMPARE2_MASK | + NRF_RTC_INT_COMPARE3_MASK); +} + +__STATIC_INLINE void nrf_drv_rtc_int_enable(nrf_drv_rtc_t const * const p_instance, uint32_t mask) +{ + nrf_rtc_int_enable(p_instance->p_reg, mask); +} + +__STATIC_INLINE uint32_t nrf_drv_rtc_counter_get(nrf_drv_rtc_t const * const p_instance) +{ + return nrf_rtc_counter_get(p_instance->p_reg); +} + +__STATIC_INLINE void nrf_drv_rtc_counter_clear(nrf_drv_rtc_t const * const p_instance) +{ + nrf_rtc_task_trigger(p_instance->p_reg,NRF_RTC_TASK_CLEAR); +} + +__STATIC_INLINE uint32_t nrf_drv_rtc_task_address_get(nrf_drv_rtc_t const * const p_instance, + nrf_rtc_task_t task) +{ + return nrf_rtc_task_address_get(p_instance->p_reg, task); +} + +__STATIC_INLINE uint32_t nrf_drv_rtc_event_address_get(nrf_drv_rtc_t const * const p_instance, + nrf_rtc_event_t event) +{ + return nrf_rtc_event_address_get(p_instance->p_reg, event); +} +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +/** + *@} + **/ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_DRV_RTC_H */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/saadc/nrf_drv_saadc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/saadc/nrf_drv_saadc.c new file mode 100644 index 0000000000000000000000000000000000000000..d9d96b8b2247d2fc4de01b9481756049a15f08f5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/saadc/nrf_drv_saadc.c @@ -0,0 +1,647 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(SAADC) +#include "nrf_drv_saadc.h" +#include "nrf_assert.h" +#include "nrf_drv_common.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "SAADC" + +#if SAADC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL SAADC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR SAADC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR SAADC_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_SAADC_EVENT_STARTED ? "NRF_SAADC_EVENT_STARTED" : \ + (event == NRF_SAADC_EVENT_END ? "NRF_SAADC_EVENT_END" : \ + (event == NRF_SAADC_EVENT_DONE ? "NRF_SAADC_EVENT_DONE" : \ + (event == NRF_SAADC_EVENT_RESULTDONE ? "NRF_SAADC_EVENT_RESULTDONE" : \ + (event == NRF_SAADC_EVENT_CALIBRATEDONE ? "NRF_SAADC_EVENT_CALIBRATEDONE" : \ + (event == NRF_SAADC_EVENT_STOPPED ? "NRF_SAADC_EVENT_STOPPED" : "UNKNOWN EVENT")))))) +#define EVT_TO_STR_LIMIT(event) (event == NRF_SAADC_LIMIT_LOW ? "NRF_SAADC_LIMIT_LOW" : \ + (event == NRF_SAADC_LIMIT_HIGH ? "NRF_SAADC_LIMIT_HIGH" : "UNKNOWN EVENT")) +#else //SAADC_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //SAADC_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +typedef enum +{ + NRF_SAADC_STATE_IDLE = 0, + NRF_SAADC_STATE_BUSY = 1, + NRF_SAADC_STATE_CALIBRATION = 2 +} nrf_saadc_state_t; + + +typedef struct +{ + nrf_saadc_input_t pselp; + nrf_saadc_input_t pseln; +} nrf_saadc_psel_buffer; + +static const nrf_drv_saadc_config_t m_default_config = NRF_DRV_SAADC_DEFAULT_CONFIG; + +/** @brief SAADC control block.*/ +typedef struct +{ + nrf_drv_saadc_event_handler_t event_handler; ///< Event handler function pointer. + volatile nrf_saadc_value_t * p_buffer; ///< Sample buffer. + volatile uint16_t buffer_size; ///< Size of the sample buffer. + volatile nrf_saadc_value_t * p_secondary_buffer; ///< Secondary sample buffer. + volatile nrf_saadc_state_t adc_state; ///< State of the SAADC. + uint32_t limits_enabled_flags; ///< Enabled limits flags. + uint16_t secondary_buffer_size; ///< Size of the secondary buffer. + uint16_t buffer_size_left; ///< When low power mode is active indicates how many samples left to convert on current buffer. + nrf_saadc_psel_buffer psel[NRF_SAADC_CHANNEL_COUNT]; ///< Pin configurations of SAADC channels. + nrf_drv_state_t state; ///< Driver initialization state. + uint8_t active_channels; ///< Number of enabled SAADC channels. + bool low_power_mode; ///< Indicates if low power mode is active. + bool conversions_end; ///< When low power mode is active indicates end of conversions on current buffer. +} nrf_drv_saadc_cb_t; + +static nrf_drv_saadc_cb_t m_cb; + +#define LOW_LIMIT_TO_FLAG(channel) ((2 * channel + 1)) +#define HIGH_LIMIT_TO_FLAG(channel) ((2 * channel)) +#define FLAG_IDX_TO_EVENT(idx) ((nrf_saadc_event_t)((uint32_t)NRF_SAADC_EVENT_CH0_LIMITH + \ + 4 * idx)) +#define LIMIT_EVENT_TO_CHANNEL(event) (uint8_t)(((uint32_t)event - \ + (uint32_t)NRF_SAADC_EVENT_CH0_LIMITH) / 8) +#define LIMIT_EVENT_TO_LIMIT_TYPE(event)((((uint32_t)event - (uint32_t)NRF_SAADC_EVENT_CH0_LIMITH) & 4) \ + ? NRF_SAADC_LIMIT_LOW : NRF_SAADC_LIMIT_HIGH) +#define HW_TIMEOUT 10000 + +void SAADC_IRQHandler(void) +{ + if (nrf_saadc_event_check(NRF_SAADC_EVENT_END)) + { + nrf_saadc_event_clear(NRF_SAADC_EVENT_END); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SAADC_EVENT_END)); + + if (!m_cb.low_power_mode || m_cb.conversions_end) + { + nrf_drv_saadc_evt_t evt; + evt.type = NRF_DRV_SAADC_EVT_DONE; + evt.data.done.p_buffer = (nrf_saadc_value_t *)m_cb.p_buffer; + evt.data.done.size = m_cb.buffer_size; + + if (m_cb.p_secondary_buffer == NULL) + { + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + } + else + { + m_cb.buffer_size_left = m_cb.secondary_buffer_size; + m_cb.p_buffer = m_cb.p_secondary_buffer; + m_cb.buffer_size = m_cb.secondary_buffer_size; + m_cb.p_secondary_buffer = NULL; + if (!m_cb.low_power_mode) + { + nrf_saadc_task_trigger(NRF_SAADC_TASK_START); + } + } + m_cb.event_handler(&evt); + m_cb.conversions_end = false; + } + } + if (m_cb.low_power_mode && nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED)) + { + nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SAADC_EVENT_STARTED)); + + if (m_cb.buffer_size_left > m_cb.active_channels) + { + // More samples to convert than for single event. + m_cb.buffer_size_left -= m_cb.active_channels; + nrf_saadc_buffer_init((nrf_saadc_value_t *)&m_cb.p_buffer[m_cb.buffer_size - + m_cb.buffer_size_left], + m_cb.active_channels); + } + else if ((m_cb.buffer_size_left == m_cb.active_channels) && + + (m_cb.p_secondary_buffer != NULL)) + { + // Samples to convert for one event, prepare next buffer. + m_cb.conversions_end = true; + m_cb.buffer_size_left = 0; + nrf_saadc_buffer_init((nrf_saadc_value_t *)m_cb.p_secondary_buffer, + m_cb.active_channels); + } + else if (m_cb.buffer_size_left == m_cb.active_channels) + { + // Samples to convert for one event, but no second buffer. + m_cb.conversions_end = true; + m_cb.buffer_size_left = 0; + } + nrf_saadc_event_clear(NRF_SAADC_EVENT_END); + nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE); + } + if (nrf_saadc_event_check(NRF_SAADC_EVENT_CALIBRATEDONE)) + { + nrf_saadc_event_clear(NRF_SAADC_EVENT_CALIBRATEDONE); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SAADC_EVENT_CALIBRATEDONE)); + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + + nrf_drv_saadc_evt_t evt; + evt.type = NRF_DRV_SAADC_EVT_CALIBRATEDONE; + m_cb.event_handler(&evt); + } + if (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED)) + { + nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SAADC_EVENT_STOPPED)); + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + } + else + { + uint32_t limit_flags = m_cb.limits_enabled_flags; + uint32_t flag_idx; + nrf_saadc_event_t event; + + while (limit_flags) + { + flag_idx = __CLZ(limit_flags); + limit_flags &= ~((1UL << 31) >> flag_idx); + event = FLAG_IDX_TO_EVENT(flag_idx); + if (nrf_saadc_event_check(event)) + { + nrf_saadc_event_clear(event); + nrf_drv_saadc_evt_t evt; + evt.type = NRF_DRV_SAADC_EVT_LIMIT; + evt.data.limit.channel = LIMIT_EVENT_TO_CHANNEL(event); + evt.data.limit.limit_type = LIMIT_EVENT_TO_LIMIT_TYPE(event); + NRF_LOG_DEBUG("Event limit, channel: %d, limit type: %s.\r\n", evt.data.limit.channel, (uint32_t)EVT_TO_STR(evt.data.limit.limit_type)); + m_cb.event_handler(&evt); + } + } + } +} + + +ret_code_t nrf_drv_saadc_init(nrf_drv_saadc_config_t const * p_config, + nrf_drv_saadc_event_handler_t event_handler) +{ + ret_code_t err_code; + + if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + if (event_handler == NULL) + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + if (p_config == NULL) + { + p_config = &m_default_config; + } + + m_cb.event_handler = event_handler; + nrf_saadc_resolution_set(p_config->resolution); + nrf_saadc_oversample_set(p_config->oversample); + m_cb.low_power_mode = p_config->low_power_mode; + m_cb.state = NRF_DRV_STATE_INITIALIZED; + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + m_cb.active_channels = 0; + m_cb.limits_enabled_flags = 0; + m_cb.conversions_end = false; + + nrf_saadc_int_disable(NRF_SAADC_INT_ALL); + nrf_saadc_event_clear(NRF_SAADC_EVENT_END); + nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED); + nrf_drv_common_irq_enable(SAADC_IRQn, p_config->interrupt_priority); + nrf_saadc_int_enable(NRF_SAADC_INT_END); + + if (m_cb.low_power_mode) + { + nrf_saadc_int_enable(NRF_SAADC_INT_STARTED); + } + + nrf_saadc_enable(); + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + + return err_code; +} + + +void nrf_drv_saadc_uninit(void) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_saadc_int_disable(NRF_SAADC_INT_ALL); + nrf_drv_common_irq_disable(SAADC_IRQn); + nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP); + + // Wait for ADC being stopped. + uint32_t timeout = HW_TIMEOUT; + + while (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED) == 0 && timeout > 0) + { + --timeout; + } + ASSERT(timeout > 0); + + nrf_saadc_disable(); + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + + for (uint32_t channel = 0; channel < NRF_SAADC_CHANNEL_COUNT; ++channel) + { + if (m_cb.psel[channel].pselp != NRF_SAADC_INPUT_DISABLED) + { + (void)nrf_drv_saadc_channel_uninit(channel); + } + } + + m_cb.state = NRF_DRV_STATE_UNINITIALIZED; +} + + +ret_code_t nrf_drv_saadc_channel_init(uint8_t channel, + nrf_saadc_channel_config_t const * const p_config) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(channel < NRF_SAADC_CHANNEL_COUNT); + // Oversampling can be used only with one channel. + ASSERT((nrf_saadc_oversample_get() == NRF_SAADC_OVERSAMPLE_DISABLED) || + (m_cb.active_channels == 0)); + ASSERT((p_config->pin_p <= NRF_SAADC_INPUT_VDD) && + (p_config->pin_p > NRF_SAADC_INPUT_DISABLED)); + ASSERT(p_config->pin_n <= NRF_SAADC_INPUT_VDD); + + ret_code_t err_code; + + // A channel can only be initialized if the driver is in the idle state. + if (m_cb.adc_state != NRF_SAADC_STATE_IDLE) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + +#ifdef NRF52_PAN_74 + if ((p_config->acq_time == NRF_SAADC_ACQTIME_3US) || (p_config->acq_time == NRF_SAADC_ACQTIME_5US)) + { + nrf_saadc_disable(); + } +#endif //NRF52_PAN_74 + + if (!m_cb.psel[channel].pselp) + { + ++m_cb.active_channels; + } + m_cb.psel[channel].pselp = p_config->pin_p; + m_cb.psel[channel].pseln = p_config->pin_n; + nrf_saadc_channel_init(channel, p_config); + nrf_saadc_channel_input_set(channel, p_config->pin_p, p_config->pin_n); + +#ifdef NRF52_PAN_74 + if ((p_config->acq_time == NRF_SAADC_ACQTIME_3US) || (p_config->acq_time == NRF_SAADC_ACQTIME_5US)) + { + nrf_saadc_enable(); + } +#endif //NRF52_PAN_74 + + NRF_LOG_INFO("Channel initialized: %d.\r\n", channel); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +ret_code_t nrf_drv_saadc_channel_uninit(uint8_t channel) +{ + ASSERT(channel < NRF_SAADC_CHANNEL_COUNT) + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code; + + // A channel can only be uninitialized if the driver is in the idle state. + if (m_cb.adc_state != NRF_SAADC_STATE_IDLE) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + if (m_cb.psel[channel].pselp) + { + --m_cb.active_channels; + } + m_cb.psel[channel].pselp = NRF_SAADC_INPUT_DISABLED; + m_cb.psel[channel].pseln = NRF_SAADC_INPUT_DISABLED; + nrf_saadc_channel_input_set(channel, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED); + nrf_drv_saadc_limits_set(channel, NRF_DRV_SAADC_LIMITL_DISABLED, NRF_DRV_SAADC_LIMITH_DISABLED); + NRF_LOG_INFO("Channel denitialized: %d.\r\n", channel); + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +uint32_t nrf_drv_saadc_sample_task_get(void) +{ + return nrf_saadc_task_address_get( + m_cb.low_power_mode ? NRF_SAADC_TASK_START : NRF_SAADC_TASK_SAMPLE); +} + + +ret_code_t nrf_drv_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * p_value) +{ + ret_code_t err_code; + + if (m_cb.adc_state != NRF_SAADC_STATE_IDLE) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + m_cb.adc_state = NRF_SAADC_STATE_BUSY; + nrf_saadc_int_disable(NRF_SAADC_INT_STARTED | NRF_SAADC_INT_END); + nrf_saadc_buffer_init(p_value, 1); + if (m_cb.active_channels > 1) + { + for (uint32_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i) + { + nrf_saadc_channel_input_set(i, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED); + } + } + nrf_saadc_channel_input_set(channel, + m_cb.psel[channel].pselp, m_cb.psel[channel].pseln); + nrf_saadc_task_trigger(NRF_SAADC_TASK_START); + nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE); + + uint32_t timeout = HW_TIMEOUT; + + while (0 == nrf_saadc_event_check(NRF_SAADC_EVENT_END) && timeout > 0) + { + timeout--; + } + nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED); + nrf_saadc_event_clear(NRF_SAADC_EVENT_END); + + NRF_LOG_INFO("Conversion value: %d, channel.\r\n", *p_value, channel); + + if (m_cb.active_channels > 1) + { + for (uint32_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i) + { + nrf_saadc_channel_input_set(i, m_cb.psel[i].pselp, m_cb.psel[i].pseln); + } + } + + if (m_cb.low_power_mode) + { + nrf_saadc_int_enable(NRF_SAADC_INT_STARTED | NRF_SAADC_INT_END); + } + else + { + nrf_saadc_int_enable(NRF_SAADC_INT_END); + } + + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + + err_code = NRF_SUCCESS; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +ret_code_t nrf_drv_saadc_buffer_convert(nrf_saadc_value_t * p_buffer, uint16_t size) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT((size % m_cb.active_channels) == 0); + ret_code_t err_code; + + + nrf_saadc_int_disable(NRF_SAADC_INT_END | NRF_SAADC_INT_CALIBRATEDONE); + if (m_cb.adc_state == NRF_SAADC_STATE_CALIBRATION) + { + nrf_saadc_int_enable(NRF_SAADC_INT_END | NRF_SAADC_INT_CALIBRATEDONE); + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + if (m_cb.adc_state == NRF_SAADC_STATE_BUSY) + { + if ( m_cb.p_secondary_buffer) + { + nrf_saadc_int_enable(NRF_SAADC_INT_END); + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + else + { + m_cb.p_secondary_buffer = p_buffer; + m_cb.secondary_buffer_size = size; + if (!m_cb.low_power_mode) + { + while (nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED) == 0); + nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED); + nrf_saadc_buffer_init(p_buffer, size); + } + nrf_saadc_int_enable(NRF_SAADC_INT_END); + err_code = NRF_SUCCESS; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + } + nrf_saadc_int_enable(NRF_SAADC_INT_END); + m_cb.adc_state = NRF_SAADC_STATE_BUSY; + + m_cb.p_buffer = p_buffer; + m_cb.buffer_size = size; + m_cb.p_secondary_buffer = NULL; + + NRF_LOG_INFO("Function: %d, buffer length: %d, active channels: %d.\r\n", + (uint32_t)__func__, size, m_cb.active_channels); + + if (m_cb.low_power_mode) + { + m_cb.buffer_size_left = size; + nrf_saadc_buffer_init(p_buffer, m_cb.active_channels); + } + else + { + nrf_saadc_buffer_init(p_buffer, size); + nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED); + nrf_saadc_task_trigger(NRF_SAADC_TASK_START); + } + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +ret_code_t nrf_drv_saadc_sample() +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code = NRF_SUCCESS; + if (m_cb.adc_state != NRF_SAADC_STATE_BUSY) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else if (m_cb.low_power_mode) + { + nrf_saadc_task_trigger(NRF_SAADC_TASK_START); + } + else + { + nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE); + } + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +ret_code_t nrf_drv_saadc_calibrate_offset() +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code; + + if (m_cb.adc_state != NRF_SAADC_STATE_IDLE) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + m_cb.adc_state = NRF_SAADC_STATE_CALIBRATION; + + nrf_saadc_event_clear(NRF_SAADC_EVENT_CALIBRATEDONE); + nrf_saadc_int_enable(NRF_SAADC_INT_CALIBRATEDONE); + nrf_saadc_task_trigger(NRF_SAADC_TASK_CALIBRATEOFFSET); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +bool nrf_drv_saadc_is_busy(void) +{ + return (m_cb.adc_state != NRF_SAADC_STATE_IDLE); +} + + +void nrf_drv_saadc_abort(void) +{ + if (nrf_drv_saadc_is_busy()) + { + nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED); + nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP); + + if (m_cb.adc_state == NRF_SAADC_STATE_CALIBRATION) + { + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + } + else + { + // Wait for ADC being stopped. + uint32_t timeout = HW_TIMEOUT; + + while ((m_cb.adc_state != NRF_SAADC_STATE_IDLE) && (timeout > 0)) + { + --timeout; + } + ASSERT(timeout > 0); + } + + m_cb.p_buffer = 0; + m_cb.p_secondary_buffer = 0; + NRF_LOG_INFO("Conversion aborted.\r\n"); + } +} + + +void nrf_drv_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(m_cb.event_handler); // only non blocking mode supported + ASSERT(limit_low >= NRF_DRV_SAADC_LIMITL_DISABLED); + ASSERT(limit_high <= NRF_DRV_SAADC_LIMITH_DISABLED); + ASSERT(limit_low < limit_high); + nrf_saadc_channel_limits_set(channel, limit_low, limit_high); + + uint32_t int_mask = nrf_saadc_limit_int_get(channel, NRF_SAADC_LIMIT_LOW); + if (limit_low == NRF_DRV_SAADC_LIMITL_DISABLED) + { + m_cb.limits_enabled_flags &= ~(0x80000000 >> LOW_LIMIT_TO_FLAG(channel)); + nrf_saadc_int_disable(int_mask); + } + else + { + m_cb.limits_enabled_flags |= (0x80000000 >> LOW_LIMIT_TO_FLAG(channel)); + nrf_saadc_int_enable(int_mask); + } + + int_mask = nrf_saadc_limit_int_get(channel, NRF_SAADC_LIMIT_HIGH); + if (limit_high == NRF_DRV_SAADC_LIMITH_DISABLED) + { + m_cb.limits_enabled_flags &= ~(0x80000000 >> HIGH_LIMIT_TO_FLAG(channel)); + nrf_saadc_int_disable(int_mask); + } + else + { + m_cb.limits_enabled_flags |= (0x80000000 >> HIGH_LIMIT_TO_FLAG(channel)); + nrf_saadc_int_enable(int_mask); + } +} +#endif //NRF_MODULE_ENABLED(SAADC) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/saadc/nrf_drv_saadc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/saadc/nrf_drv_saadc.h new file mode 100644 index 0000000000000000000000000000000000000000..45b4204e70d54ac50dbac7ac0a621bd445bdbc89 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/saadc/nrf_drv_saadc.h @@ -0,0 +1,326 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 nrf_saadc SAADC HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52 Successive Approximation Analog-to-Digital Converter (SAADC) APIs. + * @details The SAADC HAL provides basic APIs for accessing the registers of the SAADC peripheral. + * The SAADC driver provides APIs on a higher level. + * + * @defgroup nrf_drv_saadc SAADC driver + * @{ + * @ingroup nrf_saadc + * + * @brief @tagAPI52 Successive Approximation Analog-to-Digital Converter (SAADC) driver. + */ + +#ifndef NRF_DRV_SAADC_H__ +#define NRF_DRV_SAADC_H__ + +#include "sdk_config.h" +#include "nrf_saadc.h" +#include "sdk_errors.h" +#include "nrf_drv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Value that should be set as high limit to disable limit detection. + */ +#define NRF_DRV_SAADC_LIMITH_DISABLED (2047) +/** + * @brief Value that should be set as low limit to disable limit detection. + */ +#define NRF_DRV_SAADC_LIMITL_DISABLED (-2048) + +/** + * @brief Macro for setting @ref nrf_drv_saadc_config_t to default settings. + */ +#define NRF_DRV_SAADC_DEFAULT_CONFIG \ + { \ + .resolution = (nrf_saadc_resolution_t)SAADC_CONFIG_RESOLUTION, \ + .oversample = (nrf_saadc_oversample_t)SAADC_CONFIG_OVERSAMPLE, \ + .interrupt_priority = SAADC_CONFIG_IRQ_PRIORITY, \ + .low_power_mode = SAADC_CONFIG_LP_MODE \ + } + +/** + * @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings + * in single ended mode. + * + * @param PIN_P Analog input. + */ +#define NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(PIN_P) \ + { \ + .resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ + .resistor_n = NRF_SAADC_RESISTOR_DISABLED, \ + .gain = NRF_SAADC_GAIN1_6, \ + .reference = NRF_SAADC_REFERENCE_INTERNAL, \ + .acq_time = NRF_SAADC_ACQTIME_10US, \ + .mode = NRF_SAADC_MODE_SINGLE_ENDED, \ + .burst = NRF_SAADC_BURST_DISABLED, \ + .pin_p = (nrf_saadc_input_t)(PIN_P), \ + .pin_n = NRF_SAADC_INPUT_DISABLED \ + } + +/** + * @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings + * in differential mode. + * + * @param PIN_P Positive analog input. + * @param PIN_N Negative analog input. + */ +#define NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(PIN_P, PIN_N) \ + { \ + .resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ + .resistor_n = NRF_SAADC_RESISTOR_DISABLED, \ + .gain = NRF_SAADC_GAIN1_6, \ + .reference = NRF_SAADC_REFERENCE_INTERNAL, \ + .acq_time = NRF_SAADC_ACQTIME_10US, \ + .mode = NRF_SAADC_MODE_DIFFERENTIAL, \ + .pin_p = (nrf_saadc_input_t)(PIN_P), \ + .pin_n = (nrf_saadc_input_t)(PIN_N) \ + } + +/** + * @brief Analog-to-digital converter driver configuration structure. + */ +typedef struct +{ + nrf_saadc_resolution_t resolution; ///< Resolution configuration. + nrf_saadc_oversample_t oversample; ///< Oversampling configuration. + uint8_t interrupt_priority; ///< Interrupt priority. + bool low_power_mode; ///< Indicates if low power mode is active. +} nrf_drv_saadc_config_t; + +/** + * @brief Driver event types. + */ +typedef enum +{ + NRF_DRV_SAADC_EVT_DONE, ///< Event generated when the buffer is filled with samples. + NRF_DRV_SAADC_EVT_LIMIT, ///< Event generated after one of the limits is reached. + NRF_DRV_SAADC_EVT_CALIBRATEDONE ///< Event generated when the calibration is complete. +} nrf_drv_saadc_evt_type_t; + +/** + * @brief Analog-to-digital converter driver done event data. + */ +typedef struct +{ + nrf_saadc_value_t * p_buffer; ///< Pointer to buffer with converted samples. + uint16_t size; ///< Number of samples in the buffer. +} nrf_drv_saadc_done_evt_t; + +/** + * @brief Analog-to-digital converter driver limit event data. + */ +typedef struct +{ + uint8_t channel; ///< Channel on which the limit was detected. + nrf_saadc_limit_t limit_type; ///< Type of limit detected. +} nrf_drv_saadc_limit_evt_t; + +/** + * @brief Analog-to-digital converter driver event structure. + */ +typedef struct +{ + nrf_drv_saadc_evt_type_t type; ///< Event type. + union + { + nrf_drv_saadc_done_evt_t done; ///< Data for @ref NRF_DRV_SAADC_EVT_DONE event. + nrf_drv_saadc_limit_evt_t limit; ///< Data for @ref NRF_DRV_SAADC_EVT_LIMIT event. + } data; +} nrf_drv_saadc_evt_t; + +/** + * @brief ADC event handler. + * + * @param[in] p_event Pointer to an ADC event. The event structure is allocated on + * the stack, so it is valid only within the context of + * the event handler. + */ +typedef void (* nrf_drv_saadc_event_handler_t)(nrf_drv_saadc_evt_t const * p_event); + +/** + * @brief Function for initializing the SAADC. + * + * @param[in] p_config Pointer to a configuration structure. If NULL, the default one is used. + * @param[in] event_handler Event handler provided by the user. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver is already initialized. + * @retval NRF_ERROR_INVALID_PARAM If event_handler is NULL. + */ +ret_code_t nrf_drv_saadc_init(nrf_drv_saadc_config_t const * p_config, + nrf_drv_saadc_event_handler_t event_handler); + +/** + * @brief Function for uninitializing the SAADC. + * + * This function stops all ongoing conversions and disables all channels. + */ +void nrf_drv_saadc_uninit(void); + + +/** + * @brief Function for getting the address of a SAMPLE SAADC task. + * + * @return Task address. + */ +uint32_t nrf_drv_saadc_sample_task_get(void); + +/** + * @brief Function for initializing an SAADC channel. + * + * This function configures and enables the channel. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the ADC was not initialized. + * @retval NRF_ERROR_NO_MEM If the specified channel was already allocated. + */ +ret_code_t nrf_drv_saadc_channel_init(uint8_t channel, + nrf_saadc_channel_config_t const * const p_config); + + +/** + * @brief Function for uninitializing an SAADC channel. + * + * @retval NRF_SUCCESS If uninitialization was successful. + * @retval NRF_ERROR_BUSY If the ADC is busy. + */ +ret_code_t nrf_drv_saadc_channel_uninit(uint8_t channel); + +/** + * @brief Function for starting SAADC sampling. + * + * @retval NRF_SUCCESS If ADC sampling was triggered. + * @retval NRF_ERROR_INVALID_STATE If ADC is in idle state. + */ +ret_code_t nrf_drv_saadc_sample(void); + +/** + * @brief Blocking function for executing a single ADC conversion. + * + * This function selects the desired input, starts a single conversion, + * waits for it to finish, and returns the result. + * + * The function will fail if ADC is busy. + * + * @param[in] channel Channel. + * @param[out] p_value Pointer to the location where the result should be placed. + * + * @retval NRF_SUCCESS If conversion was successful. + * @retval NRF_ERROR_BUSY If the ADC driver is busy. + */ +ret_code_t nrf_drv_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * p_value); + +/** + * @brief Function for issuing conversion of data to the buffer. + * + * This function is non-blocking. The application is notified about filling the buffer by the event handler. + * Conversion will be done on all enabled channels. If the ADC is in idle state, the function will set up Easy + * DMA for the conversion. The ADC will be ready for sampling and wait for the SAMPLE task. It can be + * triggered manually by the @ref nrf_drv_saadc_sample function or by PPI using the @ref NRF_SAADC_TASK_SAMPLE + * task. If one buffer is already set and the conversion is ongoing, calling this function will + * result in queuing the given buffer. The driver will start filling the issued buffer when the first one is + * completed. If the function is called again before the first buffer is filled or calibration is in progress, + * it will return with error. + * + * @param[in] buffer Result buffer. + * @param[in] size Buffer size in words. + * + * @retval NRF_SUCCESS If conversion was successful. + * @retval NRF_ERROR_BUSY If the driver already has two buffers set or calibration is in progress. + */ +ret_code_t nrf_drv_saadc_buffer_convert(nrf_saadc_value_t * buffer, uint16_t size); + +/** + * @brief Function for triggering the ADC offset calibration. + * + * This function is non-blocking. The application is notified about completion by the event handler. + * Calibration will also trigger DONE and RESULTDONE events. + * + * The function will fail if ADC is busy or calibration is already in progress. + * + * @retval NRF_SUCCESS If calibration was started successfully. + * @retval NRF_ERROR_BUSY If the ADC driver is busy. + */ +ret_code_t nrf_drv_saadc_calibrate_offset(void); + +/** + * @brief Function for retrieving the SAADC state. + * + * @retval true If the ADC is busy. + * @retval false If the ADC is ready. + */ +bool nrf_drv_saadc_is_busy(void); + +/** + * @brief Function for aborting ongoing and buffered conversions. + * @note @ref NRF_DRV_SAADC_EVT_DONE event will be generated if there is a conversion in progress. + * Event will contain number of words in the sample buffer. + */ +void nrf_drv_saadc_abort(void); + +/** + * @brief Function for setting the SAADC channel limits. + * When limits are enabled and the result exceeds the defined bounds, the limit handler function is called. + * + * @param[in] channel SAADC channel number. + * @param[in] limit_low Lower limit (valid values from @ref NRF_DRV_SAADC_LIMITL_DISABLED to + * @ref NRF_DRV_SAADC_LIMITH_DISABLED). Conversion results below this value will trigger + * the handler function. Set to @ref NRF_DRV_SAADC_LIMITL_DISABLED to disable this limit. + * @param[in] limit_high Upper limit (valid values from @ref NRF_DRV_SAADC_LIMITL_DISABLED to + * @ref NRF_DRV_SAADC_LIMITH_DISABLED). Conversion results above this value will trigger + * the handler function. Set to @ref NRF_DRV_SAADC_LIMITH_DISABLED to disable this limit. + */ +void nrf_drv_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_SAADC_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/sdio/config/sdio_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/sdio/config/sdio_config.h new file mode 100644 index 0000000000000000000000000000000000000000..f59e553c3d589e6db4d567c8f9a6ca6ef7fb6b7a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/sdio/config/sdio_config.h @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SDIO_CONFIG_H +#define SDIO_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define SDIO_CONFIG_CLOCK_PIN_NUMBER 24 +#define SDIO_CONFIG_DATA_PIN_NUMBER 25 + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/sdio/sdio.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/sdio/sdio.c new file mode 100644 index 0000000000000000000000000000000000000000..381c77d36a0743f89c666f7ebd88603106df5ade --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/sdio/sdio.c @@ -0,0 +1,244 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include + +#include "nrf.h" +#include "nrf_delay.h" +#include "sdio.h" +#include "nrf_gpio.h" + +#include "sdio_config.h" + +/*lint ++flb "Enter library region" */ + +/*lint -e717 -save "Suppress do {} while (0) for these macros" */ +#define SDIO_CLOCK_HIGH() do { NRF_GPIO->OUTSET = (1UL << SDIO_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Pulls SCL line high */ +#define SDIO_CLOCK_LOW() do { NRF_GPIO->OUTCLR = (1UL << SDIO_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Pulls SCL line low */ +#define SDIO_DATA_HIGH() do { NRF_GPIO->OUTSET = (1UL << SDIO_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Pulls SDA line high */ +#define SDIO_DATA_LOW() do { NRF_GPIO->OUTCLR = (1UL << SDIO_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Pulls SDA line low */ +#define SDIO_DATA_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << SDIO_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Configures SDA pin as output */ +#define SDIO_CLOCK_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << SDIO_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Configures SCL pin as output */ +/*lint -restore */ + +/*lint -emacro(845,SDIO_DATA_INPUT) // A zero has been given as right argument to operator '|'" */ + +#define SDIO_DATA_INPUT() do { \ + nrf_gpio_cfg_input(25, NRF_GPIO_PIN_NOPULL); \ +} while (0) + +#define SDIO_DATA_READ() ((NRF_GPIO->IN >> SDIO_CONFIG_DATA_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SDA */ +#define SDIO_CLOCK_READ() ((NRF_GPIO->IN >> SDIO_CONFIG_CLOCK_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SCL */ +#define SDIO_DELAY() nrf_delay_us(10) /*!< Time to wait when pin states are changed. For fast-mode the delay can be zero and for standard-mode 4 us delay is sufficient. */ + +void sdio_init(void) +{ + SDIO_CLOCK_HIGH(); + SDIO_DATA_HIGH(); + SDIO_CLOCK_OUTPUT(); + SDIO_DATA_INPUT(); + + // If slave is stuck in the middle of transfer, clock out bits until the slave ACKs the transfer + for (uint_fast8_t i = 16; i--;) + { + SDIO_DELAY(); + SDIO_CLOCK_LOW(); + SDIO_DELAY(); + SDIO_CLOCK_HIGH(); + SDIO_DELAY(); + + if (SDIO_DATA_READ()) + { + break; + } + } + + for (uint_fast8_t i = 5; i--;) + { + SDIO_DELAY(); + SDIO_CLOCK_LOW(); + SDIO_DELAY(); + SDIO_CLOCK_HIGH(); + } + + SDIO_DATA_OUTPUT(); + SDIO_DATA_HIGH(); + + SDIO_DELAY(); +} + +uint8_t sdio_read_byte(uint8_t address) +{ + uint8_t data_byte = 0; + + SDIO_DATA_OUTPUT(); + + for (uint_fast8_t i = 8; i--;) + { + SDIO_DELAY(); + + SDIO_CLOCK_LOW(); + + if (address & (1U << i)) + { + SDIO_DATA_HIGH(); + } + else + { + SDIO_DATA_LOW(); + } + + SDIO_DELAY(); + + SDIO_CLOCK_HIGH(); + } + + nrf_delay_us(20); + + SDIO_DATA_INPUT(); + + for (uint_fast8_t i = 8; i--;) + { + SDIO_CLOCK_LOW(); + SDIO_DELAY(); + SDIO_CLOCK_HIGH(); + SDIO_DELAY(); + data_byte |= (uint8_t)(SDIO_DATA_READ() << i); + } + + SDIO_DATA_HIGH(); + SDIO_DATA_OUTPUT(); + + SDIO_DELAY(); + + return data_byte; +} + +void sdio_read_burst(uint8_t * target_buffer, uint8_t target_buffer_size) +{ + uint_fast8_t address = 0x63; + + SDIO_DATA_OUTPUT(); + + for (uint_fast8_t bit_index=8; bit_index--;) + { + SDIO_CLOCK_LOW(); + + if (address & (1U << bit_index)) + { + SDIO_DATA_HIGH(); + } + else + { + SDIO_DATA_LOW(); + } + + SDIO_CLOCK_HIGH(); + } + + SDIO_DATA_INPUT(); + + for (uint_fast8_t target_buffer_index = 0; target_buffer_index < target_buffer_size; target_buffer_index++) + { + target_buffer[target_buffer_index] = 0; + + for (uint_fast8_t bit_index = 8; bit_index--;) + { + SDIO_CLOCK_LOW(); + SDIO_CLOCK_HIGH(); + target_buffer[target_buffer_index] |= (uint8_t)(SDIO_DATA_READ() << bit_index); + } + } +} + +void sdio_write_byte(uint8_t address, uint8_t data_byte) +{ + // Add write indication bit + address |= 0x80; + + SDIO_DATA_OUTPUT(); + + for (uint_fast8_t i = 8; i--;) + { + SDIO_DELAY(); + + SDIO_CLOCK_LOW(); + + if (address & (1U << i)) + { + SDIO_DATA_HIGH(); + } + else + { + SDIO_DATA_LOW(); + } + + SDIO_DELAY(); + + SDIO_CLOCK_HIGH(); + } + + SDIO_DELAY(); + + for (uint_fast8_t i = 8; i--;) + { + SDIO_CLOCK_LOW(); + + if (data_byte & (1U << i)) + { + SDIO_DATA_HIGH(); + } + else + { + SDIO_DATA_LOW(); + } + + SDIO_DELAY(); + + SDIO_CLOCK_HIGH(); + + SDIO_DELAY(); + } + + SDIO_DATA_HIGH(); + + SDIO_DELAY(); +} + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/sdio/sdio.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/sdio/sdio.h new file mode 100644 index 0000000000000000000000000000000000000000..e52e7e9872afffbc9938fea05b324013af7472b5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/sdio/sdio.h @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SDIO_H +#define SDIO_H + +/*lint ++flb "Enter library region" */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file +* @brief 2-wire serial interface driver (compatible with ADNS2080 mouse sensor driver) +* +* +* @defgroup nrf_drivers_sdio SDIO driver +* @{ +* @ingroup nrf_drivers +* @brief 2-wire serial interface driver. +*/ + +/** + * @brief Function for initializing 2-wire serial interface and trying to handle stuck slaves. + * + */ +void sdio_init(void); + +/** + * @brief Function for reading a byte over 2-wire serial interface. + * + * Developer needs to implement this function in a way that suits the hardware. + * @param address Register address to read from + * @return Byte read + */ +uint8_t sdio_read_byte(uint8_t address); + +/** + * @brief Function for reading several bytes over 2-wire serial interface using burst mode. + * + * Developer needs to implement this function in a way that suits the hardware. + * @param target_buffer Buffer location to store read bytes to + * @param target_buffer_size Bytes allocated for target_buffer + */ +void sdio_read_burst(uint8_t *target_buffer, uint8_t target_buffer_size); + +/** + * @brief Function for writing a byte over 2-wire serial interface. + * + * Developer needs to implement this function in a way that suits the hardware. + * @param address Register address to write to + * @param data_byte Data byte to write + */ +void sdio_write_byte(uint8_t address, uint8_t data_byte); + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_master/nrf_drv_spi.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_master/nrf_drv_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..3b4c912e431f060b19bdaae1dc40061220523317 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_master/nrf_drv_spi.c @@ -0,0 +1,778 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(SPI) +#define ENABLED_SPI_COUNT (SPI0_ENABLED+SPI1_ENABLED+SPI2_ENABLED) +#if ENABLED_SPI_COUNT + +#include "nrf_drv_spi.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" +#include "nrf_assert.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "SPI" + +#if SPI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL SPI_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR SPI_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR SPI_CONFIG_DEBUG_COLOR +#else //SPI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //SPI_CONFIG_LOG_ENABLED +#include "nrf_log.h" + +#ifndef SPIM_PRESENT + // Make sure SPIx_USE_EASY_DMA is 0 for nRF51 (if a common + // "nrf_drv_config.h" file is provided for nRF51 and nRF52). + #undef SPI0_USE_EASY_DMA + #define SPI0_USE_EASY_DMA 0 + #undef SPI1_USE_EASY_DMA + #define SPI1_USE_EASY_DMA 0 + #undef SPI2_USE_EASY_DMA + #define SPI2_USE_EASY_DMA 0 +#endif + +#ifndef SPI0_USE_EASY_DMA +#define SPI0_USE_EASY_DMA 0 +#endif + +#ifndef SPI1_USE_EASY_DMA +#define SPI1_USE_EASY_DMA 0 +#endif + +#ifndef SPI2_USE_EASY_DMA +#define SPI2_USE_EASY_DMA 0 +#endif + +// This set of macros makes it possible to exclude parts of code when one type +// of supported peripherals is not used. +#if ((NRF_MODULE_ENABLED(SPI0) && SPI0_USE_EASY_DMA) || \ + (NRF_MODULE_ENABLED(SPI1) && SPI1_USE_EASY_DMA) || \ + (NRF_MODULE_ENABLED(SPI2) && SPI2_USE_EASY_DMA)) + #define SPIM_IN_USE +#endif +#if ((NRF_MODULE_ENABLED(SPI0) && !SPI0_USE_EASY_DMA) || \ + (NRF_MODULE_ENABLED(SPI1) && !SPI1_USE_EASY_DMA) || \ + (NRF_MODULE_ENABLED(SPI2) && !SPI2_USE_EASY_DMA)) + #define SPI_IN_USE +#endif +#if defined(SPIM_IN_USE) && defined(SPI_IN_USE) + // SPIM and SPI combined + #define CODE_FOR_SPIM(code) if (p_instance->use_easy_dma) { code } + #define CODE_FOR_SPI(code) else { code } +#elif defined(SPIM_IN_USE) && !defined(SPI_IN_USE) + // SPIM only + #define CODE_FOR_SPIM(code) { code } + #define CODE_FOR_SPI(code) +#elif !defined(SPIM_IN_USE) && defined(SPI_IN_USE) + // SPI only + #define CODE_FOR_SPIM(code) + #define CODE_FOR_SPI(code) { code } +#else + #error "Wrong configuration." +#endif + +#ifdef SPIM_IN_USE +#define END_INT_MASK NRF_SPIM_INT_END_MASK +#endif + +// Control block - driver instance local data. +typedef struct +{ + nrf_drv_spi_evt_handler_t handler; + void * p_context; + nrf_drv_spi_evt_t evt; // Keep the struct that is ready for event handler. Less memcpy. + nrf_drv_state_t state; + volatile bool transfer_in_progress; + + // [no need for 'volatile' attribute for the following members, as they + // are not concurrently used in IRQ handlers and main line code] + uint8_t ss_pin; + uint8_t orc; + uint8_t bytes_transferred; + +#if NRF_MODULE_ENABLED(SPIM_NRF52_ANOMALY_109_WORKAROUND) + uint8_t tx_length; + uint8_t rx_length; +#endif + + bool tx_done : 1; + bool rx_done : 1; + bool abort : 1; +} spi_control_block_t; +static spi_control_block_t m_cb[ENABLED_SPI_COUNT]; + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + #define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n + #define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void) + + #if NRF_MODULE_ENABLED(SPI0) + IRQ_HANDLER(0); + #endif + #if NRF_MODULE_ENABLED(SPI1) + IRQ_HANDLER(1); + #endif + #if NRF_MODULE_ENABLED(SPI2) + IRQ_HANDLER(2); + #endif + static nrf_drv_irq_handler_t const m_irq_handlers[ENABLED_SPI_COUNT] = { + #if NRF_MODULE_ENABLED(SPI0) + IRQ_HANDLER_NAME(0), + #endif + #if NRF_MODULE_ENABLED(SPI1) + IRQ_HANDLER_NAME(1), + #endif + #if NRF_MODULE_ENABLED(SPI2) + IRQ_HANDLER_NAME(2), + #endif + }; +#else + #define IRQ_HANDLER(n) void SPI##n##_IRQ_HANDLER(void) +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +ret_code_t nrf_drv_spi_init(nrf_drv_spi_t const * const p_instance, + nrf_drv_spi_config_t const * p_config, + nrf_drv_spi_evt_handler_t handler, + void * p_context) +{ + ASSERT(p_config); + spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ret_code_t err_code; + + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + if (nrf_drv_common_per_res_acquire(p_instance->p_registers, + m_irq_handlers[p_instance->drv_inst_idx]) != NRF_SUCCESS) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } +#endif + + p_cb->handler = handler; + p_cb->p_context = p_context; + + uint32_t mosi_pin; + uint32_t miso_pin; + // Configure pins used by the peripheral: + // - SCK - output with initial value corresponding with the SPI mode used: + // 0 - for modes 0 and 1 (CPOL = 0), 1 - for modes 2 and 3 (CPOL = 1); + // according to the reference manual guidelines this pin and its input + // buffer must always be connected for the SPI to work. + if (p_config->mode <= NRF_DRV_SPI_MODE_1) + { + nrf_gpio_pin_clear(p_config->sck_pin); + } + else + { + nrf_gpio_pin_set(p_config->sck_pin); + } + nrf_gpio_cfg(p_config->sck_pin, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); + // - MOSI (optional) - output with initial value 0, + if (p_config->mosi_pin != NRF_DRV_SPI_PIN_NOT_USED) + { + mosi_pin = p_config->mosi_pin; + nrf_gpio_pin_clear(mosi_pin); + nrf_gpio_cfg_output(mosi_pin); + } + else + { + mosi_pin = NRF_SPI_PIN_NOT_CONNECTED; + } + // - MISO (optional) - input, + if (p_config->miso_pin != NRF_DRV_SPI_PIN_NOT_USED) + { + miso_pin = p_config->miso_pin; + nrf_gpio_cfg_input(miso_pin, NRF_GPIO_PIN_NOPULL); + } + else + { + miso_pin = NRF_SPI_PIN_NOT_CONNECTED; + } + // - Slave Select (optional) - output with initial value 1 (inactive). + if (p_config->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) + { + nrf_gpio_pin_set(p_config->ss_pin); + nrf_gpio_cfg_output(p_config->ss_pin); + } + m_cb[p_instance->drv_inst_idx].ss_pin = p_config->ss_pin; + + CODE_FOR_SPIM + ( + NRF_SPIM_Type * p_spim = (NRF_SPIM_Type *)p_instance->p_registers; + nrf_spim_pins_set(p_spim, p_config->sck_pin, mosi_pin, miso_pin); + nrf_spim_frequency_set(p_spim, + (nrf_spim_frequency_t)p_config->frequency); + nrf_spim_configure(p_spim, + (nrf_spim_mode_t)p_config->mode, + (nrf_spim_bit_order_t)p_config->bit_order); + + nrf_spim_orc_set(p_spim, p_config->orc); + + if (p_cb->handler) + { + nrf_spim_int_enable(p_spim, END_INT_MASK); + } + + nrf_spim_enable(p_spim); + ) + CODE_FOR_SPI + ( + NRF_SPI_Type * p_spi = p_instance->p_registers; + nrf_spi_pins_set(p_spi, p_config->sck_pin, mosi_pin, miso_pin); + nrf_spi_frequency_set(p_spi, + (nrf_spi_frequency_t)p_config->frequency); + nrf_spi_configure(p_spi, + (nrf_spi_mode_t)p_config->mode, + (nrf_spi_bit_order_t)p_config->bit_order); + + m_cb[p_instance->drv_inst_idx].orc = p_config->orc; + + if (p_cb->handler) + { + nrf_spi_int_enable(p_spi, NRF_SPI_INT_READY_MASK); + } + + nrf_spi_enable(p_spi); + ) + + if (p_cb->handler) + { + nrf_drv_common_irq_enable(p_instance->irq, p_config->irq_priority); + } + + p_cb->transfer_in_progress = false; + p_cb->state = NRF_DRV_STATE_INITIALIZED; + + NRF_LOG_INFO("Init\r\n"); + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +void nrf_drv_spi_uninit(nrf_drv_spi_t const * const p_instance) +{ + spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + if (p_cb->handler) + { + nrf_drv_common_irq_disable(p_instance->irq); + } + + #define DISABLE_ALL 0xFFFFFFFF + + CODE_FOR_SPIM + ( + NRF_SPIM_Type * p_spim = (NRF_SPIM_Type *)p_instance->p_registers; + if (p_cb->handler) + { + nrf_spim_int_disable(p_spim, DISABLE_ALL); + if (p_cb->transfer_in_progress) + { + // Ensure that SPI is not performing any transfer. + nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_STOP); + while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_STOPPED)) {} + p_cb->transfer_in_progress = false; + } + } + nrf_spim_disable(p_spim); + ) + CODE_FOR_SPI + ( + NRF_SPI_Type * p_spi = p_instance->p_registers; + if (p_cb->handler) + { + nrf_spi_int_disable(p_spi, DISABLE_ALL); + } + nrf_spi_disable(p_spi); + ) + #undef DISABLE_ALL + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + nrf_drv_common_per_res_release(p_instance->p_registers); +#endif + + p_cb->state = NRF_DRV_STATE_UNINITIALIZED; +} + +ret_code_t nrf_drv_spi_transfer(nrf_drv_spi_t const * const p_instance, + uint8_t const * p_tx_buffer, + uint8_t tx_buffer_length, + uint8_t * p_rx_buffer, + uint8_t rx_buffer_length) +{ + nrf_drv_spi_xfer_desc_t xfer_desc; + xfer_desc.p_tx_buffer = p_tx_buffer; + xfer_desc.p_rx_buffer = p_rx_buffer; + xfer_desc.tx_length = tx_buffer_length; + xfer_desc.rx_length = rx_buffer_length; + + NRF_LOG_INFO("Transfer tx_len:%d, rx_len:%d.\r\n", tx_buffer_length, rx_buffer_length); + NRF_LOG_DEBUG("Tx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_tx_buffer, tx_buffer_length * sizeof(p_tx_buffer)); + return nrf_drv_spi_xfer(p_instance, &xfer_desc, 0); +} + +static void finish_transfer(spi_control_block_t * p_cb) +{ + // If Slave Select signal is used, this is the time to deactivate it. + if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) + { + nrf_gpio_pin_set(p_cb->ss_pin); + } + + // By clearing this flag before calling the handler we allow subsequent + // transfers to be started directly from the handler function. + p_cb->transfer_in_progress = false; + p_cb->evt.type = NRF_DRV_SPI_EVENT_DONE; + NRF_LOG_INFO("Transfer rx_len:%d.\r\n", p_cb->evt.data.done.rx_length); + NRF_LOG_DEBUG("Rx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_cb->evt.data.done.p_rx_buffer, + p_cb->evt.data.done.rx_length * sizeof(p_cb->evt.data.done.p_rx_buffer)); + p_cb->handler(&p_cb->evt, p_cb->p_context); +} + +#ifdef SPI_IN_USE +// This function is called from IRQ handler or, in blocking mode, directly +// from the 'nrf_drv_spi_transfer' function. +// It returns true as long as the transfer should be continued, otherwise (when +// there is nothing more to send/receive) it returns false. +static bool transfer_byte(NRF_SPI_Type * p_spi, spi_control_block_t * p_cb) +{ + // Read the data byte received in this transfer and store it in RX buffer, + // if needed. + volatile uint8_t rx_data = nrf_spi_rxd_get(p_spi); + if (p_cb->bytes_transferred < p_cb->evt.data.done.rx_length) + { + p_cb->evt.data.done.p_rx_buffer[p_cb->bytes_transferred] = rx_data; + } + + ++p_cb->bytes_transferred; + + // Check if there are more bytes to send or receive and write proper data + // byte (next one from TX buffer or over-run character) to the TXD register + // when needed. + // NOTE - we've already used 'p_cb->bytes_transferred + 1' bytes from our + // buffers, because we take advantage of double buffering of TXD + // register (so in effect one byte is still being transmitted now); + // see how the transfer is started in the 'nrf_drv_spi_transfer' + // function. + uint16_t bytes_used = p_cb->bytes_transferred + 1; + + if (p_cb->abort) + { + if (bytes_used < p_cb->evt.data.done.tx_length) + { + p_cb->evt.data.done.tx_length = bytes_used; + } + if (bytes_used < p_cb->evt.data.done.rx_length) + { + p_cb->evt.data.done.rx_length = bytes_used; + } + } + + if (bytes_used < p_cb->evt.data.done.tx_length) + { + nrf_spi_txd_set(p_spi, p_cb->evt.data.done.p_tx_buffer[bytes_used]); + return true; + } + else if (bytes_used < p_cb->evt.data.done.rx_length) + { + nrf_spi_txd_set(p_spi, p_cb->orc); + return true; + } + + return (p_cb->bytes_transferred < p_cb->evt.data.done.tx_length || + p_cb->bytes_transferred < p_cb->evt.data.done.rx_length); +} + +static void spi_xfer(NRF_SPI_Type * p_spi, + spi_control_block_t * p_cb, + nrf_drv_spi_xfer_desc_t const * p_xfer_desc) +{ + p_cb->bytes_transferred = 0; + nrf_spi_int_disable(p_spi, NRF_SPI_INT_READY_MASK); + + nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY); + + // Start the transfer by writing some byte to the TXD register; + // if TX buffer is not empty, take the first byte from this buffer, + // otherwise - use over-run character. + nrf_spi_txd_set(p_spi, + (p_xfer_desc->tx_length > 0 ? p_xfer_desc->p_tx_buffer[0] : p_cb->orc)); + + // TXD register is double buffered, so next byte to be transmitted can + // be written immediately, if needed, i.e. if TX or RX transfer is to + // be more that 1 byte long. Again - if there is something more in TX + // buffer send it, otherwise use over-run character. + if (p_xfer_desc->tx_length > 1) + { + nrf_spi_txd_set(p_spi, p_xfer_desc->p_tx_buffer[1]); + } + else if (p_xfer_desc->rx_length > 1) + { + nrf_spi_txd_set(p_spi, p_cb->orc); + } + + // For blocking mode (user handler not provided) wait here for READY + // events (indicating that the byte from TXD register was transmitted + // and a new incoming byte was moved to the RXD register) and continue + // transaction until all requested bytes are transferred. + // In non-blocking mode - IRQ service routine will do this stuff. + if (p_cb->handler) + { + nrf_spi_int_enable(p_spi, NRF_SPI_INT_READY_MASK); + } + else + { + do { + while (!nrf_spi_event_check(p_spi, NRF_SPI_EVENT_READY)) {} + nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY); + NRF_LOG_DEBUG("SPI: Event: NRF_SPI_EVENT_READY.\r\n"); + } while (transfer_byte(p_spi, p_cb)); + if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) + { + nrf_gpio_pin_set(p_cb->ss_pin); + } + } +} +#endif // SPI_IN_USE + +#ifdef SPIM_IN_USE +__STATIC_INLINE void spim_int_enable(NRF_SPIM_Type * p_spim, bool enable) +{ + if (!enable) + { + nrf_spim_int_disable(p_spim, END_INT_MASK); + } + else + { + nrf_spim_int_enable(p_spim, END_INT_MASK); + } +} + +__STATIC_INLINE void spim_list_enable_handle(NRF_SPIM_Type * p_spim, uint32_t flags) +{ + if (NRF_DRV_SPI_FLAG_TX_POSTINC & flags) + { + nrf_spim_tx_list_enable(p_spim); + } + else + { + nrf_spim_tx_list_disable(p_spim); + } + + if (NRF_DRV_SPI_FLAG_RX_POSTINC & flags) + { + nrf_spim_rx_list_enable(p_spim); + } + else + { + nrf_spim_rx_list_disable(p_spim); + } +} + +static ret_code_t spim_xfer(NRF_SPIM_Type * p_spim, + spi_control_block_t * p_cb, + nrf_drv_spi_xfer_desc_t const * p_xfer_desc, + uint32_t flags) +{ + ret_code_t err_code; + // EasyDMA requires that transfer buffers are placed in Data RAM region; + // signal error if they are not. + if ((p_xfer_desc->p_tx_buffer != NULL && !nrf_drv_is_in_RAM(p_xfer_desc->p_tx_buffer)) || + (p_xfer_desc->p_rx_buffer != NULL && !nrf_drv_is_in_RAM(p_xfer_desc->p_rx_buffer))) + { + p_cb->transfer_in_progress = false; + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + +#if NRF_MODULE_ENABLED(SPIM_NRF52_ANOMALY_109_WORKAROUND) + p_cb->tx_length = 0; + p_cb->rx_length = 0; +#endif + + nrf_spim_tx_buffer_set(p_spim, p_xfer_desc->p_tx_buffer, p_xfer_desc->tx_length); + nrf_spim_rx_buffer_set(p_spim, p_xfer_desc->p_rx_buffer, p_xfer_desc->rx_length); + + nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END); + + spim_list_enable_handle(p_spim, flags); + + if (!(flags & NRF_DRV_SPI_FLAG_HOLD_XFER)) + { + nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_START); + } +#if NRF_MODULE_ENABLED(SPIM_NRF52_ANOMALY_109_WORKAROUND) + if (flags & NRF_DRV_SPI_FLAG_HOLD_XFER) + { + nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_STARTED); + p_cb->tx_length = p_xfer_desc->tx_length; + p_cb->rx_length = p_xfer_desc->rx_length; + nrf_spim_tx_buffer_set(p_spim, p_xfer_desc->p_tx_buffer, 0); + nrf_spim_rx_buffer_set(p_spim, p_xfer_desc->p_rx_buffer, 0); + nrf_spim_int_enable(p_spim, NRF_SPIM_INT_STARTED_MASK); + } +#endif + + if (!p_cb->handler) + { + while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END)){} + if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) + { + nrf_gpio_pin_set(p_cb->ss_pin); + } + } + else + { + spim_int_enable(p_spim, !(flags & NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER)); + } + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} +#endif + +ret_code_t nrf_drv_spi_xfer(nrf_drv_spi_t const * const p_instance, + nrf_drv_spi_xfer_desc_t const * p_xfer_desc, + uint32_t flags) +{ + spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_xfer_desc->p_tx_buffer != NULL || p_xfer_desc->tx_length == 0); + ASSERT(p_xfer_desc->p_rx_buffer != NULL || p_xfer_desc->rx_length == 0); + + ret_code_t err_code = NRF_SUCCESS; + + if (p_cb->transfer_in_progress) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + else + { + if (p_cb->handler && !(flags & (NRF_DRV_SPI_FLAG_REPEATED_XFER | + NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER))) + { + p_cb->transfer_in_progress = true; + } + } + + p_cb->evt.data.done = *p_xfer_desc; + p_cb->tx_done = false; + p_cb->rx_done = false; + p_cb->abort = false; + + if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) + { + nrf_gpio_pin_clear(p_cb->ss_pin); + } + CODE_FOR_SPIM + ( + return spim_xfer(p_instance->p_registers, p_cb, p_xfer_desc, flags); + ) + CODE_FOR_SPI + ( + if (flags) + { + p_cb->transfer_in_progress = false; + err_code = NRF_ERROR_NOT_SUPPORTED; + } + else + { + spi_xfer(p_instance->p_registers, p_cb, p_xfer_desc); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + ) +} + + +void nrf_drv_spi_abort(nrf_drv_spi_t const * p_instance) +{ + spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + CODE_FOR_SPIM + ( + nrf_spim_task_trigger(p_instance->p_registers, NRF_SPIM_TASK_STOP); + while (!nrf_spim_event_check(p_instance->p_registers, NRF_SPIM_EVENT_STOPPED)) {} + p_cb->transfer_in_progress = false; + ) + CODE_FOR_SPI + ( + p_cb->abort = true; + ) +} + + +#ifdef SPIM_IN_USE +static void irq_handler_spim(NRF_SPIM_Type * p_spim, spi_control_block_t * p_cb) +{ + +#if NRF_MODULE_ENABLED(SPIM_NRF52_ANOMALY_109_WORKAROUND) + if ((nrf_spim_int_enable_check(p_spim, NRF_SPIM_INT_STARTED_MASK)) && + (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_STARTED)) ) + { + /* Handle first, zero-length, auxiliary transmission. */ + nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_STARTED); + nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END); + + ASSERT(p_spim->TXD.MAXCNT == 0); + p_spim->TXD.MAXCNT = p_cb->tx_length; + + ASSERT(p_spim->RXD.MAXCNT == 0); + p_spim->RXD.MAXCNT = p_cb->rx_length; + + /* Disable STARTED interrupt, used only in auxiliary transmission. */ + nrf_spim_int_disable(p_spim, NRF_SPIM_INT_STARTED_MASK); + + /* Start the actual, glitch-free transmission. */ + nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_START); + return; + } +#endif + + if (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END)) + { + nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END); + ASSERT(p_cb->handler); + NRF_LOG_DEBUG("SPIM: Event: NRF_SPIM_EVENT_END.\r\n"); + finish_transfer(p_cb); + } +} + +uint32_t nrf_drv_spi_start_task_get(nrf_drv_spi_t const * p_instance) +{ + NRF_SPIM_Type * p_spim = (NRF_SPIM_Type *)p_instance->p_registers; + return nrf_spim_task_address_get(p_spim, NRF_SPIM_TASK_START); +} + +uint32_t nrf_drv_spi_end_event_get(nrf_drv_spi_t const * p_instance) +{ + NRF_SPIM_Type * p_spim = (NRF_SPIM_Type *)p_instance->p_registers; + return nrf_spim_event_address_get(p_spim, NRF_SPIM_EVENT_END); +} +#endif // SPIM_IN_USE + +#ifdef SPI_IN_USE +static void irq_handler_spi(NRF_SPI_Type * p_spi, spi_control_block_t * p_cb) +{ + ASSERT(p_cb->handler); + + nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY); + NRF_LOG_DEBUG("SPI: Event: NRF_SPI_EVENT_READY.\r\n"); + + if (!transfer_byte(p_spi, p_cb)) + { + finish_transfer(p_cb); + } +} +#endif // SPI_IN_USE + +#if NRF_MODULE_ENABLED(SPI0) +IRQ_HANDLER(0) +{ + spi_control_block_t * p_cb = &m_cb[SPI0_INSTANCE_INDEX]; + #if SPI0_USE_EASY_DMA + irq_handler_spim(NRF_SPIM0, p_cb); + #else + irq_handler_spi(NRF_SPI0, p_cb); + #endif +} +#endif // NRF_MODULE_ENABLED(SPI0) + +#if NRF_MODULE_ENABLED(SPI1) +IRQ_HANDLER(1) +{ + spi_control_block_t * p_cb = &m_cb[SPI1_INSTANCE_INDEX]; + #if SPI1_USE_EASY_DMA + irq_handler_spim(NRF_SPIM1, p_cb); + #else + irq_handler_spi(NRF_SPI1, p_cb); + #endif +} +#endif // NRF_MODULE_ENABLED(SPI1) + +#if NRF_MODULE_ENABLED(SPI2) +IRQ_HANDLER(2) +{ + spi_control_block_t * p_cb = &m_cb[SPI2_INSTANCE_INDEX]; + #if SPI2_USE_EASY_DMA + irq_handler_spim(NRF_SPIM2, p_cb); + #else + irq_handler_spi(NRF_SPI2, p_cb); + #endif +} +#endif // NRF_MODULE_ENABLED(SPI2) +#endif // ENABLED_SPI_COUNT +#endif // NRF_MODULE_ENABLED(SPI) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_master/nrf_drv_spi.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_master/nrf_drv_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..c6d418cc2d8867327712e04213f5868df8da0495 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_master/nrf_drv_spi.h @@ -0,0 +1,413 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * @addtogroup nrf_spi Serial peripheral interface (SPI/SPIM) + * @ingroup nrf_drivers + * @brief Serial peripheral interface (SPI/SPIM) APIs. + * + */ + +#ifndef NRF_DRV_SPI_H__ +#define NRF_DRV_SPI_H__ + +#include "nordic_common.h" +#include "sdk_config.h" +#include "nrf_peripherals.h" +#include "nrf_spi.h" +#ifdef SPIM_PRESENT +#include "nrf_spim.h" +#endif +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(SPIM_PRESENT) + #define NRF_DRV_SPI_PERIPHERAL(id) \ + (CONCAT_3(SPI, id, _USE_EASY_DMA) == 1 ? \ + (void *)CONCAT_2(NRF_SPIM, id) \ + : (void *)CONCAT_2(NRF_SPI, id)) + #define SPI2_IRQ SPIM2_SPIS2_SPI2_IRQn + #define SPI2_IRQ_HANDLER SPIM2_SPIS2_SPI2_IRQHandler +#else + #define NRF_DRV_SPI_PERIPHERAL(id) (void *)CONCAT_2(NRF_SPI, id) +#endif +#define SPI0_IRQ SPI0_TWI0_IRQn +#define SPI0_IRQ_HANDLER SPI0_TWI0_IRQHandler +#define SPI1_IRQ SPI1_TWI1_IRQn +#define SPI1_IRQ_HANDLER SPI1_TWI1_IRQHandler + +/** + * @defgroup nrf_drv_spi SPI master driver + * @{ + * @ingroup nrf_spi + * + * @brief Multi-instance SPI master driver. + */ + +/** + * @brief SPI master driver instance data structure. + */ +typedef struct +{ + void * p_registers; ///< Pointer to the structure with SPI/SPIM peripheral instance registers. + IRQn_Type irq; ///< SPI/SPIM peripheral instance IRQ number. + uint8_t drv_inst_idx; ///< Driver instance index. + bool use_easy_dma; ///< True if the peripheral with EasyDMA (SPIM) shall be used. +} nrf_drv_spi_t; + +#define SPI0_INSTANCE_INDEX 0 +#define SPI1_INSTANCE_INDEX SPI0_INSTANCE_INDEX+SPI0_ENABLED +#define SPI2_INSTANCE_INDEX SPI1_INSTANCE_INDEX+SPI1_ENABLED + +/** + * @brief Macro for creating an SPI master driver instance. + */ +#define NRF_DRV_SPI_INSTANCE(id) \ +{ \ + .p_registers = NRF_DRV_SPI_PERIPHERAL(id), \ + .irq = CONCAT_3(SPI, id, _IRQ), \ + .drv_inst_idx = CONCAT_3(SPI, id, _INSTANCE_INDEX), \ + .use_easy_dma = CONCAT_3(SPI, id, _USE_EASY_DMA) \ +} + +/** + * @brief This value can be provided instead of a pin number for signals MOSI, + * MISO, and Slave Select to specify that the given signal is not used and + * therefore does not need to be connected to a pin. + */ +#define NRF_DRV_SPI_PIN_NOT_USED 0xFF + +/** + * @brief SPI data rates. + */ +typedef enum +{ + NRF_DRV_SPI_FREQ_125K = NRF_SPI_FREQ_125K, ///< 125 kbps. + NRF_DRV_SPI_FREQ_250K = NRF_SPI_FREQ_250K, ///< 250 kbps. + NRF_DRV_SPI_FREQ_500K = NRF_SPI_FREQ_500K, ///< 500 kbps. + NRF_DRV_SPI_FREQ_1M = NRF_SPI_FREQ_1M, ///< 1 Mbps. + NRF_DRV_SPI_FREQ_2M = NRF_SPI_FREQ_2M, ///< 2 Mbps. + NRF_DRV_SPI_FREQ_4M = NRF_SPI_FREQ_4M, ///< 4 Mbps. + NRF_DRV_SPI_FREQ_8M = NRF_SPI_FREQ_8M ///< 8 Mbps. +} nrf_drv_spi_frequency_t; + +/** + * @brief SPI modes. + */ +typedef enum +{ + NRF_DRV_SPI_MODE_0 = NRF_SPI_MODE_0, ///< SCK active high, sample on leading edge of clock. + NRF_DRV_SPI_MODE_1 = NRF_SPI_MODE_1, ///< SCK active high, sample on trailing edge of clock. + NRF_DRV_SPI_MODE_2 = NRF_SPI_MODE_2, ///< SCK active low, sample on leading edge of clock. + NRF_DRV_SPI_MODE_3 = NRF_SPI_MODE_3 ///< SCK active low, sample on trailing edge of clock. +} nrf_drv_spi_mode_t; + +/** + * @brief SPI bit orders. + */ +typedef enum +{ + NRF_DRV_SPI_BIT_ORDER_MSB_FIRST = NRF_SPI_BIT_ORDER_MSB_FIRST, ///< Most significant bit shifted out first. + NRF_DRV_SPI_BIT_ORDER_LSB_FIRST = NRF_SPI_BIT_ORDER_LSB_FIRST ///< Least significant bit shifted out first. +} nrf_drv_spi_bit_order_t; + +/** + * @brief SPI master driver instance configuration structure. + */ +typedef struct +{ + uint8_t sck_pin; ///< SCK pin number. + uint8_t mosi_pin; ///< MOSI pin number (optional). + /**< Set to @ref NRF_DRV_SPI_PIN_NOT_USED + * if this signal is not needed. */ + uint8_t miso_pin; ///< MISO pin number (optional). + /**< Set to @ref NRF_DRV_SPI_PIN_NOT_USED + * if this signal is not needed. */ + uint8_t ss_pin; ///< Slave Select pin number (optional). + /**< Set to @ref NRF_DRV_SPI_PIN_NOT_USED + * if this signal is not needed. The driver + * supports only active low for this signal. + * If the signal should be active high, + * it must be controlled externally. */ + uint8_t irq_priority; ///< Interrupt priority. + uint8_t orc; ///< Over-run character. + /**< This character is used when all bytes from the TX buffer are sent, + but the transfer continues due to RX. */ + nrf_drv_spi_frequency_t frequency; ///< SPI frequency. + nrf_drv_spi_mode_t mode; ///< SPI mode. + nrf_drv_spi_bit_order_t bit_order; ///< SPI bit order. +} nrf_drv_spi_config_t; + +/** + * @brief SPI master instance default configuration. + */ +#define NRF_DRV_SPI_DEFAULT_CONFIG \ +{ \ + .sck_pin = NRF_DRV_SPI_PIN_NOT_USED, \ + .mosi_pin = NRF_DRV_SPI_PIN_NOT_USED, \ + .miso_pin = NRF_DRV_SPI_PIN_NOT_USED, \ + .ss_pin = NRF_DRV_SPI_PIN_NOT_USED, \ + .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY, \ + .orc = 0xFF, \ + .frequency = NRF_DRV_SPI_FREQ_4M, \ + .mode = NRF_DRV_SPI_MODE_0, \ + .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST, \ +} + +#define NRF_DRV_SPI_FLAG_TX_POSTINC (1UL << 0) /**< TX buffer address incremented after transfer. */ +#define NRF_DRV_SPI_FLAG_RX_POSTINC (1UL << 1) /**< RX buffer address incremented after transfer. */ +#define NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER (1UL << 2) /**< Interrupt after each transfer is suppressed, and the event handler is not called. */ +#define NRF_DRV_SPI_FLAG_HOLD_XFER (1UL << 3) /**< Set up the transfer but do not start it. */ +#define NRF_DRV_SPI_FLAG_REPEATED_XFER (1UL << 4) /**< Flag indicating that the transfer will be executed multiple times. */ + +/** + * @brief Single transfer descriptor structure. + */ +typedef struct +{ + uint8_t const * p_tx_buffer; ///< Pointer to TX buffer. + uint8_t tx_length; ///< TX buffer length. + uint8_t * p_rx_buffer; ///< Pointer to RX buffer. + uint8_t rx_length; ///< RX buffer length. +}nrf_drv_spi_xfer_desc_t; + +/** + * @brief Macro for setting up single transfer descriptor. + * + * This macro is for internal use only. + */ +#define NRF_DRV_SPI_SINGLE_XFER(p_tx, tx_len, p_rx, rx_len) \ + { \ + .p_tx_buffer = (uint8_t const *)(p_tx), \ + .tx_length = (tx_len), \ + .p_rx_buffer = (p_rx), \ + .rx_length = (rx_len), \ + } + +/** + * @brief Macro for setting duplex TX RX transfer. + */ +#define NRF_DRV_SPI_XFER_TRX(p_tx_buf, tx_length, p_rx_buf, rx_length) \ + NRF_DRV_SPI_SINGLE_XFER(p_tx_buf, tx_length, p_rx_buf, rx_length) + +/** + * @brief Macro for setting TX transfer. + */ +#define NRF_DRV_SPI_XFER_TX(p_buf, length) \ + NRF_DRV_SPI_SINGLE_XFER(p_buf, length, NULL, 0) + +/** + * @brief Macro for setting RX transfer. + */ +#define NRF_DRV_SPI_XFER_RX(p_buf, length) \ + NRF_DRV_SPI_SINGLE_XFER(NULL, 0, p_buf, length) + +/** + * @brief SPI master driver event types, passed to the handler routine provided + * during initialization. + */ +typedef enum +{ + NRF_DRV_SPI_EVENT_DONE, ///< Transfer done. +} nrf_drv_spi_evt_type_t; + +typedef struct +{ + nrf_drv_spi_evt_type_t type; ///< Event type. + union + { + nrf_drv_spi_xfer_desc_t done; ///< Event data for DONE event. + } data; +} nrf_drv_spi_evt_t; + +/** + * @brief SPI master driver event handler type. + */ +typedef void (* nrf_drv_spi_evt_handler_t)(nrf_drv_spi_evt_t const * p_event, + void * p_context); + +/** + * @brief Function for initializing the SPI master driver instance. + * + * This function configures and enables the specified peripheral. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_config Pointer to the structure with the initial configuration. + * If NULL, the default configuration is used. + * @param handler Event handler provided by the user. If NULL, transfers + * will be performed in blocking mode. + * @param p_context Context passed to event handler. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver was already initialized. + * @retval NRF_ERROR_BUSY If some other peripheral with the same + * instance ID is already in use. This is + * possible only if PERIPHERAL_RESOURCE_SHARING_ENABLED + * is set to a value other than zero. + */ +ret_code_t nrf_drv_spi_init(nrf_drv_spi_t const * const p_instance, + nrf_drv_spi_config_t const * p_config, + nrf_drv_spi_evt_handler_t handler, + void * p_context); + +/** + * @brief Function for uninitializing the SPI master driver instance. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_spi_uninit(nrf_drv_spi_t const * const p_instance); + +/** + * @brief Function for starting the SPI data transfer. + * + * If an event handler was provided in the @ref nrf_drv_spi_init call, this function + * returns immediately and the handler is called when the transfer is done. + * Otherwise, the transfer is performed in blocking mode, which means that this function + * returns when the transfer is finished. + * + * @note Peripherals using EasyDMA (for example, SPIM) require the transfer buffers + * to be placed in the Data RAM region. If they are not and an SPIM instance is + * used, this function will fail with the error code NRF_ERROR_INVALID_ADDR. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_tx_buffer Pointer to the transmit buffer. Can be NULL + * if there is nothing to send. + * @param tx_buffer_length Length of the transmit buffer. + * @param[in] p_rx_buffer Pointer to the receive buffer. Can be NULL + * if there is nothing to receive. + * @param rx_buffer_length Length of the receive buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_BUSY If a previously started transfer has not finished + * yet. + * @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed in the Data + * RAM region. + */ +ret_code_t nrf_drv_spi_transfer(nrf_drv_spi_t const * const p_instance, + uint8_t const * p_tx_buffer, + uint8_t tx_buffer_length, + uint8_t * p_rx_buffer, + uint8_t rx_buffer_length); + +/** + * @brief Function for starting the SPI data transfer with additional option flags. + * + * Function enables customizing the transfer by using option flags. + * + * Additional options are provided using the flags parameter: + * + * - @ref NRF_DRV_SPI_FLAG_TX_POSTINC and @ref NRF_DRV_SPI_FLAG_RX_POSTINC: + * Post-incrementation of buffer addresses. Supported only by SPIM. + * - @ref NRF_DRV_SPI_FLAG_HOLD_XFER: Driver is not starting the transfer. Use this + * flag if the transfer is triggered externally by PPI. Supported only by SPIM. Use + * @ref nrf_drv_spi_start_task_get to get the address of the start task. + * - @ref NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER: No user event handler after transfer + * completion. This also means no interrupt at the end of the transfer. Supported only by SPIM. + * If @ref NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER is used, the driver does not set the instance into + * busy state, so you must ensure that the next transfers are set up when SPIM is not active. + * @ref nrf_drv_spi_end_event_get function can be used to detect end of transfer. Option can be used + * together with @ref NRF_DRV_SPI_FLAG_REPEATED_XFER to prepare a sequence of SPI transfers + * without interruptions. + * - @ref NRF_DRV_SPI_FLAG_REPEATED_XFER: Prepare for repeated transfers. You can set + * up a number of transfers that will be triggered externally (for example by PPI). An example is + * a TXRX transfer with the options @ref NRF_DRV_SPI_FLAG_RX_POSTINC, + * @ref NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER, and @ref NRF_DRV_SPI_FLAG_REPEATED_XFER. After the + * transfer is set up, a set of transfers can be triggered by PPI that will read, for example, + * the same register of an external component and put it into a RAM buffer without any interrupts. + * @ref nrf_drv_spi_end_event_get can be used to get the address of the END event, which can be + * used to count the number of transfers. If @ref NRF_DRV_SPI_FLAG_REPEATED_XFER is used, + * the driver does not set the instance into busy state, so you must ensure that the next + * transfers are set up when SPIM is not active. Supported only by SPIM. + * @note Function is intended to be used only in non-blocking mode. + * + * @param p_instance Pointer to the driver instance structure. + * @param p_xfer_desc Pointer to the transfer descriptor. + * @param flags Transfer options (0 for default settings). + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. + * @retval NRF_ERROR_NOT_SUPPORTED If the provided parameters are not supported. + * @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed in the Data + * RAM region. + */ +ret_code_t nrf_drv_spi_xfer(nrf_drv_spi_t const * const p_instance, + nrf_drv_spi_xfer_desc_t const * p_xfer_desc, + uint32_t flags); + +/** + * @brief Function for returning the address of a SPIM start task. + * + * This function should be used if @ref nrf_drv_spi_xfer was called with the flag @ref NRF_DRV_SPI_FLAG_HOLD_XFER. + * In that case, the transfer is not started by the driver, but it must be started externally by PPI. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @return Start task address. + */ +uint32_t nrf_drv_spi_start_task_get(nrf_drv_spi_t const * p_instance); + +/** + * @brief Function for returning the address of a END SPIM event. + * + * A END event can be used to detect the end of a transfer if the @ref NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER + * option is used. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @return END event address. + */ +uint32_t nrf_drv_spi_end_event_get(nrf_drv_spi_t const * p_instance); + +/** + * @brief Function for aborting ongoing transfer. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_spi_abort(nrf_drv_spi_t const * p_instance); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_SPI_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_master/spi_5W_master.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_master/spi_5W_master.c new file mode 100644 index 0000000000000000000000000000000000000000..c8ac4169d536218a035efbce702a97daabdfa257 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_master/spi_5W_master.c @@ -0,0 +1,629 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ser_phy_spi_5W_hw_driver_master spi_5W_master.c + * @{ + * @ingroup ser_phy_spi_5W_hw_driver_master + * + * @brief SPI_5W_RAW hardware driver. + */ + +#include "app_error.h" +#include "app_util_platform.h" +#include "nrf_gpio.h" +#include "nrf.h" +#include "spi_5W_master.h" +#include "ser_config_5W_app.h" +#include "ser_phy_debug_app.h" +#include "sdk_common.h" + + +#define _static + +#define DOUBLE_BUFFERED /**< A flag for enabling double buffering. */ + +#define SPI_PIN_DISCONNECTED 0xFFFFFFFF /**< A value used to the PIN deinitialization. */ +#define SPI_DEFAULT_TX_BYTE 0x00 /**< Default byte (used to clock transmission + from slave to the master) */ + +typedef struct +{ + NRF_SPI_Type * p_nrf_spi; /**< A pointer to the NRF SPI master */ + IRQn_Type irq_type; /**< A type of NVIC IRQn */ + + uint8_t * p_tx_buffer; /**< A pointer to TX buffer. */ + uint16_t tx_length; /**< A length of TX buffer. */ + uint16_t tx_index; /**< A index of the current element in the TX buffer. */ + + uint8_t * p_rx_buffer; /**< A pointer to RX buffer. */ + uint16_t rx_length; /**< A length RX buffer. */ + uint16_t rx_index; /**< A index of the current element in the RX buffer. */ + + uint16_t max_length; /**< Max length (Max of the TX and RX length). */ + uint16_t bytes_count; + uint8_t pin_slave_select; /**< A pin for Slave Select. */ + + spi_master_event_handler_t callback_event_handler; /**< A handler for event callback function. */ + spi_master_state_t state; /**< A state of an instance of SPI master. */ + bool start_flag; + bool abort_flag; + +} spi_master_instance_t; + +#ifdef _SPI_5W_ +typedef enum +{ + HOOK_STATE_DISABLED, + HOOK_STATE_IDLE, + HOOK_STATE_GUARDED, + HOOK_STATE_ABORTED, + HOOK_STATE_RESTARTED, + HOOK_STATE_PASSING +} spi_hook_state_t; + + +_static spi_master_event_handler_t m_ser_phy_event_handler; +_static spi_master_hw_instance_t m_spi_master_hw_instance; +_static spi_hook_state_t m_hook_state = HOOK_STATE_DISABLED; +#endif + +#ifdef SER_PHY_DEBUG_APP_ENABLE +_static spi_master_raw_callback_t m_debug_callback; +#endif + +_static spi_master_instance_t m_spi_master_instances[SPI_MASTER_HW_ENABLED_COUNT]; + +static __INLINE spi_master_instance_t * spi_master_get_instance( + const spi_master_hw_instance_t spi_master_hw_instance); +static __INLINE void spi_master_send_recv_irq(spi_master_instance_t * const p_spi_instance); +static __INLINE void spi_master_signal_evt(spi_master_instance_t * const p_spi_instance, + spi_master_evt_type_t event_type, + const uint16_t data); + +#ifdef SPI_MASTER_0_ENABLE +/** + * @brief SPI0 interrupt handler. + */ +void SPI0_TWI0_IRQHandler(void) +{ + if (NRF_SPI0->EVENTS_READY != 0) + { + NRF_SPI0->EVENTS_READY = 0; + + spi_master_instance_t * p_spi_instance = spi_master_get_instance(SPI_MASTER_0); + + spi_master_send_recv_irq(p_spi_instance); + } +} +#endif //SPI_MASTER_0_ENABLE + +#ifdef SPI_MASTER_1_ENABLE +/** + * @brief SPI0 interrupt handler. + */ +void SPI1_TWI1_IRQHandler(void) +{ + if (NRF_SPI1->EVENTS_READY != 0) + { + NRF_SPI1->EVENTS_READY = 0; + + spi_master_instance_t * p_spi_instance = spi_master_get_instance(SPI_MASTER_1); + + spi_master_send_recv_irq(p_spi_instance); + } +} +#endif //SPI_MASTER_1_ENABLE + +#if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) + +/**@brief Function for getting an instance of SPI master. */ +static __INLINE spi_master_instance_t * spi_master_get_instance( + const spi_master_hw_instance_t spi_master_hw_instance) +{ + return &(m_spi_master_instances[(uint8_t)spi_master_hw_instance]); +} + +/** @brief Function for initializing instance of SPI master by default values. */ +static __INLINE void spi_master_init_hw_instance(NRF_SPI_Type * p_nrf_spi, + IRQn_Type irq_type, + spi_master_instance_t * p_spi_instance) +{ + APP_ERROR_CHECK_BOOL(p_spi_instance != NULL); + + p_spi_instance->p_nrf_spi = p_nrf_spi; + p_spi_instance->irq_type = irq_type; + + p_spi_instance->p_tx_buffer = NULL; + p_spi_instance->tx_length = 0; + p_spi_instance->tx_index = 0; + + p_spi_instance->p_rx_buffer = NULL; + p_spi_instance->rx_length = 0; + p_spi_instance->rx_index = 0; + + p_spi_instance->bytes_count = 0; + p_spi_instance->max_length = 0; + p_spi_instance->pin_slave_select = 0; + + p_spi_instance->callback_event_handler = NULL; + + p_spi_instance->state = SPI_MASTER_STATE_DISABLED; + p_spi_instance->abort_flag = false; + p_spi_instance->start_flag = false; +} + +/**@brief Function for initializing TX or RX buffer. */ +static __INLINE void spi_master_buffer_init(uint8_t * const p_buf, + const uint16_t buf_len, + uint8_t * * pp_buf, + uint16_t * const p_buf_len, + uint16_t * const p_index) +{ + APP_ERROR_CHECK_BOOL(pp_buf != NULL); + APP_ERROR_CHECK_BOOL(p_buf_len != NULL); + APP_ERROR_CHECK_BOOL(p_index != NULL); + + *pp_buf = p_buf; + *p_buf_len = (p_buf != NULL) ? buf_len : 0; + *p_index = 0; +} + +/**@brief Function for releasing TX or RX buffer. */ +static __INLINE void spi_master_buffer_release(uint8_t * * const pp_buf, uint16_t * const p_buf_len) +{ + APP_ERROR_CHECK_BOOL(pp_buf != NULL); + APP_ERROR_CHECK_BOOL(p_buf_len != NULL); + + *pp_buf = NULL; + *p_buf_len = 0; +} + +/**@brief Function for sending events by callback. */ +static __INLINE void spi_master_signal_evt(spi_master_instance_t * const p_spi_instance, + spi_master_evt_type_t event_type, + const uint16_t data) +{ + APP_ERROR_CHECK_BOOL(p_spi_instance != NULL); + + if (p_spi_instance->callback_event_handler != NULL) + { + spi_master_evt_t event = {SPI_MASTER_EVT_TYPE_MAX, 0}; + event.type = event_type; + event.data = data; + p_spi_instance->callback_event_handler(event); + } +} + +/**@brief Function insert to a TX buffer another byte or two bytes (depends on flag @ref DOUBLE_BUFFERED). */ +static __INLINE void spi_master_send_initial_bytes(spi_master_instance_t * const p_spi_instance) +{ + APP_ERROR_CHECK_BOOL(p_spi_instance != NULL); + + p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) && + (p_spi_instance->tx_index < p_spi_instance->tx_length)) ? + p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] : + SPI_DEFAULT_TX_BYTE; + (p_spi_instance->tx_index)++; + + #ifdef DOUBLE_BUFFERED + + if (p_spi_instance->tx_index < p_spi_instance->max_length) + { + p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) && + (p_spi_instance->tx_index < p_spi_instance->tx_length)) ? + p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] : + SPI_DEFAULT_TX_BYTE; + (p_spi_instance->tx_index)++; + } + #endif +} + +/**@brief Function for receiving and sending data from IRQ. (The same for both IRQs). */ +static __INLINE void spi_master_send_recv_irq(spi_master_instance_t * const p_spi_instance) +{ + + uint8_t rx_byte; + + APP_ERROR_CHECK_BOOL(p_spi_instance != NULL); + APP_ERROR_CHECK_BOOL(p_spi_instance->state == SPI_MASTER_STATE_BUSY); + + p_spi_instance->bytes_count++; + rx_byte = p_spi_instance->p_nrf_spi->RXD; + + if (p_spi_instance->start_flag) + { + p_spi_instance->start_flag = false; + spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_FIRST_BYTE_RECEIVED, (uint16_t)rx_byte); + } + else if (p_spi_instance->abort_flag ) //this is tricky, but callback for SPI_MASTER_EVT_FIRST_BYTE_RECEIVED will set this flag for a first byte, which is bad because there is still byte in a buffer + { //and for a single byte transaction you will get XFERDONE event to restart + p_spi_instance->abort_flag = false; + p_spi_instance->state = SPI_MASTER_STATE_ABORTED; + nrf_gpio_pin_set(p_spi_instance->pin_slave_select); + spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_ABORTED, 0); + return; + } + + if ((p_spi_instance->p_rx_buffer != NULL) && + (p_spi_instance->rx_index < p_spi_instance->rx_length)) + { + p_spi_instance->p_rx_buffer[p_spi_instance->rx_index++] = rx_byte; + } + + if ((p_spi_instance->tx_index < p_spi_instance->max_length) && (!(p_spi_instance->abort_flag))) //do not TX if you know that there is an abort to be done - this should work for a DOUBLE BUFFERING ??? + { + p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) && + (p_spi_instance->tx_index < p_spi_instance->tx_length)) ? + p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] : + SPI_DEFAULT_TX_BYTE; + (p_spi_instance->tx_index)++; + } + + if (p_spi_instance->bytes_count >= p_spi_instance->max_length) + { + APP_ERROR_CHECK_BOOL(p_spi_instance->bytes_count == p_spi_instance->max_length); + nrf_gpio_pin_set(p_spi_instance->pin_slave_select); + p_spi_instance->state = SPI_MASTER_STATE_IDLE; + spi_master_signal_evt(p_spi_instance, + SPI_MASTER_EVT_TRANSFER_COMPLETED, + p_spi_instance->tx_index); + } + return; +} +#endif //defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) + + +/** + * @brief Function for opening and initializing a SPI master driver. */ +uint32_t spi_master_open(const spi_master_hw_instance_t spi_master_hw_instance, + spi_master_config_t const * const p_spi_master_config) +{ + #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) + + + VERIFY_PARAM_NOT_NULL(p_spi_master_config); + + spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance); + + switch (spi_master_hw_instance) + { + #ifdef SPI_MASTER_0_ENABLE + case SPI_MASTER_0: + spi_master_init_hw_instance(NRF_SPI0, SPI0_TWI0_IRQn, p_spi_instance); + break; + #endif //SPI_MASTER_0_ENABLE + + #ifdef SPI_MASTER_1_ENABLE + case SPI_MASTER_1: + spi_master_init_hw_instance(NRF_SPI1, SPI1_TWI1_IRQn, p_spi_instance); + break; + #endif //SPI_MASTER_1_ENABLE + + default: + break; + } + + //A Slave select must be set as high before setting it as output, + //because during connect it to the pin it causes glitches. + nrf_gpio_pin_set(p_spi_master_config->SPI_Pin_SS); + nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_SS); + nrf_gpio_pin_set(p_spi_master_config->SPI_Pin_SS); + + //Configure GPIO + nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_SCK); + nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_MOSI); + nrf_gpio_cfg_input(p_spi_master_config->SPI_Pin_MISO, NRF_GPIO_PIN_NOPULL); + p_spi_instance->pin_slave_select = p_spi_master_config->SPI_Pin_SS; + + /* Configure SPI hardware */ + p_spi_instance->p_nrf_spi->PSELSCK = p_spi_master_config->SPI_Pin_SCK; + p_spi_instance->p_nrf_spi->PSELMOSI = p_spi_master_config->SPI_Pin_MOSI; + p_spi_instance->p_nrf_spi->PSELMISO = p_spi_master_config->SPI_Pin_MISO; + + p_spi_instance->p_nrf_spi->FREQUENCY = p_spi_master_config->SPI_Freq; + + p_spi_instance->p_nrf_spi->CONFIG = + (uint32_t)(p_spi_master_config->SPI_CPHA << SPI_CONFIG_CPHA_Pos) | + (p_spi_master_config->SPI_CPOL << SPI_CONFIG_CPOL_Pos) | + (p_spi_master_config->SPI_ORDER << SPI_CONFIG_ORDER_Pos); + + + /* Clear waiting interrupts and events */ + p_spi_instance->p_nrf_spi->EVENTS_READY = 0; + + NVIC_ClearPendingIRQ(p_spi_instance->irq_type); + NVIC_SetPriority(p_spi_instance->irq_type, APP_IRQ_PRIORITY_MID); + + /* Clear event handler */ + p_spi_instance->callback_event_handler = NULL; + + /* Enable interrupt */ + p_spi_instance->p_nrf_spi->INTENSET = (SPI_INTENSET_READY_Set << SPI_INTENCLR_READY_Pos); + NVIC_EnableIRQ(p_spi_instance->irq_type); + + /* Enable SPI hardware */ + p_spi_instance->p_nrf_spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos); + + /* Change state to IDLE */ + p_spi_instance->state = SPI_MASTER_STATE_IDLE; + + return NRF_SUCCESS; + #else + return NRF_ERROR_NOT_SUPPORTED; + #endif +} + +/** + * @brief Function for closing a SPI master driver. + */ +void spi_master_close(const spi_master_hw_instance_t spi_master_hw_instance) +{ + #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) + spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance); + + /* Disable interrupt */ + NVIC_ClearPendingIRQ(p_spi_instance->irq_type); + NVIC_DisableIRQ(p_spi_instance->irq_type); + + p_spi_instance->p_nrf_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos); + + /* Set Slave Select pin as input with pull-up. */ + nrf_gpio_pin_set(p_spi_instance->pin_slave_select); + nrf_gpio_cfg_input(p_spi_instance->pin_slave_select, NRF_GPIO_PIN_PULLUP); + p_spi_instance->pin_slave_select = (uint8_t)0xFF; + + /* Disconnect pins from SPI hardware */ + p_spi_instance->p_nrf_spi->PSELSCK = (uint32_t)SPI_PIN_DISCONNECTED; + p_spi_instance->p_nrf_spi->PSELMOSI = (uint32_t)SPI_PIN_DISCONNECTED; + p_spi_instance->p_nrf_spi->PSELMISO = (uint32_t)SPI_PIN_DISCONNECTED; + + /* Reset to default values */ + spi_master_init_hw_instance(NULL, (IRQn_Type)0, p_spi_instance); + #else + return; + #endif +} + +/** + * @brief Function for getting current state of the SPI master driver. + */ +__INLINE spi_master_state_t spi_master_get_state( + const spi_master_hw_instance_t spi_master_hw_instance) +{ + #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) + spi_master_instance_t * spi_instance = spi_master_get_instance(spi_master_hw_instance); + return spi_instance->state; + #else + return SPI_MASTER_STATE_DISABLED; + #endif +} + +/** + * @brief Function for event handler registration. + */ +__INLINE void spi_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance, + spi_master_event_handler_t event_handler) +{ + #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) + spi_master_instance_t * spi_instance = spi_master_get_instance(spi_master_hw_instance); + spi_instance->callback_event_handler = event_handler; + #else + return; + #endif +} + +/** + * @brief Function for transmitting data between SPI master and SPI slave. + */ +uint32_t spi_master_send_recv(const spi_master_hw_instance_t spi_master_hw_instance, + uint8_t * const p_tx_buf, const uint16_t tx_buf_len, + uint8_t * const p_rx_buf, const uint16_t rx_buf_len) +{ + #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) + spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance); + + uint32_t err_code = NRF_SUCCESS; + uint16_t max_length = 0; + + if (p_spi_instance->state == SPI_MASTER_STATE_IDLE) + { + NVIC_DisableIRQ(p_spi_instance->irq_type); + + max_length = (rx_buf_len > tx_buf_len) ? rx_buf_len : tx_buf_len; + + if (max_length > 0) + { + p_spi_instance->state = SPI_MASTER_STATE_BUSY; + p_spi_instance->start_flag = true; //abort_flag should set by abort and cleared only by restart + p_spi_instance->bytes_count = 0; + p_spi_instance->max_length = max_length; + spi_master_buffer_release(&(p_spi_instance->p_tx_buffer), &(p_spi_instance->tx_length)); + spi_master_buffer_release(&(p_spi_instance->p_rx_buffer), &(p_spi_instance->rx_length)); + /* Initialize buffers */ + spi_master_buffer_init(p_tx_buf, tx_buf_len, &(p_spi_instance->p_tx_buffer), + &(p_spi_instance->tx_length), &(p_spi_instance->tx_index)); + spi_master_buffer_init(p_rx_buf, rx_buf_len, &(p_spi_instance->p_rx_buffer), + &(p_spi_instance->rx_length), &(p_spi_instance->rx_index)); + nrf_gpio_pin_clear(p_spi_instance->pin_slave_select); + spi_master_send_initial_bytes(p_spi_instance); + spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_STARTED, max_length); + } + else + { + err_code = NRF_ERROR_INVALID_PARAM; + } + + NVIC_EnableIRQ(p_spi_instance->irq_type); + } + else + { + err_code = NRF_ERROR_BUSY; + } + + return err_code; + #else + return NRF_ERROR_NOT_SUPPORTED; + #endif +} + +#ifdef _SPI_5W_ + +/** + * @brief Function for aborting transfer + */ +uint32_t spi_master_abort(const spi_master_hw_instance_t spi_master_hw_instance) +{ + spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance); + + NVIC_DisableIRQ(p_spi_instance->irq_type); + + if (p_spi_instance->state == SPI_MASTER_STATE_BUSY) + { + //set_flag - but only when there are events pending + //ignore when in IDLE - must be able to restart a completed transfer + p_spi_instance->abort_flag = true; + } + NVIC_EnableIRQ(p_spi_instance->irq_type); + return NRF_SUCCESS; +} + +/** + * @brief Function for restarting transfer + */ +uint32_t spi_master_restart(const spi_master_hw_instance_t spi_master_hw_instance) +{ + spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance); + + NVIC_DisableIRQ(p_spi_instance->irq_type); + spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_RESTARTED, 0); + p_spi_instance->state = SPI_MASTER_STATE_BUSY; + p_spi_instance->bytes_count = 0; + p_spi_instance->tx_index = 0; + p_spi_instance->rx_index = 0; + p_spi_instance->start_flag = true; + p_spi_instance->abort_flag = false; //you should force clearing abort flag - no other way for 1 byte transfer + nrf_gpio_pin_clear(p_spi_instance->pin_slave_select); + spi_master_send_initial_bytes(p_spi_instance); + NVIC_EnableIRQ(p_spi_instance->irq_type); + + return NRF_SUCCESS; +} + +static void spi_5W_master_event_handler(spi_master_evt_t evt) +{ + + switch (m_hook_state) + { + case HOOK_STATE_IDLE: + + if (evt.type == SPI_MASTER_EVT_TRANSFER_STARTED) + { + DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(0); + m_hook_state = HOOK_STATE_GUARDED; + m_ser_phy_event_handler(evt); + } + break; + + case HOOK_STATE_GUARDED: + + if (evt.type == SPI_MASTER_EVT_FIRST_BYTE_RECEIVED) + { + if (evt.data == 0) + { + DEBUG_EVT_SPI_MASTER_RAW_XFER_PASSED(0); + m_hook_state = HOOK_STATE_PASSING; + } + else + { + DEBUG_EVT_SPI_MASTER_RAW_XFER_ABORTED(0); + m_hook_state = HOOK_STATE_ABORTED; + (void)spi_master_abort(m_spi_master_hw_instance); + } + } + break; + + case HOOK_STATE_ABORTED: + + if ((evt.type == SPI_MASTER_EVT_TRANSFER_ABORTED) || + (evt.type == SPI_MASTER_EVT_TRANSFER_COMPLETED)) + { + DEBUG_EVT_SPI_MASTER_RAW_XFER_RESTARTED(0); + m_hook_state = HOOK_STATE_RESTARTED; + (void)spi_master_restart(m_spi_master_hw_instance); + } + break; + + case HOOK_STATE_RESTARTED: + + if (evt.type == SPI_MASTER_EVT_TRANSFER_RESTARTED) + { + DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(0); + m_hook_state = HOOK_STATE_GUARDED; + } + break; + + case HOOK_STATE_PASSING: + + if (evt.type == SPI_MASTER_EVT_TRANSFER_COMPLETED) + { + m_hook_state = HOOK_STATE_IDLE; + m_ser_phy_event_handler(evt); //this is the only way to get a signal from complete transaction + } + break; + + default: + break; + } +} + +void spi_5W_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance, + spi_master_event_handler_t event_handler) +{ + m_ser_phy_event_handler = event_handler; + m_spi_master_hw_instance = spi_master_hw_instance; + m_hook_state = HOOK_STATE_IDLE; + spi_master_evt_handler_reg(spi_master_hw_instance, spi_5W_master_event_handler); + return; +} + +#endif + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_master/spi_5W_master.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_master/spi_5W_master.h new file mode 100644 index 0000000000000000000000000000000000000000..7b827bf019bed0ca81dbefe59725bbdbf191704e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_master/spi_5W_master.h @@ -0,0 +1,206 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_SPI_MASTER_H +#define APP_SPI_MASTER_H + +#include +#include +#include "boards.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define _SPI_5W_ + +/**@brief Struct containing configuration parameters of the SPI master. */ +typedef struct +{ + uint32_t SPI_Freq; /**< SPI frequency. */ + uint32_t SPI_Pin_SCK; /**< SCK pin number. */ + uint32_t SPI_Pin_MISO; /**< MISO pin number. */ + uint32_t SPI_Pin_MOSI; /**< MOSI pin number .*/ + uint32_t SPI_Pin_SS; /**< Slave select pin number. */ + uint8_t SPI_ORDER; /**< Bytes order MSBFIRST or LSBFIRST. */ + uint8_t SPI_CPOL; /**< Serial clock polarity ACTIVEHIGH or ACTIVELOW. */ + uint8_t SPI_CPHA; /**< Serial clock phase LEADING or TRAILING. */ + } spi_master_config_t; + +/**@brief SPI master driver events types. */ +typedef enum +{ + SPI_MASTER_EVT_TRANSFER_STARTED = 0, /**< An event indicating that transfer has been started */ + SPI_MASTER_EVT_TRANSFER_COMPLETED, /**< An event indicating that transfer has been completed */ + SPI_MASTER_EVT_TRANSFER_ABORTED, /**< An event indicating that transfer has been aborted */ + SPI_MASTER_EVT_TRANSFER_RESTARTED, /**< An event indicating that transfer has been resumed */ + SPI_MASTER_EVT_FIRST_BYTE_RECEIVED, /**< An event indicating end of one byte transfer */ + SPI_MASTER_EVT_TYPE_MAX /**< Enumeration upper bound. */ +} spi_master_evt_type_t; + +/**@brief Struct containing parameters of the SPI MASTER event */ + typedef struct + { + spi_master_evt_type_t type; /**< Type of an event */ + uint16_t data; /**< event data - context dependent */ + } spi_master_evt_t; + + /**@brief SPI MASTER internal states types. */ + typedef enum + { + SPI_MASTER_STATE_DISABLED, /**< A state indicating that SPI master is disabled. */ + SPI_MASTER_STATE_BUSY, /**< A state indicating that SPI master is sending now. */ + SPI_MASTER_STATE_ABORTED, + SPI_MASTER_STATE_IDLE /**< A state indicating that SPI master is idle now. */ + } spi_master_state_t; + + /**@brief Instances of SPI master module. */ + typedef enum + { + #ifdef SPI_MASTER_0_ENABLE + SPI_MASTER_0, /**< A instance of SPI master 0. */ + #endif + + #ifdef SPI_MASTER_1_ENABLE + SPI_MASTER_1, /**< A instance of SPI master 1. */ + #endif + + SPI_MASTER_HW_ENABLED_COUNT /**< A number of enabled instances of SPI master. */ + } spi_master_hw_instance_t; + +/**@brief Type of generic callback function handler to be used by all SPI MASTER driver events. + * + * @param[in] spi_master_evt SPI MASTER driver event. + */ +typedef void (*spi_master_event_handler_t) (spi_master_evt_t spi_master_evt); + + +/**@brief Function for opening and initializing a SPI master driver. + * + * @note Function initializes SPI master hardware and internal module states, unregister events callback. + * + * @warning If the function has been already called, the function @ref spi_master_close has to be + * called before spi_master_open can be called again. + * + * @param[in] spi_master_hw_instance Instance of SPI master module. + * @param[in] p_spi_master_config Pointer to configuration structure which will be used + * to initialize SPI MASTER hardware. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called. + * To call it again the function @ref spi_master_close + * has to be called previously. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + */ +uint32_t spi_master_open(const spi_master_hw_instance_t spi_master_hw_instance, + spi_master_config_t const * const p_spi_master_config); + + +/**@brief Function for closing a SPI MASTER driver. + * + * @note Function disable hardware, reset internal module states and unregister events callback + * function. + * + * @param[in] spi_master_hw_instance A instance of SPI master. + */ +void spi_master_close(const spi_master_hw_instance_t spi_master_hw_instance); + + +/**@brief Function for transferring data between SPI master and SPI slave + * + * @note Function registers buffers pointed by p_tx_buf and p_rx_buf parameters, after that starts transmission. + * Function generates an event of type @ref SPI_MASTER_EVT_TRANSFER_STARTED when transfer has been started + * and @ref SPI_MASTER_EVT_TRANSFER_COMPLETED when transfer has been completed. + * + * @param[in] spi_master_hw_instance Instance of SPI master module. + * @param[in] p_tx_buf Pointer to a transmit buffer. + * @param[in] tx_buf_len Number of octets to the transfer. + * @param[out] p_rx_buf Pointer to a receive buffer. + * @param[in] rx_buf_len Number of octets to be received. + * + * @retval NRF_SUCCESS Operation success. Packet was registered to the transmission + * and event will be send upon transmission completion. + * @retval NRF_ERROR_BUSY Operation failure. Transmitting of a data is in progress. + */ + uint32_t spi_master_send_recv(const spi_master_hw_instance_t spi_master_hw_instance, + uint8_t * const p_tx_buf, const uint16_t tx_buf_len, + uint8_t * const p_rx_buf, const uint16_t rx_buf_len); + + +/**@brief Function for registration event handler. +* +* @note Function registers a event handler to be used by SPI MASTER driver for sending events. +* @ref SPI_MASTER_EVT_TRANSFER_STARTED and @ref SPI_MASTER_EVT_TRANSFER_COMPLETED. +* +* @param[in] spi_master_hw_instance Instance of SPI master module. +* @param[in] event_handler Generic callback function handler to be used +* by all SPI master driver events. +*/ +void spi_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance, + spi_master_event_handler_t event_handler); + + +/**@brief Function for getting current state of the SPI master driver. + * + * @note Function gets current state of the SPI master driver. + * + * @param[in] spi_master_hw_instance Instance of SPI master module. + * + * @retval SPI_MASTER_STATE_DISABLED SPI MASTER is disabled. + * @retval SPI_MASTER_STATE_BUSY SPI_MASTER is sending now. + * @retval SPI_MASTER_STATE_IDLE SPI_MASTER is idle now. + */ +spi_master_state_t spi_master_get_state(const spi_master_hw_instance_t spi_master_hw_instance); + +#ifdef _SPI_5W_ + +uint32_t spi_master_abort(const spi_master_hw_instance_t spi_master_hw_instance); + +uint32_t spi_master_restart(const spi_master_hw_instance_t spi_master_hw_instance); + +void spi_5W_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance, + spi_master_event_handler_t event_handler); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_slave/nrf_drv_spis.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_slave/nrf_drv_spis.c new file mode 100644 index 0000000000000000000000000000000000000000..4d1409f863586682a3195c906f4f7835fc03240d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_slave/nrf_drv_spis.c @@ -0,0 +1,495 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(SPIS) +#define ENABLED_SPIS_COUNT (SPIS0_ENABLED+SPIS1_ENABLED+SPIS2_ENABLED) +#if ENABLED_SPIS_COUNT +#include "nrf_drv_spis.h" +#include +#include +#include "nrf.h" +#include "nrf_gpio.h" +#include "app_error.h" +#include "app_util_platform.h" +#include "nrf_drv_common.h" +#include "nrf_assert.h" + +#define NRF_LOG_MODULE_NAME "SPIS" + +#if SPIS_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL SPIS_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR SPIS_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR SPIS_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) \ + (event == NRF_SPIS_EVENT_ACQUIRED ? "NRF_SPIS_EVENT_ACQUIRED" : \ + (event == NRF_SPIS_EVENT_END ? "NRF_SPIS_EVENT_END" : \ + "UNKNOWN ERROR")) + +#else //SPIS_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //SPIS_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +#if NRF_MODULE_ENABLED(SPIS_NRF52_ANOMALY_109_WORKAROUND) +#include "nrf_drv_gpiote.h" +#define USE_DMA_ISSUE_WORKAROUND +// This handler is called by the GPIOTE driver when a falling edge is detected +// on the CSN line. There is no need to do anything here. The handling of the +// interrupt itself provides a protection for DMA transfers. +static void csn_event_handler(nrf_drv_gpiote_pin_t pin, + nrf_gpiote_polarity_t action) +{ +} +#endif + + +/**@brief States of the SPI transaction state machine. */ +typedef enum +{ + SPIS_STATE_INIT, /**< Initialization state. In this state the module waits for a call to @ref spi_slave_buffers_set. */ + SPIS_BUFFER_RESOURCE_REQUESTED, /**< State where the configuration of the memory buffers, which are to be used in SPI transaction, has started. */ + SPIS_BUFFER_RESOURCE_CONFIGURED, /**< State where the configuration of the memory buffers, which are to be used in SPI transaction, has completed. */ + SPIS_XFER_COMPLETED /**< State where SPI transaction has been completed. */ +} nrf_drv_spis_state_t; + + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + #define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n + #define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void) + + #if NRF_MODULE_ENABLED(SPIS0) + IRQ_HANDLER(0); + #endif + #if NRF_MODULE_ENABLED(SPIS1) + IRQ_HANDLER(1); + #endif + #if NRF_MODULE_ENABLED(SPIS2) + IRQ_HANDLER(2); + #endif + static nrf_drv_irq_handler_t const m_irq_handlers[ENABLED_SPIS_COUNT] = { + #if NRF_MODULE_ENABLED(SPIS0) + IRQ_HANDLER_NAME(0), + #endif + #if NRF_MODULE_ENABLED(SPIS1) + IRQ_HANDLER_NAME(1), + #endif + #if NRF_MODULE_ENABLED(SPIS2) + IRQ_HANDLER_NAME(2), + #endif + }; +#else + #define IRQ_HANDLER(n) void SPIS##n##_IRQ_HANDLER(void) +#endif // PERIPHERAL_RESOURCE_SHARING_ENABLED + +#define SPIS_IRQHANDLER_TEMPLATE(NUM) \ + IRQ_HANDLER(NUM) \ + { \ + spis_irq_handler(NRF_SPIS##NUM, &m_cb[SPIS##NUM##_INSTANCE_INDEX]); \ + } + + +/**@brief SPIS control block - driver instance local data. */ +typedef struct +{ + volatile uint32_t tx_buffer_size; //!< SPI slave TX buffer size in bytes. + volatile uint32_t rx_buffer_size; //!< SPI slave RX buffer size in bytes. + nrf_drv_spis_event_handler_t handler; //!< SPI event handler. + volatile const uint8_t * tx_buffer; //!< SPI slave TX buffer. + volatile uint8_t * rx_buffer; //!< SPI slave RX buffer. + nrf_drv_state_t state; //!< driver initialization state. + volatile nrf_drv_spis_state_t spi_state; //!< SPI slave state. +} spis_cb_t; + +static spis_cb_t m_cb[ENABLED_SPIS_COUNT]; + +ret_code_t nrf_drv_spis_init(nrf_drv_spis_t const * const p_instance, + nrf_drv_spis_config_t const * p_config, + nrf_drv_spis_event_handler_t event_handler) +{ + ASSERT(p_config); + spis_cb_t * p_cb = &m_cb[p_instance->instance_id]; + ret_code_t err_code; + + NRF_SPIS_Type * p_spis = p_instance->p_reg; + + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + if ((uint32_t)p_config->mode > (uint32_t)NRF_DRV_SPIS_MODE_3) + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + if (!event_handler) + { + err_code = NRF_ERROR_NULL; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + if (nrf_drv_common_per_res_acquire(p_spis, + m_irq_handlers[p_instance->instance_id]) != NRF_SUCCESS) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } +#endif + + // Configure the SPI pins for input. + uint32_t mosi_pin; + uint32_t miso_pin; + + if (p_config->miso_pin != NRF_DRV_SPIS_PIN_NOT_USED) + { + nrf_gpio_cfg(p_config->miso_pin, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + NRF_GPIO_PIN_NOPULL, + p_config->miso_drive, + NRF_GPIO_PIN_NOSENSE); + miso_pin = p_config->miso_pin; + } + else + { + miso_pin = NRF_SPIS_PIN_NOT_CONNECTED; + } + + if (p_config->mosi_pin != NRF_DRV_SPIS_PIN_NOT_USED) + { + nrf_gpio_cfg(p_config->mosi_pin, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); + mosi_pin = p_config->mosi_pin; + } + else + { + mosi_pin = NRF_SPIS_PIN_NOT_CONNECTED; + } + + nrf_gpio_cfg(p_config->csn_pin, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + p_config->csn_pullup, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); + + nrf_gpio_cfg(p_config->sck_pin, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); + + nrf_spis_pins_set(p_spis, p_config->sck_pin, mosi_pin, miso_pin, p_config->csn_pin); + + nrf_spis_rx_buffer_set(p_spis, NULL, 0); + nrf_spis_tx_buffer_set(p_spis, NULL, 0); + + // Configure SPI mode. + nrf_spis_configure(p_spis, (nrf_spis_mode_t) p_config->mode, + (nrf_spis_bit_order_t) p_config->bit_order); + + // Configure DEF and ORC characters. + nrf_spis_def_set(p_spis, p_config->def); + nrf_spis_orc_set(p_spis, p_config->orc); + + // Clear possible pending events. + nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_END); + nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_ACQUIRED); + + // Enable END_ACQUIRE shortcut. + nrf_spis_shorts_enable(p_spis, NRF_SPIS_SHORT_END_ACQUIRE); + + m_cb[p_instance->instance_id].spi_state = SPIS_STATE_INIT; + m_cb[p_instance->instance_id].handler = event_handler; + +#if defined(USE_DMA_ISSUE_WORKAROUND) + // Configure a GPIOTE channel to generate interrupts on each falling edge + // on the CSN line. Handling of these interrupts will make the CPU active, + // and thus will protect the DMA transfers started by SPIS right after it + // is selected for communication. + // [the GPIOTE driver may be already initialized at this point (by this + // driver when another SPIS instance is used, or by an application code), + // so just ignore the returned value] + (void)nrf_drv_gpiote_init(); + static nrf_drv_gpiote_in_config_t const csn_gpiote_config = + GPIOTE_CONFIG_IN_SENSE_HITOLO(true); + ret_code_t gpiote_err_code = nrf_drv_gpiote_in_init(p_config->csn_pin, + &csn_gpiote_config, csn_event_handler); + if (gpiote_err_code != NRF_SUCCESS) + { + err_code = NRF_ERROR_INTERNAL; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + nrf_drv_gpiote_in_event_enable(p_config->csn_pin, true); +#endif + + // Enable IRQ. + nrf_spis_int_enable(p_spis, NRF_SPIS_INT_ACQUIRED_MASK | NRF_SPIS_INT_END_MASK); + nrf_drv_common_irq_enable(p_instance->irq, p_config->irq_priority); + + p_cb->state = NRF_DRV_STATE_INITIALIZED; + + // Enable SPI slave device. + nrf_spis_enable(p_spis); + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_spis_uninit(nrf_drv_spis_t const * const p_instance) +{ + spis_cb_t * p_cb = &m_cb[p_instance->instance_id]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + NRF_SPIS_Type * p_spis = p_instance->p_reg; + + #define DISABLE_ALL 0xFFFFFFFF + nrf_spis_disable(p_spis); + nrf_drv_common_irq_disable(p_instance->irq); + nrf_spis_int_disable(p_spis, DISABLE_ALL); + #undef DISABLE_ALL + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + nrf_drv_common_per_res_release(p_spis); +#endif + + p_cb->state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Initialized.\r\n"); +} + + +/**@brief Function for executing the state entry action. */ +static void spis_state_entry_action_execute(NRF_SPIS_Type * p_spis, + spis_cb_t * p_cb) +{ + nrf_drv_spis_event_t event; + + switch (p_cb->spi_state) + { + case SPIS_BUFFER_RESOURCE_REQUESTED: + nrf_spis_task_trigger(p_spis, NRF_SPIS_TASK_ACQUIRE); + break; + + case SPIS_BUFFER_RESOURCE_CONFIGURED: + event.evt_type = NRF_DRV_SPIS_BUFFERS_SET_DONE; + event.rx_amount = 0; + event.tx_amount = 0; + + APP_ERROR_CHECK_BOOL(p_cb->handler != NULL); + p_cb->handler(event); + break; + + case SPIS_XFER_COMPLETED: + event.evt_type = NRF_DRV_SPIS_XFER_DONE; + event.rx_amount = nrf_spis_rx_amount_get(p_spis); + event.tx_amount = nrf_spis_tx_amount_get(p_spis); + NRF_LOG_INFO("Transfer rx_len:%d.\r\n", event.rx_amount); + NRF_LOG_DEBUG("Rx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_cb->rx_buffer, + event.rx_amount * sizeof(p_cb->rx_buffer)); + APP_ERROR_CHECK_BOOL(p_cb->handler != NULL); + p_cb->handler(event); + break; + + default: + // No implementation required. + break; + } +} + +/**@brief Function for changing the state of the SPI state machine. + * + * @param[in] p_spis SPIS instance register. + * @param[in] p_cb SPIS instance control block. + * @param[in] new_state State where the state machine transits to. + */ +static void spis_state_change(NRF_SPIS_Type * p_spis, + spis_cb_t * p_cb, + nrf_drv_spis_state_t new_state) +{ + p_cb->spi_state = new_state; + spis_state_entry_action_execute(p_spis, p_cb); +} + + +ret_code_t nrf_drv_spis_buffers_set(nrf_drv_spis_t const * const p_instance, + const uint8_t * p_tx_buffer, + uint8_t tx_buffer_length, + uint8_t * p_rx_buffer, + uint8_t rx_buffer_length) +{ + spis_cb_t * p_cb = &m_cb[p_instance->instance_id]; + uint32_t err_code; + + VERIFY_PARAM_NOT_NULL(p_rx_buffer); + VERIFY_PARAM_NOT_NULL(p_tx_buffer); + + // EasyDMA requires that transfer buffers are placed in Data RAM region; + // signal error if they are not. + if ((p_tx_buffer != NULL && !nrf_drv_is_in_RAM(p_tx_buffer)) || + (p_rx_buffer != NULL && !nrf_drv_is_in_RAM(p_rx_buffer))) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + switch (p_cb->spi_state) + { + case SPIS_STATE_INIT: + case SPIS_XFER_COMPLETED: + case SPIS_BUFFER_RESOURCE_CONFIGURED: + p_cb->tx_buffer = p_tx_buffer; + p_cb->rx_buffer = p_rx_buffer; + p_cb->tx_buffer_size = tx_buffer_length; + p_cb->rx_buffer_size = rx_buffer_length; + err_code = NRF_SUCCESS; + + spis_state_change(p_instance->p_reg, p_cb, SPIS_BUFFER_RESOURCE_REQUESTED); + break; + + case SPIS_BUFFER_RESOURCE_REQUESTED: + err_code = NRF_ERROR_INVALID_STATE; + break; + + default: + // @note: execution of this code path would imply internal error in the design. + err_code = NRF_ERROR_INTERNAL; + break; + } + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +static void spis_irq_handler(NRF_SPIS_Type * p_spis, spis_cb_t * p_cb) +{ + // @note: as multiple events can be pending for processing, the correct event processing order + // is as follows: + // - SPI semaphore acquired event. + // - SPI transaction complete event. + + // Check for SPI semaphore acquired event. + if (nrf_spis_event_check(p_spis, NRF_SPIS_EVENT_ACQUIRED)) + { + nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_ACQUIRED); + NRF_LOG_DEBUG("SPIS: Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SPIS_EVENT_ACQUIRED)); + + switch (p_cb->spi_state) + { + case SPIS_BUFFER_RESOURCE_REQUESTED: + nrf_spis_tx_buffer_set(p_spis, (uint8_t *)p_cb->tx_buffer, p_cb->tx_buffer_size); + nrf_spis_rx_buffer_set(p_spis, (uint8_t *)p_cb->rx_buffer, p_cb->rx_buffer_size); + + nrf_spis_task_trigger(p_spis, NRF_SPIS_TASK_RELEASE); + + spis_state_change(p_spis, p_cb, SPIS_BUFFER_RESOURCE_CONFIGURED); + break; + + default: + // No implementation required. + break; + } + } + + // Check for SPI transaction complete event. + if (nrf_spis_event_check(p_spis, NRF_SPIS_EVENT_END)) + { + nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_END); + NRF_LOG_DEBUG("SPIS: Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SPIS_EVENT_END)); + + switch (p_cb->spi_state) + { + case SPIS_BUFFER_RESOURCE_CONFIGURED: + spis_state_change(p_spis, p_cb, SPIS_XFER_COMPLETED); + break; + + default: + // No implementation required. + break; + } + } +} + +#if NRF_MODULE_ENABLED(SPIS0) + SPIS_IRQHANDLER_TEMPLATE(0) +#endif + +#if NRF_MODULE_ENABLED(SPIS1) + SPIS_IRQHANDLER_TEMPLATE(1) +#endif + +#if NRF_MODULE_ENABLED(SPIS2) + SPIS_IRQHANDLER_TEMPLATE(2) +#endif + +#endif // SPI_COUNT > 0 +#endif // NRF_MODULE_ENABLED(SPIS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_slave/nrf_drv_spis.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_slave/nrf_drv_spis.h new file mode 100644 index 0000000000000000000000000000000000000000..87439e6eb10458ee5b6ac1384d3535755a1e9485 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/spi_slave/nrf_drv_spis.h @@ -0,0 +1,264 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * @addtogroup nrf_spis SPIS HAL and driver + * @ingroup nrf_drivers + * @brief SPIS APIs. + * + */ + +#ifndef SPI_SLAVE_H__ +#define SPI_SLAVE_H__ + +#include +#include "nrf.h" +#include "nrf_error.h" +#include "sdk_config.h" +#include "nrf_spis.h" +#include "nrf_gpio.h" +#include "sdk_common.h" +#include "app_util_platform.h" +#include "nrf_peripherals.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + #define SPIS0_IRQ SPI0_TWI0_IRQn + #define SPIS0_IRQ_HANDLER SPI0_TWI0_IRQHandler + #define SPIS1_IRQ SPI1_TWI1_IRQn + #define SPIS1_IRQ_HANDLER SPI1_TWI1_IRQHandler + +#if SPIS_COUNT > 2 + #define SPIS2_IRQ SPIM2_SPIS2_SPI2_IRQn + #define SPIS2_IRQ_HANDLER SPIM2_SPIS2_SPI2_IRQHandler +#endif + +/** + * @defgroup nrf_drv_spis SPI slave driver + * @{ + * @ingroup nrf_spis + * @brief Multi-instance SPI slave driver. + */ + +#define NRF_DRV_SPIS_DEFAULT_CSN_PULLUP NRF_GPIO_PIN_NOPULL /**< Default pull-up configuration of the SPI CS. */ +#define NRF_DRV_SPIS_DEFAULT_MISO_DRIVE NRF_GPIO_PIN_S0S1 /**< Default drive configuration of the SPI MISO. */ + +/** +* @brief This value can be provided instead of a pin number for the signals MOSI +* and MISO to specify that the given signal is not used and therefore +* does not need to be connected to a pin. +*/ +#define NRF_DRV_SPIS_PIN_NOT_USED 0xFF + +/** @brief SPIS transaction bit order definitions. */ +typedef enum +{ + NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST = NRF_SPIS_BIT_ORDER_LSB_FIRST, /**< Least significant bit shifted out first. */ + NRF_DRV_SPIS_BIT_ORDER_MSB_FIRST = NRF_SPIS_BIT_ORDER_MSB_FIRST /**< Most significant bit shifted out first. */ +} nrf_drv_spis_endian_t; + +/** @brief SPIS mode definitions for clock polarity and phase. */ +typedef enum +{ + NRF_DRV_SPIS_MODE_0 = NRF_SPIS_MODE_0, /**< (CPOL = 0, CPHA = 0). */ + NRF_DRV_SPIS_MODE_1 = NRF_SPIS_MODE_1, /**< (CPOL = 0, CPHA = 1). */ + NRF_DRV_SPIS_MODE_2 = NRF_SPIS_MODE_2, /**< (CPOL = 1, CPHA = 0). */ + NRF_DRV_SPIS_MODE_3 = NRF_SPIS_MODE_3 /**< (CPOL = 1, CPHA = 1). */ +} nrf_drv_spis_mode_t; + +/** @brief Event callback function event definitions. */ +typedef enum +{ + NRF_DRV_SPIS_BUFFERS_SET_DONE, /**< Memory buffer set event. Memory buffers have been set successfully to the SPI slave device, and SPI transactions can be done. */ + NRF_DRV_SPIS_XFER_DONE, /**< SPI transaction event. SPI transaction has been completed. */ + NRF_DRV_SPIS_EVT_TYPE_MAX /**< Enumeration upper bound. */ +} nrf_drv_spis_event_type_t; + +/** @brief Structure containing the event context from the SPI slave driver. */ +typedef struct +{ + nrf_drv_spis_event_type_t evt_type; //!< Type of event. + uint32_t rx_amount; //!< Number of bytes received in last transaction. This parameter is only valid for @ref NRF_DRV_SPIS_XFER_DONE events. + uint32_t tx_amount; //!< Number of bytes transmitted in last transaction. This parameter is only valid for @ref NRF_DRV_SPIS_XFER_DONE events. +} nrf_drv_spis_event_t; + +/** @brief SPI slave driver instance data structure. */ +typedef struct +{ + NRF_SPIS_Type * p_reg; //!< SPIS instance register. + uint8_t instance_id; //!< SPIS instance ID. + IRQn_Type irq; //!< IRQ of the specific instance. +} nrf_drv_spis_t; + +#define SPIS0_INSTANCE_INDEX 0 +#define SPIS1_INSTANCE_INDEX SPIS0_INSTANCE_INDEX+SPIS0_ENABLED +#define SPIS2_INSTANCE_INDEX SPIS1_INSTANCE_INDEX+SPIS1_ENABLED + +/** @brief Macro for creating an SPI slave driver instance. */ +#define NRF_DRV_SPIS_INSTANCE(id) \ +{ \ + .p_reg = CONCAT_2(NRF_SPIS, id), \ + .irq = CONCAT_3(SPIS, id, _IRQ), \ + .instance_id = CONCAT_3(SPIS, id, _INSTANCE_INDEX), \ +} + +/** @brief SPI slave instance default configuration. */ +#define NRF_DRV_SPIS_DEFAULT_CONFIG \ +{ \ + .sck_pin = NRF_DRV_SPIS_PIN_NOT_USED, \ + .mosi_pin = NRF_DRV_SPIS_PIN_NOT_USED, \ + .miso_pin = NRF_DRV_SPIS_PIN_NOT_USED, \ + .csn_pin = NRF_DRV_SPIS_PIN_NOT_USED, \ + .miso_drive = NRF_DRV_SPIS_DEFAULT_MISO_DRIVE, \ + .csn_pullup = NRF_DRV_SPIS_DEFAULT_CSN_PULLUP, \ + .orc = SPIS_DEFAULT_ORC, \ + .def = SPIS_DEFAULT_DEF, \ + .mode = (nrf_drv_spis_mode_t)SPIS_DEFAULT_MODE, \ + .bit_order = (nrf_drv_spis_endian_t)SPIS_DEFAULT_BIT_ORDER, \ + .irq_priority = SPIS_DEFAULT_CONFIG_IRQ_PRIORITY, \ +} + +/** @brief SPI peripheral device configuration data. */ +typedef struct +{ + uint32_t miso_pin; //!< SPI MISO pin (optional). + /**< Set @ref NRF_DRV_SPIS_PIN_NOT_USED + * if this signal is not needed. */ + uint32_t mosi_pin; //!< SPI MOSI pin (optional). + /**< Set @ref NRF_DRV_SPIS_PIN_NOT_USED + * if this signal is not needed. */ + uint32_t sck_pin; //!< SPI SCK pin. + uint32_t csn_pin; //!< SPI CSN pin. + nrf_drv_spis_mode_t mode; //!< SPI mode. + nrf_drv_spis_endian_t bit_order; //!< SPI transaction bit order. + nrf_gpio_pin_pull_t csn_pullup; //!< CSN pin pull-up configuration. + nrf_gpio_pin_drive_t miso_drive; //!< MISO pin drive configuration. + uint8_t def; //!< Character clocked out in case of an ignored transaction. + uint8_t orc; //!< Character clocked out after an over-read of the transmit buffer. + uint8_t irq_priority; //!< Interrupt priority. +} nrf_drv_spis_config_t; + + +/** @brief SPI slave event callback function type. + * + * @param[in] event SPI slave driver event. + */ +typedef void (*nrf_drv_spis_event_handler_t)(nrf_drv_spis_event_t event); + +/** @brief Function for initializing the SPI slave driver instance. + * + * @note When the nRF52 Anomaly 109 workaround for SPIS is enabled, this function + * initializes the GPIOTE driver as well, and uses one of GPIOTE channels + * to detect falling edges on CSN pin. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_config Pointer to the structure with the initial configuration. + * If NULL, the default configuration will be used. + * @param[in] event_handler Function to be called by the SPI slave driver upon event. + * + * @retval NRF_SUCCESS If the initialization was successful. + * @retval NRF_ERROR_INVALID_PARAM If an invalid parameter is supplied. + * @retval NRF_ERROR_BUSY If some other peripheral with the same + * instance ID is already in use. This is + * possible only if PERIPHERAL_RESOURCE_SHARING_ENABLED + * is set to a value other than zero. + * @retval NRF_ERROR_INTERNAL GPIOTE channel for detecting falling edges + * on CSN pin cannot be initialized. Possible + * only when using nRF52 Anomaly 109 workaround. + */ +ret_code_t nrf_drv_spis_init(nrf_drv_spis_t const * const p_instance, + nrf_drv_spis_config_t const * p_config, + nrf_drv_spis_event_handler_t event_handler); + +/** + * @brief Function for uninitializing the SPI slave driver instance. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_spis_uninit(nrf_drv_spis_t const * const p_instance); + +/** @brief Function for preparing the SPI slave instance for a single SPI transaction. + * + * This function prepares the SPI slave device to be ready for a single SPI transaction. It configures + * the SPI slave device to use the memory supplied with the function call in SPI transactions. + * + * When either the memory buffer configuration or the SPI transaction has been + * completed, the event callback function will be called with the appropriate event + * @ref nrf_drv_spis_event_type_t. Note that the callback function can be called before returning from + * this function, because it is called from the SPI slave interrupt context. + * + * @note This function can be called from the callback function context. + * + * @note Client applications must call this function after every @ref NRF_DRV_SPIS_XFER_DONE event if + * the SPI slave driver should be prepared for a possible new SPI transaction. + * + * @note Peripherals that are using EasyDMA (for example, SPIS) require the transfer buffers + * to be placed in the Data RAM region. Otherwise, this function will fail + * with the error code NRF_ERROR_INVALID_ADDR. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_tx_buffer Pointer to the TX buffer. + * @param[in] p_rx_buffer Pointer to the RX buffer. + * @param[in] tx_buffer_length Length of the TX buffer in bytes. + * @param[in] rx_buffer_length Length of the RX buffer in bytes. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If the operation failed because a NULL pointer was supplied. + * @retval NRF_ERROR_INVALID_STATE If the operation failed because the SPI slave device is in an incorrect state. + * @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed in the Data + * RAM region. + * @retval NRF_ERROR_INTERNAL If the operation failed because of an internal error. + */ +ret_code_t nrf_drv_spis_buffers_set(nrf_drv_spis_t const * const p_instance, + const uint8_t * p_tx_buffer, + uint8_t tx_buffer_length, + uint8_t * p_rx_buffer, + uint8_t rx_buffer_length); + + +#ifdef __cplusplus +} +#endif + +#endif // SPI_SLAVE_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/swi/nrf_drv_swi.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/swi/nrf_drv_swi.c new file mode 100644 index 0000000000000000000000000000000000000000..32bd81d80d6a7139d6585709fae8dbdb6de518d6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/swi/nrf_drv_swi.c @@ -0,0 +1,413 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_drv_common.h" +#include "nrf_error.h" +#include "nrf_assert.h" +#include +#include +#include +#include "nrf_drv_swi.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "SWI" + +#if EGU_ENABLED +#if SWI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL SWI_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR SWI_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR SWI_CONFIG_DEBUG_COLOR +#else //SWI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //SWI_CONFIG_LOG_ENABLED +#endif //EGU_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +STATIC_ASSERT(SWI_COUNT > 0); +STATIC_ASSERT(SWI_COUNT <= SWI_MAX); + +#ifdef SWI_DISABLE0 + #undef SWI_DISABLE0 + #define SWI_DISABLE0 1uL +#else + #if SWI_COUNT > 0 + #define SWI_DISABLE0 0uL + #else + #define SWI_DISABLE0 1uL + #endif +#endif + +#ifdef SWI_DISABLE1 + #undef SWI_DISABLE1 + #define SWI_DISABLE1 1uL +#else + #if SWI_COUNT > 1 + #define SWI_DISABLE1 0uL + #else + #define SWI_DISABLE1 1uL + #endif +#endif + +#ifdef SWI_DISABLE2 + #undef SWI_DISABLE2 + #define SWI_DISABLE2 1uL +#else + #if SWI_COUNT > 2 + #define SWI_DISABLE2 0uL + #else + #define SWI_DISABLE2 1uL + #endif +#endif + +#ifdef SWI_DISABLE3 + #undef SWI_DISABLE3 + #define SWI_DISABLE3 1uL +#else + #if SWI_COUNT > 3 + #define SWI_DISABLE3 0uL + #else + #define SWI_DISABLE3 1uL + #endif +#endif + +#ifdef SWI_DISABLE4 + #undef SWI_DISABLE4 + #define SWI_DISABLE4 1uL +#else + #if SWI_COUNT > 4 + #define SWI_DISABLE4 0uL + #else + #define SWI_DISABLE4 1uL + #endif +#endif + +#ifdef SWI_DISABLE5 + #undef SWI_DISABLE5 + #define SWI_DISABLE5 1uL +#else + #if SWI_COUNT > 5 + #define SWI_DISABLE5 0uL + #else + #define SWI_DISABLE5 1uL + #endif +#endif + +#define SWI_START_NUMBER ( (SWI_DISABLE0) \ + + (SWI_DISABLE0 * SWI_DISABLE1) \ + + (SWI_DISABLE0 * SWI_DISABLE1 * SWI_DISABLE2) \ + + (SWI_DISABLE0 * SWI_DISABLE1 * SWI_DISABLE2 * SWI_DISABLE3) \ + + (SWI_DISABLE0 * SWI_DISABLE1 * SWI_DISABLE2 * SWI_DISABLE3 * SWI_DISABLE4) \ + + (SWI_DISABLE0 * SWI_DISABLE1 * SWI_DISABLE2 * SWI_DISABLE3 * SWI_DISABLE4 \ + * SWI_DISABLE5) ) + +#define SWI_ARRAY_SIZE (SWI_COUNT - SWI_START_NUMBER) + +#if (SWI_COUNT <= SWI_START_NUMBER) + #undef SWI_ARRAY_SIZE + #define SWI_ARRAY_SIZE 1 +#endif + +static nrf_drv_state_t m_drv_state = NRF_DRV_STATE_UNINITIALIZED; +static nrf_swi_handler_t m_swi_handlers[SWI_ARRAY_SIZE]; + +#if !EGU_ENABLED +static nrf_swi_flags_t m_swi_flags[SWI_ARRAY_SIZE]; +#endif + +/**@brief Function for getting max channel number of given SWI. + * + * @param[in] swi SWI number. + * @return number of available channels. + */ +#if NRF_MODULE_ENABLED(EGU) +__STATIC_INLINE uint32_t swi_channel_number(nrf_swi_t swi) +{ + uint32_t retval = 0; + switch(swi){ + case 0: + retval = EGU0_CH_NUM; + break; + case 1: + retval = EGU1_CH_NUM; + break; + case 2: + retval = EGU2_CH_NUM; + break; + case 3: + retval = EGU3_CH_NUM; + break; + case 4: + retval = EGU4_CH_NUM; + break; + case 5: + retval = EGU5_CH_NUM; + break; + default: + retval = 0; + } + + return retval; +} +#else +#define swi_channel_number(swi) SWI_MAX_FLAGS +#endif + +#if NRF_MODULE_ENABLED(EGU) + +/**@brief Get the specific EGU instance. */ +__STATIC_INLINE NRF_EGU_Type * egu_instance_get(nrf_swi_t swi) +{ + return (NRF_EGU_Type*) (NRF_EGU0_BASE + (((uint32_t) swi) * (NRF_EGU1_BASE - NRF_EGU0_BASE))); +} + +/**@brief Software interrupt handler (using EGU). */ +static void nrf_drv_swi_process(nrf_swi_t swi) +{ + ASSERT(m_swi_handlers[swi - SWI_START_NUMBER]); + nrf_swi_flags_t flags = 0; + NRF_EGU_Type * NRF_EGUx = egu_instance_get(swi); + + for (uint8_t i = 0; i < swi_channel_number(swi); ++i) + { + nrf_egu_event_t egu_event = nrf_egu_event_triggered_get(NRF_EGUx, i); + if (nrf_egu_event_check(NRF_EGUx, egu_event)) + { + flags |= (1u << i); + nrf_egu_event_clear(NRF_EGUx, egu_event); + } + } + + m_swi_handlers[swi - SWI_START_NUMBER](swi, flags); +} + +#define SWI_HANDLER_TEMPLATE(NUM) void SWI##NUM##_EGU##NUM##_IRQHandler(void) \ + { \ + nrf_drv_swi_process(NUM); \ + } + +#else + +/**@brief Software interrupt handler (without EGU). */ +static void nrf_drv_swi_process(nrf_swi_t swi, nrf_swi_flags_t flags) +{ + ASSERT(m_swi_handlers[swi - SWI_START_NUMBER]); + m_swi_flags[swi - SWI_START_NUMBER] &= ~flags; + m_swi_handlers[swi - SWI_START_NUMBER](swi, flags); +} + + +#define SWI_HANDLER_TEMPLATE(NUM) void SWI##NUM##_IRQHandler(void) \ + { \ + nrf_drv_swi_process((NUM), m_swi_flags[(NUM) - SWI_START_NUMBER]); \ + } + +#endif + +#if SWI_DISABLE0 == 0 +SWI_HANDLER_TEMPLATE(0) +#endif + +#if SWI_DISABLE1 == 0 +SWI_HANDLER_TEMPLATE(1) +#endif + +#if SWI_DISABLE2 == 0 +SWI_HANDLER_TEMPLATE(2) +#endif + +#if SWI_DISABLE3 == 0 +SWI_HANDLER_TEMPLATE(3) +#endif + +#if SWI_DISABLE4 == 0 +SWI_HANDLER_TEMPLATE(4) +#endif + +#if SWI_DISABLE5 == 0 +SWI_HANDLER_TEMPLATE(5) +#endif + +#define AVAILABLE_SWI (0x3FuL & ~( \ + (SWI_DISABLE0 << 0) | (SWI_DISABLE1 << 1) | (SWI_DISABLE2 << 2) \ + | (SWI_DISABLE3 << 3) | (SWI_DISABLE4 << 4) | (SWI_DISABLE5 << 5) \ + )) + +#if (AVAILABLE_SWI == 0) + #warning No available SWIs. +#endif + +/**@brief Function for converting SWI number to system interrupt number. + * + * @param[in] swi SWI number. + * + * @retval IRQ number. + */ +__STATIC_INLINE IRQn_Type nrf_drv_swi_irq_of(nrf_swi_t swi) +{ + return (IRQn_Type)((uint32_t)SWI0_IRQn + (uint32_t)swi); +} + + +/**@brief Function for checking if given SWI is allocated. + * + * @param[in] swi SWI number. + */ +__STATIC_INLINE bool swi_is_allocated(nrf_swi_t swi) +{ + ASSERT(swi < SWI_COUNT); +#if SWI_START_NUMBER > 0 + if (swi < SWI_START_NUMBER) + { + return false; + } +#endif + /*lint -e(661) out of range case handled by assert above*/ + return m_swi_handlers[swi - SWI_START_NUMBER]; +} + +ret_code_t nrf_drv_swi_init(void) +{ + ret_code_t err_code; + + if (m_drv_state == NRF_DRV_STATE_UNINITIALIZED) + { + m_drv_state = NRF_DRV_STATE_INITIALIZED; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + err_code = NRF_ERROR_MODULE_ALREADY_INITIALIZED; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_swi_uninit(void) +{ + ASSERT(m_drv_state != NRF_DRV_STATE_UNINITIALIZED) + + for (uint32_t i = SWI_START_NUMBER; i < SWI_COUNT; ++i) + { + m_swi_handlers[i - SWI_START_NUMBER] = NULL; + nrf_drv_common_irq_disable(nrf_drv_swi_irq_of((nrf_swi_t) i)); +#if NRF_MODULE_ENABLED(EGU) + NRF_EGU_Type * NRF_EGUx = egu_instance_get(i); + nrf_egu_int_disable(NRF_EGUx, NRF_EGU_INT_ALL); +#endif + } + m_drv_state = NRF_DRV_STATE_UNINITIALIZED; + return; +} + + +void nrf_drv_swi_free(nrf_swi_t * p_swi) +{ + ASSERT(swi_is_allocated(*p_swi)); + nrf_drv_common_irq_disable(nrf_drv_swi_irq_of(*p_swi)); + m_swi_handlers[(*p_swi) - SWI_START_NUMBER] = NULL; + *p_swi = NRF_SWI_UNALLOCATED; +} + + +ret_code_t nrf_drv_swi_alloc(nrf_swi_t * p_swi, nrf_swi_handler_t event_handler, uint32_t priority) +{ +#if !NRF_MODULE_ENABLED(EGU) + ASSERT(event_handler); +#endif + uint32_t err_code = NRF_ERROR_NO_MEM; + + for (uint32_t i = SWI_START_NUMBER; i < SWI_COUNT; i++) + { + CRITICAL_REGION_ENTER(); + if ((!swi_is_allocated(i)) && (AVAILABLE_SWI & (1 << i))) + { + m_swi_handlers[i - SWI_START_NUMBER] = event_handler; + *p_swi = (nrf_swi_t) i; + nrf_drv_common_irq_enable(nrf_drv_swi_irq_of(*p_swi), priority); +#if NRF_MODULE_ENABLED(EGU) + if(event_handler != NULL) + { + NRF_EGU_Type * NRF_EGUx = egu_instance_get(i); + nrf_egu_int_enable(NRF_EGUx, NRF_EGU_INT_ALL); + } +#endif + err_code = NRF_SUCCESS; + } + CRITICAL_REGION_EXIT(); + if (err_code == NRF_SUCCESS) + { + NRF_LOG_INFO("SWI channel allocated: %d.\r\n", (*p_swi)); + break; + } + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_swi_trigger(nrf_swi_t swi, uint8_t flag_number) +{ + ASSERT(swi_is_allocated((uint32_t) swi)); + ASSERT(flag_number < swi_channel_number(swi)); +#if NRF_MODULE_ENABLED(EGU) + NRF_EGU_Type * NRF_EGUx = egu_instance_get(swi); + nrf_egu_task_trigger(NRF_EGUx, nrf_egu_task_trigger_get(NRF_EGUx, flag_number)); +#else + m_swi_flags[swi - SWI_START_NUMBER] |= (1 << flag_number); + NVIC_SetPendingIRQ(nrf_drv_swi_irq_of(swi)); +#endif +} + + +#if NRF_MODULE_ENABLED(EGU) + +uint32_t nrf_drv_swi_task_trigger_address_get(nrf_swi_t swi, uint8_t channel) +{ + NRF_EGU_Type * NRF_EGUx = egu_instance_get(swi); + return (uint32_t) nrf_egu_task_trigger_address_get(NRF_EGUx, channel); +} + +uint32_t nrf_drv_swi_event_triggered_address_get(nrf_swi_t swi, uint8_t channel) +{ + NRF_EGU_Type * NRF_EGUx = egu_instance_get(swi); + return (uint32_t) nrf_egu_event_triggered_address_get(NRF_EGUx, channel); +} + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/swi/nrf_drv_swi.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/swi/nrf_drv_swi.h new file mode 100644 index 0000000000000000000000000000000000000000..ff02bdc5659f2f1574142fdaaf75d4bc8da9aad3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/swi/nrf_drv_swi.h @@ -0,0 +1,211 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup nrf_drv_swi SWI driver + * @{ + * @ingroup nrf_drivers + * + * @brief Driver for software interrupts (SWI). + * @details The SWI driver allows the user to allocate SWIs and pass extra flags to interrupt handler functions. + */ + +#ifndef NRF_DRV_SWI_H__ +#define NRF_DRV_SWI_H__ + +#include +#include +#include "sdk_config.h" +#include "app_util.h" +#include "app_util_platform.h" +#include "sdk_common.h" +#include "sdk_errors.h" +#include "nrf_peripherals.h" + +#ifndef EGU_ENABLED + #define EGU_ENABLED 0 +#endif + +#if NRF_MODULE_ENABLED(EGU) +#include "nrf_egu.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint8_t nrf_swi_t; ///< @brief SWI channel (unsigned integer). + +/** @brief SWI user flags (unsigned integer). + * + * User flags are set during the SWI trigger and passed to the callback function as an argument. + */ +typedef uint16_t nrf_swi_flags_t; + +/** @brief Unallocated channel value. */ +#define NRF_SWI_UNALLOCATED ((nrf_swi_t) 0xFFFFFFFFuL) + +/** @brief SWI handler function. + * + * Takes two arguments: SWI number (nrf_swi_t) and flags (nrf_swi_flags_t). + */ +typedef void (* nrf_swi_handler_t)(nrf_swi_t, nrf_swi_flags_t); + +/**@brief Maximum numbers of SWIs. This number is fixed for a specific chip. */ +#if NRF_MODULE_ENABLED(EGU) +#define SWI_MAX EGU_COUNT +#else +#define SWI_MAX SWI_COUNT +/**@brief Number of flags per SWI (fixed number). */ +#define SWI_MAX_FLAGS 16 +#endif + +#ifdef SOFTDEVICE_PRESENT + #if SWI_COUNT > 2 + #undef SWI_COUNT + #define SWI_COUNT 2 + #endif +#else + #ifdef SVCALL_AS_NORMAL_FUNCTION + // Serialization is enabled. + #if SWI_COUNT > 2 + #undef SWI_COUNT + #define SWI_COUNT 2 + #endif + #endif +#endif + +#if NRF_MODULE_ENABLED(PWM_NRF52_ANOMALY_109_WORKAROUND) + #if (PWM_NRF52_ANOMALY_109_EGU_INSTANCE == 0) + #define SWI_DISABLE0 + #elif (PWM_NRF52_ANOMALY_109_EGU_INSTANCE == 1) + #define SWI_DISABLE1 + #elif (PWM_NRF52_ANOMALY_109_EGU_INSTANCE == 2) + #define SWI_DISABLE2 + #elif (PWM_NRF52_ANOMALY_109_EGU_INSTANCE == 3) + #define SWI_DISABLE3 + #elif (PWM_NRF52_ANOMALY_109_EGU_INSTANCE == 4) + #define SWI_DISABLE4 + #elif (PWM_NRF52_ANOMALY_109_EGU_INSTANCE == 5) + #define SWI_DISABLE5 + #endif +#endif + +/**@brief Default SWI priority. */ +#define SWI_DEFAULT_PRIORITY APP_IRQ_PRIORITY_LOWEST + + +/**@brief Function for initializing the SWI module. + * + * @retval NRF_SUCCESS If the module was successfully initialized. + * @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED If the module has already been initialized. + */ +ret_code_t nrf_drv_swi_init(void); + + +/**@brief Function for uninitializing the SWI module. + * + * This function also disables all SWIs. + */ +void nrf_drv_swi_uninit(void); + + +/**@brief Function for allocating a first unused SWI instance and setting a handler. + * @details The event handler function returns void and takes one uint32_t argument (SWI number). + * + * @param[out] p_swi Pointer to the SWI that has been allocated. + * @param[in] event_handler Event handler function. + * If NULL, no interrupt will be enabled (can be NULL only if the EGU driver is enabled). + * For classic SWI, must be a valid handler pointer. + * @param[in] priority Interrupt priority. + * + * @retval NRF_SUCCESS If the SWI was successfully allocated. + * @retval NRF_ERROR_NO_MEM If there is no available SWI to be used. + */ +ret_code_t nrf_drv_swi_alloc(nrf_swi_t * p_swi, nrf_swi_handler_t event_handler, uint32_t priority); + + +/**@brief Function for freeing a previously allocated SWI. + * + * @param[in,out] p_swi SWI to free. The value is changed to NRF_SWI_UNALLOCATED on success. + */ +void nrf_drv_swi_free(nrf_swi_t * p_swi); + + +/**@brief Function for triggering the SWI. + * + * @param[in] swi SWI to trigger. + * @param[in] flag_number Number of user flag to trigger. + */ +void nrf_drv_swi_trigger(nrf_swi_t swi, uint8_t flag_number); + + +#if (EGU_ENABLED > 0) || defined(__SDK_DOXYGEN__) + + +/**@brief Function for returning the EGU trigger task address. + * + * @param[in] swi SWI instance. + * @param[in] channel Number of the EGU channel. + * + * @returns EGU trigger task address. + */ +uint32_t nrf_drv_swi_task_trigger_address_get(nrf_swi_t swi, uint8_t channel); + +/**@brief Function for returning the EGU triggered event address. + * + * @param[in] swi SWI instance. + * @param[in] channel Number of the EGU channel. + * + * @returns EGU triggered event address. + */ +uint32_t nrf_drv_swi_event_triggered_address_get(nrf_swi_t swi, uint8_t channel); + +#endif // NRF_MODULE_ENABLED(EGU) + + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_SWI_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/systick/nrf_drv_systick.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/systick/nrf_drv_systick.c new file mode 100644 index 0000000000000000000000000000000000000000..242ee64cc6946bb9f8e3767579d54f4549d8750a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/systick/nrf_drv_systick.c @@ -0,0 +1,172 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(SYSTICK) +#include "nrf_drv_systick.h" +#include "nrf_systick.h" +#include "nrf.h" +#include "nrf_assert.h" + +/** + * @brief Maximum number of ticks to delay + * + * The maximum number of ticks should be much lower than + * Physical maximum count of the SysTick timer. + * It is dictated by the fact that it would be impossible to detect delay + * properly when the timer value warps around the starting point. + */ +#define NRF_DRV_SYSTICK_TICKS_MAX (NRF_SYSTICK_VAL_MASK / 2UL) + +/** + * @brief Number of milliseconds in a second + */ +#define NRF_DRV_SYSTICK_MS (1000UL) + +/** + * @brief Number of microseconds in a second + */ +#define NRF_DRV_SYSTICK_US (1000UL * NRF_DRV_SYSTICK_MS) + +/** + * @brief Number of milliseconds to wait in single loop + * + * Constant used by @ref nrd_drv_systick_delay_ms function + * to split waiting into loops and rest. + * + * It describes the number of milliseconds to wait in single loop. + * + * See @ref nrf_drv_systick_delay_ms source code for details. + */ +#define NRF_DRV_SYSTICK_MS_STEP (64U) + +/** + * @brief Checks if the given time is in correct range + * + * Function tests given time is not to big for this library. + * Assertion is used for testing. + * + * @param us Time in microseconds to check + */ +#define NRF_DRV_SYSTICK_ASSERT_TIMEOUT(us) \ + ASSERT(us <= (NRF_DRV_SYSTICK_TICKS_MAX / ((SystemCoreClock) / NRF_DRV_SYSTICK_US))); + +/** + * @brief Function that converts microseconds to ticks + * + * Function converts from microseconds to CPU ticks. + * + * @param us Number of microseconds + * + * @return Number of ticks + * + * @sa nrf_drv_systick_ms_tick + */ +static inline uint32_t nrf_drv_systick_us_tick(uint32_t us) +{ + return us * ((SystemCoreClock) / NRF_DRV_SYSTICK_US); +} + +/** + * @brief Function that converts milliseconds to ticks + * + * Function converts from milliseconds to CPU ticks. + * + * @param us Number of milliseconds + * + * @return Number of ticks + * + * @sa nrf_drv_systick_us_tick + */ +static inline uint32_t nrf_drv_systick_ms_tick(uint32_t ms) +{ + return ms * ((SystemCoreClock) / NRF_DRV_SYSTICK_MS); +} + +void nrf_drv_systick_init(void) +{ + nrf_systick_load_set(NRF_SYSTICK_VAL_MASK); + nrf_systick_csr_set( + NRF_SYSTICK_CSR_CLKSOURCE_CPU | + NRF_SYSTICK_CSR_TICKINT_DISABLE | + NRF_SYSTICK_CSR_ENABLE); +} + +void nrf_drv_systick_get(nrf_drv_systick_state_t * p_state) +{ + p_state->time = nrf_systick_val_get(); +} + +bool nrf_drv_systick_test(nrf_drv_systick_state_t const * p_state, uint32_t us) +{ + NRF_DRV_SYSTICK_ASSERT_TIMEOUT(us); + + const uint32_t diff = NRF_SYSTICK_VAL_MASK & ((p_state->time) - nrf_systick_val_get()); + return (diff >= nrf_drv_systick_us_tick(us)); +} + +void nrf_drv_systick_delay_ticks(uint32_t ticks) +{ + ASSERT(ticks <= NRF_DRV_SYSTICK_TICKS_MAX) + + const uint32_t start = nrf_systick_val_get(); + while((NRF_SYSTICK_VAL_MASK & (start - nrf_systick_val_get())) < ticks) + { + /* Nothing to do */ + } +} + +void nrf_drv_systick_delay_us(uint32_t us) +{ + NRF_DRV_SYSTICK_ASSERT_TIMEOUT(us); + nrf_drv_systick_delay_ticks(nrf_drv_systick_us_tick(us)); +} + +void nrf_drv_systick_delay_ms(uint32_t ms) +{ + uint32_t n = ms / NRF_DRV_SYSTICK_MS_STEP; + uint32_t r = ms % NRF_DRV_SYSTICK_MS_STEP; + while(0 != (n--)) + { + nrf_drv_systick_delay_ticks(nrf_drv_systick_ms_tick(NRF_DRV_SYSTICK_MS_STEP)); + } + nrf_drv_systick_delay_ticks(nrf_drv_systick_ms_tick(r)); +} + +#endif // NRF_MODULE_ENABLED(SYSTICK) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/systick/nrf_drv_systick.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/systick/nrf_drv_systick.h new file mode 100644 index 0000000000000000000000000000000000000000..34492af2a12cba28dddac840a2d931c592086f8f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/systick/nrf_drv_systick.h @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_DRV_SYSTICK_H__ +#define NRF_DRV_SYSTICK_H__ +#include +#include + + +/** + * @addtogroup nrf_systick SysTick HAL and driver + * @ingroup nrf_drivers + * @brief System Timer (SysTick) APIs + * + * The SysTick HAL provides basic APIs for accessing the registers of the system timer (SysTick). + * The SysTick driver provides APIs on a higher level. + */ + +/** + * @defgroup nrf_drv_systick SysTick driver + * @{ + * @ingroup nrf_systick + * + * This library configures SysTick as a free-running timer. + * This timer is used to generate delays and pool for timeouts. + * Only relatively short timeouts are supported. + * The SysTick works on 64MHz and is 24-bits wide. + * It means that it overflows around 4 times per second and around 250 ms + * would be the highest supported time in the library. + * But it would be really hard to detect if overflow was generated without + * using interrupts. For safely we would limit the maximum delay range by half. + */ + +/** + * @brief The value type that holds the SysTick state + * + * This variable is used to count the requested timeout. + * @sa nrf_drv_systick_get + */ +typedef struct { + uint32_t time; //!< Registered time value +}nrf_drv_systick_state_t; + +/** + * @brief Configure and start the timer + * + * Function configures SysTick as a free-running timer without interrupt. + */ +void nrf_drv_systick_init(void); + +/** + * @brief Get current SysTick state + * + * Function gets current state of the SysTick timer. + * It can be used to check time-out by @ref nrf_drv_systick_test. + * + * @param[out] p_state The pointer to the state variable to be filled + */ +void nrf_drv_systick_get(nrf_drv_systick_state_t * p_state); + +/** + * @brief Test if specified time is up in relation to remembered state + * + * @param[in] p_state Remembered state set by @ref nrf_drv_systick_get + * @param[in] us Required time-out. + * + * @retval true If current time is higher than specified state plus given time-out. + * @retval false If current time is lower than specified state plus given time-out + */ +bool nrf_drv_systick_test(nrf_drv_systick_state_t const * p_state, uint32_t us); + +/** + * @brief Blocking delay in CPU ticks + * + * @param[in] ticks Number of CPU ticks to delay. + */ +void nrf_drv_systick_delay_ticks(uint32_t ticks); + +/** + * @brief Blocking delay in us + * + * @param[in] us Number of microseconds to delay. + */ +void nrf_drv_systick_delay_us(uint32_t us); + +/** + * @brief Blocking delay in ms + * + * This delay function removes the limits of the highest possible delay value. + * + * @param[in] ms Number of milliseconds to delay. + */ +void nrf_drv_systick_delay_ms(uint32_t ms); + + +/** @} */ +#endif /* NRF_DRV_SYSTICK_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/timer/nrf_drv_timer.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/timer/nrf_drv_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..2b3bde210656429a1263e6e7bf3b647b03f70287 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/timer/nrf_drv_timer.c @@ -0,0 +1,332 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(TIMER) +#define ENABLED_TIMER_COUNT (TIMER0_ENABLED+TIMER1_ENABLED+TIMER2_ENABLED+TIMER3_ENABLED+TIMER4_ENABLED) +#if ENABLED_TIMER_COUNT +#include "nrf_drv_timer.h" +#include "nrf_drv_common.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "TIMER" + +#if TIMER_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL TIMER_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR TIMER_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR TIMER_CONFIG_DEBUG_COLOR +#else //TIMER_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //TIMER_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +/**@brief Timer control block. */ +typedef struct +{ + nrf_timer_event_handler_t handler; + void * context; + nrf_drv_state_t state; +} timer_control_block_t; + +static timer_control_block_t m_cb[ENABLED_TIMER_COUNT]; + +ret_code_t nrf_drv_timer_init(nrf_drv_timer_t const * const p_instance, + nrf_drv_timer_config_t const * p_config, + nrf_timer_event_handler_t timer_event_handler) +{ + timer_control_block_t * p_cb = &m_cb[p_instance->instance_id]; + ASSERT(((p_instance->p_reg == NRF_TIMER0) && TIMER0_ENABLED) || (p_instance->p_reg != NRF_TIMER0)); + ASSERT(((p_instance->p_reg == NRF_TIMER1) && TIMER1_ENABLED) || (p_instance->p_reg != NRF_TIMER1)); + ASSERT(((p_instance->p_reg == NRF_TIMER2) && TIMER2_ENABLED) || (p_instance->p_reg != NRF_TIMER2)); +#if TIMER_COUNT == 5 + ASSERT(((p_instance->p_reg == NRF_TIMER3) && TIMER3_ENABLED) || (p_instance->p_reg != NRF_TIMER3)); + ASSERT(((p_instance->p_reg == NRF_TIMER4) && TIMER4_ENABLED) || (p_instance->p_reg != NRF_TIMER4)); +#endif //TIMER_COUNT +#ifdef SOFTDEVICE_PRESENT + ASSERT(p_instance->p_reg != NRF_TIMER0); +#endif + ASSERT(p_config); + + ret_code_t err_code; + + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + if (timer_event_handler == NULL) + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + /* Warning 685: Relational operator '<=' always evaluates to 'true'" + * Warning in NRF_TIMER_IS_BIT_WIDTH_VALID macro. Macro validate timers resolution. + * Not necessary in nRF52 based systems. Obligatory in nRF51 based systems. + */ + + /*lint -save -e685 */ + + ASSERT(NRF_TIMER_IS_BIT_WIDTH_VALID(p_instance->p_reg, p_config->bit_width)); + + //lint -restore + + p_cb->handler = timer_event_handler; + p_cb->context = p_config->p_context; + + uint8_t i; + for (i = 0; i < p_instance->cc_channel_count; ++i) + { + nrf_timer_event_clear(p_instance->p_reg, + nrf_timer_compare_event_get(i)); + } + + nrf_drv_common_irq_enable(nrf_drv_get_IRQn(p_instance->p_reg), + p_config->interrupt_priority); + + nrf_timer_mode_set(p_instance->p_reg, p_config->mode); + nrf_timer_bit_width_set(p_instance->p_reg, p_config->bit_width); + nrf_timer_frequency_set(p_instance->p_reg, p_config->frequency); + + p_cb->state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +void nrf_drv_timer_uninit(nrf_drv_timer_t const * const p_instance) +{ + nrf_drv_common_irq_disable(nrf_drv_get_IRQn(p_instance->p_reg)); + + #define DISABLE_ALL UINT32_MAX + nrf_timer_shorts_disable(p_instance->p_reg, DISABLE_ALL); + nrf_timer_int_disable(p_instance->p_reg, DISABLE_ALL); + #undef DISABLE_ALL + + if (m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON) + { + nrf_drv_timer_disable(p_instance); + } + + m_cb[p_instance->instance_id].state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Uninitialized instance: %d.\r\n", p_instance->instance_id); +} + +void nrf_drv_timer_enable(nrf_drv_timer_t const * const p_instance) +{ + ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_INITIALIZED); + nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_START); + m_cb[p_instance->instance_id].state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Enabled instance: %d.\r\n", p_instance->instance_id); +} + +void nrf_drv_timer_disable(nrf_drv_timer_t const * const p_instance) +{ + ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON); + nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_SHUTDOWN); + m_cb[p_instance->instance_id].state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Disabled instance: %d.\r\n", p_instance->instance_id); +} + +void nrf_drv_timer_resume(nrf_drv_timer_t const * const p_instance) +{ + ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON); + nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_START); + NRF_LOG_INFO("Resumed instance: %d.\r\n", p_instance->instance_id); +} + +void nrf_drv_timer_pause(nrf_drv_timer_t const * const p_instance) +{ + ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON); + nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_STOP); + NRF_LOG_INFO("Paused instance: %d.\r\n", p_instance->instance_id); +} + +void nrf_drv_timer_clear(nrf_drv_timer_t const * const p_instance) +{ + ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); + nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_CLEAR); +} + +void nrf_drv_timer_increment(nrf_drv_timer_t const * const p_instance) +{ + ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON); + ASSERT(nrf_timer_mode_get(p_instance->p_reg) != NRF_TIMER_MODE_TIMER); + + nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_COUNT); +} + +uint32_t nrf_drv_timer_capture(nrf_drv_timer_t const * const p_instance, + nrf_timer_cc_channel_t cc_channel) +{ + ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON); + ASSERT(cc_channel < p_instance->cc_channel_count); + + nrf_timer_task_trigger(p_instance->p_reg, + nrf_timer_capture_task_get(cc_channel)); + return nrf_timer_cc_read(p_instance->p_reg, cc_channel); +} + +void nrf_drv_timer_compare(nrf_drv_timer_t const * const p_instance, + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value, + bool enable_int) +{ + nrf_timer_int_mask_t timer_int = nrf_timer_compare_int_get(cc_channel); + + if (enable_int) + { + nrf_timer_int_enable(p_instance->p_reg, timer_int); + } + else + { + nrf_timer_int_disable(p_instance->p_reg, timer_int); + } + + nrf_timer_cc_write(p_instance->p_reg, cc_channel, cc_value); + NRF_LOG_INFO("Timer id: %d, capture value set: %d, channel: %d.\r\n", p_instance->instance_id, cc_value, cc_channel); +} + +void nrf_drv_timer_extended_compare(nrf_drv_timer_t const * const p_instance, + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value, + nrf_timer_short_mask_t timer_short_mask, + bool enable_int) +{ + nrf_timer_shorts_disable(p_instance->p_reg, + (TIMER_SHORTS_COMPARE0_STOP_Msk << cc_channel) | + (TIMER_SHORTS_COMPARE0_CLEAR_Msk << cc_channel)); + + nrf_timer_shorts_enable(p_instance->p_reg, timer_short_mask); + + (void)nrf_drv_timer_compare(p_instance, + cc_channel, + cc_value, + enable_int); + NRF_LOG_INFO("Timer id: %d, capture value set: %d, channel: %d.\r\n", p_instance->instance_id, cc_value, cc_channel); +} + +void nrf_drv_timer_compare_int_enable(nrf_drv_timer_t const * const p_instance, + uint32_t channel) +{ + ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(channel < p_instance->cc_channel_count); + + nrf_timer_event_clear(p_instance->p_reg, + nrf_timer_compare_event_get(channel)); + nrf_timer_int_enable(p_instance->p_reg, + nrf_timer_compare_int_get(channel)); +} + +void nrf_drv_timer_compare_int_disable(nrf_drv_timer_t const * const p_instance, + uint32_t channel) +{ + ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(channel < p_instance->cc_channel_count); + + nrf_timer_int_disable(p_instance->p_reg, + nrf_timer_compare_int_get(channel)); +} + +static void irq_handler(NRF_TIMER_Type * p_reg, + timer_control_block_t * p_cb, + uint8_t channel_count) +{ + uint8_t i; + for (i = 0; i < channel_count; ++i) + { + nrf_timer_event_t event = nrf_timer_compare_event_get(i); + nrf_timer_int_mask_t int_mask = nrf_timer_compare_int_get(i); + + if (nrf_timer_event_check(p_reg, event) && + nrf_timer_int_enable_check(p_reg, int_mask)) + { + nrf_timer_event_clear(p_reg, event); + NRF_LOG_DEBUG("Compare event, channel: %d.\r\n", i); + p_cb->handler(event, p_cb->context); + } + } +} + +#if NRF_MODULE_ENABLED(TIMER0) +void TIMER0_IRQHandler(void) +{ + irq_handler(NRF_TIMER0, &m_cb[TIMER0_INSTANCE_INDEX], + NRF_TIMER_CC_CHANNEL_COUNT(0)); +} +#endif + +#if NRF_MODULE_ENABLED(TIMER1) +void TIMER1_IRQHandler(void) +{ + irq_handler(NRF_TIMER1, &m_cb[TIMER1_INSTANCE_INDEX], + NRF_TIMER_CC_CHANNEL_COUNT(1)); +} +#endif + +#if NRF_MODULE_ENABLED(TIMER2) +void TIMER2_IRQHandler(void) +{ + irq_handler(NRF_TIMER2, &m_cb[TIMER2_INSTANCE_INDEX], + NRF_TIMER_CC_CHANNEL_COUNT(2)); +} +#endif + +#if NRF_MODULE_ENABLED(TIMER3) +void TIMER3_IRQHandler(void) +{ + irq_handler(NRF_TIMER3, &m_cb[TIMER3_INSTANCE_INDEX], + NRF_TIMER_CC_CHANNEL_COUNT(3)); +} +#endif + +#if NRF_MODULE_ENABLED(TIMER4) +void TIMER4_IRQHandler(void) +{ + irq_handler(NRF_TIMER4, &m_cb[TIMER4_INSTANCE_INDEX], + NRF_TIMER_CC_CHANNEL_COUNT(4)); +} +#endif +#endif // ENABLED_TIMER_COUNT +#endif // NRF_MODULE_ENABLED(TIMER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/timer/nrf_drv_timer.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/timer/nrf_drv_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..8d8cba05435cbf4e9f69486583d533d0edf53083 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/timer/nrf_drv_timer.h @@ -0,0 +1,410 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * @addtogroup nrf_timer Timer HAL and driver + * @ingroup nrf_drivers + * @brief Timer APIs. + * @details The timer HAL provides basic APIs for accessing the registers + * of the timer. The timer driver provides APIs on a higher level. + * + * @defgroup nrf_drv_timer Timer driver + * @{ + * @ingroup nrf_timer + * @brief Multi-instance timer driver. + */ + +#ifndef NRF_DRV_TIMER_H__ +#define NRF_DRV_TIMER_H__ + +#include "nordic_common.h" +#include "sdk_config.h" +#include "nrf_timer.h" +#include "sdk_errors.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Timer driver instance data structure. + */ +typedef struct +{ + NRF_TIMER_Type * p_reg; ///< Pointer to the structure with TIMER peripheral instance registers. + uint8_t instance_id; ///< Driver instance index. + uint8_t cc_channel_count; ///< Number of capture/compare channels. +} nrf_drv_timer_t; + +#define ENABLED_TIMER_COUNT (TIMER0_ENABLED+TIMER1_ENABLED+TIMER2_ENABLED+TIMER3_ENABLED+TIMER4_ENABLED) + +#define TIMER0_INSTANCE_INDEX 0 +#define TIMER1_INSTANCE_INDEX TIMER0_INSTANCE_INDEX+TIMER0_ENABLED +#define TIMER2_INSTANCE_INDEX TIMER1_INSTANCE_INDEX+TIMER1_ENABLED +#define TIMER3_INSTANCE_INDEX TIMER2_INSTANCE_INDEX+TIMER2_ENABLED +#define TIMER4_INSTANCE_INDEX TIMER3_INSTANCE_INDEX+TIMER3_ENABLED + +/** + * @brief Macro for creating a timer driver instance. + */ +#define NRF_DRV_TIMER_INSTANCE(id) \ +{ \ + .p_reg = CONCAT_2(NRF_TIMER, id), \ + .instance_id = CONCAT_3(TIMER, id, _INSTANCE_INDEX), \ + .cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(id), \ +} + +/** + * @brief Timer driver instance configuration structure. + */ +typedef struct +{ + nrf_timer_frequency_t frequency; ///< Frequency. + nrf_timer_mode_t mode; ///< Mode of operation. + nrf_timer_bit_width_t bit_width; ///< Bit width. + uint8_t interrupt_priority; ///< Interrupt priority. + void * p_context; ///< Context passed to interrupt handler. +} nrf_drv_timer_config_t; + +/** + * @brief Timer driver instance default configuration. + */ +#define NRF_DRV_TIMER_DEFAULT_CONFIG \ +{ \ + .frequency = (nrf_timer_frequency_t)TIMER_DEFAULT_CONFIG_FREQUENCY,\ + .mode = (nrf_timer_mode_t)TIMER_DEFAULT_CONFIG_MODE, \ + .bit_width = (nrf_timer_bit_width_t)TIMER_DEFAULT_CONFIG_BIT_WIDTH,\ + .interrupt_priority = TIMER_DEFAULT_CONFIG_IRQ_PRIORITY, \ + .p_context = NULL \ +} + +/** + * @brief Timer driver event handler type. + * + * @param[in] event_type Timer event. + * @param[in] p_context General purpose parameter set during initialization of + * the timer. This parameter can be used to pass + * additional information to the handler function, for + * example, the timer ID. + */ +typedef void (* nrf_timer_event_handler_t)(nrf_timer_event_t event_type, + void * p_context); + +/** + * @brief Function for initializing the timer. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_config Initial configuration. Must not be NULL. + * @param[in] timer_event_handler Event handler provided by the user. + * Must not be NULL. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the instance is already initialized. + * @retval NRF_ERROR_INVALID_PARAM If no handler was provided. + */ +ret_code_t nrf_drv_timer_init(nrf_drv_timer_t const * const p_instance, + nrf_drv_timer_config_t const * p_config, + nrf_timer_event_handler_t timer_event_handler); + +/** + * @brief Function for uninitializing the timer. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_timer_uninit(nrf_drv_timer_t const * const p_instance); + +/** + * @brief Function for turning on the timer. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_timer_enable(nrf_drv_timer_t const * const p_instance); + +/** + * @brief Function for turning off the timer. + * + * Note that the timer will allow to enter the lowest possible SYSTEM_ON state + * only after this function is called. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_timer_disable(nrf_drv_timer_t const * const p_instance); + +/** + * @brief Function for pausing the timer. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_timer_pause(nrf_drv_timer_t const * const p_instance); + +/** + * @brief Function for resuming the timer. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_timer_resume(nrf_drv_timer_t const * const p_instance); + +/** + * @brief Function for clearing the timer. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_timer_clear(nrf_drv_timer_t const * const p_instance); + +/** + * @brief Function for incrementing the timer. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_timer_increment(nrf_drv_timer_t const * const p_instance); + +/** + * @brief Function for returning the address of a specific timer task. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] timer_task Timer task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_timer_task_address_get( + nrf_drv_timer_t const * const p_instance, + nrf_timer_task_t timer_task); + +/** + * @brief Function for returning the address of a specific timer capture task. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] channel Capture channel number. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_timer_capture_task_address_get( + nrf_drv_timer_t const * const p_instance, + uint32_t channel); + +/** + * @brief Function for returning the address of a specific timer event. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] timer_event Timer event. + * + * @return Event address. + */ +__STATIC_INLINE uint32_t nrf_drv_timer_event_address_get( + nrf_drv_timer_t const * const p_instance, + nrf_timer_event_t timer_event); + +/** + * @brief Function for returning the address of a specific timer compare event. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] channel Compare channel number. + * + * @return Event address. + */ +__STATIC_INLINE uint32_t nrf_drv_timer_compare_event_address_get( + nrf_drv_timer_t const * const p_instance, + uint32_t channel); + +/** + * @brief Function for capturing the timer value. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] cc_channel Capture channel number. + * + * @return Captured value. + */ +uint32_t nrf_drv_timer_capture(nrf_drv_timer_t const * const p_instance, + nrf_timer_cc_channel_t cc_channel); + +/** + * @brief Function for returning the capture value from a specific channel. + * + * Use this function to read channel values when PPI is used for capturing. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] cc_channel Capture channel number. + * + * @return Captured value. + */ +__STATIC_INLINE uint32_t nrf_drv_timer_capture_get( + nrf_drv_timer_t const * const p_instance, + nrf_timer_cc_channel_t cc_channel); + +/** + * @brief Function for setting the timer channel in compare mode. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] cc_channel Compare channel number. + * @param[in] cc_value Compare value. + * @param[in] enable_int Enable or disable the interrupt for the compare channel. + */ +void nrf_drv_timer_compare(nrf_drv_timer_t const * const p_instance, + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value, + bool enable_int); + +/** + * @brief Function for setting the timer channel in extended compare mode. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] cc_channel Compare channel number. + * @param[in] cc_value Compare value. + * @param[in] timer_short_mask Shortcut between the compare event on the channel + * and the timer task (STOP or CLEAR). + * @param[in] enable_int Enable or disable the interrupt for the compare + * channel. + */ +void nrf_drv_timer_extended_compare(nrf_drv_timer_t const * const p_instance, + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value, + nrf_timer_short_mask_t timer_short_mask, + bool enable_int); + +/** + * @brief Function for converting time in microseconds to timer ticks. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] time_us Time in microseconds. + * + * @return Number of ticks. + */ +__STATIC_INLINE uint32_t nrf_drv_timer_us_to_ticks( + nrf_drv_timer_t const * const p_instance, + uint32_t time_us); + +/** + * @brief Function for converting time in milliseconds to timer ticks. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] time_ms Time in milliseconds. + * + * @return Number of ticks. + */ +__STATIC_INLINE uint32_t nrf_drv_timer_ms_to_ticks( + nrf_drv_timer_t const * const p_instance, + uint32_t time_ms); + +/** + * @brief Function for enabling timer compare interrupt. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] channel Compare channel. + */ +void nrf_drv_timer_compare_int_enable(nrf_drv_timer_t const * const p_instance, + uint32_t channel); + +/** + * @brief Function for disabling timer compare interrupt. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] channel Compare channel. + */ +void nrf_drv_timer_compare_int_disable(nrf_drv_timer_t const * const p_instance, + uint32_t channel); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t nrf_drv_timer_task_address_get( + nrf_drv_timer_t const * const p_instance, + nrf_timer_task_t timer_task) +{ + return (uint32_t)nrf_timer_task_address_get(p_instance->p_reg, timer_task); +} + +__STATIC_INLINE uint32_t nrf_drv_timer_capture_task_address_get( + nrf_drv_timer_t const * const p_instance, + uint32_t channel) +{ + ASSERT(channel < p_instance->cc_channel_count); + return (uint32_t)nrf_timer_task_address_get(p_instance->p_reg, + nrf_timer_capture_task_get(channel)); +} + +__STATIC_INLINE uint32_t nrf_drv_timer_event_address_get( + nrf_drv_timer_t const * const p_instance, + nrf_timer_event_t timer_event) +{ + return (uint32_t)nrf_timer_event_address_get(p_instance->p_reg, timer_event); +} + +__STATIC_INLINE uint32_t nrf_drv_timer_compare_event_address_get( + nrf_drv_timer_t const * const p_instance, + uint32_t channel) +{ + ASSERT(channel < p_instance->cc_channel_count); + return (uint32_t)nrf_timer_event_address_get(p_instance->p_reg, + nrf_timer_compare_event_get(channel)); +} + +__STATIC_INLINE uint32_t nrf_drv_timer_capture_get( + nrf_drv_timer_t const * const p_instance, + nrf_timer_cc_channel_t cc_channel) +{ + return nrf_timer_cc_read(p_instance->p_reg, cc_channel); +} + +__STATIC_INLINE uint32_t nrf_drv_timer_us_to_ticks( + nrf_drv_timer_t const * const p_instance, + uint32_t timer_us) +{ + return nrf_timer_us_to_ticks(timer_us, + nrf_timer_frequency_get(p_instance->p_reg)); +} + +__STATIC_INLINE uint32_t nrf_drv_timer_ms_to_ticks( + nrf_drv_timer_t const * const p_instance, + uint32_t timer_ms) +{ + return nrf_timer_ms_to_ticks(timer_ms, + nrf_timer_frequency_get(p_instance->p_reg)); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_TIMER_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/deprecated/config/twi_master_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/deprecated/config/twi_master_config.h new file mode 100644 index 0000000000000000000000000000000000000000..8a161cc30c6b8e54a4b63b4c6048bb144d5f2032 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/deprecated/config/twi_master_config.h @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef TWI_MASTER_CONFIG +#define TWI_MASTER_CONFIG + +#ifdef __cplusplus +extern "C" { +#endif + +#define TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER (24U) +#define TWI_MASTER_CONFIG_DATA_PIN_NUMBER (25U) + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/deprecated/twi_hw_master.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/deprecated/twi_hw_master.c new file mode 100644 index 0000000000000000000000000000000000000000..767abf0ec96e5b7b7b6182a45cc59544efed15d2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/deprecated/twi_hw_master.c @@ -0,0 +1,331 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "twi_master.h" +#include "twi_master_config.h" +#include +#include +#include "nrf.h" +#include "nrf_delay.h" +#include "nrf_gpio.h" + +/* Max cycles approximately to wait on RXDREADY and TXDREADY event, + * This is optimized way instead of using timers, this is not power aware. */ +#define MAX_TIMEOUT_LOOPS (20000UL) /**< MAX while loops to wait for RXD/TXD event */ + +static bool twi_master_write(uint8_t * data, uint8_t data_length, bool issue_stop_condition) +{ + uint32_t timeout = MAX_TIMEOUT_LOOPS; /* max loops to wait for EVENTS_TXDSENT event*/ + + if (data_length == 0) + { + /* Return false for requesting data of size 0 */ + return false; + } + + NRF_TWI1->TXD = *data++; + NRF_TWI1->TASKS_STARTTX = 1; + + /** @snippet [TWI HW master write] */ + while (true) + { + while (NRF_TWI1->EVENTS_TXDSENT == 0 && NRF_TWI1->EVENTS_ERROR == 0 && (--timeout)) + { + // Do nothing. + } + + if (timeout == 0 || NRF_TWI1->EVENTS_ERROR != 0) + { + // Recover the peripheral as indicated by PAN 56: "TWI: TWI module lock-up." found at + // Product Anomaly Notification document found at + // https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822/#Downloads + NRF_TWI1->EVENTS_ERROR = 0; + NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; + NRF_TWI1->POWER = 0; + nrf_delay_us(5); + NRF_TWI1->POWER = 1; + NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos; + + (void)twi_master_init(); + + return false; + } + NRF_TWI1->EVENTS_TXDSENT = 0; + if (--data_length == 0) + { + break; + } + + NRF_TWI1->TXD = *data++; + } + /** @snippet [TWI HW master write] */ + + if (issue_stop_condition) + { + NRF_TWI1->EVENTS_STOPPED = 0; + NRF_TWI1->TASKS_STOP = 1; + /* Wait until stop sequence is sent */ + while (NRF_TWI1->EVENTS_STOPPED == 0) + { + // Do nothing. + } + } + return true; +} + + +/** @brief Function for read by twi_master. + */ +static bool twi_master_read(uint8_t * data, uint8_t data_length, bool issue_stop_condition) +{ + uint32_t timeout = MAX_TIMEOUT_LOOPS; /* max loops to wait for RXDREADY event*/ + + if (data_length == 0) + { + /* Return false for requesting data of size 0 */ + return false; + } + else if (data_length == 1) + { + NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_STOP; + } + else + { + NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_SUSPEND; + } + + NRF_PPI->CHENSET = PPI_CHENSET_CH0_Msk; + NRF_TWI1->EVENTS_RXDREADY = 0; + NRF_TWI1->TASKS_STARTRX = 1; + + /** @snippet [TWI HW master read] */ + while (true) + { + while (NRF_TWI1->EVENTS_RXDREADY == 0 && NRF_TWI1->EVENTS_ERROR == 0 && (--timeout)) + { + // Do nothing. + } + NRF_TWI1->EVENTS_RXDREADY = 0; + + if (timeout == 0 || NRF_TWI1->EVENTS_ERROR != 0) + { + // Recover the peripheral as indicated by PAN 56: "TWI: TWI module lock-up." found at + // Product Anomaly Notification document found at + // https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822/#Downloads + NRF_TWI1->EVENTS_ERROR = 0; + NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; + NRF_TWI1->POWER = 0; + nrf_delay_us(5); + NRF_TWI1->POWER = 1; + NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos; + + (void)twi_master_init(); + + return false; + } + + *data++ = NRF_TWI1->RXD; + + /* Configure PPI to stop TWI master before we get last BB event */ + if (--data_length == 1) + { + NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_STOP; + } + + if (data_length == 0) + { + break; + } + + // Recover the peripheral as indicated by PAN 56: "TWI: TWI module lock-up." found at + // Product Anomaly Notification document found at + // https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822/#Downloads + nrf_delay_us(20); + NRF_TWI1->TASKS_RESUME = 1; + } + /** @snippet [TWI HW master read] */ + + /* Wait until stop sequence is sent */ + while (NRF_TWI1->EVENTS_STOPPED == 0) + { + // Do nothing. + } + NRF_TWI1->EVENTS_STOPPED = 0; + + NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Msk; + return true; +} + + +/** + * @brief Function for detecting stuck slaves (SDA = 0 and SCL = 1) and tries to clear the bus. + * + * @return + * @retval false Bus is stuck. + * @retval true Bus is clear. + */ +static bool twi_master_clear_bus(void) +{ + uint32_t twi_state; + bool bus_clear; + uint32_t clk_pin_config; + uint32_t data_pin_config; + + // Save and disable TWI hardware so software can take control over the pins. + twi_state = NRF_TWI1->ENABLE; + NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; + + clk_pin_config = \ + NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER]; + NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] = \ + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ + | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ + | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ + | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ + | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + + data_pin_config = \ + NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER]; + NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] = \ + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ + | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ + | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ + | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ + | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + + TWI_SDA_HIGH(); + TWI_SCL_HIGH(); + TWI_DELAY(); + + if ((TWI_SDA_READ() == 1) && (TWI_SCL_READ() == 1)) + { + bus_clear = true; + } + else + { + uint_fast8_t i; + bus_clear = false; + + // Clock max 18 pulses worst case scenario(9 for master to send the rest of command and 9 + // for slave to respond) to SCL line and wait for SDA come high. + for (i=18; i--;) + { + TWI_SCL_LOW(); + TWI_DELAY(); + TWI_SCL_HIGH(); + TWI_DELAY(); + + if (TWI_SDA_READ() == 1) + { + bus_clear = true; + break; + } + } + } + + NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] = clk_pin_config; + NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] = data_pin_config; + + NRF_TWI1->ENABLE = twi_state; + + return bus_clear; +} + + +/** @brief Function for initializing the twi_master. + */ +bool twi_master_init(void) +{ + /* To secure correct signal levels on the pins used by the TWI + master when the system is in OFF mode, and when the TWI master is + disabled, these pins must be configured in the GPIO peripheral. + */ + NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] = \ + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ + | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ + | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ + | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ + | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos); + + NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] = \ + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ + | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ + | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ + | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ + | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos); + + NRF_TWI1->EVENTS_RXDREADY = 0; + NRF_TWI1->EVENTS_TXDSENT = 0; + NRF_TWI1->PSELSCL = TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER; + NRF_TWI1->PSELSDA = TWI_MASTER_CONFIG_DATA_PIN_NUMBER; + NRF_TWI1->FREQUENCY = TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos; + NRF_PPI->CH[0].EEP = (uint32_t)&NRF_TWI1->EVENTS_BB; + NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_SUSPEND; + NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Msk; + NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos; + + return twi_master_clear_bus(); +} + + +/** @brief Function for transfer by twi_master. + */ +bool twi_master_transfer(uint8_t address, + uint8_t * data, + uint8_t data_length, + bool issue_stop_condition) +{ + bool transfer_succeeded = false; + if (data_length > 0 && twi_master_clear_bus()) + { + NRF_TWI1->ADDRESS = (address >> 1); + + if ((address & TWI_READ_BIT)) + { + transfer_succeeded = twi_master_read(data, data_length, issue_stop_condition); + } + else + { + transfer_succeeded = twi_master_write(data, data_length, issue_stop_condition); + } + } + return transfer_succeeded; +} + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/deprecated/twi_master.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/deprecated/twi_master.h new file mode 100644 index 0000000000000000000000000000000000000000..4bceb87407df492df735903aa2e5c94aed6f470b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/deprecated/twi_master.h @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef TWI_MASTER_H +#define TWI_MASTER_H + +/*lint ++flb "Enter library region" */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file +* @brief Software controlled TWI Master driver. +* +* +* @defgroup lib_driver_twi_master Software controlled TWI Master driver +* @{ +* @ingroup nrf_twi +* @brief Software controlled TWI Master driver (deprecated). +* +* @warning This module is deprecated. +* +* Supported features: +* - Repeated start +* - No multi-master +* - Only 7-bit addressing +* - Supports clock stretching (with optional SMBus style slave timeout) +* - Tries to handle slaves stuck in the middle of transfer +*/ + +#define TWI_READ_BIT (0x01) //!< If this bit is set in the address field, transfer direction is from slave to master. + +#define TWI_ISSUE_STOP ((bool)true) //!< Parameter for @ref twi_master_transfer +#define TWI_DONT_ISSUE_STOP ((bool)false) //!< Parameter for @ref twi_master_transfer + +/* These macros are needed to see if the slave is stuck and we as master send dummy clock cycles to end its wait */ +/*lint -e717 -save "Suppress do {} while (0) for these macros" */ +/*lint ++flb "Enter library region" */ +#define TWI_SCL_HIGH() do { NRF_GPIO->OUTSET = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Pulls SCL line high */ +#define TWI_SCL_LOW() do { NRF_GPIO->OUTCLR = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Pulls SCL line low */ +#define TWI_SDA_HIGH() do { NRF_GPIO->OUTSET = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Pulls SDA line high */ +#define TWI_SDA_LOW() do { NRF_GPIO->OUTCLR = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Pulls SDA line low */ +#define TWI_SDA_INPUT() do { NRF_GPIO->DIRCLR = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Configures SDA pin as input */ +#define TWI_SDA_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Configures SDA pin as output */ +#define TWI_SCL_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Configures SCL pin as output */ +/*lint -restore */ + +#define TWI_SDA_READ() ((NRF_GPIO->IN >> TWI_MASTER_CONFIG_DATA_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SDA */ +#define TWI_SCL_READ() ((NRF_GPIO->IN >> TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SCL */ + +#define TWI_DELAY() nrf_delay_us(4) /*!< Time to wait when pin states are changed. For fast-mode the delay can be zero and for standard-mode 4 us delay is sufficient. */ + + +/** + * @brief Function for initializing TWI bus IO pins and checks if the bus is operational. + * + * Both pins are configured as Standard-0, No-drive-1 (open drain). + * + * @return + * @retval true TWI bus is clear for transfers. + * @retval false TWI bus is stuck. + */ +bool twi_master_init(void); + +/** + * @brief Function for transferring data over TWI bus. + * + * If TWI master detects even one NACK from the slave or timeout occurs, STOP condition is issued + * and the function returns false. + * Bit 0 (@ref TWI_READ_BIT) in the address parameter controls transfer direction; + * - If 1, master reads data_length number of bytes from the slave + * - If 0, master writes data_length number of bytes to the slave. + * + * @note Make sure at least data_length number of bytes is allocated in data if TWI_READ_BIT is set. + * @note @ref TWI_ISSUE_STOP + * + * @param address Data transfer direction (LSB) / Slave address (7 MSBs). + * @param data Pointer to data. + * @param data_length Number of bytes to transfer. + * @param issue_stop_condition If @ref TWI_ISSUE_STOP, STOP condition is issued before exiting function. If @ref TWI_DONT_ISSUE_STOP, STOP condition is not issued before exiting function. If transfer failed for any reason, STOP condition will be issued in any case. + * @return + * @retval true Data transfer succeeded without errors. + * @retval false Data transfer failed. + */ +bool twi_master_transfer(uint8_t address, uint8_t *data, uint8_t data_length, bool issue_stop_condition); + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + +#endif //TWI_MASTER_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/deprecated/twi_sw_master.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/deprecated/twi_sw_master.c new file mode 100644 index 0000000000000000000000000000000000000000..44f03da6f0ecc6ffe45b30392de72cd66f4372c4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/deprecated/twi_sw_master.c @@ -0,0 +1,519 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "twi_master.h" +#include "nrf_delay.h" + +#include "twi_master_config.h" + +/*lint -e415 -e845 -save "Out of bounds access" */ +#define TWI_SDA_STANDARD0_NODRIVE1() do { \ + NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ + |(GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ + |(GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ + |(GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ + |(GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos); \ +} while (0) /*!< Configures SDA pin to Standard-0, No-drive 1 */ + + +#define TWI_SCL_STANDARD0_NODRIVE1() do { \ + NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ + |(GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ + |(GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ + |(GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ + |(GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos); \ +} while (0) /*!< Configures SCL pin to Standard-0, No-drive 1 */ + + +/*lint -restore */ + +#ifndef TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE +#define TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE (0UL) //!< Unit is number of empty loops. Timeout for SMBus devices is 35 ms. Set to zero to disable slave timeout altogether. +#endif + +static bool twi_master_clear_bus(void); +static bool twi_master_issue_startcondition(void); +static bool twi_master_issue_stopcondition(void); +static bool twi_master_clock_byte(uint_fast8_t databyte); +static bool twi_master_clock_byte_in(uint8_t * databyte, bool ack); +static bool twi_master_wait_while_scl_low(void); + +bool twi_master_init(void) +{ + // Configure both pins to output Standard 0, No-drive (open-drain) 1 + TWI_SDA_STANDARD0_NODRIVE1(); /*lint !e416 "Creation of out of bounds pointer" */ + TWI_SCL_STANDARD0_NODRIVE1(); /*lint !e416 "Creation of out of bounds pointer" */ + + // Configure SCL as output + TWI_SCL_HIGH(); + TWI_SCL_OUTPUT(); + + // Configure SDA as output + TWI_SDA_HIGH(); + TWI_SDA_OUTPUT(); + + return twi_master_clear_bus(); +} + +bool twi_master_transfer(uint8_t address, uint8_t * data, uint8_t data_length, bool issue_stop_condition) +{ + bool transfer_succeeded = true; + + transfer_succeeded &= twi_master_issue_startcondition(); + transfer_succeeded &= twi_master_clock_byte(address); + + if (address & TWI_READ_BIT) + { + /* Transfer direction is from Slave to Master */ + while (data_length-- && transfer_succeeded) + { + // To indicate to slave that we've finished transferring last data byte + // we need to NACK the last transfer. + if (data_length == 0) + { + transfer_succeeded &= twi_master_clock_byte_in(data, (bool)false); + } + else + { + transfer_succeeded &= twi_master_clock_byte_in(data, (bool)true); + } + data++; + } + } + else + { + /* Transfer direction is from Master to Slave */ + while (data_length-- && transfer_succeeded) + { + transfer_succeeded &= twi_master_clock_byte(*data); + data++; + } + } + + if (issue_stop_condition || !transfer_succeeded) + { + transfer_succeeded &= twi_master_issue_stopcondition(); + } + + return transfer_succeeded; +} + +/** + * @brief Function for detecting stuck slaves and tries to clear the bus. + * + * @return + * @retval false Bus is stuck. + * @retval true Bus is clear. + */ +static bool twi_master_clear_bus(void) +{ + bool bus_clear; + + TWI_SDA_HIGH(); + TWI_SCL_HIGH(); + TWI_DELAY(); + + + if (TWI_SDA_READ() == 1 && TWI_SCL_READ() == 1) + { + bus_clear = true; + } + else if (TWI_SCL_READ() == 1) + { + bus_clear = false; + // Clock max 18 pulses worst case scenario(9 for master to send the rest of command and 9 for slave to respond) to SCL line and wait for SDA come high + for (uint_fast8_t i = 18; i--;) + { + TWI_SCL_LOW(); + TWI_DELAY(); + TWI_SCL_HIGH(); + TWI_DELAY(); + + if (TWI_SDA_READ() == 1) + { + bus_clear = true; + break; + } + } + } + else + { + bus_clear = false; + } + + return bus_clear; +} + +/** + * @brief Function for issuing TWI START condition to the bus. + * + * START condition is signaled by pulling SDA low while SCL is high. After this function SCL and SDA will be low. + * + * @return + * @retval false Timeout detected + * @retval true Clocking succeeded + */ +static bool twi_master_issue_startcondition(void) +{ +#if 0 + if (TWI_SCL_READ() == 1 && TWI_SDA_READ() == 1) + { + // Pull SDA low + TWI_SDA_LOW(); + } + else if (TWI_SCL_READ() == 1 && TWI_SDA_READ() == 0) + { + // Issue Stop by pulling SDA high + TWI_SDA_HIGH(); + TWI_DELAY(); + + // Then Start by pulling SDA low + TWI_SDA_LOW(); + } + else if (TWI_SCL_READ() == 0 && TWI_SDA_READ() == 0) + { + // First pull SDA high + TWI_SDA_HIGH(); + + // Then SCL high + if (!twi_master_wait_while_scl_low()) + { + return false; + } + + // Then SDA low + TWI_SDA_LOW(); + } + else if (TWI_SCL_READ() == 0 && TWI_SDA_READ() == 1) + { + // SCL high + if (!twi_master_wait_while_scl_low()) + { + return false; + } + + // Then SDA low + TWI_SDA_LOW(); + } + + TWI_DELAY(); + TWI_SCL_LOW(); +#endif + + // Make sure both SDA and SCL are high before pulling SDA low. + TWI_SDA_HIGH(); + TWI_DELAY(); + if (!twi_master_wait_while_scl_low()) + { + return false; + } + + TWI_SDA_LOW(); + TWI_DELAY(); + + // Other module function expect SCL to be low + TWI_SCL_LOW(); + TWI_DELAY(); + + return true; +} + +/** + * @brief Function for issuing TWI STOP condition to the bus. + * + * STOP condition is signaled by pulling SDA high while SCL is high. After this function SDA and SCL will be high. + * + * @return + * @retval false Timeout detected + * @retval true Clocking succeeded + */ +static bool twi_master_issue_stopcondition(void) +{ +#if 0 + if (TWI_SCL_READ() == 1 && TWI_SDA_READ() == 1) + { + // Issue start, then issue stop + + // Pull SDA low to issue START + TWI_SDA_LOW(); + TWI_DELAY(); + + // Pull SDA high while SCL is high to issue STOP + TWI_SDA_HIGH(); + } + else if (TWI_SCL_READ() == 1 && TWI_SDA_READ() == 0) + { + // Pull SDA high while SCL is high to issue STOP + TWI_SDA_HIGH(); + } + else if (TWI_SCL_READ() == 0 && TWI_SDA_READ() == 0) + { + if (!twi_master_wait_while_scl_low()) + { + return false; + } + + // Pull SDA high while SCL is high to issue STOP + TWI_SDA_HIGH(); + } + else if (TWI_SCL_READ() == 0 && TWI_SDA_READ() == 1) + { + TWI_SDA_LOW(); + TWI_DELAY(); + + // SCL high + if (!twi_master_wait_while_scl_low()) + { + return false; + } + + // Pull SDA high while SCL is high to issue STOP + TWI_SDA_HIGH(); + } + + TWI_DELAY(); +#endif + + TWI_SDA_LOW(); + TWI_DELAY(); + if (!twi_master_wait_while_scl_low()) + { + return false; + } + + TWI_SDA_HIGH(); + TWI_DELAY(); + + return true; +} + +/** + * @brief Function for clocking one data byte out and reads slave acknowledgment. + * + * Can handle clock stretching. + * After calling this function SCL is low and SDA low/high depending on the + * value of LSB of the data byte. + * SCL is expected to be output and low when entering this function. + * + * @param databyte Data byte to clock out. + * @return + * @retval true Slave acknowledged byte. + * @retval false Timeout or slave didn't acknowledge byte. + */ +static bool twi_master_clock_byte(uint_fast8_t databyte) +{ + bool transfer_succeeded = true; + + /** @snippet [TWI SW master write] */ + // Make sure SDA is an output + TWI_SDA_OUTPUT(); + + // MSB first + for (uint_fast8_t i = 0x80; i != 0; i >>= 1) + { + TWI_SCL_LOW(); + TWI_DELAY(); + + if (databyte & i) + { + TWI_SDA_HIGH(); + } + else + { + TWI_SDA_LOW(); + } + + if (!twi_master_wait_while_scl_low()) + { + transfer_succeeded = false; // Timeout + break; + } + } + + // Finish last data bit by pulling SCL low + TWI_SCL_LOW(); + TWI_DELAY(); + + /** @snippet [TWI SW master write] */ + + // Configure TWI_SDA pin as input for receiving the ACK bit + TWI_SDA_INPUT(); + + // Give some time for the slave to load the ACK bit on the line + TWI_DELAY(); + + // Pull SCL high and wait a moment for SDA line to settle + // Make sure slave is not stretching the clock + transfer_succeeded &= twi_master_wait_while_scl_low(); + + // Read ACK/NACK. NACK == 1, ACK == 0 + transfer_succeeded &= !(TWI_SDA_READ()); + + // Finish ACK/NACK bit clock cycle and give slave a moment to release control + // of the SDA line + TWI_SCL_LOW(); + TWI_DELAY(); + + // Configure TWI_SDA pin as output as other module functions expect that + TWI_SDA_OUTPUT(); + + return transfer_succeeded; +} + + +/** + * @brief Function for clocking one data byte in and sends ACK/NACK bit. + * + * Can handle clock stretching. + * SCL is expected to be output and low when entering this function. + * After calling this function, SCL is high and SDA low/high depending if ACK/NACK was sent. + * + * @param databyte Data byte to clock out. + * @param ack If true, send ACK. Otherwise send NACK. + * @return + * @retval true Byte read succesfully + * @retval false Timeout detected + */ +static bool twi_master_clock_byte_in(uint8_t *databyte, bool ack) +{ + uint_fast8_t byte_read = 0; + bool transfer_succeeded = true; + + /** @snippet [TWI SW master read] */ + // Make sure SDA is an input + TWI_SDA_INPUT(); + + // SCL state is guaranteed to be high here + + // MSB first + for (uint_fast8_t i = 0x80; i != 0; i >>= 1) + { + if (!twi_master_wait_while_scl_low()) + { + transfer_succeeded = false; + break; + } + + if (TWI_SDA_READ()) + { + byte_read |= i; + } + else + { + // No need to do anything + } + + TWI_SCL_LOW(); + TWI_DELAY(); + } + + // Make sure SDA is an output before we exit the function + TWI_SDA_OUTPUT(); + /** @snippet [TWI SW master read] */ + + *databyte = (uint8_t)byte_read; + + // Send ACK bit + + // SDA high == NACK, SDA low == ACK + if (ack) + { + TWI_SDA_LOW(); + } + else + { + TWI_SDA_HIGH(); + } + + // Let SDA line settle for a moment + TWI_DELAY(); + + // Drive SCL high to start ACK/NACK bit transfer + // Wait until SCL is high, or timeout occurs + if (!twi_master_wait_while_scl_low()) + { + transfer_succeeded = false; // Timeout + } + + // Finish ACK/NACK bit clock cycle and give slave a moment to react + TWI_SCL_LOW(); + TWI_DELAY(); + + return transfer_succeeded; +} + + +/** + * @brief Function for pulling SCL high and waits until it is high or timeout occurs. + * + * SCL is expected to be output before entering this function. + * @note If TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE is set to zero, timeout functionality is not compiled in. + * @return + * @retval true SCL is now high. + * @retval false Timeout occurred and SCL is still low. + */ +static bool twi_master_wait_while_scl_low(void) +{ +#if TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE != 0 + uint32_t volatile timeout_counter = TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE; +#endif + + // Pull SCL high just in case if something left it low + TWI_SCL_HIGH(); + TWI_DELAY(); + + while (TWI_SCL_READ() == 0) + { + // If SCL is low, one of the slaves is busy and we must wait + +#if TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE != 0 + if (timeout_counter-- == 0) + { + // If timeout_detected, return false + return false; + } +#endif + } + + return true; +} + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/nrf_drv_twi.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/nrf_drv_twi.c new file mode 100644 index 0000000000000000000000000000000000000000..6cb2aac794a3cda9a4a7d9db563b1c7576bcd2cb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/nrf_drv_twi.c @@ -0,0 +1,1264 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(TWI) +#define ENABLED_TWI_COUNT (TWI0_ENABLED+TWI1_ENABLED) +#if ENABLED_TWI_COUNT +#include "nrf_drv_twi.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" +#include "nrf_assert.h" +#include "app_util_platform.h" +#include "nrf_delay.h" + +#include + +#define NRF_LOG_MODULE_NAME "TWI" + +#if TWI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL TWI_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR TWI_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR TWI_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_DRV_TWI_EVT_DONE ? "EVT_DONE" : \ + (event == NRF_DRV_TWI_EVT_ADDRESS_NACK ? "EVT_ADDRESS_NACK" : \ + (event == NRF_DRV_TWI_EVT_DATA_NACK ? "EVT_DATA_NACK" : "UNKNOWN ERROR"))) +#define EVT_TO_STR_TWI(event) (event == NRF_TWI_EVENT_STOPPED ? "NRF_TWI_EVENT_STOPPED" : \ + (event == NRF_TWI_EVENT_RXDREADY ? "NRF_TWI_EVENT_RXDREADY" : \ + (event == NRF_TWI_EVENT_TXDSENT ? "NRF_TWI_EVENT_TXDSENT" : \ + (event == NRF_TWI_EVENT_ERROR ? "NRF_TWI_EVENT_ERROR" : \ + (event == NRF_TWI_EVENT_BB ? "NRF_TWI_EVENT_BB" : \ + (event == NRF_TWI_EVENT_SUSPENDED ? "NRF_TWI_EVENT_SUSPENDED" : "UNKNOWN ERROR")))))) +#define EVT_TO_STR_TWIM(event) (event == NRF_TWIM_EVENT_STOPPED ? "NRF_TWIM_EVENT_STOPPED" : \ + (event == NRF_TWIM_EVENT_ERROR ? "NRF_TWIM_EVENT_ERROR" : \ + (event == NRF_TWIM_EVENT_SUSPENDED ? "NRF_TWIM_EVENT_SUSPENDED" : \ + (event == NRF_TWIM_EVENT_RXSTARTED ? "NRF_TWIM_EVENT_RXSTARTED" : \ + (event == NRF_TWIM_EVENT_TXSTARTED ? "NRF_TWIM_EVENT_TXSTARTED" : \ + (event == NRF_TWIM_EVENT_LASTRX ? "NRF_TWIM_EVENT_LASTRX" : \ + (event == NRF_TWIM_EVENT_LASTTX ? "NRF_TWIM_EVENT_LASTTX" : "UNKNOWN ERROR"))))))) +#define TRANSFER_TO_STR(type) (type == NRF_DRV_TWI_XFER_TX ? "XFER_TX" : \ + (type == NRF_DRV_TWI_XFER_RX ? "XFER_RX" : \ + (type == NRF_DRV_TWI_XFER_TXRX ? "XFER_TXRX" : \ + (type == NRF_DRV_TWI_XFER_TXTX ? "XFER_TXTX" : "UNKNOWN TRANSFER TYPE")))) +#else //TWI_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define EVT_TO_STR_TWI(event) "" +#define EVT_TO_STR_TWIM(event) "" +#define TRANSFER_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //TWI_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +#define TWI0_IRQ_HANDLER SPI0_TWI0_IRQHandler +#define TWI1_IRQ_HANDLER SPI1_TWI1_IRQHandler + +#if (defined(TWIM_IN_USE) && defined(TWI_IN_USE)) + // TWIM and TWI combined + #define CODE_FOR_TWIM(code) if (p_instance->use_easy_dma) { code } + #define CODE_FOR_TWI(code) else { code } +#elif (defined(TWIM_IN_USE) && !defined(TWI_IN_USE)) + // TWIM only + #define CODE_FOR_TWIM(code) { code } + #define CODE_FOR_TWI(code) +#elif (!defined(TWIM_IN_USE) && defined(TWI_IN_USE)) + // TWI only + #define CODE_FOR_TWIM(code) + #define CODE_FOR_TWI(code) { code } +#else + #error "Wrong configuration." +#endif + +// All interrupt flags +#define DISABLE_ALL_INT_SHORT 0xFFFFFFFF + +#define SCL_PIN_INIT_CONF ( (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ + | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ + | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ + | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ + | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)) +#define SDA_PIN_INIT_CONF SCL_PIN_INIT_CONF + +#define SDA_PIN_UNINIT_CONF ( (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ + | (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) \ + | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) \ + | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) \ + | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)) +#define SCL_PIN_UNINIT_CONF SDA_PIN_UNINIT_CONF + +#define SCL_PIN_INIT_CONF_CLR ( (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ + | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ + | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ + | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ + | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos)) +#define SDA_PIN_INIT_CONF_CLR SCL_PIN_INIT_CONF_CLR + +#define HW_TIMEOUT 10000 + +// Control block - driver instance local data. +typedef struct +{ + nrf_drv_twi_evt_handler_t handler; + void * p_context; + volatile uint32_t int_mask; + nrf_drv_twi_xfer_desc_t xfer_desc; + uint32_t flags; + uint8_t * p_curr_buf; + uint8_t curr_length; + bool curr_no_stop; + nrf_drv_state_t state; + bool error; + volatile bool busy; + bool repeated; + uint8_t bytes_transferred; + bool hold_bus_uninit; +#if NRF_MODULE_ENABLED(TWIM_NRF52_ANOMALY_109_WORKAROUND) + nrf_twim_frequency_t bus_frequency; +#endif +} twi_control_block_t; + +static twi_control_block_t m_cb[ENABLED_TWI_COUNT]; + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + #define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n + #define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void) + + #if NRF_MODULE_ENABLED(TWI0) + IRQ_HANDLER(0); + #endif + #if NRF_MODULE_ENABLED(TWI1) + IRQ_HANDLER(1); + #endif + static nrf_drv_irq_handler_t const m_irq_handlers[ENABLED_TWI_COUNT] = { + #if NRF_MODULE_ENABLED(TWI0) + IRQ_HANDLER_NAME(0), + #endif + #if NRF_MODULE_ENABLED(TWI1) + IRQ_HANDLER_NAME(1), + #endif + }; +#else + #define IRQ_HANDLER(n) void SPI##n##_TWI##n##_IRQHandler(void) +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +static ret_code_t twi_process_error(uint32_t errorsrc) +{ + ret_code_t ret = NRF_ERROR_INTERNAL; + + if (errorsrc & NRF_TWI_ERROR_OVERRUN) + { + ret = NRF_ERROR_DRV_TWI_ERR_OVERRUN; + } + + if (errorsrc & NRF_TWI_ERROR_ADDRESS_NACK) + { + ret = NRF_ERROR_DRV_TWI_ERR_ANACK; + } + + if (errorsrc & NRF_TWI_ERROR_DATA_NACK) + { + ret = NRF_ERROR_DRV_TWI_ERR_DNACK; + } + + return ret; +} + +static void twi_clear_bus(nrf_drv_twi_config_t const * p_config) +{ + NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_INIT_CONF; + NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_INIT_CONF; + + nrf_gpio_pin_set(p_config->scl); + nrf_gpio_pin_set(p_config->sda); + + NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_INIT_CONF_CLR; + NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_INIT_CONF_CLR; + + nrf_delay_us(4); + + for (int i = 0; i < 9; i++) + { + if (nrf_gpio_pin_read(p_config->sda)) + { + if (i == 0) + { + return; + } + else + { + break; + } + } + nrf_gpio_pin_clear(p_config->scl); + nrf_delay_us(4); + nrf_gpio_pin_set(p_config->scl); + nrf_delay_us(4); + } + nrf_gpio_pin_clear(p_config->sda); + nrf_delay_us(4); + nrf_gpio_pin_set(p_config->sda); +} + +ret_code_t nrf_drv_twi_init(nrf_drv_twi_t const * p_instance, + nrf_drv_twi_config_t const * p_config, + nrf_drv_twi_evt_handler_t event_handler, + void * p_context) +{ + ASSERT(p_config); + ASSERT(p_config->scl != p_config->sda); + twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ret_code_t err_code; + + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + if (nrf_drv_common_per_res_acquire(p_instance->reg.p_twi, + m_irq_handlers[p_instance->drv_inst_idx]) != NRF_SUCCESS) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + + p_cb->handler = event_handler; + p_cb->p_context = p_context; + p_cb->int_mask = 0; + p_cb->repeated = false; + p_cb->busy = false; + p_cb->hold_bus_uninit = p_config->hold_bus_uninit; +#if NRF_MODULE_ENABLED(TWIM_NRF52_ANOMALY_109_WORKAROUND) + p_cb->bus_frequency = (nrf_twim_frequency_t)p_config->frequency; +#endif + + if(p_config->clear_bus_init) + { + /* Send clocks (max 9) until slave device back from stuck mode */ + twi_clear_bus(p_config); + } + + /* To secure correct signal levels on the pins used by the TWI + master when the system is in OFF mode, and when the TWI master is + disabled, these pins must be configured in the GPIO peripheral. + */ + NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_INIT_CONF; + NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_INIT_CONF; + + CODE_FOR_TWIM + ( + NRF_TWIM_Type * p_twim = p_instance->reg.p_twim; + nrf_twim_pins_set(p_twim, p_config->scl, p_config->sda); + nrf_twim_frequency_set(p_twim, + (nrf_twim_frequency_t)p_config->frequency); + ) + CODE_FOR_TWI + ( + NRF_TWI_Type * p_twi = p_instance->reg.p_twi; + nrf_twi_pins_set(p_twi, p_config->scl, p_config->sda); + nrf_twi_frequency_set(p_twi, + (nrf_twi_frequency_t)p_config->frequency); + ) + + if (p_cb->handler) + { + CODE_FOR_TWIM + ( + nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twim), + p_config->interrupt_priority); + ) + CODE_FOR_TWI + ( + nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twi), + p_config->interrupt_priority); + ) + } + + p_cb->state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +void nrf_drv_twi_uninit(nrf_drv_twi_t const * p_instance) +{ + twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + if (p_cb->handler) + { + CODE_FOR_TWIM + ( + nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twim)); + ) + CODE_FOR_TWI + ( + nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twi)); + ) + } + nrf_drv_twi_disable(p_instance); + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + nrf_drv_common_per_res_release(p_instance->reg.p_twi); +#endif + + if (!p_cb->hold_bus_uninit) + { + CODE_FOR_TWIM + ( + NRF_GPIO->PIN_CNF[p_instance->reg.p_twim->PSEL.SCL] = SCL_PIN_UNINIT_CONF; + NRF_GPIO->PIN_CNF[p_instance->reg.p_twim->PSEL.SDA] = SDA_PIN_UNINIT_CONF; + ) + CODE_FOR_TWI + ( + NRF_GPIO->PIN_CNF[p_instance->reg.p_twi->PSELSCL] = SCL_PIN_UNINIT_CONF; + NRF_GPIO->PIN_CNF[p_instance->reg.p_twi->PSELSDA] = SDA_PIN_UNINIT_CONF; + ) + } + + p_cb->state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Instance uninitialized: %d.\r\n", p_instance->drv_inst_idx); +} + +void nrf_drv_twi_enable(nrf_drv_twi_t const * p_instance) +{ + twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state == NRF_DRV_STATE_INITIALIZED); + + CODE_FOR_TWIM + ( + NRF_TWIM_Type * p_twim = p_instance->reg.p_twim; + + nrf_twim_enable(p_twim); + ) + CODE_FOR_TWI + ( + NRF_TWI_Type * p_twi = p_instance->reg.p_twi; + + nrf_twi_enable(p_twi); + ) + + p_cb->state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Instance enabled: %d.\r\n", p_instance->drv_inst_idx); +} + +void nrf_drv_twi_disable(nrf_drv_twi_t const * p_instance) +{ + twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + CODE_FOR_TWIM + ( + NRF_TWIM_Type * p_twim = p_instance->reg.p_twim; + p_cb->int_mask = 0; + nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT); + nrf_twim_shorts_disable(p_twim, DISABLE_ALL_INT_SHORT); + nrf_twim_disable(p_twim); + ) + CODE_FOR_TWI + ( + NRF_TWI_Type * p_twi = p_instance->reg.p_twi; + nrf_twi_int_disable(p_twi, DISABLE_ALL_INT_SHORT); + nrf_twi_shorts_disable(p_twi, DISABLE_ALL_INT_SHORT); + nrf_twi_disable(p_twi); + ) + + p_cb->state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Instance disabled: %d.\r\n", p_instance->drv_inst_idx); +} + +#ifdef TWI_IN_USE +static bool twi_send_byte(NRF_TWI_Type * p_twi, + uint8_t const * p_data, + uint8_t length, + uint8_t * p_bytes_transferred, + bool no_stop) +{ + if (*p_bytes_transferred < length) + { + nrf_twi_txd_set(p_twi, p_data[*p_bytes_transferred]); + ++(*p_bytes_transferred); + } + else + { + if (no_stop) + { + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_SUSPEND); + return false; + } + else + { + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP); + } + } + return true; +} + +static void twi_receive_byte(NRF_TWI_Type * p_twi, + uint8_t * p_data, + uint8_t length, + uint8_t * p_bytes_transferred) +{ + if (*p_bytes_transferred < length) + { + p_data[*p_bytes_transferred] = nrf_twi_rxd_get(p_twi); + + ++(*p_bytes_transferred); + + if (*p_bytes_transferred == length - 1) + { + nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_STOP_MASK); + } + else if (*p_bytes_transferred == length) + { + return; + } + + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME); + } +} + +static bool twi_transfer(NRF_TWI_Type * p_twi, + bool * p_error, + uint8_t * p_bytes_transferred, + uint8_t * p_data, + uint8_t length, + bool no_stop) +{ + bool do_stop_check = ((*p_error) || ((*p_bytes_transferred) == length)); + + if (*p_error) + { + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY); + } + else if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR)) + { + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); + NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR)); + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP); + *p_error = true; + } + else + { + if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_TXDSENT)) + { + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT); + NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_TXDSENT)); + if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR)) + { + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); + NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR)); + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP); + *p_error = true; + } + else + { + if (!twi_send_byte(p_twi, p_data, length, p_bytes_transferred, no_stop)) + { + return false; + } + } + } + else if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_RXDREADY)) + { + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY); + NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_RXDREADY)); + if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR)) + { + NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR)); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP); + *p_error = true; + } + else + { + twi_receive_byte(p_twi, p_data, length, p_bytes_transferred); + } + } + } + + if (do_stop_check && nrf_twi_event_check(p_twi, NRF_TWI_EVENT_STOPPED)) + { + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED); + NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_STOPPED)); + return false; + } + + return true; +} + +static ret_code_t twi_tx_start_transfer(twi_control_block_t * p_cb, + NRF_TWI_Type * p_twi, + uint8_t const * p_data, + uint8_t length, + bool no_stop) +{ + ret_code_t ret_code = NRF_SUCCESS; + volatile int32_t hw_timeout; + + hw_timeout = HW_TIMEOUT; + + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY); + nrf_twi_shorts_set(p_twi, 0); + + p_cb->bytes_transferred = 0; + p_cb->error = false; + + // In case TWI is suspended resume its operation. + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME); + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STARTTX); + + (void)twi_send_byte(p_twi, p_data, length, &p_cb->bytes_transferred, no_stop); + + if (p_cb->handler) + { + p_cb->int_mask = NRF_TWI_INT_STOPPED_MASK | + NRF_TWI_INT_ERROR_MASK | + NRF_TWI_INT_TXDSENT_MASK | + NRF_TWI_INT_RXDREADY_MASK; + nrf_twi_int_enable(p_twi, p_cb->int_mask); + } + else + { + while ((hw_timeout > 0) && + twi_transfer(p_twi, + &p_cb->error, + &p_cb->bytes_transferred, + (uint8_t *)p_data, + length, + no_stop)) + { + hw_timeout--; + } + + if (p_cb->error) + { + uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(p_twi); + + if (errorsrc) + { + ret_code = twi_process_error(errorsrc); + } + } + + if (hw_timeout <= 0) + { + nrf_twi_disable(p_twi); + nrf_twi_enable(p_twi); + ret_code = NRF_ERROR_INTERNAL; + } + + } + return ret_code; +} + +static ret_code_t twi_rx_start_transfer(twi_control_block_t * p_cb, + NRF_TWI_Type * p_twi, + uint8_t const * p_data, + uint8_t length) +{ + ret_code_t ret_code = NRF_SUCCESS; + volatile int32_t hw_timeout; + + hw_timeout = HW_TIMEOUT; + + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY); + + p_cb->bytes_transferred = 0; + p_cb->error = false; + + if (length == 1) + { + nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_STOP_MASK); + } + else + { + nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_SUSPEND_MASK); + } + // In case TWI is suspended resume its operation. + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME); + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STARTRX); + + if (p_cb->handler) + { + p_cb->int_mask = NRF_TWI_INT_STOPPED_MASK | + NRF_TWI_INT_ERROR_MASK | + NRF_TWI_INT_TXDSENT_MASK | + NRF_TWI_INT_RXDREADY_MASK; + nrf_twi_int_enable(p_twi, p_cb->int_mask); + } + else + { + while ((hw_timeout > 0) && + twi_transfer(p_twi, + &p_cb->error, + &p_cb->bytes_transferred, + (uint8_t*)p_data, + length, + false)) + { + hw_timeout--; + } + + if (p_cb->error) + { + uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(p_twi); + + if (errorsrc) + { + ret_code = twi_process_error(errorsrc); + } + } + if (hw_timeout <= 0) + { + nrf_twi_disable(p_twi); + nrf_twi_enable(p_twi); + ret_code = NRF_ERROR_INTERNAL; + } + } + return ret_code; +} + +__STATIC_INLINE ret_code_t twi_xfer(twi_control_block_t * p_cb, + NRF_TWI_Type * p_twi, + nrf_drv_twi_xfer_desc_t const * p_xfer_desc, + uint32_t flags) +{ + + ret_code_t err_code = NRF_SUCCESS; + + /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */ + nrf_twi_int_disable(p_twi, DISABLE_ALL_INT_SHORT); + + if (p_cb->busy) + { + nrf_twi_int_enable(p_twi, p_cb->int_mask); + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + else + { + p_cb->busy = (NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER & flags) ? false : true; + } + + if (flags & NRF_DRV_TWI_FLAG_HOLD_XFER) + { + err_code = NRF_ERROR_NOT_SUPPORTED; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + p_cb->flags = flags; + p_cb->xfer_desc = *p_xfer_desc; + p_cb->curr_length = p_xfer_desc->primary_length; + p_cb->p_curr_buf = p_xfer_desc->p_primary_buf; + nrf_twi_address_set(p_twi, p_xfer_desc->address); + + if (p_xfer_desc->type != NRF_DRV_TWI_XFER_RX) + { + p_cb->curr_no_stop = ((p_xfer_desc->type == NRF_DRV_TWI_XFER_TX) && + !(flags & NRF_DRV_TWI_FLAG_TX_NO_STOP)) ? false : true; + + err_code = twi_tx_start_transfer(p_cb, + p_twi, + p_xfer_desc->p_primary_buf, + p_xfer_desc->primary_length, + p_cb->curr_no_stop); + } + else + { + p_cb->curr_no_stop = false; + + err_code = twi_rx_start_transfer(p_cb, + p_twi, + p_xfer_desc->p_primary_buf, + p_xfer_desc->primary_length); + } + if (p_cb->handler == NULL) + { + p_cb->busy = false; + } + return err_code; +} +#endif + + +bool nrf_drv_twi_is_busy(nrf_drv_twi_t const * p_instance) +{ + twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + return p_cb->busy; +} + + +#ifdef TWIM_IN_USE +__STATIC_INLINE void twim_list_enable_handle(NRF_TWIM_Type * p_twim, uint32_t flags) +{ + if (NRF_DRV_TWI_FLAG_TX_POSTINC & flags) + { + nrf_twim_tx_list_enable(p_twim); + } + else + { + nrf_twim_tx_list_disable(p_twim); + } + + if (NRF_DRV_TWI_FLAG_RX_POSTINC & flags) + { + nrf_twim_rx_list_enable(p_twim); + } + else + { + nrf_twim_rx_list_disable(p_twim); + } +} +__STATIC_INLINE ret_code_t twim_xfer(twi_control_block_t * p_cb, + NRF_TWIM_Type * p_twim, + nrf_drv_twi_xfer_desc_t const * p_xfer_desc, + uint32_t flags) +{ + ret_code_t err_code = NRF_SUCCESS; + nrf_twim_task_t start_task = NRF_TWIM_TASK_STARTTX; + nrf_twim_event_t evt_to_wait = NRF_TWIM_EVENT_STOPPED; + + if (!nrf_drv_is_in_RAM(p_xfer_desc->p_primary_buf)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */ + nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT); + if (p_cb->busy) + { + nrf_twim_int_enable(p_twim, p_cb->int_mask); + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + else + { + p_cb->busy = ((NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER & flags) || + (NRF_DRV_TWI_FLAG_REPEATED_XFER & flags)) ? false: true; + } + + p_cb->xfer_desc = *p_xfer_desc; + p_cb->repeated = (flags & NRF_DRV_TWI_FLAG_REPEATED_XFER) ? true : false; + nrf_twim_address_set(p_twim, p_xfer_desc->address); + + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); + + twim_list_enable_handle(p_twim, flags); + switch (p_xfer_desc->type) + { + case NRF_DRV_TWI_XFER_TXTX: + ASSERT(!(flags & NRF_DRV_TWI_FLAG_REPEATED_XFER)); + ASSERT(!(flags & NRF_DRV_TWI_FLAG_HOLD_XFER)); + ASSERT(!(flags & NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER)); + if (!nrf_drv_is_in_RAM(p_xfer_desc->p_secondary_buf)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK); + nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX); + while (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED)) + {} + NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_TXSTARTED)); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); + nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length); + p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK; + break; + case NRF_DRV_TWI_XFER_TXRX: + nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); + if (!nrf_drv_is_in_RAM(p_xfer_desc->p_secondary_buf)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length); + nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STARTRX_MASK | + NRF_TWIM_SHORT_LASTRX_STOP_MASK); + p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; + break; + case NRF_DRV_TWI_XFER_TX: + nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); + if (NRF_DRV_TWI_FLAG_TX_NO_STOP & flags) + { + nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK); + p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK; + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED); + evt_to_wait = NRF_TWIM_EVENT_SUSPENDED; + } + else + { + nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK); + p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; + } + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); + break; + case NRF_DRV_TWI_XFER_RX: + nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); + nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTRX_STOP_MASK); + p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; + start_task = NRF_TWIM_TASK_STARTRX; + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); + break; + default: + err_code = NRF_ERROR_INVALID_PARAM; + break; + } + + if (!(flags & NRF_DRV_TWI_FLAG_HOLD_XFER) && (p_xfer_desc->type != NRF_DRV_TWI_XFER_TXTX)) + { + nrf_twim_task_trigger(p_twim, start_task); + } + + if (p_cb->handler) + { + if (flags & NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER) + { + p_cb->int_mask = NRF_TWIM_INT_ERROR_MASK; + } + nrf_twim_int_enable(p_twim, p_cb->int_mask); + +#if NRF_MODULE_ENABLED(TWIM_NRF52_ANOMALY_109_WORKAROUND) + if ((flags & NRF_DRV_TWI_FLAG_HOLD_XFER) && ((p_xfer_desc->type == NRF_DRV_TWI_XFER_TX) || + (p_xfer_desc->type == NRF_DRV_TWI_XFER_TXRX))) + { + p_cb->flags = flags; + twim_list_enable_handle(p_twim, 0); + p_twim->FREQUENCY = 0; + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); + nrf_twim_int_enable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK); + } +#endif + } + else + { + while (!nrf_twim_event_check(p_twim, evt_to_wait)) + { + if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR)) + { + NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", + (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR)); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP); + evt_to_wait = NRF_TWIM_EVENT_STOPPED; + } + } + + uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim); + + p_cb->busy = false; + + if (errorsrc) + { + err_code = twi_process_error(errorsrc); + } + } + return err_code; +} +#endif + +ret_code_t nrf_drv_twi_xfer(nrf_drv_twi_t const * p_instance, + nrf_drv_twi_xfer_desc_t const * p_xfer_desc, + uint32_t flags) +{ + + ret_code_t err_code = NRF_SUCCESS; + twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + + // TXRX and TXTX transfers are support only in non-blocking mode. + ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRF_DRV_TWI_XFER_TXRX))); + ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRF_DRV_TWI_XFER_TXTX))); + + NRF_LOG_INFO("Transfer type: %s.\r\n", (uint32_t)TRANSFER_TO_STR(p_xfer_desc->type)); + NRF_LOG_INFO("Transfer buffers length: primary: %d, secondary: %d.\r\n", + p_xfer_desc->primary_length, p_xfer_desc->secondary_length); + NRF_LOG_DEBUG("Primary buffer data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_xfer_desc->p_primary_buf, + p_xfer_desc->primary_length * sizeof(p_xfer_desc->p_primary_buf)); + NRF_LOG_DEBUG("Secondary buffer data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_xfer_desc->p_secondary_buf, + p_xfer_desc->secondary_length * sizeof(p_xfer_desc->p_secondary_buf)); + + CODE_FOR_TWIM + ( + + err_code = twim_xfer(p_cb, (NRF_TWIM_Type *)p_instance->reg.p_twim, p_xfer_desc, flags); + ) + CODE_FOR_TWI + ( + if ( (NRF_DRV_TWI_FLAG_TX_POSTINC | NRF_DRV_TWI_FLAG_RX_POSTINC) & flags) + { + err_code = NRF_ERROR_NOT_SUPPORTED; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + err_code = twi_xfer(p_cb, (NRF_TWI_Type *)p_instance->reg.p_twi, p_xfer_desc, flags); + ) + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance, + uint8_t address, + uint8_t const * p_data, + uint8_t length, + bool no_stop) +{ + nrf_drv_twi_xfer_desc_t xfer = NRF_DRV_TWI_XFER_DESC_TX(address, (uint8_t*)p_data, length); + + return nrf_drv_twi_xfer(p_instance, &xfer, no_stop ? NRF_DRV_TWI_FLAG_TX_NO_STOP : 0); +} + +ret_code_t nrf_drv_twi_rx(nrf_drv_twi_t const * p_instance, + uint8_t address, + uint8_t * p_data, + uint8_t length) +{ + nrf_drv_twi_xfer_desc_t xfer = NRF_DRV_TWI_XFER_DESC_RX(address, p_data, length); + return nrf_drv_twi_xfer(p_instance, &xfer, 0); +} + +uint32_t nrf_drv_twi_data_count_get(nrf_drv_twi_t const * const p_instance) +{ + CODE_FOR_TWIM + ( + ASSERT(false); + return 0; + ) + CODE_FOR_TWI + ( + return m_cb[p_instance->drv_inst_idx].bytes_transferred; + ) +} + +uint32_t nrf_drv_twi_start_task_get(nrf_drv_twi_t const * p_instance, + nrf_drv_twi_xfer_type_t xfer_type) +{ + CODE_FOR_TWIM + ( + return (uint32_t)nrf_twim_task_address_get(p_instance->reg.p_twim, + (xfer_type != NRF_DRV_TWI_XFER_RX) ? NRF_TWIM_TASK_STARTTX : NRF_TWIM_TASK_STARTRX); + ) + CODE_FOR_TWI + ( + return (uint32_t)nrf_twi_task_address_get(p_instance->reg.p_twi, + (xfer_type != NRF_DRV_TWI_XFER_RX) ? NRF_TWI_TASK_STARTTX : NRF_TWI_TASK_STARTRX); + ) +} + +uint32_t nrf_drv_twi_stopped_event_get(nrf_drv_twi_t const * p_instance) +{ + CODE_FOR_TWIM + ( + return (uint32_t)nrf_twim_event_address_get(p_instance->reg.p_twim, NRF_TWIM_EVENT_STOPPED); + ) + CODE_FOR_TWI + ( + return (uint32_t)nrf_twi_event_address_get(p_instance->reg.p_twi, NRF_TWI_EVENT_STOPPED); + ) +} + +#ifdef TWIM_IN_USE +static void irq_handler_twim(NRF_TWIM_Type * p_twim, twi_control_block_t * p_cb) +{ + +#if NRF_MODULE_ENABLED(TWIM_NRF52_ANOMALY_109_WORKAROUND) + /* Handle only workaround case. Can be used without TWIM handler in IRQs. */ + if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED)) + { + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); + nrf_twim_int_disable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK); + if (p_twim->FREQUENCY == 0) + { + // Set enable to zero to reset TWIM internal state. + nrf_twim_disable(p_twim); + nrf_twim_enable(p_twim); + + // Set proper frequency. + nrf_twim_frequency_set(p_twim, p_cb->bus_frequency); + twim_list_enable_handle(p_twim, p_cb->flags); + + // Start proper transmission. + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX); + return; + } + } +#endif + + ASSERT(p_cb->handler); + + if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR)) + { + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); + NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR)); + if (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED)) + { + nrf_twim_int_disable(p_twim, p_cb->int_mask); + p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK; + nrf_twim_int_enable(p_twim, p_cb->int_mask); + + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP); + return; + } + } + + nrf_drv_twi_evt_t event; + + if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED)) + { + NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_STOPPED)); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED); + event.xfer_desc = p_cb->xfer_desc; + if (p_cb->error) + { + + event.xfer_desc.primary_length = (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_RX) ? + (uint8_t)nrf_twim_rxd_amount_get(p_twim) : (uint8_t)nrf_twim_txd_amount_get(p_twim); + event.xfer_desc.secondary_length = (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXRX) ? + (uint8_t)nrf_twim_rxd_amount_get(p_twim) : (uint8_t)nrf_twim_txd_amount_get(p_twim); + + } + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTRX); + if (!p_cb->repeated || p_cb->error) + { + nrf_twim_shorts_set(p_twim, 0); + p_cb->int_mask = 0; + nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT); + } + } + else + { + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED); + NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_SUSPENDED)); + if (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TX) + { + event.xfer_desc = p_cb->xfer_desc; + if (!p_cb->repeated) + { + nrf_twim_shorts_set(p_twim, 0); + p_cb->int_mask = 0; + nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT); + } + } + else + { + nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK); + p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; + nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT); + nrf_twim_int_enable(p_twim, p_cb->int_mask); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); + return; + } + } + + uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim); + if (errorsrc & NRF_TWIM_ERROR_ADDRESS_NACK) + { + event.type = NRF_DRV_TWI_EVT_ADDRESS_NACK; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_ADDRESS_NACK)); + } + else if (errorsrc & NRF_TWIM_ERROR_DATA_NACK) + { + event.type = NRF_DRV_TWI_EVT_DATA_NACK; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_DATA_NACK)); + } + else + { + event.type = NRF_DRV_TWI_EVT_DONE; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_DONE)); + } + + if (!p_cb->repeated) + { + p_cb->busy = false; + } + p_cb->handler(&event, p_cb->p_context); +} +#endif // TWIM_IN_USE + +#ifdef TWI_IN_USE +static void irq_handler_twi(NRF_TWI_Type * p_twi, twi_control_block_t * p_cb) +{ + ASSERT(p_cb->handler); + + if (twi_transfer(p_twi, + &p_cb->error, + &p_cb->bytes_transferred, + p_cb->p_curr_buf, + p_cb->curr_length, + p_cb->curr_no_stop )) + { + return; + } + + if (!p_cb->error && + ((p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXRX) || + (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXTX)) && + p_cb->p_curr_buf == p_cb->xfer_desc.p_primary_buf) + { + p_cb->p_curr_buf = p_cb->xfer_desc.p_secondary_buf; + p_cb->curr_length = p_cb->xfer_desc.secondary_length; + p_cb->curr_no_stop = (p_cb->flags & NRF_DRV_TWI_FLAG_TX_NO_STOP); + + if (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXTX) + { + (void)twi_tx_start_transfer(p_cb, + p_twi, + p_cb->p_curr_buf, + p_cb->curr_length, + p_cb->curr_no_stop); + } + else + { + (void)twi_rx_start_transfer(p_cb, p_twi, p_cb->p_curr_buf, p_cb->curr_length); + } + } + else + { + nrf_drv_twi_evt_t event; + event.xfer_desc = p_cb->xfer_desc; + + if (p_cb->error) + { + uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(p_twi); + if (errorsrc & NRF_TWI_ERROR_ADDRESS_NACK) + { + event.type = NRF_DRV_TWI_EVT_ADDRESS_NACK; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_ADDRESS_NACK)); + } + else if (errorsrc & NRF_TWI_ERROR_DATA_NACK) + { + event.type = NRF_DRV_TWI_EVT_DATA_NACK; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_DATA_NACK)); + } + } + else + { + event.type = NRF_DRV_TWI_EVT_DONE; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_DONE)); + } + + p_cb->busy = false; + + if (!(NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER & p_cb->flags)) + { + p_cb->handler(&event, p_cb->p_context); + } + } + +} +#endif // TWI_IN_USE + +#if NRF_MODULE_ENABLED(TWI0) +IRQ_HANDLER(0) +{ + #if (TWI0_USE_EASY_DMA == 1) + irq_handler_twim(NRF_TWIM0, + #else + irq_handler_twi(NRF_TWI0, + #endif + &m_cb[TWI0_INSTANCE_INDEX]); +} +#endif // NRF_MODULE_ENABLED(TWI0) + +#if NRF_MODULE_ENABLED(TWI1) +IRQ_HANDLER(1) +{ + #if (TWI1_USE_EASY_DMA == 1) + irq_handler_twim(NRF_TWIM1, + #else + irq_handler_twi(NRF_TWI1, + #endif + &m_cb[TWI1_INSTANCE_INDEX]); +} +#endif // NRF_MODULE_ENABLED(TWI1) +#endif // TWI_COUNT +#endif // NRF_MODULE_ENABLED(TWI) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/nrf_drv_twi.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/nrf_drv_twi.h new file mode 100644 index 0000000000000000000000000000000000000000..fb9c8eb63a316728768963a93555757094ce4d59 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twi_master/nrf_drv_twi.h @@ -0,0 +1,438 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * @addtogroup nrf_twi Two Wire master interface (TWI/TWIM) + * @ingroup nrf_drivers + * @brief Two Wire master interface (TWI/TWIM) APIs. + * + * + * @defgroup nrf_drv_twi TWIS driver + * @{ + * @ingroup nrf_twi + * @brief TWI master APIs. + */ +#ifndef NRF_DRV_TWI_H__ +#define NRF_DRV_TWI_H__ + +#include "nordic_common.h" +#include "sdk_config.h" + +// This set of macros makes it possible to exclude parts of code when one type +// of supported peripherals is not used. +#if ((TWI0_ENABLED == 1 && TWI0_USE_EASY_DMA == 1) || \ + (TWI1_ENABLED == 1 && TWI1_USE_EASY_DMA == 1)) + #define TWIM_IN_USE +#endif +#if ((TWI0_ENABLED == 1 && TWI0_USE_EASY_DMA != 1) || \ + (TWI1_ENABLED == 1 && TWI1_USE_EASY_DMA != 1)) + #define TWI_IN_USE +#endif + +#include "nrf_twi.h" +#ifdef TWIM_IN_USE + #include "nrf_twim.h" +#endif +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(TWIM_IN_USE) + #define NRF_DRV_TWI_PERIPHERAL(id) \ + (CONCAT_3(TWI, id, _USE_EASY_DMA) == 1 ? \ + (void *)CONCAT_2(NRF_TWIM, id) \ + : (void *)CONCAT_2(NRF_TWI, id)) +#else + #define NRF_DRV_TWI_PERIPHERAL(id) (void *)CONCAT_2(NRF_TWI, id) +#endif + + +/** + * @brief Structure for the TWI master driver instance. + */ +typedef struct +{ + union + { +#ifdef TWIM_IN_USE + NRF_TWIM_Type * p_twim; ///< Pointer to a structure with TWIM registers. +#endif + NRF_TWI_Type * p_twi; ///< Pointer to a structure with TWI registers. + } reg; + uint8_t drv_inst_idx; ///< Driver instance index. + bool use_easy_dma; ///< True if the peripheral with EasyDMA (TWIM) shall be used. +} nrf_drv_twi_t; + +#define TWI0_INSTANCE_INDEX 0 +#define TWI1_INSTANCE_INDEX TWI0_INSTANCE_INDEX+TWI0_ENABLED + +/** + * @brief Macro for creating a TWI master driver instance. + */ +#define NRF_DRV_TWI_INSTANCE(id) \ +{ \ + .reg = {NRF_DRV_TWI_PERIPHERAL(id)}, \ + .drv_inst_idx = CONCAT_3(TWI, id, _INSTANCE_INDEX), \ + .use_easy_dma = CONCAT_3(TWI, id, _USE_EASY_DMA) \ +} + +/** + * @brief Structure for the TWI master driver instance configuration. + */ +typedef struct +{ + uint32_t scl; ///< SCL pin number. + uint32_t sda; ///< SDA pin number. + nrf_twi_frequency_t frequency; ///< TWI frequency. + uint8_t interrupt_priority; ///< Interrupt priority. + bool clear_bus_init; ///< Clear bus during init. + bool hold_bus_uninit; ///< Hold pull up state on gpio pins after uninit. +} nrf_drv_twi_config_t; + +/** + * @brief TWI master driver instance default configuration. + */ +#define NRF_DRV_TWI_DEFAULT_CONFIG \ +{ \ + .frequency = (nrf_twi_frequency_t)TWI_DEFAULT_CONFIG_FREQUENCY, \ + .scl = 31, \ + .sda = 31, \ + .interrupt_priority = TWI_DEFAULT_CONFIG_IRQ_PRIORITY, \ + .clear_bus_init = TWI_DEFAULT_CONFIG_CLR_BUS_INIT, \ + .hold_bus_uninit = TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT, \ +} + +#define NRF_DRV_TWI_FLAG_TX_POSTINC (1UL << 0) /**< TX buffer address incremented after transfer. */ +#define NRF_DRV_TWI_FLAG_RX_POSTINC (1UL << 1) /**< RX buffer address incremented after transfer. */ +#define NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER (1UL << 2) /**< Interrupt after each transfer is suppressed, and the event handler is not called. */ +#define NRF_DRV_TWI_FLAG_HOLD_XFER (1UL << 3) /**< Set up the transfer but do not start it. */ +#define NRF_DRV_TWI_FLAG_REPEATED_XFER (1UL << 4) /**< Flag indicating that the transfer will be executed multiple times. */ +#define NRF_DRV_TWI_FLAG_TX_NO_STOP (1UL << 5) /**< Flag indicating that the TX transfer will not end with a stop condition. */ + +/** + * @brief TWI master driver event types. + */ +typedef enum +{ + NRF_DRV_TWI_EVT_DONE, ///< Transfer completed event. + NRF_DRV_TWI_EVT_ADDRESS_NACK, ///< Error event: NACK received after sending the address. + NRF_DRV_TWI_EVT_DATA_NACK ///< Error event: NACK received after sending a data byte. +} nrf_drv_twi_evt_type_t; + +/** + * @brief TWI master driver transfer types. + */ +typedef enum +{ + NRF_DRV_TWI_XFER_TX, ///< TX transfer. + NRF_DRV_TWI_XFER_RX, ///< RX transfer. + NRF_DRV_TWI_XFER_TXRX, ///< TX transfer followed by RX transfer with repeated start. + NRF_DRV_TWI_XFER_TXTX ///< TX transfer followed by TX transfer with repeated start. +} nrf_drv_twi_xfer_type_t; + +/** + * @brief Structure for a TWI transfer descriptor. + */ +typedef struct +{ + nrf_drv_twi_xfer_type_t type; ///< Type of transfer. + uint8_t address; ///< Slave address. + uint8_t primary_length; ///< Number of bytes transferred. + uint8_t secondary_length; ///< Number of bytes transferred. + uint8_t * p_primary_buf; ///< Pointer to transferred data. + uint8_t * p_secondary_buf; ///< Pointer to transferred data. +} nrf_drv_twi_xfer_desc_t; + + +/**@brief Macro for setting the TX transfer descriptor. */ +#define NRF_DRV_TWI_XFER_DESC_TX(addr, p_data, length) \ + { \ + .type = NRF_DRV_TWI_XFER_TX, \ + .address = addr, \ + .primary_length = length, \ + .p_primary_buf = p_data, \ + } + +/**@brief Macro for setting the RX transfer descriptor. */ +#define NRF_DRV_TWI_XFER_DESC_RX(addr, p_data, length) \ + { \ + .type = NRF_DRV_TWI_XFER_RX, \ + .address = addr, \ + .primary_length = length, \ + .p_primary_buf = p_data, \ + } + +/**@brief Macro for setting the TXRX transfer descriptor. */ +#define NRF_DRV_TWI_XFER_DESC_TXRX(addr, p_tx, tx_len, p_rx, rx_len) \ + { \ + .type = NRF_DRV_TWI_XFER_TXRX, \ + .address = addr, \ + .primary_length = tx_len, \ + .secondary_length = rx_len, \ + .p_primary_buf = p_tx, \ + .p_secondary_buf = p_rx, \ + } + +/**@brief Macro for setting the TXTX transfer descriptor. */ +#define NRF_DRV_TWI_XFER_DESC_TXTX(addr, p_tx, tx_len, p_tx2, tx_len2) \ + { \ + .type = NRF_DRV_TWI_XFER_TXTX, \ + .address = addr, \ + .primary_length = tx_len, \ + .secondary_length = tx_len2, \ + .p_primary_buf = p_tx, \ + .p_secondary_buf = p_tx2, \ + } + +/** + * @brief Structure for a TWI event. + */ +typedef struct +{ + nrf_drv_twi_evt_type_t type; ///< Event type. + nrf_drv_twi_xfer_desc_t xfer_desc; ///< Transfer details. +} nrf_drv_twi_evt_t; + +/** + * @brief TWI event handler prototype. + */ +typedef void (* nrf_drv_twi_evt_handler_t)(nrf_drv_twi_evt_t const * p_event, + void * p_context); + +/** + * @brief Function for initializing the TWI driver instance. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_config Initial configuration. If NULL, the default configuration is used. + * @param[in] event_handler Event handler provided by the user. If NULL, blocking mode is enabled. + * @param[in] p_context Context passed to event handler. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver is in invalid state. + * @retval NRF_ERROR_BUSY If some other peripheral with the same + * instance ID is already in use. This is + * possible only if PERIPHERAL_RESOURCE_SHARING_ENABLED + * is set to a value other than zero. + */ +ret_code_t nrf_drv_twi_init(nrf_drv_twi_t const * p_instance, + nrf_drv_twi_config_t const * p_config, + nrf_drv_twi_evt_handler_t event_handler, + void * p_context); + +/** + * @brief Function for uninitializing the TWI instance. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_twi_uninit(nrf_drv_twi_t const * p_instance); + +/** + * @brief Function for enabling the TWI instance. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_twi_enable(nrf_drv_twi_t const * p_instance); + +/** + * @brief Function for disabling the TWI instance. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_twi_disable(nrf_drv_twi_t const * p_instance); + +/** + * @brief Function for sending data to a TWI slave. + * + * The transmission will be stopped when an error occurs. If a transfer is ongoing, + * the function returns the error code @ref NRF_ERROR_BUSY. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] address Address of a specific slave device (only 7 LSB). + * @param[in] p_data Pointer to a transmit buffer. + * @param[in] length Number of bytes to send. + * @param[in] no_stop If set, the stop condition is not generated on the bus + * after the transfer has completed successfully (allowing + * for a repeated start in the next transfer). + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. + * @retval NRF_ERROR_INTERNAL If an error was detected by hardware. + * @retval NRF_ERROR_INVALID_ADDR If the EasyDMA is used and memory adress in not in RAM. + * @retval NRF_ERROR_DRV_TWI_ERR_ANACK If NACK received after sending the address in polling mode. + * @retval NRF_ERROR_DRV_TWI_ERR_DNACK If NACK received after sending a data byte in polling mode. + */ +ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance, + uint8_t address, + uint8_t const * p_data, + uint8_t length, + bool no_stop); + +/** + * @brief Function for reading data from a TWI slave. + * + * The transmission will be stopped when an error occurs. If a transfer is ongoing, + * the function returns the error code @ref NRF_ERROR_BUSY. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] address Address of a specific slave device (only 7 LSB). + * @param[in] p_data Pointer to a receive buffer. + * @param[in] length Number of bytes to be received. + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. + * @retval NRF_ERROR_INTERNAL If an error was detected by hardware. + * @retval NRF_ERROR_DRV_TWI_ERR_OVERRUN If the unread data was replaced by new data + * @retval NRF_ERROR_DRV_TWI_ERR_ANACK If NACK received after sending the address in polling mode. + * @retval NRF_ERROR_DRV_TWI_ERR_DNACK If NACK received after sending a data byte in polling mode. + */ +ret_code_t nrf_drv_twi_rx(nrf_drv_twi_t const * p_instance, + uint8_t address, + uint8_t * p_data, + uint8_t length); + +/** + * @brief Function for preparing a TWI transfer. + * + * The following transfer types can be configured (@ref nrf_drv_twi_xfer_desc_t::type): + * - @ref NRF_DRV_TWI_XFER_TXRX: Write operation followed by a read operation (without STOP condition in between). + * - @ref NRF_DRV_TWI_XFER_TXTX: Write operation followed by a write operation (without STOP condition in between). + * - @ref NRF_DRV_TWI_XFER_TX: Write operation (with or without STOP condition). + * - @ref NRF_DRV_TWI_XFER_RX: Read operation (with STOP condition). + * + * Additional options are provided using the flags parameter: + * - @ref NRF_DRV_TWI_FLAG_TX_POSTINC and @ref NRF_DRV_TWI_FLAG_RX_POSTINC: Post-incrementation of buffer addresses. Supported only by TWIM. + * - @ref NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER: No user event handler after transfer completion. In most cases, this also means no interrupt at the end of the transfer. + * - @ref NRF_DRV_TWI_FLAG_HOLD_XFER: Driver is not starting the transfer. Use this flag if the transfer is triggered externally by PPI. Supported only by TWIM. + * Use @ref nrf_drv_twi_start_task_get to get the address of the start task. + * - @ref NRF_DRV_TWI_FLAG_REPEATED_XFER: Prepare for repeated transfers. You can set up a number of transfers that will be triggered externally (for example by PPI). + * An example is a TXRX transfer with the options @ref NRF_DRV_TWI_FLAG_RX_POSTINC, @ref NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER, and @ref NRF_DRV_TWI_FLAG_REPEATED_XFER. + * After the transfer is set up, a set of transfers can be triggered by PPI that will read, for example, the same register of an + * external component and put it into a RAM buffer without any interrupts. @ref nrf_drv_twi_stopped_event_get can be used to get the + * address of the STOPPED event, which can be used to count the number of transfers. If @ref NRF_DRV_TWI_FLAG_REPEATED_XFER is used, + * the driver does not set the driver instance into busy state, so you must ensure that the next transfers are set up + * when TWIM is not active. Supported only by TWIM. + * - @ref NRF_DRV_TWI_FLAG_TX_NO_STOP: No stop condition after TX transfer. + * + * @note + * Some flag combinations are invalid: + * - @ref NRF_DRV_TWI_FLAG_TX_NO_STOP with @ref nrf_drv_twi_xfer_desc_t::type different than @ref NRF_DRV_TWI_XFER_TX + * - @ref NRF_DRV_TWI_FLAG_REPEATED_XFER with @ref nrf_drv_twi_xfer_desc_t::type set to @ref NRF_DRV_TWI_XFER_TXTX + * + * If @ref nrf_drv_twi_xfer_desc_t::type is set to @ref NRF_DRV_TWI_XFER_TX and the @ref NRF_DRV_TWI_FLAG_TX_NO_STOP and @ref NRF_DRV_TWI_FLAG_REPEATED_XFER + * flags are set, two tasks must be used to trigger a transfer: TASKS_RESUME followed by TASKS_STARTTX. If no stop condition is generated, + * TWIM is in SUSPENDED state. Therefore, it must be resumed before the transfer can be started. + * + * @note + * This function should be used only if the instance is configured to work in non-blocking mode. If the function is used in blocking mode, the driver asserts. + * @note If you are using this function with TWI, the only supported flag is @ref NRF_DRV_TWI_FLAG_TX_NO_STOP. All other flags require TWIM. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_xfer_desc Pointer to the transfer descriptor. + * @param[in] flags Transfer options (0 for default settings). + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. + * @retval NRF_ERROR_NOT_SUPPORTED If the provided parameters are not supported. + * @retval NRF_ERROR_INTERNAL If an error was detected by hardware. + * @retval NRF_ERROR_INVALID_ADDR If the EasyDMA is used and memory adress in not in RAM + * @retval NRF_ERROR_DRV_TWI_ERR_OVERRUN If the unread data was replaced by new data (TXRX and RX) + * @retval NRF_ERROR_DRV_TWI_ERR_ANACK If NACK received after sending the address. + * @retval NRF_ERROR_DRV_TWI_ERR_DNACK If NACK received after sending a data byte. + */ +ret_code_t nrf_drv_twi_xfer(nrf_drv_twi_t const * p_instance, + nrf_drv_twi_xfer_desc_t const * p_xfer_desc, + uint32_t flags); + +/** + * @brief Function for checking the TWI driver state. + * + * @param[in] p_instance TWI instance. + * + * @retval true If the TWI driver is currently busy performing a transfer. + * @retval false If the TWI driver is ready for a new transfer. + */ +bool nrf_drv_twi_is_busy(nrf_drv_twi_t const * p_instance); + +/** + * @brief Function for getting the transferred data count. + * + * This function provides valid results only in legacy mode. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @return Data count. + */ +uint32_t nrf_drv_twi_data_count_get(nrf_drv_twi_t const * const p_instance); + +/** + * @brief Function for returning the address of a TWI/TWIM start task. + * + * This function should be used if @ref nrf_drv_twi_xfer was called with the flag @ref NRF_DRV_TWI_FLAG_HOLD_XFER. + * In that case, the transfer is not started by the driver, but it must be started externally by PPI. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] xfer_type Transfer type used in the last call of the @ref nrf_drv_twi_xfer function. + * + * @return Start task address (TX or RX) depending on the value of xfer_type. + */ +uint32_t nrf_drv_twi_start_task_get(nrf_drv_twi_t const * p_instance, nrf_drv_twi_xfer_type_t xfer_type); + +/** + * @brief Function for returning the address of a STOPPED TWI/TWIM event. + * + * A STOPPED event can be used to detect the end of a transfer if the @ref NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER + * option is used. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @return STOPPED event address. + */ +uint32_t nrf_drv_twi_stopped_event_get(nrf_drv_twi_t const * p_instance); +/** + *@} + **/ + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_TWI_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twis_slave/nrf_drv_twis.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twis_slave/nrf_drv_twis.c new file mode 100644 index 0000000000000000000000000000000000000000..51a39f73d91e6dde79b2fd49707845f20be09d43 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twis_slave/nrf_drv_twis.c @@ -0,0 +1,942 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(TWIS) +#define ENABLED_TWIS_COUNT (TWIS0_ENABLED+TWIS1_ENABLED) +#if ENABLED_TWIS_COUNT +#include "nrf_drv_twis.h" +#include "nrf_assert.h" +#include "app_util_platform.h" +#include "compiler_abstraction.h" + +#define NRF_LOG_MODULE_NAME "TWIS" + +#if TWIS_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL TWIS_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR TWIS_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR TWIS_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_TWIS_EVENT_STOPPED ? "NRF_TWIS_EVENT_STOPPED" : \ + (event == NRF_TWIS_EVENT_ERROR ? "NRF_TWIS_EVENT_ERROR" : \ + (event == NRF_TWIS_EVENT_RXSTARTED ? "NRF_TWIS_EVENT_RXSTARTED" : \ + (event == NRF_TWIS_EVENT_TXSTARTED ? "NRF_TWIS_EVENT_TXSTARTED" : \ + (event == NRF_TWIS_EVENT_WRITE ? "NRF_TWIS_EVENT_WRITE" : \ + (event == NRF_TWIS_EVENT_READ ? "NRF_TWIS_EVENT_READ" : "UNKNOWN EVENT")))))) +#else //TWIS_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //TWIS_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +/** + * @internal + * @ingroup lib_twis_drv + * @defgroup lib_twis_drv_ivars Software controlled TWI Slave internal variables + * + * Internal variables for TWIS. + * @{ + */ + +/** + * @brief Actual state of internal state machine + * + * Current substate of powered on state. + */ +typedef enum +{ + NRF_DRV_TWIS_SUBSTATE_IDLE, ///< No ongoing transmission + NRF_DRV_TWIS_SUBSTATE_READ_WAITING, ///< Read request received, waiting for data + NRF_DRV_TWIS_SUBSTATE_READ_PENDING, ///< Reading is actually pending (data sending) + NRF_DRV_TWIS_SUBSTATE_WRITE_WAITING, ///< Write request received, waiting for data buffer + NRF_DRV_TWIS_SUBSTATE_WRITE_PENDING, ///< Writing is actually pending (data receiving) +}nrf_drv_twis_substate_t; + +/** + * @brief Constant instance part + * + * Instance data that have not to change. + * It may be placed in FLASH memory. + */ +typedef struct +{ + NRF_TWIS_Type * const p_reg; ///< Peripheral registry address +} nrf_drv_twis_const_inst_t; + +/** + * @brief Variable instance part + * + * There are all informations for the instance that may change. + */ +typedef struct +{ + nrf_drv_state_t state; ///< Actual driver state + volatile nrf_drv_twis_substate_t substate; ///< Actual driver substate + nrf_drv_twis_event_handler_t ev_handler; ///< Event handler functiomn + volatile uint32_t error; ///< Internal error flags + /**< Internal copy of hardware errors flags merged + * with specific internal driver errors flags. + * + * @note This value can be changed in the interrupt + * and cleared in the main program. + * Always use Atomic load-store when updating + * this value in main loop. + */ +}nrf_drv_twis_var_inst_t; + + +/** The constant instance part implementation */ +static const nrf_drv_twis_const_inst_t m_const_inst[ENABLED_TWIS_COUNT] = +{ + #define X(n) { .p_reg = NRF_TWIS##n }, + #include "nrf_drv_twis_inst.def" +}; + +/** The variable instance part implementation */ +static nrf_drv_twis_var_inst_t m_var_inst[ENABLED_TWIS_COUNT] = +{ + #define X(n) { .state = NRF_DRV_STATE_UNINITIALIZED, \ + .substate = NRF_DRV_TWIS_SUBSTATE_IDLE, \ + .ev_handler = NULL, \ + .error = 0 }, + #include "nrf_drv_twis_inst.def" +}; + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + #define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n + #define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void) + + #if NRF_MODULE_ENABLED(TWIS0) + IRQ_HANDLER(0); + #endif + #if NRF_MODULE_ENABLED(TWIS1) + IRQ_HANDLER(1); + #endif + static nrf_drv_irq_handler_t const m_irq_handlers[ENABLED_TWIS_COUNT] = { + #if NRF_MODULE_ENABLED(TWIS0) + IRQ_HANDLER_NAME(0), + #endif + #if NRF_MODULE_ENABLED(TWIS1) + IRQ_HANDLER_NAME(1), + #endif + }; +#else + #define IRQ_HANDLER(n) \ + void SPIM##n##_SPIS##n##_TWIM##n##_TWIS##n##_SPI##n##_TWI##n##_IRQHandler(void) +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +/** + * @brief State processing semaphore + * + * There are semaphores used when when working in synchronous mode (without interrupts activated). + * @note + * In synchronous mode before every state checking the state machine is executed. + * But the situation where state checking function is called from main task and in the same from + * interrupt task has to be considered. + * In such a situation the @ref nrf_drv_twis_state_machine function may be interrupted by second + * call to the same function. + * If in this second call any event will be detected it may be lost because new substate would be + * overwritten when interrupted function finishes. + * In the same time information about event would be lost because it is cleared in interrupting + * function. + * @note + * To make situation described above safe, simple semaphore is implemented. + * It is just a binary flag that informs that state machine is actually executing and should not + * be processed in any interrupting function. + * Because of how it is used no atomic instructions are required to support this kind of semaphore. + * It is not waitable semaphore - function executed or not depending of its state. + */ +static uint8_t m_sm_semaphore[ENABLED_TWIS_COUNT]; + +/** + * @brief Used interrupts mask + * + * Mask for all interrupts used by this library + */ +static const uint32_t m_used_ints_mask = + NRF_TWIS_INT_STOPPED_MASK | + NRF_TWIS_INT_ERROR_MASK | + NRF_TWIS_INT_RXSTARTED_MASK | + NRF_TWIS_INT_TXSTARTED_MASK | + NRF_TWIS_INT_WRITE_MASK | + NRF_TWIS_INT_READ_MASK; + + +/** @} */ /* End of lib_driver_twis_slave_ivars */ + +/** + * @internal + * @ingroup lib_twis_drv + * @defgroup lib_twis_drv_ifunc Software controlled TWI Slave auxiliary internal functions + * + * Internal variables for TWIS. + * @{ + */ + +/** + * @brief Clear all events + * + * Function clears all actually pending events + */ +static void nrf_drv_twis_clear_all_events(NRF_TWIS_Type * const p_reg) +{ + /* Clear all events */ + nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_STOPPED); + nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_ERROR); + nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_RXSTARTED); + nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_TXSTARTED); + nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_WRITE); + nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_READ); +} + +/** + * @brief Reset all the registers to known state + * + * This function clears all registers that requires it to known state. + * TWIS is left disabled after this function. + * All events are cleared. + * @param[out] p_reg TWIS to reset register address + */ +static inline void nrf_drv_twis_swreset(NRF_TWIS_Type * const p_reg) +{ + /* Disable TWIS */ + nrf_twis_disable(p_reg); + + /* Disconnect pins */ + nrf_twis_pins_set(p_reg, ~0U, ~0U); + + /* Disable interrupt global for the instance */ + nrf_drv_common_irq_disable(nrf_drv_get_IRQn(p_reg)); + + /* Disable interrupts */ + nrf_twis_int_disable(p_reg, ~0U); +} + +/** + * @brief Configure pin + * + * Function configures selected for work as SDA or SCL. + * @param pin Pin number to configure + */ +static inline void nrf_drv_twis_config_pin(uint32_t pin, nrf_gpio_pin_pull_t pull) +{ + nrf_gpio_cfg(pin, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + pull, + NRF_GPIO_PIN_S0D1, + NRF_GPIO_PIN_NOSENSE); +} + +/** + * @brief Call event handler + * + * Function that calls event handler. + * The event handler would be only called if its value is != NULL. + * @param instNr Driver instance number that has called this runtime. + * @param[in] pev Event structure to pass to event handler + * @note + * Remember about possible multithreading. + * It is acceptable to call old event function if it was already disabled. + * What is unacceptable is jump into NULL pointer. + */ +static void nrf_drv_call_event_handler(uint8_t instNr, nrf_drv_twis_evt_t const * const pev) +{ + nrf_drv_twis_event_handler_t evh = m_var_inst[instNr].ev_handler; + if (NULL != evh) + { + evh(pev); + } +} + +/** + * @brief Auxiliary function for getting event state on right bit possition + * + * This function calls @ref nrf_twis_event_get function but the the result + * is shifted to match INTEN register scheme. + * + * @param[in,out] p_reg TWIS to read event from + * @param ev Event code + * + * @return Selected event state shifted by @ref nrf_drv_event_to_bitpos + * + * @sa nrf_twis_event_get + * @sa nrf_drv_event_to_bitpos + */ +static inline uint32_t nrf_drv_twis_event_bit_get(NRF_TWIS_Type * const p_reg, nrf_twis_event_t ev) +{ + return (uint32_t)nrf_twis_event_get_and_clear(p_reg, ev) << nrf_drv_event_to_bitpos(ev); +} + +/** + * @brief Auxiliary function for checking event bit inside given flags value + * + * Function used here to check presence of the event inside given flags value. + * It transforms given event to bit possition and then checks if in given variable it is cleared. + * + * @param flags Flags to test + * @param ev Event code + * + * @retval true Flag for selected event is set + * @retval false Flag for selected event is cleared + */ +static inline bool nrf_drv_twis_check_bit(uint32_t flags, nrf_twis_event_t ev) +{ + return 0 != (flags & (1U<TXD.PTR, evdata.data.tx_amount * sizeof(p_reg->TXD.PTR)); + nrf_drv_call_event_handler(instNr, &evdata); + /* Go to idle and repeat the state machine if READ or WRITE events detected. + * This time READ or WRITE would be started */ + substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + ev = nrf_drv_twis_clear_bit(ev, NRF_TWIS_EVENT_STOPPED); + } + else + { + nrf_drv_twis_process_error(instNr, TWIS_EVT_READ_ERROR, nrf_twis_error_source_get_and_clear(p_reg)); + substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + ev = 0; + } + break; + case NRF_DRV_TWIS_SUBSTATE_WRITE_WAITING: + if (nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_RXSTARTED) || + nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_WRITE) || + nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_READ) || + nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_STOPPED)) + { + substate = NRF_DRV_TWIS_SUBSTATE_WRITE_PENDING; + /* Any other bits requires further processing in PENDING substate */ + ev = nrf_drv_twis_clear_bit(ev, NRF_TWIS_EVENT_RXSTARTED); + } + else + { + nrf_drv_twis_process_error(instNr, TWIS_EVT_WRITE_ERROR, nrf_twis_error_source_get_and_clear(p_reg)); + substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + ev = 0; + } + break; + case NRF_DRV_TWIS_SUBSTATE_WRITE_PENDING: + if (nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_WRITE)|| + nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_READ) || + nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_STOPPED)) + { + evdata.type = TWIS_EVT_WRITE_DONE; + evdata.data.rx_amount = nrf_twis_rx_amount_get(p_reg); + nrf_drv_call_event_handler(instNr, &evdata); + /* Go to idle and repeat the state machine if READ or WRITE events detected. + * This time READ or WRITE would be started */ + substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + ev = nrf_drv_twis_clear_bit(ev, NRF_TWIS_EVENT_STOPPED); + } + else + { + nrf_drv_twis_process_error(instNr, TWIS_EVT_WRITE_ERROR, nrf_twis_error_source_get_and_clear(p_reg)); + substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + ev = 0; + } + break; + default: + substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + /* Do not clear any events and repeat the machine */ + break; + } + } + + m_var_inst[instNr].substate = substate; + if (!TWIS_NO_SYNC_MODE) + { + m_sm_semaphore[instNr] = 0; + } +} + +/** + * @brief This function + */ +static inline void nrf_drv_twis_preprocess_status(uint8_t instNr) +{ + if (!TWIS_NO_SYNC_MODE) + { + if (NULL == m_var_inst[instNr].ev_handler) + { + nrf_drv_twis_state_machine(instNr); + } + } +} + +/** + * @brief Interrupt service + * + * This function is called by all interrupts runtime for instances enabled in this library. + * @param instNr Driver instance number that has called this runtime. + */ +static inline void nrf_drv_twis_on_ISR(uint8_t instNr) +{ + nrf_drv_twis_state_machine(instNr); +} + +/** @} */ /* End of lib_driver_twis_slave_ifunc */ + + +/* ------------------------------------------------------------------------- + * Implementation of IRQ Handlers + */ +#define X(n) \ + IRQ_HANDLER(n) \ + { \ + nrf_drv_twis_on_ISR(TWIS##n##_INSTANCE_INDEX); \ + } +#include "nrf_drv_twis_inst.def" + +/* ------------------------------------------------------------------------- + * Implementation of interface functions + * + */ + + +ret_code_t nrf_drv_twis_init( + nrf_drv_twis_t const * const p_instance, + nrf_drv_twis_config_t const * p_config, + nrf_drv_twis_event_handler_t const event_handler) +{ + ASSERT(p_config); + ASSERT(p_config->scl != p_config->sda); + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type * const p_reg = m_const_inst[instNr].p_reg; + nrf_twis_config_addr_mask_t addr_mask = (nrf_twis_config_addr_mask_t)0; + ret_code_t err_code; + + if ( m_var_inst[instNr].state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + if (nrf_drv_common_per_res_acquire(p_reg, m_irq_handlers[instNr]) != + NRF_SUCCESS) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } +#endif + + if (!TWIS_ASSUME_INIT_AFTER_RESET_ONLY) + { + nrf_drv_twis_swreset(p_reg); + } + + nrf_drv_twis_config_pin(p_config->scl, p_config->scl_pull); + nrf_drv_twis_config_pin(p_config->sda, p_config->sda_pull); + + if (0 == (p_config->addr[0] | p_config->addr[1])) + addr_mask = NRF_TWIS_CONFIG_ADDRESS0_MASK; + else + { + if (0 != p_config->addr[0]) + { + addr_mask |= NRF_TWIS_CONFIG_ADDRESS0_MASK; + } + if (0 != p_config->addr[1]) + { + addr_mask |= NRF_TWIS_CONFIG_ADDRESS1_MASK; + } + } + + /* Peripheral interrupt configure + * (note - interrupts still needs to be configured in INTEN register. + * This is done in enable function) */ + nrf_drv_common_irq_enable(nrf_drv_get_IRQn(p_reg), p_config->interrupt_priority); + + /* Configure */ + nrf_twis_pins_set (p_reg, p_config->scl, p_config->sda); + nrf_twis_address_set (p_reg, 0, p_config->addr[0]); + nrf_twis_address_set (p_reg, 1, p_config->addr[1]); + nrf_twis_config_address_set(p_reg, addr_mask); + + /* Clear semaphore */ + if (!TWIS_NO_SYNC_MODE) + { + m_sm_semaphore[instNr] = 0; + } + /* Set internal instance variables */ + m_var_inst[instNr].substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + m_var_inst[instNr].ev_handler = event_handler; + m_var_inst[instNr].state = NRF_DRV_STATE_INITIALIZED; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_twis_uninit(nrf_drv_twis_t const * const p_instance) +{ + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type * const p_reg = m_const_inst[instNr].p_reg; + TWIS_PSEL_Type psel = p_reg->PSEL; + + ASSERT(m_var_inst[instNr].state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_drv_twis_swreset(p_reg); + + /* Clear pins state if */ + if (!(TWIS_PSEL_SCL_CONNECT_Msk & psel.SCL)) + { + nrf_gpio_cfg_default(psel.SCL); + } + if (!(TWIS_PSEL_SDA_CONNECT_Msk & psel.SDA)) + { + nrf_gpio_cfg_default(psel.SDA); + } + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + nrf_drv_common_per_res_release(p_reg); +#endif + + /* Clear variables */ + m_var_inst[instNr].ev_handler = NULL; + m_var_inst[instNr].state = NRF_DRV_STATE_UNINITIALIZED; +} + + +void nrf_drv_twis_enable(nrf_drv_twis_t const * const p_instance) +{ + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type * const p_reg = m_const_inst[instNr].p_reg; + nrf_drv_twis_var_inst_t * const p_var_inst = &m_var_inst[instNr]; + + ASSERT(m_var_inst[instNr].state == NRF_DRV_STATE_INITIALIZED); + + nrf_drv_twis_clear_all_events(p_reg); + + /* Enable interrupts */ + if (NULL != p_var_inst->ev_handler) + { + nrf_twis_int_enable(p_reg, m_used_ints_mask); + } + + nrf_twis_enable(p_reg); + p_var_inst->error = 0; + p_var_inst->state = NRF_DRV_STATE_POWERED_ON; + p_var_inst->substate = NRF_DRV_TWIS_SUBSTATE_IDLE; +} + + +void nrf_drv_twis_disable(nrf_drv_twis_t const * const p_instance) +{ + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type * const p_reg = m_const_inst[instNr].p_reg; + + ASSERT(m_var_inst[instNr].state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_twis_int_disable(p_reg, m_used_ints_mask); + + nrf_twis_disable(p_reg); + m_var_inst[instNr].state = NRF_DRV_STATE_INITIALIZED; +} + +/* ARM recommends not using the LDREX and STREX instructions in C code. + * This is because the compiler might generate loads and stores between + * LDREX and STREX, potentially clearing the exclusive monitor set by LDREX. + * This recommendation also applies to the byte, halfword, and doubleword + * variants LDREXB, STREXB, LDREXH, STREXH, LDREXD, and STREXD. + * + * This is the reason for the function below to be implemented in assembly. + */ +//lint -save -e578 +#if defined (__CC_ARM ) +static __ASM uint32_t nrf_drv_twis_error_get_and_clear_internal(uint32_t volatile * const perror) +{ + mov r3, r0 + mov r1, #0 +nrf_drv_twis_error_get_and_clear_internal_try + ldrex r0, [r3] + strex r2, r1, [r3] + cmp r2, r1 /* did this succeed? */ + bne nrf_drv_twis_error_get_and_clear_internal_try /* no – try again */ + bx lr +} +#elif defined ( __GNUC__ ) +static uint32_t nrf_drv_twis_error_get_and_clear_internal(uint32_t volatile * const perror) +{ + uint32_t ret; + uint32_t temp; + __ASM volatile( + " .syntax unified \n" + "nrf_drv_twis_error_get_and_clear_internal_try: \n" + " ldrex %[ret], [%[perror]] \n" + " strex %[temp], %[zero], [%[perror]] \n" + " cmp %[temp], %[zero] \n" + " bne nrf_drv_twis_error_get_and_clear_internal_try \n" + : /* Output */ + [ret]"=&l"(ret), + [temp]"=&l"(temp) + : /* Input */ + [zero]"l"(0), + [perror]"l"(perror) + ); + UNUSED_VARIABLE(temp); + return ret; +} +#elif defined ( __ICCARM__ ) +static uint32_t nrf_drv_twis_error_get_and_clear_internal(uint32_t volatile * const perror) +{ + uint32_t ret; + uint32_t temp; + __ASM volatile( + "1: \n" + " ldrex %[ret], [%[perror]] \n" + " strex %[temp], %[zero], [%[perror]] \n" + " cmp %[temp], %[zero] \n" + " bne.n 1b \n" + : /* Output */ + [ret]"=&l"(ret), + [temp]"=&l"(temp) + : /* Input */ + [zero]"l"(0), + [perror]"l"(perror) + ); + UNUSED_VARIABLE(temp); + return ret; +} +#else + #error Unknown compiler +#endif +//lint -restore + +uint32_t nrf_drv_twis_error_get_and_clear(nrf_drv_twis_t const * const p_instance) +{ + nrf_drv_twis_var_inst_t * const p_var_inst = &m_var_inst[p_instance->instNr]; + nrf_drv_twis_preprocess_status(p_instance->instNr); + /* Make sure that access to error member is atomic + * so there is no bit that is cleared if it is not copied to local variable already. */ + return nrf_drv_twis_error_get_and_clear_internal(&p_var_inst->error); +} + + +ret_code_t nrf_drv_twis_tx_prepare( + nrf_drv_twis_t const * const p_instance, + void const * const p_buf, + size_t size) +{ + ret_code_t err_code = NRF_SUCCESS; + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type * const p_reg = m_const_inst[instNr].p_reg; + nrf_drv_twis_var_inst_t * const p_var_inst = &m_var_inst[instNr]; + + /* Check power state*/ + if (p_var_inst->state != NRF_DRV_STATE_POWERED_ON) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + /* Check data address */ + if (!nrf_drv_is_in_RAM(p_buf)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + /* Check data size */ + if ((size & TWIS_TXD_MAXCNT_MAXCNT_Msk) != size) + { + err_code = NRF_ERROR_INVALID_LENGTH; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + nrf_twis_tx_prepare(p_reg, (uint8_t const *)p_buf, (nrf_twis_amount_t)size); + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + +} + + +size_t nrf_drv_twis_tx_amount(nrf_drv_twis_t const * const p_instance) +{ + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type const * const p_reg = m_const_inst[instNr].p_reg; + + return nrf_twis_tx_amount_get(p_reg); +} + + +ret_code_t nrf_drv_twis_rx_prepare( + nrf_drv_twis_t const * const p_instance, + void * const p_buf, + size_t size) +{ + ret_code_t err_code; + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type * const p_reg = m_const_inst[instNr].p_reg; + nrf_drv_twis_var_inst_t * const p_var_inst = &m_var_inst[instNr]; + + /* Check power state*/ + if (p_var_inst->state != NRF_DRV_STATE_POWERED_ON) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + /* Check data address */ + if (!nrf_drv_is_in_RAM(p_buf)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + /* Check data size */ + if ((size & TWIS_RXD_MAXCNT_MAXCNT_Msk) != size) + { + err_code = NRF_ERROR_INVALID_LENGTH; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + nrf_twis_rx_prepare(p_reg, (uint8_t *)p_buf, (nrf_twis_amount_t)size); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +size_t nrf_drv_twis_rx_amount(nrf_drv_twis_t const * const p_instance) +{ + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type const * const p_reg = m_const_inst[instNr].p_reg; + + return nrf_twis_rx_amount_get(p_reg); +} + + +bool nrf_drv_twis_is_busy(nrf_drv_twis_t const * const p_instance) +{ + nrf_drv_twis_preprocess_status(p_instance->instNr); + return NRF_DRV_TWIS_SUBSTATE_IDLE != m_var_inst[(p_instance->instNr)].substate; +} + +bool nrf_drv_twis_is_waiting_tx_buff(nrf_drv_twis_t const * const p_instance) +{ + nrf_drv_twis_preprocess_status(p_instance->instNr); + return NRF_DRV_TWIS_SUBSTATE_READ_WAITING == m_var_inst[(p_instance->instNr)].substate; +} + +bool nrf_drv_twis_is_waiting_rx_buff(nrf_drv_twis_t const * const p_instance) +{ + nrf_drv_twis_preprocess_status(p_instance->instNr); + return NRF_DRV_TWIS_SUBSTATE_WRITE_WAITING == m_var_inst[(p_instance->instNr)].substate; +} + +bool nrf_drv_twis_is_pending_tx(nrf_drv_twis_t const * const p_instance) +{ + nrf_drv_twis_preprocess_status(p_instance->instNr); + return NRF_DRV_TWIS_SUBSTATE_READ_PENDING == m_var_inst[(p_instance->instNr)].substate; +} + +bool nrf_drv_twis_is_pending_rx(nrf_drv_twis_t const * const p_instance) +{ + nrf_drv_twis_preprocess_status(p_instance->instNr); + return NRF_DRV_TWIS_SUBSTATE_WRITE_PENDING == m_var_inst[(p_instance->instNr)].substate; +} +#endif // TWIS_COUNT +#endif // NRF_MODULE_ENABLED(TWIS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twis_slave/nrf_drv_twis.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twis_slave/nrf_drv_twis.h new file mode 100644 index 0000000000000000000000000000000000000000..9989bfbd0aa53f1d47955f7e0bdeefb492683387 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twis_slave/nrf_drv_twis.h @@ -0,0 +1,396 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_DRV_TWIS_H__ +#define NRF_DRV_TWIS_H__ + +#include "sdk_config.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" +#include "sdk_errors.h" +#include "nrf_twis.h" +#include +#include "app_util.h" + +#ifdef __cplusplus +extern "C" { +#endif +/**@file + * @addtogroup nrf_twis Two Wire slave interface (TWIS) + * @ingroup nrf_drivers + * @brief Two Wire slave interface (TWIS) APIs. + * + * + * @defgroup nrf_drv_twis TWIS driver + * @{ + * @ingroup nrf_twis + * @brief TWI slave APIs. + */ + +/** + * @brief Event callback function event definitions. + */ +typedef enum +{ + TWIS_EVT_READ_REQ, ///< Read request detected + /**< If there is no buffer prepared, buf_req flag in the even will be set. + Call then @ref nrf_drv_twis_tx_prepare to give parameters for buffer. + */ + TWIS_EVT_READ_DONE, ///< Read request has finished - free any data + TWIS_EVT_READ_ERROR, ///< Read request finished with error + TWIS_EVT_WRITE_REQ, ///< Write request detected + /**< If there is no buffer prepared, buf_req flag in the even will be set. + Call then @ref nrf_drv_twis_rx_prepare to give parameters for buffer. + */ + TWIS_EVT_WRITE_DONE, ///< Write request has finished - process data + TWIS_EVT_WRITE_ERROR, ///< Write request finished with error + TWIS_EVT_GENERAL_ERROR ///< Error that happens not inside WRITE or READ transaction +} nrf_drv_twis_evt_type_t; + +/** + * @brief TWIS driver instance structure + * + * @note We only need instance number here so we could really use just a number + * that would be send to every driver function. + * But for compatibility reason this number is inserted into the structure. + */ +typedef struct +{ + uint8_t instNr; /**< Instance number */ +}nrf_drv_twis_t; + +/** + * @brief TWIS driver event structure + */ +typedef struct +{ + nrf_drv_twis_evt_type_t type; ///< Event type + union + { + bool buf_req; ///< Flag for @ref TWIS_EVT_READ_REQ and @ref TWIS_EVT_WRITE_REQ + /**< Information if transmission buffer requires to be prepared */ + uint32_t tx_amount; ///< Data for @ref TWIS_EVT_READ_DONE + uint32_t rx_amount; ///< Data for @ref TWIS_EVT_WRITE_DONE + uint32_t error; ///< Data for @ref TWIS_EVT_GENERAL_ERROR + }data; +}nrf_drv_twis_evt_t; + +/** + * @brief TWI slave event callback function type. + * + * @param[in] p_event Event information structure. + */ +typedef void (*nrf_drv_twis_event_handler_t)(nrf_drv_twis_evt_t const * const p_event); + +/** + * @brief Structure for TWIS configuration + */ +typedef struct +{ + uint32_t addr[2]; //!< Set addresses that this slave should respond. Set 0 to disable. + uint32_t scl; //!< SCL pin number + nrf_gpio_pin_pull_t scl_pull; //!< SCL pin pull + uint32_t sda; //!< SDA pin number + nrf_gpio_pin_pull_t sda_pull; //!< SDA pin pull + uint8_t interrupt_priority; //!< The priority of interrupt for the module to set +}nrf_drv_twis_config_t; + +/** + * @brief Possible error sources + * + * This is flag enum - values from this enum can be connected using logical or operator. + * @note + * We could use directly @ref nrf_twis_error_t. Error type enum is redefined here becouse + * of possible future extension (eg. supporting timeouts and synchronous mode). + */ +typedef enum +{ + NRF_DRV_TWIS_ERROR_OVERFLOW = NRF_TWIS_ERROR_OVERFLOW, /**< RX buffer overflow detected, and prevented */ + NRF_DRV_TWIS_ERROR_DATA_NACK = NRF_TWIS_ERROR_DATA_NACK, /**< NACK sent after receiving a data byte */ + NRF_DRV_TWIS_ERROR_OVERREAD = NRF_TWIS_ERROR_OVERREAD, /**< TX buffer over-read detected, and prevented */ + NRF_DRV_TWIS_ERROR_UNEXPECTED_EVENT = 1 << 8 /**< Unexpected event detected by state machine */ +}nrf_drv_twis_error_t; + +/** + * @internal + * @brief Internal macro for creating TWIS driver instance + * + * Second level of indirection in creating the instance. + * Do not use this macro directly. + * Use @ref NRF_DRV_TWIS_INSTANCE instead. + */ +#define NRF_DRV_TWIS_INSTANCE_x(id) \ + { \ + TWIS##id##_INSTANCE_INDEX \ + } + +/** + * @brief Macro for creating TWIS driver instance + * + * @param[in] id Instance index. Use 0 for TWIS0 and 1 for TWIS1 + */ +#define NRF_DRV_TWIS_INSTANCE(id) NRF_DRV_TWIS_INSTANCE_x(id) + +#define TWIS0_INSTANCE_INDEX 0 +#define TWIS1_INSTANCE_INDEX TWIS0_INSTANCE_INDEX+TWIS0_ENABLED + +/** + * @brief Generate default configuration for TWIS driver instance + */ +#define NRF_DRV_TWIS_DEFAULT_CONFIG \ +{ \ + .addr = { TWIS_DEFAULT_CONFIG_ADDR0, TWIS_DEFAULT_CONFIG_ADDR1 }, \ + .scl = 31, \ + .scl_pull = (nrf_gpio_pin_pull_t)TWIS_DEFAULT_CONFIG_SCL_PULL, \ + .sda = 31, \ + .sda_pull = (nrf_gpio_pin_pull_t)TWIS_DEFAULT_CONFIG_SDA_PULL, \ + .interrupt_priority = TWIS_DEFAULT_CONFIG_IRQ_PRIORITY \ +} + +/** + * @brief Function for initializing the TWIS driver instance. + * + * Function initializes and enables TWIS driver. + * @attention After driver initialization enable it by @ref nrf_drv_twis_enable + * + * @param[in] p_instance Pointer to the driver instance structure. + * @attention @em p_instance has to be global object. + * It would be used by interrupts so make it sure that object + * would not be destroyed when function is leaving. + * @param[in] p_config Initial configuration. + * @param[in] event_handler Event handler provided by the user. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver is already initialized. + * @retval NRF_ERROR_BUSY If some other peripheral with the same + * instance ID is already in use. This is + * possible only if PERIPHERAL_RESOURCE_SHARING_ENABLED + * is set to a value other than zero. + */ +ret_code_t nrf_drv_twis_init( + nrf_drv_twis_t const * const p_instance, + nrf_drv_twis_config_t const * p_config, + nrf_drv_twis_event_handler_t const event_handler); + +/** + * @brief Function for uninitializing the TWIS driver instance. + * + * Function initializes the peripheral and resets all registers to default values. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @note + * It is safe to call nrf_drv_twis_uninit even before initialization. + * Actually @ref nrf_drv_twis_init function calls this function to + * make sure that TWIS state is known. + * @note + * If TWIS driver was in uninitialized state before calling this function, + * selected pins would not be reset to default configuration. + */ +void nrf_drv_twis_uninit(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Enable TWIS instance + * + * This function enables TWIS instance. + * Function defined if there is needs for dynamically enabling and disabling the peripheral. + * Use @ref nrf_drv_twis_enable and @ref nrf_drv_twis_disable functions. + * They do not change any configuration registers. + * + * @param p_instance Pointer to the driver instance structure. + */ +void nrf_drv_twis_enable(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Disable TWIS instance + * + * Disabling TWIS instance gives possibility to turn off the TWIS while + * holding configuration done by @ref nrf_drv_twis_init + * + * @param p_instance Pointer to the driver instance structure. + */ +void nrf_drv_twis_disable(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Get and clear last error flags + * + * Function gets information about errors. + * This is also the only possibility to exit from error substate of the internal state machine. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @return Error flags defined in @ref nrf_drv_twis_error_t + * @attention + * This function clears error state and flags. + */ +uint32_t nrf_drv_twis_error_get_and_clear(nrf_drv_twis_t const * const p_instance); + + +/** + * @brief Prepare data for sending + * + * This function should be used in response for @ref TWIS_EVT_READ_REQ event. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_buf Transmission buffer + * @attention Transmission buffer has to be placed in RAM. + * @param size Maximum number of bytes that master may read from buffer given. + * + * @retval NRF_SUCCESS Preparation finished properly + * @retval NRF_ERROR_INVALID_ADDR Given @em p_buf is not placed inside the RAM + * @retval NRF_ERROR_INVALID_LENGTH Wrong value in @em size parameter + * @retval NRF_ERROR_INVALID_STATE Module not initialized or not enabled + */ +ret_code_t nrf_drv_twis_tx_prepare( + nrf_drv_twis_t const * const p_instance, + void const * const p_buf, + size_t size); + +/** + * @brief Get number of transmitted bytes + * + * Function returns number of bytes sent. + * This function may be called after @ref TWIS_EVT_READ_DONE or @ref TWIS_EVT_READ_ERROR events. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @return Number of bytes sent. + */ +size_t nrf_drv_twis_tx_amount(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Prepare data for receiving + * + * This function should be used in response for @ref TWIS_EVT_WRITE_REQ event. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_buf Buffer that would be filled with received data + * @attention Receiving buffer has to be placed in RAM. + * @param size Size of the buffer (maximum amount of data to receive) + * + * @retval NRF_SUCCESS Preparation finished properly + * @retval NRF_ERROR_INVALID_ADDR Given @em p_buf is not placed inside the RAM + * @retval NRF_ERROR_INVALID_LENGTH Wrong value in @em size parameter + * @retval NRF_ERROR_INVALID_STATE Module not initialized or not enabled + */ +ret_code_t nrf_drv_twis_rx_prepare( + nrf_drv_twis_t const * const p_instance, + void * const p_buf, + size_t size); + +/** + * @brief Get number of received bytes + * + * Function returns number of bytes received. + * This function may be called after @ref TWIS_EVT_WRITE_DONE or @ref TWIS_EVT_WRITE_ERROR events. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @return Number of bytes received. + */ +size_t nrf_drv_twis_rx_amount(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Function checks if driver is busy right now + * + * Actual driver substate is tested. + * If driver is in any other state than IDLE or ERROR this function returns true. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true Driver is in state other than ERROR or IDLE + * @retval false There is no transmission pending. + */ +bool nrf_drv_twis_is_busy(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Function checks if driver is waiting for tx buffer + * + * If this function returns true, it means that driver is stalled expecting + * of the @ref nrf_drv_twis_tx_prepare function call. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true Driver waits for @ref nrf_drv_twis_tx_prepare + * @retval false Driver is not in the state where it waits for preparing tx buffer. + */ +bool nrf_drv_twis_is_waiting_tx_buff(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Function checks if driver is waiting for rx buffer + * + * If this function returns true, it means that driver is staled expecting + * of the @ref nrf_drv_twis_rx_prepare function call. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true Driver waits for @ref nrf_drv_twis_rx_prepare + * @retval false Driver is not in the state where it waits for preparing rx buffer. + */ +bool nrf_drv_twis_is_waiting_rx_buff(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Check if driver is sending data + * + * If this function returns true, it means that there is ongoing output transmission. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true There is ongoing output transmission. + * @retval false Driver is in other state. + */ +bool nrf_drv_twis_is_pending_tx(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Check if driver is receiving data + * + * If this function returns true, it means that there is ongoing input transmission. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true There is ongoing input transmission. + * @retval false Driver is in other state. + */ +bool nrf_drv_twis_is_pending_rx(nrf_drv_twis_t const * const p_instance); + +/** @} */ /* End of lib_twis_drv group */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_DRV_TWIS_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twis_slave/nrf_drv_twis_inst.def b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twis_slave/nrf_drv_twis_inst.def new file mode 100644 index 0000000000000000000000000000000000000000..be40002a677051ba97419c34feabee1c22d14f4b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/twis_slave/nrf_drv_twis_inst.def @@ -0,0 +1,20 @@ +/** + * @file + * @brief Xmacro file with contains enumeration of TWIS instances to implement + * + * Use this file everywhere where anything has to be generated for all active TWIS instances. + * Xmacro format: + * + * @code + X(n) + * @endcode + * + * Where @em n is number of the instance itself (0 for NRF_TWIS0). + */ +#if (TWIS0_ENABLED == 1) + X(0) +#endif +#if (TWIS1_ENABLED == 1) + X(1) +#endif +#undef X diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/uart/nrf_drv_uart.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/uart/nrf_drv_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..38ac5ae7c30e24b93dd4584a31e725a3a6783831 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/uart/nrf_drv_uart.c @@ -0,0 +1,986 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(UART) +#include "nrf_drv_uart.h" +#include "nrf_assert.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "UART" + +#if UART_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL UART_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR UART_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR UART_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_UART_EVENT_ERROR ? "NRF_UART_EVENT_ERROR" : "UNKNOWN EVENT") +#else //UART_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //UART_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +#if (defined(UARTE_IN_USE) && defined(UART_IN_USE)) + // UARTE and UART combined + #define CODE_FOR_UARTE(code) if (m_cb[p_instance->drv_inst_idx].use_easy_dma) { code } + #define CODE_FOR_UARTE_INT(idx, code) if (m_cb[idx].use_easy_dma) { code } + #define CODE_FOR_UART(code) else { code } +#elif (defined(UARTE_IN_USE) && !defined(UART_IN_USE)) + // UARTE only + #define CODE_FOR_UARTE(code) { code } + #define CODE_FOR_UARTE_INT(idx, code) { code } + #define CODE_FOR_UART(code) +#elif (!defined(UARTE_IN_USE) && defined(UART_IN_USE)) + // UART only + #define CODE_FOR_UARTE(code) + #define CODE_FOR_UARTE_INT(idx, code) + #define CODE_FOR_UART(code) { code } +#else + #error "Wrong configuration." +#endif + +#define TX_COUNTER_ABORT_REQ_VALUE 256 + +typedef struct +{ + void * p_context; + nrf_uart_event_handler_t handler; + uint8_t const * p_tx_buffer; + uint8_t * p_rx_buffer; + uint8_t * p_rx_secondary_buffer; + volatile uint16_t tx_counter; + uint8_t tx_buffer_length; + uint8_t rx_buffer_length; + uint8_t rx_secondary_buffer_length; + volatile uint8_t rx_counter; + bool rx_enabled; + nrf_drv_state_t state; +#if (defined(UARTE_IN_USE) && defined(UART_IN_USE)) + bool use_easy_dma; +#endif +} uart_control_block_t; + +static uart_control_block_t m_cb[UART_ENABLED_COUNT]; + +__STATIC_INLINE void apply_config(nrf_drv_uart_t const * p_instance, nrf_drv_uart_config_t const * p_config) +{ + if (p_config->pseltxd != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_pin_set(p_config->pseltxd); + nrf_gpio_cfg_output(p_config->pseltxd); + } + if (p_config->pselrxd != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_cfg_input(p_config->pselrxd, NRF_GPIO_PIN_NOPULL); + } + + CODE_FOR_UARTE + ( + nrf_uarte_baudrate_set(p_instance->reg.p_uarte, (nrf_uarte_baudrate_t)p_config->baudrate); + nrf_uarte_configure(p_instance->reg.p_uarte, (nrf_uarte_parity_t)p_config->parity, + (nrf_uarte_hwfc_t)p_config->hwfc); + nrf_uarte_txrx_pins_set(p_instance->reg.p_uarte, p_config->pseltxd, p_config->pselrxd); + if (p_config->hwfc == NRF_UART_HWFC_ENABLED) + { + if (p_config->pselcts != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_cfg_input(p_config->pselcts, NRF_GPIO_PIN_NOPULL); + } + if (p_config->pselrts != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_pin_set(p_config->pselrts); + nrf_gpio_cfg_output(p_config->pselrts); + } + nrf_uarte_hwfc_pins_set(p_instance->reg.p_uarte, p_config->pselrts, p_config->pselcts); + } + ) + CODE_FOR_UART + ( + nrf_uart_baudrate_set(p_instance->reg.p_uart, p_config->baudrate); + nrf_uart_configure(p_instance->reg.p_uart, p_config->parity, p_config->hwfc); + nrf_uart_txrx_pins_set(p_instance->reg.p_uart, p_config->pseltxd, p_config->pselrxd); + if (p_config->hwfc == NRF_UART_HWFC_ENABLED) + { + if (p_config->pselcts != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_cfg_input(p_config->pselcts, NRF_GPIO_PIN_NOPULL); + } + if (p_config->pselrts != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_pin_set(p_config->pselrts); + nrf_gpio_cfg_output(p_config->pselrts); + } + nrf_uart_hwfc_pins_set(p_instance->reg.p_uart, p_config->pselrts, p_config->pselcts); + } + ) +} + +__STATIC_INLINE void interrupts_enable(const nrf_drv_uart_t * p_instance, uint8_t interrupt_priority) +{ + CODE_FOR_UARTE + ( + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDRX); + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDTX); + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ERROR); + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_RXTO); + nrf_uarte_int_enable(p_instance->reg.p_uarte, NRF_UARTE_INT_ENDRX_MASK | + NRF_UARTE_INT_ENDTX_MASK | + NRF_UARTE_INT_ERROR_MASK | + NRF_UARTE_INT_RXTO_MASK); + nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_uarte), interrupt_priority); + ) + CODE_FOR_UART + ( + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_TXDRDY); + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_RXTO); + nrf_uart_int_enable(p_instance->reg.p_uart, NRF_UART_INT_MASK_TXDRDY | + NRF_UART_INT_MASK_RXTO); + nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_uart), interrupt_priority); + ) +} + +__STATIC_INLINE void interrupts_disable(const nrf_drv_uart_t * p_instance) +{ + CODE_FOR_UARTE + ( + nrf_uarte_int_disable(p_instance->reg.p_uarte, NRF_UARTE_INT_ENDRX_MASK | + NRF_UARTE_INT_ENDTX_MASK | + NRF_UARTE_INT_ERROR_MASK | + NRF_UARTE_INT_RXTO_MASK); + nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_uarte)); + ) + CODE_FOR_UART + ( + nrf_uart_int_disable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | + NRF_UART_INT_MASK_TXDRDY | + NRF_UART_INT_MASK_ERROR | + NRF_UART_INT_MASK_RXTO); + nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_uart)); + ) + +} + +__STATIC_INLINE void pins_to_default(const nrf_drv_uart_t * p_instance) +{ + /* Reset pins to default states */ + uint32_t txd; + uint32_t rxd; + uint32_t rts; + uint32_t cts; + + CODE_FOR_UARTE + ( + txd = nrf_uarte_tx_pin_get(p_instance->reg.p_uarte); + rxd = nrf_uarte_rx_pin_get(p_instance->reg.p_uarte); + rts = nrf_uarte_rts_pin_get(p_instance->reg.p_uarte); + cts = nrf_uarte_cts_pin_get(p_instance->reg.p_uarte); + nrf_uarte_txrx_pins_disconnect(p_instance->reg.p_uarte); + nrf_uarte_hwfc_pins_disconnect(p_instance->reg.p_uarte); + ) + CODE_FOR_UART + ( + txd = nrf_uart_tx_pin_get(p_instance->reg.p_uart); + rxd = nrf_uart_rx_pin_get(p_instance->reg.p_uart); + rts = nrf_uart_rts_pin_get(p_instance->reg.p_uart); + cts = nrf_uart_cts_pin_get(p_instance->reg.p_uart); + nrf_uart_txrx_pins_disconnect(p_instance->reg.p_uart); + nrf_uart_hwfc_pins_disconnect(p_instance->reg.p_uart); + ) + + if (txd != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_cfg_default(txd); + } + + if (rxd != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_cfg_default(rxd); + } + + if (cts != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_cfg_default(cts); + } + + if (rts != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_cfg_default(rts); + } + +} + +__STATIC_INLINE void uart_enable(const nrf_drv_uart_t * p_instance) +{ + CODE_FOR_UARTE(nrf_uarte_enable(p_instance->reg.p_uarte);) + CODE_FOR_UART(nrf_uart_enable(p_instance->reg.p_uart);); +} + +__STATIC_INLINE void uart_disable(const nrf_drv_uart_t * p_instance) +{ + CODE_FOR_UARTE(nrf_uarte_disable(p_instance->reg.p_uarte);) + CODE_FOR_UART(nrf_uart_disable(p_instance->reg.p_uart);); +} + +ret_code_t nrf_drv_uart_init(const nrf_drv_uart_t * p_instance, nrf_drv_uart_config_t const * p_config, + nrf_uart_event_handler_t event_handler) +{ + ASSERT(p_config); + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ret_code_t err_code = NRF_SUCCESS; + + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + +#if (defined(UARTE_IN_USE) && defined(UART_IN_USE)) + p_cb->use_easy_dma = p_config->use_easy_dma; +#endif + apply_config(p_instance, p_config); + + p_cb->handler = event_handler; + p_cb->p_context = p_config->p_context; + + if (p_cb->handler) + { + interrupts_enable(p_instance, p_config->interrupt_priority); + } + + uart_enable(p_instance); + p_cb->rx_buffer_length = 0; + p_cb->rx_secondary_buffer_length = 0; + p_cb->tx_buffer_length = 0; + p_cb->state = NRF_DRV_STATE_INITIALIZED; + p_cb->rx_enabled = false; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + +void nrf_drv_uart_uninit(const nrf_drv_uart_t * p_instance) +{ + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + + uart_disable(p_instance); + + if (p_cb->handler) + { + interrupts_disable(p_instance); + } + + pins_to_default(p_instance); + + p_cb->state = NRF_DRV_STATE_UNINITIALIZED; + p_cb->handler = NULL; + NRF_LOG_INFO("Instance uninitialized: %d.\r\n", p_instance->drv_inst_idx); +} + +#if defined(UART_IN_USE) +__STATIC_INLINE void tx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb) +{ + nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY); + uint8_t txd = p_cb->p_tx_buffer[p_cb->tx_counter]; + p_cb->tx_counter++; + nrf_uart_txd_set(p_uart, txd); +} + +__STATIC_INLINE ret_code_t nrf_drv_uart_tx_for_uart(const nrf_drv_uart_t * p_instance) +{ + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ret_code_t err_code = NRF_SUCCESS; + + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_TXDRDY); + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STARTTX); + + tx_byte(p_instance->reg.p_uart, p_cb); + + if (p_cb->handler == NULL) + { + while (p_cb->tx_counter < (uint16_t) p_cb->tx_buffer_length) + { + while (!nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_TXDRDY) && + p_cb->tx_counter != TX_COUNTER_ABORT_REQ_VALUE) + { + } + if (p_cb->tx_counter != TX_COUNTER_ABORT_REQ_VALUE) + { + tx_byte(p_instance->reg.p_uart, p_cb); + } + } + + if (p_cb->tx_counter == TX_COUNTER_ABORT_REQ_VALUE) + { + err_code = NRF_ERROR_FORBIDDEN; + } + else + { + while (!nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_TXDRDY)) + { + } + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPTX); + } + p_cb->tx_buffer_length = 0; + } + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} +#endif + +#if defined(UARTE_IN_USE) +__STATIC_INLINE ret_code_t nrf_drv_uart_tx_for_uarte(const nrf_drv_uart_t * p_instance) +{ + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ret_code_t err_code = NRF_SUCCESS; + + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDTX); + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_TXSTOPPED); + nrf_uarte_tx_buffer_set(p_instance->reg.p_uarte, p_cb->p_tx_buffer, p_cb->tx_buffer_length); + nrf_uarte_task_trigger(p_instance->reg.p_uarte, NRF_UARTE_TASK_STARTTX); + + if (p_cb->handler == NULL) + { + bool endtx; + bool txstopped; + do + { + endtx = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDTX); + txstopped = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_TXSTOPPED); + } + while ((!endtx) && (!txstopped)); + + if (txstopped) + { + err_code = NRF_ERROR_FORBIDDEN; + } + p_cb->tx_buffer_length = 0; + } + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} +#endif + +ret_code_t nrf_drv_uart_tx(const nrf_drv_uart_t * p_instance, uint8_t const * const p_data, uint8_t length) +{ + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state == NRF_DRV_STATE_INITIALIZED); + ASSERT(length>0); + ASSERT(p_data); + + ret_code_t err_code; + + CODE_FOR_UARTE + ( + // EasyDMA requires that transfer buffers are placed in DataRAM, + // signal error if the are not. + if (!nrf_drv_is_in_RAM(p_data)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + ) + + if (nrf_drv_uart_tx_in_progress(p_instance)) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + p_cb->tx_buffer_length = length; + p_cb->p_tx_buffer = p_data; + p_cb->tx_counter = 0; + + NRF_LOG_INFO("Transfer tx_len: %d.\r\n", p_cb->tx_buffer_length); + NRF_LOG_DEBUG("Tx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_cb->p_tx_buffer, p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer)); + + CODE_FOR_UARTE + ( + return nrf_drv_uart_tx_for_uarte(p_instance); + ) + CODE_FOR_UART + ( + return nrf_drv_uart_tx_for_uart(p_instance); + ) +} + +bool nrf_drv_uart_tx_in_progress(const nrf_drv_uart_t * p_instance) +{ + return (m_cb[p_instance->drv_inst_idx].tx_buffer_length != 0); +} + +#if defined(UART_IN_USE) +__STATIC_INLINE void rx_enable(const nrf_drv_uart_t * p_instance) +{ + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_ERROR); + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_RXDRDY); + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STARTRX); +} + +__STATIC_INLINE void rx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb) +{ + if (!p_cb->rx_buffer_length) + { + nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY); + // Byte received when buffer is not set - data lost. + (void) nrf_uart_rxd_get(p_uart); + return; + } + nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY); + p_cb->p_rx_buffer[p_cb->rx_counter] = nrf_uart_rxd_get(p_uart); + p_cb->rx_counter++; +} + +__STATIC_INLINE ret_code_t nrf_drv_uart_rx_for_uart(const nrf_drv_uart_t * p_instance, uint8_t * p_data, uint8_t length, bool second_buffer) +{ + ret_code_t err_code; + + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + + if ((!p_cb->rx_enabled) && (!second_buffer)) + { + rx_enable(p_instance); + } + + if (p_cb->handler == NULL) + { + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_RXTO); + + bool rxrdy; + bool rxto; + bool error; + do + { + do + { + error = nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_ERROR); + rxrdy = nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_RXDRDY); + rxto = nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_RXTO); + } while ((!rxrdy) && (!rxto) && (!error)); + + if (error || rxto) + { + break; + } + rx_byte(p_instance->reg.p_uart, p_cb); + } while (p_cb->rx_buffer_length > p_cb->rx_counter); + + p_cb->rx_buffer_length = 0; + if (error) + { + err_code = NRF_ERROR_INTERNAL; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + if (rxto) + { + err_code = NRF_ERROR_FORBIDDEN; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + if (p_cb->rx_enabled) + { + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STARTRX); + } + else + { + // Skip stopping RX if driver is forced to be enabled. + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPRX); + } + } + else + { + nrf_uart_int_enable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + } + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} +#endif + +#if defined(UARTE_IN_USE) +__STATIC_INLINE ret_code_t nrf_drv_uart_rx_for_uarte(const nrf_drv_uart_t * p_instance, uint8_t * p_data, uint8_t length, bool second_buffer) +{ + ret_code_t err_code = NRF_SUCCESS; + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDRX); + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_RXTO); + nrf_uarte_rx_buffer_set(p_instance->reg.p_uarte, p_data, length); + if (!second_buffer) + { + nrf_uarte_task_trigger(p_instance->reg.p_uarte, NRF_UARTE_TASK_STARTRX); + } + else + { + nrf_uarte_shorts_enable(p_instance->reg.p_uarte, NRF_UARTE_SHORT_ENDRX_STARTRX); + } + + if (m_cb[p_instance->drv_inst_idx].handler == NULL) + { + bool endrx; + bool rxto; + bool error; + do { + endrx = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDRX); + rxto = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_RXTO); + error = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ERROR); + }while ((!endrx) && (!rxto) && (!error)); + + m_cb[p_instance->drv_inst_idx].rx_buffer_length = 0; + + if (error) + { + err_code = NRF_ERROR_INTERNAL; + } + + if (rxto) + { + err_code = NRF_ERROR_FORBIDDEN; + } + } + else + { + nrf_uarte_int_enable(p_instance->reg.p_uarte, NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} +#endif + +ret_code_t nrf_drv_uart_rx(const nrf_drv_uart_t * p_instance, uint8_t * p_data, uint8_t length) +{ + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + + ASSERT(m_cb[p_instance->drv_inst_idx].state == NRF_DRV_STATE_INITIALIZED); + ASSERT(length>0); + + ret_code_t err_code; + + CODE_FOR_UARTE + ( + // EasyDMA requires that transfer buffers are placed in DataRAM, + // signal error if the are not. + if (!nrf_drv_is_in_RAM(p_data)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + ) + + bool second_buffer = false; + + if (p_cb->handler) + { + CODE_FOR_UARTE + ( + nrf_uarte_int_disable(p_instance->reg.p_uarte, NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK); + ) + CODE_FOR_UART + ( + nrf_uart_int_disable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + ) + } + if (p_cb->rx_buffer_length != 0) + { + if (p_cb->rx_secondary_buffer_length != 0) + { + if (p_cb->handler) + { + CODE_FOR_UARTE + ( + nrf_uarte_int_enable(p_instance->reg.p_uarte, NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK); + ) + CODE_FOR_UART + ( + nrf_uart_int_enable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + ) + } + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + second_buffer = true; + } + + if (!second_buffer) + { + p_cb->rx_buffer_length = length; + p_cb->p_rx_buffer = p_data; + p_cb->rx_counter = 0; + p_cb->rx_secondary_buffer_length = 0; + } + else + { + p_cb->p_rx_secondary_buffer = p_data; + p_cb->rx_secondary_buffer_length = length; + } + + NRF_LOG_INFO("Transfer rx_len: %d.\r\n", length); + + + CODE_FOR_UARTE + ( + return nrf_drv_uart_rx_for_uarte(p_instance, p_data, length, second_buffer); + ) + CODE_FOR_UART + ( + return nrf_drv_uart_rx_for_uart(p_instance, p_data, length, second_buffer); + ) +} + +bool nrf_drv_uart_rx_ready(nrf_drv_uart_t const * p_instance) +{ + CODE_FOR_UARTE + ( + return nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDRX); + ) + CODE_FOR_UART + ( + return nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_RXDRDY); + ) +} + +void nrf_drv_uart_rx_enable(const nrf_drv_uart_t * p_instance) +{ + //Easy dma mode does not support enabling receiver without setting up buffer. + CODE_FOR_UARTE + ( + ASSERT(false); + ) + CODE_FOR_UART + ( + if (!m_cb[p_instance->drv_inst_idx].rx_enabled) + { + rx_enable(p_instance); + m_cb[p_instance->drv_inst_idx].rx_enabled = true; + } + ) +} + +void nrf_drv_uart_rx_disable(const nrf_drv_uart_t * p_instance) +{ + //Easy dma mode does not support enabling receiver without setting up buffer. + CODE_FOR_UARTE + ( + ASSERT(false); + ) + CODE_FOR_UART + ( + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPRX); + m_cb[p_instance->drv_inst_idx].rx_enabled = false; + ) +} + +uint32_t nrf_drv_uart_errorsrc_get(const nrf_drv_uart_t * p_instance) +{ + uint32_t errsrc; + CODE_FOR_UARTE + ( + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ERROR); + errsrc = nrf_uarte_errorsrc_get_and_clear(p_instance->reg.p_uarte); + ) + CODE_FOR_UART + ( + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_ERROR); + errsrc = nrf_uart_errorsrc_get_and_clear(p_instance->reg.p_uart); + ) + return errsrc; +} + +__STATIC_INLINE void rx_done_event(uart_control_block_t * p_cb, uint8_t bytes, uint8_t * p_data) +{ + nrf_drv_uart_event_t event; + + event.type = NRF_DRV_UART_EVT_RX_DONE; + event.data.rxtx.bytes = bytes; + event.data.rxtx.p_data = p_data; + + p_cb->handler(&event, p_cb->p_context); +} + +__STATIC_INLINE void tx_done_event(uart_control_block_t * p_cb, uint8_t bytes) +{ + nrf_drv_uart_event_t event; + + event.type = NRF_DRV_UART_EVT_TX_DONE; + event.data.rxtx.bytes = bytes; + event.data.rxtx.p_data = (uint8_t *)p_cb->p_tx_buffer; + + p_cb->tx_buffer_length = 0; + + p_cb->handler(&event, p_cb->p_context); +} + +void nrf_drv_uart_tx_abort(const nrf_drv_uart_t * p_instance) +{ + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + + CODE_FOR_UARTE + ( + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_TXSTOPPED); + nrf_uarte_task_trigger(p_instance->reg.p_uarte, NRF_UARTE_TASK_STOPTX); + if (p_cb->handler == NULL) + { + while (!nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_TXSTOPPED)); + } + ) + CODE_FOR_UART + ( + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPTX); + if (p_cb->handler) + { + tx_done_event(p_cb, p_cb->tx_counter); + } + else + { + p_cb->tx_counter = TX_COUNTER_ABORT_REQ_VALUE; + } + ) + NRF_LOG_INFO("TX transaction aborted.\r\n"); +} + +void nrf_drv_uart_rx_abort(const nrf_drv_uart_t * p_instance) +{ + CODE_FOR_UARTE + ( + nrf_uarte_task_trigger(p_instance->reg.p_uarte, NRF_UARTE_TASK_STOPRX); + ) + CODE_FOR_UART + ( + nrf_uart_int_disable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPRX); + ) + NRF_LOG_INFO("RX transaction aborted.\r\n"); +} + + +#if defined(UART_IN_USE) +__STATIC_INLINE void uart_irq_handler(NRF_UART_Type * p_uart, uart_control_block_t * p_cb) +{ + if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_ERROR) && + nrf_uart_event_check(p_uart, NRF_UART_EVENT_ERROR)) + { + nrf_drv_uart_event_t event; + nrf_uart_event_clear(p_uart, NRF_UART_EVENT_ERROR); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_UART_EVENT_ERROR)); + nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + if (!p_cb->rx_enabled) + { + nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX); + } + event.type = NRF_DRV_UART_EVT_ERROR; + event.data.error.error_mask = nrf_uart_errorsrc_get_and_clear(p_uart); + event.data.error.rxtx.bytes = p_cb->rx_buffer_length; + event.data.error.rxtx.p_data = p_cb->p_rx_buffer; + + //abort transfer + p_cb->rx_buffer_length = 0; + p_cb->rx_secondary_buffer_length = 0; + + p_cb->handler(&event,p_cb->p_context); + } + else if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_RXDRDY) && + nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXDRDY)) + { + rx_byte(p_uart, p_cb); + if (p_cb->rx_buffer_length == p_cb->rx_counter) + { + if (p_cb->rx_secondary_buffer_length) + { + uint8_t * p_data = p_cb->p_rx_buffer; + uint8_t rx_counter = p_cb->rx_counter; + + //Switch to secondary buffer. + p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length; + p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer; + p_cb->rx_secondary_buffer_length = 0; + p_cb->rx_counter = 0; + rx_done_event(p_cb, rx_counter, p_data); + } + else + { + if (!p_cb->rx_enabled) + { + nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX); + } + nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + p_cb->rx_buffer_length = 0; + rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer); + } + } + } + + if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY)) + { + if (p_cb->tx_counter < (uint16_t) p_cb->tx_buffer_length) + { + tx_byte(p_uart, p_cb); + } + else + { + nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY); + if (p_cb->tx_buffer_length) + { + tx_done_event(p_cb, p_cb->tx_buffer_length); + } + } + } + + if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXTO)) + { + nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXTO); + + // RXTO event may be triggered as a result of abort call. In th + if (p_cb->rx_enabled) + { + nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STARTRX); + } + if (p_cb->rx_buffer_length) + { + p_cb->rx_buffer_length = 0; + rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer); + } + } +} +#endif + +#if defined(UARTE_IN_USE) +__STATIC_INLINE void uarte_irq_handler(NRF_UARTE_Type * p_uarte, uart_control_block_t * p_cb) +{ + if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ERROR)) + { + nrf_drv_uart_event_t event; + + nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ERROR); + + event.type = NRF_DRV_UART_EVT_ERROR; + event.data.error.error_mask = nrf_uarte_errorsrc_get_and_clear(p_uarte); + event.data.error.rxtx.bytes = nrf_uarte_rx_amount_get(p_uarte); + event.data.error.rxtx.p_data = p_cb->p_rx_buffer; + + //abort transfer + p_cb->rx_buffer_length = 0; + p_cb->rx_secondary_buffer_length = 0; + + p_cb->handler(&event, p_cb->p_context); + } + else if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDRX)) + { + nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDRX); + uint8_t amount = nrf_uarte_rx_amount_get(p_uarte); + // If the transfer was stopped before completion, amount of transfered bytes + // will not be equal to the buffer length. Interrupted trunsfer is ignored. + if (amount == p_cb->rx_buffer_length) + { + if (p_cb->rx_secondary_buffer_length) + { + uint8_t * p_data = p_cb->p_rx_buffer; + nrf_uarte_shorts_disable(p_uarte, NRF_UARTE_SHORT_ENDRX_STARTRX); + p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length; + p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer; + p_cb->rx_secondary_buffer_length = 0; + rx_done_event(p_cb, amount, p_data); + } + else + { + p_cb->rx_buffer_length = 0; + rx_done_event(p_cb, amount, p_cb->p_rx_buffer); + } + } + } + + if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_RXTO)) + { + nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_RXTO); + if (p_cb->rx_buffer_length) + { + p_cb->rx_buffer_length = 0; + rx_done_event(p_cb, nrf_uarte_rx_amount_get(p_uarte), p_cb->p_rx_buffer); + } + } + + if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDTX)) + { + nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDTX); + if (p_cb->tx_buffer_length) + { + tx_done_event(p_cb, nrf_uarte_tx_amount_get(p_uarte)); + } + } +} +#endif + +#if UART0_ENABLED +void UART0_IRQHandler(void) +{ + CODE_FOR_UARTE_INT + ( + UART0_INSTANCE_INDEX, + uarte_irq_handler(NRF_UARTE0, &m_cb[UART0_INSTANCE_INDEX]); + ) + CODE_FOR_UART + ( + uart_irq_handler(NRF_UART0, &m_cb[UART0_INSTANCE_INDEX]); + ) +} +#endif + +#if UART1_ENABLED +void UARTE1_IRQHandler(void) +{ + CODE_FOR_UARTE_INT + ( + UART1_INSTANCE_INDEX, + uarte_irq_handler(NRF_UARTE1, &m_cb[UART1_INSTANCE_INDEX]); + ) + CODE_FOR_UART + ( + uart_irq_handler(NRF_UART1, &m_cb[UART1_INSTANCE_INDEX]); + ) +} +#endif +#endif //NRF_MODULE_ENABLED(UART) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/uart/nrf_drv_uart.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/uart/nrf_drv_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..88739dfe97678d8128cc3d74eff9a43b1940d785 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/uart/nrf_drv_uart.h @@ -0,0 +1,443 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * @addtogroup nrf_uart UART driver and HAL + * @ingroup nrf_drivers + * @brief UART API. + * @details The UART driver provides APIs for utilizing the UART peripheral. + * + * @defgroup nrf_drv_uart UART driver + * @{ + * @ingroup nrf_uart + * + * @brief UART driver. + */ + +#ifndef NRF_DRV_UART_H +#define NRF_DRV_UART_H + +#include "nrf_uart.h" +#ifdef UARTE_PRESENT +#include "nrf_uarte.h" +#endif + +#include "sdk_errors.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef UART1_ENABLED +#define UART1_ENABLED 0 +#endif + +#ifndef UART0_ENABLED +#define UART0_ENABLED 0 +#endif + +#define UART0_INSTANCE_INDEX 0 +#define UART1_INSTANCE_INDEX UART0_ENABLED +#define UART_ENABLED_COUNT UART0_ENABLED + UART1_ENABLED + +#if defined(UARTE_PRESENT) + #define NRF_DRV_UART_PERIPHERAL(id) \ + (CONCAT_3(UART, id, _CONFIG_USE_EASY_DMA) == 1 ? \ + (void *)CONCAT_2(NRF_UARTE, id) \ + : (void *)CONCAT_2(NRF_UART, id)) +#else + #define NRF_DRV_UART_PERIPHERAL(id) (void *)CONCAT_2(NRF_UART, id) +#endif + +// This set of macros makes it possible to exclude parts of code, when one type +// of supported peripherals is not used. + +#if defined(UARTE_PRESENT) + +#if (UART_EASY_DMA_SUPPORT == 1) +#define UARTE_IN_USE +#endif + +#if (UART_LEGACY_SUPPORT == 1) +#define UART_IN_USE +#endif + +#if (UART_ENABLED == 1) && ((!defined(UARTE_IN_USE) && !defined(UART_IN_USE)) || ((UART_EASY_DMA_SUPPORT == 0) && (UART_LEGACY_SUPPORT == 0))) +#error "Illegal settings in uart module!" +#endif + +#elif defined(UART_PRESENT) +#define UART_IN_USE +#endif + +/** + * @brief Structure for the UART driver instance. + */ +typedef struct +{ + union + { +#if (defined(UARTE_IN_USE)) + NRF_UARTE_Type * p_uarte; ///< Pointer to a structure with UARTE registers. +#endif +#if (defined(UART_IN_USE) || (UART_ENABLED == 0)) + NRF_UART_Type * p_uart; ///< Pointer to a structure with UART registers. +#endif + } reg; + uint8_t drv_inst_idx; ///< Driver instance index. +} nrf_drv_uart_t; + +/** + * @brief Macro for creating an UART driver instance. + */ +#define NRF_DRV_UART_INSTANCE(id) \ +{ \ + .reg = {NRF_DRV_UART_PERIPHERAL(id)}, \ + .drv_inst_idx = CONCAT_3(UART, id, _INSTANCE_INDEX),\ +} + +/** + * @brief Types of UART driver events. + */ +typedef enum +{ + NRF_DRV_UART_EVT_TX_DONE, ///< Requested TX transfer completed. + NRF_DRV_UART_EVT_RX_DONE, ///< Requested RX transfer completed. + NRF_DRV_UART_EVT_ERROR, ///< Error reported by UART peripheral. +} nrf_drv_uart_evt_type_t; + +/**@brief Structure for UART configuration. */ +typedef struct +{ + uint32_t pseltxd; ///< TXD pin number. + uint32_t pselrxd; ///< RXD pin number. + uint32_t pselcts; ///< CTS pin number. + uint32_t pselrts; ///< RTS pin number. + void * p_context; ///< Context passed to interrupt handler. + nrf_uart_hwfc_t hwfc; ///< Flow control configuration. + nrf_uart_parity_t parity; ///< Parity configuration. + nrf_uart_baudrate_t baudrate; ///< Baudrate. + uint8_t interrupt_priority; ///< Interrupt priority. +#ifdef UARTE_PRESENT + bool use_easy_dma; +#endif +} nrf_drv_uart_config_t; + +/**@brief UART default configuration. */ +#ifdef UARTE_PRESENT +#if !UART_LEGACY_SUPPORT +#define DEFAULT_CONFIG_USE_EASY_DMA true +#elif !UART_EASY_DMA_SUPPORT +#define DEFAULT_CONFIG_USE_EASY_DMA false +#else +#define DEFAULT_CONFIG_USE_EASY_DMA UART0_USE_EASY_DMA +#endif +#define NRF_DRV_UART_DEFAULT_CONFIG \ + { \ + .pseltxd = NRF_UART_PSEL_DISCONNECTED, \ + .pselrxd = NRF_UART_PSEL_DISCONNECTED, \ + .pselcts = NRF_UART_PSEL_DISCONNECTED, \ + .pselrts = NRF_UART_PSEL_DISCONNECTED, \ + .p_context = NULL, \ + .hwfc = (nrf_uart_hwfc_t)UART_DEFAULT_CONFIG_HWFC, \ + .parity = (nrf_uart_parity_t)UART_DEFAULT_CONFIG_PARITY, \ + .baudrate = (nrf_uart_baudrate_t)UART_DEFAULT_CONFIG_BAUDRATE, \ + .interrupt_priority = UART_DEFAULT_CONFIG_IRQ_PRIORITY, \ + .use_easy_dma = true \ + } +#else +#define NRF_DRV_UART_DEFAULT_CONFIG \ + { \ + .pseltxd = NRF_UART_PSEL_DISCONNECTED, \ + .pselrxd = NRF_UART_PSEL_DISCONNECTED, \ + .pselcts = NRF_UART_PSEL_DISCONNECTED, \ + .pselrts = NRF_UART_PSEL_DISCONNECTED, \ + .p_context = NULL, \ + .hwfc = (nrf_uart_hwfc_t)UART_DEFAULT_CONFIG_HWFC, \ + .parity = (nrf_uart_parity_t)UART_DEFAULT_CONFIG_PARITY, \ + .baudrate = (nrf_uart_baudrate_t)UART_DEFAULT_CONFIG_BAUDRATE, \ + .interrupt_priority = UART_DEFAULT_CONFIG_IRQ_PRIORITY, \ + } +#endif + +/**@brief Structure for UART transfer completion event. */ +typedef struct +{ + uint8_t * p_data; ///< Pointer to memory used for transfer. + uint8_t bytes; ///< Number of bytes transfered. +} nrf_drv_uart_xfer_evt_t; + +/**@brief Structure for UART error event. */ +typedef struct +{ + nrf_drv_uart_xfer_evt_t rxtx; ///< Transfer details includes number of bytes transfered. + uint32_t error_mask;///< Mask of error flags that generated the event. +} nrf_drv_uart_error_evt_t; + +/**@brief Structure for UART event. */ +typedef struct +{ + nrf_drv_uart_evt_type_t type; ///< Event type. + union + { + nrf_drv_uart_xfer_evt_t rxtx; ///< Data provided for transfer completion events. + nrf_drv_uart_error_evt_t error;///< Data provided for error event. + } data; +} nrf_drv_uart_event_t; + +/** + * @brief UART interrupt event handler. + * + * @param[in] p_event Pointer to event structure. Event is allocated on the stack so it is available + * only within the context of the event handler. + * @param[in] p_context Context passed to interrupt handler, set on initialization. + */ +typedef void (*nrf_uart_event_handler_t)(nrf_drv_uart_event_t * p_event, void * p_context); + +/** + * @brief Function for initializing the UART driver. + * + * This function configures and enables UART. After this function GPIO pins are controlled by UART. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_config Initial configuration. Default configuration used if NULL. + * @param[in] event_handler Event handler provided by the user. If not provided driver works in + * blocking mode. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If driver is already initialized. + */ +ret_code_t nrf_drv_uart_init(nrf_drv_uart_t const * p_instance, + nrf_drv_uart_config_t const * p_config, + nrf_uart_event_handler_t event_handler); + +/** + * @brief Function for uninitializing the UART driver. + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_uart_uninit(nrf_drv_uart_t const * p_instance); + +/** + * @brief Function for getting the address of a specific UART task. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_uart_task_address_get(nrf_drv_uart_t const * p_instance, + nrf_uart_task_t task); + +/** + * @brief Function for getting the address of a specific UART event. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] event Event. + * + * @return Event address. + */ +__STATIC_INLINE uint32_t nrf_drv_uart_event_address_get(nrf_drv_uart_t const * p_instance, + nrf_uart_event_t event); + +/** + * @brief Function for sending data over UART. + * + * If an event handler was provided in nrf_drv_uart_init() call, this function + * returns immediately and the handler is called when the transfer is done. + * Otherwise, the transfer is performed in blocking mode, i.e. this function + * returns when the transfer is finished. Blocking mode is not using interrupt so + * there is no context switching inside the function. + * + * @note Peripherals using EasyDMA (i.e. UARTE) require that the transfer buffers + * are placed in the Data RAM region. If they are not and UARTE instance is + * used, this function will fail with error code NRF_ERROR_INVALID_ADDR. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_data Pointer to data. + * @param[in] length Number of bytes to send. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_BUSY If driver is already transferring. + * @retval NRF_ERROR_FORBIDDEN If the transfer was aborted from a different context + * (blocking mode only, also see @ref nrf_drv_uart_rx_disable). + * @retval NRF_ERROR_INVALID_ADDR If p_data does not point to RAM buffer (UARTE only). + */ +ret_code_t nrf_drv_uart_tx(nrf_drv_uart_t const * p_instance, + uint8_t const * const p_data, uint8_t length); + +/** + * @brief Function for checking if UART is currently transmitting. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true If UART is transmitting. + * @retval false If UART is not transmitting. + */ +bool nrf_drv_uart_tx_in_progress(nrf_drv_uart_t const * p_instance); + +/** + * @brief Function for aborting any ongoing transmission. + * @note @ref NRF_DRV_UART_EVT_TX_DONE event will be generated in non-blocking mode. Event will + * contain number of bytes sent until abort was called. If Easy DMA is not used event will be + * called from the function context. If Easy DMA is used it will be called from UART interrupt + * context. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_uart_tx_abort(nrf_drv_uart_t const * p_instance); + +/** + * @brief Function for receiving data over UART. + * + * If an event handler was provided in the nrf_drv_uart_init() call, this function + * returns immediately and the handler is called when the transfer is done. + * Otherwise, the transfer is performed in blocking mode, i.e. this function + * returns when the transfer is finished. Blocking mode is not using interrupt so + * there is no context switching inside the function. + * The receive buffer pointer is double buffered in non-blocking mode. The secondary + * buffer can be set immediately after starting the transfer and will be filled + * when the primary buffer is full. The double buffering feature allows + * receiving data continuously. + * + * @note Peripherals using EasyDMA (i.e. UARTE) require that the transfer buffers + * are placed in the Data RAM region. If they are not and UARTE driver instance + * is used, this function will fail with error code NRF_ERROR_INVALID_ADDR. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_data Pointer to data. + * @param[in] length Number of bytes to receive. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_BUSY If the driver is already receiving + * (and the secondary buffer has already been set + * in non-blocking mode). + * @retval NRF_ERROR_FORBIDDEN If the transfer was aborted from a different context + * (blocking mode only, also see @ref nrf_drv_uart_rx_disable). + * @retval NRF_ERROR_INTERNAL If UART peripheral reported an error. + * @retval NRF_ERROR_INVALID_ADDR If p_data does not point to RAM buffer (UARTE only). + */ +ret_code_t nrf_drv_uart_rx(nrf_drv_uart_t const * p_instance, + uint8_t * p_data, uint8_t length); + + + +/** + * @brief Function for testing the receiver state in blocking mode. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true If the receiver has at least one byte of data to get. + * @retval false If the receiver is empty. + */ +bool nrf_drv_uart_rx_ready(nrf_drv_uart_t const * p_instance); + +/** + * @brief Function for enabling the receiver. + * + * UART has a 6-byte-long RX FIFO and it is used to store incoming data. If a user does not call the + * UART receive function before the FIFO is filled, an overrun error will appear. Enabling the receiver + * without specifying an RX buffer is supported only in UART mode (without Easy DMA). The receiver must be + * explicitly closed by the user @sa nrf_drv_uart_rx_disable. This function asserts if the mode is wrong. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_uart_rx_enable(nrf_drv_uart_t const * p_instance); + +/** + * @brief Function for disabling the receiver. + * + * This function must be called to close the receiver after it has been explicitly enabled by + * @sa nrf_drv_uart_rx_enable. The feature is supported only in UART mode (without Easy DMA). The function + * asserts if mode is wrong. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_uart_rx_disable(nrf_drv_uart_t const * p_instance); + +/** + * @brief Function for aborting any ongoing reception. + * @note @ref NRF_DRV_UART_EVT_RX_DONE event will be generated in non-blocking mode. The event will + * contain the number of bytes received until abort was called. The event is called from UART interrupt + * context. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_uart_rx_abort(nrf_drv_uart_t const * p_instance); + +/** + * @brief Function for reading error source mask. Mask contains values from @ref nrf_uart_error_mask_t. + * @note Function should be used in blocking mode only. In case of non-blocking mode, an error event is + * generated. Function clears error sources after reading. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval Mask of reported errors. + */ +uint32_t nrf_drv_uart_errorsrc_get(nrf_drv_uart_t const * p_instance); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION +__STATIC_INLINE uint32_t nrf_drv_uart_task_address_get(nrf_drv_uart_t const * p_instance, + nrf_uart_task_t task) +{ +#ifdef UART_IN_USE + return nrf_uart_task_address_get(p_instance->reg.p_uart, task); +#else + return nrf_uarte_task_address_get(p_instance->reg.p_uarte, (nrf_uarte_task_t)task); +#endif +} + +__STATIC_INLINE uint32_t nrf_drv_uart_event_address_get(nrf_drv_uart_t const * p_instance, + nrf_uart_event_t event) +{ +#ifdef UART_IN_USE + return nrf_uart_event_address_get(p_instance->reg.p_uart, event); +#else + return nrf_uarte_event_address_get(p_instance->reg.p_uarte, (nrf_uarte_event_t)event); +#endif +} +#endif //SUPPRESS_INLINE_IMPLEMENTATION + +#ifdef __cplusplus +} +#endif + +#endif //NRF_DRV_UART_H +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/usbd/nrf_drv_usbd.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/usbd/nrf_drv_usbd.c new file mode 100644 index 0000000000000000000000000000000000000000..5590276113e3f730d8737b79564573e6c2ee7826 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/usbd/nrf_drv_usbd.c @@ -0,0 +1,2056 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" +#if USBD_ENABLED +#include "nrf_drv_usbd.h" +#include "nrf.h" +#include "nordic_common.h" +#include "nrf_drv_common.h" +#include "nrf_atomic.h" +#include "nrf_delay.h" +#include "nrf_drv_clock.h" +#include "app_util_platform.h" + +#include +#include + +#define NRF_LOG_MODULE_NAME "" +#if NRF_USBD_DRV_LOG_ENABLED +#else //NRF_USBD_DRV_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //NRF_USBD_DRV_LOG_ENABLED +#include "nrf_log.h" + +#ifndef NRF_DRV_USBD_EARLY_DMA_PROCESS +/* Try to process DMA request when endpoint transmission has been detected + * and just after last EasyDMA has been processed. + * It speeds up the transmission a little (about 10% measured) + * with a cost of more CPU power used. + */ +#define NRF_DRV_USBD_EARLY_DMA_PROCESS 1 +#endif + +#ifndef NRF_DRV_USBD_PROTO1_FIX +/* Fix event system */ +#define NRF_DRV_USBD_PROTO1_FIX 1 +#endif + +#ifndef NRF_DRV_USBD_PROTO1_FIX_DEBUG +/* Debug information when events are fixed*/ +#define NRF_DRV_USBD_PROTO1_FIX_DEBUG 1 +#endif + +#if NRF_DRV_USBD_PROTO1_FIX_DEBUG +#include "nrf_log.h" +#define NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(...) NRF_LOG_DEBUG(__VA_ARGS__) +#else +#define NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(...) do {} while (0) +#endif + +#ifndef NRF_DRV_USBD_STARTED_EV_ENABLE +#define NRF_DRV_USBD_STARTED_EV_ENABLE 1 +#endif + +#ifndef NRF_USBD_ISO_DEBUG +/* Also generate information about ISOCHRONOUS events and transfers. + * Turn this off if no ISOCHRONOUS transfers are going to be debugged and this + * option generates a lot of useless messages. */ +#define NRF_USBD_ISO_DEBUG 1 +#endif + +#ifndef NRF_USBD_FAILED_TRANSFERS_DEBUG +/* Also generate debug information for failed transfers. + * It might be useful but may generate a lot of useless debug messages + * in some library usages (for example when transfer is generated and the + * result is used to check whatever endpoint was busy. */ +#define NRF_USBD_FAILED_TRANSFERS_DEBUG 1 +#endif + +#ifndef NRF_USBD_DMAREQ_PROCESS_DEBUG +/* Generate additional messages that mark the status inside + * @ref usbd_dmareq_process. + * It is useful to debug library internals but may generate a lot of + * useless debug messages. */ +#define NRF_USBD_DMAREQ_PROCESS_DEBUG 1 +#endif + + + + +#if NRF_DRV_USBD_PROTO1_FIX +#include "nrf_drv_systick.h" +#endif + +/** + * @defgroup nrf_usbdraw_drv_int USB Device driver internal part + * @internal + * @ingroup nrf_usbdraw_drv + * + * This part contains auxiliary internal macros, variables and functions. + * @{ + */ + +/** + * @brief Assert endpoint number validity + * + * Internal macro to be used during program creation in debug mode. + * Generates assertion if endpoint number is not valid. + * + * @param ep Endpoint number to validity check + */ +#define USBD_ASSERT_EP_VALID(ep) ASSERT( \ + ((NRF_USBD_EPIN_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPIN_CNT )) \ + || \ + (NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPOUT_CNT))) \ +); + +/** + * @brief Lowest position of bit for IN endpoint + * + * The first bit position corresponding to IN endpoint. + * @sa ep2bit bit2ep + */ +#define USBD_EPIN_BITPOS_0 0 + +/** + * @brief Lowest position of bit for OUT endpoint + * + * The first bit position corresponding to OUT endpoint + * @sa ep2bit bit2ep + */ +#define USBD_EPOUT_BITPOS_0 16 + +/** + * @brief Input endpoint bits mask + */ +#define USBD_EPIN_BIT_MASK (0xFFFFU << USBD_EPIN_BITPOS_0) + +/** + * @brief Output endpoint bits mask + */ +#define USBD_EPOUT_BIT_MASK (0xFFFFU << USBD_EPOUT_BITPOS_0) + +/** + * @brief Auxiliary macro to change EP number into bit position + * + * This macro is used by @ref ep2bit function but also for statically check + * the bitpos values integrity during compilation. + * + * @param[in] ep Endpoint number. + * @return Endpoint bit position. + */ +#define USBD_EP_BITPOS(ep) \ + ((NRF_USBD_EPIN_CHECK(ep) ? USBD_EPIN_BITPOS_0 : USBD_EPOUT_BITPOS_0) + NRF_USBD_EP_NR_GET(ep)) + +/** + * @brief Helper macro for creating an endpoint transfer event. + * + * @param[in] name Name of the created transfer event variable. + * @param[in] endpoint Endpoint number. + * @param[in] ep_stat Endpoint state to report. + * + * @return Initialized event constant variable. + */ +#define NRF_DRV_USBD_EP_TRANSFER_EVENT(name, endpont, ep_stat) \ + const nrf_drv_usbd_evt_t name = { \ + NRF_DRV_USBD_EVT_EPTRANSFER, \ + .data = { \ + .eptransfer = { \ + .ep = endpont, \ + .status = ep_stat \ + } \ + } \ + } + +/* Check it the bit positions values match defined DATAEPSTATUS bit positions */ +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN1) == USBD_EPDATASTATUS_EPIN1_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN2) == USBD_EPDATASTATUS_EPIN2_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN3) == USBD_EPDATASTATUS_EPIN3_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN4) == USBD_EPDATASTATUS_EPIN4_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN5) == USBD_EPDATASTATUS_EPIN5_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN6) == USBD_EPDATASTATUS_EPIN6_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN7) == USBD_EPDATASTATUS_EPIN7_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT1) == USBD_EPDATASTATUS_EPOUT1_Pos); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT2) == USBD_EPDATASTATUS_EPOUT2_Pos); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT3) == USBD_EPDATASTATUS_EPOUT3_Pos); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT4) == USBD_EPDATASTATUS_EPOUT4_Pos); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT5) == USBD_EPDATASTATUS_EPOUT5_Pos); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT6) == USBD_EPDATASTATUS_EPOUT6_Pos); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT7) == USBD_EPDATASTATUS_EPOUT7_Pos); + + +/** + * @name Internal auxiliary definitions for SETUP packet + * + * Definitions used to take out the information about last SETUP packet direction + * from @c bmRequestType. + * @{ + */ +/** The position of DIR bit in bmRequestType inside SETUP packet */ +#define USBD_DRV_REQUESTTYPE_DIR_BITPOS 7 +/** The mask of DIR bit in bmRequestType inside SETUP packet */ +#define USBD_DRV_REQUESTTYPE_DIR_MASK (1U << USBD_DRV_REQUESTTYPE_DIR_BITPOS) +/** The value of DIR bit for OUT direction (Host -> Device) */ +#define USBD_DRV_REQUESTTYPE_DIR_OUT (0U << USBD_DRV_REQUESTTYPE_DIR_BITPOS) +/** The value of DIR bit for IN direction (Device -> Host) */ +#define USBD_DRV_REQUESTTYPE_DIR_IN (1U << USBD_DRV_REQUESTTYPE_DIR_BITPOS) +/** @} */ + +/** + * @brief Current driver state + */ +static nrf_drv_state_t m_drv_state = NRF_DRV_STATE_UNINITIALIZED; + +/** + * @brief Event handler for the library + * + * Event handler that would be called on events. + * + * @note Currently it cannot be null if any interrupt is activated. + */ +static nrf_drv_usbd_event_handler_t m_event_handler; + +/** + * @brief Direction of last received Setup transfer + * + * This variable is used to redirect internal setup data event + * into selected endpoint (IN or OUT). + */ +static nrf_drv_usbd_ep_t m_last_setup_dir; + +/** + * @brief Mark endpoint readiness for DMA transfer + * + * Bits in this variable are cleared and set in interrupts. + * 1 means that endpoint is ready for DMA transfer. + * 0 means that DMA transfer cannot be performed on selected endpoint. + */ +static uint32_t m_ep_ready; + +/** + * @brief Mark endpoint with prepared data to transfer by DMA + * + * This variable can be from any place in the code (interrupt or main thread). + * It would be cleared only from USBD interrupt. + * + * Mask prepared USBD data for transmission. + * It is cleared when no more data to transmit left. + */ +static uint32_t m_ep_dma_waiting; + +/** + * @brief Current EasyDMA state + * + * Single flag, updated only inside interrupts, that marks current EasyDMA state. + * In USBD there is only one DMA channel working in background, and new transfer + * cannot be started when there is ongoing transfer on any other channel. + */ +static uint8_t m_dma_pending; + +#if NRF_DRV_USBD_PROTO1_FIX +static uint32_t m_simulated_dataepstatus; +#endif + +/** + * @brief The structure that would hold transfer configuration to every endpoint + * + * The structure that holds all the data required by the endpoint to proceed + * with LIST functionality and generate quick callback directly when data + * buffer is ready. + */ +typedef struct +{ + nrf_drv_usbd_handler_t handler; //!< Handler for current transfer, function pointer + void * p_context; //!< Context for transfer handler + size_t transfer_cnt; //!< Number of transferred bytes in the current transfer + uint16_t max_packet_size; //!< Configured endpoint size + nrf_drv_usbd_ep_status_t status; //!< NRF_SUCCESS or error code, never NRF_ERROR_BUSY - this one is calculated +}usbd_drv_ep_state_t; + +/** + * @brief The array of transfer configurations for the endpoints. + * + * The status of the transfer on each endpoint. + */ +static struct +{ + usbd_drv_ep_state_t ep_out[NRF_USBD_EPOUT_CNT]; //!< Status for OUT endpoints. + usbd_drv_ep_state_t ep_in [NRF_USBD_EPIN_CNT ]; //!< Status for IN endpoints. +}m_ep_state; + +/** + * @brief Status variables for integrated feeders. + * + * Current status for integrated feeders (IN transfers). + * Integrated feeders are used for default transfers: + * 1. Simple RAM transfer + * 2. Simple flash transfer + * 3. RAM transfer with automatic ZLP + * 4. Flash transfer with automatic ZLP + */ +nrf_drv_usbd_transfer_t m_ep_feeder_state[NRF_USBD_EPIN_CNT]; + +/** + * @brief Status variables for integrated consumers + * + * Current status for integrated consumers + * Currently one type of transfer is supported: + * 1. Transfer to RAM + * + * Transfer is finished automatically when received data block is smaller + * than the endpoint buffer or all the required data is received. + */ +nrf_drv_usbd_transfer_t m_ep_consumer_state[NRF_USBD_EPOUT_CNT]; + + +/** + * @brief Buffer used to send data directly from FLASH + * + * This is internal buffer that would be used to emulate the possibility + * to transfer data directly from FLASH. + * We do not have to care about the source of data when calling transfer functions. + * + * We do not need more buffers that one, because only one transfer can be pending + * at once. + */ +static uint32_t m_tx_buffer[CEIL_DIV( + NRF_DRV_USBD_FEEDER_BUFFER_SIZE, sizeof(uint32_t))]; + + +/* Early declaration. Documentation above definition. */ +static void usbd_dmareq_process(void); + + +#if NRF_DRV_USBD_PROTO1_FIX +static inline nrf_usbd_event_t nrf_drv_usbd_ep_to_endevent(nrf_drv_usbd_ep_t ep) +{ + USBD_ASSERT_EP_VALID(ep); + + static const nrf_usbd_event_t epin_endev[] = + { + NRF_USBD_EVENT_ENDEPIN0, + NRF_USBD_EVENT_ENDEPIN1, + NRF_USBD_EVENT_ENDEPIN2, + NRF_USBD_EVENT_ENDEPIN3, + NRF_USBD_EVENT_ENDEPIN4, + NRF_USBD_EVENT_ENDEPIN5, + NRF_USBD_EVENT_ENDEPIN6, + NRF_USBD_EVENT_ENDEPIN7, + NRF_USBD_EVENT_ENDISOIN0 + }; + static const nrf_usbd_event_t epout_endev[] = + { + NRF_USBD_EVENT_ENDEPOUT0, + NRF_USBD_EVENT_ENDEPOUT1, + NRF_USBD_EVENT_ENDEPOUT2, + NRF_USBD_EVENT_ENDEPOUT3, + NRF_USBD_EVENT_ENDEPOUT4, + NRF_USBD_EVENT_ENDEPOUT5, + NRF_USBD_EVENT_ENDEPOUT6, + NRF_USBD_EVENT_ENDEPOUT7, + NRF_USBD_EVENT_ENDISOOUT0 + }; + + return (NRF_USBD_EPIN_CHECK(ep) ? epin_endev : epout_endev)[NRF_USBD_EP_NR_GET(ep)]; +} +#endif + + +/** + * @brief Get interrupt mask for selected endpoint + * + * @param[in] ep Endpoint number + * + * @return Interrupt mask related to the EasyDMA transfer end for the + * chosen endpoint. + */ +static inline uint32_t nrf_drv_usbd_ep_to_int(nrf_drv_usbd_ep_t ep) +{ + USBD_ASSERT_EP_VALID(ep); + + static const uint8_t epin_bitpos[] = + { + USBD_INTEN_ENDEPIN0_Pos, + USBD_INTEN_ENDEPIN1_Pos, + USBD_INTEN_ENDEPIN2_Pos, + USBD_INTEN_ENDEPIN3_Pos, + USBD_INTEN_ENDEPIN4_Pos, + USBD_INTEN_ENDEPIN5_Pos, + USBD_INTEN_ENDEPIN6_Pos, + USBD_INTEN_ENDEPIN7_Pos, + USBD_INTEN_ENDISOIN_Pos + }; + static const uint8_t epout_bitpos[] = + { + USBD_INTEN_ENDEPOUT0_Pos, + USBD_INTEN_ENDEPOUT1_Pos, + USBD_INTEN_ENDEPOUT2_Pos, + USBD_INTEN_ENDEPOUT3_Pos, + USBD_INTEN_ENDEPOUT4_Pos, + USBD_INTEN_ENDEPOUT5_Pos, + USBD_INTEN_ENDEPOUT6_Pos, + USBD_INTEN_ENDEPOUT7_Pos, + USBD_INTEN_ENDISOOUT_Pos + }; + + return 1UL << (NRF_USBD_EPIN_CHECK(ep) ? epin_bitpos : epout_bitpos)[NRF_USBD_EP_NR_GET(ep)]; +} + +/** + * @name Integrated feeders and consumers + * + * Internal, default functions for transfer processing. + * @{ + */ + +/** + * @brief Integrated consumer to RAM buffer. + * + * @param p_next See @ref nrf_drv_usbd_consumer_t documentation. + * @param p_context See @ref nrf_drv_usbd_consumer_t documentation. + * @param ep_size See @ref nrf_drv_usbd_consumer_t documentation. + * @param data_size See @ref nrf_drv_usbd_consumer_t documentation. + * + * @retval true Continue transfer. + * @retval false This was the last transfer. + */ +bool nrf_drv_usbd_consumer( + nrf_drv_usbd_ep_transfer_t * p_next, + void * p_context, + size_t ep_size, + size_t data_size) +{ + nrf_drv_usbd_transfer_t * p_transfer = p_context; + ASSERT(ep_size >= data_size); + ASSERT((p_transfer->p_data.rx == NULL) || + nrf_drv_is_in_RAM((const void*)(p_transfer->p_data.ptr))); + + size_t size = p_transfer->size; + if (size < data_size) + { + /* Buffer size to small */ + p_next->size = 0; + p_next->p_data = p_transfer->p_data; + } + else + { + p_next->size = data_size; + p_next->p_data = p_transfer->p_data; + size -= data_size; + p_transfer->size = size; + p_transfer->p_data.ptr += data_size; + } + return (ep_size == data_size) && (size != 0); +} + +/** + * @brief Integrated feeder from RAM source. + * + * @param[out] p_next See @ref nrf_drv_usbd_feeder_t documentation. + * @param[in,out] p_context See @ref nrf_drv_usbd_feeder_t documentation. + * @param[in] ep_size See @ref nrf_drv_usbd_feeder_t documentation. + * + * @retval true Continue transfer. + * @retval false This was the last transfer. + */ +bool nrf_drv_usbd_feeder_ram( + nrf_drv_usbd_ep_transfer_t * p_next, + void * p_context, + size_t ep_size) +{ + nrf_drv_usbd_transfer_t * p_transfer = p_context; + ASSERT(nrf_drv_is_in_RAM((const void*)(p_transfer->p_data.ptr))); + + size_t tx_size = p_transfer->size; + if (tx_size > ep_size) + { + tx_size = ep_size; + } + + p_next->p_data = p_transfer->p_data; + p_next->size = tx_size; + + p_transfer->size -= tx_size; + p_transfer->p_data.ptr += tx_size; + + return (p_transfer->size != 0); +} + +/** + * @brief Integrated feeder from RAM source with ZLP. + * + * @param[out] p_next See @ref nrf_drv_usbd_feeder_t documentation. + * @param[in,out] p_context See @ref nrf_drv_usbd_feeder_t documentation. + * @param[in] ep_size See @ref nrf_drv_usbd_feeder_t documentation. + * + * @retval true Continue transfer. + * @retval false This was the last transfer. + */ +bool nrf_drv_usbd_feeder_ram_zlp( + nrf_drv_usbd_ep_transfer_t * p_next, + void * p_context, + size_t ep_size) +{ + nrf_drv_usbd_transfer_t * p_transfer = p_context; + ASSERT(nrf_drv_is_in_RAM((const void*)(p_transfer->p_data.ptr))); + + size_t tx_size = p_transfer->size; + if (tx_size > ep_size) + { + tx_size = ep_size; + } + + p_next->p_data.tx = (tx_size == 0) ? NULL : p_transfer->p_data.tx; + p_next->size = tx_size; + + p_transfer->size -= tx_size; + p_transfer->p_data.ptr += tx_size; + + return (tx_size != 0); +} + +/** + * @brief Integrated feeder from a flash source. + * + * @param[out] p_next See @ref nrf_drv_usbd_feeder_t documentation. + * @param[in,out] p_context See @ref nrf_drv_usbd_feeder_t documentation. + * @param[in] ep_size See @ref nrf_drv_usbd_feeder_t documentation. + * + * @retval true Continue transfer. + * @retval false This was the last transfer. + */ +bool nrf_drv_usbd_feeder_flash( + nrf_drv_usbd_ep_transfer_t * p_next, + void * p_context, + size_t ep_size) +{ + nrf_drv_usbd_transfer_t * p_transfer = p_context; + ASSERT(!nrf_drv_is_in_RAM((const void*)(p_transfer->p_data.ptr))); + + size_t tx_size = p_transfer->size; + void * p_buffer = nrf_drv_usbd_feeder_buffer_get(); + + if (tx_size > ep_size) + { + tx_size = ep_size; + } + + ASSERT(tx_size <= NRF_DRV_USBD_FEEDER_BUFFER_SIZE); + memcpy(p_buffer, (p_transfer->p_data.tx), tx_size); + + p_next->p_data.tx = p_buffer; + p_next->size = tx_size; + + p_transfer->size -= tx_size; + p_transfer->p_data.ptr += tx_size; + + return (p_transfer->size != 0); +} + +/** + * @brief Integrated feeder from a flash source with ZLP. + * + * @param[out] p_next See @ref nrf_drv_usbd_feeder_t documentation. + * @param[in,out] p_context See @ref nrf_drv_usbd_feeder_t documentation. + * @param[in] ep_size See @ref nrf_drv_usbd_feeder_t documentation. + * + * @retval true Continue transfer. + * @retval false This was the last transfer. + */ +bool nrf_drv_usbd_feeder_flash_zlp( + nrf_drv_usbd_ep_transfer_t * p_next, + void * p_context, + size_t ep_size) +{ + nrf_drv_usbd_transfer_t * p_transfer = p_context; + ASSERT(!nrf_drv_is_in_RAM((const void*)(p_transfer->p_data.ptr))); + + size_t tx_size = p_transfer->size; + void * p_buffer = nrf_drv_usbd_feeder_buffer_get(); + + if (tx_size > ep_size) + { + tx_size = ep_size; + } + + ASSERT(tx_size <= NRF_DRV_USBD_FEEDER_BUFFER_SIZE); + + if (tx_size != 0) + { + memcpy(p_buffer, (p_transfer->p_data.tx), tx_size); + p_next->p_data.tx = p_buffer; + } + else + { + p_next->p_data.tx = NULL; + } + p_next->size = tx_size; + + p_transfer->size -= tx_size; + p_transfer->p_data.ptr += tx_size; + + return (tx_size != 0); +} + +/** @} */ + +/** + * @brief Change Driver endpoint number to HAL endpoint number + * + * @param ep Driver endpoint identifier + * + * @return Endpoint identifier in HAL + * + * @sa nrf_drv_usbd_ep_from_hal + */ +static inline uint8_t ep_to_hal(nrf_drv_usbd_ep_t ep) +{ + USBD_ASSERT_EP_VALID(ep); + return (uint8_t)ep; +} + +/** + * @brief Generate start task number for selected endpoint index + * + * @param ep Endpoint number + * + * @return Task for starting EasyDMA transfer on selected endpoint. + */ +static inline nrf_usbd_task_t task_start_ep(nrf_drv_usbd_ep_t ep) +{ + USBD_ASSERT_EP_VALID(ep); + return (nrf_usbd_task_t)( + (NRF_USBD_EPIN_CHECK(ep) ? NRF_USBD_TASK_STARTEPIN0 : NRF_USBD_TASK_STARTEPOUT0) + + (NRF_USBD_EP_NR_GET(ep) * sizeof(uint32_t))); +} + +/** + * @brief Access selected endpoint state structure + * + * Function used to change or just read the state of selected endpoint. + * It is used for internal transmission state. + * + * @param ep Endpoint number + */ +static inline usbd_drv_ep_state_t* ep_state_access(nrf_drv_usbd_ep_t ep) +{ + USBD_ASSERT_EP_VALID(ep); + return ((NRF_USBD_EPIN_CHECK(ep) ? m_ep_state.ep_in : m_ep_state.ep_out) + + NRF_USBD_EP_NR_GET(ep)); +} + +/** + * @brief Change endpoint number to bit position + * + * Bit positions are defined the same way as they are placed in DATAEPSTATUS register, + * but bits for endpoint 0 are included. + * + * @param ep Endpoint number + * + * @return Bit position related to the given endpoint number + * + * @sa bit2ep + */ +static inline uint8_t ep2bit(nrf_drv_usbd_ep_t ep) +{ + USBD_ASSERT_EP_VALID(ep); + return USBD_EP_BITPOS(ep); +} + +/** + * @brief Change bit position to endpoint number + * + * @param bitpos Bit position + * + * @return Endpoint number corresponding to given bit position. + * + * @sa ep2bit + */ +static inline nrf_drv_usbd_ep_t bit2ep(uint8_t bitpos) +{ + STATIC_ASSERT(USBD_EPOUT_BITPOS_0 > USBD_EPIN_BITPOS_0); + return (nrf_drv_usbd_ep_t)((bitpos >= USBD_EPOUT_BITPOS_0) ? + NRF_USBD_EPOUT(bitpos - USBD_EPOUT_BITPOS_0) : NRF_USBD_EPIN(bitpos)); +} + +/** + * @brief Start selected EasyDMA transmission + * + * This is internal auxiliary function. + * No checking is made if EasyDMA is ready for new transmission. + * + * @param[in] ep Number of endpoint for transmission. + * If it is OUT endpoint transmission would be directed from endpoint to RAM. + * If it is in endpoint transmission would be directed from RAM to endpoint. + */ +static inline void usbd_dma_start(nrf_drv_usbd_ep_t ep) +{ + nrf_usbd_task_trigger(task_start_ep(ep)); +} + +/** + * @brief Abort pending transfer on selected endpoint + * + * @param ep Endpoint number. + * + * @note + * This function locks interrupts that may be costly. + * It is good idea to test if the endpoint is still busy before calling this function: + * @code + (m_ep_dma_waiting & (1U << ep2bit(ep))) + * @endcode + * This function would check it again, but it makes it inside critical section. + */ +static inline void usbd_ep_abort(nrf_drv_usbd_ep_t ep) +{ + CRITICAL_REGION_ENTER(); + + usbd_drv_ep_state_t * p_state = ep_state_access(ep); + + if (NRF_USBD_EPOUT_CHECK(ep)) + { + /* Host -> Device */ + if ((~m_ep_dma_waiting) & (1U<handler.consumer = NULL; + m_ep_dma_waiting &= ~(1U<status = NRF_USBD_EP_ABORTED; + } + else + { + if ((m_ep_dma_waiting | (~m_ep_ready)) & (1U< Host */ + m_ep_dma_waiting &= ~(1U<handler.feeder = NULL; + p_state->status = NRF_USBD_EP_ABORTED; + NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_ABORTED); + m_event_handler(&evt); + } + } + CRITICAL_REGION_EXIT(); +} + +void usbd_drv_ep_abort(nrf_drv_usbd_ep_t ep) +{ + usbd_ep_abort(ep); +} + + +/** + * @brief Abort all pending endpoints + * + * Function aborts all pending endpoint transfers. + */ +static void usbd_ep_abort_all(void) +{ + uint32_t ep_waiting = m_ep_dma_waiting | (m_ep_ready & USBD_EPOUT_BIT_MASK); + while (0 != ep_waiting) + { + uint8_t bitpos = __CLZ(__RBIT(ep_waiting)); + usbd_ep_abort(bit2ep(bitpos)); + ep_waiting &= ~(1U << bitpos); + } + + m_ep_ready = (((1U<status) + { + /* Nothing to do - just ignore */ + } + else if (p_state->handler.feeder == NULL) + { + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U< 0); + m_dma_pending = 0; + + usbd_drv_ep_state_t * p_state = ep_state_access(ep); + if (NRF_USBD_EP_ABORTED == p_state->status) + { + /* Nothing to do - just ignore */ + } + else if (p_state->handler.feeder == NULL) + { + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<status) + { + /* Nothing to do - just ignore */ + } + else if (p_state->handler.feeder == NULL) + { + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<status) + { + /* Nothing to do - just ignore */ + } + else if (p_state->handler.consumer == NULL) + { + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U< 0); + m_dma_pending = 0; + + nrf_usbd_epout_clear(ep); + + usbd_drv_ep_state_t * p_state = ep_state_access(ep); + if (NRF_USBD_EP_ABORTED == p_state->status) + { + /* Nothing to do - just ignore */ + } + else if (p_state->handler.consumer == NULL) + { + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<status) + { + /* Nothing to do - just ignore */ + } + else if (p_state->handler.consumer == NULL) + { + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U< Host) */ + if (0 == (m_ep_dma_waiting & (1U< Device) */ + if (0 == (m_ep_dma_waiting & (1U<handler.feeder) != NULL); + + if (NRF_USBD_EPIN_CHECK(ep)) + { + /* Device -> Host */ + continue_transfer = p_state->handler.feeder( + &transfer, + p_state->p_context, + p_state->max_packet_size); + + if (!continue_transfer) + { + p_state->handler.feeder = NULL; + if (ep == NRF_DRV_USBD_EPIN0) + { + /** Configure short right now - now if the last data is transferred, + * when host tries another data transfer, the endpoint will stall. */ + NRF_LOG_DEBUG("USB DMA process: Enable status short\r\n"); + nrf_usbd_shorts_enable(NRF_USBD_SHORT_EP0DATADONE_EP0STATUS_MASK); + } + } + } + else + { + /* Host -> Device */ + const size_t rx_size = nrf_drv_usbd_epout_size_get(ep); + continue_transfer = p_state->handler.consumer( + &transfer, + p_state->p_context, + p_state->max_packet_size, + rx_size); + + if (transfer.p_data.rx == NULL) + { + /* Dropping transfer - allow processing */ + ASSERT(transfer.size == 0); + } + else if (transfer.size < rx_size) + { + p_state->status = NRF_USBD_EP_OVERLOAD; + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<handler.consumer = NULL; + } + ASSERT(transfer.size == rx_size); + } + + m_dma_pending = 1; + m_ep_ready &= ~(1U << pos); + if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) + { + NRF_LOG_DEBUG( + "USB DMA process: Starting transfer on EP: %x, size: %u\r\n", + ep, + transfer.size); + } + /* Update number of currently transferred bytes */ + p_state->transfer_cnt += transfer.size; + /* Start transfer to the endpoint buffer */ + nrf_usbd_ep_easydma_set(ep, transfer.p_data.ptr, (uint32_t)transfer.size); + +#if NRF_DRV_USBD_PROTO1_FIX + uint32_t cnt_end = (uint32_t)(-1); + do + { + uint32_t cnt = (uint32_t)(-1); + do + { + nrf_usbd_event_clear(NRF_USBD_EVENT_STARTED); + usbd_dma_start(ep); + nrf_drv_systick_delay_us(2); + ++cnt; + }while (!nrf_usbd_event_check(NRF_USBD_EVENT_STARTED)); + if (cnt) + { + NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" DMA restarted: %u times\r\n", cnt); + } + + nrf_drv_systick_delay_us(20); + while (0 == (0x20 & *((volatile uint32_t *)(NRF_USBD_BASE + 0x474)))) + { + nrf_drv_systick_delay_us(2); + } + nrf_drv_systick_delay_us(1); + + ++cnt_end; + } while (!nrf_usbd_event_check(nrf_drv_usbd_ep_to_endevent(ep))); + if (cnt_end) + { + NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" DMA fully restarted: %u times\r\n", cnt_end); + } +#else + usbd_dma_start(ep); +#endif + if (NRF_USBD_DMAREQ_PROCESS_DEBUG) + { + NRF_LOG_DEBUG("USB DMA process - finishing\r\n"); + } + /* Transfer started - exit the loop */ + break; + } + } + else + { + if (NRF_USBD_DMAREQ_PROCESS_DEBUG) + { + NRF_LOG_DEBUG("USB DMA process - EasyDMA busy\r\n"); + } + } +} +/** @} */ + +typedef void (*nrf_drv_usbd_isr_t)(void); + +/** + * @brief USBD interrupt service runtimes + * + */ +static const nrf_drv_usbd_isr_t m_isr[] = +{ + [USBD_INTEN_USBRESET_Pos ] = USBD_ISR_Usbreset, + [USBD_INTEN_STARTED_Pos ] = USBD_ISR_Started, + [USBD_INTEN_ENDEPIN0_Pos ] = USBD_ISR_dma_epin0, + [USBD_INTEN_ENDEPIN1_Pos ] = USBD_ISR_dma_epin1, + [USBD_INTEN_ENDEPIN2_Pos ] = USBD_ISR_dma_epin2, + [USBD_INTEN_ENDEPIN3_Pos ] = USBD_ISR_dma_epin3, + [USBD_INTEN_ENDEPIN4_Pos ] = USBD_ISR_dma_epin4, + [USBD_INTEN_ENDEPIN5_Pos ] = USBD_ISR_dma_epin5, + [USBD_INTEN_ENDEPIN6_Pos ] = USBD_ISR_dma_epin6, + [USBD_INTEN_ENDEPIN7_Pos ] = USBD_ISR_dma_epin7, + [USBD_INTEN_EP0DATADONE_Pos] = USBD_ISR_SetupData, + [USBD_INTEN_ENDISOIN_Pos ] = USBD_ISR_dma_epin8, + [USBD_INTEN_ENDEPOUT0_Pos ] = USBD_ISR_dma_epout0, + [USBD_INTEN_ENDEPOUT1_Pos ] = USBD_ISR_dma_epout1, + [USBD_INTEN_ENDEPOUT2_Pos ] = USBD_ISR_dma_epout2, + [USBD_INTEN_ENDEPOUT3_Pos ] = USBD_ISR_dma_epout3, + [USBD_INTEN_ENDEPOUT4_Pos ] = USBD_ISR_dma_epout4, + [USBD_INTEN_ENDEPOUT5_Pos ] = USBD_ISR_dma_epout5, + [USBD_INTEN_ENDEPOUT6_Pos ] = USBD_ISR_dma_epout6, + [USBD_INTEN_ENDEPOUT7_Pos ] = USBD_ISR_dma_epout7, + [USBD_INTEN_ENDISOOUT_Pos ] = USBD_ISR_dma_epout8, + [USBD_INTEN_SOF_Pos ] = USBD_ISR_Sof, + [USBD_INTEN_USBEVENT_Pos ] = USBD_ISR_Event, + [USBD_INTEN_EP0SETUP_Pos ] = USBD_ISR_Setup, + [USBD_INTEN_EPDATA_Pos ] = USBD_ISR_EpDataStatus, + [USBD_INTEN_ACCESSFAULT_Pos] = USBD_ISR_AccessFault +}; + +/** + * @name Interrupt handlers + * + * @{ + */ +void USBD_IRQHandler(void) +{ + const uint32_t enabled = nrf_usbd_int_enable_get(); + uint32_t to_process = enabled; + uint32_t active = 0; + + /* Check all enabled interrupts */ + while (to_process) + { + uint8_t event_nr = __CLZ(__RBIT(to_process)); + if (nrf_usbd_event_get_and_clear((nrf_usbd_event_t)nrf_drv_bitpos_to_event(event_nr))) + { + active |= 1UL << event_nr; + } + to_process &= ~(1UL << event_nr); + } + +#if NRF_DRV_USBD_PROTO1_FIX + /* Event correcting */ + if ((0 == m_dma_pending) && (0 != (active & (USBD_INTEN_SOF_Msk)))) + { + uint8_t usbi, uoi, uii; + /* Testing */ + *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9; + uii = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + if (0 != uii) + { + uii &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + } + + *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AA; + uoi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + if (0 != uoi) + { + uoi &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + } + *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AB; + usbi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + if (0 != usbi) + { + usbi &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + } + /* Processing */ + *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AC; + uii &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); + if (0 != uii) + { + uint8_t rb; + m_simulated_dataepstatus |= ((uint32_t)uii)<status = NRF_USBD_EP_OK; + p_state->handler.feeder = NULL; + p_state->transfer_cnt = 0; + } + for (n=0; nstatus = NRF_USBD_EP_OK; + p_state->handler.consumer = NULL; + p_state->transfer_cnt = 0; + } + + return NRF_SUCCESS; +} + +ret_code_t nrf_drv_usbd_uninit(void) +{ + if (m_drv_state != NRF_DRV_STATE_INITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + + nrf_drv_clock_hfclk_release(); + m_event_handler = NULL; + m_drv_state = NRF_DRV_STATE_UNINITIALIZED; + return NRF_SUCCESS; +} + +void nrf_drv_usbd_enable(void) +{ + ASSERT(m_drv_state == NRF_DRV_STATE_INITIALIZED); + + /* Prepare for READY event receiving */ + nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK); + /* Enable the peripheral */ + nrf_usbd_enable(); + /* Waiting for peripheral to enable, this should take a few us */ + while (0 == (NRF_USBD_EVENTCAUSE_READY_MASK & nrf_usbd_eventcause_get())) + { + /* Empty loop */ + } + nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK); + + nrf_usbd_isosplit_set(NRF_USBD_ISOSPLIT_Half); + + m_ep_ready = (((1U<= NRF_DRV_STATE_INITIALIZED); +} + +bool nrf_drv_usbd_is_enabled(void) +{ + return (m_drv_state >= NRF_DRV_STATE_POWERED_ON); +} + +bool nrf_drv_usbd_is_started(void) +{ + return (nrf_drv_usbd_is_enabled() && nrf_drv_common_irq_enable_check(USBD_IRQn)); +} + +void nrf_drv_usbd_ep_max_packet_size_set(nrf_drv_usbd_ep_t ep, uint16_t size) +{ + /* Only power of 2 size allowed */ + ASSERT((size != 0) && (size & (size - 1)) == 0); + /* Packet size cannot be higher than maximum buffer size */ + ASSERT( ( NRF_USBD_EPISO_CHECK(ep) && (size <= usbd_ep_iso_capacity(ep))) + || + ((!NRF_USBD_EPISO_CHECK(ep)) && (size <= NRF_DRV_USBD_EPSIZE))); + + usbd_drv_ep_state_t * p_state = ep_state_access(ep); + p_state->max_packet_size = size; +} + +uint16_t nrf_drv_usbd_ep_max_packet_size_get(nrf_drv_usbd_ep_t ep) +{ + usbd_drv_ep_state_t const * p_state = ep_state_access(ep); + return p_state->max_packet_size; +} + +bool nrf_drv_usbd_ep_enable_check(nrf_drv_usbd_ep_t ep) +{ + return nrf_usbd_ep_enable_check(ep_to_hal(ep)); +} + +void nrf_drv_usbd_ep_enable(nrf_drv_usbd_ep_t ep) +{ + nrf_usbd_ep_enable(ep_to_hal(ep)); + nrf_usbd_int_enable(nrf_drv_usbd_ep_to_int(ep)); + + if ((NRF_USBD_EP_NR_GET(ep) != 0) && NRF_USBD_EPOUT_CHECK(ep)) + { + CRITICAL_REGION_ENTER(); + + m_ep_ready |= 1U<status = NRF_USBD_EP_ABORTED; + + CRITICAL_REGION_EXIT(); + } +} + +void nrf_drv_usbd_ep_disable(nrf_drv_usbd_ep_t ep) +{ + nrf_usbd_ep_disable(ep_to_hal(ep)); + nrf_usbd_int_disable(nrf_drv_usbd_ep_to_int(ep)); +} + +ret_code_t nrf_drv_usbd_ep_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_transfer_t const * const p_transfer) +{ + ret_code_t ret; + const uint8_t ep_bitpos = ep2bit(ep); + ASSERT(NULL != p_transfer); + + CRITICAL_REGION_ENTER(); + /* Setup data transaction can go only in one direction at a time */ + if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir)) + { + ret = NRF_ERROR_INVALID_ADDR; + if (NRF_USBD_FAILED_TRANSFERS_DEBUG) + { + NRF_LOG_DEBUG("USB driver: Transfer failed: Invalid EPr\n"); + } + } + else if ((m_ep_dma_waiting | ((~m_ep_ready) & USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos)) + { + /* IN (Device -> Host) transfer has to be transmitted out to allow new transmission */ + ret = NRF_ERROR_BUSY; + if (NRF_USBD_FAILED_TRANSFERS_DEBUG) + { + NRF_LOG_DEBUG("USB driver: Transfer failed: EP is busy\r\n");\ + } + } + else if (nrf_usbd_ep_is_stall(ep)) + { + ret = NRF_ERROR_FORBIDDEN; + if (NRF_USBD_FAILED_TRANSFERS_DEBUG) + { + NRF_LOG_DEBUG("USB driver: Transfer failed: EP is stalled\r\n"); + } + } + else + { + usbd_drv_ep_state_t * p_state = ep_state_access(ep); + /* Prepare transfer context and handler description */ + nrf_drv_usbd_transfer_t * p_context; + if (NRF_USBD_EPIN_CHECK(ep)) + { + p_context = m_ep_feeder_state + NRF_USBD_EP_NR_GET(ep); + if (nrf_drv_is_in_RAM(p_transfer->p_data.tx)) + { + /* RAM */ + if (0 == (p_transfer->flags & NRF_DRV_USBD_TRANSFER_ZLP_FLAG)) + { + p_state->handler.feeder = nrf_drv_usbd_feeder_ram; + if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) + { + NRF_LOG_DEBUG( + "USB driver: Transfer called on endpoint %x, size: %u, mode: " + "RAM\r\n", + ep, + p_transfer->size); + } + } + else + { + p_state->handler.feeder = nrf_drv_usbd_feeder_ram_zlp; + if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) + { + NRF_LOG_DEBUG( + "USB driver: Transfer called on endpoint %x, size: %u, mode: " + "RAM_ZLP\r\n", + ep, + p_transfer->size); + } + } + } + else + { + /* Flash */ + if (0 == (p_transfer->flags & NRF_DRV_USBD_TRANSFER_ZLP_FLAG)) + { + p_state->handler.feeder = nrf_drv_usbd_feeder_flash; + if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) + { + NRF_LOG_DEBUG( + "USB driver: Transfer called on endpoint %x, size: %u, mode: " + "FLASH\r\n", + ep, + p_transfer->size); + } + } + else + { + p_state->handler.feeder = nrf_drv_usbd_feeder_flash_zlp; + if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) + { + NRF_LOG_DEBUG( + "USB driver: Transfer called on endpoint %x, size: %u, mode: " + "FLASH_ZLP\r\n", + ep, + p_transfer->size); + } + } + } + } + else + { + p_context = m_ep_consumer_state + NRF_USBD_EP_NR_GET(ep); + ASSERT((p_transfer->p_data.rx == NULL) || (nrf_drv_is_in_RAM(p_transfer->p_data.rx))); + p_state->handler.consumer = nrf_drv_usbd_consumer; + } + *p_context = *p_transfer; + p_state->p_context = p_context; + + p_state->transfer_cnt = 0; + p_state->status = NRF_USBD_EP_OK; + m_ep_dma_waiting |= 1U << ep_bitpos; + ret = NRF_SUCCESS; + usbd_int_rise(); + } + CRITICAL_REGION_EXIT(); + return ret; +} + +ret_code_t nrf_drv_usbd_ep_handled_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_handler_desc_t const * const p_handler) +{ + ret_code_t ret; + const uint8_t ep_bitpos = ep2bit(ep); + ASSERT(NULL != p_handler); + + CRITICAL_REGION_ENTER(); + /* Setup data transaction can go only in one direction at a time */ + if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir)) + { + ret = NRF_ERROR_INVALID_ADDR; + if (NRF_USBD_FAILED_TRANSFERS_DEBUG) + { + NRF_LOG_DEBUG("USB driver: Transfer failed: Invalid EPr\n"); + } + } + else if ((m_ep_dma_waiting | ((~m_ep_ready) & USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos)) + { + /* IN (Device -> Host) transfer has to be transmitted out to allow a new transmission */ + ret = NRF_ERROR_BUSY; + if (NRF_USBD_FAILED_TRANSFERS_DEBUG) + { + NRF_LOG_DEBUG("USB driver: Transfer failed: EP is busy\r\n");\ + } + } + else if (nrf_usbd_ep_is_stall(ep)) + { + ret = NRF_ERROR_FORBIDDEN; + if (NRF_USBD_FAILED_TRANSFERS_DEBUG) + { + NRF_LOG_DEBUG("USB driver: Transfer failed: EP is stalled\r\n"); + } + } + else + { + /* Transfer can be configured now */ + usbd_drv_ep_state_t * p_state = ep_state_access(ep); + + p_state->transfer_cnt = 0; + p_state->handler = p_handler->handler; + p_state->p_context = p_handler->p_context; + p_state->status = NRF_USBD_EP_OK; + m_ep_dma_waiting |= 1U << ep_bitpos; + + ret = NRF_SUCCESS; + if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))) + { + NRF_LOG_DEBUG("USB driver: Transfer called on endpoint %x, mode: Handler\r\n", ep); + } + usbd_int_rise(); + } + CRITICAL_REGION_EXIT(); + return ret; +} + +void * nrf_drv_usbd_feeder_buffer_get(void) +{ + return m_tx_buffer; +} + +ret_code_t nrf_drv_usbd_ep_status_get(nrf_drv_usbd_ep_t ep, size_t * p_size) +{ + ret_code_t ret; + + usbd_drv_ep_state_t const * p_state = ep_state_access(ep); + CRITICAL_REGION_ENTER(); + *p_size = p_state->transfer_cnt; + ret = (p_state->handler.consumer == NULL) ? p_state->status : NRF_ERROR_BUSY; + CRITICAL_REGION_EXIT(); + return ret; +} + +size_t nrf_drv_usbd_epout_size_get(nrf_drv_usbd_ep_t ep) +{ + return nrf_usbd_epout_size_get(ep_to_hal(ep)); +} + +bool nrf_drv_usbd_ep_is_busy(nrf_drv_usbd_ep_t ep) +{ + return (0 != (m_ep_dma_waiting & (1UL << ep2bit(ep)))); +} + +void nrf_drv_usbd_ep_stall(nrf_drv_usbd_ep_t ep) +{ + NRF_LOG_DEBUG("USB: EP %x stalled.\r\n", ep); + nrf_usbd_ep_stall(ep_to_hal(ep)); +} + +void nrf_drv_usbd_ep_stall_clear(nrf_drv_usbd_ep_t ep) +{ + nrf_usbd_ep_unstall(ep_to_hal(ep)); +} + +bool nrf_drv_usbd_ep_stall_check(nrf_drv_usbd_ep_t ep) +{ + return nrf_usbd_ep_is_stall(ep_to_hal(ep)); +} + +void nrf_drv_usbd_setup_get(nrf_drv_usbd_setup_t * const p_setup) +{ + memset(p_setup, 0, sizeof(nrf_drv_usbd_setup_t)); + p_setup->bmRequestType = nrf_usbd_setup_bmrequesttype_get(); + p_setup->bmRequest = nrf_usbd_setup_brequest_get(); + p_setup->wValue = nrf_usbd_setup_wvalue_get(); + p_setup->wIndex = nrf_usbd_setup_windex_get(); + p_setup->wLength = nrf_usbd_setup_wlength_get(); +} + +void nrf_drv_usbd_setup_data_clear(void) +{ +#if NRF_DRV_USBD_PROTO1_FIX + /* For this fix to work properly, it must be ensured that the task is + * executed twice one after another - blocking ISR. This is however a temporary + * solution to be used only before production typeout. */ + uint32_t primask_copy = __get_PRIMASK(); + __disable_irq(); + nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT); + nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT); + __set_PRIMASK(primask_copy); +#else + nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT); +#endif +} + +void nrf_drv_usbd_setup_clear(void) +{ + nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STATUS); +} + +void nrf_drv_usbd_setup_stall(void) +{ + NRF_LOG_DEBUG("Setup stalled.\r\n"); + nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STALL); +} + +nrf_drv_usbd_ep_t nrf_drv_usbd_last_setup_dir_get(void) +{ + return m_last_setup_dir; +} + +void nrf_drv_usbd_transfer_out_drop(nrf_drv_usbd_ep_t ep) +{ + ASSERT(NRF_USBD_EPOUT_CHECK(ep)); + + if (m_ep_ready & (1U << ep2bit(ep))) + { + if (!NRF_USBD_EPISO_CHECK(ep)) + { + ret_code_t ret; + NRF_DRV_USBD_TRANSFER_OUT(transfer, 0, 0); + ret = nrf_drv_usbd_ep_transfer(ep, &transfer); + ASSERT(ret == NRF_SUCCESS); + UNUSED_VARIABLE(ret); + } + } +} + +#endif // USBD_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/usbd/nrf_drv_usbd.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/usbd/nrf_drv_usbd.h new file mode 100644 index 0000000000000000000000000000000000000000..b622cb4b7f49f51cdfef748548a850ef57096fb5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/usbd/nrf_drv_usbd.h @@ -0,0 +1,834 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef NRF_DRV_USBD_H__ +#define NRF_DRV_USBD_H__ + +#include "nrf_drv_common.h" +#include "sdk_errors.h" +#include "nrf_usbd.h" +#include +#include +#include "app_util.h" +/** + * @defgroup nrf_drv_usbd USB Device raw IP HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52840 USB Device APIs. + * @details The USB Device HAL provides basic APIs for accessing + * the registers of the USBD. + * The USB Device driver provides APIs on a higher level. + */ + +/** + * @ingroup nrf_drv_usbd + * @defgroup nrf_usbdraw_drv USB Device raw IP driver + * + * @brief @tagAPI52840 USB Device raw IP driver. + * @{ + */ + +/** + * @name Possible schemes of DMA scheduling + * + * Definition of available configuration constants used by DMA scheduler + * @{ + */ + /** + * @brief Highly prioritized access + * + * Endpoint with lower number has always higher priority and its data would + * be transfered first. + * OUT endpoints ale processed before IN endpoints + */ + #define NRF_DRV_USBD_DMASCHEDULER_PRIORITIZED 0 + + /** + * @brief Round robin scheme + * + * All endpoints are processed in round-robin scheme. + * It means that when one endpoint is processed next in order would be + * the nearest with lower number. + * When no endpoints with lower number requires processing - then + * all endpoints from 0 are tested. + */ + #define NRF_DRV_USBD_DMASCHEDULER_ROUNDROBIN 1 + +/** @} */ + +/** + * @brief Number of bytes in the endpoint + * + * Constant that informs about endpoint size + */ +#define NRF_DRV_USBD_EPSIZE 64 + +/** + * @brief Number of bytes for isochronous endpoints + * + * Number of bytes for isochronous endpoints in total. + * This number would be shared between IN and OUT endpoint. + * It may be also assigned totaly to one endpoint. + * @sa nrf_usbd_isosplit_set + * @sa nrf_usbd_isosplit_get + */ +#define NRF_DRV_USBD_ISOSIZE 1024 + +/** + * @brief The size of internal feeder buffer. + * + * @sa nrf_drv_usbd_feeder_buffer_get + */ +#define NRF_DRV_USBD_FEEDER_BUFFER_SIZE NRF_DRV_USBD_EPSIZE + +/** + * @name Macros for creating endpoint identifiers + * + * Auxiliary macros to be used to create Endpoint identifier that is compatible + * with USB specification. + * @{ + */ + + /** + * @brief Create identifier for IN endpoint + * + * Simple macro to create IN endpoint identifier for given endpoint number. + * + * @param[in] n Endpoint number. + * + * @return Endpoint identifier that connects endpoint number and endpoint direction. + */ + #define NRF_DRV_USBD_EPIN(n) ((nrf_drv_usbd_ep_t)NRF_USBD_EPIN(n)) + /** + * @brief Create identifier for OUT endpoint + * + * Simple macro to create OUT endpoint identifier for given endpoint number. + * + * @param[in] n Endpoint number. + * + * @return Endpoint identifier that connects endpoint number and endpoint direction. + */ + #define NRF_DRV_USBD_EPOUT(n) ((nrf_drv_usbd_ep_t)NRF_USBD_EPOUT(n)) + +/** @} */ + +/** + * @brief Endpoint identifier + * + * Endpoint identifier used in the driver. + * This endpoint number is consistent with USB 2.0 specification. + */ +typedef enum +{ + NRF_DRV_USBD_EPOUT0 = NRF_USBD_EPOUT(0), /**< Endpoint OUT 0 */ + NRF_DRV_USBD_EPOUT1 = NRF_USBD_EPOUT(1), /**< Endpoint OUT 1 */ + NRF_DRV_USBD_EPOUT2 = NRF_USBD_EPOUT(2), /**< Endpoint OUT 2 */ + NRF_DRV_USBD_EPOUT3 = NRF_USBD_EPOUT(3), /**< Endpoint OUT 3 */ + NRF_DRV_USBD_EPOUT4 = NRF_USBD_EPOUT(4), /**< Endpoint OUT 4 */ + NRF_DRV_USBD_EPOUT5 = NRF_USBD_EPOUT(5), /**< Endpoint OUT 5 */ + NRF_DRV_USBD_EPOUT6 = NRF_USBD_EPOUT(6), /**< Endpoint OUT 6 */ + NRF_DRV_USBD_EPOUT7 = NRF_USBD_EPOUT(7), /**< Endpoint OUT 7 */ + NRF_DRV_USBD_EPOUT8 = NRF_USBD_EPOUT(8), /**< Endpoint OUT 8 */ + + NRF_DRV_USBD_EPIN0 = NRF_USBD_EPIN(0), /**< Endpoint IN 0 */ + NRF_DRV_USBD_EPIN1 = NRF_USBD_EPIN(1), /**< Endpoint IN 1 */ + NRF_DRV_USBD_EPIN2 = NRF_USBD_EPIN(2), /**< Endpoint IN 2 */ + NRF_DRV_USBD_EPIN3 = NRF_USBD_EPIN(3), /**< Endpoint IN 3 */ + NRF_DRV_USBD_EPIN4 = NRF_USBD_EPIN(4), /**< Endpoint IN 4 */ + NRF_DRV_USBD_EPIN5 = NRF_USBD_EPIN(5), /**< Endpoint IN 5 */ + NRF_DRV_USBD_EPIN6 = NRF_USBD_EPIN(6), /**< Endpoint IN 6 */ + NRF_DRV_USBD_EPIN7 = NRF_USBD_EPIN(7), /**< Endpoint IN 7 */ + NRF_DRV_USBD_EPIN8 = NRF_USBD_EPIN(8), /**< Endpoint IN 8 */ +}nrf_drv_usbd_ep_t; + +/** + * @brief Events generated by the library + * + * Enumeration of possible events that may be generated by the library. + */ +typedef enum +{ + NRF_DRV_USBD_EVT_SOF, /**< Start Of Frame event on USB bus detected */ + NRF_DRV_USBD_EVT_RESET, /**< Reset condition on USB bus detected */ + NRF_DRV_USBD_EVT_SUSPEND, /**< This device should go to suspend mode now */ + NRF_DRV_USBD_EVT_RESUME, /**< This device should resume from suspend now */ + NRF_DRV_USBD_EVT_SETUP, /**< Setup frame received and decoded */ + NRF_DRV_USBD_EVT_EPTRANSFER, /**< + * For Rx (OUT: Host->Device): + * 1. The packet has been received but there is no buffer prepared for transfer already. + * 2. Whole transfer has been finished + * + * For Tx (IN: Device->Host): + * The last packet from requested transfer has been transfered over USB bus and acknowledged + */ + NRF_DRV_USBD_EVT_CNT /**< Number of defined events */ +}nrf_drv_usbd_event_type_t; + +/** + * @brief Possible endpoint error codes + * + * Error codes that may be returned with @ref NRF_DRV_USBD_EVT_EPTRANSFER + */ +typedef enum +{ + NRF_USBD_EP_OK, /**< No error */ + NRF_USBD_EP_WAITING, /**< Data received, no buffer prepared already - waiting for configured transfer */ + NRF_USBD_EP_OVERLOAD, /**< Received number of bytes cannot fit given buffer + * This error would also be returned when next_transfer function has been defined + * but currently received data cannot fit completely in current buffer. + * No data split from single endpoint transmission is supported. + * + * When this error is reported - data is left inside endpoint buffer. + * Clear endpoint or prepare new buffer and read it. + */ + NRF_USBD_EP_ABORTED, /**< EP0 transfer can be aborted when new setup comes. + * Any other transfer can be aborted by USB reset or library stopping. + */ +}nrf_drv_usbd_ep_status_t; + + +/** + * @brief Event structure + * + * Structure passed to event handler + */ +typedef struct +{ + nrf_drv_usbd_event_type_t type; + union + { + struct{ + uint16_t framecnt; //!< Current value of frame counter + }sof; //!< Data aviable for @ref NRF_DRV_USBD_EVT_SOF + struct{ + nrf_drv_usbd_ep_t ep; //!< Endpoint number + }isocrc; + struct{ + nrf_drv_usbd_ep_t ep; //!< Endpoint number + nrf_drv_usbd_ep_status_t status; //!< Status for the endpoint + }eptransfer; + }data; +}nrf_drv_usbd_evt_t; + +/** + * @brief USBD event callback function type. + * + * @param[in] p_event Event information structure. + */ +typedef void (*nrf_drv_usbd_event_handler_t)(nrf_drv_usbd_evt_t const * const p_event); + +/** + * @brief Universal data pointer. + * + * Universal data pointer that can be used for any type of transfer. + */ +typedef union +{ + void const * tx; //!< Constant TX buffer pointer. + void * rx; //!< Writable RX buffer pointer. + uint32_t ptr; //!< Numeric value used internally by the library. +}nrf_drv_usbd_data_ptr_t; + +/** + * @brief Structure to be filled with information about the next transfer. + * + * This is used mainly for transfer feeders and consumers. + * It describes a single endpoint transfer and therefore the size of the buffer + * can never be higher than the endpoint size. + */ +typedef struct +{ + nrf_drv_usbd_data_ptr_t p_data; //!< Union with available data pointers used by the library. + size_t size; //!< Size of the requested transfer. +}nrf_drv_usbd_ep_transfer_t; + +/** + * @brief Flags for the current transfer. + * + * Flags configured for the transfer that can be merged using the bitwise 'or' operator (|). + */ +typedef enum +{ + NRF_DRV_USBD_TRANSFER_ZLP_FLAG = 1U << 0, //!< Add a zero-length packet. +}nrf_drv_usbd_transfer_flags_t; + +/** + * @brief Total transfer configuration. + * + * This structure is used to configure total transfer information. + * It is used by internal built-in feeders and consumers. + */ +typedef struct +{ + nrf_drv_usbd_data_ptr_t p_data; //!< Union with available data pointers used by the library. + size_t size; //!< Total size of the requested transfer. + uint32_t flags; //!< Transfer flags. + /**< Use the @ref nrf_drv_usbd_transfer_flags_t values. */ +}nrf_drv_usbd_transfer_t; + + +/** + * @brief Auxiliary macro for declaring IN transfer description with flags. + * + * The base macro for creating transfers with any configuration option. + * + * @param name Instance name. + * @param tx_buff Buffer to transfer. + * @param tx_size Transfer size. + * @param tx_flags Flags for the transfer (see @ref nrf_drv_usbd_transfer_flags_t). + * + * @return Configured variable with total transfer description. + */ +#define NRF_DRV_USBD_TRANSFER_IN_FLAGS(name, tx_buff, tx_size, tx_flags) \ + const nrf_drv_usbd_transfer_t name = { \ + .p_data = { .tx = (tx_buff) }, \ + .size = (tx_size), \ + .flags = (tx_flags) \ + } + +/** + * @brief Helper macro for declaring IN transfer description + * + * Normal transfer mode, no ZLP would be automatically generated. + * + * @sa nrf_drv_usbd_transfer_t + * @sa NRF_DRV_USBD_TRANSFER_IN_ZLP + * + * @param name Instance name + * @param tx_buff Buffer to transfer + * @param tx_size Transfer size + * + * @return Configured variable with total transfer description + * + */ +#define NRF_DRV_USBD_TRANSFER_IN(name, tx_buff, tx_size) \ + NRF_DRV_USBD_TRANSFER_IN_FLAGS(name, tx_buff, tx_size, 0) + +/** + * @brief Helper macro for declaring IN transfer description + * + * ZLP mode - Zero Length Packet would be generated on the end of the transfer + * (always!). + * + * @sa nrf_drv_usbd_transfer_t + * @sa NRF_DRV_USBD_TRANSFER_IN + * + * @param name Instance name + * @param tx_buff Buffer to transfer + * @param tx_size Transfer size + * + * @return Configured variable with total transfer description + */ +#define NRF_DRV_USBD_TRANSFER_IN_ZLP(name, tx_buff, tx_size) \ + NRF_DRV_USBD_TRANSFER_IN_FLAGS( \ + name, \ + tx_buff, \ + tx_size, \ + NRF_DRV_USBD_TRANSFER_ZLP_FLAG) + +/** + * @brief Helper macro for declaring OUT transfer item (@ref nrf_drv_usbd_transfer_t) + * + * @param name Instance name + * @param rx_buff Buffer to transfer + * @param rx_size Transfer size + * */ +#define NRF_DRV_USBD_TRANSFER_OUT(name, rx_buff, rx_size) \ + const nrf_drv_usbd_transfer_t name = { \ + .p_data = { .rx = (rx_buff) }, \ + .size = (rx_size), \ + .flags = 0 \ + } + +/** + * @brief USBD transfer feeder. + * + * Pointer for a transfer feeder. + * Transfer feeder is a feedback function used to prepare a single + * TX (Device->Host) endpoint transfer. + * + * The transfers provided by the feeder must be simple: + * - The size of the transfer provided by this function is limited to a single endpoint buffer. + * Bigger transfers are not handled automatically in this case. + * - Flash transfers are not automatically supported- you must copy them to the RAM buffer before. + * + * @note + * This function may use @ref nrf_drv_usbd_feeder_buffer_get to gain a temporary buffer + * that can be used to prepare transfer. + * + * @param[out] p_next Structure with the data for the next transfer to be filled. + * Required only if the function returns true. + * @param[in,out] p_context Context variable configured with the transfer. + * @param[in] ep_size The endpoint size. + * + * @retval false The current transfer is the last one - you do not need to call + * the function again. + * @retval true There is more data to be prepared and when the current transfer + * finishes, the feeder function is expected to be called again. + */ +typedef bool (*nrf_drv_usbd_feeder_t)( + nrf_drv_usbd_ep_transfer_t * p_next, + void * p_context, + size_t ep_size); + +/** + * @brief USBD transfer consumer. + * + * Pointer for a transfer consumer. + * Transfer consumer is a feedback function used to prepare a single + * RX (Host->Device) endpoint transfer. + * + * The transfer must provide a buffer big enough to fit the whole data from the endpoint. + * Otherwise, the NRF_USBD_EP_OVERLOAD event is generated. + * + * @param[out] p_next Structure with the data for the next transfer to be filled. + * Required only if the function returns true. + * @param[in,out] p_context Context variable configured with the transfer. + * @param[in] ep_size The endpoint size. + * @param[in] data_size Number of received bytes in the endpoint buffer. + * + * @retval false Current transfer is the last one - you do not need to call + * the function again. + * @retval true There is more data to be prepared and when current transfer + * finishes, the feeder function is expected to be called again. + */ +typedef bool (*nrf_drv_usbd_consumer_t)( + nrf_drv_usbd_ep_transfer_t * p_next, + void * p_context, + size_t ep_size, + size_t data_size); + +/** + * @brief Universal transfer handler. + * + * Union with feeder and consumer function pointer. + */ +typedef union +{ + nrf_drv_usbd_feeder_t feeder; //!< Feeder function pointer. + nrf_drv_usbd_consumer_t consumer; //!< Consumer function pointer. +}nrf_drv_usbd_handler_t; + +/** + * @brief USBD transfer descriptor. + * + * Universal structure that may hold the setup for callback configuration for + * IN or OUT type of the transfer. + */ +typedef struct +{ + nrf_drv_usbd_handler_t handler; //!< Handler for the current transfer, function pointer. + void * p_context; //!< Context for the transfer handler. +}nrf_drv_usbd_handler_desc_t; + +/** + * @brief Setup packet structure + * + * Structure that contains interpreted SETUP packet. + */ +typedef struct +{ + uint8_t bmRequestType; //!< byte 0 + uint8_t bmRequest; //!< byte 1 + uint16_t wValue; //!< byte 2 + uint16_t wIndex; //!< byte 4, 5 + uint16_t wLength; //!< byte 6, 7 +}nrf_drv_usbd_setup_t; + +/** + * @brief Library initialization + * + * @param[in] event_handler Event handler provided by the user. + */ +ret_code_t nrf_drv_usbd_init(nrf_drv_usbd_event_handler_t const event_handler); + +/** + * @brief Library deinitialization + */ +ret_code_t nrf_drv_usbd_uninit(void); + +/** + * @brief Enable the USBD port + * + * After calling this function USBD peripheral would be enabled. + * It means that High Frequency clock would be requested and USB LDO would be enabled. + * + * In normal situation this function should be called in reaction to USBDETECTED + * event from POWER peripheral. + * + * Interrupts and USB pins pull-up would stay disabled until @ref nrf_drv_usbd_start + * function is called. + */ +void nrf_drv_usbd_enable(void); + +/** + * @brief Disable the USBD port + * + * After calling this function USBD peripheral would be disabled. + * No events would be detected or processed by the library. + * Clock for the peripheral would be disconnected. + */ +void nrf_drv_usbd_disable(void); + +/** + * @brief Start USB functionality + * + * After calling this function USBD peripheral should be fully functional + * and all new incoming events / interrupts would be processed by the library. + * + * Also only after calling this function host sees new connected device. + * + * Call this function when USBD power LDO regulator is ready - on USBPWRRDY event + * from POWER peripheral. + * + * @param enable_sof The flag that is used to enable SOF processing. + * If it is false, SOF interrupt is left disabled and will not be generated. + * This improves power saving if SOF is not required. + * + * @note If the isochronous endpoints are going to be used, + * it is required to enable the SOF. + * In other case any isochronous endpoint would stay busy + * after first transmission. + */ +void nrf_drv_usbd_start(bool enable_sof); + +/** + * @brief Stop USB functionality + * + * This function disables USBD pull-up and interrupts. + * + * @note + * This function can also be used to logically disconnect USB from the HOST that + * would force it to enumerate device after calling @ref nrf_drv_usbd_start. + */ +void nrf_drv_usbd_stop(void); + +/** + * @brief Check if driver is initialized + * + * @retval false Driver is not initialized + * @retval true Driver is initialized + */ +bool nrf_drv_usbd_is_initialized(void); + +/** + * @brief Check if driver is enabled + * + * @retval false Driver is disabled + * @retval true Driver is enabled + */ +bool nrf_drv_usbd_is_enabled(void); + +/** + * @brief Check if driver is started + * + * @retval false Driver is not started + * @retval true Driver is started (fully functional) + * @note The USBD peripheral interrupt state is checked + */ +bool nrf_drv_usbd_is_started(void); + +/** + * @brief Configure packet size that should be supported by the endpoint + * + * The real endpoint buffer size is always the same. + * This value sets max packet size that would be transmitted over the endpoint. + * This is required by the library + * + * @param[in] ep Endpoint number + * @param[in] size Required maximum packet size + * + * @note Endpoint size is always set to @ref NRF_DRV_USBD_EPSIZE or @ref NRF_DRV_USBD_ISOSIZE / 2 + * when @ref nrf_drv_usbd_ep_enable function is called. + */ +void nrf_drv_usbd_ep_max_packet_size_set(nrf_drv_usbd_ep_t ep, uint16_t size); + +/** + * @brief Get configured endpoint packet size + * + * Function to get configured endpoint size on the buffer. + * + * @param[in] ep Endpoint number + * + * @return Maximum pocket size configured on selected endpoint + */ +uint16_t nrf_drv_usbd_ep_max_packet_size_get(nrf_drv_usbd_ep_t ep); + +/** + * @brief Check if the selected endpoint is enabled. + * + * @param ep Endpoint number to check. + * + * @retval true Endpoint is enabled. + * @retval false Endpoint is disabled. + */ +bool nrf_drv_usbd_ep_enable_check(nrf_drv_usbd_ep_t ep); + +/** + * @brief Enable selected endpoint + * + * This function enables endpoint itself and its interrupts. + * @param ep Endpoint number to enable + * + * @note + * Max packet size is set to endpoint default maximum value. + * + * @sa nrf_drv_usbd_ep_max_packet_size_set + */ +void nrf_drv_usbd_ep_enable(nrf_drv_usbd_ep_t ep); + +/** + * @brief Disable selected endpoint + * + * This function disables endpoint itself and its interrupts. + * @param ep Endpoint number to disable + */ +void nrf_drv_usbd_ep_disable(nrf_drv_usbd_ep_t ep); + +/** + * @brief Start sending data over endpoint + * + * Function initializes endpoint transmission. + * This is asynchronous function - it finishes immediately after configuration + * for transmission is prepared. + * + * @note Data buffer pointed by p_data have to be kept active till + * @ref NRF_DRV_USBD_EVT_EPTRANSFER event is generated. + * + * @param[in] ep Endpoint number. + * For IN endpoint sending would be initiated. + * For OUT endpoint receiving would be initiated. + * @param[in] p_transfer + * + * @retval NRF_ERROR_BUSY Selected endpoint is pending. + * @retval NRF_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0. + * @retval NRF_ERROR_FORBIDDEN Endpoint stalled. + * @retval NRF_SUCCESS Transfer queued or started. + */ +ret_code_t nrf_drv_usbd_ep_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_transfer_t const * const p_transfer); + +/** + * @brief Start sending data over the endpoint using the transfer handler function. + * + * This function initializes an endpoint transmission. + * Just before data is transmitted, the transfer handler + * is called and it prepares a data chunk. + * + * @param[in] ep Endpoint number. + * For an IN endpoint, sending is initiated. + * For an OUT endpoint, receiving is initiated. + * @param p_handler Transfer handler - feeder for IN direction and consumer for + * OUT direction. + * + * @retval NRF_ERROR_BUSY Selected endpoint is pending. + * @retval NRF_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0. + * @retval NRF_ERROR_FORBIDDEN Endpoint stalled. + * @retval NRF_SUCCESS Transfer queued or started. + */ +ret_code_t nrf_drv_usbd_ep_handled_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_handler_desc_t const * const p_handler); + +/** + * @brief Get the temporary buffer to be used by the feeder. + * + * This buffer is used for TX transfers and it can be reused automatically + * when the transfer is finished. + * Use it for transfer preparation. + * + * May be used inside the feeder configured in @ref nrf_drv_usbd_ep_handled_transfer. + * + * @return Pointer to the buffer that can be used temporarily. + * + * @sa NRF_DRV_USBD_FEEDER_BUFFER_SIZE + */ +void * nrf_drv_usbd_feeder_buffer_get(void); + +/** + * @brief Get the information about last finished or current transfer + * + * Function returns the status of the last buffer set for transfer on selected endpoint. + * The status considers last buffer set by @ref nrf_drv_usbd_ep_transfer function or + * by transfer callback function. + * + * @param[in] ep Endpoint number. + * @param[out] p_size Information about the current/last transfer size. + * + * @retval NRF_SUCCESS Transfer already finished + * @retval NRF_ERROR_BUSY Ongoing transfer + * @retval NRF_ERROR_DATA_SIZE Too much of data received that cannot fit into buffer and cannot be splited into chunks. + * This may happen if buffer size is not a multiplication of endpoint buffer size. + */ +ret_code_t nrf_drv_usbd_ep_status_get(nrf_drv_usbd_ep_t ep, size_t * p_size); + +/** + * @brief Get number of received bytes + * + * Get the number of received bytes. + * The function behavior is undefined when called on IN endpoint. + * + * @param ep Endpoint number. + * + * @return Number of received bytes + */ +size_t nrf_drv_usbd_epout_size_get(nrf_drv_usbd_ep_t ep); + +/** + * @brief Check if endpoint buffer is ready or is under USB IP control + * + * Function to test if endpoint is busy. + * Endpoint that is busy cannot be accessed by MCU. + * It means that: + * - OUT (TX) endpoint: Last uploaded data is still in endpoint and is waiting + * to be received by the host. + * - IN (RX) endpoint: Endpoint is ready to receive data from the host + * and the endpoint does not have any data. + * When endpoint is not busy: + * - OUT (TX) endpoint: New data can be uploaded. + * - IN (RX) endpoint: New data can be downloaded using @ref nrf_drv_usbd_ep_transfer + * function. + */ +bool nrf_drv_usbd_ep_is_busy(nrf_drv_usbd_ep_t ep); + +/** + * @brief Stall endpoint + * + * Stall endpoit to send error information during next transfer request from + * the host. + * + * @note To stall endpoint it is safer to use @ref nrf_drv_usbd_setup_stall + * @note Stalled endpoint would not be cleared when DMA transfer finishes. + * + * @param ep Endpoint number to stall + * + */ +void nrf_drv_usbd_ep_stall(nrf_drv_usbd_ep_t ep); + +/** + * @brief Clear stall flag on endpoint + * + * This function clears endpoint that is stalled. + * @note + * If it is OUT endpoint (receiving) it would be also prepared for reception. + * It means that busy flag would be set. + * @note + * In endpoint (transmitting) would not be cleared - it gives possibility to + * write new data before transmitting. + */ +void nrf_drv_usbd_ep_stall_clear(nrf_drv_usbd_ep_t ep); + +/** + * @brief Check if endpoint is stalled + * + * This function gets stall state of selected endpoint + * + * @param ep Endpoint number to check + */ +bool nrf_drv_usbd_ep_stall_check(nrf_drv_usbd_ep_t ep); + +/** + * @brief Get parsed setup data + * + * Function fills the parsed setup data structure. + * + * @param[out] p_setup Pointer to data structure that would be filled by + * parsed data. + */ +void nrf_drv_usbd_setup_get(nrf_drv_usbd_setup_t * const p_setup); + +/** + * @brief Clear only for data transmission on setup endpoint + * + * This function may be called if any more data in control write transfer is expected. + * Clears only OUT endpoint to be able to take another OUT data token. + * It does not allow STATUS stage. + * @sa nrf_drv_usbd_setup_clear + */ +void nrf_drv_usbd_setup_data_clear(void); + +/** + * @brief Clear setup endpoint + * + * This function acknowledges setup when SETUP command was received and processed. + * It has to be called if no data respond for the SETUP command is sent. + * + * When there is any data transmission after SETUP command the data transmission + * itself would clear the endpoint. + */ +void nrf_drv_usbd_setup_clear(void); + +/** + * @brief Stall setup endpoint + * + * Mark and error on setup endpoint. + */ +void nrf_drv_usbd_setup_stall(void); + +/** +* @note +* This function locks interrupts that may be costly. +* It is good idea to test if the endpoint is still busy before calling this function: +* @code + (m_ep_dma_waiting & (1U << ep2bit(ep))) +* @endcode +* This function would check it again, but it makes it inside critical section. +*/ +void usbd_drv_ep_abort(nrf_drv_usbd_ep_t ep); + +/** + * @brief Get the information about expected transfer SETUP data direction + * + * Function returns the information about last expected transfer direction. + * + * @retval NRF_DRV_USBD_EPOUT0 Expecting OUT (Host->Device) direction or no data + * @retval NRF_DRV_USBD_EPIN0 Expecting IN (Device->Host) direction + */ +nrf_drv_usbd_ep_t nrf_drv_usbd_last_setup_dir_get(void); + +/** + * @brief Drop transfer on OUT endpoint + * + * @param[in] ep OUT endpoint ID + */ +void nrf_drv_usbd_transfer_out_drop(nrf_drv_usbd_ep_t ep); + +/** @} */ +#endif /* NRF_DRV_USBD_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/wdt/nrf_drv_wdt.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/wdt/nrf_drv_wdt.c new file mode 100644 index 0000000000000000000000000000000000000000..be5baaf61a1c39c6e43f4e613afed3f4fd149e16 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/wdt/nrf_drv_wdt.c @@ -0,0 +1,175 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(WDT) +#include "nrf_drv_wdt.h" +#include "nrf_drv_common.h" +#include "nrf_error.h" +#include "nrf_assert.h" +#include "nrf_wdt.h" +#include "app_util_platform.h" +#include +#include + +#define NRF_LOG_MODULE_NAME "WDT" + +#if WDT_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL WDT_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR WDT_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR WDT_CONFIG_DEBUG_COLOR +#else //WDT_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //WDT_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +/**@brief WDT event handler. */ +static nrf_wdt_event_handler_t m_wdt_event_handler; + +/**@brief WDT state. */ +static nrf_drv_state_t m_state; + +/**@brief WDT alloc table. */ +static uint32_t m_alloc_index; + +static const nrf_drv_wdt_config_t m_default_config = NRF_DRV_WDT_DEAFULT_CONFIG; + +/**@brief WDT interrupt handler. */ +void WDT_IRQHandler(void) +{ + if (nrf_wdt_int_enable_check(NRF_WDT_INT_TIMEOUT_MASK) == true) + { + nrf_wdt_event_clear(NRF_WDT_EVENT_TIMEOUT); + m_wdt_event_handler(); + } +} + + +ret_code_t nrf_drv_wdt_init(nrf_drv_wdt_config_t const * p_config, + nrf_wdt_event_handler_t wdt_event_handler) +{ + ASSERT(wdt_event_handler != NULL); + ret_code_t err_code; + m_wdt_event_handler = wdt_event_handler; + + if (m_state == NRF_DRV_STATE_UNINITIALIZED) + { + m_state = NRF_DRV_STATE_INITIALIZED; + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; + } + + if (p_config == NULL) + { + p_config = &m_default_config; + } + + nrf_wdt_behaviour_set(p_config->behaviour); + + + + + + + + nrf_wdt_reload_value_set((p_config->reload_value * 32768) / 1000); + + nrf_drv_common_irq_enable(WDT_IRQn, p_config->interrupt_priority); + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(err_code)); + return err_code; +} + + +void nrf_drv_wdt_enable(void) +{ + ASSERT(m_alloc_index != 0); + ASSERT(m_state == NRF_DRV_STATE_INITIALIZED); + nrf_wdt_int_enable(NRF_WDT_INT_TIMEOUT_MASK); + nrf_wdt_task_trigger(NRF_WDT_TASK_START); + m_state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Enabled.\r\n"); +} + + +void nrf_drv_wdt_feed(void) +{ + ASSERT(m_state == NRF_DRV_STATE_POWERED_ON); + for (uint32_t i = 0; i < m_alloc_index; i++) + { + nrf_wdt_reload_request_set((nrf_wdt_rr_register_t)(NRF_WDT_RR0 + i)); + } +} + +ret_code_t nrf_drv_wdt_channel_alloc(nrf_drv_wdt_channel_id * p_channel_id) +{ + ret_code_t result; + ASSERT(p_channel_id); + ASSERT(m_state == NRF_DRV_STATE_INITIALIZED); + + CRITICAL_REGION_ENTER(); + if (m_alloc_index < NRF_WDT_CHANNEL_NUMBER) + { + *p_channel_id = (nrf_drv_wdt_channel_id)(NRF_WDT_RR0 + m_alloc_index); + m_alloc_index++; + nrf_wdt_reload_request_enable(*p_channel_id); + result = NRF_SUCCESS; + } + else + { + result = NRF_ERROR_NO_MEM; + } + CRITICAL_REGION_EXIT(); + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)NRF_LOG_ERROR_STRING_GET(result)); + return result; +} + +void nrf_drv_wdt_channel_feed(nrf_drv_wdt_channel_id channel_id) +{ + ASSERT(m_state == NRF_DRV_STATE_POWERED_ON); + nrf_wdt_reload_request_set(channel_id); +} +#endif //NRF_MODULE_ENABLED(WDT) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/wdt/nrf_drv_wdt.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/wdt/nrf_drv_wdt.h new file mode 100644 index 0000000000000000000000000000000000000000..4fdd1d9cbbd6de2acb3fb230bc6f2f30b4de2631 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/drivers_nrf/wdt/nrf_drv_wdt.h @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * @addtogroup nrf_wdt WDT HAL and driver + * @ingroup nrf_drivers + * @brief Watchdog timer (WDT) APIs. + * @details The WDT HAL provides basic APIs for accessing the registers of the watchdog timer. + * The WDT driver provides APIs on a higher level. + * @defgroup nrf_drv_wdt WDT driver + * @{ + * @ingroup nrf_wdt + * + * @brief Driver for managing the watchdog timer (WDT). + */ + +#ifndef NRF_DRV_WDT_H__ +#define NRF_DRV_WDT_H__ + +#include +#include +#include "sdk_errors.h" +#include "nrf_wdt.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Struct for WDT initialization. */ +typedef struct +{ + nrf_wdt_behaviour_t behaviour; /**< WDT behaviour when CPU in sleep/halt mode. */ + uint32_t reload_value; /**< WDT reload value in ms. */ + uint8_t interrupt_priority; /**< WDT interrupt priority */ +} nrf_drv_wdt_config_t; + +/**@brief WDT event handler function type. */ +typedef void (*nrf_wdt_event_handler_t)(void); + +/**@brief WDT channel id type. */ +typedef nrf_wdt_rr_register_t nrf_drv_wdt_channel_id; + +#define NRF_DRV_WDT_DEAFULT_CONFIG \ + { \ + .behaviour = (nrf_wdt_behaviour_t)WDT_CONFIG_BEHAVIOUR, \ + .reload_value = WDT_CONFIG_RELOAD_VALUE, \ + .interrupt_priority = WDT_CONFIG_IRQ_PRIORITY, \ + } +/** + * @brief This function initializes watchdog. + * + * @param[in] p_config Initial configuration. Default configuration used if NULL. + * @param[in] wdt_event_handler specifies event handler provided by user. + * + * @note Function asserts if wdt_event_handler is NULL. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +ret_code_t nrf_drv_wdt_init(nrf_drv_wdt_config_t const * p_config, + nrf_wdt_event_handler_t wdt_event_handler); + +/** + * @brief This function allocate watchdog channel. + * + * @note This function can not be called after nrf_drv_wdt_start(void). + * + * @param[out] p_channel_id ID of granted channel. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +ret_code_t nrf_drv_wdt_channel_alloc(nrf_drv_wdt_channel_id * p_channel_id); + +/** + * @brief This function starts watchdog. + * + * @note After calling this function the watchdog is started, so the user needs to feed all allocated + * watchdog channels to avoid reset. At least one watchdog channel has to be allocated. + */ +void nrf_drv_wdt_enable(void); + +/** + * @brief This function feeds the watchdog. + * + * @details Function feeds all allocated watchdog channels. + */ +void nrf_drv_wdt_feed(void); + +/** + * @brief This function feeds the invidual watchdog channel. + * + * @param[in] channel_id ID of watchdog channel. + */ +void nrf_drv_wdt_channel_feed(nrf_drv_wdt_channel_id channel_id); + +/**@brief Function for returning a requested task address for the wdt driver module. + * + * @param[in] task One of the peripheral tasks. + * + * @retval Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_wdt_ppi_task_addr(nrf_wdt_task_t task) +{ + return nrf_wdt_task_address_get(task); +} + +/**@brief Function for returning a requested event address for the wdt driver module. + * + * @param[in] event One of the peripheral events. + * + * @retval Event address + */ +__STATIC_INLINE uint32_t nrf_drv_wdt_ppi_event_addr(nrf_wdt_event_t event) +{ + return nrf_wdt_event_address_get(event); +} + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/802_15_4_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/802_15_4_config.h new file mode 100644 index 0000000000000000000000000000000000000000..7aa301c66361c4943ffd1a75699dfd5cea3b54bd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/802_15_4_config.h @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef STACK_802_15_4_CONFIG_H__ +#define STACK_802_15_4_CONFIG_H__ + +#define CONFIG_DEBUG 1 +#define CONFIG_MM_DEBUG 1 +#define CONFIG_TEST_CHANNEL 15 +#define CONFIG_TEST_CHANNEL_MASK (1 << CONFIG_TEST_CHANNEL) +#define CONFIG_BEACON_ENABLED 1 +#define CONFIG_SECURE 1 +#define CONFIG_FFD_DEVICE 1 +#define CONFIG_RXE_ENABLED 1 +#define CONFIG_GTS_ENABLED 1 +#define CONFIG_SYNC_REQ_ENABLED 1 +#define CONFIG_ASSOCIATE_IND_ENABLED 1 +#define CONFIG_ORPHAN_ENABLED 1 +#define CONFIG_START_ENABLED 1 +#define CONFIG_ED_SCAN_ENABLED 1 +#define CONFIG_ACTIVE_SCAN_ENABLED 1 +#define CONFIG_PURGE_ENABLED 1 +#define CONFIG_PANID_CONFLICT_RESOLUTION_ENABLED 1 +#define CONFIG_ASSOCIATION_REQ_CMD_RX_ENABLED 1 +#define CONFIG_ASSOCIATION_REQ_CMD_TX_ENABLED 1 +#define CONFIG_ASSOCIATION_RESP_CMD_RX_ENABLED 1 +#define CONFIG_ASSOCIATION_RESP_CMD_TX_ENABLED 1 +#define CONFIG_DISASSOCIATION_NTF_CMD_RX_ENABLED 1 +#define CONFIG_DISASSOCIATION_NTF_CMD_TX_ENABLED 1 +#define CONFIG_DATA_REQ_CMD_RX_ENABLED 1 +#define CONFIG_DATA_REQ_CMD_TX_ENABLED 1 +#define CONFIG_PAN_CONFLICT_NTF_CMD_RX_ENABLED 1 +#define CONFIG_PAN_CONFLICT_NTF_CMD_TX_ENABLED 1 +#define CONFIG_ORPHAN_NTF_CMD_RX_ENABLED 1 +#define CONFIG_ORPHAN_NTF_CMD_TX_ENABLED 1 +#define CONFIG_BEACON_REQ_CMD_RX_ENABLED 1 +#define CONFIG_BEACON_REQ_CMD_TX_ENABLED 1 +#define CONFIG_COORD_REALIGN_CMD_RX_ENABLED 1 +#define CONFIG_COORD_REALIGN_CMD_TX_ENABLED 1 +#define CONFIG_GTS_REQ_CMD_RX_ENABLED 1 +#define CONFIG_GTS_REQ_CMD_TX_ENABLED 1 +#define CONFIG_INDIRECT_ENGINE_ENABLED 1 +#define CONFIG_ASSOCIATE_REQ_ENABLED 1 +#define CONFIG_DISASSOCIATE_ENABLED 1 +#define CONFIG_PANID_CONFLICT_ENABLED 1 +#define CONFIG_SYNC_ENABLED 1 +#define CONFIG_NONE_ADDR_SUPPORT_ENABLED 1 +#define CONFIG_PASSIVE_ORPHAN_SCAN_ENABLED 1 +#define CONFIG_PROMISCUOUS_MODE_ENABLED 1 +#define CONFIG_USE_SYS_TASK_NOTIFIER 1 +#define CONFIG_POOL_SIZE 0x2000 +#define CONFIG_PHY_FRAME_POOL_SIZE 4 +#define CONFIG_MEMORY_POLLING_INTERVAL_MS 10 +#define CONFIG_MAX_SLEEP_APPROVERS 32 +#define CONFIG_HAL_UART_CHANNELS 1 +#define CONFIG_MAC_KEY_TABLE_SIZE 8 +#define CONFIG_MAC_DEVICE_TABLE_SIZE 8 +#define CONFIG_MAC_SECURITY_LEVEL_TABLE_SIZE 8 +#define CONFIG_MAC_KEY_ID_LOOKUP_LIST_SIZE 8 +#define CONFIG_MAC_KEY_DEVICE_LIST_SIZE 8 +#define CONFIG_MAC_KEY_USAGE_LIST_SIZE 8 +#define CONFIG_IEEE_ADDRESS 0x0123456789ABCDEFULL +#define CONFIG_BEACON_RX_TIME 5000 +#define CONFIG_TEST_SUBTREE_MAC 1 + +#endif // STACK_802_15_4_CONFIG_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_atomic.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_atomic.h new file mode 100644 index 0000000000000000000000000000000000000000..67733516d791e849c419bd7c80860133e711ef78 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_atomic.h @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_ATOMIC_H_INCLUDED +#define HAL_ATOMIC_H_INCLUDED + +#include + +/** @file + * This file contains declarations of the Atomic section routines and necessary types. + * + * @defgroup hal_atomic HAL Atomic API + * @{ + * @brief Module to declare HAL Atomic API + */ + +typedef volatile uint32_t atomic_t; + + +/**@brief Enters atomic section. + * + * @details Disables global interrupts. + * + * @param[in] p_atomic pointer to buffer to store current value of the status register. + */ +void hal_atomic_start(atomic_t * p_atomic); + +/** + * @brief Exits atomic section + * + * @details Restores status register + * + * @param[in] p_atomic pointer to buffer to restore current value of the status register from. + */ +void hal_atomic_end(atomic_t * p_atomic); + +/** @} */ + +#endif // HAL_ATOMIC_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_clock.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_clock.h new file mode 100644 index 0000000000000000000000000000000000000000..8bc6d9099360cfa43bb8b53a0ee167f5bba5b47e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_clock.h @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_CLOCK_H_INCLUDED +#define HAL_CLOCK_H_INCLUDED + + +/** @brief This function performs initialization and configuration of processor's + * clock module. + */ +void hal_clock_init(void); + + +#endif /* HAL_CLOCK_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_debug_interface.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_debug_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..c8af88c58a085746cb37653a1396539e5f82373d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_debug_interface.h @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_DEBUG_INTERFACE_H_INCLUDED +#define HAL_DEBUG_INTERFACE_H_INCLUDED + + +#if defined(NRF52) || defined(NRF52840_XXAA) + +#include "nrf_assert.h" + +#endif // NRF52 + + +#ifdef CONFIG_DEBUG + +#include + +#define HAL_DEBUG_INTERFACE_INIT() hal_debug_init() +#define HAL_DEBUG_INTERFACE_PUT(c, n) hal_debug_put(c, n) +#define HAL_DEBUG_INTERFACE_PUTC(c) hal_debug_putc(c) +#define HAL_DEBUG_INTERFACE_PUTS(s) hal_debug_puts(s) + +/** + * @brief Debug interface initialization + */ +void hal_debug_init(void); + +/** + * @brief Sends string to the debug interface + * + * @details send debug data using debug interface + * + * @param[in] p_data debug string. + * @param[in] len string length. + */ +void hal_debug_put(const void * p_data, uint8_t len); + +/** + * @brief Sends char symbol to the debug interface + * + * @details send debug data using debug interface + * + * @param[in] data char symbol. + */ +void hal_debug_putc(const char data); + +/** + * @brief Sends a null-terminated string to the debug interface + * + * @details send debug data using debug interface + * + * @param[in] p_data null-terminated string. + */ +void hal_debug_puts(const char * p_data); + +#else + +/* If debug is disabled, these macros are just a stub.*/ +#define HAL_DEBUG_INTERFACE_INIT() +#define HAL_DEBUG_INTERFACE_PUT(c, n) +#define HAL_DEBUG_INTERFACE_PUTC(c) +#define HAL_DEBUG_INTERFACE_PUTS(s) + +#endif // CONFIG_DEBUG + + +#endif // HAL_DEBUG_INTERFACE_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_delay.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_delay.h new file mode 100644 index 0000000000000000000000000000000000000000..6f1311ef31534d759d58d7facb7801d730f37882 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_delay.h @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_DELAY_H_INCLUDED +#define HAL_DELAY_H_INCLUDED + +#include + +/** @file + * This file contains declaration of the Hardware Delay routine. + * + * @defgroup hal_delay HAL Delay API + * @{ + * @brief Module to declare HAL Delay API + */ + +/**@brief Function for delaying execution for number of microseconds. + * + * @param[in] number_of_us number of microseconds to delay. + */ +void hal_delay(uint32_t number_of_us); + +/** @} */ + +#endif // HAL_DELAY_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_led.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_led.h new file mode 100644 index 0000000000000000000000000000000000000000..11c980ec6fc032e072dff72d5920b4672340b440 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_led.h @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_LED_H_INCLUDED +#define HAL_LED_H_INCLUDED + +#include + +#define HAL_LED_AMOUNT 4 + +void hal_led_init(uint32_t led_mask); +void hal_led_on(uint32_t led_mask); +void hal_led_off(uint32_t led_mask); +void hal_led_toggle(uint32_t led_mask); + +#endif /* HAL_LED_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_mutex.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_mutex.h new file mode 100644 index 0000000000000000000000000000000000000000..979b5f4875d5a8648f877b07fb5406bc55f217e5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_mutex.h @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_MUTEX_H_INCLUDED +#define HAL_MUTEX_H_INCLUDED + +#include "hal_atomic.h" + +/** @file + * This is a simple mutex interface to be used in System Memory Manager + * to make it thread aware. + * + * @details NRF52 implementation is void and PC implementation is identical to atomic. + */ + + +#if defined ( __GNUC__ ) +#include +typedef volatile sig_atomic_t mutex_t; +#else +#include +typedef volatile uint32_t mutex_t; +#endif + + +/**@brief Configures mutex lock before first usage. + * + * @param[inout] p_mutex pointer to mutex variable. + */ +void hal_mutex_init(mutex_t * p_mutex); + +/**@brief Atomically sets mutex. If set is failed, enters spin lock loop. + * + * @param[in] p_mutex pointer to mutex variable. + */ +void hal_mutex_lock(mutex_t * p_mutex); + +/** + * @brief Atomically clears mutex. Every other thread, spinning at this lock may + * try to lock it afterwards. + * + * @param[in] p_mutex pointer to mutex variable. + */ +void hal_mutex_unlock(mutex_t * p_mutex); + +#endif /* HAL_MUTEX_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_rng.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_rng.h new file mode 100644 index 0000000000000000000000000000000000000000..f66c6f9fa062e887d1eec2ffc3ce48a4734fc9d6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_rng.h @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_RNG_H_INCLUDED +#define HAL_RNG_H_INCLUDED + +#include + +/** @file + * This file contains declaration of the random number generator routine. + * + * @defgroup hal_rng HAL Random Number Generator API + * @{ + * @brief Module to declare HAL Random Number Generator API + */ + +/**@brief Initialize hardware random generator. + */ +extern void hal_rand_init(void); + +/**@brief Generates random number using hardware. + * + * @return An unsigned 8-bits random number. + */ +extern uint8_t hal_rand_get(void); + +/** @} */ + +#endif /* HAL_RNG_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_sleep.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_sleep.h new file mode 100644 index 0000000000000000000000000000000000000000..ea1e157bac8fbc5d381748d16ce2d533734053b0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_sleep.h @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_SLEEP_H_INCLUDED +#define HAL_SLEEP_H_INCLUDED + +#include + +/** @file + * This file contains declaration of the HAL sleep interface. + * + * @defgroup hal_sleep HAL Sleep API + * @{ + * @brief Module to declare HAL Sleep API + */ + +/**@brief Converts days to milliseconds */ +#define DAYS_TO_MS(d) ((d) * 3600L * 24L * 1000L ) + +/**@brief Converts hours to milliseconds */ +#define HOURS_TO_MS(h) ((h) * 3600L * 1000L ) + +/**@brief Converts minutes to milliseconds */ +#define MINS_TO_MS(m) ((m) * 60L * 1000L ) + +/**@brief Converts seconds to milliseconds */ +#define SEC_TO_MS(s) ((s) * 1000L ) + +/**@brief Information, provided by the HAL, in order to explain the reason, + * which caused the system to wake up. + */ +typedef enum +{ + UNKNOWN_INTERRUPT, /**< HAL can't define a wake up reason */ + RTC_CC_INTERRUPT /**< RTC interrupt was the awakening reason */ +} hal_wakeup_reason_t; + + +/**@brief Puts hardware into the sleep mode for some milliseconds. + * + * @param[in] sleep_time_ms Time to sleep in ms + * + * @retval wakeup_reason Specifies reason of awakening + */ +hal_wakeup_reason_t hal_sleep(uint32_t sleep_time_ms); + + +/**@brief Initialization of the sleep module + * + */ +void hal_sleep_init(void); + +/** @} */ + +#endif /* HAL_SLEEP_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_task_scheduler.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_task_scheduler.h new file mode 100644 index 0000000000000000000000000000000000000000..8a9d6ee4e9aa1380ab2c9d8b0b3109389a07da0f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_task_scheduler.h @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_TASK_H_INCLUDED +#define HAL_TASK_H_INCLUDED + +#include +#include "hal_atomic.h" +#include "sys_utils.h" +#include "sys_task_scheduler.h" + +/**@brief Identificators for registered HAL handlers. + * + * @details enumeration with identificators of registered HAL handlers. + * HAL handlers will be called from the HAL task. + */ +typedef enum +{ + HAL_TIMER_TASK_ID, + HAL_UART_TASK_ID, + HAL_TIMER_CRITICAL_MANUAL_TASK, + HAL_TASKS_AMOUNT, +} hal_task_id_t; + + +/**@brief Prototype of a HAL task handler. + * + * @details Handler which will be called from HAL task. + */ +typedef void (* hal_task_handler_t)(void); + + +void hal_task_handler(void); +void hal_timer_task_handler(void); +void hal_uart_task_handler(void); +void hal_timer_critical_manual_handler(void); + +/**@brief Pending HAL tasks. + * + * @details Variable which includes markers of pending HAL tasks. + */ +extern volatile uint_fast16_t g_hal_tasks; + + +/**@brief Notify task scheduler to add a HAL task for execution. + * + * @details The function sets a marker for the HAL task for execution. + * + * @param[in] hal_task_id HAL task identifier (see \ref hal_task_id_t enumeration). + */ +static inline void hal_task_post(hal_task_id_t hal_task_id) +{ + atomic_t atomic = 0; + + hal_atomic_start(&atomic); + g_hal_tasks |= BIT(hal_task_id); + hal_atomic_end(&atomic); + + sys_task_post(HAL_TASK_ID); +} + +/**@brief Removes a task from pending list in HAL task scheduler. + * + * @details The function removes a marker from the HAL execution list. + * + * @param[in] hal_task_id HAL task identifier (see \ref hal_task_id_t enumeration). + */ +static inline void hal_task_unpost(hal_task_id_t hal_task_id) +{ + atomic_t atomic = 0; + + hal_atomic_start(&atomic); + g_hal_tasks &= ~BIT(hal_task_id); + hal_atomic_end(&atomic); +} + +#endif // HAL_TASK_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_timer.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..7b7707c82685cb2d4109ed3a77c6a2eebedc9dd9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_timer.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_TIMER_H_INCLUDED +#define HAL_TIMER_H_INCLUDED + +#include "hal_delay.h" +#include + +/**@brief Initializes hardware timer. + */ +void hal_timer_init(void); + + +/**@brief Starts hardware timer. + * + * @param[in] interval timer interval in microseconds for timer start. + */ +void hal_timer_start(uint64_t interval); + + +/**@brief Stops hardware timer. + */ +void hal_timer_stop(void); + + +/**@brief Reads microseconds passed since the device start. + * + * @return time in microseconds since the device was launched. + */ +uint64_t hal_time_get(void); + +#endif /* HAL_TIMER_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_timer_critical.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_timer_critical.h new file mode 100644 index 0000000000000000000000000000000000000000..1497eab596e78d5bb08a8526f6cac45225882da5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_timer_critical.h @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_TIMER_CRITICAL_H_INCLUDED +#define HAL_TIMER_CRITICAL_H_INCLUDED + +#include +#include + + +/**@brief Prototype for critical timer handler. + */ +typedef void (* hal_timer_critical_handler_t)(void); + + +/**@brief Starts hardware critical timer. + * + * @param[in] interval_us timer interval for timer start. + * @param[in] handler critical timer event handler. + */ +void hal_timer_critical_start(uint32_t interval_us, hal_timer_critical_handler_t handler); + + +/**@brief Stops hardware critical timer. + */ +void hal_timer_critical_stop(void); + + +/**@brief Check if critical timer is currently used. + * + * @retval timer_state true - timer is running now + * false - timer in stop mode + */ +bool is_critical_timer_started(void); + + +#endif /* HAL_TIMER_CRITICAL_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_trace_interface.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_trace_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..333574de01912eb6ec042d5b31562d0cac04136b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_trace_interface.h @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_TRACE_INTERFACE_H_INCLUDED +#define HAL_TRACE_INTERFACE_H_INCLUDED + +#ifdef CONFIG_TRACE + +#include "hal_uart.h" + +#define HAL_TRACE_INTERFACE_REUSE(p_uart_desc) hal_trace_reuse(p_uart_desc) +#define HAL_TRACE_INTERFACE_INIT() hal_trace_init() +#define HAL_TRACE_INTERFACE_PUTS(s) hal_trace_puts(s) +#define HAL_TRACE_INTERFACE_FINALIZE() hal_trace_finalize() + +/** + * @brief Trace interface initialization + */ +void hal_trace_init(void); + +/** + * @brief Initializes trace interface, using already initialized UART. + * + * @param[in] p_uart_desc UART descriptor, which has been already initialized. + */ +void hal_trace_reuse(hal_uart_descriptor_t * p_uart_desc); + +/** + * @brief Sends a null-terminated string to the debug interface + * + * @details send debug data using debug interface + * + * @param[in] p_data null-terminated string. + */ +void hal_trace_puts(const char * p_data); + + +/** + * @brief Finalizes buffered trace data output to UART, + * before commencing non-buffered assertion output + */ +void hal_trace_finalize(void); + + +#else + +/* If debug is disabled, these macros are just a stub.*/ +#define HAL_TRACE_INTERFACE_REUSE(p_uart_desc) +#define HAL_TRACE_INTERFACE_INIT() +#define HAL_TRACE_INTERFACE_PUTS(s) +#define HAL_TRACE_INTERFACE_FINALIZE() + +#endif // CONFIG_DEBUG + +#endif // HAL_TRACE_INTERFACE_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_uart.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..f5acc334a30b7005bc7fb6ddbf4714bfdf4582fb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_uart.h @@ -0,0 +1,276 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_UART_H_INCLUDED +#define HAL_UART_H_INCLUDED + +#include +#include +#include + +/** @file + * This file contains declarations of the routines, types and macros to implement the UART protocol. + * + * @defgroup hal_uart HAL UART protocol + * @{ + * @brief Module to declare HAL UART protocol + */ + +/** @brief Maximum size in bytes of input and output buffers. */ +#define MAX_QUEUE_LENGTH 0xffffu + +/** @brief Maximum size in bytes of data can be stored in hardware unit output buffer. */ +#define MAX_TX_CHUNK_SIZE UCHAR_MAX + +/** @brief UART baudrate. */ +typedef enum +{ + HAL_UART_BAUDRATE_38400, /**< 38400 bits per second.*/ + HAL_UART_BAUDRATE_115200, /**< 115200 bits per second.*/ + HAL_UART_BAUDRATE_230400 /**< 230400 bits per second.*/ +} hal_uart_baudrate_t; + +/** @brief UART parity check. */ +typedef enum +{ + HAL_UART_PARITY_NONE, /**< Do not check parity.*/ + HAL_UART_PARITY_EVEN /**< Check even parity.*/ +} hal_uart_parity_t; + +/** @brief UART flow control. */ +typedef enum +{ + HAL_UART_FLOW_CONTROL_DISABLED, /**< Flow control is disabled.*/ + HAL_UART_FLOW_CONTROL_ENABLED, /**< Flow control is enabled.*/ +} hal_uart_flow_control_t; + +/** @brief UART character size settings. */ +typedef enum +{ + HAL_UART_FIVE_BITS_CHAR = 5, /**< 5 bits character.*/ + HAL_UART_SIX_BITS_CHAR, /**< 6 bits character.*/ + HAL_UART_SEVEN_BITS_CHAR, /**< 7 bits character.*/ + HAL_UART_EIGHT_BITS_CHAR, /**< 8 bits character.*/ +} hal_uart_char_size_t; + +/** @brief UART stop bits settings. */ +typedef enum +{ + HAL_UART_ONE_STOP_BIT, /**< 1 stop bit.*/ + HAL_UART_ONEHALF_STOP_BITS, /**< 1.5 stop bits.*/ + HAL_UART_TWO_STOP_BITS, /**< 2 stop bits.*/ +} hal_uart_stop_bits_t; + +/** @brief Represents error source for the UART driver. There might be other values, + * representing clearer elaborating of error statuses, if this module is used + * with Windows or Linux. + */ +typedef enum +{ + HAL_UART_ERROR_NONE = 0, /**< Success.*/ + HAL_UART_ERROR_TX_OVERFLOW = 252, /**< This error happens when amount of elements in + the transmitter ring buffer exceeds its size. + All the data above limit is not placed into + buffer.*/ + HAL_UART_ERROR_RX_OVERFLOW = 253, /**< This error happens when amount of elements in + the receiver ring buffer exceeds its size. + All the unread data is overwritten with new + received data.*/ + HAL_UART_ERROR_RX_UNDERFLOW = 254, /**< This error happens when the user-side software + tries to read more elements than it is available + in the receive buffer. + The user-side buffer will be filled with all available + characters and then the error handler is started.*/ + HAL_UART_ERROR_HW_ERROR = 255, /**< There is some unrecoverable error in hardware.*/ +} hal_uart_error_t; + +/** + * @brief User-side handler of UART read and write events. + * + * @param[in] channel event channel number. + * @param[in] char_count number of characters successfully sent before entering + * the callback function. + */ +typedef void (*hal_uart_handler_t)(uint32_t channel, size_t char_count); + +/** + * @brief User-side handler for UART error events. + * + * @param[in] channel event channel number. + * @param[in] error_id call reason. + */ +typedef void (*hal_uart_error_handler_t)(uint32_t channel, hal_uart_error_t error_id); + +/** @brief HAL UART configuration structure. + */ +typedef struct +{ + uint32_t module; /**< UART module number. By now zero + is the only option.*/ + uint32_t tx_pin; /**< Number of pin used as TX.*/ + uint32_t rx_pin; /**< Number of pin used as RX.*/ + uint32_t cts_pin; /**< Number of pin used as CTS.*/ + uint32_t rts_pin; /**< Number of pin used as RTS.*/ + hal_uart_baudrate_t baudrate; /**< Baudrate selector.*/ + hal_uart_parity_t parity; /**< Parity selector.*/ + hal_uart_flow_control_t flow_control; /**< Flow control selector.*/ + hal_uart_char_size_t char_size; /**< Size of char in bits.*/ + hal_uart_stop_bits_t stop_bits; /**< Stop bits number.*/ +} hal_uart_config_t; + +/** + * @brief This structure defines the UART module operation. + * + * If \a write_buffer_ptr is defined as NULL, then sending data will work + * in blocking way, that is call for \a hal_uart_write will be completed + * only after sending of the last byte passed as input parameter. + * + * If \a read_buffer_ptr is defined as NULL, then driver will drop every + * received byte. + */ +typedef struct +{ + hal_uart_config_t uart_config; /**< UART settings struct.*/ + hal_uart_handler_t write_handler; /**< Callback function for write operation.*/ + void * write_buffer_ptr; /**< User-side buffer for write operation.*/ + size_t write_buffer_size; /**< Size of write operation buffer.*/ + hal_uart_handler_t read_handler; /**< Callback function for read operation.*/ + void * read_buffer_ptr; /**< User-side buffer for read operation.*/ + size_t read_buffer_size; /**< Size of read operation buffer.*/ + hal_uart_error_handler_t error_handler; /**< Callback function in case of something + goes wrong.*/ +} hal_uart_descriptor_t; + +/** + * @brief Configures UART interface using input parameter. + * + * @param[in] config pointer to a config struct. + * @param[in] descriptor pointer to a descriptor struct. + * + * @return Return status of operation. + */ +hal_uart_error_t hal_uart_open(const hal_uart_config_t * config, + const hal_uart_descriptor_t * descriptor); + +/** + * @brief Sends data in a non-blocking way. + * + * @param[in] descriptor pointer to the UART module operation structure. + * @param[in] data pointer to the user-side buffer of output data. + * @param[in] length number of bytes to transmit. + * + * If descriptor has a non-null \a write_buffer_ptr then this function will use it + * as a temporary buffer and will copy input \a data to it before starting + * transmit. If descriptor has the NULL \a write_buffer_ptr, then the user-side code + * is responsible to retain \a data until \a write_handler is called. + */ +void hal_uart_write(const hal_uart_descriptor_t * descriptor, + const uint8_t * data, + const size_t length); + +/** + * @brief Sends a null-terminated C-string in a non-blocking way. + * + * @param[in] descriptor pointer to the UART module operation structure. + * @param[in] s null-terminated string to send. + */ +void hal_uart_puts(const hal_uart_descriptor_t * descriptor, const char * s); + +/** + * @brief Receives data in a non-blocking way. + * + * @param[in] descriptor pointer to the UART module operation structure. + * @param[out] data pointer to the user-side buffer used to receive data. + * @param[in] length number of bytes to receive. + * + * If descriptor has a non-null \a read_buffer_ptr, then this function is used to + * copy input characters from it to \a data. + * If \a read_buffer_ptr is NULL, then this function ignores all inputs. + */ +void hal_uart_read(const hal_uart_descriptor_t * descriptor, + uint8_t * data, + const size_t length); + +/** + * @brief Returns number of bytes available to read from the income buffer of the + * driver. + * + * @param[in] descriptor pointer to driver structure. + * + * @return Number of bytes available to read. + */ +size_t hal_uart_read_buffer_size_get(const hal_uart_descriptor_t * descriptor); + +/** + * @brief Returns number of bytes available to write to the outgoing buffer of the + * driver. + * + * @param[in] descriptor pointer to driver structure. + * + * @return Number of bytes available to write. + */ +size_t hal_uart_write_buffer_size_get(const hal_uart_descriptor_t * descriptor); + +/** + * @brief This function deallocates resources previously allocated by hal_uart_open. + * + * @param[in] descriptor pointer to driver structure. + * + * @return Return status of operation. + */ +hal_uart_error_t hal_uart_close(const hal_uart_descriptor_t * descriptor); + + +#if defined(CONFIG_TRACE) && defined(CONFIG_DEBUG) + +/** + * @brief Finalizes remaining trace data output to UART. + * + * @details This debugging feature is needed to finalize buffered trace output + * to UART before commencing non-buffered assertion output. + */ +void hal_uart_trace_finalize(void); + +#endif + +/** @} */ + +#endif /* HAL_UART_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_uart_task_scheduler.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_uart_task_scheduler.h new file mode 100644 index 0000000000000000000000000000000000000000..7f44a5808b95b761e0443515d12506ce9f697080 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/hal_uart_task_scheduler.h @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_UART_TASK_SCHEDULER_H_INCLUDED +#define HAL_UART_TASK_SCHEDULER_H_INCLUDED + +#include +#include "hal_atomic.h" +#include "hal_task_scheduler.h" +#include "sys_utils.h" + +/**@brief Identificators for registered UART event handlers. + * + * @details enumeration with identificators of registered UART event handlers. + * UART handlers will be called from the HAL_UART task. */ +typedef enum +{ + HAL_UART_RX_TASK_ID, + HAL_UART_TX_TASK_ID, + HAL_UART_ERROR_TASK_ID, + HAL_UART_TASKS_AMOUNT, +} hal_uart_task_id_t; + +/**@brief Prototype of a UART task handler. + * + * @details Handler which will be called from HAL_UART task. */ +typedef void (* hal_uart_task_handler_t)(uint32_t channel); + +void hal_uart_rx_handler(uint32_t channel); +void hal_uart_tx_handler(uint32_t channel); +void hal_uart_error_handler(uint32_t channel); + +/**@brief UART channels. + * + * @details Array which includes event id for every channel it happened. */ +extern volatile uint16_t g_hal_uart_modules_tasks[CONFIG_HAL_UART_CHANNELS]; + + +/**@brief Notifies HAL task scheduler to add an UART task for execution. + * + * @details The function sets a marker for the UART event task for execution. + * And sets this marker for a channel where event happened. + * + * @param[in] channel event channel. + * @param[in] hal_uart_task_id HAL task identificator. */ +static inline void hal_uart_task_post(uint32_t channel, + uint8_t hal_uart_task_id) +{ + atomic_t atomic = 0; + + hal_atomic_start(&atomic); + g_hal_uart_modules_tasks[channel] |= BIT(hal_uart_task_id); + hal_atomic_end(&atomic); + + hal_task_post(HAL_UART_TASK_ID); +} + +#endif /* HAL_UART_TASK_SCHEDULER_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/nrf52_soc/hal_nrf52_exceptions.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/nrf52_soc/hal_nrf52_exceptions.h new file mode 100644 index 0000000000000000000000000000000000000000..e40e96c82c743475aa0faae334b63ff22416df52 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/nrf52_soc/hal_nrf52_exceptions.h @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_EXCEPTIONS_H_INCLUDED +#define HAL_EXCEPTIONS_H_INCLUDED + +#include + +/** @brief Size of stack dump in 4-byte words.*/ +#define HAL_EXCEPTIONS_DUMP_SIZE 16 +/** @brief Defines where to put a '\n' in stack dump. + * + * This value defines power of 2 items in one row. + * E.g. 3 gives 2 ^ 3 = 8 items in a row.*/ +#define HAL_EXCEPTIONS_ITEMS_IN_LINE 3 + +/** @brief This structure holds values of fault status registers.*/ +typedef struct +{ + uint32_t CFSR; /*!< Configurable Fault Status Register.*/ + uint32_t HFSR; /*!< HardFault Status Register.*/ + uint32_t DFSR; /*!< Debug Fault Status Register.*/ + uint32_t AFSR; /*!< Auxiliary Fault Status Register.*/ +} hal_exceptions_status_registers_t; + +/** @brief This structure is put into dump monitor port and holds values of said + * registers when exception has happen.*/ +typedef struct +{ + uint32_t R0; /**< Register R0 (Argument 1 / word result).*/ + uint32_t R1; /**< Register R1 (Argument 2 / double-word result).*/ + uint32_t R2; /**< Register R2 (Argument 3).*/ + uint32_t R3; /**< Register R3 (Argument 4).*/ + uint32_t R12; /**< Register R12 (Scratch register (corruptible)).*/ + uint32_t LR; /**< Link register (R14).*/ + uint32_t PC; /**< Program counter (R15).*/ + uint32_t PSR; /**< Combined processor status register.*/ + uint32_t* FP; /**< Value of register, which may be used as Frame Pointer.*/ +} hal_exceptions_dump_t; + +#endif // HAL_EXCEPTIONS_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/nrf52_soc/hal_nrf52_rtc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/nrf52_soc/hal_nrf52_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..ed445c10ccc03ef053b66c93b9dc05cc54dd0b6f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/nrf52_soc/hal_nrf52_rtc.h @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_NRF52_RTC_H_INCLUDED +#define HAL_NRF52_RTC_H_INCLUDED + +#include "nordic_common.h" +#include "nrf_drv_config.h" +#include "nrf_drv_common.h" +#include "nrf_drv_rtc.h" +#include "nrf_rtc.h" + + +// RTC counter bitlenght +#define LAGEST_PRESCALER_VALUE 4096 +// RTC counter bitlenght +#define RTC_CNT_BITLENGHT 24 +// Longest sleep time, ms +#define LONGEST_SLEEP_TIME ((( 1UL << RTC_CNT_BITLENGHT ) \ + /(RTC_INPUT_FREQ/LAGEST_PRESCALER_VALUE)) * 1000UL ) + +// Shortest sleep time, ms +#define SHORTEST_SLEEP_TIME 1 + +/**@brief Function for initialize low frequency clock + */ +void rtc_lfclk_start(void); + + +/** @brief Function initialization and configuration of RTC driver instance. + * + * @param[in] uint32_t after this time compare event will be triggered + */ +void rtc_start(uint32_t sleep_time_ms); + +/** @brief Stop RTC + */ +void rtc_stop(void); + +/** @brief Get RTC counter + * + * @retval uint32_t Contents of RTC counter register. + */ +uint32_t rtc_cnt_get(void); + +/** @brief Get time elapsed since cnt_ticks + * + * @param[in] cnt_ticks Number of rtc-ticks + * + * @retval uint32_t Time since cnt_ticks, ms + */ +uint64_t get_rtc_time_since(uint32_t cnt_ticks); + +/** @brief Check if rtc compare interrupt was triggered after calling + * rtc_start function + * + * @retval bool true - compare interrupt was triggered + * false - it wasn't + */ +bool is_rtc_comp_irq_triggerd(void); + +#endif /* HAL_NRF52_RTC_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/nrf52_soc/hal_nrf52_timer.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/nrf52_soc/hal_nrf52_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..2f9e161b360308fe2235a7486e60c1c2076ee92c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/HAL/nrf52_soc/hal_nrf52_timer.h @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HAL_NRF52_TIMER_INCLUDED +#define HAL_NRF52_TIMER_INCLUDED + + +/**@brief Pause hardware timer. + */ +void hal_timer_pause(void); + + +/**@brief Resume hardware timer. + */ +void hal_timer_resume(void); + + +/**@brief Set a new system time + * + * @param[in] time_us time to set. + */ +void hal_time_adjust(uint64_t time_us); + + +/**@brief Uninit hardwware timer + */ +void hal_timer_uninit(void); + + + + +#endif /* HAL_NRF52_TIMER_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_auto_request.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_auto_request.h new file mode 100644 index 0000000000000000000000000000000000000000..93db1fa073dae93899f0a0ef127fa2d4954f7303 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_auto_request.h @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_AUTO_REQUEST_H_INCLUDED +#define MAC_AUTO_REQUEST_H_INCLUDED + +/** @file + * + * @defgroup mac_auto_request MAC auto request + * @ingroup mac_15_4 + * @{ + */ + +/** + * @brief This function is called when a new beacon has been sent. + * + * @param[in] p_ind - Pointer to beacon indication structure. + */ +void mac_auto_request_notify_ind(mac_beacon_ind_t * p_ind); + +/** @} */ + +#endif /* MAC_AUTO_REQUEST_H_INCLUDED_ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_common.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_common.h new file mode 100644 index 0000000000000000000000000000000000000000..adbd7f0543750298f73631639177147a01eff986 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_common.h @@ -0,0 +1,467 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_COMMON_H_INCLUDED +#define MAC_COMMON_H_INCLUDED + +#include +#include "phy_common.h" + +#if (CONFIG_SECURE == 1) +#include "mac_security.h" +#endif + +/** @file + * Types and declarations common for different MLME transactions listed here. + * + * @defgroup mac_common MAC Common API + * @ingroup mac_15_4 + * @{ + * @brief Module for declaring MAC Common API. + * @details The Common MAC module contains declarations of commonly used MAC routines and necessary + * macros and types. + */ + +/**@brief Maximum interval for acknowledgement frame to arrive in microseconds. + * + * macAckWaitDuration = aUnitBackoffPeriod(only for beacon enabled PAN) + + * aTurnaroundTime + + * phySHRDuration + ceil(6 * phySymbolsPerOctet) = + * 20 + 12 + 10 + 6 * 2 = + * 54 symbols / 62.5 ksymbols/s = 864 us (544 us for beacon disabled PAN) + */ +#if (CONFIG_BEACON_ENABLED == 1) +#define macAckWaitDuration 864 +#else +#define macAckWaitDuration 544 +#endif + +/**@brief The maximum number of octets added by the MAC + * sublayer to the MAC payload of a beacon frame. + */ +#define aMaxBeaconOverhead 75 + +/**@brief The number of symbols forming the basic time period + * used by the CSMA-CA algorithm. + */ +#define aUnitBackoffPeriod 20UL + +/**@brief The number of symbols forming a superframe slot + * when the superframe order is equal to 0. + */ +#define aBaseSlotDuration 60UL + +/**@brief The number of slots contained in any superframe. */ +#define aNumSuperframeSlots 16UL + +/**@brief The number of symbols forming a superframe when + * the superframe order is equal to 0. + */ +#define aBaseSuperframeDuration (aBaseSlotDuration * aNumSuperframeSlots) + +/**@brief The maximum size, in octets, of a beacon payload. */ +#define aMaxBeaconPayloadLength (aMaxPHYPacketSize - aMaxBeaconOverhead) + +/**@brief The maximum number of octets added by the MAC + * sublayer to the PSDU without security. + */ +#define aMaxMPDUUnsecuredOverhead 25 + +/**@brief The maximum number of octets that can be transmitted in the MAC Payload + * field of an unsecured MAC frame that will be guaranteed not to exceed aMaxPHYPacketSize. + */ +#define aMaxMACSafePayloadSize (aMaxPHYPacketSize - aMaxMPDUUnsecuredOverhead) + +/**@brief The minimum number of octets added by the MAC sublayer to the PSDU.*/ +#define aMinMPDUOverhead 9 + +/**@brief The maximum number of octets that can be transmitted in the MAC + * Payload field. + */ +#define aMaxMACPayloadSize (aMaxPHYPacketSize - aMinMPDUOverhead) + +/**@brief The maximum size of an MPDU, in octets, that can be followed by a SIFS period. */ +#define aMaxSIFSFrameSize 18 + +/**@brief The minimum number of symbols forming the CAP. + * + * @details This ensures that MAC commands can still be transferred to devices + * when GTSs are being used. + */ +#define aMinCAPLength 440 + +/**@brief The number of superframes in which a GTS descriptor exists + * in the beacon frame of the PAN coordinator. + */ +#define aGTSDescPersistenceTime 4 + +/**@brief The number of consecutive lost beacons that will cause the MAC sublayer + * of a receiving device to declare a loss of synchronization. + */ +#define aMaxLostBeacons 4 + +/**@brief Maximum number of battery life extension periods. */ +#define MAC_MIN_BATT_LIFE_EXT_PERIODS 6 +/**@brief Minimum number of battery life extension periods. */ +#define MAC_MAX_BATT_LIFE_EXT_PERIODS 41 + +/**@brief Minimum value for macBeaconOrder parameter. */ +#define MAC_MIN_BEACON_ORDER 0 +/**@brief Maximum value for macBeaconOrder parameter. */ +#define MAC_MAX_BEACON_ORDER 15 + +/**@brief Minimum value for macMaxCSMABackoffs parameter. */ +#define MAC_MIN_MAX_CSMA_BACKOFFS 0 +/**@brief Maximum value for macMaxCSMABackoffs parameter. */ +#define MAC_MAX_MAX_CSMA_BACKOFFS 5 + +/**@brief Minimum value for macMinBE parameter. */ +#define MAC_MIN_MIN_BE 0 + +/**@brief Minimum value for macMaxBE parameter. */ +#define MAC_MIN_MAX_BE 3 +/**@brief Maximum value for macMaxBE parameter. */ +#define MAC_MAX_MAX_BE 8 + +/**@brief Minimum value for macSuperframeOrder parameter. */ +#define MAC_MIN_SUPERFRAME_ORDER 0 +/**@brief Maximum value for macSuperframeOrder parameter. */ +#define MAC_MAX_SUPERFRAME_ORDER 15 + +/**@brief Minimum value for macMaxFrameRetries parameter. */ +#define MAC_MIN_MAX_FRAME_RETRIES 0 +/**@brief Maximum value for macMaxFrameRetries parameter. */ +#define MAC_MAX_MAX_FRAME_RETRIES 7 + +/**@brief Minimum value for macResponseWaitTime parameter. */ +#define MAC_MIN_RESPONSE_WAIT_TIME 2 +/**@brief Maximum value for macResponseWaitTime parameter. */ +#define MAC_MAX_RESPONSE_WAIT_TIME 64 + +/**@brief A handy macro for a never initialized short address. */ +#define MAC_SHORT_ADDRESS_NOT_SET 0xFFFF + +/**@brief A handy macro for a never initialized short address. */ +#define MAC_EXTENDED_ADDRESS_NOT_SET 0xFFFFFFFFFFFFFFFFULL + +/**@brief A value of MAC beacon order attribute which determines + * a state with no periodic beacons. + */ +#define MAC_NO_BEACONS 15 + +/**@brief A handy macro for broadcast address. */ +#define MAC_BROADCAST_SHORT_ADDRESS 0xFFFF + +/**@brief A handy macro for unknown PAN ID. */ +#define MAC_BROADCAST_PANID 0xFFFF + +/**@brief Short address field value that is used when the device does not + * support short addressing mode. + */ +#define MAC_EXTENDED_ADDRESS_ONLY 0xFFFE + +/**@brief Final CAP slot field value in the beacon for non-beacon enabled PAN. */ +#define MAC_FINAL_CAP_SLOT_NBPAN 15 + +/**@brief Total amount of slots available in beacon enabled PAN. */ +#define MAC_SLOT_AMOUNT 16 + +/**@brief This is the value of auto request key index until it has been set. */ +#define MAC_SECURITY_KEY_INDEX_NOT_SET 0xFF + +/**@brief Length of short MAC address in bytes. */ +#define MAC_ADDR_SHORT_LEN 2 + +/**@brief Length of extended MAC address in bytes. */ +#define MAC_ADDR_EXTENDED_LEN 8 + +/**@brief Length of PAN ID field in bytes. */ +#define MAC_PAN_ID_LEN 2 + +/**@brief MAC footer (FCS) size. */ +#define MAC_MFR_SIZE 2 + +/**@brief Maximum auxiliary header length */ +#if (CONFIG_SECURE == 1) +#define MAC_MAX_AUX_HEADER_SIZE 14 +#else +#define MAC_MAX_AUX_HEADER_SIZE 0 +#endif + +/**@brief Maximum MAC header length */ +#define MAC_MAX_MHR_SIZE (PHY_MAX_HEADER_SIZE + \ + 2 /* Frame control */ + \ + 1 /* Data sequence number */ + \ + 2 * (sizeof(uint16_t) + (sizeof(uint64_t))) /* Two PAN IDs and extended addresses */ + \ + MAC_MAX_AUX_HEADER_SIZE) +/**@brief Maximum MAC header length for beacon frame */ +#define MAC_MAX_BCN_MHR_SIZE (PHY_MAX_HEADER_SIZE + \ + 2 /* Frame control field */ + \ + 1 /* Beacon sequence number */ + \ + sizeof(uint16_t) /* PAN ID */ + \ + sizeof(uint64_t) /* Extended address */ + \ + MAC_MAX_AUX_HEADER_SIZE) + + +/**@brief Memory which should be reserved for MAC fields */ +#if (CONFIG_SECURE == 1) +#define MAC_MEMORY_RESERVE (MAC_MAX_MHR_SIZE + MAX_MIC_SIZE + MAC_MFR_SIZE) +#else +#define MAC_MEMORY_RESERVE (MAC_MAX_MHR_SIZE + MAC_MFR_SIZE) +#endif + +/**@brief Offset of MAC payload in the frame buffer */ +#define MAC_MAX_MSDU_OFFSET MAC_MAX_MHR_SIZE + +/**@brief Possible MAC frame types. */ +typedef enum +{ + MAC_BEACON, /**< Frame is a beacon. */ + MAC_DATA, /**< Frame is a data frame. */ + MAC_ACK, /**< Frame is a MAC ACKnowledgement. */ + MAC_COMMAND /**< Frame is a MAC command. */ +} mac_frame_type_t; + +/**@brief MAC ADDRESS. */ +typedef union +{ + uint16_t short_address; /**< 16-bit short address. */ + uint64_t long_address; /**< 64-bit long address. */ +} mac_addr_t; + +/**@brief MAC ADDR MODE. */ +typedef enum +{ + MAC_ADDR_NONE = 0, /**< NO address is used. */ + MAC_ADDR_SHORT = 2, /**< Short address is used. */ + MAC_ADDR_LONG = 3 /**< Long address is used. */ +} mac_addr_mode_t; + +typedef enum +{ + MAC_FRAME_VERSION_2003, /**< IEEE 802.15.4-2003 compliant. */ + MAC_FRAME_VERSION_2006 /**< IEEE 802.15.4-2006 compliant. */ +} mac_frame_version_t; + +/** + * @brief MAC status + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.17 + * excluding: + * MAC_IS_NOT_AVAILABLE + * This status is necessary for synchronous API. + */ +typedef enum +{ + MAC_SUCCESS = 0x00, /* 0 */ /**< Operation is successful. */ + MAC_COUNTER_ERROR = 0xDB, /* 219 */ /**< The frame counter purportedly applied + by the originator of the received + frame is invalid. */ + MAC_IMPROPER_KEY_TYPE = 0xDC, /* 220 */ /**< The key purportedly applied by the + originator of the received frame is + not allowed to be used with that + frame type according to the key usage + policy of the recipient. */ + MAC_IMPROPER_SECURITY_LEVEL = 0xDD, /* 221 */ /**< The security level purportedly applied + by the originator of the received + frame does not meet the minimum + security level required/expected by + the recipient for that frame type. */ + MAC_UNSUPPORTED_LEGACY = 0xDE, /* 222 */ /**< The received frame was purportedly + secured using security based on IEEE + Std 802.15.4-2003, and such security + is not supported by this standard. */ + MAC_UNSUPPORTED_SECURITY = 0xDF, /* 223 */ /**< The security purportedly applied by + the originator of the received frame + is not supported. */ + MAC_BEACON_LOSS = 0xE0, /* 224 */ /**< The beacon was lost following a + synchronization request. */ + MAC_CHANNEL_ACCESS_FAILURE = 0xE1, /* 225 */ /**< A transmission could not take place + due to activity on the channel, i.e. + the CSMA-CA mechanism has failed. */ + MAC_DENIED = 0xE2, /* 226 */ /**< The GTS request has been denied by + the PAN coordinator. */ + MAC_DISABLE_TRX_FAILURE = 0xE3, /* 227 */ /**< The attempt to disable the + transceiver has failed. */ + MAC_SECURITY_ERROR = 0xE4, /* 228 */ /**< Cryptographic processing of the + received secured frame failed. */ + MAC_FRAME_TOO_LONG = 0xE5, /* 229 */ /**< Either a frame resulting from + processing has a length that is + greater than aMaxPHYPacketSize or + a requested transaction is too large + to fit in the CAP or GTS. */ + MAC_INVALID_GTS = 0xE6, /* 230 */ /**< The requested GTS transmission failed + because the specified GTS either did + not have a transmit GTS direction or + was not defined. */ + MAC_INVALID_HANDLE = 0xE7, /* 231 */ /**< A request to purge an MSDU from the + transaction queue was made using an + MSDU handle that was not found in + the transaction table. */ + MAC_INVALID_PARAMETER = 0xE8, /* 232 */ /**< A parameter in the primitive is + either not supported or is out of + the valid range. */ + MAC_NO_ACK = 0xE9, /* 233 */ /**< No acknowledgment was received after + macMaxFrameRetries. */ + MAC_NO_BEACON = 0xEA, /* 234 */ /**< A scan operation failed to find any + network beacons. */ + MAC_NO_DATA = 0xEB, /* 235 */ /**< No response data was available + following a request. */ + MAC_NO_SHORT_ADDRESS = 0xEC, /* 236 */ /**< The operation failed because a 16-bit + short address was not allocated. */ + MAC_OUT_OF_CAP = 0xED, /* 237 */ /**< A receiver enable request was + unsuccessful because it could not be + completed within the CAP. + @note The enumeration description is + not used in this standard, and it is + included only to meet the backwards + compatibility requirements for + IEEE Std 802.15.4-2003. */ + MAC_PAN_ID_CONFLICT = 0xEE, /* 238 */ /**< A PAN identifier conflict has been + detected and communicated to the PAN + coordinator. */ + MAC_REALIGNMENT = 0xEF, /* 239 */ /**< A coordinator realignment command has + been received. */ + MAC_TRANSACTION_EXPIRED = 0xF0, /* 240 */ /**< The transaction has expired and its + information was discarded. */ + MAC_TRANSACTION_OVERFLOW = 0xF1, /* 241 */ /**< There is no capacity to store the + transaction. */ + MAC_TX_ACTIVE = 0xF2, /* 242 */ /**< The transceiver was in the transmitter + enabled state when the receiver was + requested to be enabled. + @note The enumeration description is + not used in this standard, and it is + included only to meet the backwards + compatibility requirements for + IEEE Std 802.15.4-2003. */ + MAC_UNAVAILABLE_KEY = 0xF3, /* 243 */ /**< The key purportedly used by the + originator of the received frame is + not available or, if available, the + originating device is not known or is + blacklisted with that particular + key. */ + MAC_UNSUPPORTED_ATTRIBUTE = 0xF4, /* 244 */ /**< A SET/GET request was issued with the + identifier of a PIB attribute that is + not supported. */ + MAC_INVALID_ADDRESS = 0xF5, /* 245 */ /**< A request to send data was + unsuccessful because neither the source + address parameters nor the destination + address parameters were present. */ + MAC_ON_TIME_TOO_LONG = 0xF6, /* 246 */ /**< A receiver enable request was + unsuccessful because it specified a + number of symbols that was longer than + the beacon interval. */ + MAC_PAST_TIME = 0xF7, /* 247 */ /**< A receiver enable request was + unsuccessful because it could not be + completed within the current superframe + and was not permitted to be deferred + until the next superframe. */ + MAC_TRACKING_OFF = 0xF8, /* 248 */ /**< The device was instructed to start + sending beacons based on the timing + of the beacon transmissions of its + coordinator, but the device is not + currently tracking the beacon of its + coordinator. */ + MAC_INVALID_INDEX = 0xF9, /* 249 */ /**< An attempt to write to a MAC PIB + attribute that is in a table failed + because the specified table index + was out of range. */ + MAC_LIMIT_REACHED = 0xFA, /* 250 */ /**< A scan operation terminated + prematurely because the number of + PAN descriptors stored reached an + implementation specified maximum. */ + MAC_READ_ONLY = 0xFB, /* 251 */ /**< A SET/GET request was issued with the + identifier of an attribute that is + read only. */ + MAC_SCAN_IN_PROGRESS = 0xFC, /* 252 */ /**< A request to perform a scan operation + failed because the MLME was in the + process of performing a previously + initiated scan operation. */ + MAC_SUPERFRAME_OVERLAP = 0xFD, /* 253 */ /**< The device was instructed to start + sending beacons based on the timing + of the beacon transmissions of its + coordinator, but the instructed start + time overlapped the transmission time + of the beacon of its coordinator. */ + /* Statuses out from standard. It is used for synchronous API */ + MAC_IS_NOT_AVAILABLE = 0xFF /* 255 */ /**< MAC is not available. */ +} mac_status_t; + +/** + * @brief Payload descriptor. + * + * @details Not covered by the standard. + * Contains information sufficient to allow the next higher layer to clean + * the memory allocated for incoming frames. + */ +typedef struct +{ + /** + * Pointer to the set of octets forming the frame payload being indicated by + * the MAC sublayer entity. + */ + uint8_t * p_payload; + /** + * Offset of the payload data relative to the beginning of the frame. + * Equal to the MAC header. + */ + uint8_t payload_offset; +} mac_payload_descriptor_t; + +/** @brief Command frame IDs defined by the MAC sublayer that are listed + * in Table 82 of the standard. + */ +typedef enum +{ + MAC_CMD_ASSOC_REQ = 0x01, /**< Association request.*/ + MAC_CMD_ASSOC_RESP = 0x02, /**< Association response.*/ + MAC_CMD_DISASSOC_NTF = 0x03, /**< Disassociation notification.*/ + MAC_CMD_DATA_REQ = 0x04, /**< Data request.*/ + MAC_CMD_PANID_CONFLICT_NTF = 0x05, /**< PAN ID conflict notification.*/ + MAC_CMD_ORPHAN_NTF = 0x06, /**< Orphan notification.*/ + MAC_CMD_BEACON_REQ = 0x07, /**< Beacon request.*/ + MAC_CMD_COORD_REALIGN = 0x08, /**< Coordinator realignment.*/ + MAC_CMD_GTS_REQ = 0x09 /**< GTS request.*/ +} mac_command_id_t; +/** @} */ + + +#endif // MAC_COMMON_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mcps_data.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mcps_data.h new file mode 100644 index 0000000000000000000000000000000000000000..0bc812dd2fd31c43b421d8949a8de827681ae724 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mcps_data.h @@ -0,0 +1,333 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MCPS_DATA_H_INCLUDED +#define MAC_MCPS_DATA_H_INCLUDED + +#include +#include "mac_common.h" +#include "mac_task_scheduler.h" + +/** @file + * The MAC Data module declares the MAC Data transmittion routines and necessary types + * according to the MAC specification. + * + * @defgroup mac_data MAC MCPS Data API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MCPS Data API. + * @details The MAC MCPS Data module declares the MAC Data transmission routines and necessary types according + * to the MAC specification. More specifically, MAC data request mcps_data_req(), and MAC Data + * indication mcps_data_ind() primitives are declared. The confirmation callback typedef is + * declared as mcps_data_conf_cb_t. + */ + +/** + * @brief TX options bit fields. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.1. + */ +#define TX_ACKNOWLEDGED_BIT (0) +#define TX_GTS_BIT (1) +#define TX_INDIRECT_BIT (2) + + +/** + * @brief TX options for MAC data transmission. + * + * @details The three bits (b0, b1, b2) indicate the transmission options for this MSDU. + * For b0, 1 = acknowledged transmission, 0 = unacknowledged transmission. + * For b1, 1 = GTS transmission, 0 = CAP transmission for a beacon-enabled PAN. + * For b2, 1 = indirect transmission, 0 = direct transmission. + * For a nonbeacon-enabled PAN, bit b1 should always be set to 0. + */ +typedef struct +{ + uint8_t ack : 1; + uint8_t gts : 1; + uint8_t indirect : 1; + uint8_t : 5; +} mac_tx_options_t; + + +/** + * @brief MCPS-DATA.confirm. + * + * @details The MCPS-DATA.confirm primitive reports the results of a request to transfer + * a data SPDU (MSDU) from a local SSCS entity to a single peer SSCS entity. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.2. + */ +typedef struct +{ + /** The handle associated with the MSDU being confirmed. */ + uint8_t msdu_handle; + + /** The status of the last MSDU transmission. */ + mac_status_t status; + + /** + * Optional. The time, in symbols, at which the data was transmitted (see 7.5.4.1). + * + * The value of this parameter will be considered valid only if the value of the + * status parameter is SUCCESS; if the status parameter is not equal to + * SUCCESS, the value of the Timestamp parameter will not be used for any other + * purpose. The symbol boundary is described by macSyncSymbolOffset (see Table 86 in 7.4.1). + * + * This is a 24-bit value, and the precision of this value will be a minimum of 20 bits, + * with the lowest 4 bits being the least significant. + */ + uint32_t timestamp; +} mcps_data_conf_t; + + +/** + * @brief MCPS-DATA.request. + * + * @details The MCPS-DATA.request primitive requests the transfer of + * a data SPDU (i.e., MSDU) from a local SSCS entity to a single peer SSCS entity. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.1. + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** Confirm to this request. */ + mcps_data_conf_t confirm; + + /** + * The source addressing mode for this primitive and + * subsequent MPDU. This value can take one of the following values: + * @ref mac_addr_mode_t + * 0x00 = no address (addressing fields omitted, see 7.2.1.1.8). + * 0x01 = reserved. + * 0x02 = 16-bit short address. + * 0x03 = 64-bit extended address. + */ + mac_addr_mode_t src_addr_mode; + + /** + * The destination addressing mode for this primitive + * and subsequent MPDU. + * According to 7.1.1.1.1, Table 41. + */ + mac_addr_mode_t dst_addr_mode; + + /** The 16-bit PAN identifier of the entity to which the MSDU is being transferred. */ + uint16_t dst_pan_id; + + /** The individual device address of the entity to which the MSDU is being transferred. */ + mac_addr_t dst_addr; + + /** The number of octets contained in the MSDU to be transmitted by + * the MAC sublayer entity. + */ + uint8_t msdu_length; + + /** + * The pointer to the set of octets forming the MSDU + * to be transmitted by the MAC sublayer entity. + * + * Caller must provide enough space for MAC and PHY header before this pointer. + */ + uint8_t * msdu; + + /** The handle associated with the MSDU to be transmitted by the MAC sublayer entity. */ + uint8_t msdu_handle; + + /** + * The bits (b0, b1, b2) indicate the transmission options for this MSDU. + * For b0, 1 = acknowledged transmission, 0 = unacknowledged transmission. + * For b1, 1 = GTS transmission, 0 = CAP transmission for a beacon-enabled PAN. + * For b2, 1 = indirect transmission, 0 = direct transmission. + * For a nonbeacon-enabled PAN, bit b1 should always be set to 0. + */ + mac_tx_options_t tx_options; +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID node. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mcps_data_req_t; + +/** + * @brief Private information passed with MCPS-DATA.indication. + * Not covered by the standard. + */ +typedef struct +{ + /** RSSI value, which corresponds to packet that caused this indication. */ + int8_t rssi; + /** Value of a pending bit from MHR. */ + uint8_t pending_bit; +} mcps_data_ind_private_t; + +/** + * @brief MCPS-DATA.indication + * + * @details The MCPS-DATA.indication primitive indicates the transfer of + * a data SPDU (i.e., MSDU) from the MAC sublayer to the local SSCS entity. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.3 + */ +typedef struct +{ + mcps_data_ind_private_t service; + + /** + * The source addressing mode for this primitive corresponding to the received MPDU. + * According to 7.1.1.1.1, Table 43. + */ + mac_addr_mode_t src_addr_mode; + + /** The 16-bit PAN identifier of the entity from which the MSDU was received. */ + uint16_t src_pan_id; + + /** The individual device address of the entity from which the MSDU was received. */ + mac_addr_t src_addr; + + /** + * The destination addressing mode for this primitive corresponding to the received MPDU. + * According to 7.1.1.1.1, Table 43. + */ + mac_addr_mode_t dst_addr_mode; + + /** The 16-bit PAN identifier of the entity to which the MSDU is being transferred. */ + uint16_t dst_pan_id; + + /** The individual device address of the entity to which the MSDU is being transferred. */ + mac_addr_t dst_addr; + + /** The number of octets contained in the MSDU being indicated by the MAC sublayer entity. */ + uint8_t msdu_length; + + /** + * The information that is required for the next higher layer to read incoming message and to + * free the memory allocated for this message. + */ + mac_payload_descriptor_t msdu; + + /** + * LQI value measured during reception of the MPDU. + * Lower values represent lower LQI (see 6.9.8). + */ + uint8_t mpdu_link_quality; + + /** The DSN of the received data frame. */ + uint8_t dsn; + + /** + * Optional. The time, in symbols, at which the data was received (see 7.5.4.1). + * The symbol boundary is described by macSyncSymbolOffset (see Table 86 in 7.4.1). + * + * This is a 24-bit value, and the precision of this value shall be a minimum of 20 bits, + * with the lowest 4 bits being the least significant. + */ + uint32_t timestamp; +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID node. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mcps_data_ind_t; + + +/** + * @brief Confirmation function. + * + * @details The MCPS-DATA.confirm primitive is generated by the MAC sublayer + * entity in response to an MCPS-DATA. request primitive. The MCPS-DATA.confirm + * primitive returns a status of either SUCCESS, indicating that the request to + * transmit was successful, or the appropriate error code. + * The status values are fully described in 7.1.1.1.3 and subclauses referenced by 7.1.1.1.3. + * + * @param Pointer to confirmation primitive. + */ +typedef void (* mcps_data_conf_cb_t)(mcps_data_conf_t *); + + +/** + * @brief MCPS-DATA.request service + * + * @details The MCPS-DATA.request primitive is generated by a local SSCS entity + * when a data SPDU (i.e., MSDU) is to be transferred to a peer SSCS entity. + * After request completion, user callback will be issued with + * valid data stored in structure @ref mcps_data_conf_t. + * + * @param req Pointer to MCPS-DATA request structure. + * @param conf_cb Pointer to confirmation function (user callback). + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.2. + */ +void mcps_data_req(mcps_data_req_t * req, mcps_data_conf_cb_t conf_cb); + + +/** + * @brief MCPS-DATA.indication handler. + * + * @details The MCPS-DATA.indication primitive is generated by the MAC sublayer and + * issued to the SSCS on receipt of a data frame at the local MAC sublayer entity + * that passes the appropriate message filtering operations as described in 7.5.6.2. + * + * @param ind MCPS-DATA.indication structure. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.3. + */ +extern void mcps_data_ind(mcps_data_ind_t * ind); + +/** + * @brief Free memory allocated for incoming message. + * + * @details The function will be invoked after all manipulations + * with MSDU are completed. That is necessary to return the memory allocated by MAC + * into the heap. + * + * @param p_payload_descriptor - Pointer to MSDU descriptor. + */ +void mac_mem_msdu_free(mac_payload_descriptor_t * p_payload_descriptor); + +/** @} */ + +#endif // MAC_MCPS_DATA_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mcps_purge.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mcps_purge.h new file mode 100644 index 0000000000000000000000000000000000000000..3ab0af1395ed64adc8a8299bd002bc08b2881e62 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mcps_purge.h @@ -0,0 +1,152 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MCPS_PURGE_H_INCLUDED +#define MAC_MCPS_PURGE_H_INCLUDED + +#if (CONFIG_PURGE_ENABLED == 1) + +#include +#include "mac_common.h" +#include "mac_task_scheduler.h" + +/** @file + * The MAC Purge module declares the MAC Purge routines and necessary types + * according to the MAC specification. + * + * @defgroup mac_purge MAC MCPS Purge API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MCPS Purge API. + * @details The MAC MCPS Purge module declares the MAC Purge routines and necessary types according to + * the MAC specification. More specifically, MAC purge request mcps_purge_req(), and the + * confirmation callback typedef is declared as mcps_purge_conf_cb_t. An additional primitive + * not covered by the standard is declared. This is mpcs_purge() which is a synchronous version + * of mcps_purge_req(). + */ + +/** + * @brief MCPS-PURGE.confirm. + * + * @details The MCPS-PURGE.confirm primitive allows the MAC sublayer to notify the next higher layer + * of the success of its request to purge an MSDU from the transaction queue. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.5. + */ +typedef struct +{ + /** The handle of the MSDU to be purged from the transaction queue. */ + uint8_t msdu_handle; + + /** The status of the request to be purged an MSDU from the transaction queue. */ + mac_status_t status; +} mcps_purge_conf_t; + + +/** + * @brief MCPS-PURGE.request. + * + * @details The MCPS-PURGE.request primitive allows the next higher layer + * to purge an MSDU from the transaction queue. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.4. + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** Confirmation to this request. */ + mcps_purge_conf_t confirm; + + /** The handle of the MSDU to be purged from the transaction queue. */ + uint8_t msdu_handle; +} mcps_purge_req_t; + + +/** + * @brief Confirmation function. + * + * @details The MCPS-PURGE.confirm primitive is generated by the MAC sublayer + * entity in response to an MCPS-PURGE.request primitive. The MCPS-PURGE.confirm + * primitive returns a status of either SUCCESS, indicating that the purge request + * was successful, or INVALID_HANDLE, indicating an error. + * The status values are fully described in 7.1.1.4.3. + * + * @param Pointer to confirmation primitive. + */ +typedef void (* mcps_purge_conf_cb_t)(mcps_purge_conf_t *); + + +/** + * @brief MCPS-PURGE.request service. + * + * @details The MCPS-PURGE.request primitive is generated by the next higher layer + * whenever an MSDU is to be purged from the transaction queue. + * After request completion, user callback will be issued with + * valid data stored in structure mcps_purge_conf_t. + * + * @param req Pointer to MCPS-PURGE request structure. + * @param conf_cb Pointer to the confirmation function (user callback). + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.4. + */ +void mcps_purge_req(mcps_purge_req_t * req, mcps_purge_conf_cb_t conf_cb); + +/** + * @brief Performs MCPS-PURGE.request directly (without request - confirm approach). + * + * @details Optional. Not covered by the standard. + * + * The MCPS-PURGE.request primitive is generated by the next higher layer + * whenever an MSDU is to be purged from the transaction queue. + * + * @param req Pointer to MCPS-PURGE request structure. + * + * @return Result of the purge procedure. + */ +mac_status_t mcps_purge(mcps_purge_req_t * req); + +/** @} */ + +#endif // (CONFIG_PURGE_ENABLED == 1) + +#endif // MAC_MCPS_PURGE_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_associate.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_associate.h new file mode 100644 index 0000000000000000000000000000000000000000..5b85a8442cce13ebdbcf0ea0dbcf6d0512f034b1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_associate.h @@ -0,0 +1,324 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_ASSOCIATE_H_INCLUDED +#define MAC_MLME_ASSOCIATE_H_INCLUDED + +#include +#include "mac_common.h" +#include "mac_task_scheduler.h" + +/** @file + * The MAC Association module declares the MAC Association routines and necessary types/macros + * according to the MAC specification. + * + * @defgroup mac_assoc MAC MLME Association API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME Association API. + * @details The MLME Association module declares Association MAC routines and necessary macros/types according + * to the MAC specification. More specifically, MLME Association request aka mlme_associate_req(), + * MLME Association confirm callback typedef aka mlme_associate_conf_cb_t, MLME Association indication + * as mlme_associate_ind(), and MLME Response aka mlme_associate_resp() primitives are declared. + */ + +/** + * @brief Capability information field. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.3.1.2. + */ +#define ALTERNATE_PAN_COORDINATOR_BIT (0) +#define DEVICE_TYPE_BIT (1) +#define POWER_SOURCE_BIT (2) +#define RECEIVER_ON_WHEN_IDLE_BIT (3) +#define SECURITY_CAPABILITY_BIT (6) +#define ALLOCATE_ADDRESS_BIT (7) + + +/** + * @brief Capability information field. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.3.1.2. + */ +typedef struct +{ + uint8_t alternate_pan_coordinator : 1; + uint8_t device_type : 1; + uint8_t power_source : 1; + uint8_t rx_on_when_idle : 1; + uint8_t reserved : 2; + uint8_t security_capability : 1; + uint8_t allocate_address : 1; +} mac_capability_t; + +/**@brief The Alternate PAN Coordinator subfield of the Capability Information field. */ +typedef enum +{ + MAC_CAP_CANNOT_BE_PAN_COORD = 0, /**< Device is not capable of becoming + the PAN coordinator.*/ + MAC_CAP_CAN_BE_PAN_COORD /**< Device is capable of becoming + the PAN coordinator.*/ +} mac_cap_alt_pan_coord_t; + +/**@brief The Device Type subfield of the Capability Information field. */ +typedef enum +{ + MAC_CAP_RFD_DEVICE = 0, /**< Device is an RFD.*/ + MAC_CAP_FFD_DEVICE /**< Device is an FFD.*/ +} mac_cap_device_type_t; + +/**@brief The Power Source subfield of the Capability Information field. */ +typedef enum +{ + MAC_CAP_BATTERY_POWERED = 0, /**< Device is not AC-powered.*/ + MAC_CAP_MAINS_POWERED /**< Device is receiving power from the + alternating current mains.*/ +} mac_cap_power_source_t; + +/**@brief The Receiver On When Idle subfield of the Capability Information field. */ +typedef enum +{ + MAC_CAP_RX_OFF_WHEN_IDLE = 0, /**< Device conserves power during idle.*/ + MAC_CAP_RX_ON_WHEN_IDLE /**< Device does not disable its receiver + to conserve power during idle periods.*/ +} mac_cap_rx_when_idle_t; + +/**@brief The Security Capability subfield of the Capability Information field. */ +typedef enum +{ + MAC_CAP_CANNOT_SECURE = 0, /**< Device does not support securing.*/ + MAC_CAP_CAN_SECURE /**< Device is capable of sending and receiving + cryptographically protected MAC frames.*/ +} mac_cap_secure_t; + +/**@brief The Allocate Address subfield of the Capability Information field. */ +typedef enum +{ + MAC_CAP_SHORT_ADDR_NOT_REQ = 0, /**< The coordinator will not allocate a + 16-bit short address as a result of + the association procedure.*/ + MAC_CAP_SHORT_ADDR_REQ /**< The coordinator will allocate a + 16-bit short address as a result of + the association procedure.*/ +} mac_cap_allocate_addr_t; + +#if (CONFIG_ASSOCIATE_REQ_ENABLED == 1) + +/** + * @brief MLME-ASSOCIATE.confirm + * + * The MLME-ASSOCIATE.confirm primitive is generated by the initiating MLME and + * issued to its next higher layer in response to an MLME-ASSOCIATE.request primitive. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.4. + */ +typedef struct +{ + uint16_t assoc_short_address; /**< Association short 16-bit address. */ + mac_status_t status; /**< Status of operation. */ +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_associate_conf_t; + + +/** + * @brief MLME-ASSOCIATE.request. + * + * @details Allows a device to request an association with a coordinator. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.1. + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** Confirmation to this request. */ + mlme_associate_conf_t confirm; + + /** + * A total of 27 channels numbered 0 to 26. + * are available per channel page (section 6.1.2.1). + */ + uint8_t logical_channel; + + /** + * A total of 32 channel pages are available + * with channel pages 3 to 31 being reserved + * for future use (section 6.1.2.2). + */ +#ifdef CONFIG_SUB_GHZ + uint8_t channel_page; /**< Channel page. */ +#endif + mac_addr_mode_t coord_addr_mode; /**< Coordinator address mode. */ + uint16_t coord_pan_id; /**< Coordinator PAN ID. */ + mac_addr_t coord_address; /**< Coordinator address. */ + mac_capability_t capability_information; /**< Capability information. */ +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_associate_req_t; + + +#if (CONFIG_ASSOCIATE_IND_ENABLED == 1) +/** + * @brief MLME-ASSOCIATE.indication. + * + * @details The MLME-ASSOCIATE.indication primitive is generated by the MLME of + * the coordinator and issued to its next higher layer to indicate the reception + * of an association request command. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.2. + */ +typedef struct +{ + uint64_t device_address; /**< 64-bit IEEE address. */ + uint8_t capability_information; /**< Capability information. */ +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_associate_ind_t; + + +/** + * @brief MLME-ASSOCIATE.response. + * + * @details Generated by the next higher layer of a coordinator and issued + * to its MLME in order to respond to the MLME-ASSOCIATE.indication primitive. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.3. + */ +typedef struct +{ + uint64_t device_address; /**< 64-bit IEEE address. */ + uint16_t assoc_short_address; /**< Association short 16-bit address. */ + mac_status_t status; /**< Status of operation. */ +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_associate_resp_t; + +#endif // (CONFIG_ASSOCIATE_IND_ENABLED == 1) + +/** + * @brief Confirmation function. + * + * @details The MLME-ASSOCIATE.confirm primitive is generated by the + * initiating MLME and issued to its next higher layer in response to + * an MLME-ASSOCIATE.request primitive. If the request was successful, + * the status parameter will indicate a successful association, as + * contained in the Status field of the association response command. + * Otherwise, the status parameter indicates either an error code from + * the received association response command or the appropriate error + * code from Table 50. + * The status values are fully described in 7.1.3.1.3 and subclauses referenced by 7.1.3.1.3. + * + * @param Pointer to confirmation primitive. + */ +typedef void (* mlme_associate_conf_cb_t)(mlme_associate_conf_t *); + + +/** + * @brief MLME-ASSOCIATE request. + * + * @details Requests an association with a PAN through a coordinator + * After request completion, user callback will be issued with + * valid data stored in structure mlme_set_conf_t. + * + * @param req MLME_ASSOCIATE request structure. + * @param conf_cb Pointer to user callback. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.5 + */ +void mlme_associate_req(mlme_associate_req_t * req, mlme_associate_conf_cb_t conf_cb); + + +#if (CONFIG_ASSOCIATE_IND_ENABLED == 1) + +/** + * @brief MLME-ASSOCIATE indication handler. + * + * @details Indicates an association with a PAN through a coordinator + * next higher layer of a coordinator receives the MLME-ASSOCIATE.indication + * primitive to determine whether to accept or reject the unassociated device + * using an algorithm outside the scope of standard. + * + * @param ind MLME ASSOCIATE indication structure. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.5. + */ +extern void mlme_associate_ind(mlme_associate_ind_t * ind); + + +/** + * @brief MLME-ASSOCIATE response. + * + * @details Respond to an association with a PAN and issue to its MLME in order to + * respond to the MLME-ASSOCIATE.indication. + * Response structure passed as a parameter to this function must be retained + * in memory until the related MLME-COMM-STATUS.indication is received. + * + * @param resp MLME_ASSOCIATE response structure. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.5. + */ +void mlme_associate_resp(mlme_associate_resp_t * resp); + +#endif // (CONFIG_ASSOCIATE_IND_ENABLED == 1) + +#endif // (CONFIG_ASSOCIATE_REQ_ENABLED == 1) + +/** @} */ + +#endif // MAC_MLME_ASSOCIATE_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_beacon_notify.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_beacon_notify.h new file mode 100644 index 0000000000000000000000000000000000000000..3b6863030796425fb7926abc2910cb20badf768c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_beacon_notify.h @@ -0,0 +1,175 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_BEACON_NOTIFY_H_INCLUDED +#define MAC_MLME_BEACON_NOTIFY_H_INCLUDED + +#include +#include +#include "mac_common.h" +#include "mac_time.h" + +/** @file + * The MAC Beacon notify module declares the MAC beacon notification routine and necessary + * types/macros according to the MAC specification. + * + * @defgroup mac_beacon_notify MAC MLME Beacon Notify API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME Beacon Notify API. + * @details The MAC Beacon Notify module declares Beacon Notify MLME routines and necessary macros/types + * according to the MAC specification. MAC MLME Beacon notify indication is declared as + * mlme_beacon_notify_ind(). + */ + +/**@brief This constant is defined in 7.2.2.1.7 Address List field + * + * @details The maximum number of addresses pending shall be limited to seven and may comprise + * both short and extended addresses. + */ +#define MAC_PENDING_ADDR_MAX 7 + +/*@brief The maximum length of GTS fields inside beacon in octets. + * + * @details This definition is used to allocate memory for outgoing beacon. + */ +#define MAC_MAX_GTS_FIELD_LEN 23 + +/**@brief Superframe specification structure.*/ +typedef struct +{ + uint16_t beacon_order : 4; + uint16_t superframe_order : 4; + uint16_t final_cap_slot : 4; + uint16_t battery_life_extension : 1; + uint16_t reserved : 1; + uint16_t pan_coordinator : 1; + uint16_t association_permit : 1; +} mac_superframe_spec_t; + + +/** @brief List of pending addresses + * Short addresses are at the top of the table. + */ +typedef struct +{ + mac_addr_t addr_list[MAC_PENDING_ADDR_MAX]; + /**< Addresses array. */ + uint8_t short_addr_number; /**< Number of short addresses in the array. */ + uint8_t ext_addr_number; /**< Number of long addresses in the array. */ +} mac_pending_addr_list_t; + +/**@brief PAN Descriptor structure. + * + * @details See Table 55-Elements of PANDescriptor. + */ +typedef struct +{ + mac_addr_mode_t coord_addr_mode; /**< Coordinator addressing mode. */ + uint16_t coord_pan_id; /**< Coordinator PAN ID. */ + mac_addr_t coord_address; /**< Coordinator address. */ + uint8_t logical_channel; /**< Logical channel. */ +#ifdef CONFIG_SUB_GHZ + uint8_t channel_page; /**< Channel page. */ +#endif + mac_superframe_spec_t superframe_spec; /**< Superframe specification. */ + bool gts_permit; /**< Is GTS permitted? */ + uint8_t link_quality; /**< Link quality. */ + mac_timestamp_t timestamp; /**< Timestamp. */ +#if (CONFIG_SECURE == 1) + uint8_t security_failure; /**< Security failure. */ + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mac_pan_descriptor_t; + + +/**@brief Pending Address Specification + * + * @details See Figure 51-Format of the Pending Address Specification field. + */ +typedef struct +{ + uint8_t pending_short : 3; + uint8_t : 1; + uint8_t pending_extended : 3; + uint8_t : 1; +} mac_pend_addr_spec_t; + + +/**@brief MLME-BEACON-NOTIFY.indication parameters + * + * @details See 7.1.5.1 MLME-BEACON-NOTIFY.indication + */ +typedef struct +{ + uint8_t bsn; /**< Beacon sequence number. */ + mac_pan_descriptor_t pan_descriptor; /**< PAN descriptor. */ + mac_pend_addr_spec_t pend_addr_spec; /**< Pending address specification. */ + mac_addr_t addr_list[MAC_PENDING_ADDR_MAX]; + /**< Addresses array. */ + uint8_t sdu_length; /**< SDU length. */ + mac_payload_descriptor_t sdu; /**< SDU. */ +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_beacon_notify_ind_t; + + +/**@brief User implemented function, which handles MLME-BEACON-NOTIFY.indication. + * + * @details The MLME-BEACON-NOTIFY.indication primitive is used to send parameters contained + * within a beacon frame received by the MAC sublayer to the next higher layer. + * The primitive also sends a measure of the LQI and the time the beacon frame + * was received. See 7.1.5.1 MLME-BEACON-NOTIFY.indication. + * + * @param ind MLME-BEACON-NOTIFY.indication parameters. See @ref mlme_beacon_notify_ind_t. + */ +extern void mlme_beacon_notify_ind(mlme_beacon_notify_ind_t * ind); + +/** @} */ + +#endif // MAC_MLME_BEACON_NOTIFY_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_comm_status.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_comm_status.h new file mode 100644 index 0000000000000000000000000000000000000000..3d290f1b50d74d50d4dd73e59cea604969be49a4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_comm_status.h @@ -0,0 +1,128 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_COMM_STATUS_H_INCLUDED +#define MAC_MLME_COMM_STATUS_H_INCLUDED + +#include +#include "mac_common.h" + +/** @file + * The MAC Comm Status module declares the MAC communication status indication routine and + * necessary types/macros according to the MAC specification. + * + * @defgroup mac_comm_status MAC MLME Comm Status API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME Comm Status API. + * @details The MAC Comm Status module declares communication status indication MLME routine and necessary + * macros/types according to the MAC specification. MAC MLME Comm Status indication is declared as + * mlme_comm_status_ind(). + */ + +/** + * @brief MLME-COMM-STATUS.indication + * + * @details The MLME-COMM-STATUS.indication primitive allows the MLME to indicate a + * communication status. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.12.1 + */ +typedef struct +{ + /** + * The 16-bit PAN identifier of the device from which the frame was received or to + * which the frame was being sent. + */ + uint16_t pan_id; + + /** + * The source addressing mode for this primitive. This value can take one of the + * following values: + * @ref mac_addr_mode_t + * 0x00 = no address (addressing fields omitted). + * 0x01 = reserved. + * 0x02 = 16-bit short address. + * 0x03 = 64-bit extended address. + */ + mac_addr_mode_t src_addr_mode; + + /** + * The individual device address of the entity from which the frame causing the error + * originated. + */ + mac_addr_t src_addr; + + /** + * The destination addressing mode for this primitive. + * According to 7.1.12.1.1, Table 69. + */ + mac_addr_mode_t dst_addr_mode; + + /** The individual device address of the device for which the frame was intended. */ + mac_addr_t dst_addr; + + /** The communications status. */ + mac_status_t status; + + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +} mlme_comm_status_ind_t; + + +/** + * @brief MLME-COMM-STATUS.indication handler + * + * @details The MLME-COMM-STATUS.indication primitive is generated by the MLME and issued to its next higher + * layer either following a transmission instigated through a response primitive or on receipt of a frame that + * generates an error in its security processing (see 7.5.8.2.3). + * + * @param ind MLME-COMM-STATUS.indication structure. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.12.1 + */ +extern void mlme_comm_status_ind(mlme_comm_status_ind_t * ind); + +/** @} */ + +#endif // MAC_MLME_COMM_STATUS_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_disassociate.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_disassociate.h new file mode 100644 index 0000000000000000000000000000000000000000..922b9c1032e838efa1ab3f1f9996a387c06bcb25 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_disassociate.h @@ -0,0 +1,199 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_DISASSOCIATE_H_INCLUDED +#define MAC_MLME_DISASSOCIATE_H_INCLUDED + +#if (CONFIG_DISASSOCIATE_ENABLED == 1) + +#include +#include +#include "mac_common.h" +#include "mac_task_scheduler.h" + +/** @file + * The MAC MLME Disassociate module declares the MAC disassociation routines and + * necessary types/macros according to the MAC specification. + * + * @defgroup mac_diassociate MAC MLME Disassociate API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME Disassociate API. + * @details The MLME Disassociation module declares Disassociation MAC routines and necessary types + * according to the MAC specification. More specifically, MLME Disassociation request aka + * mlme_disassociate_req(), MLME Disassociation confirm callback typedef aka + * mlme_disassociate_conf_cb_t, and MLME Disassociation indication as mlme_disassociate_ind() + * primitives are declared. + */ + +/** + * @brief MAC Disassociation Reason field + * + * In accordance with IEEE Std 802.15.4-2006, section 7.3.2.2 + */ +typedef enum +{ + /** The coordinator wishes the device to leave the PAN. */ + MAC_COORD_REASON = 1, + /** The device wishes to leave the PAN. */ + MAC_DEV_REASON = 2 +} mac_disassociate_reason_t; + + +/** + * @brief MLME-DISASSOCIATE.confirm + * + * @details On receipt of the MLME-DISASSOCIATE.confirm primitive, the next + * higher layer of the initiating device is notified of the result of the + * disassociation attempt. If the disassociation attempt was successful, + * the status parameter will be set to SUCCESS. Otherwise, the status parameter + * indicates the error. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.4.3 + */ +typedef struct +{ + mac_status_t status; /**< Status of operation. */ + mac_addr_mode_t device_addr_mode; /**< Device addressing mode. */ + uint16_t device_pan_id; /**< Device PAN ID. */ + mac_addr_t device_address; /**< Device address. */ +} mlme_disassociate_conf_t; + + +/** + * @brief MLME-DISASSOCIATE.request + * + * @details The MLME-DISASSOCIATE.request primitive is generated by the next + * higher layer of an associated device and issued to its MLME to request + * disassociation from the PAN. It is also generated by the next higher layer + * of the coordinator and issued to its MLME to instruct an + * associated device to leave the PAN. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.4.1 + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** Confirm to this request. */ + mlme_disassociate_conf_t confirm; + + mac_addr_mode_t device_addr_mode; /**< Device addressing mode. */ + uint16_t device_pan_id; /**< Device PAN ID. */ + mac_addr_t device_address; /**< Device address. */ + mac_disassociate_reason_t disassociate_reason; /**< Disassociation reason. */ + bool tx_indirect; /**< Is TX indirect? */ +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_disassociate_req_t; + + +/** + * @brief MLME-DISASSOCIATE.indication + * + * @details Is generated by the MLME and issued to its next higher + * layer on receipt of a disassociation notification command. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.4.2 + */ +typedef struct +{ + uint64_t device_address; /**< Device address. */ + mac_disassociate_reason_t disassociate_reason; /**< Disassociation reason. */ +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_disassociate_ind_t; + + +/** + * @brief Customer's function of confirmation + * + * @details The MLME-DISASSOCIATE.confirm primitive is generated by the initiating + * MLME and issued to its next higher layer in response to an MLME-DISASSOCIATE.request + * primitive. This primitive returns a status of either SUCCESS, indicating that the + * disassociation request was successful, or the appropriate error code. + * The status values are fully described in 7.1.4.1.3 and subclauses referenced by 7.1.4.1.3. + * + * @param pointer to confirmation primitive + */ +typedef void (* mlme_disassociate_conf_cb_t)(mlme_disassociate_conf_t *); + + +/** + * @brief MLME-DISASSOCIATE request + * + * @details Request disassociation with a PAN + * After request completion, user callback will be issued with + * valid data stored in structure @ref mlme_disassociate_conf_t. + * + * @param req MLME_DISASSOCIATE request structure. + * @param conf_cb pointer to user callback. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.4.4 + */ +void mlme_disassociate_req(mlme_disassociate_req_t * req, mlme_disassociate_conf_cb_t conf_cb); + + +/** + * @brief MLME-DISASSOCIATE indication handler + * + * @details Indicates an disassociation with a PAN + * + * @param ind MLME_DISASSOCIATE indication structure. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.4.4 + */ +extern void mlme_disassociate_ind(mlme_disassociate_ind_t * ind); + +/** @} */ + +#endif // (CONFIG_DISASSOCIATE_ENABLED == 1) + +#endif // MAC_MLME_DISASSOCIATE_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_gts.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_gts.h new file mode 100644 index 0000000000000000000000000000000000000000..000d349a2f4c0ddf8d65085e4fd3a1dc3c51b6f9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_gts.h @@ -0,0 +1,211 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_GTS_H_INCLUDED +#define MAC_MLME_GTS_H_INCLUDED + +#if (CONFIG_GTS_ENABLED == 1) + +#include +#include "mac_common.h" +#include "mac_task_scheduler.h" + +/** @file + * The MAC MLME GTS module declares the MAC Guaranteed time slots routines and + * necessary types/macros according to the MAC specification. + * + * @defgroup mac_gts MAC MLME GTS API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME GTS API. + * @details The MAC GTS module declares MAC Guaranteed Time Slots routines and necessary types according to + * the MAC specification. More specifically, MLME GTS request aka mlme_gts_req(), MLME GTS indicaton + * aka mlme_gts_ind(), and MLME GTS confirm callback typedef aka mlme_gts_conf_cb_t primitives are + * declared. + */ + +/**@brief GTS directions, from device side. */ +typedef enum +{ + MAC_GTS_DIR_TXONLY = 0, /**< TX only direction. */ + MAC_GTS_DIR_RXONLY = 1 /**< RX only direction. */ +} mac_gts_direction_t; + + +/**@brief GTS characteristics type. */ +typedef enum +{ + MAC_GTS_DEALLOC = 0, /**< GTS Dealloc. */ + MAC_GTS_ALLOC = 1 /**< GTS Alloc. */ +} mac_gts_characteristics_type_t; + + +/**@brief MAC GTS characteristics (not packed) + * + * @details See Section 7.3.9.2 + */ +typedef union +{ + struct + { + uint8_t gts_length : 4; + uint8_t gts_direction : 1; + uint8_t characterictics_type : 1; + uint8_t : 2; + } bit; + uint8_t all; +} mac_gts_characteristics_t; + +/** + * @brief MLME-GTS.confirm + * + * @details The MLME-GTS.confirm primitive reports the results of a + * request to allocate a new GTS or deallocate an existing GTS. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.2 + */ +typedef struct +{ + mac_gts_characteristics_t gts_characteristics; /**< GTS characteristics. */ + mac_status_t status; /**< Status of operation. */ +} mlme_gts_conf_t; + + +/** + * @brief MLME-GTS.request + * + * @details The MLME-GTS.request primitive allows a device to send a request + * to the PAN coordinator to allocate a new GTS or to deallocate an existing GTS. + * This primitive is also used by the PAN coordinator to initiate a GTS deallocation. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.1 + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** Confirm to this request. */ + mlme_gts_conf_t confirm; + + mac_gts_characteristics_t gts_characteristics; /**< GTS characteristics. */ +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_gts_req_t; + + +/** + * @brief MLME-GTS.indication + * + * @details The MLME-GTS.indication primitive indicates that a + * GTS has been allocated or that a previously allocated GTS + * has been deallocated. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.3 + */ +typedef struct +{ + uint16_t device_address; /**< Device address. */ + mac_gts_characteristics_t gts_characteristics; /**< GTS characteristics. */ +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_gts_ind_t; + + +/** + * @brief MLME-GTS confirm callback + * + * @details The MLME-GTS.confirm primitive is generated by the MLME and + * issued to its next higher layer in response to a previously + * issued MLME-GTS.request primitive. + * + * @param MLME_GTS callback structure. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.4 + */ +typedef void (* mlme_gts_conf_cb_t)(mlme_gts_conf_t *); + + +/** + * @brief MLME-GTS request + * + * @details The MLME-GTS.request primitive is generated by the next higher + * layer of a device and issued to its MLME to request the allocation of a + * new GTS or to request the deallocation of an existing GTS. It is also + * generated by the next higher layer of the PAN coordinator and issued to + * its MLME to request the deallocation of an existing GTS. + * + * @param req MLME_GTS request structure. + * @param conf_cb pointer to user callback. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.4 + */ +void mlme_gts_req(mlme_gts_req_t * req, mlme_gts_conf_cb_t conf_cb); + + +/** + * @brief MLME-GTS indication handler + * + * @details The MLME-GTS.indication primitive is generated by the MLME of + * the PAN coordinator to its next higher layer whenever a GTS is allocated + * or deallocated following the reception of a GTS request command (see 7.3.9) + * by the MLME. The MLME of the PAN coordinator also generates this primitive when a GTS + * deallocation is initiated by the PAN coordinator itself. + * + * @param ind MLME_GTS indication structure. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.4 + */ +extern void mlme_gts_ind(mlme_gts_ind_t * ind); + +/** @} */ + +#endif // (CONFIG_GTS_ENABLED == 1) + +#endif // MAC_MLME_GTS_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_orphan.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_orphan.h new file mode 100644 index 0000000000000000000000000000000000000000..b2de2af838f80f70615a9c8b989a5de7f6400586 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_orphan.h @@ -0,0 +1,151 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_ORPHAN_H_INCLUDED +#define MAC_MLME_ORPHAN_H_INCLUDED + +#if (CONFIG_ORPHAN_ENABLED == 1) + +#include +#include +#include "mac_common.h" + +/** @file + * The MAC MLME Orphan module declares the MAC Orphan routines and + * necessary types/macros according to the MAC specification. + * + * @defgroup mac_orphan MAC MLME Orphan API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME Orphan API. + * @details The MAC Orphan module declares routines and necessary types to deal with the Orphan devices + * according to the MAC specification. More specifically, MAC MLME Orphan indication aka + * mlme_orphan_ind(), MAC MLME Orphan response aka mlme_orphan_resp() primitives are declared. + */ + +/** + * @brief MLME-ORPHAN.indication + * + * @details The MLME-ORPHAN.indication primitive allows the MLME of a coordinator + * to notify the next higher layer of the presence of an orphaned device. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.8.1 + */ +typedef struct +{ + /** The address of the orphaned device. */ + uint64_t orphan_address; +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_orphan_ind_t; + + +/** + * @brief MLME-ORPHAN.response + * + * @details The MLME-ORPHAN.response primitive allows the next higher layer of a coordinator + * to respond to the MLME-ORPHAN.indication primitive. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.8.2 + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** The address of the orphaned device. */ + uint64_t orphan_address; + + /** + * The 16-bit short address allocated to the orphaned device if it is associated with this + * coordinator. The special short address 0xfffe indicates that no short address was + * allocated, and the device will use its 64-bit extended address in all communications. + * If the device was not associated with this coordinator, this field will contain the + * value 0xffff and be ignored on receipt. + */ + uint16_t short_address; + + /** TRUE if the orphaned device is associated with this coordinator or FALSE otherwise. */ + bool associated_member; +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_orphan_resp_t; + + +/** + * @brief MLME-ORPHAN.indication handler + * + * @details The MLME-ORPHAN.indication primitive is generated by the MLME of a coordinator + * and issued to its next higher layer on receipt of an orphan notification command (see 7.3.6). + * + * @param ind MLME-ORPHAN.indication structure. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.8.1 + */ +extern void mlme_orphan_ind(mlme_orphan_ind_t * ind); + + +/** + * @brief MLME-ORPHAN.response handler + * + * @details The MLME-ORPHAN.response primitive is generated by the next higher layer and issued to its MLME + * when it reaches a decision about whether the orphaned device indicated in the MLME-ORPHAN.indication + * primitive is associated. + * + * @param resp MLME-ORPHAN.response structure. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.8.2 + */ +void mlme_orphan_resp(mlme_orphan_resp_t * resp); + +/** @} */ + +#endif // (CONFIG_ORPHAN_ENABLED == 1) + +#endif // MAC_MLME_ORPHAN_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_pib.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_pib.h new file mode 100644 index 0000000000000000000000000000000000000000..cca2585de0f2c961861be18d3fed90b3d0ceec2c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_pib.h @@ -0,0 +1,506 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_PIB_H_INCLUDED +#define MAC_MLME_PIB_H_INCLUDED + +#include +#include "mac_common.h" +#include "phy_plme_pib.h" +#include "mac_task_scheduler.h" +#include "mac_security.h" +#include "sys_debug.h" + +/** @file + * The MAC MLME PIB module declares the MAC PHY Information Base routines and + * necessary types/macros according to the MAC specification. + * + * @defgroup mac_pib MAC MLME PIB API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME PIB API. + * @details The MAC PIB module declares routines and necessary types to deal with the PHY Information Base + * functionality related to MAC. More specifically, MLME PIB Get request aka mlme_get_req(), MLME + * PIB Set request aka mlme_set_req(), MLME PIB confirmation callbacks aka mlme_get_conf_cb_t, and + * mlme_set_conf_cb_t primitives are declared. Two additional primitives not covered by the + * standard are declared. These are mlme_get() and mlme_set() which are synchronous versions of + * mlme_get_req() and mlme_set_req() accordingly. There is one helper informational routine + * mlme_pib_attr_size_calc() to count MLME attribute size in bytes. Refer to the + * mac_pib_param_test application for detailed samples of implementation of these primitives. + * This module also defines the MAC Table API. The tables can be used to deal with MAC attributes. + * A special initialization routine mac_table_init() should be called before using of any other MAC + * table API. The mac_table_reset() routine is used to clean up an existing (initialized) table. + * mac_table_idx_get() searches through a MAC table to find the item with requested idx. The + * mac_table_item_set() routine is needed to substitute a table item with a new value. The + * mac_table_item_remove() routine removes the item with the given index from the table and + * frees all resources associated with the item. mac_table_item_front() and mac_table_item_next() + * return the first and next item from the table. The mac_table_size_get() routine returns the + * number of items in the table, while mac_table_is_empty() checks if the table is empty. + */ + +/** + * @brief MAC PIB attribute identificators + * + * In accordance with IEEE Std 802.15.4-2006, section 7.4.2 + */ +typedef enum +{ + MAC_ACK_WAIT_DURATION = 0x40, + MAC_ASSOCIATION_PERMIT, + MAC_AUTO_REQUEST, + MAC_BATT_LIFE_EXT, + MAC_BATT_LIFE_EXT_PERIODS, + MAC_BEACON_PAYLOAD, /* 0x45 */ + MAC_BEACON_PAYLOAD_LENGTH, + MAC_BEACON_ORDER, /**< Specification of how often the + coordinator transmits its + beacon. If BO = 15, the + coordinator will not transmit + a periodic beacon.*/ + MAC_BEACON_TX_TIME, + MAC_BSN, + MAC_COORD_EXTENDED_ADDRESS, /* 0x4A */ + MAC_COORD_SHORT_ADDRESS, + MAC_DSN, + MAC_GTS_PERMIT, + MAC_MAX_CSMA_BACKOFFS, + MAC_MIN_BE, + MAC_PAN_ID, /* 0x50 */ + MAC_PROMISCUOUS_MODE, + MAC_RX_ON_WHEN_IDLE, + MAC_SHORT_ADDRESS, + MAC_SUPERFRAME_ORDER, + MAC_TRANSACTION_PERSISTENCE_TIME, /* 0x55 */ + MAC_ASSOCIATED_PAN_COORD, + MAC_MAX_BE, + MAC_MAX_FRAME_TOTAL_WAIT_TIME, + MAC_MAX_FRAME_RETRIES, + MAC_RESPONSE_WAIT_TIME, /* 0x5A */ + MAC_SYNC_SYMBOL_OFFSET, + MAC_TIMESTAMP_SUPPORTED, + MAC_SECURITY_ENABLED, + MAC_MIN_LIFS_PERIOD, /* 0x5E No attribute id in Table 86.*/ + MAC_MIN_SIFS_PERIOD, /* 0x5F No attribute id in Table 86.*/ + MAC_EXTENDED_ADDRESS, /* 0x60 Not covered by standard.*/ + MAC_IS_PAN_COORD, + +#if (CONFIG_SECURE == 1) + MAC_KEY_TABLE = 0x71, + MAC_KEY_TABLE_ENTRIES, + MAC_DEVICE_TABLE, + MAC_DEVICE_TABLE_ENTRIES, + MAC_SECURITY_LEVEL_TABLE, /* 0x75 */ + MAC_SECURITY_LEVEL_TABLE_ENTRIES, + MAC_FRAME_COUNTER, + MAC_AUTO_REQUEST_SECURITY_LEVEL, + MAC_AUTO_REQUEST_KEY_ID_MODE, + MAC_AUTO_REQUEST_KEY_SOURCE, /* 0x7A */ + MAC_AUTO_REQUEST_KEY_INDEX, + MAC_DEFAULT_KEY_SOURCE, + MAC_PAN_COORD_EXTENDED_ADDRESS, + MAC_PAN_COORD_SHORT_ADDRESS, + + /* Items below do not covered by the standard */ + + // these three IDs are used to make access to the root of security tables + MAC_KEY_TABLE_POINTER, + MAC_DEVICE_TABLE_POINTER, + MAC_SECURITY_LEVEL_TABLE_POINTER, + + // these three IDs are stored inside PIB base and + // used to get table item sizes + MAC_KEY_ID_LOOKUP_LIST, + MAC_KEY_DEVICE_LIST, + MAC_KEY_USAGE_LIST, +#endif +} mlme_pib_attr_id_t; + + +/** + * @brief United PIB attribute identifiers + * + * To unite access to MAC and PHY PIB by one API + */ +typedef union +{ + mlme_pib_attr_id_t mlme_id; /**< PIB is MAC-based. */ + plme_pib_attr_id_t plme_id; /**< PIB is PHY-based. */ +} pib_id_t; + + +/** + * @brief MLME-GET.confirm + * + * @details structure for confirming information about a given PIB attribute. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.6.2 + */ +typedef struct +{ + mac_status_t status; /**< Status of operation. */ + pib_id_t pib_attribute; /**< PIB Attribute. */ + uint8_t pib_attribute_idx; /**< PIB Attribute index. */ + /** value size is calculated with 'mlme_pib_attr_size_calc' */ + uint8_t * value; /**< Attribute value. */ +} mlme_get_conf_t; + + +/** + * @brief MLME-GET.request + * + * @details structure for requesting information about a given PIB attribute. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.6.1 + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** Confirm to this request. */ + mlme_get_conf_t confirm; + + pib_id_t pib_attribute; /**< PIB Attribute. */ + uint8_t pib_attribute_idx; /**< PIB Attribute index. */ +} mlme_get_req_t; + + +/** + * @brief MLME-SET.confirm + * + * @details structure for reporting the results of an attempt to write a value + * to a PIB attribute. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.13.2 + */ +typedef struct +{ + mac_status_t status; /**< Status of operation. */ + pib_id_t pib_attribute; /**< PIB Attribute. */ + uint8_t pib_attribute_idx; /**< PIB Attribute index. */ +} mlme_set_conf_t; + + +/** + * @brief MLME-SET.request + * + * @details structure for setting a PIB attribute. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.13.1 + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** Confirm to this request. */ + mlme_set_conf_t confirm; + + pib_id_t pib_attribute; /**< PIB Attribute. */ + uint8_t pib_attribute_idx; /**< PIB Attribute index. */ + uint8_t * value; /**< Attribute value. The value size is calculated + with mlme_pib_attr_size_calc. */ +} mlme_set_req_t; + + +/** + * @brief Customer's function of confirmation + * + * @details The MLME-GET.confirm primitive is generated by the MLME and issued + * to its next higher layer in response to an MLME-GET.request primitive. + * This primitive returns a status of either SUCCESS, indicating that the request + * to read a PIB attribute was successful, or an error code of UNSUPPORTED_ATTRIBUTE. + * When an error code of UNSUPPORTED_ATTRIBUTE is returned, the PIBAttribute value + * parameter will be set to length zero. The status values are fully described in 7.1.6.1.3. + * + * @param pointer to confirmation primitive + */ +typedef void (* mlme_get_conf_cb_t)(mlme_get_conf_t *); + + +/** + * @brief Customer's function of confirmation + * + * @details The MLME-SET.confirm primitive is generated by the MLME and issued to its + * next higher layer in response to an MLME-SET.request primitive. The MLME-SET.confirm + * primitive returns a status of either SUCCESS, indicating that the requested value was + * written to the indicated PIB attribute, or the appropriate error code. + * The status values are fully described in 7.1.13.1.3. + * + * @param pointer to confirmation primitive + */ +typedef void (* mlme_set_conf_cb_t)(mlme_set_conf_t *); + + +/** + * @brief MLME-GET request + * + * @details Request information about a given PIB attribute. + * + * @param[in] req pointer to request structure. + * @param[in] conf_cb pointer to user callback. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.6. + * See \a mlme_get() for more details. + */ +void mlme_get_req(mlme_get_req_t * req, mlme_get_conf_cb_t conf_cb); + + +/** + * @brief MLME-SET request + * + * @details Request to set a PIB attribute. + * After request completion, user callback will be issued with + * valid data stored in structure @ref mlme_set_conf_t. + * + * See \a mlme_set() for more details. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.13 + * + * @param[in] req MLME_SET request structure. + * @param[in] conf_cb pointer to user callback. + */ +void mlme_set_req(mlme_set_req_t * req, mlme_set_conf_cb_t conf_cb); + + +/** + * @brief Counts MLME attribute size + * + * @details This is an implementation-specific function not covered by the standard. + * + * @param[in] id attribute id. + * @param[in] idx index inside the table in case the attribute is a table. + * + * @return size of attribute in bytes. + */ +size_t mlme_pib_attr_size_calc(pib_id_t id, uint8_t idx); + + +/** + * @brief Gets parameters from PIB directly (without request - confirm approach) + * + * @details Optional. Not covered by a standard. + * + * For non-tabled attributes this function will return value to location + * passed to the last argument. + * + * For tabled attributes this function will return pointer to + * a descriptor structure of corresponding table. + * + * @param[in] id attribute id. + * @param[in] idx index inside the table in case the attribute is a table. + * @param[out] mem either pointer to memory where attribute value is returned + * (for all attributes except MAC_KEY_TABLE, MAC_DEVICE_TABLE, + * MAC_SECURITY_LEVEL_TABLE), or pointer to memory where pointer + * to attribute storage place is returned. + * + * @return status of operation + */ +mac_status_t mlme_get(pib_id_t id, uint8_t idx, void * mem); + + +/** + * @brief Sets parameters to PIB directly (without request - confirm approach) + * + * @details Optional. Not covered by a standard. + * + * This function performs copying or replacement of some attribute value + * into the PIB base memory. + * + * Note, that all security tables are copied into dynamic memory, that + * mlme_set is responsible to allocate. For nested tables copying is done + * in a shallow manner (in Python sense). It means that passed \a mac_key_descr_t + * is copied as-is, without creating copies of internal tables. + * Caller must allocate and prepare all nested tables such as + * #MAC_KEY_DEVICE_LIST, #MAC_KEY_ID_LOOKUP_LIST and #MAC_KEY_USAGE_LIST + * before calling this function. + * + * Passed attribute value will replace the current one, if the item with such + * \a id and \a idx already exists. This function is responsible for + * freeing all items during destruction of existing objects. + * + * @note Nested tables may be expanded and reduced with \a mac_table_item_set() + * and other similar functions. + * + * @param[in] id attribute id. + * @param[in] idx index inside the table in case the attribute is a table. + * @param[out] mem pointer to memory for parameter storing. + * + * @return status of operation + */ +mac_status_t mlme_set(pib_id_t id, uint8_t idx, void * mem); + + +#if (CONFIG_SECURE == 1) +/** + * @brief Initializes a table. This function MUST be called before accessing + * to a newly allocated table. + * + * @param[out] p_table Pointer to a fresh table. + */ +void mac_table_init(mac_table_t * p_table); + +/** + * @brief Resets a table, freeing all its elements. + * + * @param[in] p_table Pointer to the table to reset. + * @param[in] id One of #MAC_KEY_TABLE, #MAC_DEVICE_TABLE, #MAC_SECURITY_LEVEL_TABLE, + * #MAC_KEY_ID_LOOKUP_LIST, #MAC_KEY_DEVICE_LIST, #MAC_KEY_USAGE_LIST to let + * function know about the size of p_item. + */ +void mac_table_reset(mac_table_t * p_table, mlme_pib_attr_id_t id); + +/** + * @brief Searches through mac_table_t and finds the item with requested idx. + * + * @param[in] p_table Table to search through. + * @param[in] idx Item idx to match. + * + * @return Pointer to mac_table_item_t with requested idx or NULL if such + * an item cannot be found. + */ +mac_table_item_t * mac_table_idx_get(const mac_table_t * p_table, uint8_t idx); + +/** + * @brief Sets new value item for mac_table_t. + * + * @param[out] p_table Pointer to the table to add item to. + * @param[in] p_item Pointer to a new item. This item must include appropriate idx + * (less than the maximum table size). + * @param[in] id One of #MAC_KEY_TABLE, #MAC_DEVICE_TABLE, #MAC_SECURITY_LEVEL_TABLE, + * #MAC_KEY_ID_LOOKUP_LIST, #MAC_KEY_DEVICE_LIST, #MAC_KEY_USAGE_LIST to let + * function know about the size of p_item. + * @param[in] idx Item index inside the selected table. + * + * @details This function performs a "deep copy" of passed table item to conform with + * mlme_set behavior. New copy resides in the heap memory. If an item with requested + * idx has been already set earlier, this function frees the old item and pushes + * a new one instead. + * + * @retval #MAC_INVALID_INDEX if idx exceeds allowed maximum number of items in + * the table. + * @retval #MAC_LIMIT_REACHED if there is no enough dynamic memory to put this item + * into the security table. + * @retval #MAC_SUCCESS if insertion has been performed successfully. + */ +mac_status_t mac_table_item_set(mac_table_t * p_table, + const mac_table_item_t * p_item, + mlme_pib_attr_id_t id, + uint8_t idx); + +/** + * @brief Removes an item from a mac_table_t instance and frees all resources, + * associated with this item. + * + * @param[out] p_table Pointer to the table to remove item from. + * @param[in] id One of #MAC_KEY_TABLE, #MAC_DEVICE_TABLE, #MAC_SECURITY_LEVEL_TABLE, + * #MAC_KEY_ID_LOOKUP_LIST, #MAC_KEY_DEVICE_LIST, #MAC_KEY_USAGE_LIST to let + * function perform down-casting correctly. + * @param[in] idx Item index inside of selected table. + * + * @retval #MAC_INVALID_INDEX if passed index is not found in the table or exceeds + * the allowed maximum. + * @retval #MAC_SUCCESS if no errors happen during removing. + */ +mac_status_t mac_table_item_remove(mac_table_t * p_table, + mlme_pib_attr_id_t id, + uint8_t idx); + +/** + * @brief Gets first available item from a table. + * + * @details This function might be used along with \a mac_table_item_next to + * search through some table. + * + * @param[in] p_table Pointer to a MAC table. + * + * @return Pointer to the first table item or NULL if the table is empty. + */ +mac_table_item_t * mac_table_item_front(const mac_table_t * p_table); + +/** + * @brief Returns the next available item in table. + * + * @details MAC tables are stored unsorted in memory, so there is no guarantee that + * index of the next item is always greater or smaller than the current one. + * Items are not stored in chronological order either. + * + * @param[in] p_table Pointer to a table to select item from. + * @param[in] p_current_item Pointer to the current item. + * + * @return Pointer to the next item in table or NULL, if the item is the last one. + */ +mac_table_item_t * mac_table_item_next(const mac_table_t * p_table, + const mac_table_item_t * p_current_item); + +/** + * @brief Gets number of items used inside mac_table_t. + * + * @param[in] p_table Pointer to interested table. + * + * @return 8-bit integer equal to number of items inside the table that have + * been set at least once. + */ +static inline uint8_t mac_table_size_get(const mac_table_t * p_table) +{ + ASSERT(p_table != NULL); + + return p_table->size; +} + +/** + * @brief This function checks if a MAC table is empty. + * + * @param[in] p_table Pointer to a MAC table. + * + * @return true if there are no items inside table, false otherwise. + */ +static inline bool mac_table_is_empty(const mac_table_t * p_table) +{ + ASSERT(p_table != NULL); + + return sys_queue_is_empty(&p_table->queue); +} +#endif + +/** @} */ + +#endif // MAC_MLME_PIB_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_poll.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_poll.h new file mode 100644 index 0000000000000000000000000000000000000000..acb4bb672dc8026732f102d7c63398c4b8002839 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_poll.h @@ -0,0 +1,151 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_POLL_H_INCLUDED +#define MAC_MLME_POLL_H_INCLUDED + +#include +#include "mac_common.h" +#include "mac_task_scheduler.h" + +/** @file + * The MAC MLME Poll module declares the MAC Poll primitives and necessary types + * according to the MAC specification. + * + * @defgroup mac_poll MAC MLME Poll API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME Poll API. + * @details The MAC Poll module declares MLME Poll primitives and necessary types according to + * the MAC specification. More specifically, MLME Poll request aka mlme_poll_req(), MLME Poll + * indicaton aka mlme_poll_ind(), and MLME Poll confirm callback typedef aka mlme_poll_conf_cb_t + * primitives are declared. + */ + +/**@brief MLME-POLL.confirm + * + * @details The MLME-POLL.confirm primitive reports the results of a request + * to poll the coordinator for data. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.16.2 + */ +typedef struct +{ + mac_status_t status; /**< Status of operation. */ +} mlme_poll_conf_t; + + +/**@brief MLME-POLL.request + * + * @details The MLME-POLL.request primitive prompts the device + * to request data from the coordinator. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.16.1 + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** Confirm to this request. */ + mlme_poll_conf_t confirm; + + mac_addr_mode_t coord_addr_mode; /**< Coordinator address mode. */ + uint16_t coord_pan_id; /**< Coordinator PAN ID. */ + mac_addr_t coord_address; /**< Coordinator address. */ +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_poll_req_t; + +/** @brief MLME-Poll.indication + * + * @details The MLME-POLL.indication primitive indicates the reception + * of a Data request command frame by the MAC sub-layer and issued to + * the local SSCS (service specific convergence sublayer). + */ +typedef struct +{ + mac_addr_mode_t src_addr_mode; /**< Source address mode. */ + mac_addr_t src_address; /**< Source address. */ +} mlme_poll_ind_t; + + +/**@brief Prototype of the user-implemented MLME-POLL.confirm callback function. + * + * @details The MLME-POLL.confirm primitive is generated by the MLME and issued + * to its next higher layer in response to an MLME-POLL.request primitive. + * If the request was successful, the status parameter will be equal to SUCCESS, + * indicating a successful poll for data. Otherwise, the status parameter indicates the + * appropriate error code. The status values are fully described in 7.1.16.1.3 and + * the subclauses referenced by 7.1.16.1.3. + * + * @param pointer to a confirmation primitive. + */ +typedef void (* mlme_poll_conf_cb_t)(mlme_poll_conf_t *); + + +/**@brief MLME-POLL.request + * + * @details The MLME-POLL.request primitive is generated by the next higher layer and + * issued to its MLME when data are to be requested from a coordinator. + * + * @param[in] req MLME-POLL.request parameters + * @param[in] conf_cb User-implemented callback function, which will be + * called by MLME in order to pass MLME-POLL.confirm to the user. + */ +void mlme_poll_req(mlme_poll_req_t * req, mlme_poll_conf_cb_t conf_cb); + +/**@brief MLME-POLL.indication + * + * @details The MLME-Poll.indication primitive notifies the next higher level that + * a request for data has been received. + * + * @param[in] p_ind pointer to a poll indication structure + */ +extern void mlme_poll_ind(mlme_poll_ind_t * p_ind); + +/** @} */ + +#endif // MAC_MLME_POLL_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_reset.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_reset.h new file mode 100644 index 0000000000000000000000000000000000000000..8e1c6e64d90a733163832ffa850aece485501328 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_reset.h @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_RESET_H_INCLUDED +#define MAC_MLME_RESET_H_INCLUDED + +#include +#include +#include "mac_common.h" +#include "mac_task_scheduler.h" + +/** @file + * The MAC MLME Reset module declares the MAC Reset primitives and necessary types + * according to the MAC specification. + * + * @defgroup mac_reset MAC MLME Reset API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME Reset API. + * @details The MAC Reset module declares MLME Reset primitives and necessary types according to + * the MAC specification. More specifically, MLME Reset request aka mlme_reset_req(), and MLME + * Reset confirm callback typedef aka mlme_reset_conf_cb_t primitives are declared. + */ + +/**@brief MLME-Reset.confirm + * + * @details The MLME-Reset.confirm primitive reports the results of a request + * to reset MAC layer of the device. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.9.2 + */ +typedef struct +{ + mac_status_t status; /**< Status of operation. */ +} mlme_reset_conf_t; + +/**@brief MLME-RESET.request + * + * @details The MLME-RESET.request primitive allows the next + * higher layer to request that the MLME performs a reset operation. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.9.1 + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** Confirm to this request. */ + mlme_reset_conf_t confirm; + + bool set_default_pib; /**< Set the default PIB. */ +} mlme_reset_req_t; + + +/** + * @brief MLME-RESET confirm callback + * + * @details The MLME-RESET.confirm primitive is generated by the MLME and + * issued to its next higher layer in response to an MLME-RESET.request primitive and + * following the receipt of the PLME-SET-TRXSTATE.confirm primitive. + * + * @param reset status (@c MAC_SUCCESS only). + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.9.2 + */ +typedef void (* mlme_reset_conf_cb_t)(mlme_reset_conf_t *); + + +/** + * @brief MLME-RESET request + * + * @details The MLME-RESET.request primitive is generated by the next higher layer and + * issued to the MLME to request a reset of the MAC sublayer to its initial conditions. + * The MLME-RESET.request primitive is issued prior to the use of the MLME-START.request + * or the MLME-ASSOCIATE.request primitives. + * + * @param[in] req pointer to MCPS-RESET.request structure. + * @param[in] conf_cb pointer to user callback. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.9.1 + */ +void mlme_reset_req(mlme_reset_req_t * req, mlme_reset_conf_cb_t conf_cb); + +/** @} */ + +#endif // MAC_MLME_RESET_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_rx_enable.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_rx_enable.h new file mode 100644 index 0000000000000000000000000000000000000000..9873cae2850e8b031627075e7a319024c11c172e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_rx_enable.h @@ -0,0 +1,181 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_RX_ENABLE_H_INCLUDED +#define MAC_MLME_RX_ENABLE_H_INCLUDED + +#if (CONFIG_RXE_ENABLED == 1) + +#include +#include +#include "mac_common.h" +#include "mac_task_scheduler.h" + +/** @file + * The MAC MLME RX-Enable module declares the MAC RX-Enable primitives and necessary types + * according to the MAC specification. + * + * @defgroup mac_rx_enable MAC MLME RX-Enable API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME RX-Enable API. + * @details The MAC RX-Enable module declares MLME RX-Enable primitives and necessary types according to + * the MAC specification. More specifically, MLME RX-Enable request aka mlme_rx_enable_req(), + * and MLME RX-Enable confirm callback typedef aka mlme_rx_enable_conf_cb_t primitives are + * declared. One additional primitive not covered by the standard is declared. This is + * mlme_rx_enable() which is synchronous (i.e. does not require confirmation) version of + * mlme_rx_enable_req(). + */ + +/** + * @brief MLME-RX-ENABLE.confirm + * + * @details The MLME-RX-ENABLE.confirm primitive reports the results of an attempt + * to enable or disable the receiver. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.10.2 + */ +typedef struct +{ + mac_status_t status; /**< Status of operation. */ +} mlme_rx_enable_conf_t; + + +/** + * @brief MLME-RX-ENABLE.request + * + * @details The MLME-RX-ENABLE.request primitive allows the next higher layer + * to request that the receiver is either enabled for a finite period of time or disabled. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.10.1 + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** Confirm to this request. */ + mlme_rx_enable_conf_t confirm; + + /** + * @details + * TRUE if the requested operation can be deferred until the next superframe + * if the requested time has already passed. + * FALSE if the requested operation is only to be attempted in the current superframe. + * + * If the issuing device is the PAN coordinator, the term superframe refers to its own + * superframe. Otherwise, the term refers to the superframe of the coordinator through + * which the issuing device is associated. + * + * @note This parameter is ignored for nonbeacon-enabled PANs. + */ + bool defer_permit; + + /** + * @details + * The number of symbols measured from the start of the superframe before the receiver is + * to be enabled or disabled. + * This is a 24-bit value, and the precision of this value shall be a minimum of 20 bits, + * with the lowest 4 bits being the least significant. + * + * If the issuing device is the PAN coordinator, the term superframe refers to its own + * superframe. Otherwise, the term refers to the superframe of the coordinator through + * which the issuing device is associated. + * + * @note This parameter is ignored for nonbeacon-enabled PANs. + */ + uint32_t rx_on_time; + + /** + * The number of symbols the receiver is to be enabled for. + * + * If this parameter is equal to 0x000000, the receiver is to be disabled. + */ + uint32_t rx_on_duration; +} mlme_rx_enable_req_t; + + +/** + * @brief Customer's function of confirmation. + * + * @details The MLME-RX-ENABLE.confirm primitive is generated by the MLME and issued to + * its next higher layer in response to an MLME-RX-ENABLE.request primitive. + * + * @param pointer to a confirmation primitive. + */ +typedef void (* mlme_rx_enable_conf_cb_t)(mlme_rx_enable_conf_t *); + +/** + * @brief MLME-RX-ENABLE.request service + * + * @details The MLME-RX-ENABLE.request primitive is generated by the next higher layer and + * issued to the MLME to enable the receiver for a fixed duration, at a time relative to the + * start of the current or next superframe on a beacon-enabled PAN or immediately on a + * nonbeacon-enabled PAN. This primitive may also be generated to cancel a previously generated + * request to enable the receiver. After request completion, user callback will be issued with + * valid data stored in structure mlme_rx_enable_conf_t. + * + * @note The receiver is enabled or disabled exactly once per primitive request. + * + * @param[in] req pointer to MLME-RX-ENABLE request structure. + * @param[in] conf_cb - pointer to confirm function (user callback). + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.10.1 + */ +void mlme_rx_enable_req(mlme_rx_enable_req_t * req, mlme_rx_enable_conf_cb_t conf_cb); + + +/** + * @brief Enables permission for receiving. + * + * @details Optional. Not covered by a standard. + * + * @param[in] req pointer to MLME-RX-ENABLE request structure. + * + * @return status of operation. + */ +mac_status_t mlme_rx_enable(mlme_rx_enable_req_t * req); + +/** @} */ + +#endif // (CONFIG_RXE_ENABLED == 1) + +#endif // MAC_MLME_RX_ENABLE_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_scan.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_scan.h new file mode 100644 index 0000000000000000000000000000000000000000..1b5342411f84b5ddcb0fe00237834d3c3fbf5bbd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_scan.h @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_SCAN_H_INCLUDED +#define MAC_MLME_SCAN_H_INCLUDED + +#include +#include "mac_common.h" +#include "mac_mlme_beacon_notify.h" +#include "mac_task_scheduler.h" + +/** @file + * The MAC MLME Scan module declares the MAC Scan primitives and necessary types + * according to the MAC specification. + * + * @defgroup mac_scan MAC MLME Scan API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME Scan API. + * @details The MAC Scan module declares MLME Scan primitives and necessary types according to + * the MAC specification. More specifically, MLME Scan request aka mlme_scan_req(), and MLME + * Scan confirm callback typedef aka mlme_scan_conf_cb_t primitives are declared. + */ + +/**@brief Type of scan. */ +typedef enum +{ + ED_SCAN = 0, /**< Energy detection scan. */ + ACTIVE_SCAN, /**< Active scan. */ + PASSIVE_SCAN, /**< Passive scan. */ + ORPHAN_SCAN /**< Orphan scan. */ +} mac_scan_type_t; + +/** + * @brief MLME-SCAN.confirm + * + * @details The MLME-SCAN.confirm reports the result of the channel scan request. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.11.2 + */ +typedef struct +{ + mac_status_t status; /**< Status of operation. */ + mac_scan_type_t scan_type; /**< Scan type. */ +#ifdef CONFIG_SUB_GHZ + uint8_t channel_page; /**< Channel page. */ +#endif + uint32_t unscanned_channels; /**< Unscanned channels. */ + uint8_t result_list_size; /**< Result list size. */ + uint8_t * energy_detect_list; /**< Energy detection list. */ + mac_pan_descriptor_t * pan_descriptor_list; /**< PAN descriptor list. */ +} mlme_scan_conf_t; + +/** + * @brief MLME-SCAN.request + * + * @details The MLME-SCAN.request primitive is used to initiate a channel + * scan over a given list of channels. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.11.1 + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** Confirm to this request. */ + mlme_scan_conf_t confirm; + + mac_scan_type_t scan_type; /**< Scan type. */ + uint32_t scan_channels; /**< Scan channels. */ + uint8_t scan_duration; /**< Scan duration. */ + + uint8_t pan_descriptors_buf_size; /**< PAN descriptor buffer size. */ + mac_pan_descriptor_t * pan_descriptors_buf; /**< PAN descriptor buffer. */ + + uint8_t energy_detect_buf_size; /**< Energy detection buffer size. */ + uint8_t * energy_detect_buf; /**< Energy detection buffer. */ + +#ifdef CONFIG_SUB_GHZ + uint8_t channel_page; /**< Channel page. */ +#endif +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_scan_req_t; + + +/** + * @brief User callback to scan request. + * + * @details The MLME-SCAN.confirm primitive is generated by the MLME and issued to + * its next higher layer when the channel scan initiated with + * the MLME-SCAN.request primitive has completed. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.11.2 + */ +typedef void (* mlme_scan_conf_cb_t)(mlme_scan_conf_t *); + + +/** + * @brief MLME-SCAN request + * + * @details The MLME-SCAN.request primitive is generated by the next higher layer and + * issued to its MLME to initiate a channel scan to search for activity within the POS + * of the device. This primitive can be used to perform an ED scan to determine channel + * usage, an active or passive scan to locate beacon frames containing any PAN identifier, + * or an orphan scan to locate a PAN to which the device is currently associated. + * + * @param[in] req MLME-SCAN request structure. + * @param[in] conf_cb pointer to user callback. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.11.1 + */ +void mlme_scan_req(mlme_scan_req_t * req, mlme_scan_conf_cb_t conf_cb); + +/** @} */ + +#endif // MAC_MLME_SCAN_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_start.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_start.h new file mode 100644 index 0000000000000000000000000000000000000000..173e539aab394274ba5ee8e8ce698725339a28c1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_start.h @@ -0,0 +1,150 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_START_H_INCLUDED +#define MAC_MLME_START_H_INCLUDED + +#if (CONFIG_START_ENABLED == 1) + +#include +#include "mac_common.h" +#include "sys_utils.h" +#include "mac_task_scheduler.h" + +/** @file + * The MAC MLME Start module declares the MAC Start primitives and necessary types + * according to the MAC specification. + * + * @defgroup mac_start MAC MLME Start API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME Start API. + * @details The MAC Start module declares MLME Start primitives and necessary types according to + * the MAC specification. More specifically, MLME Start request aka mlme_start_req(), and MLME + * Start confirm callback typedef aka mlme_start_conf_cb_t primitives are declared. + */ + +/**@brief MLME-Start.confirm + * + * @details The MLME-Start.confirm primitive reports the results of a request + * to start the device. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.14.1.2 + */ +typedef struct +{ + mac_status_t status; /**< Status of operation. */ +} mlme_start_conf_t; + +/** + * @brief MLME-START.request + * + * @details The MLME-START.request primitive allows the PAN coordinator + * to initiate a new PAN or to start using a new superframe configuration. + * This primitive may also be used by a device already associated with an + * existing PAN to start using a new superframe configuration. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.14.1.1 + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + /** Confirm to this request. */ + mlme_start_conf_t confirm; + + uint16_t pan_id; /**< PAN ID. */ + uint8_t logical_channel; /**< Logical channel. */ +#ifdef CONFIG_SUB_GHZ + uint8_t channel_page; /**< Channel page. */ +#endif + uint32_t start_time; /**< Start time. */ + uint8_t beacon_order; /**< Beacon order. */ + uint8_t superframe_order; /**< Superframe order. */ + bool pan_coordinator; /**< Is PAN Coordinator? */ + bool battery_life_extension; /**< Is battery life long? */ + bool coord_realignment; /**< Is coordinator realignment? */ +#if (CONFIG_SECURE == 1) + /* The security parameters for the coordinator realignment are declared below. */ + uint8_t coord_realign_security_level; /**< Security level. */ + uint8_t coord_realign_key_id_mode; /**< Key ID mode. */ + uint64_t coord_realign_key_source; /**< Key source. */ + uint8_t coord_realign_key_index; /**< Key index. */ + + /* The security parameters for the beacon are declared below. */ + uint8_t beacon_security_level; /**< Security level. */ + uint8_t beacon_key_id_mode; /**< Key ID mode. */ + uint64_t beacon_key_source; /**< Key source. */ + uint8_t beacon_key_index; /**< Key index. */ +#endif +} mlme_start_req_t; + + +/** + * @brief Callback to the next higher layer. + * + * @details After request completion, passed callback + * will be issued with status provided as a parameter. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.14.2.2 + */ +typedef void (* mlme_start_conf_cb_t)(mlme_start_conf_t *); + + +/** + * @brief MLME-START request. + * + * @details Generated by the next higher layer and issued to its MLME to + * request that a device starts using a new superframe configuration. + * + * @param[in] req MLME-START request structure. + * @param[in] conf_cb pointer to user callback. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.14.1.2 + */ +void mlme_start_req(mlme_start_req_t * req, mlme_start_conf_cb_t conf_cb); + +/** @} */ + +#endif // (CONFIG_START_ENABLED == 1) + +#endif // MAC_MLME_START_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_sync.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_sync.h new file mode 100644 index 0000000000000000000000000000000000000000..b6c219d72493b222db67b211317450364a6e0408 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_mlme_sync.h @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_MLME_SYNC_H_INCLUDED +#define MAC_MLME_SYNC_H_INCLUDED + +#if (CONFIG_SYNC_ENABLED == 1) + +#include +#include "mac_common.h" +#include "mac_task_scheduler.h" + +/** @file + * The MAC MLME Sync module declares the MAC Sync primitives and necessary types + * according to the MAC specification. + * + * @defgroup mac_sync MAC MLME Sync API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME Sync API. + * @details The MAC Sync module declares MLME Sync and sync loss primitives and necessary types according to + * the MAC specification. More specifically, MLME Sync request aka mlme_sync_req(), and MLME + * Sync Loss indication aka mlme_sync_loss_ind() primitives are declared. + */ + +/**@brief Sync Loss reason enumeration. */ +typedef enum +{ + MAC_SYNC_BEACON_LOST, /**< Beacon lost. */ + MAC_SYNC_REALIGNMENT, /**< Realignment. */ + MAC_SYNC_PAN_ID_CONFLICT /**< PAN ID Conflict. */ +} mlme_sync_loss_reason_t; + +/** + * @brief MLME-SYNC-LOSS.indication + * + * @details On receipt of the MLME-SYNC-LOSS.indication primitive, the next + * higher layer is notified of a loss of synchronization. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.15.2 + */ +typedef struct +{ + mlme_sync_loss_reason_t loss_reason; /**< Loss reason. */ + uint16_t pan_id; /**< PAN ID. */ + uint8_t logical_channel; /**< Logical channel. */ +#ifdef CONFIG_SUB_GHZ + uint8_t channel_page; /**< Channel page. */ +#endif +#if (CONFIG_SECURE == 1) + uint8_t security_level; /**< Security level. */ + uint8_t key_id_mode; /**< Key ID mode. */ + uint64_t key_source; /**< Key source. */ + uint8_t key_index; /**< Key index. */ +#endif +} mlme_sync_loss_ind_t; + + +#if (CONFIG_SYNC_REQ_ENABLED == 1) +/** + * @brief MLME-SYNC.request + * + * @details The MLME-SYNC.request primitive is generated by the next higher + * layer of a device on a beacon-enabled PAN and issued to its MLME to + * synchronize with the coordinator. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.15.1 + */ +typedef struct +{ + /** Do not edit this field. */ + mac_abstract_req_t service; + + uint8_t logical_channel; /**< Logical channel. */ +#ifdef CONFIG_SUB_GHZ + uint8_t channel_page; /**< Channel page. */ +#endif + bool track_beacon; /**< Track beacon? */ +} mlme_sync_req_t; + +/** + * @brief MLME-SYNC-LOSS indication. + * + * @details Generated by the MLME of a device and issued to its next + * higher layer in the event of a loss of synchronization with the + * coordinator. It is also generated by the MLME of the PAN coordinator + * and issued to its next higher layer in the event of a PAN ID conflict. + * + * @param[in] ind MLME-SYNC-LOSS indication structure. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.4 + */ +extern void mlme_sync_loss_ind(mlme_sync_loss_ind_t * ind); + + +/** + * @brief MLME-SYNC request. + * + * @details Generated by the next higher layer of a device on a + * beacon-enabled PAN and issued to its MLME to synchronize with + * the coordinator. + * + * @param[in] req MLME_SYNC request structure. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.1.15.1 + */ +void mlme_sync_req(mlme_sync_req_t * req); + +#endif // (CONFIG_SYNC_REQ_ENABLED == 1) + +/** @} */ + +#endif // (CONFIG_SYNC_ENABLED == 1) + +#endif // MAC_MLME_SYNC_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_panid_conflict.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_panid_conflict.h new file mode 100644 index 0000000000000000000000000000000000000000..7af75424d8e0bde49631cea30ccfb86463152dd8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_panid_conflict.h @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_PANID_CONFLICT_H_INCLUDED +#define MAC_PANID_CONFLICT_H_INCLUDED + +#if (CONFIG_PANID_CONFLICT_ENABLED == 1) + +#include "mac_common.h" + +/** @file + * @defgroup mac_pan_id PAN ID Conflict API + * @ingroup mac_15_4 + * @{ + * @brief Module for handling PAN ID conflicts. + */ + +/** + * @brief A callback function used to notify Pan ID conflict detection algorithm about + * a new beacon frame. + * + * @param p_beacon - pointer to beacon descriptor struct. + */ +void mac_panid_conflict_beacon_notify_ind(const mac_beacon_ind_t * p_beacon); + +#if (CONFIG_PANID_CONFLICT_RESOLUTION_ENABLED == 1) +/**@brief Callback function which handles end of Pan ID conflict cmd TX, + * called by FP + * @param[in] status Confirmation status to be raised + */ +void mac_panid_conflict_cb(mac_status_t status); +#endif + +/**@brief Indicates whether the pan id conflict was detected + * + * @return Result of pan id conflict detection + */ +bool mac_panid_conflict_detected(void); + +/** @} */ + +#endif + +#endif /* MAC_PANID_CONFLICT_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_security.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_security.h new file mode 100644 index 0000000000000000000000000000000000000000..7678fcfb19e7f6c707360411fe5b2ce2c6009e56 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_security.h @@ -0,0 +1,318 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_SECURITY_H_INCLUDED +#define MAC_SECURITY_H_INCLUDED + +#include "sys_queue.h" +#include "sec_aes_ccm.h" + +/** @file + * The MAC MLME Security module declares the MAC Security types + * according to the MAC specification. + * + * @defgroup mac_security MAC MLME Security API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC MLME Security API. + * @details The MAC Security module declares types/macros needed to implement and use the MAC security + * engine according to the MAC specification. No routines or callbacks are declared here. + */ + +/** + * @brief MAC sublayer security levels. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.6.2.2.1 + */ +typedef enum +{ + MAC_SEC_OFF = 0, /**< Security is OFF. */ + MAC_SEC_MIC32, /**< MIC32 security. */ + MAC_SEC_MIC64, /**< MIC64 security. */ + MAC_SEC_MIC128, /**< MIC128 security. */ + MAC_SEC_ENC, /**< ENC security. */ + MAC_SEC_ENC_MIC32, /**< ENC/MIC32 security. */ + MAC_SEC_ENC_MIC64, /**< ENC/MIC64 security. */ + MAC_SEC_ENC_MIC128 /**< ENC/MIC128 security. */ +} mac_security_level_t; + + +/** + * @brief MAC key identifier mode. + * + * In accordance with IEEE Std 802.15.4-2006, section 7.6.2.2.2 + */ +typedef enum +{ + MAC_KEY_ID_IMPL = 0, /**< Impl. */ + MAC_KEY_ID_ONE_OCTET, /**< One octet. */ + MAC_KEY_ID_FOUR_OCTET, /**< 4 octets. */ + MAC_KEY_ID_EIGHT_OCTET /**< 8 octets. */ +} mac_key_id_mode_t; + +/**@brief Size (in bytes) of short security look up item. This size is + * set when lookup size equals to 0. + */ +#define MAC_LOOKUP_DATA_SIZE_SHORT 5 + +/**@brief Size (in bytes) of long security Key look up item. This size is + * set when lookup size equals to 1. + */ +#define MAC_KEY_LOOKUP_DATA_SIZE_LONG 9 + +/**@brief Size (in bytes) of long security Data look up item. This size is + * set when lookup size equals to 1. + */ +#define MAC_DATA_LOOKUP_DATA_SIZE_LONG 8 + +/**@brief Length of \a mac_key_source_t. Equals to extended address length. */ +#define MAC_KEY_SOURCE_SIZE 8 + +/**@brief This bit-mask is used to get UniqueDevice field value of + * \a mac_key_device_descr_t. + */ +#define MAC_KEY_DEVICE_FLAG_UNIQUE 0x01 + +/**@brief This bit-mask is used to get BlackListed field value of + * \a mac_key_device_descr_t. + */ +#define MAC_KEY_DEVICE_FLAG_BLACKLISTED 0x02 + +/**@brief Length of key. */ +#define MAC_SECURITY_KEY_SIZE 16 + +/**@brief Length of nonce for aes-ccm algorithm .*/ +#define MAC_SECURITY_NONCE_SIZE 13 + +/**@brief Maximum MIC size .*/ +#define MAX_MIC_SIZE 16 + +/**@brief This type is used to store security key .*/ +typedef uint8_t mac_key_t[MAC_SECURITY_KEY_SIZE]; + +/**@brief This type is used to store security key lookup data .*/ +typedef uint8_t mac_key_lookup_data_t[MAC_KEY_LOOKUP_DATA_SIZE_LONG]; + +/**@brief This type is used to store security data lookup data .*/ +typedef uint8_t mac_data_lookup_data_t[MAC_DATA_LOOKUP_DATA_SIZE_LONG]; + +/**@brief This type is used to store security key source address .*/ +typedef uint64_t mac_key_source_t; + +/**@brief This type represents key LookupDataSize according to Table 94 .*/ +typedef enum +{ + KEY_LOOKUP_SIZE_FIVE = 0, /**< Size is 5. */ + KEY_LOOKUP_SIZE_NINE = 1 /**< Size is 9. */ +} mac_key_lookup_size_t; + +/**@brief This type represents real size of key LookupData .*/ +typedef enum +{ + KEY_LOOKUP_SIZE_FIVE_VAL = 5, /**< Size is 5. */ + KEY_LOOKUP_SIZE_NINE_VAL = 9 /**< Size is 9. */ +} mac_key_lookup_size_val_t; + +/**@brief This type represents data LookupDataSize .*/ +typedef enum +{ + DATA_LOOKUP_SIZE_FOUR_VAL = 4, /**< Size is 4. */ + DATA_LOOKUP_SIZE_EIGHT_VAL = 8 /**< Size is 8. */ +} mac_data_lookup_size_val_t; + +/**@brief Abstract type to work with growing tables such as some of MAC + * security attributes. + */ +typedef struct +{ + sys_queue_t queue; /**< Service field .*/ + uint8_t size; /**< Number of currently allocated + items inside the table .*/ +} mac_table_t; + +/**@brief Due to processing algorithm this field MUST be the first inside a + * table or list. + */ +typedef struct +{ + sys_queue_item_t item; /**< Service field .*/ + uint8_t idx; /**< Index inside table .*/ +} mac_table_item_t; + +/**@brief KeyIdLookupDescriptor as described in Table 94 .*/ +typedef struct +{ + mac_table_item_t table_service; /**< Service field .*/ + mac_key_lookup_data_t data; /**< Set of 5 or 9 bytes. + Data used to identify the key .*/ + mac_key_lookup_size_t size; /**< A value of LOOKUP_SIZE_FIVE indicates a set + of 5 bytes; a value of LOOKUP_SIZE_NINE + indicates a set of 9 bytes .*/ +} mac_key_id_lookup_descr_t; + + +/**@brief KeyIdLookupLis as described in Table 89 .*/ +typedef mac_table_t mac_key_id_lookup_list_t; + + +/**@brief DeviceDescriptor as described in Table 93 .*/ +typedef struct +{ + mac_table_item_t table_service; /**< Service field .*/ + uint16_t pan_id; /**< The 16-bit PAN identifier of the device in + this DeviceDescriptor .*/ + uint16_t short_address; /**< The 16-bit short address of the device in + this DeviceDescriptor. A value of + #MAC_EXTENDED_ADDRESS_ONLY + indicates that this device is using only its + extended address. A value of + #MAC_BROADCAST_SHORT_ADDRESS + indicates that this value is unknown .*/ + uint64_t extended_address; /**< The 64-bit IEEE extended address of the + device in this DeviceDescriptor. This + element is also used in unsecuring + operations on incoming frames .*/ + uint32_t frame_counter; /**< The incoming frame counter of the device + in this DeviceDescriptor. This value is used + to ensure sequential freshness of frames .*/ + bool exempt; /**< Indication of whether the device may + override the minimum security level + settings defined in \a mac_security_level_table_t .*/ +} mac_device_descr_t; + + +/**@brief DeviceTable as described in Table 93 .*/ +typedef mac_table_t mac_device_table_t; + + +/**@brief KeyDeviceDescriptor as described in Table 91 .*/ +typedef struct +{ + mac_table_item_t table_service; /**< Service field .*/ + uint8_t device_handle; /**< Handle to the DeviceDescriptor + corresponding to the device (see + \a mac_device_descr_t). + The value is an index of the device descriptor + instance from device table .*/ + uint8_t unique_device : 1; /**< Indication of whether the device indicated + by DeviceDescriptorHandle is uniquely + associated with the KeyDescriptor, i.e., it + is a link key as opposed to a group key .*/ + uint8_t blacklisted : 1; /**< Indication of whether the device indicated + by DeviceDescriptorHandle previously + communicated with this key prior to the + exhaustion of the frame counter. If TRUE, + this indicates that the device shall not use + this key further because it exhausted its + use of the frame counter used with this + key .*/ +} mac_key_device_descr_t; + + +/**@brief KeyDeviceList as described in Table 89 .*/ +typedef mac_table_t mac_key_device_list_t; + + +/**@brief KeyUsageDescriptor as described in Table 90 .*/ +typedef struct +{ + mac_table_item_t table_service; /**< Service field .*/ + + uint8_t frame_type : 3; /**< See \a mac_frame_type_t .*/ + uint8_t cmd_frame_id : 4; /**< See \a mac_command_id_t .*/ +} mac_key_usage_descr_t; + + +/**@brief KeyUsageList as described in Table 89 .*/ +typedef mac_table_t mac_key_usage_list_t; + + +/**@brief KeyDescriptor as described in Table 89 .*/ +typedef struct +{ + mac_table_item_t table_service; /**< Service field .*/ + mac_key_id_lookup_list_t id_lookup_list; /**< A list of KeyIdLookupDescriptor entries + used to identify this KeyDescriptor .*/ + mac_key_device_list_t key_device_list; /**< A list of KeyDeviceDescriptor entries + indicating which devices are currently + using this key, including their blacklist + status .*/ + mac_key_usage_list_t key_usage_list; /**< A list of KeyUsageDescriptor entries + indicating which frame types this key may + be used with .*/ + mac_key_t key; /**< The actual value of the key .*/ +} mac_key_descr_t; + + +/**@brief KeyTable as described in Table 88 .*/ +typedef mac_table_t mac_key_table_t; + + +/**@brief SecurityLevelDescriptor as described in Table 93 .*/ +typedef struct +{ + mac_table_item_t table_service; /**< Service field. */ + + uint16_t frame_type : 3; /**< See \a mac_frame_type_t .*/ + uint16_t cmd_frame_id : 4; /**< See \a mac_command_id_t .*/ + uint16_t security_min : 3; /**< The minimal required/expected security + level for incoming MAC frames with the + indicated frame type and, if present, + command frame type (see + \a mac_security_level_t) .*/ + uint16_t override_min : 1; /**< Indication of whether originating devices + for which the Exempt flag is set may + override the minimum security level + indicated by the SecurityMinimum + element. If TRUE, this indicates that for + originating devices with Exempt status, + the incoming security level zero is + acceptable, in addition to the incoming + security levels meeting the minimum + expected security level indicated by the + SecurityMinimum element .*/ +} mac_security_level_descr_t; + +typedef mac_table_t mac_security_level_table_t; + +/** @} */ + +#endif // MAC_SECURITY_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_task_scheduler.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_task_scheduler.h new file mode 100644 index 0000000000000000000000000000000000000000..950f962a5f21bc93699f0d1e3211b2674c44b030 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_task_scheduler.h @@ -0,0 +1,205 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_TASK_SCHEDULER_H_INCLUDED +#define MAC_TASK_SCHEDULER_H_INCLUDED + +#include +#include "sys_queue.h" +#include "sys_time.h" + +/** @file + * + * @defgroup mac_task_scheduler MAC task scheduler + * @ingroup mac_15_4 + * @{ + * @brief Module for MAC task scheduling. + */ + +/**@brief Identifiers for external requests. + */ +typedef enum +{ +#if (CONFIG_PURGE_ENABLED == 1) + MAC_PURGE_REQ_ID, +#endif +#if (CONFIG_ASSOCIATE_REQ_ENABLED == 1) + MAC_ASSOCIATE_REQ_ID, +#endif +#if (CONFIG_DISASSOCIATE_ENABLED == 1) + MAC_DISASSOCIATE_REQ_ID, +#endif + MAC_GET_REQ_ID, +#if (CONFIG_GTS_ENABLED == 1) + MAC_GTS_REQ_ID, +#endif + MAC_RESET_REQ_ID, +#if (CONFIG_RXE_ENABLED == 1) + MAC_RX_ENABLE_REQ_ID, +#endif + MAC_SCAN_REQ_ID, + MAC_SET_REQ_ID, +#if (CONFIG_SYNC_REQ_ENABLED == 1) + MAC_SYNC_REQ_ID, +#endif + MAC_POLL_REQ_ID, +#if (CONFIG_START_ENABLED == 1) + MAC_START_REQ_ID, +#endif + MAC_DATA_REQ_ID, +#if (CONFIG_ORPHAN_ENABLED == 1) + MAC_ORPHAN_RESP_ID, +#endif + MAC_REQS_AMOUNT +} mac_req_id_t; + + +/**@brief Identifiers for internal handlers. + * + * These handlers are used for private MAC task scheduling. + */ +typedef enum +{ +#if (CONFIG_FFD_DEVICE == 1) && (CONFIG_BEACON_ENABLED == 1) + MAC_SUPERFRAME_OUT_TASK_ID, +#endif + MAC_CSMA_CA_TASK_ID, +#if (CONFIG_START_ENABLED == 1) + MAC_START_TASK_ID, +#endif + MAC_FP_TX_TASK_ID, + MAC_DATA_DIR_CONF_ID, +#if (CONFIG_INDIRECT_ENGINE_ENABLED == 1) + MAC_INDIR_ENGINE_REQ_ID, +#endif + MAC_FP_RX_TASK_ID, +#if (CONFIG_ORPHAN_ENABLED == 1) + MAC_ORPHAN_IND_ID, +#endif +#if (CONFIG_DISASSOCIATE_ENABLED == 1) + MAC_DISASSOC_IND_ID, +#endif +#if (CONFIG_SYNC_ENABLED == 1) + MAC_SYNC_LOSS_IND_ID, +#endif + MAC_GET_CONF_ID, + MAC_SET_CONF_ID, + MAC_REQ_QUEUE_TASK_ID, + MAC_MEM_ALLOCATOR_TASK_ID, + MAC_POLL_TASK_ID, + MAC_SCAN_CONF_ID, + MAC_TASKS_AMOUNT +} mac_task_id_t; + + +/**@brief MAC request descriptor. + */ +typedef struct +{ + sys_queue_item_t item; + mac_req_id_t id; + void * p_conf_cb; //pointer to confirmation primitive +} mac_abstract_req_t; + +/**@brief scheduler memory. + */ +typedef struct +{ + sys_queue_t outer_req_queue; + volatile uint32_t pending_tasks; + bool mac_scheduler_busy; +} mac_scheduler_mem_t; + +/**@brief MAC task handler prototype. + * + * @details Handler which will be called by the MAC scheduler. + */ +typedef void (* mac_task_handler_t)(void); + +/**@brief MAC external requests queue task handler prototype. + * + * @details Handler which will be called by the MAC scheduler inside + * corresponding task handler. + */ +typedef void (* mac_req_handler_t)(mac_abstract_req_t *); + +/**@brief Initialize MAC scheduler. + * + * @details Clean up MAC request's queue. + */ +void mac_init(void); + +/**@brief MAC task handler. + * + * @details Handler invokes a MAC primitives routine for a request according to + * the requests identification. + */ +void mac_task_handler(void); + +/**@brief Scheduler request from some MAC primitive. + * + * @details Place request to MAC scheduler queue for a further handling. + * + * @param[in] p_req Pointer to a request structure. + */ +void mac_request_schedule(mac_abstract_req_t * p_req); + +/**@brief Internal function of MAC API. + * + * This function is used to post tasks between MAC primitives. + * + * @param[in] id MAC task ID. + * + */ +void mac_internal_task_post(mac_task_id_t id); + +/**@brief Internal function of MAC API. + * + * Notifies mac scheduler that incoming request has been completely + * served and may be safely removed from MAC task queue. + * + * @param[in] p_req Pointer to a request structure. + */ +void mac_close_request(mac_abstract_req_t * p_req); + +/** @} */ + +#endif // MAC_TASK_SCHEDULER_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_time.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_time.h new file mode 100644 index 0000000000000000000000000000000000000000..b2fa6b63bf0f0c871a6354c33d472f6b73f212d7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/MAC/mac_time.h @@ -0,0 +1,151 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MAC_TIME_H_INCLUDED +#define MAC_TIME_H_INCLUDED + +#include +#include "sys_time.h" +#include "hal_timer.h" +#include "hal_timer_critical.h" +#include "sys_debug.h" + +/** @file + * The MAC Time module declares some useful macros/types and routines that deal with the MAC + * timer. + * + * @defgroup mac_time MAC Time API + * @ingroup mac_15_4 + * @{ + * @brief Module to declare MAC Time API. + * @details The MAC Time module declares some useful macros/types and routines that deal with the MAC + * timer. More specifically, some convertion routines such as mac_timestamp_from_systime(), + * mac_time_from_us(), and mac_time_to_us() are declared here. + */ + +/**@brief This mask shall always be used after any mathematical operation on + * mac_time_t to avoid overflow. + */ +#define MAC_TIME_MASK 0xFFFFFFULL + +/**@brief Type of MAC time in symbols. */ +typedef uint32_t mac_time_t; + +/**@brief Type is used to save timestamps with microsecond precision. */ +typedef uint32_t mac_timestamp_t; + + +/**@brief Gets timestamp from system time. + * + * @param[in] time_us System time. + * + * @return Time in us but smaller type size. + */ +static inline mac_timestamp_t mac_timestamp_from_systime(sys_time_t time_us) +{ + return (mac_timestamp_t)time_us; +} + +/**@brief Converts microseconds to symbol time. + * + * @details Symbol time is measured in PHY Symbol Periods (16 us). + * + * @param[in] time_us Time in microseconds. + * + * @return Time in PHY Symbol Periods (16 us). + */ +static inline mac_time_t mac_time_from_us(sys_time_t time_us) +{ + return (mac_time_t)((time_us >> 4ull) & MAC_TIME_MASK); +} + + +/**@brief Converts symbol time to microseconds. + * + * @details Symbol time is measured in PHY Symbol Periods (16 us). + * + * @param[in] time_symbol Time in PHY Symbol Periods (16 us). + * + * @return Time in microseconds. + */ +static inline sys_time_t mac_time_to_us(mac_time_t time_symbol) +{ + return time_symbol << 4u; +} + + +/**@brief Starts the critical MAC timer. + * + * @details The callback function of the critical MAC timer will be called from + * the timer's interrupt routine. Only one critical MAC timer can run + * at the same time. + * + * @warning This is internal MAC functionality, needed for the realtime channel access. + * This function must not be used by other modules. + * + * @param[in] interval_us Interval in microseconds, after which the callback + * function will be called. + * @param[in] callback Callback function to be called after the specified inteval. + */ +static inline void mac_timer_critical_start(sys_time_t interval_us, void (* callback)(void)) +{ + // Make sure interval_us fits into 32 bits, since hardware critical timer is 32 bit. + ASSERT(interval_us < (1ULL << 32)); + + hal_timer_critical_start((uint32_t)interval_us, callback); +} + + +/**@brief Stops the critical MAC timer. + * + * @details After critical MAC timer is stopped with this function, its callback will not be called. + * + * @warning This is internal MAC functionality, needed for the realtime channel access. + * This function must not be used by other modules. + */ +static inline void mac_timer_critical_stop(void) +{ + hal_timer_critical_stop(); +} + +/** @} */ + +#endif // MAC_TIME_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_common.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_common.h new file mode 100644 index 0000000000000000000000000000000000000000..a871c65d0bfb2bf0aecc35fc151131798d70478d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_common.h @@ -0,0 +1,243 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef PHY_COMMON_H_INCLUDED +#define PHY_COMMON_H_INCLUDED + +/** @file + * This file contains declarations of commonly used PHY routines and necessary macros/types. + * + * @defgroup phy_common PHY Common API + * @{ + * @brief Module to declare PHY Common API + */ + +/**@brief The maximum PSDU size (in octets) the PHY shall be able to receive (aMaxPHYPacketSize). + * + * @details See Table 22 - PHY constants. + */ +#define PHY_MAX_PACKET_SIZE 127 + + +/**@brief The maximum PHR size (in octets). + * + * @details See 6.3 PPDU format. + */ +#define PHY_MAX_HEADER_SIZE 1 + +/**@brief Maximum PPDU size */ +#define PHY_MAX_PPDU_SIZE (PHY_MAX_HEADER_SIZE + PHY_MAX_PACKET_SIZE) + +/**@brief Position of PHY header related to income PPDU start pointer.*/ +#define PHY_HEADER_POS (-1) + +/**@brief Size of PHY header in bytes.*/ +#define PHY_HEADER_SIZE 1 + +/**@brief Maximum channel number.*/ +#define PHY_MAX_CHANNEL_NUM 0x1A + +/**@brief Minimum channel number.*/ +#define PHY_MIN_CHANNEL_NUM 0x0B + +// for 2400 MHz O-QPSK 1 octet = 2 symbols 1 symbol = 32bits chip +#define aMaxPHYPacketSize PHY_MAX_PACKET_SIZE // in octets +#define aTurnaroundTime 12 // in symbols + +#define aTurnaroundTimeUs 192 // in us + + +// Read only parameters +#define PHY_CURRENT_PAGE 0x0u +#define PHY_CHANNEL_SUPPORTED 0x07FFF800ul +#define PHY_SHR_DURATION 10u +#define PHY_MAX_FRAME_DURATION (PHY_SHR_DURATION + (int)((aMaxPHYPacketSize + 1) * PHY_SYMBOLS_PER_OCTET)) +#define PHY_SYMBOLS_PER_OCTET 2u + +// CCA values +#define PHY_TRX_CCA_MODE0 0 +#define PHY_TRX_CCA_MODE1 1 +#define PHY_TRX_CCA_MODE2 2 +#define PHY_TRX_CCA_MODE3 3 + + +/** @brief Minimum value that can be used to set radio transmit power. Equals + * to -32 dBm. + * + * This is a combination of digits which includes: + * 2 MSBs represent the tolerance on the transmit power + * 6 LSBs which may be written to, represent a signed integer in twos-complement format, + * corresponding to the nominal transmit power of the device in decibels relative to 1 mW. + * All combinations less than 0xBF are valid. + */ +#define PHY_MIN_TX_POWER 0x20 + +/** @brief Internal parameter of the PHY layer. + * + * @details Position of the sign bit inside transmit power attribute.*/ +#define PHY_TRANSMIT_POWER_SIGN_BIT_POS 5 + +/** @brief Internal parameter of the PHY layer. + * + * @details This mask hides transmit power from transmit power attribute value, + * but leaves precision bitfield. + */ +#define PHY_TRANSMIT_POWER_MASK 0xC0 + +/** @brief Internal parameter of the PHY layer. + * + * @details This mask hides precision bitfield from transmit power attribute value, + * leaving transmit power unchanged. + */ +#define PHY_TRANSMIT_POWER_MASK_INV 0x3F + +// Possible transmit power +#define DBM_11 ( 11 & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_10 ( 10 & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_9 ( 9 & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_8 ( 8 & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_7 ( 7 & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_6 ( 6 & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_5 ( 5 & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_4 ( 4 & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_3 ( 3 & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_2 ( 2 & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_1 ( 1 & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_0 ( 0 & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_1 (( -1) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_2 (( -2) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_3 (( -3) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_4 (( -4) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_5 (( -5) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_6 (( -6) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_7 (( -7) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_8 (( -8) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_9 (( -9) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_10 ((-10) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_11 ((-11) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_12 ((-12) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_13 ((-13) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_14 ((-14) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_15 ((-15) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_16 ((-16) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_17 ((-17) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_18 ((-18) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_19 ((-19) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_20 ((-20) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_21 ((-21) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_22 ((-22) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_23 ((-23) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_24 ((-24) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_25 ((-25) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_26 ((-26) & PHY_TRANSMIT_POWER_MASK_INV) +#define DBM_MIN_27 ((-27) & PHY_TRANSMIT_POWER_MASK_INV) + + +/**@brief Common PHY enumerations description used in various PHY primitives. + * + * @details See Table 18-PHY enumerations description for detailed info on the statuses up to PHY_READ_ONLY. + * The statuses with higher numbers are implementation specific and used for synchronous API only. + */ +typedef enum +{ + /** The CCA attempt has detected a busy channel. */ + PHY_BUSY = 0x00, + + /** The transceiver is asked to change its state while receiving. */ + PHY_BUSY_RX = 0x01, + + /** The transceiver is asked to change its state while transmitting. */ + PHY_BUSY_TX = 0x02, + + /** The transceiver is to be switched off immediately. */ + PHY_FORCE_TRX_OFF = 0x03, + + /** The CCA attempt has detected an idle channel. */ + PHY_IDLE = 0x04, + + /** A SET/GET request was issued with a parameter in the primitive that is + out of the valid range. */ + PHY_INVALID_PARAMETER = 0x05, + + /** The transceiver is in or is to be configured into the receiver enabled state. */ + PHY_RX_ON = 0x06, + + /** A SET/GET, an ED operation, or a transceiver state change was successful. */ + PHY_SUCCESS = 0x07, + + /** The transceiver is in or is to be configured into the transceiver disabled state. */ + PHY_TRX_OFF = 0x08, + + /** The transceiver is in or is to be configured into the transmitter enabled state. */ + PHY_TX_ON = 0x09, + + /** A SET/GET request was issued with the identifier of an attribute that is not supported. */ + PHY_UNSUPPORTED_ATTRIBUTE = 0x0A, + + /** A SET/GET request was issued with the identifier of an attribute that is read-only.*/ + PHY_READ_ONLY = 0x0B, + + + /* Statuses out of the standard. They are used for synchronous API */ + /** Transceiver is forced to change it's state to PHY_TX_ON (potential packet drop). */ + PHY_FORCE_TX_ON = 0xFB, + + /** Data with ACK request transmitted successfully + * and pending bit in received ACK is set to one. + */ + PHY_SUCCESS_DATA_PENDING = 0xFC, + + /** Data cannot be sent due to failed CCA results.*/ + PHY_CHANNEL_ACCESS_FAILURE = 0xFD, + + /** Data had been sent but ACK frame hasn't been received.*/ + PHY_NO_ACK = 0xFE, + + /** PHY is not available for synchronous access */ + PHY_IS_NOT_AVAILABLE = 0xFF +} phy_enum_t; + +/**@brief PHY status type.*/ +typedef phy_enum_t phy_status_t; + +/** @} */ + +#endif // PHY_COMMON_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_pd_data.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_pd_data.h new file mode 100644 index 0000000000000000000000000000000000000000..07eb3f3dd5e12dbdb4193457311df7c2a0dc4140 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_pd_data.h @@ -0,0 +1,172 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef PHY_PD_DATA_H_INCLUDED +#define PHY_PD_DATA_H_INCLUDED + + +#include +#include +#include "sys_utils.h" +#include "sys_time.h" +#include "phy_common.h" +#include "mac_time.h" +#include "sys_queue.h" + +/** @file + * This file contains declarations of PHY Data transmittion routines and necessary types. + * + * @defgroup phy_data PHY Data API + * @{ + * @brief Module to declare PHY Data API + */ + +/**@brief PD-DATA.request parameters. + * + * @details See 6.2.1.1 PD-DATA.request. + * See Table 6 - PD-DATA.request parameters. + */ +typedef struct +{ + /** The set of octets forming the PSDU to be transmitted by the PHY entity. */ + uint8_t * psdu; + + /** The number of octets contained in the PSDU to be transmitted by the PHY entity. + Valid range: less or equal to @ref PHY_MAX_PACKET_SIZE. */ + uint8_t psdu_length; +} pd_data_req_t; + + +/**@brief PD-DATA.confirm parameters. + * + * @details See 6.2.1.2 PD-DATA.confirm. + * See Table 7 - PD-DATA.confirm parameters. + */ +typedef struct +{ + /** The result of the request to transmit a packet. + * Valid range: PHY_SUCCESS, PHY_RX_ON, PHY_TRX_OFF, PHY_BUSY_TX. + * See @ref phy_enum_t. + * + * When radio chip successfully transmits data, but cannot receive + * ACK in FAST_ACK mode, the result is PHY_TX_ON. + */ + phy_enum_t status; +} pd_data_conf_t; + +/**@brief Private information which is passed with PD-DATA.indication. + * Not covered by standard. + */ +typedef struct +{ + /** RSSI value, which corresponds to packet that caused this indication. */ + int8_t rssi; + + /** Buffer to store incoming frame. */ + uint8_t frame_buffer[PHY_MAX_PACKET_SIZE + PHY_MAX_HEADER_SIZE]; + + /** Timestamp of the moment when PHY header octet reception has been started. */ + mac_timestamp_t timestamp; + + /** This field allows storing instances of this structure in a queue. */ + sys_queue_item_t queue_item; +#ifdef CONFIG_PHY_CERT_CRC_HOOK + bool crc_status; +#endif +} pd_data_ind_private_t; + +/**@brief PD-DATA.indication parameters. + * + * @details See 6.2.1.3 PD-DATA.indication. + * See Table 8 - PD-DATA.indication parameters. + */ +typedef struct +{ + /** Service field. */ + pd_data_ind_private_t service; + + /** The set of octets forming the PSDU received by the PHY entity. */ + uint8_t * psdu; + + /** The number of octets contained in the PSDU received by the PHY entity. + Valid range: less or equal to @ref PHY_MAX_PACKET_SIZE. */ + uint8_t psdu_length; + + /** Link quality (LQI) value measured during reception of the PPDU (see 6.9.8). + Valid range: 0x00 - 0xFF. */ + uint8_t ppdu_link_quality; +} pd_data_ind_t; + +/**@brief PD-DATA.request primitive. + * + * @details The PD-DATA.request primitive requests the transfer of an MPDU (i.e., PSDU) + * from the MAC sublayer to the local PHY entity. + * See 6.2.1.1 PD-DATA.request. + * + * @param[in] req Pointer to PD-DATA.request parameters. See @ref pd_data_req_t. + */ +void pd_data_req(pd_data_req_t * req); + +/**@brief PD-DATA.confirm primitive. + * + * @details Callback function, implemented by the next higher layer, + * which handles the PD-DATA.confirm primitive. + * See 6.2.1.2 PD-DATA.confirm. + * + * @param[out] conf Pointer to PD-DATA.confirm parameters. See @ref pd_data_conf_t. + */ +void pd_data_conf(pd_data_conf_t * conf); + +/**@brief PD-DATA.indication primitive. + * + * @details The PD-DATA.indication primitive indicates the transfer of an MPDU (i.e., PSDU) + * from the PHY to the local MAC sublayer entity. + * See 6.2.1.3 PD-DATA.indication. + * This function must be implemented by the next higher layer. + * + * @param[out] ind Pointer to PD-DATA.indication parameters. See @ref pd_data_ind_t. + * Data are valid until next fully received packet. + */ +void pd_data_ind(pd_data_ind_t * ind); + +/** @} */ + +#endif // PHY_PD_DATA_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_plme_cca.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_plme_cca.h new file mode 100644 index 0000000000000000000000000000000000000000..09f27f3ad7ba672737f01bf85e91b07810c602da --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_plme_cca.h @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef PHY_PLME_CCA_H_INCLUDED +#define PHY_PLME_CCA_H_INCLUDED + +#include +#include "phy_common.h" + +/** @file + * This file contains declarations of Clear Channel Assessment PHY routines and necessary types. + * + * @defgroup phy_cca PHY CCA API + * @{ + * @brief Module to declare PHY CCA API + */ + +/**@brief PLME-CCA.confirm parameters + * + * @details The PLME-CCA.confirm primitive is generated by + * the initiating PLME and issued to its next higher layer + * in response to an PLME-CCA.request primitive. + * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.2.1 + */ +typedef struct +{ + /** One of PHY_TRX_OFF, PHY_BUSY or PHY_IDLE. */ + phy_enum_t status; +} plme_cca_conf_t; + + +/**@brief PLME-CCA.request + * + * @details Request for clear channel assessment. + * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.1 + */ +void plme_cca_req(void); + + +/**@brief PLME-CCA.confirm callback function, implemented by the next higher layer. + * + * @details The PLME-CCA.confirm primitive is generated by the PLME and issued + * to its next higher layer in response to an PLME-CCA.request primitive. + * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.2 + * + * @param[out] conf Pointer to PLME-CCA.confirm parameters + */ +void plme_cca_conf(plme_cca_conf_t * conf); + + +/**@brief Direct (synchronous) PLME-CCA.request + * + * @details Optional. Not covered by a standard. + * + * @return One of PHY_TRX_OFF, PHY_BUSY or PHY_IDLE, + * or implementation defined error code in case of + * unavailability of access to system resources. + */ +phy_enum_t plme_cca(void); + +/** @} */ + +#endif // PHY_PLME_CCA_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_plme_ed.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_plme_ed.h new file mode 100644 index 0000000000000000000000000000000000000000..e768ddb05f87968fce409bf2bd481c7692b2eea6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_plme_ed.h @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef PHY_PLME_ED_H_INCLUDED +#define PHY_PLME_ED_H_INCLUDED + +#include +#include "phy_common.h" + +/** @file + * This file contains declarations of Energy Detection PHY routines and necessary types. + * + * @defgroup phy_ed PHY ED API + * @{ + * @brief Module to declare PHY ED API + */ + +/**@brief Describes the current state of the ED algorithm. */ +typedef enum +{ + PHY_PLME_ED_STATE_IDLE, /**< Algorithm is idle. */ + PHY_PLME_ED_STATE_BUSY /**< Currently performing ED. */ +} phy_plme_ed_state_t; + +/**@brief This structure holds static data of this module. */ +typedef struct +{ + phy_plme_ed_state_t state; +} phy_plme_ed_mem_t; + +/**@brief PLME-ED.confirm parameters. + * + * @details The PLME-ED.confirm primitive is generated by the PLME and issued + * to its next higher layer in response to an PLME-ED.request primitive. + * + * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.4.1. + */ +typedef struct +{ + /** One of PHY_SUCCESS, PHY_TRX_OFF or PHY_TX_ON. */ + phy_enum_t status; + + /** Energy level for the current channel, if status is SUCCESS. */ + uint8_t energy_level; +} plme_ed_conf_t; + + +/**@brief PLME-ED.request. + * + * @details Request ED measurement for the current channel. + * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.3. + */ +void plme_ed_req(void); + + +/**@brief The PLME-ED.confirm callback function, implemented by the next higher layer. + * + * @details The PLME-ED.confirm primitive is generated by the PLME and issued + * to its next higher layer in response to an PLME-ED.request primitive. + * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.4. + * + * @param[out] conf Pointer to PLME-ED.confirm parameters + */ +void plme_ed_conf(plme_ed_conf_t * conf); + +/** @} */ + +#endif // PHY_PLME_ED_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_plme_pib.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_plme_pib.h new file mode 100644 index 0000000000000000000000000000000000000000..c2d9bb3016736adc14a234e35f14b767a7164b53 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_plme_pib.h @@ -0,0 +1,206 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef PHY_PLME_PIB_H_INCLUDED +#define PHY_PLME_PIB_H_INCLUDED + +#include +#include +#include "phy_common.h" + +/** @file + * This file contains declarations of PHY Information Base routines and necessary types. + * + * @defgroup phy_pib PHY PIB API + * @{ + * @brief Module to declare PHY PIB API + */ + +#define PHY_TX_POWER_TOLERANCE_1DB 0x00 +#define PHY_TX_POWER_TOLERANCE_3DB 0x40 +#define PHY_TX_POWER_TOLERANCE_6DB 0x80 +#define PHY_TX_POWER_TOLERANCE_MASK 0xC0 + +/** + * @brief PHY PIB attribute identificators. + * + * @details In accordance with IEEE Std 802.15.4-2006, section 6.4.2. + */ +typedef enum +{ + PHY_CURRENT_CHANNEL_ID = 0x00, /**< Current channel. */ + PHY_CHANNELS_SUPPORTED_ID = 0x01, /**< Supported channels. @note read only. */ + PHY_TRANSMIT_POWER_ID = 0x02, /**< Transmit power. */ + PHY_CCA_MODE_ID = 0x03, /**< CCA mode. */ + PHY_CURRENT_PAGE_ID = 0x04, /**< Current page. */ + PHY_MAX_FRAME_DURATION_ID = 0X05, /**< MAX Frame duration. @note read only. */ + PHY_SHR_DURATION_ID = 0x06, /**< SHR Duration. @note read only. */ + PHY_SYMBOLS_PER_OCTET_ID = 0x07, /**< Symbols per octet. @note read only. */ +} plme_pib_attr_id_t; + + +/** + * @brief PHY PIB attribute type sizes. + * + * @details In accordance with IEEE Std 802.15.4-2006, Table 23. + */ +typedef union +{ + uint8_t phy_current_channel; /**< Current channel. */ + uint32_t phy_channels_supported; /**< Supported channels. */ + int8_t phy_transmit_power; /**< Returns one of the DBM_xxx macro values. */ + uint8_t phy_cca_mode; /**< CCA mode. */ + uint8_t phy_current_page; /**< Current page. */ + uint16_t phy_max_frame_duration; /**< MAX Frame duration. */ + uint8_t phy_shr_duration; /**< SHR Duration. */ + uint16_t phy_symbols_per_octet; /**< Symbols per octet. */ +} phy_pib_item_t; + + +/**@brief PLME-GET.request parameters. + * + * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.5. + */ +typedef struct +{ + plme_pib_attr_id_t pib_attribute; /**< PIB attribute. */ +} plme_get_req_t; + + +/**@brief PLME-GET.confirm parameters. + * + * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.6. + */ +typedef struct +{ + phy_status_t status; /**< Status of operation. */ + plme_pib_attr_id_t pib_attribute; /**< PIB attribute. */ + phy_pib_item_t pib_attribute_value; /**< Attribute value. */ +} plme_get_conf_t; + + +/**@brief PLME-SET.request parameters. + * + * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.9. + */ +typedef struct +{ + plme_pib_attr_id_t pib_attribute; /**< PIB attribute. */ + phy_pib_item_t pib_attribute_value; /**< Attribute value. */ +} plme_set_req_t; + + +/**@brief PLME-SET.confirm parameters. + * + * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.10. + */ +typedef struct +{ + phy_status_t status; /**< Status of operation. */ + plme_pib_attr_id_t pib_attribute; /**< PIB attribute. */ +} plme_set_conf_t; + + +/**@brief PLME-GET.request. + * + * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.5. + * + * @param[in] req Pointer to PLME-GET.request parameters. See @ref plme_get_req_t. + */ +void plme_get_req(plme_get_req_t * req); + + +/**@brief PLME-GET.confirm callback function, implemented by the next higher layer. + * + * @details The PLME-GET.confirm primitive is generated by the PLME and issued + * to its next higher layer in response to an PLME-GET.request primitive. + * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.6. + * + * @param[out] conf Pointer to PLME-GET.confirm parameters. See @ref plme_get_conf_t. + */ +void plme_get_conf(plme_get_conf_t * conf); + + +/**@brief PLME-SET.request. + * + * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.9. + * + * @param[in] req Pointer to PLME-SET.request parameters. See @ref plme_set_req_t. + */ +void plme_set_req(plme_set_req_t * req); + + +/**@brief PLME-SET.confirm callback function, implemented by the next higher layer. + * + * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.10. + * + * @param[out] conf Pointer to PLME-SET.confirm parameters. See @ref plme_set_conf_t. + */ +void plme_set_conf(plme_set_conf_t * conf); + +/** + * @brief Getting parameters from PIB directly (without request - confirm approach) + * + * @details Optional. Not covered by a standard. + * + * @param[in] id attribute id. + * @param[out] mem pointer to memory for parameter storing. + * + * @return status of operation. + */ +phy_status_t plme_get(plme_pib_attr_id_t id, void * mem); + + +/** + * @brief Setting parameters to PIB directly (without request - confirm approach) + * + * @details Optional. Not covered by a standard. + * + * @param[in] id attribute id. + * @param[out] mem pointer to memory for parameter storing. + * + * @return status of operation. + */ +phy_status_t plme_set(plme_pib_attr_id_t id, void * mem); + +/** @} */ + +#endif // PHY_PLME_PIB_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_plme_trx.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_plme_trx.h new file mode 100644 index 0000000000000000000000000000000000000000..c9e8038406be75cd630287eff174034da7e37d12 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/PHY/phy_plme_trx.h @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef PHY_PLME_TRX_H_INCLUDED +#define PHY_PLME_TRX_H_INCLUDED + +#include +#include "phy_common.h" + +/** @file + * This file contains declarations of PHY TRX routines and necessary types. + * + * @defgroup phy_trx PHY TRX API + * @{ + * @brief Module to declare PHY TRX API + */ + +/** + * @brief PLME-SET_TRX_STATE.request parameters. + * + * @details The PLME-SET_TRX_STATE.request primitive is generated + * by the next higher layer of a device and issued to its PLME to + * set transmitter status. + * + * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.7.1 + */ +typedef struct +{ + /** One of PHY_RX_ON, PHY_TRX_OFF, PHY_FORCE_TRX_OFF, PHY_TX_ON or PHY_FORCE_TX_ON. */ + phy_enum_t state; +} plme_trx_req_t; + + +/** + * @brief PLME-TRX.confirm parameters. + * + * @details The PLME-TRX.confirm primitive is generated by + * PLME and issued to its next higher layer in response to + * an PLME-SET_TRX_STATE.request primitive. + * + * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.8.1 + */ +typedef struct +{ + /** Holds result of trx state change request. + * + * @details Equals to PHY_SUCCESS if state changed successfully + * or current PHY state in either case. + */ + phy_enum_t status; +} plme_trx_conf_t; + + +/**@brief PLME-SET_TRX_STATE request. + * + * @details Request PHY to change internal operating state. + * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.7 + * + * @param[in] req Pointer to PLME-SET_TRX_STATE.request parameters. + * See @ref plme_trx_req_t. + */ +void plme_set_trx_state_req(plme_trx_req_t * req); + + +/**@brief PLME-SET_TRX_STATE.confirm callback function, implemented by the next higher layer. + * + * @details The PLME-SET_TRX_STATE.confirm primitive is generated + * by the PLME and issued to its next higher layer in response to + * an PLME-SET_TRX_STATE.request primitive. + * + * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.8 + * + * @param[out] conf Pointer to PLME-TRX.confirm parameters. See @ref plme_trx_conf_t. + */ +void plme_set_trx_state_conf(plme_trx_conf_t * conf); + + +/**@brief Direct (synchronous) PLME-SET_TRX_STATE access. + * + * @details Optional. Not covered by the standard. + + * @param[in] state One of PHY_RX_ON, PHY_TRX_OFF, PHY_FORCE_TRX_OFF or PHY_TX_ON. + * + * @return PHY_SUCCESS if state changed successfully or current PHY state + * in either case. + */ +phy_enum_t plme_set_trx_state(phy_enum_t state); + +/** @} */ + +#endif // PHY_PLME_TRX_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_api_spec.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_api_spec.h new file mode 100644 index 0000000000000000000000000000000000000000..aba4e9b32108abf059c46a7975b64f9e3ccc58b3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_api_spec.h @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef RAL_API_SPEC_H_INCLUDED +#define RAL_API_SPEC_H_INCLUDED + +#include +#include "ral_critical_queue.h" + +/**@brief Specific CCA MODE for FPGA RAL + */ +#define RAL_TRX_CCA_MODE4 4 + +/**@brief Maximum available value of CCA MODE for FPGA RAL + */ +#define RAL_TRX_CCA_MODE_MAX RAL_TRX_CCA_MODE4 + +/**@brief Maximum duration of CCA algorithm including a task scheduling + */ +#define RAL_LONGEST_CCA_DURATION_US 500 + +/**@brief Maximum transmit power in dBm + */ +#define RAL_MAXIMUM_TX_POWER 9 + +/**@brief Maximum tolerance of transmit power in dBm + */ +#define RAL_TX_POWER_TOLERANCE PHY_TX_POWER_TOLERANCE_6DB + +/**@brief Value of RF signal power (in dBm) for RSSI equals zero. + */ +#define RSSI_BASE_VAL 90 + +/**@brief Values above this shouldn't appear in RSSI register result.*/ +#define RSSI_REG_MAX_VAL 20 + + +/**@brief Controls whether radio module will automatically calculate Frame + * Control Sequence field. + * + * @param auto_fcs_enabled if set to true, automatically generated FCS will + * replace the last two bytes of PHY service data unit. + */ +void ral_auto_fcs_set(bool auto_fcs_enabled); + +/**@brief Turns RAL RX on in a critical way */ +void nrf_radio_rx_on_initiate(void); + +#endif// RAL_API_SPEC_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_critical_queue.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_critical_queue.h new file mode 100644 index 0000000000000000000000000000000000000000..47d9c32564f3c6d626f7cbaf1c94e0c4c64c575e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_critical_queue.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef RAL_CRITICAL_QUEUE_H_INCLUDED +#define RAL_CRITICAL_QUEUE_H_INCLUDED + +typedef struct ral_critical_queue_item_s +{ + volatile struct ral_critical_queue_item_s * next; +} ral_critical_queue_item_t; + +typedef struct +{ + volatile ral_critical_queue_item_t * first; + volatile ral_critical_queue_item_t * last; +} ral_critical_queue_t; + +/**@brief Initialize critical queue */ +void ral_critical_queue_init(ral_critical_queue_t * p_queue); + +/**@brief Push item to the critical queue */ +void ral_critical_queue_push( + ral_critical_queue_t * p_queue, + ral_critical_queue_item_t * p_item); + +/**@brief Pop item from the critical queue */ +ral_critical_queue_item_t * ral_critical_queue_pop( + ral_critical_queue_t * p_queue); + +/**@brief Check if the critical queue is empty */ +bool ral_critical_queue_is_empty(ral_critical_queue_t * p_queue); + +#endif// RAL_CRITICAL_QUEUE_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_fsm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_fsm.h new file mode 100644 index 0000000000000000000000000000000000000000..2db009586ce4df257cf1c7e542b7970c8b3e154f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_fsm.h @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef RAL_FSM_H_INCLUDED +#define RAL_FSM_H_INCLUDED + +#include "sys_fsm.h" + +// list of possible events +typedef enum +{ + E_RESET, + E_TRX_END, /**< Radio signals that TX or RX is complete.*/ + E_TX_REQ, /**< Initiates upload of a frame into radio memory and + transmission of it into air.*/ + E_TRX_OFF, + E_TX_ON, + E_RX_ON, +} ral_fsm_events_t; + +// states +typedef enum +{ +/* State symbol for short FSM debug mode */ +/* I */ S_TRX_OFF, +/* J */ S_TX_ON, +/* */ S_BUSY_TX, +/* G */ S_RX_ON, +/* B */ S_BUSY_RX, +} ral_fsm_states_t; + +/**@brief Reads current state of RAL state machine. + * + * @return Current state. + */ +ral_fsm_states_t ral_fsm_current_state_get(void); + +/**@brief Initializes finite state machine of radio chip.*/ +void ral_fsm_init(void); + +/**@brief Sends new event to radio FSM. This function is used for + * changing radio state. + * + * @param event - event id for FSM. + * @param p_data - pointer to event specific data (expects pointer to ral_mem_t). + */ +void ral_fsm_event_post(ral_fsm_events_t event, void * p_data); + +#endif /* RAL_FSM_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_fsm_private.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_fsm_private.h new file mode 100644 index 0000000000000000000000000000000000000000..b759afcaae282da7a4001de82711c1dac366425c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_fsm_private.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef RAL_FSM_PRIVATE_H_INCLUDED +#define RAL_FSM_PRIVATE_H_INCLUDED + +#include "nrf52840.h" +#include "nrf52840_bitfields.h" + +/** @brief Private RAL function. Sets radio module into TRX_OFF mode if + * it was in RX or TX mode. */ +void ral_fsm_a_trx_off(void * p_data); + +/** @brief Private RAL function. Sets radio module into TRX_OFF mode if + * it was in BUSY_RX or BUSY_TX mode. */ +void ral_fsm_a_force_trx_off(void * p_data); + +/** @brief Private RAL function. Switches radio module from TRX_OFF + * to TX_ON mode. */ +void ral_fsm_a_tx_on(void * p_data); + +/** @brief Private RAL function. Switches radio module from TRX_OFF + * to RX_ON mode. */ +void ral_fsm_a_rx_on(void * p_data); + +/** @brief Private RAL function. Switches radio module from TX_ON + * to RX_ON mode. */ +void ral_fsm_a_tx_to_rx(void * p_data); + +/** @brief Private RAL function. Switches radio module from RX_ON + * to TX_ON mode. */ +void ral_fsm_a_rx_to_tx(void * p_data); + +/** @brief Private RAL function. Prepares RX frame buffer for the next received frame. */ +void ral_rx_frame_buffer_prepare(void); + + +#endif /* RAL_FSM_PRIVATE_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_irq_handlers.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_irq_handlers.h new file mode 100644 index 0000000000000000000000000000000000000000..fc48981aa93efc9906a63039a515675890f16192 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_irq_handlers.h @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef RAL_IRQ_HANDLERS_H_INCLUDED +#define RAL_IRQ_HANDLERS_H_INCLUDED + +#define RAL_NRF_BCC_COMPARE_VALUE 32 +#define RAL_NRF_BCC_COMPARE_NONE (RAL_NRF_BCC_COMPARE_VALUE + 16) +#define RAL_NRF_BCC_COMPARE_SHORT (RAL_NRF_BCC_COMPARE_VALUE + 32) +#define RAL_NRF_BCC_COMPARE_LONG (RAL_NRF_BCC_COMPARE_VALUE + 80) + +/**@brief RAL IRQ handler symbol importer (dummy function). + * + * @details This function is only used to correctly import + * RADIO_IRQHandler symbol. + */ +void ral_irq_handler_import(void); + +#endif// RAL_IRQ_HANDLERS_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_rf_init.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_rf_init.h new file mode 100644 index 0000000000000000000000000000000000000000..b45b6cd626a1104ac22c3ddb285bec555fcdcf98 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/nrf52_soc/ral_rf_init.h @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef RAL_INIT_H_INCLUDED +#define RAL_INIT_H_INCLUDED + +/**@brief Initializes radio transceiver. + */ +void ral_rf_init(void); + +/**@brief Channel number setting. + * + * @param channel_num - channel number + */ +void ral_rf_channel_set(uint8_t channel_num); + +/**@brief Channel number getting. + * + * @return channel number + */ +uint8_t ral_rf_channel_get(void); + +#endif /* RAL_INIT_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/ral_api.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/ral_api.h new file mode 100644 index 0000000000000000000000000000000000000000..7faf4c4a0eb2de678a6ca960bac7ce26cea8fc36 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/RAL/ral_api.h @@ -0,0 +1,222 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef RAL_API_H_INCLUDED +#define RAL_API_H_INCLUDED + +#include "ral_api_spec.h" +#include "sys_time.h" +#include "phy_common.h" +#include "phy_pd_data.h" +#include "mac_common.h" +#include "mac_mlme_pib.h" +#include "mac_time.h" +#include +#include + +/**@file ral_api.h + * + * @brief Radio abstraction layer interface. + * + * @details These are requirements for the implementation code: + * + * - no frames must be received between new frame indication and + * a call to ral_data_ind_read. + */ + +// various constants to use with MAC/PHY header parsing +#define PHR_POS 0 +#define PHR_SIZE 1 +#define CRC_SIZE 2 +#define MAC_FRAME_CTRL_POS 0 +#define MAC_FRAME_CTRL_SIZE 2 +#define ACK_REQUEST_MASK 0x20 +#define SEQ_NUM_POS (MAC_FRAME_CTRL_POS + MAC_FRAME_CTRL_SIZE) +#define ACK_PD_BIT_MASK 0x0010 + +#define FRAME_TYPE_MASK 0x0007 +#define FRAME_TYPE_BEACON 0x0000 +#define FRAME_TYPE_DATA 0x0001 +#define FRAME_TYPE_ACK 0x0002 +#define FRAME_TYPE_COMMAND 0x0003 + +#define FRAME_PENDING_MASK 0x0008 + +/**@brief RAL atomic section */ +typedef volatile uint8_t ral_atomic_t; + +// private RAL data +typedef struct +{ + volatile uint8_t tx_seq_num; + volatile bool ack_needed; + volatile bool waiting_for_ack; + volatile ral_atomic_t ral_atomic; + volatile mac_timestamp_t received_frame_timestamp; + volatile bool spi_transfer; + volatile bool cca_performing; +#if defined(AT86RF231) + volatile int8_t ed_value; + volatile bool unread_frame; /** This flag is used to deny transmission if incoming frame + has not been read from radio buffer. + todo: remove this deny to accelerate data exchange. + */ + volatile bool is_promiscuous_mode; /**< Set to true if promiscuous mode is enabled.*/ +#elif (defined(NRF52_SERIES) || defined(NRF52)) + // pointer to free memory for rx DMA + volatile uint8_t * p_buffer; + volatile sys_time_t calibr_value; + volatile uint8_t bcc_part; + ral_critical_queue_t critical_rx_queue; + ral_critical_queue_t critical_rx_pool; +#endif +} ral_mem_t; + + +/**@brief Initializes radio abstraction layer. + */ +void ral_init(void); + +/**@brief Performs synchronous ED measurement. + */ +uint8_t ral_ed_perform(void); + +/**@brief Sends request to change radio state. + * + * @param state - New radio state. One of... + * + * @return PHY_SUCCESS, if state has been successfully achieved; + * current state, if state cannot be reached.*/ +phy_enum_t ral_state_set(const phy_enum_t state); + +/**@brief Returns current state of radio. + */ +phy_enum_t ral_state_get(void); + +/**@brief Puts radio into sleep mode + */ +void ral_sleep(void); + + /**@brief Awakes a radio + */ +void ral_wakeup(void); + +/**@brief Performs synchronous cca. + */ +phy_status_t ral_cca_perform(void); + +/**@brief Sends PHY frame. + * + * @param[in] pd_data - full data frame to be send. + * + * @details RAL automatically adds header and FCS control bytes + * to \a pd_data. Caller must reserve 1 byte before \a psdu + * pointer and may leave last two bytes of payload (i.e. FCS + * control field) uninitialized. + * + * RF chip or RAL code is responsible to receive an ACK frame. + * After ACK is handled, device should be restored to the TX state.*/ +void ral_data_req(pd_data_req_t * pd_data); + +/**@brief Reads indication frame from radio. + * + * @param[out] ind - pointer to indication frame that will be filled + * with new frame data. + * + * @param[out] is_last_frame - indicates if this is last currently available frame in RAL + * (if false, this function needs to be called again to extract the next available frame) + * +* RAL code or RF chip is responsible to send an ACK frame, if it was required + * by the sender. In this case radio state should be restored to RX state after + * ACK frame is transmitted. + * + * @retval true Data read successfully, ind contains valid frame. + * @retval false Data read failed, ind doesn't contain valid frame. + */ +bool ral_data_ind_read(pd_data_ind_t ** ind, bool * is_last_frame); + +/**@brief Enable data flow from radio hardware after it was disabled + * by ral_data_flow_disable(). + */ +void ral_data_flow_enable(void); + + +/**@brief Disable data flow from radio hardware + */ +void ral_data_flow_disable(void); + + +/**@brief This function is used to set attribute from MAC or PHY layer + * without checking of its boundaries. + * + * @param id - one of #MAC_SHORT_ADDRESS, #MAC_EXTENDED_ADDRESS, #MAC_PAN_ID + * and some other values. + * @param p_value - pointer to new value. + */ +void ral_attribute_set(uint8_t id, const void * p_value); + + +/**@brief This function is used to get a copy of attribute value stored inside + * radio module. + * + * @param id - one of #PHY_CURRENT_CHANNEL_ID, #PHY_TRANSMIT_POWER_ID or + * PHY_CCA_MODE_ID. Other attributes are not supported. + * @param p_value - pointer to new value. + */ +void ral_attribute_get(uint8_t id, void * p_attr_value); + +/**@brief This function is used to define frame start time by it's size + * and the timestamp, when RX IRQ has been received. + * + * @param irq_time - moment when IRQ has been received. + * @param frame_size - size of received frame in bytes. + * + * @retval MAC timestamp when PHY header has been started to receive. + */ +mac_timestamp_t ral_rx_start_time(mac_timestamp_t irq_time, uint8_t frame_size); + +/**@brief This function performs RSSI. + * + * @retval RSSI sample value. + */ +uint8_t ral_rssi_get(void); + +#endif /* RAL_API_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SecAL/sec_aes_ccm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SecAL/sec_aes_ccm.h new file mode 100644 index 0000000000000000000000000000000000000000..2998256d2037d6125f9180421e0cba7977883a22 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SecAL/sec_aes_ccm.h @@ -0,0 +1,128 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SEC_AES_CCM_H_INCLUDED +#define SEC_AES_CCM_H_INCLUDED + +#include + +/** @file + * This file contains declarations of the AES CCM encryption/decryption routines and necessary types. + * It also contains the declaration of the Security Abstract library initialization routine. + * + * @defgroup sec_aes_ccm Security AES CCM declarations + * @ingroup sec_15_4 + * @{ + * @brief Module to declare Security AES CCM API + */ + +/** + * @brief AES CCM Status enumeration. + */ +typedef enum +{ + AES_CCM_OK, /**< AES CCM operation succeeded. */ + AES_ENGINE_FAIL, /**< AES engine failed. */ + AES_CCM_FAIL, /**< CCM algorithm failed. */ + AES_CCM_AUTH_FAIL /**< CCM authentication failed. */ +} sec_aes_ccm_status_t; + +/** + * @brief AES CCM request. + * + * @details The AES CCM request primitive is issued by the AES user. + * There are two use cases for the request: + * The first one is to encrypt the user text with some given key. + * The second one is to decrypt the cipher text against the key. + * The encrypted or decrypted data is stored in text_data. + */ +typedef struct +{ + /** Counted authentication tag. */ + uint8_t * mic; + /** Security level identifier. */ + uint8_t level; + /** A 128-bit-long string to be used as a key. Each entity must have evidence that access + * to this key is restricted to the entity itself and its intended key sharing group member(s). */ + uint8_t * key; + /** A nonce N of 15 - L octets. Within the scope of any encryption key, the nonce value must be unique. */ + uint8_t * nonce; + /** An octet string representing plain text data in case of encryption and cipher text data + * in case of decryption. */ + uint8_t * text_data; + /** Text data length. */ + uint8_t text_data_len; + /** Octet string representing input data to perform authentication. */ + uint8_t * auth_data; + /** Auth data length. */ + uint8_t auth_data_len; +} sec_aes_ccm_req_t; + + +/** + * @brief Function for initializing the security abstraction layer. + */ +void sec_init(void); + +/** + * @brief AES CCM encryption transformation. + * + * @details Performs synchronous encryption of data. + * + * @param req Encryption request structure. + * @return AES_CCM_OK on success, otherwise an implementation defined error. + */ +sec_aes_ccm_status_t sec_aes_ccm_enc(sec_aes_ccm_req_t * req); + + +/** + * @brief AES CCM decryption transformation. + * + * @details Performs synchronous decryption of a cipher. + * + * @param req Decryption request structure. + * @return AES_CCM_OK on success, otherwise an implementation defined error. + */ +sec_aes_ccm_status_t sec_aes_ccm_dec(sec_aes_ccm_req_t * req); + +/** @} */ + +#endif /* SEC_AES_CCM_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SecAL/sec_aes_entity.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SecAL/sec_aes_entity.h new file mode 100644 index 0000000000000000000000000000000000000000..7390518e7f89cede7b5e09d4838fbb1ecfe0cb30 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SecAL/sec_aes_entity.h @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SEC_AES_ENTITY_H_INCLUDED +#define SEC_AES_ENTITY_H_INCLUDED + +#include + +/** @file + * This file contains declaration of the AES encryption routine. + * It also contains the declaration of the AES entity initialization routine. + * + * @defgroup aes_entity Security AES entity declarations + * @ingroup sec_15_4 + * @{ + * @brief Module to declare AES entity API. + */ + +/** + * @brief Function for initializing the AES ECB module. + */ +void aes_entity_init(void); + +/** + * @brief AES encryption. + * + * @details Performs synchronous encryption of text against the key. + * Encrypted data is stored to text memory. + * + * @param key Pointer to a 128-bit key. + * @param text Pointer to a 128-bit plain text data. + */ +void aes_handle(uint8_t * key, uint8_t * text); + +/** @} */ + +#endif /* SEC_AES_ENTITY_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_crc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_crc.h new file mode 100644 index 0000000000000000000000000000000000000000..4150aca89a7bd7d8b0604def66bd57581b74e646 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_crc.h @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYS_CRC_H_INCLUDED +#define SYS_CRC_H_INCLUDED + +#include +#include + +/** @file + * This file contains declarations of the CRC computing routines and necessary macros/types. + * + * @defgroup sys_crc System CRC API + * @ingroup sys_15_4 + * @{ + * @brief Module to declare System CRC API. + * @details The CRC module implements a set of routines to compute the 16-bit CRC value for octet arrays. + */ + +/** + * @brief Defines an initial value for the CRC sum. + */ +#define SYS_CRC_INIT 0 + +/** + * @brief CRC value type. This module uses 16-bit CRC. + */ +typedef uint16_t sys_crc_t; + +/** + * @brief Function for computing CRC value for given data. + * + * @param[in] p_data Pointer to data to compute. + * @param[in] length Length of data. + * + * @return Returns the CRC value for input data. + */ +sys_crc_t sys_crc_calc(const uint8_t * p_data, size_t length); + +/** + * @brief Function for updating the CRC value taking into the account the previously counted value. + * + * @details This function is used when input data is represented by several pieces. + * Consequently, a call to this function for each piece will give a correct + * total CRC value. + * + * @param[in] current_crc Previously counted CRC value. Should be SYS_CRC_INIT for the first piece. + * @param[in] p_data Pointer to the current piece of data. + * @param[in] length Length of the current piece of data. + * + * @return Returns the updated CRC value. + */ +sys_crc_t sys_crc_continue(sys_crc_t current_crc, const uint8_t * p_data, size_t length); + +/** @} */ + +#endif /* SYS_CRC_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_debug.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_debug.h new file mode 100644 index 0000000000000000000000000000000000000000..b30117ce98dff48a917548fc3d8775ef08cd6333 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_debug.h @@ -0,0 +1,177 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYS_DEBUG_H_INCLUDED +#define SYS_DEBUG_H_INCLUDED + + +#include "hal_debug_interface.h" +#include "hal_trace_interface.h" +#include +#include + +/* This header file contains macros for debugging. */ + +#ifndef ASSERT + #ifdef CONFIG_DEBUG + #define ASSERT(CONDITION_STATEMENT) \ + do \ + { \ + bool LOCAL_CONDITION_CHECK = (CONDITION_STATEMENT); \ + if (LOCAL_CONDITION_CHECK != true) \ + { \ + sys_assert_handler((#CONDITION_STATEMENT), __LINE__, __FILE__); \ + } \ + } while (0) + #else + + #define ASSERT(CONDITION_STATEMENT) + + #endif // CONFIG_DEBUG +#endif // ASSERT + +#ifndef ASSERT_INFO + #ifdef CONFIG_DEBUG + #define ASSERT_INFO(CONDITION_STATEMENT, INFO_FMT, ...) \ + do \ + { \ + bool LOCAL_CONDITION_CHECK = (CONDITION_STATEMENT); \ + if (LOCAL_CONDITION_CHECK != true) \ + { \ + sys_assert_info_handler((#CONDITION_STATEMENT), __LINE__, __FILE__, \ + INFO_FMT, __VA_ARGS__); \ + } \ + } while (0) + + #else + + #define ASSERT_INFO(CONDITION_STATEMENT, INFO_FMT, ...) + + #endif // CONFIG_DEBUG +#endif // ASSERT_INFO + +#ifndef ASSERT_STATIC + #ifdef CONFIG_DEBUG + #define ASSERT_STATIC(e) do { enum {SA = 1/(e)}; } while (0) + #else + #define ASSERT_STATIC(e) + #endif // CONFIG_DEBUG +#endif // ASSERT_STATIC + +/** + * @defgroup sys_debug Debugging macros + * @ingroup sys_15_4 + * @{ + * @brief Functions used for debugging. + */ + + +/**@brief System assertion fault handler. + * + * @details This macro should be used whenever an assertion fault is detected. + * + * @param[in] CONDITION_STRING Assertion condition string, which occurred to be not true. + */ +#define SYS_ASSERT_HANDLER(CONDITION_STRING) \ + do \ + { \ + sys_assert_handler(CONDITION_STRING, __LINE__, __FILE__); \ + } while (0) + + +#ifndef TRACE_PUTS + #ifdef CONFIG_TRACE + #define TRACE_PUTS(s) HAL_TRACE_INTERFACE_PUTS(s) + #else + #define TRACE_PUTS(s) + #endif //CONFIG_TRACE +#endif //TRACE_PUTS + + +#ifndef TRACE + #ifdef CONFIG_TRACE + #define TRACE(INFO_FMT, ...) sys_trace_handler(INFO_FMT, __VA_ARGS__) + #else + #define TRACE(INFO_FMT, ...) + #endif // CONFIG_DEBUG +#endif // TRACE + + +/**@brief System assertion fault handler function. + * + * @param[in] condition Assertion condition string, which was expected to be true. + * + * @param[in] line Line number. + * + * @param[in] file File name. + */ +extern void sys_assert_handler( + const char * condition, const int line, const char * file); + + +/**@brief System assertion fault handler function with additional assertion information. + * + * @param[in] condition Assertion condition string, which was expected to be true. + * + * @param[in] line Line number. + * + * @param[in] file File name. + * + * @param[in] info_fmt Format string for additional assert information. + * + * @param[in] ... Arguments list corresponding to the format string. + */ +extern void sys_assert_info_handler( + const char * condition, const int line, const char * file, + const char * info_fmt, ...); + + +/**@brief System trace output handler function. + * + * @param[in] fmt Format string for trace output. + * + * @param[in] ... Arguments list corresponding to the format string. + */ +extern void sys_trace_handler(const char * fmt, ...); + +/** @} */ + +#endif // SYS_DEBUG_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_events.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_events.h new file mode 100644 index 0000000000000000000000000000000000000000..3454a2d55714c6c4be26980c2ba04e38ba150820 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_events.h @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYS_EVENTS_H_INCLUDED +#define SYS_EVENTS_H_INCLUDED + +#include +#include "sys_queue.h" + +/** @file + * This file contains declarations of the Events API and necessary types. The Events feature is implemented + * using the Queue functionality. + * + * @defgroup sys_events System events API + * @ingroup sys_15_4 + * @{ + * @brief Module for declaring system events API. + * @details The Events module defines some routines to subscribe/unsubscribe to/from system events. The events pool + * can be extended by adding new events to the sys_event_id_t enumeration. The registered callbacks + * can be called for an array of events. The callbacks can be called implicitly via posting the event by the + * sys_event_post() routine. + */ + +/**@brief IDs of globally available events. + * + * @details Event IDs are system extension points that allow the user to implement + * specific processing of predefined set of events, occurring in different modules. + */ +typedef enum +{ + SYS_EVENT_FALLING_ASLEEP, /**< Falling asleep event. */ + SYS_EVENT_WAKE_UP, /**< Waking up event. */ + SYS_EVENT_OUT_OF_MEMORY, /**< Out of memory event. */ + SYS_EVENT_MEMORY_FREED, /**< Memory was freed up event. */ + + /** \note The list of system events can be extended during the implementation phase. */ + + /* The following event IDs are used only for unit testing */ + TST_EVENT_0, /**< Test event #0. */ + TST_EVENT_1, /**< Test event #1. */ + TST_EVENT_2, /**< Test event #2. */ + +#if (CONFIG_USE_SYS_TASK_NOTIFIER == 1) + /** This event is posted when there are unhandled events available in + * any of the schedulers. + */ + SYS_EVENT_NEW_TASK, +#endif + + SYS_EVENTS_AMOUNT +} sys_event_id_t; + + +/**@brief Prototype of user-implemented callback for processing an event. + * + * @details This callback is registered for the given event by a *_subscribe routine, + * and is then called by the system events engine, when this event occurs. + * + * @param[in] p_data Pointer to the data, specific for this event. + */ +typedef void (* sys_event_callback_t)(const void * p_data); + + +/**@brief Event descriptor. + * + * @details This descriptor is used to subscribe/unsubscribe to/from the event. + */ +typedef struct +{ + /** Service field. */ + sys_queue_item_t queue_item; + + /** ID of the event to which this callback is to be subscribed. */ + sys_event_id_t event_id; + + /** Callback function which is to be called when this event occurs. */ + sys_event_callback_t callback; +} sys_event_desc_t; + + +/**@brief Function for initializing the global events infrastructure. + */ +void sys_events_init(void); + + +/**@brief Function for subscribing to a system event. + * + * @param[in] p_event_desc Pointer to the event descriptor. + */ +void sys_event_subscribe(sys_event_desc_t * p_event_desc); + + +/**@brief Function for unsubscribing from a system event event. + * + * @param[in] p_event_desc Pointer to the event descriptor. + */ +void sys_event_unsubscribe(sys_event_desc_t * p_event_desc); + + +/**@brief Function for subscribing to a group of events. + * + * @param[in] p_desc_array Pointer to the array of event descriptors. + * @param[in] desc_amount Amount of event descriptors in the array. + */ +void sys_events_array_subscribe(sys_event_desc_t * p_desc_array, size_t desc_amount); + + +/**@brief Function for unsubscribing from the group of events. + * + * + * @param[in] p_desc_array Pointer to the array of event descriptors. + * @param[in] desc_amount Amount of the event descriptors in the array. + */ +void sys_events_array_unsubscribe(sys_event_desc_t * p_desc_array, size_t desc_amount); + + +/**@brief Function for posting an event. + * + * @details This function is used to notify all the subscribers of the given events via + * their callbacks, when the given event occurs. + * + * @param[in] event_id ID of the event to be posted. + * @param[in] p_data Pointer to be passed to the event handlers' callbacks. + */ +void sys_event_post(sys_event_id_t event_id, const void * p_data); + +/** @} */ + +#endif // SYS_EVENTS_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_fsm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_fsm.h new file mode 100644 index 0000000000000000000000000000000000000000..9213252a9d05d7a3100e3af1a94c2e5767d31fb3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_fsm.h @@ -0,0 +1,286 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYS_FSM_H_INCLUDED +#define SYS_FSM_H_INCLUDED + +#include +#include + +/** @file + * This file contains declarations of the Finite State Machine (FSM) primitives and necessary types. + * + * @defgroup sys_fsm Finite State Machine API + * @ingroup sys_15_4 + * @{ + * @brief Module to declare Finite State Machine API + * @details The FSM module implements the Finite State Machine abstraction. The user is intended to implement a transition + * table of states with guards and actions in order to represent some event-driven subject. When a table is + * implemented, call sys_fsm_init() to initialize the FSM. After that, the only routine to + * work with FSM is sys_fsm_event_post(). + */ + +/**@brief Fixed-size type for FSM state ID. + */ +typedef uint8_t sys_fsm_state_id_t; + + +/**@brief Fixed-size type for FSM event ID. + */ +typedef uint8_t sys_fsm_event_id_t; + + +/**@brief Fixed-size type for FSM guard condition ID. + */ +typedef uint8_t sys_fsm_guard_id_t; + + +/**@brief Fixed-size type for FSM action ID. + */ +typedef uint8_t sys_fsm_action_id_t; + + +/**@brief FSM transition description (item of FSM transition table). + * + * @details When an event with given event_id occurs, the guard condition with guard_id + * is checked, and if it returns true, the action with action_id is performed, + * and state machine is switched to the state with new_state_id. + */ +typedef struct +{ + sys_fsm_event_id_t event_id; /**< FSM event ID. */ + sys_fsm_guard_id_t guard_id; /**< FSM guard ID. */ + sys_fsm_action_id_t action_id; /**< FSM action ID. */ + sys_fsm_state_id_t new_state_id; /**< New state ID. */ +#if defined(CONFIG_FSM_DEBUG) + const char * debug_string; +#endif +} sys_fsm_transition_t; + + +/**@brief FSM transition declaration (item of FSM transition table). + */ +#if defined(CONFIG_FSM_DEBUG) +# define SYS_FSM_TRANSITION(event_id, guard_id, action_id, new_state_id) \ + {(event_id), (guard_id), (action_id), (new_state_id), \ + "(" #event_id ", " #guard_id ", " #action_id " -> " #new_state_id ")"} +#else +# define SYS_FSM_TRANSITION(event_id, guard_id, action_id, new_state_id) \ + {(event_id), (guard_id), (action_id), (new_state_id)} +#endif + + +/**@brief FSM state declaration. + * + * @details The state is an aggregator item of the FSM transition table, aggregating + * the transitions, declared immediately after this state declaration. + * All transition declaration items, following the state declaration item, + * will be aggregated in this state, until the next state declaration item, + * or the "end of table" item. + */ +#define SYS_FSM_STATE(state_id) \ + {(state_id) | SYS_FSM_STATE_FLAG, 0, 0, 0} + + +/**@brief Empty guard condition ID. + * + * @details Special value of the guard_id field. If it is used in transition declaration, + * guard check will be omitted. + */ +#define SYS_FSM_NO_GUARD 0xFF + + +/**@brief Empty guard condition ID (useful synonym). + * + * @details Special value of the guard_id field. If it is used in transition declaration, + * guard check will be omitted. + */ +#define SYS_FSM_OTHERWISE 0xFF + + +/**@brief Empty guard condition ID (useful synonym). + * + * @details Special value of the guard_id field. If it is used in transition declaration, + * guard check will be omitted. + */ +#define SYS_FSM_ALWAYS 0xFF + + +/**@brief Empty action ID. + * + * @details Special value of the action_id field. If it is used in transition declaration, + * no action will be performed during the transition. + */ +#define SYS_FSM_NO_ACTION 0xFF + + +/**@brief Same state ID. + * + * @details Special value of the next_state_id field. If it is used in transition + * declaration, the current state will not be changed. + */ +#define SYS_FSM_SAME_STATE 0xFF + + +/**@brief Any state ID. + * + * @details Special value of the event_id field. If it is used in transition + * declaration table, then the transitions listed in this state will be applied + * in case they have not been listed in the transition table for the + * current FSM state. + * Only one SYS_FSM_STATE(SYS_FSM_ANY_STATE) can be present in the transition table. + */ +#define SYS_FSM_ANY_STATE 0xFF + + +/**@brief State declaration flag. + * + * @details Special flag of the event_id field. This flag is used to distinguish + * between state declaration and transition declaration. + */ +#define SYS_FSM_STATE_FLAG 0x80 + + +/**@brief Prototype of a user-defined FSM guard condition function. + * + * @details You must implement a single FSM guard condition function which will + * use an ID of the needed guard check as a parameter. + * + * @param[in] guard_id Guard condition ID to be checked. + * @param[in] p_data Additional FSM specific data. + * + * @retval true Transition is allowed, false otherwise. + */ +typedef bool (* sys_fsm_guard_t)(sys_fsm_guard_id_t guard_id, void * p_data); + + +/**@brief Prototype of a user-defined FSM action function. + * + * @details You must implement a single FSM action function which will + * use an ID of the needed action as a parameter. + * + * @param[in] action_id Action ID to be performed. + * @param[in] p_data Additional FSM specific data. + */ +typedef void (* sys_fsm_action_t)(sys_fsm_action_id_t action_id, void * p_data); + + +/**@brief Constant FSM descriptor which can reside in read-only memory. + */ +typedef struct +{ +#if defined(CONFIG_FSM_DEBUG) + const char * debug_fsm_name; +#endif + /** Pointer to the transition table. + */ + const sys_fsm_transition_t * transition_table; + + /** Number of transitions in the transition table. + */ + uint8_t transitions_amount; + + /** Initial state ID. + */ + sys_fsm_state_id_t initial_state; + + /** Pointer to the guard condition function. + */ + sys_fsm_guard_t guard; + + /** Pointer to the action function. + */ + sys_fsm_action_t action; +} sys_fsm_const_descriptor_t; + + +/**@brief FSM dynamic descriptor, holding the current state of the FSM. +*/ +typedef struct +{ + /** Pointer to the constant FSM descriptor which can reside in read-only memory. + */ + const sys_fsm_const_descriptor_t * fsm_const_desc; + + /** Index of the "any state transitions" block. + */ + uint8_t any_state_transitions_index; + + /** Current state ID. + */ + volatile sys_fsm_state_id_t current_state; + + /** Recursion protection. + */ + volatile uint8_t recursion_protection; +} sys_fsm_t; + + +#if defined(CONFIG_FSM_DEBUG) + #define FSM_DEBUG_NAME(name_string) .debug_fsm_name = name_string, +#else + #define FSM_DEBUG_NAME(name_string) +#endif + + +/**@brief Function for initializing a specific FSM. + * + * @param[in] p_fsm Pointer to FSM descriptor to initialize. + * @param[in] p_fsm_const Pointer to constant FSM descriptor with transition table, etc. + */ +void sys_fsm_init(sys_fsm_t * p_fsm, const sys_fsm_const_descriptor_t * p_fsm_const); + + +/**@brief Function for posting an event to FSM. + * + * @details This function causes FSM transition from the current state to the new state, + * according to the transition table of this FSM. + * The corresponding guard check and action is performed. + * + * @param[in] p_fsm Pointer to FSM descriptor. + * @param[in] event_id Event ID to post. + * @param[in] p_data Pointer to the FSM-specific data. + */ +void sys_fsm_event_post(sys_fsm_t * p_fsm, sys_fsm_event_id_t event_id, void * p_data); + +/** @} */ + +#endif // SYS_FSM_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_init.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_init.h new file mode 100644 index 0000000000000000000000000000000000000000..513b2f23260e241214bf95eaadafef17557e7c33 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_init.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYS_INIT_H_INCLUDED +#define SYS_INIT_H_INCLUDED + +#include + +/** + * @defgroup sys_15_4_init Initialization API + * @ingroup sys_15_4 + * @{ + * @brief API for initizalizing the system abstraction library. + */ + +/** @brief Initializes every component of this stack. + * + * This function must be called before using any of the components. + * + * @param[in] p_start Pool start address. + * @param[in] size Size of the pool in bytes. + * + * @details The pool start address must be aligned on the ALIGN_VALUE boundary, which is + * defined in @c sys_utils.h. + * The pool size should be multiple of an ALIGN_VALUE, which is defined in @c sys_utils.h. + */ +void sys_init(void * p_start, size_t size); + +/** @} */ + +#endif /* SYS_INIT_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_list.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_list.h new file mode 100644 index 0000000000000000000000000000000000000000..4fd4847b30c46ed36e11a5e89203b397eac7fc92 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_list.h @@ -0,0 +1,248 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYS_LIST_H_INCLUDED +#define SYS_LIST_H_INCLUDED + +/** @file + * This file contains declarations of the doubly linked list primitives and necessary types. + * This implementation is Linux-proven and used in the memory management module. + * + * @defgroup sys_list Doubly linked list API. + * @ingroup sys_15_4 + * @{ + * @brief Module to declare the doubly linked list API. + */ + +/** + * Internal list "head" struct. + */ +struct sys_list_head +{ + struct sys_list_head * next; + struct sys_list_head * prev; +}; + +typedef struct sys_list_head sys_list_head_t; + + +/** + * @brief Initializes a list by variable name. + * @warning this macro assumes that a list "head" (sys_list_head_t) variable + * with name \a name is already created. + * + * @param[inout] name The "head" struct name. + */ +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +/** + * @brief Defines and initializes a new list. + * @details A call to this macro creates a new variable with the given name and + * initializes it as a list "head". + * + * @param[inout] name The "head" struct name. + */ +#define LIST_HEAD(name) sys_list_head_t name = { &(name), &(name) } + + +/** + * @brief Initializes a list by pointer. + * + * @param[inout] ptr Pointer to a list. + */ +#define INIT_LIST_HEAD(ptr) \ + do \ + { \ + (ptr)->prev = (ptr); \ + (ptr)->next = (ptr); \ + } while (0) + + +/** + * @brief Checks if a list is empty. + * + * @param[in] sys_list_head Pointer to a list. + * @return 0 if not empty, non-zero otherwise. + */ +#define IS_EMPTY(sys_list_head) (sys_list_head)->next == (sys_list_head) + + +/** + * @brief Adds a new item to the list between \a l_prev and \a l_next elements. + * @warning This routine assumes that \a l_next is next to \a l_prev in the list. + * @note This is an internal helper routine which is not intended to be used by the user. + * + * @param[in] l_prev Pointer to the previous element. + * @param[in] l_next Pointer to the next element. + * @param[in] l_new Pointer to a new element. + */ +static inline void sys_ll_list_add(sys_list_head_t * l_prev, + sys_list_head_t * l_next, + sys_list_head_t * l_new) +{ + l_new->prev = l_prev; + l_prev->next = l_new; + l_next->prev = l_new; + l_new->next = l_next; +} + +/** + * @brief Deletes an element between \a l_prev and \a l_next elements. + * @warning This macro assumes that \a l_next is next to \a l_prev in the list. + * @note This is an internal helper routine which is not intended to be used by the user. + * + * @param[in] l_prev Pointer to the previous element. + * @param[in] l_next Pointer to the next element. + */ +static inline void sys_ll_list_del(sys_list_head_t * l_next, + sys_list_head_t * l_prev) +{ + l_next->prev = l_prev; + l_prev->next = l_next; +} + +/** + * @brief Function for adding a new item to the head of the list. + * + * @param[in] new Pointer to a new element. + * @param[in] head Pointer to the list head. + */ +static inline void sys_list_add(sys_list_head_t * new, sys_list_head_t * head) +{ + sys_ll_list_add(head, head->next, new); +} + + +/** + * @brief Function for adding a new item to the tail of the list. + * + * @param[in] new Pointer to a new element. + * @param[in] head Pointer to the list head. + */ +static inline void sys_list_add_tail(sys_list_head_t * new, sys_list_head_t * head) +{ + sys_ll_list_add(head->prev, head, new); +} + + +/** + * @brief Function for deleting an entry from list. + * + * @param[in] entry The element to delete from the list. + */ +static inline void sys_list_del(sys_list_head_t * entry) +{ + sys_ll_list_del(entry->next, entry->prev); +} + + +/** + * @brief Function for deleting an entry from the list and reinitializing it. + * + * @param[in] entry The element to delete from the list. + */ +static inline void sys_list_del_init(sys_list_head_t * entry) +{ + sys_ll_list_del(entry->next, entry->prev); + INIT_LIST_HEAD(entry); +} + + +/** + * @brief Function for testing if a list is empty. + + * @param[in] head The list to test. + * @return 0 if not empty, non-zero otherwise. + */ +static inline unsigned int sys_list_empty(sys_list_head_t * head) +{ + return IS_EMPTY(head); +} + + +/** + * @brief Sets a pointer to a variable to the parent structure pointer using a + * pointer to a field in this structure. + * + * @note This is a version of @ref GET_PARENT_BY_FIELD() extended by setting to a variable. + * + * @param[out] ll_ret_var Variable pointer name to return. + * @param[in] ll_ptr Pointer to the structure field. + * @param[in] ll_type Name of the parent structure. + * @param[in] ll_member Name of the structure field. + */ +#define SYS_LIST_ENTRY(ll_ret_var, ll_ptr, ll_type, ll_member) \ + do \ + { \ + size_t p = (size_t) ll_ptr; \ + size_t off = offsetof(ll_type, ll_member); \ + ll_ret_var = (ll_type *) (p - off); \ + } while (0) + + +/** + * @brief Iterates through the list. + * @note Use @ref SYS_LIST_FOR_EACH_SAFE() for thread-safe cases. + * + * @param[out] pos Iterator variable. + * @param[in] head Pointer to the list head. + */ +#define SYS_LIST_FOR_EACH(pos, head) \ + for (pos = ((head)->next); \ + ((pos) != (head)); \ + pos = (pos)->next) + + +/** + * @brief Thread-safe version of @ref SYS_LIST_FOR_EACH(). + * + * @param[out] ll_pos Iterator variable. + * @param[out] ll_pos_n Temporary iterator variable (next entry). + * @param[in] ll_head Pointer to the list head. + */ +#define SYS_LIST_FOR_EACH_SAFE(ll_pos, ll_pos_n, ll_head) \ + for (ll_pos = (ll_head)->next, ll_pos_n = (ll_head)->next->next; \ + (ll_pos) != (ll_head); \ + ll_pos = ll_pos_n, ll_pos_n = ll_pos->next) + +/** @} */ + +#endif /* SYS_LIST_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_memory_manager.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_memory_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..ccf89b1924d6ddbe51d4ca07fd6162882eb2003f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_memory_manager.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/* This module declares the Memory Management functionality. + * Please use sys_mm_init before calling to any module routines. + * Call sys_mm_alloc to allocate memory. + * Use sys_mm_free to free the allocated memory + */ + +#ifndef SYS_MEMORY_MANAGER_H_INCLUDED +#define SYS_MEMORY_MANAGER_H_INCLUDED + +#include +#include + +/** @file + * This file contains declarations of the Memory manager API. + * + * @defgroup sys_memory_manager Memory Manager API + * @ingroup sys_15_4 + * @{ + * @brief Module to declare Memory Manager API. + * @details The Memory Manager module implements the standard API for allocating/freeing memory chunks. The module must + * be initialized by sys_mm_init() before a call to any alloc/free routines. The memory can be allocated by a + * call to sys_mm_alloc() and freed by a call to sys_mm_free(). Minimal chunk of memory to allocate is one byte, + * however the sys_mm_alloc() routine will allocate the number of bytes aligned to the length of the + * machine word (e.g. 4 bytes for 32-bit architectures). The module is implemented using the doubly linked + * lists API. + */ + +/**@brief Function for initializing the memory manager. + * @details Initialize the memory manager pool of the 'size' bytes length at 'p_start' address. + * + * @param p_start Pool start address. + * @param size Size of the pool in bytes. + */ +void sys_mm_init(void * p_start, size_t size); + + +/**@brief Function for allocating memory in the pool. + * @details Search and allocate free memory resources. + * + * @param[in] size Size of the requested memory. + * + * @retval Pointer to allocated memory, + * NULL in case of error. + */ +void * sys_mm_alloc(size_t size); + + +/**@brief Function for freeing the allocated memory. + * + * @param[in] p_addr Pointer to the memory to free. + * + */ +void sys_mm_free(void * p_addr); + +/** @} */ + +#endif // SYS_MEMORY_MANAGER_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_queue.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_queue.h new file mode 100644 index 0000000000000000000000000000000000000000..28efae24076d7251cf3f205c389e7917322ab3dc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_queue.h @@ -0,0 +1,290 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYS_QUEUE_H_INCLUDED +#define SYS_QUEUE_H_INCLUDED + +#include +#include + +/** @file + * This file contains declarations of the primitives to work with queues and necessary types. + * + * @defgroup sys_queues Queue API + * @ingroup sys_15_4 + * @{ + * @brief Module to declare the queue API. + * @details The queue module implements a set of routines to deal with queues. Before + * any calls to its API are issued, a queue must be initialized using sys_queue_init(). The following routines + * return queue items from different parts of an initialized queue without removing it from the queue: + * sys_queue_front(), sys_queue_back(), sys_queue_next(), and sys_queue_at(). + * The following routines insert elements to the queue: sys_queue_push_front(), + * sys_queue_push_back(), sys_queue_push_predicated(), sys_queue_push_predicated_force(), and sys_queue_insert(). + * The following routines remove elements from the queue: sys_queue_pop_front(), sys_queue_remove(), + * sys_queue_remove_after(). These helper routines get information about a queue: sys_queue_size() and + * sys_queue_is_empty(). The module also supports an iterator macro implemented by SYS_QUEUE_FOR_EACH(). + */ + +/**@brief Queue item descriptor. + * + * @details In order to store any user data struct in a queue, the user struct should contain + * a field of type 'sys_queue_item_t'. This field may be at any offset. + * The user data item can be cast from the queue item, + * by the \ref GET_PARENT_BY_FIELD() macro from sys_utils.h. + */ +typedef struct sys_queue_item_s +{ + struct sys_queue_item_s * next; +} sys_queue_item_t; + +/**@brief Queue descriptor. + */ +typedef sys_queue_item_t sys_queue_t; + +/**@brief Prototype of a predicate function for pushing an item into the queue. + * + * @details As a user of the queue library, implement the predicate function and pass it + * as a parameter to \ref sys_queue_push_predicated(). You can choose + * whether insertion of a new item should be done before the given existing item of + * the queue, or not. + * + * @param[in] p_before_item Pointer to the existing item before which a new item + * should be inserted. + * @param[in] p_new_item Pointer to the item to be inserted into the queue. + * + * @retval true Insertion is to be done before the given item, false otherwise. + */ +typedef bool (* sys_queue_push_predicate_t)( + sys_queue_item_t * p_before_item, + sys_queue_item_t * p_new_item); + + +/**@brief Function for initializing the queue before any other usage of the queue. + * + * @details Initialize (reset) the queue to its initial state. The queue becomes empty. + * + * @param[in] p_queue Queue to be initialized. + */ +void sys_queue_init(sys_queue_t * p_queue); + + +/**@brief Function for getting the front (head) item of the queue without removing it. + * + * @details Return a pointer to the item from the head of the queue but leave it in the queue. + * + * @param[in] p_queue Queue to get the item from. + * + * @retval Pointer to the head item of the queue, or NULL if the queue is empty. + */ +sys_queue_item_t * sys_queue_front(const sys_queue_t * p_queue); + + +/**@brief Function for getting the back (tail) item of the queue without removing it. + * + * @details Return a pointer to the item from the tail of the queue but leave it in the queue. + * + * @param[in] p_queue Queue to get the item from. + * + * @retval Pointer to the tail item of the queue, or NULL if the queue is empty. + */ +sys_queue_item_t * sys_queue_back(const sys_queue_t * p_queue); + + +/**@brief Function for getting the item, next to the given item of the queue. + * + * @details Return a pointer to the next item after the given one, or NULL if the + * given item is the last item of the queue. + * + * @param[in] p_queue Pointer to the queue. + * @param[in] p_item Pointer to the item. + * + * @retval Pointer to the next item after the given one, or NULL if the + * given item is the last item of the queue. + */ +sys_queue_item_t * sys_queue_next(const sys_queue_t * p_queue, const sys_queue_item_t * p_item); + + +/**@brief Function for pushing an item to the front (head) of the queue. + * + * @details This function inserts an item to the head of the queue. + * + * @param[in] p_queue Queue to push the item to. + * @param[in] p_item Item to insert to the front of the queue. + */ +void sys_queue_push_front(sys_queue_t * p_queue, sys_queue_item_t * p_item); + + +/**@brief Function for pushing an item to the back (tail) of the queue. + * + * @details This function inserts an item to the tail of the queue. + * + * @param[in] p_queue Queue to push the item to. + * @param[in] p_item Item to insert to the tail of the queue. + */ +void sys_queue_push_back(sys_queue_t * p_queue, sys_queue_item_t * p_item); + + +/**@brief Function for pushing an item to the queue with a predicate. + * + * @details Conditionally push an item to the queue using the given predicate that tries to determine + * the insertion position. + * + * @param[in] p_queue Queue to push the item to. + * @param[in] p_item Item to be pushed. + * @param[in] predicate Predicate to be used to find the insertion position. + * + * @retval true The item was inserted into the queue, false otherwise. + */ +bool sys_queue_push_predicated( + sys_queue_t * p_queue, + sys_queue_item_t * p_item, + sys_queue_push_predicate_t predicate); + + +/**@brief Function for pushing an item to the queue with a predicate forcing insertion to the tail if the predicate + * fails. + * + * @details Unconditionally push an item to the queue using the given predicate that tries to + * determine the insertion position. + * If predicate returns false, then force the insertion to the tail of the queue. + * + * @param[in] p_queue Queue to push item to. + * @param[in] p_item Item to be pushed. + * @param[in] predicate Predicate to be used to find the insertion position. + */ +void sys_queue_push_predicated_force( + sys_queue_t * p_queue, + sys_queue_item_t * p_item, + sys_queue_push_predicate_t predicate); + + +/**@brief Function for getting and removing the front (head) item from the queue. + * + * @details Get an item from the head of the queue and remove it from the queue. + * + * @param[in] p_queue Queue to get and remove the head item from. + * + * @retval Pointer to the head item of queue or NULL if the queue is empty. + */ +sys_queue_item_t * sys_queue_pop_front(sys_queue_t * p_queue); + + +/**@brief Function for removing an item from the queue. + * + * @details The given item will be removed from the queue. + * + * @note The complexity of this function is O(n). Use function \ref sys_queue_remove_after() + * whenever the previous item of the queue is known. + * + * @param[in] p_queue Queue to remove the item from. + * @param[in] p_item Item to remove from the queue. + */ +void sys_queue_remove(sys_queue_t * p_queue, sys_queue_item_t * p_item); + + +/**@brief Function for removing the item after the given item from the queue. + * + * @details The item next to the given one will be removed from the queue. + * + * @param[in] p_queue Queue to remove the item from. + * @param[in] p_after_item Next to this item will be removed. + */ +void sys_queue_remove_after(sys_queue_t * p_queue, sys_queue_item_t * p_after_item); + + +/**@brief Function for returning the current size of a queue, i.e. number of elements inside it. + * + * @details This function goes through the whole queue, so it is relatively slow. + * + * @param[in] p_queue Queue to work with. + * + * @retval Number of items currently inserted into the queue. + */ +uint8_t sys_queue_size(const sys_queue_t * p_queue); + + +/**@brief Function for returning a pointer to the item inside a queue represented by an index. + * + * @details This function searches through the whole queue, so it is relatively slow. + * + * @param[in] p_queue Queue to work with. + * @param[in] index Requested index. + * + * @retval Pointer to the requested item or NULL if the queue size is less + * than \a index. + */ +sys_queue_item_t * sys_queue_at(const sys_queue_t * p_queue, const uint8_t index); + + +/**@brief Function for inserting an item at the specified position represented by an index in the queue. + * If this position is too big, it is inserted to the tail of the queue. + * + * @details This function searches through the whole queue, so it is relatively slow. + * + * @param[in] p_queue Queue to insert to. + * @param[in] p_item Item to be inserted. + * @param[in] pos Position inside the queue (0 is the front). + */ +void sys_queue_insert(sys_queue_t * p_queue, sys_queue_item_t * p_item, const uint8_t pos); + + +/**@brief Function for determining if a queue is empty. + * + * @param[in] p_queue Queue to be checked. + * + * @retval True if queue is empty, false otherwise. + */ +bool sys_queue_is_empty(const sys_queue_t * p_queue); + + +/**@brief Macro for iterating through all items in the queue. + * + * @param[in] p_queue Pointer to the queue (sys_queue_t *). + * @param[in] p_iterator Variable to be used as an iterator (sys_queue_item_t *). + */ +#define SYS_QUEUE_FOR_EACH(p_queue, p_iterator) \ + for (sys_queue_item_t * p_iterator = sys_queue_front(p_queue); \ + p_iterator != NULL; \ + p_iterator = sys_queue_next(p_queue, p_iterator)) + +/** @} */ + +#endif // SYS_QUEUE_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_ringbuffer.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_ringbuffer.h new file mode 100644 index 0000000000000000000000000000000000000000..7a8ce2e7889da957478d4bcec47863ac71c49629 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_ringbuffer.h @@ -0,0 +1,202 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYS_RINGBUFFER_H_INCLUDED +#define SYS_RINGBUFFER_H_INCLUDED + +#include +#include +#include + +/** @file + * This file contains declarations of the Ring buffer routines and necessary types. Please note that + * each ring buffer element should have size of 1 byte. + * + * @defgroup sys_ringbuffer System Ring buffer API + * @ingroup sys_15_4 + * @{ + * @brief Module for declaring System Ring buffer API. + * @details The Ring Buffer module implements routines to deal with the ring buffer. The following routines are supported: + * sys_ringbuffer_insert(), sys_ringbuffer_remove() to operate with single element. The + * sys_ringbuffer_remove_multiple() can be used to remove (read) several elements at once. The + * sys_ringbuffer_clear(), sys_ringbuffer_init(), and sys_ringbuffer_init_over() functions are used to clean up and + * initialize the ring buffer. Some information about the initialized ring buffer is available via the + * following routines: sys_ringbuffer_size_get() to get the number of used elements, sys_ringbuffer_chunk_get() + * to return the biggest, available to read, continuous chunk of elements, sys_ringbuffer_is_empty() and + * sys_ringbuffer_is_full() to check if the ring buffer is empty/full, and sys_ringbuffer_max_size_get() to get + * the ring buffer capacity. One of the samples for ring buffer usage is the UART implementation. + */ + +/** This structure holds all necessary information about a ring buffer. It is intentionally left undocumented + * by Doxygen. + * + * All these fields are private and must NOT be changed by the user. + */ +typedef struct +{ + size_t write_index; + size_t read_index; + uint8_t * array; + size_t size; + bool is_full; +} sys_ringbuffer_t; + +/** @brief Function for initializing an empty ring buffer over passed memory. + * + * @param[inout] buffer Instance of sys_ringbuffer_t that will be initialized. + * @param[in] memory Start address of the memory region used as a ring buffer. + * @param[in] length Size in bytes of the memory region used as a ring buffer. + */ +void sys_ringbuffer_init(sys_ringbuffer_t * buffer, + const void * memory, + const size_t length); + +/** @brief Function for initializing a ring buffer over passed memory and marking all + * pre_init_length elements as inserted. + * + * @details This function may be used to initialize a buffer with some + * pre-initialized data in it. Passed memory region is interpreted by this function + * as an already filled (partly or fully) ring buffer so that \a pre_init_length + * elements are marked as inserted. + * + * @param[inout] buffer Instance of sys_ringbuffer_t that will be initialized. + * @param[in] memory Start address of the memory region used as a ring buffer. + * @param[in] pre_init_length Number of elements (bytes) that had already been in \a memory. + * They would be inserted into the newly-initialized ring buffer in a FIFO manner. + * @param[in] length Size of the memory region used as a ring buffer. + */ +void sys_ringbuffer_init_over(sys_ringbuffer_t * buffer, + const void * memory, + const size_t pre_init_length, + const size_t length); + +/** @brief Function for removing an element from a ring buffer and returning it. + * + * @param[inout] buf Instance of @c sys_ringbuffer_t. + * + * @return Value of the removed element. + * + * @warning This buffer has no underflow control except assert. + */ +uint8_t sys_ringbuffer_remove(sys_ringbuffer_t * buf); + +/** @brief Function for quickly removing up to chunk_size elements from a ring buffer + * and marking those elements as available in the ring buffer. + * + * @param[inout] buffer Instance of @c sys_ringbuffer_t. + * @param[in] chunk_size Number of elements to release. + */ +void sys_ringbuffer_remove_multiple(sys_ringbuffer_t * buffer, + const size_t chunk_size); + +/** @brief Function for inserting a new element into a ring buffer. + * + * @param[inout] buffer Instance of @c sys_ringbuffer_t. + * @param[in] data Element value to insert. + * + * @warning In case of overflow, this buffer will overwrite the oldest + * element and the number of available elements will remain unchanged. + */ +void sys_ringbuffer_insert(sys_ringbuffer_t * buffer, const uint8_t data); + +/** @brief Function for clearing an instance of \a sys_ringbuffer_t, making it empty. + * + * @param[inout] buffer Instance of @c sys_ringbuffer_t. + */ +void sys_ringbuffer_clear(sys_ringbuffer_t * buffer); + +/** @brief Function for returning the number of used elements in a ring buffer instance. + * + * @param[inout] buf Instance of sys_ringbuffer_t. + * + * @return Number of elements. + */ +size_t sys_ringbuffer_size_get(const sys_ringbuffer_t * buf); + +/** @brief Function for returning the biggest, available to read, continuous chunk from a ring buffer array. + * + * @param[inout] buffer Instance of @c sys_ringbuffer_t. + * @param[out] chunk Pointer to a memory chunk removed from the ring buffer. + * @param[out] chunk_size Size of the removed chunk. + * + * @warning The returned chunk is still part of the ring buffer. To make the chunk elements available + * for write, call @c sys_ringbuffer_remove_multiple() after the chunk is processed. + */ +void sys_ringbuffer_chunk_get(sys_ringbuffer_t * buffer, + void ** chunk, + size_t * chunk_size); + +/** @brief Function for checking whether a ring buffer is empty. + * + * @param[inout] buf Instance of @c sys_ringbuffer_t. + * + * @return True if the ring buffer is empty. + */ +static inline bool sys_ringbuffer_is_empty(const sys_ringbuffer_t * buf) +{ + return ((buf->write_index == buf->read_index) && (!buf->is_full)); +} + +/** @brief Function for checking whether a ring buffer is full. + * + * @param[inout] buf Instance of @c sys_ringbuffer_t. + * + * @return True if number of items in the buffer equals to (length - 1). + */ +static inline bool sys_ringbuffer_is_full(const sys_ringbuffer_t * buf) +{ + return buf->is_full; +} + +/** @brief Function for returning number of elements that can be potentially put into the buffer. + * + * @param[inout] buf Instance of @c sys_ringbuffer_t. + * + * @return Number of elements. + */ +static inline size_t sys_ringbuffer_max_size_get(const sys_ringbuffer_t * buf) +{ + return buf->size; +} + +/** @} */ + +#endif /* SYS_RINGBUFFER_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_sleep.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_sleep.h new file mode 100644 index 0000000000000000000000000000000000000000..cf776bbbbdcb38855ebdbe999d96e0d99ccb299f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_sleep.h @@ -0,0 +1,155 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYS_SLEEP_H_INCLUDED +#define SYS_SLEEP_H_INCLUDED + +#include +#include "sys_events.h" +#include "hal_sleep.h" + + +/** @file + * + * @defgroup sys_sleep Falling Asleep API + * @ingroup sys_15_4 + * @{ + * @brief Module for declaring the Falling Asleep API. + * @details Because additional preparation may be required to be done by user modules, + * prior to putting hardware into the sleep mode, a notification and approval mechanism + * is provided to the user. + * Each module that wants to be notified about the "falling asleep" event, has to subscribe + * to the HAL_EVENT_FALLING_ASLEEP event, using sys_sleep_approver_register(), and to + * get the unique approver's ID value. + * In the handler of the HAL_EVENT_FALLING_ASLEEP event, the module is able to perform + * the required preparation before falling asleep, and to approve the falling asleep request, + * using the module unique approver ID, after all preparation to sleep is finished. + * The hardware will fall asleep only after all the registered approvers + * approve the fall asleep request. + */ + +/**@brief Approver ID typedef. + */ +typedef uint8_t sys_sleep_approver_id_t; + + +/* Sanity check for CONFIG_MAX_SLEEP_APPROVERS + */ +#if (!defined(CONFIG_MAX_SLEEP_APPROVERS)) +# error "CONFIG_MAX_SLEEP_APPROVERS must be defined in config file" +#elif (CONFIG_MAX_SLEEP_APPROVERS >= 256) +# error "CONFIG_MAX_SLEEP_APPROVERS must be less than 256" +#endif + + +/**@brief Function for initializing the system sleep module. + * + * @details This function must be called before any usage of the System Sleep module. + */ +void sys_sleep_init(void); + + +/**@brief Function for registering the approver of the system sleep request. + * + * @details After the sleep approver is registered with this function, the hardware will + * not fall asleep without its approval. + * + * @param[in] p_event_falling_asleep Event descriptor, which will handle + * the SYS_EVENT_FALLING_ASLEEP event. + * @param[in] p_event_wake_up Event descriptor, which will handle + * the SYS_EVENT_WAKE_UP event. + * + * @retval The unique approver ID, reserved for this newly-registered approver. + * This ID will be required to approve system sleep requests by this approver module. + */ +sys_sleep_approver_id_t sys_sleep_approver_register( + sys_event_desc_t * p_event_falling_asleep, + sys_event_desc_t * p_event_wake_up); + + +/**@brief Function for unregistering the approver of the system sleep request. + * + * @details After the approver is unregistered, its approval will not be + * required to put the system into sleep mode. + * + * @param[in] approver_id The unique approver ID to be unregistered. + * @param[in] p_event_falling_asleep Event descriptor to unsubscribe from + * the SYS_EVENT_FALLING_ASLEEP event. + * @param[in] p_event_wake_up Event descriptor to unsubscribe from + * the SYS_EVENT_WAKE_UP event. + */ +void sys_sleep_approver_unregister( + sys_sleep_approver_id_t approver_id, + sys_event_desc_t * p_event_falling_asleep, + sys_event_desc_t * p_event_wake_up); + + +/**@brief Function for approving the system sleep request. + * + * @details This function is to be called by the registered approver + * in order to approve putting the system into the sleep mode. + * + * @param[in] approver_id The unique approver ID. + */ +void sys_sleep_approve(sys_sleep_approver_id_t approver_id); + + +/**@brief Function for requesting the system to safely enter into sleep mode. + * + * @details This function notifies all the registered sleep approvers with the + * HAL_EVENT_FALLING_ASLEEP event, allowing them to perform all the needed preparation + * before the hardware falls asleep. The hardware will enter sleep mode only after + * all registered approvers approve the fall asleep request. + * + * @param[in] sleep_time_ms Defines sleep time in ms. + */ +void sys_sleep_request_ms(uint32_t sleep_time_ms); + + +/**@brief Function for getting information about the wakeup reason. + * + * @retval hal_wakeup_reason Interrupt source which was the wakeup reason. + */ +hal_wakeup_reason_t sys_sleep_wakeup_reason(void); + +/** @} */ + +#endif // SYS_SLEEP_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_task_scheduler.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_task_scheduler.h new file mode 100644 index 0000000000000000000000000000000000000000..8550adb404dec446df5db8ffde0482cbb5094046 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_task_scheduler.h @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYS_TASK_SCHEDULER_H_INCLUDED +#define SYS_TASK_SCHEDULER_H_INCLUDED + +#include +#include +#include "sys_utils.h" +#include "hal_atomic.h" +#include "sys_events.h" + +/** @file + * @defgroup sys_task_scheduler Task scheduler + * @ingroup sys_15_4 + * @{ + * @brief Module for task scheduling. + */ + +/**@brief Identificators for registered handlers. + * + * Handlers will be called from the task scheduler. + */ +typedef enum +{ + PHY_TASK_ID, + HAL_TASK_ID, +#if (CONFIG_HIGHEST_LAYER_PHY == 0) + MAC_TASK_ID, +#endif + APP_TASK_ID, + SYS_TASK_ID, + SYS_TASKS_AMOUNT +} sys_task_ids_t; + +/**@brief Prototype of a task handler. + * + * @details Handler which will be called by the scheduler. + */ +typedef void (* sys_task_handler_t)(void); + +/**@brief Pending tasks. + * + * @details Variable which includes markers of pending tasks. + */ +extern volatile uint_fast16_t g_tasks; + +/**@brief Notify task scheduler to add a task for execution. + * + * @details The function sets a marker for the task for execution. + * The task handler implements a tree architecture. + * Task handler of each layer includes handlers of the layer's components. + * + * @param[in] task_id Task identificator. + */ +static inline void sys_task_post(sys_task_ids_t task_id) +{ + atomic_t atomic = 0; + + hal_atomic_start(&atomic); + g_tasks |= BIT(task_id); +#if (CONFIG_USE_SYS_TASK_NOTIFIER == 1) + sys_event_post(SYS_EVENT_NEW_TASK, NULL); +#endif + hal_atomic_end(&atomic); +} + +/**@brief Returns true, if there are any event flags awaiting in the system scheduler. + */ +static inline bool sys_tasks_pending(void) +{ + return g_tasks != 0; +} + +/**@brief Handle tasks in the main function. + * + * @details Handle tasks in the main function. + */ +void sys_task_run(void); + +/** @} */ + +#endif // SYS_TASK_SCHEDULER_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_time.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_time.h new file mode 100644 index 0000000000000000000000000000000000000000..a2a08d5defe9b8949d043f11f91b6ce683c01270 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_time.h @@ -0,0 +1,180 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYS_TIME_H_INCLUDED +#define SYS_TIME_H_INCLUDED + +#include +#include "sys_queue.h" + +/** @file + * This file contains declarations of the primitives to work with Time (timers) and necessary types. + * + * @defgroup sys_time Time API + * @ingroup sys_15_4 + * @{ + * @brief Module for declaring Time API. + * @details The system time module implements some routines to deal with time (timers). The timer can be started by + * sys_timer_start(), stopped by sys_timer_stop(), and adjusted after sleep by sys_timer_adjust(). Some + * information can be acquired by sys_timer_is_started() and sys_time_get(). The correct API for implementing hardware + * delays is sys_time_delay_us(). Note that the module must be initialized by sys_timers_init() which + * is done by sys_init(). + */ + +/**@brief Unsigned type of system time. + */ +typedef uint64_t sys_time_t; + +/**@brief Signed type of system time. + */ +typedef int64_t sys_signed_time_t; + +/**@brief Prototype of the user-defined timer callback. + * + * @param p_data Pointer to the data, specific for this callback. + */ +typedef void (* sys_timer_callback_t)(void * p_data); + + +/**@brief System timer type (one-shot or periodic timer). + */ +typedef enum +{ + SYS_TIMER_ONESHOT, /**< The timer is Oneshot */ + SYS_TIMER_PERIODIC /**< The timer is Periodic */ +} sys_timer_type_t; + + +/**@brief Timer descriptor. + */ +typedef struct +{ + /** Service field. */ + sys_queue_item_t item; + + /** Service field. */ + sys_time_t absolute_time; + + /** Relevant time moment, at which this timer is programmed to be triggered, + * measured in microseconds. + */ + sys_time_t interval; + + /** Periodic or one-shot timer. + * + * @details If type is set to SYS_TIMER_PERIODIC, the timer will restart automatically + * with the same period. + */ + sys_timer_type_t type; + + /** Timer callback function. + * + * @details This function is to be called, when this timer triggers. + */ + sys_timer_callback_t callback; + + /** Timer callback parameter. + * + * @details This pointer is to be passed to the timer callback function. + */ + void * p_data; +} sys_timer_t; + + +/**@brief Function for initializing the timers module. + */ +void sys_timers_init(void); + + +/**@brief Function for starting the timer. + * + * @details See the description of \ref sys_timer_t fields for the details + * on how to program the timer. + * + * @param[in] p_timer Pointer to a valid timer descriptor, which is filled by the user, + * according to \ref sys_timer_t fields description. + */ +void sys_timer_start(sys_timer_t * p_timer); + + +/**@brief Function for stopping the timer. + * + * @details This function is used to stop the timer, which was started earlier. + * After this function is called, the timer will not fire. + * + * @param[in] p_timer Pointer to a valid timer descriptor. + */ +void sys_timer_stop(sys_timer_t * p_timer); + + +/**@brief Function for checking if input timer has been started. + * + * @param[in] p_timer Pointer to a timer. + * + * @retval true p_timer has been started and has not been stopped yet. + * @retval false p_timer has never been started or already timed out. + */ +bool sys_timer_is_started(sys_timer_t * p_timer); + + +/**@brief Function for getting the current system time. + * + * @retval The current system timer counter value in microseconds. + */ +sys_time_t sys_time_get(void); + + +/**@brief Function for implementing a delay for short hardware delays. + * + * @warning Interrupts are NOT disabled inside this function. + * + * @param[in] delay_us Number of microseconds to delay. + */ +void sys_time_delay_us(uint32_t delay_us); + + +/**@brief Function for executing expired timers after sleep. + */ +void sys_timer_adjust(void); + +/** @} */ + +#endif // SYS_TIME_H_INCLUDED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_utils.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..7e3283d34d07fd536374358b9046b39b8e4199da --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/api/SysAL/sys_utils.h @@ -0,0 +1,524 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SYS_UTILS_H_INCLUDED +#define SYS_UTILS_H_INCLUDED + +#include +#include +#include +#if defined(__GNUC__) +#include +#endif +#ifdef __MINGW32__ +#define ffs __builtin_ffs +#endif + +/** @file + * This file contains definitions of useful macros and types. + * + * @defgroup sys_utils System Utilities API + * @ingroup sys_15_4 + * @{ + * @brief Module to declare System Utilities API. + * @details The System Utilities module implements multiple useful macros and inlines for the whole stack. Including + * this header you will get access to GET_PARENT_BY_FIELD(), FIELD_SIZE() to work with complex structures, + * ARRAY_SIZE() for arrays, mathematics macros like IMP(), LL_MIN(), LL_MAX(), CEIL(), ROUND(), Bitmap helpers + * and many others. The variable arguments support macros are also defined here. Some SWAP routines are implemented + * by this module as well. + */ + +/**@brief Returns the pointer to the data structure + * + * @param[in] struct_type name of the parent structure + * @param[in] field_name name of the structure field + * @param[in] field_pointer pointer to the structure field + * + * @retval Pointer to the parent structure which includes the field. + */ +#define GET_PARENT_BY_FIELD(struct_type, field_name, field_pointer) \ + ((struct_type*)(void*)(((uint8_t*)field_pointer) - offsetof(struct_type, field_name))) + + +/**@brief Returns the implication of two given expressions x and y. + * @details The implication means: if X==TRUE then Y==TRUE. + * The formula is: (X imp Y) = ((not X) or Y) + */ +#define IMP(x, y) ( !(x) || (y) ) + + +/**@brief Returns the minimum of two given expressions x and y. + */ +#define LL_MIN(x, y) ( ((x) < (y)) ? (x) : (y) ) + + +/**@brief Returns the maximum of two given expressions x and y. + */ +#define LL_MAX(x, y) ( ((x) > (y)) ? (x) : (y) ) + + +/**@brief Returns the quotient of a divided by b rounded upwards to the nearest + * integer. + */ +#define CEIL(a, b) ((a) ? (((a) - 1U) / (b) + 1U) : 0U) + + +/**@brief Returns the quotient of a divided by b rounded to the nearest integer + * according to the standard arithmetic rules: if the fractional part of (a/b) is greater + * or equal to 0.5 then the result is rounded upwards; if the fractional part of (a/b) is + * less then 0.5 the result is rounded downwards. + * + * @note Use this formula only for unsigned arguments. The formula is not compatible with + * the signed arguments: when a and b have different signs it gives incorrect result. + */ +#define ROUND(a, b) ( ((a) + ((b) >> 1)) / (b) ) + + +/**@brief Declares a long bitmap named name of size bits. The size is rounded + * upwards to come a multiple of 8. + */ +#define BITMAP_DECLARE(name, size) uint8_t name[CEIL(size, 8)] + +/**@brief Clears all bits in given bitmap. + */ +#define BITMAP_RESET(name) memset((name), 0U, sizeof(name)) + +/**@brief Returns the value of a bit at position bit in the long bitmap named name. + */ +#define BITMAP_ISSET(name, bit) ( 0 != ((name)[(bit) >> 3] & (1 << ((bit) & 0x7))) ) + +/**@brief Sets the bit at position bit in the long bitmap named name. + */ +#define BITMAP_SET(name, bit) (name)[(bit) >> 3] |= (1 << ((bit) & 0x7)) + +/**@brief Clears the bit at position bit in the long bitmap named name. + */ +#define BITMAP_CLR(name, bit) (name)[(bit) >> 3] &= ~(1 << ((bit) & 0x7)) + +/**@brief Assigns the given bitmap with the second bitmap. + */ +#define BITMAP_ASSIGN(nameDst, nameSrc) memcpy((nameDst), (nameSrc), sizeof(nameDst)) + +/**@brief Compares two bitmaps and returns zero if they are equal. + */ +#define BITMAP_EQUAL(name1, name2) ((sizeof(name1) == sizeof(name2)) && \ + (memcmp((name1), (name2), sizeof(name1)) == 0)) + +/**@brief Checks number. Return true if number is power of two. + */ +#define LL_IS_POWER_OF_TWO(name) ((0 != (name)) && (0 == ((name)&(name - 1)))) + +/**@brief Return True if mask is fully included into a given set and False otherwise + */ +#define IS_SUBSET_OF(mask, set) ((mask) == ((set) & (mask))) + +/**@brief Creates a bit mask with single set bit on the specified position. + */ +#define BIT(pos) (1UL << (pos)) + +/**@brief Gets the given bit in the given value + */ +#define BIT_GET(val, pos) ((((uint32_t)val) & BIT(pos)) != 0) + +/**@brief Sets or clears the given bit in the given value + */ +#define BIT_SET(val, pos, bit) { \ + if (bit) \ + { \ + val |= BIT(pos); \ + } \ + else \ + { \ + val &= ~BIT(pos); \ + } \ + } + +/**@brief Returns two to the income power.*/ +#define POWER2(n) (1ULL << (n)) + +/**@brief Creates a bit mask of specified length. + */ +#define BIT_MASK(len) (BIT(len) - 1UL) + +/**@brief Creates a bit field mask of specified length and start position. + */ +#define BIT_FIELD_MASK(start, len) (BIT_MASK(len) << (start)) + +/**@brief Creates a bit field mask of specified length, start position and value. + */ +#define BIT_FIELD_VALUE(value, start, len) (((value) & BIT_MASK(len)) << (start)) + +/**@brief Extracts a bit field value of specified start position and length. + */ +#define GET_BITFIELD_VALUE(bitmask, start, len) (((bitmask) >> (start)) & BIT_MASK(len)) + +/**@brief Inserts a bit field value with specified start position and length. + */ +#define SET_BITFIELD_VALUE(bitmask, start, len, value) \ + (bitmask = (bitmask & ~BIT_FIELD_MASK(start, len)) | BIT_FIELD_VALUE(value, start, len)) + +/**@brief Extracts a mask from a BITMAP. + * BITMAP MUST be aligned and mask length MUST be one of 2, 4, 8, 16, 32. + */ +#define BITMAP_MASK_GET(bitmap, bit, len) \ + GET_BITFIELD_VALUE(((uint32_t*)(bitmap))[(bit) >> 5], (bit) & 0x1F, len) + +/**@brief Sets up a mask to a BITMAP. + * BITMAP MUST be aligned and mask length MUST be one of 2, 4, 8, 16, 32. + */ +#define BITMAP_MASK_SET(bitmap, bit, len, value) \ + SET_BITFIELD_VALUE(((uint32_t*)(bitmap))[(bit) >> 5], (bit) & 0x1F, len, value) + +/**@brief Gets amount of the arguments. + */ +#define VA_NARGS(...) VA_NARGS_EVAL(__VA_ARGS__) +#define VA_NARGS_EVAL(...) VA_NARGS_IMPL(__VA_ARGS__, \ + /* 255, 254, */ 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, \ + 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, \ + 223, 222, 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 208, \ + 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, 196, 195, 194, 193, 192, \ + 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, \ + 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162, 161, 160, \ + 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, \ + 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 128, \ + 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, \ + 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, \ + 095, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \ + 079, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, \ + 063, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, \ + 047, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, \ + 031, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, \ + 015, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) + +/**@brief Helper macro. Gets amount of the arguments. + */ +#define VA_NARGS_IMPL(_________1, _2, _3, _4, _5, _6, _7, \ + _8, _9, _10, _11, _12, _13, _14, _15, \ + __16, _17, _18, _19, _20, _21, _22, _23, \ + _24, _25, _26, _27, _28, _29, _30, _31, \ + __32, _33, _34, _35, _36, _37, _38, _39, \ + _40, _41, _42, _43, _44, _45, _46, _47, \ + __48, _49, _50, _51, _52, _53, _54, _55, \ + _56, _57, _58, _59, _60, _61, _62, _63, \ + __64, _65, _66, _67, _68, _69, _70, _71, \ + _72, _73, _74, _75, _76, _77, _78, _79, \ + __80, _81, _82, _83, _84, _85, _86, _87, \ + _88, _89, _90, _91, _92, _93, _94, _95, \ + __96, _97, _98, _99, _100, _101, _102, _103, \ + _104, _105, _106, _107, _108, _109, _110, _111, \ + _112, _113, _114, _115, _116, _117, _118, _119, \ + _120, _121, _122, _123, _124, _125, _126, _127, \ + _128, _129, _130, _131, _132, _133, _134, _135, \ + _136, _137, _138, _139, _140, _141, _142, _143, \ + _144, _145, _146, _147, _148, _149, _150, _151, \ + _152, _153, _154, _155, _156, _157, _158, _159, \ + _160, _161, _162, _163, _164, _165, _166, _167, \ + _168, _169, _170, _171, _172, _173, _174, _175, \ + _176, _177, _178, _179, _180, _181, _182, _183, \ + _184, _185, _186, _187, _188, _189, _190, _191, \ + _192, _193, _194, _195, _196, _197, _198, _199, \ + _200, _201, _202, _203, _204, _205, _206, _207, \ + _208, _209, _210, _211, _212, _213, _214, _215, \ + _216, _217, _218, _219, _220, _221, _222, _223, \ + _224, _225, _226, _227, _228, _229, _230, _231, \ + _232, _233, _234, _235, _236, _237, _238, _239, \ + _240, _241, _242, _243, _244, _245, _246, _247, \ + _248, _249, _250, _251, _252, _253, /* _254, _255, */\ + N, ...) N + +/**@brief Gets amount of the arguments. Execute by compiler. + */ +#define VA_NARGS_COMPILE_TIME(...) ((uint8_t)(sizeof((uint8_t[]){ __VA_ARGS__ })/sizeof(uint8_t))) + +/**@brief Swaps values. + */ +#define SWAP_XOR(a, b) (((a) ^ (b)) && ((b) ^= (a) ^= (b), (a) ^= (b))) + +/**@brief Compare two number and take care of overflow threshold limit. + */ +#define COMPARE_WITH_THRESHOLD(a, b, threshold) \ + (((LL_MAX((a), (b)) - LL_MIN((a), (b))) < (threshold)) ? ((a) >= (b) ? 1 : 0) : ((a) > (b) ? 0 : 1)) + + +#define ROUND_MASK(a) ((a) - 1) +#define ROUND_UP(x, a) (((x) + ROUND_MASK(a)) & ~ROUND_MASK(a)) +#define ROUND_DOWN(x, a) ((x) & ~ROUND_MASK(a)) + +/**@brief Dereferences input pointer \a y as a type \a x. + * + * @param[in] x type name. + * @param[in] y pointer name. + */ +#define DEREF_VOID_PTR_AS(x, y) (*(x *)y) + +/**@brief Extends some bit value to the left extending 2's complement value + * to 8-bit length. + * + * @param[out] result variable, where result is store to. + * @param[in] x input value. + * @param[in] sign_pos an integer in range 2..6 specifying bit position of sign bit. + */ +#define SIGN_EXTENSION(result, x, sign_pos) \ + do \ + { \ + result = x & (1 << sign_pos) ? \ + x | (~((1 << (sign_pos + 1)) - 1)) : \ + x & ((1 << (sign_pos + 1)) - 1); \ + } while (0) + +/**@brief Clears some most significant bits of integer value reducing it precision. + * Name and interface of the macro emphasizes complementary action to #SIGN_EXTENSION. + * + * @param[out] result variable, where result is store to. + * @param[in] x input value. + * @param[in] sign_pos an integer in range 2..6 specifying bit position of sign bit. + */ +#define SIGN_COMPRESSION(result, x, sign_pos) \ + do \ + { \ + result = x & ((1 << (sign_pos + 1)) - 1); \ + } while (0) + +/************************* PROTOTYPES **************************************************/ +/**@brief Swaps values of two bytes. + * + */ +static inline void SWAP8(uint8_t * const x, uint8_t * const y) +{ + uint8_t _x = *x; + *x = *y; + *y = _x; +} + +/**@brief Swaps values of two double words (DWORD). + * + */ +static inline void SWAP32(uint32_t * const x, uint32_t * const y) +{ + uint32_t _x = *x; + *x = *y; + *y = _x; +} + +/**@brief Swaps values of two arrays. + * + * @param[inout] x array pointer + * @param[inout] y array pointer + * @param[in] length amount of bytes to swap + */ +static inline void SWAP_ARRAYS(void * x, void * y, uint32_t length) +{ + uint8_t *_x = (uint8_t *)(void *)x; + uint8_t *_y = (uint8_t *)(void *)y; + if (0x0 == ((((size_t)_x) | ((size_t)_y)) & 0x3)) + { + size_t len4 = length / sizeof(uint32_t); + for (size_t i = 0; i < len4; i++) + { + SWAP32((uint32_t*)_x, (uint32_t*)_y); + _x += sizeof(uint32_t); + _y += sizeof(uint32_t); + } + length &= 0x3; + } + + for (size_t i = 0; i < length; i++) + { + SWAP8(_x, _y); + _x++; + _y++; + } +} + + +/**@brief Find the first bit of the bitmap with the given value + * (one or zero, as specified). + * + * @param[in] p_bitmap Pointer to bitmap. + * @param[in] bitmap_size Number of bits in the bitmap. + * @param[in] bit_value The bit value to find (one or zero). + * + * @retval Bit position of the bit with specified value, or bitmap_size if no such bit + * was found. + */ +static inline size_t bitmap_find_bit(uint8_t * p_bitmap, size_t bitmap_size, uint8_t bit_value) +{ +#if defined(__GNUC__) + if (bitmap_size <= 32) + { + uint32_t bitmap; + memcpy(&bitmap, p_bitmap, sizeof(uint32_t)); + if (!bit_value) + { + bitmap ^= 0xFFFFFFFF; + } + size_t result = ffs(bitmap); + if (result == 0 || result > bitmap_size) + { + return bitmap_size; + } + // built-in ffs implementation gives ffs(1) = 1, not 0 + return result - 1; + } + else +#endif + { + for (size_t i = 0; i < bitmap_size; i++) + { + if (BITMAP_ISSET(p_bitmap, i) == bit_value) + { + return i; + } + } + return bitmap_size; + } +} + +/**@brief Returns least significant byte of word. + */ +#define LSB_WORD(x) ((uint8_t)(x & 0xFF)) + +/**@brief Returns least significant byte of halfword. + */ +#define LSB_HWORD(x) LSB_WORD(x) + +/**@brief Returns most significant byte of halfword. + */ +#define MSB_HWORD(x) ((uint8_t)(x >> 8)) + +#define ALIGN_VALUE (sizeof(size_t)) + +/**@brief Compiler-independent definitions. + */ +#if defined ( __CC_ARM ) + + #ifndef __WEAK + #define __WEAK __weak + #endif + + #ifndef PACK + #define PACK __attribute__ ((packed)) + #endif + + #ifndef BEGIN_PACK + #define BEGIN_PACK + #endif + + #ifndef END_PACK + #define END_PACK + #endif + +#ifndef __ALIGN + #define __ALIGN(n) __align(n) +#endif + +#elif defined ( __ICCARM__ ) + + #ifndef __WEAK + #define __WEAK __weak + #endif + + #ifndef PACK + #define PACK + #endif + + #ifndef BEGIN_PACK + #define BEGIN_PACK _Pragma("pack(push, 1)") + #endif + + #ifndef END_PACK + #define END_PACK _Pragma("pack(pop)") + #endif + +#ifndef __ALIGN + #define __ALIGN(n) +#endif + +#elif defined ( __GNUC__ ) + + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + + #ifndef PACK + #define PACK __attribute__ ((packed)) + #endif + + #ifndef BEGIN_PACK + #define BEGIN_PACK _Pragma("pack(push,1)") + + #endif + + #ifndef END_PACK + #define END_PACK _Pragma("pack(pop)") + #endif + +#ifndef __ALIGN + #define __ALIGN(n) __attribute__((aligned(n))) +#endif + +#elif defined ( __TASKING__ ) + + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + + #ifndef PACK + #define PACK __attribute__ ((packed)) + #endif + + #ifndef BEGIN_PACK + #define BEGIN_PACK + #endif + + #ifndef END_PACK + #define END_PACK + #endif + +#ifndef __ALIGN + #define __ALIGN(n) __align(n) +#endif + +#endif + +/** @} */ + +#endif /* SYS_UTILS_H_INCLUDED */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/license.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/license.txt new file mode 100644 index 0000000000000000000000000000000000000000..fa9d825ba3a12be8a73a1af2ecfb014b85843ff1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/license.txt @@ -0,0 +1,38 @@ +Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + +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, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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 Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/src/rng_entity.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/src/rng_entity.c new file mode 100644 index 0000000000000000000000000000000000000000..8c0b9d2b6b21804fd357c1c926bc48a549dd0aff --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/src/rng_entity.c @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "nrf_rng.h" +#include "hal_rng.h" +#include "sys_utils.h" + +/**@brief Initialize hardware random generator. + */ +void hal_rand_init(void) +{ + /** For future use */ +} + +/**@brief Generates random number using hardware. + * + * @details The process takes about 150 us.*/ +uint8_t hal_rand_get(void) +{ + nrf_rng_task_trigger(NRF_RNG_TASK_START); + while(!nrf_rng_event_get(NRF_RNG_EVENT_VALRDY)); + nrf_rng_task_trigger(NRF_RNG_TASK_STOP); + nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); + + return nrf_rng_random_value_get(); +} + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/src/sec_aes_entity.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/src/sec_aes_entity.c new file mode 100644 index 0000000000000000000000000000000000000000..ed71ed7ae3cae2d10c2b4f5e16f7358cde376b63 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/experimental_802_15_4/src/sec_aes_entity.c @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2016 - 2017 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh. + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "nrf_ecb.h" +#include "sec_aes_entity.h" +#include "sec_aes_ccm.h" +#include "sys_debug.h" +#include "sys_utils.h" + +void aes_entity_init(void) +{ + bool is_successful = nrf_ecb_init(); + ASSERT(is_successful); + (void)is_successful; +} + +void aes_handle(uint8_t * key, uint8_t * text) +{ + nrf_ecb_set_key(key); + bool is_successful = nrf_ecb_crypt(text, text); + ASSERT(is_successful); + (void)is_successful; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic/nrf_atomic.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic/nrf_atomic.h new file mode 100644 index 0000000000000000000000000000000000000000..4a64f685129a48d8395db0e68e1738cc742e1376 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic/nrf_atomic.h @@ -0,0 +1,347 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup nrf_atomic Atomic operations API + * @ingroup app_atfifo + * @{ + * + * @brief @tagAPI52 This module implements C11 stdatomic.h simplified API. + At this point only Cortex-M3/M4 cores are supported (LDREX/STREX instructions). + * Atomic types are limited to @ref nrf_atomic_u32_t and @ref nrf_atomic_flag_t. + */ + +#ifndef NRF_ATOMIC_H__ +#define NRF_ATOMIC_H__ + +#include "sdk_common.h" +#include "nrf_atomic_internal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Stores value to an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value to store + * + * @return Old value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_store_fetch(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value); + + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return old_val; +} + +/** + * @brief Stores value to an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value to store + * + * @return New value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_store(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value); + + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return new_val; +} + +/** + * @brief Logical OR operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand OR operation + * + * @return Old value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_or_fetch(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return old_val; +} + +/** + * @brief Logical OR operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand OR operation + * + * @return New value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_or(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return new_val; +} + +/** + * @brief Logical AND operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand AND operation + * + * @return Old value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_and_fetch(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(and, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return old_val; +} + +/** + * @brief Logical AND operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand AND operation + * + * @return New value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_and(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(and, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return new_val; +} + +/** + * @brief Logical XOR operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand XOR operation + * + * @return Old value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_xor_fetch(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return old_val; +} + +/** + * @brief Logical XOR operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand XOR operation + * + * @return New value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_xor(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return new_val; +} + +/** + * @brief Arithmetic ADD operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand ADD operation + * + * @return Old value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_add_fetch(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(add, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return old_val; +} + +/** + * @brief Arithmetic ADD operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand ADD operation + * + * @return New value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_add(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(add, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return new_val; +} + +/** + * @brief Arithmetic SUB operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand SUB operation + * + * @return Old value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_sub_fetch(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return old_val; +} + +/** + * @brief Arithmetic SUB operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand SUB operation + * + * @return New value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_sub(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return new_val; +} + +/**************************************************************************************************/ + +/** + * @brief Logic one bit flag set operation on an atomic object + * + * @param[in] p_data Atomic flag memory pointer + * + * @return Old flag value + * */ +static inline uint32_t nrf_atomic_flag_set_fetch(nrf_atomic_flag_t * p_data) +{ + return nrf_atomic_u32_or_fetch(p_data, 1); +} + +/** + * @brief Logic one bit flag set operation on an atomic object + * + * @param[in] p_data Atomic flag memory pointer + * + * @return New flag value + * */ +static inline uint32_t nrf_atomic_flag_set(nrf_atomic_flag_t * p_data) +{ + return nrf_atomic_u32_or(p_data, 1); +} + +/** + * @brief Logic one bit flag clear operation on an atomic object + * + * @param[in] p_data Atomic flag memory pointer + * + * @return Old flag value + * */ +static inline uint32_t nrf_atomic_flag_clear_fetch(nrf_atomic_flag_t * p_data) +{ + return nrf_atomic_u32_and_fetch(p_data, 0); +} + +/** + * @brief Logic one bit flag clear operation on an atomic object + * + * @param[in] p_data Atomic flag memory pointer + * + * @return New flag value + * */ +static inline uint32_t nrf_atomic_flag_clear(nrf_atomic_flag_t * p_data) +{ + return nrf_atomic_u32_and(p_data, 0); +} + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_ATOMIC_H__ */ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic/nrf_atomic_internal.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic/nrf_atomic_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..25ba23df5de36d225b3a59c64d36f548f7723f51 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic/nrf_atomic_internal.h @@ -0,0 +1,244 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_ATOMIC_INTERNAL_H__ +#define NRF_ATOMIC_INTERNAL_H__ + +#include "sdk_common.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * + * @defgroup nrf_atomic_internal Atomic operations internals + * @ingroup nrf_atomic + * @{ + * + */ + +/* Only Cortex M cores > 3 support LDREX/STREX instructions*/ +#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0 +#error "Unsupported core version" +#endif + +/** + * @brief Atomic 32 bit unsigned type + * */ +typedef volatile uint32_t nrf_atomic_u32_t; + +/** + * @brief Atomic 1 bit flag type (technically 32 bit) + * */ +typedef volatile uint32_t nrf_atomic_flag_t; + +#if defined ( __CC_ARM ) +static __asm uint32_t nrf_atomic_internal_mov(nrf_atomic_u32_t * p_ptr, + uint32_t value, + uint32_t * p_new) +{ + /* The base standard provides for passing arguments in core registers (r0-r3) and on the stack. + * Registers r4 and r5 have to be saved on stack. Note that only even number of register push are + * allowed. This is a requirement of the Procedure Call Standard for the ARM Architecture [AAPCS]. + * */ + push {r4, r5} + mov r4, r0 + +loop_mov + ldrex r0, [r4] + mov r5, r1 + strex r3, r5, [r4] + cmp r3, #0 + bne loop_mov + + str r5, [r2] + pop {r4, r5} + bx lr +} + + +static __asm uint32_t nrf_atomic_internal_orr(nrf_atomic_u32_t * p_ptr, + uint32_t value, + uint32_t * p_new) +{ + push {r4, r5} + mov r4, r0 + +loop_orr + ldrex r0, [r4] + orr r5, r0, r1 + strex r3, r5, [r4] + cmp r3, #0 + bne loop_orr + + str r5, [r2] + pop {r4, r5} + bx lr +} + +static __asm uint32_t nrf_atomic_internal_and(nrf_atomic_u32_t * p_ptr, + uint32_t value, + uint32_t * p_new) +{ + push {r4, r5} + mov r4, r0 + +loop_and + ldrex r0, [r4] + and r5, r0, r1 + strex r3, r5, [r4] + cmp r3, #0 + bne loop_and + + str r5, [r2] + pop {r4, r5} + bx lr +} + +static __asm uint32_t nrf_atomic_internal_eor(nrf_atomic_u32_t * p_ptr, + uint32_t value, + uint32_t * p_new) +{ + push {r4, r5} + mov r4, r0 + +loop_eor + ldrex r0, [r4] + eor r5, r0, r1 + strex r3, r5, [r4] + cmp r3, #0 + bne loop_eor + + str r5, [r2] + pop {r4, r5} + bx lr +} + +static __asm uint32_t nrf_atomic_internal_add(nrf_atomic_u32_t * p_ptr, + uint32_t value, + uint32_t * p_new) +{ + push {r4, r5} + mov r4, r0 + +loop_add + ldrex r0, [r4] + add r5, r0, r1 + strex r3, r5, [r4] + cmp r3, #0 + bne loop_add + + str r5, [r2] + pop {r4, r5} + bx lr +} + +static __asm uint32_t nrf_atomic_internal_sub(nrf_atomic_u32_t * p_ptr, + uint32_t value, + uint32_t * p_new) +{ + push {r4, r5} + mov r4, r0 + +loop_sub + ldrex r0, [r4] + sub r5, r0, r1 + strex r3, r5, [r4] + cmp r3, #0 + bne loop_sub + + str r5, [r2] + pop {r4, r5} + bx lr +} + + +#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \ + old_val = nrf_atomic_internal_##asm_op(ptr, value, &new_val) + +#elif defined ( __ICCARM__ ) || defined ( __GNUC__ ) + +/** + * @brief Atomic operation generic macro + * @param[in] asm_op operation: mov, orr, and, eor, add, sub + * @param[out] old_val atomic object output (uint32_t), value before operation + * @param[out] new_val atomic object output (uint32_t), value after operation + * @param[in] value atomic operation operand + * */ +#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \ +{ \ + uint32_t str_res; \ + __ASM volatile( \ + "1: ldrex %["#old_val"], [%["#ptr"]]\n" \ + NRF_ATOMIC_OP_##asm_op(new_val, old_val, value) \ + " strex %[str_res], %["#new_val"], [%["#ptr"]]\n" \ + " teq %[str_res], #0\n" \ + " bne.n 1b" \ + : \ + [old_val]"=&r" (old_val), \ + [new_val]"=&r" (new_val), \ + [str_res]"=&r" (str_res) \ + : \ + [ptr]"r" (ptr), \ + [value]"r" (value) \ + : "cc"); \ + UNUSED_PARAMETER(str_res); \ +} + +#define NRF_ATOMIC_OP_mov(new_val, old_val, value) "mov %["#new_val"], %["#value"]\n" +#define NRF_ATOMIC_OP_orr(new_val, old_val, value) "orr %["#new_val"], %["#old_val"], %["#value"]\n" +#define NRF_ATOMIC_OP_and(new_val, old_val, value) "and %["#new_val"], %["#old_val"], %["#value"]\n" +#define NRF_ATOMIC_OP_eor(new_val, old_val, value) "eor %["#new_val"], %["#old_val"], %["#value"]\n" +#define NRF_ATOMIC_OP_add(new_val, old_val, value) "add %["#new_val"], %["#old_val"], %["#value"]\n" +#define NRF_ATOMIC_OP_sub(new_val, old_val, value) "sub %["#new_val"], %["#old_val"], %["#value"]\n" + +#else +#error "Unsupported compiler" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_ATOMIC_INTERNAL_H__ */ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic/nrf_atomic_sanity_check.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic/nrf_atomic_sanity_check.h new file mode 100644 index 0000000000000000000000000000000000000000..f07006cf7cba54c073bac305ef5c47549777b35e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic/nrf_atomic_sanity_check.h @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_ATOMIC_SANITY_CHECK_H__ +#define NRF_ATOMIC_SANITY_CHECK_H__ + +#include "nrf_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Quick sanity check of nrf_atomic API + * */ +static inline void nrf_atomic_sanity_check(void) +{ +#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER) + nrf_atomic_u32_t val; + nrf_atomic_u32_t flag; + + /*Fetch version tests*/ + val = 0; + ASSERT(nrf_atomic_u32_store_fetch(&val, 10) == 0); + ASSERT(nrf_atomic_u32_store_fetch(&val, 0) == 10); + + val = 0; + ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 16) == 0); + ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 5) == ((1 << 16))); + ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 5) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_or_fetch(&val, 0) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_or_fetch(&val, 0xFFFFFFFF) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_or_fetch(&val, 0xFFFFFFFF) == (0xFFFFFFFF)); + + val = 0xFFFFFFFF; + ASSERT(nrf_atomic_u32_and_fetch(&val, ~(1 << 16)) == 0xFFFFFFFF); + ASSERT(nrf_atomic_u32_and_fetch(&val, ~(1 << 5)) == (0xFFFFFFFF & ~((1 << 16)))); + ASSERT(nrf_atomic_u32_and_fetch(&val, 0) == (0xFFFFFFFF & ~(((1 << 16) | (1 << 5))))); + ASSERT(nrf_atomic_u32_and_fetch(&val, 0xFFFFFFFF) == (0)); + + val = 0; + ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 16)) == 0); + ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 5)) == ((1 << 16))); + ASSERT(nrf_atomic_u32_xor_fetch(&val, 0) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 16) | (1 << 5)) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_xor_fetch(&val, 0) == (0)); + + val = 0; + ASSERT(nrf_atomic_u32_add_fetch(&val, 100) == 0); + ASSERT(nrf_atomic_u32_add_fetch(&val, 100) == 100); + ASSERT(nrf_atomic_u32_add_fetch(&val, 1 << 24) == 200); + ASSERT(nrf_atomic_u32_add_fetch(&val, 0) == (200 + (1 << 24))); + ASSERT(nrf_atomic_u32_add_fetch(&val, 0xFFFFFFFF) == (200 + (1 << 24))); + ASSERT(nrf_atomic_u32_add_fetch(&val, 0) == (200 - 1 + (1 << 24))); + + val = 1000; + ASSERT(nrf_atomic_u32_sub_fetch(&val, 100) == 1000); + ASSERT(nrf_atomic_u32_sub_fetch(&val, 100) == 900); + ASSERT(nrf_atomic_u32_sub_fetch(&val, 0) == 800); + ASSERT(nrf_atomic_u32_sub_fetch(&val, 0xFFFFFFFF) == 800); + ASSERT(nrf_atomic_u32_sub_fetch(&val, 0) == 801); + + flag = 0; + ASSERT(nrf_atomic_flag_set_fetch(&flag) == 0); + ASSERT(nrf_atomic_flag_set_fetch(&flag) == 1); + ASSERT(nrf_atomic_flag_clear_fetch(&flag) == 1); + ASSERT(nrf_atomic_flag_clear_fetch(&flag) == 0); + + /*No fetch version tests*/ + val = 0; + ASSERT(nrf_atomic_u32_store(&val, 10) == 10); + ASSERT(nrf_atomic_u32_store(&val, 0) == 0); + + val = 0; + ASSERT(nrf_atomic_u32_or(&val, 1 << 16) == 1 << 16); + ASSERT(nrf_atomic_u32_or(&val, 1 << 5) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_or(&val, 1 << 5) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_or(&val, 0) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_or(&val, 0xFFFFFFFF) == 0xFFFFFFFF); + + val = 0xFFFFFFFF; + ASSERT(nrf_atomic_u32_and(&val, ~(1 << 16)) == (0xFFFFFFFF & ~((1 << 16)))); + ASSERT(nrf_atomic_u32_and(&val, ~(1 << 5)) == (0xFFFFFFFF & ~(((1 << 16) | (1 << 5))))); + ASSERT(nrf_atomic_u32_and(&val, 0) == 0); + + val = 0; + ASSERT(nrf_atomic_u32_xor(&val, (1 << 16)) == ((1 << 16))); + ASSERT(nrf_atomic_u32_xor(&val, (1 << 5)) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_xor(&val, 0) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_xor(&val, (1 << 16) | (1 << 5)) == 0); + + val = 0; + ASSERT(nrf_atomic_u32_add(&val, 100) == 100); + ASSERT(nrf_atomic_u32_add(&val, 100) == 200); + ASSERT(nrf_atomic_u32_add(&val, 1 << 24) == (200 + (1 << 24))); + ASSERT(nrf_atomic_u32_add(&val, 0) == (200 + (1 << 24))); + ASSERT(nrf_atomic_u32_add(&val, 0xFFFFFFFF) == (200 - 1 + (1 << 24))); + + val = 1000; + ASSERT(nrf_atomic_u32_sub(&val, 100) == 900); + ASSERT(nrf_atomic_u32_sub(&val, 100) == 800); + ASSERT(nrf_atomic_u32_sub(&val, 0) == 800); + ASSERT(nrf_atomic_u32_sub(&val, 0xFFFFFFFF) == 801); + + flag = 0; + ASSERT(nrf_atomic_flag_set(&flag) == 1); + ASSERT(nrf_atomic_flag_set(&flag) == 1); + ASSERT(nrf_atomic_flag_clear(&flag) == 0); + ASSERT(nrf_atomic_flag_clear(&flag) == 0); +#endif +} + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_ATOMIC_SANITY_CHECK_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic_fifo/app_atfifo.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic_fifo/app_atfifo.c new file mode 100644 index 0000000000000000000000000000000000000000..90a044258e75316faa09c4e317b87d77a90e7c8c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic_fifo/app_atfifo.c @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "app_atfifo.h" +#include "app_atfifo_internal.h" +#include +#include "app_util.h" + + +/* Unions testing */ +STATIC_ASSERT(sizeof(nrf_atfifo_postag_t) == sizeof(uint32_t)); + + +ret_code_t app_atfifo_init(app_atfifo_t * const p_fifo, void * p_buf, uint16_t buf_size, uint16_t item_size) +{ + if(NULL == p_buf) + { + return NRF_ERROR_NULL; + } + if(0 != (buf_size % item_size)) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_fifo->p_buf = p_buf; + p_fifo->tail.tag = 0; + p_fifo->head.tag = 0; + p_fifo->buf_size = buf_size; + p_fifo->item_size = item_size; + + return NRF_SUCCESS; +} + + +ret_code_t app_atfifo_clear(app_atfifo_t * const p_fifo) +{ + bool resleased = app_atfifo_space_clear(p_fifo); + return resleased ? NRF_SUCCESS : NRF_ERROR_BUSY; +} + + +ret_code_t app_atfifo_put(app_atfifo_t * const p_fifo, void const * p_var, size_t size, bool * const p_visible) +{ + app_atfifo_wcontext_t context; + bool visible; + void * p_d = app_atfifo_wopen(p_fifo, &context, size); + if(NULL == p_d) + { + return NRF_ERROR_NO_MEM; + } + + memcpy(p_d, p_var, size); + + visible = app_atfifo_wcommit(p_fifo, &context); + if(NULL != p_visible) + { + *p_visible = visible; + } + return NRF_SUCCESS; +} + + +void * app_atfifo_wopen_internal(app_atfifo_t * const p_fifo, app_atfifo_wcontext_t * p_context) +{ + if(app_atfifo_wspace_req(p_fifo, &(p_context->last_tail))) + { + return ((uint8_t*)(p_fifo->p_buf)) + p_context->last_tail.pos.wr; + } + return NULL; +} + + +bool app_atfifo_wcommit(app_atfifo_t * const p_fifo, app_atfifo_wcontext_t * p_context) +{ + if((p_context->last_tail.pos.wr) == (p_context->last_tail.pos.rd)) + { + app_atfifo_wspace_close(p_fifo); + return true; + } + return false; +} + + +ret_code_t app_atfifo_get(app_atfifo_t * const p_fifo, void * const p_var, size_t size, bool * p_released) +{ + app_atfifo_rcontext_t context; + bool released; + void const * p_s = app_atfifo_ropen(p_fifo, &context, size); + if(NULL == p_s) + { + return NRF_ERROR_NOT_FOUND; + } + + memcpy(p_var, p_s, size); + + released = app_atfifo_rflush(p_fifo, &context); + if(NULL != p_released) + { + *p_released = released; + } + return NRF_SUCCESS; +} + + +void const * app_atfifo_ropen_internal(app_atfifo_t * const p_fifo, app_atfifo_rcontext_t * p_context) +{ + if(app_atfifo_rspace_req(p_fifo, &(p_context->last_head))) + { + return ((uint8_t*)(p_fifo->p_buf)) + p_context->last_head.pos.rd; + } + return NULL; +} + + +bool app_atfifo_rflush(app_atfifo_t * const p_fifo, app_atfifo_rcontext_t * p_context) +{ + if((p_context->last_head.pos.wr) == (p_context->last_head.pos.rd)) + { + app_atfifo_rspace_close(p_fifo); + return true; + } + return false; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic_fifo/app_atfifo.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic_fifo/app_atfifo.h new file mode 100644 index 0000000000000000000000000000000000000000..1f7d5a820ae735f8d0a745ffad245ccd7cab13a1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic_fifo/app_atfifo.h @@ -0,0 +1,448 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_ATFIFO_H__ +#define APP_ATFIFO_H__ + +#include +#include "nordic_common.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup app_atfifo Atomic FIFO implementation + * @ingroup app_common + * + * @brief @tagAPI52 FIFO implementation that allows for making atomic transactions without + * locking interrupts. + * + * @details There are two types of functions to prepare FIFO writing: + * - Single function for simple access: + * @code + * if(NRF_SUCCESS != nrf_atfifo_put(&my_fifo, &data, NULL)) + * { + * // Error handling + * } + * @endcode + * - Function pair to limit data coping: + * @code + * struct point3d + * { + * int x, y, z; + * }point3d_t; + * nrf_atfifo_context_t context; + * point3d_t * point; + * + * if(NULL != (point = nrf_atfifo_wopen(&my_fifo, &context))) + * { + * ret_code_t ret; + * point->x = a; + * point->y = b; + * point->z = c; + * if(nrf_atfifo_wcommit(&my_fifo, &context)) + * { + * // Send an information to the rest of the system + * // that there is new data in the FIFO available to read. + * } + * } + * else + * { + * // Error handling + * } + * + * @endcode + * @note + * This Atomic FIFO implementation requires that the operation that was + * opened last would be finished (committed/flushed) first. + * This is typical for operations performed from the interrupt runtime + * when the other operation is performed from main thread. + * + * This implementation does not support typical multithreading operating system + * access where operations can be started and finished in totally unrelated order. + * + * @{ + */ + +/** + * @brief Read and write position structure + * + * A structure that holds read and write position used by fifo head and tail. + */ +typedef struct nrf_atfifo_postag_pos_s +{ + uint16_t wr; //!< First free space to write a data + uint16_t rd; //!< A place after the last data to read +}nrf_atfifo_postag_pos_t; + +/** + * @brief End data index tag + * + * A tag used to mark end of data. + * To properly realize atomic data committing the whole variable has to be + * accessed atomically. + */ +typedef union nrf_atfifo_postag_u +{ + uint32_t tag; //!< Whole tag, used for atomic, 32 bit access + nrf_atfifo_postag_pos_t pos; //! Structure that holds reading and writing position separately +}nrf_atfifo_postag_t; + +/** + * @brief The FIFO instance + * + * The instance of atomic FIFO. + * Used with all FIFO functions. + */ +typedef struct app_atfifo_s +{ + void * p_buf; //!< Pointer to the data buffer + nrf_atfifo_postag_t tail; //!< Read and write tail position tag + nrf_atfifo_postag_t head; //!< Read and write head position tag + uint16_t buf_size; //!< FIFO size in number of bytes (has to be divisible by @c item_size) + uint16_t item_size; //!< Size of single FIFO item +}app_atfifo_t; + +/** + * @brief FIFO write operation context + * + * Context structure used to mark opened commit. + * All the data required to properly access the data and then commit it after writing. + */ +typedef struct app_atfifo_wcontext_s +{ + nrf_atfifo_postag_t last_tail; //!< Tail tag value that was here when opening FIFO to write +}app_atfifo_wcontext_t; + + +/** + * @brief FIFO read operation context + * + * Context structure used to mark opened read operation. + * All the data required to properly flush the accessed data after accessing. + */ +typedef struct app_atfifo_rcontext_s +{ + nrf_atfifo_postag_t last_head; //!< Head tag value that was here when opening FIFO to read +}app_atfifo_rcontext_t; + + +/** + * @defgroup app_atfifo_instmacros FIFO instance macros + * + * A group of macros helpful for FIFO instance creation and initialization. + * They may be used to create and initialize instances for most use cases. + * + * FIFO may also be created and initialized directly using + * @ref app_atfifo_init function. + * @{ + */ + /** + * @brief Macro to generate the name for data buffer + * + * The name of the data buffer that would be created by + * @ref APP_ATFIFO_DEF macro. + * + * @param[in] fifo_id The identifier of the FIFO object. + * + * @return The name of the buffer variable. + */ + #define APP_ATFIFO_BUF_NAME(fifo_id) CONCAT_2(fifo_id, _data) + + /** + * @brief Macro to generate the name for FIFO instance + * + * The name of instance variable that would be created by + * @ref APP_ATFIFO_DEF macro. + * + * @param[in] fifo_id The identifier of the FIFO object. + * + * @return The name of the instance variable. + */ + #define APP_ATFIFO_INST_NAME(fifo_id) CONCAT_2(fifo_id, _inst) + + /** + * @brief Instance creation macro + * + * Creates FIFO object variable itself and + * + * Use example: + * @code + * APP_ATFIFO_DEF(my_fifo, uint16_t, 12); + * APP_ATFIFO_INIT(my_fifo); + * + * uint16_t some_val = 45; + * app_atfifo_put(my_fifo, &some_val, sizeof(some_val), NULL); + * app_atfifo_get(my_fifo, &some_val, sizeof(some_val), NULL); + * @endcode + * + * @param[in] fifo_id The identifier of FIFO object. + * This identifier would be a pointer to the instance. + * It makes it possible to use this directly for the functions + * that operates on the FIFO. + * Because it is static const object, it should be optimized by the compiler. + * @param[in] storage_type The type of data that would be stored in the FIFO. + * @param[in] item_cnt The capacity of created FIFO in maximum number of items that may be stored. + * The phisical size of the buffer would be 1 element bigger. + */ + #define APP_ATFIFO_DEF(fifo_id, storage_type, item_cnt) \ + static storage_type APP_ATFIFO_BUF_NAME(fifo_id)[(item_cnt)+1]; \ + static app_atfifo_t APP_ATFIFO_INST_NAME(fifo_id); \ + static app_atfifo_t * const fifo_id = &APP_ATFIFO_INST_NAME(fifo_id) + + /** + * @brief Use this macro to initialize FIFO declared previously by the macro + * + * Use this macro to simplify FIFO initialization. + * + * @note + * This macro can be only used on FIFO object defined by @ref APP_ATFIFO_DEF macro. + * + * @param[in] fifo_id The identifier of the FIFO object. + * + * @return The value from @ref app_atfifo_init function. + */ + #define APP_ATFIFO_INIT(fifo_id) \ + app_atfifo_init( \ + fifo_id, \ + &APP_ATFIFO_BUF_NAME(fifo_id), \ + sizeof(APP_ATFIFO_BUF_NAME(fifo_id)), \ + sizeof(APP_ATFIFO_BUF_NAME(fifo_id)[0]) \ + ) + +/** @} */ + +/** + * @brief Initializing the FIFO + * + * Preparing FIFO instance to work. + * + * @param[out] p_fifo FIFO object to initialize. + * @param[in,out] p_buf FIFO buffer for storing data. + * @param[in] buf_size Total buffer size (has to be divisible by @c item_size). + * @param[in] item_size Size of single item hold inside the FIFO. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_NULL If a NULL pointer is provided as buffer. + * @retval NRF_ERROR_INVALID_LENGTH If size of buffer provided is divisible by @c item_size. + * + * @note + * Buffer size has to be able to fit 1 element more than designed FIFO capacity. + * This one, empty element is used for overflow checking. + */ +ret_code_t app_atfifo_init(app_atfifo_t * const p_fifo, void * p_buf, uint16_t buf_size, uint16_t item_size); + +/** + * @brief Clear the FIFO + * + * Clearing the FIFO. + * + * If this function is called during some opened and uncommitted write operation, + * the FIFO would be cleared up to the currently ongoing commit. + * There is no possibility to cancel ongoing commit. + * + * If this function is called during some opened and unflushed read operation, + * the read position in head would be set, but copying it into write head position + * would be left to read closing operation. + * + * This way there would be no more data to read, but the memory would be released + * in the moment when it is safe. + * + * @param[in,out] p_fifo FIFO object. + * + * @retval NRF_SUCCESS FIFO totally cleared + * @retval NRF_ERROR_BUSY Function called in the middle of writing or reading operation. + * If we are in the middle of writing operation, + * FIFO was cleared up to the already started, and uncommitted write. + * If we are in the middle of write operation, + * write head was only moved. It would be copied into read tail when reading operation + * would be flushed. + */ +ret_code_t app_atfifo_clear(app_atfifo_t * const p_fifo); + +/** + * @brief Put data into FIFO + * + * Function to that puts data into the FIFO atomically. + * + * @param[in,out] p_fifo FIFO object. + * @param[in] p_var Variable to copy. + * @param[in] size Size of the variable to copy. + * Can be smaller or equal to the FIFO item size. + * @param[out] p_visible See value returned by @ref app_atfifo_wcommit. + * If may be NULL if the caller does not care about current operation status. + * + * @retval NRF_SUCCESS If an element has been successfully added to the FIFO. + * @retval NRF_ERROR_NO_MEM If the FIFO is full. + * + * @note + * To avoid data copying one may use @ref app_atfifo_wopen and @ref app_atfifo_wcommit + * functions pair. + */ +ret_code_t app_atfifo_put(app_atfifo_t * const p_fifo, void const * const p_var, size_t size, bool * const p_visible); + +/** + * @brief Open FIFO for writing, internal function + * + * Function called to start FIFO write operation and access the given FIFO buffer directly. + * + * @param[in,out] p_fifo FIFO object. + * @param[out] p_context The operation context, required by @ref app_atfifo_wcommit. + * + * @return Pointer to the space where variable data may be stored. + * NULL if there is no space in the buffer. + * + * @note + * Do not use this function directly. + * Use @ref app_atfifo_wopen instead. + */ +void * app_atfifo_wopen_internal(app_atfifo_t * const p_fifo, app_atfifo_wcontext_t * p_context); + +/** + * @brief Open FIFO for writing + * + * Function called to start FIFO write operation and access the given FIFO buffer directly. + * + * @param[in,out] p_fifo FIFO object. + * @param[out] p_context The operation context, required by @ref app_atfifo_wcommit. + * @param[in] size Requested size of the buffer. Currently used only for integrity checking when debugging. + * + * @return Pointer to the space where variable data may be stored. + * NULL if there is no space in the buffer. + * + * @note Always finish writing operation by @ref app_atfifo_wcommit + */ +static inline void * app_atfifo_wopen(app_atfifo_t * const p_fifo, app_atfifo_wcontext_t * p_context, size_t size) +{ + ASSERT(size <= p_fifo->item_size); + UNUSED_PARAMETER(size); + return app_atfifo_wopen_internal(p_fifo, p_context); +} + +/** + * @brief Close the writing operation + * + * Function need to be called to finally commit opened write operation. + * It sets all the buffers and finally mark the data to be visible to read. + * + * @param[in,out] p_fifo FIFO object. + * @param[in] p_context Operation context, filled by the @ref app_atfifo_wopen function. + * + * @retval true The data is actually ready and would be visible to read. + * @retval false The internal commit was marked, but the writing operation interrupted another writing operation. + * The data would be available to read when the interrupted operation would be committed. + */ +bool app_atfifo_wcommit(app_atfifo_t * const p_fifo, app_atfifo_wcontext_t * p_context); + +/** + * @brief Get single value from the FIFO + * + * Function gets the value from the top from the FIFO. + * The value is removed from the FIFO memory. + * + * @param[in,out] p_fifo FIFO object. + * @param[out] p_var Pointer to the variable to store data. + * @param[in] size Size of the data we are going to load. + * @param[out] p_released See the values returned by @ref app_atfifo_rflush. + * + * @retval NRF_SUCCESS Element was successfully copied from FIFO memory. + * @retval NRF_ERROR_NOT_FOUND No data in the FIFO. + */ +ret_code_t app_atfifo_get(app_atfifo_t * const p_fifo, void * const p_var, size_t size, bool * p_released); + +/** + * @brief Open FIFO for reading, internal function + * + * Function called to start FIFO read operation and access the given FIFO buffer directly. + * + * @param[in,out] p_fifo FIFO object. + * @param[out] p_context The operation context, required by @ref app_atfifo_rflush + * + * @return Pointer to data buffer or NULL if there is no data in the FIFO. + * + * @note + * Do not use this function directly. + * Use @ref app_atfifo_ropen instead. + */ +void const * app_atfifo_ropen_internal(app_atfifo_t * const p_fifo, app_atfifo_rcontext_t * p_context); + + +/** + * @brief Open FIFO for reading + * + * Function called to start FIFO read operation and access the FIFO buffer directly. + * + * @param[in,out] p_fifo FIFO object. + * @param[out] p_context The operation context, required by @ref app_atfifo_rflush + * @param[in] size Requested size of the buffer. Currently used only for integrity checking when debugging. + * + * @return Pointer to data buffer or NULL if there is no data in the FIFO. + */ +static inline void const * app_atfifo_ropen(app_atfifo_t * const p_fifo, app_atfifo_rcontext_t * p_context, size_t size) +{ + ASSERT(size <= p_fifo->item_size); + UNUSED_PARAMETER(size); + return app_atfifo_ropen_internal(p_fifo, p_context); +} + +/** + * @brief Close reading operation + * + * Function used to finish reading operation. + * If this reading operation did not interrupt another reading operation the head write buffer is moved. + * If this reading operation was placed in the middle of another reading, the new read pointer is only written. + * + * @param[in,out] p_fifo FIFO object. + * @param[in] p_context Context of the reading operation that we are going to close. + * + * @retval true This operation is not generated in the middle of another read operation and the write head would be updated to read head (space is released). + * @retval false This operation was performed in the middle of another read operation and the write buffer head was not moved (no space is released). + */ +bool app_atfifo_rflush(app_atfifo_t * const p_fifo, app_atfifo_rcontext_t * p_context); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_ATFIFO_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic_fifo/app_atfifo_internal.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic_fifo/app_atfifo_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..9503280f3f4da758f6c7f9c943840a2e400ce08b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/atomic_fifo/app_atfifo_internal.h @@ -0,0 +1,577 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/** + * @file + * @brief Atomic FIFO internal file + * + * This file should be included only by app_atfifo internally. + * Needs app_atfifo.h included first. + */ +#ifndef APP_ATFIFO_H__ +#error This is internal file. Do not include this file in your program. +#endif + +#ifndef APP_ATFIFO_INTERNAL_H__ +#define APP_ATFIFO_INTERNAL_H__ +#include +#include "nrf.h" +#include "app_util.h" +#include "nordic_common.h" + +#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0 +#error Unsupported core version +#endif + +/* + * Make sure that rd and wr pos in a tag are aligned like expected + * Changing this would require changes inside assembly code! + */ +STATIC_ASSERT(offsetof(nrf_atfifo_postag_pos_t, wr) == 0); +STATIC_ASSERT(offsetof(nrf_atfifo_postag_pos_t, rd) == 2); + +/** + * @brief Atomically reserve space for new write + * + * @param[in,out] p_fifo FIFO object. + * @param[out] old_tail Tail position tag before new space was reserved + * + * @retval true Space available + * @retval false Memory full + * + * @sa app_atfifo_wspace_close + */ +static bool app_atfifo_wspace_req(app_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail); + +/** + * @brief Atomically mark all written data available + * + * This function marks all data available for reading. + * This marking is done by copying tail.pos.wr into tail.pos.rd. + * + * It has to be called only when closing the first write. + * It cannot be called if some write access was interrupted. + * See the code below: + * @code + * if(old_tail.pos.wr == old_tail.pos.rd) + * { + * app_atfifo_wspace_close(my_fifo); + * return true; + * } + * return false; + * @endcode + * + * @param[in,out] p_fifo FIFO object. + * + * @sa app_atfifo_wspace_req + */ +static void app_atfifo_wspace_close(app_atfifo_t * const p_fifo); + +/** + * @brief Atomically get part of the buffer to read data + * + * @param[in,out] p_fifo FIFO object. + * @param[out] old_head Head position tag before data buffer was read + * + * @retval true Data available for reading + * @retval false No data in the buffer + * + * @sa app_atfifo_rspace_close + */ +static bool app_atfifo_rspace_req(app_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head); + +/** + * @brief Atomically release all read data + * + * This function marks all data that was actually read as free space, + * available for writing. + * This marking is done by copying head.pos.rd into head.pos.wr. + * + * It has to be called only when closing the first read. + * It cannot be called when current read access interrupted some other read access. + * See code below: + * @code + * if(old_head.pos.wr == old_head.pos.rd) + * { + * app_atfifo_rspace_close(my_fifo); + * return true; + * } + * return false; + * @endcode + * + * @param[in,out] p_fifo FIFO object. + * + * @sa app_atfifo_rspace_req + */ +static void app_atfifo_rspace_close(app_atfifo_t * const p_fifo); + +/** + * @brief Safely clear the FIFO, internal function + * + * This function realizes the functionality required by @ref app_atfifo_clear. + * + * @param[in,out] p_fifo FIFO object. + * + * @retval true All the data was released + * @retval false All the data available for releasing was released, but there is some pending transfer. + */ +static bool app_atfifo_space_clear(app_atfifo_t * const p_fifo); + + +/* --------------------------------------------------------------------------- + * Implementation starts here + */ + +#if defined ( __CC_ARM ) + + +__ASM bool app_atfifo_wspace_req(app_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail) +{ + /* Registry usage: + * R0 - p_fifo + * R1 - p_old_tail + * R2 - internal variable old_tail (saved by caller) + * R3 - internal variable new_tail (saved by caller) + * R4 - internal temporary register (saved by this function) + * R5 - not used stored to keep the stack aligned to 8 bytes + * Returned value: + * R0 (bool - 32 bits) + */ + push {r4, r5} +app_atfifo_wspace_req_repeat + /* Load tail tag and set memory monitor !!! R2 - old tail !!! */ + ldrex r2, [r0, #__cpp(offsetof(app_atfifo_t, tail))] + /* Extract write position !!! R3 !!! */ + uxth r3, r2 + /* Increment address with overload support !!! R4 used temporary !!! */ + ldrh r4, [r0, #__cpp(offsetof(app_atfifo_t, item_size))] + add r3, r4 + ldrh r4, [r0, #__cpp(offsetof(app_atfifo_t, buf_size))] + cmp r3, r4 + it hs + subhs r3, r3, r4 + + /* Check if FIFO would overload after making this increment !!! R4 used temporary !!! */ + ldrh r4, [r0, #__cpp(offsetof(app_atfifo_t, head) + offsetof(nrf_atfifo_postag_pos_t, wr))] + cmp r3, r4 + ittt eq + clrexeq + moveq r0, #__cpp(false) + beq app_atfifo_wspace_req_exit + + /* Pack everything back !!! R3 - new tail !!! */ + /* Copy lower byte from new_tail, and higher byte is a value from the top of old_tail */ + pkhbt r3, r3, r2 + + /* Store new value clearing memory monitor !!! R4 used temporary !!! */ + strex r4, r3, [r0, #__cpp(offsetof(app_atfifo_t, tail))] + cmp r4, #0 + bne app_atfifo_wspace_req_repeat + + /* Return true */ + mov r0, #__cpp(true) +app_atfifo_wspace_req_exit + /* Save old tail */ + str r2, [r1] + pop {r4, r5} + bx lr +} + + +__ASM void app_atfifo_wspace_close(app_atfifo_t * const p_fifo) +{ + /* Registry usage: + * R0 - p_fifo + * R1 - internal temporary register + * R2 - new_tail + */ +app_atfifo_wspace_close_repeat + ldrex r2, [r0, #__cpp(offsetof(app_atfifo_t, tail))] + /* Copy from lower byte to higher */ + pkhbt r2, r2, r2, lsl #16 + + strex r1, r2, [r0, #__cpp(offsetof(app_atfifo_t, tail))] + cmp r1, #0 + bne app_atfifo_wspace_close_repeat + bx lr +} + + +__ASM bool app_atfifo_rspace_req(app_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head) +{ + /* Registry usage: + * R0 - p_fifo + * R1 - p_old_head + * R2 - internal variable old_head (saved by caller) + * R3 - internal variable new_head (saved by caller) + * R4 - internal temporary register (saved by this function) + * R5 - not used stored to keep the stack aligned to 8 bytes + * Returned value: + * R0 (bool - 32 bits) + */ + push {r4, r5} +app_atfifo_rspace_req_repeat + /* Load tail tag and set memory monitor !!! R2 - old tail !!! */ + ldrex r2, [r0, #__cpp(offsetof(app_atfifo_t, head))] + /* Extract read position !!! R3 !!! */ + uxth r3, r2, ror #16 + + /* Check if we have any data !!! R4 used temporary !!! */ + ldrh r4, [r0, #__cpp(offsetof(app_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd))] + cmp r3, r4 + ittt eq + clrexeq + moveq r0, #__cpp(false) + beq app_atfifo_rspace_req_exit + + /* Increment address with overload support !!! R4 used temporary !!! */ + ldrh r4, [r0, #__cpp(offsetof(app_atfifo_t, item_size))] + add r3, r4 + ldrh r4, [r0, #__cpp(offsetof(app_atfifo_t, buf_size))] + cmp r3, r4 + it hs + subhs r3, r3, r4 + + /* Pack everything back !!! R3 - new tail !!! */ + /* Copy lower byte from old_head, and higher byte is a value from write_pos */ + pkhbt r3, r2, r3, lsl #16 + + /* Store new value clearing memory monitor !!! R4 used temporary !!! */ + strex r4, r3, [r0, #__cpp(offsetof(app_atfifo_t, head))] + cmp r4, #0 + bne app_atfifo_rspace_req_repeat + + /* Return true */ + mov r0, #__cpp(true) +app_atfifo_rspace_req_exit + /* Save old head */ + str r2, [r1] + pop {r4, r5} + bx lr +} + + +__ASM void app_atfifo_rspace_close(app_atfifo_t * const p_fifo) +{ + /* Registry usage: + * R0 - p_fifo + * R1 - internal temporary register + * R2 - new_tail + */ +app_atfifo_rspace_close_repeat + ldrex r2, [r0, #__cpp(offsetof(app_atfifo_t, head))] + /* Copy from higher byte to lower */ + pkhtb r2, r2, r2, asr #16 + + strex r1, r2, [r0, #__cpp(offsetof(app_atfifo_t, head))] + cmp r1, #0 + bne app_atfifo_rspace_close_repeat + bx lr +} + + +__ASM bool app_atfifo_space_clear(app_atfifo_t * const p_fifo) +{ + /* Registry usage: + * R0 - p_fifo as input, bool output after + * R1 - tail, rd pointer, new_head + * R2 - head_old, destroyed when creating new_head + * R3 - p_fifo - copy + */ + mov r3, r0 +app_atfifo_space_clear_repeat + /* Load old head in !!! R2 register !!! and read pointer of tail in !!! R1 register !!! */ + ldrex r2, [r3, #__cpp(offsetof(app_atfifo_t, head))] + ldrh r1, [r3, #__cpp(offsetof(app_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd))] + cmp r2, r2, ror #16 + /* Return false as default */ + mov r0, #__cpp(false) + /* Create new head in !!! R1 register !!! Data in !!! R2 register broken !!! */ + itett ne + uxthne r2, r2 + orreq r1, r1, r1, lsl #16 + orrne r1, r2, r1, lsl #16 + + /* Skip header test */ + bne app_atfifo_space_clear_head_test_skip + + /* Load whole tail and test it !!! R2 used !!! */ + ldr r2, [r3, #__cpp(offsetof(app_atfifo_t, tail))] + cmp r2, r2, ror #16 + /* Return true if equal */ + it eq + moveq r0, #__cpp(true) + +app_atfifo_space_clear_head_test_skip + /* Store and test if success !!! R2 used temporary !!! */ + strex r2, r1, [r3, #__cpp(offsetof(app_atfifo_t, head))] + cmp r2, #0 + bne app_atfifo_space_clear_repeat + bx lr +} + +#elif defined ( __ICCARM__ ) || defined ( __GNUC__ ) + +bool app_atfifo_wspace_req(app_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail) +{ + volatile bool ret; + volatile uint32_t old_tail; + uint32_t new_tail; + uint32_t temp; + + __ASM volatile( + /* For more comments see Keil version above */ + "1: \n" + " ldrex %[old_tail], [%[p_fifo], %[offset_tail]] \n" + " uxth %[new_tail], %[old_tail] \n" + " \n" + " ldrh %[temp], [%[p_fifo], %[offset_item_size]] \n" + " add %[new_tail], %[temp] \n" + " ldrh %[temp], [%[p_fifo], %[offset_buf_size]] \n" + " cmp %[new_tail], %[temp] \n" + " it hs \n" + " subhs %[new_tail], %[new_tail], %[temp] \n" + " \n" + " ldrh %[temp], [%[p_fifo], %[offset_head_wr]] \n" + " cmp %[new_tail], %[temp] \n" + " ittt eq \n" + " clrexeq \n" + " moveq %[ret], %[false_val] \n" + " beq.n 2f \n" + " \n" + " pkhbt %[new_tail], %[new_tail], %[old_tail] \n" + " \n" + " strex %[temp], %[new_tail], [%[p_fifo], %[offset_tail]] \n" + " cmp %[temp], #0 \n" + " bne.n 1b \n" + " \n" + " mov %[ret], %[true_val] \n" + "2: \n" + : /* Output operands */ + [ret] "=r"(ret), + [temp] "=&r"(temp), + [old_tail]"=&r"(old_tail), + [new_tail]"=&r"(new_tail) + : /* Input operands */ + [p_fifo] "r"(p_fifo), + [offset_tail] "J"(offsetof(app_atfifo_t, tail)), + [offset_head_wr] "J"(offsetof(app_atfifo_t, head) + offsetof(nrf_atfifo_postag_pos_t, wr)), + [offset_item_size]"J"(offsetof(app_atfifo_t, item_size)), + [offset_buf_size] "J"(offsetof(app_atfifo_t, buf_size)), + [true_val] "I"(true), + [false_val] "I"(false) + : /* Clobbers */ + "cc"); + + p_old_tail->tag = old_tail; + UNUSED_VARIABLE(new_tail); + UNUSED_VARIABLE(temp); + return ret; +} + + +void app_atfifo_wspace_close(app_atfifo_t * const p_fifo) +{ + uint32_t temp; + uint32_t new_tail; + + __ASM volatile( + /* For more comments see Keil version above */ + "1: \n" + " ldrex %[new_tail], [%[p_fifo], %[offset_tail]] \n" + " pkhbt %[new_tail],%[new_tail], %[new_tail], lsl #16 \n" + " \n" + " strex %[temp], %[new_tail], [%[p_fifo], %[offset_tail]] \n" + " cmp %[temp], #0 \n" + " bne.n 1b \n" + : /* Output operands */ + [temp] "=&r"(temp), + [new_tail] "=&r"(new_tail) + : /* Input operands */ + [p_fifo] "r"(p_fifo), + [offset_tail] "J"(offsetof(app_atfifo_t, tail)) + : /* Clobbers */ + "cc"); + + UNUSED_VARIABLE(temp); + UNUSED_VARIABLE(new_tail); +} + + +bool app_atfifo_rspace_req(app_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head) +{ + volatile bool ret; + volatile uint32_t old_head; + uint32_t new_head; + uint32_t temp; + + __ASM volatile( + /* For more comments see Keil version above */ + "1: \n" + " ldrex %[old_head], [%[p_fifo], %[offset_head]] \n" + " uxth %[new_head], %[old_head], ror #16 \n" + " \n" + " ldrh %[temp], [%[p_fifo], %[offset_tail_rd]] \n" + " cmp %[new_head], %[temp] \n" + " ittt eq \n" + " clrexeq \n" + " moveq %[ret], %[false_val] \n" + " beq.n 2f \n" + " \n" + " ldrh %[temp], [%[p_fifo], %[offset_item_size]] \n" + " add %[new_head], %[temp] \n" + " ldrh %[temp], [%[p_fifo], %[offset_buf_size]] \n" + " cmp %[new_head], %[temp] \n" + " it hs \n" + " subhs %[new_head], %[new_head], %[temp] \n" + " \n" + " pkhbt %[new_head], %[old_head], %[new_head], lsl #16 \n" + " \n" + " strex %[temp], %[new_head], [%[p_fifo], %[offset_head]] \n" + " cmp %[temp], #0 \n" + " bne.n 1b \n" + " \n" + " mov %[ret], %[true_val] \n" + "2: \n" + : /* Output operands */ + [ret] "=r"(ret), + [temp] "=&r"(temp), + [old_head]"=&r"(old_head), + [new_head]"=&r"(new_head) + : /* Input operands */ + [p_fifo] "r"(p_fifo), + [offset_head] "J"(offsetof(app_atfifo_t, head)), + [offset_tail_rd] "J"(offsetof(app_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd)), + [offset_item_size]"J"(offsetof(app_atfifo_t, item_size)), + [offset_buf_size] "J"(offsetof(app_atfifo_t, buf_size)), + [true_val] "I"(true), + [false_val] "I"(false) + : /* Clobbers */ + "cc"); + + p_old_head->tag = old_head; + UNUSED_VARIABLE(new_head); + UNUSED_VARIABLE(temp); + return ret; +} + + +void app_atfifo_rspace_close(app_atfifo_t * const p_fifo) +{ + uint32_t temp; + uint32_t new_head; + + __ASM volatile( + /* For more comments see Keil version above */ + "1: \n" + " ldrex %[new_head], [%[p_fifo], %[offset_head]] \n" + " pkhtb %[new_head],%[new_head], %[new_head], asr #16 \n" + " \n" + " strex %[temp], %[new_head], [%[p_fifo], %[offset_head]] \n" + " cmp %[temp], #0 \n" + " bne.n 1b \n" + : /* Output operands */ + [temp] "=&r"(temp), + [new_head] "=&r"(new_head) + : /* Input operands */ + [p_fifo] "r"(p_fifo), + [offset_head] "J"(offsetof(app_atfifo_t, head)) + : /* Clobbers */ + "cc"); + + UNUSED_VARIABLE(temp); + UNUSED_VARIABLE(new_head); +} + + +bool app_atfifo_space_clear(app_atfifo_t * const p_fifo) +{ + volatile bool ret; + uint32_t old_head; /* This variable is left broken after assembly code finishes */ + uint32_t new_head; + + __ASM volatile( + "1: \n" + " ldrex %[old_head], [%[p_fifo], %[offset_head]] \n" + " ldrh %[new_head], [%[p_fifo], %[offset_tail_rd]] \n" + " cmp %[old_head], %[old_head], ror #16 \n" + " \n" + " mov %[ret], %[false_val] \n" + " \n" + " itett ne \n" + " uxthne %[old_head], %[old_head] \n" + " orreq %[new_head], %[new_head], %[new_head], lsl #16 \n" + " orrne %[new_head], %[old_head], %[new_head], lsl #16 \n" + " \n" + " bne.n 2f \n" + " \n" + " ldr %[old_head], [%[p_fifo], %[offset_tail]] \n" + " cmp %[old_head], %[old_head], ror #16 \n" + " it eq \n" + " moveq %[ret], %[true_val] \n" + " \n" + "2: \n" + " strex %[old_head], %[new_head], [%[p_fifo], %[offset_head]] \n" + " cmp %[old_head], #0 \n" + " bne.n 1b \n" + : /* Output operands */ + [ret] "=&r"(ret), + [old_head] "=&r"(old_head), + [new_head] "=&r"(new_head) + : /* Input operands */ + [p_fifo] "r"(p_fifo), + [offset_head] "J"(offsetof(app_atfifo_t, head)), + [offset_tail] "J"(offsetof(app_atfifo_t, tail)), + [offset_tail_rd] "J"(offsetof(app_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd)), + [true_val] "I"(true), + [false_val] "I"(false) + : /* Clobbers */ + "cc"); + + UNUSED_VARIABLE(old_head); + UNUSED_VARIABLE(new_head); + return ret; +} + +#else +#error Unsupported compiler +#endif + +#endif /* APP_ATFIFO_INTERNAL_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/balloc/nrf_balloc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/balloc/nrf_balloc.c new file mode 100644 index 0000000000000000000000000000000000000000..88edd63adcc11e2761808827e0ade6fc822e964c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/balloc/nrf_balloc.c @@ -0,0 +1,322 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" + #if NRF_MODULE_ENABLED(NRF_BALLOC) + +#include "nrf_balloc.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "NRF_BALLOC" +#if NRF_BALLOC_CONFIG_LOG_ENABLED + #define NRF_LOG_LEVEL NRF_BALLOC_CONFIG_LOG_LEVEL + #define NRF_LOG_INFO_COLOR NRF_BALLOC_CONFIG_INFO_COLOR + #define NRF_LOG_DEBUG_COLOR NRF_BALLOC_CONFIG_DEBUG_COLOR +#else + #define NRF_LOG_LEVEL 0 +#endif // NRF_BALLOC_CONFIG_LOG_ENABLED +#include "nrf_log.h" + +#define HEAD_GUARD_FILL 0xBAADF00D /**< Magic number used to mark head guard.*/ +#define TAIL_GUARD_FILL 0xBAADCAFE /**< Magic number used to mark tail guard.*/ +#define FREE_MEM_FILL 0xBAADBAAD /**< Magic number used to mark free memory.*/ + +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED +/**@brief Validate block memory, prepare block guards, and calculate pointer to the element. + * + * @param[in] p_pool Pointer to the memory pool. + * @param[in] p_head Pointer to the beginning of the block. + * + * @return Pointer to the element. + */ +__STATIC_INLINE void * nrf_balloc_block_unwrap(nrf_balloc_t const * p_pool, void * p_head) +{ + ASSERT((p_pool != NULL) && ((p_pool->block_size % sizeof(uint32_t)) == 0)); + ASSERT((p_head != NULL) && (((uint32_t)(p_head) % sizeof(uint32_t)) == 0)); + + uint32_t head_words = NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(p_pool->debug_flags); + uint32_t tail_words = NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(p_pool->debug_flags); + + uint32_t * p_tail = (uint32_t *)((size_t)(p_head) + p_pool->block_size); + uint32_t * p_element = (uint32_t *)p_head + head_words; + + if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags)) + { + for (uint32_t * ptr = p_head; ptr < p_tail; ptr++) + { + if (*ptr != FREE_MEM_FILL) + { + NRF_LOG_ERROR("Detected free memory corruption at %p (%p != %p, pool: %p)\r\n", + (uint32_t)ptr, *ptr, FREE_MEM_FILL, (uint32_t)p_pool); + APP_ERROR_CHECK_BOOL(false); + } + } + } + + for (uint32_t * ptr = p_head; ptr < p_element; ptr++) + { + *ptr = HEAD_GUARD_FILL; + } + + for (uint32_t * ptr = ( p_tail - tail_words); ptr < p_tail; ptr++) + { + *ptr = TAIL_GUARD_FILL; + } + + return p_element; +} + +/**@brief Calculate pointer to the block, validate block guards, and mark block memory as free. + * + * @param[in] p_pool Pointer to the memory pool. + * @param[in] p_element Pointer to the element. + * + * @return Pointer to the beginning of the block. + */ +__STATIC_INLINE void * nrf_balloc_element_wrap(nrf_balloc_t const * p_pool, void * p_element) +{ + ASSERT((p_pool != NULL) && ((p_pool->block_size % sizeof(uint32_t)) == 0)); + ASSERT((p_element != NULL) && (((uint32_t)(p_element) % sizeof(uint32_t)) == 0)); + + uint32_t head_words = NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(p_pool->debug_flags); + uint32_t tail_words = NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(p_pool->debug_flags); + + uint32_t * p_head = (uint32_t *)p_element - head_words; + uint32_t * p_tail = (uint32_t *)((size_t)(p_head) + p_pool->block_size); + + for (uint32_t * ptr = p_head; ptr < (uint32_t *)p_element; ptr++) + { + if (*ptr != HEAD_GUARD_FILL) + { + NRF_LOG_ERROR("Detected Head Guard corruption at %p (%p != %p, pool: %p)\r\n", + (uint32_t)ptr, *ptr, HEAD_GUARD_FILL, (uint32_t)p_pool); + APP_ERROR_CHECK_BOOL(false); + } + } + + for (uint32_t * ptr = ( p_tail - tail_words); ptr < p_tail; ptr++) + { + if (*ptr != TAIL_GUARD_FILL) + { + NRF_LOG_ERROR("Detected Tail Guard corruption at %p (%p != %p, pool: %p)\r\n", + (uint32_t)ptr, *ptr, TAIL_GUARD_FILL, (uint32_t)p_pool); + APP_ERROR_CHECK_BOOL(false); + } + } + + if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags)) + { + for (uint32_t * ptr = p_head; ptr < p_tail; ptr++) + { + *ptr = FREE_MEM_FILL; + } + } + + return p_head; +} + +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + +/**@brief Convert block index to a pointer. + * + * @param[in] p_pool Pointer to the memory pool. + * @param[in] idx Index of the block. + * + * @return Pointer to the beginning of the block. + */ +static void * nrf_balloc_idx2block(nrf_balloc_t const * p_pool, uint8_t idx) +{ + ASSERT(p_pool != NULL); + return (uint8_t *)(p_pool->p_memory_begin) + ((size_t)(idx) * p_pool->block_size); +} + +/**@brief Convert block pointer to index. + * + * @param[in] p_pool Pointer to the memory pool. + * @param[in] p_block Pointer to the beginning of the block. + * + * @return Index of the block. + */ +static uint8_t nrf_balloc_block2idx(nrf_balloc_t const * p_pool, void const * p_block) +{ + ASSERT(p_pool != NULL); + return ((size_t)(p_block) - (size_t)(p_pool->p_memory_begin)) / p_pool->block_size; +} + +ret_code_t nrf_balloc_init(nrf_balloc_t const * p_pool) +{ + VERIFY_PARAM_NOT_NULL(p_pool); + + ASSERT(p_pool->p_cb); + ASSERT(p_pool->p_stack_base); + ASSERT(p_pool->p_stack_limit); + ASSERT(p_pool->p_memory_begin); + ASSERT(p_pool->block_size); + + NRF_LOG_INFO("Init\r\n"); + +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + ASSERT(p_pool->p_memory_end); + + if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags)) + { + for (uint32_t * ptr = p_pool->p_memory_begin; ptr < (uint32_t *)(p_pool->p_memory_end); ptr++) + { + *ptr = FREE_MEM_FILL; + } + } +#endif + + p_pool->p_cb->p_stack_pointer = p_pool->p_stack_base; + uint8_t pool_size = p_pool->p_stack_limit - p_pool->p_stack_base; + while (pool_size--) + { + *(p_pool->p_cb->p_stack_pointer)++ = pool_size; + } + + p_pool->p_cb->max_utilization = 0; + + return NRF_SUCCESS; +} + +void * nrf_balloc_alloc(nrf_balloc_t const * p_pool) +{ + ASSERT(p_pool != NULL); + + void * p_block = NULL; + + CRITICAL_REGION_ENTER(); + + if (p_pool->p_cb->p_stack_pointer > p_pool->p_stack_base) + { + // Allocate block. + p_block = nrf_balloc_idx2block(p_pool, *--(p_pool->p_cb->p_stack_pointer)); + + // Update utilization statistics. + uint8_t utilization = p_pool->p_stack_limit - p_pool->p_cb->p_stack_pointer; + if (p_pool->p_cb->max_utilization < utilization) + { + p_pool->p_cb->max_utilization = utilization; + } + } + + CRITICAL_REGION_EXIT(); + +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + if (p_block != NULL) + { + p_block = nrf_balloc_block_unwrap(p_pool, p_block); + } +#endif + + NRF_LOG_DEBUG("nrf_balloc_alloc(p_pool: %p, p_element: %p)\r\n", + (uint32_t)p_pool, (uint32_t)p_block); + return p_block; +} + +void nrf_balloc_free(nrf_balloc_t const * p_pool, void * p_element) +{ + ASSERT(p_pool != NULL); + ASSERT(p_element != NULL) + NRF_LOG_DEBUG("nrf_balloc_free(p_pool: %p, p_element: %p)\r\n", + (uint32_t)p_pool, (uint32_t)p_element); + +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + void * p_block = nrf_balloc_element_wrap(p_pool, p_element); + + // These checks could be done outside critical region as they use only pool configuration data. + if (NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(p_pool->debug_flags)) + { + // Check if the element belongs to this pool. + if ((p_block < p_pool->p_memory_begin) || (p_block >= p_pool->p_memory_end)) + { + NRF_LOG_ERROR("Attempted to free element that does belong to the pool (pool: %p, element: %p)\r\n", + (uint32_t)p_pool, (uint32_t)p_element); + APP_ERROR_CHECK_BOOL(false); + } + + // Check if the pointer is valid. + if ((((size_t)(p_block) - (size_t)(p_pool->p_memory_begin)) % p_pool->block_size) != 0) + { + NRF_LOG_ERROR("Atempted to free corrupted element address (pool: %p, element: %p)\r\n", + (uint32_t)p_pool, (uint32_t)p_element); + APP_ERROR_CHECK_BOOL(false); + } + } +#else + void * p_block = p_element; +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + + CRITICAL_REGION_ENTER(); + +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + // These checks have to be done in critical region as they use p_pool->p_stack_pointer. + if (NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(p_pool->debug_flags)) + { + // Check for allocated/free ballance. + if (p_pool->p_cb->p_stack_pointer >= p_pool->p_stack_limit) + { + NRF_LOG_ERROR("Attempted to free an element while the pool is full (pool: %p, element: %p)\r\n", + (uint32_t)p_pool, (uint32_t)p_element); + APP_ERROR_CHECK_BOOL(false); + } + } + + if (NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_GET(p_pool->debug_flags)) + { + // Check for double free. + for (uint8_t * p_idx = p_pool->p_stack_base; p_idx < p_pool->p_cb->p_stack_pointer; p_idx++) + { + if (nrf_balloc_idx2block(p_pool, *p_idx) == p_block) + { + NRF_LOG_ERROR("Attempted to double-free an element (pool: %p, element: %p)\r\n", + (uint32_t)p_pool, (uint32_t)p_element); + APP_ERROR_CHECK_BOOL(false); + } + } + } +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + + // Free the element. + *(p_pool->p_cb->p_stack_pointer)++ = nrf_balloc_block2idx(p_pool, p_block); + + CRITICAL_REGION_EXIT(); +} + +#endif // NRF_MODULE_ENABLED(NRF_BALLOC) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/balloc/nrf_balloc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/balloc/nrf_balloc.h new file mode 100644 index 0000000000000000000000000000000000000000..7a986ccf04f1a6220626c9d617f3dddb71433dc8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/balloc/nrf_balloc.h @@ -0,0 +1,296 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @defgroup nrf_balloc Block memory allocator + * @{ + * @ingroup app_common + * @brief This module handles block memory allocator features. + */ + + +#ifndef NRF_BALLOC_H__ +#define NRF_BALLOC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sdk_errors.h" +#include "sdk_config.h" +#include "app_util_platform.h" + +/**@defgroup NRF_BALLOC_DEBUG Macros for preparing debug flags for block allocator module. + * @{ */ +#define NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_SET(words) (((words) & 0xFF) << 0) +#define NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(flags) (((flags) >> 0) & 0xFF) +#define NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_SET(words) (((words) & 0xFF) << 8) +#define NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(flags) (((flags) >> 8) & 0xFF) + +#define NRF_BALLOC_DEBUG_BASIC_CHECKS_SET(enable) (!!(enable) << 16) +#define NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(flags) (flags & (1 << 16)) +#define NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_SET(enable) (!!(enable) << 17) +#define NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_GET(flags) (flags & (1 << 17)) +#define NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_SET(enable) (!!(enable) << 18) +#define NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(flags) (flags & (1 << 18)) +/**@} */ + +/**@brief Default debug flags for @ref nrf_balloc. This is used by the @ref NRF_BALLOC_DEF macro. + * Flags can be changed in @ref sdk_config. + */ +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + #define NRF_BALLOC_DEFAULT_DEBUG_FLAGS \ + ( \ + NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_SET(NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS) | \ + NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_SET(NRF_BALLOC_CONFIG_TAIL_WORDS) | \ + NRF_BALLOC_DEBUG_BASIC_CHECKS_SET(NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED) | \ + NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_SET(NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED) | \ + NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_SET(NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED) \ + ) +#else + #define NRF_BALLOC_DEFAULT_DEBUG_FLAGS 0 +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + +/**@brief Block memory allocator control block.*/ +typedef struct +{ + uint8_t * p_stack_pointer; //!< Current allocation stack pointer. + uint8_t max_utilization; //!< Maximum utilization of the memory pool. +} nrf_balloc_cb_t; + +/**@brief Block memory allocator pool instance. The pool is made of elements of the same size. */ +typedef struct +{ + nrf_balloc_cb_t * p_cb; //!< Pointer to the instance control block. + uint8_t * p_stack_base; //!< Base of the allocation stack. + /**< + * Stack is used to store handlers to not allocated elements. + */ + uint8_t * p_stack_limit; //!< Maximum possible value of the allocation stack pointer. + void * p_memory_begin; //!< Pointer to the start of the memory pool. + /**< + * Memory is used as a heap for blocks. + */ +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + void * p_memory_end; //!< Pointer to the end of the memory pool. + uint32_t debug_flags; //!< Debugging settings. + /**< + * Debug flag should be created by @ref NRF_BALLOC_DEBUG. + */ +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + uint16_t block_size; //!< Size of the allocated block (including debug overhead). + /**< + * Single block contains user element with header and tail + * words. + */ +} nrf_balloc_t; + +/**@brief Get total memory consumed by single block (element size with overhead caused by debug + * flags). + * + * @param[in] _element_size Size of an element. + * @param[in] _debug_flags Debug flags. + */ +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + #define NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) \ + ( \ + (sizeof(uint32_t) * NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(_debug_flags)) + \ + ALIGN_NUM(sizeof(uint32_t), (_element_size)) + \ + (sizeof(uint32_t) * NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(_debug_flags)) \ + ) +#else + #define NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) \ + ALIGN_NUM(sizeof(uint32_t), (_element_size)) +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + +/**@brief Create a block allocator instance with custom debug flags. + * + * @note This macro reserves memory for the given block allocator instance. + * + * @param[in] _name Name of the allocator. + * @param[in] _element_size Size of one element. + * @param[in] _pool_size Size of the pool. + * @param[in] _debug_flags Debug flags (@ref NRF_BALLOC_DEBUG). + */ +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + #define NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, _debug_flags) \ + STATIC_ASSERT((_pool_size) <= UINT8_MAX); \ + static uint8_t _name##_nrf_balloc_pool_stack[(_pool_size)]; \ + static uint32_t _name##_nrf_balloc_pool_mem \ + [NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) * (_pool_size) / sizeof(uint32_t)]; \ + static nrf_balloc_cb_t _name##_nrf_balloc_cb; \ + static const nrf_balloc_t _name = \ + { \ + .p_cb = &_name##_nrf_balloc_cb, \ + .p_stack_base = _name##_nrf_balloc_pool_stack, \ + .p_stack_limit = _name##_nrf_balloc_pool_stack + (_pool_size), \ + .p_memory_begin = _name##_nrf_balloc_pool_mem, \ + .block_size = NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags), \ + .p_memory_end = (uint8_t *)_name##_nrf_balloc_pool_mem \ + + NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) * (_pool_size),\ + .debug_flags = (_debug_flags), \ + } +#else + #define NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, _debug_flags) \ + STATIC_ASSERT((_pool_size) <= UINT8_MAX); \ + static uint8_t _name##_nrf_balloc_pool_stack[(_pool_size)]; \ + static uint32_t _name##_nrf_balloc_pool_mem \ + [NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) * (_pool_size) / sizeof(uint32_t)]; \ + static nrf_balloc_cb_t _name##_nrf_balloc_cb; \ + static const nrf_balloc_t _name = \ + { \ + .p_cb = &_name##_nrf_balloc_cb, \ + .p_stack_base = _name##_nrf_balloc_pool_stack, \ + .p_stack_limit = _name##_nrf_balloc_pool_stack + (_pool_size), \ + .p_memory_begin = _name##_nrf_balloc_pool_mem, \ + .block_size = NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags), \ + } +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + +/**@brief Create a block allocator instance. + * + * @note This macro reserves memory for the given block allocator instance. + * + * @param[in] _name Name of the allocator. + * @param[in] _element_size Size of one element. + * @param[in] _pool_size Size of the pool. + */ +#define NRF_BALLOC_DEF(_name, _element_size, _pool_size) \ + NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, NRF_BALLOC_DEFAULT_DEBUG_FLAGS) + +/**@brief Create a block allocator interface. + * + * @param[in] _type Type which is allocated. + * @param[in] _name Name of the allocator. + */ +#define NRF_BALLOC_INTERFACE_DEC(_type, _name) \ + _type * _name##_alloc(void); \ + void _name##_free(_type * p_element) + +/**@brief Define a custom block allocator interface. + * + * @param[in] _attr Function attribute that will be added to allocator function definition. + * @param[in] _type Type which is allocated. + * @param[in] _name Name of the allocator. + * @param[in] _p_pool Pool from which data will be allocated. + */ +#define NRF_BALLOC_INTERFACE_CUSTOM_DEF(_attr, _type, _name, _p_pool) \ + _attr _type * _name##_alloc(void) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_pool) != NULL); \ + ASSERT((_p_pool)->block_size >= \ + NRF_BALLOC_BLOCK_SIZE(sizeof(_type), (_p_pool)->debug_flags)); \ + GCC_PRAGMA("GCC diagnostic pop") \ + return (_type *)(nrf_balloc_alloc(_p_pool)); \ + } \ + \ + _attr void _name##_free(_type * p_element) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_pool) != NULL); \ + ASSERT((_p_pool)->block_size >= \ + NRF_BALLOC_BLOCK_SIZE(sizeof(_type), (_p_pool)->debug_flags)); \ + GCC_PRAGMA("GCC diagnostic pop") \ + nrf_balloc_free((_p_pool), p_element); \ + } + +/**@brief Define block allocator interface. + * + * @param[in] _type Type which is allocated. + * @param[in] _name Name of the allocator. + * @param[in] _p_pool Pool from which data will be allocated. + */ +#define NRF_BALLOC_INTERFACE_DEF(_type, _name, _p_pool) \ + NRF_BALLOC_INTERFACE_CUSTOM_DEF(/* empty */, _type, _name, _p_pool) + +/**@brief Define a local block allocator interface. + * + * @param[in] _type Type which is allocated. + * @param[in] _name Name of the allocator. + * @param[in] _p_pool Pool from which data will be allocated. + */ +#define NRF_BALLOC_INTERFACE_LOCAL_DEF(_type, _name, _p_pool) \ + NRF_BALLOC_INTERFACE_CUSTOM_DEF(static, _type, _name, _p_pool) + +/**@brief Function for initializing a block memory allocator pool. + * + * @param[out] p_pool Pointer to the pool that is to be initialized. + * + * @return NRF_SUCCESS on success, otherwise error code. + */ +ret_code_t nrf_balloc_init(nrf_balloc_t const * p_pool); + +/**@brief Function for allocating an element from the pool. + * + * @note This module guarantees that the returned memory is aligned to 4. + * + * @param[in] p_pool Pointer to the memory pool from which the element will be allocated. + * + * @return Allocated element or NULL if the specified pool is empty. + */ +void * nrf_balloc_alloc(nrf_balloc_t const * p_pool); + +/**@brief Function for freeing an element back to the pool. + * + * @param[in] p_pool Pointer to the memory pool. + * @param[in] p_element Element to be freed. + */ +void nrf_balloc_free(nrf_balloc_t const * p_pool, void * p_element); + +/**@brief Function for getting maximum memory pool utilization. + * + * @param[in] p_pool Pointer to the memory pool instance. + * + * @return Maximum number of elements allocated from the pool. + */ +__STATIC_INLINE uint8_t nrf_balloc_max_utilization_get(nrf_balloc_t const * p_pool) +{ + ASSERT(p_pool != NULL); + return p_pool->p_cb->max_utilization; +} + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BALLOC_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/empty/nrf_block_dev_empty.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/empty/nrf_block_dev_empty.c new file mode 100644 index 0000000000000000000000000000000000000000..129ad6314aa4d0f515d6e897ae80f19daffb3a26 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/empty/nrf_block_dev_empty.c @@ -0,0 +1,210 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_block_dev_empty.h" + +/**@file + * + * @ingroup nrf_block_dev + * @{ + * + * @brief This module implements block device API. It would behave like: + * - /dev/empty for write operations + * - /dev/zero for read operations + */ + +static ret_code_t block_dev_empty_init(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ev_handler ev_handler, + void const * p_context) +{ + ASSERT(p_blk_dev); + nrf_block_dev_empty_t const * p_empty_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); + nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work; + + /* Calculate block device geometry.... */ + p_work->geometry.blk_size = p_empty_dev->empty_config.block_size; + p_work->geometry.blk_count = p_empty_dev->empty_config.block_count; + p_work->p_context = p_context; + p_work->ev_handler = ev_handler; + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_INIT, + NRF_BLOCK_DEV_RESULT_SUCCESS, + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return NRF_SUCCESS; +} + +static ret_code_t block_dev_empty_uninit(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_empty_t const * p_empty_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); + nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work; + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_UNINIT, + NRF_BLOCK_DEV_RESULT_SUCCESS, + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + memset(p_work, 0, sizeof(nrf_block_dev_empty_work_t)); + return NRF_SUCCESS; +} + +static ret_code_t block_dev_empty_read_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_empty_t const * p_empty_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); + nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work; + + memset(p_blk->p_buff, 0, p_empty_dev->p_work->geometry.blk_size * p_blk->blk_count); + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_READ_DONE, + NRF_BLOCK_DEV_RESULT_SUCCESS, + p_blk, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return NRF_SUCCESS; +} + +static ret_code_t block_dev_empty_write_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_empty_t const * p_empty_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); + nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work; + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, + NRF_BLOCK_DEV_RESULT_SUCCESS, + p_blk, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return NRF_SUCCESS; +} + +static ret_code_t block_dev_empty_ioctl(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ioctl_req_t req, void * p_data) +{ + nrf_block_dev_empty_t const * p_empty_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); + switch (req) + { + case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH: + { + bool * p_flushing = p_data; + if (p_flushing) + { + *p_flushing = false; + } + return NRF_SUCCESS; + } + case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS: + { + if (p_data == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + nrf_block_dev_info_strings_t const * * pp_strings = p_data; + *pp_strings = &p_empty_dev->info_strings; + return NRF_SUCCESS; + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +static nrf_block_dev_geometry_t const * block_dev_empty_geometry(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_empty_t const * p_empty_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); + nrf_block_dev_empty_work_t const * p_work = p_empty_dev->p_work; + + return &p_work->geometry; +} + +const nrf_block_dev_ops_t nrf_block_device_empty_ops = { + .init = block_dev_empty_init, + .uninit = block_dev_empty_uninit, + .read_req = block_dev_empty_read_req, + .write_req = block_dev_empty_write_req, + .ioctl = block_dev_empty_ioctl, + .geometry = block_dev_empty_geometry, +}; + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/empty/nrf_block_dev_empty.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/empty/nrf_block_dev_empty.h new file mode 100644 index 0000000000000000000000000000000000000000..b8b38e855f648697527619bcb195658b74dcf0bc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/empty/nrf_block_dev_empty.h @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_BLOCK_DEV_EMPTY_H__ +#define NRF_BLOCK_DEV_EMPTY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf_block_dev.h" + + +/**@file + * + * @defgroup nrf_block_dev_empty Empty implementation + * @ingroup nrf_block_dev + * + * This module implements block device API. It works like: + * - /dev/empty for write operations + * - /dev/zero for read operations + * @{ + * + */ + +/** + * @brief EMPTY block device operations + * */ +extern const nrf_block_dev_ops_t nrf_block_device_empty_ops; + +/** + * @brief Work structure of EMPTY block device. + */ +typedef struct { + nrf_block_dev_geometry_t geometry; //!< Block device geometry + nrf_block_dev_ev_handler ev_handler; //!< Block device event handler + void const * p_context; //!< Context handle passed to event handler +} nrf_block_dev_empty_work_t; + + +/** + * @brief EMPTY block device config initializer (@ref nrf_block_dev_empty_config_t) + * + * @param blk_size Block size + * @param blk_count Block count + * */ +#define NRF_BLOCK_DEV_EMPTY_CONFIG(blk_size, blk_count) { \ + .block_size = (blk_size), \ + .block_count = (blk_count) \ +} + +/** + * @brief EMPTY block device config + */ +typedef struct { + uint32_t block_size; //!< Desired block size + uint32_t block_count; //!< Desired block count +} nrf_block_dev_empty_config_t; + +/** + * @brief EMPTY block device + * */ +typedef struct { + nrf_block_dev_t block_dev; //!< Block device + nrf_block_dev_info_strings_t info_strings; //!< Block device information strings + nrf_block_dev_empty_config_t empty_config; //!< EMPTY block device config + nrf_block_dev_empty_work_t * p_work; //!< EMPTY block device work structure +} nrf_block_dev_empty_t; + +/** + * @brief Defines a EMPTY block device. + * + * @param name Instance name + * @param config Configuration @ref nrf_block_dev_empty_config_t + * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG + * */ +#define NRF_BLOCK_DEV_EMPTY_DEFINE(name, config, info) \ + static nrf_block_dev_empty_work_t CONCAT_2(name, _work); \ + static const nrf_block_dev_empty_t name = { \ + .block_dev = { .p_ops = &nrf_block_device_empty_ops }, \ + .info_strings = BRACKET_EXTRACT(info), \ + .empty_config = config, \ + .p_work = &CONCAT_2(name, _work), \ + } + +/** + * @brief Returns block device API handle from EMPTY block device. + * + * @param[in] p_blk_empty EMPTY block device + * @return Block device handle + */ +static inline nrf_block_dev_t const * +nrf_block_dev_empty_ops_get(nrf_block_dev_empty_t const * p_blk_empty) +{ + return &p_blk_empty->block_dev; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_BLOCK_DEV_EMPTY_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/nrf_block_dev.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/nrf_block_dev.h new file mode 100644 index 0000000000000000000000000000000000000000..7955932c9cd3a0fc70f039c7dc2c1d59693b7092 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/nrf_block_dev.h @@ -0,0 +1,352 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_BLOCK_DEV_H__ +#define NRF_BLOCK_DEV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sdk_common.h" +#include "nrf_assert.h" + +#include + +/**@file + * + * @defgroup nrf_block_dev Block device + * @{ + * @ingroup app_common + * + * @brief This module implements unified block device API. It could used as a middle layer between + * filesystems and memories. + */ + +/** + * @brief Block device request descriptor item. + */ +typedef struct { + uint32_t blk_id; //!< Block ID + uint32_t blk_count; //!< Block count + void * p_buff; //!< Data buffer +} nrf_block_req_t; + + +/** + * @brief Helper macro to create block device read/write request item + * + * @param name Instance name + * @param block_start Block number start + * @param block_count Number of blocks + * @param buff Buffer to read/write + */ +#define NRF_BLOCK_DEV_REQUEST(name, block_start, block_count, buff) \ + nrf_block_req_t name = { \ + .blk_id = block_start, \ + .blk_count = block_count, \ + .p_buff = buff, \ + } +/** + * @brief Block device events. + * + * Events are propagated when event handler is defined (@ref nrf_blk_dev_init) + * + */ +typedef enum { + NRF_BLOCK_DEV_EVT_INIT, /**< Passed to event handler when init is done*/ + NRF_BLOCK_DEV_EVT_UNINIT, /**< Passed to event handler when uninit is done*/ + NRF_BLOCK_DEV_EVT_BLK_READ_DONE, /**< Passed to event handler block read operation is done*/ + NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, /**< Passed to event handler block write operation is done*/ +} nrf_block_dev_event_type_t; + +typedef enum { + NRF_BLOCK_DEV_RESULT_SUCCESS = 0, /**< Operation completed succsefully*/ + NRF_BLOCK_DEV_RESULT_IO_ERROR, /**< I/O error*/ + NRF_BLOCK_DEV_RESULT_TIMEOUT, /**< Device timeout*/ +} nrf_block_dev_result_t; + +/** + * @brief Block device event + * */ +typedef struct { + nrf_block_dev_event_type_t ev_type; //!< Event type + nrf_block_dev_result_t result; //!< Operation status + nrf_block_req_t const * p_blk_req; //!< Block request + void const * p_context; //!< Event context +} nrf_block_dev_event_t; + +struct nrf_block_dev_s; + +/** + * @brief Block device event handler. + * + * @param[in] p_blk_dev Block device handle + * @param[in] p_event Block device event + */ +typedef void (* nrf_block_dev_ev_handler)(struct nrf_block_dev_s const * p_blk_dev, + nrf_block_dev_event_t const * p_event); + +/** + * @brief Block device geometry + */ +typedef struct { + uint32_t blk_count; //!< Block count + uint32_t blk_size; //!< Block size +} nrf_block_dev_geometry_t; + +/** + * @brief Block device information strings + */ +typedef struct { + const char * p_vendor; //!< Vendor string + const char * p_product; //!< Product string + const char * p_revision; //!< Revision string +} nrf_block_dev_info_strings_t; + +/** + * @brief Block device information config + * + * @param vendor Vendor string + * @param product Product string + * @param revision Revision string + * */ +#define NFR_BLOCK_DEV_INFO_CONFIG(vendor, product, revision) ( { \ + .p_vendor = vendor, \ + .p_product = product, \ + .p_revision = revision, \ +}) + +/** + * @brief Empty info string initializer + * */ +#define NFR_BLOCK_DEV_INFO_CONFIG_EMPTY \ + NFR_BLOCK_DEV_INFO_CONFIG(NULL, NULL, NULL) + +/** + * @brief Block device IOCTL requests + */ +typedef enum { + NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH = 0, /**< Cache flush IOCTL request*/ + NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS, /**< Get info strings IOCTL request*/ +} nrf_block_dev_ioctl_req_t; + + +/** + * @brief Helper macro to get block device address from specific instance + * + * @param instance Block device instance + * @param member Block device member name + * */ +#define NRF_BLOCKDEV_BASE_ADDR(instance, member) &(instance).member + +/** + * @brief Block device API + * */ +typedef struct nrf_block_dev_s { + struct nrf_block_dev_ops_s { + /** + * @brief @ref nrf_blk_dev_init + */ + ret_code_t (*init)(struct nrf_block_dev_s const * p_blk_dev, + nrf_block_dev_ev_handler ev_handler, + void const * p_context); + + /** + * @brief @ref nrf_blk_dev_uninit + */ + ret_code_t (*uninit)(struct nrf_block_dev_s const * p_blk_dev); + + /** + * @brief @ref nrf_blk_dev_read_req + */ + ret_code_t (*read_req)(struct nrf_block_dev_s const * p_blk_dev, + nrf_block_req_t const * p_blk); + + /** + * @brief @ref nrf_blk_dev_write_req + */ + ret_code_t (*write_req)(struct nrf_block_dev_s const * p_blk_dev, + nrf_block_req_t const * p_blk); + + /** + * @brief @ref nrf_blk_dev_ioctl + */ + ret_code_t (*ioctl)(struct nrf_block_dev_s const * p_blk_dev, + nrf_block_dev_ioctl_req_t req, + void * p_data); + + /** + * @brief @ref nrf_blk_dev_geometry + */ + nrf_block_dev_geometry_t const * (*geometry)(struct nrf_block_dev_s const * p_blk_dev); + } const * p_ops; +} nrf_block_dev_t; + +/** + * @brief Internals of @ref nrf_block_dev_t + * */ +typedef struct nrf_block_dev_ops_s nrf_block_dev_ops_t; + +/** + * @brief Initializes a block device. + * + * @param[in] p_blk_dev Block device handle + * @param[in] ev_handler Event handler (pass NULL to work in synchronous mode) + * @param[in] p_context Context passed to event handler + * + * @return Standard error code + */ +static inline ret_code_t nrf_blk_dev_init(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ev_handler ev_handler, + void const * p_context) +{ + ASSERT(p_blk_dev->p_ops->init); + return p_blk_dev->p_ops->init(p_blk_dev, ev_handler, p_context); +} + +/** + * @brief Un-initializes a block device. + * + * @param[in] p_blk_dev Block device handle + * + * @return Standard error code + */ +static inline ret_code_t nrf_blk_dev_uninit(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev->p_ops->uninit); + return p_blk_dev->p_ops->uninit(p_blk_dev); +} + +/** + * @brief Block read request. + * + * In synchronous mode this function will execute the read operation + * and wait for its completion. In asynchronous mode the function will only request + * the operation and return immediately. Then, the @ref NRF_BLOCK_DEV_EVT_BLK_READ_DONE + * event will signal that operation has been completed and the specified buffer contains + * valid data. + * + * @param[in] p_blk_dev Block device handle + * @param[in] p_blk Block device request + * + * @return Standard error code + */ +static inline ret_code_t nrf_blk_dev_read_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev->p_ops->read_req); + ASSERT(p_blk_dev->p_ops->geometry); + + if (p_blk->blk_id >= p_blk_dev->p_ops->geometry(p_blk_dev)->blk_count) + { + return NRF_ERROR_INVALID_PARAM; + } + + return p_blk_dev->p_ops->read_req(p_blk_dev, p_blk); +} + +/** + * @brief Block write request. + * + * In synchronous mode this function will execute the write operation + * and wait for its completion. In asynchronous mode the function will only request + * the operation and return immediately. Then, the @ref NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE + * event will signal that operation has been completed and the specified buffer + * can be freed. + * + * @param[in] p_blk_dev Block device handle + * @param[in] p_blk Block device request + * + * @return Standard error code + */ +static inline ret_code_t nrf_blk_dev_write_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev->p_ops->write_req); + ASSERT(p_blk_dev->p_ops->geometry); + + if (p_blk->blk_id >= p_blk_dev->p_ops->geometry(p_blk_dev)->blk_count) + { + return NRF_ERROR_INVALID_PARAM; + } + + return p_blk_dev->p_ops->write_req(p_blk_dev, p_blk); +} + +/** + * @brief IO control function. + * + * @param[in] p_blk_dev Block device handle + * @param[in] req Block device ioctl request + * @param[in] p_data Block device ioctl data + * + * @return Standard error code + * */ +static inline ret_code_t nrf_blk_dev_ioctl(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ioctl_req_t req, + void * p_data) +{ + ASSERT(p_blk_dev->p_ops->ioctl); + return p_blk_dev->p_ops->ioctl(p_blk_dev, req, p_data); +} + +/** + * @brief Return a geometry of a block device. + * + * @param[in] p_blk_dev Block device handle + * + * @return Block size and count @ref nrf_block_dev_geometry_t + */ +static inline nrf_block_dev_geometry_t const * +nrf_blk_dev_geometry(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev->p_ops->geometry); + return p_blk_dev->p_ops->geometry(p_blk_dev); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_BLOCK_DEV_H__ */ + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c new file mode 100644 index 0000000000000000000000000000000000000000..5ca286a6698535b2aea7d24cbd897a251e929b8f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c @@ -0,0 +1,757 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_serial_flash_params.h" +#include "nrf_block_dev_qspi.h" + +/**@file + * + * @ingroup nrf_block_dev_qspi + * @{ + * + * @brief This module implements block device API. It should be used as a reference block device. + */ + +#define QSPI_STD_CMD_WRSR 0x01 /**< Write status register command*/ +#define QSPI_STD_CMD_RSTEN 0x66 /**< Reset enable command*/ +#define QSPI_STD_CMD_RST 0x99 /**< Reset command*/ +#define QSPI_STD_CMD_READ_ID 0x9F /**< Read ID command*/ + +#define BD_PAGE_PROGRAM_SIZE 256 /**< Page program size (minimum block size)*/ + +#define BD_ERASE_UNIT_INVALID_ID 0xFFFFFFFF /**< Invalid erase unit number*/ +#define BD_ERASE_UNIT_ERASE_VAL 0xFFFFFFFF /**< Erased memory value*/ + +/** + * @brief Block to erase unit translation + * + * @param blk_id Block index + * @param blk_size Block size + * */ +#define BD_BLOCK_TO_ERASEUNIT(blk_id, blk_size) \ + ((blk_id) * (blk_size)) / (NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE) + +/** + * @brief Blocks per erase unit + * + * @param blk_size Block size + * */ +#define BD_BLOCKS_PER_ERASEUNIT(blk_size) \ + (NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE / (blk_size)) + + +static ret_code_t block_dev_qspi_eunit_write(nrf_block_dev_qspi_t const * p_qspi_dev, + nrf_block_req_t * p_blk_left); + + +static void block_dev_qspi_read_from_eunit(nrf_block_dev_qspi_t const * p_qspi_dev) +{ + nrf_block_dev_qspi_work_t const * p_work = p_qspi_dev->p_work; + + /*In write-back mode data that we read might not be the same as in erase unit buffer*/ + uint32_t eunit_start = BD_BLOCK_TO_ERASEUNIT(p_work->req.blk_id, + p_work->geometry.blk_size); + + uint32_t eunit_end = BD_BLOCK_TO_ERASEUNIT(p_work->req.blk_id + p_work->req.blk_count, + p_work->geometry.blk_size); + + if ((eunit_start > p_work->erase_unit_idx) || (eunit_end < p_work->erase_unit_idx)) + { + /*Do nothing. Read request doesn't hit current cached erase unit*/ + return; + } + + /*Case 1: Copy data from start erase unit*/ + if (eunit_start == p_work->erase_unit_idx) + { + size_t blk = p_work->req.blk_id % + BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size); + size_t cnt = BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) - blk; + size_t off = p_work->geometry.blk_size * blk; + + if (cnt > p_work->req.blk_count) + { + cnt = p_work->req.blk_count; + } + + memcpy(p_work->req.p_buff, + p_work->p_erase_unit_buff + off, + cnt * p_work->geometry.blk_size); + + return; + } + + /*Case 2: Copy data from end erase unit*/ + if (eunit_end == p_work->erase_unit_idx) + { + size_t cnt = (p_work->req.blk_id + p_work->req.blk_count) % + BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size); + size_t off = (p_work->erase_unit_idx * BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) - + p_work->req.blk_id) * p_work->geometry.blk_size; + + if (cnt > p_work->req.blk_count) + { + cnt = p_work->req.blk_count; + } + + memcpy((uint8_t *)p_work->req.p_buff + off, + p_work->p_erase_unit_buff, + cnt * p_work->geometry.blk_size); + + return; + } + + /*Case 3: Copy data from eunit_start < p_work->erase_unit_idx < eunit_end*/ + size_t off = (p_work->erase_unit_idx * BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) - + p_work->req.blk_id) * p_work->geometry.blk_size; + + memcpy((uint8_t *)p_work->req.p_buff + off, + p_work->p_erase_unit_buff, + NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE); +} + +/** + * @brief Active QSPI block device handle. Only one instance. + * */ +static nrf_block_dev_qspi_t const * m_active_qspi_dev; + +static void qspi_handler(nrf_drv_qspi_evt_t event, void * p_context) +{ + if (m_active_qspi_dev != p_context) + { + return; + } + + nrf_block_dev_qspi_t const * p_qspi_dev = p_context; + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + nrf_block_req_t * p_blk_left = &p_work->left_req; + + switch (p_work->state) + { + case NRF_BLOCK_DEV_QSPI_STATE_READ_EXEC: + { + if (p_work->writeback_mode) + { + block_dev_qspi_read_from_eunit(p_qspi_dev); + } + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE; + if (p_work->ev_handler) + { + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_READ_DONE, + NRF_BLOCK_DEV_RESULT_SUCCESS, + &p_work->req, + p_work->p_context + }; + + p_work->ev_handler(&p_qspi_dev->block_dev, &ev); + } + + break; + } + case NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD: + { + ret_code_t ret; + uint32_t erase_unit = BD_BLOCK_TO_ERASEUNIT(p_blk_left->blk_id, + p_work->geometry.blk_size); + UNUSED_VARIABLE(erase_unit); + ASSERT(erase_unit == p_work->erase_unit_idx); + + /* Check if block is in erase unit buffer*/ + ret = block_dev_qspi_eunit_write(p_qspi_dev, p_blk_left); + ASSERT(ret == NRF_SUCCESS); + UNUSED_VARIABLE(ret); + break; + } + case NRF_BLOCK_DEV_QSPI_STATE_WRITE_ERASE: + case NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC: + { + /*Clear last programmed block*/ + uint32_t block_to_program = __CLZ(__RBIT(p_work->erase_unit_dirty_blocks)); + + if (p_work->state == NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC) + { + p_work->erase_unit_dirty_blocks ^= 1u << block_to_program; + } + + if (p_work->erase_unit_dirty_blocks == 0) + { + if (p_work->left_req.blk_count) + { + /*Load next erase unit*/ + ret_code_t ret; + uint32_t eunit = BD_BLOCK_TO_ERASEUNIT(p_blk_left->blk_id, + p_work->geometry.blk_size); + + p_work->erase_unit_idx = eunit; + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD; + + ret = nrf_drv_qspi_read(p_work->p_erase_unit_buff, + NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE, + p_work->erase_unit_idx * + NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE); + UNUSED_VARIABLE(ret); + + break; + } + + /*All blocks are programmed. Call event handler if required.*/ + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE; + if (p_work->ev_handler && !p_work->cache_flushing) + { + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, + NRF_BLOCK_DEV_RESULT_SUCCESS, + &p_work->req, + p_work->p_context + }; + + p_work->ev_handler(&p_qspi_dev->block_dev, &ev); + } + + p_work->cache_flushing = false; + break; + } + + /*Get next block to program from program mask*/ + block_to_program = __CLZ(__RBIT(p_work->erase_unit_dirty_blocks)); + uint32_t dst_address = (p_work->erase_unit_idx * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE) + + (block_to_program * p_work->geometry.blk_size); + + const void * p_src_address = p_work->p_erase_unit_buff + + block_to_program * p_work->geometry.blk_size; + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC; + ret_code_t ret = nrf_drv_qspi_write(p_src_address, + p_work->geometry.blk_size, + dst_address); + UNUSED_VARIABLE(ret); + break; + } + default: + ASSERT(0); + break; + } +} + +static void wait_for_idle(nrf_block_dev_qspi_t const * p_qspi_dev) +{ + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + while (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE) + { + __WFI(); + } +} + +static ret_code_t block_dev_qspi_init(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ev_handler ev_handler, + void const * p_context) +{ + ASSERT(p_blk_dev); + nrf_block_dev_qspi_t const * p_qspi_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev); + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + nrf_drv_qspi_config_t const * p_qspi_cfg = &p_qspi_dev->qspi_bdev_config.qspi_config; + + ret_code_t ret = NRF_SUCCESS; + + if (p_qspi_dev->qspi_bdev_config.block_size % BD_PAGE_PROGRAM_SIZE) + { + /*Unsupported block size*/ + return NRF_ERROR_NOT_SUPPORTED; + } + + if (NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE % p_qspi_dev->qspi_bdev_config.block_size) + { + /*Unsupported block size*/ + return NRF_ERROR_NOT_SUPPORTED; + } + + if (m_active_qspi_dev) + { + /* QSPI instance is BUSY*/ + return NRF_ERROR_BUSY; + } + + ret = nrf_drv_qspi_init(p_qspi_cfg, qspi_handler, (void *)p_blk_dev); + if (ret != NRF_SUCCESS) + { + return ret; + } + + nrf_qspi_cinstr_conf_t cinstr_cfg = { + .opcode = QSPI_STD_CMD_RSTEN, + .length = NRF_QSPI_CINSTR_LEN_1B, + .io2_level = true, + .io3_level = true, + .wipwait = true, + .wren = true + }; + + /* Send reset enable */ + ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); + if (ret != NRF_SUCCESS) + { + return ret; + } + + /* Send reset command */ + cinstr_cfg.opcode = QSPI_STD_CMD_RST; + ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); + if (ret != NRF_SUCCESS) + { + return ret; + } + + /* Get 3 byte identification value */ + uint8_t rdid_buf[3] = {0, 0, 0}; + cinstr_cfg.opcode = QSPI_STD_CMD_READ_ID; + cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_4B; + ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, rdid_buf); + if (ret != NRF_SUCCESS) + { + return ret; + } + + nrf_serial_flash_params_t const * serial_flash_id = nrf_serial_flash_params_get(rdid_buf); + + if (!serial_flash_id) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if (serial_flash_id->erase_size != NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + /* Calculate block device geometry.... */ + uint32_t blk_size = p_qspi_dev->qspi_bdev_config.block_size; + uint32_t blk_count = serial_flash_id->size / p_qspi_dev->qspi_bdev_config.block_size; + + if (!blk_count || (blk_count % BD_BLOCKS_PER_ERASEUNIT(blk_size))) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + p_work->geometry.blk_size = blk_size; + p_work->geometry.blk_count = blk_count; + p_work->p_context = p_context; + p_work->ev_handler = ev_handler; + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE; + p_work->erase_unit_idx = BD_ERASE_UNIT_INVALID_ID; + p_work->writeback_mode = (p_qspi_dev->qspi_bdev_config.flags & + NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK) != 0; + m_active_qspi_dev = p_qspi_dev; + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_INIT, + NRF_BLOCK_DEV_RESULT_SUCCESS, + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return NRF_SUCCESS; +} + +static ret_code_t block_dev_qspi_uninit(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_qspi_t const * p_qspi_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev); + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + if (m_active_qspi_dev != p_qspi_dev) + { + /* QSPI instance is BUSY*/ + return NRF_ERROR_BUSY; + } + + if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE) + { + /* Previous asynchronous operation in progress*/ + return NRF_ERROR_BUSY; + } + + if (p_work->ev_handler) + { + /*Asynchronous operation*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_UNINIT, + NRF_BLOCK_DEV_RESULT_SUCCESS, + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_DISABLED; + nrf_drv_qspi_uninit(); + + memset(p_work, 0, sizeof(nrf_block_dev_qspi_work_t)); + m_active_qspi_dev = NULL; + return NRF_SUCCESS; +} + +static ret_code_t block_dev_qspi_read_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_qspi_t const * p_qspi_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev); + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + ret_code_t ret = NRF_SUCCESS; + + if (m_active_qspi_dev != p_qspi_dev) + { + /* QSPI instance is BUSY*/ + return NRF_ERROR_BUSY; + } + + if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE) + { + /* Previous asynchronous operation in progress*/ + return NRF_ERROR_BUSY; + } + + p_work->left_req = *p_blk; + p_work->req = *p_blk; + nrf_block_req_t * p_blk_left = &p_work->left_req; + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_READ_EXEC; + ret = nrf_drv_qspi_read(p_blk_left->p_buff, + p_blk_left->blk_count * p_work->geometry.blk_size, + p_blk_left->blk_id * p_work->geometry.blk_size); + + if (ret != NRF_SUCCESS) + { + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE; + return ret; + } + + p_blk_left->p_buff = NULL; + p_blk_left->blk_count = 0; + + if (!p_work->ev_handler && (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)) + { + /*Synchronous operation*/ + wait_for_idle(p_qspi_dev); + } + + return ret; +} + +static bool block_dev_qspi_update_eunit(nrf_block_dev_qspi_t const * p_qspi_dev, + size_t off, + const void * p_src, + size_t len) +{ + ASSERT((len % sizeof(uint32_t)) == 0) + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + uint32_t * p_dst32 = (uint32_t *)(p_work->p_erase_unit_buff + off); + const uint32_t * p_src32 = p_src; + + bool erase_required = false; + len /= sizeof(uint32_t); + + /*Do normal copying until erase unit is not required*/ + do + { + if (*p_dst32 != *p_src32) + { + if (*p_dst32 != BD_ERASE_UNIT_ERASE_VAL) + { + erase_required = true; + } + + /*Mark block as dirty*/ + p_work->erase_unit_dirty_blocks |= 1u << (off / p_work->geometry.blk_size); + } + + *p_dst32++ = *p_src32++; + off += sizeof(uint32_t); + } while (--len); + + return erase_required; +} + +static ret_code_t block_dev_qspi_write_start(nrf_block_dev_qspi_t const * p_qspi_dev) +{ + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + if (!p_work->erase_required) + { + /*Get first block to program from program mask*/ + uint32_t block_to_program = __CLZ(__RBIT(p_work->erase_unit_dirty_blocks)); + uint32_t dst_address = (p_work->erase_unit_idx * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE) + + (block_to_program * p_work->geometry.blk_size); + + const void * p_src_address = p_work->p_erase_unit_buff + + block_to_program * p_work->geometry.blk_size; + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC; + return nrf_drv_qspi_write(p_src_address, + p_work->geometry.blk_size, + dst_address); + } + + /*Erase is required*/ + uint32_t address = (p_work->erase_unit_idx * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE); + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_WRITE_ERASE; + p_work->erase_required = false; + + return nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, address); +} + +static ret_code_t block_dev_qspi_eunit_write(nrf_block_dev_qspi_t const * p_qspi_dev, + nrf_block_req_t * p_blk_left) +{ + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + size_t blk = p_blk_left->blk_id % + BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size); + size_t cnt = BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) - blk; + size_t off = p_work->geometry.blk_size * blk; + + if (cnt > p_blk_left->blk_count) + { + cnt = p_blk_left->blk_count; + } + + bool erase_required = block_dev_qspi_update_eunit(p_qspi_dev, + off, + p_blk_left->p_buff, + cnt * p_work->geometry.blk_size); + if (erase_required) + { + p_work->erase_required = true; + } + + p_blk_left->blk_count -= cnt; + p_blk_left->blk_id += cnt; + p_blk_left->p_buff = (uint8_t *)p_blk_left->p_buff + cnt * p_work->geometry.blk_size; + + if (p_work->erase_required) + { + uint32_t blk_size = p_work->geometry.blk_size; + p_work->erase_unit_dirty_blocks |= (1u << BD_BLOCKS_PER_ERASEUNIT(blk_size)) - 1; + } + + if (p_work->erase_unit_dirty_blocks == 0 || p_work->writeback_mode) + { + /*No dirty blocks detected. Write end.*/ + if (p_work->ev_handler && p_blk_left->blk_count == 0) + { + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, + NRF_BLOCK_DEV_RESULT_SUCCESS, + &p_work->req, + p_work->p_context + }; + + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE; + p_work->ev_handler(&p_qspi_dev->block_dev, &ev); + return NRF_SUCCESS; + } + } + + return block_dev_qspi_write_start(p_qspi_dev); +} + +static ret_code_t block_dev_qspi_write_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_qspi_t const * p_qspi_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev); + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + ret_code_t ret = NRF_SUCCESS; + + if (m_active_qspi_dev != p_qspi_dev) + { + /* QSPI instance is BUSY*/ + return NRF_ERROR_BUSY; + } + + if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE) + { + /* Previous asynchronous operation in progress*/ + return NRF_ERROR_BUSY; + } + + p_work->left_req = *p_blk; + p_work->req = *p_blk; + + nrf_block_req_t * p_blk_left = &p_work->left_req; + + uint32_t erase_unit = BD_BLOCK_TO_ERASEUNIT(p_blk_left->blk_id, + p_work->geometry.blk_size); + + /* Check if block is in erase unit buffer*/ + if (erase_unit == p_work->erase_unit_idx) + { + ret = block_dev_qspi_eunit_write(p_qspi_dev, p_blk_left); + } + else + { + if (p_work->writeback_mode) + { + ret = block_dev_qspi_write_start(p_qspi_dev); + } + else + { + p_work->erase_unit_idx = erase_unit; + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD; + + ret = nrf_drv_qspi_read(p_work->p_erase_unit_buff, + NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE, + erase_unit * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE); + } + } + + if (ret != NRF_SUCCESS) + { + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE; + return ret; + } + + if (!p_work->ev_handler && (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)) + { + /*Synchronous operation*/ + wait_for_idle(p_qspi_dev); + } + + return ret; +} + +static ret_code_t block_dev_qspi_ioctl(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ioctl_req_t req, + void * p_data) +{ + ASSERT(p_blk_dev); + nrf_block_dev_qspi_t const * p_qspi_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev); + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + switch (req) + { + case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH: + { + bool * p_flushing = p_data; + if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE) + { + return NRF_ERROR_BUSY; + } + + if (!p_work->writeback_mode || p_work->erase_unit_dirty_blocks == 0) + { + if (p_flushing) + { + *p_flushing = false; + } + + return NRF_SUCCESS; + } + + ret_code_t ret = block_dev_qspi_write_start(p_qspi_dev); + if (ret == NRF_SUCCESS) + { + if (p_flushing) + { + *p_flushing = true; + } + p_work->cache_flushing = true; + } + + return ret; + } + case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS: + { + if (p_data == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + nrf_block_dev_info_strings_t const * * pp_strings = p_data; + *pp_strings = &p_qspi_dev->info_strings; + return NRF_SUCCESS; + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +static nrf_block_dev_geometry_t const * block_dev_qspi_geometry(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_qspi_t const * p_qspi_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev); + nrf_block_dev_qspi_work_t const * p_work = p_qspi_dev->p_work; + + return &p_work->geometry; +} + +const nrf_block_dev_ops_t nrf_block_device_qspi_ops = { + .init = block_dev_qspi_init, + .uninit = block_dev_qspi_uninit, + .read_req = block_dev_qspi_read_req, + .write_req = block_dev_qspi_write_req, + .ioctl = block_dev_qspi_ioctl, + .geometry = block_dev_qspi_geometry, +}; + + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h new file mode 100644 index 0000000000000000000000000000000000000000..e3f9bbfa186877592cbc4e91e1a596d98f3ba206 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h @@ -0,0 +1,172 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_BLOCK_DEV_QSPI_H__ +#define NRF_BLOCK_DEV_QSPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf_block_dev.h" +#include "nrf_drv_qspi.h" + +/**@file + * + * @defgroup nrf_block_dev_qspi QSPI implementation + * @ingroup nrf_block_dev + * @{ + * + */ + +/** + * @brief QSPI block device operations + * */ +extern const nrf_block_dev_ops_t nrf_block_device_qspi_ops; + +/** + * @brief QSPI block device internal erase unit buffer size + * */ +#define NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE (4096) + +/** + * @brief Internal Block device state + */ +typedef enum { + NRF_BLOCK_DEV_QSPI_STATE_DISABLED = 0, /**< QSPI block device state DISABLED */ + NRF_BLOCK_DEV_QSPI_STATE_IDLE, /**< QSPI block device state IDLE */ + NRF_BLOCK_DEV_QSPI_STATE_READ_EXEC, /**< QSPI block device state READ_EXEC */ + NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD, /**< QSPI block device state EUNIT_LOAD */ + NRF_BLOCK_DEV_QSPI_STATE_WRITE_ERASE, /**< QSPI block device state WRITE_ERASE */ + NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC, /**< QSPI block device state WRITE_EXEC */ +} nrf_block_dev_qspi_state_t; + +/** + * @brief Work structure of QSPI block device + */ +typedef struct { + volatile nrf_block_dev_qspi_state_t state; //!< QSPI block device state + + nrf_block_dev_geometry_t geometry; //!< Block device geometry + nrf_block_dev_ev_handler ev_handler; //!< Block device event handler + void const * p_context; //!< Context handle passed to event handler + nrf_block_req_t req; //!< Block READ/WRITE request: original value + nrf_block_req_t left_req; //!< Block READ/WRITE request: left value + + bool cache_flushing; //!< QSPI cache flush in progress flag + bool writeback_mode; //!< QSPI write-back mode flag + bool erase_required; //!< QSPI erase required flag + uint32_t erase_unit_idx; //!< QSPI erase unit index + uint32_t erase_unit_dirty_blocks; //!< QSPI erase unit dirty blocks mask + uint8_t p_erase_unit_buff[NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE]; //!< QSPI erase unit buffer (fixed value) +} nrf_block_dev_qspi_work_t; + +/** + * @brief QSPI block device flags*/ +typedef enum { + NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK = (1u << 0) //!< Cache write-back mode enable flag +} nrf_block_dev_qspi_flag_t; + +/** + * @brief QSPI block device config initializer (@ref nrf_block_dev_qspi_config_t) + * + * @param blk_size Block size + * @param blk_flags Block device flags, @ref nrf_block_dev_qspi_flag_t + * @param qspi_drv_config QPSI driver config + * */ +#define NRF_BLOCK_DEV_QSPI_CONFIG(blk_size, blk_flags, qspi_drv_config) { \ + .block_size = (blk_size), \ + .flags = (blk_flags), \ + .qspi_config = qspi_drv_config \ +} + +/** + * @brief QSPI block device config + */ +typedef struct { + uint32_t block_size; //!< Desired block size + uint32_t flags; //!< QSPI block device flags + nrf_drv_qspi_config_t qspi_config; //!< QSPI configuration +} nrf_block_dev_qspi_config_t; + +/** + * @brief QSPI block device + * */ +typedef struct { + nrf_block_dev_t block_dev; //!< Block device + nrf_block_dev_info_strings_t info_strings; //!< Block device information strings + nrf_block_dev_qspi_config_t qspi_bdev_config; //!< QSPI block device config + nrf_block_dev_qspi_work_t * p_work; //!< QSPI block device work structure +} nrf_block_dev_qspi_t; + +/** + * @brief Defines a QSPI block device. + * + * @param name Instance name + * @param config Configuration @ref nrf_block_dev_qspi_config_t + * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG + * */ +#define NRF_BLOCK_DEV_QSPI_DEFINE(name, config, info) \ + static nrf_block_dev_qspi_work_t CONCAT_2(name, _work); \ + static const nrf_block_dev_qspi_t name = { \ + .block_dev = { .p_ops = &nrf_block_device_qspi_ops }, \ + .info_strings = BRACKET_EXTRACT(info), \ + .qspi_bdev_config = config, \ + .p_work = &CONCAT_2(name, _work), \ + } + +/** + * @brief Returns block device API handle from QSPI block device. + * + * @param[in] p_blk_qspi QSPI block device + * @return Block device handle + */ +static inline nrf_block_dev_t const * +nrf_block_dev_qspi_ops_get(nrf_block_dev_qspi_t const * p_blk_qspi) +{ + return &p_blk_qspi->block_dev; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_BLOCK_DEV_QSPI_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/qspi/nrf_serial_flash_params.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/qspi/nrf_serial_flash_params.c new file mode 100644 index 0000000000000000000000000000000000000000..28bbdd2e8e7cdec4673dfeb92c372ce897d68e46 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/qspi/nrf_serial_flash_params.c @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_serial_flash_params.h" + +static const nrf_serial_flash_params_t m_sflash_params[] = { + { /*MXIC MX25R6435F*/ + .read_id = { 0xC2, 0x28, 0x17 }, + .capabilities = 0x00, + .size = 8 * 1024 * 1024, + .erase_size = 4 * 1024, + .program_size = 256, + } +}; + +nrf_serial_flash_params_t const * nrf_serial_flash_params_get(const uint8_t * p_read_id) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(m_sflash_params); ++i) + { + if (memcmp(m_sflash_params[i].read_id, p_read_id, sizeof(m_sflash_params[i].read_id)) == 0) + { + return &m_sflash_params[i]; + } + } + + return NULL; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/qspi/nrf_serial_flash_params.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/qspi/nrf_serial_flash_params.h new file mode 100644 index 0000000000000000000000000000000000000000..eec6d6c5c8a17d709f6df30a961392f392a5c6b0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/qspi/nrf_serial_flash_params.h @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SERIAL_FLASH_PARAMS_H__ +#define NRF_SERIAL_FLASH_PARAMS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sdk_common.h" + +/**@file + * + * @defgroup nrf_serial_flash_params Serial flash memory parameters + * @ingroup nrf_block_dev + * @{ + * + */ + +/** + * @brief Serial flash memory parameters + * */ +typedef struct { + uint8_t read_id[3]; //!< Read identification command (0x9F) result + uint8_t capabilities; //!< Serial flash memory capabilities + uint32_t size; //!< Serial flash memory size (bytes) + uint32_t erase_size; //!< Serial flash memory erase unit size (bytes) + uint32_t program_size; //!< Serial flash memory program size (bytes) +} nrf_serial_flash_params_t; + + +/** + * @brief Returns serial flash memory identification descriptor + * + * @param p_read_params Memory read identification command result + * + * @return Serial flash memory descriptor (NULL if not found) + * */ +nrf_serial_flash_params_t const * nrf_serial_flash_params_get(const uint8_t * p_read_params); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SERIAL_FLASH_PARAMS_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/ram/nrf_block_dev_ram.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/ram/nrf_block_dev_ram.c new file mode 100644 index 0000000000000000000000000000000000000000..ba834a1b38a309197b237eb64bc7b8cf96ca360b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/ram/nrf_block_dev_ram.c @@ -0,0 +1,205 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_block_dev_ram.h" + +/**@file + * + * @ingroup nrf_block_dev + * @{ + * + * @brief This module implements block device API. It should be used as a reference block device. + */ + +static ret_code_t block_dev_ram_init(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ev_handler ev_handler, + void const * p_context) +{ + ASSERT(p_blk_dev); + nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev); + nrf_block_dev_ram_work_t * p_work = p_ram_dev->p_work; + + /* Calculate block device geometry.... */ + p_work->geometry.blk_size = p_ram_dev->ram_config.block_size; + p_work->geometry.blk_count = p_ram_dev->ram_config.size / + p_ram_dev->ram_config.block_size; + p_work->p_context = p_context; + p_work->ev_handler = ev_handler; + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_INIT, + NRF_BLOCK_DEV_RESULT_SUCCESS, + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return NRF_SUCCESS; +} + +static ret_code_t block_dev_ram_uninit(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev); + nrf_block_dev_ram_work_t * p_work = p_ram_dev->p_work; + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_UNINIT, + NRF_BLOCK_DEV_RESULT_SUCCESS, + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + memset(p_work, 0, sizeof(nrf_block_dev_ram_work_t)); + return NRF_SUCCESS; +} + +static ret_code_t block_dev_ram_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk, + nrf_block_dev_event_type_t event) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev); + nrf_block_dev_ram_config_t const * p_ram_config = &p_ram_dev->ram_config; + nrf_block_dev_ram_work_t const * p_work = p_ram_dev->p_work; + + /*Synchronous operation*/ + uint8_t * p_buff = p_ram_config->p_work_buffer; + p_buff += p_blk->blk_id * p_work->geometry.blk_size; + + const void * p_src = (event == NRF_BLOCK_DEV_EVT_BLK_READ_DONE) ? p_buff : p_blk->p_buff; + void * p_dst = (event == NRF_BLOCK_DEV_EVT_BLK_READ_DONE) ? p_blk->p_buff : p_buff; + + memcpy(p_dst, p_src, p_work->geometry.blk_size * p_blk->blk_count); + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + event, + NRF_BLOCK_DEV_RESULT_SUCCESS, + p_blk, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return NRF_SUCCESS; +} + +static ret_code_t block_dev_ram_read_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + return block_dev_ram_req(p_blk_dev, p_blk, NRF_BLOCK_DEV_EVT_BLK_READ_DONE); +} + +static ret_code_t block_dev_ram_write_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + return block_dev_ram_req(p_blk_dev, p_blk, NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE); +} + +static ret_code_t block_dev_ram_ioctl(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ioctl_req_t req, + void * p_data) +{ + nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev); + switch (req) + { + case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH: + { + bool * p_flushing = p_data; + if (p_flushing) + { + *p_flushing = false; + } + return NRF_SUCCESS; + } + case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS: + { + if (p_data == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + nrf_block_dev_info_strings_t const * * pp_strings = p_data; + *pp_strings = &p_ram_dev->info_strings; + return NRF_SUCCESS; + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + + +static nrf_block_dev_geometry_t const * block_dev_ram_geometry(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev); + nrf_block_dev_ram_work_t const * p_work = p_ram_dev->p_work; + + return &p_work->geometry; +} + +const nrf_block_dev_ops_t nrf_block_device_ram_ops = { + .init = block_dev_ram_init, + .uninit = block_dev_ram_uninit, + .read_req = block_dev_ram_read_req, + .write_req = block_dev_ram_write_req, + .ioctl = block_dev_ram_ioctl, + .geometry = block_dev_ram_geometry, +}; + + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/ram/nrf_block_dev_ram.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/ram/nrf_block_dev_ram.h new file mode 100644 index 0000000000000000000000000000000000000000..c860f9ae15a26ed39ff851d7ecb0b05edf3eb491 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/ram/nrf_block_dev_ram.h @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_BLOCK_DEV_RAM_H__ +#define NRF_BLOCK_DEV_RAM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf_block_dev.h" + +/**@file + * + * @defgroup nrf_block_dev_ram RAM implementation + * @ingroup nrf_block_dev + * @{ + + * + * @brief This module implements block device API. It should be used as a reference block device. + */ + +/** + * @brief RAM block device operations + * */ +extern const nrf_block_dev_ops_t nrf_block_device_ram_ops; + +/** + * @brief Work structure of RAM block device + */ +typedef struct { + nrf_block_dev_geometry_t geometry; //!< Block device geometry + nrf_block_dev_ev_handler ev_handler; //!< Block device event handler + void const * p_context; //!< Context handle passed to event handler +} nrf_block_dev_ram_work_t; + + +/** + * @brief RAM block device config initializer (@ref nrf_block_dev_ram_config_t) + * + * @param blk_size Block size + * @param buffer RAM work buffer + * @param buffer_size RAM work buffer size + * */ +#define NRF_BLOCK_DEV_RAM_CONFIG(blk_size, buffer, buffer_size) { \ + .block_size = (blk_size), \ + .p_work_buffer = (buffer), \ + .size = (buffer_size), \ +} + +/** + * @brief Ram block device config + */ +typedef struct { + uint32_t block_size; //!< Desired block size + void * p_work_buffer; //!< Ram work buffer + size_t size; //!< Ram work buffer size +} nrf_block_dev_ram_config_t; + +/** + * @brief Ram block device + * */ +typedef struct { + nrf_block_dev_t block_dev; //!< Block device + nrf_block_dev_info_strings_t info_strings; //!< Block device information strings + nrf_block_dev_ram_config_t ram_config; //!< Ram block device config + nrf_block_dev_ram_work_t * p_work; //!< Ram block device work structure +} nrf_block_dev_ram_t; + +/** + * @brief Defines a RAM block device. + * + * @param name Instance name + * @param config Configuration @ref nrf_block_dev_ram_config_t + * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG + * */ +#define NRF_BLOCK_DEV_RAM_DEFINE(name, config, info) \ + static nrf_block_dev_ram_work_t CONCAT_2(name, _work); \ + static const nrf_block_dev_ram_t name = { \ + .block_dev = { .p_ops = &nrf_block_device_ram_ops }, \ + .info_strings = BRACKET_EXTRACT(info), \ + .ram_config = config, \ + .p_work = &CONCAT_2(name, _work), \ + } + +/** + * @brief Returns block device API handle from RAM block device. + * + * @param[in] p_blk_ram Ram block device + * @return Block device handle + */ +static inline nrf_block_dev_t const * +nrf_block_dev_ram_ops_get(nrf_block_dev_ram_t const * p_blk_ram) +{ + return &p_blk_ram->block_dev; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_BLOCK_DEV_RAM_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c new file mode 100644 index 0000000000000000000000000000000000000000..3b02bc604eed615ad334ab5b079cec970feb4b30 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c @@ -0,0 +1,392 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_block_dev_sdc.h" + +/**@file + * + * @ingroup nrf_block_dev_sdc + * @{ + * + * @brief This module implements block device API. It should be used as a reference block device. + */ + + +static volatile sdc_result_t m_last_result; + + +/** + * @brief Active SDC block device handle. Only one instance. + * */ +static nrf_block_dev_sdc_t const * m_active_sdc_dev; + + + +static void wait_func(void) +{ +} + +static void sdc_wait() +{ + while (app_sdc_busy_check()) + { + wait_func(); + } +} + + +static void sdc_handler(sdc_evt_t const * p_event) +{ + m_last_result = p_event->result; + nrf_block_dev_sdc_t const * p_sdc_dev = m_active_sdc_dev; + nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work; + + switch (p_event->type) + { + case SDC_EVT_INIT: + { + p_work->geometry.blk_count = app_sdc_info_get()->num_blocks; + p_work->geometry.blk_size = SDC_SECTOR_SIZE; + if (m_active_sdc_dev->p_work->ev_handler) + { + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_INIT, + ((p_event->result == SDC_SUCCESS) ? \ + NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR), + NULL, + p_work->p_context + }; + p_work->ev_handler(&p_sdc_dev->block_dev, &ev); + } + } + break; + + case SDC_EVT_READ: + if (m_active_sdc_dev->p_work->ev_handler) + { + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_READ_DONE, + ((p_event->result == SDC_SUCCESS) ? \ + NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR), + &p_work->req, + p_work->p_context + }; + p_work->ev_handler(&p_sdc_dev->block_dev, &ev); + } + break; + + case SDC_EVT_WRITE: + if (m_active_sdc_dev->p_work->ev_handler) + { + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, + ((p_event->result == SDC_SUCCESS) ? \ + NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR), + &p_work->req, + p_work->p_context + }; + p_work->ev_handler(&p_sdc_dev->block_dev, &ev); + } + break; + + default: + APP_ERROR_CHECK(NRF_ERROR_INTERNAL); + return; + } +} + + +static ret_code_t block_dev_sdc_init(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ev_handler ev_handler, + void const * p_context) +{ + ASSERT(p_blk_dev); + nrf_block_dev_sdc_t const * p_sdc_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev); + nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work; + + if (p_sdc_dev->sdc_bdev_config.block_size != SDC_SECTOR_SIZE) + { + /* Unsupported block size. */ + return NRF_ERROR_NOT_SUPPORTED; + } + + if (m_active_sdc_dev) + { + /* SDC instance is busy. */ + return NRF_ERROR_BUSY; + } + + p_work->p_context = p_context; + p_work->ev_handler = ev_handler; + m_active_sdc_dev = p_sdc_dev; + + ret_code_t err_code = NRF_SUCCESS; + + err_code = app_sdc_init(&p_sdc_dev->sdc_bdev_config.sdc_config, sdc_handler); + if (err_code == NRF_SUCCESS) + { + if (!ev_handler) + { + /* Synchronous mode - wait for the card. */ + sdc_wait(); + err_code = ((m_last_result == SDC_SUCCESS) ? NRF_SUCCESS : NRF_ERROR_TIMEOUT); + } + } + + if (err_code != NRF_SUCCESS) + { + m_active_sdc_dev = NULL; + + if (ev_handler) + { + /* Call the user handler with an error status. */ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_INIT, + NRF_BLOCK_DEV_RESULT_IO_ERROR, + NULL, + p_work->p_context + }; + p_work->ev_handler(p_blk_dev, &ev); + } + } + + return err_code; +} + +static ret_code_t block_dev_sdc_uninit(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_sdc_t const * p_sdc_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev); + nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work; + + if (m_active_sdc_dev != p_sdc_dev) + { + /* SDC instance is busy. */ + return NRF_ERROR_BUSY; + } + + if (app_sdc_busy_check()) + { + /* Previous asynchronous operation in progress. */ + return NRF_ERROR_BUSY; + } + + ret_code_t err_code = app_sdc_uninit(); + if (err_code == NRF_SUCCESS) + { + /* Free the instance on success. */ + m_active_sdc_dev = NULL; + } + + if (p_work->ev_handler) + { + /* SDC uninitialization is a synchronous operation. Call event handler. */ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_UNINIT, + ((err_code == NRF_SUCCESS) ? \ + NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR), + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return err_code; +} + +static ret_code_t block_dev_sdc_read_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_sdc_t const * p_sdc_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev); + nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work; + + ret_code_t err_code = NRF_SUCCESS; + + if (m_active_sdc_dev != p_sdc_dev) + { + /* SDC instance is busy. */ + return NRF_ERROR_BUSY; + } + + if (app_sdc_busy_check()) + { + /* Previous asynchronous operation in progress. */ + return NRF_ERROR_BUSY; + } + + p_work->req = *p_blk; + err_code = app_sdc_block_read(p_blk->p_buff, p_blk->blk_id, p_blk->blk_count); + if (err_code == NRF_SUCCESS) + { + if (!p_work->ev_handler) + { + /* Synchronous mode - wait for the card. */ + sdc_wait(); + err_code = ((m_last_result == SDC_SUCCESS) ? NRF_SUCCESS : NRF_ERROR_TIMEOUT); + } + } + + if ((p_work->ev_handler) && (err_code != NRF_SUCCESS)) + { + /* Call the user handler with an error status. */ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_READ_DONE, + NRF_BLOCK_DEV_RESULT_IO_ERROR, + &p_work->req, + p_work->p_context + }; + p_work->ev_handler(p_blk_dev, &ev); + } + + return err_code; +} + +static ret_code_t block_dev_sdc_write_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_sdc_t const * p_sdc_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev); + nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work; + + ret_code_t err_code = NRF_SUCCESS; + + if (m_active_sdc_dev != p_sdc_dev) + { + /* SDC instance is busy. */ + return NRF_ERROR_BUSY; + } + + if (app_sdc_busy_check()) + { + /* Previous asynchronous operation in progress. */ + return NRF_ERROR_BUSY; + } + + p_work->req = *p_blk; + err_code = app_sdc_block_write(p_blk->p_buff, p_blk->blk_id, p_blk->blk_count); + if (err_code == NRF_SUCCESS) + { + if (!p_work->ev_handler) + { + /* Synchronous mode - wait for the card. */ + sdc_wait(); + err_code = ((m_last_result == SDC_SUCCESS) ? NRF_SUCCESS : NRF_ERROR_TIMEOUT); + } + } + + if ((p_work->ev_handler) && (err_code != NRF_SUCCESS)) + { + /* Call the user handler with an error status. */ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_READ_DONE, + NRF_BLOCK_DEV_RESULT_IO_ERROR, + &p_work->req, + p_work->p_context + }; + p_work->ev_handler(p_blk_dev, &ev); + } + + return err_code; +} + +static ret_code_t block_dev_sdc_ioctl(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ioctl_req_t req, + void * p_data) +{ + nrf_block_dev_sdc_t const * p_sdc_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev); + switch (req) + { + case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH: + { + bool * p_flushing = p_data; + if (p_flushing) + { + *p_flushing = false; + } + return NRF_SUCCESS; + } + case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS: + { + if (p_data == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + nrf_block_dev_info_strings_t const * * pp_strings = p_data; + *pp_strings = &p_sdc_dev->info_strings; + return NRF_SUCCESS; + } + default: + break; + } + + + return NRF_ERROR_NOT_SUPPORTED; +} + +static nrf_block_dev_geometry_t const * block_dev_sdc_geometry(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_sdc_t const * p_sdc_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev); + nrf_block_dev_sdc_work_t const * p_work = p_sdc_dev->p_work; + + return &p_work->geometry; +} + +const nrf_block_dev_ops_t nrf_block_device_sdc_ops = { + .init = block_dev_sdc_init, + .uninit = block_dev_sdc_uninit, + .read_req = block_dev_sdc_read_req, + .write_req = block_dev_sdc_write_req, + .ioctl = block_dev_sdc_ioctl, + .geometry = block_dev_sdc_geometry, +}; + + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h new file mode 100644 index 0000000000000000000000000000000000000000..8233bd9b57ed16a1dbe359fa1823adc9e69b2a05 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h @@ -0,0 +1,139 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup nrf_block_dev_sdc SDC implementation + * @ingroup nrf_block_dev + * @{ + * + */ + + +#ifndef NRF_BLOCK_DEV_SDC_H__ +#define NRF_BLOCK_DEV_SDC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf_block_dev.h" +#include "app_sdcard.h" + +/** + * @brief SDC block device operations + * */ +extern const nrf_block_dev_ops_t nrf_block_device_sdc_ops; + +/** + * @brief Work structure of SDC block device + */ +typedef struct { + nrf_block_dev_geometry_t geometry; //!< Block device geometry + nrf_block_dev_ev_handler ev_handler; //!< Block device event handler + nrf_block_req_t req; //!< Block READ/WRITE request + void const * p_context; //!< Context handle passed to event handler +} nrf_block_dev_sdc_work_t; + +/** + * @brief SDC block device config initializer (@ref nrf_block_dev_sdc_config_t) + * + * @param blk_size Block size + * @param sdc_lib_config SDC library config (@ref app_sdc_config_t) + * */ +#define NRF_BLOCK_DEV_SDC_CONFIG(blk_size, sdc_lib_config) \ +{ \ + .block_size = (blk_size), \ + .sdc_config = sdc_lib_config \ +} + + +/** + * @brief SDC block device config + */ +typedef struct { + uint32_t block_size; //!< Desired block size + app_sdc_config_t sdc_config; //!< SDC library configuration +} nrf_block_dev_sdc_config_t; + +/** + * @brief SDC block device + * */ +typedef struct { + nrf_block_dev_t block_dev; //!< Block device + nrf_block_dev_info_strings_t info_strings; //!< Block device information strings + nrf_block_dev_sdc_config_t sdc_bdev_config; //!< SDC block device config + nrf_block_dev_sdc_work_t * p_work; //!< SDC block device work structure +} nrf_block_dev_sdc_t; + +/** + * @brief Defines a SDC block device. + * + * @param name Instance name + * @param config Configuration @ref nrf_block_dev_sdc_config_t + * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG + * */ +#define NRF_BLOCK_DEV_SDC_DEFINE(name, config, info) \ + static nrf_block_dev_sdc_work_t CONCAT_2(name, _work); \ + static const nrf_block_dev_sdc_t name = { \ + .block_dev = { .p_ops = &nrf_block_device_sdc_ops }, \ + .info_strings = BRACKET_EXTRACT(info), \ + .sdc_bdev_config = config, \ + .p_work = &CONCAT_2(name, _work), \ + } + +/** + * @brief Returns block device API handle from SDC block device. + * + * @param[in] p_blk_sdc SDC block device + * @return Block device handle + */ +static inline nrf_block_dev_t const * +nrf_block_dev_sdc_ops_get(nrf_block_dev_sdc_t const * p_blk_sdc) +{ + return &p_blk_sdc->block_dev; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_BLOCK_DEV_SDC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/ble_dfu/nrf_ble_dfu.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/ble_dfu/nrf_ble_dfu.c new file mode 100644 index 0000000000000000000000000000000000000000..ad99d031f3f88dbc06672e76d3f6bc83e6f3fad1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/ble_dfu/nrf_ble_dfu.c @@ -0,0 +1,1056 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_ble_dfu.h" + +#include +#include "sdk_common.h" +#include "nrf_dfu_req_handler.h" +#include "nrf_dfu_transport.h" +#include "nrf_dfu_mbr.h" +#include "nrf_bootloader_info.h" +#include "ble_conn_params.h" +#include "boards.h" +#include "nrf_log.h" +#include "ble_hci.h" +#include "app_timer.h" +#include "softdevice_handler_appsh.h" +#include "nrf_log.h" +#include "nrf_delay.h" +#include "nrf_dfu_handling_error.h" + +#define ADVERTISING_LED_PIN_NO BSP_LED_0 /**< Is on when device is advertising. */ +#define CONNECTED_LED_PIN_NO BSP_LED_1 /**< Is on when device has connected. */ + +#define DEVICE_NAME "DfuTarg" /**< Name of device. Will be included in the advertising data. */ +#define MANUFACTURER_NAME "NordicSemiconductor" /**< Manufacturer. Will be passed to Device Information Service. */ + +#define MIN_CONN_INTERVAL (uint16_t)(MSEC_TO_UNITS(15, UNIT_1_25_MS)) /**< Minimum acceptable connection interval. */ +#define MAX_CONN_INTERVAL_MS 30 /**< Maximum acceptable connection interval in milliseconds. */ +#define MAX_CONN_INTERVAL (uint16_t)(MSEC_TO_UNITS(MAX_CONN_INTERVAL_MS, UNIT_1_25_MS)) /**< Maximum acceptable connection interval . */ +#define SLAVE_LATENCY 0 /**< Slave latency. */ +#define CONN_SUP_TIMEOUT (4 * 100) /**< Connection supervisory timeout (4 seconds). */ + +#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(100) /**< Time from the Connected event to first time sd_ble_gap_conn_param_update is called (100 milliseconds). */ +#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(500) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (500 milliseconds). */ +#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */ + +#define MAX_ADV_DATA_LENGTH 20 /**< Maximum length of advertising data. */ + +#define APP_ADV_INTERVAL MSEC_TO_UNITS(25, UNIT_0_625_MS) /**< The advertising interval (25 ms.). */ +#define APP_ADV_TIMEOUT_IN_SECONDS BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED /**< The advertising timeout in units of seconds. This is set to @ref BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED so that the advertisement is done as long as there there is a call to @ref dfu_transport_close function.*/ + +#define APP_FEATURE_NOT_SUPPORTED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2 /**< Reply when unsupported features are requested. */ + +#define MAX_DFU_PKT_LEN (20) /**< Maximum length (in bytes) of the DFU Packet characteristic. */ +#define PKT_CREATE_PARAM_LEN (6) /**< Length (in bytes) of the parameters for Create Object request. */ +#define PKT_SET_PRN_PARAM_LEN (3) /**< Length (in bytes) of the parameters for Set Packet Receipt Notification request. */ +#define PKT_READ_OBJECT_INFO_PARAM_LEN (2) /**< Length (in bytes) of the parameters for Read Object Info request. */ +#define MAX_RESPONSE_LEN (17) /**< Maximum length (in bytes) of the response to a Control Point command. */ + +#define DFU_BLE_FLAG_NONE (0) +#define DFU_BLE_FLAG_SERVICE_INITIALIZED (1 << 0) /**< Flag to check if the DFU service was initialized by the application.*/ +#define DFU_BLE_FLAG_IS_ADVERTISING (1 << 1) /**< Flag to indicate if advertising is ongoing.*/ +#define DFU_BLE_FLAG_TEAR_DOWN_IN_PROGRESS (1 << 2) /**< Flag to indicate whether a tear down is in progress. A tear down could be because the application has initiated it or the peer has disconnected. */ + +static ble_dfu_t m_dfu; /**< Structure used to identify the Device Firmware Update service. */ +static uint16_t m_pkt_notif_target; /**< Number of packets of firmware data to be received before transmitting the next Packet Receipt Notification to the DFU Controller. */ +static uint16_t m_pkt_notif_target_cnt; /**< Number of packets of firmware data received after sending last Packet Receipt Notification or since the receipt of a @ref BLE_DFU_PKT_RCPT_NOTIF_ENABLED event from the DFU service, which ever occurs later.*/ +static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */ +static uint32_t m_flags; +static uint8_t m_notif_buffer[MAX_RESPONSE_LEN]; /**< Buffer used for sending notifications to peer. */ + +//lint -save -e545 -esym(526, dfu_trans) -esym(528, dfu_trans) +DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const dfu_trans) = +{ + .init_func = ble_dfu_transport_init, + .close_func = ble_dfu_transport_close +}; +//lint -restore + + +/**@brief Function for handling a Connection Parameters error. + * + * @param[in] nrf_error Error code. + */ +static void conn_params_error_handler(uint32_t nrf_error) +{ + APP_ERROR_HANDLER(nrf_error); +} + + +/**@brief Function for initializing the Connection Parameters module. + */ +static uint32_t conn_params_init(void) +{ + ble_conn_params_init_t cp_init = {0}; + + cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; + cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; + cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; + cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; + cp_init.disconnect_on_fail = false; + cp_init.error_handler = conn_params_error_handler; + + return ble_conn_params_init(&cp_init); +} + + +/**@brief Function for the Advertising functionality initialization. + * + * @details Encodes the required advertising data and passes it to the stack. + * The advertising data encoded here is specific for DFU. + * Setting advertising data can by done by calling @ref ble_advdata_set. + */ +static uint32_t advertising_init(uint8_t adv_flags) +{ + uint32_t err_code; + uint16_t len_advdata = 9; + uint16_t max_device_name_length = MAX_ADV_DATA_LENGTH - len_advdata; + uint16_t actual_device_name_length = max_device_name_length; + + uint8_t p_encoded_advdata[MAX_ADV_DATA_LENGTH]; + + // Encode flags. + p_encoded_advdata[0] = 0x2; + p_encoded_advdata[1] = BLE_GAP_AD_TYPE_FLAGS; + p_encoded_advdata[2] = adv_flags; + + // Encode 'more available' uuid list. + p_encoded_advdata[3] = 0x3; + p_encoded_advdata[4] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE; + p_encoded_advdata[5] = LSB_16(BLE_DFU_SERVICE_UUID); + p_encoded_advdata[6] = MSB_16(BLE_DFU_SERVICE_UUID); + + // Get GAP device name and length + err_code = sd_ble_gap_device_name_get(&p_encoded_advdata[9], &actual_device_name_length); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Set GAP device in advertising data. + if (actual_device_name_length <= max_device_name_length) + { + p_encoded_advdata[7] = actual_device_name_length + 1; // (actual_length + ADV_AD_TYPE_FIELD_SIZE(1)) + p_encoded_advdata[8] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME; + len_advdata += actual_device_name_length; + } + else + { + // Must use a shorter advertising name than the actual name of the device + p_encoded_advdata[7] = max_device_name_length + 1; // (length + ADV_AD_TYPE_FIELD_SIZE(1)) + p_encoded_advdata[8] = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME; + len_advdata = MAX_ADV_DATA_LENGTH; + } + return sd_ble_gap_adv_data_set(p_encoded_advdata, len_advdata, NULL, 0); +} + + +/**@brief Function for starting advertising. + */ +static uint32_t advertising_start(void) +{ + uint32_t err_code; + ble_gap_adv_params_t adv_params; + + if ((m_flags & DFU_BLE_FLAG_IS_ADVERTISING) != 0) + { + return NRF_SUCCESS; + } + + // Initialize advertising parameters (used when starting advertising). + memset(&adv_params, 0, sizeof(adv_params)); + + err_code = advertising_init(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); + VERIFY_SUCCESS(err_code); + + adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; + adv_params.p_peer_addr = NULL; + adv_params.fp = BLE_GAP_ADV_FP_ANY; + adv_params.interval = APP_ADV_INTERVAL; + adv_params.timeout = APP_ADV_TIMEOUT_IN_SECONDS; + + err_code = sd_ble_gap_adv_start(&adv_params, BLE_CONN_CFG_TAG_DEFAULT); + VERIFY_SUCCESS(err_code); + + nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); + nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); + + m_flags |= DFU_BLE_FLAG_IS_ADVERTISING; + return NRF_SUCCESS; +} + + +/**@brief Function for stopping advertising. + */ +static uint32_t advertising_stop(void) +{ + uint32_t err_code; + + if ((m_flags & DFU_BLE_FLAG_IS_ADVERTISING) == 0) + { + return NRF_SUCCESS; + } + + err_code = sd_ble_gap_adv_stop(); + VERIFY_SUCCESS(err_code); + + nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); + + m_flags |= DFU_BLE_FLAG_IS_ADVERTISING; + return NRF_SUCCESS; +} + + +static bool is_cccd_configured(ble_dfu_t * p_dfu) +{ + uint8_t cccd_val_buf[BLE_CCCD_VALUE_LEN]; + ble_gatts_value_t gatts_value = {0}; + + gatts_value.len = BLE_CCCD_VALUE_LEN; + gatts_value.p_value = cccd_val_buf; + + // Check the CCCD Value of DFU Control Point. + uint32_t err_code = sd_ble_gatts_value_get(m_conn_handle, + p_dfu->dfu_ctrl_pt_handles.cccd_handle, + &gatts_value); + VERIFY_SUCCESS(err_code); + + return ble_srv_is_notification_enabled(cccd_val_buf); +} + + +static uint32_t send_hvx(uint16_t conn_handle, uint16_t value_handle, uint16_t len) +{ + ble_gatts_hvx_params_t hvx_params = {0}; + + hvx_params.handle = value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.p_len = &len; + hvx_params.p_data = m_notif_buffer; + + return sd_ble_gatts_hvx(conn_handle, &hvx_params); +} + + +static uint32_t response_send(ble_dfu_t * p_dfu, + uint8_t op_code, + nrf_dfu_res_code_t resp_val) +{ + uint16_t index = 0; + + NRF_LOG_DEBUG("Sending Response: [0x%01x, 0x%01x]\r\n", op_code, resp_val); + +#ifndef NRF51 + if (p_dfu == NULL) + { + return NRF_ERROR_NULL; + } +#endif + + if ((m_conn_handle == BLE_CONN_HANDLE_INVALID) || (m_flags & DFU_BLE_FLAG_SERVICE_INITIALIZED) == 0) + { + return NRF_ERROR_INVALID_STATE; + } + + m_notif_buffer[index++] = BLE_DFU_OP_CODE_RESPONSE; + + // Encode the Request Op code + m_notif_buffer[index++] = op_code; + + // Encode the Response Value. + m_notif_buffer[index++] = (uint8_t)resp_val; + + // If the error was an extended error code, add the error to the response. + if (resp_val == NRF_DFU_RES_CODE_EXT_ERROR) + { + m_notif_buffer[index++] = ext_error_get(); + // Clear the last extended error code + (void) ext_error_set(NRF_DFU_EXT_ERROR_NO_ERROR); + } + + return send_hvx(m_conn_handle, p_dfu->dfu_ctrl_pt_handles.value_handle, index); +} + + +static uint32_t response_crc_cmd_send(ble_dfu_t * p_dfu, + uint32_t offset, + uint32_t crc) +{ + uint16_t index = 0; + + NRF_LOG_DEBUG("Sending CRC: [0x60, 0x03, 0x01, 0:x%08x, CRC:0x%08x]\r\n", offset, crc); + +#ifndef NRF51 + if (p_dfu == NULL) + { + return NRF_ERROR_NULL; + } +#endif + + if ((m_conn_handle == BLE_CONN_HANDLE_INVALID) || (m_flags & DFU_BLE_FLAG_SERVICE_INITIALIZED) == 0) + { + return NRF_ERROR_INVALID_STATE; + } + + m_notif_buffer[index++] = BLE_DFU_OP_CODE_RESPONSE; + + // Encode the Request Op code + m_notif_buffer[index++] = BLE_DFU_OP_CODE_CALCULATE_CRC; + + // Encode the Response Value. + m_notif_buffer[index++] = (uint8_t)NRF_DFU_RES_CODE_SUCCESS; + + // Encode the Offset Value. + index += uint32_encode(offset, &m_notif_buffer[index]); + + // Encode the Crc Value. + index += uint32_encode(crc, &m_notif_buffer[index]); + + return send_hvx(m_conn_handle, p_dfu->dfu_ctrl_pt_handles.value_handle, index); +} + + +static uint32_t response_select_object_cmd_send(ble_dfu_t * p_dfu, + uint32_t max_size, + uint32_t offset, + uint32_t crc) +{ + uint16_t index = 0; + + NRF_LOG_DEBUG("Sending Object Info: [0x60, 0x06, 0x01 max: 0:x%08x 0:x%08x, CRC:0x%08x]\r\n", + max_size, offset, crc); +#ifndef NRF51 + if (p_dfu == NULL) + { + return NRF_ERROR_NULL; + } +#endif + + if ((m_conn_handle == BLE_CONN_HANDLE_INVALID) || (m_flags & DFU_BLE_FLAG_SERVICE_INITIALIZED) == 0) + { + return NRF_ERROR_INVALID_STATE; + } + + m_notif_buffer[index++] = BLE_DFU_OP_CODE_RESPONSE; + + // Encode the Request Op code + m_notif_buffer[index++] = BLE_DFU_OP_CODE_SELECT_OBJECT; + + // Encode the Success Response Value. + m_notif_buffer[index++] = (uint8_t)NRF_DFU_RES_CODE_SUCCESS; + + // Encode the Max Size Value. + index += uint32_encode(max_size, &m_notif_buffer[index]); + + // Encode the Offset Value. + index += uint32_encode(offset, &m_notif_buffer[index]); + + // Encode the Crc Value. + index += uint32_encode(crc, &m_notif_buffer[index]); + + return send_hvx(m_conn_handle, p_dfu->dfu_ctrl_pt_handles.value_handle, index); +} + + +/**@brief Function for handling a Write event on the Control Point characteristic. + * + * @param[in] p_dfu DFU Service Structure. + * @param[in] p_ble_write_evt Pointer to the write event received from BLE stack. + * + * @return NRF_SUCCESS on successful processing of control point write. Otherwise an error code. + */ +static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t * p_ble_write_evt) +{ + nrf_dfu_res_code_t res_code; + nrf_dfu_req_t dfu_req; + nrf_dfu_res_t dfu_res = {{{0}}}; + + memset(&dfu_req, 0, sizeof(nrf_dfu_req_t)); + + switch (p_ble_write_evt->data[0]) + { + case BLE_DFU_OP_CODE_CREATE_OBJECT: + + if (p_ble_write_evt->len != PKT_CREATE_PARAM_LEN) + { + return response_send(p_dfu, + BLE_DFU_OP_CODE_CREATE_OBJECT, + NRF_DFU_RES_CODE_INVALID_PARAMETER); + } + + NRF_LOG_DEBUG("Received create object\r\n"); + + // Reset the packet receipt notification on create object + m_pkt_notif_target_cnt = m_pkt_notif_target; + + // Get type parameter + //lint -save -e415 + dfu_req.obj_type = p_ble_write_evt->data[1]; + //lint -restore + + // Get length value + //lint -save -e416 + dfu_req.object_size = uint32_decode(&(p_ble_write_evt->data[2])); + //lint -restore + + // Set req type + dfu_req.req_type = NRF_DFU_OBJECT_OP_CREATE; + + res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + return response_send(p_dfu, BLE_DFU_OP_CODE_CREATE_OBJECT, res_code); + + case BLE_DFU_OP_CODE_EXECUTE_OBJECT: + NRF_LOG_DEBUG("Received execute object\r\n"); + + // Set req type + dfu_req.req_type = NRF_DFU_OBJECT_OP_EXECUTE; + + res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + return response_send(p_dfu, BLE_DFU_OP_CODE_EXECUTE_OBJECT, res_code); + + case BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF: + NRF_LOG_DEBUG("Set receipt notif\r\n"); + if (p_ble_write_evt->len != PKT_SET_PRN_PARAM_LEN) + { + return (response_send(p_dfu, + BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF, + NRF_DFU_RES_CODE_INVALID_PARAMETER)); + } + + //lint -save -e415 + m_pkt_notif_target = uint16_decode(&(p_ble_write_evt->data[1])); + //lint -restore + m_pkt_notif_target_cnt = m_pkt_notif_target; + + return response_send(p_dfu, BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF, NRF_DFU_RES_CODE_SUCCESS); + + case BLE_DFU_OP_CODE_CALCULATE_CRC: + NRF_LOG_DEBUG("Received calculate CRC\r\n"); + + dfu_req.req_type = NRF_DFU_OBJECT_OP_CRC; + + res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + if (res_code == NRF_DFU_RES_CODE_SUCCESS) + { + return response_crc_cmd_send(p_dfu, dfu_res.offset, dfu_res.crc); + } + else + { + return response_send(p_dfu, BLE_DFU_OP_CODE_CALCULATE_CRC, res_code); + } + + case BLE_DFU_OP_CODE_SELECT_OBJECT: + + NRF_LOG_DEBUG("Received select object\r\n"); + if (p_ble_write_evt->len != PKT_READ_OBJECT_INFO_PARAM_LEN) + { + return response_send(p_dfu, + BLE_DFU_OP_CODE_SELECT_OBJECT, + NRF_DFU_RES_CODE_INVALID_PARAMETER); + } + + // Set object type to read info about + //lint -save -e415 + dfu_req.obj_type = p_ble_write_evt->data[1]; + //lint -restore + + dfu_req.req_type = NRF_DFU_OBJECT_OP_SELECT; + + res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + if (res_code == NRF_DFU_RES_CODE_SUCCESS) + { + return response_select_object_cmd_send(p_dfu, dfu_res.max_size, dfu_res.offset, dfu_res.crc); + } + else + { + return response_send(p_dfu, BLE_DFU_OP_CODE_SELECT_OBJECT, res_code); + } + + default: + NRF_LOG_WARNING("Received unsupported OP code\r\n"); + // Unsupported op code. + return response_send(p_dfu, + p_ble_write_evt->data[0], + NRF_DFU_RES_CODE_INVALID_PARAMETER); + } +} + + +/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event from the + * SoftDevice. + * + * @param[in] p_dfu DFU Service Structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static bool on_rw_authorize_req(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) +{ + uint32_t err_code; + ble_gatts_rw_authorize_reply_params_t auth_reply = {0}; + ble_gatts_evt_rw_authorize_request_t * p_authorize_request; + ble_gatts_evt_write_t * p_ble_write_evt; + + p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request); + p_ble_write_evt = &(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write); + + if ((p_authorize_request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && + (p_authorize_request->request.write.handle == p_dfu->dfu_ctrl_pt_handles.value_handle) && + (p_authorize_request->request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ) && + (p_authorize_request->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) && + (p_authorize_request->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL) ) + { + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.params.write.update = 1; + auth_reply.params.write.offset = p_ble_write_evt->offset; + auth_reply.params.write.len = p_ble_write_evt->len; + auth_reply.params.write.p_data = p_ble_write_evt->data; + + if (!is_cccd_configured(p_dfu)) + { + // Send an error response to the peer indicating that the CCCD is improperly configured. + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR; + + // Ignore response of auth reply + (void)sd_ble_gatts_rw_authorize_reply(m_conn_handle, &auth_reply); + return false; + } + + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + + err_code = sd_ble_gatts_rw_authorize_reply(m_conn_handle, &auth_reply); + return err_code == NRF_SUCCESS ? true: false; + } + else + { + return false; + } +} + + +/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the SoftDevice. + * + * @param[in] p_dfu DFU Service Structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_write(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) +{ + if (p_ble_evt->evt.gatts_evt.params.write.handle == p_dfu->dfu_pkt_handles.value_handle) + { + nrf_dfu_res_code_t res_code; + nrf_dfu_req_t dfu_req; + nrf_dfu_res_t dfu_res = {{{0}}}; + + memset(&dfu_req, 0, sizeof(nrf_dfu_req_t)); + + // Set req type + dfu_req.req_type = NRF_DFU_OBJECT_OP_WRITE; + + // Set data and length + dfu_req.p_req = p_ble_evt->evt.gatts_evt.params.write.data; + dfu_req.req_len = p_ble_evt->evt.gatts_evt.params.write.len; + + res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + if(res_code != NRF_DFU_RES_CODE_SUCCESS) + { + NRF_LOG_ERROR("Failure to run packet write\r\n"); + } + + // Check if a packet receipt notification is needed to be sent. + if (m_pkt_notif_target != 0 && --m_pkt_notif_target_cnt == 0) + { + (void)response_crc_cmd_send(p_dfu, dfu_res.offset, dfu_res.crc); + + // Reset the counter for the number of firmware packets. + m_pkt_notif_target_cnt = m_pkt_notif_target; + } + } +} + + +/**@brief Function for the Application's SoftDevice event handler. + * + * @param[in] p_ble_evt SoftDevice event. + */ +static void on_ble_evt(ble_evt_t * p_ble_evt) +{ + uint32_t err_code; + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + { + nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); + nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); + + m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + m_flags &= ~DFU_BLE_FLAG_IS_ADVERTISING; + } break; + + case BLE_GAP_EVT_DISCONNECTED: + { + // Restart advertising so that the DFU Controller can reconnect if possible. + err_code = advertising_start(); + APP_ERROR_CHECK(err_code); + + m_conn_handle = BLE_CONN_HANDLE_INVALID; + } break; + + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + { + nrf_dfu_req_handler_reset_if_dfu_complete(); + } break; + + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + { + err_code = sd_ble_gap_sec_params_reply(m_conn_handle, + BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, + NULL, + NULL); + APP_ERROR_CHECK(err_code); + } break; + + case BLE_GATTS_EVT_TIMEOUT: + { + if (p_ble_evt->evt.gatts_evt.params.timeout.src == BLE_GATT_TIMEOUT_SRC_PROTOCOL) + { + err_code = sd_ble_gap_disconnect(m_conn_handle, + BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + APP_ERROR_CHECK(err_code); + } + } break; + + case BLE_EVT_USER_MEM_REQUEST: + { + err_code = sd_ble_user_mem_reply(m_conn_handle, NULL); + APP_ERROR_CHECK(err_code); + } break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + { + if (p_ble_evt->evt.gatts_evt.params.authorize_request.type + != BLE_GATTS_AUTHORIZE_TYPE_INVALID) + { + if (on_rw_authorize_req(&m_dfu, p_ble_evt)) + { + err_code = on_ctrl_pt_write(&m_dfu, + &(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write)); +#ifdef NRF_DFU_DEBUG_VERSION + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Could not handle on_ctrl_pt_write. err_code: 0x%04x\r\n", err_code); + } +#else + // Swallow result + (void) err_code; +#endif + } + } + } break; + + case BLE_GAP_EVT_SEC_INFO_REQUEST: + { + err_code = sd_ble_gap_sec_info_reply(p_ble_evt->evt.gap_evt.conn_handle, NULL, NULL, NULL); + APP_ERROR_CHECK(err_code); + } break; + + case BLE_GATTS_EVT_SYS_ATTR_MISSING: + { + err_code = sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gap_evt.conn_handle, NULL, 0, 0); + APP_ERROR_CHECK(err_code); + } break; + + case BLE_GATTS_EVT_WRITE: + { + on_write(&m_dfu, p_ble_evt); + } break; + +#if (NRF_SD_BLE_API_VERSION >= 3) + case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: + { + err_code = sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle, + BLE_GATT_ATT_MTU_DEFAULT); + APP_ERROR_CHECK(err_code); + } break; // BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST + + case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: + { + ble_gap_data_length_params_t const dlp = + { + .max_rx_octets = BLE_GAP_DATA_LENGTH_AUTO, + .max_tx_octets = BLE_GAP_DATA_LENGTH_AUTO, + }; + + err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gatts_evt.conn_handle, + &dlp, NULL); + APP_ERROR_CHECK(err_code); + } break; // BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST +#endif + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for dispatching a SoftDevice event. + * + * @details This function is called from the SoftDevice event interrupt handler after a + * SoftDevice event has been received. + * + * @param[in] p_ble_evt SoftDevice event. + */ +static void ble_evt_dispatch(ble_evt_t * p_ble_evt) +{ + ble_conn_params_on_ble_evt(p_ble_evt); + on_ble_evt(p_ble_evt); +} + + +/**@brief Function for the LEDs initialization. + * + * @details Initializes all LEDs used by this application. + */ +static void leds_init(void) +{ + nrf_gpio_cfg_output(ADVERTISING_LED_PIN_NO); + nrf_gpio_cfg_output(CONNECTED_LED_PIN_NO); + nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); + nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); +} + + +static uint32_t gap_address_change(void) +{ + uint32_t err_code; + ble_gap_addr_t addr; + +#if (NRF_SD_BLE_API_VERSION < 3) + err_code = sd_ble_gap_address_get(&addr); +#else + err_code = sd_ble_gap_addr_get(&addr); +#endif + + VERIFY_SUCCESS(err_code); + + // Increase the BLE address by one when advertising openly. + addr.addr[0] += 1; + +#if (NRF_SD_BLE_API_VERSION < 3) + err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr); +#else + err_code = sd_ble_gap_addr_set(&addr); +#endif + + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} + + +/**@brief Function for the GAP initialization. + * + * @details This function will setup all the necessary GAP (Generic Access Profile) parameters of + * the device. It also sets the permissions and appearance. + */ +static uint32_t gap_params_init(void) +{ + uint32_t err_code; + ble_gap_conn_params_t gap_conn_params = {0}; + ble_gap_conn_sec_mode_t sec_mode; + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); + + err_code = gap_address_change(); + VERIFY_SUCCESS(err_code); + + err_code = sd_ble_gap_device_name_set(&sec_mode, + (const uint8_t *)DEVICE_NAME, + strlen(DEVICE_NAME)); + + VERIFY_SUCCESS(err_code); + + gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; + gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; + gap_conn_params.slave_latency = SLAVE_LATENCY; + gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; + + err_code = sd_ble_gap_ppcp_set(&gap_conn_params); + return err_code; +} + + +static uint32_t ble_stack_init(bool init_softdevice) +{ + uint32_t err_code; + nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC; + + if (init_softdevice) + { + err_code = nrf_dfu_mbr_init_sd(); + VERIFY_SUCCESS(err_code); + } + + NRF_LOG_DEBUG("vector table: 0x%08x\r\n", BOOTLOADER_START_ADDR); + err_code = sd_softdevice_vector_table_base_set(BOOTLOADER_START_ADDR); + VERIFY_SUCCESS(err_code); + NRF_LOG_DEBUG("vector table: 0x%08x\r\n", BOOTLOADER_START_ADDR); + + NRF_LOG_DEBUG("Error code - sd_softdevice_vector_table_base_set: 0x%08x\r\n", err_code); + + NRF_LOG_DEBUG("Before SOFTDEVICE_HANDLER_APPSH_INIT\r\n"); + SOFTDEVICE_HANDLER_APPSH_INIT(&clock_lf_cfg, true); + NRF_LOG_DEBUG("After SOFTDEVICE_HANDLER_APPSH_INIT\r\n"); + + // Fetch the start address of the application RAM. + uint32_t ram_start = 0; + err_code = softdevice_app_ram_start_get(&ram_start); + APP_ERROR_CHECK(err_code); + + // Overwrite some of the default configurations for the BLE stack. + ble_cfg_t ble_cfg; + + // Configure the maximum number of connections. + memset(&ble_cfg, 0, sizeof(ble_cfg)); + ble_cfg.gap_cfg.role_count_cfg.periph_role_count = BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT; + ble_cfg.gap_cfg.role_count_cfg.central_role_count = 0; + ble_cfg.gap_cfg.role_count_cfg.central_sec_count = 0; + err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, ram_start); + APP_ERROR_CHECK(err_code); + NRF_LOG_INFO("Error code - sd_ble_cfg_set: 0x%08x\r\n", err_code); + VERIFY_SUCCESS(err_code); + + NRF_LOG_DEBUG("Enabling softdevice.\r\n"); + // Enable BLE stack. + err_code = softdevice_enable(&ram_start); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Failed softdevice_enable: 0x%08x\r\n", err_code); + } + else + { + NRF_LOG_DEBUG("Softdevice enabled\r\n"); + } + + return err_code; +} + + +/**@brief Function for adding DFU Packet characteristic to the BLE Stack. + * + * @param[in] p_dfu DFU Service structure. + * + * @return NRF_SUCCESS on success. Otherwise an error code. + */ +static uint32_t dfu_pkt_char_add(ble_dfu_t * const p_dfu) +{ + ble_gatts_char_md_t char_md = {{0}}; + ble_gatts_attr_t attr_char_value = {0}; + ble_gatts_attr_md_t attr_md = {{0}}; + ble_uuid_t char_uuid; + + char_md.char_props.write_wo_resp = 1; + + char_uuid.type = p_dfu->uuid_type; + char_uuid.uuid = BLE_DFU_PKT_CHAR_UUID; + + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.vlen = 1; + + attr_char_value.p_uuid = &char_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.max_len = MAX_DFU_PKT_LEN; + attr_char_value.p_value = NULL; + + return sd_ble_gatts_characteristic_add(p_dfu->service_handle, + &char_md, + &attr_char_value, + &p_dfu->dfu_pkt_handles); +} + + +/**@brief Function for adding DFU Control Point characteristic to the BLE Stack. + * + * @param[in] p_dfu DFU Service structure. + * + * @return NRF_SUCCESS on success. Otherwise an error code. + */ +static uint32_t dfu_ctrl_pt_add(ble_dfu_t * const p_dfu) +{ + ble_gatts_char_md_t char_md = {{0}}; + ble_gatts_attr_t attr_char_value = {0}; + ble_gatts_attr_md_t attr_md = {{0}}; + ble_uuid_t char_uuid; + + char_md.char_props.write = 1; + char_md.char_props.notify = 1; + + char_uuid.type = p_dfu->uuid_type; + char_uuid.uuid = BLE_DFU_CTRL_PT_UUID; + + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.wr_auth = 1; + attr_md.vlen = 1; + + attr_char_value.p_uuid = &char_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.max_len = BLE_GATT_ATT_MTU_DEFAULT; + attr_char_value.p_value = NULL; + + return sd_ble_gatts_characteristic_add(p_dfu->service_handle, + &char_md, + &attr_char_value, + &p_dfu->dfu_ctrl_pt_handles); +} + + +/**@brief Function for checking if the CCCD of DFU Control point is configured for Notification. + * + * @details This function checks if the CCCD of DFU Control Point characteristic is configured + * for Notification by the DFU Controller. + * + * @param[in] p_dfu DFU Service structure. + * + * @return True if the CCCD of DFU Control Point characteristic is configured for Notification. + * False otherwise. + */ +uint32_t ble_dfu_init(ble_dfu_t * p_dfu) +{ + ble_uuid_t service_uuid; + uint32_t err_code; + +#ifndef NRF51 + if (p_dfu == NULL) + { + return NRF_ERROR_NULL; + } +#endif + + m_conn_handle = BLE_CONN_HANDLE_INVALID; + + BLE_UUID_BLE_ASSIGN(service_uuid, BLE_DFU_SERVICE_UUID); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &service_uuid, + &(p_dfu->service_handle)); + VERIFY_SUCCESS(err_code); + + const ble_uuid128_t base_uuid128 = + { + { + 0x50, 0xEA, 0xDA, 0x30, 0x88, 0x83, 0xB8, 0x9F, + 0x60, 0x4F, 0x15, 0xF3, 0x00, 0x00, 0xC9, 0x8E + } + }; + err_code = sd_ble_uuid_vs_add(&base_uuid128, &p_dfu->uuid_type); + VERIFY_SUCCESS(err_code); + + err_code = dfu_pkt_char_add(p_dfu); + VERIFY_SUCCESS(err_code); + + err_code = dfu_ctrl_pt_add(p_dfu); + VERIFY_SUCCESS(err_code); + + m_flags |= DFU_BLE_FLAG_SERVICE_INITIALIZED; + + return NRF_SUCCESS; +} + + +uint32_t ble_dfu_transport_init(void) +{ + uint32_t err_code; + + m_flags &= ~DFU_BLE_FLAG_NONE; + + leds_init(); + + err_code = ble_stack_init(true); + VERIFY_SUCCESS(err_code); + + err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch); + VERIFY_SUCCESS(err_code); + + err_code = gap_params_init(); + VERIFY_SUCCESS(err_code); + + // Initialize the Device Firmware Update Service. + err_code = ble_dfu_init(&m_dfu); + VERIFY_SUCCESS(err_code); + + err_code = conn_params_init(); + VERIFY_SUCCESS(err_code); + + err_code = advertising_start(); + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} + + +uint32_t ble_dfu_transport_close(void) +{ + uint32_t err_code = NRF_SUCCESS; + + NRF_LOG_DEBUG("Disconnecting\r\n"); + + if (m_conn_handle != BLE_CONN_HANDLE_INVALID) + { + // Disconnect from peer. + err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + VERIFY_SUCCESS(err_code); + } + else if ((m_flags & DFU_BLE_FLAG_IS_ADVERTISING) != 0) + { + // If not connected, then the device will be advertising. Hence stop the advertising. + err_code = advertising_stop(); + VERIFY_SUCCESS(err_code); + } + + // Stop the timer, disregard the result. + (void)ble_conn_params_stop(); + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/ble_dfu/nrf_ble_dfu.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/ble_dfu/nrf_ble_dfu.h new file mode 100644 index 0000000000000000000000000000000000000000..bf86b020ab0c8352d99435e7108c413f58be793b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/ble_dfu/nrf_ble_dfu.h @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup nrf_ble_dfu DFU BLE Service + * @{ + * @ingroup sdk_nrf_bootloader + * @brief Device Firmware Update (DFU) transport layer for Bluetooth low energy. + * + * @details The Device Firmware Update (DFU) Service is a GATT-based service that can be used for + * performing firmware updates over BLE. Note that this implementation uses + * vendor-specific UUIDs for the service and characteristics and is intended to demonstrate + * firmware updates over BLE. See @ref lib_dfu_transport_ble "DFU Transport: BLE" for more information on the service and the profile. + */ + +#ifndef NRF_BLE_DFU_H__ +#define NRF_BLE_DFU_H__ + +#include +#include "ble_gatts.h" +#include "ble.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +// This is a 16-bit UUID. +#define BLE_DFU_SERVICE_UUID 0xFE59 //!< The UUID of the DFU Service. + +// These UUIDs are used with the Nordic base address to create a 128-bit UUID (0x8EC9XXXXF3154F609FB8838830DAEA50). +#define BLE_DFU_CTRL_PT_UUID 0x0001 //!< The UUID of the DFU Control Point. +#define BLE_DFU_PKT_CHAR_UUID 0x0002 //!< The UUID of the DFU Packet Characteristic. + + +/**@brief BLE DFU opcodes. + * + * @details These types of opcodes are used in control point access. + */ +typedef enum +{ + BLE_DFU_OP_CODE_CREATE_OBJECT = 0x01, /**< Value of the opcode field for a 'Create object' request. */ + BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF = 0x02, /**< Value of the opcode field for a 'Set Packet Receipt Notification' request. */ + BLE_DFU_OP_CODE_CALCULATE_CRC = 0x03, /**< Value of the opcode field for a 'Calculating checksum' request. */ + BLE_DFU_OP_CODE_EXECUTE_OBJECT = 0x04, /**< Value of the opcode field for an 'Initialize DFU parameters' request. */ + BLE_DFU_OP_CODE_SELECT_OBJECT = 0x06, /**< Value of the opcode field for a 'Select object' request. */ + BLE_DFU_OP_CODE_RESPONSE = 0x60 /**< Value of the opcode field for a response.*/ +} ble_dfu_op_code_t; + + +/**@brief DFU Service. + * + * @details This structure contains status information related to the service. + */ +typedef struct +{ + uint16_t service_handle; /**< Handle of the DFU Service (as provided by the SoftDevice). */ + uint8_t uuid_type; /**< UUID type assigned to the DFU Service by the SoftDevice. */ + ble_gatts_char_handles_t dfu_pkt_handles; /**< Handles related to the DFU Packet Characteristic. */ + ble_gatts_char_handles_t dfu_ctrl_pt_handles; /**< Handles related to the DFU Control Point Characteristic. */ +} ble_dfu_t; + + +/**@brief Function for initializing the DFU Service. + * + * @retval NRF_SUCCESS If the DFU Service and its characteristics were successfully added to the + * SoftDevice. Otherwise, an error code is returned. + */ +uint32_t ble_dfu_transport_init(void); + + +/**@brief Function for closing down the DFU Service and disconnecting from the host. + * + * @retval NRF_SUCCESS If the DFU Service was correctly closed down. + */ +uint32_t ble_dfu_transport_close(void); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_DFU_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu.c new file mode 100644 index 0000000000000000000000000000000000000000..0598cc02ece85a5f20db691d753d105c6b756b2f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu.c @@ -0,0 +1,206 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_dfu.h" + +#include "nrf_dfu_transport.h" +#include "nrf_dfu_utils.h" +#include "nrf_bootloader_app_start.h" +#include "nrf_dfu_settings.h" +#include "nrf_gpio.h" +#include "app_scheduler.h" +#include "app_timer.h" +#include "nrf_log.h" +#include "boards.h" +#include "nrf_bootloader_info.h" +#include "nrf_dfu_req_handler.h" +#ifdef NRF_DFU_DEBUG_VERSION +#include "nrf_delay.h" +#endif //NRF_DFU_DEBUG_VERSION +#ifndef SOFTDEVICE_PRESENT +#include "nrf_soc.h" +#endif + +#define SCHED_MAX_EVENT_DATA_SIZE MAX(APP_TIMER_SCHED_EVENT_DATA_SIZE, 0) /**< Maximum size of scheduler events. */ +#define BOOTLOADER_DFU_START 0xB1 /**< Magic value written to retention register when starting DFU buttonless. */ +#define SCHED_QUEUE_SIZE 20 /**< Maximum number of events in the scheduler queue. */ + + +// Weak function implementation + +/** @brief Weak implemenation of nrf_dfu_check_enter. + * + * @note This function must be overridden to enable entering DFU mode at will. + * Default behaviour is to enter DFU when BOOTLOADER_BUTTON is pressed. + */ +__WEAK bool nrf_dfu_enter_check(void) +{ + if (nrf_gpio_pin_read(BOOTLOADER_BUTTON) == 0) + { + return true; + } + + if(NRF_POWER->GPREGRET == BOOTLOADER_DFU_START) + { + return true; + } + + if (s_dfu_settings.enter_buttonless_dfu == 1) + { + s_dfu_settings.enter_buttonless_dfu = 0; + APP_ERROR_CHECK(nrf_dfu_settings_write(NULL)); + return true; + } + return false; +} + + +// Internal Functions +static void reset_delay_timer_handler(void * p_context) +{ + NRF_LOG_DEBUG("Reset delay timer expired, resetting.\r\n"); +#ifdef NRF_DFU_DEBUG_VERSION + nrf_delay_ms(100); +#endif + NVIC_SystemReset(); +} + +/**@brief Function for initializing the timer handler module (app_timer). + */ +static void timers_init(void) +{ + APP_ERROR_CHECK(app_timer_init()); + APP_ERROR_CHECK( app_timer_create(&nrf_dfu_utils_reset_delay_timer, APP_TIMER_MODE_SINGLE_SHOT, reset_delay_timer_handler) ); +} + + +/** @brief Function for event scheduler initialization. + */ +static void scheduler_init(void) +{ + APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE); +} + + +static void wait_for_event() +{ + // Transport is waiting for event? + while(true) + { + // Can't be emptied like this because of lack of static variables +#ifdef BLE_STACK_SUPPORT_REQD + (void)sd_app_evt_wait(); +#else + __WFI(); +#endif + app_sched_execute(); + } +} + + +void nrf_dfu_wait() +{ +#ifdef BLE_STACK_SUPPORT_REQD + (void)sd_app_evt_wait(); +#else + __WFI(); +#endif + app_sched_execute(); +} + + +uint32_t nrf_dfu_init() +{ + uint32_t ret_val = NRF_SUCCESS; + uint32_t enter_bootloader_mode = 0; + + NRF_LOG_DEBUG("In real nrf_dfu_init\r\n"); + + nrf_dfu_settings_init(); + timers_init(); + + // Continue ongoing DFU operations + // Note that this part does not rely on SoftDevice interaction + ret_val = nrf_dfu_continue(&enter_bootloader_mode); + if(ret_val != NRF_SUCCESS) + { + NRF_LOG_DEBUG("Could not continue DFU operation: 0x%08x\r\n", ret_val); + enter_bootloader_mode = 1; + } + + // Check if there is a reason to enter DFU mode + // besides the effect of the continuation + if (nrf_dfu_enter_check()) + { + NRF_LOG_DEBUG("Application sent bootloader request\n"); + enter_bootloader_mode = 1; + } + + NRF_POWER->GPREGRET = 0; + + if(enter_bootloader_mode != 0 || !nrf_dfu_app_is_valid()) + { + scheduler_init(); + + // Initializing transports + ret_val = nrf_dfu_transports_init(); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_ERROR("Could not initalize DFU transport: 0x%08x\r\n", ret_val); + return ret_val; + } + + (void)nrf_dfu_req_handler_init(); + + // This function will never return + NRF_LOG_DEBUG("Waiting for events\r\n"); + wait_for_event(); + NRF_LOG_DEBUG("After waiting for events\r\n"); + } + + if (nrf_dfu_app_is_valid()) + { + NRF_LOG_DEBUG("Jumping to: 0x%08x\r\n", MAIN_APPLICATION_START_ADDR); + nrf_bootloader_app_start(MAIN_APPLICATION_START_ADDR); + } + + // Should not be reached! + NRF_LOG_INFO("After real nrf_dfu_init\r\n"); + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu.h new file mode 100644 index 0000000000000000000000000000000000000000..2c9f08341f5fe90e10de385c03dd0c8c6c844df3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu.h @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup sdk_nrf_dfu DFU bootloader + * @{ + * @ingroup sdk_nrf_bootloader + * @brief Bootloader with Device Firmware Update (DFU) functionality. + * + * The DFU bootloader module, in combination with the @ref sdk_bootloader module, + * can be used to implement a bootloader that supports Device Firmware Updates. + */ + + +#ifndef NRF_DFU_H__ +#define NRF_DFU_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BOOTLOADER_BUTTON (BSP_BUTTON_3) /**< Button for entering DFU mode. */ + +/** @brief Function for initializing a DFU operation. + * + * This function initializes a DFU operation and any transports that are registered + * in the system. + * + * @retval NRF_SUCCESS If the DFU operation was successfully initialized. + */ +uint32_t nrf_dfu_init(void); + + +/** @brief Function for checking if DFU mode should be entered. + * + * This function checks whether DFU mode is required. + * + * @retval true If DFU mode must be entered. + * @retval false If there is no need to enter DFU mode. + */ +bool nrf_dfu_enter_check(void); + + +/** @brief Function for checking if DFU should be reset (failsafe). + * + * This function will check if DFU should be reset (failsafe). + * + * If this returns true, DFU mode will be entered and DFU will be reset. + * + * @retval true If DFU must be reset (failsafe). + * @retval false If there is no need to reset DFU. + */ +bool nrf_dfu_check_failsafe_reset(void); + + +/** @brief Function for blocking until an event (i.e. incoming BLE packet) arrives. + */ +void nrf_dfu_wait(void); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_flash.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_flash.c new file mode 100644 index 0000000000000000000000000000000000000000..94dccba598d68b3d8d2b37c38648fa7a18f35c58 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_flash.c @@ -0,0 +1,313 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_dfu_flash.h" +#include "nrf_dfu_types.h" +#include "nrf_nvmc.h" +#include "nrf_log.h" + +#define FLASH_FLAG_NONE (0) +#define FLASH_FLAG_OPER (1<<0) +#define FLASH_FLAG_FAILURE_SINCE_LAST (1<<1) +#define FLASH_FLAG_SD_ENABLED (1<<2) + +static uint32_t m_flags; /*lint -e551*/ + + +#ifdef BLE_STACK_SUPPORT_REQD +#include "softdevice_handler.h" +#include "fstorage.h" + +// Function prototypes +static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result); + +FS_REGISTER_CFG(fs_config_t fs_dfu_config) = +{ + .callback = fs_evt_handler, // Function for event callbacks. + .p_start_addr = (uint32_t*)MBR_SIZE, + .p_end_addr = (uint32_t*)BOOTLOADER_SETTINGS_ADDRESS + CODE_PAGE_SIZE +}; + + +static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result) +{ + // Clear the operation flag + m_flags &= ~FLASH_FLAG_OPER; + + if (result == FS_SUCCESS) + { + // Clear flag for ongoing operation and failure since last + m_flags &= ~FLASH_FLAG_FAILURE_SINCE_LAST; + } + else + { + NRF_LOG_ERROR("Generating failure\r\n"); + m_flags |= FLASH_FLAG_FAILURE_SINCE_LAST; + } + + if (evt->p_context) + { + //lint -e611 + ((dfu_flash_callback_t)evt->p_context)(evt, result); + } +} + +#endif + + +uint32_t nrf_dfu_flash_init(bool sd_enabled) +{ + uint32_t err_code = NRF_SUCCESS; + +#ifdef BLE_STACK_SUPPORT_REQD + // Only run this initialization if SD is enabled + if(sd_enabled) + { + NRF_LOG_DEBUG("------- nrf_dfu_flash_init-------\r\n"); + if (fs_fake_init() != FS_SUCCESS) + { + NRF_LOG_ERROR("Not initializing the thing\r\n"); + return NRF_ERROR_INVALID_STATE; + } + + // Enable access to the whole range + + + err_code = softdevice_sys_evt_handler_set(fs_sys_event_handler); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Not initializing the thing 2\r\n"); + return NRF_ERROR_INVALID_STATE; + } + + // Setting flag to indicate that SD is enabled to ensure fstorage is use in calls + // to do flash operations. + m_flags = FLASH_FLAG_SD_ENABLED; + } + else +#endif + { + m_flags = FLASH_FLAG_NONE; + } + + return err_code; +} + + +fs_ret_t nrf_dfu_flash_store(uint32_t const * p_dest, uint32_t const * const p_src, uint32_t len_words, dfu_flash_callback_t callback) +{ + fs_ret_t ret_val = FS_SUCCESS; + +#ifdef BLE_STACK_SUPPORT_REQD + if ((m_flags & FLASH_FLAG_SD_ENABLED) != 0) + { + // Check if there is a pending error + if ((m_flags & FLASH_FLAG_FAILURE_SINCE_LAST) != 0) + { + NRF_LOG_ERROR("Flash: Failure since last\r\n"); + return FS_ERR_FAILURE_SINCE_LAST; + } + + // Set the flag to indicate ongoing operation + m_flags |= FLASH_FLAG_OPER; + //lint -e611 + ret_val = fs_store(&fs_dfu_config, p_dest, p_src, len_words, (void*)callback); + + if (ret_val != FS_SUCCESS) + { + NRF_LOG_ERROR("Flash: failed %d\r\n", ret_val); + return ret_val; + } + + // Set the flag to indicate ongoing operation + m_flags |= FLASH_FLAG_OPER; + } + else +#endif + { + +#ifndef NRF51 + if ((p_src == NULL) || (p_dest == NULL)) + { + return FS_ERR_NULL_ARG; + } + + // Check that both pointers are word aligned. + if (((uint32_t)p_src & 0x03) || + ((uint32_t)p_dest & 0x03)) + { + return FS_ERR_UNALIGNED_ADDR; + } + + if (len_words == 0) + { + NRF_LOG_ERROR("Flash: Invalid length (NVMC)\r\n"); + return FS_ERR_INVALID_ARG; + } +#endif + + nrf_nvmc_write_words((uint32_t)p_dest, p_src, len_words); + + #if (__LINT__ != 1) + if (callback) + { + fs_evt_t evt = + { + .id = FS_EVT_STORE, + .p_context = (void*)callback, + .store = + { + .length_words = len_words, + .p_data = p_dest + } + }; + callback(&evt, FS_SUCCESS); + } + #endif + } + + return ret_val; +} + + +/** @brief Internal function to initialize DFU BLE transport + */ +fs_ret_t nrf_dfu_flash_erase(uint32_t const * p_dest, uint32_t num_pages, dfu_flash_callback_t callback) +{ + fs_ret_t ret_val = FS_SUCCESS; + NRF_LOG_DEBUG("Erasing: 0x%08x, num: %d\r\n", (uint32_t)p_dest, num_pages); + +#ifdef BLE_STACK_SUPPORT_REQD + + if ((m_flags & FLASH_FLAG_SD_ENABLED) != 0) + { + // Check if there is a pending error + if ((m_flags & FLASH_FLAG_FAILURE_SINCE_LAST) != 0) + { + NRF_LOG_ERROR("Erase: Failure since last\r\n"); + return FS_ERR_FAILURE_SINCE_LAST; + } + + m_flags |= FLASH_FLAG_OPER; + ret_val = fs_erase(&fs_dfu_config, p_dest, num_pages, (void*)callback); + + if (ret_val != FS_SUCCESS) + { + NRF_LOG_ERROR("Erase failed: %d\r\n", ret_val); + m_flags &= ~FLASH_FLAG_OPER; + return ret_val; + } + + // Set the flag to indicate ongoing operation + m_flags |= FLASH_FLAG_OPER; + } + else +#endif + { +#ifndef NRF51 + // Softdevice is not present or activated. Run the NVMC instead + if (((uint32_t)p_dest & (CODE_PAGE_SIZE-1)) != 0) + { + NRF_LOG_ERROR("Invalid address\r\n"); + return FS_ERR_UNALIGNED_ADDR; + } +#endif + + uint16_t first_page = ((uint32_t)p_dest / CODE_PAGE_SIZE); + do + { + nrf_nvmc_page_erase((uint32_t)p_dest); + p_dest += CODE_PAGE_SIZE/sizeof(uint32_t); + } + while(--num_pages > 0); + + + if (callback) + { + #if (__LINT__ != 1) + fs_evt_t evt = + { + .id = FS_EVT_ERASE, + .p_context = (void*)callback, + .erase = + { + .first_page = first_page, + .last_page = ((uint32_t)p_dest / CODE_PAGE_SIZE) + } + }; + callback(&evt, FS_SUCCESS); + #else + (void)first_page; + #endif + } + } + + return ret_val; +} + + +void nrf_dfu_flash_error_clear(void) +{ + m_flags &= ~FLASH_FLAG_FAILURE_SINCE_LAST; +} + + +fs_ret_t nrf_dfu_flash_wait(void) +{ + NRF_LOG_DEBUG("Waiting for finished...\r\n"); + +#ifdef BLE_STACK_SUPPORT_REQD + if ((m_flags & FLASH_FLAG_SD_ENABLED) != 0) + { + while ((m_flags & FLASH_FLAG_OPER) != 0) + { + (void)sd_app_evt_wait(); + } + + if ((m_flags & FLASH_FLAG_FAILURE_SINCE_LAST) != 0) + { + NRF_LOG_ERROR("Failure since last\r\n"); + return FS_ERR_FAILURE_SINCE_LAST; + } + } +#endif + + NRF_LOG_DEBUG("After wait!\r\n"); + return FS_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_flash.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..db2c770e536e8498d25f8bd144a2fcacc53408ee --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_flash.h @@ -0,0 +1,156 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup sdk_nrf_dfu_flash Flash operations + * @{ + * @ingroup sdk_nrf_dfu + */ + +#ifndef NRF_DFU_FLASH_H__ +#define NRF_DFU_FLASH_H__ + +#include +#include +#include "fstorage.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief fstorage event handler function for DFU fstorage operations. + * + * This function is intended to be registered to the fstorage module as the event handler for all DFU flash operations. + * When each flash operation has completed or failed this function will be called. + * + * See ::fs_cb_t for implementation details. + */ +typedef fs_cb_t dfu_flash_callback_t; + +/**@brief Function for initializing the flash module. + * + * You can use this module with or without a SoftDevice: + * - If the module is initialized with the SoftDevice enabled flag set, the @ref fstorage + * module is used as back end for all flash operations. Flash storage calls + * are asynchronous; the SoftDevice manages when the actual operation in + * flash is done. + * - If the module is initialized with the SoftDevice enabled flag not set, + * the non-volatile memory controller (NVMC) driver handles the flash operations + * by directly accessing flash. These operations are synchronous. + * + * @param[in] sd_enabled Set the flash handling to run with or without the SoftDevice enabled. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_STATE If the fstorage module could not be initiated or the SoftDevice could not set the event handler. + */ +uint32_t nrf_dfu_flash_init(bool sd_enabled); + + +/**@brief Function for storing data to flash (with or without the SoftDevice enabled). + * + * @warning The content to be stored must be kept at @p p_src until the operation is + * complete. Without SoftDevice, the operation is complete when the function + * returns. With SoftDevice, the operation is complete when the fstorage event is received. + * + * @param[in] p_dest Pointer to the address where the data should be stored. + * @param[in] p_src Pointer to the address where the data should be copied from. + * This address can be in flash or RAM. + * @param[in] len_words The number of words to be copied from @p p_src to @p p_dest. + * @param[in] callback Pointer to the callback function. + * + * @retval FS_SUCCESS If the operation was successful. + * @retval FS_ERR_FAILURE_SINCE_LAST If an error occurred in another transaction and fstorage cannot continue before + * the event has been dealt with. + * @retval FS_ERR_UNALIGNED_ADDR If @p p_src or @p p_dest is not word-aligned. Ensure that the address pointed to is divisible by four. + * @retval FS_ERR_INVALID_ARG If @p len_words is zero. It is not possible to write zero words. + * @retval FS_ERR_NULL_ARG If @p p_src or @p p_dest is NULL. + * + * @retval FS_ERR_NOT_INITIALIZED If the fstorage module is not initialized. + * @retval FS_ERR_INVALID_CFG If the initialization of the fstorage module is invalid. + * @retval FS_ERR_QUEUE_FULL If the internal operation queue of the fstorage module is full. + */ +fs_ret_t nrf_dfu_flash_store(uint32_t const * p_dest, uint32_t const * const p_src, uint32_t len_words, dfu_flash_callback_t callback); + + +/**@brief Function for erasing data from flash (with or without the SoftDevice enabled). + * + * @param[in] p_dest The address of the first byte to be deleted. + * @param[in] num_pages The number of flash pages to be deleted. + * @param[in] callback Pointer to the callback function. + * + * @retval FS_SUCCESS If the operation was successful. + * @retval FS_ERR_UNALIGNED_ADDR If @p p_dest is not aligned to a page boundary. + * @retval FS_ERR_INVALID_ADDR If @p p_dest does not point to the start of a flash page or the operation would + * go beyond the flash memory boundary. + * @retval FS_ERR_NOT_INITIALIZED If the fstorage module is not initialized. + * @retval FS_ERR_INVALID_CFG If the initialization of the fstorage module is invalid. + * @retval FS_ERR_NULL_ARG If @p p_dest is NULL. + * @retval FS_ERR_INVALID_ARG If @p num_pages is zero. + * @retval FS_ERR_QUEUE_FULL If the internal operation queue of the fstorage module is full. + */ +fs_ret_t nrf_dfu_flash_erase(uint32_t const * p_dest, uint32_t num_pages, dfu_flash_callback_t callback); + + +/**@brief Function for clearing an error that has occurred during fstorage operations. + */ +void nrf_dfu_flash_error_clear(void); + + +/**@brief Function for waiting for an event from fstorage. + * + * This function halts execution until an event is received from the SoftDevice. + * You can use this function to halt execution until a flash operation has completed, to prevent + * tampering with the source data until fstorage is done with it. + * + * @retval FS_SUCCESS If the operation was successful. + * @retval FS_ERR_FAILURE_SINCE_LAST If an error has occurred in another transaction and fstorage cannot continue before + * the event has been dealt with. + */ +fs_ret_t nrf_dfu_flash_wait(void); + + +#ifdef __cplusplus +} +#endif + + +#endif // NRF_DFU_FLASH_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c new file mode 100644 index 0000000000000000000000000000000000000000..b78d8850177728b8a7c5523ceacd422c62f74753 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_dfu_handling_error.h" + +#include "nrf_log.h" +#include "nrf_dfu_req_handler.h" + +static nrf_dfu_ext_error_code_t m_last_error = NRF_DFU_EXT_ERROR_NO_ERROR; + +nrf_dfu_res_code_t ext_error_set(nrf_dfu_ext_error_code_t error_code) +{ + m_last_error = error_code; + + return NRF_DFU_RES_CODE_EXT_ERROR; +} + +nrf_dfu_ext_error_code_t ext_error_get() +{ + nrf_dfu_ext_error_code_t last_error = m_last_error; + m_last_error = NRF_DFU_EXT_ERROR_NO_ERROR; + + return last_error; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h new file mode 100644 index 0000000000000000000000000000000000000000..a13a71bfdfe9ebba2eaa2989742509d89892ee13 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + + /**@file + * + * @defgroup nrf_dfu_rescodes DFU result codes + * @{ + * @ingroup sdk_nrf_dfu_transport + * @brief When the DFU controller sends requests to the DFU bootloader on + * the DFU target, the DFU bootloader answers with any of these result codes. + */ + + +#ifndef DFU_HANDLING_ERROR_H__ +#define DFU_HANDLING_ERROR_H__ + +#include "nrf_dfu_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief DFU request result codes. + * + * @details The DFU transport layer creates request events of type @ref nrf_dfu_req_op_t. Such events return one of these result codes. + */ +typedef enum +{ + NRF_DFU_RES_CODE_INVALID = 0x00, /**< Invalid opcode. */ + NRF_DFU_RES_CODE_SUCCESS = 0x01, /**< Operation successful. */ + NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED = 0x02, /**< Opcode not supported. */ + NRF_DFU_RES_CODE_INVALID_PARAMETER = 0x03, /**< Missing or invalid parameter value. */ + NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES = 0x04, /**< Not enough memory for the data object. */ + NRF_DFU_RES_CODE_INVALID_OBJECT = 0x05, /**< Data object does not match the firmware and hardware requirements, the signature is wrong, or parsing the command failed. */ + NRF_DFU_RES_CODE_UNSUPPORTED_TYPE = 0x07, /**< Not a valid object type for a Create request. */ + NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED = 0x08, /**< The state of the DFU process does not allow this operation. */ + NRF_DFU_RES_CODE_OPERATION_FAILED = 0x0A, /**< Operation failed. */ + NRF_DFU_RES_CODE_EXT_ERROR = 0x0B, /**< Extended error. The next byte of the response contains the error code of the extended error (see @ref nrf_dfu_ext_error_code_t). */ +} nrf_dfu_res_code_t; + +/**@brief DFU request extended result codes. + * + * @details When an event returns @ref NRF_DFU_RES_CODE_EXT_ERROR, it also stores an extended error code. + * The transport layer can then send the extended error code together with the error code to give + * the controller additional information about the cause of the error. + */ +typedef enum +{ + NRF_DFU_EXT_ERROR_NO_ERROR = 0x00, /**< No extended error code has been set. This error indicates an implementation problem. */ + NRF_DFU_EXT_ERROR_INVALID_ERROR_CODE = 0x01, /**< Invalid error code. This error code should never be used outside of development. */ + NRF_DFU_EXT_ERROR_WRONG_COMMAND_FORMAT = 0x02, /**< The format of the command was incorrect. This error code is not used in the + current implementation, because @ref NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED + and @ref NRF_DFU_RES_CODE_INVALID_PARAMETER cover all + possible format errors. */ + NRF_DFU_EXT_ERROR_UNKNOWN_COMMAND = 0x03, /**< The command was successfully parsed, but it is not supported or unknown. */ + NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID = 0x04, /**< The init command is invalid. The init packet either has + an invalid update type or it is missing required fields for the update type + (for example, the init packet for a SoftDevice update is missing the SoftDevice size field). */ + NRF_DFU_EXT_ERROR_FW_VERSION_FAILURE = 0x05, /**< The firmware version is too low. For an application, the version must be greater than + the current application. For a bootloader, it must be greater than or equal + to the current version. This requirement prevents downgrade attacks.*/ + NRF_DFU_EXT_ERROR_HW_VERSION_FAILURE = 0x06, /**< The hardware version of the device does not match the required + hardware version for the update. */ + NRF_DFU_EXT_ERROR_SD_VERSION_FAILURE = 0x07, /**< The array of supported SoftDevices for the update does not contain + the FWID of the current SoftDevice. */ + NRF_DFU_EXT_ERROR_SIGNATURE_MISSING = 0x08, /**< The init packet does not contain a signature. This error code is not used in the + current implementation, because init packets without a signature + are regarded as invalid. */ + NRF_DFU_EXT_ERROR_WRONG_HASH_TYPE = 0x09, /**< The hash type that is specified by the init packet is not supported by the DFU bootloader. */ + NRF_DFU_EXT_ERROR_HASH_FAILED = 0x0A, /**< The hash of the firmware image cannot be calculated. */ + NRF_DFU_EXT_ERROR_WRONG_SIGNATURE_TYPE = 0x0B, /**< The type of the signature is unknown or not supported by the DFU bootloader. */ + NRF_DFU_EXT_ERROR_VERIFICATION_FAILED = 0x0C, /**< The hash of the received firmware image does not match the hash in the init packet. */ + NRF_DFU_EXT_ERROR_INSUFFICIENT_SPACE = 0x0D, /**< The available space on the device is insufficient to hold the firmware. */ +} nrf_dfu_ext_error_code_t; + + +/**@brief Function for setting an extended error code that can be retrieved later. + * + * @details When an extended error occurs in the DFU process, this function can be used to store the error. + * + * @param error_code The error code to store. + * + * @retval NRF_DFU_RES_CODE_EXT_ERROR + */ +nrf_dfu_res_code_t ext_error_set(nrf_dfu_ext_error_code_t error_code); + +/**@brief Function for getting the most recent extended error code. + * + * @details This function is used by the transport layer to fetch the most recent extended error code. + * + * @return The most recent error code. If the function is called again before a new error occurs, @ref NRF_DFU_EXT_ERROR_NO_ERROR is returned. + */ +nrf_dfu_ext_error_code_t ext_error_get( void ); + + +#ifdef __cplusplus +} +#endif + +#endif // DFU_HANDLING_ERROR_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_mbr.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_mbr.c new file mode 100644 index 0000000000000000000000000000000000000000..3b933a73e54602d0a45e172a7658ca48766a354a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_mbr.c @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_dfu_mbr.h" +#include "nrf_mbr.h" +#include "nrf_dfu_types.h" +#include "nrf_log.h" + +uint32_t nrf_dfu_mbr_copy_bl(uint32_t * p_src, uint32_t len) +{ + uint32_t ret_val; + uint32_t const len_words = len / sizeof(uint32_t); + + sd_mbr_command_t command = + { + .command = SD_MBR_COMMAND_COPY_BL, + .params.copy_bl.bl_src = p_src, + .params.copy_bl.bl_len = len_words + }; + + ret_val = sd_mbr_command(&command); + + return ret_val; +} + + +uint32_t nrf_dfu_mbr_copy_sd(uint32_t * p_dst, uint32_t * p_src, uint32_t len) +{ + uint32_t ret_val; + uint32_t const len_words = len / sizeof(uint32_t); + + if((len_words & (CODE_PAGE_SIZE / sizeof(uint32_t) - 1)) != 0) + return NRF_ERROR_INVALID_LENGTH; + + sd_mbr_command_t command = + { + .command = SD_MBR_COMMAND_COPY_SD, + .params.copy_sd.src = p_src, + .params.copy_sd.dst = p_dst, + .params.copy_sd.len = len_words + }; + + ret_val = sd_mbr_command(&command); + + return ret_val; +} + + +uint32_t nrf_dfu_mbr_init_sd(void) +{ + uint32_t ret_val; + + sd_mbr_command_t command = + { + .command = SD_MBR_COMMAND_INIT_SD + }; + + ret_val = sd_mbr_command(&command); + + return ret_val; +} + + +uint32_t nrf_dfu_mbr_compare(uint32_t * p_ptr1, uint32_t * p_ptr2, uint32_t len) +{ + uint32_t ret_val; + uint32_t const len_words = len / sizeof(uint32_t); + + sd_mbr_command_t command = + { + .command = SD_MBR_COMMAND_COMPARE, + .params.compare.ptr1 = p_ptr1, + .params.compare.ptr2 = p_ptr2, + .params.compare.len = len_words + }; + + ret_val = sd_mbr_command(&command); + + return ret_val; +} + + +uint32_t nrf_dfu_mbr_vector_table_set(uint32_t address, uint8_t is_temporary) +{ + uint32_t ret_val; + + NRF_LOG_DEBUG("running vector table set\r\n"); + sd_mbr_command_t command = + { + .command = SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, + .params.base_set.address = address, +#ifndef SOFTDEVICE_PRESENT + .params.base_set.temporary = is_temporary, +#endif + }; + + ret_val = sd_mbr_command(&command); + NRF_LOG_DEBUG("After running vector table set\r\n"); + + return ret_val; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_mbr.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_mbr.h new file mode 100644 index 0000000000000000000000000000000000000000..d8ca9d8404fad60e6588d52407993586bbb9e827 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_mbr.h @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup sdk_nrf_dfu_mbr MBR functions + * @{ + * @ingroup sdk_nrf_dfu + */ + +#ifndef NRF_DFU_MBR_H__ +#define NRF_DFU_MBR_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for copying the bootloader using an MBR command. + * + * @param[in] p_src Source address of the bootloader data to copy. + * @param[in] len Length of the data to copy in bytes. + * + * @return This function will return only if the command request could not be run. + * See @ref sd_mbr_command_copy_bl_t for possible return values. + */ +uint32_t nrf_dfu_mbr_copy_bl(uint32_t * p_src, uint32_t len); + + +/** @brief Function for copying the SoftDevice using an MBR command. + * + * @param[in] p_dst Target of the SoftDevice copy. + * @param[in] p_src Source address of the SoftDevice image to copy. + * @param[in] len Length of the data to copy in bytes. + * + * @retval NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. + * @retval NRF_ERROR_INVALID_LENGTH Invalid len + * @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. + * @retval NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + */ +uint32_t nrf_dfu_mbr_copy_sd(uint32_t * p_dst, uint32_t * p_src, uint32_t len); + + +/** @brief Function for initializing the SoftDevice using an MBR command. + * + * @retval NRF_SUCCESS If the SoftDevice was copied successfully. + * Any other return value indicates that the SoftDevice + * could not be copied. + */ +uint32_t nrf_dfu_mbr_init_sd(void); + + +/** @brief Function for comparing source and target using an MBR command. + * + * @param[in] p_ptr1 First pointer to data to compare. + * @param[in] p_ptr2 Second pointer to data to compare. + * @param[in] len Length of the data to compare in bytes. + * + * @retval NRF_SUCCESS If the content of both memory blocks is equal. + * @retval NRF_ERROR_NULL If the content of the memory blocks differs. + */ +uint32_t nrf_dfu_mbr_compare(uint32_t * p_ptr1, uint32_t * p_ptr2, uint32_t len); + + +/** @brief Function for setting the address of the vector table using an MBR command. + * + * @param[in] address Address of the new vector table. + * @param[in] is_temporary If set to 1 the new forwarding address will not be stored + * in flash. + * + * @retval NRF_SUCCESS If the address of the new vector table was set. Any other + * return value indicates that the address could not be set. + */ +uint32_t nrf_dfu_mbr_vector_table_set(uint32_t address, uint8_t is_temporary); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_MBR_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h new file mode 100644 index 0000000000000000000000000000000000000000..6793c94a4b490e4b2f43b2c3f824fb4a0a92560b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h @@ -0,0 +1,192 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup sdk_nrf_dfu_req_handler Request handling + * @{ + * @ingroup sdk_nrf_dfu + */ + +#ifndef NRF_DFU_REQ_HANDLER_H__ +#define NRF_DFU_REQ_HANDLER_H__ + +#include +#include +#include "nrf_dfu_types.h" +#include "nrf_dfu_handling_error.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**@brief DFU object types. + */ +typedef enum +{ + NRF_DFU_OBJ_TYPE_INVALID, /**< Invalid object type.*/ + NRF_DFU_OBJ_TYPE_COMMAND, /**< Command object packet.*/ + NRF_DFU_OBJ_TYPE_DATA, /**< Data object.*/ +} nrf_dfu_obj_type_t; + + +/**@brief DFU request operation codes. + * + * @details The DFU transport layer creates request events of these types. The implementation of @ref nrf_dfu_req_handler_on_req handles requests of these types. + */ +typedef enum +{ + + NRF_DFU_OBJECT_OP_NONE = 0, /**< No operation set. */ + NRF_DFU_OBJECT_OP_CREATE = 1, /**< Create operation. The length of the request indicates the required size. When called, the created object is selected. */ + NRF_DFU_OBJECT_OP_WRITE = 2, /**< Write operation. When called, offset and CRC of the selected object are reported back. */ + NRF_DFU_OBJECT_OP_EXECUTE = 3, /**< Execute operation. When called, the selected object is executed. */ + NRF_DFU_OBJECT_OP_CRC = 4, /**< Calculate checksum operation. When called, offset and CRC of the selected object are reported back. */ + NRF_DFU_OBJECT_OP_SELECT = 6, /**< Select operation. When called, the object of the given type is selected, and information about the object is reported back. */ + NRF_DFU_OBJECT_OP_OTHER = 7, /**< A user-defined DFU request type. The application must define how to interpret the request. */ +} nrf_dfu_req_op_t; + + +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + // Anonymous unions are enabled by default. +#endif + + +/** @brief Definition of a DFU request sent from the transport layer. + * + * @details When the transport layer gets a DFU event, it calls the function @ref nrf_dfu_req_handler_on_req to handle the DFU request. + */ +typedef struct +{ + nrf_dfu_req_op_t req_type; /**< Request operation type. */ + + union + { + struct + { + uint32_t obj_type; /**< Object type of the object to be created for a request of type @ref NRF_DFU_OBJECT_OP_CREATE. */ + uint32_t object_size; /**< Size of the object to be created for a request of type @ref NRF_DFU_OBJECT_OP_CREATE. Note that the object size is not the same as the size of the firmware. */ + }; + + struct + { + uint8_t * p_req; /**< Pointer to an array holding the serialized version of the request. */ + uint32_t req_len; /**< Length of the request array. */ + }; + }; +} nrf_dfu_req_t; + + +/** @brief Response used during DFU operations. + */ +typedef struct +{ + union + { + struct + { + uint8_t * p_res; /**< Pointer to an array holding the serialized version of the response. */ + uint32_t res_len; /**< Length of the response array. */ + }; + + struct + { + uint32_t max_size; /**< Maximum size of the object of a given type. */ + uint32_t offset; /**< Current offset. */ + uint32_t crc; /**< Current CRC. */ + }; + }; +} nrf_dfu_res_t; + +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + // Leave anonymous unions enabled. +#elif defined(__GNUC__) + // Anonymous unions are enabled by default. +#endif + + +/** @brief Function for initializing the request handling module. + * + * @details This function initializes the flash with or without the SoftDevice, depending on the project configuration. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_STATE If the fstorage module could not be initiated or the SoftDevice could not set the event handler. + */ +uint32_t nrf_dfu_req_handler_init(void); + + +/** @brief Function type for handling a DFU request. + * + * @param[in,out] p_context Pointer to context-specific RAM required for + * running the command request. + * This value may be NULL if the command request + * does not require context-specific RAM. + * @param[in,out] p_req Pointer to the structure holding the DFU request. + * @param[in,out] p_res Pointer to the structure holding the DFU response. + * + * @retval NRF_DFU_RES_CODE_SUCCESS If the command request was executed successfully. + * Any other error code indicates that the request + * could not be handled. + */ +nrf_dfu_res_code_t nrf_dfu_req_handler_on_req(void * p_context, nrf_dfu_req_t * p_req, nrf_dfu_res_t * p_res); + + +/** @brief Function for resetting the device when the DFU process is complete. + * + * @details Checks if the DFU transfer is complete. If it is complete, all transports are closed down + * and reset is called. + */ +void nrf_dfu_req_handler_reset_if_dfu_complete(void); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_REQ_HANDLER_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_settings.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_settings.c new file mode 100644 index 0000000000000000000000000000000000000000..5dfb5413714769d53756558cff4f971e72170fd8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_settings.c @@ -0,0 +1,264 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_dfu_settings.h" +#include "nrf_dfu_flash.h" +#include "nrf_log.h" +#include "crc32.h" +#include +#include "app_scheduler.h" +#include "nrf_delay.h" + +/** @brief This variable reserves a codepage for bootloader specific settings, + * to ensure the compiler doesn't locate any code or variables at his location. + */ +#if defined (__CC_ARM ) + + uint8_t m_dfu_settings_buffer[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS))) + __attribute__((used)); + +#elif defined ( __GNUC__ ) + + uint8_t m_dfu_settings_buffer[CODE_PAGE_SIZE] __attribute__ ((section(".bootloaderSettings"))) + __attribute__((used)); + +#elif defined ( __ICCARM__ ) + + __no_init __root uint8_t m_dfu_settings_buffer[CODE_PAGE_SIZE] @ BOOTLOADER_SETTINGS_ADDRESS; + +#else + + #error Not a valid compiler/linker for m_dfu_settings placement. + +#endif // Compiler specific + +#ifndef BL_SETTINGS_ACCESS_ONLY +#if defined( NRF52_SERIES ) + +/**@brief This variable reserves a codepage for mbr parameters, to ensure the compiler doesn't + * locate any code or variables at his location. + */ +#if defined ( __CC_ARM ) + + uint8_t m_mbr_params_page[CODE_PAGE_SIZE] __attribute__((at(NRF_MBR_PARAMS_PAGE_ADDRESS))) __attribute__((used)); + +#elif defined ( __GNUC__ ) + + uint8_t m_mbr_params_page[CODE_PAGE_SIZE] __attribute__ ((section(".mbrParamsPage"))); + +#elif defined ( __ICCARM__ ) + + __no_init uint8_t m_mbr_params_page[CODE_PAGE_SIZE] @ NRF_MBR_PARAMS_PAGE_ADDRESS; + +#else + + #error Not a valid compiler/linker for m_mbr_params_page placement. + +#endif // Compiler specific + + +/**@brief This variable makes the linker script write the mbr parameters page address to the + * UICR register. This value will be written in the HEX file and thus written to the + * UICR when the bootloader is flashed into the chip. + */ +#if defined ( __CC_ARM ) + uint32_t m_uicr_mbr_params_page_address __attribute__((at(NRF_UICR_MBR_PARAMS_PAGE_ADDRESS))) + = NRF_MBR_PARAMS_PAGE_ADDRESS; + +#elif defined ( __GNUC__ ) + volatile uint32_t m_uicr_mbr_params_page_address __attribute__ ((section(".uicrMbrParamsPageAddress"))) + = NRF_MBR_PARAMS_PAGE_ADDRESS; +#elif defined ( __ICCARM__ ) + + __root const uint32_t m_uicr_mbr_params_page_address @ NRF_UICR_MBR_PARAMS_PAGE_ADDRESS + = NRF_MBR_PARAMS_PAGE_ADDRESS; + +#else + + #error Not a valid compiler/linker for m_mbr_params_page placement. + +#endif // Compiler specific + +#endif // #if defined( NRF52_SERIES ) + +#endif // #ifndef BL_SETTINGS_ACCESS_ONLY + +nrf_dfu_settings_t s_dfu_settings; + +//lint -save -esym(551, flash_operation_pending) +static bool flash_operation_pending; // barrier for reading flash +//lint -restore + +static dfu_flash_callback_t m_callback; + + +static void dfu_settings_write_callback(fs_evt_t const * const evt, fs_ret_t result) +{ + if (result == FS_SUCCESS) + { + flash_operation_pending = false; + } + if (m_callback != NULL) + { + m_callback(evt, result); + } +} + +static void delay_operation(void) +{ + nrf_delay_ms(100); + app_sched_execute(); +} + +static void wait_for_pending(void) +{ + while (flash_operation_pending == true) + { + NRF_LOG_DEBUG("Waiting for other flash operation to finish.\r\n"); + delay_operation(); + } +} + + +static void wait_for_queue(void) +{ +#ifdef BLE_STACK_SUPPORT_REQD + while (fs_queue_is_full()) + { + NRF_LOG_DEBUG("Waiting for available space on flash queue.\r\n"); + delay_operation(); + } +#endif +} + + +uint32_t nrf_dfu_settings_calculate_crc(void) +{ + // the crc is calculated from the s_dfu_settings struct, except the crc itself and the init command + return crc32_compute((uint8_t*)&s_dfu_settings + 4, sizeof(nrf_dfu_settings_t) - 4 - sizeof(s_dfu_settings.init_command), NULL); +} + + +void nrf_dfu_settings_init(void) +{ + NRF_LOG_DEBUG("running nrf_dfu_settings_init\r\n"); + + uint32_t crc; + + flash_operation_pending = false; + + // Copy the DFU settings out of flash and into a buffer in RAM. + memcpy((void*)&s_dfu_settings, &m_dfu_settings_buffer[0], sizeof(nrf_dfu_settings_t)); + + if(s_dfu_settings.crc != 0xFFFFFFFF) + { + // CRC is set. Content must be valid + crc = nrf_dfu_settings_calculate_crc(); + if(crc == s_dfu_settings.crc) + { + return; + } + } + + // Reached if nothing is configured or if CRC was wrong + NRF_LOG_DEBUG("!!!!!!!!!!!!!!! Resetting bootloader settings !!!!!!!!!!!\r\n"); + memset(&s_dfu_settings, 0x00, sizeof(nrf_dfu_settings_t)); + s_dfu_settings.settings_version = NRF_DFU_SETTINGS_VERSION; + APP_ERROR_CHECK(nrf_dfu_settings_write(NULL)); +} + + +ret_code_t nrf_dfu_settings_write(dfu_flash_callback_t callback) +{ + ret_code_t err_code = FS_SUCCESS; + NRF_LOG_DEBUG("Erasing old settings at: 0x%08x\r\n", (uint32_t)&m_dfu_settings_buffer[0]); + + // Wait for any ongoing operation (because of multiple calls to nrf_dfu_settings_write) + wait_for_pending(); + + flash_operation_pending = true; + m_callback = callback; + + do + { + wait_for_queue(); + + // Not setting the callback function because ERASE is required before STORE + // Only report completion on successful STORE. + err_code = nrf_dfu_flash_erase((uint32_t*)&m_dfu_settings_buffer[0], 1, NULL); + + } while (err_code == FS_ERR_QUEUE_FULL); + + + if (err_code != FS_SUCCESS) + { + NRF_LOG_ERROR("Erasing from flash memory failed.\r\n"); + flash_operation_pending = false; + return NRF_ERROR_INTERNAL; + } + + s_dfu_settings.crc = nrf_dfu_settings_calculate_crc(); + + NRF_LOG_DEBUG("Writing 0x%08x words\r\n", sizeof(nrf_dfu_settings_t)/4); + + static nrf_dfu_settings_t temp_dfu_settings; + memcpy(&temp_dfu_settings, &s_dfu_settings, sizeof(nrf_dfu_settings_t)); + + do + { + wait_for_queue(); + + err_code = nrf_dfu_flash_store((uint32_t*)&m_dfu_settings_buffer[0], + (uint32_t*)&temp_dfu_settings, + sizeof(nrf_dfu_settings_t)/4, + dfu_settings_write_callback); + + } while (err_code == FS_ERR_QUEUE_FULL); + + if (err_code != FS_SUCCESS) + { + NRF_LOG_ERROR("Storing to flash memory failed.\r\n"); + flash_operation_pending = false; + return NRF_ERROR_INTERNAL; + } + + NRF_LOG_DEBUG("Writing settings...\r\n"); + return NRF_SUCCESS; +} + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_settings.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..33dd1ee1fef88e2ad137ca31f7b7e0b7d606d9f1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_settings.h @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup nrf_dfu_settings DFU settings + * @{ + * @ingroup sdk_nrf_dfu + */ + +#ifndef NRF_DFU_SETTINGS_H__ +#define NRF_DFU_SETTINGS_H__ + +#include +#include "app_util_platform.h" +#include "nrf_dfu_types.h" +#include "nrf_dfu_flash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Global DFU settings. + * + * @note Using this variable is not thread-safe. + * + */ +extern nrf_dfu_settings_t s_dfu_settings; + + +/** @brief Function for writing DFU settings to flash. + * + * @param[in] callback Pointer to a function that is called after completing the write operation. + * + * @retval NRF_SUCCESS If the write process was successfully initiated. + * @retval NRF_ERROR_INTERNAL If a flash error occurred. + */ +ret_code_t nrf_dfu_settings_write(dfu_flash_callback_t callback); + + +/** @brief Function for initializing the DFU settings module. + */ +void nrf_dfu_settings_init(void); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_SETTINGS_H__ + +/**@} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_transport.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_transport.c new file mode 100644 index 0000000000000000000000000000000000000000..5039e0d8c0d05af479e2bb5a4415c86efc7706da --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_transport.c @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_dfu_transport.h" +#include "nrf_log.h" + + +#define DFU_TRANS_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(dfu_trans, nrf_dfu_transport_t, (i)) +#define DFU_TRANS_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(dfu_trans, nrf_dfu_transport_t) + +//lint -esym(526, dfu_transBase) -esym(526, dfu_transLimit) +NRF_SECTION_DEF(dfu_trans, const nrf_dfu_transport_t); + +uint32_t nrf_dfu_transports_init(void) +{ + uint32_t const num_transports = DFU_TRANS_SECTION_ITEM_COUNT; + uint32_t ret_val = NRF_SUCCESS; + + NRF_LOG_DEBUG("In nrf_dfu_transports_init\r\n"); + + NRF_LOG_DEBUG("num transports: %d\r\n", num_transports); + + for (uint32_t i = 0; i < num_transports; i++) + { + nrf_dfu_transport_t * const trans = DFU_TRANS_SECTION_ITEM_GET(i); + ret_val = trans->init_func(); + if (ret_val != NRF_SUCCESS) + { + break; + } + } + + NRF_LOG_DEBUG("After nrf_dfu_transports_init\r\n"); + + return ret_val; +} + + +uint32_t nrf_dfu_transports_close(void) +{ + uint32_t const num_transports = DFU_TRANS_SECTION_ITEM_COUNT; + uint32_t ret_val = NRF_SUCCESS; + + NRF_LOG_DEBUG("In nrf_dfu_transports_close\r\n"); + + NRF_LOG_DEBUG("num transports: %d\r\n", num_transports); + + for (uint32_t i = 0; i < num_transports; i++) + { + nrf_dfu_transport_t * const trans = DFU_TRANS_SECTION_ITEM_GET(i); + ret_val = trans->close_func(); + if (ret_val != NRF_SUCCESS) + { + break; + } + } + + NRF_LOG_DEBUG("After nrf_dfu_transports_init\r\n"); + + return ret_val; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_transport.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_transport.h new file mode 100644 index 0000000000000000000000000000000000000000..258f4420d4cd8432272c0690db05c30ffdc33108 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_transport.h @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup sdk_nrf_dfu_transport DFU transport + * @{ + * @ingroup sdk_nrf_bootloader + * @brief Generic Device Firmware Update (DFU) transport interface. + * + * @details The DFU transport module defines a generic interface that must + * be implemented for each transport layer. + */ + +#ifndef NRF_DFU_TRANSPORT_H__ +#define NRF_DFU_TRANSPORT_H__ + +#include +#include "nrf_section.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Function type for initializing a DFU transport. + * + * @details This function initializes a DFU transport. The implementation + * of the function must initialize DFU mode and stay in service + * until either the device is reset or the DFU operation is finalized. + * When the DFU transport receives requests, it should call @ref nrf_dfu_req_handler_on_req for handling the requests. + * + * @retval NRF_SUCCESS If initialization was successful for the transport. Any other return code indicates that the DFU transport could not be initialized. + */ +typedef uint32_t (*nrf_dfu_init_fn_t)(void); + + +/** @brief Function type for closing down a DFU transport. + * + * @details This function closes down a DFU transport in a gentle way. + * + * @retval NRF_SUCCESS If closing was successful for the transport. Any other return code indicates that the DFU transport could not be closed closed down. + */ +typedef uint32_t (*nrf_dfu_disconnect_fn_t)(void); + + +/** @brief DFU transport registration. + * + * @details Every DFU transport must provide a registration of the initialization function. + */ +typedef struct +{ + nrf_dfu_init_fn_t init_func; /**< Registration of the init function to run to initialize a DFU transport. */ + nrf_dfu_disconnect_fn_t close_func; /**< Registration of the close function to close down a DFU transport. */ +} nrf_dfu_transport_t; + + +/** @brief Function for initializing all the registered DFU transports. + * + * @retval NRF_SUCCESS If all DFU transport were initialized successfully. + * Any other error code indicates that at least one DFU + * transport could not be initialized. + */ +uint32_t nrf_dfu_transports_init(void); + +/** @brief Function for closing down all the registered DFU transports. + * + * @retval NRF_SUCCESS If all DFU transport were closed down successfully. + * Any other error code indicates that at least one DFU + * transport could not be closed down. + */ +uint32_t nrf_dfu_transports_close(void); + + +/** @brief Macro for registering a DFU transport by using section variables. + * + * @details This macro places a variable in a section named "dfu_trans", which + * is initialized by @ref nrf_dfu_transports_init. + */ +#define DFU_TRANSPORT_REGISTER(trans_var) NRF_SECTION_ITEM_REGISTER(dfu_trans, trans_var) + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_TRANSPORT_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_types.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_types.h new file mode 100644 index 0000000000000000000000000000000000000000..6b26f7114fb7aa6721f3d086b4bdbb1bae980009 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_types.h @@ -0,0 +1,278 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup sdk_nrf_dfu_types DFU types + * @{ + * @ingroup sdk_nrf_dfu + */ + +#ifndef NRF_DFU_TYPES_H__ +#define NRF_DFU_TYPES_H__ + +#include +#include + +#include "nrf.h" +#include "nrf_mbr.h" +#ifdef SOFTDEVICE_PRESENT +#include "nrf_sdm.h" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(SOFTDEVICE_PRESENT) + +#include "nrf_sdm.h" + +/** @brief Start address of the SoftDevice (excluding the area for the MBR). + */ +#define SOFTDEVICE_REGION_START MBR_SIZE + + +#ifndef CODE_REGION_1_START +#define CODE_REGION_1_START SD_SIZE_GET(MBR_SIZE) +#endif + + +#else + +#ifndef CODE_REGION_1_START +#define CODE_REGION_1_START MBR_SIZE +#endif + +#endif + + +#define INIT_COMMAND_MAX_SIZE 256 /**< Maximum size of the init command stored in dfu_settings. */ + +/** @brief Size of a flash codepage. This value is used for calculating the size of the reserved + * flash space in the bootloader region. It is checked against NRF_UICR->CODEPAGESIZE + * at run time to ensure that the region is correct. + */ +#if defined(NRF51) + #define CODE_PAGE_SIZE (PAGE_SIZE_IN_WORDS * sizeof(uint32_t)) +#elif defined(NRF52) || defined(NRF52840_XXAA) + #define CODE_PAGE_SIZE (MBR_PAGE_SIZE_IN_WORDS * sizeof(uint32_t)) +#else + #error "Architecture not set." +#endif + + +/** @brief Maximum size of a data object.*/ +#if defined( NRF51 ) + #define DATA_OBJECT_MAX_SIZE (CODE_PAGE_SIZE * 4) +#elif defined( NRF52_SERIES ) || defined ( __SDK_DOXYGEN__ ) + #define DATA_OBJECT_MAX_SIZE (CODE_PAGE_SIZE) +#else + #error "Architecture not set." +#endif + +/** @brief Page location of the bootloader settings address. + */ + +#if defined ( NRF51 ) + #define BOOTLOADER_SETTINGS_ADDRESS (0x0003FC00UL) +#elif defined( NRF52832_XXAA ) + #define BOOTLOADER_SETTINGS_ADDRESS (0x0007F000UL) +#elif defined( NRF52840_XXAA ) + #define BOOTLOADER_SETTINGS_ADDRESS (0x000FF000UL) +#else + #error No valid target set for BOOTLOADER_SETTINGS_ADDRESS. +#endif + + + +#if defined(NRF52832_XXAA) + +/** + * @brief MBR parameters page in UICR. + * + * Register location in UICR where the page address of the MBR parameters page is stored (only used by the nRF52 MBR). + * + * @note If the value at the given location is 0xFFFFFFFF, no MBR parameters page is set. + */ +#define NRF_UICR_MBR_PARAMS_PAGE_ADDRESS (NRF_UICR_BASE + 0x18) + + +/** @brief Page location of the MBR parameters page address. + * + */ +#define NRF_MBR_PARAMS_PAGE_ADDRESS (0x0007E000UL) + +#endif + +#if defined(NRF52840_XXAA) + +/** + * @brief MBR parameters page in UICR. + * + * Register location in UICR where the page address of the MBR parameters page is stored (only used by the nRF52 MBR). + * + * @note If the value at the given location is 0xFFFFFFFF, no MBR parameters page is set. + */ +#define NRF_UICR_MBR_PARAMS_PAGE_ADDRESS (NRF_UICR_BASE + 0x18) + + +/** @brief Page location of the MBR parameters page address. + * + */ +#define NRF_MBR_PARAMS_PAGE_ADDRESS (0x000FE000UL) + +#endif + + +/** @brief Size of the flash space reserved for application data. + */ +#ifndef DFU_APP_DATA_RESERVED +#define DFU_APP_DATA_RESERVED CODE_PAGE_SIZE * 3 +#endif + + +/** @brief Total size of the region between the SoftDevice and the bootloader. + */ +#define DFU_REGION_TOTAL_SIZE ((* (uint32_t *)NRF_UICR_BOOTLOADER_START_ADDRESS) - CODE_REGION_1_START) + +#ifdef SOFTDEVICE_PRESENT +/** @brief Start address of the SoftDevice (excluding the area for the MBR). + */ +#define SOFTDEVICE_REGION_START MBR_SIZE + + +/** @brief Size of the Code Region 0, found in the UICR.CLEN0 register. + * + * @details This value is identical to the start of Code Region 1. This value is used for + * compilation safety, because the linker will fail if the application expands + * into the bootloader. At run time, the bootloader uses the value found in UICR.CLEN0. + */ + +#ifndef CODE_REGION_1_START +#define CODE_REGION_1_START SD_SIZE_GET(MBR_SIZE) +#endif +#else +#ifndef CODE_REGION_1_START +#define CODE_REGION_1_START MBR_SIZE +#endif +#endif + +#define NRF_DFU_CURRENT_BANK_0 0x00 +#define NRF_DFU_CURRENT_BANK_1 0x01 + +#define NRF_DFU_BANK_LAYOUT_DUAL 0x00 +#define NRF_DFU_BANK_LAYOUT_SINGLE 0x01 + + +/** @brief DFU bank state codes. + * + * @details The DFU bank state indicates the content of a bank: + * A valid image of a certain type or an invalid image. + */ + +#define NRF_DFU_BANK_INVALID 0x00 /**< Invalid image. */ +#define NRF_DFU_BANK_VALID_APP 0x01 /**< Valid application. */ +#define NRF_DFU_BANK_VALID_SD 0xA5 /**< Valid SoftDevice. */ +#define NRF_DFU_BANK_VALID_BL 0xAA /**< Valid bootloader. */ +#define NRF_DFU_BANK_VALID_SD_BL 0xAC /**< Valid SoftDevice and bootloader. */ + + +/** @brief Description of a single bank. */ +#pragma pack(4) +typedef struct +{ + uint32_t image_size; /**< Size of the image in the bank. */ + uint32_t image_crc; /**< CRC of the image. If set to 0, the CRC is ignored. */ + uint32_t bank_code; /**< Identifier code for the bank. */ +} nrf_dfu_bank_t; + +/**@brief DFU progress. + * + * Be aware of the difference between objects and firmware images. A firmware image consists of multiple objects, each of a maximum size @ref DATA_OBJECT_MAX_SIZE. + */ +typedef struct +{ + uint32_t command_size; /**< The size of the current init command stored in the DFU settings. */ + uint32_t command_offset; /**< The offset of the currently received init command data. The offset will increase as the init command is received. */ + uint32_t command_crc; /**< The calculated CRC of the init command (calculated after the transfer is completed). */ + + uint32_t data_object_size; /**< The size of the last object created. Note that this size is not the size of the whole firmware image.*/ + + uint32_t firmware_image_crc; /**< CRC value of the current firmware (continuously calculated as data is received). */ + uint32_t firmware_image_crc_last; /**< The CRC of the last executed object. */ + uint32_t firmware_image_offset; /**< The offset of the current firmware image being transferred. Note that this offset is the offset in the entire firmware image and not only the current object. */ + uint32_t firmware_image_offset_last;/**< The offset of the last executed object from the start of the firmware image. */ +} dfu_progress_t; + + +/**@brief DFU settings for application and bank data. + */ +typedef struct +{ + uint32_t crc; /**< CRC for the stored DFU settings, not including the CRC itself. If 0xFFFFFFF, the CRC has never been calculated. */ + uint32_t settings_version; /**< Version of the currect dfu settings struct layout.*/ + uint32_t app_version; /**< Version of the last stored application. */ + uint32_t bootloader_version; /**< Version of the last stored bootloader. */ + + uint32_t bank_layout; /**< Bank layout: single bank or dual bank. This value can change. */ + uint32_t bank_current; /**< The bank that is currently used. */ + + nrf_dfu_bank_t bank_0; /**< Bank 0. */ + nrf_dfu_bank_t bank_1; /**< Bank 1. */ + + uint32_t write_offset; /**< Write offset for the current operation. */ + uint32_t sd_size; /**< SoftDevice size (if combined BL and SD). */ + + dfu_progress_t progress; /**< Current DFU progress. */ + + uint32_t enter_buttonless_dfu; + uint8_t init_command[INIT_COMMAND_MAX_SIZE]; /**< Buffer for storing the init command. */ +} nrf_dfu_settings_t; +#pragma pack() // revert pack settings + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_TYPES_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_utils.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..dd72353099ca96c601e5579cce8e4f7aa2793b1f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_utils.c @@ -0,0 +1,625 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_dfu_utils.h" + +#include +#include "nrf_dfu_settings.h" +#include "nrf_dfu_mbr.h" +#include "nrf_bootloader_app_start.h" +#include "nrf_bootloader_info.h" +#include "crc32.h" +#include "nrf_log.h" +#include "app_timer.h" + + +static app_timer_t nrf_dfu_utils_reset_delay_timer_data = { {0} }; +const app_timer_id_t nrf_dfu_utils_reset_delay_timer = &nrf_dfu_utils_reset_delay_timer_data; + +/** + * Round up val to the next page boundry + */ +static uint32_t align_to_page(uint32_t val, uint32_t page_size) +{ + return ((val + page_size - 1 ) &~ (page_size - 1)); +} + + +static void nrf_dfu_invalidate_bank(nrf_dfu_bank_t * p_bank) +{ + // Set the bank-code to invalid, and reset size/CRC + memset(p_bank, 0, sizeof(nrf_dfu_bank_t)); + + // Reset write pointer after completed operation + s_dfu_settings.write_offset = 0; + + // Reset SD size + s_dfu_settings.sd_size = 0; + + // Promote dual bank layout + s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_DUAL; + + // Signify that bank 0 is empty + s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_0; +} + + +/** @brief Function to continue App update + * + * @details This function will be called after reset if there is a valid application in Bank1 + * required to be copied down to bank0. + * + * @param[in] src_addr Source address of the application to copy from Bank1 to Bank0. + * + * @retval NRF_SUCCESS Continuation was successful. + * @retval NRF_ERROR_NULL Invalid data during compare. + * @retval FS_ERR_UNALIGNED_ADDR A call to fstorage was not aligned to a page boundary or the address was not word aliged. + * @retval FS_ERR_INVALID_ADDR The destination of a call to fstorage does not point to + * the start of a flash page or the operation would + * go beyond the flash memory boundary. + * @retval FS_ERR_NOT_INITIALIZED The fstorage module is not initialized. + * @retval FS_ERR_INVALID_CFG The initialization of the fstorage module is invalid. + * @retval FS_ERR_NULL_ARG A call to fstorage had an invalid NULL argument. + * @retval FS_ERR_INVALID_ARG A call to fstorage had invalid arguments. + * @retval FS_ERR_QUEUE_FULL If the internal operation queue of the fstorage module is full. + * @retval FS_ERR_FAILURE_SINCE_LAST If an error occurred in another transaction and fstorage cannot continue before + * the event has been dealt with. + */ +static uint32_t nrf_dfu_app_continue(uint32_t src_addr) +{ + // This function only in use when new app is present in bank 1 + uint32_t const image_size = s_dfu_settings.bank_1.image_size; + uint32_t const split_size = CODE_PAGE_SIZE; // Arbitrary number that must be page aligned + + uint32_t ret_val = NRF_SUCCESS; + uint32_t target_addr = MAIN_APPLICATION_START_ADDR + s_dfu_settings.write_offset; + uint32_t length_left = (image_size - s_dfu_settings.write_offset); + uint32_t cur_len; + uint32_t crc; + + NRF_LOG_DEBUG("Enter nrf_dfu_app_continue\r\n"); + + // Copy the application down safely + do + { + cur_len = (length_left > split_size) ? split_size : length_left; + + // Erase the target page + ret_val = nrf_dfu_flash_erase((uint32_t*) target_addr, split_size / CODE_PAGE_SIZE, NULL); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + // Flash one page + ret_val = nrf_dfu_flash_store((uint32_t*)target_addr, (uint32_t*)src_addr, cur_len, NULL); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + ret_val = nrf_dfu_mbr_compare((uint32_t*)target_addr, (uint32_t*)src_addr, cur_len); + if (ret_val != NRF_SUCCESS) + { + // We will not retry the copy + NRF_LOG_ERROR("Invalid data during compare: target: 0x%08x, src: 0x%08x\r\n", target_addr, src_addr); + return ret_val; + } + + // Erase the head (to handle growing bank 0) + ret_val = nrf_dfu_flash_erase((uint32_t*) src_addr, split_size / CODE_PAGE_SIZE, NULL); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_ERROR("App update: Failure erasing page at addr: 0x%08x\r\n", src_addr); + return ret_val; + } + + s_dfu_settings.write_offset += cur_len; + ret_val = nrf_dfu_settings_write(NULL); + + target_addr += cur_len; + src_addr += cur_len; + + length_left -= cur_len; + } + while(length_left > 0); + + // Check the crc of the copied data. Enable if so. + crc = crc32_compute((uint8_t*)MAIN_APPLICATION_START_ADDR, image_size, NULL); + + if (crc == s_dfu_settings.bank_1.image_crc) + { + NRF_LOG_DEBUG("Setting app as valid\r\n"); + s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_VALID_APP; + s_dfu_settings.bank_0.image_crc = crc; + s_dfu_settings.bank_0.image_size = image_size; + } + else + { + NRF_LOG_ERROR("CRC computation failed for copied app: " + "src crc: 0x%08x, res crc: 0x%08x\r\n", + s_dfu_settings.bank_1.image_crc, + crc); + } + + nrf_dfu_invalidate_bank(&s_dfu_settings.bank_1); + ret_val = nrf_dfu_settings_write(NULL); + + return ret_val; +} + +/** @brief Function to execute the continuation of a SoftDevice update. + * + * @param[in] src_addr Source address of the SoftDevice to copy from. + * @param[in] p_bank Pointer to the bank where the SoftDevice resides. + * + * @retval NRF_SUCCESS Continuation was successful. + * @retval NRF_ERROR_INVALID_LENGTH Invalid len + * @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. + * @retval NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + * @retval NRF_ERROR_NULL If the content of the memory blocks differs after copying. + */ +#if defined(SOFTDEVICE_PRESENT) +static uint32_t nrf_dfu_sd_continue_impl(uint32_t src_addr, + nrf_dfu_bank_t * p_bank) +{ + uint32_t ret_val = NRF_SUCCESS; + uint32_t target_addr = SOFTDEVICE_REGION_START + s_dfu_settings.write_offset; + uint32_t length_left = align_to_page(s_dfu_settings.sd_size - s_dfu_settings.write_offset, CODE_PAGE_SIZE); + uint32_t split_size = align_to_page(length_left / 4, CODE_PAGE_SIZE); + + NRF_LOG_DEBUG("Enter nrf_bootloader_dfu_sd_continue\r\n"); + + // This can be a continuation due to a power failure + src_addr += s_dfu_settings.write_offset; + + if (s_dfu_settings.sd_size != 0 && s_dfu_settings.write_offset == s_dfu_settings.sd_size) + { + NRF_LOG_DEBUG("SD already copied\r\n"); + return NRF_SUCCESS; + } + + if (s_dfu_settings.write_offset == 0) + { + NRF_LOG_DEBUG("Updating SD. Old SD ver: %d, New ver: %d\r\n", SD_VERSION_GET(MBR_SIZE) / 100000, SD_VERSION_GET(src_addr) / 100000); + } + + do + { + // If less than split size remain, reduce split size to avoid overwriting bank 0. + if (split_size > length_left) + { + split_size = align_to_page(length_left, CODE_PAGE_SIZE); + } + + NRF_LOG_DEBUG("Copying [0x%08x-0x%08x] to [0x%08x-0x%08x]: Len: 0x%08x\r\n", src_addr, src_addr + split_size, target_addr, target_addr + split_size, split_size); + + // Copy a chunk of the SD. Size in words + ret_val = nrf_dfu_mbr_copy_sd((uint32_t*)target_addr, (uint32_t*)src_addr, split_size); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_ERROR("Failed to copy SD: target: 0x%08x, src: 0x%08x, len: 0x%08x\r\n", target_addr, src_addr, split_size); + return ret_val; + } + + NRF_LOG_DEBUG("Finished copying [0x%08x-0x%08x] to [0x%08x-0x%08x]: Len: 0x%08x\r\n", src_addr, src_addr + split_size, target_addr, target_addr + split_size, split_size); + + // Validate copy. Size in words + ret_val = nrf_dfu_mbr_compare((uint32_t*)target_addr, (uint32_t*)src_addr, split_size); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_ERROR("Failed to Compare SD: target: 0x%08x, src: 0x%08x, len: 0x%08x\r\n", target_addr, src_addr, split_size); + return ret_val; + } + + NRF_LOG_DEBUG("Validated 0x%08x-0x%08x to 0x%08x-0x%08x: Size: 0x%08x\r\n", src_addr, src_addr + split_size, target_addr, target_addr + split_size, split_size); + + target_addr += split_size; + src_addr += split_size; + + if (split_size > length_left) + { + length_left = 0; + } + else + { + length_left -= split_size; + } + + NRF_LOG_DEBUG("Finished with the SD update.\r\n"); + + // Save the updated point of writes in case of power loss + s_dfu_settings.write_offset = s_dfu_settings.sd_size - length_left; + ret_val = nrf_dfu_settings_write(NULL); + } + while (length_left > 0); + + return ret_val; +} + +/** + * @brief Flash storage callback used to reset the device if no new DFU is initiated within the timers expiration. + * + * After the completion of a SD, BL or SD + BL update, the controller might want to update the + * application as well. Because of this, the DFU target will stay in bootloader mode for some + * time after completion. However, if no such update is received the device should reset to + * to look for a valid app and resume regular operation. + */ +static void reset_device_callback( fs_evt_t const * const evt, fs_ret_t result ) +{ + // Verify that the current application is valid. + if (nrf_dfu_app_is_valid()) + { + // Start a timer which resets the device on expiration. + NRF_LOG_DEBUG("Starting reset delay timer\r\n"); + uint32_t err_code = app_timer_start(nrf_dfu_utils_reset_delay_timer, APP_TIMER_TICKS(RESET_DELAY_LENGTH_MS), NULL); + APP_ERROR_CHECK(err_code); + } +} + + +/** @brief Function to continue SoftDevice update + * + * @details This function will be called after reset if there is a valid SoftDevice in Bank0 or Bank1 + * required to be relocated and activated through MBR commands. + * + * @param[in] src_addr Source address of the SoftDevice to copy from. + * @param[in] p_bank Pointer to the bank where the SoftDevice resides. + * + * @retval NRF_SUCCESS Continuation was successful. + * @retval NRF_ERROR_INVALID_LENGTH Invalid len + * @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. + * @retval NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + * @retval NRF_ERROR_NULL If the content of the memory blocks differs after copying. + */ +static uint32_t nrf_dfu_sd_continue(uint32_t src_addr, + nrf_dfu_bank_t * p_bank) +{ + uint32_t ret_val; + + ret_val = nrf_dfu_sd_continue_impl(src_addr, p_bank); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_ERROR("SD update continuation failed\r\n"); + return ret_val; + } + + nrf_dfu_invalidate_bank(p_bank); + + // Upon successful completion, the callback function will be called and reset the device. If a valid app i present, it will launch. + NRF_LOG_DEBUG("Writing settings and reseting device.\r\n"); + ret_val = nrf_dfu_settings_write(reset_device_callback); + + return ret_val; +} +#endif + +/** @brief Function to continue Bootloader update + * + * @details This function will be called after reset if there is a valid Bootloader in Bank0 or Bank1 + * required to be relocated and activated through MBR commands. + * + * @param[in] src_addr Source address of the BL to copy from. + * @param[in] p_bank Pointer to the bank where the SoftDevice resides. + * + * @return This fucntion will not return if the bootloader is copied succesfully. + * After the copy is verified the device will reset and start the new bootloader. + * + * @retval NRF_SUCCESS Continuation was successful. + * @retval NRF_ERROR_INVALID_LENGTH Invalid length of flash operation. + * @retval NRF_ERROR_NO_MEM if no parameter page is provided (see sds for more info). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. + * @retval NRF_ERROR_INTERNAL internal error that should not happen. + * @retval NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set. + */ +static uint32_t nrf_dfu_bl_continue(uint32_t src_addr, nrf_dfu_bank_t * p_bank) +{ + uint32_t ret_val = NRF_SUCCESS; + uint32_t const len = (p_bank->image_size - s_dfu_settings.sd_size); + + // if the update is a combination of BL + SD, offset with SD size to get BL start address + src_addr += s_dfu_settings.sd_size; + + NRF_LOG_DEBUG("Verifying BL: Addr: 0x%08x, Src: 0x%08x, Len: 0x%08x\r\n", MAIN_APPLICATION_START_ADDR, src_addr, len); + + + // If the bootloader is the same as the banked version, the copy is finished + ret_val = nrf_dfu_mbr_compare((uint32_t*)BOOTLOADER_START_ADDR, (uint32_t*)src_addr, len); + if (ret_val == NRF_SUCCESS) + { + NRF_LOG_DEBUG("Bootloader was verified\r\n"); + + // Invalidate bank, marking completion + nrf_dfu_invalidate_bank(p_bank); + + // Upon successful completion, the callback function will be called and reset the device. If a valid app i present, it will launch. + NRF_LOG_DEBUG("Writing settings and reseting device.\r\n"); + ret_val = nrf_dfu_settings_write(reset_device_callback); + } + else + { + NRF_LOG_DEBUG("Bootloader not verified, copying: Src: 0x%08x, Len: 0x%08x\r\n", src_addr, len); + // Bootloader is different than the banked version. Continue copy + // Note that if the SD and BL was combined, then the split point between them is in s_dfu_settings.sd_size + ret_val = nrf_dfu_mbr_copy_bl((uint32_t*)src_addr, len); + if(ret_val != NRF_SUCCESS) + { + NRF_LOG_ERROR("Request to copy BL failed\r\n"); + } + } + + return ret_val; +} + + +/** @brief Function to continue combined Bootloader and SoftDevice update + * + * @details This function will be called after reset if there is a valid Bootloader and SoftDevice in Bank0 or Bank1 + * required to be relocated and activated through MBR commands. + * + * @param[in] src_addr Source address of the combined Bootloader and SoftDevice to copy from. + * @param[in] p_bank Pointer to the bank where the SoftDevice resides. + * + * @retval NRF_SUCCESS Continuation was successful. + * @retval NRF_ERROR_INVALID_LENGTH Invalid len + * @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. + * @retval NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + * @retval NRF_ERROR_NULL If the content of the memory blocks differs after copying. + * @retval NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set. + */ +#if defined(SOFTDEVICE_PRESENT) +static uint32_t nrf_dfu_sd_bl_continue(uint32_t src_addr, nrf_dfu_bank_t * p_bank) +{ + uint32_t ret_val = NRF_SUCCESS; + + NRF_LOG_DEBUG("Enter nrf_dfu_sd_bl_continue\r\n"); + + ret_val = nrf_dfu_sd_continue_impl(src_addr, p_bank); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_ERROR("SD+BL: SD copy failed\r\n"); + return ret_val; + } + + ret_val = nrf_dfu_bl_continue(src_addr, p_bank); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_ERROR("SD+BL: BL copy failed\r\n"); + return ret_val; + } + + return ret_val; +} +#endif + +static uint32_t nrf_dfu_continue_bank(nrf_dfu_bank_t * p_bank, uint32_t src_addr, uint32_t * p_enter_dfu_mode) +{ + uint32_t ret_val = NRF_SUCCESS; + + switch (p_bank->bank_code) + { + case NRF_DFU_BANK_VALID_APP: + NRF_LOG_DEBUG("Valid App\r\n"); + if(s_dfu_settings.bank_current == NRF_DFU_CURRENT_BANK_1) + { + // Only continue copying if valid app in bank1 + ret_val = nrf_dfu_app_continue(src_addr); + } + break; +#if defined(SOFTDEVICE_PRESENT) + case NRF_DFU_BANK_VALID_SD: + NRF_LOG_DEBUG("Valid SD\r\n"); + // There is a valid SD that needs to be copied (or continued) + ret_val = nrf_dfu_sd_continue(src_addr, p_bank); + (*p_enter_dfu_mode) = 1; + break; +#endif + + case NRF_DFU_BANK_VALID_BL: + NRF_LOG_DEBUG("Valid BL\r\n"); + // There is a valid BL that must be copied (or continued) + ret_val = nrf_dfu_bl_continue(src_addr, p_bank); + break; + +#if defined(SOFTDEVICE_PRESENT) + case NRF_DFU_BANK_VALID_SD_BL: + NRF_LOG_DEBUG("Valid SD + BL\r\n"); + // There is a valid SD + BL that must be copied (or continued) + ret_val = nrf_dfu_sd_bl_continue(src_addr, p_bank); + // Set the bank-code to invalid, and reset size/CRC + (*p_enter_dfu_mode) = 1; + break; +#endif + + case NRF_DFU_BANK_INVALID: + default: + NRF_LOG_ERROR("Single: Invalid bank\r\n"); + break; + } + + return ret_val; +} + +uint32_t nrf_dfu_continue(uint32_t * p_enter_dfu_mode) +{ + uint32_t ret_val; + nrf_dfu_bank_t * p_bank; + uint32_t src_addr = CODE_REGION_1_START; + + NRF_LOG_DEBUG("Enter nrf_dfu_continue\r\n"); + + if (s_dfu_settings.bank_layout == NRF_DFU_BANK_LAYOUT_SINGLE ) + { + p_bank = &s_dfu_settings.bank_0; + } + else if(s_dfu_settings.bank_current == NRF_DFU_CURRENT_BANK_0) + { + p_bank = &s_dfu_settings.bank_0; + } + else + { + p_bank = &s_dfu_settings.bank_1; + src_addr += align_to_page(s_dfu_settings.bank_0.image_size, CODE_PAGE_SIZE); + } + + ret_val = nrf_dfu_continue_bank(p_bank, src_addr, p_enter_dfu_mode); + return ret_val; +} + + +bool nrf_dfu_app_is_valid(void) +{ + NRF_LOG_DEBUG("Enter nrf_dfu_app_is_valid\r\n"); + if (s_dfu_settings.bank_0.bank_code != NRF_DFU_BANK_VALID_APP) + { + // Bank 0 has no valid app. Nothing to boot + NRF_LOG_DEBUG("Return false in valid app check\r\n"); + return false; + } + + // If CRC == 0, this means CRC check is skipped. + if (s_dfu_settings.bank_0.image_crc != 0) + { + uint32_t crc = crc32_compute((uint8_t*) CODE_REGION_1_START, + s_dfu_settings.bank_0.image_size, + NULL); + + if (crc != s_dfu_settings.bank_0.image_crc) + { + // CRC does not match with what is stored. + NRF_LOG_DEBUG("Return false in CRC\r\n"); + return false; + } + } + + NRF_LOG_DEBUG("Return true. App was valid\r\n"); + return true; +} + + +uint32_t nrf_dfu_find_cache(uint32_t size_req, bool dual_bank_only, uint32_t * p_address) +{ + uint32_t free_size = DFU_REGION_TOTAL_SIZE - DFU_APP_DATA_RESERVED; + nrf_dfu_bank_t * p_bank; + + NRF_LOG_DEBUG("Enter nrf_dfu_find_cache\r\n"); + + if (p_address == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Simple check if size requirement can me met + if(free_size < size_req) + { + NRF_LOG_DEBUG("No way to fit the new firmware on device\r\n"); + return NRF_ERROR_NO_MEM; + } + + NRF_LOG_DEBUG("Bank content\r\n"); + NRF_LOG_DEBUG("Bank type: %d\r\n", s_dfu_settings.bank_layout); + NRF_LOG_DEBUG("Bank 0 code: 0x%02x: Size: %d\r\n", s_dfu_settings.bank_0.bank_code, s_dfu_settings.bank_0.image_size); + NRF_LOG_DEBUG("Bank 1 code: 0x%02x: Size: %d\r\n", s_dfu_settings.bank_1.bank_code, s_dfu_settings.bank_1.image_size); + + // Setting bank_0 as candidate + p_bank = &s_dfu_settings.bank_0; + + // Setting candidate address + (*p_address) = MAIN_APPLICATION_START_ADDR; + + // Calculate free size + if (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP) + { + // Valid app present. + + NRF_LOG_DEBUG("free_size before bank select: %d\r\n", free_size); + + free_size -= align_to_page(p_bank->image_size, CODE_PAGE_SIZE); + + NRF_LOG_DEBUG("free_size: %d, size_req: %d\r\n", free_size, size_req); + + // Check if we can fit the new in the free space or if removal of old app is required. + if(size_req > free_size) + { + // Not enough room in free space (bank_1) + if ((dual_bank_only)) + { + NRF_LOG_ERROR("Failure: dual bank restriction\r\n"); + return NRF_ERROR_NO_MEM; + } + + // Can only support single bank update, clearing old app. + s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_SINGLE; + s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_0; + p_bank = &s_dfu_settings.bank_0; + NRF_LOG_DEBUG("Enforcing single bank\r\n"); + } + else + { + // Room in bank_1 for update + // Ensure we are using dual bank layout + s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_DUAL; + s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1; + p_bank = &s_dfu_settings.bank_1; + // Set to first free page boundry after previous app + (*p_address) += align_to_page(s_dfu_settings.bank_0.image_size, CODE_PAGE_SIZE); + NRF_LOG_DEBUG("Using second bank\r\n"); + } + } + else + { + // No valid app present. Promoting dual bank. + s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_DUAL; + s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_0; + + p_bank = &s_dfu_settings.bank_0; + NRF_LOG_DEBUG("No previous, using bank 0\r\n"); + } + + // Set the bank-code to invalid, and reset size/CRC + memset(p_bank, 0, sizeof(nrf_dfu_bank_t)); + + // Store the Firmware size in the bank for continuations + p_bank->image_size = size_req; + return NRF_SUCCESS; +} + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_utils.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..7111c2c36b170b2de6155acef4203a16ea33f662 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/dfu/nrf_dfu_utils.h @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup sdk_nrf_dfu_utils DFU utilities + * @{ + * @ingroup sdk_nrf_dfu + */ + +#ifndef NRF_DFU_UTILS_H__ +#define NRF_DFU_UTILS_H__ + +#include +#include +#include "nrf_dfu_types.h" +#include "app_timer.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +// 3400ms is the smallest stable value with nrf connect for PC v1.1.1. +// 7500ms is the smallest stable value with nrf connect for Android v1.1.1. +// Smaller values may allow the device to reset before the next DFU transation is started. +#define RESET_DELAY_LENGTH_MS 10000 +extern const app_timer_id_t nrf_dfu_utils_reset_delay_timer; + +/** @brief Function for continuing an ongoing DFU operation. + * + * @details This function initiates or continues the DFU copy-back + * routines. These routines are fail-safe operations to activate + * either a new SoftDevice, Bootloader, combination of SoftDevice and + * Bootloader, or a new application. + * + * @details This function relies on accessing MBR commands through supervisor calls. + * It does not rely on the SoftDevice for flash operations. + * + * @note When updating the bootloader or both bootloader and SoftDevice in combination, + * this function does not return, but rather initiate a reboot to activate + * the new bootloader. + * + * @param[in,out] p_enter_dfu_mode True if the continuation failed or the update requires DFU mode. + * + * @retval NRF_SUCCESS If the DFU operation was continued successfully. + * Any other error code indicates that the DFU operation could + * not be continued. + */ +uint32_t nrf_dfu_continue(uint32_t * p_enter_dfu_mode); + + +/** @brief Function for checking if the main application is valid. + * + * @details This function checks if there is a valid application + * located at Bank 0. + * + * @retval true If a valid application has been detected. + * @retval false If there is no valid application. + */ +bool nrf_dfu_app_is_valid(void); + + +/** @brief Function for finding a cache write location for the DFU process. + * + * @details This function checks the size requirements and selects a location for + * placing the cache of the DFU images. + * The function tries to find enough space in Bank 1. If there is not enough space, + * the present application is erased. + * + * @param[in] size_req Requirements for the size of the new image. + * @param[in] dual_bank_only True to enforce dual-bank updates. In this case, if there + * is not enough space for caching the DFU image, the existing + * application is retained and the function returns an error. + * @param[out] p_address Updated to the cache address if a cache location is found. + * + * @retval NRF_SUCCESS If a cache location was found for the DFU process. + * @retval NRF_ERROR_NO_MEM If there is no space available on the device to continue the DFU process. + */ +uint32_t nrf_dfu_find_cache(uint32_t size_req, bool dual_bank_only, uint32_t * p_address); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_UTILS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader.c new file mode 100644 index 0000000000000000000000000000000000000000..57330d625793f13693401d3302ba876454424b62 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader.c @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_bootloader.h" + +#include "compiler_abstraction.h" +#include "nrf.h" +#include "nrf_bootloader_app_start.h" +#include "nrf_log.h" +#include "nrf_dfu.h" +#include "nrf_error.h" + + +/** @brief Weak implemenation of nrf_dfu_init + * + * @note This function will be overridden if nrf_dfu.c is + * compiled and linked with the project + */ + #if (__LINT__ != 1) +__WEAK uint32_t nrf_dfu_init(void) +{ + NRF_LOG_DEBUG("in weak nrf_dfu_init\r\n"); + return NRF_SUCCESS; +} +#endif + + +/** @brief Weak implementation of nrf_dfu_init + * + * @note This function must be overridden in application if + * user-specific initialization is needed. + */ +__WEAK uint32_t nrf_dfu_init_user(void) +{ + NRF_LOG_DEBUG("in weak nrf_dfu_init_user\r\n"); + return NRF_SUCCESS; +} + + +uint32_t nrf_bootloader_init(void) +{ + NRF_LOG_DEBUG("In nrf_bootloader_init\r\n"); + + uint32_t ret_val = NRF_SUCCESS; + + #if 0 + // Call user-defined init function if implemented + ret_val = nrf_dfu_init_user(); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + #endif + + // Call DFU init function if implemented + ret_val = nrf_dfu_init(); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + NRF_LOG_DEBUG("After nrf_bootloader_init\r\n"); + return ret_val; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader.h new file mode 100644 index 0000000000000000000000000000000000000000..f0f05b36d52a4efc669a8571f58afd285907828c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader.h @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup sdk_nrf_bootloader Bootloader modules + * @ingroup app_common + * @brief Modules for creating a bootloader. + * + * @defgroup sdk_bootloader Bootloader + * @{ + * @ingroup sdk_nrf_bootloader + * @brief Basic bootloader. + * + * The bootloader module can be used to implement a basic bootloader that + * can be extended with, for example, Device Firmware Update (DFU) support + * or custom functionality. + */ + +#ifndef NRF_BOOTLOADER_H__ +#define NRF_BOOTLOADER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for initializing the bootloader. + * + * @details This function is the entry point of all bootloader operations. + * If DFU functionality is compiled in, the DFU process is initialized + * when running this function. + * + * @retval NRF_SUCCESS If the bootloader was successfully initialized. + * Any other return code indicates that the operation failed. + */ +uint32_t nrf_bootloader_init(void); + + +/** @brief Function for customizing the bootloader initialization. + * + * @details This function is called during the initialization of the bootloader. + * It is implemented as weak function that can be overridden in the main file of the application. + * + * @retval NRF_SUCCESS If the user initialization was run successfully. + */ +uint32_t nrf_bootloader_user_init(void); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BOOTLOADER_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_app_start.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_app_start.c new file mode 100644 index 0000000000000000000000000000000000000000..18a84b1139b7e0c2b49f35c1733f722be82d669b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_app_start.c @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "nrf_bootloader_app_start.h" +#include "nrf_log.h" +#include "nrf_dfu_mbr.h" + +#if defined(SOFTDEVICE_PRESENT) +#include "nrf_sdm.h" +#endif + +extern void nrf_bootloader_app_start_impl(uint32_t start_addr); + +void nrf_bootloader_app_start(uint32_t start_addr) +{ + NRF_LOG_DEBUG("Running nrf_bootloader_app_start with address: 0x%08x\r\n", start_addr); + uint32_t err_code; + + //NRF_LOG_INFO("Initializing SD in mbr\r\n"); + err_code = nrf_dfu_mbr_init_sd(); + if(err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Failed running nrf_dfu_mbr_init_sd\r\n"); + return; + } + + // Disable interrupts + NRF_LOG_DEBUG("Disabling interrupts\r\n"); + + NVIC->ICER[0]=0xFFFFFFFF; +#if defined(__NRF_NVIC_ISER_COUNT) && __NRF_NVIC_ISER_COUNT == 2 + NVIC->ICER[1]=0xFFFFFFFF; +#endif + + // Set the sd softdevice vector table base address + NRF_LOG_DEBUG("Setting SD vector table base: 0x%08x\r\n", start_addr); + err_code = sd_softdevice_vector_table_base_set(start_addr); + if(err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Failed running sd_softdevice_vector_table_base_set\r\n"); + return; + } + + // Run application + nrf_bootloader_app_start_impl(start_addr); +} + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_app_start.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_app_start.h new file mode 100644 index 0000000000000000000000000000000000000000..8d5c7a3f09dc7f4444b93568e4c0e8737f57d6b4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_app_start.h @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup sdk_bootloader_app Application start + * @{ + * @ingroup sdk_bootloader + */ + +#ifndef NRF_BOOTLOADER_APP_START_H__ +#define NRF_BOOTLOADER_APP_START_H__ + +#include + +/**@brief Function for starting another application (and aborting the current one). + * + * @details This function uses the provided address to swap the stack pointer and then load + * the address of the reset handler to be executed. It checks the current system mode + * (thread/handler). If in thread mode, it resets into the other application. + * If in handler mode, isr_abort is executed to ensure that handler mode is left correctly. + * It then jumps into the reset handler of the other application. + * + * @note This function will never return, but issues a reset into the provided application. + * + * @param[in] start_addr Start address of the other application. This address must point to the + initial stack pointer of the application. + * + */ +void nrf_bootloader_app_start(uint32_t start_addr); + +#endif // NRF_BOOTLOADER_APP_START_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_app_start_asm.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_app_start_asm.c new file mode 100644 index 0000000000000000000000000000000000000000..47d16f74214cdb1f15803b66f909a008b5f6a283 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_app_start_asm.c @@ -0,0 +1,179 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "compiler_abstraction.h" + +#if defined ( __CC_ARM ) +__ASM void nrf_bootloader_app_start_impl(uint32_t start_addr) +{ + LDR R5, [R0] ; Get App initial MSP for bootloader. + MSR MSP, R5 ; Set the main stack pointer to the applications MSP. + LDR R0, [R0, #0x04] ; Load Reset handler into R0. This will be first argument to branch instruction (BX). + + MOVS R4, #0xFF ; Load ones to R4. + SXTB R4, R4 ; Sign extend R4 to obtain 0xFFFFFFFF instead of 0xFF. + MRS R5, IPSR ; Load IPSR to R5 to check for handler or thread mode. + CMP R5, #0x00 ; Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader. + BNE isr_abort ; If not zero we need to exit current ISR and jump to reset handler of bootloader. + + MRS R1, CONTROL ; Get CONTROL register value + MOVS R2, #0x02 ; load 2 to r2 + BICS R1, R2 ; clear value of CONTROL->SPSEL - > make sure MSP will be used + MSR CONTROL, R1 ; set the stack pointer to MSP + + MOV LR, R4 ; Clear the link register and set to ones to ensure no return, R4 = 0xFFFFFFFF. + BX R0 ; Branch to reset handler of bootloader. + +isr_abort + ; R4 contains ones from line above. Will be popped as R12 when exiting ISR (Cleaning up the registers). + MOV R5, R4 ; Fill with ones before jumping to reset handling. We be popped as LR when exiting ISR. Ensures no return to application. + MOV R6, R0 ; Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR. + MOVS r7, #0x21 ; Move MSB reset value of xPSR to R7. Will be popped as xPSR when exiting ISR. xPSR is 0x21000000 thus MSB is 0x21. + REV r7, r7 ; Reverse byte order to put 0x21 as MSB. + PUSH {r4-r7} ; Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR. + + MOVS R4, #0x00 ; Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers). + MOVS R5, #0x00 ; Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers). + MOVS R6, #0x00 ; Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers). + MOVS R7, #0x00 ; Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers). + PUSH {r4-r7} ; Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine. + + MOVS R0, #0xF9 ; Move the execution return command into register, 0xFFFFFFF9. + SXTB R0, R0 ; Sign extend R0 to obtain 0xFFFFFFF9 instead of 0xF9. + BX R0 ; No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application. + ALIGN +} + +#elif defined ( __GNUC__ ) + +void __attribute__ ((noinline)) nrf_bootloader_app_start_impl(uint32_t start_addr) +{ + __ASM volatile( + "ldr r0, [%0]\t\n" // Get App initial MSP for bootloader. + "msr msp, r0\t\n" // Set the main stack pointer to the applications MSP. + "ldr r0, [%0, #0x04]\t\n" // Load Reset handler into R0. + + "movs r4, #0xFF\t\n" // Move ones to R4. + "sxtb r4, r4\t\n" // Sign extend R4 to obtain 0xFFFFFFFF instead of 0xFF. + + "mrs r5, IPSR\t\n" // Load IPSR to R5 to check for handler or thread mode. + "cmp r5, #0x00\t\n" // Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader. + "bne isr_abort\t\n" // If not zero we need to exit current ISR and jump to reset handler of bootloader. + + "mrs r1, control\t\n" // Get CONTROL register value + "movs r2, #0x02\t\n" // load 2 to r2 + "bic r1, r2\t\n" // clear value of CONTROL->SPSEL - > make sure MSP will be used + "msr control, r1\t\n" // set the stack pointer to MSP + + "mov lr, r4\t\n" // Clear the link register and set to ones to ensure no return. + "bx r0\t\n" // Branch to reset handler of bootloader. + + "isr_abort: \t\n" + + "mov r5, r4\t\n" // Fill with ones before jumping to reset handling. Will be popped as LR when exiting ISR. Ensures no return to application. + "mov r6, r0\t\n" // Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR. + "movs r7, #0x21\t\n" // Move MSB reset value of xPSR to R7. Will be popped as xPSR when exiting ISR. xPSR is 0x21000000 thus MSB is 0x21. + "rev r7, r7\t\n" // Reverse byte order to put 0x21 as MSB. + "push {r4-r7}\t\n" // Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR. + + "movs r4, #0x00\t\n" // Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers). + "movs r5, #0x00\t\n" // Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers). + "movs r6, #0x00\t\n" // Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers). + "movs r7, #0x00\t\n" // Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers). + "push {r4-r7}\t\n" // Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine. + + "movs r0, #0xF9\t\n" // Move the execution return command into register, 0xFFFFFFF9. + "sxtb r0, r0\t\n" // Sign extend R0 to obtain 0xFFFFFFF9 instead of 0xF9. + "bx r0\t\n" // No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application. + ".align\t\n" + :: "r" (start_addr) // Argument list for the gcc assembly. start_addr is %0. + : "r0", "r4", "r5", "r6", "r7" // List of register maintained manually. + ); +} + +#elif defined ( __ICCARM__ ) + +void nrf_bootloader_app_start_impl(uint32_t start_addr) +{ + __ASM("ldr r5, [%0]\n" // Get App initial MSP for bootloader. + "msr msp, r5\n" // Set the main stack pointer to the applications MSP. + "ldr r0, [%0, #0x04]\n" // Load Reset handler into R0. + + "movs r4, #0x00\n" // Load zero into R4. + "mvns r4, r4\n" // Invert R4 to ensure it contain ones. + + "mrs r5, IPSR\n" // Load IPSR to R5 to check for handler or thread mode + "cmp r5, #0x00\n" // Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader. + "bne.n isr_abort\n" // If not zero we need to exit current ISR and jump to reset handler of bootloader. + + "mrs r1, control\n" // Get CONTROL register value + "movs r2, #0x02\n" // load 2 to r2 + "bics r1, r2\n" // clear value of CONTROL->SPSEL - > make sure MSP will be used + "msr control, r1\n" // set the stack pointer to MSP + + "mov lr, r4\n" // Clear the link register and set to ones to ensure no return. + "bx r0\n" // Branch to reset handler of bootloader. + + "isr_abort: \n" + // R4 contains ones from line above. We be popped as R12 when exiting ISR (Cleaning up the registers). + "mov r5, r4\n" // Fill with ones before jumping to reset handling. Will be popped as LR when exiting ISR. Ensures no return to application. + "mov r6, r0\n" // Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR. + "movs r7, #0x21\n" // Move MSB reset value of xPSR to R7. Will be popped as xPSR when exiting ISR. xPSR is 0x21000000 thus MSB is 0x21. + "rev r7, r7\n" // Reverse byte order to put 0x21 as MSB. + "push {r4-r7}\n" // Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR. + + "movs r4, #0x00\n" // Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers). + "movs r5, #0x00\n" // Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers). + "movs r6, #0x00\n" // Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers). + "movs r7, #0x00\n" // Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers). + "push {r4-r7}\n" // Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine. + + "movs r0, #0x06\n" // Load 0x06 into R6 to prepare for exec return command. + "mvns r0, r0\n" // Invert 0x06 to obtain EXEC_RETURN, 0xFFFFFFF9. + "bx r0\n" // No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application. + :: "r" (start_addr) // Argument list for the IAR assembly. start_addr is %0. + : "r0", "r4", "r5", "r6", "r7"); // List of register maintained manually. +} + +#else + +#error Compiler not supported. + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_app_start_nosd.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_app_start_nosd.c new file mode 100644 index 0000000000000000000000000000000000000000..0fe3a29567ab8802f0b4c7dff25c12a742d79593 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_app_start_nosd.c @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "nrf_bootloader_app_start.h" +#include "nrf_log.h" +#include "nrf_dfu_mbr.h" + +extern void nrf_bootloader_app_start_impl(uint32_t start_addr); + +void nrf_bootloader_app_start(uint32_t start_addr) +{ + NRF_LOG_DEBUG("Running nrf_bootloader_app_start with address: 0x%08x\r\n", start_addr); + uint32_t err_code; + + // Disable interrupts + NRF_LOG_DEBUG("Disabling interrupts\r\n"); + + NVIC->ICER[0]=0xFFFFFFFF; +#if defined(__NRF_NVIC_ISER_COUNT) && __NRF_NVIC_ISER_COUNT == 2 + NVIC->ICER[1]=0xFFFFFFFF; +#endif + + NRF_LOG_DEBUG("Setting MBR vector table base: 0x%08x\r\n", start_addr); + err_code = nrf_dfu_mbr_vector_table_set(start_addr, true); + if(err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Failed running nrf_dfu_mbr_vector_table_set\r\n"); + return; + } + + // Run application + nrf_bootloader_app_start_impl(start_addr); +} + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_info.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_info.c new file mode 100644 index 0000000000000000000000000000000000000000..e3e58695795165a551af0cee98186e32e2db1853 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_info.c @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_bootloader_info.h" + + +/** @brief This variable ensures that the linker script will write the bootloader start address + * to the UICR register. This value will be written in the HEX file and thus written to + * UICR when the bootloader is flashed into the chip. + */ +#if defined (__CC_ARM ) + #pragma push + #pragma diag_suppress 1296 + uint32_t m_uicr_bootloader_start_address __attribute__((at(NRF_UICR_BOOTLOADER_START_ADDRESS))) + = BOOTLOADER_START_ADDR; + #pragma pop +#elif defined ( __GNUC__ ) + volatile uint32_t m_uicr_bootloader_start_address __attribute__ ((section(".uicrBootStartAddress"))) + = BOOTLOADER_START_ADDR; +#elif defined ( __ICCARM__ ) + __root const uint32_t m_uicr_bootloader_start_address @ NRF_UICR_BOOTLOADER_START_ADDRESS + = BOOTLOADER_START_ADDR; +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_info.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_info.h new file mode 100644 index 0000000000000000000000000000000000000000..fc0cd586573c244fa8675ecae887858392f7d480 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/nrf_bootloader_info.h @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup sdk_bootloader_info Information + * @{ + * @ingroup sdk_bootloader + */ + +#ifndef NRF_BOOTLOADER_INFO_H__ +#define NRF_BOOTLOADER_INFO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf.h" +#include "nrf_mbr.h" + +#if defined(SOFTDEVICE_PRESENT) +#include "nrf_sdm.h" +#else +#include "nrf_mbr.h" +#endif + +/** @brief External definitions of symbols for the start of the application image. + */ +#if (__LINT__ == 1) + // No implementation +#elif defined ( __CC_ARM ) + extern uint32_t* Image$$ER_IROM1$$Base __attribute__((used)); +#elif defined ( __GNUC__ ) + extern uint32_t * __isr_vector; +#elif defined ( __ICCARM__ ) + extern void * __vector_table; +#else + #error Not a valid compiler/linker for application image symbols. +#endif + + +/** @brief Macro for getting the start address of the application image. + * + * This macro is valid only when absolute placement is used for the application + * image. The macro is not a compile time symbol. It cannot be used as a + * constant expression, for example, inside a static assert or linker script + * at-placement. + */ +#if (__LINT__ == 1) + #define BOOTLOADER_START_ADDR (0x3AC00) +#elif BOOTLOADER_START_ADDR + // Bootloader start address is defined at project level +#elif defined (__CC_ARM) + #define BOOTLOADER_START_ADDR (uint32_t)&Image$$ER_IROM1$$Base +#elif defined (__GNUC__) + #define BOOTLOADER_START_ADDR (uint32_t)&__isr_vector +#elif defined (__ICCARM__) + #define BOOTLOADER_START_ADDR (uint32_t)&__vector_table +#else + #error Not a valid compiler/linker for BOOTLOADER_START_ADDR. +#endif + + +/** + * @brief Bootloader start address in UICR. + * + * Register location in UICR where the bootloader start address is stored. + * + * @note If the value at the given location is 0xFFFFFFFF, the bootloader address is not set. + */ +#define NRF_UICR_BOOTLOADER_START_ADDRESS (NRF_UICR_BASE + 0x14) + + +#ifndef MAIN_APPLICATION_START_ADDR + + +#if defined(SOFTDEVICE_PRESENT) + +/** @brief Main application start address (if the project uses a SoftDevice). + * + * @note The start address is equal to the end address of the SoftDevice. + */ +#define MAIN_APPLICATION_START_ADDR (SD_SIZE_GET(MBR_SIZE)) + +#else +#define MAIN_APPLICATION_START_ADDR MBR_SIZE +#endif // #ifdef SOFTDEVICE_PRESENT +#endif // #ifndef MAIN_APPLICATION_START_ADDR + + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef NRF_BOOTLOADER_INFO_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/serial_dfu/nrf_serial_dfu.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/serial_dfu/nrf_serial_dfu.c new file mode 100644 index 0000000000000000000000000000000000000000..e6e5da3d0f3bd0fd337409d7999720891cefcdf3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/serial_dfu/nrf_serial_dfu.c @@ -0,0 +1,405 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_serial_dfu.h" + +#include +#include "boards.h" +#include "app_util_platform.h" +#include "nrf_dfu_transport.h" +#include "nrf_dfu_req_handler.h" +#include "slip.h" +#include "nrf_log.h" + + +#define AVAILABLE_LED_PIN_NO BSP_LED_0 /**< Is on when serial DFU transport is enabled (but not connected). */ +#define CONNECTED_LED_PIN_NO BSP_LED_1 /**< Is on when device has connected. */ + + +#define CREATE_OBJECT_REQUEST_LEN (sizeof(uint8_t)+sizeof(uint32_t)) +#define SET_RECEIPT_NOTIF_REQUEST_LEN (sizeof(uint16_t)) +#define CALCULATE_CRC_REQUEST_LEN 0 +#define EXECUTE_OBJECT_REQUEST_LEN 0 +#define SELECT_OBJECT_REQUEST_LEN (sizeof(uint8_t)) +#define GET_SERIAL_MTU_REQUEST_LEN 0 + +#define MAX_RESPONSE_SIZE (1+1+3*4) + +static serial_dfu_t m_dfu; + + +//lint -save -e545 -esym(526, dfu_trans) -esym(528, dfu_trans) +DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const dfu_trans) = +{ + .init_func = serial_dfu_transport_init, + .close_func = serial_dfu_transport_close +}; +//lint -restore + + +ANON_UNIONS_ENABLE + +typedef struct +{ + uint8_t op_code; + nrf_dfu_res_code_t resp_val; + union + { + struct + { + uint32_t offset; + uint32_t crc; + } crc_response; + + struct + { + uint32_t max_size; + uint32_t offset; + uint32_t crc; + } select_response; + + struct + { + uint16_t mtu; + } serial_mtu_response; + }; + +} serial_dfu_response_t; + +ANON_UNIONS_DISABLE + + +/**@brief Function for the LEDs initialization. + * + * @details Initializes all LEDs used by this application. + */ +static void leds_init(void) +{ + nrf_gpio_cfg_output(AVAILABLE_LED_PIN_NO); + nrf_gpio_cfg_output(CONNECTED_LED_PIN_NO); + nrf_gpio_pin_clear(AVAILABLE_LED_PIN_NO); + nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); +} + +static void response_send(serial_dfu_t * p_dfu, + serial_dfu_response_t * p_response) +{ + uint8_t response_buffer[MAX_RESPONSE_SIZE]; + uint8_t encoded_response[MAX_RESPONSE_SIZE*2 + 1]; + uint32_t encoded_response_length; + + uint16_t index = 0; + + NRF_LOG_DEBUG("Sending Response: [0x%01x, 0x%01x]\r\n", p_response->op_code, p_response->resp_val); + + response_buffer[index++] = SERIAL_DFU_OP_CODE_RESPONSE; + + // Encode the Request Op code + response_buffer[index++] = p_response->op_code; + + // Encode the Response Value. + response_buffer[index++] = (uint8_t)p_response->resp_val; + + if (p_response->resp_val == NRF_DFU_RES_CODE_SUCCESS) + { + switch (p_response->op_code) + { + case SERIAL_DFU_OP_CODE_CALCULATE_CRC: + index += uint32_encode(p_response->crc_response.offset, &response_buffer[index]); + index += uint32_encode(p_response->crc_response.crc, &response_buffer[index]); + break; + + case SERIAL_DFU_OP_CODE_SELECT_OBJECT: + index += uint32_encode(p_response->select_response.max_size, &response_buffer[index]); + index += uint32_encode(p_response->select_response.offset, &response_buffer[index]); + index += uint32_encode(p_response->select_response.crc, &response_buffer[index]); + break; + + case SERIAL_DFU_OP_CODE_GET_SERIAL_MTU: + index += uint16_encode(p_response->serial_mtu_response.mtu, &response_buffer[index]); + break; + + default: + // no implementation + break; + } + } + + // encode into slip + (void)slip_encode(encoded_response, response_buffer, index, &encoded_response_length); + + // send + (void)nrf_drv_uart_tx(&p_dfu->uart_instance, encoded_response, encoded_response_length); +} + +static void on_packet_received(serial_dfu_t * p_dfu) +{ + nrf_dfu_req_t dfu_req; + nrf_dfu_res_t dfu_res = {{{0}}}; + + serial_dfu_response_t serial_response; + + memset(&dfu_req, 0, sizeof(nrf_dfu_req_t)); + + const serial_dfu_op_code_t op_code = (serial_dfu_op_code_t)p_dfu->recv_buffer[0]; + const uint16_t packet_payload_len = p_dfu->slip.current_index - 1; + uint8_t * p_payload = &p_dfu->recv_buffer[1]; + + serial_response.op_code = op_code; + + nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); + nrf_gpio_pin_set(AVAILABLE_LED_PIN_NO); + + switch (op_code) + { + case SERIAL_DFU_OP_CODE_CREATE_OBJECT: + + if (packet_payload_len != CREATE_OBJECT_REQUEST_LEN) + { + serial_response.resp_val = NRF_DFU_RES_CODE_INVALID_PARAMETER; + break; + } + + NRF_LOG_DEBUG("Received create object\r\n"); + + // Reset the packet receipt notification on create object + p_dfu->pkt_notif_target_count = p_dfu->pkt_notif_target; + + // Get type parameter + dfu_req.obj_type = p_payload[0]; + + // Get length value + dfu_req.object_size = uint32_decode(&p_payload[1]); + + // Set req type + dfu_req.req_type = NRF_DFU_OBJECT_OP_CREATE; + + serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + break; + + case SERIAL_DFU_OP_CODE_SET_RECEIPT_NOTIF: + NRF_LOG_DEBUG("Set receipt notif\r\n"); + if (packet_payload_len != SET_RECEIPT_NOTIF_REQUEST_LEN) + { + serial_response.resp_val = NRF_DFU_RES_CODE_INVALID_PARAMETER; + break; + } + + p_dfu->pkt_notif_target = uint16_decode(&p_payload[0]); + p_dfu->pkt_notif_target_count = p_dfu->pkt_notif_target; + + serial_response.resp_val = NRF_DFU_RES_CODE_SUCCESS; + break; + + case SERIAL_DFU_OP_CODE_CALCULATE_CRC: + NRF_LOG_DEBUG("Received calculate CRC\r\n"); + + dfu_req.req_type = NRF_DFU_OBJECT_OP_CRC; + + serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + serial_response.crc_response.offset = dfu_res.offset; + serial_response.crc_response.crc = dfu_res.crc; + break; + + case SERIAL_DFU_OP_CODE_EXECUTE_OBJECT: + NRF_LOG_DEBUG("Received execute object\r\n"); + + // Set req type + dfu_req.req_type = NRF_DFU_OBJECT_OP_EXECUTE; + + serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + break; + + case SERIAL_DFU_OP_CODE_SELECT_OBJECT: + + NRF_LOG_DEBUG("Received select object\r\n"); + if (packet_payload_len != SELECT_OBJECT_REQUEST_LEN) + { + serial_response.resp_val = NRF_DFU_RES_CODE_INVALID_PARAMETER; + break; + } + + // Set object type to read info about + dfu_req.obj_type = p_payload[0]; + + dfu_req.req_type = NRF_DFU_OBJECT_OP_SELECT; + + serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + serial_response.select_response.max_size = dfu_res.max_size; + serial_response.select_response.offset = dfu_res.offset; + serial_response.select_response.crc = dfu_res.crc; + break; + + case SERIAL_DFU_OP_CODE_GET_SERIAL_MTU: + NRF_LOG_DEBUG("Received get serial mtu\r\n"); + + serial_response.resp_val = NRF_DFU_RES_CODE_SUCCESS; + serial_response.serial_mtu_response.mtu = sizeof(p_dfu->recv_buffer); + break; + + case SERIAL_DFU_OP_CODE_WRITE_OBJECT: + // Set req type + dfu_req.req_type = NRF_DFU_OBJECT_OP_WRITE; + + // Set data and length + dfu_req.p_req = &p_payload[0]; + dfu_req.req_len = packet_payload_len; + + serial_response.resp_val = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + if(serial_response.resp_val != NRF_DFU_RES_CODE_SUCCESS) + { + NRF_LOG_ERROR("Failure to run packet write\r\n"); + } + + // Check if a packet receipt notification is needed to be sent. + if (p_dfu->pkt_notif_target != 0 && --p_dfu->pkt_notif_target_count == 0) + { + serial_response.op_code = SERIAL_DFU_OP_CODE_CALCULATE_CRC; + serial_response.crc_response.offset = dfu_res.offset; + serial_response.crc_response.crc = dfu_res.crc; + + // Reset the counter for the number of firmware packets. + p_dfu->pkt_notif_target_count = p_dfu->pkt_notif_target; + } + break; + + default: + // Unsupported op code. + NRF_LOG_WARNING("Received unsupported OP code\r\n"); + serial_response.resp_val = NRF_DFU_RES_CODE_INVALID_PARAMETER; + break; + } + + if (op_code != SERIAL_DFU_OP_CODE_WRITE_OBJECT) + { + response_send(p_dfu, &serial_response); + } +} + + +static __INLINE void on_rx_complete(serial_dfu_t * p_dfu, uint8_t * p_data, uint8_t len) +{ + ret_code_t ret_code; + + ret_code = slip_decode_add_byte(&p_dfu->slip, p_data[0]); + + if (ret_code == NRF_SUCCESS) + { + on_packet_received(p_dfu); + + // reset the slip decoding + p_dfu->slip.current_index = 0; + p_dfu->slip.state = SLIP_STATE_DECODING; + } + + (void)nrf_drv_uart_rx(&m_dfu.uart_instance, &m_dfu.uart_buffer, 1); +} + +static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context) +{ + switch (p_event->type) + { + case NRF_DRV_UART_EVT_TX_DONE: + nrf_dfu_req_handler_reset_if_dfu_complete(); + break; + + case NRF_DRV_UART_EVT_RX_DONE: + on_rx_complete((serial_dfu_t*)p_context, p_event->data.rxtx.p_data, p_event->data.rxtx.bytes); + break; + + case NRF_DRV_UART_EVT_ERROR: + APP_ERROR_HANDLER(p_event->data.error.error_mask); + break; + } +} + + +uint32_t serial_dfu_transport_init(void) +{ + uint32_t err_code; + + leds_init(); + + m_dfu.slip.p_buffer = m_dfu.recv_buffer; + m_dfu.slip.current_index = 0; + m_dfu.slip.buffer_len = sizeof(m_dfu.recv_buffer); + m_dfu.slip.state = SLIP_STATE_DECODING; + + nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG; + + uart_config.pseltxd = TX_PIN_NUMBER; + uart_config.pselrxd = RX_PIN_NUMBER; + uart_config.pselcts = CTS_PIN_NUMBER; + uart_config.pselrts = RTS_PIN_NUMBER; + uart_config.hwfc = NRF_UART_HWFC_ENABLED; + uart_config.p_context = &m_dfu; + + + nrf_drv_uart_t instance = NRF_DRV_UART_INSTANCE(0); + memcpy(&m_dfu.uart_instance, &instance, sizeof(instance)); + + err_code = nrf_drv_uart_init(&m_dfu.uart_instance, + &uart_config, + uart_event_handler); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Failed initializing uart\n"); + return err_code; + } + + nrf_drv_uart_rx_enable(&m_dfu.uart_instance); + + err_code = nrf_drv_uart_rx(&m_dfu.uart_instance, &m_dfu.uart_buffer, 1); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Failed initializing rx\n"); + } + + NRF_LOG_DEBUG("UART initialized\n"); + + return err_code; +} + + +uint32_t serial_dfu_transport_close(void) +{ + nrf_drv_uart_uninit(&m_dfu.uart_instance); + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/serial_dfu/nrf_serial_dfu.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/serial_dfu/nrf_serial_dfu.h new file mode 100644 index 0000000000000000000000000000000000000000..e81f0d50705fff4985c48cda8000df15bddccd91 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bootloader/serial_dfu/nrf_serial_dfu.h @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/**@file + * + * @defgroup nrf_serial_dfu Serial DFU transport layer + * @{ + * @ingroup sdk_nrf_bootloader + * @brief Device Firmware Update (DFU) transport layer using UART. + * + * @details The transport layer can be used for performing firmware updates over UART. + * The implementation uses SLIP to encode packets. + */ + +#ifndef NRF_SERIAL_DFU_H__ +#define NRF_SERIAL_DFU_H__ + +#include +#include "nrf_drv_uart.h" +#include "slip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Serial DFU opcodes. + */ +typedef enum +{ + SERIAL_DFU_OP_CODE_CREATE_OBJECT = 0x01, /**< Value of the opcode field for a 'Create object' request. */ + SERIAL_DFU_OP_CODE_SET_RECEIPT_NOTIF = 0x02, /**< Value of the opcode field for a 'Set Packet Receipt Notification' request. */ + SERIAL_DFU_OP_CODE_CALCULATE_CRC = 0x03, /**< Value of the opcode field for a 'Calculating checksum' request. */ + SERIAL_DFU_OP_CODE_EXECUTE_OBJECT = 0x04, /**< Value of the opcode field for an 'Initialize DFU parameters' request. */ + SERIAL_DFU_OP_CODE_SELECT_OBJECT = 0x06, /**< Value of the opcode field for a 'Select object' request. */ + SERIAL_DFU_OP_CODE_GET_SERIAL_MTU = 0x07, /**< Value of the opcode field for a 'Get Serial MTU' request. */ + SERIAL_DFU_OP_CODE_WRITE_OBJECT = 0x08, /**< Value of the opcode indicating a write to the current object. */ + SERIAL_DFU_OP_CODE_RESPONSE = 0x60 /**< Value of the opcode field for a response.*/ +} serial_dfu_op_code_t; + +/**@brief DFU transport layer state. + * + * @details This structure contains status information related to the transport layer. + */ +typedef struct +{ + nrf_drv_uart_t uart_instance; /**< Structure holding the state of the UART driver. */ + slip_t slip; + + uint8_t uart_buffer; + uint8_t recv_buffer[256 + 1]; + + uint16_t pkt_notif_target; + uint16_t pkt_notif_target_count; +} serial_dfu_t; + + +/**@brief Function for initializing the transport layer. + * + * @retval NRF_SUCCESS If the transport layer was successfully initialized. Otherwise, an error code is returned. + */ +uint32_t serial_dfu_transport_init(void); + + +/**@brief Function for closing down the transport layer. + * + * @retval NRF_SUCCESS If the transport layer was correctly closed down. + */ +uint32_t serial_dfu_transport_close(void); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SERIAL_DFU_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp.c new file mode 100644 index 0000000000000000000000000000000000000000..2a6181b4d55de966919238f2fe85dfdc1fff802b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp.c @@ -0,0 +1,630 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "bsp.h" +#include +#include +#include "nordic_common.h" +#include "nrf.h" +#include "nrf_gpio.h" +#include "nrf_error.h" +#include "bsp_config.h" +#include "boards.h" + +#ifndef BSP_SIMPLE +#include "app_timer.h" +#include "app_button.h" +#endif // BSP_SIMPLE + +#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) +static bsp_indication_t m_stable_state = BSP_INDICATE_IDLE; +static bool m_leds_clear = false; +static uint32_t m_indication_type = 0; +static bool m_alert_on = false; +APP_TIMER_DEF(m_leds_timer_id); +APP_TIMER_DEF(m_alert_timer_id); +#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + +#if BUTTONS_NUMBER > 0 +#ifndef BSP_SIMPLE +static bsp_event_callback_t m_registered_callback = NULL; +static bsp_button_event_cfg_t m_events_list[BUTTONS_NUMBER] = {{BSP_EVENT_NOTHING, BSP_EVENT_NOTHING}}; +APP_TIMER_DEF(m_button_timer_id); +static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action); +#endif // BSP_SIMPLE + +#ifndef BSP_SIMPLE +static const app_button_cfg_t app_buttons[BUTTONS_NUMBER] = +{ + #ifdef BSP_BUTTON_0 + {BSP_BUTTON_0, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_0 + + #ifdef BSP_BUTTON_1 + {BSP_BUTTON_1, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_1 + + #ifdef BSP_BUTTON_2 + {BSP_BUTTON_2, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_2 + + #ifdef BSP_BUTTON_3 + {BSP_BUTTON_3, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_3 + + #ifdef BSP_BUTTON_4 + {BSP_BUTTON_4, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_4 + + #ifdef BSP_BUTTON_5 + {BSP_BUTTON_5, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_5 + + #ifdef BSP_BUTTON_6 + {BSP_BUTTON_6, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_6 + + #ifdef BSP_BUTTON_7 + {BSP_BUTTON_7, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_7 + +}; +#endif // BSP_SIMPLE +#endif // BUTTONS_NUMBER > 0 + +#if (BUTTONS_NUMBER > 0) +bool bsp_button_is_pressed(uint32_t button) +{ + return bsp_board_button_state_get(button); +} +#endif + +#if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE) +/**@brief Function for handling button events. + * + * @param[in] pin_no The pin number of the button pressed. + * @param[in] button_action Action button. + */ +static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action) +{ + bsp_event_t event = BSP_EVENT_NOTHING; + uint32_t button = 0; + uint32_t err_code; + static uint8_t current_long_push_pin_no; /**< Pin number of a currently pushed button, that could become a long push if held long enough. */ + static bsp_event_t release_event_at_push[BUTTONS_NUMBER]; /**< Array of what the release event of each button was last time it was pushed, so that no release event is sent if the event was bound after the push of the button. */ + + button = bsp_board_pin_to_button_idx(pin_no); + + if (button < BUTTONS_NUMBER) + { + switch (button_action) + { + case APP_BUTTON_PUSH: + event = m_events_list[button].push_event; + if (m_events_list[button].long_push_event != BSP_EVENT_NOTHING) + { + err_code = app_timer_start(m_button_timer_id, APP_TIMER_TICKS(BSP_LONG_PUSH_TIMEOUT_MS), (void*)¤t_long_push_pin_no); + if (err_code == NRF_SUCCESS) + { + current_long_push_pin_no = pin_no; + } + } + release_event_at_push[button] = m_events_list[button].release_event; + break; + case APP_BUTTON_RELEASE: + (void)app_timer_stop(m_button_timer_id); + if (release_event_at_push[button] == m_events_list[button].release_event) + { + event = m_events_list[button].release_event; + } + break; + case BSP_BUTTON_ACTION_LONG_PUSH: + event = m_events_list[button].long_push_event; + } + } + + if ((event != BSP_EVENT_NOTHING) && (m_registered_callback != NULL)) + { + m_registered_callback(event); + } +} + +/**@brief Handle events from button timer. + * + * @param[in] p_context parameter registered in timer start function. + */ +static void button_timer_handler(void * p_context) +{ + bsp_button_event_handler(*(uint8_t *)p_context, BSP_BUTTON_ACTION_LONG_PUSH); +} + + +#endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE) + + +#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) +static void leds_off(void) +{ + if (m_alert_on) + { + uint32_t i; + for(i = 0; i < LEDS_NUMBER; i++) + { + if (i != BSP_LED_ALERT) + { + bsp_board_led_off(i); + } + } + } + else + { + bsp_board_leds_off(); + } +} + + +/**@brief Configure leds to indicate required state. + * @param[in] indicate State to be indicated. + */ +static uint32_t bsp_led_indication(bsp_indication_t indicate) +{ + uint32_t err_code = NRF_SUCCESS; + uint32_t next_delay = 0; + + if(m_leds_clear) + { + m_leds_clear = false; + leds_off(); + } + + switch (indicate) + { + case BSP_INDICATE_IDLE: + leds_off(); + m_stable_state = indicate; + break; + + case BSP_INDICATE_SCANNING: + case BSP_INDICATE_ADVERTISING: + // in advertising blink LED_0 + if (bsp_board_led_state_get(BSP_LED_INDICATE_INDICATE_ADVERTISING)) + { + bsp_board_led_off(BSP_LED_INDICATE_INDICATE_ADVERTISING); + next_delay = indicate == + BSP_INDICATE_ADVERTISING ? ADVERTISING_LED_OFF_INTERVAL : + ADVERTISING_SLOW_LED_OFF_INTERVAL; + } + else + { + bsp_board_led_on(BSP_LED_INDICATE_INDICATE_ADVERTISING); + next_delay = indicate == + BSP_INDICATE_ADVERTISING ? ADVERTISING_LED_ON_INTERVAL : + ADVERTISING_SLOW_LED_ON_INTERVAL; + } + + m_stable_state = indicate; + err_code = app_timer_start(m_leds_timer_id, APP_TIMER_TICKS(next_delay), NULL); + break; + + case BSP_INDICATE_ADVERTISING_WHITELIST: + // in advertising quickly blink LED_0 + if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_WHITELIST)) + { + bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_WHITELIST); + next_delay = indicate == + BSP_INDICATE_ADVERTISING_WHITELIST ? + ADVERTISING_WHITELIST_LED_OFF_INTERVAL : + ADVERTISING_SLOW_LED_OFF_INTERVAL; + } + else + { + bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_WHITELIST); + next_delay = indicate == + BSP_INDICATE_ADVERTISING_WHITELIST ? + ADVERTISING_WHITELIST_LED_ON_INTERVAL : + ADVERTISING_SLOW_LED_ON_INTERVAL; + } + m_stable_state = indicate; + err_code = app_timer_start(m_leds_timer_id, APP_TIMER_TICKS(next_delay), NULL); + break; + + case BSP_INDICATE_ADVERTISING_SLOW: + // in advertising slowly blink LED_0 + if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_SLOW)) + { + bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_SLOW); + next_delay = indicate == + BSP_INDICATE_ADVERTISING_SLOW ? ADVERTISING_SLOW_LED_OFF_INTERVAL : + ADVERTISING_SLOW_LED_OFF_INTERVAL; + } + else + { + bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_SLOW); + next_delay = indicate == + BSP_INDICATE_ADVERTISING_SLOW ? ADVERTISING_SLOW_LED_ON_INTERVAL : + ADVERTISING_SLOW_LED_ON_INTERVAL; + } + m_stable_state = indicate; + err_code = app_timer_start(m_leds_timer_id, APP_TIMER_TICKS(next_delay), NULL); + break; + + case BSP_INDICATE_ADVERTISING_DIRECTED: + // in advertising very quickly blink LED_0 + if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_DIRECTED)) + { + bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_DIRECTED); + next_delay = indicate == + BSP_INDICATE_ADVERTISING_DIRECTED ? + ADVERTISING_DIRECTED_LED_OFF_INTERVAL : + ADVERTISING_SLOW_LED_OFF_INTERVAL; + } + else + { + bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_DIRECTED); + next_delay = indicate == + BSP_INDICATE_ADVERTISING_DIRECTED ? + ADVERTISING_DIRECTED_LED_ON_INTERVAL : + ADVERTISING_SLOW_LED_ON_INTERVAL; + } + m_stable_state = indicate; + err_code = app_timer_start(m_leds_timer_id, APP_TIMER_TICKS(next_delay), NULL); + break; + + case BSP_INDICATE_BONDING: + // in bonding fast blink LED_0 + bsp_board_led_invert(BSP_LED_INDICATE_BONDING); + + m_stable_state = indicate; + err_code = + app_timer_start(m_leds_timer_id, APP_TIMER_TICKS(BONDING_INTERVAL), NULL); + break; + + case BSP_INDICATE_CONNECTED: + bsp_board_led_on(BSP_LED_INDICATE_CONNECTED); + m_stable_state = indicate; + break; + + case BSP_INDICATE_SENT_OK: + // when sending shortly invert LED_1 + m_leds_clear = true; + bsp_board_led_invert(BSP_LED_INDICATE_SENT_OK); + err_code = app_timer_start(m_leds_timer_id, APP_TIMER_TICKS(SENT_OK_INTERVAL), NULL); + break; + + case BSP_INDICATE_SEND_ERROR: + // on receving error invert LED_1 for long time + m_leds_clear = true; + bsp_board_led_invert(BSP_LED_INDICATE_SEND_ERROR); + err_code = app_timer_start(m_leds_timer_id, APP_TIMER_TICKS(SEND_ERROR_INTERVAL), NULL); + break; + + case BSP_INDICATE_RCV_OK: + // when receving shortly invert LED_1 + m_leds_clear = true; + bsp_board_led_invert(BSP_LED_INDICATE_RCV_OK); + err_code = app_timer_start(m_leds_timer_id, APP_TIMER_TICKS(RCV_OK_INTERVAL), NULL); + break; + + case BSP_INDICATE_RCV_ERROR: + // on receving error invert LED_1 for long time + m_leds_clear = true; + bsp_board_led_invert(BSP_LED_INDICATE_RCV_ERROR); + err_code = app_timer_start(m_leds_timer_id, APP_TIMER_TICKS(RCV_ERROR_INTERVAL), NULL); + break; + + case BSP_INDICATE_FATAL_ERROR: + // on fatal error turn on all leds + bsp_board_leds_on(); + m_stable_state = indicate; + break; + + case BSP_INDICATE_ALERT_0: + case BSP_INDICATE_ALERT_1: + case BSP_INDICATE_ALERT_2: + case BSP_INDICATE_ALERT_3: + case BSP_INDICATE_ALERT_OFF: + err_code = app_timer_stop(m_alert_timer_id); + next_delay = (uint32_t)BSP_INDICATE_ALERT_OFF - (uint32_t)indicate; + + // a little trick to find out that if it did not fall through ALERT_OFF + if (next_delay && (err_code == NRF_SUCCESS)) + { + if (next_delay > 1) + { + err_code = app_timer_start(m_alert_timer_id, + APP_TIMER_TICKS(((uint16_t)next_delay * ALERT_INTERVAL)), + NULL); + } + bsp_board_led_on(BSP_LED_ALERT); + m_alert_on = true; + } + else + { + bsp_board_led_off(BSP_LED_ALERT); + m_alert_on = false; + + } + break; + + case BSP_INDICATE_USER_STATE_OFF: + leds_off(); + m_stable_state = indicate; + break; + + case BSP_INDICATE_USER_STATE_0: + leds_off(); + bsp_board_led_on(BSP_LED_INDICATE_USER_LED1); + m_stable_state = indicate; + break; + + case BSP_INDICATE_USER_STATE_1: + leds_off(); + bsp_board_led_on(BSP_LED_INDICATE_USER_LED2); + m_stable_state = indicate; + break; + + case BSP_INDICATE_USER_STATE_2: + leds_off(); + bsp_board_led_on(BSP_LED_INDICATE_USER_LED1); + bsp_board_led_on(BSP_LED_INDICATE_USER_LED2); + m_stable_state = indicate; + break; + + case BSP_INDICATE_USER_STATE_3: + + case BSP_INDICATE_USER_STATE_ON: + bsp_board_leds_on(); + m_stable_state = indicate; + break; + + default: + break; + } + + return err_code; +} + + +/**@brief Handle events from leds timer. + * + * @note Timer handler does not support returning an error code. + * Errors from bsp_led_indication() are not propagated. + * + * @param[in] p_context parameter registered in timer start function. + */ +static void leds_timer_handler(void * p_context) +{ + UNUSED_PARAMETER(p_context); + + if (m_indication_type & BSP_INIT_LED) + { + UNUSED_VARIABLE(bsp_led_indication(m_stable_state)); + } +} + + +/**@brief Handle events from alert timer. + * + * @param[in] p_context parameter registered in timer start function. + */ +static void alert_timer_handler(void * p_context) +{ + UNUSED_PARAMETER(p_context); + bsp_board_led_invert(BSP_LED_ALERT); +} +#endif // #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + + +/**@brief Configure indicators to required state. + */ +uint32_t bsp_indication_set(bsp_indication_t indicate) +{ + uint32_t err_code = NRF_SUCCESS; + +#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + + if (m_indication_type & BSP_INIT_LED) + { + err_code = bsp_led_indication(indicate); + } + +#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + return err_code; +} + + +uint32_t bsp_init(uint32_t type, bsp_event_callback_t callback) +{ + uint32_t err_code = NRF_SUCCESS; + +#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + m_indication_type = type; +#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + +#if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE) + m_registered_callback = callback; + + // BSP will support buttons and generate events + if (type & BSP_INIT_BUTTONS) + { + uint32_t num; + + for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++) + { + err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT); + } + + if (err_code == NRF_SUCCESS) + { + err_code = app_button_init((app_button_cfg_t *)app_buttons, + BUTTONS_NUMBER, + APP_TIMER_TICKS(50)); + } + + if (err_code == NRF_SUCCESS) + { + err_code = app_button_enable(); + } + + if (err_code == NRF_SUCCESS) + { + err_code = app_timer_create(&m_button_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + button_timer_handler); + } + } +#elif (BUTTONS_NUMBER > 0) && (defined BSP_SIMPLE) + + if (type & BSP_INIT_BUTTONS) + { + bsp_board_buttons_init(); + } +#endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE) + +#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + + if (type & BSP_INIT_LED) + { + bsp_board_leds_init(); + } + + // timers module must be already initialized! + if (err_code == NRF_SUCCESS) + { + err_code = + app_timer_create(&m_leds_timer_id, APP_TIMER_MODE_SINGLE_SHOT, leds_timer_handler); + } + + if (err_code == NRF_SUCCESS) + { + err_code = + app_timer_create(&m_alert_timer_id, APP_TIMER_MODE_REPEATED, alert_timer_handler); + } +#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + + return err_code; +} + + +#ifndef BSP_SIMPLE +/**@brief Assign specific event to button. + */ +uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event) +{ + uint32_t err_code = NRF_SUCCESS; + +#if BUTTONS_NUMBER > 0 + if (button < BUTTONS_NUMBER) + { + if (event == BSP_EVENT_DEFAULT) + { + // Setting default action: BSP_EVENT_KEY_x for PUSH actions, BSP_EVENT_NOTHING for RELEASE and LONG_PUSH actions. + event = (action == BSP_BUTTON_ACTION_PUSH) ? (bsp_event_t)(BSP_EVENT_KEY_0 + button) : BSP_EVENT_NOTHING; + } + switch (action) + { + case BSP_BUTTON_ACTION_PUSH: + m_events_list[button].push_event = event; + break; + case BSP_BUTTON_ACTION_LONG_PUSH: + m_events_list[button].long_push_event = event; + break; + case BSP_BUTTON_ACTION_RELEASE: + m_events_list[button].release_event = event; + break; + default: + err_code = NRF_ERROR_INVALID_PARAM; + break; + } + } + else + { + err_code = NRF_ERROR_INVALID_PARAM; + } +#else + err_code = NRF_ERROR_INVALID_PARAM; +#endif // BUTTONS_NUMBER > 0 + + return err_code; +} + +#endif // BSP_SIMPLE + + +uint32_t bsp_buttons_enable() +{ +#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE) + return app_button_enable(); +#else + return NRF_ERROR_NOT_SUPPORTED; +#endif +} + +uint32_t bsp_buttons_disable() +{ +#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE) + return app_button_disable(); +#else + return NRF_ERROR_NOT_SUPPORTED; +#endif +} + +uint32_t bsp_wakeup_button_enable(uint32_t button_idx) +{ +#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE) + nrf_gpio_cfg_sense_set(bsp_board_button_idx_to_pin(button_idx), + BUTTONS_ACTIVE_STATE ? NRF_GPIO_PIN_SENSE_HIGH :NRF_GPIO_PIN_SENSE_LOW); + return NRF_SUCCESS; +#else + UNUSED_PARAMETER(button_idx); + return NRF_ERROR_NOT_SUPPORTED; +#endif +} + +uint32_t bsp_wakeup_button_disable(uint32_t button_idx) +{ +#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE) + nrf_gpio_cfg_sense_set(bsp_board_button_idx_to_pin(button_idx), + NRF_GPIO_PIN_NOSENSE); + return NRF_SUCCESS; +#else + UNUSED_PARAMETER(button_idx); + return NRF_ERROR_NOT_SUPPORTED; +#endif +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp.h new file mode 100644 index 0000000000000000000000000000000000000000..92d3b1da38085ac3429b6caad77b04dacbfd3233 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp.h @@ -0,0 +1,311 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup bsp Board Support Package + * @{ + * @ingroup app_common + * + * @brief BSP module. + * @details This module provides a layer of abstraction from the board. + * It allows the user to indicate certain states on LEDs in a simple way. + * Module functionality can be modified by defining BSP_SIMPLE to reduce + * functionality of this module to enable and read state of the buttons. + */ + +#ifndef BSP_H__ +#define BSP_H__ + +#include +#include +#include "boards.h" + +#define BSP_INIT_NONE 0 /**< This define specifies the type of initialization without support for LEDs and buttons (@ref bsp_init).*/ +#define BSP_INIT_LED (1 << 0) /**< This bit enables LEDs during initialization (@ref bsp_init).*/ +#define BSP_INIT_BUTTONS (1 << 1) /**< This bit enables buttons during initialization (@ref bsp_init).*/ + +#if !defined(BSP_DEFINES_ONLY) && !defined(BSP_SIMPLE) +#include "app_button.h" + +#define BSP_BUTTON_ACTION_PUSH (APP_BUTTON_PUSH) /**< Represents pushing a button. See @ref bsp_button_action_t. */ +#define BSP_BUTTON_ACTION_RELEASE (APP_BUTTON_RELEASE) /**< Represents releasing a button. See @ref bsp_button_action_t. */ +#define BSP_BUTTON_ACTION_LONG_PUSH (2) /**< Represents pushing and holding a button for @ref BSP_LONG_PUSH_TIMEOUT_MS milliseconds. See also @ref bsp_button_action_t. */ + +#endif + +/* BSP_UART_SUPPORT + * This define enables UART support module. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint8_t bsp_button_action_t; /**< The different actions that can be performed on a button. */ + +#define BSP_INDICATIONS_LIST { \ + "BSP_INDICATE_IDLE", \ + "BSP_INDICATE_SCANNING", \ + "BSP_INDICATE_ADVERTISING", \ + "BSP_INDICATE_ADVERTISING_WHITELIST", \ + "BSP_INDICATE_ADVERTISING_SLOW", \ + "BSP_INDICATE_ADVERTISING_DIRECTED", \ + "BSP_INDICATE_BONDING", \ + "BSP_INDICATE_CONNECTED", \ + "BSP_INDICATE_SENT_OK", \ + "BSP_INDICATE_SEND_ERROR", \ + "BSP_INDICATE_RCV_OK", \ + "BSP_INDICATE_RCV_ERROR", \ + "BSP_INDICATE_FATAL_ERROR", \ + "BSP_INDICATE_ALERT_0", \ + "BSP_INDICATE_ALERT_1", \ + "BSP_INDICATE_ALERT_2", \ + "BSP_INDICATE_ALERT_3", \ + "BSP_INDICATE_ALERT_OFF", \ + "BSP_INDICATE_USER_STATE_OFF", \ + "BSP_INDICATE_USER_STATE_0", \ + "BSP_INDICATE_USER_STATE_1", \ + "BSP_INDICATE_USER_STATE_2", \ + "BSP_INDICATE_USER_STATE_3", \ + "BSP_INDICATE_USER_STATE_ON" \ +} /**< See @ref examples_bsp_states for a list of how these states are indicated for the PCA10028/PCA10040 board and the PCA10031 dongle.*/ + + +/**@brief BSP indication states. + * + * @details See @ref examples_bsp_states for a list of how these states are indicated for the PCA10028/PCA10040 board and the PCA10031 dongle. + */ +typedef enum +{ + BSP_INDICATE_FIRST = 0, + BSP_INDICATE_IDLE = BSP_INDICATE_FIRST, /**< See \ref BSP_INDICATE_IDLE.*/ + BSP_INDICATE_SCANNING, /**< See \ref BSP_INDICATE_SCANNING.*/ + BSP_INDICATE_ADVERTISING, /**< See \ref BSP_INDICATE_ADVERTISING.*/ + BSP_INDICATE_ADVERTISING_WHITELIST, /**< See \ref BSP_INDICATE_ADVERTISING_WHITELIST.*/ + BSP_INDICATE_ADVERTISING_SLOW, /**< See \ref BSP_INDICATE_ADVERTISING_SLOW.*/ + BSP_INDICATE_ADVERTISING_DIRECTED, /**< See \ref BSP_INDICATE_ADVERTISING_DIRECTED.*/ + BSP_INDICATE_BONDING, /**< See \ref BSP_INDICATE_BONDING.*/ + BSP_INDICATE_CONNECTED, /**< See \ref BSP_INDICATE_CONNECTED.*/ + BSP_INDICATE_SENT_OK, /**< See \ref BSP_INDICATE_SENT_OK.*/ + BSP_INDICATE_SEND_ERROR, /**< See \ref BSP_INDICATE_SEND_ERROR.*/ + BSP_INDICATE_RCV_OK, /**< See \ref BSP_INDICATE_RCV_OK.*/ + BSP_INDICATE_RCV_ERROR, /**< See \ref BSP_INDICATE_RCV_ERROR.*/ + BSP_INDICATE_FATAL_ERROR, /**< See \ref BSP_INDICATE_FATAL_ERROR.*/ + BSP_INDICATE_ALERT_0, /**< See \ref BSP_INDICATE_ALERT_0.*/ + BSP_INDICATE_ALERT_1, /**< See \ref BSP_INDICATE_ALERT_1.*/ + BSP_INDICATE_ALERT_2, /**< See \ref BSP_INDICATE_ALERT_2.*/ + BSP_INDICATE_ALERT_3, /**< See \ref BSP_INDICATE_ALERT_3.*/ + BSP_INDICATE_ALERT_OFF, /**< See \ref BSP_INDICATE_ALERT_OFF.*/ + BSP_INDICATE_USER_STATE_OFF, /**< See \ref BSP_INDICATE_USER_STATE_OFF.*/ + BSP_INDICATE_USER_STATE_0, /**< See \ref BSP_INDICATE_USER_STATE_0.*/ + BSP_INDICATE_USER_STATE_1, /**< See \ref BSP_INDICATE_USER_STATE_1.*/ + BSP_INDICATE_USER_STATE_2, /**< See \ref BSP_INDICATE_USER_STATE_2.*/ + BSP_INDICATE_USER_STATE_3, /**< See \ref BSP_INDICATE_USER_STATE_3.*/ + BSP_INDICATE_USER_STATE_ON, /**< See \ref BSP_INDICATE_USER_STATE_ON.*/ + BSP_INDICATE_LAST = BSP_INDICATE_USER_STATE_ON +} bsp_indication_t; + +/**@brief BSP events. + * + * @note Events from BSP_EVENT_KEY_0 to BSP_EVENT_KEY_LAST are by default assigned to buttons. + */ +typedef enum +{ + BSP_EVENT_NOTHING = 0, /**< Assign this event to an action to prevent the action from generating an event (disable the action). */ + BSP_EVENT_DEFAULT, /**< Assign this event to an action to assign the default event to the action. */ + BSP_EVENT_CLEAR_BONDING_DATA, /**< Persistent bonding data should be erased. */ + BSP_EVENT_CLEAR_ALERT, /**< An alert should be cleared. */ + BSP_EVENT_DISCONNECT, /**< A link should be disconnected. */ + BSP_EVENT_ADVERTISING_START, /**< The device should start advertising. */ + BSP_EVENT_ADVERTISING_STOP, /**< The device should stop advertising. */ + BSP_EVENT_WHITELIST_OFF, /**< The device should remove its advertising whitelist. */ + BSP_EVENT_BOND, /**< The device should bond to the currently connected peer. */ + BSP_EVENT_RESET, /**< The device should reset. */ + BSP_EVENT_SLEEP, /**< The device should enter sleep mode. */ + BSP_EVENT_WAKEUP, /**< The device should wake up from sleep mode. */ + BSP_EVENT_SYSOFF, /**< The device should enter system off mode (without wakeup). */ + BSP_EVENT_DFU, /**< The device should enter DFU mode. */ + BSP_EVENT_KEY_0, /**< Default event of the push action of BSP_BUTTON_0 (only if this button is present). */ + BSP_EVENT_KEY_1, /**< Default event of the push action of BSP_BUTTON_1 (only if this button is present). */ + BSP_EVENT_KEY_2, /**< Default event of the push action of BSP_BUTTON_2 (only if this button is present). */ + BSP_EVENT_KEY_3, /**< Default event of the push action of BSP_BUTTON_3 (only if this button is present). */ + BSP_EVENT_KEY_4, /**< Default event of the push action of BSP_BUTTON_4 (only if this button is present). */ + BSP_EVENT_KEY_5, /**< Default event of the push action of BSP_BUTTON_5 (only if this button is present). */ + BSP_EVENT_KEY_6, /**< Default event of the push action of BSP_BUTTON_6 (only if this button is present). */ + BSP_EVENT_KEY_7, /**< Default event of the push action of BSP_BUTTON_7 (only if this button is present). */ + BSP_EVENT_KEY_LAST = BSP_EVENT_KEY_7, +} bsp_event_t; + + +typedef struct +{ + bsp_event_t push_event; /**< The event to fire on regular button press. */ + bsp_event_t long_push_event; /**< The event to fire on long button press. */ + bsp_event_t release_event; /**< The event to fire on button release. */ +} bsp_button_event_cfg_t; + +/**@brief BSP module event callback function type. + * + * @details Upon an event in the BSP module, this callback function will be called to notify + * the application about the event. + * + * @param[in] bsp_event_t BSP event type. + */ +typedef void (* bsp_event_callback_t)(bsp_event_t); + + +/**@brief Function for initializing BSP. + * + * @details The function initializes the board support package to allow state indication and + * button reaction. Default events are assigned to buttons. + * @note Before calling this function, you must initiate the following required modules: + * - @ref app_timer for LED support + * - @ref app_gpiote for button support + * + * @param[in] type Type of peripherals used. + * @param[in] callback Function to be called when button press/event is detected. + * + * @retval NRF_SUCCESS If the BSP module was successfully initialized. + * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized. + * @retval NRF_ERROR_NO_MEM If the maximum number of timers has already been reached. + * @retval NRF_ERROR_INVALID_PARAM If GPIOTE has too many users. + * @retval NRF_ERROR_INVALID_STATE If button or GPIOTE has not been initialized. + */ +uint32_t bsp_init(uint32_t type, bsp_event_callback_t callback); + + +/**@brief Function for checking button states. + * + * @details This function checks if the button is pressed. If the button ID is out of range, + * the function returns false. + * + * @param[in] button Button ID to check. + * + * @retval true If the button is pressed. + * @retval false If the button is not pressed. + */ +bool bsp_button_is_pressed(uint32_t button); + + +/**@brief Function for assigning a specific event to a button. + * + * @details This function allows redefinition of standard events assigned to buttons. + * To unassign events, provide the event @ref BSP_EVENT_NOTHING. + * + * @param[in] button Button ID to be redefined. + * @param[in] action Button action to assign event to. + * @param[in] event Event to be assigned to button. + * + * @retval NRF_SUCCESS If the event was successfully assigned to button. + * @retval NRF_ERROR_INVALID_PARAM If the button ID or button action was invalid. + */ +uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event); + + +/**@brief Function for configuring indicators to required state. + * + * @details This function indicates the required state by means of LEDs (if enabled). + * + * @note Alerts are indicated independently. + * + * @param[in] indicate State to be indicated. + * + * @retval NRF_SUCCESS If the state was successfully indicated. + * @retval NRF_ERROR_NO_MEM If the internal timer operations queue was full. + * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized, + * or internal timer has not been created. + */ +uint32_t bsp_indication_set(bsp_indication_t indicate); + + +/**@brief Function for enabling all buttons. + * + * @details After calling this function, all buttons will generate events when pressed, and + * all buttons will be able to wake the system up from sleep mode. + * + * @retval NRF_SUCCESS If the buttons were successfully enabled. + * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined. + * @return A propagated error. + */ +uint32_t bsp_buttons_enable(void); + + +/**@brief Function for disabling all buttons. + * + * @details After calling this function, no buttons will generate events when pressed, and + * no buttons will be able to wake the system up from sleep mode. + * + * @retval NRF_SUCCESS If the buttons were successfully disabled. + * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined. + * @return A propagated error. + */ +uint32_t bsp_buttons_disable(void); + + +/**@brief Function for enabling wakeup from SYSTEM OFF for given button. + * + * @details After calling this function, button can be used to wake up the chip. + * This function should only be called immediately before going into sleep. + * + * @param[in] button_idx Index of the button. + * + * @retval NRF_SUCCESS If the button was successfully enabled. + * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined. + */ +uint32_t bsp_wakeup_button_enable(uint32_t button_idx); + + +/**@brief Function for disabling wakeup for the given button. + * + * @param[in] button_idx index of the button. + * + * @retval NRF_SUCCESS If the button was successfully disabled. + * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined. + */ +uint32_t bsp_wakeup_button_disable(uint32_t button_idx); + + +#ifdef __cplusplus +} +#endif + +#endif // BSP_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_btn_ant.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_btn_ant.c new file mode 100644 index 0000000000000000000000000000000000000000..69fe04cb44907ad063cb38ac7575c803c9e8f372 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_btn_ant.c @@ -0,0 +1,171 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "bsp_btn_ant.h" +#include +#include "bsp.h" +#include "ant_stack_handler_types.h" +#include "ant_parameters.h" + +#define BTN_ID_WAKEUP 3 /**< ID of button used to wake up the application. */ +#define BTN_ID_SLEEP 3 /**< ID of button used to put the application into sleep mode. */ + +#define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */ + + + /**@brief This macro will return from the current function if err_code + * is not NRF_SUCCESS or NRF_ERROR_INVALID_PARAM. + */ +#define RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code) \ +do \ +{ \ + if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_INVALID_PARAM)) \ + { \ + return err_code; \ + } \ +} \ +while (0) + + +/**@brief This macro will return from the current function if err_code + * is not NRF_SUCCESS or NRF_ERROR_NOT_SUPPORTED. + */ +#define RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code) \ +do \ +{ \ + if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_NOT_SUPPORTED)) \ + { \ + return err_code; \ + } \ +} \ +while (0) + + +static bool m_connected = false; /**< Notify if channel is connected. */ + + + /**@brief Function for configuring the buttons for connection. + * + * @retval NRF_SUCCESS Configured successfully. + * @return A propagated error code. + */ +static uint32_t connection_buttons_configure(void) +{ + uint32_t err_code; + + err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP, + BTN_ACTION_SLEEP, + BSP_EVENT_DEFAULT); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + return NRF_SUCCESS; +} + + +/**@brief Function for configuring the buttons for searching. + * + * @retval NRF_SUCCESS Configured successfully. + * @return A propagated error code. + */ +static uint32_t searching_buttons_configure(void) +{ + uint32_t err_code; + + err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP, + BTN_ACTION_SLEEP, + BSP_EVENT_SLEEP); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + return NRF_SUCCESS; +} + + +uint32_t bsp_btn_ant_sleep_mode_prepare(void) +{ + uint32_t err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP); + RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code); + + return NRF_SUCCESS; +} + + +void bsp_btn_ant_on_ant_evt(ant_evt_t * p_ant_evt) +{ + uint32_t err_code; + + switch (p_ant_evt->event) + { + case EVENT_RX: + if (!m_connected) + { + err_code = connection_buttons_configure(); + APP_ERROR_CHECK(err_code); + } + + m_connected = true; + break; + + case EVENT_RX_FAIL_GO_TO_SEARCH: + m_connected = false; + + err_code = searching_buttons_configure(); + APP_ERROR_CHECK(err_code); + break; + + default: + break; + } +} + + +uint32_t bsp_btn_ant_init(void) +{ + uint32_t err_code = NRF_SUCCESS; + + if (!m_connected) + { + err_code = searching_buttons_configure(); + } + else + { + err_code = connection_buttons_configure(); + } + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_btn_ant.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_btn_ant.h new file mode 100644 index 0000000000000000000000000000000000000000..53b268c60038bf090000fb813dc07f8c623af83e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_btn_ant.h @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup bsp_btn_ant BSP: ANT Button Module + * @{ + * @ingroup bsp + * + * @brief Module for controlling ANT behavior through button actions. + * + * @details The application must propagate ANT events to the ANT Button Module. + * Based on these events, the ANT Button Module configures the Board Support Package + * to generate BSP events for certain button actions. These BSP events should then be + * handled by the application's BSP event handler. + * + */ + +#ifndef BSP_BTN_ANT_H__ +#define BSP_BTN_ANT_H__ + +#include +#include "ant_stack_handler_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /**@brief Function for initializing the ANT Button Module. + * + * Before calling this function, the BSP module must be initialized with buttons. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error code is + * returned. + */ +uint32_t bsp_btn_ant_init(void); + +/**@brief Function for setting up wakeup buttons before going into sleep mode. + * + * @retval NRF_SUCCESS If the buttons were prepared successfully. Otherwise, a propagated error + * code is returned. + */ +uint32_t bsp_btn_ant_sleep_mode_prepare(void); + +/**@brief Function for handling the application's ANT stack events. + * + * @details This function handles all events from the ANT stack that are of interest to this module. + * + * @param[in] p_ant_evt ANT stack event. + */ +void bsp_btn_ant_on_ant_evt(ant_evt_t * p_ant_evt); + + +#ifdef __cplusplus +} +#endif + +#endif /* BSP_BTN_ANT_H__ */ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_btn_ble.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_btn_ble.c new file mode 100644 index 0000000000000000000000000000000000000000..d1071db25758c7a275b1f22ed305bfe6fe3d36bf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_btn_ble.c @@ -0,0 +1,264 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "bsp_btn_ble.h" +#include +#include +#include +#include "ble.h" +#include "bsp.h" + + +#define BTN_ID_WAKEUP 0 /**< ID of button used to wake up the application. */ +#define BTN_ID_SLEEP 0 /**< ID of button used to put the application into sleep mode. */ +#define BTN_ID_DISCONNECT 0 /**< ID of button used to gracefully terminate a connection on long press. */ +#define BTN_ID_WAKEUP_BOND_DELETE 1 /**< ID of button used to wake up the application and delete all bonding information. */ +#define BTN_ID_WHITELIST_OFF 1 /**< ID of button used to turn off usage of the whitelist. */ + +#define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */ +#define BTN_ACTION_DISCONNECT BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to gracefully terminate a connection on long press. */ +#define BTN_ACTION_WHITELIST_OFF BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to turn off usage of the whitelist. */ + + + +/**@brief This macro will return from the current function if err_code + * is not NRF_SUCCESS. + */ +#define RETURN_ON_ERROR(err_code) \ +do \ +{ \ + if ((err_code) != NRF_SUCCESS) \ + { \ + return err_code; \ + } \ +} \ +while (0) + + +/**@brief This macro will return from the current function if err_code + * is not NRF_SUCCESS or NRF_ERROR_INVALID_PARAM. + */ +#define RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code) \ +do \ +{ \ + if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_INVALID_PARAM)) \ + { \ + return err_code; \ + } \ +} \ +while (0) + + +/**@brief This macro will return from the current function if err_code + * is not NRF_SUCCESS or NRF_ERROR_NOT_SUPPORTED. + */ +#define RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code) \ +do \ +{ \ + if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_NOT_SUPPORTED)) \ + { \ + return err_code; \ + } \ +} \ +while (0) + + +/**@brief This macro will call the registered error handler if err_code + * is not NRF_SUCCESS and the error handler is not NULL. + */ +#define CALL_HANDLER_ON_ERROR(err_code) \ +do \ +{ \ + if (((err_code) != NRF_SUCCESS) && (m_error_handler != NULL)) \ + { \ + m_error_handler(err_code); \ + } \ +} \ +while (0) + + +static bsp_btn_ble_error_handler_t m_error_handler = NULL; /**< Error handler registered by the user. */ +static uint32_t m_num_connections = 0; /**< Number of connections the device is currently in. */ + + +/**@brief Function for configuring the buttons for connection. + * + * @retval NRF_SUCCESS Configured successfully. + * @return A propagated error code. + */ +static uint32_t connection_buttons_configure() +{ + uint32_t err_code; + + err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP, + BTN_ACTION_SLEEP, + BSP_EVENT_DEFAULT); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF, + BTN_ACTION_WHITELIST_OFF, + BSP_EVENT_WHITELIST_OFF); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT, + BTN_ACTION_DISCONNECT, + BSP_EVENT_DISCONNECT); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + return NRF_SUCCESS; +} + + +/**@brief Function for configuring the buttons for advertisement. + * + * @retval NRF_SUCCESS Configured successfully. + * @return A propagated error code. + */ +static uint32_t advertising_buttons_configure() +{ + uint32_t err_code; + + err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT, + BTN_ACTION_DISCONNECT, + BSP_EVENT_DEFAULT); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF, + BTN_ACTION_WHITELIST_OFF, + BSP_EVENT_WHITELIST_OFF); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP, + BTN_ACTION_SLEEP, + BSP_EVENT_SLEEP); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + return NRF_SUCCESS; +} + + +/**@brief Function for extracting the BSP event valid at startup. + * + * @details When a button was used to wake up the device, the button press will not generate an + * interrupt. This function reads which button was pressed at startup, and returns the + * appropriate BSP event. + * + * @param[out] p_startup_event Where to put the extracted BSP event. + */ +static void startup_event_extract(bsp_event_t * p_startup_event) +{ + // React to button states + if (bsp_button_is_pressed(BTN_ID_WAKEUP_BOND_DELETE)) + { + *p_startup_event = BSP_EVENT_CLEAR_BONDING_DATA; + } + else if (bsp_button_is_pressed(BTN_ID_WAKEUP)) + { + *p_startup_event = BSP_EVENT_WAKEUP; + } + else + { + *p_startup_event = BSP_EVENT_NOTHING; + } +} + + +uint32_t bsp_btn_ble_sleep_mode_prepare(void) +{ + uint32_t err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP); + RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code); + + err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP_BOND_DELETE); + RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code); + + return NRF_SUCCESS; +} + + +void bsp_btn_ble_on_ble_evt(ble_evt_t * p_ble_evt) +{ + uint32_t err_code; + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + if (m_num_connections == 0) + { + err_code = connection_buttons_configure(); + CALL_HANDLER_ON_ERROR(err_code); + } + + m_num_connections++; + break; + + case BLE_GAP_EVT_DISCONNECTED: + m_num_connections--; + + if (m_num_connections == 0) + { + err_code = advertising_buttons_configure(); + CALL_HANDLER_ON_ERROR(err_code); + } + break; + + default: + break; + } +} + + +uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt) +{ + uint32_t err_code = NRF_SUCCESS; + + m_error_handler = error_handler; + + if (p_startup_bsp_evt != NULL) + { + startup_event_extract(p_startup_bsp_evt); + } + + if (m_num_connections == 0) + { + err_code = advertising_buttons_configure(); + } + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_btn_ble.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_btn_ble.h new file mode 100644 index 0000000000000000000000000000000000000000..5bf76b7020b1448ade7c421c743d964be0184671 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_btn_ble.h @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup bsp_btn_ble BSP: BLE Button Module + * @{ + * @ingroup bsp + * + * @brief Module for controlling BLE behavior through button actions. + * + * @details The application must propagate BLE events to the BLE Button Module. + * Based on these events, the BLE Button Module configures the Board Support Package + * to generate BSP events for certain button actions. These BSP events should then be + * handled by the application's BSP event handler. + * + */ + +#ifndef BSP_BTN_BLE_H__ +#define BSP_BTN_BLE_H__ + +#include +#include "ble.h" +#include "bsp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief BLE Button Module error handler type. */ +typedef void (*bsp_btn_ble_error_handler_t) (uint32_t nrf_error); + +/**@brief Function for initializing the BLE Button Module. + * + * Before calling this function, the BSP module must be initialized with buttons. + * + * @param[out] error_handler Error handler to call in case of internal errors in BLE Button + * Module. + * @param[out] p_startup_bsp_evt If not a NULL pointer, the value is filled with an event + * (or BSP_EVENT_NOTHING) derived from the buttons pressed on + * startup. For example, if the bond delete wakeup button was pressed + * to wake up the device, *p_startup_bsp_evt is set to + * @ref BSP_EVENT_CLEAR_BONDING_DATA. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error code is + * returned. + */ +uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt); + +/**@brief Function for setting up wakeup buttons before going into sleep mode. + * + * @retval NRF_SUCCESS If the buttons were prepared successfully. Otherwise, a propagated error + * code is returned. + */ +uint32_t bsp_btn_ble_sleep_mode_prepare(void); + +/**@brief Function for handling the application's BLE stack events. + * + * @details This function handles all events from the BLE stack that are of interest to this module. + * + * @param[in] p_ble_evt BLE stack event. + */ +void bsp_btn_ble_on_ble_evt(ble_evt_t * p_ble_evt); + + +#ifdef __cplusplus +} +#endif + +#endif /* BSP_BTN_BLE_H__ */ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_config.h new file mode 100644 index 0000000000000000000000000000000000000000..47b264a88420cbb25604a0ec1d1a2eaba6b1e929 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_config.h @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup bsp Board Support Package + * @{ + * @ingroup app_common + * + * @brief BSP module. + * @details This module provides a layer of abstraction from the board. + * It allows the user to indicate certain states on LEDs in a simple way. + * Module functionality can be modified by additional defines: + * - BSP_SIMPLE - reduces functionality of this module to enable + * and read state of the buttons. + * - BSP_UART_SUPPORT - enables support for UART. + */ + +#ifndef BSP_CONFIG_H__ +#define BSP_CONFIG_H__ + +#include +#include +#include "boards.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(BSP_DEFINES_ONLY) && !defined(BSP_SIMPLE) +#include "app_button.h" + +#define BSP_BUTTON_ACTION_PUSH (APP_BUTTON_PUSH) /**< Represents pushing a button. See @ref bsp_button_action_t. */ +#define BSP_BUTTON_ACTION_RELEASE (APP_BUTTON_RELEASE) /**< Represents releasing a button. See @ref bsp_button_action_t. */ +#define BSP_BUTTON_ACTION_LONG_PUSH (2) /**< Represents pushing and holding a button for @ref BSP_LONG_PUSH_TIMEOUT_MS milliseconds. See also @ref bsp_button_action_t. */ +#endif + +#define BSP_MS_TO_TICK(MS) (m_app_ticks_per_100ms * (MS / 100)) + + +#define BUTTON_ERASE_BONDING BSP_BUTTON_0_MASK +#define BUTTON_ERASE_ALL BSP_BUTTON_1_MASK +#define BUTTON_ADVERTISE BSP_BUTTON_0_MASK +#define BUTTON_CLEAR_EVT BSP_BUTTON_1_MASK +#define BUTTON_CAPSLOCK BSP_BUTTON_2_MASK +#define BSP_BUTTONS_ALL 0xFFFFFFFF +#define BSP_BUTTONS_NONE 0 + +#define BSP_LONG_PUSH_TIMEOUT_MS (1000) /**< The time to hold for a long push (in milliseconds). */ +/**@brief Types of BSP initialization. + */ + +#define ADVERTISING_LED_ON_INTERVAL 200 +#define ADVERTISING_LED_OFF_INTERVAL 1800 + +#define ADVERTISING_DIRECTED_LED_ON_INTERVAL 200 +#define ADVERTISING_DIRECTED_LED_OFF_INTERVAL 200 + +#define ADVERTISING_WHITELIST_LED_ON_INTERVAL 200 +#define ADVERTISING_WHITELIST_LED_OFF_INTERVAL 800 + +#define ADVERTISING_SLOW_LED_ON_INTERVAL 400 +#define ADVERTISING_SLOW_LED_OFF_INTERVAL 4000 + +#define BONDING_INTERVAL 100 + +#define SENT_OK_INTERVAL 100 +#define SEND_ERROR_INTERVAL 500 + +#define RCV_OK_INTERVAL 100 +#define RCV_ERROR_INTERVAL 500 + +#define ALERT_INTERVAL 200 + +#define BSP_LED_INDICATE_SENT_OK BSP_BOARD_LED_1 +#define BSP_LED_INDICATE_SEND_ERROR BSP_BOARD_LED_1 +#define BSP_LED_INDICATE_RCV_OK BSP_BOARD_LED_1 +#define BSP_LED_INDICATE_RCV_ERROR BSP_BOARD_LED_1 +#define BSP_LED_INDICATE_CONNECTED BSP_BOARD_LED_0 +#define BSP_LED_INDICATE_BONDING BSP_BOARD_LED_0 +#define BSP_LED_INDICATE_ADVERTISING_DIRECTED BSP_BOARD_LED_0 +#define BSP_LED_INDICATE_ADVERTISING_SLOW BSP_BOARD_LED_0 +#define BSP_LED_INDICATE_ADVERTISING_WHITELIST BSP_BOARD_LED_0 +#define BSP_LED_INDICATE_INDICATE_ADVERTISING BSP_BOARD_LED_0 + +#define BSP_LED_INDICATE_USER_LED1 BSP_BOARD_LED_0 +#define BSP_LED_INDICATE_USER_LED2 BSP_BOARD_LED_1 +#define BSP_LED_INDICATE_USER_LED3 BSP_BOARD_LED_2 +#define BSP_LED_INDICATE_USER_LED4 BSP_BOARD_LED_3 + +#define BSP_LED_ALERT BSP_BOARD_LED_2 + +#ifdef __cplusplus +} +#endif + +#endif // BSP_CONFIG_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_nfc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_nfc.c new file mode 100644 index 0000000000000000000000000000000000000000..d42e1ab41211b4352d6fb6d883bdc365587eb713 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_nfc.c @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "bsp_nfc.h" +#include "bsp.h" +#include "nrf.h" +#include "app_util_platform.h" + +#ifndef BSP_SIMPLE +#define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */ + +ret_code_t bsp_nfc_btn_init(uint32_t sleep_button) +{ + uint32_t err_code = bsp_event_to_button_action_assign(sleep_button, + BTN_ACTION_SLEEP, + BSP_EVENT_SLEEP); + return err_code; +} + +ret_code_t bsp_nfc_btn_deinit(uint32_t sleep_button) +{ + uint32_t err_code = bsp_event_to_button_action_assign(sleep_button, + BTN_ACTION_SLEEP, + BSP_EVENT_DEFAULT); + return err_code; +} + +ret_code_t bsp_nfc_sleep_mode_prepare(void) +{ +#if defined(NFCT_PRESENT) + // Check if peripheral is not used. + CRITICAL_REGION_ENTER(); +#ifdef NRF52832_XXAA + if ((*(uint32_t *)0x40005410 & 0x07) == 0) +#else + if ((NRF_NFCT->NFCTAGSTATE & NFCT_NFCTAGSTATE_NFCTAGSTATE_Msk) + == NFCT_NFCTAGSTATE_NFCTAGSTATE_Disabled) +#endif // NRF52832_XXAA + { + NRF_NFCT->TASKS_SENSE = 1; + } + CRITICAL_REGION_EXIT(); + return NRF_SUCCESS; +#else + return NRF_ERROR_NOT_SUPPORTED; +#endif +} +#endif //BSP_SIMPLE diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_nfc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_nfc.h new file mode 100644 index 0000000000000000000000000000000000000000..9e0380aa8c7a8ec6a38a1a83ec64cb615e6f6e9a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/bsp/bsp_nfc.h @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup bsp_nfc NFC BSP Module + * @{ + * @ingroup bsp + * + * @brief Module for setting the NFCT peripheral as a wakeup source. + * + * @details The application must notify this module before going into System OFF mode. + * Based on this notification, the NFC BSP Module sets the NFCT peripheral as a wakeup source + * through the Board Support Package. Additionally, any BSP Button can be configured to + * generate BSP sleep events. This module is applicable only if NFCT is used exclusively for + * wakeup. If NFCT is used for a different purpose, this module cannot be used. + */ + +#ifndef BSP_NFC_H__ +#define BSP_NFC_H__ + +#include +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Function for initializing the NFC Button Module. + * + * Before calling this function, the BSP module must be initialized with buttons. The chosen + * button is used to generate @ref BSP_EVENT_SLEEP events. + * + * @param[in] sleep_button Button ID used to generate @ref BSP_EVENT_SLEEP event. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error + * code is returned. + */ +ret_code_t bsp_nfc_btn_init(uint32_t sleep_button); + +/**@brief Function for deinitializing the NFC Button Module. + * + * Before calling this function, the BSP module must be initialized with buttons. The chosen + * button is used to generate default @ref BSP_EVENT_DEFAULT events. + * + * @param[in] sleep_button Button ID used to restore default event generation. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error + * code is returned. + */ +ret_code_t bsp_nfc_btn_deinit(uint32_t sleep_button); + +/**@brief Function for setting up NFCT peripheral as wake-up source. + * + * This function must be called before going into System OFF mode. + * + * @note This function is only applicable if NFCT is used exclusively for wakeup. + * If NFCT is used for a different purpose, this function cannot be used. + * + * @retval NRF_SUCCESS If NFCT peripheral was prepared successfully. Otherwise, + * a propagated error code is returned. + */ +ret_code_t bsp_nfc_sleep_mode_prepare(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BSP_NFC_H__ */ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/button/app_button.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/button/app_button.c new file mode 100644 index 0000000000000000000000000000000000000000..9cc900097fa45fb6837e5080eb96d2611b412d40 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/button/app_button.c @@ -0,0 +1,219 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BUTTON) +#include "app_button.h" +#include "app_timer.h" +#include "app_error.h" +#include "nrf_drv_gpiote.h" +#include "nrf_assert.h" + + +static app_button_cfg_t const * mp_buttons = NULL; /**< Button configuration. */ +static uint8_t m_button_count; /**< Number of configured buttons. */ +static uint32_t m_detection_delay; /**< Delay before a button is reported as pushed. */ +APP_TIMER_DEF(m_detection_delay_timer_id); /**< Polling timer id. */ + + +static uint32_t m_pin_state; +static uint32_t m_pin_transition; + +/**@brief Function for handling the timeout that delays reporting buttons as pushed. + * + * @details The detection_delay_timeout_handler(...) is a call-back issued from the app_timer + * module. It is called with the p_context parameter. The p_context parameter is + * provided to the app_timer module when a timer is started, using the call + * @ref app_timer_start. On @ref app_timer_start the p_context will be holding the + * currently pressed buttons. + * + * @param[in] p_context Pointer used for passing information app_start_timer() was called. + * In the app_button module the p_context holds information on pressed + * buttons. + */ +static void detection_delay_timeout_handler(void * p_context) +{ + uint8_t i; + + // Pushed button(s) detected, execute button handler(s). + for (i = 0; i < m_button_count; i++) + { + app_button_cfg_t const * p_btn = &mp_buttons[i]; + uint32_t btn_mask = 1 << p_btn->pin_no; + if (btn_mask & m_pin_transition) + { + m_pin_transition &= ~btn_mask; + bool pin_is_set = nrf_drv_gpiote_in_is_set(p_btn->pin_no); + if ((m_pin_state & (1 << p_btn->pin_no)) == (pin_is_set << p_btn->pin_no)) + { + uint32_t transition = !(pin_is_set ^ (p_btn->active_state == APP_BUTTON_ACTIVE_HIGH)); + + if (p_btn->button_handler) + { + p_btn->button_handler(p_btn->pin_no, transition); + } + } + } + } +} + +static void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) +{ + uint32_t err_code; + uint32_t pin_mask = 1 << pin; + + // Start detection timer. If timer is already running, the detection period is restarted. + // NOTE: Using the p_context parameter of app_timer_start() to transfer the pin states to the + // timeout handler (by casting event_pins_mask into the equally sized void * p_context + // parameter). + err_code = app_timer_stop(m_detection_delay_timer_id); + if (err_code != NRF_SUCCESS) + { + // The impact in app_button of the app_timer queue running full is losing a button press. + // The current implementation ensures that the system will continue working as normal. + return; + } + + if (!(m_pin_transition & pin_mask)) + { + if (nrf_drv_gpiote_in_is_set(pin)) + { + m_pin_state |= pin_mask; + } + else + { + m_pin_state &= ~(pin_mask); + } + m_pin_transition |= (pin_mask); + + err_code = app_timer_start(m_detection_delay_timer_id, m_detection_delay, NULL); + if (err_code != NRF_SUCCESS) + { + // The impact in app_button of the app_timer queue running full is losing a button press. + // The current implementation ensures that the system will continue working as normal. + } + } + else + { + m_pin_transition &= ~pin_mask; + } +} + +uint32_t app_button_init(app_button_cfg_t const * p_buttons, + uint8_t button_count, + uint32_t detection_delay) +{ + uint32_t err_code; + + if (detection_delay < APP_TIMER_MIN_TIMEOUT_TICKS) + { + return NRF_ERROR_INVALID_PARAM; + } + + if (!nrf_drv_gpiote_is_init()) + { + err_code = nrf_drv_gpiote_init(); + VERIFY_SUCCESS(err_code); + } + + // Save configuration. + mp_buttons = p_buttons; + m_button_count = button_count; + m_detection_delay = detection_delay; + + m_pin_state = 0; + m_pin_transition = 0; + + while (button_count--) + { + app_button_cfg_t const * p_btn = &p_buttons[button_count]; + + nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); + config.pull = p_btn->pull_cfg; + + err_code = nrf_drv_gpiote_in_init(p_btn->pin_no, &config, gpiote_event_handler); + VERIFY_SUCCESS(err_code); + } + + // Create polling timer. + return app_timer_create(&m_detection_delay_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + detection_delay_timeout_handler); +} + +uint32_t app_button_enable(void) +{ + ASSERT(mp_buttons); + + uint32_t i; + for (i = 0; i < m_button_count; i++) + { + nrf_drv_gpiote_in_event_enable(mp_buttons[i].pin_no, true); + } + + return NRF_SUCCESS; +} + + +uint32_t app_button_disable(void) +{ + ASSERT(mp_buttons); + + uint32_t i; + for (i = 0; i < m_button_count; i++) + { + nrf_drv_gpiote_in_event_disable(mp_buttons[i].pin_no); + } + + // Make sure polling timer is not running. + return app_timer_stop(m_detection_delay_timer_id); +} + + +bool app_button_is_pushed(uint8_t button_id) +{ + ASSERT(button_id <= m_button_count); + ASSERT(mp_buttons != NULL); + + app_button_cfg_t const * p_btn = &mp_buttons[button_id]; + bool is_set = nrf_drv_gpiote_in_is_set(p_btn->pin_no); + + return !(is_set ^ (p_btn->active_state == APP_BUTTON_ACTIVE_HIGH)); +} +#endif //NRF_MODULE_ENABLED(BUTTON) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/button/app_button.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/button/app_button.h new file mode 100644 index 0000000000000000000000000000000000000000..9b2e4793877197475e53a602b12ebd9f41d586eb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/button/app_button.h @@ -0,0 +1,146 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup app_button Button Handler + * @{ + * @ingroup app_common + * + * @brief Buttons handling module. + * + * @details The button handler uses the @ref app_gpiote to detect that a button has been + * pushed. To handle debouncing, it will start a timer in the GPIOTE event handler. + * The button will only be reported as pushed if the corresponding pin is still active when + * the timer expires. If there is a new GPIOTE event while the timer is running, the timer + * is restarted. + * + * @note The app_button module uses the app_timer module. The user must ensure that the queue in + * app_timer is large enough to hold the app_timer_stop() / app_timer_start() operations + * which will be executed on each event from GPIOTE module (2 operations), as well as other + * app_timer operations queued simultaneously in the application. + * + * @note Even if the scheduler is not used, app_button.h will include app_scheduler.h, so when + * compiling, app_scheduler.h must be available in one of the compiler include paths. + */ + +#ifndef APP_BUTTON_H__ +#define APP_BUTTON_H__ + +#include +#include +#include "nrf.h" +#include "app_error.h" +#include "nrf_gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define APP_BUTTON_PUSH 1 /**< Indicates that a button is pushed. */ +#define APP_BUTTON_RELEASE 0 /**< Indicates that a button is released. */ +#define APP_BUTTON_ACTIVE_HIGH 1 /**< Indicates that a button is active high. */ +#define APP_BUTTON_ACTIVE_LOW 0 /**< Indicates that a button is active low. */ + +/**@brief Button event handler type. */ +typedef void (*app_button_handler_t)(uint8_t pin_no, uint8_t button_action); + +/**@brief Button configuration structure. */ +typedef struct +{ + uint8_t pin_no; /**< Pin to be used as a button. */ + uint8_t active_state; /**< APP_BUTTON_ACTIVE_HIGH or APP_BUTTON_ACTIVE_LOW. */ + nrf_gpio_pin_pull_t pull_cfg; /**< Pull-up or -down configuration. */ + app_button_handler_t button_handler; /**< Handler to be called when button is pushed. */ +} app_button_cfg_t; + +/**@brief Pin transition direction struct. */ +typedef struct +{ + uint32_t high_to_low; /**Pin went from high to low */ + uint32_t low_to_high; /**Pin went from low to high */ +} pin_transition_t; + +/**@brief Function for initializing the Buttons. + * + * @details This function will initialize the specified pins as buttons, and configure the Button + * Handler module as a GPIOTE user (but it will not enable button detection). + * + * @note Normally initialization should be done using the APP_BUTTON_INIT() macro + * + * @note app_button_enable() function must be called in order to enable the button detection. + * + * @param[in] p_buttons Array of buttons to be used (NOTE: Must be static!). + * @param[in] button_count Number of buttons. + * @param[in] detection_delay Delay from a GPIOTE event until a button is reported as pushed. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t app_button_init(app_button_cfg_t const * p_buttons, + uint8_t button_count, + uint32_t detection_delay); + +/**@brief Function for enabling button detection. + * + * @retval NRF_SUCCESS Module successfully enabled. + */ +uint32_t app_button_enable(void); + +/**@brief Function for disabling button detection. + * + * @retval NRF_SUCCESS Button detection successfully disabled. Error code otherwise. + */ +uint32_t app_button_disable(void); + +/**@brief Function for checking if a button is currently being pushed. + * + * @param[in] button_id Button index (in the app_button_cfg_t array given to app_button_init) to be checked. + * + * @return Button state. + */ +bool app_button_is_pushed(uint8_t button_id); + + +#ifdef __cplusplus +} +#endif + +#endif // APP_BUTTON_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c new file mode 100644 index 0000000000000000000000000000000000000000..fa0242952cd7fe69e33f8c225d82ce5633c45742 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CLI_CDC_ACM) +#include "nrf_cli_cdc_acm.h" +#include "nrf_queue.h" + +static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_cdc_acm_user_event_t event); + + +/** + * @brief Interfaces list passed to @ref APP_USBD_CDC_ACM_GLOBAL_DEF + * */ +#define NRF_CLI_CDC_ACM_INTERFACES_CONFIG() \ + APP_USBD_CDC_ACM_CONFIG(NRF_CLI_CDC_ACM_COMM_INTERFACE, \ + NRF_CLI_CDC_ACM_COMM_EPIN, \ + NRF_CLI_CDC_ACM_DATA_INTERFACE, \ + NRF_CLI_CDC_ACM_DATA_EPIN, \ + NRF_CLI_CDC_ACM_DATA_EPOUT) + +static const uint8_t m_cdc_acm_class_descriptors[] = { + APP_USBD_CDC_ACM_DEFAULT_DESC(NRF_CLI_CDC_ACM_COMM_INTERFACE, + NRF_CLI_CDC_ACM_COMM_EPIN, + NRF_CLI_CDC_ACM_DATA_INTERFACE, + NRF_CLI_CDC_ACM_DATA_EPIN, + NRF_CLI_CDC_ACM_DATA_EPOUT) +}; + +/*lint -save -e26 -e40 -e64 -e123 -e505 -e651*/ + +/** + * @brief CDC_ACM class instance. + * */ +APP_USBD_CDC_ACM_GLOBAL_DEF(nrf_cli_cdc_acm, + NRF_CLI_CDC_ACM_INTERFACES_CONFIG(), + cdc_acm_user_ev_handler, + m_cdc_acm_class_descriptors +); + +/*lint -restore*/ + +NRF_QUEUE_DEF(uint8_t, + m_rx_queue, + NRF_DRV_USBD_EPSIZE, + NRF_QUEUE_MODE_OVERFLOW); + +static bool m_port_is_open; +static char m_rx_buffer[NRF_DRV_USBD_EPSIZE]; + +/** + * @brief User event handler. + * */ +static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_cdc_acm_user_event_t event) +{ + app_usbd_cdc_acm_t const * p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst); + + + + switch (event) + { + case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN: + { + m_port_is_open = true; + /*Setup first transfer*/ + ret_code_t ret = app_usbd_cdc_acm_read(&nrf_cli_cdc_acm, + m_rx_buffer, + sizeof(m_rx_buffer)); + APP_ERROR_CHECK(ret); + break; + } + case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE: + m_port_is_open = false; + break; + case APP_USBD_CDC_ACM_USER_EVT_TX_DONE: + break; + case APP_USBD_CDC_ACM_USER_EVT_RX_DONE: + { + /*Get amount of data transfered*/ + size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm); + size_t qsize = nrf_queue_in(&m_rx_queue, m_rx_buffer, size); + ASSERT(size == qsize); + + /*Setup next transfer*/ + ret_code_t ret = app_usbd_cdc_acm_read(&nrf_cli_cdc_acm, + m_rx_buffer, + sizeof(m_rx_buffer)); + + ASSERT(ret == NRF_SUCCESS); /*Should not happen*/ + break; + } + default: + break; + } +} + +static ret_code_t cli_cdc_acm_init(void) +{ + return NRF_SUCCESS; +} + +static ret_code_t cli_cdc_acm_uninit(void) +{ + return NRF_SUCCESS; +} + +static ret_code_t cli_cdc_acm_read(void * p_data, + size_t length, + size_t * p_cnt) +{ + size_t size = nrf_queue_out(&m_rx_queue, p_data, length); + if (p_cnt) + { + *p_cnt = size; + } + + return NRF_SUCCESS; +} + +static ret_code_t cli_cdc_acm_write(const void * p_data, + size_t length, + size_t * p_cnt) +{ + ret_code_t ret; + do { + + ret = app_usbd_cdc_acm_write(&nrf_cli_cdc_acm, p_data, length); + if (ret == NRF_SUCCESS && p_cnt) + { + *p_cnt = length; + } + + } while(ret == NRF_ERROR_BUSY); + + return ret; +} + +const nrf_cli_transport_t nrf_cli_cdc_acm_transport = { + .init = cli_cdc_acm_init, + .uninit = cli_cdc_acm_uninit, + .read = cli_cdc_acm_read, + .write = cli_cdc_acm_write, +}; + +bool nrf_cli_cdc_acm_port_is_open(void) +{ + return m_port_is_open; +} + +#endif // NRF_MODULE_ENABLED(NRF_CLI_CDC_ACM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h new file mode 100644 index 0000000000000000000000000000000000000000..9e9408a10d6b941263852b1b9a3e271c371f64cd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CLI_CDC_ACM_H__ +#define NRF_CLI_CDC_ACM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "nrf_cli.h" +#include "app_usbd_cdc_acm.h" + + +/**@file + * + * @defgroup nrf_cli_cdc_acm CDC ACM command line interface transport layer. + * @ingroup nrf_cli + * + * @{ + * + */ + +/** + * @brief Command line interface transport. + * */ +extern const nrf_cli_transport_t nrf_cli_cdc_acm_transport; + +/** + * @brief Command line interface class instance. + * */ +extern const app_usbd_cdc_acm_t nrf_cli_cdc_acm; + + +/** + * @brief Get CDC ACM port status. + * */ +bool nrf_cli_cdc_acm_port_is_open(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_CLI_CDC_ACM_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/nrf_cli.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/nrf_cli.c new file mode 100644 index 0000000000000000000000000000000000000000..9e6d512a246d8f4d5b8c31688043f5462cade966 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/nrf_cli.c @@ -0,0 +1,875 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CLI) +#include +#include +#include + +#include "nrf_cli.h" +#include "nrf_assert.h" + +/** + * @brief Maximum commands per line after tab key press. + * */ +#define NRF_CLI_TAB_CMD_PER_LINE (8) + +static void cli_write(nrf_cli_t const * p_cli, + void const * p_data, + size_t length, + size_t * p_cnt) +{ + ASSERT(p_cli && p_data); + ASSERT(p_cli->p_iface->write); + ret_code_t ret = p_cli->p_iface->write(p_data, length, p_cnt); + UNUSED_VARIABLE(ret); +} + +static void cli_read(nrf_cli_t const * p_cli, + void * p_data, + size_t length, + size_t * p_cnt) +{ + ASSERT(p_cli && p_data); + ASSERT(p_cli->p_iface->read); + ret_code_t ret = p_cli->p_iface->read(p_data, length, p_cnt); + UNUSED_VARIABLE(ret); +} + +#if NRF_CLI_VT100_COLORS +static void vt100_color_set(nrf_cli_t const * p_cli, vt100_color_t color) +{ + const uint8_t cmd[] = VT100_COLOR(color); + + if (p_cli->p_ctx->vt100_ctx.col.col == color) + { + return; + } + + p_cli->p_ctx->vt100_ctx.col.col = color; + cli_write(p_cli, cmd, sizeof(cmd), NULL); +} + +static void vt100_bgcolor_set(nrf_cli_t const * p_cli, vt100_color_t bgcolor) +{ + const uint8_t cmd[] = VT100_BGCOLOR(bgcolor); + + if (p_cli->p_ctx->vt100_ctx.col.bgcol == bgcolor) + { + return; + } + + p_cli->p_ctx->vt100_ctx.col.bgcol = bgcolor; + cli_write(p_cli, cmd, sizeof(cmd), NULL); +} + +static void vt100_colors_store(nrf_cli_t const * p_cli, + vt100_colors_t * p_color) +{ + memcpy(p_color, &p_cli->p_ctx->vt100_ctx.col, sizeof(vt100_colors_t)); +} + +static void vt100_colors_restore(nrf_cli_t const * p_cli, + vt100_colors_t const * p_color) +{ + vt100_color_set(p_cli, p_color->col); + vt100_bgcolor_set(p_cli, p_color->bgcol); +} + +static void vt100_screen_clear(nrf_cli_t const * p_cli) +{ + static const uint8_t cmd[] = VT100_CLEARSCREEN; + cli_write(p_cli, cmd, sizeof(cmd), NULL); +} + +static void vt100_cursor_set(nrf_cli_t const * p_cli, uint16_t x, uint16_t y) +{ + char cmd[24]; + sprintf(cmd, "%c[%d;%dH", VT100_ASCII_ESC, y + 1, x + 1); + + cli_write(p_cli, cmd, strlen(cmd), NULL); +} +#else +static void vt100_color_set(nrf_cli_t const * p_cli, vt100_color_t color) {} +static void vt100_bgcolor_set(nrf_cli_t const * p_cli, vt100_color_t bgcolor) {} +static void vt100_colors_store(nrf_cli_t const * p_cli, + vt100_colors_t * p_color) {} +static void vt100_colors_restore(nrf_cli_t const * p_cli, + vt100_colors_t const * p_color) {} +static void vt100_screen_clear(nrf_cli_t const * p_cli) {} +static void vt100_cursor_set(nrf_cli_t const * p_cli, uint16_t x, uint16_t y) {} +#endif + +static void cli_putc(nrf_cli_t const * p_cli, char ch) +{ + cli_write(p_cli, &ch, sizeof(ch), NULL); +} + +ret_code_t nrf_cli_init(nrf_cli_t const * p_cli) +{ + ASSERT(p_cli); + ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name && p_cli->p_cmd_set); + + ret_code_t ret = p_cli->p_iface->init(); + if (ret != NRF_SUCCESS) + { + return ret; + } + + memset(p_cli->p_ctx, 0, sizeof(nrf_cli_ctx_t)); + p_cli->p_ctx->state = NRF_CLI_STATE_INITIALIZED; + + vt100_color_set(p_cli, NRF_CLI_NORMAL); + vt100_bgcolor_set(p_cli, VT100_COLOR_BLACK); + vt100_cursor_set(p_cli, 0, 0); + vt100_screen_clear(p_cli); + + return NRF_SUCCESS; +} + + +ret_code_t nrf_cli_uninit(nrf_cli_t const * p_cli) +{ + ASSERT(p_cli); + ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name && p_cli->p_cmd_set); + + ret_code_t ret = p_cli->p_iface->uninit(); + if (ret != NRF_SUCCESS) + { + return ret; + } + + memset(p_cli->p_ctx, 0, sizeof(nrf_cli_ctx_t)); + p_cli->p_ctx->state = NRF_CLI_STATE_UNINITIALIZED; + + return NRF_SUCCESS; +} + +static void cli_state_change(nrf_cli_t const * p_cli, nrf_cli_state_t state) +{ + p_cli->p_ctx->state = state; + switch (p_cli->p_ctx->state) + { + case NRF_CLI_STATE_COLLECT: + p_cli->p_ctx->cmd_buff_pos = 0; + nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "%s", p_cli->p_name); + break; + default: + break; + } +} + +ret_code_t nrf_cli_start(nrf_cli_t const * p_cli) +{ + if (p_cli->p_ctx->state != NRF_CLI_STATE_INITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + + cli_state_change(p_cli, NRF_CLI_STATE_COLLECT); + return NRF_SUCCESS; +} + +ret_code_t nrf_cli_stop(nrf_cli_t const * p_cli) +{ + if (p_cli->p_ctx->state == NRF_CLI_STATE_INITIALIZED || + p_cli->p_ctx->state == NRF_CLI_STATE_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + + cli_state_change(p_cli, NRF_CLI_STATE_INITIALIZED); + return NRF_SUCCESS; +} + +static void cli_handle_tab(nrf_cli_t const * p_cli) +{ + size_t i; + + if (p_cli->p_ctx->cmd_buff_pos == 0) + { + /*Show all commands*/ + for (i = 0; i < p_cli->cmd_count; i++) + { + if ((i % NRF_CLI_TAB_CMD_PER_LINE) == 0) + { + nrf_cli_fprintf(p_cli, NRF_CLI_WARNING, "\r\n"); + } + + nrf_cli_fprintf(p_cli, NRF_CLI_WARNING, " %s", + p_cli->p_cmd_set[i].p_syntax); + } + + nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "\r\n%s", p_cli->p_name); + return; + } + + size_t match_cnt = 0; + size_t last_match = 0; + + for (i = 0; i < p_cli->cmd_count; i++) + { + if (strncmp(p_cli->p_cmd_set[i].p_syntax, + p_cli->p_ctx->cmd_buff, + p_cli->p_ctx->cmd_buff_pos) != 0) + { + continue; + } + + match_cnt++; + last_match = i; + } + + if (match_cnt == 0) + { + return; + } + + if (match_cnt == 1) + { + size_t pos = p_cli->p_ctx->cmd_buff_pos; + + strcpy(p_cli->p_ctx->cmd_buff + p_cli->p_ctx->cmd_buff_pos, + p_cli->p_cmd_set[last_match].p_syntax + pos); + + p_cli->p_ctx->cmd_buff_pos = + strlen(p_cli->p_cmd_set[last_match].p_syntax); + + p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos] = ' '; + ++p_cli->p_ctx->cmd_buff_pos; + p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos] = '\0'; + + nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s", + p_cli->p_ctx->cmd_buff + pos); + return; + } + + uint32_t k = 0; + for (i = 0; i < p_cli->cmd_count; i++) + { + if (strncmp(p_cli->p_cmd_set[i].p_syntax, + p_cli->p_ctx->cmd_buff, + p_cli->p_ctx->cmd_buff_pos)) + { + continue; + } + + if ((k % NRF_CLI_TAB_CMD_PER_LINE) == 0) + { + nrf_cli_fprintf(p_cli, NRF_CLI_WARNING, "\r\n"); + } + + nrf_cli_fprintf(p_cli, NRF_CLI_WARNING, " %s", + p_cli->p_cmd_set[i].p_syntax); + k++; + } + + nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "\r\n%s", p_cli->p_name); + p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos] = '\0'; + nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s", p_cli->p_ctx->cmd_buff); + + return; +} + +#if NRF_CLI_HISTORY_COUNT != 0 +static size_t cli_history_increment_mod(size_t act) +{ + if (act < (NRF_CLI_HISTORY_COUNT - 1)) + { + return act + 1; + } + + return 0; +} + +static size_t cli_history_decrement_mod(size_t act) +{ + if (act > 0) + { + return act - 1; + } + + return NRF_CLI_HISTORY_COUNT - 1; +} + + +static void cli_history_handle(nrf_cli_t const * p_cli, bool up) +{ + size_t len; + size_t act = p_cli->p_ctx->cmd_history_act; + if (!up) + { + if (act == p_cli->p_ctx->cmd_history_pos) + { + return; + } + + act = cli_history_increment_mod(act); + if (act == p_cli->p_ctx->cmd_history_pos && + p_cli->p_ctx->cmd_history_mode) + { + size_t clear_size = strlen(p_cli->p_ctx->cmd_buff); + memset(p_cli->p_ctx->cmd_buff, ' ', clear_size); + p_cli->p_ctx->cmd_buff[clear_size] = '\0'; + nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "\r%s%s\r", + p_cli->p_name, + p_cli->p_ctx->cmd_buff); + + p_cli->p_ctx->cmd_history_mode = false; + p_cli->p_ctx->cmd_history_act = act; + cli_state_change(p_cli, NRF_CLI_STATE_COLLECT); + return; + } + } + else + { + if (act == p_cli->p_ctx->cmd_history_pos && + p_cli->p_ctx->cmd_history_mode) + { + return; + } + act = cli_history_decrement_mod(act); + } + + p_cli->p_ctx->cmd_history_mode = true; + len = strlen(p_cli->p_ctx->cmd_history_buff[act]); + if (!len) + { + return; + } + + size_t clear_size = strlen(p_cli->p_ctx->cmd_buff); + if (clear_size > len) + { + nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "\r%s", p_cli->p_name); + memset(p_cli->p_ctx->cmd_buff, ' ', clear_size); + p_cli->p_ctx->cmd_buff[clear_size] = '\0'; + nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s", p_cli->p_ctx->cmd_buff); + } + + p_cli->p_ctx->cmd_history_act = act; + p_cli->p_ctx->cmd_buff_pos = len; + + strcpy(p_cli->p_ctx->cmd_buff, p_cli->p_ctx->cmd_history_buff[act]); + nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "\r%s", p_cli->p_name); + nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s", p_cli->p_ctx->cmd_buff); +} +#else +static void cli_history_handle(nrf_cli_t const * p_cli, bool up) +{ +} +#endif + +static void cli_state_collect(nrf_cli_t const * p_cli) +{ + size_t count = 0; + char data = '\0'; + + while (1) + { + cli_read(p_cli, &data, sizeof(data), &count); + if (count == 0) + { + return; + } + + if (p_cli->p_ctx->escape) + { + p_cli->p_ctx->escape = false; + if (data == '[') + { + p_cli->p_ctx->arrow = true; + return; + } + } + + if (p_cli->p_ctx->arrow) + { + p_cli->p_ctx->arrow = false; + switch (data) + { + case 'A': /*UP arrow*/ + cli_history_handle(p_cli, true); + break; + case 'B': /*DOWN arrow*/ + cli_history_handle(p_cli, false); + break; + default: + break; + } + return; + } + + switch (data) + { + case VT100_ASCII_ESC: + p_cli->p_ctx->escape = true; + break; + case '\0': + break; + case '\t': + cli_handle_tab(p_cli); + break; + case '\n': + break; + case '\r': + if (p_cli->p_ctx->cmd_buff_pos == 0) + { + nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "\r\n", p_cli->p_name); + cli_state_change(p_cli, NRF_CLI_STATE_COLLECT); + break; + } + + p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos] = '\0'; + ++p_cli->p_ctx->cmd_buff_pos; + cli_state_change(p_cli, NRF_CLI_STATE_EXECUTE); + break; + case VT100_ASCII_BSPACE: //ASCII backspace + case VT100_ASCII_DEL: //ASCII delete + + if (p_cli->p_ctx->cmd_buff_pos == 0) + { + break; + } + + cli_putc(p_cli, VT100_ASCII_BSPACE); + cli_putc(p_cli, ' '); + cli_putc(p_cli, VT100_ASCII_BSPACE); + --p_cli->p_ctx->cmd_buff_pos; + + break; + default: + + if (!isprint((int)data)) + { + break; + } + + p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos] = data; + ++p_cli->p_ctx->cmd_buff_pos; + + if (p_cli->p_ctx->cmd_buff_pos == NRF_CLI_CMD_BUFF_SIZE) + { + p_cli->p_ctx->cmd_buff_pos = 0; + nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, + "\r\n input buffer overflow NRF_CLI_CMD_BUFF_SIZE"); + cli_state_change(p_cli, NRF_CLI_STATE_COLLECT); + return; + } + + cli_putc(p_cli, data); + break; + } + } +} + +#if NRF_CLI_HISTORY_COUNT != 0 +static void cli_history_save(nrf_cli_t const * p_cli) +{ + p_cli->p_ctx->cmd_history_mode = false; + (void)strncpy(p_cli->p_ctx->cmd_history_buff[p_cli->p_ctx->cmd_history_pos], + p_cli->p_ctx->cmd_buff, + p_cli->p_ctx->cmd_buff_pos); + + size_t pos = p_cli->p_ctx->cmd_buff_pos; + p_cli->p_ctx->cmd_history_buff[p_cli->p_ctx->cmd_history_pos][pos] = '\0'; + + p_cli->p_ctx->cmd_history_pos = + cli_history_increment_mod(p_cli->p_ctx->cmd_history_pos); + p_cli->p_ctx->cmd_history_act = p_cli->p_ctx->cmd_history_pos; +} +#else +static void cli_history_save(nrf_cli_t const * p_cli) {} +#endif + +static void cli_state_execute(nrf_cli_t const * p_cli) +{ + /*Create argument list.*/ + char * p_start = p_cli->p_ctx->cmd_buff; + const char * p_end = &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]; + + cli_history_save(p_cli); + + memset(p_cli->p_ctx->argv, 0, sizeof(p_cli->p_ctx->argv)); + + p_cli->p_ctx->argc = 1; + p_cli->p_ctx->argv[0] = p_start; + + + bool was_blank = false; + while (p_start < p_end) + { + if (*p_start == ' ' || *p_start == '\t') + { + *p_start = '\0'; + was_blank = true; + ++p_start; + continue; + } + + if (was_blank && *p_start != '\0') + { + if (p_cli->p_ctx->argc >= NRF_CLI_ARGC_MAX) + { + nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, + "\r\n too many parameters >= NRF_CLI_ARGC_MAX\r\n"); + cli_state_change(p_cli, NRF_CLI_STATE_COLLECT); + return; + } + + was_blank = false; + p_cli->p_ctx->argv[p_cli->p_ctx->argc] = p_start; + ++p_cli->p_ctx->argc; + } + + ++p_start; + } + + /*Try match command syntax.*/ + for (size_t i = 0; i < p_cli->cmd_count; ++i) { + + if (strcmp(p_cli->p_ctx->argv[0], p_cli->p_cmd_set[i].p_syntax) != 0) + { + continue; + } + + ASSERT(p_cli->p_cmd_set[i].handler); + p_cli->p_ctx->p_current_cmd = &p_cli->p_cmd_set[i]; + + nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\r\n"); + p_cli->p_ctx->p_current_cmd->handler(p_cli, + p_cli->p_ctx->argc, + p_cli->p_ctx->argv); + cli_state_change(p_cli, NRF_CLI_STATE_COLLECT); + return; + + } + + nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s", "\r\ncommand not found\r\n"); + cli_state_change(p_cli, NRF_CLI_STATE_COLLECT); +} + +void nrf_cli_process(nrf_cli_t const * p_cli) +{ + ASSERT(p_cli); + + switch (p_cli->p_ctx->state) + { + case NRF_CLI_STATE_UNINITIALIZED: + case NRF_CLI_STATE_INITIALIZED: + break; + case NRF_CLI_STATE_COLLECT: + cli_state_collect(p_cli); + break; + case NRF_CLI_STATE_EXECUTE: + cli_state_execute(p_cli); + break; + default: + break; + } + +} + + +void nrf_cli_fprintf(nrf_cli_t const * p_cli, + vt100_color_t color, + const char * p_fmt, + ...) +{ + vt100_colors_t col; + vt100_colors_store(p_cli, &col); + + va_list args = {0}; + va_start(args, p_fmt); + + int32_t ret = vsnprintf(p_cli->p_ctx->printf_buff, + NRF_CLI_PRINTF_BUFF_SIZE, + p_fmt, + args); + va_end(args); + UNUSED_VARIABLE(ret); + vt100_color_set(p_cli, color); + cli_write(p_cli, + p_cli->p_ctx->printf_buff, + strlen(p_cli->p_ctx->printf_buff), + NULL); + vt100_colors_restore(p_cli, &col); +} + +void nrf_cli_getopt_ctx_init(size_t argc, + char ** pp_argv, + size_t opt_count, + nrf_cli_getopt_option_t const * p_opt, + nrf_cli_getopt_ctx_t * p_optctx) +{ + ASSERT(p_optctx); + ASSERT(p_opt); + + p_optctx->argc = argc; + p_optctx->pp_argv = pp_argv; + p_optctx->opt_count = opt_count; + p_optctx->p_opt = p_opt; + p_optctx->arg_idx = 0; + p_optctx->p_optarg = NULL; +} + +int32_t nrf_cli_getopt(nrf_cli_getopt_ctx_t * p_optctx) +{ + ASSERT(p_optctx); + + if (p_optctx->arg_idx == p_optctx->argc) + { + /*No more arguments to parse.*/ + return -1; + } + + /*Reset option argument*/ + p_optctx->p_optarg = NULL; + + /*Set current token.*/ + const char * p_current = p_optctx->pp_argv[p_optctx->arg_idx]; + ++p_optctx->arg_idx; + + ASSERT(p_current); + + /*Current if argument is an option. It must start with -. */ + if (p_current[0] != '-') + { + /* Argument is not an option. Set optarg and return '?' as a no option + * indicator. */ + p_optctx->p_optarg = p_current; + return '?'; + } + + nrf_cli_getopt_option_t const * p_found_opt = NULL; + + /*Short option option syntax*/ + if ((p_current[1]) != '\0' && (p_current[2] == '\0')) + { + + for (size_t i = 0; i < p_optctx->opt_count; i++) + { + if (p_current[1] != p_optctx->p_opt[i].optname_short) + { + continue; + } + + p_found_opt = &p_optctx->p_opt[i]; + break; + } + } + else if (p_current[1] == '-' && p_current[2] != '\0') + { + /*Long option option syntax*/ + const char * p_syntax_start = &p_current[2]; + + for (size_t i = 0; i < p_optctx->opt_count; i++) + { + if (strcmp(p_syntax_start, p_optctx->p_opt[i].p_optname) != 0) + { + continue; + } + + p_found_opt = &p_optctx->p_opt[i]; + break; + } + } + else + { + /*Option syntax error.*/ + p_optctx->p_optarg = p_current; + return '?'; + } + + if (p_found_opt == NULL) + { + p_optctx->p_optarg = p_current; + return '?'; + } + + if (p_found_opt->type == NRF_CLI_GETOPT_TYPE_NO_ARG) + { + return p_found_opt->optname_short; + } + + char const * p_arg = p_optctx->pp_argv[p_optctx->arg_idx]; + if (p_optctx->arg_idx == p_optctx->argc || p_arg[0] == '-') + { + if (p_found_opt->type == NRF_CLI_GETOPT_TYPE_REQUIRED) + { + /*Argument is required but it seems that it is an option.*/ + p_optctx->p_optarg = p_current; + return '?'; + } + } + + ++p_optctx->arg_idx; + + p_optctx->p_optarg = p_arg; + return p_found_opt->optname_short; +} + +void nrf_cli_opt_help_show(nrf_cli_t const * p_cli, + nrf_cli_getopt_option_t const * p_opt, + size_t opt_len) +{ + /*Show current command help string*/ + nrf_cli_fprintf(p_cli, + NRF_CLI_NORMAL, + "%s - %s\r\n", + p_cli->p_ctx->p_current_cmd->p_syntax, + p_cli->p_ctx->p_current_cmd->p_help); + + nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Options:\r\n"); + + for (size_t i = 0; i < opt_len; ++i) + { + + nrf_cli_fprintf(p_cli, + NRF_CLI_NORMAL, + " -%c, --%s\t%s\r\n", + p_opt[i].optname_short, + p_opt[i].p_optname, + p_opt[i].p_optname_help); + } +} + +void nrf_cli_cmd_list(nrf_cli_t const * p_cli, size_t argc, char **argv) +{ + /*Show help of command.*/ + bool verbose = false; + + static const nrf_cli_getopt_option_t opt[] = { + + NRF_CLI_OPT( + "help", + 'h', + NRF_CLI_GETOPT_TYPE_NO_ARG, + "show command help" + ), + NRF_CLI_OPT( + "verbose", + 'v', + NRF_CLI_GETOPT_TYPE_NO_ARG, + "show all command help strings" + ) + }; + + nrf_cli_getopt_ctx_t opt_ctx; + nrf_cli_getopt_ctx_init(argc - 1, argv + 1, ARRAY_SIZE(opt), opt, &opt_ctx); + + do + { + int32_t c = nrf_cli_getopt(&opt_ctx); + if (c < 0) + { + break; + } + + switch (c) + { + case 'v': + verbose = true; + break; + case 'h': + nrf_cli_opt_help_show(p_cli, opt, ARRAY_SIZE(opt)); + return; + case '?': + nrf_cli_fprintf(p_cli, NRF_CLI_WARNING, + "list: unknown option: %s\r\n", + nrf_cli_optarg_get(&opt_ctx)); + break; + default: + break; + } + } while (1); + + + /*Find command in command list*/ + for (size_t i = 0; i < p_cli->cmd_count; ++i) + { + if (verbose) + { + nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, " %s - %s\r\n", + p_cli->p_cmd_set[i].p_syntax, + p_cli->p_cmd_set[i].p_help); + } + else + { + nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, " %s\r\n", + p_cli->p_cmd_set[i].p_syntax); + } + } +} + +void nrf_cli_cmd_clear(nrf_cli_t const * p_cli, size_t argc, char **argv) +{ + (void)argc; + (void)argv; + vt100_cursor_set(p_cli, 0, 0); + vt100_screen_clear(p_cli); +} + +void nrf_cli_cmd_history(nrf_cli_t const * p_cli, size_t argc, char **argv) +{ + (void)argc; + (void)argv; +#if NRF_CLI_HISTORY_COUNT + size_t pos = p_cli->p_ctx->cmd_history_pos; + size_t i, j = 0; + + for (i = 0; i < NRF_CLI_HISTORY_COUNT; ++i) + { + const char * p_entry = p_cli->p_ctx->cmd_history_buff[pos]; + pos = cli_history_increment_mod(pos); + size_t len = strlen(p_entry); + if (!len) + { + continue; + } + + nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "[%3d] %s\r\n", j++, p_entry); + } +#else + nrf_cli_fprintf(p_cli, NRF_CLI_WARNING, " history: not available\r\n"); +#endif +} + +#endif // NRF_MODULE_ENABLED(NRF_CLI) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/nrf_cli.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/nrf_cli.h new file mode 100644 index 0000000000000000000000000000000000000000..9153a693e6c8ea62d80ef0da2229d951b0bb77f3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/nrf_cli.h @@ -0,0 +1,416 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CLI_H__ +#define NRF_CLI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sdk_common.h" +#include "nrf_cli_vt100.h" + +/** + * @defgroup nrf_cli Command Line Interface + * @ingroup app_common + * + * @brief Module for unified command line handling. + * + * @{ + */ + +/** + * @brief Alias to @ref nrf_cli. Must be created here to satisfy + * module declaration order dependencies. + * */ +typedef struct nrf_cli nrf_cli_t; + +/** + * @brief CLI command descriptor. + **/ +typedef struct { + const char * p_syntax; //!< Command syntax strings. + const char * p_help; //!< Command help string. + + void (*handler)(nrf_cli_t const * p_cli, size_t argc, char **argv); //!< Command handler. +} nrf_cli_cmd_t; + + +/** + * @brief Initializes CLI command descriptor (@ref nrf_cli_cmd_t). + * + * @param _syntax Command syntax (for example: "history"). + * @param _help Command help string (string used in built-in help command). + * @param _handler Handler function. + * */ +#define NRF_CLI_CMD(_syntax, _help, _handler) { \ + .p_syntax = _syntax, \ + .p_help = _help, \ + .handler = _handler, \ +} + +/** + * @brief Internal CLI state. + * */ +typedef enum { + NRF_CLI_STATE_UNINITIALIZED, //!< State uninitialized. + NRF_CLI_STATE_INITIALIZED, //!< State initialized. + NRF_CLI_STATE_COLLECT, //!< State collect. + NRF_CLI_STATE_EXECUTE, //!< State execute. +} nrf_cli_state_t; + +/** + * @brief Unified CLI transport interface. + * */ +typedef struct { + /** + * @brief Initializes CLI transport interface. + * + * @return Standard error code. + * */ + ret_code_t (*init)(void); + + /** + * @brief Uninitialize CLI transport interface. + * + * @return Standard error code. + * */ + ret_code_t (*uninit)(void); + + /** + * @brief Writes data to transport interface. + * + * @param p_data Source buffer. + * @param length Source buffer length. + * @param p_cnt Number of bytes written (NULL might be passed). + * + * @return Standard error code. + * */ + ret_code_t (*write)(const void * p_data, size_t length, size_t * p_cnt); + + /** + * @brief Reads data from transport interface. + * + * @param p_data Destination buffer. + * @param length Destination buffer length. + * @param p_cnt Number of bytes received (NULL might be passed). + * + * @return Standard error code. + * */ + ret_code_t (*read)(void * p_data, size_t length, size_t * p_cnt); + +} nrf_cli_transport_t; + +/** + * @brief CLI instance context. + * */ +typedef struct { + nrf_cli_state_t state; //!< Internal module state. + nrf_cli_cmd_t const * p_current_cmd; //!< Current executed command. + + vt100_ctx_t vt100_ctx; //!< VT100 color and cursor position. + + bool escape; //!< Escape sequence indicator. + bool arrow; //!< Arrow escape sequence indicator. + size_t argc; //!< Number of arguments. + char * argv[NRF_CLI_ARGC_MAX]; //!< Argument list. + + size_t cmd_buff_pos; //!< Command buffer position. + char cmd_buff[NRF_CLI_CMD_BUFF_SIZE]; //!< Command input buffer. + + char printf_buff[NRF_CLI_PRINTF_BUFF_SIZE]; //!< Printf buffer size. + +#if NRF_CLI_HISTORY_COUNT != 0 + bool cmd_history_mode; + size_t cmd_history_pos; //!< Command history position. + size_t cmd_history_act; //!< Command history last entry. + char cmd_history_buff[NRF_CLI_HISTORY_COUNT][NRF_CLI_CMD_BUFF_SIZE]; //!< Command history buffer. +#endif +} nrf_cli_ctx_t; + +/** + * @brief CLI instance internals. + * + * @ref nrf_cli_t + * */ +struct nrf_cli { + const char * p_name; //!< Terminal name. + + nrf_cli_transport_t const * p_iface; //!< Transport interface. + nrf_cli_cmd_t const * p_cmd_set; //!< Command set array. + size_t cmd_count; //!< Command set array size. + nrf_cli_ctx_t * p_ctx; //!< Internal context. +}; + + +/** + * @brief Macro for defining command line interface instance. + * + * @param name Instance name. + * @param cli_prefix CLI prefix string. + * @param transport_iface Transport interface. + * @param cmd_set_tab Command set array. + * */ +#define NRF_CLI_DEF(name, cli_prefix, transport_iface, cmd_set_tab) \ + static nrf_cli_ctx_t CONCAT_2(name, _ctx); \ + static const nrf_cli_t name = { \ + .p_name = cli_prefix, \ + .p_iface = &transport_iface, \ + .p_cmd_set = cmd_set_tab, \ + .cmd_count = ARRAY_SIZE(cmd_set_tab), \ + .p_ctx = &CONCAT_2(name, _ctx), \ + } + +/** + * @brief Initializes a transport layer and internal CLI state. + * + * @param p_cli CLI instance. + * + * @return Standard error code. + * */ +ret_code_t nrf_cli_init(nrf_cli_t const * p_cli); + +/** + * @brief Uninitializes a transport layer and internal CLI state. + * + * @param p_cli CLI instance. + * + * @return Standard error code. + * */ +ret_code_t nrf_cli_uninit(nrf_cli_t const * p_cli); + +/** + * @brief Start CLI processing. + * + * @param p_cli CLI instance. + * + * @return Standard error code. + * */ +ret_code_t nrf_cli_start(nrf_cli_t const * p_cli); + +/** + * @brief Stop CLI processing. + * + * @param p_cli CLI instance. + * + * @return Standard error code. + * */ +ret_code_t nrf_cli_stop(nrf_cli_t const * p_cli); + +#define NRF_CLI_NORMAL VT100_COLOR_WHITE /**< Normal color printf. */ +#define NRF_CLI_INFO VT100_COLOR_GREEN /**< Info color printf. */ +#define NRF_CLI_WARNING VT100_COLOR_YELLOW /**< Warning color printf. */ +#define NRF_CLI_ERROR VT100_COLOR_RED /**< Error color printf. */ + +/** + * @brief Printf like function, which send formated data stream to CLI. + * + * @param p_cli CLI instance. + * @param color Printf color. + * @param p_fmt Format string. + * @param ... List of parameters to print. + * */ +void nrf_cli_fprintf(nrf_cli_t const * p_cli, + vt100_color_t color, + const char * p_fmt, + ...); + +/** + * @brief Process function, which should be executed when data is ready + * in transport interface. + * + * @param p_cli CLI instance. + * */ +void nrf_cli_process(nrf_cli_t const * p_cli); + +/** + * @brief Option argument type. + * */ +typedef enum { + NRF_CLI_GETOPT_TYPE_NO_ARG, /**< No argument required.*/ + NRF_CLI_GETOPT_TYPE_REQUIRED, /**< Argument required.*/ + NRF_CLI_GETOPT_TYPE_OPTIONAL, /**< Argument optional.*/ +} nrf_cli_getopt_type_t; + + +/** + * @brief Option descriptor. + * */ +typedef struct { + const char * p_optname; //!< Option long name. + const char optname_short; //!< Option short name. + nrf_cli_getopt_type_t type; //!< Option type. + const char * p_optname_help; //!< Option help string. +} nrf_cli_getopt_option_t; + + +/** + * @brief Option structure initializer @ref nrf_cli_getopt_option_t. + * + * @param _optname Option name long. + * @param _shortname Option name short. + * @param _type Option type @ref nrf_cli_getopt_type_t. + * @param _help Option help string. + * */ +#define NRF_CLI_OPT(_optname, _shortname, _type, _help) { \ + .p_optname = _optname, \ + .optname_short = _shortname, \ + .type = _type, \ + .p_optname_help = _help, \ +} + +/** + * @brief Getopt parser context. + * */ +typedef struct { + size_t argc; //!< Number of arguments. + char ** pp_argv; //!< Argument list. + size_t arg_idx; //!< Current argument index. + const char * p_optarg; //!< Current option argument. + + nrf_cli_getopt_option_t const * p_opt; //!< Option list. + size_t opt_count; //!< Option list size. +} nrf_cli_getopt_ctx_t; + + +/** + * @brief Initializes getopt parser context. + * + * @param argc Number of arguments. + * @param pp_argv Argument list. + * @param opt_count Number of options. + * @param p_opt Option array. + * @param p_optctx Option parser context. + * */ +void nrf_cli_getopt_ctx_init(size_t argc, + char ** pp_argv, + size_t opt_count, + nrf_cli_getopt_option_t const * p_opt, + nrf_cli_getopt_ctx_t * p_optctx); + +/** + * @brief Standard library getopt/getopt_long method replacement. + * + * @param p_optctx Option parser context. + * + * @return Parsed option (one letter options are supported by this parser). + * @retval '?' unknown option / no required argument. + * @retval -1 if all options have been processed. + * @retval other if option was successfully parsed. + * */ +int32_t nrf_cli_getopt(nrf_cli_getopt_ctx_t * p_optctx); + +/** + * @brief Returns handle to current parsed argument + * (optarg variable replacement). + * + * @warning This call is only valid while @ref nrf_cli_getopt + * is returning >= 0. + * @param p_optctx Option parser context. + * + * @return Handle to option argument. + * */ +__STATIC_INLINE const char * nrf_cli_optarg_get(nrf_cli_getopt_ctx_t * p_optctx) +{ + return p_optctx->p_optarg; +} + +/** + * @brief Shows command help and options. May be used as default '-h' option + * handler. It will print actual command help and option description: + * + * Example output: + * @code + nrf_cli:~$ list -h + list - list all commands + Options: + -h, --help show command help + -v, --verbose show all command help strings + * @endcode + * + * @param p_cli CLI instance. + * @param p_opt Option array. + * @param opt_len Option array size. + * */ +void nrf_cli_opt_help_show(nrf_cli_t const * p_cli, + nrf_cli_getopt_option_t const * p_opt, + size_t opt_len); + +/** + * @brief List command handler. + * + * @param p_cli CLI instance. + * @param argc Number of argv parameters. + * @param argv Parameter list. + * */ +void nrf_cli_cmd_list(nrf_cli_t const * p_cli, size_t argc, char **argv); + +/** + * @brief Clear screen command handler. + * + * @param p_cli CLI instance. + * @param argc Number of argv parameters. + * @param argv Parameter list. + **/ +void nrf_cli_cmd_clear(nrf_cli_t const * p_cli, size_t argc, char **argv); + +/** + * @brief Show history command handler. + * + * @param p_cli CLI instance. + * @param argc Number of argv parameters. + * @param argv Parameter list. + **/ +void nrf_cli_cmd_history(nrf_cli_t const * p_cli, size_t argc, char **argv); +/** + * @brief Built-in command set. + * */ +#define NRF_CLI_BUILTIN_CMD_SET \ + NRF_CLI_CMD("list", "list all commands", nrf_cli_cmd_list), \ + NRF_CLI_CMD("clear", "clear screen", nrf_cli_cmd_clear), \ + NRF_CLI_CMD("history", "command history", nrf_cli_cmd_history) \ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_CLI_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/nrf_cli_vt100.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/nrf_cli_vt100.h new file mode 100644 index 0000000000000000000000000000000000000000..0883df8ebc6801db0fa3ee5eaad0c0a77092088f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/nrf_cli_vt100.h @@ -0,0 +1,653 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CLI_VT100_H__ +#define NRF_CLI_VT100_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#define VT100_ASCII_ESC 0x1b +#define VT100_ASCII_DEL 0x7F +#define VT100_ASCII_BSPACE 0x08 + +#define VT100_SETNL \ + { \ + VT100_ASCII_ESC, '[', '2', '0', 'h' \ + } /* Set new line mode */ +#define VT100_SETAPPL \ + { \ + VT100_ASCII_ESC, '[', '?', '1', 'h' \ + } /* Set cursor key to application */ +#define VT100_SETCOL \ + { \ + VT100_ASCII_ESC, '[', '?', '3', 'h' \ + } /* Set number of columns to 132 */ +#define VT100_SETSMOOTH \ + { \ + VT100_ASCII_ESC, '[', '?', '4', 'h' \ + } /* Set smooth scrolling */ +#define VT100_SETREVSCRN \ + { \ + VT100_ASCII_ESC, '[', '?', '5', 'h' \ + } /* Set reverse video on screen */ +#define VT100_SETORGREL \ + { \ + VT100_ASCII_ESC, '[', '?', '6', 'h' \ + } /* Set origin to relative */ +#define VT100_SETWRAP \ + { \ + VT100_ASCII_ESC, '[', '?', '7', 'h' \ + } /* Set auto-wrap mode */ +#define VT100_SETREP \ + { \ + VT100_ASCII_ESC, '[', '?', '8', 'h' \ + } /* Set auto-repeat mode */ +#define VT100_SETINTER \ + { \ + VT100_ASCII_ESC, '[', '?', '9', 'h' \ + } /* Set interlacing mode */ + +#define VT100_SETLF \ + { \ + VT100_ASCII_ESC, '[', '2', '0', 'l' \ + } /* Set line feed mode */ +#define VT100_SETCURSOR \ + { \ + VT100_ASCII_ESC, '[', '?', '1', 'l' \ + } /* Set cursor key to cursor */ +#define VT100_SETVT52 \ + { \ + VT100_ASCII_ESC, '[', '?', '2', 'l' \ + } /* Set VT52 (versus ANSI) */ +#define VT100_RESETCOL \ + { \ + VT100_ASCII_ESC, '[', '?', '3', 'l' \ + } /* Set number of columns to 80 */ +#define VT100_SETJUMP \ + { \ + VT100_ASCII_ESC, '[', '?', '4', 'l' \ + } /* Set jump scrolling */ +#define VT100_SETNORMSCRN \ + { \ + VT100_ASCII_ESC, '[', '?', '5', 'l' \ + } /* Set normal video on screen */ +#define VT100_SETORGABS \ + { \ + VT100_ASCII_ESC, '[', '?', '6', 'l' \ + } /* Set origin to absolute */ +#define VT100_RESETWRAP \ + { \ + VT100_ASCII_ESC, '[', '?', '7', 'l' \ + } /* Reset auto-wrap mode */ +#define VT100_RESETREP \ + { \ + VT100_ASCII_ESC, '[', '?', '8', 'l' \ + } /* Reset auto-repeat mode */ +#define VT100_RESETINTER \ + { \ + VT100_ASCII_ESC, '[', '?', '9', 'l' \ + } /* Reset interlacing mode */ + +#define VT100_ALTKEYPAD \ + { \ + VT100_ASCII_ESC, '=' \ + } /* Set alternate keypad mode */ +#define VT100_NUMKEYPAD \ + { \ + VT100_ASCII_ESC, '>' \ + } /* Set numeric keypad mode */ + +#define VT100_SETUKG0 \ + { \ + VT100_ASCII_ESC, '(', 'A' \ + } /* Set United Kingdom G0 character set */ +#define VT100_SETUKG1 \ + { \ + VT100_ASCII_ESC, ')', 'A' \ + } /* Set United Kingdom G1 character set */ +#define VT100_SETUSG0 \ + { \ + VT100_ASCII_ESC, '(', 'B' \ + } /* Set United States G0 character set */ +#define VT100_SETUSG1 \ + { \ + VT100_ASCII_ESC, ')', 'B' \ + } /* Set United States G1 character set */ +#define VT100_SETSPECG0 \ + { \ + VT100_ASCII_ESC, '(', '0' \ + } /* Set G0 special chars. & line set */ +#define VT100_SETSPECG1 \ + { \ + VT100_ASCII_ESC, ')', '0' \ + } /* Set G1 special chars. & line set */ +#define VT100_SETALTG0 \ + { \ + VT100_ASCII_ESC, '(', '1' \ + } /* Set G0 alternate character ROM */ +#define VT100_SETALTG1 \ + { \ + VT100_ASCII_ESC, ')', '1' \ + } /* Set G1 alternate character ROM */ +#define VT100_SETALTSPECG0 \ + { \ + VT100_ASCII_ESC, '(', '2' \ + } /* Set G0 alt char ROM and spec. graphics */ +#define VT100_SETALTSPECG1 \ + { \ + VT100_ASCII_ESC, ')', '2' \ + } /* Set G1 alt char ROM and spec. graphics */ + +#define VT100_SETSS2 \ + { \ + VT100_ASCII_ESC, 'N' \ + } /* Set single shift 2 */ +#define VT100_SETSS3 \ + { \ + VT100_ASCII_ESC, 'O' \ + } /* Set single shift 3 */ + +#define VT100_MODESOFF \ + { \ + VT100_ASCII_ESC, '[', 'm' \ + } /* Turn off character attributes */ +#define VT100_MODESOFF_ \ + { \ + VT100_ASCII_ESC, '[', '0', 'm' \ + } /* Turn off character attributes */ +#define VT100_BOLD \ + { \ + VT100_ASCII_ESC, '[', '1', 'm' \ + } /* Turn bold mode on */ +#define VT100_LOWINT \ + { \ + VT100_ASCII_ESC, '[', '2', 'm' \ + } /* Turn low intensity mode on */ +#define VT100_UNDERLINE \ + { \ + VT100_ASCII_ESC, '[', '4', 'm' \ + } /* Turn underline mode on */ +#define VT100_BLINK \ + { \ + VT100_ASCII_ESC, '[', '5', 'm' \ + } /* Turn blinking mode on */ +#define VT100_REVERSE \ + { \ + VT100_ASCII_ESC, '[', '7', 'm' \ + } /* Turn reverse video on */ +#define VT100_INVISIBLE \ + { \ + VT100_ASCII_ESC, '[', '8', 'm' \ + } /* Turn invisible text mode on */ + +#define VT100_SETWIN(t, b) \ + { \ + VT100_ASCII_ESC, '[', (t), ';', (b), 'r' \ + } /* Set top and bottom line#s of a window */ + +#define VT100_CURSORUP(n) \ + { \ + VT100_ASCII_ESC, '[', (n), 'A' \ + } /* Move cursor up n lines */ +#define VT100_CURSORDN(n) \ + { \ + VT100_ASCII_ESC, '[', (n), 'B' \ + } /* Move cursor down n lines */ +#define VT100_CURSORRT(n) \ + { \ + VT100_ASCII_ESC, '[', (n), 'C' \ + } /* Move cursor right n lines */ +#define VT100_CURSORLF(n) \ + { \ + VT100_ASCII_ESC, '[', (n), 'D' \ + } /* Move cursor left n lines */ +#define VT100_CURSORHOME \ + { \ + VT100_ASCII_ESC, '[', 'H' \ + } /* Move cursor to upper left corner */ +#define VT100_CURSORHOME_ \ + { \ + VT100_ASCII_ESC, '[', ';', 'H' \ + } /* Move cursor to upper left corner */ +#define VT100_CURSORPOS(v, h) \ + { \ + VT100_ASCII_ESC, '[', (v), ';', (h), 'H' \ + } /* Move cursor to screen location v,h */ + +#define VT100_HVHOME \ + { \ + VT100_ASCII_ESC, '[', 'f' \ + } /* Move cursor to upper left corner */ +#define VT100_HVHOME_ \ + { \ + VT100_ASCII_ESC, '[', ';', 'f' \ + } /* Move cursor to upper left corner */ +#define VT100_HVPOS(v, h) \ + { \ + VT100_ASCII_ESC, '[', (v), ';', (h), 'f' \ + } /* Move cursor to screen location v,h */ +#define VT100_INDEX \ + { \ + VT100_ASCII_ESC, 'D' \ + } /* Move/scroll window up one line */ +#define VT100_REVINDEX \ + { \ + VT100_ASCII_ESC, 'M' \ + } /* Move/scroll window down one line */ +#define VT100_NEXTLINE \ + { \ + VT100_ASCII_ESC, 'E' \ + } /* Move to next line */ +#define VT100_SAVECURSOR \ + { \ + VT100_ASCII_ESC, '7' \ + } /* Save cursor position and attributes */ +#define VT100_RESTORECURSOR \ + { \ + VT100_ASCII_ESC, '8' \ + } /* Restore cursor position and attribute */ + +#define VT100_TABSET \ + { \ + VT100_ASCII_ESC, 'H' \ + } /* Set a tab at the current column */ +#define VT100_TABCLR \ + { \ + VT100_ASCII_ESC, '[', 'g' \ + } /* Clear a tab at the current column */ +#define VT100_TABCLR_ \ + { \ + VT100_ASCII_ESC, '[', '0', 'g' \ + } /* Clear a tab at the current column */ +#define VT100_TABCLRALL \ + { \ + VT100_ASCII_ESC, '[', '3', 'g' \ + } /* Clear all tabs */ + +#define VT100_DHTOP \ + { \ + VT100_ASCII_ESC, '#', '3' \ + } /* Double-height letters, top half */ +#define VT100_DHBOT \ + { \ + VT100_ASCII_ESC, '#', '4' \ + } /* Double-height letters, bottom hal */ +#define VT100_SWSH \ + { \ + VT100_ASCII_ESC, '#', '5' \ + } /* Single width, single height letters */ +#define VT100_DWSH \ + { \ + VT100_ASCII_ESC, '#', '6' \ + } /* Double width, single height letters */ + +#define VT100_CLEAREOL \ + { \ + VT100_ASCII_ESC, '[', 'K' \ + } /* Clear line from cursor right */ +#define VT100_CLEAREOL_ \ + { \ + VT100_ASCII_ESC, '[', '0', 'K' \ + } /* Clear line from cursor right */ +#define VT100_CLEARBOL \ + { \ + VT100_ASCII_ESC, '[', '1', 'K' \ + } /* Clear line from cursor left */ +#define VT100_CLEARLINE \ + { \ + VT100_ASCII_ESC, '[', '2', 'K' \ + } /* Clear entire line */ + +#define VT100_CLEAREOS \ + { \ + VT100_ASCII_ESC, '[', 'J' \ + } /* Clear screen from cursor down */ +#define VT100_CLEAREOS_ \ + { \ + VT100_ASCII_ESC, '[', '0', 'J' \ + } /* Clear screen from cursor down */ +#define VT100_CLEARBOS \ + { \ + VT100_ASCII_ESC, '[', '1', 'J' \ + } /* Clear screen from cursor up */ +#define VT100_CLEARSCREEN \ + { \ + VT100_ASCII_ESC, '[', '2', 'J' \ + } /* Clear entire screen */ + +#define VT100_DEVSTAT \ + { \ + VT100_ASCII_ESC, '5', 'n' \ + } /* Device status report */ +#define VT100_TERMOK \ + { \ + VT100_ASCII_ESC, '0', 'n' \ + } /* Response: terminal is OK */ +#define VT100_TERMNOK \ + { \ + VT100_ASCII_ESC, '3', 'n' \ + } /* Response: terminal is not OK */ + +#define VT100_GETCURSOR \ + { \ + VT100_ASCII_ESC, '[', '6', 'n' \ + } /* Get cursor position */ +#define VT100_CURSORPOSAT \ + { \ + VT100_ASCII_ESC, (v), ';', (h), 'R' \ + } /* Response: cursor is at v,h */ + +#define VT100_IDENT \ + { \ + VT100_ASCII_ESC, '[', 'c' \ + } /* Identify what terminal type */ +#define VT100_IDENT_ \ + { \ + VT100_ASCII_ESC, '[', '0', 'c' \ + } /* Identify what terminal type */ +#define VT100_GETTYPE \ + { \ + VT100_ASCII_ESC, '[', '?', '1', ';', (n), '0', 'c' \ + } /* Response: terminal type code n */ + +#define VT100_RESET \ + { \ + VT100_ASCII_ESC, 'c' \ + } /* Reset terminal to initial state */ + +#define VT100_ALIGN \ + { \ + VT100_ASCII_ESC, '#', '8' \ + } /* Screen alignment display */ +#define VT100_TESTPU \ + { \ + VT100_ASCII_ESC, '[', '2', ';', '1', 'y' \ + } /* Confidence power up test */ +#define VT100_TESTLB \ + { \ + VT100_ASCII_ESC, '[', '2', ';', '2', 'y' \ + } /* Confidence loopback test */ +#define VT100_TESTPUREP \ + { \ + VT100_ASCII_ESC, '[', '2', ';', '9', 'y' \ + } /* Repeat power up test */ +#define VT100_TESTLBREP \ + { \ + VT100_ASCII_ESC, '[', '2', ';', '1', '0', 'y' \ + } /* Repeat loopback test */ + +#define VT100_LEDSOFF \ + { \ + VT100_ASCII_ESC, '[', '0', 'q' \ + } /* Turn off all four leds */ +#define VT100_LED1 \ + { \ + VT100_ASCII_ESC, '[', '1', 'q' \ + } /* Turn on LED #1 */ +#define VT100_LED2 \ + { \ + VT100_ASCII_ESC, '[', '2', 'q' \ + } /* Turn on LED #2 */ +#define VT100_LED3 \ + { \ + VT100_ASCII_ESC, '[', '3', 'q' \ + } /* Turn on LED #3 */ +#define VT100_LED4 \ + { \ + VT100_ASCII_ESC, '[', '4', 'q' \ + } /* Turn on LED #4 */ + +/* Function Keys */ + +#define VT100_PF1 \ + { \ + VT100_ASCII_ESC, 'O', 'P' \ + } +#define VT100_PF2 \ + { \ + VT100_ASCII_ESC, 'O', 'Q' \ + } +#define VT100_PF3 \ + { \ + VT100_ASCII_ESC, 'O', 'R' \ + } +#define VT100_PF4 \ + { \ + VT100_ASCII_ESC, 'O', 'S' \ + } + +/* Arrow keys */ + +#define VT100_UP_RESET \ + { \ + VT100_ASCII_ESC, 'A' \ + } +#define VT100_UP_SET \ + { \ + VT100_ASCII_ESC, 'O', 'A' \ + } +#define VT100_DOWN_RESET \ + { \ + VT100_ASCII_ESC, 'B' \ + } +#define VT100_DOWN_SET \ + { \ + VT100_ASCII_ESC, 'O', 'B' \ + } +#define VT100_RIGHT_RESET \ + { \ + VT100_ASCII_ESC, 'C' \ + } +#define VT100_RIGHT_SET \ + { \ + VT100_ASCII_ESC, 'O', 'C' \ + } +#define VT100_LEFT_RESET \ + { \ + VT100_ASCII_ESC, 'D' \ + } +#define VT100_LEFT_SET \ + { \ + VT100_ASCII_ESC, 'O', 'D' \ + } + +/* Numeric Keypad Keys */ + +#define VT100_NUMERIC_0 \ + { \ + '0' \ + } +#define VT100_ALT_0 \ + { \ + VT100_ASCII_ESC, 'O', 'p' \ + } +#define VT100_NUMERIC_1 \ + { \ + '1' \ + } +#define VT100_ALT_1 \ + { \ + VT100_ASCII_ESC, 'O', 'q' \ + } +#define VT100_NUMERIC_2 \ + { \ + '2' \ + } +#define VT100_ALT_2 \ + { \ + VT100_ASCII_ESC, 'O', 'r' \ + } +#define VT100_NUMERIC_3 \ + { \ + '3' \ + } +#define VT100_ALT_3 \ + { \ + VT100_ASCII_ESC, 'O', 's' \ + } +#define VT100_NUMERIC_4 \ + { \ + '4' \ + } +#define VT100_ALT_4 \ + { \ + VT100_ASCII_ESC, 'O', 't' \ + } +#define VT100_NUMERIC_5 \ + { \ + '5' \ + } +#define VT100_ALT_5 \ + { \ + VT100_ASCII_ESC, 'O', 'u' \ + } +#define VT100_NUMERIC_6 \ + { \ + '6' \ + } +#define VT100_ALT_6 \ + { \ + VT100_ASCII_ESC, 'O', 'v' \ + } +#define VT100_NUMERIC_7 \ + { \ + '7' \ + } +#define VT100_ALT_7 \ + { \ + VT100_ASCII_ESC, 'O', 'w' \ + } +#define VT100_NUMERIC_8 \ + { \ + '8' \ + } +#define VT100_ALT_8 \ + { \ + VT100_ASCII_ESC, 'O', 'x' \ + } +#define VT100_NUMERIC_9 \ + { \ + '9', +#define VT100_ALT_9 \ + { \ + VT100_ASCII_ESC, 'O', 'y' \ + } +#define VT100_NUMERIC_MINUS \ + { \ + '-' \ + } +#define VT100_ALT_MINUS \ + { \ + VT100_ASCII_ESC, 'O', 'm' \ + } +#define VT100_NUMERIC_COMMA \ + { \ + ',' \ + } +#define VT100_ALT_COMMA \ + { \ + VT100_ASCII_ESC, 'O', 'l' \ + } +#define VT100_NUMERIC_PERIOD \ + { \ + '.' \ + } +#define VT100_ALT_PERIOD \ + { \ + VT100_ASCII_ESC, 'O', 'n' \ + } +#define VT100_NUMERIC_ENTER \ + { \ + ASCII_CR \ + } +#define VT100_ALT_ENTER \ + { \ + VT100_ASCII_ESC, 'O', 'M' \ + } + + +typedef enum { + VT100_COLOR_BLACK = 0, + VT100_COLOR_RED, + VT100_COLOR_GREEN, + VT100_COLOR_YELLOW, + VT100_COLOR_BLUE, + VT100_COLOR_MAGENTA, + VT100_COLOR_CYAN, + VT100_COLOR_WHITE, + + VT100_COLOR_END +} vt100_color_t; + +#define VT100_COLOR(__col) \ + { \ + VT100_ASCII_ESC, '[', '3', '0' + __col, 'm' \ + } +#define VT100_BGCOLOR(__col) \ + { \ + VT100_ASCII_ESC, '[', '4', '0' + __col, 'm' \ + } + +typedef struct { + uint16_t x; + uint16_t y; +} vt100_cursor_t; + +typedef struct { + vt100_color_t col; + vt100_color_t bgcol; +} vt100_colors_t; + +typedef struct { + vt100_cursor_t cur; + vt100_colors_t col; +} vt100_ctx_t; + + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_CLI_VT100_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/rtt/nrf_cli_rtt.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/rtt/nrf_cli_rtt.c new file mode 100644 index 0000000000000000000000000000000000000000..f987737ae78b9b8693b5f69df7c5f188d11405b4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/rtt/nrf_cli_rtt.c @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CLI_RTT) +#include +#include +#include "nrf_cli_rtt.h" + + + +static ret_code_t cli_rtt_init(void) +{ + SEGGER_RTT_Init(); + return NRF_SUCCESS; +} + +static ret_code_t cli_rtt_uninit(void) +{ + return NRF_SUCCESS; +} + +static ret_code_t cli_rtt_read(void * p_data, + size_t length, + size_t * p_cnt) +{ + size_t rcnt = SEGGER_RTT_Read(NRF_CLI_RTT_TERMINAL_ID, p_data, length); + if (p_cnt) + { + *p_cnt = rcnt; + } + + return NRF_SUCCESS; +} + +static ret_code_t cli_rtt_write(const void * p_data, + size_t length, + size_t * p_cnt) +{ + size_t wcnt; + size_t acc = 0; + do { + wcnt = SEGGER_RTT_Write(NRF_CLI_RTT_TERMINAL_ID, p_data, length); + + acc += wcnt; + length -= wcnt; + } while (length); + + if (p_cnt) + { + *p_cnt = acc; + } + + return NRF_SUCCESS; +} + +const nrf_cli_transport_t nrf_cli_rtt_transport = { + .init = cli_rtt_init, + .uninit = cli_rtt_uninit, + .read = cli_rtt_read, + .write = cli_rtt_write, +}; + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/rtt/nrf_cli_rtt.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/rtt/nrf_cli_rtt.h new file mode 100644 index 0000000000000000000000000000000000000000..c2e59716eeef1fcaa6ef15bc4ed7f88cbb1ef4df --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/rtt/nrf_cli_rtt.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CLI_RTT_H__ +#define NRF_CLI_RTT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf_cli.h" + + +/**@file + * + * @defgroup nrf_cli_rtt RTT command line interface transport layer. + * @ingroup nrf_cli + * + * @{ + * + */ + +/** + * @brief Command line interface transport. + * */ +extern const nrf_cli_transport_t nrf_cli_rtt_transport; + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_CLI_RTT_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/uart/nrf_cli_uart.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/uart/nrf_cli_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..c0bc6590fe3ab4fd9c139ab8b0db320fca6e4e3f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/uart/nrf_cli_uart.c @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CLI_UART) +#include "nrf_cli_uart.h" +#include "app_uart.h" +#include "boards.h" + +static void uart_error_handle(app_uart_evt_t * p_event) +{ + if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR) + { + APP_ERROR_HANDLER(p_event->data.error_communication); + } + else if (p_event->evt_type == APP_UART_FIFO_ERROR) + { + APP_ERROR_HANDLER(p_event->data.error_code); + } +} + + +static ret_code_t cli_uart_init(void) +{ + uint32_t err_code; + + const app_uart_comm_params_t comm_params = + { + RX_PIN_NUMBER, + TX_PIN_NUMBER, + RTS_PIN_NUMBER, + CTS_PIN_NUMBER, + APP_UART_FLOW_CONTROL_ENABLED, + false, + UART_BAUDRATE_BAUDRATE_Baud115200 + }; + + APP_UART_FIFO_INIT(&comm_params, + NRF_CLI_UART_RX_BUF_SIZE, + NRF_CLI_UART_TX_BUF_SIZE, + uart_error_handle, + APP_IRQ_PRIORITY_LOWEST, + err_code); + + return err_code; +} + +static ret_code_t cli_uart_uninit(void) +{ + return NRF_SUCCESS; +} + +static ret_code_t cli_uart_read(void * p_data, + size_t length, + size_t * p_cnt) +{ + uint8_t * p_buff = p_data; + size_t acc = 0; + + while (app_uart_get(p_buff) == NRF_SUCCESS) + { + ++p_buff; + ++acc; + + if (acc == length) + { + break; + } + } + + if (p_cnt) + { + *p_cnt = acc; + } + + return NRF_SUCCESS; +} + +static ret_code_t cli_uart_write(const void * p_data, + size_t length, + size_t * p_cnt) +{ + size_t acc = 0; + + uint8_t const * p_buff = p_data; + do { + while (app_uart_put(*p_buff) != NRF_SUCCESS) + { + + } + + ++p_buff; + ++acc; + } while (acc < length); + + if (p_cnt) + { + *p_cnt = acc; + } + + return NRF_SUCCESS; +} + +const nrf_cli_transport_t nrf_cli_uart_transport = { + .init = cli_uart_init, + .uninit = cli_uart_uninit, + .read = cli_uart_read, + .write = cli_uart_write, +}; + +#endif + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/uart/nrf_cli_uart.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/uart/nrf_cli_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..6ae324ff7260aa7d62fd035a983bfba8897bc278 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/cli/uart/nrf_cli_uart.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CLI_UART_H__ +#define NRF_CLI_UART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "nrf_cli.h" + + +/**@file + * + * @defgroup nrf_cli_uart UART command line interface transport layer. + * @ingroup nrf_cli + * + * @{ + * + */ + +/** + * @brief Command line interface transport. + * */ +extern const nrf_cli_transport_t nrf_cli_uart_transport; + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_CLI_UART_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crc16/crc16.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crc16/crc16.c new file mode 100644 index 0000000000000000000000000000000000000000..59fcc2efdc1919ec5c083ea69ae4cc41fa4b702c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crc16/crc16.c @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(CRC16) +#include "crc16.h" + +#include + +uint16_t crc16_compute(uint8_t const * p_data, uint32_t size, uint16_t const * p_crc) +{ + uint16_t crc = (p_crc == NULL) ? 0xFFFF : *p_crc; + + for (uint32_t i = 0; i < size; i++) + { + crc = (uint8_t)(crc >> 8) | (crc << 8); + crc ^= p_data[i]; + crc ^= (uint8_t)(crc & 0xFF) >> 4; + crc ^= (crc << 8) << 4; + crc ^= ((crc & 0xFF) << 4) << 1; + } + + return crc; +} +#endif //NRF_MODULE_ENABLED(CRC16) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crc16/crc16.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crc16/crc16.h new file mode 100644 index 0000000000000000000000000000000000000000..f80e8a139b59fe90fcb9ef3a5d2779b967729709 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crc16/crc16.h @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup crc16 CRC16 compute + * @{ + * @ingroup hci_transport + * + * @brief This module implements CRC-16-CCITT (polynomial 0x1021) with 0xFFFF initial value. + * The data can be passed in multiple blocks. + */ + +#ifndef CRC16_H__ +#define CRC16_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Function for calculating CRC-16 in blocks. + * + * Feed each consecutive data block into this function, along with the current value of p_crc as + * returned by the previous call of this function. The first call of this function should pass NULL + * as the initial value of the crc in p_crc. + * + * @param[in] p_data The input data block for computation. + * @param[in] size The size of the input data block in bytes. + * @param[in] p_crc The previous calculated CRC-16 value or NULL if first call. + * + * @return The updated CRC-16 value, based on the input supplied. + */ +uint16_t crc16_compute(uint8_t const * p_data, uint32_t size, uint16_t const * p_crc); + + +#ifdef __cplusplus +} +#endif + +#endif // CRC16_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crc32/crc32.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crc32/crc32.c new file mode 100644 index 0000000000000000000000000000000000000000..5bc7a71dcb3bfede17f24cef6b76da0edffd665e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crc32/crc32.c @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(CRC32) +#include "crc32.h" + +#include + +uint32_t crc32_compute(uint8_t const * p_data, uint32_t size, uint32_t const * p_crc) +{ + uint32_t crc; + + crc = (p_crc == NULL) ? 0xFFFFFFFF : ~(*p_crc); + for (uint32_t i = 0; i < size; i++) + { + crc = crc ^ p_data[i]; + for (uint32_t j = 8; j > 0; j--) + { + crc = (crc >> 1) ^ (0xEDB88320U & ((crc & 1) ? 0xFFFFFFFF : 0)); + } + } + return ~crc; +} +#endif //NRF_MODULE_ENABLED(CRC32) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crc32/crc32.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crc32/crc32.h new file mode 100644 index 0000000000000000000000000000000000000000..6961cb077533a929f4d8a59f60eea4b135ce4662 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crc32/crc32.h @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup crc32 CRC32 compute + * @{ + * @ingroup hci_transport + * + * @brief This module implements the CRC-32 calculation in the blocks. + */ + +#ifndef CRC32_H__ +#define CRC32_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Function for calculating CRC-32 in blocks. + * + * Feed each consecutive data block into this function, along with the current value of p_crc as + * returned by the previous call of this function. The first call of this function should pass NULL + * as the initial value of the crc in p_crc. + * + * @param[in] p_data The input data block for computation. + * @param[in] size The size of the input data block in bytes. + * @param[in] p_crc The previous calculated CRC-32 value or NULL if first call. + * + * @return The updated CRC-32 value, based on the input supplied. + */ +uint32_t crc32_compute(uint8_t const * p_data, uint32_t size, uint32_t const * p_crc); + + +#ifdef __cplusplus +} +#endif + +#endif // CRC32_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_ecdh.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_ecdh.c new file mode 100644 index 0000000000000000000000000000000000000000..485b4d2317197b92dcef2adcb6b55c7ff9788e9e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_ecdh.c @@ -0,0 +1,234 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) +#include "nrf_crypto_hash.h" +#include "nrf_crypto_ecdh.h" + +#if defined(NRF_CRYPTO_BACKEND_CC310_LIB) && (NRF_CRYPTO_BACKEND_CC310_LIB == 1) + +#include +#include "cc310_lib_init.h" +#include "cc310_lib_keys.h" +#include "cc310_lib_shared.h" +#include "nrf_log.h" +#include "nrf_crypto_types.h" +#include "crys_ecpki_dh.h" + +static void swap_array_endian(uint8_t * p_in, uint32_t len, uint8_t * p_out) +{ + for(uint32_t i = 0; i < len; i++) + { + p_out[len-i-1] = p_in[i]; + } +} + +static uint32_t ecdh_shared_secret_compute_result_get(CRYSError_t error) +{ + uint32_t ret_val; + + switch(error) + { + case CRYS_OK: + ret_val = NRF_SUCCESS; + break; + + /* From calling CRYS_ECDH_SVDP_DH */ + case CRYS_ECDH_SVDP_DH_INVALID_PARTNER_PUBL_KEY_PTR_ERROR: + ret_val = NRF_ERROR_INVALID_ADDR; + break; + + case CRYS_ECDH_SVDP_DH_PARTNER_PUBL_KEY_VALID_TAG_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_ECDH_SVDP_DH_INVALID_USER_PRIV_KEY_PTR_ERROR: + ret_val = NRF_ERROR_INVALID_ADDR; + break; + + case CRYS_ECDH_SVDP_DH_USER_PRIV_KEY_VALID_TAG_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_PTR_ERROR: + ret_val = NRF_ERROR_INVALID_ADDR; + break; + + case CRYS_ECDH_SVDP_DH_INVALID_TEMP_DATA_PTR_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_PTR_ERROR: + ret_val = NRF_ERROR_INVALID_ADDR; + break; + + case CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR: + ret_val = NRF_ERROR_INVALID_LENGTH; + break; + + case CRYS_ECDH_SVDP_DH_ILLEGAL_DOMAIN_ID_ERROR: + ret_val = NRF_ERROR_NOT_SUPPORTED; + break; + + case CRYS_ECDH_SVDP_DH_NOT_CONCENT_PUBL_AND_PRIV_DOMAIN_ID_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + /* From calling EcWrstDhDeriveSharedSecret */ + #if 0 + case ECWRST_DH_SHARED_VALUE_IS_ON_INFINITY_ERROR: + ret_val = NRF_ERROR_INTERNAL; + break; + #endif + default: + ret_val = NRF_ERROR_INTERNAL; + break; + + } + + return ret_val; +} + + +uint32_t nrf_crypto_ecdh_shared_secret_compute(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t const * p_private_key, + nrf_value_length_t const * p_public_key, + nrf_value_length_t * p_shared_secret) +{ + uint32_t ret_val; + CRYSError_t crys_error; + CRYS_ECPKI_Domain_t * p_domain; + CRYS_ECPKI_UserPrivKey_t * p_private_key_user; + CRYS_ECPKI_UserPublKey_t * p_public_key_user; + CRYS_ECDH_TempData_t temp_buffer; + uint32_t shared_secret_size; + uint32_t shared_secret_size_temp; + uint8_t shared_secret[NRF_CRYPTO_ECDH_SHARED_SECRET_MAX_SIZE]; + + // Check that the library has been initialized + if (!nrf_crypto_is_initialized()) + { + return NRF_ERROR_INVALID_STATE; + } + + if (p_private_key == NULL || + p_public_key == NULL || + p_shared_secret == NULL ) + { + return NRF_ERROR_NULL; + } + + if (p_private_key->p_value == NULL || + p_public_key->p_value == NULL || + p_shared_secret->p_value == NULL ) + { + return NRF_ERROR_INVALID_ADDR; + } + + // Get the curve domain from curve_type + if (!cc310_curve_domain_get(curve_info.curve_type, &p_domain)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + // Ensure the private key size is valid + if (p_private_key->length != NRF_CRYPTO_ECC_PRIVATE_KEY_MAX_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Ensure the public key size is valid + if (p_public_key->length != NRF_CRYPTO_ECC_PUBLIC_KEY_MAX_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + ret_val = nrf_crypto_ecdh_shared_secret_size_get(curve_info.curve_type, &shared_secret_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + shared_secret_size_temp = shared_secret_size; + + // Ensure the shared secret can hold the output + if (p_shared_secret->length != shared_secret_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Convert to the cc310 user types for private and public keys + p_private_key_user = (CRYS_ECPKI_UserPrivKey_t *) p_private_key->p_value; + p_public_key_user = (CRYS_ECPKI_UserPublKey_t *) p_public_key->p_value; + + crys_error = CRYS_ECDH_SVDP_DH(p_public_key_user, + p_private_key_user, + shared_secret, + &shared_secret_size_temp, + &temp_buffer); + + ret_val = ecdh_shared_secret_compute_result_get(crys_error); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + if (shared_secret_size_temp != shared_secret_size) + { + return NRF_ERROR_INTERNAL; + } + + // Convert result to Little endian + if (curve_info.endian_type == NRF_CRYPTO_ENDIAN_LE) + { + swap_array_endian(shared_secret, shared_secret_size, p_shared_secret->p_value); + } + else + { + memcpy(p_shared_secret->p_value, shared_secret, shared_secret_size); + } + + + return ret_val; +} + +#endif // NRF_CRYPTO_BACKEND_CC310_LIB + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_ecdsa.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_ecdsa.c new file mode 100644 index 0000000000000000000000000000000000000000..4a8b24840ddcaa99e5b998be4d6452d578e02c1b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_ecdsa.c @@ -0,0 +1,345 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#if defined(NRF_CRYPTO_BACKEND_CC310_LIB) && (NRF_CRYPTO_BACKEND_CC310_LIB == 1) + +#include "cc310_lib_ecdsa.h" +#include "cc310_lib_init.h" +#include "cc310_lib_shared.h" +#include "ssi_pal_types.h" +#include "ssi_pal_mem.h" +#include "sns_silib.h" +#include "crys_rnd.h" +#include "crys_ecpki_ecdsa.h" +#include "crys_kdf_error.h" +#include "crys_hash_error.h" +#include "nrf_crypto_types.h" +#include "nrf_error.h" + +extern CRYS_RND_Context_t * gp_rnd_context; + + +static uint32_t ecdsa_result_get(CRYSError_t error) +{ + uint32_t ret_val = NRF_ERROR_INTERNAL; + + // TODO: Invalid data + switch(error) + { + /* From calling CRYS_KDF_KeyDerivFunc */ + case CRYS_KDF_INVALID_ARGUMENT_POINTER_ERROR: + ret_val = NRF_ERROR_INVALID_ADDR; + break; + + case CRYS_KDF_INVALID_ARGUMENT_HASH_MODE_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_KDF_INVALID_KEY_DERIVATION_MODE_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_KDF_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_KDF_INVALID_OTHER_INFO_SIZE_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_KDF_INVALID_KEYING_DATA_SIZE_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + /* From calling CRYS_HASH_Init, CRYS_HASH_Update and CRYS_HASH_Finish (KDF internal) */ + case CRYS_HASH_INVALID_USER_CONTEXT_POINTER_ERROR: + ret_val = NRF_ERROR_INVALID_ADDR; + break; + + case CRYS_HASH_ILLEGAL_OPERATION_MODE_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_HASH_DATA_IN_POINTER_INVALID_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_HASH_DATA_SIZE_ILLEGAL: + ret_val = NRF_ERROR_INVALID_LENGTH; + break; + + case CRYS_HASH_INVALID_RESULT_BUFFER_POINTER_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_HASH_DATA_SIZE_IS_ILLEGAL_FOR_CSI_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_HASH_ILLEGAL_PARAMS_ERROR: + + break; + } + + return ret_val; +} + +/**@brief Internal function to get the hash type that was used to generate the hash + * used for ECDSA sign/verify. + */ +bool ecdsa_hash_algorithm_get(nrf_hash_type_t hash_type, + CRYS_ECPKI_HASH_OpMode_t * p_hash_mode) +{ + switch(hash_type) + { + case NRF_CRYPTO_HASH_TYPE_SHA1: + (*p_hash_mode) = CRYS_ECPKI_AFTER_HASH_SHA1_mode; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA224: + (*p_hash_mode) = CRYS_ECPKI_AFTER_HASH_SHA224_mode; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA256: + (*p_hash_mode) = CRYS_ECPKI_AFTER_HASH_SHA256_mode; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA384: + (*p_hash_mode) = CRYS_ECPKI_AFTER_HASH_SHA384_mode; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA512: + (*p_hash_mode) = CRYS_ECPKI_AFTER_HASH_SHA512_mode; + break; + + default: + return false; + } + + return true; +} + + +uint32_t nrf_crypto_ecdsa_sign_hash(nrf_crypto_signature_info_t sig_info, + nrf_value_length_t const * p_private_key, + nrf_value_length_t const * p_hash, + nrf_value_length_t * p_signature) +{ + uint32_t ret_val; + CRYSError_t crys_error; + CRYS_ECPKI_Domain_t * p_domain; + nrf_crypto_ecdsa_sizes_t sig_sizes; + + // TODO: What is this? + CRYS_ECDSA_SignUserContext_t * p_sig_user_context = NULL; + CRYS_ECPKI_UserPrivKey_t * p_private_key_user; + CRYS_ECPKI_HASH_OpMode_t hash_mode; + + // Check if library has been initialized + if (!nrf_crypto_is_initialized()) + { + return NRF_ERROR_INVALID_STATE; + } + + // Basic parameter testing. + if (p_private_key == NULL || + p_signature == NULL || + p_hash == NULL ) + { + return NRF_ERROR_NULL; + } + + if (p_private_key->p_value == NULL || + p_hash->p_value == NULL || + p_signature->p_value == NULL ) + { + return NRF_ERROR_INVALID_ADDR; + } + + // Get the sizes for the keys, hash and signature + ret_val = nrf_crypto_ecdsa_sizes_get(sig_info, &sig_sizes); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + // Check signature size. + if (p_signature->length != sig_sizes.signature_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Check if private key size. + if (p_private_key->length != sig_sizes.private_key_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Check the hash size. + if (p_hash->length != sig_sizes.hash_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Try to get the correct curve domain. + if (!cc310_curve_domain_get(sig_info.curve_type, &p_domain)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + // Get the hash type to indicate that hash has already been calculated. + if (!ecdsa_hash_algorithm_get(sig_info.hash_type, &hash_mode)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + p_private_key_user = (CRYS_ECPKI_UserPrivKey_t*)p_private_key->p_value; + + crys_error = CRYS_ECDSA_Sign(gp_rnd_context, + p_sig_user_context, + p_private_key_user, + hash_mode, + p_hash->p_value, + p_hash->length, + p_signature->p_value, + &p_signature->length); + + ret_val = ecdsa_result_get(crys_error); + return ret_val; +} + + +uint32_t nrf_crypto_ecdsa_verify_hash(nrf_crypto_signature_info_t sig_info, + nrf_value_length_t const * p_public_key, + nrf_value_length_t const * p_hash, + nrf_value_length_t const * p_signature) +{ + uint32_t ret_val; + CRYSError_t crys_error; + CRYS_ECPKI_Domain_t * p_domain; + CRYS_ECDSA_VerifyUserContext_t * p_verify_context_user = NULL; + nrf_crypto_ecdsa_sizes_t sig_sizes; + CRYS_ECPKI_UserPublKey_t * p_public_key_user; + CRYS_ECPKI_HASH_OpMode_t hash_mode; + + // Check if library has been initialized + if (!nrf_crypto_is_initialized()) + { + return NRF_ERROR_INVALID_STATE; + } + + if (p_public_key == NULL || + p_hash == NULL || + p_signature == NULL ) + { + return NRF_ERROR_NULL; + } + + if (p_public_key->p_value == NULL || + p_hash->p_value == NULL || + p_signature->p_value == NULL ) + { + return NRF_ERROR_INVALID_ADDR; + } + + // Get the sizes for the keys, hash and signature + ret_val = nrf_crypto_ecdsa_sizes_get(sig_info, &sig_sizes); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + // Check the signature size. + if (p_signature->length != sig_sizes.signature_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Check the private key size. + if (p_public_key->length != sig_sizes.public_key_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Check the hash size. + if (p_hash->length != sig_sizes.hash_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Try to get the correct curve domain + if (!cc310_curve_domain_get(sig_info.curve_type, &p_domain)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + // Get the hash type to indicate that hash has already been calculated. + if (!ecdsa_hash_algorithm_get(sig_info.hash_type, &hash_mode)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + p_public_key_user = (CRYS_ECPKI_UserPublKey_t *)p_public_key->p_value; + + crys_error = CRYS_ECDSA_Verify(p_verify_context_user, + p_public_key_user, + hash_mode, + p_signature->p_value, + p_signature->length, + p_hash->p_value, + p_hash->length); + + ret_val = ecdsa_result_get(crys_error); + return ret_val; +} + +#endif // NRF_CRYPTO_BACKEND_CC310_LIB + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_ecdsa.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_ecdsa.h new file mode 100644 index 0000000000000000000000000000000000000000..0cb83dcd8c2fc1056a5c6340b3fd972cb0c8eca2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_ecdsa.h @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef CC310_LIB_ECDSA_H__ +#define CC310_LIB_ECDSA_H__ + +/** @file + * + * @defgroup nrf_crypto_backend_cc310_lib_ecdsa CC310 backend ECDSA types. + * @{ + * @ingroup nrf_crypto_backend_cryptocell + * + * @brief Provides types required for CC310 backend ECDSA. + */ + +#include "nrf_crypto_ecdsa.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Size of ECDSA signing context. + */ +#define NRF_CRYPTO_ECDSA_SIGN_CONTEXT_SIZE sizeof(ECDSA_SignUserContext_t) + + +/** @brief Size of ECDSA verification context. + */ +#define NRF_CRYPTO_ECDSA_VERIFY_CONTEXT_SIZE sizeof(ECDSA_VerifyUserContext_t) + + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // #ifndef CC310_LIB_ECDSA_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_hash.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_hash.c new file mode 100644 index 0000000000000000000000000000000000000000..cf2fcab05fda8cee35875660f6c5bb6b5f4d64f9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_hash.c @@ -0,0 +1,333 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#if defined(NRF_CRYPTO_BACKEND_CC310_LIB) && (NRF_CRYPTO_BACKEND_CC310_LIB == 1) + +#include "cc310_lib_hash.h" +#include "cc310_lib_init.h" +#include +#include "crys_hash.h" +#include "crys_hash_error.h" +#include "nrf_error.h" +#include "crys_rnd.h" + +bool hash_algorithm_get(nrf_hash_type_t hash_type, CRYS_HASH_OperationMode_t * p_hash_mode) +{ + if (p_hash_mode == NULL) + { + return false; + } + + switch(hash_type) + { + case NRF_CRYPTO_HASH_TYPE_MD5: + (*p_hash_mode) = CRYS_HASH_MD5_mode; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA1: + (*p_hash_mode) = CRYS_HASH_SHA1_mode; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA224: + (*p_hash_mode) = CRYS_HASH_SHA224_mode; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA256: + (*p_hash_mode) = CRYS_HASH_SHA256_mode; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA384: + (*p_hash_mode) = CRYS_HASH_SHA384_mode; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA512: + (*p_hash_mode) = CRYS_HASH_SHA512_mode; + break; + + default: + return NRF_ERROR_NOT_SUPPORTED; + } + + return NRF_SUCCESS; +} + + +static uint32_t hash_result_get(CRYSError_t error) +{ + uint32_t ret_val; + + switch(error) + { + case CRYS_OK: + ret_val = NRF_SUCCESS; + break; + + case CRYS_HASH_INVALID_USER_CONTEXT_POINTER_ERROR: + ret_val = NRF_ERROR_INVALID_ADDR; + break; + + case CRYS_HASH_ILLEGAL_OPERATION_MODE_ERROR: + ret_val = NRF_ERROR_NOT_SUPPORTED; + break; + + case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR: + ret_val = NRF_ERROR_INVALID_DATA; + break; + + case CRYS_HASH_DATA_IN_POINTER_INVALID_ERROR: + ret_val = NRF_ERROR_INVALID_ADDR; + break; + + case CRYS_HASH_DATA_SIZE_ILLEGAL: + ret_val = NRF_ERROR_INVALID_LENGTH; + break; + + case CRYS_HASH_INVALID_RESULT_BUFFER_POINTER_ERROR: + ret_val = NRF_ERROR_INVALID_ADDR; + break; + + case CRYS_HASH_DATA_SIZE_IS_ILLEGAL_FOR_CSI_ERROR: + ret_val = NRF_ERROR_INVALID_LENGTH; + break; + + case CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR: + ret_val = NRF_ERROR_INVALID_STATE; + break; + + case CRYS_HASH_ILLEGAL_PARAMS_ERROR: + ret_val = NRF_ERROR_INTERNAL; + break; + + case CRYS_HASH_CTX_SIZES_ERROR: + ret_val = NRF_ERROR_INVALID_LENGTH; + break; + + case CRYS_HASH_IS_NOT_SUPPORTED: + ret_val = NRF_ERROR_NOT_SUPPORTED; + break; + + default: + ret_val = NRF_ERROR_INTERNAL; + break; + } + + return ret_val; +} + + +uint32_t nrf_crypto_hash_init(nrf_crypto_hash_info_t hash_info, + nrf_value_length_t * p_hash_context) +{ + uint32_t ret_val; + CRYSError_t crys_error; + CRYS_HASH_OperationMode_t hash_type = CRYS_HASH_OperationModeLast; + CRYS_HASHUserContext_t * p_hash_context_user; + + // Check if library has been initialized + if (!nrf_crypto_is_initialized()) + { + return NRF_ERROR_INVALID_STATE; + } + + if (p_hash_context == NULL) + { + return NRF_ERROR_NULL; + } + + if (p_hash_context->p_value == NULL) + { + return NRF_ERROR_INVALID_ADDR; + } + + if (p_hash_context->length != NRF_CRYPTO_HASH_CONTEXT_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (!hash_algorithm_get(hash_info.hash_type, &hash_type)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if (hash_info.endian_type != NRF_CRYPTO_ENDIAN_LE) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + // Convert hash context to cc310 user format + p_hash_context_user = (CRYS_HASHUserContext_t *)p_hash_context->p_value; + + crys_error = CRYS_HASH_Init(p_hash_context_user, hash_type); + ret_val = hash_result_get(crys_error); + return ret_val; +} + + +uint32_t nrf_crypto_hash_update(nrf_value_length_t * p_hash_context, + uint8_t const * p_data, + uint32_t len) +{ + uint32_t ret_val; + CRYSError_t crys_error; + CRYS_HASHUserContext_t * p_hash_context_user; + + // Check if library has been initialized + if (!nrf_crypto_is_initialized()) + { + return NRF_ERROR_INVALID_STATE; + } + + if (p_hash_context == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + if (p_hash_context->p_value == NULL) + { + return NRF_ERROR_INVALID_ADDR; + } + + if (p_hash_context->length != NRF_CRYPTO_HASH_CONTEXT_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Convert hash context to cc310 user format + p_hash_context_user = (CRYS_HASHUserContext_t *)p_hash_context->p_value; + + crys_error = CRYS_HASH_Update(p_hash_context_user, (uint8_t*)p_data, len); + ret_val = hash_result_get(crys_error); + return ret_val; +} + + +uint32_t nrf_crypto_hash_finalize(nrf_crypto_hash_info_t hash_info, + nrf_value_length_t * p_hash_context, + nrf_value_length_t * p_hash) +{ + uint32_t ret_val; + CRYSError_t crys_error; + CRYS_HASHUserContext_t * p_hash_context_user; + CRYS_HASH_Result_t * p_hash_result = (CRYS_HASH_Result_t *)p_hash->p_value; + + // Check if library has been initialized + if (!nrf_crypto_is_initialized()) + { + return NRF_ERROR_INVALID_STATE; + } + + // Check the parameters + if (p_hash_context == NULL || + p_hash == NULL ) + { + return NRF_ERROR_NULL; + } + + if (p_hash_context->p_value == NULL || + p_hash->p_value == NULL) + { + return NRF_ERROR_INVALID_ADDR; + } + + // Check the length of the hash context + if(p_hash_context->length != NRF_CRYPTO_HASH_CONTEXT_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Check the length of the hash + + + // Convert hash context to cc310 user format + p_hash_context_user = (CRYS_HASHUserContext_t *)p_hash_context->p_value; + + // Not sure about this + crys_error = CRYS_HASH_Finish(p_hash_context_user, *p_hash_result); + ret_val = hash_result_get(crys_error); + return ret_val; +} + + +uint32_t nrf_crypto_hash_compute(nrf_crypto_hash_info_t hash_info, + uint8_t const * p_data, + uint32_t len, + nrf_value_length_t * p_hash) +{ + uint32_t ret_val; + CRYSError_t crys_error; + CRYS_HASH_OperationMode_t hash_type = CRYS_HASH_OperationModeLast; + CRYS_HASH_Result_t * p_hash_result; + + if (p_data == NULL || p_hash == NULL) + { + return NRF_ERROR_NULL; + } + + if (p_hash->p_value == NULL) + { + return NRF_ERROR_INVALID_ADDR; + } + + if(!hash_algorithm_get(hash_info.hash_type, &hash_type)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + // Currently only supporting LE hash + if(hash_info.endian_type != NRF_CRYPTO_ENDIAN_LE) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + // Convert output buffer to valid. + p_hash_result = (CRYS_HASH_Result_t *)p_hash->p_value; + + + crys_error = CRYS_HASH(hash_type, (uint8_t*)p_data, len, *p_hash_result); + ret_val = hash_result_get(crys_error); + return ret_val; +} + +#endif // NRF_CRYPTO_BACKEND_CC310_LIB + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_hash.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_hash.h new file mode 100644 index 0000000000000000000000000000000000000000..7c62229fa82780eae851338d929ce34c73cbff3e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_hash.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef CC310_LIB_HASH_H__ +#define CC310_LIB_HASH_H__ + +/** @file + * + * @defgroup nrf_crypto_backend_cc310_lib_hash CC310 backend hash types. + * @{ + * @ingroup nrf_crypto_backend_cryptocell + * + * @brief Provides types required for CC310 backend hash. + */ + +#include "nrf_crypto_hash.h" +#include "crys_hash.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Size of hash context context. + */ +#define NRF_CRYPTO_HASH_CONTEXT_SIZE sizeof(CRYS_HASHUserContext_t) + + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // #ifndef CC310_LIB_HASH_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_init.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_init.c new file mode 100644 index 0000000000000000000000000000000000000000..61ace8ce0c92995653e8e7c61785d4b60c7d1b85 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_init.c @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#if defined(NRF_CRYPTO_BACKEND_CC310_LIB) && (NRF_CRYPTO_BACKEND_CC310_LIB == 1) + +#include "nrf_crypto_init.h" +#include "cc310_lib_init.h" +#include "cc310_lib_shared.h" +#include "crys_rnd.h" +#include "sns_silib.h" + +// Temporary setting this before real handling of memory management +CRYS_RND_Context_t g_rnd_context; + +// Temporary setting this before real handling of memory management +CRYS_RND_WorkBuff_t g_rnd_work_buffer; + + +/**@brief Pointer to contigious memory holding random number context data + * + * @note The data pointed to must be available in the duration of the usage of Cryptocell api functions. + */ +CRYS_RND_Context_t * gp_rnd_context = &g_rnd_context; + +/**@brief Pointer to contigious memory for the rnd initialization workspace + * + * @note The Data pointed to must be available in the duration of the initialization of the Cryptocell + * or during reseeding of rng. + */ +CRYS_RND_WorkBuff_t * gp_rnd_work_buffer = &g_rnd_work_buffer; + +static uint32_t init_result_get(uint32_t crys_error) +{ + uint32_t ret_val = NRF_ERROR_INTERNAL; + switch(crys_error) + { + case CRYS_OK: + ret_val = NRF_SUCCESS; + break; + + default: + ret_val = NRF_ERROR_INTERNAL; + break; + } + + return ret_val; +} + + +static uint32_t uninit_result_get(uint32_t crys_error) +{ + uint32_t ret_val; + + switch(crys_error) + { + default: + ret_val = NRF_ERROR_INTERNAL; + } + + return ret_val; +} + + +uint32_t nrf_crypto_init(void) +{ + //nrf_crypto_init_info_h * p_init_info + uint32_t ret_val; + CRYSError_t crys_error; + + // Initialize the cryptocell by setting hardware register + NRF_CRYPTOCELL->ENABLE = 1; + + // Initialize the CC310 run-time library + crys_error = SaSi_LibInit(gp_rnd_context, gp_rnd_work_buffer); + ret_val = init_result_get(crys_error); + return ret_val; +} + + +uint32_t nrf_crypto_uninit(void) +{ + uint32_t ret_val; + CRYSError_t crys_error; + + // Check that the library has been initialized. If not, exit. + if (gp_rnd_context == NULL) + { + return NRF_SUCCESS; + } + + crys_error = SaSi_LibFini(gp_rnd_context); + + // Set rnd context to zero to signal that the library is uninitialized + gp_rnd_context = NULL; + + ret_val = uninit_result_get(crys_error); + return ret_val; +} + + +bool nrf_crypto_is_initialized(void) +{ + return (gp_rnd_context != NULL); +} + + +#endif // NRF_CRYPTO_BACKEND_CC310_LIB + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_init.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_init.h new file mode 100644 index 0000000000000000000000000000000000000000..19f1f0d4d85bb87e8cf51c14d2d68105025b3c1b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_init.h @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef CC310_LIB_INIT_H__ +#define CC310_LIB_INIT_H__ + +/** @file + * + * @defgroup nrf_crypto_backend_cc310_lib_init CC310 backend initialization types. + * @{ + * @ingroup nrf_crypto_backend_cryptocell + * + * @brief Provides types required for CC310 backend initialization. + */ + +#include "nrf_crypto_init.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Size of buffer required to initalize nrf_crypto CC310 backend. + */ +#define NRF_CRYPTO_INIT_RAM_BUFFER (0) + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // #ifndef CC310_LIB_INIT_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_keys.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_keys.c new file mode 100644 index 0000000000000000000000000000000000000000..57263d65113559a6a9e1c5f71503e18510d5f0b7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_keys.c @@ -0,0 +1,465 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#if defined(NRF_CRYPTO_BACKEND_CC310_LIB) && (NRF_CRYPTO_BACKEND_CC310_LIB == 1) + +#include +#include "nrf_crypto_keys.h" +#include "cc310_lib_keys.h" +#include "cc310_lib_init.h" +#include "cc310_lib_shared.h" +#include "nrf_log.h" +#include "nrf_crypto_types.h" +#include "crys_ecpki_error.h" +#include "crys_ecpki_build.h" +#include "crys_ecpki_kg.h" +#include "string.h" + +extern CRYS_RND_Context_t * gp_rnd_context; + +static void swap_array_endian(uint8_t * p_in, uint32_t len, uint8_t * p_out) +{ + uint32_t i; + for(i = 0; i < len; i++) + { + p_out[len-i-1] = p_in[i]; + } +} + +static uint32_t key_pair_generate_result_get(CRYSError_t crys_error) +{ + uint32_t ret_val= NRF_ERROR_INTERNAL; + + switch(crys_error) + { + case CRYS_OK: + ret_val = NRF_SUCCESS; + break; + case CRYS_ECPKI_RND_CONTEXT_PTR_ERROR: + ret_val = NRF_ERROR_INVALID_STATE; + break; + + case CRYS_ECPKI_ILLEGAL_D0MAIN_ID_ERROR: + ret_val = NRF_ERROR_NOT_SUPPORTED; + break; + + case CRYS_ECPKI_DOMAIN_PTR_ERROR: + ret_val = NRF_ERROR_INTERNAL; + break; + + case CRYS_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR: + ret_val = NRF_ERROR_INVALID_ADDR; + break; + + case CRYS_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR: + ret_val = NRF_ERROR_INVALID_ADDR; + break; + + case CRYS_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR: + ret_val = NRF_ERROR_INTERNAL; + break; + + #if 0 + /* From calling CRYS_RND_GenerateVectorInRange */ + case CRYS_RND_GEN_VECTOR_FUNC_ERROR: + ret_val = NRF_ERROR_INVALID_STATE; + break; + + case CRYS_RND_VECTOR_OUT_SIZE_ERROR: + ret_val = NRF_ERROR_INVALID_STATE; + break; + + case CRYS_RND_CONTEXT_PTR_INVALID_ERROR: + ret_val = NRF_ERROR_INVALID_STATE; + break; + + case CRYS_RND_MAX_VECTOR_IS_TOO_SMALL_ERROR: + ret_val = NRF_ERROR_INVALID_STATE; + break; + #endif + + #if 0 + case ECWRST_SCALAR_MULT_INVALID_SCALAR_VALUE_ERROR: + ret_val = NRF_ERROR_INVALID_STATE; + break; + + case ECWRST_SCALAR_MULT_INVALID_MOD_ORDER_SIZE_ERROR: + ret_val = NRF_ERROR_INVALID_STATE; + break; + #endif + default: + ret_val = NRF_ERROR_INTERNAL; + break; + } + + + return ret_val; +} + + +static uint32_t public_key_calculate_result_get(CRYSError_t crys_error) +{ + uint32_t ret_val; + + switch(crys_error) + { + case CRYS_OK: + ret_val = NRF_SUCCESS; + break; + + default: + ret_val = NRF_ERROR_INTERNAL; + break; + } + + return ret_val; +} + + +static uint32_t public_key_build_result_get(CRYSError_t crys_error) +{ + uint32_t ret_val; + + switch(crys_error) + { + case CRYS_OK: + NRF_LOG_INFO("Key build result successful!\r\n"); + ret_val = NRF_SUCCESS; + break; + + default: + ret_val = NRF_ERROR_INTERNAL; + break; + } + + return ret_val; + +} + +static uint32_t public_key_export_result_get(CRYSError_t crys_error) +{ + uint32_t ret_val = NRF_SUCCESS; + + switch(crys_error) + { + case CRYS_OK: + NRF_LOG_INFO("Key build result successful!\r\n"); + ret_val = NRF_SUCCESS; + break; + + #if 0 + case CRYS_COMMON_DATA_SIZE_ILLEGAL: + ret_val = NRF_ERROR_INTERNAL; + break; + #endif + + case CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_ERROR: + ret_val = NRF_ERROR_INVALID_LENGTH; + break; + + default: + ret_val = NRF_ERROR_INTERNAL; + break; + } + + return ret_val; + +} + +uint32_t nrf_crypto_ecc_key_pair_generate(nrf_crypto_curve_info_t curve_type, + nrf_value_length_t * p_private_key, + nrf_value_length_t * p_public_key) +{ + uint32_t ret_val; + CRYSError_t crys_error; + CRYS_ECPKI_Domain_t * p_domain; + + CRYS_ECPKI_KG_TempData_t temp_ecpki_kg_buffer; + + CRYS_ECPKI_UserPrivKey_t * p_private_key_user; + CRYS_ECPKI_UserPublKey_t * p_public_key_user; + + // Check that the library has been initialized + if (!nrf_crypto_is_initialized()) + { + return NRF_ERROR_INVALID_STATE; + } + + if (p_private_key == NULL || p_public_key == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Get the curve domain from curve_type + if (!cc310_curve_domain_get(curve_type.curve_type, &p_domain)) + { + NRF_LOG_INFO("Could not get curve domain!\r\n"); + return NRF_ERROR_NOT_SUPPORTED; + } + + + // Ensure the private key can hold the internal type. + if (p_private_key->length != NRF_CRYPTO_ECC_PRIVATE_KEY_MAX_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Ensure the public key can hold the external type. + if (p_public_key->length != NRF_CRYPTO_ECC_PUBLIC_KEY_MAX_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + + p_private_key_user = (CRYS_ECPKI_UserPrivKey_t *)p_private_key->p_value; + p_public_key_user = (CRYS_ECPKI_UserPublKey_t *)p_public_key->p_value; + + crys_error = CRYS_ECPKI_GenKeyPair(gp_rnd_context, + p_domain, + p_private_key_user, + p_public_key_user, + &temp_ecpki_kg_buffer, + NULL ); + + + + ret_val = key_pair_generate_result_get(crys_error); + return ret_val; +} + + +uint32_t nrf_crypto_ecc_public_key_calculate(nrf_crypto_curve_info_t curve_type, + nrf_value_length_t const * p_private_key, + nrf_value_length_t * p_public_key) +{ + uint32_t ret_val; + + ret_val = public_key_calculate_result_get(CRYS_OK); + return ret_val; +} + + +uint32_t nrf_crypto_ecc_private_key_to_raw(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t const * p_private_key, + nrf_value_length_t * p_private_key_raw) +{ + return NRF_SUCCESS; +} + + +uint32_t nrf_crypto_ecc_public_key_to_raw(nrf_crypto_curve_info_t curve_type, + nrf_value_length_t const * p_public_key, + nrf_value_length_t * p_raw_key) +{ + uint32_t ret_val; + CRYSError_t crys_error; + CRYS_ECPKI_UserPublKey_t * p_public_key_user; + CRYS_ECPKI_Domain_t * p_domain; + uint32_t raw_param_size; + uint32_t compact_key_size; + uint32_t public_key_raw_size; + uint8_t public_key_buffer[NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP521R1 + 1]; + + // Check that both the public key and raw key is valid + if (p_public_key == NULL || p_raw_key == NULL) + { + return NRF_ERROR_NULL; + } + + // Get the curve domain from curve_type + if (!cc310_curve_domain_get(curve_type.curve_type, &p_domain)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + ret_val = nrf_crypto_ecc_public_key_size_get(curve_type.curve_type, &public_key_raw_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + // Ensure the public key can hold the raw representation. + if(public_key_raw_size != p_raw_key->length) + { + return NRF_ERROR_INVALID_LENGTH; + } + + compact_key_size = public_key_raw_size + 1; + + // Convert the key to the + p_public_key_user = (CRYS_ECPKI_UserPublKey_t *)p_public_key->p_value; + + crys_error = CRYS_ECPKI_ExportPublKey(p_public_key_user, + CRYS_EC_PointUncompressed, + public_key_buffer, + &compact_key_size); + ret_val = public_key_export_result_get(crys_error); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + // format is [tag][x][y] + if(compact_key_size != public_key_raw_size + 1) + { + return NRF_ERROR_INTERNAL; + } + + if (public_key_buffer[0] != 0x04) + { + return NRF_ERROR_INTERNAL; + } + + raw_param_size = compact_key_size / 2; + + if (curve_type.endian_type == NRF_CRYPTO_ENDIAN_LE) + { + // Swap X value + swap_array_endian(public_key_buffer + 1, raw_param_size, p_raw_key->p_value); + // Swap Y value + swap_array_endian(public_key_buffer + raw_param_size + 1, raw_param_size, p_raw_key->p_value + raw_param_size); + } + else + { + // X and Y value is already in the correct order. + memcpy(p_raw_key->p_value, public_key_buffer + 1, compact_key_size); + } + + return NRF_SUCCESS; +} + + +uint32_t nrf_crypto_ecc_public_key_from_raw(nrf_crypto_curve_info_t curve_type, + nrf_value_length_t * p_public_key_raw, + nrf_value_length_t * p_public_key) +{ + uint32_t ret_val; + CRYSError_t crys_error; + CRYS_ECPKI_UserPublKey_t * p_public_key_user; + CRYS_ECPKI_Domain_t * p_domain; + uint32_t raw_key_size; + uint32_t raw_param_size; + + // Compact representation of public key according to IEEE1363, + // using 1 byte to designate the format. + // Using a largest public key for size (used key will be equal or smaller). + uint8_t compact_rep[NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP521R1 + 1]; + + // Check that both the public key and raw key is valid + if (p_public_key == NULL || p_public_key_raw == NULL) + { + return NRF_ERROR_NULL; + } + + if (p_public_key->p_value == NULL || + p_public_key_raw->p_value == NULL ) + { + return NRF_ERROR_INVALID_ADDR; + } + + // Get the curve domain from curve_type + if (!cc310_curve_domain_get(curve_type.curve_type, &p_domain)) + { + NRF_LOG_INFO("Could not get curve domain\r\n"); + return NRF_ERROR_NOT_SUPPORTED; + } + + ret_val = nrf_crypto_ecc_public_key_size_get(curve_type.curve_type, &raw_key_size); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_INFO("Could not get key size\r\n"); + return NRF_SUCCESS; + } + + // Ensure the public key can hold the external type. + if (p_public_key_raw->length != raw_key_size) + { + NRF_LOG_INFO("p_raw_key->length != raw_key_size\r\n"); + return NRF_ERROR_INVALID_LENGTH; + } + + // Ensure the public key can hold the internal type. + if (p_public_key->length != sizeof(CRYS_ECPKI_UserPublKey_t)) + { + NRF_LOG_INFO("p_public_key->length != sizeof(CRYS_ECPKI_UserPublKey_t)\r\n"); + return NRF_ERROR_INVALID_LENGTH; + } + + raw_param_size = raw_key_size / 2; + + // Add one to hold the prefix. + raw_key_size += 1; + + // Compact representation is big-endian by IEEE1636 spec. + // Indicate that we have a key with X and Y (non-compressed) + compact_rep[0] = 0x04; + if(curve_type.endian_type == NRF_CRYPTO_ENDIAN_LE) + { + // Swap X value + swap_array_endian(p_public_key_raw->p_value, raw_param_size, compact_rep + 1); + // Swap Y value + swap_array_endian(p_public_key_raw->p_value + raw_param_size, raw_param_size, compact_rep + raw_param_size + 1); + } + else + { + // X and Y value is already in the correct order for CryptoCell. + memcpy(compact_rep + 1, p_public_key_raw->p_value, raw_key_size); + } + + // Set the pointer to be the return value. + p_public_key_user = (CRYS_ECPKI_UserPublKey_t *)p_public_key->p_value; + + NRF_LOG_INFO("Building public key!\r\n"); + crys_error = CRYS_ECPKI_BuildPublKey(p_domain, + compact_rep, + raw_key_size, + p_public_key_user); + NRF_LOG_INFO("Finished building public key: 0x%08x!\r\n", crys_error); + + ret_val = public_key_build_result_get(crys_error); + return ret_val; +} + + +#endif // NRF_CRYPTO_BACKEND_CC310_LIB + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_keys.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_keys.h new file mode 100644 index 0000000000000000000000000000000000000000..9d791c6ab1bb983154dce2c2e2fdc35148d84a6d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_keys.h @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef CC310_LIB_KEYS_H__ +#define CC310_LIB_KEYS_H__ + +/** @file + * + * @defgroup nrf_crypto_backend_cc310_lib_ecc_keys CC310 backend ECC key types. + * @{ + * @ingroup nrf_crypto_backend_cryptocell + * + * @brief Provides types required for CC310 backend ECC keys. + */ + +#include "nrf_crypto_ecdsa.h" +#include "crys_ecpki_types.h" + +#ifdef __cplusplus +extern "C" { +#if 0 +} +#endif +#endif + +/**@brief Macro to get the size of the internal represenation of a private key + * in the CryptoCell API. + */ +#define NRF_CRYPTO_ECC_PRIVATE_KEY_MAX_SIZE (sizeof(CRYS_ECPKI_UserPrivKey_t)) + +/**@brief Macro to get the size of the internal represenation of a public key + * in the CryptoCell API. + */ +#define NRF_CRYPTO_ECC_PUBLIC_KEY_MAX_SIZE (sizeof(CRYS_ECPKI_UserPublKey_t)) + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // #ifndef CC310_LIB_KEYS_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_rng.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_rng.c new file mode 100644 index 0000000000000000000000000000000000000000..097ee7763402ab57ebe64fd84aa927cc05740769 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_rng.c @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#if defined(NRF_CRYPTO_BACKEND_CC310_LIB) && (NRF_CRYPTO_BACKEND_CC310_LIB == 1) + +#include "nrf_crypto.h" +#include "nrf_crypto_rng.h" +#include "cc310_lib_init.h" +#include "crys_rnd.h" + +extern CRYS_RND_Context_t * gp_rnd_context; + +static uint32_t rng_result_get(CRYSError_t crys_error) +{ + uint32_t ret_val; + + switch(crys_error) + { + case CRYS_OK: + ret_val = NRF_SUCCESS; + break; + + default: + ret_val = NRF_ERROR_INTERNAL; + break; + } + + return ret_val; +} + +uint32_t nrf_crypto_rng_init(void) +{ + // No need to do anything as library init takes care of initialization of rng. + return NRF_SUCCESS; +} + +uint32_t nrf_crypto_rng_vector_generate(uint8_t * p_target, uint32_t length) +{ + uint32_t ret_val; + CRYSError_t crys_error; + + if (p_target == NULL) + { + return NRF_ERROR_NULL; + } + + crys_error = CRYS_RND_GenerateVector(&gp_rnd_context->rndState, length, p_target); + ret_val = rng_result_get(crys_error); + return ret_val; +} + +#endif // NRF_CRYPTO_BACKEND_CC310_LIB + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_shared.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_shared.c new file mode 100644 index 0000000000000000000000000000000000000000..294a72e7d2125fcb0c2fbb2c8764b3ce3121ec43 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_shared.c @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#if defined(NRF_CRYPTO_BACKEND_CC310_LIB) && (NRF_CRYPTO_BACKEND_CC310_LIB == 1) + +#include "nrf_crypto.h" +#include "cc310_lib_shared.h" +#include "crys_ecpki_domain.h" + +bool cc310_curve_domain_get(nrf_ecc_curve_type_t curve_type, CRYS_ECPKI_Domain_t ** p_domain) +{ + CRYS_ECPKI_DomainID_t domain_id; + switch(curve_type) + { + case NRF_CRYPTO_CURVE_SECP160R1: + domain_id = CRYS_ECPKI_DomainID_secp160r1; + break; + + case NRF_CRYPTO_CURVE_SECP192R1: + domain_id = CRYS_ECPKI_DomainID_secp192r1; + break; + + case NRF_CRYPTO_CURVE_SECP224R1: + domain_id = CRYS_ECPKI_DomainID_secp224r1; + break; + + case NRF_CRYPTO_CURVE_SECP256R1: + domain_id = CRYS_ECPKI_DomainID_secp256r1; + break; + + case NRF_CRYPTO_CURVE_SECP384R1: + domain_id = CRYS_ECPKI_DomainID_secp384r1; + break; + + case NRF_CRYPTO_CURVE_SECP521R1: + domain_id = CRYS_ECPKI_DomainID_secp521r1; + break; + + case NRF_CRYPTO_CURVE_SECP192K1: + domain_id = CRYS_ECPKI_DomainID_secp160k1; + break; + + case NRF_CRYPTO_CURVE_SECP224K1: + domain_id = CRYS_ECPKI_DomainID_secp224k1; + break; + + case NRF_CRYPTO_CURVE_SECP256K1: + domain_id = CRYS_ECPKI_DomainID_secp256k1; + break; + + default: + return false; + } + + (*p_domain) = (CRYS_ECPKI_Domain_t*)CRYS_ECPKI_GetEcDomain(domain_id); + return true; +} + +#endif // NRF_CRYPTO_BACKEND_CC310_LIB + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_shared.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_shared.h new file mode 100644 index 0000000000000000000000000000000000000000..432bea9e1b639c74f3335b32296e237c08184256 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/cc310_lib/cc310_lib_shared.h @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef CC310_LIB_HASH_H__ +#define CC310_LIB_HASH_H__ + +/** @file + * + * @defgroup nrf_crypto_backend_cc310_lib_shared CC310 backend shared functions. + * @{ + * @ingroup nrf_crypto_backend_cryptocell + * + * @brief Provides shared functions required for CC310 backend. + */ + +#include +#include "nrf_crypto_types.h" +#include "crys_ecpki_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function to get micro_ecc curve domain from curve_type + * + * @param[in] curve_type Curve type get domain for. + * @param[out] pp_domain Double pointer to curve domain structure. + * + * @retval True True if curve domain was successfully located. + */ +bool cc310_curve_domain_get(nrf_ecc_curve_type_t curve_type, CRYS_ECPKI_Domain_t ** pp_domain); + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // #ifndef CC310_LIB_HASH_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_ecdh.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_ecdh.c new file mode 100644 index 0000000000000000000000000000000000000000..845d42763995a12f14fe5d7a5c654d9345a16a41 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_ecdh.c @@ -0,0 +1,170 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#if defined(NRF_CRYPTO_BACKEND_MICRO_ECC) && (NRF_CRYPTO_BACKEND_MICRO_ECC == 1) + +#if defined(NRF_CRYPTO_SUPPORTS_RNG) && NRF_CRYPTO_SUPPORTS_RNG == 1 + +#include "nrf_crypto.h" +#include "micro_ecc_lib_ecdh.h" +#include "micro_ecc_lib_keys.h" +#include "micro_ecc_lib_init.h" +#include "micro_ecc_lib_shared.h" + +#include "uECC.h" + + +static void swap_array_endian(uint8_t * p_in, uint32_t len, uint8_t * p_out) +{ + uint32_t i; + for(i = 0; i < len; i++) + { + p_out[len-i-1] = p_in[i]; + } +} + + +uint32_t nrf_crypto_ecdh_shared_secret_compute(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t const * p_private_key, + nrf_value_length_t const * p_public_key, + nrf_value_length_t * p_shared_secret) +{ + uint32_t ret_val; + uint32_t public_key_size; + uint32_t private_key_size; + uint32_t shared_secret_size; + const struct uECC_Curve_t * p_curve; + uint8_t shared_secret[NRF_CRYPTO_ECDH_SHARED_SECRET_MAX_SIZE]; + + // This function does not require initialized nrf_crypto for this backend. + + // Check private key + if (p_private_key == NULL || + p_public_key == NULL || + p_shared_secret == NULL ) + { + return NRF_ERROR_NULL; + } + + if (p_private_key->p_value == NULL || + p_public_key->p_value == NULL || + p_shared_secret->p_value == NULL ) + { + return NRF_ERROR_INVALID_ADDR; + } + + // Check type alignment + if (!is_word_aligned(p_private_key->p_value) || + !is_word_aligned(p_public_key->p_value) || + !is_word_aligned(p_shared_secret->p_value) ) + { + return NRF_ERROR_INVALID_ADDR; + } + + // Check public key size + ret_val = nrf_crypto_ecc_public_key_size_get(curve_info.curve_type, &public_key_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + if (public_key_size != p_public_key->length) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Check private key size + ret_val = nrf_crypto_ecc_private_key_size_get(curve_info.curve_type, &private_key_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + if (private_key_size != p_private_key->length) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Check shared secret size + ret_val = nrf_crypto_ecdh_shared_secret_size_get(curve_info.curve_type, &shared_secret_size); + if (ret_val != NRF_SUCCESS) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (shared_secret_size != p_shared_secret->length) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (!micro_ecc_curve_domain_get(curve_info.curve_type, &p_curve)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if (!uECC_shared_secret(p_public_key->p_value, + p_private_key->p_value, + shared_secret, + p_curve)) + { + return NRF_ERROR_INTERNAL; + } + + // Convert result to Little endian + if (curve_info.endian_type == NRF_CRYPTO_ENDIAN_LE) + { + memcpy(p_shared_secret->p_value, shared_secret, shared_secret_size); + } + else + { + swap_array_endian(shared_secret, shared_secret_size, p_shared_secret->p_value); + } + + + return NRF_SUCCESS; +} + +#endif // Supports RNG + +#endif // NRF_CRYPTO_BACKEND_MICRO_ECC + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_ecdh.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_ecdh.h new file mode 100644 index 0000000000000000000000000000000000000000..bb1be41dbc8cb0acf9947eab365e7e6a11161302 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_ecdh.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MICRO_ECC_ECDH_H__ +#define MICRO_ECC_ECDH_H__ + +#include +#include "nrf_crypto_ecdh.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + + +#endif // MICRO_ECC_ECDH_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_ecdsa.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_ecdsa.c new file mode 100644 index 0000000000000000000000000000000000000000..dbebb0714b7d4b6a9084a979ae0ab0fa159ab687 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_ecdsa.c @@ -0,0 +1,214 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#if defined(NRF_CRYPTO_BACKEND_MICRO_ECC) && (NRF_CRYPTO_BACKEND_MICRO_ECC == 1) + +#include "nrf_crypto_hash.h" +#include "nrf_crypto_ecdsa.h" +#include "nrf_crypto_types.h" +#include "micro_ecc_lib_ecdsa.h" +#include "micro_ecc_lib_keys.h" +#include "micro_ecc_lib_shared.h" +#include "nrf_log.h" + +#include "uECC.h" + +#if defined(NRF_CRYPTO_SUPPORTS_RNG) && NRF_CRYPTO_SUPPORTS_RNG == 1 + +uint32_t nrf_crypto_ecdsa_sign_hash(nrf_crypto_signature_info_t sig_info, + nrf_value_length_t const * p_private_key, + nrf_value_length_t const * p_hash, + nrf_value_length_t * p_signature) +{ + uint32_t ret_val; + nrf_crypto_ecdsa_sizes_t sig_sizes; + const struct uECC_Curve_t * p_curve = uECC_secp256r1(); + + // Parameter NULL testing. + if (p_private_key == NULL || + p_hash == NULL || + p_signature == NULL ) + { + return NRF_ERROR_NULL; + } + + if (p_private_key->p_value == NULL || + p_hash->p_value == NULL || + p_signature->p_value == NULL ) + { + return NRF_ERROR_INVALID_ADDR; + } + + // Ensure data is aligned + if (!is_word_aligned(p_private_key->p_value) || + !is_word_aligned(p_hash->p_value) || + !is_word_aligned(p_signature->p_value) ) + { + return NRF_ERROR_INVALID_ADDR; + } + + // Get the sizes for the keys, hash and signature + ret_val = nrf_crypto_ecdsa_sizes_get(sig_info, &sig_sizes); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + // Check the private key size. + if (p_private_key->length != sig_sizes.private_key_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Check if hash size. + if (p_hash->length != sig_sizes.hash_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Check the signature size. + if (p_signature->length != sig_sizes.signature_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Get the curve domain to use for signing + if (!micro_ecc_curve_domain_get(sig_info.curve_type, &p_curve)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + // Create a signature of the hash data. + if(uECC_sign(p_private_key->p_value, p_hash->p_value, p_hash->length, p_signature->p_value, p_curve)) + { + return NRF_ERROR_INTERNAL; + } + + return NRF_SUCCESS; +} + +#endif + +uint32_t nrf_crypto_ecdsa_verify_hash(nrf_crypto_signature_info_t sig_info, + nrf_value_length_t const * p_public_key, + nrf_value_length_t const * p_hash, + nrf_value_length_t const * p_signature) +{ + uint32_t ret_val; + nrf_crypto_ecdsa_sizes_t sig_sizes; + const struct uECC_Curve_t * p_curve = uECC_secp256r1(); + + // Parameter NULL testing + if (p_public_key == NULL || + p_hash == NULL || + p_signature == NULL ) + { + return NRF_ERROR_NULL; + } + + if (p_public_key->p_value == NULL || + p_hash->p_value == NULL || + p_signature->p_value == NULL ) + { + return NRF_ERROR_INVALID_ADDR; + } + + // Check alignment for data. + if (!is_word_aligned(p_public_key->p_value) || + !is_word_aligned(p_hash->p_value) || + !is_word_aligned(p_signature->p_value) ) + { + return NRF_ERROR_INVALID_ADDR; + } + + // Get the sizes for the keys, hash and signature + ret_val = nrf_crypto_ecdsa_sizes_get(sig_info, &sig_sizes); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + // Check the public key size. + if (p_public_key->length != sig_sizes.public_key_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Check the hash size. + if (p_hash->length != sig_sizes.hash_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Check the signature size. + if (p_signature->length != sig_sizes.signature_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Get the curve domain to use for verifying + #if 0 + // Optimizer in keil/gcc not able to optimize away other unused curves. + // Setting to only supported curve type. + if (!micro_ecc_curve_domain_get(sig_info.curve_type, &p_curve)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + #else + if (sig_info.curve_type != NRF_CRYPTO_CURVE_SECP256R1) + { + return NRF_ERROR_NOT_SUPPORTED; + } + #endif + + // Verify the signature by the hash + if (uECC_verify(p_public_key->p_value, p_hash->p_value, p_hash->length, p_signature->p_value, p_curve) == 0) + { + return NRF_ERROR_INVALID_DATA; + } + + return NRF_SUCCESS; +} + +#endif // NRF_CRYPTO_BACKEND_MICRO_ECC + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_ecdsa.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_ecdsa.h new file mode 100644 index 0000000000000000000000000000000000000000..7de66b699bf8a56943799bc4ec1bb4476ea10a03 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_ecdsa.h @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MICRO_ECC_ECDSA_H__ +#define MICRO_ECC_ECDSA_H__ + +/** @file + * + * @defgroup nrf_crypto_backend_micro_ecc_lib_ecdsa micro-ecc backend ECDSA types. + * @{ + * @ingroup nrf_crypto_backend_microecc + * + * @brief Provides types required for micro_ecc backend ECDSA. + */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Size of ECDSA signing context. + */ +#define NRF_CRYPTO_ECDSA_SIGN_CONTEXT_SIZE (0) + + +/** @brief Size of ECDSA verification context. + */ +#define NRF_CRYPTO_ECDSA_VERIFY_CONTEXT_SIZE (0) + + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // MICRO_ECC_ECDSA_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_init.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_init.c new file mode 100644 index 0000000000000000000000000000000000000000..68bbec3fb3022da0eb24cdc89e843e080aec2aa9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_init.c @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#if defined(NRF_CRYPTO_BACKEND_MICRO_ECC) && (NRF_CRYPTO_BACKEND_MICRO_ECC == 1) + +#include "micro_ecc_lib_init.h" +#include "nrf_crypto_rng.h" +#include "uECC.h" + +static bool g_is_initialized = false; + +uint32_t nrf_crypto_init(void) +{ + uint32_t ret_val = NRF_SUCCESS; + +#if defined(NRF_CRYPTO_SUPPORTS_RNG) && (NRF_CRYPTO_SUPPORTS_RNG == 1) + + ret_val = nrf_crypto_rng_init(); + +#endif + + if (ret_val == NRF_SUCCESS) + { + g_is_initialized = true; + } + else + { + g_is_initialized = false; + } + + return ret_val; +} + +uint32_t nrf_crypto_uninit(void) +{ + // Not possible in this nrf_crypto backend. + return NRF_SUCCESS; +} + +bool nrf_crypto_is_initialized(void) +{ + return g_is_initialized; +} + +#endif // NRF_CRYPTO_BACKEND_MICRO_ECC + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_init.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_init.h new file mode 100644 index 0000000000000000000000000000000000000000..537d04a93226e326025401dd1bf4c6732b599190 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_init.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MICRO_ECC_LIB_INIT_H__ +#define MICRO_ECC_LIB_INIT_H__ + +/** @file + * + * @defgroup nrf_crypto_backend_micro_ecc_lib_init micro-ecc backend initialization types. + * @{ + * @ingroup nrf_crypto_backend_microecc + * + * @brief Provides types required for CC310 backend initialization. + */ + +#include "nrf_crypto_init.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Size of buffer required to initalize nrf_crypto micro_ecc backend. + */ +#define NRF_CRYPTO_INIT_RAM_BUFFER (0) + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // MICRO_ECC_LIB_INIT_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_keys.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_keys.c new file mode 100644 index 0000000000000000000000000000000000000000..8f13aa064ba5b79957088334f4fd6b6ff7d3f330 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_keys.c @@ -0,0 +1,279 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#if defined(NRF_CRYPTO_BACKEND_MICRO_ECC) && (NRF_CRYPTO_BACKEND_MICRO_ECC == 1) + +#include "micro_ecc_lib_keys.h" +#include "micro_ecc_lib_shared.h" +#include "micro_ecc_lib_init.h" +#include "nrf_crypto_types.h" + +#include "uECC.h" + + +#if !defined(NRF_CRYPTO_BACKEND_SW) +#error Enable NRF_CRYPTO_BACKEND_SW in SDK config for key generation (required random number generator) +#endif + +#if defined(NRF_CRYPTO_SUPPORTS_RNG) && NRF_CRYPTO_SUPPORTS_RNG == 1 + +uint32_t nrf_crypto_ecc_key_pair_generate(nrf_crypto_curve_info_t curve_type, + nrf_value_length_t * p_private_key, + nrf_value_length_t * p_public_key) +{ + uint32_t ret_val; + uint32_t private_key_size; + uint32_t public_key_size; + const struct uECC_Curve_t * p_curve; + + if (!nrf_crypto_is_initialized()) + { + return NRF_ERROR_INVALID_STATE; + } + + if (p_private_key == NULL || + p_public_key == NULL) + { + return NRF_ERROR_NULL; + } + + if (p_private_key->p_value == NULL || + p_public_key->p_value == NULL ) + { + return NRF_ERROR_INVALID_ADDR; + } + + if (!is_word_aligned(p_private_key->p_value) || !is_word_aligned(p_public_key->p_value)) + { + return NRF_ERROR_INVALID_ADDR; + } + + ret_val = nrf_crypto_ecc_private_key_size_get(curve_type.curve_type, &private_key_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + if (p_private_key->length != private_key_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + ret_val = nrf_crypto_ecc_public_key_size_get(curve_type.curve_type, &public_key_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + if (p_public_key->length != public_key_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (!micro_ecc_curve_domain_get(curve_type.curve_type, &p_curve)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if (uECC_make_key(p_public_key->p_value, p_private_key->p_value, p_curve) == 0) + { + return NRF_ERROR_INTERNAL; + } + + return NRF_SUCCESS; +} + + + +uint32_t nrf_crypto_ecc_public_key_calculate(nrf_crypto_curve_info_t curve_type, + nrf_value_length_t const * p_private_key, + nrf_value_length_t * p_public_key) +{ + uint32_t ret_val; + uint32_t private_key_size; + uint32_t public_key_size; + const struct uECC_Curve_t * p_curve; + + // This function does not require initialized nrf_crypto backend library. + + if (p_private_key == NULL || p_public_key == NULL) + { + return NRF_ERROR_NULL; + } + + if (p_private_key->p_value == NULL || + p_public_key->p_value == NULL) + { + return NRF_ERROR_INVALID_ADDR; + } + + ret_val = nrf_crypto_ecc_private_key_size_get(curve_type.curve_type, &private_key_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + if (p_private_key->length != private_key_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + ret_val = nrf_crypto_ecc_public_key_size_get(curve_type.curve_type, &public_key_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + if (p_public_key->length != public_key_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (!is_word_aligned(p_private_key->p_value) || !is_word_aligned(p_public_key->p_value)) + { + return NRF_ERROR_INVALID_ADDR; + } + + if (!micro_ecc_curve_domain_get(curve_type.curve_type, &p_curve)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if (uECC_compute_public_key(p_private_key->p_value, p_public_key->p_value, p_curve) == 0) + { + return NRF_ERROR_INTERNAL; + } + + return NRF_SUCCESS; +} + +#endif + +uint32_t nrf_crypto_ecc_private_key_to_raw(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t const * p_private_key, + nrf_value_length_t * p_private_key_raw) +{ + uint32_t ret_val; + uint32_t private_key_size; + + if (p_private_key == NULL || p_private_key_raw == NULL) + { + return NRF_ERROR_NULL; + } + + if (p_private_key->p_value == NULL || + p_private_key_raw->p_value == NULL ) + { + return NRF_ERROR_INVALID_ADDR; + } + + ret_val = nrf_crypto_ecc_private_key_size_get(curve_info.curve_type, &private_key_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + if (p_private_key_raw->length != private_key_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (p_private_key->length != private_key_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Copy the private key directly. + memcpy(p_private_key_raw->p_value, p_private_key->p_value, private_key_size); + return NRF_SUCCESS; +} + +uint32_t nrf_crypto_ecc_public_key_to_raw(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t const * p_public_key, + nrf_value_length_t * p_raw_key) +{ + uint32_t ret_val; + uint32_t public_key_size; + + if (p_public_key == NULL || p_raw_key == NULL) + { + return NRF_ERROR_NULL; + } + + if (p_public_key->p_value == NULL || + p_raw_key->p_value == NULL ) + { + return NRF_ERROR_INVALID_ADDR; + } + + ret_val = nrf_crypto_ecc_public_key_size_get(curve_info.curve_type, &public_key_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + if (p_raw_key->length != public_key_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (p_public_key->length != public_key_size) + { + return NRF_ERROR_INVALID_LENGTH; + } + + memcpy(p_raw_key->p_value, p_public_key->p_value, p_raw_key->length); + return NRF_SUCCESS; +} + +uint32_t nrf_crypto_ecc_public_key_from_raw(nrf_crypto_curve_info_t curve_type, + nrf_value_length_t * p_public_key_raw, + nrf_value_length_t * p_public_key) +{ + // TODO: Parameter testing + memcpy(p_public_key->p_value, p_public_key_raw->p_value, p_public_key_raw->length); + return NRF_SUCCESS; +} + +#endif // NRF_CRYPTO_BACKEND_MICRO_ECC + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_keys.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_keys.h new file mode 100644 index 0000000000000000000000000000000000000000..3bcdb2eef22240e47091b22579900d77a962c204 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_keys.h @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MICRO_ECC_LIB_KEYS_H__ +#define MICRO_ECC_LIB_KEYS_H__ + +/** @file + * + * @defgroup nrf_crypto_backend_micro_ecc_lib_ecc_keys micro-ecc backend ECC key types. + * @{ + * @ingroup nrf_crypto_backend_microecc + * + * @brief Provides types required for CC310 backend ECC keys. + */ + +#include +#include "nrf_crypto_keys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // MICRO_ECC_LIB_KEYS_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_shared.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_shared.c new file mode 100644 index 0000000000000000000000000000000000000000..4f37ca9b7fc0518f776af7f1c64d33e521ba69a7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_shared.c @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#if defined(NRF_CRYPTO_BACKEND_MICRO_ECC) && (NRF_CRYPTO_BACKEND_MICRO_ECC == 1) + +#include "micro_ecc_lib_shared.h" +#include "nrf_crypto_types.h" +#include "uECC.h" + +bool micro_ecc_curve_domain_get(nrf_ecc_curve_type_t curve_type, struct uECC_Curve_t const ** p_curve) +{ + switch(curve_type) + { +#if defined(uECC_SUPPORTS_secp160r1) && uECC_SUPPORTS_secp160r1 == 1 + case NRF_CRYPTO_CURVE_SECP160R1: + *p_curve = uECC_secp160r1(); + break; +#endif + +#if defined(uECC_SUPPORTS_secp192r1) && uECC_SUPPORTS_secp192r1 == 1 + case NRF_CRYPTO_CURVE_SECP192R1: + *p_curve = uECC_secp192r1(); + break; +#endif + +#if defined(uECC_SUPPORTS_secp224r1) && uECC_SUPPORTS_secp224r1 == 1 + case NRF_CRYPTO_CURVE_SECP224R1: + *p_curve = uECC_secp224r1(); + break; + +#endif + + case NRF_CRYPTO_CURVE_SECP256R1: + *p_curve = uECC_secp256r1(); + break; + +#if defined(uECC_SUPPORTS_secp256k1) && defined(NRF_CRYPTO_CURVE_SECP256R1) +#if NRF_CRYPTO_CURVE_SECP256R1 == 1 + case NRF_CRYPTO_CURVE_SECP256K1: + *p_curve = uECC_secp256k1(); + break; +#endif +#endif + + default: + return false; + + } + + return true; +} + + +#endif // NRF_CRYPTO_BACKEND_MICRO_ECC + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_shared.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_shared.h new file mode 100644 index 0000000000000000000000000000000000000000..94daa3cd975ed7dfaf9daebc8864ba761cad0ce1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/micro_ecc/micro_ecc_lib_shared.h @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef MICRO_ECC_LIB_SHARED_H__ +#define MICRO_ECC_LIB_SHARED_H__ + +/** @file + * + * @defgroup nrf_crypto_backend_micro_ecc_lib_shared micro-ecc backend shared functions. + * @{ + * @ingroup nrf_crypto_backend_microecc + * + * @brief Provides shared functions required for micro_ecc backend. + */ + +#include +#include +#include "nrf_crypto_types.h" +#include "uECC.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function to get micro_ecc curve domain from curve_type + * + * @param[in] curve_type Curve type get domain for. + * @param[in] pp_domain Double pointer to curve domain structure. + * + * @retval True True if curve domain was successfully located. + */ +bool micro_ecc_curve_domain_get(nrf_ecc_curve_type_t curve_type, struct uECC_Curve_t const ** pp_domain); + + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // MICRO_ECC_LIB_SHARED_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/nrf_crypto_sw/nrf_crypto_sw_hash.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/nrf_crypto_sw/nrf_crypto_sw_hash.c new file mode 100644 index 0000000000000000000000000000000000000000..d66d3b3c34d64d435281337892de810f85596d3c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/nrf_crypto_sw/nrf_crypto_sw_hash.c @@ -0,0 +1,218 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#if defined(NRF_CRYPTO_BACKEND_MICRO_ECC) && (NRF_CRYPTO_BACKEND_MICRO_ECC == 1) + +#include "nrf_crypto_hash.h" +#include "nrf_crypto_mem.h" +#include "nrf_crypto_sw_hash.h" +#include "sha256.h" +#include "nrf_log.h" + +uint32_t nrf_crypto_hash_init(nrf_crypto_hash_info_t hash_info, + nrf_value_length_t * p_hash_context) +{ + uint32_t ret_val; + sha256_context_t * p_hash_context_user; + + if (p_hash_context == NULL) + { + return NRF_ERROR_NULL; + } + + if (p_hash_context->p_value == NULL) + { + return NRF_ERROR_INVALID_ADDR; + } + + if (p_hash_context->length < NRF_CRYPTO_HASH_CONTEXT_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Currently SHA256 is the only available hash algorithm + if(hash_info.hash_type != NRF_CRYPTO_HASH_TYPE_SHA256) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + p_hash_context_user = (sha256_context_t *)p_hash_context->p_value; + + ret_val = sha256_init(p_hash_context_user); + return ret_val; +} + +uint32_t nrf_crypto_hash_update(nrf_value_length_t * p_hash_context, + uint8_t const * p_data, + uint32_t len) +{ + uint32_t ret_val; + sha256_context_t * p_hash_context_user; + + if (p_hash_context == NULL || p_data == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + if (p_hash_context->length < NRF_CRYPTO_HASH_CONTEXT_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_hash_context_user = (sha256_context_t *)p_hash_context->p_value; + + ret_val = sha256_update(p_hash_context_user, p_data, len); + return ret_val; +} + + +uint32_t nrf_crypto_hash_finalize(nrf_crypto_hash_info_t hash_info, + nrf_value_length_t * p_hash_context, + nrf_value_length_t * p_hash) +{ + uint32_t ret_val; + sha256_context_t * p_hash_context_user; + uint8_t endian_type; + uint32_t hash_size; + + if (p_hash_context == NULL || p_hash == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Check hash context size + if (p_hash_context->length != NRF_CRYPTO_HASH_CONTEXT_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_hash_context_user = (sha256_context_t *)p_hash_context->p_value; + + // Check if hash is correct size + ret_val = nrf_crypto_hash_size_get(hash_info.hash_type, &hash_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + if (hash_size != p_hash->length) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (hash_info.endian_type == NRF_CRYPTO_ENDIAN_LE) + { + endian_type = 1; + } + else + { + endian_type = 0; + } + + ret_val = sha256_final(p_hash_context_user, p_hash->p_value, endian_type); + return ret_val; +} + + +uint32_t nrf_crypto_hash_compute(nrf_crypto_hash_info_t hash_info, + uint8_t const * p_data, + uint32_t len, + nrf_value_length_t * p_hash) +{ + uint32_t ret_val; + uint32_t hash_size; + sha256_context_t hash_context; + nrf_value_length_t hash_context_desc = + { + .p_value = (uint8_t*)&hash_context, + .length = sizeof(hash_context) + }; + + // Basic parameter testing. + if (p_hash == NULL || p_data == NULL) + { + return NRF_ERROR_NULL; + } + + if (p_hash->p_value == NULL) + { + return NRF_ERROR_INVALID_ADDR; + } + + // Currently SHA256 is the only available hash algorithm + if (hash_info.hash_type != NRF_CRYPTO_HASH_TYPE_SHA256) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + // Check if hash is correct size. + ret_val = nrf_crypto_hash_size_get(hash_info.hash_type, &hash_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + if (hash_size != p_hash->length) + { + return NRF_ERROR_INVALID_LENGTH; + } + + ret_val = nrf_crypto_hash_init(hash_info, &hash_context_desc); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + ret_val = nrf_crypto_hash_update(&hash_context_desc, p_data, len); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + ret_val = nrf_crypto_hash_finalize(hash_info, &hash_context_desc, p_hash); + return ret_val; +} + + +#endif // NRF_CRYPTO_BACKEND_SW + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/nrf_crypto_sw/nrf_crypto_sw_hash.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/nrf_crypto_sw/nrf_crypto_sw_hash.h new file mode 100644 index 0000000000000000000000000000000000000000..d82b729f890ae89bf2acd11a99ea29ed645b8205 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/nrf_crypto_sw/nrf_crypto_sw_hash.h @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CRYPTO_SW_HASH_H__ +#define NRF_CRYPTO_SW_HASH_H__ + +/** @file + * + * @defgroup nrf_crypto_sw_hash Software-based hashing using sha256 + * @{ + * @ingroup nrf_crypto_backend_microecc + * + * @brief Macros for type sizes in nrf_crypt SW backend. + */ + +#include +#include "nrf_crypto_types.h" +#include "sha256.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Size of buffer required for hash context object. + */ +#define NRF_CRYPTO_HASH_CONTEXT_SIZE sizeof(sha256_context_t) + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif // #ifndef NRF_CRYPTO_HASH_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/nrf_crypto_sw/nrf_crypto_sw_rng.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/nrf_crypto_sw/nrf_crypto_sw_rng.c new file mode 100644 index 0000000000000000000000000000000000000000..01f3587c2d029bb2f569238dc48d126677600a5a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/nrf_crypto_sw/nrf_crypto_sw_rng.c @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#include "nrf_drv_rng.h" +#include "nrf_crypto_rng.h" + +#if defined(NRF_CRYPTO_BACKEND_MICRO_ECC) && (NRF_CRYPTO_BACKEND_MICRO_ECC == 1) +#if defined(NRF_CRYPTO_SUPPORTS_RNG) && (NRF_CRYPTO_SUPPORTS_RNG == 1) + +#include "uECC.h" + +/** @brief Function to greate random data conformant to the format of the + * micro_ecc API. + */ +static int rng_func(uint8_t * p_target, unsigned size) +{ + uint32_t err_code; + err_code = nrf_crypto_rng_vector_generate(p_target, size); + if (err_code == NRF_SUCCESS) + { + return 1; + } + else + { + return 0; + } +} + + +uint32_t nrf_crypto_rng_init(void) +{ + uint32_t ret_val; + + ret_val = nrf_drv_rng_init(NULL); + if (ret_val == NRF_SUCCESS) + { + uECC_set_rng(rng_func); + } + + return ret_val; +} + + +uint32_t nrf_crypto_rng_vector_generate(uint8_t * p_target, uint32_t length) +{ + uint32_t err_code; + uint8_t available; + uint8_t cur_len; + uint8_t left = length; + + if (p_target == NULL) + { + return NRF_ERROR_NULL; + } + + do + { + nrf_drv_rng_bytes_available(&available); + cur_len = MIN(left, available); + + err_code = nrf_drv_rng_rand(p_target + (length - left), cur_len); + if(err_code != NRF_SUCCESS) + { + return err_code; + } + + // Remove current length of generated data + left -= cur_len; + + } while(left > 0); + + return NRF_SUCCESS; +} + +#endif // NRF_CRYPTO_SUPPORTS_RNG + +#endif // NRF_CRYPTO_BACKEND_MICRO_ECC + +#endif // NRF_CRYPTO_BACKEND_SW diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/nrf_crypto_sw/nrf_crypto_sw_rng.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/nrf_crypto_sw/nrf_crypto_sw_rng.h new file mode 100644 index 0000000000000000000000000000000000000000..8bba3796e0c9ed70d25e07e41ef8c277e589b598 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/backend/nrf_crypto_sw/nrf_crypto_sw_rng.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CRYPTO_SW_RNG_H__ +#define NRF_CRYPTO_SW_RNG_H__ + +/** @file + * + * @defgroup nrf_crypto_sw_rng Random Number Generation using nrf_drv_rng + * @{ + * @ingroup nrf_crypto_backend_microecc + * + * @brief Macros for type sizes for RNG in nrf_crypto backend. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Size of buffer required for initializing RNG. + */ +#define NRF_CRYPTO_RNG_INIT_SIZE (0) + +/** @brief Size of buffer required for RNG context object. + */ +#define NRF_CRYPTO_RNG_CONTEXT_SIZE (0) + + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif // #ifndef NRF_CRYPTO_SW_RNG_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto.c new file mode 100644 index 0000000000000000000000000000000000000000..d2cff179a72a2a0edc5682380f64ba9ae6e71fbd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto.c @@ -0,0 +1,158 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_error.h" +#include "sdk_common.h" +#include "ecc.h" +#include "sha256.h" +#include "nrf_crypto.h" + +uint32_t nrf_crypto_init(void) +{ + ecc_init(false); + + return NRF_SUCCESS; +} + + +uint32_t nrf_crypto_public_key_compute(uint32_t curve, + nrf_crypto_key_t const *p_sk, + nrf_crypto_key_t *p_pk) +{ + if(curve != NRF_CRYPTO_CURVE_SECP256R1) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if(p_sk->len != ECC_P256_SK_LEN || p_pk->len != ECC_P256_PK_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + + return ecc_p256_public_key_compute(p_sk->p_le_data, p_pk->p_le_data); +} + + +uint32_t nrf_crypto_shared_secret_compute(uint32_t curve, + nrf_crypto_key_t const *p_sk, + nrf_crypto_key_t const *p_pk, + nrf_crypto_key_t *p_ss) +{ + if(curve != NRF_CRYPTO_CURVE_SECP256R1) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if(p_sk->len != ECC_P256_SK_LEN || p_pk->len != ECC_P256_PK_LEN || p_ss->len != ECC_P256_SK_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + + return ecc_p256_shared_secret_compute(p_sk->p_le_data, p_pk->p_le_data, p_ss->p_le_data); +} + +uint32_t nrf_crypto_sign(uint32_t curve, + nrf_crypto_key_t const *p_sk, + nrf_crypto_key_t const *p_hash, + nrf_crypto_key_t *p_sig) +{ + if(curve != NRF_CRYPTO_CURVE_SECP256R1) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if(p_sk->len != ECC_P256_SK_LEN || p_sig->len != ECC_P256_PK_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + return ecc_p256_sign(p_sk->p_le_data, p_hash->p_le_data, p_hash->len, p_sig->p_le_data); +} + +uint32_t nrf_crypto_verify(uint32_t curve, + nrf_crypto_key_t const *p_pk, + nrf_crypto_key_t const *p_hash, + nrf_crypto_key_t const *p_sig) +{ + if(curve != NRF_CRYPTO_CURVE_SECP256R1) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if(p_pk->len != ECC_P256_PK_LEN || p_sig->len != ECC_P256_PK_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + + return ecc_p256_verify(p_pk->p_le_data, p_hash->p_le_data, p_hash->len, p_sig->p_le_data); +} + + +uint32_t nrf_crypto_hash_compute(uint32_t hash_alg, + uint8_t const *p_data, + uint32_t len, + nrf_crypto_key_t *p_hash) +{ + ret_code_t err_code; + sha256_context_t ctx; + + if(hash_alg != NRF_CRYPTO_HASH_ALG_SHA256) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if(p_hash->len != (256 >> 3)) + { + return NRF_ERROR_INVALID_LENGTH; + } + + err_code = sha256_init(&ctx); + VERIFY_SUCCESS(err_code); + + err_code = sha256_update(&ctx, p_data, len); + VERIFY_SUCCESS(err_code); + + err_code = sha256_final(&ctx, p_hash->p_le_data, 1); + VERIFY_SUCCESS(err_code); + + p_hash->len = (256 >> 3); + + return NRF_SUCCESS; +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto.h new file mode 100644 index 0000000000000000000000000000000000000000..60f192d802c276ee060dc9a26feccd5d73ef99c1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto.h @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CRYPTO_H__ +#define NRF_CRYPTO_H__ + +#include +#include "nrf_crypto_init.h" +#include "nrf_crypto_mem.h" +#include "nrf_crypto_keys.h" +#include "nrf_crypto_hash.h" +#include "nrf_crypto_ecdsa.h" +#include "nrf_crypto_ecdh.h" +#include "nrf_crypto_rng.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_crypto Cryptography library + * @ingroup app_common + * @{ + * + * @brief Cryptography library (nrf_crypto). + * + * @details The cryptography library provides functions to compute keys, shared secrets, and hashes, + * and to sign and verify data using digital signatures. + * @} + * + * @defgroup nrf_crypto_backends Backends + * @ingroup nrf_crypto + * @{ + * + * @brief Backends for the cryptography library. + * + * @details The cryptography library can be used with several backends that provide different functionality. + * @} + * + * @defgroup nrf_crypto_backend_cryptocell Hardware-accelerated backend (CryptoCell) + * @ingroup nrf_crypto_backends + * @{ + * + * @brief @tagAPI52840 Hardware-accelerated backend for the cryptography library based on CryptoCell (CC310). + * + * @details The CryptoCell backend is available on the nRF52840 SoC only, because it requires cryptography hardware. It uses the @ref cryptocell_api. + * @} + * + * @defgroup nrf_crypto_backend_microecc Software backend (micro-ecc) + * @ingroup nrf_crypto_backends + * @{ + * + * @brief Software backend for the cryptography library based on micro-ecc. + * + * @details The Software backend uses the external micro-ecc library. Make sure to install the library if you use this backend. See @ref lib_crypto_installing for details. + * + * @ref nrf_crypto_sw_hash "Hashing" and @ref nrf_crypto_sw_rng "random number generation" must be enabled separately. + * @} + * + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_CRYPTO_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_ecdh.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_ecdh.c new file mode 100644 index 0000000000000000000000000000000000000000..402f4c59dbd82f812d0be2321b48b6e28e4a51ef --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_ecdh.c @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#include "nrf_crypto_ecdh.h" +#include "nrf_crypto_mem.h" + +#if NRF_CRYPTO_BACKEND_MICRO_ECC +#include "micro_ecc_lib_ecdh.h" +#endif + +uint32_t nrf_crypto_ecdh_shared_secret_size_get(nrf_ecc_curve_type_t curve_type, + uint32_t * p_size) +{ + if(p_size == NULL) + { + return NRF_ERROR_NULL; + } + + switch(curve_type) + { + case NRF_CRYPTO_CURVE_SECP160R1: + (*p_size)= NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP160R1; + break; + + case NRF_CRYPTO_CURVE_SECP192R1: + (*p_size) = NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP192R1; + break; + + case NRF_CRYPTO_CURVE_SECP224R1: + (*p_size) = NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP224R1; + break; + + case NRF_CRYPTO_CURVE_SECP256R1: + (*p_size) = NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP256R1; + break; + + case NRF_CRYPTO_CURVE_SECP384R1: + (*p_size) = NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP384R1; + break; + + case NRF_CRYPTO_CURVE_SECP521R1: + (*p_size) = NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP521R1; + break; + + case NRF_CRYPTO_CURVE_SECP192K1: + (*p_size) = NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP192K1; + break; + + case NRF_CRYPTO_CURVE_SECP224K1: + (*p_size) = NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP224K1; + break; + + case NRF_CRYPTO_CURVE_SECP256K1: + (*p_size) = NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP256K1; + break; + + default: + (*p_size) = 0; + return NRF_ERROR_NOT_SUPPORTED; + } + + return NRF_SUCCESS; +} + + +uint32_t nrf_crypto_ecdh_shared_secret_allocate(nrf_crypto_curve_info_t curve_type, + nrf_value_length_t * p_shared_secret, + nrf_value_length_t const * p_raw_shared_secret) +{ + uint32_t ret_val; + uint32_t shared_secret_size; + + if (p_shared_secret == NULL) + { + return NRF_ERROR_NULL; + } + + ret_val = nrf_crypto_ecdh_shared_secret_size_get(curve_type.curve_type, &shared_secret_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + ret_val = nrf_crypto_mem_allocate(shared_secret_size, p_shared_secret); + if (ret_val == NRF_SUCCESS) + { + return ret_val; + } + + return ret_val; +} + + +uint32_t nrf_crypto_ecdh_shared_secret_free(nrf_value_length_t * p_shared_secret) +{ + uint32_t ret_val; + + if (p_shared_secret == NULL) + { + return NRF_ERROR_NULL; + } + + // Memory was already freed + if (p_shared_secret->length == 0) + { + return NRF_SUCCESS; + } + + ret_val = nrf_crypto_mem_free(p_shared_secret); + return ret_val; +} + + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_ecdh.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_ecdh.h new file mode 100644 index 0000000000000000000000000000000000000000..7d39fa72a8390bd22c1ad98ab5f10bdec0108336 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_ecdh.h @@ -0,0 +1,186 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CRYPTO_ECDH_H__ +#define NRF_CRYPTO_ECDH_H__ + +/** @file + * + * @defgroup nrf_crypto_ecdh ECDH related functions + * @{ + * @ingroup nrf_crypto + * + * @brief Provides ECDH related functionality through nrf_crypto. + */ + +#include +#include "nrf_crypto_types.h" + +#ifdef __cplusplus +extern "C" { +#if 0 +} +#endif +#endif + + +/** @brief Macro to create an instance of a ECDH shared secret with a given name. + * + * @note This creates the value length structure used for nrf_crypto APIs and a + * buffer to hold the shared secret without using dynamically allocated memory. + * + * @param[in] name Name of the variable to hold an ECDH shared secret. + * @param[in] type Either SECP160R1, SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1. + */ +#define NRF_CRYPTO_ECDH_SHARED_SECRET_INSTANCE_CREATE(name, type) \ +__ALIGN(4) static uint8_t \ + name ## _backing[STRING_CONCATENATE(NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_, type)]; \ +static nrf_value_length_t name = \ +{ \ + .p_value = name ## _backing, \ + .length = STRING_CONCATENATE(NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_, type) \ +} + + +/** @brief Macro to create an instance of a ECDH shared secret with a given name, type and input. + * + * If the input is not of the correct size a static assert will be occur compile-time. + * + * @note This creates the value length structure used for nrf_crypto APIs and a + * buffer to hold the shared secret without using dynamically allocated memory. + * + * @param[in] name Name of the variable to hold an ECDH shared secret. + * @param[in] type Either SECP160R1, SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1. + * @param[in] input Input must be an array of correct size according to the curve type. + */ +#define NRF_CRYPTO_ECDH_SHARED_SECRET_CREATE_FROM_ARRAY(name, type, input) \ +STATIC_ASSERT(sizeof(input) == STRING_CONCATENATE(NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_, type)); \ +static nrf_value_length_t name = \ +{ \ + .p_value = input, \ + .length = STRING_CONCATENATE(NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_, type) \ +} + + +/**@brief Function to get the shared secret size given curve type. + * + * @param[in] curve_type Elliptic curve to use. + * @param[in,out] p_size Pointer to variable to hold size of shared secret. + * + * @retval NRF_SUCCESS Shared secret size was calculated. + * @retval NRF_ERROR_NOT_SUPPORTED Selected curve was not supported. + */ +uint32_t nrf_crypto_ecdh_shared_secret_size_get(nrf_ecc_curve_type_t curve_type, + uint32_t * p_size); + + +/**@brief Function to allocate dynamic memory for ECDH shared secret. + * + * @param[in] curve_type Elliptic curve to use. + * @param[in,out] p_shared_secret Pointer to structure to hold a shared secret. + * @param[in] p_raw_shared_secret Pointer to structure holding a raw representation + * of a shared secret. If this is not NULL, the value + * will be copied to the allocated memory. + * + * @retval NRF_SUCCESS Memory for the public key was successfully allocated. + @retval NRF_ERROR_NULL If any of the parameters was NULL. + * @retval Any other error code reported by the memory manager. + */ +uint32_t nrf_crypto_ecdh_shared_secret_allocate(nrf_crypto_curve_info_t curve_type, + nrf_value_length_t * p_shared_secret, + nrf_value_length_t const * p_raw_shared_secret); + + +/**@brief Function to free allocated memory for ECDH shared secret. + * + * @param[in] p_shared_secret + * + * @retval NRF_SUCCESS Memory for the ECDH shared secret was successfully freed. + * @retval Any other error code reported by the memory manager. + */ +uint32_t nrf_crypto_ecdh_shared_secret_free(nrf_value_length_t * p_shared_secret); + + +/**@brief Function for computing a shared secret from a key pair. + * + * @note Length of allocated buffers for private key, public key and + * shared secret is taken as input. + * + * @param[in] curve_info Elliptic curve to use, and requested endianness of @p p_shared_secret. + * @param[in] p_private_key Pointer to structure holding private key. + * @param[in] p_public_key Pointer to structure holding public key. + * @param[in,out] p_shared_secret Pointer to structure to hold the calculated shared secret. + * After the call the length variable will be updated to the + * actual length of the shared secret data + * + * @retval NRF_SUCCESS If the shared secret was computed successfully. + * @retval NRF_ERROR_INVALID_STATE If the function was called when nrf_crypto was uninitialized. + * @retval NRF_ERROR_NULL If the provided key, hash or signature parameters was NULL. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected elliptic curve is not supported. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers are invalid. + * @retval NRF_ERROR_INVALID_DATA If any of the keys or result data is deemed invalid by the + * nrf_crypto backend. + * @retval NRF_ERROR_INVALID_LENGTH If the length of allocated data for keys or result is + * incorrect. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypto backend. + */ +uint32_t nrf_crypto_ecdh_shared_secret_compute(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t const * p_private_key, + nrf_value_length_t const * p_public_key, + nrf_value_length_t * p_shared_secret); + + +/**@brief Macro to express curve information for Bluetooth LE Secure Connection (LESC) + */ +#define NRF_CRYPTO_BLE_ECDH_CURVE_INFO (nrf_crypto_curve_info_t) \ +{ \ + .curve_type = NRF_CRYPTO_CURVE_SECP256R1, \ + .endian_type = NRF_CRYPTO_ENDIAN_LE \ +} + + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // #ifndef NRF_CRYPTO_ECDH_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_ecdsa.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_ecdsa.c new file mode 100644 index 0000000000000000000000000000000000000000..f4a8402395a4a180b473953bb37c3e9f91fd65a1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_ecdsa.c @@ -0,0 +1,227 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#include "nrf_crypto_ecdsa.h" +#include "nrf_crypto_hash.h" +#include "nrf_crypto_mem.h" + +#if NRF_CRYPTO_BACKEND_CC310_LIB +#include "cc310_lib_ecdsa.h" +#endif + +#if NRF_CRYPTO_BACKEND_MICRO_ECC +#include "micro_ecc_lib_ecdsa.h" +#endif + + +uint32_t nrf_crypto_ecdsa_signature_size_get(nrf_ecc_curve_type_t curve_type, uint32_t * p_sig_size) +{ + switch(curve_type) + { + case NRF_CRYPTO_CURVE_SECP160R1: + (*p_sig_size)= NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP160R1; + break; + + case NRF_CRYPTO_CURVE_SECP192R1: + (*p_sig_size) = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP192R1; + break; + + case NRF_CRYPTO_CURVE_SECP224R1: + (*p_sig_size) = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP224R1; + break; + + case NRF_CRYPTO_CURVE_SECP256R1: + (*p_sig_size) = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP256R1; + break; + + case NRF_CRYPTO_CURVE_SECP384R1: + (*p_sig_size) = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP384R1; + break; + + case NRF_CRYPTO_CURVE_SECP521R1: + (*p_sig_size) = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP521R1; + break; + + case NRF_CRYPTO_CURVE_SECP192K1: + (*p_sig_size) = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP192K1; + break; + + case NRF_CRYPTO_CURVE_SECP224K1: + (*p_sig_size) = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP224K1; + break; + + case NRF_CRYPTO_CURVE_SECP256K1: + (*p_sig_size) = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP256K1; + break; + + case NRF_CRYPTO_CURVE_CURVE25519: + // Not supported. Use Ed25519 instead of ECDSA. + (*p_sig_size) = 0; + return NRF_ERROR_NOT_SUPPORTED; + + default: + (*p_sig_size) = 0; + return NRF_ERROR_NOT_SUPPORTED; + } + + return NRF_SUCCESS; +} + + +uint32_t nrf_crypto_ecdsa_sizes_get(nrf_crypto_signature_info_t sig_info, + nrf_crypto_ecdsa_sizes_t * p_sizes) +{ + uint32_t ret_val; + + switch(sig_info.curve_type) + { + case NRF_CRYPTO_CURVE_SECP160R1: + p_sizes->private_key_size = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP160R1; + p_sizes->public_key_size = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP160R1; + p_sizes->signature_size = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP160R1; + break; + + case NRF_CRYPTO_CURVE_SECP192R1: + p_sizes->private_key_size = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP192R1; + p_sizes->public_key_size = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP192R1; + p_sizes->signature_size = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP192R1; + break; + + case NRF_CRYPTO_CURVE_SECP224R1: + p_sizes->private_key_size = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP224R1; + p_sizes->public_key_size = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP224R1; + p_sizes->signature_size = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP224R1; + break; + + case NRF_CRYPTO_CURVE_SECP256R1: + p_sizes->private_key_size = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP256R1; + p_sizes->public_key_size = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP256R1; + p_sizes->signature_size = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP256R1; + break; + + case NRF_CRYPTO_CURVE_SECP384R1: + p_sizes->private_key_size = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP384R1; + p_sizes->public_key_size = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP384R1; + p_sizes->signature_size = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP384R1; + break; + + case NRF_CRYPTO_CURVE_SECP521R1: + p_sizes->private_key_size = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP521R1; + p_sizes->public_key_size = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP521R1; + p_sizes->signature_size = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP521R1; + break; + + case NRF_CRYPTO_CURVE_SECP192K1: + p_sizes->private_key_size = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP192K1; + p_sizes->public_key_size = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP192K1; + p_sizes->signature_size = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP192K1; + break; + + case NRF_CRYPTO_CURVE_SECP224K1: + p_sizes->private_key_size = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP224K1; + p_sizes->public_key_size = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP224K1; + p_sizes->signature_size = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP224K1; + break; + + case NRF_CRYPTO_CURVE_SECP256K1: + p_sizes->private_key_size = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP256K1; + p_sizes->public_key_size = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP256K1; + p_sizes->signature_size = NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP256K1; + break; + + case NRF_CRYPTO_CURVE_CURVE25519: + // Not supported. Use Ed25519 (EDDSA) instead of ECDSA. + p_sizes->private_key_size = 0; + p_sizes->public_key_size = 0; + p_sizes->signature_size = 0; + return NRF_ERROR_NOT_SUPPORTED; + + default: + p_sizes->private_key_size = 0; + p_sizes->public_key_size = 0; + p_sizes->signature_size = 0; + return NRF_ERROR_NOT_SUPPORTED; + } + + ret_val = nrf_crypto_hash_size_get(sig_info.hash_type, &p_sizes->hash_size); + return ret_val; +} + + +uint32_t nrf_crypto_ecdsa_signature_allocate(nrf_crypto_signature_info_t sig_info, + nrf_value_length_t * p_signature, + nrf_value_length_t const * p_raw_signature) +{ + uint32_t ret_val; + uint32_t sig_size; + + if (p_signature == NULL) + { + return NRF_ERROR_NULL; + } + + ret_val = nrf_crypto_ecdsa_signature_size_get(sig_info.curve_type, &sig_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + ret_val = nrf_crypto_mem_allocate(sig_size, p_signature); + return ret_val; +} + + +uint32_t nrf_crypto_ecdsa_signature_free(nrf_value_length_t * p_signature) +{ + uint32_t ret_val; + + if (p_signature == NULL) + { + return NRF_ERROR_NULL; + } + + ret_val = nrf_crypto_mem_free(p_signature); + return ret_val; +} + + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_ecdsa.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_ecdsa.h new file mode 100644 index 0000000000000000000000000000000000000000..eefea5e4ac9c5ce34500f1c4a8073bd0cff26aed --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_ecdsa.h @@ -0,0 +1,254 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CRYPTO_ECDSA_H__ +#define NRF_CRYPTO_ECDSA_H__ + +/** @file + * + * @defgroup nrf_crypto_ecdsa ECDSA related functions + * @{ + * @ingroup nrf_crypto + * + * @brief Provides ECDSA related functionality through nrf_crypto. + */ + +#include +#include "nrf_crypto_types.h" + +#ifdef __cplusplus +extern "C" { +#if 0 +} +#endif +#endif + + +/** @brief Macro to create an instance of a ECDSA sign context by a given name. + * + * @note This creates the value length structure used for nrf_crypto APIs and a + * buffer to hold the sign context without using dynamically allocated memory. + */ +#define NRF_CRYPTO_ECDSA_SIGN_CONTEXT_INSTANCE_CREATE(name) \ +static uint8_t name ## _buffer[NRF_CRYPTO_ECDSASIGN_CONTEXT_SIZE]; \ +static nrf_value_length_t name = \ +{ \ + .p_value = name ## _buffer, \ + .length = NRF_CRYPTO_SIGN_CONTEXT_SIZE \ +} + + +/** @brief Macro to create an instance of a ECDSA verify context by a given name. + * + * @note This creates the value length structure used for nrf_crypto APIs and a + * buffer to hold the verify context without using dynamically allocated memory. + */ +#define NRF_CRYPTO_VERIFY_CONTEXT_INSTANCE_CREATE(name) \ +static uint8_t name ## _buffer[NRF_CRYPTO_ECDSA_VERIFY_CONTEXT_SIZE]; \ +static nrf_value_length_t name = \ +{ \ + .p_value = name ## _buffer, \ + .length = NRF_CRYPTO_ECDSA_VERIFY_CONTEXT_SIZE \ +} + + +/** @brief Macro to create an instance of an ECDSA signature by a given name and type. + * + * @param[in] name Name of the ECDSA signature instance. + * @param[in] type Either SECP160R1, SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1 + * + * @note This creates the value length structure used for nrf_crypto APIs and a + * buffer to hold the signature without using dynamically allocated memory. + */ +#define NRF_CRYPTO_ECDSA_SIGNATURE_CREATE(name, type) \ +static uint8_t name ## _buffer[STRING_CONCATENATE(NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_, type)]; \ +static nrf_value_length_t name = \ +{ \ + .p_value = name ## _buffer, \ + .length = STRING_CONCATENATE(NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_, type) \ +} + + +/** @brief Macro to create an instance of an ECDSA signature by a given name, type and input. + * + * If the input is not of the correct size a static assert will be occur compile-time. + * + * @note This creates the value length structure used for nrf_crypto APIs and a + * buffer to hold the signature without using dynamically allocated memory. + * + * @param[in] name Name of the ECDSA signature instance. + * @param[in] type Either SECP160R1, SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1 + * @param[in] input Input must be an array of correct size according to the curve type. + * + */ +#define NRF_CRYPTO_ECDSA_SIGNATURE_INSTANCE_CREATE_FROM_INPUT(name, type, input) \ +STATIC_ASSERT(sizeof(input) == STRING_CONCATENATE(NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_, type)); \ +static nrf_value_length_t name = \ +{ \ + .p_value = name ## _buffer, \ + .length = STRING_CONCATENATE(NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_, type) \ +} + + +/**@brief Function to get the size of a ECDSA signature given curve type. + * + * @param[in] curve_type Elliptic curve to use. + * @param[in] p_sig_size Pointer to variable to hold size of a signature. + * + * @retval NRF_SUCCESS If the he signature size was calculated. + * @retval NRF_ERROR_NULL If p_sizes was NULL. + * @retval NRF_ERROR_NOT_SUPPORTED Selected curve was not supported. + */ +uint32_t nrf_crypto_ecdsa_signature_size_get(nrf_ecc_curve_type_t curve_type, uint32_t * p_sig_size); + + +/**@brief Function to get the sizes used for ECDSA sign/verify given curve_type + * + * @details This function will report back the private/public key, signature and hash sizes. + * + * @param[in] sig_info Elliptic curve and hash to use. + * @param[in] p_sizes Pointer to variable to hold the key, hash and signature sizes. + * + * @retval NRF_SUCCESS If the ECDSA sizes was calculated. + * @retval NRF_ERROR_NULL If p_sizes was NULL. + * @retval NRF_ERROR_NOT_SUPPORTED Selected curve or hash was not supported. + */ +uint32_t nrf_crypto_ecdsa_sizes_get(nrf_crypto_signature_info_t sig_info, + nrf_crypto_ecdsa_sizes_t * p_sizes); + + +/**@brief Function to allocate dynamic memory for holding a signature + * + * @note The signature must be allocated before calling this + * function. + * + * @note If p_raw_signature is not NULL, then the content will be copied to the + * allocated buffer. + * + * @param[in] sig_info Curve and hash function used for representing a signature + * @param[in,out] p_signature Pointer to value-length structure to hold the signature. + * @param[in] p_raw_signature Pointer to byte representation of raw key given curve type. + * + * @retval NRF_SUCCESS Memory for the signature was successfully allocated. + * @retval NRF_ERROR_NULL Signature parameter was NULL. + * @retval Any other error code reported by the memory manager. + */ +uint32_t nrf_crypto_ecdsa_signature_allocate(nrf_crypto_signature_info_t sig_info, + nrf_value_length_t * p_signature, + nrf_value_length_t const * p_raw_signature); + + +/**@brief Function to free dynamic memory allocated for holding a signature + * + * @param[in,out] p_signature Pointer to value-length structure that holds the + * allocated space to be freed. + * + * @retval NRF_SUCCESS Memory for the signature was successfully allocated. + * @retval NRF_ERROR_NULL Signature parameter was NULL. + * @retval Any other error code reported by the memory manager. + */ +uint32_t nrf_crypto_ecdsa_signature_free(nrf_value_length_t * p_signature); + + +/**@brief Function for signing a hash using a private key. + * + * @note Key sizes and signature must be allocated before calling this + * function. + * + * @param[in] sig_info Elliptic curve to use for signing and endianness + * of the resulting signature. + * @param[in] p_private_key Pointer to structure holding private key. + * @param[in] p_hash Pointer to structure holding hash to use for signing. + * @param[in,out] p_signature Pointer to structure holding signature. + * + * @retval NRF_SUCCESS If the signature was created successfully. + * @retval NRF_ERROR_INVALID_STATE If the function was called when nrf_crypto was + * uninitialized. + * @retval NRF_ERROR_NULL If the provided key, hash or signature parameters was NULL. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected curve or hash type is not supported. + * @retval NRF_ERROR_INVALID_ADDR If the key, hash or signature paramenters aren't aligned. + * @retval NRF_ERROR_INVALID_LENGTH If the allocated length of the provided private key or hash + * is invalid or the signature is bigger than the size of the + * provided buffer. + * @retval NRF_ERROR_INVALID_DATA If any of the keys or result data is deemed invalid by the + * nrf_crypto backend. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypto backend. + */ +uint32_t nrf_crypto_ecdsa_sign_hash(nrf_crypto_signature_info_t sig_info, + nrf_value_length_t const * p_private_key, + nrf_value_length_t const * p_hash, + nrf_value_length_t * p_signature); + + +/**@brief Function for verifying a hash using a public key. + * + * @note Key sizes and signature must be allocated before calling this + * function. + * + * @param[in] sig_info Elliptic curve to use for verification and endianness + * of the signature given as input. + * @param[in] p_public_key Pointer to structure holding public key. + * @param[in] p_hash Pointer to structure holding hash to use for verification. + * @param[in,out] p_signature Pointer to structure holding signature. + * + * @retval NRF_SUCCESS If the signature was verified and is valid. + * @retval NRF_ERROR_INVALID_DATA If the signature did not match the provided hash. + * @retval NRF_ERROR_INVALID_ADDR If the key, hash or signature data aren't aligned. + * @retval NRF_ERROR_INVALID_STATE If the function was called when nrf_crypto was uninitialized. + * @retval NRF_ERROR_NULL If the provided key, hash or signature parameters was NULL. + * @retval NRF_ERROR_INVALID_LENGTH If the length of the provided public key, hash, or signature + * is invalid. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected curve or hash type is not supported. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers is invalid. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypto backend. + */ +uint32_t nrf_crypto_ecdsa_verify_hash(nrf_crypto_signature_info_t sig_info, + nrf_value_length_t const * p_public_key, + nrf_value_length_t const * p_hash, + nrf_value_length_t const * p_signature); + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // #ifndef NRF_CRYPTO_ECDSA_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_hash.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_hash.c new file mode 100644 index 0000000000000000000000000000000000000000..7f29fd28a8434052cddcdd637d3e1aaa5d6cd455 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_hash.c @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#include "nrf_crypto_hash.h" +#include "nrf_crypto_mem.h" + +#if NRF_CRYPTO_BACKEND_CC310_LIB +#include "cc310_lib_hash.h" +#endif + +#if NRF_CRYPTO_BACKEND_SW +#include "nrf_crypto_sw_hash.h" +#endif + +uint32_t nrf_crypto_hash_size_get(nrf_hash_type_t hash_type, uint32_t * p_hash_size) +{ + switch(hash_type) + { + case NRF_CRYPTO_HASH_TYPE_MD5: + (*p_hash_size) = NRF_CRYPTO_HASH_SIZE_MD5; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA1: + (*p_hash_size) = NRF_CRYPTO_HASH_SIZE_SHA1; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA224: + (*p_hash_size) = NRF_CRYPTO_HASH_SIZE_SHA224; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA256: + (*p_hash_size) = NRF_CRYPTO_HASH_SIZE_SHA256; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA384: + (*p_hash_size) = NRF_CRYPTO_HASH_SIZE_SHA384; + break; + + case NRF_CRYPTO_HASH_TYPE_SHA512: + (*p_hash_size) = NRF_CRYPTO_HASH_SIZE_SHA512; + break; + + default: + return NRF_ERROR_NOT_SUPPORTED; + } + + return NRF_SUCCESS; +} + + +uint32_t nrf_crypto_hash_context_allocate(nrf_crypto_hash_info_t hash_info, + nrf_value_length_t * p_hash_context) +{ + uint32_t ret_val; + uint32_t hash_context_size = NRF_CRYPTO_HASH_CONTEXT_SIZE; + + if (p_hash_context == NULL) + { + return NRF_ERROR_NULL; + } + + ret_val = nrf_crypto_mem_allocate(hash_context_size, p_hash_context); + return ret_val; +} + + +uint32_t nrf_crypto_hash_context_free(nrf_value_length_t * p_hash_context) +{ + uint32_t ret_val; + + if (p_hash_context == NULL) + { + return NRF_ERROR_NULL; + } + + ret_val = nrf_crypto_mem_free(p_hash_context); + return ret_val; +} + + +uint32_t nrf_crypto_hash_allocate(nrf_crypto_hash_info_t hash_info, + nrf_value_length_t * p_hash, + nrf_value_length_t const * p_raw_hash) +{ + uint32_t ret_val; + uint32_t hash_size; + + if (p_hash == NULL) + { + return NRF_ERROR_NULL; + } + + ret_val = nrf_crypto_hash_size_get(hash_info.hash_type, &hash_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + ret_val = nrf_crypto_mem_allocate(hash_size, p_hash); + if (ret_val == NRF_SUCCESS) + { + return ret_val; + } + + return ret_val; + +} + + +uint32_t nrf_crypto_hash_free(nrf_value_length_t * p_hash) +{ + uint32_t ret_val; + + if (p_hash == NULL) + { + return NRF_ERROR_NULL; + } + + ret_val = nrf_crypto_mem_free(p_hash); + return ret_val; +} + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_hash.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_hash.h new file mode 100644 index 0000000000000000000000000000000000000000..77c6809ce2277dc6ec46d41214da1b4a69cf1065 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_hash.h @@ -0,0 +1,303 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CRYPTO_HASH_H__ +#define NRF_CRYPTO_HASH_H__ + +/** @file + * + * @defgroup nrf_crypto_hash Cryptographic hash related functions. + * @{ + * @ingroup nrf_crypto + * + * @brief Provides cryptographic hash related functionality through nrf_crypto. + */ + +#include +#include "nrf_crypto_types.h" +#include "app_util.h" + +#ifdef __cplusplus +extern "C" { +#if 0 +} +#endif +#endif + + +/** @brief Internal macro to get the size of a given hash type + * + * @param[in] type Either MD5, SHA0, SHA1, SHA224, SHA256, SHA384 or SHA512 + */ +#define NRF_CRYPTO_HASH_SIZE(type) \ + STRING_CONCATENATE(NRF_CRYPTO_HASH_SIZE_, type) + + +/** @brief Macro to create an instance of a hash context by a given name and type. + * + * @note This creates the value length structure and + * a backing buffer without using dynamically allocated memory. + */ +#define NRF_CRYPTO_HASH_CONTEXT_CREATE(name, type) \ +__ALIGN(4) static uint8_t name ## _buffer[NRF_CRYPTO_HASH_CONTEXT_MAX_SIZE]; \ +static nrf_value_length_t name = \ +{ \ + .p_value = name ## _buffer, \ + .length = NRF_CRYPTO_HASH_CONTEXT_MAX_SIZE \ +} + + +/** @brief Macro to create an instance of a hash by a given name and type. + * + * @param[in] name Name of the hash instance. + * @param[in] type Either MD5, SHA0, SHA1, SHA224, SHA256, SHA384 or SHA512. + * + * @note This creates the value length structure and a backing + * buffer without using dynamically allocated memory. + */ +#define NRF_CRYPTO_HASH_CREATE(name, type) \ +__ALIGN(4) static uint8_t name ## _buffer[NRF_CRYPTO_HASH_SIZE(type)]; \ +static nrf_value_length_t name = \ +{ \ + .p_value = name ## _buffer, \ + .length = NRF_CRYPTO_HASH_SIZE(type) \ +} + + +/** @brief Macro to create an instance of a hash by a given name and type and + * input buffer. + * + * If the input is not of the correct size a static assert will be occur compile-time. + * + * @param[in] name Name of the hash instance. + * @param[in] type Either MD5, SHA0, SHA1, SHA224, SHA256, SHA384 or SHA512. + * @param[in] input Array used as input buffer. + * + * @note This creates the value length structure and a backing + * buffer without using dynamically allocated memory. + */ +#define NRF_CRYPTO_HASH_CREATE_FROM_ARRAY(name, type, input) \ +STATIC_ASSERT(sizeof(input) == NRF_CRYPTO_HASH_SIZE(type)) \ +static nrf_value_length_t name = \ +{ \ + .p_value = (uint8_t*) input, \ + .length = NRF_CRYPTO_HASH_SIZE(type) \ +} + + +/**@brief Function to get the size of a given hash type + * + * @param[in] hash_type Type of hash. + * @param[in,out] p_hash_size Pointer to variable to hold the hash size. Must not be NULL. + * + * @retval NRF_SUCCESS Hash function found. + * @retval NRF_ERROR_NULL p_hash_size was NULL. + * @retval NRF_ERROR_NOT_SUPPORTED Requested hash type isn't supported. + */ +uint32_t nrf_crypto_hash_size_get(nrf_hash_type_t hash_type, uint32_t * p_hash_size); + + +/**@brief Function to dynamically allocate memory to hold a hash context used + * when calculating hash as a non-integrated step. + * + * @param[in] hash_info Hashing algorithm to create context for + * @param[in,out] p_hash_context Pointer to value-length structure to hold allocated space. + * + * @retval NRF_SUCCESS Space was successfully allocated. + */ +uint32_t nrf_crypto_hash_context_allocate(nrf_crypto_hash_info_t hash_info, + nrf_value_length_t * p_hash_context); + + +/**@brief Function to free dynamically allocated memory for hash context + * used when calculating hash as a non-integrated step. + * + * @note The length value of the value length structure will be set to + * zero when the memory is freed. There is no impact of running this + * function on already deallocated memory. + * + * @param[in,out] p_hash_context Pointer a to value-length structure that holds the allocated space + * to be freed. + * @retval NRF_SUCCESS Space was successfully freed. + */ +uint32_t nrf_crypto_hash_context_free(nrf_value_length_t * p_hash_context); + + +/**@brief Function to dynamically allocate memory to hold a hash value. + * + * @param[in] hash_info Structure holding info about hash algorithm to use and + * endianness for the computed hash. + * @param[in,out] p_hash Pointer to value-length structure to hold allocated space. + * @param[in] p_raw_hash Pointer to value length structure to hold raw representation + * of hash. + * + * @retval NRF_SUCCESS Space was successfully alloacted. + */ +uint32_t nrf_crypto_hash_allocate(nrf_crypto_hash_info_t hash_info, + nrf_value_length_t * p_hash, + nrf_value_length_t const * p_raw_hash); + + +/** @brief Function to free dynamically allocated memory for a hash value. + * + * @note The length value of the value length structure will be set to + * zero when the memory is freed. There is no impact of running this + * function on already deallocated memory. + * + * @param[in,out] p_hash Pointer to a value-length structure that holds the + * allocated space to be freed. + * + * @retval NRF_SUCCESS Space was successfully freed. + */ +uint32_t nrf_crypto_hash_free(nrf_value_length_t * p_hash); + + +/**@brief Function for computing a hash from arbitrary data. + * + * @note The context object is assumed to be an opaque type defined by the + * nrf_crypto backend. See @ref NRF_CRYPTO_HASH_CONTEXT_SIZE for the relevant + * nrf_crypto backend. + * + * @param[in] hash_info Structure holding info about hash algorithm to use and + * endianness for the computed hash. + * @param[in,out] p_hash_context Pointer to structure holding context information for + * the hash computation. + * + * @retval NRF_SUCCESS If the hash initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the function was called when nrf_crypto was + * uninitialized. + * @retval NRF_ERROR_NULL If the hash context parameter was NULL. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected hash algorithm is not supported. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers are invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the hash is bigger than the size of the provided buffer. + * @retval NRF_ERROR_INVALID_DATA If the hash context was deemed invalid by the nrf_crypto + * backend. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypto backend. + */ +uint32_t nrf_crypto_hash_init(nrf_crypto_hash_info_t hash_info, + nrf_value_length_t * p_hash_context); + + +/**@brief Function for computing a hash or a digest from arbitrary data. + * + * @note The context object is assumed to be an opaque type defined by the + * nrf_crypto backend. See @ref NRF_CRYPTO_HASH_CONTEXT_SIZE for the relevant + * nrf_crypto backend. + * + * @param[in,out] p_hash_context Pointer to structure holding context information for + * the hash computation. + * @param[in] p_data Pointer to data to be hashed. + * @param[in] len Length of the data to be hashed. + * + * @retval NRF_SUCCESS If the hash was computed successfully. + * @retval NRF_ERROR_NULL If the hash context parameter was NULL. + * @retval NRF_ERROR_INVALID_STATE If the function was called when nrf_crypto was + * uninitialized. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected hash algorithm is not supported. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers are invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the size of the hash context is invalid. + * @retval NRF_ERROR_INVALID_DATA If the hash context was deemed invalid by the nrf_crypto + * backend. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypto backend. + */ +uint32_t nrf_crypto_hash_update(nrf_value_length_t * p_hash_context, + uint8_t const * p_data, + uint32_t len); + + +/**@brief Function for computing a hash from arbitrary data. + * + * @note The context object is assumed to be an opaque type defined by the + * nrf_crypto backend. See @ref NRF_CRYPTO_HASH_CONTEXT_SIZE for the relevant + * nrf_crypto backend. + * + * @param[in] hash_info Structure holding info about hash algorithm to use. + * @param[in,out] p_hash_context Pointer to structure holding context information for + * the hash computation. + * @param[in,out] p_hash Pointer to structure holding the calculated hash. + * + * @retval NRF_SUCCESS If the hash was computed successfully. + * @retval NRF_ERROR_INVALID_STATE If the function was called when nrf_crypto was + * uninitialized. + * @retval NRF_ERROR_NULL If the any of the parameters was NULL. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected hash algorithm is not supported. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers are invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the hash is bigger than the size of the provided buffer + * or the size of the hash context is invalid. + * @retval NRF_ERROR_INVALID_DATA If the hash context was deemed invalid by the nrf_crypto + * backend. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypto backend. + */ +uint32_t nrf_crypto_hash_finalize(nrf_crypto_hash_info_t hash_info, + nrf_value_length_t * p_hash_context, + nrf_value_length_t * p_hash); + + +/**@brief Function for computing a hash from arbitrary data in a single integrated step. + * + * @param[in] hash_info Structure holding info about hash algorithm to use and endianness + * for the computed hash. + * @param[in] p_data Pointer to data to be hashed. + * @param[in] len Length of the data to be hashed. + * @param[in,out] p_hash Pointer to structure holding the calculated hash. + * + * @retval NRF_SUCCESS If the hash was computed successfully. + * @retval NRF_ERROR_INVALID_STATE If the function was called when nrf_crypto was + * uninitialized. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected hash algorithm is not supported. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers are invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the hash is bigger than the size of the provided buffer + * or the size of the hash context is invalid. + * @retval NRF_ERROR_INVALID_DATA If the hash context was deemed invalid by the nrf_crypto + * backend. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypto backend. + */ +uint32_t nrf_crypto_hash_compute(nrf_crypto_hash_info_t hash_info, + uint8_t const * p_data, + uint32_t len, + nrf_value_length_t * p_hash); + + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // #ifndef NRF_CRYPTO_HASH_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_init.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_init.c new file mode 100644 index 0000000000000000000000000000000000000000..4df4bbdcbae2acfe574930c138e347dca6ea3879 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_init.c @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#include "nrf_crypto_init.h" + +#if NRF_CRYPTO_BACKEND_CC310_LIB +#include "cc310_lib_init.h" +#endif + +#if NRF_CRYPTO_BACKEND_MICRO_ECC +#include "micro_ecc_lib_init.h" +#endif + + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_init.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_init.h new file mode 100644 index 0000000000000000000000000000000000000000..001e5cea379cc819535389b86e68b825808b94d4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_init.h @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CRYPTO_INIT_H__ +#define NRF_CRYPTO_INIT_H__ + +/** @file + * + * @defgroup nrf_crypto_initialization Initialization. + * @{ + * @ingroup nrf_crypto + * + * @brief Provides nrf_crypto initialization related functions. + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "nrf_crypto_types.h" + +/**@brief Function for initializing the cryptography library. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypt backend. + */ +uint32_t nrf_crypto_init(void); + + +/**@brief Function for uninitializing the cryptography library. + * + * @retval NRF_SUCCESS If unititialization was successful. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypt backend. + */ +uint32_t nrf_crypto_uninit(void); + + +/**@brief Function reporting if nrf_crypto has been initialized. + * + * @retval True If cryptographic library is initialized. + * @retval False If cryptographic library isn't initialized. + */ +bool nrf_crypto_is_initialized(void); + + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // NRF_CRYPTO_INIT_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_keys.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_keys.c new file mode 100644 index 0000000000000000000000000000000000000000..472f47ef9cc7ca98fc342b0a0ec66545a1f5e408 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_keys.c @@ -0,0 +1,246 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#include "nrf_crypto_keys.h" +#include "nrf_crypto_mem.h" + +#if NRF_CRYPTO_BACKEND_CC310_LIB +#include "cc310_lib_keys.h" +#endif + +#if NRF_CRYPTO_BACKEND_MICRO_ECC +#include "micro_ecc_lib_keys.h" +#endif + + +uint32_t nrf_crypto_ecc_private_key_size_get(nrf_ecc_curve_type_t curve_type, + uint32_t * p_key_size) +{ + if(p_key_size == NULL) + { + return NRF_ERROR_NULL; + } + + switch(curve_type) + { + case NRF_CRYPTO_CURVE_SECP160R1: + (*p_key_size)= NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP160R1; + break; + + case NRF_CRYPTO_CURVE_SECP192R1: + (*p_key_size) = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP192R1; + break; + + case NRF_CRYPTO_CURVE_SECP224R1: + (*p_key_size) = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP224R1; + break; + + case NRF_CRYPTO_CURVE_SECP256R1: + (*p_key_size) = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP256R1; + break; + + case NRF_CRYPTO_CURVE_SECP384R1: + (*p_key_size) = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP384R1; + break; + + case NRF_CRYPTO_CURVE_SECP521R1: + (*p_key_size) = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP521R1; + break; + + case NRF_CRYPTO_CURVE_SECP192K1: + (*p_key_size) = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP192K1; + break; + + case NRF_CRYPTO_CURVE_SECP224K1: + (*p_key_size) = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP224K1; + break; + + case NRF_CRYPTO_CURVE_SECP256K1: + (*p_key_size) = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP256K1; + break; + + default: + (*p_key_size) = 0; + return NRF_ERROR_NOT_SUPPORTED; + } + + return NRF_SUCCESS; +} + +uint32_t nrf_crypto_ecc_public_key_size_get(nrf_ecc_curve_type_t curve_type, + uint32_t * p_key_size) +{ + if(p_key_size == NULL) + { + return NRF_ERROR_NULL; + } + + switch(curve_type) + { + case NRF_CRYPTO_CURVE_SECP160R1: + (*p_key_size)= NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP160R1; + break; + + case NRF_CRYPTO_CURVE_SECP192R1: + (*p_key_size) = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP192R1; + break; + + case NRF_CRYPTO_CURVE_SECP224R1: + (*p_key_size) = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP224R1; + break; + + case NRF_CRYPTO_CURVE_SECP256R1: + (*p_key_size) = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP256R1; + break; + + case NRF_CRYPTO_CURVE_SECP384R1: + (*p_key_size) = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP384R1; + break; + + case NRF_CRYPTO_CURVE_SECP521R1: + (*p_key_size) = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP521R1; + break; + + case NRF_CRYPTO_CURVE_SECP192K1: + (*p_key_size) = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP192K1; + break; + + case NRF_CRYPTO_CURVE_SECP224K1: + (*p_key_size) = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP224K1; + break; + + case NRF_CRYPTO_CURVE_SECP256K1: + (*p_key_size) = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP256K1; + break; + + default: + (*p_key_size) = 0; + return NRF_ERROR_NOT_SUPPORTED; + } + + return NRF_SUCCESS; +} + + +uint32_t nrf_crypto_ecc_private_key_allocate(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t * p_private_key, + nrf_value_length_t const * p_raw_key) +{ + uint32_t ret_val; + uint32_t key_size; + + if (p_private_key == NULL) + { + return NRF_ERROR_NULL; + } + + ret_val = nrf_crypto_ecc_private_key_size_get(curve_info.curve_type, &key_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + ret_val = nrf_crypto_mem_allocate(key_size, p_private_key); + if (ret_val == NRF_SUCCESS) + { + return ret_val; + } + + return ret_val; +} + +uint32_t nrf_crypto_ecc_private_key_free(nrf_value_length_t * p_private_key) +{ + uint32_t ret_val; + + if (p_private_key == NULL) + { + return NRF_ERROR_NULL; + } + + ret_val = nrf_crypto_mem_free(p_private_key); + return ret_val; +} + +uint32_t nrf_crypto_ecc_public_key_allocate(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t * p_public_key, + nrf_value_length_t const * p_raw_key) +{ + uint32_t ret_val; + uint32_t key_size; + + if (p_public_key == NULL) + { + return NRF_ERROR_NULL; + } + + ret_val = nrf_crypto_ecc_public_key_size_get(curve_info.curve_type, &key_size); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + ret_val = nrf_crypto_mem_allocate(key_size, p_public_key); + if (ret_val == NRF_SUCCESS) + { + return ret_val; + } + + return ret_val; +} + + +uint32_t nrf_crypto_ecc_public_key_free(nrf_value_length_t * p_public_key) +{ + uint32_t ret_val; + + if (p_public_key == NULL) + { + return NRF_ERROR_NULL; + } + + ret_val = nrf_crypto_mem_free(p_public_key); + return ret_val; +} + + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_keys.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_keys.h new file mode 100644 index 0000000000000000000000000000000000000000..34da51ecbc6f7d82c2eac334572730d939cc4bc6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_keys.h @@ -0,0 +1,531 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CRYPTO_KEYS_H__ +#define NRF_CRYPTO_KEYS_H__ + +/** @file + * + * @defgroup nrf_crypto_keys ECC key handling functions. + * @{ + * @ingroup nrf_crypto + * + * @brief Provides functions to allocate, free, generate and convert ECC key types. + */ + +#include +#include "nrf_crypto_types.h" + +#include "sdk_config.h" +#if NRF_CRYPTO_BACKEND_CC310_LIB +#include "cc310_lib_keys.h" +#endif + +#if NRF_CRYPTO_BACKEND_MICRO_ECC +#include "micro_ecc_lib_keys.h" +#endif + + +#ifdef __cplusplus +extern "C" { +#if 0 +} +#endif +#endif + + +/** @brief Internal macro to calculate size required to hold a ECC private key + * given curve type(domain), according to the used nrf_crypto backend. + * + * @warning The size representation by running this macro is described by the + * memory requirements of the nrf_crypto backend. This size does not + * correspond to the size required to hold a raw key. + * @param[in] type Curve type. Either SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1. + */ +#if defined(NRF_CRYPTO_BACKEND_CC310_LIB) && (NRF_CRYPTO_BACKEND_CC310_LIB == 1) + +#define NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE(type) \ + (NRF_CRYPTO_ECC_PRIVATE_KEY_MAX_SIZE) + +#else + +#define NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE(type) \ + (STRING_CONCATENATE(NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_, type)) + +#endif // defined(NRF_CRYPTO_BACKEND_CC310_LIB) + + +/** @brief Internal macro to calculate size required to hold a ECC public key + * given curve type(domain), according to the used nrf_crypto backend. + * + * @warning The size representation by running this macro is described by the + * memory requirements of the nrf_crypto backend. This size does not + * correspond to the size required to hold a raw key. + * + * @param[in] type Curve type. Either SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1. + */ +#if defined(NRF_CRYPTO_BACKEND_CC310_LIB) && (NRF_CRYPTO_BACKEND_CC310_LIB == 1) + +#define NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE(type) \ + (NRF_CRYPTO_ECC_PUBLIC_KEY_MAX_SIZE) + +#else + +#define NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE(type) \ + (STRING_CONCATENATE(NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_, type)) + +#endif // defined(NRF_CRYPTO_BACKEND_CC310_LIB) + +/** @brief Macro to create an instance of an ECC private key + * given name and type. + * + * @note This creates the value length structure used for Nordic APIs with a buffer + * to hold the actual ECC private key data. The ECC private key type is opaque and + * the size and format of the data is dependant on the nrf_crypto backend. + * + * @note To convert this key to a raw representation required for external APIS, please + * use the function @ref nrf_crypto_ecc_public_key_to_raw. + * This may not be supported by all nrf_crypto backends. + * + * @param[in] name Name of the ECC private key instance. + * @param[in] type Curve type. Either SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1. + */ +#define NRF_CRYPTO_ECC_PRIVATE_KEY_CREATE(name, type) \ +__ALIGN(4) static uint8_t \ + name ## _buffer[NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE(type)]; \ +nrf_value_length_t name = \ +{ \ + .p_value = name ## _buffer, \ + .length = NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE(type) \ +} + + +/** @brief Macro to create an instance of an ECC public key by a given name and type. + * + * @note This creates the value length structure used for Nordic APIs with a buffer + * to hold the actual ECC public key data. The ECC public key type is opaque and + * the size and format of the data is dependant on the nrf_crypto backend. + * + * @note To convert this key to a raw representation required for external APIS, please + * use the function @ref nrf_crypto_ecc_public_key_to_raw. + * This may not be supported by all nrf_crypto backends. + * + * @param[in] name Name of the ECC PUBLIC key instance. + * @param[in] type Curve type. Either SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1. + */ +#define NRF_CRYPTO_ECC_PUBLIC_KEY_CREATE(name, type) \ +__ALIGN(4) static uint8_t \ + name ## _buffer[NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE(type)]; \ +nrf_value_length_t name = \ +{ \ + .p_value = name ## _buffer, \ + .length = NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE(type) \ +} + + +/** @brief Internal macro to calculate size required to hold a ECC private key + * in raw format given curve type(domain), according to the used + * nrf_crypto backend. + * + * @warning The size representation by running this macro is described by the + * memory requirements of the nrf_crypto backend. This size does not + * correspond to the size required to hold a raw key. + * @param[in] type Curve type. Either SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1. + */ + +#define NRF_CRYPTO_ECC_PRIVATE_RAW_KEY_SIZE(type) \ + (STRING_CONCATENATE(NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_, type)) + + +/** @brief Internal macro to calculate size required to hold a ECC public key + * in raw representatio given curve type(domain), + * according to the used nrf_crypto backend. + * + * @warning The size representation by running this macro is described by the + * memory requirements of the nrf_crypto backend. This size does not + * correspond to the size required to hold a raw key. + * + * @param[in] type Curve type. Either SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1. + */ +#define NRF_CRYPTO_ECC_PUBLIC_RAW_KEY_SIZE(type) \ + (STRING_CONCATENATE(NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_, type)) + + +/** @brief Macro to create an instance of a raw representation of an ECC private key + * given name and type. + * + * @note This creates the value length structure used for external APIs that require + * an aligned version of a private key where curve-domain and endianness is + * described elsewhere. + * + * @warning The raw private key can not be used directly in the nrf_crypto APIs. + * + * @warning The output of this macro is subject to change. + * + * @param[in] name Name of the ECC private key instance. + * @param[in] type Curve type. Either SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1. + */ +#define NRF_CRYPTO_ECC_PRIVATE_KEY_RAW_CREATE(name, type) \ +__ALIGN(4) static uint8_t \ + name ## _buffer[NRF_CRYPTO_ECC_PRIVATE_RAW_KEY_SIZE(type)]; \ +nrf_value_length_t name = \ +{ \ + .p_value = name ## _buffer, \ + .length = NRF_CRYPTO_ECC_PRIVATE_RAW_KEY_SIZE(type) \ +} + + +/** @brief Macro to create a value length structure to represent a raw ECC private key + * by a given name, type and an uint8_t array buffer to hold the raw private key. + * If the input is not of the correct size a static assert will be occur compile-time. + * + * + * @note This creates the value length structure used for external APIs that require + * an aligned version of a private key where curve-domain and endianness is + * described elsewhere. + * + * @note The value length pair generated by running this macro can be used as input in the + * function @ref nrf_crypto_ecc_private_key_to_raw to hold a raw private key type. + * + * @warning There is no API function to convert private key from a raw representation in the + * nrf_crypto CryptoCell (cc310) backend. Running this macro while nrf_crypto + * CryptoCell backend is enabled will cause a static assertion. + * + * @param[in] name Name of the ECC private key instance. + * @param[in] type Curve type. Either SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1. + * @param[in] input Array holding the private key. + */ +#define NRF_CRYPTO_ECC_PRIVATE_KEY_RAW_CREATE_FROM_ARRAY(name, type, input) \ +STATIC_ASSERT(sizeof(input) == NRF_CRYPTO_ECC_PRIVATE_RAW_KEY_SIZE(type)) \ +static nrf_value_length_t name = \ +{ \ + .p_value = (uint8_t*)input, \ + .length = NRF_CRYPTO_ECC_PRIVATE_RAW_KEY_SIZE(type) \ +} + +/** @brief Macro to create an instance of a araw representation of an ECC public key + * given name and type. + * + * @note This creates the value length structure used for external APIs that require + * an aligned version of a public key where curve-domain and endianness is + * described elsewhere. + * +¨* @note The value length pair generated by running this macro can be used as input in the + * function @ref nrf_crypto_ecc_public_key_to_raw to hold a raw private key type. + * + * @param[in] name Name of the ECC PUBLIC key instance. + * @param[in] type Curve type. Either SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1. + */ +#define NRF_CRYPTO_ECC_PUBLIC_KEY_RAW_CREATE(name, type) \ +__ALIGN(4) static uint8_t \ + name ## _buffer[NRF_CRYPTO_ECC_PUBLIC_RAW_KEY_SIZE(type)]; \ +nrf_value_length_t name = \ +{ \ + .p_value = name ## _buffer, \ + .length = NRF_CRYPTO_ECC_PUBLIC_RAW_KEY_SIZE(type) \ +} + + +/** @brief Macro to create an instance of an ECC public key by a given + * name, type and array input. + * If the input is not of the correct size a static assert will be occur compile-time. + * + * + * @note This creates the value length structure used for external APIs that require + * an aligned version of a private key where curve-domain and endianness is + * described elsewhere. + * + * @note The value length pair generated by running this macro can be used as input in the + * function @ref nrf_crypto_ecc_private_key_to_raw to hold a raw public key type. + * + * @param[in] name Name of the ECC PUBLIC key instance. + * @param[in] type Curve type. Either SECP192R1, SECP224R1, SECP256R1, SECP384R1, + * SECP521R1, SECP192K1, SECP224K1, or SECP256K1. + * @param[in] input Array of data used as the buffer. + */ +#define NRF_CRYPTO_ECC_PUBLIC_KEY_RAW_CREATE_FROM_ARRAY(name, type, input) \ +STATIC_ASSERT(sizeof(input) == NRF_CRYPTO_ECC_PUBLIC_RAW_KEY_SIZE(type)); \ +static nrf_value_length_t name = \ +{ \ + .p_value = (uint8_t*)input, \ + .length = NRF_CRYPTO_ECC_PUBLIC_RAW_KEY_SIZE(type) \ +} + +/**@brief Function to get the private key size given curve_type. + * + * @param[in] curve_type Curve type to get private key size for. + * @param[in,out] p_key_size Pointer to variable to hold the private key size. + * + * @retval NRF_SUCCESS If the private key size was successfully found. + * @retval NRF_ERROR_NULL If the p_key_size was NULL. + * @retval NRF_ERROR_NOT_SUPPORTED If the curve type was not supported. + */ +uint32_t nrf_crypto_ecc_private_key_size_get(nrf_ecc_curve_type_t curve_type, + uint32_t * p_key_size); + + +/**@brief Function to get the public key size given curve_type. + * + * @param[in] curve_type Curve type to get public key size for. + * @param[in,out] p_key_size Pointer to variable to hold the public key size. + * + * @retval NRF_SUCCESS If the public key size was successfully found. + * @retval NRF_ERROR_NULL If the p_key_size was NULL. + * @retval NRF_ERROR_NOT_SUPPORTED If the curve type was not supported. + */ +uint32_t nrf_crypto_ecc_public_key_size_get(nrf_ecc_curve_type_t curve_type, + uint32_t * p_key_size); + + +/**@brief Function to allocate dynamic memory for holding a ECC private key. + * + * @note Memory dynamically allocated by calling this function will be aligned to a + * uint32_t address. + * + * @param[in] curve_info Curve type used for ECC private key. + * @param[in,out] p_private_key Pointer to a value length structure to hold a private key. + * @param[in] p_raw_key Pointer to value length structure holding raw + * representation of a private key taken as input. + * If this is set to NULL, no initialization will take place. + * + * @retval NRF_SUCCESS If memory for the private key was successfully allocated. + * @retval NRF_ERROR_NULL If p_private_key was NULL. + * @retval Any other error code reported by the memory manager. + */ +uint32_t nrf_crypto_ecc_private_key_allocate(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t * p_private_key, + nrf_value_length_t const * p_raw_key); + + +/**@brief Function to free allocated memory for ECC private key. + * + * @note Memory dynamically allocated by calling this function will be aligned to a + * uint32_t address. + * + * @param[in] p_private_key Pointer to structure holdign + * + + * @retval NRF_SUCCESS if memory for the private key was successfully freed. + * @retval NRF_ERROR_NULL If p_private_key was NULL. + * @retval Any other error code reported by the memory manager. + */ +uint32_t nrf_crypto_ecc_private_key_free(nrf_value_length_t * p_private_key); + + +/**@brief Function to allocate dynamic memory for holdign a ECC public key. + * + * @param[in] curve_info Curve type used for ECC public key. + * @param[in,out] p_public_key Pointer to a value length structure to hold a public key. + * @param[in] p_raw_key Pointer to value length structure holding raw + * representation of a public key taken as input. + * If this is set to NULL, no initialization will take place. + * + * @retval NRF_SUCCESS If memory for the public key was successfully allocated. + * @retval NRF_ERROR_NULL If p_public_key was NULL. + * @retval Any other error code reported by the memory manager. + */ +uint32_t nrf_crypto_ecc_public_key_allocate(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t * p_public_key, + nrf_value_length_t const * p_raw_key); + + +/**@brief Function to free allocated memory for ECC private key. + * + * @param[in] p_public_key Pointer to value length structure holding public key to free. + * + * @retval NRF_SUCCESS If memory for the public key was successfully freed. + * @retval NRF_ERROR_NULL If p_public_key was NULL. + * @retval Any other error code reported by the memory manager. + */ +uint32_t nrf_crypto_ecc_public_key_free(nrf_value_length_t * p_public_key); + + +/**@brief Function to generate ECC private public keypair given curve type. + * + * @note This function will not allocate any memory. Private and public keys given as + * input must be pointing to previously allocated memory. + * + * @note This function needs RNG functionality. See @ref NRF_CRYPTO_SUPPORTS_RNG for the + * nrf_crypto backends that require external source of RNG data. + * + * @param[in] curve_info Curve type used for key pair generation. + * @param[in,out] p_private_key Pointer to a value length structure to hold a private key. + * @param[in,out] p_public_key Pointer to a value length structure to hold a public key. + * + * @retval NRF_SUCCESS The ECC key pair was generated successfully. + * @retval NRF_ERROR_INVALID_STATE If the function was called when nrf_crypto was + * uninitialized. + * @retval NRF_ERROR_NULL If the any of the parameters was NULL. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers are invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the key pair size is different to the provided buffers. + * @retval NRF_ERROR_NOT_SUPPORTED If the key pair generation is not supported for the given curve type. + * @retval NRF_ERROR_INTERNAL Unexpected error. Possibly because @ref NRF_CRYPTO_SUPPORTS_RNG is 0. + */ +uint32_t nrf_crypto_ecc_key_pair_generate(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t * p_private_key, + nrf_value_length_t * p_public_key); + + +/**@brief Function to calculate ECC public key given a ECC private key as input + * + * @note This function will not allocate any memory. The public key given as input + * must be pointing to previously allocated memory. + * + * @param[in] curve_info Curve type used for public key. + * @param[in] p_private_key Pointer to a value length structure holding a private key. + * @param[in, out] p_public_key Pointer to a value length structure to hold the calculated + * key. + * + * @retval NRF_SUCCESS If the public key was calculated successfully. + * @retval NRF_ERROR_INVALID_STATE If the function was called when nrf_crypto was + * uninitialized. + * @retval NRF_ERROR_NULL If the any of the parameters was NULL. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers are invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the key pair size is different to the provided buffers. + * @retval NRF_ERROR_NOT_SUPPORTED If the public key calculation is not supported. + */ +uint32_t nrf_crypto_ecc_public_key_calculate(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t const * p_private_key, + nrf_value_length_t * p_public_key); + + +/**@brief Function to convert ECC private key to a raw representation for use in external APIs. + * + * @note This function will not allocate any memory. The raw public key given as output parameter + * must be pointing to previously allocated memory. + * + * @note The format of the data for the converted ECC public key must be aligned and will + * use the least amount of space required to represent the key. + * + * @warning The nrf_crypto backend may not support converting a private key to a raw representation. + * This is subject to change. + * + * @param[in] curve_info Info of the curve type (domain) and the endianness of the + * resulting raw key. + * @param[in] p_private_key Value length structure holding a private key to be + * converted to a raw representation. + * @param[in,out] p_private_key_raw Value length structure to hold the converted private key. + * + * @retval NRF_SUCCESS If the private key was converted to raw representation. + * @retval NRF_ERROR_INVALID_STATE If the function was called when nrf_crypto was + * uninitialized. + * @retval NRF_ERROR_NULL If the any of the parameters was NULL. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers are invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the size of the public key and result is invalid. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected curve is not supported. + * @retval NRF_ERROR_INVALID_DATA If the private key was deemed invalid by the nrf_crypto + * backend. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypto backend. + */ +uint32_t nrf_crypto_ecc_private_key_to_raw(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t const * p_private_key, + nrf_value_length_t * p_private_key_raw); + + +/**@brief Function to convert ECC public key to a raw representation for use in external APIs. + * + * @note This function will not allocate any memory. The raw public key given as output parameter + * must be pointing to previously allocated memory. + * The format of the data for the converted ECC public key must be aligned and will + * use the least amount of space required to represent the key. + * + * @param[in] curve_info Info of the curve type (domain) and the endianness of + * the resulting raw key. + * @param[in] p_public_key Value length structure holding a public key to be + * converted to a raw representation. + * @param[in,out] p_public_key_raw Value length structure to hold the converted public key. + * + * @retval NRF_SUCCESS If the public key was converted to raw representation. + * @retval NRF_ERROR_INVALID_STATE If the function was called when nrf_crypto was + * uninitialized. + * @retval NRF_ERROR_NULL If the any of the parameters was NULL. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers are invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the size of the public key and result is invalid. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected curve is not supported. + * @retval NRF_ERROR_INVALID_DATA If the public key was deemed invalid by the nrf_crypto + * backend. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypto backend. + */ +uint32_t nrf_crypto_ecc_public_key_to_raw(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t const * p_public_key, + nrf_value_length_t * p_public_key_raw); + + +/**@brief Function to convert ECC public key from a raw representation for use in nrf_crypto API. + * + * @note This function will not allocate any memory. The public key given as output parameter + * must be pointing to previously allocated memory. + * The format of the data for the converted ECC public key must be aligned and will + * use the least amount of space required to represent the key. + * + * @param[in] curve_info Info of the curve type (domain) and the endianness of the + * raw public key given as input. + * @param[in] p_public_key_raw Value length structure to hold the converted public key. + * @param[in,out] p_public_key Value length structure holding a private key to be converted to a raw representation. + * + * @retval NRF_SUCCESS If the public key was converted fron raw representation. + * @retval NRF_ERROR_INVALID_STATE If the function was called when nrf_crypto was + * uninitialized. + * @retval NRF_ERROR_NULL If the any of the parameters was NULL. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers are invalid. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected curve is not supported. + * @retval NRF_ERROR_INVALID_LENGTH If the size of the public key and result is invalid. + * @retval NRF_ERROR_INVALID_DATA If the public key was deemed invalid by the nrf_crypto + * backend. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypto backend. + */ +uint32_t nrf_crypto_ecc_public_key_from_raw(nrf_crypto_curve_info_t curve_info, + nrf_value_length_t * p_public_key_raw, + nrf_value_length_t * p_public_key); +#ifdef __cplusplus +} +#endif + + /**@} */ + +#endif // NRF_CRYPTO_KEYS_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_mem.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..c547645dc188c052978844ea25ba54566683eaad --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_mem.c @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#include "nrf_crypto_mem.h" +#include "mem_manager.h" + +uint32_t nrf_crypto_mem_init(void) +{ + uint32_t ret_val; + + ret_val = nrf_mem_init(); + return ret_val; +} + +uint32_t nrf_crypto_mem_allocate(uint32_t size, nrf_value_length_t * p_result) +{ + uint32_t ret_val; + uint32_t allocated_size; + + if (p_result == NULL) + { + return NRF_ERROR_NULL; + } + + ret_val = nrf_mem_reserve(&p_result->p_value, &allocated_size); + if (ret_val == NRF_SUCCESS) + { + p_result->length = size; + } + else + { + p_result->length = 0; + } + + return ret_val; +} + +uint32_t nrf_crypto_mem_free(nrf_value_length_t * p_mem) +{ + if (p_mem == NULL) + { + return NRF_ERROR_NULL; + } + + if(p_mem->length != 0) + { + nrf_free(p_mem->p_value); + } + + return NRF_SUCCESS; +} + + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_mem.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..58d0ee7dc14597cdec1caa01df4c2116cf53f47d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_mem.h @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CRYPTO_MEM_H__ + #define NRF_CRYPTO_MEM_H__ + +/** @file + * + * @defgroup nrf_crypto_mem Dynamic memory management module + * @{ + * @ingroup nrf_crypto + * + * @brief Module to manage dynamically allocated memory used by nrf_crypto APIs + */ + +#include +#include "nrf_crypto_types.h" + + #ifdef __cplusplus +extern "C" { +#if 0 +} +#endif +#endif + +/** @brief Function to initialize the nrf_crypto memory module. + * + * @retval NRF_SUCCESS The nrf_crypto memory manager initialized successfully. + * @retval Any other error code reported by the memory manager. + */ +uint32_t nrf_crypto_mem_init(void); + + +/**@brief Function to allocate memory for use by the nrf_crypto API. + * + * @param[in] size Length in bytes to allocate + * @param[in,out] p_result Pointer to value length structure to hold information about the allocated memory. + * + * @retval NRF_SUCCESS The memory was allocated successfully. + * @retval Any other error code reported by the memory manager. + */ +uint32_t nrf_crypto_mem_allocate(uint32_t size, nrf_value_length_t * p_result); + + +/**@brief Function to free memory to use by nrf_crypto API. + * + * @param[in] p_mem Pointer to value length structure holding information about allocated memory to free + * + * @retval NRF_SUCCESS The memory was freed successfully. + * @retval Any other error code reported by the memory manager. + */ +uint32_t nrf_crypto_mem_free(nrf_value_length_t * p_mem); + +#ifdef __cplusplus +} +#endif + +/**@} */ + + #endif // NRF_CRYPTO_MEM_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_rng.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_rng.c new file mode 100644 index 0000000000000000000000000000000000000000..ef1945adf2f8134bd610c4e0b811916f212992b9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_rng.c @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CRYPTO) + +#include "nrf_crypto_rng.h" +#include "nrf_drv_rng.h" + +#if NRF_CRYPTO_BACKEND_SW +#include "nrf_crypto_sw_rng.h" +#endif + +#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_rng.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_rng.h new file mode 100644 index 0000000000000000000000000000000000000000..5ef7f255af8be02793b2df45780189b8c942acec --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_rng.h @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CRYPTO_RNG_H__ +#define NRF_CRYPTO_RNG_H__ + +/** @file + * + * @defgroup nrf_crypto_rng Random number generation related functions. + * @{ + * @ingroup nrf_crypto + * + * @brief Provides functions to initialize rng subsystem and generate random data. + */ + +#include +#include "nrf_crypto_types.h" + +#ifdef __cplusplus +extern "C" { +#if 0 +} +#endif +#endif + +/**@brief Initialize the random number generator + * + * @note This function is called by @ref nrf_crypto_init. + * + * @retval NRF_SUCCESS If random number generator was initialized successfully. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypto backend. + */ +uint32_t nrf_crypto_rng_init(void); + +/**@brief Generate random data into a buffer, given length as an input. + * + * @param[in,out] p_target Pointer to a buffer to accept the random generated data. + * This buffer must be the same length as the length input. + * @param[in] length Length (in bytes) to generate random data for. + * + * @retval NRF_SUCCESS Data was generated successfully. + * @retval NRF_ERROR_NULL p_target was NULL. + * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypto backend. + */ +uint32_t nrf_crypto_rng_vector_generate(uint8_t * p_target, uint32_t length); + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // #ifndef NRF_CRYPTO_RNG_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_svc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_svc.c new file mode 100644 index 0000000000000000000000000000000000000000..940fc9faf5d295112219f671149abfc4a12c07ca --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_svc.c @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_svc_function.h" +#include "nrf_error.h" +#include "sdk_common.h" + +/* use direct calls */ +#define SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION +#include "nrf_crypto.h" + +#ifndef NRF51 + +SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_init) = +{ + .svc_num = NRF_SVCI_SVC_NUM, + .svci_num = NRF_CRYPTO_SVCI_INIT, + .func_ptr = (nrf_svc_func_t)&nrf_crypto_init +}; + +SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_public_key_compute) = +{ + .svc_num = NRF_SVCI_SVC_NUM, + .svci_num = NRF_CRYPTO_SVCI_PUBLIC_KEY_COMPUTE, + .func_ptr = (nrf_svc_func_t)&nrf_crypto_public_key_compute +}; + +SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_shared_secret_compute) = +{ + .svc_num = NRF_SVCI_SVC_NUM, + .svci_num = NRF_CRYPTO_SVCI_SHARED_SECRET_COMPUTE, + .func_ptr = (nrf_svc_func_t)&nrf_crypto_shared_secret_compute +}; + +SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_sign) = +{ + .svc_num = NRF_SVCI_SVC_NUM, + .svci_num = NRF_CRYPTO_SVCI_SIGN, + .func_ptr = (nrf_svc_func_t)&nrf_crypto_sign +}; + +#endif + +SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_verify) = +{ + .svc_num = NRF_SVCI_SVC_NUM, + .svci_num = NRF_CRYPTO_SVCI_VERIFY, + .func_ptr = (nrf_svc_func_t)&nrf_crypto_verify +}; + +SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_hash_compute) = +{ + .svc_num = NRF_SVCI_SVC_NUM, + .svci_num = NRF_CRYPTO_SVCI_HASH_COMPUTE, + .func_ptr = &nrf_crypto_hash_compute +}; diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_types.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_types.h new file mode 100644 index 0000000000000000000000000000000000000000..4e71a8a9519b0855ab5e7f8fc1b4f68806422399 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/crypto/nrf_crypto_types.h @@ -0,0 +1,252 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CRYPTO_TYPES_H__ +#define NRF_CRYPTO_TYPES_H__ + +/** @file + * + * @defgroup nrf_crypto_types Commonly shared types + * @{ + * @ingroup nrf_crypto + * + * @brief Provides definitions of commonly shared cryptographic types like hashes and curves used in the nrf_crypto APIs. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Generic type to hold pointer to value and length + */ +typedef struct +{ + uint8_t * p_value; + uint32_t length; + +} nrf_value_length_t; + + +/**@defgroup NRF_CRYPTO_CURVES Cryptographic curves + * @brief Cryptographic curves that are available to the application. + * @{ */ +typedef enum +{ + NRF_CRYPTO_CURVE_INVALID = 0x00, //!< Invalid curve. + NRF_CRYPTO_CURVE_SECP160R1 = 0x01, //!< NIST 160-bit. + NRF_CRYPTO_CURVE_SECP192R1 = 0x02, //!< NIST 192-bit. + NRF_CRYPTO_CURVE_SECP224R1 = 0x03, //!< NIST 224-bit. + NRF_CRYPTO_CURVE_SECP256R1 = 0x04, //!< NIST 256-bit. + NRF_CRYPTO_CURVE_SECP384R1 = 0x05, //!< NIST 384-bit. + NRF_CRYPTO_CURVE_SECP521R1 = 0x06, //!< NIST 521-bit. + NRF_CRYPTO_CURVE_SECP192K1 = 0x07, //!< Koblitz 192-bit. + NRF_CRYPTO_CURVE_SECP224K1 = 0x08, //!< Koblitz 224-bit. + NRF_CRYPTO_CURVE_SECP256K1 = 0x09, //!< Koblitz 256-bit. + NRF_CRYPTO_CURVE_CURVE25519 = 0x0A, //!< Curve 25519. +} nrf_ecc_curve_type_t; +/** @} */ + +/** @brief Hashing algorithms that are available through nrf_crypto. + * + * @note All cryptographic hash types may not be available through the nrf_crypto backend. + */ +typedef enum +{ + NRF_CRYPTO_HASH_TYPE_INVALID = 0x00, //!< Invalid hashing algorithm. + NRF_CRYPTO_HASH_TYPE_MD5 = 0x01, //!< MD5. + NRF_CRYPTO_HASH_TYPE_SHA1 = 0x03, //!< SHA-1. + NRF_CRYPTO_HASH_TYPE_SHA224 = 0x04, //!< SHA-224 (SHA-2). + NRF_CRYPTO_HASH_TYPE_SHA256 = 0x05, //!< SHA-256 (SHA-2). + NRF_CRYPTO_HASH_TYPE_SHA384 = 0x06, //!< SHA-384 (SHA-2). + NRF_CRYPTO_HASH_TYPE_SHA512 = 0x07, //!< SHA-512 (SHA-2). + +} nrf_hash_type_t; + +/**@defgroup NRF_CRYPTO_HASH_SIZES Cryptographic hash sizes + * @brief Sizes of different cryptographic hashes. + * @{ */ +#define NRF_CRYPTO_HASH_SIZE_MD5 (20) +#define NRF_CRYPTO_HASH_SIZE_SHA1 (20) +#define NRF_CRYPTO_HASH_SIZE_SHA224 (28) +#define NRF_CRYPTO_HASH_SIZE_SHA256 (32) +#define NRF_CRYPTO_HASH_SIZE_SHA384 (48) +#define NRF_CRYPTO_HASH_SIZE_SHA512 (64) +/** @} */ + +/**@defgroup NRF_CRYPTO_ECDSA_SIGNATURE_SIZES ECDSA signature sizes. + * @brief Sizes of different ECDSA signatures. + * @{ */ +#define NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP160R1 (40) +#define NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP192R1 (48) +#define NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP224R1 (56) +#define NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP256R1 (64) +#define NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP384R1 (96) +#define NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP521R1 (132) +#define NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP192K1 (48) +#define NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP224K1 (56) +#define NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP256K1 (64) +#define NRF_CRYPTO_ECDSA_SIGNATURE_MAX_SIZE NRF_CRYPTO_ECDSA_SIGNATURE_SIZE_SECP521R1 +/** @} */ + + +/**@defgroup NRF_CRYPTO_ECC_PRIVATE_KEY_SIZES ECC private key sizes. + * @brief Sizes of different elliptical curve cryptography private keys. + * @{ */ +#define NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP160R1 (20) +#define NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP192R1 (24) +#define NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP224R1 (28) +#define NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP256R1 (32) +#define NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP384R1 (48) +#define NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP521R1 (66) +#define NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP192K1 (24) +#define NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP224K1 (28) +#define NRF_CRYPTO_ECC_PRIVATE_KEY_SIZE_SECP256K1 (32) +/** @} */ + +/**@defgroup NRF_CRYPTO_ECC_PUBLIC_KEY_SIZES ECC public key sizes. + * @brief Sizes of different elliptical curve cryptographic public keys. + * @{ */ +#define NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP160R1 (40) +#define NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP192R1 (48) +#define NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP224R1 (56) +#define NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP256R1 (64) +#define NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP384R1 (96) +#define NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP521R1 (132) +#define NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP192K1 (48) +#define NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP224K1 (56) +#define NRF_CRYPTO_ECC_PUBLIC_KEY_SIZE_SECP256K1 (64) +/** @} */ + +/**@defgroup NRF_CRYPTO_ECDH_SHARED_SECRET_SIZES ECDH shared secret sizes. + * @brief Sizes of ECDH shared secret values. + * @{ */ +#define NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP160R1 (20) +#define NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP192R1 (24) +#define NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP224R1 (28) +#define NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP256R1 (32) +#define NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP384R1 (48) +#define NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP521R1 (66) +#define NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP192K1 (24) +#define NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP224K1 (28) +#define NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP256K1 (32) +#define NRF_CRYPTO_ECDH_SHARED_SECRET_MAX_SIZE NRF_CRYPTO_ECDH_SHARED_SECRET_SIZE_SECP521R1 +/** @} */ + + + + +/** @brief Type definition for endianness. + */ +typedef enum +{ + NRF_CRYPTO_ENDIAN_LE = 0x00, + NRF_CRYPTO_ENDIAN_BE = 0x01 + +} nrf_endian_type_t; + + +/** @brief Combined structure containing curve type, hash type and endian type. + */ +typedef struct +{ + nrf_ecc_curve_type_t curve_type; + nrf_hash_type_t hash_type; + nrf_endian_type_t endian_type; + +} nrf_crypto_signature_info_t; + + +/** @brief Combined structure containin curve type and endian type. + */ +typedef struct +{ + nrf_ecc_curve_type_t curve_type; + nrf_endian_type_t endian_type; + +} nrf_crypto_curve_info_t; + + +/** @brief Combined structure containing hash type and endian type. + */ +typedef struct +{ + nrf_hash_type_t hash_type; + nrf_endian_type_t endian_type; + +} nrf_crypto_hash_info_t; + + +/**@brief Combined to hold sizes used by ECDSA sign/verify. + */ +typedef struct +{ + uint32_t public_key_size; //!< Public key size. + uint32_t private_key_size; //!< Private key size. + uint32_t signature_size; //!< Signature size. + uint32_t hash_size; //!< Hash size. +} nrf_crypto_ecdsa_sizes_t; + + +/**@brief Structure holding hash size according to algorithm. + */ +typedef struct +{ + uint32_t hash_size; +} nrf_crypto_hash_sizes_t; + + +/**@brief Macro to declare a cryptographic curve used in + * BLE Secure Connections (LESC). + */ +#define BLE_LESC_CURVE_TYPE_INFO \ +(nrf_crypto_curve_info_t) \ +{ \ + .curve_type = NRF_CRYPTO_CURVE_SECP256R1, \ + .endian_type = NRF_CRYPTO_ENDIAN_LE \ +} + +#ifdef __cplusplus +} +#endif + +/**@} */ + +#endif // #ifndef NRF_CRYPTO_TYPES_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/csense/nrf_csense.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/csense/nrf_csense.c new file mode 100644 index 0000000000000000000000000000000000000000..44429b80ee3c33b1c199c08e139e9e3393e4449f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/csense/nrf_csense.c @@ -0,0 +1,661 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" + +#if NRF_MODULE_ENABLED(NRF_CSENSE) + +#include + +#include "nrf_csense.h" +#include "nrf_peripherals.h" +#include "nrf_assert.h" + +#if defined(__CC_ARM) +#elif defined(__ICCARM__) +#elif defined(__GNUC__) + #ifndef __CLZ + #define __CLZ(x) __builtin_clz(x) + #endif +#endif + +APP_TIMER_DEF(nrf_csense_timer); + +typedef struct +{ + nrf_csense_event_handler_t event_handler; //!< Event handler for module. + nrf_drv_state_t state; //!< State of module. + uint32_t ticks; //!< Timeout ticks of app_timer instance controlling csense module. + uint16_t raw_analog_values[MAX_ANALOG_INPUTS]; //!< Raw values of measurements. + uint8_t enabled_analog_channels_mask; //!< Mask of enabled channels. +} nrf_csense_t; + +/* Module instance. */ +static nrf_csense_t m_nrf_csense; + +/* First of touch elements instances that creates linked list. */ +static nrf_csense_instance_t * mp_nrf_csense_instance_head; + +/* Buffer for values got from measurements. */ +static uint16_t m_values_buffer[NRF_CSENSE_MAX_PADS_NUMBER]; + +/** + * @brief Function for handling time-outs. + * + * @param[in] p_context General purpose pointer. Will be passed to the time-out handler + * when the timer expires. + */ +static void csense_timer_handler(void * p_context) +{ + if (m_nrf_csense.state != NRF_DRV_STATE_POWERED_ON) + { + return; + } + + if (nrf_drv_csense_sample() == NRF_ERROR_BUSY) + { + return; + } +} + + +/** + * @brief Function for updating maximum or minimum value. + * + * @param [in] p_instance Pointer to csense instance. + * @param [in] p_pad Pointer to pad which should be checked for minimum or maximum value. + */ +__STATIC_INLINE void min_or_max_update(nrf_csense_instance_t const * p_instance, + nrf_csense_pad_t * p_pad) +{ + uint16_t val = m_nrf_csense.raw_analog_values[p_pad->analog_input_number]; + + if (p_instance->min_max[p_pad->pad_index].min_value > val) + { + p_instance->min_max[p_pad->pad_index].min_value = val; + } + + if (p_instance->min_max[p_pad->pad_index].max_value < val) + { + p_instance->min_max[p_pad->pad_index].max_value = val; + } +} + + +/** + * @brief Function for calculating proportions on slider pad. + * + * @note This function help to self calibrate the pads. + * + * @param [in] p_instance Pointer to csense instance. + * @param [in] p_pad Pointer to pad to calculate ratio for. + * + * @return Difference between maximum and minimum values read on pads or 0 if minimum is bigger than maximum. + * + */ +__STATIC_INLINE uint16_t ratio_calculate(nrf_csense_instance_t const * p_instance, + nrf_csense_pad_t * p_pad) +{ + if (p_instance->min_max[p_pad->pad_index].max_value > p_instance->min_max[p_pad->pad_index].min_value) + { + uint16_t scale; + scale = (uint16_t)(p_instance->min_max[p_pad->pad_index].max_value - + p_instance->min_max[p_pad->pad_index].min_value); + return scale; + } + else + { + return 0; + } +} + + +/** + * @brief Function for calculating step. + * + * Function calculates step for slider basing on index of touched pads and values measured on + * them and neighboring pads. + * + * @param[in] p_instance Pointer to csense instance. + * @param[in] pad_index Index of the pad. + * + * @return Detected touched step. + */ +static uint16_t calculate_step(nrf_csense_instance_t * p_instance, + uint8_t pad_index) +{ + uint16_t step = 0; + uint32_t values_sum; + uint32_t values_product; + + pad_index += 1; + + values_sum = m_values_buffer[pad_index] + m_values_buffer[pad_index - 1] + + m_values_buffer[pad_index + 1]; + values_product = (uint32_t)(p_instance->steps-1) * + (m_values_buffer[pad_index - 1] * (pad_index - 2) + + m_values_buffer[pad_index] * (pad_index - 1) + + m_values_buffer[pad_index + 1] * (pad_index)); + step = 1 + ROUNDED_DIV(values_product, (values_sum * (p_instance->number_of_pads - 1))); // Add 1 to the result of the division + // to get the appropriate range of values. + memset((void*)m_values_buffer, 0, sizeof(m_values_buffer)); + + return step; +} + + +/** + * @brief Function for finding mask of touched pads. + * + * @param [in] p_instance Pointer to csense instance. + * + * @return Mask of touched pads. + */ +static uint32_t find_touched_mask(nrf_csense_instance_t const * p_instance) +{ + uint32_t touched_mask = 0; + uint16_t max_value = 0; + uint16_t ratio; + nrf_csense_pad_t * p_pad; + + for (p_pad = p_instance->p_nrf_csense_pad; NULL != p_pad; p_pad = p_pad->p_next_pad) // run through all pads and look for those with biggest value + { + min_or_max_update(p_instance, p_pad); + + ratio = ratio_calculate(p_instance, p_pad); + if (ratio == 0) + { + return 0; + } + uint16_t val = + (uint16_t)(((uint32_t)(m_nrf_csense.raw_analog_values[p_pad->analog_input_number] - + p_instance->min_max[p_pad->pad_index].min_value) * + NRF_CSENSE_MAX_VALUE) / ratio); + m_values_buffer[p_pad->pad_index+1] = val; + + if (val > max_value) + { + max_value = val; + touched_mask = (1UL << (p_pad->pad_index)); + } + else if (val == max_value) + { + max_value = val; + touched_mask |= (1UL << (p_pad->pad_index)); + } + } + + return touched_mask; +} + + +/** + * @brief Function for finding touched pad. + * + * If there is more than one pad connected to an analog channel this functions which one was actually touched. This is done by + * comparing values of neighboring pads. + * + * @param [in] instance Pointer to csense instance. + * @param [in] touched_mask Mask of touched pads. + * + * @return Touched pad. + */ +static uint16_t find_touched_pad(nrf_csense_instance_t const * p_instance, + uint32_t touched_mask) +{ + uint8_t i; + uint8_t biggest_deviation = 0; + uint8_t temp_biggest = 0; + uint16_t pad = UINT16_MAX; + static uint16_t previous_pad = 0; + + for (i = 0; i < (p_instance->number_of_pads); i++) + { + if ((1UL << i) & touched_mask) + { + temp_biggest = m_values_buffer[i]; + temp_biggest += m_values_buffer[i + 2]; + + if ((i != 0) && (i != ((p_instance->number_of_pads-1)))) + { + temp_biggest /= 2; + } + + if ((temp_biggest > NRF_CSENSE_PAD_DEVIATION) && + (temp_biggest > biggest_deviation)) + { + biggest_deviation = temp_biggest; + pad = i; + } + } + } + + if (pad == UINT16_MAX) + { + pad = previous_pad; + } + else + { + previous_pad = pad; + } + + return pad; +} + + +/** + * @brief Function for finding touched step. + * + * @param [in] instance Pointer to csense instance. + * + * @return Detected touched step. + */ +static uint16_t find_touched_step(nrf_csense_instance_t * p_instance) +{ + uint32_t touched_mask = 0; + uint16_t pad = 0; + uint16_t step; + + touched_mask = find_touched_mask(p_instance); + + if (touched_mask == 0) + { + return UINT16_MAX; + } + + if ((touched_mask & (-(int32_t)touched_mask)) == touched_mask) // Check if there is only one pad with greatest value. + { + pad = 31 - __CLZ(touched_mask); + } + else + { + pad = find_touched_pad(p_instance, touched_mask); + } + + step = calculate_step(p_instance, pad); + return step; +} + + +/** + * @brief Event handler for csense. + * + * param [in] p_event_struct Pointer to event structure. + */ +static void csense_event_handler(nrf_drv_csense_evt_t * p_event_struct) +{ + nrf_csense_evt_t event; + static uint16_t prev_analog_values[MAX_ANALOG_INPUTS]; + bool touched = false; + nrf_csense_instance_t * instance; + uint8_t i; + + if ((m_nrf_csense.enabled_analog_channels_mask & (1UL << (p_event_struct->analog_channel))) == 0) + { + return; + } + + m_nrf_csense.raw_analog_values[p_event_struct->analog_channel] = p_event_struct->read_value; + + if (nrf_drv_csense_is_busy()) + { + return; + } + + for (instance = mp_nrf_csense_instance_head; instance != NULL; + instance = instance->p_next_instance) // run through all instances + { + if (instance->is_active) + { + event.p_instance = instance; + nrf_csense_pad_t * p_pad = instance->p_nrf_csense_pad; + + for (i = 0; i < MAX_ANALOG_INPUTS; i++) + { + if ((m_nrf_csense.raw_analog_values[i] < + (prev_analog_values[i] - NRF_CSENSE_PAD_HYSTERESIS)) || + (m_nrf_csense.raw_analog_values[i] > + (prev_analog_values[i] + NRF_CSENSE_PAD_HYSTERESIS))) + { + touched = true; + break; + } + } + + if (touched) + { + touched = false; + + for (p_pad = instance->p_nrf_csense_pad; p_pad != NULL; + p_pad = p_pad->p_next_pad) + { + if (m_nrf_csense.raw_analog_values[p_pad->analog_input_number] > + p_pad->threshold) + { + touched = true; + break; + } + } + } + else + { + continue; + } + + // Specify the event + if ((instance->is_touched) && touched) + { + // dragged + if (instance->number_of_pads > 1) + { + event.params.slider.step = find_touched_step(instance); + event.nrf_csense_evt_type = NRF_CSENSE_SLIDER_EVT_DRAGGED; + + m_nrf_csense.event_handler(&event); + } + } + else if ((!(instance->is_touched)) && touched) + { + // pressed + if (instance->number_of_pads > 1) + { + event.params.slider.step = find_touched_step(instance); + event.nrf_csense_evt_type = NRF_CSENSE_SLIDER_EVT_PRESSED; + } + else + { + event.nrf_csense_evt_type = NRF_CSENSE_BTN_EVT_PRESSED; + } + instance->is_touched = true; + + m_nrf_csense.event_handler(&event); + } + else if ((instance->is_touched) && (!touched)) + { + // released + if (instance->number_of_pads > 1) + { + event.params.slider.step = find_touched_step(instance); + event.nrf_csense_evt_type = NRF_CSENSE_SLIDER_EVT_RELEASED; + } + else + { + event.nrf_csense_evt_type = NRF_CSENSE_BTN_EVT_RELEASED; + } + instance->is_touched = false; + + m_nrf_csense.event_handler(&event); + } + else + { + // nothing changed + } + } + + touched = false; + } + + memset(m_values_buffer, 0, sizeof(m_values_buffer)); + memcpy(prev_analog_values, m_nrf_csense.raw_analog_values, + sizeof(m_nrf_csense.raw_analog_values)); +} + + +ret_code_t nrf_csense_init(nrf_csense_event_handler_t event_handler, + uint32_t ticks) +{ + ASSERT(event_handler != NULL); + ASSERT(m_nrf_csense.state == NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code; + + static const nrf_drv_csense_config_t m_csense_config = + { + .output_pin = NRF_CSENSE_OUTPUT_PIN + }; + + m_nrf_csense.event_handler = event_handler; + m_nrf_csense.ticks = ticks; + mp_nrf_csense_instance_head = NULL; + + err_code = app_timer_create(&nrf_csense_timer, APP_TIMER_MODE_REPEATED, csense_timer_handler); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = nrf_drv_csense_init(&m_csense_config, csense_event_handler); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + m_nrf_csense.state = NRF_DRV_STATE_INITIALIZED; + + return NRF_SUCCESS; +} + + +ret_code_t nrf_csense_uninit(void) +{ + ASSERT(m_nrf_csense.state != NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code; + nrf_csense_instance_t ** pp_instance = &mp_nrf_csense_instance_head; + + err_code = nrf_drv_csense_uninit(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (m_nrf_csense.enabled_analog_channels_mask != 0) + { + err_code = app_timer_stop(nrf_csense_timer); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + while ((*pp_instance) != NULL) + { + nrf_csense_instance_t ** pp_instance_next = (&(*pp_instance)->p_next_instance); + (*pp_instance) = NULL; + pp_instance = pp_instance_next; + } + + memset((void *)&m_nrf_csense, 0, sizeof(nrf_csense_t)); + + m_nrf_csense.state = NRF_DRV_STATE_UNINITIALIZED; + + + return NRF_SUCCESS; +} + +ret_code_t nrf_csense_add(nrf_csense_instance_t * const p_instance) +{ + ASSERT(m_nrf_csense.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_instance->p_next_instance == NULL); + ASSERT(p_instance != NULL); + + ret_code_t err_code; + + nrf_csense_instance_t ** pp_instance = &mp_nrf_csense_instance_head; + + while ((*pp_instance) != NULL) + { + ASSERT((*pp_instance) != p_instance); + pp_instance = &((*pp_instance)->p_next_instance); + } + + *pp_instance = p_instance; + + err_code = nrf_csense_enable(p_instance); + return err_code; +} + +ret_code_t nrf_csense_enable(nrf_csense_instance_t * const p_instance) +{ + ASSERT(m_nrf_csense.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_instance != NULL); + + ret_code_t err_code; + nrf_csense_pad_t const * p_pad; + uint8_t analog_channels_mask = 0; + + if (m_nrf_csense.enabled_analog_channels_mask == 0) + { + err_code = app_timer_start(nrf_csense_timer, m_nrf_csense.ticks, NULL); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + p_instance->is_active = true; + + for (p_pad = p_instance->p_nrf_csense_pad; p_pad != NULL; p_pad = p_pad->p_next_pad) + { + p_instance->min_max[p_pad->pad_index].min_value = UINT16_MAX; + + // If channel was already enabled skip it. + if ((m_nrf_csense.enabled_analog_channels_mask & (1UL << (p_pad->analog_input_number))) == 0) + { + analog_channels_mask |= (1UL << (p_pad->analog_input_number)); + m_nrf_csense.enabled_analog_channels_mask |= (1UL << (p_pad->analog_input_number)); + } + } + + m_nrf_csense.state = NRF_DRV_STATE_POWERED_ON; + nrf_drv_csense_channels_enable(analog_channels_mask); + + return NRF_SUCCESS; +} + + +ret_code_t nrf_csense_disable(nrf_csense_instance_t * const p_instance) +{ + ASSERT(m_nrf_csense.state == NRF_DRV_STATE_POWERED_ON); + + ret_code_t err_code; + nrf_csense_instance_t * p_instance_temp = mp_nrf_csense_instance_head; + nrf_csense_pad_t const * p_pad; + uint8_t channels_mask = 0; + uint8_t instance_channels_mask = 0; + + for (p_instance_temp = mp_nrf_csense_instance_head; p_instance_temp != NULL; + p_instance_temp = p_instance_temp->p_next_instance) + { + for (p_pad = p_instance_temp->p_nrf_csense_pad; p_pad != NULL; p_pad = p_pad->p_next_pad) + { + if (p_instance_temp == p_instance) + { + instance_channels_mask |= (1UL << (p_pad->analog_input_number)); + p_instance->is_active = false; + } + else + { + channels_mask |= (1UL << (p_pad->analog_input_number)); + } + } + } + + nrf_drv_csense_channels_disable((~channels_mask) & instance_channels_mask); + + m_nrf_csense.enabled_analog_channels_mask = channels_mask; + + if (m_nrf_csense.enabled_analog_channels_mask == 0) + { + err_code = app_timer_stop(nrf_csense_timer); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + m_nrf_csense.state = NRF_DRV_STATE_INITIALIZED; + } + + return NRF_SUCCESS; +} + + +ret_code_t nrf_csense_ticks_set(uint32_t ticks) +{ + ASSERT(m_nrf_csense.state != NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code; + + if (nrf_drv_csense_is_busy()) + { + return NRF_ERROR_BUSY; + } + + m_nrf_csense.ticks = ticks; + + if (m_nrf_csense.state == NRF_DRV_STATE_POWERED_ON) + { + err_code = app_timer_stop(nrf_csense_timer); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = app_timer_start(nrf_csense_timer, ticks, NULL); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +ret_code_t nrf_csense_steps_set(nrf_csense_instance_t * const p_instance, uint16_t steps) +{ + if (p_instance->is_active) + { + return NRF_ERROR_INVALID_STATE; + } + + p_instance->steps = steps; + + return NRF_SUCCESS; +} +#endif //NRF_MODULE_ENABLED(NRF_CSENSE) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/csense/nrf_csense.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/csense/nrf_csense.h new file mode 100644 index 0000000000000000000000000000000000000000..c5116832160eba3dffb85528cca42eee5fbd343b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/csense/nrf_csense.h @@ -0,0 +1,344 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CSENSE_H__ +#define NRF_CSENSE_H__ + +#include +#include "nrf.h" +#include "sdk_errors.h" +#include "app_timer.h" +#include "nrf_drv_csense.h" +#include "nrf_csense_macros.h" +#include "app_util.h" + +/** @file + * + * @defgroup nrf_csense Capacitive sensor library + * @{ + * @ingroup app_common + * + * @brief Module for using the capacitive sensor library with support for many instances of sliders, wheels, and buttons. + */ + +/** + * @brief Macro for returning the address of a variable. + */ +#define NRF_CSENSE_GET_INSTANCE_ID(instance) (&instance) + +/** + * @brief Statically allocate memory for the instance of a capacitive sensor. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_BUTTON_DEF(name, p1) NRF_CSENSE_INTERNAL_BUTTON_DEF(name, p1) + +/** + * @brief Macro for creating a 2-pad slider instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_SLIDER_2_DEF(name, steps_no, p1, p2) NRF_CSENSE_INTERNAL_SLIDER_2_DEF(name, steps_no, p1, p2) + +/** + * @brief Macro for creating a 3-pad slider instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_SLIDER_3_DEF(name, steps_no, p1, p2, p3) NRF_CSENSE_INTERNAL_SLIDER_3_DEF(name, steps_no, p1, p2, p3) + +/** + * @brief Macro for creating a 4-pad slider instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_SLIDER_4_DEF(name, steps_no, p1, p2, p3, p4) NRF_CSENSE_INTERNAL_SLIDER_4_DEF(name, steps_no, p1, p2, p3, p4) + +/** + * @brief Macro for creating a 5-pad slider instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p5 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_SLIDER_5_DEF(name, steps_no, p1, p2, p3, p4, p5) NRF_CSENSE_INTERNAL_SLIDER_5_DEF(name, steps_no, p1, p2, p3, p4, p5) + +/** + * @brief Macro for creating a 3-pad wheel instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_WHEEL_3_DEF(name, steps_no, p1, p2, p3) NRF_CSENSE_INTERNAL_WHEEL_3_DEF(name, steps_no, p1, p2, p3) + +/** + * @brief Macro for creating a 4-pad wheel instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_WHEEL_4_DEF(name, steps_no, p1, p2, p3, p4) NRF_CSENSE_INTERNAL_WHEEL_4_DEF(name, steps_no, p1, p2, p3, p4) + +/** + * @brief Macro for creating a 5-pad wheel instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p5 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_WHEEL_5_DEF(name, steps_no, p1, p2, p3, p4, p5) NRF_CSENSE_INTERNAL_WHEEL_5_DEF(name, steps_no, p1, p2, p3, p4, p5) + +/** + * @cond (NODOX) + * @defgroup nrf_csense_internal Auxiliary internal types declarations + * @brief Module for internal usage inside the library only. + * @details These definitions are available to the user, but they should not + * be accessed directly. Use the API to access them. + * @{ + * + */ + + /* + * @brief Forward declaration of capacitive sensor instance. + */ + typedef struct nrf_csense_instance_s nrf_csense_instance_t; + + /* + * @brief Forward declaration of a capacitive sensor pad. + */ + typedef struct nrf_csense_pad_s nrf_csense_pad_t; + + /** + * @brief Structure with pointer to min and max values measured on pads. + */ + typedef struct + { + uint16_t max_value; //!< Max value measured on pads. + uint16_t min_value; //!< Min value measured on pads. + }nrf_csense_min_max_t; + + /** + * @brief Structure with single instance parameters. This can be either a slider or a button. + */ + struct nrf_csense_instance_s + { + nrf_csense_instance_t * p_next_instance; //!< Pointer to the next instance. + nrf_csense_pad_t * p_nrf_csense_pad; //!< Pointer to the first pad of the module. + nrf_csense_min_max_t * min_max; //!< Structure with pointers to min and max values measured on pads. + uint16_t steps; //!< Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + uint8_t number_of_pads; //!< Number of pads that the instance is using. + bool is_active; //!< Flag to indicate if the instance is active. + bool is_touched; //!< Flag to indicate if the instance is touched. + void * p_context; //!< General purpose pointer. + }; + + /* Structure with single pad parameters used for initialization. */ + struct nrf_csense_pad_s + { + nrf_csense_pad_t * p_next_pad; //!< Pointer to the next pad. + uint16_t threshold; //!< Threshold voltage on pad/time of charging to decide if the pad was touched. + uint8_t pad_index; //!< Index of the pad. + uint8_t analog_input_number; //!< Analog input connected to the pad. + }; + +/** @} + * @endcond + */ + +/** + * @brief Enum for nrf_csense events. + */ +typedef enum +{ + NRF_CSENSE_BTN_EVT_PRESSED, //!< Event for pad pressed. + NRF_CSENSE_BTN_EVT_RELEASED, //!< Event for pad released. + NRF_CSENSE_SLIDER_EVT_PRESSED, //!< Event for pad pressed. + NRF_CSENSE_SLIDER_EVT_RELEASED, //!< Event for pad released. + NRF_CSENSE_SLIDER_EVT_DRAGGED, //!< Event for pad dragged. +}nrf_csense_evt_type_t; + +/** + * @brief Structure with slider event data including the measured step. + */ +typedef struct +{ + uint16_t step; //!< Measured step. +} nrf_csense_slider_evt_t; + +/** + * @brief Event data union for nrf_csense events. + */ +typedef union +{ + nrf_csense_slider_evt_t slider; //!< Structure with slider event data including the measured step. +} nrf_csense_evt_param_t; + +/** + * @brief Structure with event parameters. + */ +typedef struct +{ + nrf_csense_evt_type_t nrf_csense_evt_type; //!< Type of event. + nrf_csense_instance_t * p_instance; //!< Pointer to instance. + nrf_csense_evt_param_t params; //!< Event data union for nrf_csense events. +}nrf_csense_evt_t; + +/** + * @brief Capacitive sensor handler type. + */ +typedef void (* nrf_csense_event_handler_t)(nrf_csense_evt_t * p_evt); + +/** + * @brief Function for setting a handler of the instance. + * + * @param [in] p_instance Pointer to the instance whose steps are going to be changed. + * @param [in] p_context General purpose pointer. Will be passed to the callback function. + */ +__STATIC_INLINE void nrf_csense_instance_context_set(nrf_csense_instance_t * const p_instance, void * p_context) +{ + p_instance->p_context = p_context; +} + +/** + * @brief Function for initializing the module. After initialization, no instances are enabled. + * + * @param [in] event_handler Event handler for the Capacitive Sensor module. + * @param [in] ticks Time in app_timer ticks between next conversions. + * + * @retval NRF_ERROR_INVALID_PARAM If invalid parameter was provided. + * @retval NRF_ERROR_INVALID_STATE If one of the used modules is in invalid state. + * @retval NRF_ERROR_INTERNAL If an error occured while initializing one of the modules used by the capacitive sensor library. + * @retval NRF_SUCCESS If the module was initialized successfully. + */ +ret_code_t nrf_csense_init(nrf_csense_event_handler_t event_handler, uint32_t ticks); + +/** + * @brief Function for uninitializing the module. + * + * @return Values returned by @ref nrf_drv_csense_uninit and @ref app_timer_stop. + */ +ret_code_t nrf_csense_uninit(void); + +/** + * @brief Function for adding an instance of capacitive sensor to a linked list. + * + * The function calls @ref nrf_csense_enable to enable the instance that was added to the linked list. + * + * @param [in] p_instance Pointer to the capacitive sensor instance. It is saved by the module and is used whenever the instance is referred. + * + * @return Values returned by @ref nrf_csense_enable. + */ +ret_code_t nrf_csense_add(nrf_csense_instance_t * const p_instance); + +/** + * @brief Function for enabling a single instance. + * + * @param [in,out] p_instance Pointer to the capacitive sensor instance. It is saved by the module and is used whenever the instance is referred. + * + * @return Values returned by @ref app_timer_start. + */ +ret_code_t nrf_csense_enable(nrf_csense_instance_t * const p_instance); + +/** + * @brief Function for disabling an instance. + * + * @param [in] p_instance Pointer to the instance to be disabled. + * + * @retval NRF_ERROR_INVALID_PARAM If the instance was already disabled. + * @retval NRF_SUCCESS If the instance was disabled successfully. + */ +ret_code_t nrf_csense_disable(nrf_csense_instance_t * const p_instance); + +/** + * @brief Function for setting ticks between next measurements. + * + * @param [in] ticks New time between conversions in app_timer ticks. + * + * @retval NRF_ERROR_BUSY If the capacitive sensor was busy. + * @retval NRF_ERROR_INVALID_PARAM If an invalid parameter was provided. + * @retval NRF_ERROR_INVALID_STATE If app_timer was in invalid state. + * @retval NRF_SUCCESS If ticks were set successfully. + */ +ret_code_t nrf_csense_ticks_set(uint32_t ticks); + +/** + * @brief Function for setting steps of an instance. + * + * Note that you have do disable the instance before you can change its number of steps. + * + * @param [in] p_instance Pointer to the instance whose steps are going to be changed. + * @param [in] steps New steps value. + * + * @retval NRF_ERROR_BUSY If the capacitive sensor was busy. + * @retval NRF_SUCCESS If steps were set successfully. + */ +ret_code_t nrf_csense_steps_set(nrf_csense_instance_t * const p_instance, uint16_t steps); + + +/** @} */ + +#endif //NRF_CSENSE_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/csense/nrf_csense_macros.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/csense/nrf_csense_macros.h new file mode 100644 index 0000000000000000000000000000000000000000..72b933889a8be7c6e44fc469881f71e8aa795f15 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/csense/nrf_csense_macros.h @@ -0,0 +1,359 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_CSENSE_MACROS_H__ +#define NRF_CSENSE_MACROS_H__ + +/** @file + * + * @defgroup nrf_csense_macros Capacitive sensor macros + * @{ + * @ingroup nrf_csense + * + * @brief A set of macros to facilitate creation of a new capacitive sensor instance. + */ + +#define NRF_CSENSE_INTERNAL_BUTTON_DEF(name, p1) \ + static nrf_csense_pad_t CONCAT_2(name, _pad) = \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }; \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax); \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = &CONCAT_2(name, _pad), \ + .min_max = &CONCAT_2(name, _minmax), \ + .steps = 1, \ + .number_of_pads = 1, \ + .is_active = false, \ + .is_touched = false \ + }; + +#define NRF_CSENSE_INTERNAL_SLIDER_2_DEF(name, steps_no, p1, p2) \ + static nrf_csense_pad_t CONCAT_2(name, _pad)[2] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + } \ + }; \ + \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[2]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 2, \ + .is_active = false, \ + .is_touched = false \ + }; + +#define NRF_CSENSE_INTERNAL_SLIDER_3_DEF(name, steps_no, p1, p2, p3) \ + static nrf_csense_pad_t CONCAT_2(name, _pad)[3] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[2], \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p3, \ + .pad_index = 2, \ + .analog_input_number = GET_ARG_1 p3 \ + } \ + }; \ + \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[3]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 3, \ + .is_active = false, \ + .is_touched = false \ + }; + +#define NRF_CSENSE_INTERNAL_SLIDER_4_DEF(name, steps_no, p1, p2, p3, p4) \ + static nrf_csense_pad_t CONCAT_2(name, _pad)[4] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[2], \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[3], \ + .threshold = GET_ARG_2 p3, \ + .pad_index = 2, \ + .analog_input_number = GET_ARG_1 p3 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p4, \ + .pad_index = 3, \ + .analog_input_number = GET_ARG_1 p4 \ + } \ + }; \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[4]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 4, \ + .is_active = false, \ + .is_touched = false \ + }; + +#define NRF_CSENSE_INTERNAL_SLIDER_5_DEF(name, steps_no, p1, p2, p3, p4, p5) \ + static nrf_csense_pad_t CONCAT_2(name, _pad)[5] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[2], \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[3], \ + .threshold = GET_ARG_2 p3, \ + .pad_index = 2, \ + .analog_input_number = GET_ARG_1 p3 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[4], \ + .threshold = GET_ARG_2 p4, \ + .pad_index = 3, \ + .analog_input_number = GET_ARG_1 p4 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p5, \ + .pad_index = 4, \ + .analog_input_number = GET_ARG_1 p5 \ + } \ + }; \ + \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[5]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 5, \ + .is_active = false, \ + .is_touched = false \ + }; + +#define NRF_CSENSE_INTERNAL_WHEEL_3_DEF(name, steps_no, p1, p2, p3) \ + static nrf_csense_pad_t CONCAT_2(name, _pad)[4] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[2], \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[3], \ + .threshold = GET_ARG_2 p3, \ + .pad_index = 2, \ + .analog_input_number = GET_ARG_1 p3 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 3, \ + .analog_input_number = GET_ARG_1 p1 \ + } \ + }; \ + \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[4]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 4, \ + .is_active = false, \ + .is_touched = false \ + }; + + +#define NRF_CSENSE_INTERNAL_WHEEL_4_DEF(name, steps_no, p1, p2, p3, p4) \ + static nrf_csense_pad_t CONCAT_2(name, _pad)[5] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[2], \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[3], \ + .threshold = GET_ARG_2 p3, \ + .pad_index = 2, \ + .analog_input_number = GET_ARG_1 p3 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[4], \ + .threshold = GET_ARG_2 p4, \ + .pad_index = 3, \ + .analog_input_number = GET_ARG_1 p4 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 4, \ + .analog_input_number = GET_ARG_1 p1 \ + } \ + }; \ + \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[5]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 5, \ + .is_active = false, \ + .is_touched = false \ + }; + +#define NRF_CSENSE_INTERNAL_WHEEL_5_DEF(name, steps_no, p1, p2, p3, p4, p5)\ + static nrf_csense_pad_t CONCAT_2(name, _pad)[6] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[2], \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[3], \ + .threshold = GET_ARG_2 p3, \ + .pad_index = 2, \ + .analog_input_number = GET_ARG_1 p3 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[4], \ + .threshold = GET_ARG_2 p4, \ + .pad_index = 3, \ + .analog_input_number = GET_ARG_1 p4 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[5], \ + .threshold = GET_ARG_2 p5, \ + .pad_index = 4, \ + .analog_input_number = GET_ARG_1 p5 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 5, \ + .analog_input_number = GET_ARG_1 p1 \ + } \ + }; \ + \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[6]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 6, \ + .is_active = false, \ + .is_touched = false \ + }; + +/** @} */ + +#endif // NRF_CSENSE_MACROS_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/csense_drv/nrf_drv_csense.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/csense_drv/nrf_drv_csense.c new file mode 100644 index 0000000000000000000000000000000000000000..e6fe0a8cb3a24d26134b2d7e8c9ce7a041e76750 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/csense_drv/nrf_drv_csense.c @@ -0,0 +1,633 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_DRV_CSENSE) +#include "nrf_drv_csense.h" +#include "nrf_peripherals.h" +#include "nrf_gpio.h" +#include "app_error.h" +#include "app_util_platform.h" +#include "nrf_assert.h" +#include "string.h" +#include + +#if defined(__CORTEX_M) && (__CORTEX_M < 4) +#ifndef ARM_MATH_CM0PLUS +#define ARM_MATH_CM0PLUS +#endif +/*lint -save -e689 */ +#include "arm_math.h" +/*lint -restore */ +#endif + +#if USE_COMP +#include "nrf_drv_comp.h" +#include "nrf_drv_ppi.h" +#include "nrf_drv_timer.h" +#endif //USE_COMP + +#if USE_COMP == 0 +#ifdef ADC_PRESENT +#include "nrf_drv_adc.h" + +/** + * @defgroup adc_defines ADC defines to count input voltage. + * @{ + */ +#define ADC_RES_10BIT 1024 +#define ADC_INPUT_PRESCALER 3 +#define ADC_REF_VBG_VOLTAGE 1.2 +/* @} */ + +/* ADC channel used to call conversion. */ +static nrf_drv_adc_channel_t adc_channel = NRF_DRV_ADC_DEFAULT_CHANNEL(0); +#elif defined(SAADC_PRESENT) +#include "nrf_drv_saadc.h" + +/** + * @defgroup saadc_defines SAADC defines to count input voltage. + * @{ + */ +#define SAADC_RES_10BIT 1024 +#define SAADC_INPUT_PRESCALER 3 +#define SAADC_REF_VBG_VOLTAGE 0.6 +/* @} */ + +/* SAADC channel used to call conversion. */ +static nrf_saadc_channel_config_t saadc_channel = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0); +#endif //ADC_PRESENT +#endif //USE_COMP + +#if USE_COMP +/* Number of channels required by PPI. */ +#define PPI_REQUIRED_CHANNELS 3 + +/* Array of PPI channels. */ +static nrf_ppi_channel_t m_ppi_channels[PPI_REQUIRED_CHANNELS]; + + +/** + * @defgroup timer_instances Timer instances. + * @{ + */ +static const nrf_drv_timer_t m_timer0 = NRF_DRV_TIMER_INSTANCE(TIMER0_FOR_CSENSE); +static const nrf_drv_timer_t m_timer1 = NRF_DRV_TIMER_INSTANCE(TIMER1_FOR_CSENSE); +/* @} */ +#endif //USE_COMP + +/* Configuration of the capacitive sensor module. */ +typedef struct +{ + volatile nrf_drv_state_t module_state; /**< State of the module. */ + nrf_drv_csense_event_handler_t event_handler; /**< Event handler for capacitor sensor events. */ + uint16_t analog_values[MAX_ANALOG_INPUTS]; /**< Array containing analog values measured on the corresponding COMP/ADC channel. */ + volatile bool busy; /**< Indicates state of module - busy if there are ongoing conversions. */ + volatile uint8_t cur_chann_idx; /**< Current channel to be read if enabled. */ + volatile uint8_t adc_channels_input_mask; /**< Enabled channels. */ + uint8_t output_pin; /**< Pin to generate signal charging capacitors. */ + uint8_t channels_to_read; /**< Mask of channels remaining to be read in the current measurement. */ + volatile bool timers_powered_on; /**< Flag to indicate if timers were already started. */ +}csense_t; + +static csense_t m_csense; + +/** + * @brief Function for determining the next analog channel to be read. + */ +__STATIC_INLINE void calculate_next_channel(void) +{ + m_csense.cur_chann_idx = 31 - __CLZ(m_csense.channels_to_read); +} + +/** + * @brief Function for handling conversion values. + * + * @param[in] val Value received from ADC or COMP. + */ +static void conversion_handler(uint16_t val) +{ + nrf_drv_csense_evt_t event_struct; + +#if USE_COMP == 0 + nrf_gpio_pin_set(m_csense.output_pin); +#endif //USE_COMP + + m_csense.analog_values[m_csense.cur_chann_idx] = val; + + event_struct.read_value = val; + event_struct.analog_channel = m_csense.cur_chann_idx; + + m_csense.channels_to_read &= ~(1UL< 0) // Start new conversion. + { + ret_code_t err_code; + calculate_next_channel(); + err_code = nrf_drv_csense_sample(); + if(err_code != NRF_SUCCESS) + { + return; + } + } +} + +#if USE_COMP +/** + * @brief Timer0 interrupt handler. + * + * @param[in] event_type Timer event. + * @param[in] p_context General purpose parameter set during initialization of + * the timer. This parameter can be used to pass + * additional information to the handler function, for + * example, the timer ID. + */ +static void counter_compare_handler(nrf_timer_event_t event_type, void* p_context) +{ + if(event_type == NRF_TIMER_EVENT_COMPARE0) + { + uint16_t val = nrf_drv_timer_capture_get(&m_timer1, NRF_TIMER_CC_CHANNEL1); + nrf_drv_timer_pause(&m_timer1); + nrf_drv_timer_clear(&m_timer1); + + /* Handle finished measurement. */ + conversion_handler(val); + } +} + +/** + * @brief Dummy handler. + * + * @param[in] event_type Timer event. + * @param[in] p_context General purpose parameter set during initialization of + * the timer. This parameter can be used to pass + * additional information to the handler function, for + * example, the timer ID. + */ +static void dummy_handler(nrf_timer_event_t event_type, void* p_context){} + +/** + * @brief Function for initializing timers. + * + * @retval NRF_ERROR_INTERNAL If there were error initializing timers. + * @retval NRF_SUCCESS If timers were initialized successfully. + */ +static ret_code_t timer_init(void) +{ + ret_code_t err_code; + + //set first timer in timer mode to get period of relaxation oscillator + nrf_drv_timer_config_t timer_config = NRF_DRV_TIMER_DEFAULT_CONFIG; + timer_config.mode = NRF_TIMER_MODE_TIMER; + err_code = nrf_drv_timer_init(&m_timer1, &timer_config, dummy_handler); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + //set second timer in counter mode and generate event on tenth period + timer_config.mode = NRF_TIMER_MODE_COUNTER; + err_code = nrf_drv_timer_init(&m_timer0, &timer_config, counter_compare_handler); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + nrf_drv_timer_extended_compare(&m_timer0, NRF_TIMER_CC_CHANNEL0, MEASUREMENT_PERIOD, (nrf_timer_short_mask_t)(NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK | NRF_TIMER_SHORT_COMPARE0_STOP_MASK), true); + + return NRF_SUCCESS; +} + +/** + * @brief Function for initializing and enabling PPI channels. + * + * @retval NRF_ERROR_INTERNAL If there were error initializing or enabling PPI channels. + * @retval NRF_SUCCESS If PPI channels were initialized and enabled successfully. + */ +static ret_code_t ppi_init(void) +{ + ret_code_t err_code; + uint8_t i; + + err_code = nrf_drv_ppi_init(); + if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED)) + { + return NRF_ERROR_INTERNAL; + } + + for(i = 0; i < PPI_REQUIRED_CHANNELS ; i++) + { + err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channels[i]); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + } + + err_code = nrf_drv_ppi_channel_assign(m_ppi_channels[0], nrf_drv_comp_event_address_get(NRF_COMP_EVENT_CROSS), nrf_drv_timer_task_address_get(&m_timer0, NRF_TIMER_TASK_COUNT)); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + err_code = nrf_drv_ppi_channel_assign(m_ppi_channels[1], nrf_drv_timer_event_address_get(&m_timer0, NRF_TIMER_EVENT_COMPARE0), nrf_drv_timer_task_address_get(&m_timer1, NRF_TIMER_TASK_CAPTURE1)); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + err_code = nrf_drv_ppi_channel_fork_assign(m_ppi_channels[1], nrf_drv_comp_task_address_get(NRF_COMP_TASK_STOP)); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + err_code = nrf_drv_ppi_channel_assign(m_ppi_channels[2], nrf_drv_comp_event_address_get(NRF_COMP_EVENT_READY), nrf_drv_timer_task_address_get(&m_timer0, NRF_TIMER_TASK_CLEAR)); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + err_code = nrf_drv_ppi_channel_fork_assign(m_ppi_channels[2], nrf_drv_timer_task_address_get(&m_timer1, NRF_TIMER_TASK_CLEAR)); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + + for(i = 0; i < PPI_REQUIRED_CHANNELS ; i++) + { + err_code = nrf_drv_ppi_channel_enable(m_ppi_channels[i]); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + } + + return NRF_SUCCESS; +} + +/** + * @brief Dummy handler for COMP events. + * + * @param[in] event COMP event. + */ +static void comp_event_handler(nrf_comp_event_t event){} + +/** + * @brief Function for initializing COMP module in relaxation oscillator mode. + * + * @note The frequency of the oscillator depends on threshold voltages, current source and capacitance of pad and can be calculated as f_OSC = I_SOURCE / (2C·(VUP-VDOWN) ). + * + * @retval NRF_ERROR_INTERNAL If there were error while initializing COMP driver. + * @retval NRF_SUCCESS If the COMP driver initialization was successful. + */ +static ret_code_t comp_init(void) +{ + ret_code_t err_code; + nrf_drv_comp_config_t m_comp_config = NRF_DRV_COMP_DEFAULT_CONFIG(NRF_COMP_INPUT_0); + + /* Workaround for Errata 12 "COMP: Reference ladder is not correctly calibrated" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + *(volatile uint32_t *)0x40013540 = (*(volatile uint32_t *)0x10000324 & 0x00001F00) >> 8; + + m_comp_config.isource = NRF_COMP_ISOURCE_Ien10uA; + + err_code = nrf_drv_comp_init(&m_comp_config, comp_event_handler); + if(err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + return NRF_SUCCESS; +} +#endif //USE_COMP + +#if USE_COMP == 0 +#ifdef ADC_PRESENT +/** + * @brief ADC handler. + * + * @param[in] p_event Pointer to analog-to-digital converter driver event. + */ +void adc_handler(nrf_drv_adc_evt_t const * p_event) +{ + nrf_gpio_pin_set(m_csense.output_pin); + uint16_t val; + val = (uint16_t)(p_event->data.sample.sample * + ADC_REF_VBG_VOLTAGE * 1000 * + ADC_INPUT_PRESCALER / ADC_RES_10BIT); + conversion_handler(val); +} + +/** + * @brief Function for initializing ADC. + */ +static ret_code_t adc_init(void) +{ + ret_code_t err_code; + + adc_channel.config.config.input = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD; + + nrf_drv_adc_config_t adc_config = NRF_DRV_ADC_DEFAULT_CONFIG; + err_code = nrf_drv_adc_init(&adc_config, adc_handler); + if(err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + nrf_gpio_pin_set(m_csense.output_pin); + + return NRF_SUCCESS; +} +#elif defined(SAADC_PRESENT) +/** + * @brief SAADC handler. + * + * @param[in] p_event Pointer to analog-to-digital converter driver event. + */ +void saadc_handler(nrf_drv_saadc_evt_t const * p_event) +{ + nrf_gpio_pin_set(m_csense.output_pin); + uint16_t val; + (void)nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 1); + val = (uint16_t)(*p_event->data.done.p_buffer * + SAADC_REF_VBG_VOLTAGE * 1000 * + SAADC_INPUT_PRESCALER / SAADC_RES_10BIT); + conversion_handler(val); +} + +/** + * @brief Function for initializing SAADC. + */ +static ret_code_t saadc_init(void) +{ + ret_code_t err_code; + static nrf_saadc_value_t saadc_value; + + saadc_channel.gain = NRF_SAADC_GAIN1_3; + + err_code = nrf_drv_saadc_init(NULL, saadc_handler); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + nrf_gpio_pin_set(m_csense.output_pin); + + err_code = nrf_drv_saadc_channel_init(0, &saadc_channel); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + err_code = nrf_drv_saadc_buffer_convert(&saadc_value, 1); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + nrf_saadc_disable(); + + return NRF_SUCCESS; +} +#endif //ADC_PRESENT +#endif //USE_COMP + +ret_code_t nrf_drv_csense_init(nrf_drv_csense_config_t const * p_config, nrf_drv_csense_event_handler_t event_handler) +{ + ASSERT(m_csense.module_state == NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_config->output_pin <= NUMBER_OF_PINS); + + ret_code_t err_code; + + if(p_config == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + if(event_handler == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + m_csense.busy = false; + +#if USE_COMP == 0 + m_csense.output_pin = p_config->output_pin; + nrf_gpio_cfg_output(m_csense.output_pin); + nrf_gpio_pin_set(m_csense.output_pin); +#endif //COMP_PRESENT + + m_csense.event_handler = event_handler; + +#if USE_COMP + err_code = comp_init(); + if(err_code != NRF_SUCCESS) + { + return err_code; + } + err_code = timer_init(); + if(err_code != NRF_SUCCESS) + { + return err_code; + } + err_code = ppi_init(); + if(err_code != NRF_SUCCESS) + { + return err_code; + } +#else +#ifdef ADC_PRESENT + err_code = adc_init(); + if(err_code != NRF_SUCCESS) + { + return err_code; + } +#elif defined(SAADC_PRESENT) + err_code = saadc_init(); + if(err_code != NRF_SUCCESS) + { + return err_code; + } +#endif //ADC_PRESENT +#endif //USE_COMP + + m_csense.module_state = NRF_DRV_STATE_INITIALIZED; + + return NRF_SUCCESS; +} + +ret_code_t nrf_drv_csense_uninit(void) +{ + ASSERT(m_csense.module_state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_drv_csense_channels_disable(0xFF); + +#if USE_COMP + ret_code_t err_code; + uint8_t i; + + nrf_drv_timer_uninit(&m_timer0); + nrf_drv_timer_uninit(&m_timer1); + nrf_drv_comp_uninit(); + for(i =0; i < 3; i++) + { + err_code = nrf_drv_ppi_channel_free(m_ppi_channels[i]); + if(err_code != NRF_SUCCESS) + { + return err_code; + } + } + err_code = nrf_drv_ppi_uninit(); + if(err_code != NRF_SUCCESS) + { + return err_code; + } +#else +#ifdef ADC_PRESENT + nrf_drv_adc_uninit(); +#elif defined(SAADC_PRESENT) + nrf_drv_saadc_uninit(); +#endif //ADC_PRESENT +#endif //USE_COMP + + m_csense.module_state = NRF_DRV_STATE_UNINITIALIZED; + + memset((void*)&m_csense, 0, sizeof(m_csense)); + + return NRF_SUCCESS; +} + +void nrf_drv_csense_channels_enable(uint8_t channels_mask) +{ + ASSERT(m_csense.module_state != NRF_DRV_STATE_UNINITIALIZED); + + m_csense.busy = true; + + m_csense.module_state = NRF_DRV_STATE_POWERED_ON; + + m_csense.adc_channels_input_mask |= channels_mask; + + m_csense.busy = false; +} + +void nrf_drv_csense_channels_disable(uint8_t channels_mask) +{ + ASSERT(m_csense.module_state == NRF_DRV_STATE_POWERED_ON); + + m_csense.adc_channels_input_mask &= ~channels_mask; + + if(m_csense.adc_channels_input_mask == 0) + { + m_csense.module_state = NRF_DRV_STATE_INITIALIZED; + } +} + +uint16_t nrf_drv_csense_channel_read(uint8_t csense_channel) +{ + return m_csense.analog_values[csense_channel]; +} + +ret_code_t nrf_drv_csense_sample(void) +{ + ASSERT(m_csense.module_state == NRF_DRV_STATE_POWERED_ON); + + if(m_csense.adc_channels_input_mask != 0) + { + if(m_csense.channels_to_read == 0) + { +#if USE_COMP == 0 && defined(SAADC_PRESENT) + nrf_saadc_enable(); +#endif + if(nrf_drv_csense_is_busy() == true) + { + return NRF_ERROR_BUSY; + } + m_csense.busy = true; + m_csense.channels_to_read = m_csense.adc_channels_input_mask; + calculate_next_channel(); + } + +#if USE_COMP + if (!m_csense.timers_powered_on) + { + nrf_drv_timer_enable(&m_timer0); + nrf_drv_timer_enable(&m_timer1); + m_csense.timers_powered_on = true; + } + else + { + nrf_drv_timer_resume(&m_timer0); + nrf_drv_timer_resume(&m_timer1); + } + nrf_drv_comp_pin_select((nrf_comp_input_t)m_csense.cur_chann_idx); + nrf_drv_comp_start(0, 0); +#else + ret_code_t err_code; +#ifdef ADC_PRESENT + adc_channel.config.config.ain = (nrf_adc_config_input_t)(1< +#include "sdk_errors.h" +#include "app_timer.h" +#include "nrf_drv_common.h" + +/** @file + * + * @defgroup nrf_drv_csense Capacitive sensor low-level library + * @{ + * @ingroup app_common + * + * @brief Module for using the capacitive sensor on low-energy level. + */ + +/** @brief Maximum number of analog inputs. */ +#define MAX_ANALOG_INPUTS 8 + +/** + * @brief Module initializing structure. + */ +typedef struct +{ + uint8_t output_pin; /**< Pin on which to generate voltage for charging the capacitors. */ +}nrf_drv_csense_config_t; + +/** + * @brief Structure holding event parameters. + */ +typedef struct +{ + uint16_t read_value; /**< Value which was read on the analog channel. For nRF51, this value is voltage in millivolts. For nRF52, it is time in ticks of 10 periods of the relaxation oscillator. Voltage corresponds to capacitance of the pad attached to analog channel and gets higher once it + is touched. Period of relaxation also corresponds to the pad capacitance and increases its value when capacitance gets + higher. */ + uint8_t analog_channel; /**< Index of the analog channel from which the value was read. */ +}nrf_drv_csense_evt_t; + +/** + * @brief Capacitive sensor event handler. Called from conversion handler. + * + * @param[in] event_struct Structure holding event parameters. + */ +typedef void (* nrf_drv_csense_event_handler_t) (nrf_drv_csense_evt_t * p_event_struct); + +/** + * @brief Function for initializing the module. + * + * @details After calling this function, the module is in initialized state and all channels are disabled. The @ref nrf_drv_csense_channels_enable + * function must be called. This function initializes all modules required by the capacitive sensor library: ADC for (nRF51) or TIMERs, PPIs, and COMP (for nRF52). + * + * @param[in] p_config Structure for initializing the module. + * @param[in] event_handler Event handler for capacitive sensor events. + * + * @retval NRF_ERROR_INVALID_PARAM Invalid parameter. + * @retval NRF_ERROR_NO_MEM Timer operations queue was full. + * @retval NRF_ERROR_INTERNAL Error occurred during timers, PPI's, or COMP initialization. + * @retval NRF_SUCCESS Module was initialized successfully. + * + * @sa nrf_drv_csense_channels_enable + */ +ret_code_t nrf_drv_csense_init(nrf_drv_csense_config_t const * p_config, nrf_drv_csense_event_handler_t event_handler); + +/** + * @brief Function for unintializing the capacitive sensor. Clears the mask of enabled channels. + * + * @return Values returned by @ref nrf_drv_ppi_channel_free. + */ +ret_code_t nrf_drv_csense_uninit(void); + +/** + * @brief Function for enabling analog channels for the capacitive sensor. + * + * @param[in] channels_mask Mask of analog channels to be enabled. + */ +void nrf_drv_csense_channels_enable(uint8_t channels_mask); + +/** + * @brief Function for disabling analog channels of the capacitive sensor. + * + * @param[in] channels_mask Mask of analog channels to be disabled. + */ +void nrf_drv_csense_channels_disable(uint8_t channels_mask); + +/** + * @brief Function for getting the last read value from an analog channel. + * + * @param[in] csense_channel Number of the channel to get the value from. + * + * @return Analog value measured on the channel. + */ +uint16_t nrf_drv_csense_channel_read(uint8_t csense_channel); + +/** + * @brief Function for triggering a measurement on all enabled analog channels. The handler will be called on every completed measurement. + * + * @retval NRF_ERROR_BUSY If the module was busy or SAADC module is in use and was busy. + * @retval NRF_SUCCESS If the measurement was triggered successfully. + */ +ret_code_t nrf_drv_csense_sample(void); + +/** + * @brief Function for checking if the module is busy. + * + * @return True if busy or false if not busy. + */ +bool nrf_drv_csense_is_busy(void); + +/** @} */ + +#endif //NRF_DRV_CSENSE_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/ecc/ecc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/ecc/ecc.c new file mode 100644 index 0000000000000000000000000000000000000000..4f5686bdb284de56cb833f30a3d54b6cbeb9127a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/ecc/ecc.c @@ -0,0 +1,206 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @brief Elliptic Curve Cryptography Interface + * + */ + +#include +#include +#include +#include "nordic_common.h" +#include "app_timer.h" +#include "app_util.h" +#include "nrf_log.h" +#include "nrf_drv_rng.h" +#include "ecc.h" + +#include "uECC.h" + + +static int ecc_rng(uint8_t *dest, unsigned size) +{ + nrf_drv_rng_block_rand(dest, (uint32_t) size); + return 1; +} + +void ecc_init(bool rng) +{ + if(rng) + { + uECC_set_rng(ecc_rng); + } +} + +ret_code_t ecc_p256_keypair_gen(uint8_t *p_le_sk, uint8_t *p_le_pk) +{ + const struct uECC_Curve_t * p_curve; + + if (!p_le_sk || !p_le_pk) + { + return NRF_ERROR_NULL; + } + + if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_pk)) + { + return NRF_ERROR_INVALID_ADDR; + } + + p_curve = uECC_secp256r1(); + + int ret = uECC_make_key((uint8_t *) p_le_pk, (uint8_t *) p_le_sk, p_curve); + if (!ret) + { + return NRF_ERROR_INTERNAL; + } + + return NRF_SUCCESS; +} + +ret_code_t ecc_p256_public_key_compute(uint8_t const *p_le_sk, uint8_t *p_le_pk) +{ + const struct uECC_Curve_t * p_curve; + + if (!p_le_sk || !p_le_pk) + { + return NRF_ERROR_NULL; + } + + if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_pk)) + { + return NRF_ERROR_INVALID_ADDR; + } + + p_curve = uECC_secp256r1(); + + //NRF_LOG_INFO("uECC_compute_public_key\r\n"); + int ret = uECC_compute_public_key((uint8_t *) p_le_sk, (uint8_t *) p_le_pk, p_curve); + if (!ret) + { + return NRF_ERROR_INTERNAL; + } + + //NRF_LOG_INFO("uECC_compute_public_key complete: %d\r\n", ret); + return NRF_SUCCESS; +} + +ret_code_t ecc_p256_shared_secret_compute(uint8_t const *p_le_sk, uint8_t const *p_le_pk, uint8_t *p_le_ss) +{ + const struct uECC_Curve_t * p_curve; + + if (!p_le_sk || !p_le_pk || !p_le_ss) + { + return NRF_ERROR_NULL; + } + + if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_pk) || !is_word_aligned(p_le_ss)) + { + return NRF_ERROR_INVALID_ADDR; + } + + p_curve = uECC_secp256r1(); + + //NRF_LOG_INFO("uECC_shared_secret\r\n"); + int ret = uECC_shared_secret((uint8_t *) p_le_pk, (uint8_t *) p_le_sk, p_le_ss, p_curve); + if (!ret) + { + return NRF_ERROR_INTERNAL; + } + + //NRF_LOG_INFO("uECC_shared_secret complete: %d\r\n", ret); + return NRF_SUCCESS; +} + +ret_code_t ecc_p256_sign(uint8_t const *p_le_sk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t *p_le_sig) +{ + const struct uECC_Curve_t * p_curve; + + if (!p_le_sk || !p_le_hash || !p_le_sig) + { + return NRF_ERROR_NULL; + } + + if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_hash) || !is_word_aligned(p_le_sig)) + { + return NRF_ERROR_INVALID_ADDR; + } + + p_curve = uECC_secp256r1(); + + //NRF_LOG_INFO("uECC_sign\r\n"); + int ret = uECC_sign((const uint8_t *) p_le_sk, (const uint8_t *) p_le_hash, (unsigned) hlen, (uint8_t *) p_le_sig, p_curve); + if (!ret) + { + return NRF_ERROR_INTERNAL; + } + + //NRF_LOG_INFO("uECC_sign complete: %d\r\n", ret); + return NRF_SUCCESS; +} + +ret_code_t ecc_p256_verify(uint8_t const *p_le_pk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t const *p_le_sig) +{ + const struct uECC_Curve_t * p_curve; + + if (!p_le_pk || !p_le_hash || !p_le_sig) + { + return NRF_ERROR_NULL; + } + + if (!is_word_aligned(p_le_pk) || !is_word_aligned(p_le_hash) || !is_word_aligned(p_le_sig)) + { + return NRF_ERROR_INVALID_ADDR; + } + + p_curve = uECC_secp256r1(); + + //NRF_LOG_INFO("uECC_verify\r\n"); + int ret = uECC_verify((const uint8_t *) p_le_pk, (const uint8_t *) p_le_hash, (unsigned) hlen, (uint8_t *) p_le_sig, p_curve); + if (!ret) + { + return NRF_ERROR_INVALID_DATA; + } + + //NRF_LOG_INFO("uECC_verify complete: %d\r\n", ret); + return NRF_SUCCESS; + +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/ecc/ecc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/ecc/ecc.h new file mode 100644 index 0000000000000000000000000000000000000000..d8adbf4d0540a73e54184bc89b239163fe36d2fb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/ecc/ecc.h @@ -0,0 +1,143 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @defgroup ecc Elliptic Curve Cryptography interface + * @{ + * @ingroup app_common + * @brief Elliptic Curve Cryptography interface + */ + +#ifndef ECC_H__ +#define ECC_H__ + +#include +#include +#include "nordic_common.h" +#include "nrf_error.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ECC_P256_SK_LEN 32 +#define ECC_P256_PK_LEN 64 + +/**@brief Initialize the ECC module. + * + * @param[in] rng Use a random number generator. + * + * */ +void ecc_init(bool rng); + +/**@brief Create a public/private key pair. + * + * @param[out] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary. + * @param[out] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary. + * + * @retval NRF_SUCCESS Key pair successfuly created. + * @retval NRF_ERROR_NULL NULL pointer provided. + * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided. + * @retval NRF_ERROR_INTERNAL Internal error during key generation. + */ +ret_code_t ecc_p256_keypair_gen(uint8_t *p_le_sk, uint8_t* p_le_pk); + +/**@brief Create a public key from a provided private key. + * + * @param[in] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary. + * @param[out] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary. + * + * @retval NRF_SUCCESS Public key successfuly created. + * @retval NRF_ERROR_NULL NULL pointer provided. + * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided. + * @retval NRF_ERROR_INTERNAL Internal error during key generation. + */ +ret_code_t ecc_p256_public_key_compute(uint8_t const *p_le_sk, uint8_t* p_le_pk); + +/**@brief Create a shared secret from a provided public/private key pair. + * + * @param[in] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary. + * @param[in] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary. + * @param[out] p_le_ss Shared secret. Pointer must be aligned to a 4-byte boundary. + * + * @retval NRF_SUCCESS Shared secret successfuly created. + * @retval NRF_ERROR_NULL NULL pointer provided. + * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided. + * @retval NRF_ERROR_INTERNAL Internal error during key generation. + */ +ret_code_t ecc_p256_shared_secret_compute(uint8_t const *p_le_sk, uint8_t const * p_le_pk, uint8_t *p_le_ss); + +/**@brief Sign a hash or digest using a private key. + * + * @param[in] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary. + * @param[in] p_le_hash Hash. Pointer must be aligned to a 4-byte boundary. + * @param[in] hlen Hash length in bytes. + * @param[out] p_le_sig Signature. Pointer must be aligned to a 4-byte boundary. + * + * @retval NRF_SUCCESS Signature successfuly created. + * @retval NRF_ERROR_NULL NULL pointer provided. + * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided. + * @retval NRF_ERROR_INTERNAL Internal error during signature generation. + */ +ret_code_t ecc_p256_sign(uint8_t const *p_le_sk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t *p_le_sig); + +/**@brief Verify a signature using a public key. + * + * @param[in] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary. + * @param[in] p_le_hash Hash. Pointer must be aligned to a 4-byte boundary. + * @param[in] hlen Hash length in bytes. + * @param[in] p_le_sig Signature. Pointer must be aligned to a 4-byte boundary. + * + * @retval NRF_SUCCESS Signature verified. + * @retval NRF_ERROR_INVALID_DATA Signature failed verification. + * @retval NRF_ERROR_NULL NULL pointer provided. + * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided. + * @retval NRF_ERROR_INTERNAL Internal error during signature verification. + */ +ret_code_t ecc_p256_verify(uint8_t const *p_le_pk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t const *p_le_sig); + + +#ifdef __cplusplus +} +#endif + +#endif // ECC_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es.h new file mode 100644 index 0000000000000000000000000000000000000000..fbee66cd76ca50818131d02ee8b41f6f24edc2ac --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es.h @@ -0,0 +1,198 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ES_H__ +#define ES_H__ + +#include +#include "app_util_platform.h" + +/** + * @file + * + * @defgroup eddystone_types Frame types and data formats + * @brief Definitions specific to Eddystone frame types and data formats. + * @ingroup eddystone + * @{ + */ + +/** @brief Swap 2 bytes. + */ +#define BYTES_SWAP_16BIT(x) (x << 8 | x >> 8) + +/** @brief Reverse 4 bytes. + */ +#define BYTES_REVERSE_32BIT(x) \ + ((x << 24 | ((x << 8) & 0x00FF0000)) | (((x >> 8) & 0x0000FF00) | x >> 24)) + +/** @brief Check if the error code is equal to NRF_SUCCESS. If it is not, return the error code. + */ +#define RETURN_IF_ERROR(PARAM) \ + if ((PARAM) != NRF_SUCCESS) \ + { \ + return (PARAM); \ + } + +#define ES_UUID 0xFEAA //!< UUID for Eddystone beacons according to specification. + +#define ES_UID_FRAME_TYPE 0x00 //!< UID frame type (fixed at 0x00). +#define ES_UID_RFU 0x00, 0x00 //!< Reserved for future use according to specification. + +#define ES_URL_FRAME_TYPE 0x10 //!< URL frame type (fixed at 0x10). +#define ES_URL_SCHEME 0x00 //!< URL prefix scheme according to specification (0x00 = "http://www"). + +#define ES_TLM_FRAME_TYPE 0x20 //!< TLM frame type (fixed at 0x20). +#define ES_EID_FRAME_TYPE 0x30 //!< EID frame type (fixed at 0x30). + +#define ES_FRAME_TYPE_LENGTH (1) //!< Length of a frame type field. + +#define ES_UID_LENGTH (20) //!< Length of a UID frame. +#define ES_UID_NAMESPACE_LENGTH (10) //!< Length of a UID frame namespace field. +#define ES_UID_INSTANCE_LENGTH (6) //!< Length of a UID frame instance field. +#define ES_UID_RFU_LENGTH (2) //!< Length of a UID frame RFU field. + +#define ES_URL_LENGTH (20) //!< Length of a URL frame. +#define ES_URL_URL_SCHEME_LENGTH (1) //!< Length of a URL frame URL scheme field. +#define ES_URL_ENCODED_URL_LENGTH (17) //!< Maximum length of a URL frame encoded URL field. + +#define ES_TLM_LENGTH (14) //!< Length of a TLM frame. +#define ES_TLM_VBATT_LENGTH (2) //!< Length of a TLM frame VBATT field. +#define ES_TLM_TEMP_LENGTH (2) //!< Length of a TLM frame TEMP field. +#define ES_TLM_ADV_CNT_LENGTH (4) //!< Length of a TLM frame ADV count field. +#define ES_TLM_SEC_CNT_LENGTH (4) //!< Length of a TLM frame seconds field. + +#define ES_EID_LENGTH (10) //!< Length of an EID frame. +#define ES_EID_ID_LENGTH (8) //!< Length of an EID frame ephemeral ID field. +#define ES_EID_GATTS_READ_LENGTH (14) +#define ES_EID_GATTS_READ_FRAME_TYPE_IDX (0) +#define ES_EID_GATTS_READ_EXPONENT_IDX (1) +#define ES_EID_GATTS_READ_CLCK_VALUE_IDX (2) +#define ES_EID_GATTS_READ_EID_IDX (6) + +#define ES_ETLM_LENGTH (18) //!< Length of an eTLM frame. +#define ES_ETLM_ECRYPTED_LENGTH (ES_TLM_VBATT_LENGTH + \ + ES_TLM_TEMP_LENGTH + \ + ES_TLM_ADV_CNT_LENGTH + \ + ES_TLM_SEC_CNT_LENGTH) //!< Length of an eTLM frame encrypted TLM field. + +#define ES_ETLM_RFU (0x00) //!< eTLM frame RFU field value. +#define ES_SPEC_VERSION_BYTE (0x00) //!< eTLM frame specification version field value. + +/** @brief Eddystone frame type values. These values are advertised as frame types. */ +typedef enum +{ + ES_FRAME_TYPE_UID = ES_UID_FRAME_TYPE, /**< UID frame type. */ + ES_FRAME_TYPE_URL = ES_URL_FRAME_TYPE, /**< URL frame type. */ + ES_FRAME_TYPE_TLM = ES_TLM_FRAME_TYPE, /**< TLM frame type. */ + ES_FRAME_TYPE_EID = ES_EID_FRAME_TYPE /**< EID frame type. */ +} es_frame_type_t; + +/** @brief TLM version values. */ +typedef enum +{ + ES_TLM_VERSION_TLM = 0x00, /**< TLM. */ + ES_TLM_VERSION_ETLM = 0x01 /**< Encrypted TLM (eTLM). */ +} es_tlm_version_t; + +/** @brief UID frame data representation. + * @note This is a packed structure. Therefore, you should not change it. + */ +typedef PACKED_STRUCT +{ + es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t). + int8_t ranging_data; //!< Calibrated TX power at 0 m. + int8_t namespace[ES_UID_NAMESPACE_LENGTH]; //!< UID namespace. + int8_t instance[ES_UID_INSTANCE_LENGTH]; //!< UID instance. + int8_t rfu[ES_UID_RFU_LENGTH]; //!< RFU. +} es_uid_frame_t; + + +/** @brief URL frame data representation. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t). + int8_t ranging_data; //!< Calibrated TX power at 0 m. + uint8_t url_scheme; //!< URL scheme. + uint8_t encoded_url[ES_URL_ENCODED_URL_LENGTH]; //!< Encoded URL (variable length). +} es_url_frame_t; + + +/** @brief TLM frame data representation. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t). + es_tlm_version_t version; //!< TLM version (see @ref es_tlm_version_t). + int8_t vbatt[ES_TLM_VBATT_LENGTH]; //!< Battery voltage (in 1 mV units). + int8_t temp[ES_TLM_TEMP_LENGTH]; //!< Beacon temperature. + int8_t adv_cnt[ES_TLM_ADV_CNT_LENGTH]; //!< Advertising PDU count. + int8_t sec_cnt[ES_TLM_SEC_CNT_LENGTH]; //!< Time since power-on or reboot. +} es_tlm_frame_t; + +/** @brief EID frame data representation. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t). + int8_t ranging_data; //!< Calibrated TX power at 0 m. + int8_t eid[ES_EID_ID_LENGTH]; //!< 8-byte ephemeral identifier. +} es_eid_frame_t; + + +/** @brief eTLM frame data representation. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t). + es_tlm_version_t version; //!< TLM version (see @ref es_tlm_version_t). + int8_t encrypted_tlm[ES_ETLM_ECRYPTED_LENGTH]; //!< Encrypted TLM data. + int16_t random_salt; //!< Salt + int16_t msg_integrity_check; //!< Message integrity check. +} es_etlm_frame_t; + +/** + * @} + */ + +#endif // ES_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv.c new file mode 100644 index 0000000000000000000000000000000000000000..adbc5a551618059088e674fd7d46ebd1b8c4dfb1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv.c @@ -0,0 +1,308 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "es_adv.h" +#include "app_error.h" +#include "es_adv_frame.h" +#include "es_adv_timing.h" +#include "es_tlm.h" +#include "es_slot.h" + +static es_adv_evt_handler_t m_adv_evt_handler; //!< Eddystone advertisement event handler. +static bool m_is_connected = false; //!< Is the Eddystone beacon in a connected state. +static bool m_remain_connectable = false; //!< Should the Eddystone beacon remain connectable. +static uint8_t m_ecs_uuid_type = 0; //!< UUID type of the Eddystone Configuration Service. +static uint16_t m_adv_interval = APP_CFG_NON_CONN_ADV_INTERVAL_MS; //!< Current advertisement interval. + +/**@brief Function for invoking registered callback. + * + * @param[in] evt Event to issue to callback. + */ +static void invoke_callback(es_adv_evt_t evt) +{ + if (m_adv_evt_handler != NULL) + { + m_adv_evt_handler(evt); + } +} + +/**@brief Starting advertising. + * @param[in] p_adv_params Advertisement parameters to use. + */ +static void adv_start(ble_gap_adv_params_t * p_adv_params) +{ + ret_code_t err_code = NRF_SUCCESS; + + es_tlm_adv_cnt_inc(); + + err_code = sd_ble_gap_adv_start(p_adv_params, BLE_CONN_CFG_TAG_DEFAULT); + + if (err_code != NRF_ERROR_BUSY && err_code != NRF_SUCCESS) + { + APP_ERROR_CHECK(err_code); + } +} + + +/**@brief Given state of Eddystone beacon, get advertisement parameters. */ +static void get_adv_params(ble_gap_adv_params_t * p_adv_params, + bool non_connectable, + bool remain_connectable) +{ + // Initialize advertising parameters (used when starting advertising). + memset(p_adv_params, 0, sizeof(ble_gap_adv_params_t)); + + // Non-connectable + p_adv_params->type = + non_connectable ? BLE_GAP_ADV_TYPE_ADV_NONCONN_IND : BLE_GAP_ADV_TYPE_ADV_IND; + p_adv_params->p_peer_addr = NULL; // Undirected advertisement. + p_adv_params->fp = BLE_GAP_ADV_FP_ANY; + p_adv_params->interval = non_connectable ? BLE_GAP_ADV_INTERVAL_MAX : 1000; + p_adv_params->timeout = non_connectable + ? APP_CFG_NON_CONN_ADV_TIMEOUT + : (remain_connectable ? 0 : APP_CFG_CONNECTABLE_ADV_TIMEOUT); +} + + +/**@brief Update advertisement data and start connectable advertisements. */ +static void connectable_adv_start(void) +{ + ble_gap_adv_params_t connectable_adv_params; + ble_advdata_t scrsp_data; + ble_uuid_t scrp_uuids[] = {{BLE_UUID_ESCS_SERVICE, m_ecs_uuid_type}}; + + memset(&scrsp_data, 0, sizeof(scrsp_data)); + scrsp_data.name_type = BLE_ADVDATA_FULL_NAME; + scrsp_data.include_appearance = false; + scrsp_data.uuids_complete.uuid_cnt = sizeof(scrp_uuids) / sizeof(scrp_uuids[0]); + scrsp_data.uuids_complete.p_uuids = scrp_uuids; + + // As the data to be written does not depend on the slot_no, we can safely send + es_adv_frame_fill_connectable_adv_data(&scrsp_data); + + get_adv_params(&connectable_adv_params, false, m_remain_connectable); + adv_start(&connectable_adv_params); + + invoke_callback(ES_ADV_EVT_CONNECTABLE_ADV_STARTED); +} + + +static void adv_stop(void) +{ + ret_code_t err_code; + + err_code = sd_ble_gap_adv_stop(); + if (err_code != NRF_ERROR_INVALID_STATE) + { + APP_ERROR_CHECK(err_code); + } + + es_adv_timing_stop(); +} + + +static void adv_restart(void) +{ + if (!m_remain_connectable) + { + es_adv_start_non_connctable_adv(); + } + + else + { + connectable_adv_start(); + } +} + + +/**@brief Function handling events from @ref es_adv_timing.c. + * + * @param[in] p_evt Advertisement timing event. + */ +static void adv_timing_callback(const es_adv_timing_evt_t * p_evt) +{ + ret_code_t err_code; + ble_gap_adv_params_t non_connectable_adv_params; + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + // As new advertisement data will be loaded, stop advertising. + err_code = sd_ble_gap_adv_stop(); + if (err_code != NRF_ERROR_INVALID_STATE) + { + APP_ERROR_CHECK(err_code); + } + + // If a non-eTLM frame is to be advertised. + if (p_evt->evt_id == ES_ADV_TIMING_EVT_ADV_SLOT) + { + err_code = sd_ble_gap_tx_power_set(p_reg->slots[p_evt->slot_no].radio_tx_pwr); + APP_ERROR_CHECK(err_code); + + es_adv_frame_fill_non_connectable_adv_data(p_evt->slot_no, false); + } + + // If an eTLM frame is to be advertised + else if (p_evt->evt_id == ES_ADV_TIMING_EVT_ADV_ETLM) + { + err_code = sd_ble_gap_tx_power_set(p_reg->slots[p_reg->tlm_slot].radio_tx_pwr); + APP_ERROR_CHECK(err_code); + + es_adv_frame_fill_non_connectable_adv_data(p_evt->slot_no, true); + } + + invoke_callback(ES_ADV_EVT_NON_CONN_ADV); + + get_adv_params(&non_connectable_adv_params, true, m_remain_connectable); + adv_start(&non_connectable_adv_params); +} + + +void es_adv_start_connectable_adv(void) +{ + if (!m_is_connected) + { + adv_stop(); + + connectable_adv_start(); + } +} + + +void es_adv_start_non_connctable_adv(void) +{ + es_adv_timing_start(m_adv_interval); +} + + +void es_adv_remain_connectable_set(bool remain_connectable) +{ + m_remain_connectable = remain_connectable; +} + + +bool es_adv_remain_connectable_get(void) +{ + return m_remain_connectable; +} + + +void es_adv_on_ble_evt(ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + m_is_connected = true; + + // The beacon must provide these advertisements for the client to see updated values + // during the connection. + es_adv_start_non_connctable_adv(); + break; + + case BLE_GAP_EVT_DISCONNECTED: + m_is_connected = false; + + // Stop all advertising to give some time for writing to flash. + adv_stop(); + adv_restart(); + break; + + case BLE_GAP_EVT_TIMEOUT: + if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING && + !m_is_connected) + { + adv_restart(); + } + break; + + default: + break; + } +} + + +void es_adv_interval_set(nrf_ble_escs_adv_interval_t interval) +{ + const es_slot_reg_t * p_reg = es_slot_get_registry(); + uint16_t min_valid_adv_interval; + + bool eTLM_required = (p_reg->num_configured_eid_slots > 0) && (p_reg->tlm_configured); + + min_valid_adv_interval = eTLM_required ? \ + p_reg->num_configured_slots * (APP_CONFIG_ADV_FRAME_SPACING_MS_MIN + \ + APP_CONFIG_ADV_FRAME_ETLM_SPACING_MS) \ + : \ + p_reg->num_configured_slots * APP_CONFIG_ADV_FRAME_SPACING_MS_MIN; + + m_adv_interval = (interval > min_valid_adv_interval) ? interval : min_valid_adv_interval; + +#ifdef APP_CONFIG_ADV_INTERVAL_MS_MAX + if (m_adv_interval > APP_CONFIG_ADV_INTERVAL_MS_MAX) + { + m_adv_interval = APP_CONFIG_ADV_INTERVAL_MS_MAX; + } +#endif // APP_CONFIG_ADV_INTERVAL_MS_MAX +} + + +nrf_ble_escs_adv_interval_t es_adv_interval_get(void) +{ + return m_adv_interval; +} + + +void es_adv_init(uint8_t ecs_uuid_type, + es_adv_evt_handler_t adv_event_handler, + nrf_ble_escs_adv_interval_t adv_interval, + bool remain_connectable) +{ + m_ecs_uuid_type = ecs_uuid_type; + m_adv_evt_handler = adv_event_handler; + m_is_connected = false; + m_remain_connectable = remain_connectable; + m_adv_interval = adv_interval; + + es_tlm_init(); + + es_adv_timing_init(adv_timing_callback); +} + +void es_adv_timers_init(void) +{ + es_adv_timing_timers_init(); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv.h new file mode 100644 index 0000000000000000000000000000000000000000..d910a45edc008f9178aa303d913d685ac1886eab --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv.h @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ES_ADV_H__ +#define ES_ADV_H__ + +#include "nrf_ble_escs.h" + +/** + * @file + * @defgroup eddystone_adv Eddystone advertising module + * @brief Types and functions for handling advertising in Eddystone beacons. + * @ingroup eddystone + * @{ + */ + +/** @brief Eddystone Advertiser events. */ +typedef enum +{ + ES_ADV_EVT_NON_CONN_ADV, + ES_ADV_EVT_CONNECTABLE_ADV_STARTED, +} es_adv_evt_t; + +/** @brief Eddystone Advertiser event handler. */ +typedef void (*es_adv_evt_handler_t)(es_adv_evt_t evt); + +/** @brief Function for initializing the module. + * + * @param[in] ecs_uuid_type ECS UUID type used for advertising the Eddystone Configuration Service UUID. + * @param[in] adv_event_handler Eddystone advertiser event handler. + * @param[in] adv_interval Advertisement interval to use. + * @param[in] remain_connectable Flag that specifies if advertisements should remain connectable. + */ +void es_adv_init(uint8_t ecs_uuid_type, + es_adv_evt_handler_t adv_event_handler, + nrf_ble_escs_adv_interval_t adv_interval, + bool remain_connectable); + +/** @brief Function for passing BLE events to this module. + * + * @param[in] p_ble_evt Pointer to the BLE evt. + */ +void es_adv_on_ble_evt(ble_evt_t * p_ble_evt); + +/** @brief Function for starting the advertisements. + */ +void es_adv_start_non_connctable_adv(void); + +/** @brief Function for specifying if the beacon should remain connectable. + * + * @param[in] remain_connectable Value to be set. + */ +void es_adv_remain_connectable_set(bool remain_connectable); + +/** @brief Function for starting connectable advertisements. + */ +void es_adv_start_connectable_adv(void); + +/** @brief Function for setting the base advertisement interval for non-connectable advertisements. + * + * The minimum allowed advertisement interval is calculated based on the configured minimum advertisement + * frame spacings and the number of configured slots. If eTLM slots are configured a separate minimum + * advertisement frame spacing is used for those. If @p interval is outside of range, the closest valid value + * is set. + * + * @param interval The new advertisement interval. + */ +void es_adv_interval_set(nrf_ble_escs_adv_interval_t interval); + +/** @brief Function for getting a pointer to the current advertisement interval. + * + * @retval Pointer to the current advertisement interval. + */ +nrf_ble_escs_adv_interval_t es_adv_interval_get(void); + +/** @brief Function for getting the value of the 'remain_connectable' field. + * + * @retval Value of 'remain_connectable'. + */ +bool es_adv_remain_connectable_get(void); + +/** @brief Function for initializing the Eddystone advertisement timers. + */ +void es_adv_timers_init(void); + +/** + * @} + */ + +#endif // ES_ADV_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_frame.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_frame.c new file mode 100644 index 0000000000000000000000000000000000000000..aef38555441e0654fc1ae6d6aaa4a2db878ad00f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_frame.c @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "es_adv_frame.h" +#include "es_slot.h" + + +/**@brief Function for setting advertisement data, using 'ble_advdata_set'. + * + * @param[in] p_scrsp_data Scan response data. + * @param[in] p_es_data_array Eddystone service data array. + */ +static void fill_adv_data(ble_advdata_t * p_scrsp_data, uint8_array_t * p_es_data_array) +{ + ble_advdata_t adv_data; + ret_code_t err_code; + ble_uuid_t adv_uuids[] = {{ES_UUID, BLE_UUID_TYPE_BLE}}; + uint8_array_t es_data_array = {0}; + + ble_advdata_service_data_t service_data; // Structure to hold Service Data. + + service_data.service_uuid = APP_ES_UUID; // Eddystone UUID to allow discoverability on iOS devices. + + service_data.data = (p_es_data_array != NULL) ? *p_es_data_array : es_data_array; + + // Build and set advertising data. + memset(&adv_data, 0, sizeof(ble_advdata_t)); + + adv_data.name_type = BLE_ADVDATA_NO_NAME; + adv_data.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; + adv_data.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]); + adv_data.uuids_complete.p_uuids = adv_uuids; + adv_data.p_service_data_array = &service_data; + adv_data.service_data_count = (p_es_data_array != NULL) ? 1 : 0; + + err_code = ble_advdata_set(&adv_data, p_scrsp_data); + APP_ERROR_CHECK(err_code); +} + + +void es_adv_frame_fill_connectable_adv_data(ble_advdata_t * p_scrsp_data) +{ + fill_adv_data(p_scrsp_data, NULL); +} + + +void es_adv_frame_fill_non_connectable_adv_data(uint8_t slot_no, bool etlm) +{ + uint8_array_t es_data_array = {0}; + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + if (etlm) + { + es_slot_etlm_update(slot_no); + + // If eTLM, the incoming slot_no points to the corresponding EID slot, update to point to TLM slot. + slot_no = p_reg->tlm_slot; + } + + // If TLM, update the TLM data. + else if (p_reg->slots[slot_no].adv_frame.type == ES_FRAME_TYPE_TLM) + { + es_slot_tlm_update(); + } + + es_data_array.p_data = (uint8_t *)&p_reg->slots[slot_no].adv_frame.frame; + es_data_array.size = p_reg->slots[slot_no].adv_frame.length; + + fill_adv_data(NULL, &es_data_array); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_frame.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_frame.h new file mode 100644 index 0000000000000000000000000000000000000000..10eacb08270b3f89c116c44b0196211af5762e7b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_frame.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ES_ADV_FRAME_H__ +#define ES_ADV_FRAME_H__ + +#include +#include "ble_advdata.h" + +/** + * @file + * @addtogroup eddystone_adv + * @{ + */ + +/**@brief Function for setting up connectable advertisement data using @ref + * ble_advdata_set. + * + * @param[in] p_scrsp_data Pointer to the scan response data. + */ +void es_adv_frame_fill_connectable_adv_data(ble_advdata_t * p_scrsp_data); + +/**@brief Function for setting up non-connectable advertisement data using @ref + * ble_advdata_set. + * + * @param[in] slot_no Slot to fill in data for. + * @param[in] etlm Flag that specifies if Eddystone-TLM is required. + */ +void es_adv_frame_fill_non_connectable_adv_data(uint8_t slot_no, bool etlm); + +/** + * @} + */ + +#endif // ES_ADV_FRAME_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_timing.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_timing.c new file mode 100644 index 0000000000000000000000000000000000000000..b625a5a984f85847f5232735a150c77a93cbc61c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_timing.c @@ -0,0 +1,220 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "app_timer.h" +#include "es_adv_timing.h" +#include "es_adv_timing_resolver.h" +#include "es_slot.h" + + +APP_TIMER_DEF(m_es_adv_interval_timer); //!< Timer for advertising the set of slots. +APP_TIMER_DEF(m_es_slot_timer); //!< Timer for advertising individual slots. + +static nrf_ble_escs_adv_interval_t m_current_adv_interval; //!< Current advertisement interval. +static es_adv_timing_callback_t m_timing_mgr_callback; //!< Registered callback. +static es_adv_timing_resolver_result_t m_adv_timing_result; //!< Current advertising timing result. +static bool m_non_conn_adv_active; //!< Is the beacon advertising non-conn advertisements? + +/**@brief Function for invoking registered callback. + * + * @param[in] p_evt Event to issue to callback. + */ +static void invoke_callback(const es_adv_timing_evt_t * p_evt) +{ + if (m_timing_mgr_callback != NULL && m_non_conn_adv_active) + { + m_timing_mgr_callback(p_evt); + } +} + + +#if APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1 +static bool frame_to_adv_is_tlm(const es_adv_timing_evt_t * p_evt) +{ + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + return (p_reg->tlm_configured && + (p_evt->slot_no == p_reg->tlm_slot || p_evt->evt_id == ES_ADV_TIMING_EVT_ADV_ETLM)); +} + + +static bool tlm_should_be_advertised(uint32_t adv_event_cnt) +{ + return (adv_event_cnt % APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO) == 0; +} +#endif // APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1 + + +/**@brief Timeout handler for the advertisement slot timer. */ +static void adv_slot_timeout(void * p_context) +{ + + ret_code_t err_code; + uint32_t active_slot_index = (uint32_t)p_context; + + es_adv_timing_evt_t evt; + + evt.slot_no = m_adv_timing_result.timing_results[active_slot_index].slot_no; + + evt.evt_id = m_adv_timing_result.timing_results[active_slot_index].is_etlm + ? ES_ADV_TIMING_EVT_ADV_ETLM + : ES_ADV_TIMING_EVT_ADV_SLOT; + + // Trigger an event for the next slot if this slot is not the last to be advertised in this event. + // Note: since we check 'm_adv_timing_result.len_timing_results > 1' we can safely cast the result of + // the subtraction to a uint32. + if (m_non_conn_adv_active && \ + m_adv_timing_result.len_timing_results > 1 && \ + active_slot_index < (uint32_t)(m_adv_timing_result.len_timing_results - 1)) + { + err_code = app_timer_start( m_es_slot_timer, + APP_TIMER_TICKS(m_adv_timing_result.timing_results[active_slot_index].delay_ms), + (void*)(active_slot_index + 1)); + APP_ERROR_CHECK(err_code); + } + +#if APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1 + static uint32_t adv_event_cnt = 0; + + if (active_slot_index == 0) + { + adv_event_cnt++; + } + + if (frame_to_adv_is_tlm(&evt) && !tlm_should_be_advertised(adv_event_cnt)) + { + return; + } +#endif // APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1 + + invoke_callback(&evt); +} + + +/**@brief Timeout handler for the advertisement interval timer. */ +static void adv_interval_timeout(void * p_context) +{ + if (es_slot_get_registry()->num_configured_slots > 0) + { + // Trigger slot timeout for advertising the first slot. + // Note: The slot number is not the index in the slot registry, it is the index of the active slots. + adv_slot_timeout(NULL); + } + + if(m_non_conn_adv_active) + { + uint32_t err_code = app_timer_start(m_es_adv_interval_timer, + APP_TIMER_TICKS(m_current_adv_interval), + NULL); + APP_ERROR_CHECK(err_code); + } +} + + +void es_adv_timing_timers_init(void) +{ + ret_code_t err_code; + + err_code = app_timer_create(&m_es_adv_interval_timer, + APP_TIMER_MODE_SINGLE_SHOT, + adv_interval_timeout); + APP_ERROR_CHECK(err_code); + + err_code = app_timer_create(&m_es_slot_timer, + APP_TIMER_MODE_SINGLE_SHOT, + adv_slot_timeout); + APP_ERROR_CHECK(err_code); +} + + +/**@brief Function for finding and setting advertisement timing configuration. */ +static void adv_timing_set(void) +{ + ret_code_t err_code; + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + es_adv_timing_resolver_input_t resolver_input = { + .adv_interval = m_current_adv_interval, + .p_result = &m_adv_timing_result, + .num_slots_configured = p_reg->num_configured_slots, + .p_slots_configured = p_reg->slots_configured, + .num_eid_slots_configured = p_reg->num_configured_eid_slots, + .p_eid_slots_configured = p_reg->eid_slots_configured, + .tlm_configured = p_reg->tlm_configured, + .tlm_slot = p_reg->tlm_slot}; + + err_code = es_adv_timing_resolve(&resolver_input); + APP_ERROR_CHECK(err_code); +} + + +void es_adv_timing_start(uint16_t adv_interval) +{ + ret_code_t err_code; + + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + m_non_conn_adv_active = true; + + if (p_reg->num_configured_slots > 0) + { + m_current_adv_interval = adv_interval; + + err_code = app_timer_start(m_es_adv_interval_timer, + APP_TIMER_TICKS(m_current_adv_interval), + NULL); + APP_ERROR_CHECK(err_code); + + adv_timing_set(); + } +} + + +void es_adv_timing_stop(void) +{ + m_non_conn_adv_active = false; // Stops timers from being re-fired. +} + + +void es_adv_timing_init(es_adv_timing_callback_t p_handler) +{ + m_non_conn_adv_active = false; + m_timing_mgr_callback = p_handler; + memset(&m_adv_timing_result, 0, sizeof(m_adv_timing_result)); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_timing.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_timing.h new file mode 100644 index 0000000000000000000000000000000000000000..2d613970b356fb5c4cff0dce3e66f6b1585ab358 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_timing.h @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ES_ADV_TIMING_H__ +#define ES_ADV_TIMING_H__ + +#include + +/** + * @file + * @defgroup eddystone_adv_timing Timing + * @brief Events and functions for advertisement timing. + * @ingroup eddystone_adv + * @{ + */ + +/**@brief Eddystone advertisement timing event types. */ +typedef enum +{ + ES_ADV_TIMING_EVT_ADV_SLOT, //!< Advertising non-eTLM slot. + ES_ADV_TIMING_EVT_ADV_ETLM //!< Advertising eTLM slot. +} es_adv_timing_evt_id_t; + +/**@brief Eddystone advertisement timing event. */ +typedef struct +{ + es_adv_timing_evt_id_t evt_id; //!< Event type ID. + uint8_t slot_no; /**< @brief Slot number. + * @details For non-eTLM events: The slot number to advertise. + * + * For eTLM events: The slot number of the corresponding EID slot. */ +} es_adv_timing_evt_t; + +/**@brief Eddystone advertisement timing event callback. + * + * @param[in] p_evt Pointer to the Eddystone advertisement timing event. + */ +typedef void (*es_adv_timing_callback_t)(const es_adv_timing_evt_t * p_evt); + +/**@brief Function for starting Eddystone advertisement timing event generation. */ +void es_adv_timing_start(uint16_t adv_interval); + + +/**@brief Function for stopping Eddystone advertisement timing event generation. */ +void es_adv_timing_stop(void); + +/**@brief Function for initializing the Eddystone advertisement timers. + */ +void es_adv_timing_timers_init(void); + +/**@brief Function for initializing the Eddystone advertisement timing module. + * + * @param[in] handler Eddystone advertisement timing event handler to register. + */ +void es_adv_timing_init(es_adv_timing_callback_t handler); + +/** + * @} + */ + +#endif // ES_ADV_TIMING_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_timing_resolver.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_timing_resolver.c new file mode 100644 index 0000000000000000000000000000000000000000..5506b7a3674b4726dbc453c0551cec6c6b5ecf96 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_timing_resolver.c @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "es_adv_timing_resolver.h" +#include "sdk_macros.h" + +/**@brief Function for finding delay to use after each non-eTLM advertisement. + * + * @param[in] adv_interval Configured advertisement interval. + * @param[in] num_slots_configured Number of configured slots. + * @param[in] eTLM_required Is there an eTLM slot. + */ +static uint16_t get_adv_delay(uint16_t adv_interval, + uint8_t num_slots_configured, + bool eTLM_required) +{ + // If eTLM is required, don't count this when calculating delay. + return adv_interval / (num_slots_configured - (eTLM_required ? 1 : 0)); +} + + +/**@brief Function for checking if given slot_no is an EID slot. + * + * @param[in] slot_no Slot number to check. + * @param[in] p_eid_slots_configured Pointer to list of configured EID slots. + * @param[in] num_eid_slots_configured Number of EID slots configured. + */ +static bool is_eid(uint8_t slot_no, const uint8_t * p_eid_slots_configured, uint8_t num_eid_slots_configured) +{ + for (uint32_t i = 0; i < num_eid_slots_configured; ++i) + { + if (slot_no == p_eid_slots_configured[i]) + { + return true; + } + } + + return false; +} + +ret_code_t es_adv_timing_resolve(es_adv_timing_resolver_input_t * p_input) +{ + VERIFY_PARAM_NOT_NULL(p_input); + + uint8_t result_index = 0; + bool eTLM_required = p_input->tlm_configured && p_input->num_eid_slots_configured > 0; + uint16_t base_delay; + + if (p_input->num_slots_configured == 0) + { + return NRF_ERROR_INVALID_PARAM; + } + + base_delay = get_adv_delay(p_input->adv_interval, p_input->num_slots_configured, eTLM_required); + + for (uint32_t i = 0; i < p_input->num_slots_configured; ++i) + { + uint8_t slot_no = p_input->p_slots_configured[i]; + + if (!(eTLM_required && slot_no == p_input->tlm_slot)) + { + es_adv_timing_resolver_adv_timing_t * p_current_result = &p_input->p_result->timing_results[result_index]; + p_current_result->slot_no = slot_no; + p_current_result->is_etlm = false; + + // If an eTLM is to be advertised for this frame, this value will be changed. + p_current_result->delay_ms = base_delay; + + result_index++; + + if (eTLM_required && + is_eid(slot_no, p_input->p_eid_slots_configured, p_input->num_eid_slots_configured)) + { + es_adv_timing_resolver_adv_timing_t * p_eTLM_timing_result = + &p_input->p_result->timing_results[result_index]; + + p_current_result->delay_ms = APP_CONFIG_ADV_FRAME_ETLM_SPACING_MS; // Update delay from EID to eTLM frame. + + p_eTLM_timing_result->slot_no = slot_no; // Point to EID slot-no, as this will be + // used for finding the correct EIK. + p_eTLM_timing_result->is_etlm = true; // Configure as eTLM frame. + + if (base_delay > APP_CONFIG_ADV_FRAME_ETLM_SPACING_MS) + { + p_eTLM_timing_result->delay_ms = + base_delay - + APP_CONFIG_ADV_FRAME_ETLM_SPACING_MS; // Set delay of eTLM frame. + } + + else + { + p_eTLM_timing_result->delay_ms = APP_CONFIG_ADV_FRAME_SPACING_MS_MIN; + } + + result_index++; + } + } + } + + p_input->p_result->len_timing_results = result_index; // Note: index has been increased to equal length of result. + + if(p_input->p_result->len_timing_results > 0) + { + p_input->p_result->timing_results[p_input->p_result->len_timing_results - 1].delay_ms = 0; // Last Slot does not need delay. + } + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_timing_resolver.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_timing_resolver.h new file mode 100644 index 0000000000000000000000000000000000000000..caf654d19e8a63563e4a8af7615154c912fcf9bf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_adv_timing_resolver.h @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ES_ADV_TIMING_RESOLVER_H__ +#define ES_ADV_TIMING_RESOLVER_H__ + +#include +#include +#include "es_app_config.h" + +/** + * @file + * @addtogroup eddystone_adv_timing + * @{ + */ + +/** @brief Timing parameters for a single slot. */ +typedef struct +{ + bool is_etlm; //!< Flag that specifies if the slot is an eTLM. + uint8_t slot_no; /**< @brief Slot number. @details + * For non-eTLM slots: The slot number of the given frame. + * + * For eTLM slots: The slot number of the corresponding EID frame. */ + uint16_t delay_ms; //!< Delay from this frame to the next. +} es_adv_timing_resolver_adv_timing_t; + +/**@brief Results of calculating advertisement delays. */ +typedef struct +{ + es_adv_timing_resolver_adv_timing_t timing_results[APP_MAX_ADV_SLOTS - APP_MAX_EID_SLOTS + + (APP_MAX_EID_SLOTS * 2)]; //!< List of timing results. + uint8_t len_timing_results; //!< Length of results. +} es_adv_timing_resolver_result_t; + +/**@brief Input to the timing resolver. */ +typedef struct +{ + uint16_t adv_interval; //!< Global advertisement interval. + uint8_t num_slots_configured; //!< Number of configured slots. + const uint8_t * p_slots_configured; //!< Pointer to the list of configured slots. + uint8_t num_eid_slots_configured; //!< Number of configured EID slots. + const uint8_t * p_eid_slots_configured; //!< Pointer to the list of configured EID slots. + bool tlm_configured; //!< Flag that specifies if TLM slot is configured. + uint8_t tlm_slot; //!< Slot number of the TLM slot (if @p tlm_configured is true). + es_adv_timing_resolver_result_t * p_result; //!< Output result. +} es_adv_timing_resolver_input_t; + +/**@brief Function for getting the input for advertisement interval calculation. + * + * @param[in,out] p_input Input to advertisement interval calculation (see @ref es_adv_timing_resolver_input_t). + * @retval NRF_SUCCESS If the operation was successful. Otherwise, an error code is returned. + */ +ret_code_t es_adv_timing_resolve(es_adv_timing_resolver_input_t * p_input); + +/** + * @} + */ + +#endif // ES_ADV_TIMING_RESOLVER_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_battery_voltage.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_battery_voltage.h new file mode 100644 index 0000000000000000000000000000000000000000..f958243ae39ae5b0239aabf1e974a57212a8c345 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_battery_voltage.h @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ES_BATTERY_VOLTAGE_H__ +#define ES_BATTERY_VOLTAGE_H__ + +#include + +/** + * @file + * + * @addtogroup eddystone_tlm + * @{ + */ + +/**@brief Function for initializing the battery voltage module. + */ +void es_battery_voltage_init(void); + +/**@brief Function for reading the battery voltage. + * + * @param[out] p_vbatt Pointer to the battery voltage value. + */ +void es_battery_voltage_get(uint16_t * p_vbatt); + +/** + * @} + */ + +#endif // ES_BATTERY_VOLTAGE_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_battery_voltage_adc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_battery_voltage_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..689af6b2e829e5cd53eb2473005a325a0a494f9b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_battery_voltage_adc.c @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "app_error.h" +#include "es_battery_voltage.h" +#include "nrf_drv_adc.h" + +static uint16_t m_batt_lvl_in_milli_volts; + +#define ADC_REF_VOLTAGE_IN_MILLIVOLTS 600 // /< Reference voltage (in milli volts) used by ADC while doing conversion. +#define DIODE_FWD_VOLT_DROP_MILLIVOLTS 270 // /< Typical forward voltage drop of the diode (Part no: SD103ATW-7-F) that is connected in series with the voltage supply. This is the voltage drop when the forward current is 1mA. Source: Data sheet of 'SURFACE MOUNT SCHOTTKY BARRIER DIODE ARRAY' available at www.diodes.com. +#define ADC_RES_10BIT 1024 // /< Maximum digital value for 10-bit ADC conversion. +#define ADC_PRE_SCALING_COMPENSATION 6 // /< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage. +#define ADC_REF_VBG_VOLTAGE_IN_MILLIVOLTS 1200 // /< Value in millivolts for voltage used as reference in ADC conversion on NRF51. +#define ADC_INPUT_PRESCALER 3 // /< Input prescaler for ADC convestion on NRF51. + +static nrf_adc_value_t adc_buf[1]; +#define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE) \ + ((((ADC_VALUE) *ADC_REF_VBG_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_INPUT_PRESCALER) + +static void adc_event_handler(nrf_drv_adc_evt_t const * p_event) +{ + if (p_event->type == NRF_DRV_ADC_EVT_DONE) + { + nrf_adc_value_t adc_result; + ret_code_t err_code; + + adc_result = p_event->data.done.p_buffer[0]; + + err_code = nrf_drv_adc_buffer_convert(p_event->data.done.p_buffer, 1); + APP_ERROR_CHECK(err_code); + + m_batt_lvl_in_milli_volts = + ADC_RESULT_IN_MILLI_VOLTS(adc_result) + DIODE_FWD_VOLT_DROP_MILLIVOLTS; + } +} + + +void es_battery_voltage_init(void) +{ + ret_code_t err_code = nrf_drv_adc_init(NULL, adc_event_handler); + + APP_ERROR_CHECK(err_code); + + static nrf_drv_adc_channel_t channel = + NRF_DRV_ADC_DEFAULT_CHANNEL(NRF_ADC_CONFIG_INPUT_DISABLED); + channel.config.config.input = (uint32_t)NRF_ADC_CONFIG_SCALING_SUPPLY_ONE_THIRD; + nrf_drv_adc_channel_enable(&channel); + + err_code = nrf_drv_adc_buffer_convert(&adc_buf[0], 1); + APP_ERROR_CHECK(err_code); + nrf_drv_adc_sample(); +} + + +void es_battery_voltage_get(uint16_t * p_vbatt) +{ + *p_vbatt = m_batt_lvl_in_milli_volts; + if (!nrf_adc_is_busy()) + { + nrf_drv_adc_sample(); + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_battery_voltage_saadc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_battery_voltage_saadc.c new file mode 100644 index 0000000000000000000000000000000000000000..70afa7a7b74b582bb320970cbb8400d04ee76c40 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_battery_voltage_saadc.c @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "es_battery_voltage.h" +#include "nrf_drv_saadc.h" +#include "sdk_macros.h" + +#define ADC_REF_VOLTAGE_IN_MILLIVOLTS 600 //!< Reference voltage (in milli volts) used by ADC while doing conversion. +#define DIODE_FWD_VOLT_DROP_MILLIVOLTS 270 //!< Typical forward voltage drop of the diode (Part no: SD103ATW-7-F) that is connected in series with the voltage supply. This is the voltage drop when the forward current is 1mA. Source: Data sheet of 'SURFACE MOUNT SCHOTTKY BARRIER DIODE ARRAY' available at www.diodes.com. +#define ADC_RES_10BIT 1024 //!< Maximum digital value for 10-bit ADC conversion. +#define ADC_PRE_SCALING_COMPENSATION 6 //!< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage. +#define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE) \ + ((((ADC_VALUE) *ADC_REF_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_PRE_SCALING_COMPENSATION) + +static nrf_saadc_value_t adc_buf; //!< Buffer used for storing ADC value. +static uint16_t m_batt_lvl_in_milli_volts; //!< Current battery level. + +/**@brief Function handling events from 'nrf_drv_saadc.c'. + * + * @param[in] p_evt SAADC event. + */ +static void saadc_event_handler(nrf_drv_saadc_evt_t const * p_evt) +{ + if (p_evt->type == NRF_DRV_SAADC_EVT_DONE) + { + nrf_saadc_value_t adc_result; + + adc_result = p_evt->data.done.p_buffer[0]; + + m_batt_lvl_in_milli_volts = + ADC_RESULT_IN_MILLI_VOLTS(adc_result) + DIODE_FWD_VOLT_DROP_MILLIVOLTS; + } +} + + +void es_battery_voltage_init(void) +{ + ret_code_t err_code = nrf_drv_saadc_init(NULL, saadc_event_handler); + + APP_ERROR_CHECK(err_code); + + nrf_saadc_channel_config_t config = + NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD); + err_code = nrf_drv_saadc_channel_init(0, &config); + APP_ERROR_CHECK(err_code); + + err_code = nrf_drv_saadc_buffer_convert(&adc_buf, 1); + APP_ERROR_CHECK(err_code); + + err_code = nrf_drv_saadc_sample(); + APP_ERROR_CHECK(err_code); +} + + +void es_battery_voltage_get(uint16_t * p_vbatt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_vbatt); + + *p_vbatt = m_batt_lvl_in_milli_volts; + if (!nrf_drv_saadc_is_busy()) + { + ret_code_t err_code = nrf_drv_saadc_buffer_convert(&adc_buf, 1); + APP_ERROR_CHECK(err_code); + + err_code = nrf_drv_saadc_sample(); + APP_ERROR_CHECK(err_code); + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_flash.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_flash.c new file mode 100644 index 0000000000000000000000000000000000000000..901c2ea42aa3581c9a3dc1b47234c1d129b68d57 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_flash.c @@ -0,0 +1,346 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "es_flash.h" +#include "es_util.h" +#include "app_scheduler.h" +#include "ble_hci.h" +#include "fds.h" +#include "nrf_nvic.h" + +#define SIZE_OF_PRIV_KEY ESCS_ECDH_KEY_SIZE //!< Size of ECDH private key. +#define SIZE_OF_PUB_KEY ESCS_ECDH_KEY_SIZE //!< Size of ECDH public key. +#define SIZE_OF_LOCK_KEY ESCS_AES_KEY_SIZE //!< Size of lock key. +#define FILE_ID_ES_FLASH 0x1337 //!< File ID used for all flash access EXCEPT lock code. +#define FILE_ID_ES_FLASH_LOCK_KEY 0x1338 //!< File ID used for lock code flash access. +#define RECORD_KEY_FLAGS 0x1 //!< File record for flash flags. +#define RECORD_KEY_PRIV_KEY 0x2 //!< File record for private key. +#define RECORD_KEY_PUB_KEY 0x3 //!< File record for public key. +#define RECORD_KEY_LOCK_KEY 0x4 //!< File record for lock key. +#define RECORD_KEY_BEACON_CONFIG 0x5 //!< File record for lock key. + +static uint16_t RECORD_KEY_SLOTS[5] = {0x6, 0x7, 0x8, 0x9, 0xa}; //!< File record for slots. + +/**@brief Structure used for invoking flash access function. */ +typedef struct +{ + uint16_t record_key; + uint16_t file_id; + uint8_t * p_chunk_buf; + uint8_t * p_data; + uint16_t size_bytes; + es_flash_access_t access_type; +} flash_access_params_t; + +static volatile uint32_t m_num_pending_ops; //!< Current number of outstanding FDS operations. +static volatile bool m_factory_reset; //!< Should factory reset be performed. +static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; //!< Current connection handle. + + +#if APP_MAX_ADV_SLOTS > 32 +#error "APP_MAX_ADV_SLOTS must be <= 32" +#endif + +#define SLOT_DECL(i, _) __ALIGN(4) static uint8_t slot## i ##_buf[sizeof(es_slot_t)]; +EVAL(REPEAT(APP_MAX_ADV_SLOTS, SLOT_DECL, ~)) + +__ALIGN(4) static uint8_t lock_key_buf[SIZE_OF_LOCK_KEY]; //!< Buffer for lock key flash access. + +#define SLOT(i, _) slot## i ##_buf, +static uint8_t * slots_buf_p[APP_MAX_ADV_SLOTS] = { + EVAL(REPEAT(APP_MAX_ADV_SLOTS, SLOT, ~)) +}; + +__ALIGN(4) static uint8_t flash_flags_buf[sizeof(es_flash_flags_t)]; //!< Buffer for flash flags flash access. +__ALIGN(4) static uint8_t beacon_config_buf[sizeof(es_flash_beacon_config_t)]; //!< Buffer for beacon config flash access. + +/**@brief Function handling scheduled FDS garbage collection. */ +static void fds_gc_event(void * p_event_data, uint16_t event_size) +{ + ret_code_t fds_err_code; + + fds_err_code = fds_gc(); + if (fds_err_code != FDS_SUCCESS) + APP_ERROR_CHECK_BOOL(NRF_ERROR_INTERNAL); + m_num_pending_ops++; +} + + +/**@brief Function handling FDS events. + * + * @param[in] p_evt FDS event. + */ +static void fds_cb(fds_evt_t const * const p_evt) +{ + ret_code_t err_code; + + switch (p_evt->id) + { + case FDS_EVT_INIT: + m_num_pending_ops = 0; + break; + + case FDS_EVT_DEL_FILE: + case FDS_EVT_DEL_RECORD: + // Schedule garbage collection + err_code = app_sched_event_put(NULL, 0, fds_gc_event); + APP_ERROR_CHECK(err_code); + break; + + case FDS_EVT_GC: + if (m_factory_reset && m_conn_handle != BLE_CONN_HANDLE_INVALID) + { + err_code = + sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + APP_ERROR_CHECK(err_code); + } + + // Fall through: + case FDS_EVT_UPDATE: + case FDS_EVT_WRITE: + if (m_num_pending_ops > 0) + { + m_num_pending_ops--; + } + break; + } +} + + +/**@brief Function performing flash access (read/write/clear). + * + * @param[in] p_params Flash access parameters. + */ +static ret_code_t access_flash_data(const flash_access_params_t * p_params) +{ + ret_code_t err_code; + fds_record_chunk_t chunk = {.p_data = p_params->p_chunk_buf}; + fds_record_t record_to_write = {.data.p_chunks = &chunk, .file_id = p_params->file_id}; + fds_flash_record_t record = {0}; + fds_record_desc_t desc = {0}; + fds_find_token_t ft = {0}; + + err_code = fds_record_find_by_key(p_params->record_key, &desc, &ft); + + // If its a read or clear, we can not accept errors on lookup + if (p_params->access_type == ES_FLASH_ACCESS_READ) + { + RETURN_IF_ERROR(err_code); + } + + if (p_params->access_type == ES_FLASH_ACCESS_CLEAR && err_code == FDS_ERR_NOT_FOUND) + { + return NRF_SUCCESS; + } + + switch (p_params->access_type) + { + case ES_FLASH_ACCESS_READ: + err_code = fds_record_open(&desc, &record); + RETURN_IF_ERROR(err_code); + + memcpy(p_params->p_data, record.p_data, p_params->size_bytes); + + err_code = fds_record_close(&desc); + RETURN_IF_ERROR(err_code); + + break; + + case ES_FLASH_ACCESS_WRITE: + // Note chunk.p_data points to p_params->p_chunk_buf + memcpy(p_params->p_chunk_buf, p_params->p_data, p_params->size_bytes); + + chunk.length_words = p_params->size_bytes / 4; + + if (p_params->size_bytes % 4 != 0) + { + chunk.length_words++; + } + + record_to_write.key = p_params->record_key; + + record_to_write.data.num_chunks = 1; + + if (err_code == FDS_ERR_NOT_FOUND) + { + err_code = fds_record_write(&desc, &record_to_write); + } + + else + { + err_code = fds_record_update(&desc, &record_to_write); + } + + RETURN_IF_ERROR(err_code); + m_num_pending_ops++; + break; + + case ES_FLASH_ACCESS_CLEAR: + err_code = fds_record_delete(&desc); + RETURN_IF_ERROR(err_code); + m_num_pending_ops++; + break; + + default: + break; + } + return NRF_SUCCESS; +} + + +ret_code_t es_flash_access_lock_key(uint8_t * p_lock_key, es_flash_access_t access_type) +{ + flash_access_params_t params = {.record_key = RECORD_KEY_LOCK_KEY, + .file_id = FILE_ID_ES_FLASH_LOCK_KEY, + .p_chunk_buf = lock_key_buf, + .p_data = (uint8_t *)p_lock_key, + .size_bytes = SIZE_OF_LOCK_KEY, + .access_type = access_type}; + + return access_flash_data(¶ms); +} + + +ret_code_t es_flash_access_beacon_config(es_flash_beacon_config_t * p_config, + es_flash_access_t access_type) +{ + ret_code_t err_code; + + flash_access_params_t params = {.record_key = RECORD_KEY_BEACON_CONFIG, + .file_id = FILE_ID_ES_FLASH, + .p_chunk_buf = beacon_config_buf, + .p_data = (uint8_t *)p_config, + .size_bytes = sizeof(es_flash_beacon_config_t), + .access_type = access_type}; + + err_code = access_flash_data(¶ms); + + return err_code; +} + + +ret_code_t es_flash_access_slot_configs(uint8_t slot_no, + es_slot_t * p_slot, + es_flash_access_t access_type) +{ + if (slot_no >= APP_MAX_ADV_SLOTS) + { + return NRF_ERROR_INVALID_PARAM; + } + + flash_access_params_t params = {.record_key = RECORD_KEY_SLOTS[slot_no], + .file_id = FILE_ID_ES_FLASH, + .p_chunk_buf = slots_buf_p[slot_no], + .p_data = (uint8_t *)p_slot, + .size_bytes = sizeof(es_slot_t), + .access_type = access_type}; + + return access_flash_data(¶ms); +} + + +ret_code_t es_flash_access_flags(es_flash_flags_t * p_flags, es_flash_access_t access_type) +{ + flash_access_params_t params = {.record_key = RECORD_KEY_FLAGS, + .file_id = FILE_ID_ES_FLASH, + .p_chunk_buf = flash_flags_buf, + .p_data = (uint8_t *)p_flags, + .size_bytes = sizeof(es_flash_flags_t), + .access_type = access_type}; + + return access_flash_data(¶ms); +} + + +ret_code_t es_flash_factory_reset(void) +{ + // Delete everything except the lock key: + ret_code_t ret_code = fds_file_delete(FILE_ID_ES_FLASH); + + if (ret_code == FDS_SUCCESS) + m_factory_reset = true; + return ret_code; +} + + +uint32_t es_flash_num_pending_ops(void) +{ + return m_num_pending_ops; +} + + +void es_flash_on_ble_evt(ble_evt_t * p_evt) +{ + switch (p_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + m_conn_handle = p_evt->evt.common_evt.conn_handle; + break; + + case BLE_GAP_EVT_DISCONNECTED: + m_conn_handle = BLE_CONN_HANDLE_INVALID; + if (m_factory_reset) + { + (void)sd_nvic_SystemReset(); + } + break; + } +} + + +ret_code_t es_flash_init(void) +{ + ret_code_t err_code; + + m_num_pending_ops = 1; // Will be set to 0 when getting FDS_EVT_INIT event + + m_conn_handle = BLE_CONN_HANDLE_INVALID; + + m_factory_reset = false; + + err_code = fds_register(fds_cb); + RETURN_IF_ERROR(err_code); + + err_code = fds_init(); + RETURN_IF_ERROR(err_code); + + return NRF_SUCCESS; +} + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_flash.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_flash.h new file mode 100644 index 0000000000000000000000000000000000000000..d1129aa6a4d9b9be08b94c0ff317ebc2eada35fe --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_flash.h @@ -0,0 +1,177 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ES_FLASH_H__ +#define ES_FLASH_H__ + +#include +#include +#include "es_slot.h" + + +/** + * @file + * @defgroup eddystone_flash Flash access + * @brief Types and functions to access the flash of the Eddystone beacon. + * @ingroup eddystone + * @{ + */ + +#define WORD_SIZE 4 + +#define FLASH_ACCES_ERROR_CHECK_ALLOW_NOT_FOUND(err_code) \ + if (err_code != (FDS_ERR_NOT_FOUND)) \ + APP_ERROR_CHECK(err_code); + +#define FLASH_OP_WAIT() \ + uint32_t pending_ops = es_flash_num_pending_ops(); \ + while (pending_ops != 0) \ + { \ + pending_ops = es_flash_num_pending_ops(); \ + } + +/**@brief Beacon configuration. */ +typedef struct +{ + nrf_ble_escs_adv_interval_t adv_interval; //!< Advertising interval. + bool remain_connectable; //!< Flag that specifies if the beacon should remain connectable. +} es_flash_beacon_config_t; + +/**@brief Structure for keeping track of which slot has a configuration that must be restored upon reboot. + * @details The size of this structure must be word aligned and match the flash block size of 32 bytes. + */ +typedef struct +{ + bool slot_is_empty[APP_MAX_ADV_SLOTS]; //!< Flag that indicates whether the slot is empty. + uint8_t padding[WORD_SIZE - ((APP_MAX_ADV_SLOTS + 1) % WORD_SIZE)]; //!< Padding used to ensure word alignment. +} es_flash_flags_t; + +/**@brief Flash access types. + */ +typedef enum +{ + ES_FLASH_ACCESS_READ, //!< Read data. + ES_FLASH_ACCESS_WRITE, //!< Write data. + ES_FLASH_ACCESS_CLEAR //!< Clear data. +} es_flash_access_t; + +/**@brief Function for accessing beacon configurations. + * + * @param[out,in] p_config Pointer to the beacon configuration buffer. + * @param[in] access_type Access type (see @ref es_flash_access_t). + * @return For possible return values, see: + * - @ref fds_record_find_by_key + * - @ref fds_record_open + * - @ref fds_record_close + * - @ref fds_record_write + * - @ref fds_record_update + * - @ref fds_record_delete + */ +ret_code_t es_flash_access_beacon_config(es_flash_beacon_config_t * p_config, + es_flash_access_t access_type); + +/**@brief Function for accessing slot configuration from flash. + * + * @param[in] slot_no Slot index. + * @param[out,in] p_slot Pointer to the slot configuration buffer. + * @param[in] access_type Access type (see @ref es_flash_access_t). + * @return For possible return values, see: + * - @ref fds_record_find_by_key + * - @ref fds_record_open + * - @ref fds_record_close + * - @ref fds_record_write + * - @ref fds_record_update + * - @ref fds_record_delete + */ +ret_code_t es_flash_access_slot_configs(uint8_t slot_no, + es_slot_t * p_slot, + es_flash_access_t access_type); + + +/**@brief Function for accessing the beacon lock key from flash. + * + * @param[out,in] p_lock_key Pointer to the lock key buffer. + * @param[in] access_type Access type (see @ref es_flash_access_t). + * @return For possible return values, see: + * - @ref fds_record_find_by_key + * - @ref fds_record_open + * - @ref fds_record_close + * - @ref fds_record_write + * - @ref fds_record_update + * - @ref fds_record_delete + */ +ret_code_t es_flash_access_lock_key(uint8_t * p_lock_key, es_flash_access_t access_type); + +/**@brief Function for accessing the flash configuration flag from flash. + * + * @param[out,in] p_flags Pointer to the flag buffer. + * @param[in] access_type Access type (see @ref es_flash_access_t). + * @return For possible return values, see: + * - @ref fds_record_find_by_key + * - @ref fds_record_open + * - @ref fds_record_close + * - @ref fds_record_write + * - @ref fds_record_update + * - @ref fds_record_delete + */ +ret_code_t es_flash_access_flags(es_flash_flags_t * p_flags, es_flash_access_t access_type); + +/**@brief Function for retrieving the number of queued operations. + * @return The number of operations that are queued. + */ +uint32_t es_flash_num_pending_ops(void); + +/**@brief Function for performing a factory reset. + * @return FDS return code. + */ +ret_code_t es_flash_factory_reset(void); + +void es_flash_on_ble_evt(ble_evt_t * p_evt); + +/**@brief Function for initializing the flash module. + * + * @return See @ref fds_init for possible return values. + */ +ret_code_t es_flash_init(void); + +/** + * @} + */ + +#endif // ES_FLASH_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts.c new file mode 100644 index 0000000000000000000000000000000000000000..a2a5b81e26c1a268e424ade521cf58fa88df94c9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts.c @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "es_gatts.h" +#include "es_gatts_read.h" +#include "es_gatts_write.h" +#include "es_slot.h" + +static nrf_ble_escs_lock_state_read_t m_lock_state; +static uint8_t m_active_slot; + +/**@brief Function checking if beacon is unlocked. + * + * @param[in] p_escs Pointer to Eddystone Configuration Service. + * + * @retval true If beacon is unlocked. + * @retval false If beacon is locked. + */ +static bool is_beacon_unlocked(const nrf_ble_escs_t * p_escs) +{ + return m_lock_state != NRF_BLE_ESCS_LOCK_STATE_LOCKED; +} + + +ret_code_t es_gatts_send_reply(nrf_ble_escs_t * p_escs, + ble_gatts_rw_authorize_reply_params_t * p_reply) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_reply); + + if (p_escs->conn_handle != BLE_CONN_HANDLE_INVALID) + { + return sd_ble_gatts_rw_authorize_reply(p_escs->conn_handle, p_reply); + } + + return NRF_ERROR_INVALID_STATE; +} + + +ret_code_t es_gatts_send_op_not_permitted(nrf_ble_escs_t * p_escs, bool read) +{ + ble_gatts_rw_authorize_reply_params_t reply = {0}; + + VERIFY_PARAM_NOT_NULL(p_escs); + + if (read) + { + reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; + reply.params.read.gatt_status = BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED; + } + + else + { + reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED; + } + + return es_gatts_send_reply(p_escs, &reply); +} + + + +void es_gatts_handle_write(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t val_handle, + uint8_t * p_data, + uint16_t length) +{ + ret_code_t err_code; + + if (is_beacon_unlocked(p_escs)) + { + if (uuid == BLE_UUID_ESCS_UNLOCK_CHAR) + { + err_code = es_gatts_send_op_not_permitted(p_escs, false); + APP_ERROR_CHECK(err_code); + } + + else + { + err_code = es_gatts_write_handle_unlocked_write( + p_escs, uuid, val_handle, p_data, length, m_active_slot); + APP_ERROR_CHECK(err_code); + } + } + + else + { + if (uuid == BLE_UUID_ESCS_UNLOCK_CHAR) + { + err_code = es_gatts_write_handle_unlock(p_escs, p_data, length, val_handle); + APP_ERROR_CHECK(err_code); + } + + else + { + err_code = es_gatts_send_op_not_permitted(p_escs, false); + APP_ERROR_CHECK(err_code); + } + } +} + + +void es_gatts_handle_read(nrf_ble_escs_t * p_escs, uint16_t uuid, uint16_t val_handle) +{ + ret_code_t err_code; + + if (is_beacon_unlocked(p_escs)) + { + if (uuid == BLE_UUID_ESCS_UNLOCK_CHAR) + { + err_code = es_gatts_send_op_not_permitted(p_escs, true); + APP_ERROR_CHECK(err_code); + } + + else + { + err_code = es_gatts_read_handle_unlocked_read(p_escs, uuid, val_handle, m_active_slot, m_lock_state); + APP_ERROR_CHECK(err_code); + } + } + + else // Beacon is locked. + { + if (uuid == BLE_UUID_ESCS_UNLOCK_CHAR) + { + err_code = es_gatts_read_handle_unlock(p_escs); + APP_ERROR_CHECK(err_code); + } + + else + { + err_code = es_gatts_read_handle_locked_read(p_escs, uuid, m_lock_state); + APP_ERROR_CHECK(err_code); + } + } +} + + +ret_code_t es_gatts_init(nrf_ble_escs_t * p_ble_escs) +{ + VERIFY_PARAM_NOT_NULL(p_ble_escs); + + m_active_slot = 0; + m_lock_state = NRF_BLE_ESCS_LOCK_STATE_LOCKED; + + p_ble_escs->p_active_slot = &m_active_slot; + p_ble_escs->p_lock_state = &m_lock_state; + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts.h new file mode 100644 index 0000000000000000000000000000000000000000..760f40ef326fb96a0ebf52c15a0ff96ec3c13736 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts.h @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef ES_GATTS_H__ +#define ES_GATTS_H__ + +#include +#include "nrf_ble_escs.h" + +/** + * @file + * @defgroup eddystone_gatts GATTS + * @brief Functions for handling GATTS write and read requests. + * @ingroup eddystone + * @{ + */ + +ret_code_t es_gatts_init(nrf_ble_escs_t * p_ble_escs); + +/**@brief Function for handling all write requests from the Central. + * + * @param[in] p_escs Pointer to the Eddystone Configuration Service. + * @param[in] uuid The UUID of the characteristic that is being written to. + * @param[in] val_handle Value handle field of the characteristic handle of the characteristic that is being written to. + * @param[in] p_data Pointer to the data to be written. + * @param[in] length Length of the data to be written. + * + */ +void es_gatts_handle_write(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t val_handle, + uint8_t * p_data, + uint16_t length); + + +/**@brief Function for handling all read requests from the Central. + * + * @param[in] p_escs Pointer to the Eddystone Configuration Service. + * @param[in] uuid The UUID of the characteristic that is being read from. + * @param[in] val_handle Value handle field of the characteristic handle of the characteristic that is being read from. + * + */ +void es_gatts_handle_read(nrf_ble_escs_t * p_escs, uint16_t uuid, uint16_t val_handle); + +/**@brief Function for sending an RW-authorization reply. + * + * @param[in] p_escs Pointer to the Eddystone Configuration Service. + * @param[in] p_reply Pointer to the reply to send. + * + * @retval NRF_SUCCESS If the reply was successfully issued to the SoftDevice. + * @retval NRF_ERROR_NULL If either of the pointers @p p_escs or @p p_reply is NULL. + * @retval NRF_ERROR_INVALID_STATE If the connection handle of @p p_escs is invalid. + * @return Otherwise, an error code from sd_ble_gatts_rw_authorize_reply() is returned. + */ +ret_code_t es_gatts_send_reply(nrf_ble_escs_t * p_escs, ble_gatts_rw_authorize_reply_params_t * p_reply); + +/**@brief Function for sending an RW-authorization reply with status 'Operation not permitted'. + * + * @param[in] p_escs Pointer to the Eddystone Configuration Service. + * @param[in] op_is_read Flag that specifies if the operation being responded to is a 'read' operation. + If false, a 'write' operation is assumed. + * + * @retval NRF_ERROR_NULL If @p p_escs is NULL. + * @return Otherwise, the error code from es_gatts_send_reply() is returned. + */ +ret_code_t es_gatts_send_op_not_permitted(nrf_ble_escs_t * p_escs, bool op_is_read); + +/** + * @} + */ + +#endif // ES_GATTS_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts_read.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts_read.c new file mode 100644 index 0000000000000000000000000000000000000000..80b2977892ff456c2ddf8ad94facb4d3f0da2b7f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts_read.c @@ -0,0 +1,246 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "es_gatts_read.h" +#include "es_adv.h" +#include "es_gatts.h" +#include "es_security.h" +#include "es_slot.h" + +static ret_code_t send_read_reply(nrf_ble_escs_t * p_escs, ble_gatts_rw_authorize_reply_params_t * p_reply) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_reply); + + p_reply->type = BLE_GATTS_AUTHORIZE_TYPE_READ; + p_reply->params.read.update = 1; + p_reply->params.read.offset = 0; + + return es_gatts_send_reply(p_escs, p_reply); +} + + +static ret_code_t read_value(nrf_ble_escs_t * p_escs, uint8_t length, const void * p_value) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_value); + + ble_gatts_rw_authorize_reply_params_t reply = {0}; + reply.params.read.len = length; + reply.params.read.p_data = p_value; + reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS; + + return send_read_reply(p_escs, &reply); +} + + +static ret_code_t read_from_gattdb(nrf_ble_escs_t * p_escs, uint16_t val_handle) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + + ret_code_t err_code; + + // Go straight to the characteristic + uint8_t value_buffer[ESCS_ADV_SLOT_CHAR_LENGTH_MAX] = {0}; + ble_gatts_value_t value = {.len = sizeof(value_buffer), + .offset = 0, + .p_value = &(value_buffer[0])}; + + err_code = sd_ble_gatts_value_get(p_escs->conn_handle, val_handle, &value); + RETURN_IF_ERROR(err_code); + + return read_value(p_escs, value.len, value.p_value); +} + + +static ret_code_t read_adv_slot(nrf_ble_escs_t * p_escs, uint8_t active_slot, const es_slot_reg_t * p_reg) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + + ble_gatts_rw_authorize_reply_params_t reply = {0}; + uint8_t eid_buf[14]; + + // If an EID slot is read, load scaler, clock value and ephemeral ID. + if (p_reg->slots[active_slot].adv_frame.type == ES_FRAME_TYPE_EID) + { + /*lint -save -e666 */ + uint32_t clock_value = es_security_clock_get(active_slot); + clock_value = BYTES_REVERSE_32BIT(clock_value); + /*lint -restore */ + + reply.params.read.len = ES_EID_GATTS_READ_LENGTH; + + // Fill EID buffer with data + eid_buf[ES_EID_GATTS_READ_FRAME_TYPE_IDX] = ES_FRAME_TYPE_EID; + eid_buf[ES_EID_GATTS_READ_EXPONENT_IDX] = es_security_scaler_get(active_slot); + + memcpy(&eid_buf[ES_EID_GATTS_READ_CLCK_VALUE_IDX], &clock_value, sizeof(clock_value)); + /*lint -save -e545 */ + memcpy(&eid_buf[ES_EID_GATTS_READ_EID_IDX], + &p_reg->slots[active_slot].adv_frame.frame.eid.eid, + ES_EID_ID_LENGTH); + /*lint -restore */ + reply.params.read.p_data = eid_buf; + } + + // Otherwise, simply load the contents of the frame. + else + { + // Check if slot being read is an eTLM slot. + if ((p_reg->num_configured_eid_slots > 0) && p_reg->tlm_configured && (p_reg->tlm_slot == active_slot)) + { + // Fill eTLM slot using EID key from first EID slot. + es_slot_etlm_update(p_reg->eid_slots_configured[0]); + } + reply.params.read.len = p_reg->slots[active_slot].adv_frame.length; + reply.params.read.p_data = (uint8_t *)&p_reg->slots[active_slot].adv_frame.frame; + } + + reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS; + + return send_read_reply(p_escs, &reply); +} + + +ret_code_t es_gatts_read_handle_locked_read(nrf_ble_escs_t * p_escs, uint16_t uuid, uint8_t lock_state) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + + if (uuid == BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR) + { + uint8_t retval = APP_IS_REMAIN_CONNECTABLE_SUPPORTED; + return read_value(p_escs, sizeof(retval), &retval); + } + + else if (uuid == BLE_UUID_ESCS_LOCK_STATE_CHAR) + { + return read_value(p_escs, sizeof(lock_state), &lock_state); + } + + else + { + return es_gatts_send_op_not_permitted(p_escs, true); + } +} + + +ret_code_t es_gatts_read_handle_unlock(nrf_ble_escs_t * p_escs) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + + ret_code_t err_code; + uint8_t key_buff[ESCS_AES_KEY_SIZE]; + + err_code = es_security_random_challenge_generate(key_buff); + RETURN_IF_ERROR(err_code); + + es_security_unlock_prepare(key_buff); + + return read_value(p_escs, ESCS_AES_KEY_SIZE, key_buff); +} + + +ret_code_t es_gatts_read_handle_unlocked_read(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t val_handle, + uint8_t active_slot, + uint8_t lock_state) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + switch (uuid) + { + case BLE_UUID_ESCS_BROADCAST_CAP_CHAR: + case BLE_UUID_ESCS_UNLOCK_CHAR: + case BLE_UUID_ESCS_PUBLIC_ECDH_KEY_CHAR: + case BLE_UUID_ESCS_ACTIVE_SLOT_CHAR: + return read_from_gattdb(p_escs, val_handle); + + case BLE_UUID_ESCS_LOCK_STATE_CHAR: + return read_value(p_escs, sizeof(lock_state), &lock_state); + + case BLE_UUID_ESCS_ADV_INTERVAL_CHAR: + { + nrf_ble_escs_adv_interval_t adv_interval = es_adv_interval_get(); + adv_interval = BYTES_SWAP_16BIT(adv_interval); + return read_value(p_escs, sizeof(adv_interval), &adv_interval); + } + + case BLE_UUID_ESCS_RADIO_TX_PWR_CHAR: + return read_value(p_escs, + sizeof(nrf_ble_escs_radio_tx_pwr_t), + &p_reg->slots[active_slot].radio_tx_pwr); + + case BLE_UUID_ESCS_ADV_TX_PWR_CHAR: + return read_value(p_escs, + sizeof(nrf_ble_escs_radio_tx_pwr_t), + p_reg->slots[active_slot].adv_custom_tx_power + ? (uint8_t *)(&p_reg->slots[active_slot].custom_tx_power) + : (uint8_t *)(&p_reg->slots[active_slot].radio_tx_pwr)); + + case BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR: + { + uint8_t retval = APP_IS_REMAIN_CONNECTABLE_SUPPORTED; + return read_value(p_escs, sizeof(retval), &retval); + } + + case BLE_UUID_ESCS_EID_ID_KEY_CHAR: + if (p_reg->slots[active_slot].configured && + (p_reg->slots[active_slot].adv_frame.type == ES_FRAME_TYPE_EID)) + { + return read_value(p_escs, + sizeof(nrf_ble_escs_eid_id_key_t), + &p_reg->slots[active_slot].encrypted_eid_id_key); + } + + else + { + return es_gatts_send_op_not_permitted(p_escs, true); + } + + case BLE_UUID_ESCS_RW_ADV_SLOT_CHAR: + return read_adv_slot(p_escs, active_slot, p_reg); + + default: + return NRF_ERROR_INVALID_PARAM; + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts_read.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts_read.h new file mode 100644 index 0000000000000000000000000000000000000000..bacd51903c2d2264dedee1d782188f6614d88596 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts_read.h @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef ES_GATTS_READ_H__ +#define ES_GATTS_READ_H__ + +#include +#include "nrf_ble_escs.h" + +/** + * @file + * @defgroup eddystone_gatts_read GATTS read + * @brief Functions for handling GATTS read requests. + * @ingroup eddystone_gatts + * @{ + */ + +ret_code_t es_gatts_read_send_not_permitted(nrf_ble_escs_t * p_escs); + +ret_code_t es_gatts_read_handle_unlocked_read(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t val_handle, + uint8_t active_slot, + uint8_t lock_state); + +ret_code_t es_gatts_read_handle_unlock(nrf_ble_escs_t * p_escs); + +ret_code_t es_gatts_read_handle_locked_read(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint8_t lock_state); + +/** + * @} + */ + +#endif // ES_GATTS_READ_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts_write.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts_write.c new file mode 100644 index 0000000000000000000000000000000000000000..986e3883398a27acd63167f9bbf6f731bd6297b1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts_write.c @@ -0,0 +1,254 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "es_gatts_write.h" +#include "es_adv.h" +#include "es_flash.h" +#include "es_gatts.h" +#include "es_security.h" + + +static ret_code_t send_write_reply(nrf_ble_escs_t * p_escs, ble_gatts_rw_authorize_reply_params_t * p_reply) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_reply); + + p_reply->type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + p_reply->params.write.update = 1; + p_reply->params.write.offset = 0; + + return es_gatts_send_reply(p_escs, p_reply); +} + + +/**@brief Function checking if length of event is correct, given the frame data. + * + * @param[in] p_data Written ADV Slot data. + * @param[in] length Written length. + * + * @retval true If length is valid. + * @retval false If length is not valid. + */ +static bool length_is_valid(uint8_t * p_data, uint8_t length) +{ + if (length == 0 || (length == 1 && p_data[0] == 0)) + { + return true; + } + + else + { + switch ((es_frame_type_t)p_data[0]) + { + case ES_FRAME_TYPE_UID: + return length == ESCS_UID_WRITE_LENGTH; + + case ES_FRAME_TYPE_URL: + return ((length >= ESCS_URL_MIN_WRITE_LENGTH) && (length <= ESCS_URL_WRITE_LENGTH)); + + case ES_FRAME_TYPE_TLM: + return (length == ESCS_TLM_WRITE_LENGTH); + + case ES_FRAME_TYPE_EID: + return ((length == ESCS_EID_WRITE_ECDH_LENGTH) || + (length == ESCS_EID_WRITE_IDK_LENGTH)); + + default: + return false; + } + } +} + + +ret_code_t es_gatts_write_handle_unlocked_write(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t val_handle, + uint8_t * p_data, + uint16_t length, + uint8_t active_slot) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_data); + + ret_code_t err_code; + ble_gatts_rw_authorize_reply_params_t reply = {0}; + bool long_write = false; + + reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + + switch (uuid) + { + case BLE_UUID_ESCS_ACTIVE_SLOT_CHAR: + if (*p_data > APP_MAX_ADV_SLOTS - 1) + { + // Invalid Attribute Length: for an attempt to write illegal values. + // The beacon will list the total number of available slots in the + // max_supported_total_slots field in the Capabilities characteristic. + reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH; + length = 0; + } + break; + + case BLE_UUID_ESCS_ADV_INTERVAL_CHAR: + es_adv_interval_set(BYTES_SWAP_16BIT(*(nrf_ble_escs_adv_interval_t *)p_data)); + break; + + case BLE_UUID_ESCS_RADIO_TX_PWR_CHAR: + es_slot_radio_tx_pwr_set(active_slot, *(nrf_ble_escs_radio_tx_pwr_t *)(p_data)); + break; + + case BLE_UUID_ESCS_ADV_TX_PWR_CHAR: + // Update slot info so that ADV data will only be read from what is written by client. + es_slot_set_adv_custom_tx_power(active_slot, *(nrf_ble_escs_radio_tx_pwr_t *)(p_data)); + break; + + case BLE_UUID_ESCS_LOCK_STATE_CHAR: + if (length == 1 && (*p_data == NRF_BLE_ESCS_LOCK_BYTE_LOCK || + *p_data == NRF_BLE_ESCS_LOCK_BYTE_DISABLE_AUTO_RELOCK)) + { + // Do nothing special, allow the write. + } + else if (length == ESCS_LOCK_STATE_NEW_LOCK_CODE_WRITE_LENGTH && + *p_data == NRF_BLE_ESCS_LOCK_BYTE_LOCK) + { + // 0x00 + key[16] : transition to lock state and update the lock code. + err_code = es_security_lock_code_update((p_data) + 1); + RETURN_IF_ERROR(err_code); + + // Only write the lock byte (0x00) to the characteristic, so set length to 1. + length = 1; + } + else + { + // Any invalid values locks the characteristic by default. + *p_data = NRF_BLE_ESCS_LOCK_BYTE_LOCK; + length = 1; + } + break; + + case BLE_UUID_ESCS_RW_ADV_SLOT_CHAR: + if (length > 20) + { + long_write = true; + } + reply.params.write.gatt_status = length_is_valid(p_data, length) + ? BLE_GATT_STATUS_SUCCESS + : BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH; + + if (reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) + { + es_slot_on_write(active_slot, length, p_data); + es_adv_interval_set(es_adv_interval_get()); // Ensure that valid advertisement interval is used. + } + break; + + case BLE_UUID_ESCS_FACTORY_RESET_CHAR: + if (*p_data == 0x0B) + { + err_code = es_flash_factory_reset(); + RETURN_IF_ERROR(err_code); + } + break; + + case BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR: +#if APP_IS_REMAIN_CONNECTABLE_SUPPORTED == ESCS_FUNCT_REMAIN_CONNECTABLE_SUPPORTED_Yes + if (*p_data != 0) + { + es_adv_remain_connectable_set(true); + } + + else + { + es_adv_remain_connectable_set(false); + } +#endif + break; + + default: + break; + } + reply.params.write.len = length; + reply.params.write.p_data = p_data; + + if (!long_write) + { + return send_write_reply(p_escs, &reply); + } + + else + { + return NRF_SUCCESS; + } +} + + +ret_code_t es_gatts_write_handle_unlock(nrf_ble_escs_t * p_escs, + uint8_t * p_data, + uint16_t length, + uint16_t val_handle) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_data); + + ret_code_t err_code; + ble_gatts_rw_authorize_reply_params_t reply = {0}; + ble_gatts_value_t value = {.len = length, .offset = 0, .p_value = p_data}; + + if (length == ESCS_AES_KEY_SIZE) + { + err_code = sd_ble_gatts_value_set(p_escs->conn_handle, val_handle, &value); + + if (err_code == NRF_SUCCESS) + { + reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + es_security_unlock_verify((value.p_value)); + } + + else + { + reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED; + } + } + + reply.params.write.len = length; + reply.params.write.p_data = (const uint8_t *)value.p_value; + + return send_write_reply(p_escs, &reply); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts_write.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts_write.h new file mode 100644 index 0000000000000000000000000000000000000000..fc69b9ee1dccba7d7916664a863052d3dab673ce --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_gatts_write.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef ES_GATTS_WRITE_H__ +#define ES_GATTS_WRITE_H__ + +#include +#include "nrf_ble_escs.h" + +/** + * @file + * @defgroup eddystone_gatts_write GATTS write + * @brief Functions for handling GATTS write requests. + * @ingroup eddystone_gatts + * @{ + */ + +ret_code_t es_gatts_write_handle_unlocked_write(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t val_handle, + uint8_t * p_data, + uint16_t length, + uint8_t active_slot); + +ret_code_t es_gatts_write_handle_unlock(nrf_ble_escs_t * p_escs, + uint8_t * p_data, + uint16_t length, + uint16_t val_handle); + +/** + * @} + */ + +#endif // ES_GATTS_WRITE_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_security.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_security.c new file mode 100644 index 0000000000000000000000000000000000000000..dcda9ed43ad05a894a3ccf0cb3bfb564fa81e23a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_security.c @@ -0,0 +1,530 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "es_security.h" +#include "aes.h" +#include "app_timer.h" +#include "cifra_eax_aes.h" +#include "es_flash.h" +#include "es_stopwatch.h" +#include "fds.h" +#include "modes.h" +#include "occ_curve25519.h" +#include "occ_hmac_sha256.h" + +#define TK_ROLLOVER 0x10000 + +#define NONCE_SIZE (6) +#define TAG_SIZE (2) +#define SALT_SIZE (2) +#define TLM_DATA_SIZE (ES_TLM_LENGTH - 2) +#define EIK_SIZE (ESCS_AES_KEY_SIZE) + +/**@brief Timing structure. */ +typedef struct +{ + uint32_t time_counter; + uint8_t k_scaler; +} es_security_timing_t; + +/**@brief Security slot structure. */ +typedef struct +{ + nrf_ecb_hal_data_t aes_ecb_ik; + nrf_ecb_hal_data_t aes_ecb_tk; + uint8_t eid[ES_EID_ID_LENGTH]; + es_security_timing_t timing; + bool is_occupied; +} es_security_slot_t; + +/**@brief Key pair structure. */ +typedef struct +{ + uint8_t private[ESCS_ECDH_KEY_SIZE]; + uint8_t public[ESCS_ECDH_KEY_SIZE]; +} ecdh_key_pair_t; + +/**@brief ECDH structure. */ +typedef struct +{ + ecdh_key_pair_t ecdh_key_pair; +} es_security_ecdh_t; + +static nrf_ecb_hal_data_t m_aes_ecb_lk; +static es_security_slot_t m_security_slot[APP_MAX_EID_SLOTS]; +static es_security_ecdh_t m_ecdh; +static es_security_msg_cb_t m_security_callback; +static es_stopwatch_id_t m_seconds_passed_sw_id; + +/**@brief Generates a EID with the Temporary Key*/ +static void eid_generate(uint8_t slot_no) +{ + memset(m_security_slot[slot_no].aes_ecb_tk.cleartext, 0, ESCS_AES_KEY_SIZE); + m_security_slot[slot_no].aes_ecb_tk.cleartext[11] = m_security_slot[slot_no].timing.k_scaler; + + uint32_t k_bits_cleared_time = + (m_security_slot[slot_no].timing.time_counter >> m_security_slot[slot_no].timing.k_scaler) + << m_security_slot[slot_no].timing.k_scaler; + + m_security_slot[slot_no].aes_ecb_tk.cleartext[12] = + (uint8_t)((k_bits_cleared_time >> 24) & 0xff); + m_security_slot[slot_no].aes_ecb_tk.cleartext[13] = + (uint8_t)((k_bits_cleared_time >> 16) & 0xff); + m_security_slot[slot_no].aes_ecb_tk.cleartext[14] = (uint8_t)((k_bits_cleared_time >> 8) & 0xff); + m_security_slot[slot_no].aes_ecb_tk.cleartext[15] = (uint8_t)((k_bits_cleared_time) & 0xff); + + AES128_ECB_encrypt(m_security_slot[slot_no].aes_ecb_tk.cleartext, + m_security_slot[slot_no].aes_ecb_tk.key, + m_security_slot[slot_no].aes_ecb_tk.ciphertext); + + memcpy(m_security_slot[slot_no].eid, + m_security_slot[slot_no].aes_ecb_tk.ciphertext, + ES_EID_ID_LENGTH); + + m_security_callback(slot_no, ES_SECURITY_MSG_EID); +} + + +/**@brief Generates a temporary key with the Identity key. */ +static void temp_key_generate(uint8_t slot_no) +{ + memset(m_security_slot[slot_no].aes_ecb_ik.cleartext, 0, ESCS_AES_KEY_SIZE); + m_security_slot[slot_no].aes_ecb_ik.cleartext[11] = 0xFF; + m_security_slot[slot_no].aes_ecb_ik.cleartext[14] = + (uint8_t)((m_security_slot[slot_no].timing.time_counter >> 24) & 0xff); + m_security_slot[slot_no].aes_ecb_ik.cleartext[15] = + (uint8_t)((m_security_slot[slot_no].timing.time_counter >> 16) & 0xff); + + AES128_ECB_encrypt(m_security_slot[slot_no].aes_ecb_ik.cleartext, + m_security_slot[slot_no].aes_ecb_ik.key, + m_security_slot[slot_no].aes_ecb_ik.ciphertext); + + memcpy(m_security_slot[slot_no].aes_ecb_tk.key, + m_security_slot[slot_no].aes_ecb_ik.ciphertext, + ESCS_AES_KEY_SIZE); +} + + +static void check_rollovers_and_update_eid(uint8_t slot_no) +{ + if (m_security_slot[slot_no].timing.time_counter % TK_ROLLOVER == 0) + { + temp_key_generate(slot_no); + } + /*lint -save -e573 */ + if ((m_security_slot[slot_no].timing.time_counter % + (2 << (m_security_slot[slot_no].timing.k_scaler - 1))) == 0) + { + eid_generate(slot_no); + } + /*lint -restore */ +} + + +/**@brief Initialize lock code from flash. If it does not exist, copy from APP_CONFIG_LOCK_CODE. + */ +static void lock_code_init(uint8_t * p_lock_buff) +{ + ret_code_t err_code; + + err_code = es_flash_access_lock_key(p_lock_buff, ES_FLASH_ACCESS_READ); + FLASH_ACCES_ERROR_CHECK_ALLOW_NOT_FOUND(err_code); + + // If no lock keys exist, then generate one and copy it to buffer. + if (err_code == FDS_ERR_NOT_FOUND) + { + uint8_t lock_code[16] = APP_CONFIG_LOCK_CODE; + + memcpy(p_lock_buff, lock_code, sizeof(lock_code)); + + err_code = es_flash_access_lock_key(p_lock_buff, ES_FLASH_ACCESS_WRITE); + APP_ERROR_CHECK(err_code); + } +} + + +/**@brief Generates a the private/public ECDH key pair. + * + * @param[out] p_priv_buffer buffer of size 32 bytes to hold the private key. + * @param[out] p_pub_buffer buffer of size 32 bytes to hold the public key. + */ +static void es_beacon_ecdh_pair_generate(uint8_t * p_priv_buffer, uint8_t * p_pub_buffer) +{ + // Generate random beacon private key. + uint8_t pool_size; + uint8_t bytes_available; + + (void)sd_rand_application_pool_capacity_get(&pool_size); + (void)sd_rand_application_bytes_available_get(&bytes_available); + + while (bytes_available < pool_size) + { + // wait for SD to acquire enough RNs. + (void)sd_rand_application_bytes_available_get(&bytes_available); + } + + (void)sd_rand_application_vector_get(p_priv_buffer, pool_size); + + if (pool_size < ESCS_ECDH_KEY_SIZE) + { + (void)sd_rand_application_bytes_available_get(&bytes_available); + + while (bytes_available < (ESCS_ECDH_KEY_SIZE - pool_size)) + { + // Wait for SD to acquire enough RNs. + (void)sd_rand_application_bytes_available_get(&bytes_available); + } + (void)sd_rand_application_vector_get(p_priv_buffer + pool_size, + ESCS_ECDH_KEY_SIZE - pool_size); + } + + // Create beacon public 32-byte ECDH key from private 32-byte ECDH key. + occ_curve25519_scalarmult_base(p_pub_buffer, p_priv_buffer); +} + + +void es_security_update_time(void) +{ + static uint32_t timer_persist; + uint32_t second_since_last_invocation = es_stopwatch_check(m_seconds_passed_sw_id); + + if (second_since_last_invocation > 0) + { + for (uint32_t i = 0; i < APP_MAX_EID_SLOTS; ++i) + { + if (m_security_slot[i].is_occupied) + { + m_security_slot[i].timing.time_counter += second_since_last_invocation; + check_rollovers_and_update_eid(i); + } + } + + // Every 24 hr, write the new EID timer to flash. + timer_persist += second_since_last_invocation; + const uint32_t TWENTY_FOUR_HOURS = 60 * 60 * 24; + if (timer_persist >= TWENTY_FOUR_HOURS) + { + for (uint32_t i = 0; i < APP_MAX_EID_SLOTS; ++i) + { + if (m_security_slot[i].is_occupied) + { + m_security_callback(i, ES_SECURITY_MSG_STORE_TIME); + } + } + timer_persist = 0; + } + } +} + + +void es_security_eid_slots_restore(uint8_t slot_no, + uint8_t k_scaler, + uint32_t time_counter, + const uint8_t * p_ik) +{ + m_security_slot[slot_no].timing.k_scaler = k_scaler; + m_security_slot[slot_no].timing.time_counter = time_counter; + memcpy(m_security_slot[slot_no].aes_ecb_ik.key, p_ik, ESCS_AES_KEY_SIZE); + m_security_slot[slot_no].is_occupied = true; + m_security_callback(slot_no, ES_SECURITY_MSG_IK); + temp_key_generate(slot_no); + eid_generate(slot_no); +} + + +ret_code_t es_security_lock_code_update(uint8_t * p_ecrypted_key) +{ + uint8_t temp_buff[ESCS_AES_KEY_SIZE] = {0}; + + AES128_ECB_decrypt(p_ecrypted_key, m_aes_ecb_lk.key, temp_buff); + + memcpy(m_aes_ecb_lk.key, temp_buff, ESCS_AES_KEY_SIZE); + return es_flash_access_lock_key(m_aes_ecb_lk.key, ES_FLASH_ACCESS_WRITE); +} + + +void es_security_unlock_prepare(uint8_t * p_challenge) +{ + memcpy(m_aes_ecb_lk.cleartext, p_challenge, ESCS_AES_KEY_SIZE); + AES128_ECB_encrypt(m_aes_ecb_lk.cleartext, m_aes_ecb_lk.key, m_aes_ecb_lk.ciphertext); +} + + +void es_security_unlock_verify(uint8_t * p_unlock_token) +{ + if (memcmp(p_unlock_token, m_aes_ecb_lk.ciphertext, ESCS_AES_KEY_SIZE) == 0) + { + m_security_callback(0, ES_SECURITY_MSG_UNLOCKED); + } +} + + +ret_code_t es_security_random_challenge_generate(uint8_t * p_rand_chlg_buff) +{ + return sd_rand_application_vector_get(p_rand_chlg_buff, ESCS_AES_KEY_SIZE); +} + + +void es_security_shared_ik_receive(uint8_t slot_no, uint8_t * p_encrypted_ik, uint8_t scaler_k) +{ + m_security_slot[slot_no].is_occupied = true; + m_security_slot[slot_no].timing.k_scaler = scaler_k; + m_security_slot[slot_no].timing.time_counter = APP_CONFIG_TIMING_INIT_VALUE; + + AES128_ECB_decrypt(p_encrypted_ik, m_aes_ecb_lk.key, m_security_slot[slot_no].aes_ecb_ik.key); + + temp_key_generate(slot_no); + eid_generate(slot_no); + + m_security_callback(slot_no, ES_SECURITY_MSG_IK); +} + + +void es_security_client_pub_ecdh_receive(uint8_t slot_no, uint8_t * p_pub_ecdh, uint8_t scaler_k) +{ + static uint8_t attempt_counter = 0; + + m_security_slot[slot_no].is_occupied = true; + m_security_slot[slot_no].timing.k_scaler = scaler_k; + m_security_slot[slot_no].timing.time_counter = APP_CONFIG_TIMING_INIT_VALUE; + + uint8_t beacon_private[ESCS_ECDH_KEY_SIZE]; // Beacon private ECDH key + uint8_t beacon_public[ESCS_ECDH_KEY_SIZE]; // Beacon public ECDH key + uint8_t phone_public[ESCS_ECDH_KEY_SIZE]; // Phone public ECDH key + uint8_t shared[ESCS_ECDH_KEY_SIZE]; // Shared secret ECDH key + const uint8_t salt[1] = {0x01}; // Salt + uint8_t identity_key[ESCS_AES_KEY_SIZE]; // Identity Key + + // Get public 32-byte service ECDH key from phone. + memcpy(phone_public, p_pub_ecdh, ESCS_ECDH_KEY_SIZE); + + // Generate new set of keys for use with this EID slot. + es_beacon_ecdh_pair_generate(beacon_private, beacon_public); + memcpy(m_ecdh.ecdh_key_pair.private, beacon_private, ESCS_ECDH_KEY_SIZE); + memcpy(m_ecdh.ecdh_key_pair.public, beacon_public, ESCS_ECDH_KEY_SIZE); + + // Generate shared 32-byte ECDH secret from beacon private service ECDH key and phone public ECDH key. + occ_curve25519_scalarmult(shared, beacon_private, phone_public); + + // Generate key material using shared ECDH secret as salt and public_keys as key material. RFC 2104 HMAC-SHA256. + uint8_t digest[64]; + uint8_t public_keys[64]; + memcpy(public_keys, phone_public, 32); + memcpy(public_keys + 32, beacon_public, 32); + + occ_hmac_sha256(digest, public_keys, 64, shared, 32); + + // Zero check of the shared secret becoming zero, try generating a new key pair if so. Max attempt limit twice. + uint8_t empty_check[32] = {0}; + + if (memcmp(empty_check, shared, 32) == 0) + { + if (attempt_counter < 2) + { + attempt_counter++; + es_beacon_ecdh_pair_generate(beacon_private, beacon_public); + } + } + else + { + attempt_counter = 0; + } + + // Generate 16-byte Identity Key from shared ECDH secret using RFC 2104 HMAC-SHA256 and salt. + uint8_t digest_salted[64]; + occ_hmac_sha256(digest_salted, digest, 32, salt, 1); + + memcpy(identity_key, digest_salted, ESCS_AES_KEY_SIZE); + + memcpy(m_security_slot[slot_no].aes_ecb_ik.key, identity_key, ESCS_AES_KEY_SIZE); + + temp_key_generate(slot_no); + eid_generate(slot_no); + + m_security_callback(slot_no, ES_SECURITY_MSG_ECDH); + m_security_callback(slot_no, ES_SECURITY_MSG_IK); +} + + +void es_security_pub_ecdh_get(uint8_t slot_no, uint8_t * p_edch_buffer) +{ + memcpy(p_edch_buffer, m_ecdh.ecdh_key_pair.public, ESCS_ECDH_KEY_SIZE); +} + + +uint32_t es_security_clock_get(uint8_t slot_no) +{ + return m_security_slot[slot_no].timing.time_counter; +} + + +void es_security_eid_slot_destroy(uint8_t slot_no) +{ + memset(&m_security_slot[slot_no], 0, sizeof(es_security_slot_t)); +} + + +uint8_t es_security_scaler_get(uint8_t slot_no) +{ + return m_security_slot[slot_no].timing.k_scaler; +} + + +void es_security_eid_get(uint8_t slot_no, uint8_t * p_eid_buffer) +{ + memcpy(p_eid_buffer, m_security_slot[slot_no].eid, ES_EID_ID_LENGTH); +} + + +void es_security_encrypted_eid_id_key_get(uint8_t slot_no, uint8_t * p_key_buffer) +{ + memcpy(m_aes_ecb_lk.cleartext, m_security_slot[slot_no].aes_ecb_ik.key, ESCS_AES_KEY_SIZE); + AES128_ECB_encrypt(m_aes_ecb_lk.cleartext, m_aes_ecb_lk.key, m_aes_ecb_lk.ciphertext); + memcpy(p_key_buffer, m_aes_ecb_lk.ciphertext, ESCS_AES_KEY_SIZE); +} + + +void es_security_plain_eid_id_key_get(uint8_t slot_no, uint8_t * p_key_buffer) +{ + memcpy(p_key_buffer, m_security_slot[slot_no].aes_ecb_ik.key, ESCS_AES_KEY_SIZE); +} + + +void es_security_tlm_to_etlm(uint8_t ik_slot_no, es_tlm_frame_t * p_tlm, es_etlm_frame_t * p_etlm) +{ + cf_prp prp; // Describe the block cipher to use. + + uint8_t plain[TLM_DATA_SIZE] = {0}; // Plaintext tlm, without the frame byte and version. + size_t nplain = TLM_DATA_SIZE; // Length of message plaintext. + + /*lint -save -e420 */ + memcpy(plain, &p_tlm->vbatt[0], sizeof(plain)); + + const uint8_t header = 0; // Additionally authenticated data (AAD). + size_t nheader = 0; // Length of header (AAD). May be zero. + + uint8_t key[EIK_SIZE] = {0}; // Encryption/decryption key: EIK. + size_t nkey = EIK_SIZE; // Length of encryption/decryption key. + + memcpy(key, &m_security_slot[ik_slot_no].aes_ecb_ik.key[0], EIK_SIZE); + /*lint -restore */ + + uint8_t nonce[NONCE_SIZE] = {0}; // Nonce. This must not repeat for a given key. + size_t nnonce = NONCE_SIZE; // Length of nonce.First 4 bytes are beacon time base with k-bits cleared. + // Last two bits are randomly generated + + // Take the current timestamp and clear the lowest K bits, use it as nonce. + uint32_t k_bits_cleared_time = (m_security_slot[ik_slot_no].timing.time_counter + >> m_security_slot[ik_slot_no].timing.k_scaler) + << m_security_slot[ik_slot_no].timing.k_scaler; + + + nonce[0] = (uint8_t)((k_bits_cleared_time >> 24) & 0xff); + nonce[1] = (uint8_t)((k_bits_cleared_time >> 16) & 0xff); + nonce[2] = (uint8_t)((k_bits_cleared_time >> 8) & 0xff); + nonce[3] = (uint8_t)((k_bits_cleared_time) & 0xff); + + // Generate random salt. + uint8_t salt[SALT_SIZE] = {0}; + (void)sd_rand_application_vector_get(salt, SALT_SIZE); + memcpy(&nonce[4], salt, SALT_SIZE); + + uint8_t cipher[ES_ETLM_ECRYPTED_LENGTH]; // Ciphertext output. nplain bytes are written. + uint8_t tag[TAG_SIZE] = {0}; // Authentication tag. ntag bytes are written. + size_t ntag = TAG_SIZE; // Length of authentication tag. + + // Encryption + // -------------------------------------------------------------------------- + cf_aes_context ctx; + cf_aes_init(&ctx, key, nkey); + + prp.encrypt = (cf_prp_block)cf_aes_encrypt; // Encryption context + prp.decrypt = (cf_prp_block)cf_aes_decrypt; // Decryption context + prp.blocksz = ESCS_AES_KEY_SIZE; + + cf_eax_encrypt(&prp, + &ctx, + plain, // Plaintext input, aka TLM + nplain, // Length of TLM + &header, // Empty + nheader, // Empty + nonce, // Nonce input + nnonce, // Length of nonce + cipher, // Encrypted output + tag, // Authentication tag output + ntag // Length of authentication tag + ); + + // Construct the eTLM. + // -------------------------------------------------------------------------- + p_etlm->frame_type = p_tlm->frame_type; + p_etlm->version = ES_TLM_VERSION_ETLM; + memcpy(p_etlm->encrypted_tlm, cipher, ES_ETLM_ECRYPTED_LENGTH); + memcpy((uint8_t *)&p_etlm->random_salt, salt, SALT_SIZE); + memcpy((uint8_t *)&p_etlm->msg_integrity_check, tag, TAG_SIZE); +} + + +ret_code_t es_security_init(es_security_msg_cb_t security_callback) +{ + ret_code_t err_code; + + if (security_callback == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Get lock code from 'es_app_config.h', or fetch it from flash if exists. + lock_code_init(m_aes_ecb_lk.key); + + m_security_callback = security_callback; + + memset(&m_ecdh, 0, sizeof(es_security_ecdh_t)); + + for (uint32_t i = 0; i < APP_MAX_EID_SLOTS; ++i) + { + m_security_slot[i].timing.time_counter = APP_CONFIG_TIMING_INIT_VALUE; + } + err_code = es_stopwatch_create(&m_seconds_passed_sw_id, APP_TIMER_TICKS(1000)); + APP_ERROR_CHECK(err_code); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_security.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_security.h new file mode 100644 index 0000000000000000000000000000000000000000..26c57a246ccaee03547ab6e8f016d83b2fcbc8e1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_security.h @@ -0,0 +1,238 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ES_SECURITY_H__ +#define ES_SECURITY_H__ + +#include "app_error.h" +#include "nrf_ble_escs.h" + +/** + * @file + * @defgroup eddystone_security Security + * @brief Types and functions for dealing with security of Eddystone beacons. + * @ingroup eddystone + * @{ + */ + +/**@brief Security events. + */ +typedef enum +{ + ES_SECURITY_MSG_UNLOCKED, //!< Beacon is unlocked. + ES_SECURITY_MSG_EID, //!< EID has been generated. + ES_SECURITY_MSG_IK, //!< IK has been generated. + ES_SECURITY_MSG_ECDH, //!< Public ECDH has been generated. + ES_SECURITY_MSG_STORE_TIME //!< EID slot time must be stored. +} es_security_msg_t; + +/* @brief Callback for security events. */ +typedef void (*es_security_msg_cb_t)(uint8_t slot_no, es_security_msg_t msg_type); + +/**@brief EID configuration. + * + * @details This structure is used to preserve or restore an EID slot. + * + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + es_frame_type_t frame_type; + uint8_t k_scaler; + uint32_t time_counter; + uint8_t ik[ESCS_AES_KEY_SIZE]; +} es_eid_config_t; + +/**@brief Eddystone beacon lock state. + */ +typedef nrf_ble_escs_lock_state_read_t es_security_lock_state_t; + +/**@brief Function for initializing the security module. + * + * @param[in] msg_cb Callback function. + * + * @return See @ref app_timer_start for possible return values. + */ +ret_code_t es_security_init(es_security_msg_cb_t msg_cb); + +/**@brief Function for updating the lock code and storing it to flash. + * + * @param[in] p_encrypted_key Pointer to the new lock code. + * + * @return See @ref es_flash_access_lock_key for possible return values. + */ +ret_code_t es_security_lock_code_update(uint8_t * p_encrypted_key); + +/**@brief Function for reading the challenge and encrypting it with AES_ECB. + * + * @details The result of the encryption is compared with the provided unlock token + * in @ref es_security_unlock_verify. + * + * @param[in] p_challenge Pointer to the challenge buffer. + * + * @return See @ref sd_ecb_block_encrypt for possible return values. + */ +void es_security_unlock_prepare(uint8_t * p_challenge); + +/**@brief Function for unlocking the beacon. + * + * @details This function compares the result from @ref es_security_unlock_prepare to the input + * unlock token and unlocks the beacon if matching. + * + * @param[in] p_unlock_token The unlock token written by the client. + */ +void es_security_unlock_verify(uint8_t * p_unlock_token); + +/**@brief Function for generating a random challenge for the unlock characteristic. + * + * @param[out] p_rand_chlg_buff Pointer to a buffer to which the random challenge is copied. + * + * @return See @ref sd_rand_application_vector_get for possible return values. + */ +ret_code_t es_security_random_challenge_generate(uint8_t * p_rand_chlg_buff); + +/**@brief Function for storing the public ECDH key from the client in the beacon registration process. + * + * @details This function starts a series of cryptographic activities, including the generation of temporary keys and EIDs. + * + * @param[in] slot_no The index of the slot whose public ECDH key is retrieved. + * @param[in] p_pub_ecdh Pointer to the public ECDH. + * @param[in] scaler_k K rotation scaler. + */ +void es_security_client_pub_ecdh_receive(uint8_t slot_no, uint8_t * p_pub_ecdh, uint8_t scaler_k); + + +/**@brief Function for storing the shared IK from the client in the beacon registration process. + * + * @details This function starts a series of cryptographic activities, including the generation of temporary keys and EIDs. + * + * @param[in] slot_no The index of the slot whose public ECDH key is retrieved. + * @param[in] p_encrypted_ik Pointer to the received IK. + * @param[in] scaler_k K rotation scaler. + */ +void es_security_shared_ik_receive(uint8_t slot_no, uint8_t * p_encrypted_ik, uint8_t scaler_k); + +/**@brief Function for copying the 32-byte ECDH key into the provided buffer. + * + * @param[in] slot_no The index of the slot whose public ECDH key is retrieved. + * @param[out] p_edch_buffer Pointer to the buffer. + */ +void es_security_pub_ecdh_get(uint8_t slot_no, uint8_t * p_edch_buffer); + +/**@brief Function for returning the beacon clock value (in little endian). + * + * @param[in] slot_no The index of the slot. + * + * @return 32-bit clock value. + */ +uint32_t es_security_clock_get(uint8_t slot_no); + +/**@brief Function for updating the beacon time counter. + * + * @details This function checks how much time has passed since the last + * invocation and, if required, updates the EID, the temporary key, or both. + * The function generates an @ref ES_SECURITY_MSG_STORE_TIME event + * for each active security slot every 24 hours. + */ +void es_security_update_time(void); + +/**@brief Function for returning the rotation exponent scaler value. + * + * @param[in] slot_no The index of the slot. + * + * @return K rotation scaler. + */ +uint8_t es_security_scaler_get(uint8_t slot_no); + +/**@brief Function for copying the 8-byte EID into the provided buffer. + * + * @param[in] slot_no The index of the slot whose EID is retrieved. + * @param[out] p_eid_buffer Pointer to the buffer. + */ +void es_security_eid_get(uint8_t slot_no, uint8_t * p_eid_buffer); + +/**@brief Function for restoring an EID slot. + * + * @param[in] slot_no The index of the slot to restore. + * @param[in] k_scaler K rotation scaler. + * @param[in] time_counter EID slot time counter value (in seconds). + * @param[in] p_ik Pointer to the identity key of the specified slot. + */ +void es_security_eid_slots_restore(uint8_t slot_no, + uint8_t k_scaler, + uint32_t time_counter, + const uint8_t * p_ik); + +/**@brief Function for destroying stored EID states. + * + * @details This function should be called when the slot is either overwritten as another slot or + * cleared by writing an empty byte or a single 0. + * + * @param[in] slot_no The index of the slot to destroy. + */ +void es_security_eid_slot_destroy(uint8_t slot_no); + +/**@brief Function for copying the 16-byte EID ID key into the provided buffer. + * + * @param[in] slot_no The index of the EID slot whose IK is retrieved. + * @param[out] p_key_buffer Buffer for the key. + */ +void es_security_plain_eid_id_key_get(uint8_t slot_no, uint8_t * p_key_buffer); + +/**@brief Function for copying the 16-byte LK encrypted EID ID key into the provided buffer. + * + * @param[in] slot_no The index of the EID slot whose encrypted IK is retrieved. + * @param[out] p_key_buffer Buffer for the key. + */ +void es_security_encrypted_eid_id_key_get(uint8_t slot_no, uint8_t * p_key_buffer); + + +/**@brief Function for converting a TLM frame into an eTLM frame using the EIK of the specified slot. + * + * @param[in] ik_slot_no The index of the EID slot whose IK is paired with the eTLM. + * @param[in] p_tlm Pointer to the TLM frame buffer. + * @param[out] p_etlm Pointer to the eTLM frame buffer. + */ +void es_security_tlm_to_etlm(uint8_t ik_slot_no, es_tlm_frame_t * p_tlm, es_etlm_frame_t * p_etlm); + +/** + * @} + */ + +#endif // ES_SECURITY_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_slot.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_slot.c new file mode 100644 index 0000000000000000000000000000000000000000..5622461b975c02f6a97ef18c0eb1c1e3359e18ad --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_slot.c @@ -0,0 +1,440 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "es_slot.h" +#include "es_flash.h" +#include "es_security.h" +#include "es_slot_reg.h" +#include "es_tlm.h" +#include "fds.h" + +static es_slot_reg_t m_reg; //!< Slot registry. +static bool m_eid_loaded_from_flash; //!< Set to true if EID slot has been loaded from flash. + +#define RANGING_DATA_INDEX (1) //!< Index of ranging data within frames that contain ranging data. +#define RANGING_DATA_LENGTH (1) //!< Length of ranging data. + +/**@brief Enforce legal slot number. + * + * @param[in] p_slot Pointer to the slot number variable to check. + */ +static void slot_boundary_check(uint8_t * p_slot) +{ + if (*p_slot > (APP_MAX_ADV_SLOTS - 1)) + { + *p_slot = (APP_MAX_ADV_SLOTS - 1); + } +} + + +/**@brief Function loading slot data from flash. + * + * @param[in] slot_no Slot number to be used. + */ +static void load_slot_from_flash(uint8_t slot_no) +{ + ret_code_t err_code; + + err_code = es_flash_access_slot_configs(slot_no, &m_reg.slots[slot_no], ES_FLASH_ACCESS_READ); + if (err_code != FDS_ERR_NOT_FOUND) + { + APP_ERROR_CHECK(err_code); + + if (m_reg.slots[slot_no].adv_frame.type == ES_FRAME_TYPE_EID) + { + m_eid_loaded_from_flash = true; + + es_security_eid_slots_restore(slot_no, + m_reg.slots[slot_no].k_scaler, + m_reg.slots[slot_no].seconds, + (const uint8_t *)m_reg.slots[slot_no].ik); + } + + else + { + // If a non-EID slot has been loaded, update the state of m_reg immediately. + es_slot_reg_update_slot_list_info_on_add(&m_reg, slot_no, m_reg.slots[slot_no].adv_frame.type, true); + } + } +} + + +/**@brief Function for setting the ranging data field to be broadcast in the frame. + * + * @param[in] slot_no The slot index. + * @param[in] tx_power The radio tx power to be calibrated to ranging data. + */ +static void set_ranging_data_for_slot(uint8_t slot_no, nrf_ble_escs_radio_tx_pwr_t tx_power) +{ + int8_t ranging_data_array[ESCS_NUM_OF_SUPPORTED_TX_POWER] = APP_CONFIG_CALIBRATED_RANGING_DATA; + nrf_ble_escs_radio_tx_pwr_t supported_tx[ESCS_NUM_OF_SUPPORTED_TX_POWER] = + ESCS_SUPPORTED_TX_POWER; + + int8_t ranging_data = 0; + + if (m_reg.slots[slot_no].adv_custom_tx_power) + { + ranging_data = m_reg.slots[slot_no].custom_tx_power; + } + + else + { + for (uint32_t i = 0; i < ESCS_NUM_OF_SUPPORTED_TX_POWER; ++i) + { + if (supported_tx[i] >= tx_power) + { + ranging_data = ranging_data_array[i]; + break; + } + } + } + es_adv_frame_t * frame = &m_reg.slots[slot_no].adv_frame; + switch (frame->type) + { + case ES_FRAME_TYPE_UID: + { + es_uid_frame_t * uid = &frame->frame.uid; + uid->ranging_data = ranging_data; + break; + } + + case ES_FRAME_TYPE_URL: + { + es_url_frame_t * url = &frame->frame.url; + url->ranging_data = ranging_data; + break; + } + + case ES_FRAME_TYPE_EID: + { + es_eid_frame_t * eid = &frame->frame.eid; + eid->ranging_data = ranging_data; + break; + } + + case ES_FRAME_TYPE_TLM: + APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM); + break; + } +} + + +/**@brief Function configuring a non-EID slot. + * + * @param[in] slot_no Slot number to be used. + * @param[in] length Length of write operation. + * @param[in] p_frame_data Pointer to written data. + */ +static void configure_slot(uint8_t slot_no, uint8_t length, uint8_t * p_frame_data) +{ + // If a TLM slot is being configured and there already exists a TLM. + if ((es_frame_type_t)p_frame_data[0] == ES_FRAME_TYPE_TLM && m_reg.tlm_configured) + { + return; // Silently ignore any attempts to create more than one TLM slot as there is no point. + } + + es_slot_reg_update_slot_list_info_on_add(&m_reg, slot_no, (es_frame_type_t)p_frame_data[0], false); + + // For convenience, frame_type is stored in two places, set both. + m_reg.slots[slot_no].adv_frame.type = (es_frame_type_t)p_frame_data[0]; + memcpy(&m_reg.slots[slot_no].adv_frame.frame, &m_reg.slots[slot_no].adv_frame.type, 1); + + uint8_t * p_data_after_ranging_data = ((uint8_t *)(&m_reg.slots[slot_no].adv_frame.frame) + + RANGING_DATA_INDEX + RANGING_DATA_LENGTH); + + switch (m_reg.slots[slot_no].adv_frame.type) + { + case ES_FRAME_TYPE_UID: + // Fall through. + case ES_FRAME_TYPE_URL: + memcpy(p_data_after_ranging_data, &p_frame_data[1], length); + set_ranging_data_for_slot(slot_no, APP_CFG_DEFAULT_RADIO_TX_POWER); + m_reg.slots[slot_no].adv_frame.length = length + 1; // + 1 for ranging data + break; + + case ES_FRAME_TYPE_TLM: + es_tlm_tlm_get(&m_reg.slots[slot_no].adv_frame.frame.tlm); + m_reg.slots[slot_no].adv_frame.length = ES_TLM_LENGTH; + break; + + default: + break; + } +} + + +/**@brief Function configuring an EID slot. + * + * @param[in] slot_no Slot number to be used. + * @param[in] length Length of write operation. + * @param[in] p_frame_data Pointer to written data. + */ +static void configure_eid_slot(uint8_t slot_no, uint8_t length, uint8_t * p_frame_data) +{ + bool clear_eid_slot = false; + + // Do not update slot count, as this will be done when in the callback invoked when the EID data + // is ready. + // As it takes a while to do the calculation, temporarily remove the slot being overwritten. + // The slot will be re-added in the callback invoked when the EID data is ready. + clear_eid_slot = es_slot_reg_clear_slot(&m_reg, slot_no); + + if (clear_eid_slot) + { + es_security_eid_slot_destroy(slot_no); + } + + if (p_frame_data[0] != ES_FRAME_TYPE_EID) + { + APP_ERROR_CHECK(NRF_ERROR_INVALID_STATE); + } + + if (length == ESCS_EID_WRITE_ECDH_LENGTH) + { + es_security_client_pub_ecdh_receive(slot_no, + &p_frame_data[ESCS_EID_WRITE_PUB_KEY_INDEX], + p_frame_data[ESCS_EID_WRITE_ECDH_LENGTH -1]); + } + + else if (length == ESCS_EID_WRITE_IDK_LENGTH) + { + es_security_shared_ik_receive(slot_no, + &p_frame_data[ESCS_EID_WRITE_ENC_ID_KEY_INDEX], + p_frame_data[ESCS_EID_WRITE_IDK_LENGTH - 1]); + } + + else + { + // Invalid length being written. + APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM); + } +} + + +ret_code_t es_slot_write_to_flash(uint8_t slot_no) +{ + if (m_reg.slots[slot_no].configured) + { + // If its an EID, we need to store some metadata in order to re-initialize the EID. + if (m_reg.slots[slot_no].adv_frame.type == ES_FRAME_TYPE_EID) + { + m_reg.slots[slot_no].seconds = es_security_clock_get(slot_no); + m_reg.slots[slot_no].k_scaler = es_security_scaler_get(slot_no); + es_security_plain_eid_id_key_get(slot_no, m_reg.slots[slot_no].ik); + } + return es_flash_access_slot_configs(slot_no, &m_reg.slots[slot_no], ES_FLASH_ACCESS_WRITE); + } + + else + { + return es_flash_access_slot_configs(slot_no, NULL, ES_FLASH_ACCESS_CLEAR); + } +} + + +void es_slot_radio_tx_pwr_set(uint8_t slot_no, nrf_ble_escs_radio_tx_pwr_t radio_tx_pwr) +{ + slot_boundary_check(&slot_no); + + m_reg.slots[slot_no].radio_tx_pwr = radio_tx_pwr; + + if (!m_reg.slots[slot_no].adv_custom_tx_power) // Only update TX power in ADV if custom TX power is not set + { + set_ranging_data_for_slot(slot_no, radio_tx_pwr); + } +} + + +void es_slot_set_adv_custom_tx_power(uint8_t slot_no, nrf_ble_escs_adv_tx_pwr_t tx_pwr) +{ + slot_boundary_check(&slot_no); + + m_reg.slots[slot_no].adv_custom_tx_power = true; + m_reg.slots[slot_no].custom_tx_power = tx_pwr; + set_ranging_data_for_slot(slot_no, tx_pwr); +} + + +void es_slot_on_write(uint8_t slot_no, uint8_t length, uint8_t * p_frame_data) +{ + slot_boundary_check(&slot_no); + + if (p_frame_data == NULL) + { + APP_ERROR_CHECK(NRF_ERROR_NULL); + } + + // Cleared + if (length == 0 || (length == 1 && p_frame_data[0] == 0)) + { + (void)es_slot_reg_clear_slot(&m_reg, slot_no); + } + // EID slot being configured + else if (p_frame_data[0] == ES_FRAME_TYPE_EID && + (length == ESCS_EID_WRITE_ECDH_LENGTH || length == ESCS_EID_WRITE_IDK_LENGTH)) + { + if (m_reg.slots[slot_no].configured) + (void)es_slot_reg_clear_slot(&m_reg, slot_no); + configure_eid_slot(slot_no, length, p_frame_data); + } + // Non-EID slot configured. + else + { + if (m_reg.slots[slot_no].configured) + (void)es_slot_reg_clear_slot(&m_reg, slot_no); + configure_slot(slot_no, length, p_frame_data); + } +} + + +void es_slot_encrypted_eid_id_key_set(uint8_t slot_no, nrf_ble_escs_eid_id_key_t * p_eid_id_key) +{ + slot_boundary_check(&slot_no); + if (p_eid_id_key != NULL) + { + memcpy(&(m_reg.slots[slot_no].encrypted_eid_id_key), p_eid_id_key, + sizeof(nrf_ble_escs_eid_id_key_t)); + } +} + + +void es_slot_eid_ready(uint8_t slot_no) +{ + m_reg.slots[slot_no].adv_frame.type = ES_FRAME_TYPE_EID; + m_reg.slots[slot_no].adv_frame.length = ES_EID_LENGTH; + es_security_eid_get(slot_no, (uint8_t *)m_reg.slots[slot_no].adv_frame.frame.eid.eid); + m_reg.slots[slot_no].adv_frame.frame.eid.frame_type = ES_FRAME_TYPE_EID; + set_ranging_data_for_slot(slot_no, m_reg.slots[slot_no].radio_tx_pwr); + + if (m_eid_loaded_from_flash) + { + es_slot_reg_update_slot_list_info_on_add(&m_reg, slot_no, ES_FRAME_TYPE_EID, true); + m_eid_loaded_from_flash = false; + } + + else + { + es_slot_reg_update_slot_list_info_on_add(&m_reg, slot_no, ES_FRAME_TYPE_EID, false); + } +} + + +static bool slot_is_eid(uint8_t eid_slot_no) +{ + for (uint32_t i = 0; i < m_reg.num_configured_eid_slots; ++i) + { + if (m_reg.eid_slots_configured[i] == eid_slot_no) + { + return true; + } + } + + return false; +} + + +void es_slot_tlm_update(void) +{ + if (m_reg.tlm_configured) + { + es_tlm_tlm_get(&m_reg.slots[m_reg.tlm_slot].adv_frame.frame.tlm); + } +} + + +void es_slot_etlm_update(uint8_t eid_slot_no) +{ + es_tlm_frame_t tlm; + es_etlm_frame_t etlm; + + // Ignore the request if eTLM is not required or slot no does not correspond to an EID slot. + if (!es_slot_reg_etlm_required(&m_reg) || !slot_is_eid(eid_slot_no)) + { + return; + } + + es_tlm_tlm_get(&tlm); + + es_security_tlm_to_etlm(eid_slot_no, &tlm, &etlm); + + memcpy(&m_reg.slots[m_reg.tlm_slot].adv_frame.frame.etlm, &etlm, sizeof(es_etlm_frame_t)); + m_reg.slots[m_reg.tlm_slot].adv_frame.length = sizeof(es_etlm_frame_t); +} + + +const es_slot_reg_t * es_slot_get_registry(void) +{ + return (const es_slot_reg_t *)&m_reg; +} + + +void es_slots_init(const es_slot_t * p_default_slot) +{ + ret_code_t err_code; + es_flash_flags_t flash_flags = {{0}}; + + es_slot_reg_init(&m_reg); + + m_eid_loaded_from_flash = false; + + // Read the flash flags to see if there are any previously stored slot configs + err_code = es_flash_access_flags(&flash_flags, ES_FLASH_ACCESS_READ); + + if (err_code == FDS_ERR_NOT_FOUND) + { + // Factory reset or initial boot, load default data + memcpy(&m_reg.slots[0], p_default_slot, sizeof(*p_default_slot)); + es_slot_reg_update_slot_list_info_on_add(&m_reg, 0, p_default_slot->adv_frame.type, true); + } + + else + { + APP_ERROR_CHECK(err_code); + + for (uint32_t i = 0; i < APP_MAX_ADV_SLOTS; ++i) + { + if (!flash_flags.slot_is_empty[i]) + { + load_slot_from_flash(i); + } + } + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_slot.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_slot.h new file mode 100644 index 0000000000000000000000000000000000000000..c1e9186e93b6b9daf9deca1b8c7abc23a02fc0a5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_slot.h @@ -0,0 +1,202 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ES_SLOT_H__ +#define ES_SLOT_H__ + +#include +#include "es_app_config.h" +#include "nrf_ble_escs.h" + +/** + * @file + * @defgroup eddystone_slot Slots + * @brief Types and functions for handling Eddystone slots. + * @ingroup eddystone + * @{ + */ + +/**@brief Advertisable frame types that can be passed in to the advertising + * data during non-connectable slot advertising. */ + +typedef struct +{ + union + { + es_uid_frame_t uid; //!< UID frame. + es_url_frame_t url; //!< URL frame. + es_tlm_frame_t tlm; //!< TLM frame. + es_eid_frame_t eid; //!< EID frame. + es_etlm_frame_t etlm; //!< eTLM frame. + } frame; + es_frame_type_t type; //!< Type defined twice for convenience (because the other one is inside a union). + uint8_t length; +}es_adv_frame_t; + +/**@brief Slot. */ +typedef struct +{ + uint8_t slot_no; //!< Identifier for the slot, indexed at 0. + nrf_ble_escs_radio_tx_pwr_t radio_tx_pwr; //!< Radio TX power (in dB). + nrf_ble_escs_eid_id_key_t encrypted_eid_id_key; //!< EID key for the slot. + es_adv_frame_t adv_frame; //!< Frame structure to be passed in for advertising data. + bool adv_custom_tx_power; //!< Flag that specifies if the client has written to the 'Advertised TX Power' field of this slot. + nrf_ble_escs_radio_tx_pwr_t custom_tx_power; //!< Custom TX power to advertise (only if @ref adv_custom_tx_power is true). + bool configured; //!< Is this slot configured and active. + uint8_t k_scaler; + uint32_t seconds; + uint8_t ik[ESCS_AES_KEY_SIZE]; +} es_slot_t; + +/**@brief Slot registry. */ +typedef struct +{ + es_slot_t slots[APP_MAX_ADV_SLOTS]; + uint8_t num_configured_slots; + uint8_t num_configured_eid_slots; + uint8_t slots_configured[APP_MAX_ADV_SLOTS]; + uint8_t eid_slots_configured[APP_MAX_EID_SLOTS]; + uint8_t tlm_slot; + bool tlm_configured; + uint8_t scaler_k; + uint8_t enc_key[ESCS_AES_KEY_SIZE]; +} es_slot_reg_t; + +/**@brief Function for initializing the Eddystone slots with default values. + * + * @details This function synchronizes all slots with the initial values. + * + * @param[in] p_default_slot Pointer to the default parameters for a slot. + */ +void es_slots_init(const es_slot_t * p_default_slot); + +/**@brief Function for setting the advertising interval of the specified slot. + * + * For compatibility with the Eddystone specifications, @p p_adv_interval must point to + * a 16-bit big endian value (coming from the characteristic write request), + * which is then converted to a little endian value inside the function before + * it is written into the variable in the slot. + * + * @parameternoteslot + * @parameternoteadv + * + * @param[in] slot_no The index of the slot. + * @param[in,out] p_adv_interval Pointer to the advertisement interval (in ms) to set. + * @param[in] global Flag that should be set if the beacon does not support variable advertising intervals. + */ +void es_slot_adv_interval_set(uint8_t slot_no, + nrf_ble_escs_adv_interval_t * p_adv_interval, + bool global); + +/**@brief Function for setting the TX power of the specified slot. + * + * @parameternoteslot + * @parameternotetxpower + * + * @param[in] slot_no The index of the slot. + * @param[in,out] radio_tx_pwr TX power value to set. + */ +void es_slot_radio_tx_pwr_set(uint8_t slot_no, nrf_ble_escs_radio_tx_pwr_t radio_tx_pwr); + +/**@brief Function for setting the R/W ADV of the specified slot. + * + * @parameternoteslot + * + * @param[in] slot_no The index of the slot. + * @param[in,out] length The length of the data written or read. + * @param[in,out] p_frame_data Pointer to the data. + * + */ +void es_slot_on_write(uint8_t slot_no, uint8_t length, uint8_t * p_frame_data); + +/**@brief Function for writing the slot's configuration to flash. + * + * @param[in] slot_no The index of the slot. + */ +ret_code_t es_slot_write_to_flash(uint8_t slot_no); + +/**@brief Function for setting the slot's encrypted EID Identity Key to be displayed in the EID Identity Key characteristic. + * + * @parameternoteslot + * + * @param[in] slot_no The index of the slot. + * @param[in,out] p_eid_id_key Pointer to a @ref nrf_ble_escs_eid_id_key_t structure from where the key will be written. + */ +void es_slot_encrypted_eid_id_key_set(uint8_t slot_no, nrf_ble_escs_eid_id_key_t * p_eid_id_key); + +/**@brief Function for marking an EID slot as ready for populating. + * + * @details Call this function when an EID has been generated and the advertisement frame can be populated with the EID. + * + * @param[in] slot_no The index of the slot. + */ +void es_slot_eid_ready(uint8_t slot_no); + +/**@brief Function for updating the TLM slot with updated data. */ +void es_slot_tlm_update(void); + +/**@brief Function for updating the TLM slot with eTLM data. + * + * @details This function uses the EID identity key from the given EID slot number to update the TLM slot. + * + * @param[in] eid_slot_no EID slot to get EID identity key from. + */ +void es_slot_etlm_update(uint8_t eid_slot_no); + +/**@brief Function for getting a pointer to the slot registry. + * + * @return A pointer to the slot registry. + */ +const es_slot_reg_t * es_slot_get_registry(void); + +/**@brief Function for setting a custom advertisement TX power for a given slot. + * + * @parameternoteslot + * @parameternotetxpower + * + * @param[in] slot_no The index of the slot. + * @param[in] tx_pwr Advertised TX power to be set. + */ +void es_slot_set_adv_custom_tx_power(uint8_t slot_no, nrf_ble_escs_adv_tx_pwr_t tx_pwr); + +/** + * @} + */ + +#endif // ES_SLOT_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_slot_reg.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_slot_reg.c new file mode 100644 index 0000000000000000000000000000000000000000..23fab923123900890e0651778399742e5d8f8cbc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_slot_reg.c @@ -0,0 +1,181 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "es_slot_reg.h" + +#define ES_SLOT_NOT_CONFIGURED 0xab /** Value set in configured lists to indicate not configured slot. */ + +/**@brief Function updating 'tlm_configured' property of slot registry when slot is being cleared. + * + * @param[in] p_reg Pointer to slot registry. + * @param[in] slot_no Slot number to be used. + */ +static void update_tlm_configured_on_clearing(es_slot_reg_t * p_reg, uint8_t slot_no) +{ + if (p_reg->tlm_configured && slot_no == p_reg->tlm_slot) + { + p_reg->tlm_configured = false; + } +} + + +/**@brief Function updating 'num_configured_slots' and 'slots_configured' properties of slot registry when slot is being cleared. + * + * @param[in] p_configured Pointer to list of configured slots. + * @param[in] p_num_configured_slots Pointer to number of configured slots. + * @param[in] slot_no Slot number to clear. + */ +static void configured_slots_on_clear_update(uint8_t * p_configured, uint8_t * p_num_configured_slots, uint8_t slot_no) +{ + uint8_t index_of_last_configured_slot = *p_num_configured_slots - 1; + + for (uint32_t i = 0; i < APP_MAX_ADV_SLOTS; ++i) + { + if (p_configured[i] == slot_no) + { + // Copy all values 'to the right' of the cleared slot one step to the left. + if (i < index_of_last_configured_slot) + { + for (uint32_t j = i; j < index_of_last_configured_slot; ++j) + { + p_configured[j] = p_configured[j + 1]; + } + // Write ES_SLOT_NOT_CONFIGURED to all rightmost not configured indexes. + memset(&p_configured[index_of_last_configured_slot], + ES_SLOT_NOT_CONFIGURED, + APP_MAX_ADV_SLOTS - index_of_last_configured_slot); + } + + else + { + // There are no values 'to the right', simply overwrite with ES_SLOT_NOT_CONFIGURED + p_configured[i] = ES_SLOT_NOT_CONFIGURED; + } + + *p_num_configured_slots -= 1; + + return; + } + } +} + + +bool es_slot_reg_etlm_required(const es_slot_reg_t * p_reg) +{ + return (p_reg->num_configured_eid_slots > 0 && p_reg->tlm_configured); +} + + +bool es_slot_reg_clear_slot(es_slot_reg_t * p_reg, uint8_t slot_no) +{ + bool eid_has_been_cleared = false; + + if (p_reg->slots[slot_no].configured) + { + update_tlm_configured_on_clearing(p_reg, slot_no); + + configured_slots_on_clear_update(p_reg->slots_configured, + &p_reg->num_configured_slots, + slot_no); + + if (p_reg->slots[slot_no].adv_frame.type == ES_FRAME_TYPE_EID) + { + configured_slots_on_clear_update(p_reg->eid_slots_configured, + &p_reg->num_configured_eid_slots, + slot_no); + + eid_has_been_cleared = true; + } + + p_reg->slots[slot_no].configured = false; + } + + memset(&p_reg->slots[slot_no], 0, sizeof(p_reg->slots[slot_no])); + + return eid_has_been_cleared; +} + + +void es_slot_reg_update_slot_list_info_on_add(es_slot_reg_t * p_reg, + uint8_t slot_no, + es_frame_type_t frame_type, + bool init) +{ + if (frame_type == ES_FRAME_TYPE_TLM) + { + p_reg->tlm_configured = true; + p_reg->tlm_slot = slot_no; + } + + if (!p_reg->slots[slot_no].configured || init) + { + p_reg->slots[slot_no].configured = true; + + // Note, we use 'num_configured_slots' before incrementing it, so it is pointing to the correct index. + p_reg->slots_configured[p_reg->num_configured_slots] = slot_no; + + p_reg->num_configured_slots++; + + if (frame_type == ES_FRAME_TYPE_EID) + { + p_reg->eid_slots_configured[p_reg->num_configured_eid_slots] = slot_no; + + p_reg->num_configured_eid_slots++; + } + } + + // If an already configured slot has changed from anything TO an EID slot. + else if (frame_type == ES_FRAME_TYPE_EID && + p_reg->slots[slot_no].adv_frame.type != ES_FRAME_TYPE_EID) + { + p_reg->eid_slots_configured[p_reg->num_configured_eid_slots] = slot_no; + + p_reg->num_configured_eid_slots++; + } +} + + +void es_slot_reg_init(es_slot_reg_t * p_reg) +{ + p_reg->tlm_configured = false; + memset(p_reg->slots_configured, ES_SLOT_NOT_CONFIGURED, APP_MAX_ADV_SLOTS); + memset(p_reg->eid_slots_configured, ES_SLOT_NOT_CONFIGURED, APP_MAX_EID_SLOTS); + p_reg->num_configured_eid_slots = 0; + p_reg->num_configured_slots = 0; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_slot_reg.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_slot_reg.h new file mode 100644 index 0000000000000000000000000000000000000000..690bb698f49634b2add2e9f6b356e71d4f6ffdef --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_slot_reg.h @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ES_SLOT_REG_H__ +#define ES_SLOT_REG_H__ + +#include +#include "es_slot.h" + +/** + * @file + * @addtogroup eddystone_slot + * @{ + */ + +/** @brief Function for checking if an eTLM frame is required. + * + * @param[in] p_reg Pointer to the slot registry. + * + * @retval true If an eTLM frame is required. + * @retval false Otherwise. + */ +bool es_slot_reg_etlm_required(const es_slot_reg_t * p_reg); + +/** @brief Function for clearing a slot. + * + * @param[in] p_reg Pointer to the slot registry. + * @param[in] slot_no The slot number to clear. + * + * @retval true If an EID slot was cleared. + */ +bool es_slot_reg_clear_slot(es_slot_reg_t * p_reg, uint8_t slot_no); + +/** @brief Function for updating the state of the slot registry after adding a slot. + * + * @param[in] p_reg Pointer to the slot registry. + * @param[in] slot_no The slot number that was added. + * @param[in] frame_type The frame type that was added. + * @param[in] init Information if the data is loaded during initialization. Set this + * parameter to false if the call is a result of a write to the Eddystone Configuration Service. + */ +void es_slot_reg_update_slot_list_info_on_add(es_slot_reg_t * p_reg, uint8_t slot_no, es_frame_type_t frame_type, bool init); + +/** @brief Function for initializing the slot registry. + * + * @param[in] p_reg Pointer to the slot registry to initialize. + */ +void es_slot_reg_init(es_slot_reg_t * p_reg); + +/** + * @} + */ + +#endif // ES_SLOT_REG_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_stopwatch.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_stopwatch.c new file mode 100644 index 0000000000000000000000000000000000000000..d21027c9741211737e765984b481cf9fd479ef95 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_stopwatch.c @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include +#include "es_stopwatch.h" +#include "sdk_macros.h" +#include "app_timer.h" +#include "es_app_config.h" + +static uint32_t m_ticks_last_returned[ES_STOPWATCH_MAX_USERS]; +static uint32_t m_ids_ticks_wrap[ES_STOPWATCH_MAX_USERS]; +static uint8_t m_nof_ids = 0; +static bool m_initialized = false; + +uint32_t es_stopwatch_check(es_stopwatch_id_t id) +{ + uint32_t ticks_current = app_timer_cnt_get(); + uint32_t ticks_diff; + + if (m_ids_ticks_wrap[id] == 0) + { + APP_ERROR_CHECK(NRF_ERROR_INVALID_STATE); + } + + ticks_diff = app_timer_cnt_diff_compute(ticks_current, m_ticks_last_returned[id]); + + if (ticks_diff >= m_ids_ticks_wrap[id]) + { + m_ticks_last_returned[id] = (ticks_current / m_ids_ticks_wrap[id]) * m_ids_ticks_wrap[id]; + + return ticks_diff / m_ids_ticks_wrap[id]; + } + + return 0; +} + +ret_code_t es_stopwatch_create(es_stopwatch_id_t * p_sw_id, uint32_t ticks_wrap) +{ + VERIFY_PARAM_NOT_NULL(p_sw_id); + + if (m_nof_ids == ES_STOPWATCH_MAX_USERS) + { + return NRF_ERROR_INVALID_STATE; + } + + if (!m_initialized) + { + return NRF_ERROR_MODULE_NOT_INITIALZED; + } + + *p_sw_id = m_nof_ids; + + m_ids_ticks_wrap[m_nof_ids] = ticks_wrap; + + m_nof_ids++; + + return NRF_SUCCESS; +} + + +void es_stopwatch_init(void) +{ + m_nof_ids = 0; + memset(m_ticks_last_returned, 0, sizeof(m_ticks_last_returned)); + memset(m_ids_ticks_wrap, 0, sizeof(m_ids_ticks_wrap)); + m_initialized = true; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_stopwatch.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_stopwatch.h new file mode 100644 index 0000000000000000000000000000000000000000..ade07c83137332da1bbe680e5d6f0e15db9807b5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_stopwatch.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ES_SECURITY_TIMING_H__ +#define ES_SECURITY_TIMING_H__ + +#include +#include "app_error.h" + +/** + * @file + * @addtogroup eddystone_security + * @{ + */ + +typedef uint8_t es_stopwatch_id_t; + +/**@brief Function for getting the number of seconds passed since the last invocation. + * @details If the function returns zero, the 'last time called' state is not updated. If a non-zero value + * is returned, the 'last time called' state will point to the last whole second. + * @return Number of seconds passed since the last invocation. + */ +uint32_t es_stopwatch_check(es_stopwatch_id_t id); + +ret_code_t es_stopwatch_create(es_stopwatch_id_t * p_sw_id, uint32_t ticks_wrap); + +/**@brief Function for initializing the security timing module. + */ +void es_stopwatch_init(void); + +/** + * @} + */ + +#endif // ES_SECURITY_TIMING_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_tlm.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_tlm.c new file mode 100644 index 0000000000000000000000000000000000000000..ad7df3703ff0f480f01b72bfbc3a2c74e4868a86 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_tlm.c @@ -0,0 +1,140 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "app_timer.h" +#include "es_tlm.h" +#include "es_app_config.h" +#include "es_battery_voltage.h" +#include "es_stopwatch.h" +#include "nrf_soc.h" + +#define TICKS_100_MS APP_TIMER_TICKS(100) //!< Tick count for 100ms. + +static es_tlm_frame_t m_tlm; +static uint32_t m_le_adv_cnt; +static es_stopwatch_id_t m_time_sec_sw_id; +static es_stopwatch_id_t m_tlm_refresh_sw_id; + +/**@brief Function for updating the ADV_SEC field of TLM*/ +static void update_time(void) +{ + static uint32_t time_total_100_ms = 0; + uint32_t be_time_100_ms; // Big endian version of 0.1 second counter. + + time_total_100_ms += es_stopwatch_check(m_time_sec_sw_id); + + be_time_100_ms = BYTES_REVERSE_32BIT(time_total_100_ms); + + memcpy(m_tlm.sec_cnt, &be_time_100_ms, ES_TLM_SEC_CNT_LENGTH); +} + + +/**@brief Function for updating the TEMP field of TLM*/ +static void update_temp(void) +{ + int32_t temp; // variable to hold temp reading + (void)sd_temp_get(&temp); // get new temperature + int16_t temp_new = (int16_t) temp; // convert from int32_t to int16_t + m_tlm.temp[0] = (uint8_t)((temp_new >> 2) & 0xFFUL); // Right-shift by two to remove decimal part + m_tlm.temp[1] = (uint8_t)((temp_new << 6) & 0xFFUL); // Left-shift 6 to get fractional part with 0.25 degrees C resolution +} + + +/**@brief Function for updating the VBATT field of TLM*/ +static void update_vbatt(void) +{ + uint16_t vbatt; // Variable to hold voltage reading + es_battery_voltage_get(&vbatt); // Get new battery voltage + m_tlm.vbatt[0] = (uint8_t)(vbatt >> 8); + m_tlm.vbatt[1] = (uint8_t)vbatt; +} + + +static void update_adv_cnt(void) +{ + uint32_t be_adv_cnt = BYTES_REVERSE_32BIT(m_le_adv_cnt); + memcpy(m_tlm.adv_cnt, (uint8_t *)(&be_adv_cnt), ES_TLM_ADV_CNT_LENGTH); +} + + +void es_tlm_tlm_get(es_tlm_frame_t * p_tlm_frame) +{ + // Note that frame type and TLM version fields are set in initialization. + update_time(); + update_adv_cnt(); + + if (es_stopwatch_check(m_tlm_refresh_sw_id) > 0) + { + update_temp(); + update_vbatt(); + } + + memcpy(p_tlm_frame, &m_tlm, sizeof(es_tlm_frame_t)); +} + + +void es_tlm_adv_cnt_inc(void) +{ + m_le_adv_cnt++; +} + + +void es_tlm_init(void) +{ + ret_code_t err_code; + + memset(&m_tlm, 0, sizeof(m_tlm)); + m_tlm.frame_type = ES_FRAME_TYPE_TLM; + m_tlm.version = ES_TLM_VERSION_TLM; + m_le_adv_cnt = 0; + + update_time(); + update_vbatt(); + update_temp(); + + err_code = es_stopwatch_create(&m_time_sec_sw_id, APP_TIMER_TICKS(100)); + APP_ERROR_CHECK(err_code); + + err_code = es_stopwatch_create( + &m_tlm_refresh_sw_id, + APP_TIMER_TICKS(APP_CONFIG_TLM_TEMP_VBATT_UPDATE_INTERVAL_SECONDS * 1000)); + APP_ERROR_CHECK(err_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_tlm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_tlm.h new file mode 100644 index 0000000000000000000000000000000000000000..dbc995273b635426118a3bf59a4c4f07c426357d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_tlm.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ES_TLM_H__ +#define ES_TLM_H__ + +#include "es.h" + +/** + * @file + * @defgroup eddystone_tlm TLM + * @brief Functions for the Eddystone telemetry (TLM) manager. + * @ingroup eddystone_adv + * @{ + */ + +/**@brief Function for initializing the TLM manager. + * + * @return See @ref app_timer_start for possible return values. + */ +void es_tlm_init(void); + +/**@brief Function for getting the current TLM. + * + * @param[in] p_tlm_frame Pointer to the TLM frame to which the frame is retrieved. + */ +void es_tlm_tlm_get(es_tlm_frame_t * p_tlm_frame); + +/**@brief Function for incrementing the ADV_CNT field of the TLM frame. + * + * @details This function should be called every time a frame is advertised. + * + */ +void es_tlm_adv_cnt_inc(void); + +/** + * @} + */ + +#endif // ES_TLM_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_util.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_util.h new file mode 100644 index 0000000000000000000000000000000000000000..3db1302c5164163cea1dab99af1a65972f1922f5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/es_util.h @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +// See https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms + +#ifndef ES_UTIL_H__ +#define ES_UTIL_H__ + +#define BOOL(x) COMPL(NOT(x)) +#define IF(c) IIF(BOOL(c)) + +#define CHECK_N(x, n, ...) n +#define CHECK(...) CHECK_N(__VA_ARGS__, 0,) +#define PROBE(x) x, 1, + +#define EAT(...) +#define EXPAND(...) __VA_ARGS__ +#define WHEN(c) IF(c)(EXPAND, EAT) + +#define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x)) +#define NOT_0 PROBE(~) + +#define COMPL(b) PRIMITIVE_CAT(COMPL_, b) +#define COMPL_0 1 +#define COMPL_1 0 + +#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__) +#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ + +#define IIF(c) PRIMITIVE_CAT(IIF_, c) +#define IIF_0(t, ...) __VA_ARGS__ +#define IIF_1(t, ...) t + +#define DEC(x) PRIMITIVE_CAT(DEC_, x) +#define DEC_0 0 +#define DEC_1 0 +#define DEC_2 1 +#define DEC_3 2 +#define DEC_4 3 +#define DEC_5 4 +#define DEC_6 5 +#define DEC_7 6 +#define DEC_8 7 +#define DEC_9 8 +#define DEC_10 9 +#define DEC_11 10 +#define DEC_12 11 +#define DEC_13 12 +#define DEC_14 13 +#define DEC_15 14 +#define DEC_16 15 +#define DEC_17 16 +#define DEC_18 17 +#define DEC_19 18 +#define DEC_20 19 +#define DEC_21 20 +#define DEC_22 21 +#define DEC_23 22 +#define DEC_24 23 +#define DEC_25 24 +#define DEC_26 25 +#define DEC_27 26 +#define DEC_28 27 +#define DEC_29 28 +#define DEC_30 29 +#define DEC_31 30 +#define DEC_32 31 + +#define EMPTY() +#define DEFER(id) id EMPTY() +#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)() +#define EXPAND(...) __VA_ARGS__ + +#define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__))) +#define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__))) +#define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__))) +#define EVAL3(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__))) +#define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__))) +#define EVAL5(...) __VA_ARGS__ + +#define REPEAT(count, macro, ...) \ + WHEN(count) \ + ( \ + OBSTRUCT(REPEAT_INDIRECT) () \ + ( \ + DEC(count), macro, __VA_ARGS__ \ + ) \ + OBSTRUCT(macro) \ + ( \ + DEC(count), __VA_ARGS__ \ + ) \ + ) +#define REPEAT_INDIRECT() REPEAT + + +/** + * @} + */ + +#endif // ES_UTIL_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/nrf_ble_es.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/nrf_ble_es.c new file mode 100644 index 0000000000000000000000000000000000000000..cf8a0db805528f34b852b2f50848cb46785509c1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/nrf_ble_es.c @@ -0,0 +1,429 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "nrf_ble_es.h" +#include "app_error.h" +#include "fds.h" +#include "es_adv.h" +#include "es_battery_voltage.h" +#include "es_flash.h" +#include "es_gatts.h" +#include "es_security.h" +#include "es_slot.h" +#include "es_stopwatch.h" +#include "escs_defs.h" + +static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; //!< Connection handle. +static nrf_ble_escs_t m_ble_ecs; //!< Struct identifying the Eddystone Config Service. +static nrf_ble_es_evt_handler_t m_evt_handler; //!< Event handler. + +/**@brief Function for invoking registered callback. + * + * @param[in] evt Event to issue to callback. + */ +static void handle_evt(nrf_ble_es_evt_t evt) +{ + if (m_evt_handler != NULL) + { + m_evt_handler(evt); + } +} + + +/**@brief Function resetting MAC address. Will resume advertisement. */ +static void new_address_set(void) +{ + + ret_code_t err_code; + uint8_t bytes_available; + ble_gap_addr_t new_address; + + new_address.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC; + + // Randomize the MAC address on every EID generation + (void)sd_rand_application_bytes_available_get(&bytes_available); + + while (bytes_available < BLE_GAP_ADDR_LEN) + { + // wait for SD to acquire enough RNs + (void)sd_rand_application_bytes_available_get(&bytes_available); + } + + (void)sd_rand_application_vector_get(new_address.addr, BLE_GAP_ADDR_LEN); + + // Stop advertising to ensure that it is possible to change the address. + (void)sd_ble_gap_adv_stop(); + + do + { +#if NRF_SD_BLE_API_VERSION >= 3 + err_code = sd_ble_gap_addr_set(&new_address); +#else + err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &new_address); +#endif // NRF_SD_BLE_API_VERSION + }while(err_code == NRF_ERROR_INVALID_STATE); + + APP_ERROR_CHECK(err_code); + + if(es_adv_remain_connectable_get()) + { + es_adv_start_connectable_adv(); + } + else + { + es_adv_start_non_connctable_adv(); + } +} + + +/**@brief Function updating MAC address if required. + * + * @param[in] demand_new_mac If 'true', mac address will be updated on next invocation when not connected. + * If 'false', simply check if we have an outstanding demand for new MAC and update if not connected. + */ +static void check_and_update_mac_address(bool demand_new_mac) +{ + static bool reset_mac_address = false; + + if (demand_new_mac) + { + reset_mac_address = true; + } + + // Not possible to update MAC address while in a connection + if (m_conn_handle != BLE_CONN_HANDLE_INVALID) + { + return; + } + + else if (reset_mac_address) + { + reset_mac_address = false; + + new_address_set(); + } +} + + +/**@brief Function to lock the beacon (change lock state characteristic to LOCKED) + */ +static void lock_beacon(void) +{ + *(m_ble_ecs.p_lock_state) = NRF_BLE_ESCS_LOCK_STATE_LOCKED; +} + + +/**@brief Function for handling BLE event from the SoftDevice. + * + * @param[in] p_ble_evt Pointer to BLE event. + */ +static void on_ble_evt(ble_evt_t * p_ble_evt) +{ + ret_code_t err_code; + es_flash_flags_t flash_flag = {{0}}; + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + m_conn_handle = p_ble_evt->evt.common_evt.conn_handle; + *(m_ble_ecs.p_active_slot) = 0; + break; + + case BLE_GAP_EVT_DISCONNECTED: + m_conn_handle = BLE_CONN_HANDLE_INVALID; + + for (uint32_t i = 0; i < APP_MAX_ADV_SLOTS; ++i) + { + err_code = es_slot_write_to_flash(i); + APP_ERROR_CHECK(err_code); + + flash_flag.slot_is_empty[i] = !p_reg->slots[i].configured; + } + + err_code = es_flash_access_flags(&flash_flag, ES_FLASH_ACCESS_WRITE); + APP_ERROR_CHECK(err_code); + + es_flash_beacon_config_t beacon_config; + beacon_config.adv_interval = es_adv_interval_get(); + beacon_config.remain_connectable = es_adv_remain_connectable_get(); + + err_code = es_flash_access_beacon_config(&beacon_config, ES_FLASH_ACCESS_WRITE); + APP_ERROR_CHECK(err_code); + + if (*m_ble_ecs.p_lock_state == NRF_BLE_ESCS_LOCK_STATE_UNLOCKED) + { + lock_beacon(); + } + + check_and_update_mac_address(false); + + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Callback function to receive messages from the security module + * + * @details Need to be passed in during es_security_init(). The security + * module will callback anytime a particular security process is completed + * + * @params[in] slot_no Index of the slot + * @params[in] msg_type Message type corersponding to different security components + */ +static void nrf_ble_escs_security_cb(uint8_t slot_no, es_security_msg_t msg_type) +{ + nrf_ble_escs_eid_id_key_t encrypted_id_key; + nrf_ble_escs_public_ecdh_key_t pub_ecdh_key; + + ret_code_t err_code; + static ble_gatts_value_t value; + + switch (msg_type) + { + case ES_SECURITY_MSG_UNLOCKED: + *(m_ble_ecs.p_lock_state) = NRF_BLE_ESCS_LOCK_STATE_UNLOCKED; + break; + + case ES_SECURITY_MSG_EID: + es_slot_eid_ready(slot_no); +#ifdef MAC_RANDOMIZED + check_and_update_mac_address(true); +#endif // MAC_RANDOMIZED + break; + + case ES_SECURITY_MSG_IK: + es_security_encrypted_eid_id_key_get(slot_no, (uint8_t *)encrypted_id_key.key); + // Set the EID ID key in the slot so it can be exposed in the characteristic + es_slot_encrypted_eid_id_key_set(slot_no, &encrypted_id_key); + break; + + case ES_SECURITY_MSG_ECDH: + es_security_pub_ecdh_get(slot_no, (uint8_t *)pub_ecdh_key.key); + + // Set the characteristic to the ECDH key value + value.len = sizeof(nrf_ble_escs_public_ecdh_key_t); + value.offset = 0; + value.p_value = (uint8_t *)pub_ecdh_key.key; + + if (m_conn_handle != BLE_CONN_HANDLE_INVALID) + { + err_code = sd_ble_gatts_value_set(m_ble_ecs.conn_handle, + m_ble_ecs.pub_ecdh_key_handles.value_handle, + &value); + if (err_code != NRF_SUCCESS) + { + APP_ERROR_CHECK(err_code); + } + } + break; + + case ES_SECURITY_MSG_STORE_TIME: + // Every 24 hours any EID slots time is stored to flash to allow for power lock_state_handles + // recovery. Only time needs to be stored, but just store the entire slot anyway for API simplicity. + err_code = es_slot_write_to_flash(slot_no); + APP_ERROR_CHECK(err_code); + + break; + + default: + APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM); // Should never happen + break; + } +} + + +/**@brief Function for handling advertisement events from 'es_adv'. + * + * @param[in] evt Advertisement event to handle. + */ +static void adv_evt_handler(es_adv_evt_t evt) +{ + switch (evt) + { + case ES_ADV_EVT_NON_CONN_ADV: + handle_evt(NRF_BLE_ES_EVT_ADVERTISEMENT_SENT); + es_security_update_time(); + break; + + case ES_ADV_EVT_CONNECTABLE_ADV_STARTED: + handle_evt(NRF_BLE_ES_EVT_CONNECTABLE_ADV_STARTED); + break; + } +} + + +/**@brief Initialize the ECS with initial values for the characteristics and other necessary modules */ +static void ble_escs_init(void) +{ + ret_code_t err_code; + nrf_ble_escs_init_t ecs_init; + nrf_ble_escs_init_params_t init_params; + int8_t tx_powers[ESCS_NUM_OF_SUPPORTED_TX_POWER] = ESCS_SUPPORTED_TX_POWER; + + /*Init the broadcast capabilities characteristic*/ + memset(&init_params.broadcast_cap, 0, sizeof(init_params.broadcast_cap)); + init_params.broadcast_cap.vers_byte = ES_SPEC_VERSION_BYTE; + init_params.broadcast_cap.max_supp_total_slots = APP_MAX_ADV_SLOTS; + init_params.broadcast_cap.max_supp_eid_slots = APP_MAX_EID_SLOTS; + init_params.broadcast_cap.cap_bitfield = ( (APP_IS_VARIABLE_ADV_SUPPORTED << ESCS_BROADCAST_VAR_ADV_SUPPORTED_Pos) + | (APP_IS_VARIABLE_TX_POWER_SUPPORTED << ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Pos)) + & (ESCS_BROADCAST_VAR_RFU_MASK); + init_params.broadcast_cap.supp_frame_types = ( (APP_IS_URL_SUPPORTED << ESCS_FRAME_TYPE_URL_SUPPORTED_Pos) + | (APP_IS_UID_SUPPORTED << ESCS_FRAME_TYPE_UID_SUPPORTED_Pos) + | (APP_IS_TLM_SUPPORTED << ESCS_FRAME_TYPE_TLM_SUPPORTED_Pos) + | (APP_IS_EID_SUPPORTED << ESCS_FRAME_TYPE_EID_SUPPORTED_Pos)) + & (ESCS_FRAME_TYPE_RFU_MASK); + memcpy(init_params.broadcast_cap.supp_radio_tx_power, tx_powers, ESCS_NUM_OF_SUPPORTED_TX_POWER); + + init_params.adv_interval = APP_CFG_NON_CONN_ADV_INTERVAL_MS; + init_params.adv_tx_pwr = APP_CFG_DEFAULT_RADIO_TX_POWER; + init_params.radio_tx_pwr = 0x00; + init_params.factory_reset = 0; + init_params.remain_connectable.r_is_non_connectable_supported = APP_IS_REMAIN_CONNECTABLE_SUPPORTED; + + // Initialize evt handlers and the service + memset(&ecs_init, 0, sizeof(ecs_init)); + ecs_init.write_evt_handler = es_gatts_handle_write; + ecs_init.read_evt_handler = es_gatts_handle_read; + ecs_init.p_init_vals = &(init_params); + + err_code = nrf_ble_escs_init(&m_ble_ecs, &ecs_init); + APP_ERROR_CHECK(err_code); +} + + +/**@brief Function for initializing 'es_adv' module. */ +static void adv_init(void) +{ + ret_code_t err_code; + es_flash_beacon_config_t beacon_config; + + err_code = es_flash_access_beacon_config(&beacon_config, ES_FLASH_ACCESS_READ); + + if (err_code == FDS_ERR_NOT_FOUND) + { + beacon_config.adv_interval = APP_CFG_NON_CONN_ADV_INTERVAL_MS; + beacon_config.remain_connectable = false; + } + + else + { + APP_ERROR_CHECK(err_code); + } + + es_adv_init(m_ble_ecs.uuid_type, + adv_evt_handler, + beacon_config.adv_interval, + beacon_config.remain_connectable); +} + + +/**@brief Function for initializing es_slots module. */ +static void adv_slots_init(void) +{ + uint8_t default_frame_data[DEFAULT_FRAME_LENGTH] = DEFAULT_FRAME_DATA; + + es_slot_t default_adv_slot = {.slot_no = 0, + .radio_tx_pwr = 0, + .adv_frame.type = DEFAULT_FRAME_TYPE, + .adv_frame.length = DEFAULT_FRAME_LENGTH, + .adv_custom_tx_power = false, + .configured = true}; + + memcpy(&default_adv_slot.adv_frame.frame, default_frame_data, DEFAULT_FRAME_LENGTH); + + es_slots_init(&default_adv_slot); +} + + +void nrf_ble_es_on_ble_evt(ble_evt_t * p_ble_evt) +{ + ret_code_t err_code; + + es_adv_on_ble_evt(p_ble_evt); + err_code = nrf_ble_escs_on_ble_evt(&m_ble_ecs, p_ble_evt); + APP_ERROR_CHECK(err_code); + on_ble_evt(p_ble_evt); + es_flash_on_ble_evt(p_ble_evt); +} + + +void nrf_ble_es_on_start_connectable_advertising(void) +{ + es_adv_start_connectable_adv(); +} + + +void nrf_ble_es_init(nrf_ble_es_evt_handler_t evt_handler) +{ + ret_code_t err_code; + + m_evt_handler = evt_handler; + m_conn_handle = BLE_CONN_HANDLE_INVALID; + + es_stopwatch_init(); + + err_code = es_gatts_init(&m_ble_ecs); + APP_ERROR_CHECK(err_code); + + err_code = es_flash_init(); + APP_ERROR_CHECK(err_code); + + while (es_flash_num_pending_ops() > 0) + { + ; // Busy wait while initialization of FDS module completes + } + + err_code = es_security_init(nrf_ble_escs_security_cb); + APP_ERROR_CHECK(err_code); + + es_adv_timers_init(); + ble_escs_init(); + adv_slots_init(); + es_battery_voltage_init(); + adv_init(); + es_adv_start_non_connctable_adv(); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/nrf_ble_es.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/nrf_ble_es.h new file mode 100644 index 0000000000000000000000000000000000000000..b668ccaabf4e5c916638cb47831fb337e3b09193 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/eddystone/nrf_ble_es.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef NRF_ES_H__ +#define NRF_ES_H__ + +#include +#include "ble.h" + +/** + * @file + * @defgroup eddystone Eddystone library + * @ingroup app_common + * @{ + * + * @brief Library for Eddystone beacons. This library is used in the @ref ble_sdk_app_es. + * + * @note The API documentation is provided for reference only. You should + * not modify this library, and you should not use any functions + * except for the main level functions defined in @c nrf_ble_es.h + * in different contexts. + */ + +/** @brief Eddystone event types. */ +typedef enum { + NRF_BLE_ES_EVT_ADVERTISEMENT_SENT, //!< A non-connectable Eddystone frame advertisement was sent. + NRF_BLE_ES_EVT_CONNECTABLE_ADV_STARTED, //!< Advertising in connectable mode was started. +}nrf_ble_es_evt_t; + +/**@brief Eddystone event handler type. */ +typedef void (*nrf_ble_es_evt_handler_t)(nrf_ble_es_evt_t evt); + +/**@brief Function for handling the application's BLE stack events. + * + * @details This function handles all events from the BLE stack that are of + * interest to the Eddystone library. It must be called from the @ref + * softdevice_handler callback for all BLE events that are received from the + * SoftDevice. + * + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void nrf_ble_es_on_ble_evt(ble_evt_t * p_ble_evt); + +/**@brief Function for putting the beacon in connectable mode. + * + * @details This function makes the beacon advertise connectable advertisements. + * If the beacon is in a connected state, the request is ignored. + */ +void nrf_ble_es_on_start_connectable_advertising(void); + +/** @brief Function for initializing the Eddystone library. + * + * @param[in] evt_handler Event handler to be called for handling BLE events. + */ +void nrf_ble_es_init(nrf_ble_es_evt_handler_t evt_handler); + +/** + * @} + */ + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/experimental_section_vars/nrf_section.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/experimental_section_vars/nrf_section.h new file mode 100644 index 0000000000000000000000000000000000000000..28f126bc5a608825880108cfc20bfdcfd8959ff1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/experimental_section_vars/nrf_section.h @@ -0,0 +1,179 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SECTION_H__ +#define NRF_SECTION_H__ + +#include "nordic_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup section_vars Section variables + * @ingroup app_common + * @{ + * + * @brief Section variables. + */ +#if defined(__ICCARM__) +// Enable IAR language extensions +#pragma language=extended +#endif + +/**@brief Macro for obtaining the address of the beginning of a section. + * + * param[in] section_name Name of the section. + */ +#if defined(__CC_ARM) +//lint -save -e27 Illegal character (0x24) +#define NRF_SECTION_START_ADDR(section_name) &CONCAT_2(section_name, $$Base) +//lint -restore + +#elif defined(__GNUC__) +#define NRF_SECTION_START_ADDR(section_name) &CONCAT_2(__start_, section_name) + +#elif defined(__ICCARM__) +#define NRF_SECTION_START_ADDR(section_name) __section_begin(STRINGIFY(section_name)) +#endif + +/**@brief Macro for obtaining the address of the end of a section. + * + * @param[in] section_name Name of the section. + */ +#if defined(__CC_ARM) +//lint -save -e27 Illegal character (0x24) +#define NRF_SECTION_END_ADDR(section_name) &CONCAT_2(section_name, $$Limit) +//lint -restore + +#elif defined(__GNUC__) +#define NRF_SECTION_END_ADDR(section_name) &CONCAT_2(__stop_, section_name) + +#elif defined(__ICCARM__) +#define NRF_SECTION_END_ADDR(section_name) __section_end(STRINGIFY(section_name)) +#endif + +/**@brief Macro for retrieving the length of a given section, in bytes. + * + * @param[in] section_name Name of the section. + */ +#define NRF_SECTION_LENGTH(section_name) \ + ((size_t)NRF_SECTION_END_ADDR(section_name) - \ + (size_t)NRF_SECTION_START_ADDR(section_name)) + +/**@brief Macro for creating a section. + * + * @param[in] section_name Name of the section. + * @param[in] data_type Data type of the variables to be registered in the section. + * + * @warning Data type must be word aligned to prevent padding. + */ +#if defined(__CC_ARM) +//lint -save -e27 Illegal character (0x24) +#define NRF_SECTION_DEF(section_name, data_type) \ + extern data_type * CONCAT_2(section_name, $$Base); \ + extern void * CONCAT_2(section_name, $$Limit) +//lint -restore + +#elif defined(__GNUC__) +#define NRF_SECTION_DEF(section_name, data_type) \ + extern data_type * CONCAT_2(__start_, section_name); \ + extern void * CONCAT_2(__stop_, section_name) + +#elif defined(__ICCARM__) +#define NRF_SECTION_DEF(section_name, data_type) \ + _Pragma(STRINGIFY(section = STRINGIFY(section_name))); + +#endif + +/**@brief Macro for declaring a variable and registering it in a section. + * + * @details Declares a variable and registers it in a named section. This macro ensures that the + * variable is not stripped away when using optimizations. + * + * @note The order in which variables are placed in a section is dependent on the order in + * which the linker script encounters the variables during linking. + * + * @param[in] section_name Name of the section. + * @param[in] section_var Variable in which to register the given section. + */ +#if defined(__CC_ARM) +#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \ + static section_var __attribute__ ((section(STRINGIFY(section_name)))) __attribute__((used)) + +#elif defined(__GNUC__) +#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \ + static section_var __attribute__ ((section("."STRINGIFY(section_name)))) __attribute__((used)) + +#elif defined(__ICCARM__) +#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \ + __root section_var @ STRINGIFY(section_name) +#endif + +/**@brief Macro for retrieving a variable from a section. + * + * @warning The stored symbol can only be resolved using this macro if the + * type of the data is word aligned. The operation of acquiring + * the stored symbol relies on the size of the stored type. No + * padding can exist in the named section in between individual + * stored items or this macro will fail. + * + * @param[in] section_name Name of the section. + * @param[in] data_type Data type of the variable. + * @param[in] i Index of the variable in section. + */ +#define NRF_SECTION_ITEM_GET(section_name, data_type, i) \ + ((data_type*)NRF_SECTION_START_ADDR(section_name) + (i)) + +/**@brief Macro for getting the number of variables in a section. + * + * @param[in] section_name Name of the section. + * @param[in] data_type Data type of the variables in the section. + */ +#define NRF_SECTION_ITEM_COUNT(section_name, data_type) \ + NRF_SECTION_LENGTH(section_name) / sizeof(data_type) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SECTION_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/experimental_section_vars/nrf_section_iter.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/experimental_section_vars/nrf_section_iter.c new file mode 100644 index 0000000000000000000000000000000000000000..a3a66e337d941a60790b06edf4c1afa5db7543bb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/experimental_section_vars/nrf_section_iter.c @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_SECTION_ITER) + +#include "nrf_section_iter.h" + +#if !defined(__GNUC__) +static void nrf_section_iter_item_set(nrf_section_iter_t * p_iter) +{ + ASSERT(p_iter != NULL); + ASSERT(p_iter->p_set != NULL); + ASSERT(p_iter->p_section != NULL); + while (true) + { + if (p_iter->p_section == p_iter->p_set->p_last) + { + // End of the section set. + p_iter->p_item = NULL; + return; + } + + if (p_iter->p_section->p_start != p_iter->p_section->p_end) + { + // Not empty section. + p_iter->p_item = p_iter->p_section->p_start; + return; + } + + // Next section. + p_iter->p_section++; + } +} +#endif + +void nrf_section_iter_init(nrf_section_iter_t * p_iter, nrf_section_set_t const * p_set) +{ + ASSERT(p_iter != NULL); + ASSERT(p_set != NULL); + + p_iter->p_set = p_set; + +#if defined(__GNUC__) + p_iter->p_item = p_iter->p_set->section.p_start; + if (p_iter->p_item == p_iter->p_set->section.p_end) + { + p_iter->p_item = NULL; + } +#else + p_iter->p_section = p_set->p_first; + nrf_section_iter_item_set(p_iter); +#endif +} + +void nrf_section_iter_next(nrf_section_iter_t * p_iter) +{ + ASSERT(p_iter != NULL); + ASSERT(p_iter->p_set != NULL); + + if (p_iter->p_item == NULL) + { + return; + } + + p_iter->p_item = (void *)((size_t)(p_iter->p_item) + p_iter->p_set->item_size); + +#if defined(__GNUC__) + if (p_iter->p_item == p_iter->p_set->section.p_end) + { + p_iter->p_item = NULL; + } + +#else + ASSERT(p_iter->p_section != NULL); + // If current section ended? + if (p_iter->p_item == p_iter->p_section->p_end) + { + p_iter->p_section++; + nrf_section_iter_item_set(p_iter); + } +#endif +} +#endif // NRF_MODULE_ENABLED(NRF_SECTION_ITER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/experimental_section_vars/nrf_section_iter.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/experimental_section_vars/nrf_section_iter.h new file mode 100644 index 0000000000000000000000000000000000000000..5fe239d10e90dd59798d5d28ad117b5b6f3d04cf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/experimental_section_vars/nrf_section_iter.h @@ -0,0 +1,186 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SECTION_ITER_H__ +#define NRF_SECTION_ITER_H__ +#include +#include "nrf_section.h" +#include "app_util.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup nrf_section_iter Section variables iterator + * @ingroup app_common + * @{ + */ + +/**@brief Single section description structure. */ +typedef struct +{ + void * p_start; //!< Pointer to the start of section. + void * p_end; //!< Pointer to the end of section. +} nrf_section_t; + +/**@brief Set of the sections description structure. */ +typedef struct +{ +#if defined(__GNUC__) + nrf_section_t section; //!< Description of the set of sections. + /**< + * In case of GCC all sections in the set are sorted and + * placed in contiguous area, because they are treated as + * one section. + */ +#else + nrf_section_t const * p_first; //!< Pointer to the first section in the set. + nrf_section_t const * p_last; //!< Pointer to the last section in the set. +#endif + size_t item_size; //!< Size of the single item in the section. +} nrf_section_set_t; + +/**@brief Section iterator structure. */ +typedef struct +{ + nrf_section_set_t const * p_set; //!< Pointer to the appropriate section set. +#if !defined(__GNUC__) + nrf_section_t const * p_section; //!< Pointer to the selected section. + /**< + * In case of GCC all sections in the set are sorted and + * placed in contiguous area, because they are treated + * as one section. + */ +#endif + void * p_item; //!< Pointer to the selected item in the section. +} nrf_section_iter_t; + +/**@brief Create a section set instance. + * + * @note This macro reserves memory for the given section set instance. + * + * @details Section set is an ordered group of sections. + * + * @param[in] _name Name of the section set. + * @param[in] _type Type of the elements stored in the section. + * @param[in] _count Number of the sections in the set. This parameter is ignored in case of GCC. + */ +#if defined(__GNUC__) +#define NRF_SECTION_SET_DEF(_name, _type, _count) \ + NRF_SECTION_DEF(_name, _type); \ + static const nrf_section_set_t _name = { \ + .section = { \ + .p_start = NRF_SECTION_START_ADDR(_name), \ + .p_end = NRF_SECTION_END_ADDR(_name), \ + }, \ + .item_size = sizeof(_type), \ + } + +#else +#define NRF_SECTION_SET_DEF(_name, _type, _count) \ + MACRO_REPEAT_FOR(_count, NRF_SECTION_DEF_, _name, _type) \ + static const nrf_section_t CONCAT_2(_name, _array)[] = \ + { \ + MACRO_REPEAT_FOR(_count, NRF_SECTION_SET_DEF_, _name) \ + }; \ + static const nrf_section_set_t _name = { \ + .p_first = CONCAT_2(_name, _array), \ + .p_last = CONCAT_2(_name, _array) + ARRAY_SIZE(CONCAT_2(_name, _array)), \ + .item_size = sizeof(_type), \ + } + +#define NRF_SECTION_DEF_(_priority, _name, _type) \ + NRF_SECTION_DEF(CONCAT_2(_name, _priority), _type); + +#define NRF_SECTION_SET_DEF_(_priority, _name) \ + { \ + .p_start = NRF_SECTION_START_ADDR(CONCAT_2(_name, _priority)), \ + .p_end = NRF_SECTION_END_ADDR(CONCAT_2(_name, _priority)), \ + }, + +#endif + +/**@brief Macro to declare a variable and register it in the section set. + * + * @note The order of the section in the set is based on the priority. The order with which + * variables are placed in a section is dependant on the order with which the linker + * encouters the variables during linking. + * + * @param[in] _name Name of the section set. + * @param[in] _priority Priority of the desired section. + * @param[in] _var The variable to register in the given section. + */ +#define NRF_SECTION_SET_ITEM_REGISTER(_name, _priority, _var) \ + NRF_SECTION_ITEM_REGISTER(CONCAT_2(_name, _priority), _var) + +/**@brief Function for initializing the section set iterator. + * + * @param[in] p_iter Pointer to the iterator. + * @param[in] p_set Pointer to the sections set. + */ +void nrf_section_iter_init(nrf_section_iter_t * p_iter, nrf_section_set_t const * p_set); + +/**@brief Function for incrementing iterator. + * + * @param[in] p_iter Pointer to the iterator. + */ +void nrf_section_iter_next(nrf_section_iter_t * p_iter); + +/**@brief Function for getting the element pointed to by the iterator. + * + * @param[in] p_iter Pointer to the iterator. + * + * @retval Pointer to the element or NULL if iterator points end of the set. + */ +static inline void * nrf_section_iter_get(nrf_section_iter_t const * p_iter) +{ + ASSERT(p_iter); + return p_iter->p_item; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SECTION_ITER_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fds/fds.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fds/fds.c new file mode 100644 index 0000000000000000000000000000000000000000..7c0a94468b853553caae8a9b0df310fa0013fe64 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fds/fds.c @@ -0,0 +1,2104 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(FDS) +#include "fds.h" +#include "fds_internal_defs.h" + +#include +#include +#include +#include "fstorage.h" +#include "nrf_error.h" + +#if defined(FDS_CRC_ENABLED) + #include "crc16.h" +#endif + + +static void fs_event_handler(fs_evt_t const * const evt, fs_ret_t result); + +// Our fstorage configuration. +FS_REGISTER_CFG(fs_config_t fs_config) = +{ + .callback = fs_event_handler, + .num_pages = FDS_PHY_PAGES, + // We register with the highest priority in order to be assigned + // the pages with the highest memory address (closest to the bootloader). + .priority = 0xFF +}; + +// Used to flag a record as dirty, i.e. ready for garbage collection. +// Must be statically allocated since it will be written to flash. +__ALIGN(4) static fds_tl_t const m_fds_tl_dirty = +{ + .record_key = FDS_RECORD_KEY_DIRTY, + .length_words = 0xFFFF // Leave the record length field unchanged in flash. +}; + +// Internal status flags. +static uint8_t m_flags; + +// The number of registered users and their callback functions. +static uint8_t m_users; +static fds_cb_t m_cb_table[FDS_MAX_USERS]; + +// The latest (largest) record ID written so far. +static uint32_t m_latest_rec_id; + +// The internal queues. +static fds_op_queue_t m_op_queue; +static fds_chunk_queue_t m_chunk_queue; + +// Structures used to hold informations about virtual pages. +static fds_page_t m_pages[FDS_MAX_PAGES]; +static fds_swap_page_t m_swap_page; + +// Garbage collection data. +static fds_gc_data_t m_gc; + + +static void flag_set(fds_flags_t flag) +{ + CRITICAL_SECTION_ENTER(); + m_flags |= flag; + CRITICAL_SECTION_EXIT(); +} + + +static void flag_clear(fds_flags_t flag) +{ + CRITICAL_SECTION_ENTER(); + m_flags &= ~(flag); + CRITICAL_SECTION_EXIT(); +} + + +static bool flag_is_set(fds_flags_t flag) +{ + return (m_flags & flag); +} + + +static void event_send(fds_evt_t const * const p_evt) +{ + for (uint32_t user = 0; user < FDS_MAX_USERS; user++) + { + if (m_cb_table[user] != NULL) + { + m_cb_table[user](p_evt); + } + } +} + + +static void event_prepare(fds_op_t const * const p_op, fds_evt_t * const p_evt) +{ + switch (p_op->op_code) + { + case FDS_OP_INIT: + p_evt->id = FDS_EVT_INIT; + break; + + case FDS_OP_WRITE: + p_evt->id = FDS_EVT_WRITE; + p_evt->write.file_id = p_op->write.header.ic.file_id; + p_evt->write.record_key = p_op->write.header.tl.record_key; + p_evt->write.record_id = p_op->write.header.record_id; + break; + + case FDS_OP_UPDATE: + p_evt->id = FDS_EVT_UPDATE; + p_evt->write.file_id = p_op->write.header.ic.file_id; + p_evt->write.record_key = p_op->write.header.tl.record_key; + p_evt->write.record_id = p_op->write.header.record_id; + p_evt->write.is_record_updated = (p_op->write.step == FDS_OP_WRITE_DONE); + break; + + case FDS_OP_DEL_RECORD: + p_evt->id = FDS_EVT_DEL_RECORD; + p_evt->del.file_id = p_op->del.file_id; + p_evt->del.record_key = p_op->del.record_key; + p_evt->del.record_id = p_op->del.record_to_delete; + break; + + case FDS_OP_DEL_FILE: + p_evt->id = FDS_EVT_DEL_FILE; + p_evt->del.file_id = p_op->del.file_id; + p_evt->del.record_key = FDS_RECORD_KEY_DIRTY; + break; + + case FDS_OP_GC: + p_evt->id = FDS_EVT_GC; + break; + + default: + // Should not happen. + break; + } +} + + +static bool header_is_valid(fds_header_t const * const p_header) +{ + return ((p_header->ic.file_id != FDS_FILE_ID_INVALID) && + (p_header->tl.record_key != FDS_RECORD_KEY_DIRTY)); +} + + +static bool address_is_valid(uint32_t const * const p_addr) +{ + return ((p_addr != NULL) && + (p_addr >= fs_config.p_start_addr) && + (p_addr <= fs_config.p_end_addr) && + (is_word_aligned(p_addr))); +} + + +static bool chunk_is_aligned(fds_record_chunk_t const * const p_chunk, uint32_t num_chunks) +{ + for (uint32_t i = 0; i < num_chunks; i++) + { + if (!is_word_aligned(p_chunk[i].p_data)) + { + return false; + } + } + return true; +} + + +// Reads a page tag, and determines if the page is used to store data or as swap. +static fds_page_type_t page_identify(uint32_t const * const p_page_addr) +{ + if (p_page_addr[FDS_PAGE_TAG_WORD_0] != FDS_PAGE_TAG_MAGIC) + { + return FDS_PAGE_UNDEFINED; + } + + switch (p_page_addr[FDS_PAGE_TAG_WORD_1]) + { + case FDS_PAGE_TAG_SWAP: + return FDS_PAGE_SWAP; + + case FDS_PAGE_TAG_DATA: + return FDS_PAGE_DATA; + + default: + return FDS_PAGE_UNDEFINED; + } +} + + +static bool page_is_erased(uint32_t const * const p_page_addr) +{ + for (uint32_t i = 0; i < FDS_PAGE_SIZE; i++) + { + if (*(p_page_addr + i) != FDS_ERASED_WORD) + { + return false; + } + } + + return true; +} + + +// NOTE: Must be called from within a critical section. +static bool page_has_space(uint16_t page, uint16_t length_words) +{ + length_words += m_pages[page].write_offset; + length_words += m_pages[page].words_reserved; + return (length_words < FDS_PAGE_SIZE); +} + + +// Given a pointer to a record, find the index of the page on which it is stored. +// Returns FDS_SUCCESS if the page is found, FDS_ERR_NOT_FOUND otherwise. +static ret_code_t page_from_record(uint16_t * const p_page, uint32_t const * const p_rec) +{ + ret_code_t ret = FDS_ERR_NOT_FOUND; + + CRITICAL_SECTION_ENTER(); + for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) + { + if ((p_rec > m_pages[i].p_addr) && + (p_rec < m_pages[i].p_addr + FDS_PAGE_SIZE)) + { + ret = FDS_SUCCESS; + *p_page = i; + break; + } + } + CRITICAL_SECTION_EXIT(); + + return ret; +} + + +// Scan a page to determine how many words have been written to it. +// This information is used to set the page write offset during initialization. +// Additionally, this function updates the latest record ID as it proceeds. +// If an invalid record header is found, the can_gc argument is set to true. +static void page_scan(uint32_t const * p_addr, + uint16_t * const words_written, + bool * const can_gc) +{ + uint32_t const * const p_end_addr = p_addr + FDS_PAGE_SIZE; + bool dirty_record_found = false; + + p_addr += FDS_PAGE_TAG_SIZE; + *words_written = FDS_PAGE_TAG_SIZE; + + while ((p_addr < p_end_addr) && (*p_addr != FDS_ERASED_WORD)) + { + // NOTE: Skip records with a dirty key or with a missing file ID. + fds_header_t const * const p_header = (fds_header_t*)p_addr; + + if (!header_is_valid(p_header)) + { + dirty_record_found = true; + } + else + { + // Update the latest (largest) record ID. + if (p_header->record_id > m_latest_rec_id) + { + m_latest_rec_id = p_header->record_id; + } + } + + // Jump to the next record. + p_addr += (FDS_HEADER_SIZE + p_header->tl.length_words); + *words_written += (FDS_HEADER_SIZE + p_header->tl.length_words); + } + + if (can_gc != NULL) + { + *can_gc = dirty_record_found; + } +} + + +static void page_offsets_update(fds_page_t * const p_page, uint16_t length_words) +{ + p_page->write_offset += (FDS_HEADER_SIZE + length_words); + p_page->words_reserved -= (FDS_HEADER_SIZE + length_words); +} + + +// Tags a page as swap, i.e., reserved for GC. +static ret_code_t page_tag_write_swap() +{ + // Needs to be statically allocated since it will be written to flash. + static uint32_t const page_tag_swap[] = {FDS_PAGE_TAG_MAGIC, FDS_PAGE_TAG_SWAP}; + return fs_store(&fs_config, m_swap_page.p_addr, page_tag_swap, FDS_PAGE_TAG_SIZE, NULL); +} + + +// Tags a page as data, i.e, ready for storage. +static ret_code_t page_tag_write_data(uint32_t const * const p_page_addr) +{ + // Needs to be statically allocated since it will be written to flash. + static uint32_t const page_tag_data[] = {FDS_PAGE_TAG_MAGIC, FDS_PAGE_TAG_DATA}; + return fs_store(&fs_config, p_page_addr, page_tag_data, FDS_PAGE_TAG_SIZE, NULL); +} + + +// Reserve space on a page. +// NOTE: this function takes into the account the space required for the record header. +static ret_code_t write_space_reserve(uint16_t length_words, uint16_t * p_page) +{ + bool space_reserved = false; + uint16_t const total_len_words = length_words + FDS_HEADER_SIZE; + + if (total_len_words >= FDS_PAGE_SIZE - FDS_PAGE_TAG_SIZE) + { + return FDS_ERR_RECORD_TOO_LARGE; + } + + CRITICAL_SECTION_ENTER(); + for (uint16_t page = 0; page < FDS_MAX_PAGES; page++) + { + if ((m_pages[page].page_type == FDS_PAGE_DATA) && + (page_has_space(page, total_len_words))) + { + space_reserved = true; + *p_page = page; + + m_pages[page].words_reserved += total_len_words; + break; + } + } + CRITICAL_SECTION_EXIT(); + + return (space_reserved) ? FDS_SUCCESS : FDS_ERR_NO_SPACE_IN_FLASH; +} + + +// Undo a write_space_reserve() call. +// NOTE: Must be called within a critical section. +static void write_space_free(uint16_t length_words, uint16_t page) +{ + m_pages[page].words_reserved -= (length_words + FDS_HEADER_SIZE); +} + + +static uint32_t record_id_new(void) +{ + CRITICAL_SECTION_ENTER(); + m_latest_rec_id++; + CRITICAL_SECTION_EXIT(); + return m_latest_rec_id; +} + + +// Given a page and a record, finds the next valid record on that page. If p_record is NULL, +// search from the beginning of the page, otherwise, resume searching from the address +// pointed by p_record. Returns true if a record is found, returns false otherwise. +// If no record is found, p_record is unchanged. +static bool record_find_next(uint16_t page, uint32_t const ** p_record) +{ + fds_header_t const * p_header; + uint32_t const * p_next_rec = (*p_record); + + // If this is not the first invocation on this page, then jump to the next record. + // Otherwise, start searching from the beginning of the page. + if (p_next_rec != NULL) + { + p_header = ((fds_header_t*)p_next_rec); + p_next_rec += (FDS_HEADER_SIZE + p_header->tl.length_words); + } + else + { + p_next_rec = m_pages[page].p_addr + FDS_PAGE_TAG_SIZE; + } + + // Read records from the page, until a valid record is found or the end of the page is + // reached. The argument p_record is only updated if a valid record is found. + while ((p_next_rec < (m_pages[page].p_addr + FDS_PAGE_SIZE) && + *p_next_rec != FDS_ERASED_WORD)) + { + p_header = (fds_header_t*)p_next_rec; + + if (header_is_valid(p_header)) + { + *p_record = p_next_rec; + return true; + } + else + { + // The record is not valid, jump to the next. + p_next_rec += (FDS_HEADER_SIZE + (p_header->tl.length_words)); + } + } + + // No more valid records on this page. + return false; +} + + +// Find a record given its descriptor and retrive the page in which the record is stored. +// NOTE: Do not pass NULL as an argument for p_page. +static bool record_find_by_desc(fds_record_desc_t * const p_desc, uint16_t * const p_page) +{ + // If the gc_run_count field in the descriptor matches our counter, then the record has + // not been moved. If the address is valid, and the record ID matches, there is no need + // to find the record again. Only lookup the page in which the record is stored. + + if ((address_is_valid(p_desc->p_record)) && + (p_desc->gc_run_count == m_gc.run_count) && + (p_desc->record_id == ((fds_header_t*)p_desc->p_record)->record_id)) + { + return (page_from_record(p_page, p_desc->p_record) == FDS_SUCCESS); + } + + // Otherwise, find the record in flash. + for (*p_page = 0; *p_page < FDS_MAX_PAGES; (*p_page)++) + { + // Set p_record to NULL to make record_find_next() search from the beginning of the page. + uint32_t const * p_record = NULL; + + while (record_find_next(*p_page, &p_record)) + { + fds_header_t const * const p_header = (fds_header_t*)p_record; + if (p_header->record_id == p_desc->record_id) + { + p_desc->p_record = p_record; + p_desc->gc_run_count = m_gc.run_count; + return true; + } + } + } + + return false; +} + + +// Search for a record and return its descriptor. +// If p_file_id is NULL, only the record key will be used for matching. +// If p_record_key is NULL, only the file ID will be used for matching. +// If both are NULL, it will iterate through all records. +static ret_code_t record_find(uint16_t const * const p_file_id, + uint16_t const * const p_record_key, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token) +{ + if (!flag_is_set(FDS_FLAG_INITIALIZED)) + { + return FDS_ERR_NOT_INITIALIZED; + } + + if (p_desc == NULL || p_token == NULL) + { + return FDS_ERR_NULL_ARG; + } + + // Begin (or resume) searching for a record. + for (; p_token->page < FDS_MAX_PAGES; p_token->page++) + { + if (m_pages[p_token->page].page_type != FDS_PAGE_DATA) + { + // Skip this page. + continue; + } + + while (record_find_next(p_token->page, &p_token->p_addr)) + { + fds_header_t const * const p_header = (fds_header_t*)p_token->p_addr; + + // A valid record was found, check its header for a match. + if ((p_file_id != NULL) && + (p_header->ic.file_id != *p_file_id)) + { + continue; + } + + if ((p_record_key != NULL) && + (p_header->tl.record_key != *p_record_key)) + { + continue; + } + + // Record found; update the descriptor. + p_desc->record_id = p_header->record_id; + p_desc->p_record = p_token->p_addr; + p_desc->gc_run_count = m_gc.run_count; + + return FDS_SUCCESS; + } + + // We have scanned an entire page. Set the address in the token to NULL + // so that it will be updated in the next iteration. + p_token->p_addr = NULL; + } + + return FDS_ERR_NOT_FOUND; +} + + +// Retrieve basic statistics about dirty records on a page. +static void dirty_records_stat(uint16_t page, + uint16_t * const p_dirty_records, + uint16_t * const p_word_count) +{ + fds_header_t const * p_header; + uint32_t const * p_rec; + + p_rec = m_pages[page].p_addr + FDS_PAGE_TAG_SIZE; + + while ((p_rec < (m_pages[page].p_addr + FDS_PAGE_SIZE)) && + (*p_rec != FDS_ERASED_WORD)) + { + p_header = (fds_header_t*)p_rec; + + if (!header_is_valid(p_header)) + { + (*p_dirty_records) += 1; + (*p_word_count) += FDS_HEADER_SIZE + p_header->tl.length_words; + } + + p_rec += (FDS_HEADER_SIZE + (p_header->tl.length_words)); + } +} + + +// Advances one position in the queue. +// Returns true if the queue is not empty. +static bool queue_advance(void) +{ + // Reset the current element. + memset(&m_op_queue.op[m_op_queue.rp], 0x00, sizeof(fds_op_t)); + + if (m_op_queue.count != 0) + { + // Advance in the queue, wrapping around if necessary. + m_op_queue.rp = (m_op_queue.rp + 1) % FDS_OP_QUEUE_SIZE; + m_op_queue.count--; + } + + return (m_op_queue.count != 0); +} + + +// Given a pointer to an element in the chunk queue, computes the pointer to +// the next element in the queue. Handles wrap around. +void chunk_queue_next(fds_record_chunk_t ** pp_chunk) +{ + if ((*pp_chunk) != &m_chunk_queue.chunk[FDS_CHUNK_QUEUE_SIZE - 1]) + { + (*pp_chunk)++; + return; + } + + *pp_chunk = &m_chunk_queue.chunk[0]; +} + + +// Retrieve the current chunk, and advance the queue. +static void chunk_queue_get_and_advance(fds_record_chunk_t ** pp_chunk) +{ + if (m_chunk_queue.count != 0) + { + // Point to the current chunk and advance the queue. + *pp_chunk = &m_chunk_queue.chunk[m_chunk_queue.rp]; + + m_chunk_queue.rp = (m_chunk_queue.rp + 1) % FDS_CHUNK_QUEUE_SIZE; + m_chunk_queue.count--; + } +} + + +static void chunk_queue_skip(fds_op_t const * const p_op) +{ + if ((p_op->op_code == FDS_OP_WRITE) || + (p_op->op_code == FDS_OP_UPDATE)) + { + m_chunk_queue.rp += p_op->write.chunk_count; + m_chunk_queue.count -= p_op->write.chunk_count; + } +} + + +// Enqueue an operation. +static bool op_enqueue(fds_op_t const * const p_op, + uint32_t num_chunks, + fds_record_chunk_t const * const p_chunk) +{ + uint32_t idx; + bool ret = false; + + CRITICAL_SECTION_ENTER(); + if ((m_op_queue.count <= FDS_OP_QUEUE_SIZE - 1) && + (m_chunk_queue.count <= FDS_CHUNK_QUEUE_SIZE - num_chunks)) + { + idx = (m_op_queue.count + m_op_queue.rp) % FDS_OP_QUEUE_SIZE; + + m_op_queue.op[idx] = *p_op; + m_op_queue.count++; + + if (num_chunks != 0) + { + idx = (m_chunk_queue.count + m_chunk_queue.rp) % FDS_CHUNK_QUEUE_SIZE; + + fds_record_chunk_t * p_chunk_dst; + p_chunk_dst = &m_chunk_queue.chunk[idx]; + + for (uint32_t i = 0; i < num_chunks; i++) + { + *p_chunk_dst = p_chunk[i]; + chunk_queue_next(&p_chunk_dst); + } + + m_chunk_queue.count += num_chunks; + } + + ret = true; + } + CRITICAL_SECTION_EXIT(); + + return ret; +} + + +// This function is called during initialization to setup the page structure (m_pages) and +// provide additional information regarding eventual further initialization steps. +static fds_init_opts_t pages_init() +{ + uint32_t ret = NO_PAGES; + // The index of the page being initialized in m_pages[]. + uint16_t page = 0; + bool swap_set_but_not_found = false; + + for (uint16_t i = 0; i < FDS_VIRTUAL_PAGES; i++) + { + uint32_t const * const p_page_addr = fs_config.p_start_addr + (i * FDS_PAGE_SIZE); + fds_page_type_t const page_type = page_identify(p_page_addr); + + switch (page_type) + { + case FDS_PAGE_UNDEFINED: + if (page_is_erased(p_page_addr)) + { + if (m_swap_page.p_addr != NULL) + { + // If a swap page is already set, flag the page as erased (in m_pages) + // and try to tag it as data (in flash) later on during initialization. + m_pages[page].page_type = FDS_PAGE_ERASED; + m_pages[page].p_addr = p_page_addr; + m_pages[page].write_offset = FDS_PAGE_TAG_SIZE; + + // This is a candidate for a potential new swap page, in case the + // current swap is going to be promoted to complete a GC instance. + m_gc.cur_page = page; + page++; + } + else + { + // If there is no swap page yet, use this one. + m_swap_page.p_addr = p_page_addr; + m_swap_page.write_offset = FDS_PAGE_TAG_SIZE; + swap_set_but_not_found = true; + } + + ret |= PAGE_ERASED; + } + else + { + // Do not initialize or use this page. + m_pages[page++].page_type = FDS_PAGE_UNDEFINED; + } + break; + + case FDS_PAGE_DATA: + m_pages[page].page_type = FDS_PAGE_DATA; + m_pages[page].p_addr = p_page_addr; + // Scan the page to compute its write offset and determine whether or not the page + // can be garbage collected. Additionally, update the latest kwown record ID. + page_scan(p_page_addr, &m_pages[page].write_offset, &m_pages[page].can_gc); + + ret |= PAGE_DATA; + page++; + + break; + + case FDS_PAGE_SWAP: + if (swap_set_but_not_found) + { + m_pages[page].page_type = FDS_PAGE_ERASED; + m_pages[page].p_addr = m_swap_page.p_addr; + m_pages[page].write_offset = FDS_PAGE_TAG_SIZE; + + page++; + } + + m_swap_page.p_addr = p_page_addr; + // If the swap is promoted, this offset should be kept, otherwise, + // it should be set to FDS_PAGE_TAG_SIZE. + page_scan(p_page_addr, &m_swap_page.write_offset, NULL); + + ret |= (m_swap_page.write_offset == FDS_PAGE_TAG_SIZE) ? + PAGE_SWAP_CLEAN : PAGE_SWAP_DIRTY; + break; + + default: + // Shouldn't happen. + break; + } + } + + return (fds_init_opts_t)ret; +} + + +// Write the first part of a record header (the key and length). +static ret_code_t record_header_write_begin(fds_op_t * const p_op, uint32_t * const p_addr) +{ + ret_code_t ret; + ret = fs_store(&fs_config, p_addr + FDS_OFFSET_TL, + (uint32_t*)&p_op->write.header.tl, FDS_HEADER_SIZE_TL, NULL); + + // Write the record ID next. + p_op->write.step = FDS_OP_WRITE_RECORD_ID; + + return (ret == FS_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY; +} + + +static ret_code_t record_header_write_id(fds_op_t * const p_op, uint32_t * const p_addr) +{ + ret_code_t ret; + ret = fs_store(&fs_config, p_addr + FDS_OFFSET_ID, + (uint32_t*)&p_op->write.header.record_id, FDS_HEADER_SIZE_ID, NULL); + + // If this record has zero chunk, write the last part of the header directly. + // Otherwise, write the record chunks next. + p_op->write.step = (p_op->write.chunk_count != 0) ? FDS_OP_WRITE_CHUNKS : + FDS_OP_WRITE_HEADER_FINALIZE; + + return (ret == FS_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY; +} + + +static ret_code_t record_header_write_finalize(fds_op_t * const p_op, uint32_t * const p_addr) +{ + ret_code_t ret; + ret = fs_store(&fs_config, p_addr + FDS_OFFSET_IC, + (uint32_t*)&p_op->write.header.ic, FDS_HEADER_SIZE_IC, NULL); + + // If this is a simple write operation, then this is the last step. + // If this is an update instead, delete the old record next. + p_op->write.step = (p_op->op_code == FDS_OP_UPDATE) ? FDS_OP_WRITE_FLAG_DIRTY : + FDS_OP_WRITE_DONE; + + return (ret == FS_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY; +} + + +static ret_code_t record_header_flag_dirty(uint32_t * const p_record, uint16_t page_to_gc) +{ + // Flag the record as dirty. + fs_ret_t ret = fs_store(&fs_config, p_record, + (uint32_t*)&m_fds_tl_dirty, FDS_HEADER_SIZE_TL, NULL); + + if (ret != FS_SUCCESS) + { + return FDS_ERR_BUSY; + } + + m_pages[page_to_gc].can_gc = true; + + return FDS_SUCCESS; +} + + +static ret_code_t record_find_and_delete(fds_op_t * const p_op) +{ + ret_code_t ret; + uint16_t page; + fds_record_desc_t desc = {0}; + + desc.record_id = p_op->del.record_to_delete; + + if (record_find_by_desc(&desc, &page)) + { + fds_header_t const * const p_header = (fds_header_t const *)desc.p_record; + + // Copy the record key and file ID, so that they can be returned in the event. + // In case this function is run as part of an update, there is no need to copy + // the file ID and record key since they are present in the header stored + // in the queue element. + + p_op->del.file_id = p_header->ic.file_id; + p_op->del.record_key = p_header->tl.record_key; + + // Flag the record as dirty. + ret = record_header_flag_dirty((uint32_t*)desc.p_record, page); + } + else + { + // The record never existed, or it has already been deleted. + ret = FDS_ERR_NOT_FOUND; + } + + return ret; +} + + +// Finds a record within a file and flags it as dirty. +static ret_code_t file_find_and_delete(fds_op_t * const p_op) +{ + ret_code_t ret; + fds_record_desc_t desc; + + // This token must persist across calls. + static fds_find_token_t tok = {0}; + + // Pass NULL to ignore the record key. + ret = record_find(&p_op->del.file_id, NULL, &desc, &tok); + + if (ret == FDS_SUCCESS) + { + // A record was found: flag it as dirty. + ret = record_header_flag_dirty((uint32_t*)desc.p_record, tok.page); + } + else // FDS_ERR_NOT_FOUND + { + // No more records were found. Zero the token, so that it can be reused. + memset(&tok, 0x00, sizeof(fds_find_token_t)); + } + + return ret; +} + + +// Writes a record chunk to flash and advances the chunk queue. Additionally, decrements +// the number of chunks left to write for this operation and accumulates the offset. +static ret_code_t record_write_chunk(fds_op_t * const p_op, uint32_t * const p_addr) +{ + ret_code_t ret; + fds_record_chunk_t * p_chunk = NULL; + + // Retrieve the next chunk to be written. + chunk_queue_get_and_advance(&p_chunk); + + ret = fs_store(&fs_config, p_addr + p_op->write.chunk_offset, + p_chunk->p_data, p_chunk->length_words, NULL); + + // Accumulate the offset. + p_op->write.chunk_offset += p_chunk->length_words; + + // Decrement the number of chunks left to write. + // NOTE: If chunk_count is initially zero, this function is not called + // because this step is skipped entirely. See record_header_write_id(). + p_op->write.chunk_count--; + + if (p_op->write.chunk_count == 0) + { + // All record chunks have been written; write the last part of + // the record header to finalize the write operation. + p_op->write.step = FDS_OP_WRITE_HEADER_FINALIZE; + } + + return (ret == NRF_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY; +} + + +#if defined(FDS_CRC_ENABLED) + +static bool crc_verify_success(uint16_t crc, uint16_t len_words, uint32_t const * const p_data) +{ + uint16_t computed_crc; + + // The CRC is computed on the entire record, except the CRC field itself. + // The record header is 12 bytes, out of these we have to skip bytes 6 to 8 where the + // CRC itself is stored. Then we compute the CRC for the rest of the record, from byte 8 of + // the header (where the record ID begins) to the end of the record data. + computed_crc = crc16_compute((uint8_t const *)p_data, 6, NULL); + computed_crc = crc16_compute((uint8_t const *)p_data + 8, + (FDS_HEADER_SIZE_ID + len_words) * sizeof(uint32_t), + &computed_crc); + + return (computed_crc == crc); +} + +#endif + + +static void gc_init(void) +{ + m_gc.run_count++; + m_gc.cur_page = 0; + m_gc.resume = false; + + // Setup which pages to GC. Defer checking for open records and the can_gc flag, + // as other operations might change those while GC is running. + for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) + { + m_gc.do_gc_page[i] = (m_pages[i].page_type == FDS_PAGE_DATA); + } +} + + +// Obtain the next page to be garbage collected. +// Returns true if there are pages left to garbage collect, returns false otherwise. +static bool gc_page_next(uint16_t * const p_next_page) +{ + bool ret = false; + + for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) + { + if (m_gc.do_gc_page[i]) + { + // Do not attempt to GC this page again. + m_gc.do_gc_page[i] = false; + + // Only GC pages with no open records and with some records which have been deleted. + if ((m_pages[i].records_open == 0) && (m_pages[i].can_gc == true)) + { + *p_next_page = i; + ret = true; + break; + } + } + } + + return ret; +} + + +static ret_code_t gc_swap_erase(void) +{ + m_gc.state = GC_DISCARD_SWAP; + m_swap_page.write_offset = FDS_PAGE_TAG_SIZE; + + return fs_erase(&fs_config, m_swap_page.p_addr, FDS_PHY_PAGES_IN_VPAGE, NULL); +} + + +// Erase the page being garbage collected, or erase the swap in case there are any open +// records on the page being garbage collected. +static ret_code_t gc_page_erase(void) +{ + uint32_t ret; + uint16_t const gc = m_gc.cur_page; + + if (m_pages[gc].records_open == 0) + { + ret = fs_erase(&fs_config, m_pages[gc].p_addr, FDS_PHY_PAGES_IN_VPAGE, NULL); + m_gc.state = GC_ERASE_PAGE; + } + else + { + // If there are open records, stop garbage collection on this page. + // Discard the swap and try to garbage collect another page. + ret = gc_swap_erase(); + } + + return ret; +} + + +// Copy the current record to swap. +static ret_code_t gc_record_copy(void) +{ + fds_header_t const * const p_header = (fds_header_t*)m_gc.p_record_src; + uint32_t const * const p_dest = m_swap_page.p_addr + m_swap_page.write_offset; + uint16_t const record_len = FDS_HEADER_SIZE + p_header->tl.length_words; + + m_gc.state = GC_COPY_RECORD; + + // Copy the record to swap; it is guaranteed to fit in the destination page, + // so there is no need to check its size. This will either succeed or timeout. + return fs_store(&fs_config, p_dest, m_gc.p_record_src, record_len, NULL); +} + + +static ret_code_t gc_record_find_next(void) +{ + ret_code_t ret; + + // Find the next valid record to copy. + if (record_find_next(m_gc.cur_page, &m_gc.p_record_src)) + { + ret = gc_record_copy(); + } + else + { + // No more records left to copy on this page; swap pages. + ret = gc_page_erase(); + } + + return ret; +} + + +// Promote the swap by tagging it as a data page. +static ret_code_t gc_swap_promote(void) +{ + m_gc.state = GC_PROMOTE_SWAP; + return page_tag_write_data(m_pages[m_gc.cur_page].p_addr); +} + + +// Tag the page just garbage collected as swap. +static ret_code_t gc_tag_new_swap(void) +{ + m_gc.state = GC_TAG_NEW_SWAP; + m_gc.p_record_src = NULL; + return page_tag_write_swap(); +} + + +static ret_code_t gc_next_page(void) +{ + if (!gc_page_next(&m_gc.cur_page)) + { + // No pages left to GC; GC has terminated. Reset the state. + m_gc.state = GC_BEGIN; + m_gc.cur_page = 0; + m_gc.p_record_src = NULL; + + return FDS_OP_COMPLETED; + } + + return gc_record_find_next(); +} + + +// Update the swap page offeset after a record has been successfully copied to it. +static void gc_update_swap_offset(void) +{ + fds_header_t const * const p_header = (fds_header_t*)m_gc.p_record_src; + uint16_t const record_len = FDS_HEADER_SIZE + p_header->tl.length_words; + + m_swap_page.write_offset += record_len; +} + + +static void gc_swap_pages(void) +{ + // The page being garbage collected will be the new swap page, + // and the current swap will be used as a data page (promoted). + uint32_t const * const p_addr = m_swap_page.p_addr; + + m_swap_page.p_addr = m_pages[m_gc.cur_page].p_addr; + m_pages[m_gc.cur_page].p_addr = p_addr; + + // Keep the offset for this page, but reset it for the swap. + m_pages[m_gc.cur_page].write_offset = m_swap_page.write_offset; + m_swap_page.write_offset = FDS_PAGE_TAG_SIZE; +} + + +static void gc_state_advance(void) +{ + switch (m_gc.state) + { + case GC_BEGIN: + gc_init(); + m_gc.state = GC_NEXT_PAGE; + break; + + // A record was successfully copied. + case GC_COPY_RECORD: + gc_update_swap_offset(); + m_gc.state = GC_FIND_NEXT_RECORD; + break; + + // A page was successfully erased. Prepare to promote the swap. + case GC_ERASE_PAGE: + gc_swap_pages(); + m_gc.state = GC_PROMOTE_SWAP; + break; + + // Swap was discarded because the page being GC'ed had open records. + case GC_DISCARD_SWAP: + // Swap was sucessfully promoted. + case GC_PROMOTE_SWAP: + // Prepare to tag the page just GC'ed as swap. + m_gc.state = GC_TAG_NEW_SWAP; + break; + + case GC_TAG_NEW_SWAP: + m_gc.state = GC_NEXT_PAGE; + break; + + default: + // Should not happen. + break; + } +} + + +// Initialize the filesystem. +static ret_code_t init_execute(uint32_t prev_ret, fds_op_t * const p_op) +{ + ret_code_t ret = FDS_ERR_INTERNAL; + + if (prev_ret != FS_SUCCESS) + { + // A previous operation has timed out. + flag_clear(FDS_FLAG_INITIALIZING); + return FDS_ERR_OPERATION_TIMEOUT; + } + + switch (p_op->init.step) + { + case FDS_OP_INIT_TAG_SWAP: + // The page write offset was determined previously by pages_init(). + ret = page_tag_write_swap(); + p_op->init.step = FDS_OP_INIT_TAG_DATA; + break; + + case FDS_OP_INIT_TAG_DATA: + { + // Tag remaining erased pages as data. + bool write_reqd = false; + for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) + { + if (m_pages[i].page_type == FDS_PAGE_ERASED) + { + ret = page_tag_write_data(m_pages[i].p_addr); + m_pages[i].page_type = FDS_PAGE_DATA; + write_reqd = true; + break; + } + } + if (!write_reqd) + { + flag_set(FDS_FLAG_INITIALIZED); + flag_clear(FDS_FLAG_INITIALIZING); + return FDS_OP_COMPLETED; + } + } + break; + + case FDS_OP_INIT_ERASE_SWAP: + ret = fs_erase(&fs_config, m_swap_page.p_addr, FDS_PHY_PAGES_IN_VPAGE, NULL); + // If the swap is going to be discarded then reset its write_offset. + m_swap_page.write_offset = FDS_PAGE_TAG_SIZE; + p_op->init.step = FDS_OP_INIT_TAG_SWAP; + break; + + case FDS_OP_INIT_PROMOTE_SWAP: + { + // When promoting the swap, keep the write_offset set by pages_init(). + ret = page_tag_write_data(m_swap_page.p_addr); + + uint16_t const gc = m_gc.cur_page; + uint32_t const * const p_old_swap = m_swap_page.p_addr; + + // Execute the swap. + m_swap_page.p_addr = m_pages[gc].p_addr; + m_pages[gc].p_addr = p_old_swap; + + // Copy the offset from the swap to the new page. + m_pages[gc].write_offset = m_swap_page.write_offset; + m_swap_page.write_offset = FDS_PAGE_TAG_SIZE; + + m_pages[gc].page_type = FDS_PAGE_DATA; + p_op->init.step = FDS_OP_INIT_TAG_SWAP; + } + break; + + default: + // Should not happen. + break; + } + + if (ret != FDS_SUCCESS) + { + // fstorage queue was full. + flag_clear(FDS_FLAG_INITIALIZING); + return FDS_ERR_BUSY; + } + + return FDS_OP_EXECUTING; +} + + +// Executes write and update operations. +static ret_code_t write_execute(uint32_t prev_ret, fds_op_t * const p_op) +{ + ret_code_t ret; + uint32_t * p_write_addr; + fds_page_t * const p_page = &m_pages[p_op->write.page]; + + // This must persist across calls. + static fds_record_desc_t desc = {0}; + // When a record is updated, this variable will hold the page where the old + // copy was stored. This will be used to set the can_gc flag when the header is + // invalidated (FDS_OP_WRITE_FLAG_DIRTY). + static uint16_t page; + + if (prev_ret != FS_SUCCESS) + { + // The previous operation has timed out, update offsets. + page_offsets_update(p_page, p_op->write.header.tl.length_words); + return FDS_ERR_OPERATION_TIMEOUT; + } + + // Compute the address where to write data. + p_write_addr = (uint32_t*)(p_page->p_addr + p_page->write_offset); + + // Execute the current step of the operation, and set one to be executed next. + switch (p_op->write.step) + { + case FDS_OP_WRITE_FIND_RECORD: + { + // The first step of updating a record constists of locating the copy to be deleted. + // If the old copy couldn't be found for any reason then the update should fail. + // This prevents duplicates when queuing multiple updates of the same record. + desc.p_record = NULL; + desc.record_id = p_op->write.record_to_delete; + + if (!record_find_by_desc(&desc, &page)) + { + return FDS_ERR_NOT_FOUND; + } + // Setting the step is redundant since we are falling through. + } + // Fallthrough to FDS_OP_WRITE_HEADER_BEGIN. + + case FDS_OP_WRITE_HEADER_BEGIN: + ret = record_header_write_begin(p_op, p_write_addr); + break; + + case FDS_OP_WRITE_RECORD_ID: + ret = record_header_write_id(p_op, p_write_addr); + break; + + case FDS_OP_WRITE_CHUNKS: + ret = record_write_chunk(p_op, p_write_addr); + break; + + case FDS_OP_WRITE_HEADER_FINALIZE: + ret = record_header_write_finalize(p_op, p_write_addr); + break; + + case FDS_OP_WRITE_FLAG_DIRTY: + ret = record_header_flag_dirty((uint32_t*)desc.p_record, page); + p_op->write.step = FDS_OP_WRITE_DONE; + break; + + case FDS_OP_WRITE_DONE: + ret = FDS_OP_COMPLETED; + +#if defined(FDS_CRC_ENABLED) + if (flag_is_set(FDS_FLAG_VERIFY_CRC)) + { + if (!crc_verify_success(p_op->write.header.ic.crc16, + p_op->write.header.tl.length_words, + p_write_addr)) + { + ret = FDS_ERR_CRC_CHECK_FAILED; + } + } +#endif + break; + + default: + ret = FDS_ERR_INTERNAL; + break; + } + + // An operation has either completed or failed. It may have failed because fstorage + // ran out of memory, or because the user tried to delete a record which did not exist. + if (ret != FDS_OP_EXECUTING) + { + // There won't be another callback for this operation, so update the page offset now. + page_offsets_update(p_page, p_op->write.header.tl.length_words); + } + + return ret; +} + + +static ret_code_t delete_execute(uint32_t prev_ret, fds_op_t * const p_op) +{ + ret_code_t ret; + + if (prev_ret != FS_SUCCESS) + { + return FDS_ERR_OPERATION_TIMEOUT; + } + + switch (p_op->del.step) + { + case FDS_OP_DEL_RECORD_FLAG_DIRTY: + ret = record_find_and_delete(p_op); + p_op->del.step = FDS_OP_DEL_DONE; + break; + + case FDS_OP_DEL_FILE_FLAG_DIRTY: + ret = file_find_and_delete(p_op); + if (ret == FDS_ERR_NOT_FOUND) + { + // No more records could be found. + // There won't be another callback for this operation, so return now. + ret = FDS_OP_COMPLETED; + } + break; + + case FDS_OP_DEL_DONE: + ret = FDS_OP_COMPLETED; + break; + + default: + ret = FDS_ERR_INTERNAL; + break; + } + + return ret; +} + + +static ret_code_t gc_execute(uint32_t prev_ret) +{ + ret_code_t ret; + + if (prev_ret != FS_SUCCESS) + { + return FDS_ERR_OPERATION_TIMEOUT; + } + + if (m_gc.resume) + { + m_gc.resume = false; + } + else + { + gc_state_advance(); + } + + switch (m_gc.state) + { + case GC_NEXT_PAGE: + ret = gc_next_page(); + break; + + case GC_FIND_NEXT_RECORD: + ret = gc_record_find_next(); + break; + + case GC_COPY_RECORD: + ret = gc_record_copy(); + break; + + case GC_ERASE_PAGE: + ret = gc_page_erase(); + break; + + case GC_PROMOTE_SWAP: + ret = gc_swap_promote(); + break; + + case GC_TAG_NEW_SWAP: + ret = gc_tag_new_swap(); + break; + + default: + // Should not happen. + ret = FDS_ERR_INTERNAL; + break; + } + + // Either FDS_OP_EXECUTING, FDS_OP_COMPLETED, FDS_ERR_BUSY or FDS_ERR_INTERNAL. + return ret; +} + + +static void queue_process(fs_ret_t result) +{ + ret_code_t ret; + fds_op_t * const p_op = &m_op_queue.op[m_op_queue.rp]; + + switch (p_op->op_code) + { + case FDS_OP_INIT: + ret = init_execute(result, p_op); + break; + + case FDS_OP_WRITE: + case FDS_OP_UPDATE: + ret = write_execute(result, p_op); + break; + + case FDS_OP_DEL_RECORD: + case FDS_OP_DEL_FILE: + ret = delete_execute(result, p_op); + break; + + case FDS_OP_GC: + ret = gc_execute(result); + break; + + default: + ret = FDS_ERR_INTERNAL; + break; + } + + if (ret != FDS_OP_EXECUTING) + { + fds_evt_t evt; + + if (ret == FDS_OP_COMPLETED) + { + evt.result = FDS_SUCCESS; + } + else + { + // Either FDS_ERR_BUSY, FDS_ERR_OPERATION_TIMEOUT, + // FDS_ERR_CRC_CHECK_FAILED or FDS_ERR_NOT_FOUND. + evt.result = ret; + + // If this operation had any chunks in the queue, skip them. + chunk_queue_skip(p_op); + } + + event_prepare(p_op, &evt); + event_send(&evt); + + // Advance the queue, and if there are any queued operations, process them. + if (queue_advance()) + { + queue_process(FS_SUCCESS); + } + else + { + // No more elements in the queue. Clear the FDS_FLAG_PROCESSING flag, + // so that new operation can start processing the queue. + flag_clear(FDS_FLAG_PROCESSING); + } + } +} + + +static void queue_start(void) +{ + if (!flag_is_set(FDS_FLAG_PROCESSING)) + { + flag_set(FDS_FLAG_PROCESSING); + queue_process(FS_SUCCESS); + } +} + + +static void fs_event_handler(fs_evt_t const * const p_evt, fs_ret_t result) +{ + queue_process(result); +} + + +// Enqueues write and update operations. +static ret_code_t write_enqueue(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record, + fds_reserve_token_t const * const p_tok, + fds_op_code_t op_code) +{ + ret_code_t ret; + fds_op_t op; + uint16_t page; + uint16_t crc = 0; + uint16_t length_words = 0; + + if (!flag_is_set(FDS_FLAG_INITIALIZED)) + { + return FDS_ERR_NOT_INITIALIZED; + } + + if (p_record == NULL) + { + return FDS_ERR_NULL_ARG; + } + + if ((p_record->file_id == FDS_FILE_ID_INVALID) || + (p_record->key == FDS_RECORD_KEY_DIRTY)) + { + return FDS_ERR_INVALID_ARG; + } + + if (!chunk_is_aligned(p_record->data.p_chunks, + p_record->data.num_chunks)) + { + return FDS_ERR_UNALIGNED_ADDR; + } + + // No space was previously reserved for this operation. + if (p_tok == NULL) + { + // Compute the total length of the record. + for (uint32_t i = 0; i < p_record->data.num_chunks; i++) + { + length_words += p_record->data.p_chunks[i].length_words; + } + + // Find a page where to write data. + ret = write_space_reserve(length_words, &page); + + if (ret != FDS_SUCCESS) + { + // There is either not enough flash space available (FDS_ERR_NO_SPACE_IN_FLASH) or + // the record exceeds the virtual page size (FDS_ERR_RECORD_TOO_LARGE). + return ret; + } + } + else + { + page = p_tok->page; + length_words = p_tok->length_words; + } + + // Initialize the operation. + op.op_code = op_code; + op.write.step = FDS_OP_WRITE_HEADER_BEGIN; + op.write.page = page; + op.write.chunk_count = p_record->data.num_chunks; + op.write.chunk_offset = FDS_OFFSET_DATA; + op.write.header.record_id = record_id_new(); + op.write.header.ic.file_id = p_record->file_id; + op.write.header.tl.record_key = p_record->key; + op.write.header.tl.length_words = length_words; + + if (op_code == FDS_OP_UPDATE) + { + op.write.step = FDS_OP_WRITE_FIND_RECORD; + // Save the record ID of the record to be updated. + op.write.record_to_delete = p_desc->record_id; + } + +#if defined (FDS_CRC_ENABLED) + // First, compute the CRC for the first 6 bytes of the header which contain the + // record key, length and file ID, then, compute the CRC of the record ID (4 bytes). + crc = crc16_compute((uint8_t*)&op.write.header, 6, NULL); + crc = crc16_compute((uint8_t*)&op.write.header.record_id, 4, &crc); + + for (uint32_t i = 0; i < p_record->data.num_chunks; i++) + { + // Compute the CRC for the record data. + crc = crc16_compute((uint8_t*)p_record->data.p_chunks[i].p_data, + p_record->data.p_chunks[i].length_words * sizeof(uint32_t), &crc); + } +#endif + + op.write.header.ic.crc16 = crc; + + // Attempt to enqueue the operation. + if (!op_enqueue(&op, p_record->data.num_chunks, p_record->data.p_chunks)) + { + // No space availble in the queues. Cancel the reservation of flash space. + CRITICAL_SECTION_ENTER(); + write_space_free(length_words, page); + CRITICAL_SECTION_EXIT(); + + return FDS_ERR_NO_SPACE_IN_QUEUES; + } + + // Initialize the record descriptor, if provided. + if (p_desc != NULL) + { + p_desc->p_record = NULL; + // Don't invoke record_id_new() again ! + p_desc->record_id = op.write.header.record_id; + p_desc->record_is_open = false; + p_desc->gc_run_count = m_gc.run_count; + } + + // Start processing the queue, if necessary. + queue_start(); + + return FDS_SUCCESS; +} + + +ret_code_t fds_register(fds_cb_t cb) +{ + ret_code_t ret; + + CRITICAL_SECTION_ENTER(); + if (m_users == FDS_MAX_USERS) + { + ret = FDS_ERR_USER_LIMIT_REACHED; + } + else + { + m_cb_table[m_users] = cb; + m_users++; + + ret = FDS_SUCCESS; + } + CRITICAL_SECTION_EXIT(); + + return ret; +} + + +ret_code_t fds_init(void) +{ + fds_evt_t const evt_success = + { + .id = FDS_EVT_INIT, + .result = FDS_SUCCESS + }; + + // No initialization is necessary. Notify the application immediately. + if (flag_is_set(FDS_FLAG_INITIALIZED)) + { + event_send(&evt_success); + return FDS_SUCCESS; + } + + if (flag_is_set(FDS_FLAG_INITIALIZING)) + { + return FDS_SUCCESS; + } + + flag_set(FDS_FLAG_INITIALIZING); + + (void)fs_init(); + + // Initialize the page structure (m_pages), and determine which + // initialization steps are required given the current state of the filesystem. + fds_op_t op; + op.op_code = FDS_OP_INIT; + + fds_init_opts_t init_opts = pages_init(); + + switch (init_opts) + { + case NO_PAGES: + case NO_SWAP: + return FDS_ERR_NO_PAGES; + + case ALREADY_INSTALLED: + // No initialization is necessary. Notify the application immediately. + flag_set(FDS_FLAG_INITIALIZED); + flag_clear(FDS_FLAG_INITIALIZING); + event_send(&evt_success); + return FDS_SUCCESS; + + case FRESH_INSTALL: + case TAG_SWAP: + op.init.step = FDS_OP_INIT_TAG_SWAP; + break; + + case PROMOTE_SWAP: + case PROMOTE_SWAP_INST: + op.init.step = FDS_OP_INIT_PROMOTE_SWAP; + break; + + case DISCARD_SWAP: + op.init.step = FDS_OP_INIT_ERASE_SWAP; + break; + + case TAG_DATA: + case TAG_DATA_INST: + op.init.step = FDS_OP_INIT_TAG_DATA; + break; + + default: + // Should not happen. + break; + } + + // This cannot fail since it will be the first operation in the queue. + (void)op_enqueue(&op, 0, NULL); + + queue_start(); + + return FDS_SUCCESS; +} + + +ret_code_t fds_record_open(fds_record_desc_t * const p_desc, + fds_flash_record_t * const p_flash_rec) +{ + uint16_t page; + + if ((p_desc == NULL) || (p_flash_rec == NULL)) + { + return FDS_ERR_NULL_ARG; + } + + // Find the record if necessary. + if (record_find_by_desc(p_desc, &page)) + { + fds_header_t const * const p_header = (fds_header_t*)p_desc->p_record; + +#if defined(FDS_CRC_ENABLED) + if (!crc_verify_success(p_header->ic.crc16, + p_header->tl.length_words, + p_desc->p_record)) + { + return FDS_ERR_CRC_CHECK_FAILED; + } +#endif + + CRITICAL_SECTION_ENTER(); + m_pages[page].records_open++; + CRITICAL_SECTION_EXIT(); + + // Initialize p_flash_rec. + p_flash_rec->p_header = p_header; + p_flash_rec->p_data = (p_desc->p_record + FDS_HEADER_SIZE); + + // Set the record as open in the descriptor. + p_desc->record_is_open = true; + + return FDS_SUCCESS; + } + + // The record could not be found. + // It either never existed or it has been deleted. + return FDS_ERR_NOT_FOUND; +} + + +ret_code_t fds_record_close(fds_record_desc_t * const p_desc) +{ + ret_code_t ret; + uint16_t page; + + if (p_desc == NULL) + { + return FDS_ERR_NULL_ARG; + } + + if (record_find_by_desc((fds_record_desc_t*)p_desc, &page)) + { + CRITICAL_SECTION_ENTER(); + if ((m_pages[page].records_open > 0) && (p_desc->record_is_open)) + { + + m_pages[page].records_open--; + p_desc->record_is_open = false; + + ret = FDS_SUCCESS; + } + else + { + ret = FDS_ERR_NO_OPEN_RECORDS; + } + CRITICAL_SECTION_EXIT(); + } + else + { + ret = FDS_ERR_NOT_FOUND; + } + + return ret; +} + + +ret_code_t fds_reserve(fds_reserve_token_t * const p_tok, uint16_t length_words) +{ + ret_code_t ret; + uint16_t page; + + if (!flag_is_set(FDS_FLAG_INITIALIZED)) + { + return FDS_ERR_NOT_INITIALIZED; + } + + if (p_tok == NULL) + { + return FDS_ERR_NULL_ARG; + } + + ret = write_space_reserve(length_words, &page); + + if (ret == FDS_SUCCESS) + { + p_tok->page = page; + p_tok->length_words = length_words; + } + + return ret; +} + + +ret_code_t fds_reserve_cancel(fds_reserve_token_t * const p_tok) +{ + ret_code_t ret; + + if (!flag_is_set(FDS_FLAG_INITIALIZED)) + { + return FDS_ERR_NOT_INITIALIZED; + } + + if (p_tok == NULL) + { + return FDS_ERR_NULL_ARG; + } + + if (p_tok->page > FDS_MAX_PAGES) + { + // The page does not exist. This shouldn't happen. + return FDS_ERR_INVALID_ARG; + } + + fds_page_t const * const p_page = &m_pages[p_tok->page]; + + CRITICAL_SECTION_ENTER(); + if (p_page->words_reserved - (FDS_HEADER_SIZE + p_tok->length_words) >= 0) + { + // Free reserved space. + write_space_free(p_tok->length_words, p_tok->page); + + // Clean the token. + p_tok->page = 0; + p_tok->length_words = 0; + ret = FDS_SUCCESS; + } + else + { + // We are trying to cancel a reservation of more words than how many are + // currently reserved on the page. Clearly, this shouldn't happen. + ret = FDS_ERR_INVALID_ARG; + } + CRITICAL_SECTION_EXIT(); + + return ret; +} + + +ret_code_t fds_record_write(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record) +{ + return write_enqueue(p_desc, p_record, NULL, FDS_OP_WRITE); +} + + +ret_code_t fds_record_write_reserved(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record, + fds_reserve_token_t const * const p_tok) +{ + // A NULL token is not allowed when writing to a reserved space. + if (p_tok == NULL) + { + return FDS_ERR_NULL_ARG; + } + + return write_enqueue(p_desc, p_record, p_tok, FDS_OP_WRITE); +} + + +ret_code_t fds_record_update(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record) +{ + // A NULL descriptor is not allowed when updating a record. + if (p_desc == NULL) + { + return FDS_ERR_NULL_ARG; + } + + return write_enqueue(p_desc, p_record, NULL, FDS_OP_UPDATE); +} + + +ret_code_t fds_record_delete(fds_record_desc_t * const p_desc) +{ + fds_op_t op; + + if (!flag_is_set(FDS_FLAG_INITIALIZED)) + { + return FDS_ERR_NOT_INITIALIZED; + } + + if (p_desc == NULL) + { + return FDS_ERR_NULL_ARG; + } + + op.op_code = FDS_OP_DEL_RECORD; + op.del.step = FDS_OP_DEL_RECORD_FLAG_DIRTY; + op.del.record_to_delete = p_desc->record_id; + + if (op_enqueue(&op, 0, NULL)) + { + queue_start(); + return FDS_SUCCESS; + } + + return FDS_ERR_NO_SPACE_IN_QUEUES; +} + + +ret_code_t fds_file_delete(uint16_t file_id) +{ + fds_op_t op; + + if (!flag_is_set(FDS_FLAG_INITIALIZED)) + { + return FDS_ERR_NOT_INITIALIZED; + } + + if (file_id == FDS_FILE_ID_INVALID) + { + return FDS_ERR_INVALID_ARG; + } + + op.op_code = FDS_OP_DEL_FILE; + op.del.step = FDS_OP_DEL_FILE_FLAG_DIRTY; + op.del.file_id = file_id; + + if (op_enqueue(&op, 0, NULL)) + { + queue_start(); + return FDS_SUCCESS; + } + + return FDS_ERR_NO_SPACE_IN_QUEUES; +} + + +ret_code_t fds_gc(void) +{ + fds_op_t op; + + if (!flag_is_set(FDS_FLAG_INITIALIZED)) + { + return FDS_ERR_NOT_INITIALIZED; + } + + op.op_code = FDS_OP_GC; + + if (op_enqueue(&op, 0, NULL)) + { + if (m_gc.state != GC_BEGIN) + { + // Resume GC by retrying the last step. + m_gc.resume = true; + } + + queue_start(); + return FDS_SUCCESS; + } + + return FDS_ERR_NO_SPACE_IN_QUEUES; +} + + +ret_code_t fds_record_iterate(fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token) +{ + return record_find(NULL, NULL, p_desc, p_token); +} + + +ret_code_t fds_record_find(uint16_t file_id, + uint16_t record_key, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token) +{ + return record_find(&file_id, &record_key, p_desc, p_token); +} + + +ret_code_t fds_record_find_by_key(uint16_t record_key, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token) +{ + return record_find(NULL, &record_key, p_desc, p_token); +} + + +ret_code_t fds_record_find_in_file(uint16_t file_id, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token) +{ + return record_find(&file_id, NULL, p_desc, p_token); +} + + +ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc, + uint32_t record_id) +{ + if (p_desc == NULL) + { + return FDS_ERR_NULL_ARG; + } + + // Zero the descriptor and set the record_id field. + memset(p_desc, 0x00, sizeof(fds_record_desc_t)); + p_desc->record_id = record_id; + + return FDS_SUCCESS; +} + + +ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc, + uint32_t * const p_record_id) +{ + if ((p_desc == NULL) || (p_record_id == NULL)) + { + return FDS_ERR_NULL_ARG; + } + + *p_record_id = p_desc->record_id; + + return FDS_SUCCESS; +} + + +ret_code_t fds_stat(fds_stat_t * const p_stat) +{ + uint16_t const words_in_page = FDS_PAGE_SIZE; + // The largest number of free contiguous words on any page. + uint16_t contig_words = 0; + + if (!flag_is_set(FDS_FLAG_INITIALIZED)) + { + return FDS_ERR_NOT_INITIALIZED; + } + + if (p_stat == NULL) + { + return FDS_ERR_NULL_ARG; + } + + memset(p_stat, 0x00, sizeof(fds_stat_t)); + + for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) + { + uint32_t const * p_record = NULL; + uint16_t const words_used = m_pages[i].write_offset + m_pages[i].words_reserved; + + p_stat->open_records += m_pages[i].records_open; + p_stat->words_reserved += m_pages[i].words_reserved; + p_stat->words_used += words_used; + contig_words = (words_in_page - words_used); + + if (contig_words > p_stat->largest_contig) + { + p_stat->largest_contig = contig_words; + } + + while (record_find_next(i, &p_record)) + { + p_stat->valid_records++; + } + + dirty_records_stat(i, &p_stat->dirty_records, &p_stat->freeable_words); + } + + return FDS_SUCCESS; +} + + +#if defined(FDS_CRC_ENABLED) + +ret_code_t fds_verify_crc_on_writes(bool enable) +{ + if (enable) + { + flag_set(FDS_FLAG_VERIFY_CRC); + } + else + { + flag_clear(FDS_FLAG_VERIFY_CRC); + } + + return FDS_SUCCESS; +} + +#endif +#endif //NRF_MODULE_ENABLED(FDS) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fds/fds.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fds/fds.h new file mode 100644 index 0000000000000000000000000000000000000000..898906aca6fe30944f3538ad80b8f03b83c104fe --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fds/fds.h @@ -0,0 +1,760 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef FDS_H__ +#define FDS_H__ + +/** + * @defgroup fds Flash Data Storage + * @ingroup app_common + * @{ + * + * @brief Flash Data Storage (FDS). + * + * @details Flash Data Storage is a minimalistic, record-oriented file system for the on-chip + * flash. Files are stored as a collection of records of variable length. FDS supports + * synchronous read operations and asynchronous write operations (write, update, + * and delete). FDS can be used from multiple threads. + */ + +#include +#include +#include "sdk_errors.h" +#include "app_util_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Invalid file ID. + * + * This value must not be used as a file ID by the application. + */ +#define FDS_FILE_ID_INVALID (0xFFFF) + + +/**@brief Record key for deleted records. + * + * This key is used to flag a record as "dirty", which means that it should be removed during + * the next garbage collection. This value must not be used as a record key by the application. + */ +#define FDS_RECORD_KEY_DIRTY (0x0000) + + +/**@brief FDS return values. + */ +enum +{ + FDS_SUCCESS = NRF_SUCCESS, //!< The operation completed successfully. + FDS_ERR_OPERATION_TIMEOUT, //!< Error. The operation timed out. + FDS_ERR_NOT_INITIALIZED, //!< Error. The module has not been initialized. + FDS_ERR_UNALIGNED_ADDR, //!< Error. The input data is not aligned to a word boundary. + FDS_ERR_INVALID_ARG, //!< Error. The parameter contains invalid data. + FDS_ERR_NULL_ARG, //!< Error. The parameter is NULL. + FDS_ERR_NO_OPEN_RECORDS, //!< Error. The record is not open, so it cannot be closed. + FDS_ERR_NO_SPACE_IN_FLASH, //!< Error. There is no space in flash memory. + FDS_ERR_NO_SPACE_IN_QUEUES, //!< Error. There is no space in the internal queues. + FDS_ERR_RECORD_TOO_LARGE, //!< Error. The record exceeds the maximum allowed size. + FDS_ERR_NOT_FOUND, //!< Error. The record was not found. + FDS_ERR_NO_PAGES, //!< Error. No flash pages are available. + FDS_ERR_USER_LIMIT_REACHED, //!< Error. The maximum number of users has been reached. + FDS_ERR_CRC_CHECK_FAILED, //!< Error. The CRC check failed. + FDS_ERR_BUSY, //!< Error. The underlying flash subsystem was busy. + FDS_ERR_INTERNAL, //!< Error. An internal error occurred. +}; + + +/**@brief Part of the record metadata. + * + * Contains the record key and the length of the record data. + */ +typedef struct +{ + uint16_t record_key; //!< The record key (must be in the range 0x0001 - 0xBFFF). + uint16_t length_words; //!< The length of the record data (in 4-byte words). +} fds_tl_t; + + +/**@brief Part of the record metadata. + * + * Contains the ID of the file that the record belongs to and the CRC16 check value of the record. + */ +typedef struct +{ + uint16_t file_id; //!< The ID of the file that the record belongs to. + + /**@brief CRC16 check value. + * + * The CRC is calculated over the entire record as stored in flash (including the record + * metadata except the CRC field itself). The CRC standard employed is CRC-16-CCITT. + */ + uint16_t crc16; +} fds_ic_t; + + +/**@brief The record metadata as stored in flash. + */ +typedef struct +{ + fds_tl_t tl; //!< See @ref fds_tl_t. + fds_ic_t ic; //!< See @ref fds_ic_t. + uint32_t record_id; //!< The unique record ID (32 bits). +} fds_header_t; + + +/**@brief The record descriptor structure that is used to manipulate records. + * + * This structure is used by the FDS module. You must provide the descriptor to the module when + * you manipulate existing records. However, you should never modify it or use any of its fields. + * + * @note Never reuse the same descriptor for different records. + */ +typedef struct +{ + uint32_t record_id; //!< The unique record ID. + uint32_t const * p_record; //!< The last known location of the record in flash. + uint16_t gc_run_count; //!< Number of times garbage collection has been run. + bool record_is_open; //!< Whether the record is currently open. +} fds_record_desc_t; + + +/**@brief Structure that can be used to read the contents of a record stored in flash. + * + * This structure does not reflect the physical layout of a record in flash, but it points + * to the locations where the record header (metadata) and the record data are stored. + */ +typedef struct +{ + fds_header_t const * p_header; //!< Location of the record header in flash. + void const * p_data; //!< Location of the record data in flash. +} fds_flash_record_t; + + +/**@brief A chunk of record data to be written to flash. + * + * @p p_data must be aligned to a word boundary. Make sure to keep it in + * memory until the operation has completed, which is indicated by the respective FDS event. + */ +typedef struct +{ + void const * p_data; //!< Pointer to the data to store. Must be word-aligned. + uint16_t length_words; //!< Length of data pointed to by @p p_data (in 4-byte words). +} fds_record_chunk_t; + + +/**@brief A record to be written to flash. + */ +typedef struct +{ + uint16_t file_id; //!< The ID of the file that the record belongs to. + uint16_t key; //!< The record key. + struct + { + fds_record_chunk_t const * p_chunks; //!< The chunks that make up the record data. + uint16_t num_chunks; //!< The number of chunks that make up the data. + } data; +} fds_record_t; + + +/**@brief A token to a reserved space in flash, created by @ref fds_reserve. + * + * This token can be used to write the record in the reserved space (@ref fds_record_write_reserved) + * or to cancel the reservation (@ref fds_reserve_cancel). + */ +typedef struct +{ + uint16_t page; //!< The logical ID of the page where space was reserved. + uint16_t length_words; //!< The amount of space reserved (in 4-byte words). +} fds_reserve_token_t; + + +/**@brief A token to keep information about the progress of @ref fds_record_find, + * @ref fds_record_find_by_key, and @ref fds_record_find_in_file. + * + * @note Always zero-initialize the token before using it for the first time. + * @note Never reuse the same token to search for different records. + */ +typedef struct +{ + uint32_t const * p_addr; + uint16_t page; +} fds_find_token_t; + + +/**@brief FDS event IDs. + */ +typedef enum +{ + FDS_EVT_INIT, //!< Event for @ref fds_init. + FDS_EVT_WRITE, //!< Event for @ref fds_record_write and @ref fds_record_write_reserved. + FDS_EVT_UPDATE, //!< Event for @ref fds_record_update. + FDS_EVT_DEL_RECORD, //!< Event for @ref fds_record_delete. + FDS_EVT_DEL_FILE, //!< Event for @ref fds_file_delete. + FDS_EVT_GC //!< Event for @ref fds_gc. +} fds_evt_id_t; + + +ANON_UNIONS_ENABLE + +/**@brief An FDS event. + */ +typedef struct +{ + fds_evt_id_t id; //!< The event ID. See @ref fds_evt_id_t. + ret_code_t result; //!< The result of the operation related to this event. + union + { + struct + { + /* Currently not used. */ + uint16_t pages_not_mounted; + } init; + struct + { + uint32_t record_id; + uint16_t file_id; + uint16_t record_key; + bool is_record_updated; + } write; //!< Information for @ref FDS_EVT_WRITE and @ref FDS_EVT_UPDATE events. + struct + { + uint32_t record_id; + uint16_t file_id; + uint16_t record_key; + uint16_t records_deleted_count; + } del; //!< Information for @ref FDS_EVT_DEL_RECORD and @ref FDS_EVT_DEL_FILE events. + struct + { + /* Currently not used. */ + uint16_t pages_skipped; + uint16_t space_reclaimed; + } gc; + }; +} fds_evt_t; + +ANON_UNIONS_DISABLE + + +/**@brief File system statistics. */ +typedef struct +{ + uint16_t open_records; //!< The number of open records. + uint16_t valid_records; //!< The number of valid records. + uint16_t dirty_records; //!< The number of deleted ("dirty") records. + uint16_t words_reserved; //!< The number of words reserved by @ref fds_reserve(). + + /**@brief The number of words written to flash, including those reserved for future writes. + */ + uint16_t words_used; + + /**@brief The largest number of free contiguous words in the file system. + * + * This number determines the largest record that can be stored by FDS. + * It takes into account all reservations for future writes. + */ + uint16_t largest_contig; + + /**@brief The largest number of words that can be reclaimed by garbage collection. + * + * The actual amount of space freed by garbage collection might be less than this value if + * records are open while garbage collection is run. + */ + uint16_t freeable_words; +} fds_stat_t; + + +/**@brief FDS event handler function prototype. + * + * @param p_evt The event. + */ +typedef void (*fds_cb_t)(fds_evt_t const * const p_evt); + + +/**@brief Function for registering an FDS event handler. + * + * The maximum amount of handlers that can be registered can be configured by changing the value + * of @ref FDS_MAX_USERS in fds_config.h. + * + * @param[in] cb The event handler function. + * + * @retval FDS_SUCCESS If the event handler was registered successfully. + * @retval FDS_ERR_USER_LIMIT_REACHED If the maximum number of registered callbacks is reached. + */ +ret_code_t fds_register(fds_cb_t cb); + + +/**@brief Function for initializing the module. + * + * This function initializes the module and installs the file system (unless it is installed + * already). + * + * This function is asynchronous. Completion is reported through an event. Make sure to call + * @ref fds_register before calling @ref fds_init so that you receive the completion event. + * + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NO_PAGES If there is no space available in flash memory to install the + * file system. + */ +ret_code_t fds_init(void); + + +/**@brief Function for writing a record to flash. + * + * There are no restrictions on the file ID and the record key, except that the record key must be + * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from + * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of + * the file ID or the record key. All records with the same file ID are grouped into one file. + * If no file with the specified ID exists, it is created. There can be multiple records with the + * same record key in a file. + * + * Some modules need exclusive use of certain file IDs and record keys. See @ref lib_fds_functionality_keys + * for details. + * + * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and + * because it is not buffered internally, it must be kept in memory until the callback for the + * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE + * words minus 14 bytes. + * + * This function is asynchronous. Completion is reported through an event that is sent to + * the registered event handler function. + * + * @param[out] p_desc The descriptor of the record that was written. Pass NULL if you do not + * need the descriptor. + * @param[in] p_record The record to be written to flash. + * + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_record is NULL. + * @retval FDS_ERR_INVALID_ARG If the file ID or the record key is invalid. + * @retval FDS_ERR_UNALIGNED_ADDR If the record data is not aligned to a 4 byte boundary. + * @retval FDS_ERR_RECORD_TOO_LARGE If the record data exceeds the maximum length. + * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full or there are more record + * chunks than can be buffered. + * @retval FDS_ERR_NO_SPACE_IN_FLASH If there is not enough free space in flash to store the + * record. + */ +ret_code_t fds_record_write(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record); + + +/**@brief Function for reserving space in flash. + * + * This function can be used to reserve space in flash memory. To write a record into the reserved + * space, use @ref fds_record_write_reserved. Alternatively, use @ref fds_reserve_cancel to cancel + * a reservation. + * + * Note that this function does not write any data to flash. + * + * @param[out] p_token A token that can be used to write a record in the reserved space or + * cancel the reservation. + * @param[in] length_words The length of the record data (in 4-byte words). + * + * @retval FDS_SUCCESS If the flash space was reserved successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_token is NULL instead of a valid token address. + * @retval FDS_ERR_RECORD_TOO_LARGE If the record length exceeds the maximum length. + * @retval FDS_ERR_NO_SPACE_IN_FLASH If there is not enough free space in flash to store the + * record. + */ +ret_code_t fds_reserve(fds_reserve_token_t * const p_token, uint16_t length_words); + + +/**@brief Function for canceling an @ref fds_reserve operation. + * + * @param[in] p_token The token that identifies the reservation, produced by @ref fds_reserve. + * + * @retval FDS_SUCCESS If the reservation was canceled. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_token is NULL instead of a valid token address. + * @retval FDS_ERR_INVALID_ARG If @p p_token contains invalid data. + */ +ret_code_t fds_reserve_cancel(fds_reserve_token_t * const p_token); + + +/**@brief Function for writing a record to a space in flash that was reserved using + * @ref fds_reserve. + * + * There are no restrictions on the file ID and the record key, except that the record key must be + * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from + * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of + * the file ID or the record key. All records with the same file ID are grouped into one file. + * If no file with the specified ID exists, it is created. There can be multiple records with the + * same record key in a file. + * + * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and + * because it is not buffered internally, it must be kept in memory until the callback for the + * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE + * words minus 14 bytes. + * + * This function is asynchronous. Completion is reported through an event that is sent to the + * registered event handler function. + * + * @note + * This function behaves similarly to @ref fds_record_write, with the exception that it never + * fails with the error @ref FDS_ERR_NO_SPACE_IN_FLASH. + * + * @param[out] p_desc The descriptor of the record that was written. Pass NULL if you do not + * need the descriptor. + * @param[in] p_record The record to be written to flash. + * @param[in] p_token The token that identifies the space reserved in flash. + * + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_token is NULL instead of a valid token address. + * @retval FDS_ERR_INVALID_ARG If the file ID or the record key is invalid. + * @retval FDS_ERR_UNALIGNED_ADDR If the record data is not aligned to a 4 byte boundary. + * @retval FDS_ERR_RECORD_TOO_LARGE If the record data exceeds the maximum length. + * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full or there are more record + * chunks than can be buffered. + */ +ret_code_t fds_record_write_reserved(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record, + fds_reserve_token_t const * const p_token); + + +/**@brief Function for deleting a record. + * + * Deleted records cannot be located using @ref fds_record_find, @ref fds_record_find_by_key, or + * @ref fds_record_find_in_file. Additionally, they can no longer be opened using + * @ref fds_record_open. + * + * Note that deleting a record does not free the space it occupies in flash memory. + * To reclaim flash space used by deleted records, call @ref fds_gc to run garbage collection. + * + * This function is asynchronous. Completion is reported through an event that is sent to the + * registered event handler function. + * + * @param[in] p_desc The descriptor of the record that should be deleted. + * + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If the specified record descriptor @p p_desc is NULL. + * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full. + */ +ret_code_t fds_record_delete(fds_record_desc_t * const p_desc); + + +/**@brief Function for deleting all records in a file. + * + * This function deletes a file, including all its records. Deleted records cannot be located + * using @ref fds_record_find, @ref fds_record_find_by_key, or @ref fds_record_find_in_file. + * Additionally, they can no longer be opened using @ref fds_record_open. + * + * Note that deleting records does not free the space they occupy in flash memory. + * To reclaim flash space used by deleted records, call @ref fds_gc to run garbage collection. + * + * This function is asynchronous. Completion is reported through an event that is sent to the + * registered event handler function. + * + * @param[in] file_id The ID of the file to be deleted. + * + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_INVALID_ARG If the specified @p file_id is invalid. + * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full. + */ +ret_code_t fds_file_delete(uint16_t file_id); + + +/**@brief Function for updating a record. + * + * Updating a record first writes a new record (@p p_record) to flash and then deletes the + * old record (identified by @p p_desc). + * + * There are no restrictions on the file ID and the record key, except that the record key must be + * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from + * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of + * the file ID or the record key. All records with the same file ID are grouped into one file. + * If no file with the specified ID exists, it is created. There can be multiple records with the + * same record key in a file. + * + * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and + * because it is not buffered internally, it must be kept in memory until the callback for the + * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE + * words minus 14 bytes. + * + * This function is asynchronous. Completion is reported through an event that is sent to the + * registered event handler function. + * + * @param[in, out] p_desc The descriptor of the record to update. When the function + * returns with FDS_SUCCESS, this parameter contains the + * descriptor of the newly written record. + * @param[in] p_record The updated record to be written to flash. + * + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_INVALID_ARG If the file ID or the record key is invalid. + * @retval FDS_ERR_UNALIGNED_ADDR If the record data is not aligned to a 4 byte boundary. + * @retval FDS_ERR_RECORD_TOO_LARGE If the record data exceeds the maximum length. + * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full or there are more record + * chunks than can be buffered. + * @retval FDS_ERR_NO_SPACE_IN_FLASH If there is not enough free space in flash to store the + * updated record. + */ +ret_code_t fds_record_update(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record); + + +/**@brief Function for iterating through all records in flash. + * + * To search for the next record, call the function again and supply the same @ref fds_find_token_t + * structure to resume searching from the last record that was found. + * + * Note that the order with which records are iterated is not defined. + * + * @param[out] p_desc The descriptor of the record that was found. + * @param[out] p_token A token containing information about the progress of the operation. + * + * @retval FDS_SUCCESS If a record was found. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL. + * @retval FDS_ERR_NOT_FOUND If no matching record was found. + */ +ret_code_t fds_record_iterate(fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token); + + +/**@brief Function for searching for records with a given record key in a file. + * + * This function finds the first record in a file that has the given record key. To search for the + * next record with the same key in the file, call the function again and supply the same + * @ref fds_find_token_t structure to resume searching from the last record that was found. + * + * @param[in] file_id The file ID. + * @param[in] record_key The record key. + * @param[out] p_desc The descriptor of the record that was found. + * @param[out] p_token A token containing information about the progress of the operation. + * + * @retval FDS_SUCCESS If a record was found. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL. + * @retval FDS_ERR_NOT_FOUND If no matching record was found. + */ +ret_code_t fds_record_find(uint16_t file_id, + uint16_t record_key, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token); + + +/**@brief Function for searching for records with a given record key. + * + * This function finds the first record with a given record key, independent of the file it + * belongs to. To search for the next record with the same key, call the function again and supply + * the same @ref fds_find_token_t structure to resume searching from the last record that was found. + * + * @param[in] record_key The record key. + * @param[out] p_desc The descriptor of the record that was found. + * @param[out] p_token A token containing information about the progress of the operation. + * + * @retval FDS_SUCCESS If a record was found. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL. + * @retval FDS_ERR_NOT_FOUND If no record with the given key was found. + */ +ret_code_t fds_record_find_by_key(uint16_t record_key, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token); + + +/**@brief Function for searching for any record in a file. + * + * This function finds the first record in a file, independent of its record key. + * To search for the next record in the same file, call the function again and supply the same + * @ref fds_find_token_t structure to resume searching from the last record that was found. + * + * @param[in] file_id The file ID. + * @param[out] p_desc The descriptor of the record that was found. + * @param[out] p_token A token containing information about the progress of the operation. + * + * @retval FDS_SUCCESS If a record was found. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL. + * @retval FDS_ERR_NOT_FOUND If no matching record was found. + */ +ret_code_t fds_record_find_in_file(uint16_t file_id, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token); + + +/**@brief Function for opening a record for reading. + * + * This function opens a record that is stored in flash, so that it can be read. The function + * initializes an @ref fds_flash_record_t structure, which can be used to access the record data as + * well as its associated metadata. The pointers provided in the @ref fds_flash_record_t structure + * are pointers to flash memory. + * + * Opening a record with @ref fds_record_open prevents garbage collection to run on the virtual + * flash page in which record is stored, so that the contents of the memory pointed by fields in + * @ref fds_flash_record_t are guaranteed to remain unmodified as long as the record is kept open. + * + * When you are done reading a record, call @ref fds_record_close to close it. Garbage collection + * can then reclaim space on the virtual page where the record is stored. Note that you must + * provide the same descriptor for @ref fds_record_close as you did for this function. + * + * @param[in] p_desc The descriptor of the record to open. + * @param[out] p_flash_record The record, as stored in flash. + * + * @retval FDS_SUCCESS If the record was opened successfully. + * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_flash_record is NULL. + * @retval FDS_ERR_NOT_FOUND If the record was not found. It might have been deleted, or + * it might not have been written yet. + * @retval FDS_ERR_CRC_CHECK_FAILED If the CRC check for the record failed. + */ +ret_code_t fds_record_open(fds_record_desc_t * const p_desc, + fds_flash_record_t * const p_flash_record); + + +/**@brief Function for closing a record. + * + * Closing a record allows garbage collection to run on the virtual page in which the record is + * stored (if no other records remain open on that page). The descriptor passed as an argument + * must be the same as the one used to open the record using @ref fds_record_open. + * + * Note that closing a record does not invalidate its descriptor. You can still supply the + * descriptor to all functions that accept a record descriptor as a parameter. + * + * @param[in] p_desc The descriptor of the record to close. + * + * @retval FDS_SUCCESS If the record was closed successfully. + * @retval FDS_ERR_NULL_ARG If @p p_desc is NULL. + * @retval FDS_ERR_NO_OPEN_RECORDS If the record is not open. + * @retval FDS_ERR_NOT_FOUND If the record could not be found. + */ +ret_code_t fds_record_close(fds_record_desc_t * const p_desc); + + +/**@brief Function for running garbage collection. + * + * Garbage collection reclaims the flash space that is occupied by records that have been deleted, + * or that failed to be completely written due to, for example, a power loss. + * + * This function is asynchronous. Completion is reported through an event that is sent to the + * registered event handler function. + * + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full. + */ +ret_code_t fds_gc(void); + + +/**@brief Function for obtaining a descriptor from a record ID. + * + * This function can be used to reconstruct a descriptor from a record ID, like the one that is + * passed to the callback function. + * + * @note + * This function does not check whether a record with the given record ID exists. + * If a non-existing record ID is supplied, the resulting descriptor is invalid and will cause + * other functions to fail when it is supplied as parameter. + * + * @param[out] p_desc The descriptor of the record with the given record ID. + * @param[in] record_id The record ID for which a descriptor should be returned. + * + * @retval FDS_SUCCESS If a descriptor was returned. + * @retval FDS_ERR_NULL_ARG If @p p_desc is NULL. + */ +ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc, + uint32_t record_id); + + +/**@brief Function for obtaining a record ID from a record descriptor. + * + * This function can be used to extract a record ID from a descriptor. For example, you could use + * it in the callback function to compare the record ID of an event to the record IDs of the + * records for which you have a descriptor. + * + * @warning + * This function does not check whether the record descriptor is valid. If the descriptor is not + * initialized or has been tampered with, the resulting record ID might be invalid. + * + * @param[in] p_desc The descriptor from which the record ID should be extracted. + * @param[out] p_record_id The record ID that is contained in the given descriptor. + * + * @retval FDS_SUCCESS If a record ID was returned. + * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_record_id is NULL. + */ +ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc, + uint32_t * const p_record_id); + + +/**@brief Function for retrieving file system statistics. + * + * This function retrieves file system statistics, such as the number of open records, the space + * that can be reclaimed by garbage collection, and others. + * + * @param[out] p_stat File system statistics. + * + * @retval FDS_SUCCESS If the statistics were returned successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_stat is NULL. + */ +ret_code_t fds_stat(fds_stat_t * const p_stat); + + +#if defined(FDS_CRC_ENABLED) + +/**@brief Function for enabling and disabling CRC verification for write operations. + * + * CRC verification ensures that data that is queued for writing does not change before the write + * actually happens. Use this function to enable or disable CRC verification. If verification is + * enabled, the error @ref FDS_ERR_CRC_CHECK_FAILED is returned in the event for + * @ref fds_record_write, @ref fds_record_write_reserved, or @ref fds_record_update if + * verification fails. + * + * @note + * CRC verification is enabled or disabled globally, thus for all users of the FDS module. + * + * @param[in] enabled 1 to enable CRC verification. 0 to disable CRC verification. + * + * @retval FDS_SUCCESS If CRC verification was enabled or disabled successfully. + */ +ret_code_t fds_verify_crc_on_writes(bool enabled); + +#endif + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif // FDS_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fds/fds_internal_defs.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fds/fds_internal_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..5ffc3259eac77ab41c9623971bbf68f3567193ec --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fds/fds_internal_defs.h @@ -0,0 +1,344 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef FDS_INTERNAL_DEFS_H__ +#define FDS_INTERNAL_DEFS_H__ +#include "sdk_config.h" +#include +#include + +#if defined (FDS_THREADS) + #include "nrf_soc.h" + #include "app_util_platform.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define FDS_PAGE_TAG_SIZE (2) // Page tag size, in 4-byte words. +#define FDS_PAGE_TAG_WORD_0 (0) // Offset of the first word in the page tag from the page address. +#define FDS_PAGE_TAG_WORD_1 (1) // Offset of the second word in the page tag from the page address. + +// Page tag constants +#define FDS_PAGE_TAG_MAGIC (0xDEADC0DE) +#define FDS_PAGE_TAG_SWAP (0xF11E01FF) +#define FDS_PAGE_TAG_DATA (0xF11E01FE) + +#define FDS_ERASED_WORD (0xFFFFFFFF) + +#define FDS_OFFSET_TL (0) // Offset of TL from the record base address, in 4-byte words. +#define FDS_OFFSET_IC (1) // Offset of IC from the record base address, in 4-byte words. +#define FDS_OFFSET_ID (2) // Offset of ID from the record base address, in 4-byte words. +#define FDS_OFFSET_DATA (3) // Offset of the data (chunks) from the record base address, in 4-byte words. + +#define FDS_HEADER_SIZE_TL (1) // Size of the TL part of the header, in 4-byte words. +#define FDS_HEADER_SIZE_IC (1) // Size of the IC part of the header, in 4-byte words. +#define FDS_HEADER_SIZE_ID (1) // Size of the record ID in the header, in 4-byte words. +#define FDS_HEADER_SIZE (3) // Size of the whole header, in 4-byte words. + +#define FDS_OP_EXECUTING (FS_SUCCESS) +#define FDS_OP_COMPLETED (0x1D1D) + +// The size of a physical page, in 4-byte words. +#if defined(NRF51) + #define FDS_PHY_PAGE_SIZE (256) + #elif (defined(NRF52) || defined(NRF52840_XXAA)) + #define FDS_PHY_PAGE_SIZE (1024) +#endif + +// The number of physical pages to be used. This value is configured indirectly. +#define FDS_PHY_PAGES ((FDS_VIRTUAL_PAGES * FDS_VIRTUAL_PAGE_SIZE) / FDS_PHY_PAGE_SIZE) + +// The size of a virtual page, in number of physical pages. +#define FDS_PHY_PAGES_IN_VPAGE (FDS_VIRTUAL_PAGE_SIZE / FDS_PHY_PAGE_SIZE) + +// The number of pages available to store data; which is the total minus one (the swap). +#define FDS_MAX_PAGES (FDS_VIRTUAL_PAGES - 1) + + // Just a shorter name for the size, in words, of a virtual page. +#define FDS_PAGE_SIZE (FDS_VIRTUAL_PAGE_SIZE) + + +#if (FDS_VIRTUAL_PAGE_SIZE % FDS_PHY_PAGE_SIZE != 0) + #error "FDS_VIRTUAL_PAGE_SIZE must be a multiple of the size of a physical page." +#endif + +#if (FDS_VIRTUAL_PAGES < 2) + #error "FDS requires at least two virtual pages." +#endif + + +// FDS internal status flags. +typedef enum +{ + FDS_FLAG_INITIALIZING = (1 << 0), // The module is initializing. + FDS_FLAG_INITIALIZED = (1 << 1), // The module is initialized. + FDS_FLAG_PROCESSING = (1 << 2), // The queue is being processed. + FDS_FLAG_VERIFY_CRC = (1 << 3), // Verify CRC upon writing a record. +} fds_flags_t; + + +// Page types. +typedef enum +{ + FDS_PAGE_DATA, // Page is ready for storage. + FDS_PAGE_SWAP, // Page is reserved for garbage collection. + FDS_PAGE_ERASED, // Page is erased. + FDS_PAGE_UNDEFINED, // Undefined page type. +} fds_page_type_t; + + +typedef struct +{ + fds_page_type_t page_type; // The page type. + uint32_t const * p_addr; // The address of the page. + uint16_t write_offset; // The page write offset, in 4-byte words. + uint16_t words_reserved; // The amount of words reserved by fds_write_reserve(). + uint16_t records_open; // The number of records opened using fds_open(). + bool can_gc; // Indicates that there are some records that have been deleted. +} fds_page_t; + + +typedef struct +{ + uint32_t const * p_addr; + uint16_t write_offset; +} fds_swap_page_t; + + +// FDS op-codes. +typedef enum +{ + FDS_OP_NONE, + FDS_OP_INIT, // Initialize the module. + FDS_OP_WRITE, // Write a record to flash. + FDS_OP_UPDATE, // Update a record. + FDS_OP_DEL_RECORD, // Delete a record. + FDS_OP_DEL_FILE, // Delete a file. + FDS_OP_GC // Run garbage collection. +} fds_op_code_t; + + +typedef enum +{ + FDS_OP_INIT_TAG_SWAP, + FDS_OP_INIT_TAG_DATA, + FDS_OP_INIT_ERASE_SWAP, + FDS_OP_INIT_PROMOTE_SWAP, +} fds_init_step_t; + + +typedef enum +{ + FDS_OP_WRITE_HEADER_BEGIN, // Write the record key and length. + FDS_OP_WRITE_HEADER_FINALIZE, // Write the file ID and CRC. + FDS_OP_WRITE_RECORD_ID, // Write the record ID. + FDS_OP_WRITE_CHUNKS, // Write the record data. + FDS_OP_WRITE_FIND_RECORD, + FDS_OP_WRITE_FLAG_DIRTY, // Flag a record as dirty (as part of an update operation). + FDS_OP_WRITE_DONE, +} fds_write_step_t; + + +typedef enum +{ + FDS_OP_DEL_RECORD_FLAG_DIRTY, // Flag a record as dirty. + FDS_OP_DEL_FILE_FLAG_DIRTY, // Flag multiple records as dirty. + FDS_OP_DEL_DONE, +} fds_delete_step_t; + + +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + // anonymous unions are enabled by default +#endif + +typedef struct +{ + fds_op_code_t op_code; // The opcode for the operation. + union + { + struct + { + fds_init_step_t step; // The current step the operation is at. + } init; + struct + { + fds_header_t header; + fds_write_step_t step; // The current step the operation is at. + uint16_t page; // The page the flash space for this command was reserved. + uint16_t chunk_offset; // Offset used for writing record chunks, in 4-byte words. + uint8_t chunk_count; // Number of chunks to be written. + uint32_t record_to_delete; // The record to delete in case this is an update. + } write; + struct + { + fds_delete_step_t step; + uint16_t file_id; + uint16_t record_key; + uint32_t record_to_delete; + } del; + }; +} fds_op_t; + +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + // leave anonymous unions enabled +#elif defined(__GNUC__) + // anonymous unions are enabled by default +#endif + + +typedef struct +{ + fds_op_t op[FDS_OP_QUEUE_SIZE]; // Queued flash operations. + uint32_t rp; // The index of the command being executed. + uint32_t count; // Number of elements in the queue. +} fds_op_queue_t; + + +typedef struct +{ + fds_record_chunk_t chunk[FDS_CHUNK_QUEUE_SIZE]; + uint32_t rp; + uint32_t count; +} fds_chunk_queue_t; + + +enum +{ + PAGE_ERASED = 0x1, // One or more erased pages found. + PAGE_DATA = 0x2, // One or more data pages found. + PAGE_SWAP_CLEAN = 0x4, // A clean (empty) swap page was found. + PAGE_SWAP_DIRTY = 0x8, // A dirty (non-empty) swap page was found. +}; + + +typedef enum +{ + // No erased pages or FDS pages found. + // This is a fatal error. + NO_PAGES, + + // The filesystem can not be garbage collected. + // This is a fatal error. + NO_SWAP = (PAGE_DATA), + + // Perform a fresh installation. + FRESH_INSTALL = (PAGE_ERASED), + + // Tag an erased page as swap. + TAG_SWAP = (PAGE_ERASED | PAGE_DATA), + + // Tag all erased pages as data. + TAG_DATA = (PAGE_ERASED | PAGE_SWAP_CLEAN), + + // Tag all remaining erased pages as data. + TAG_DATA_INST = (PAGE_ERASED | PAGE_DATA | PAGE_SWAP_CLEAN), + + // The swap is dirty, likely because the device powered off during GC. + // Because there is also an erased page, assume that that page has been garbage collected. + // Hence, tag the swap as data (promote), an erased page as swap and remaining pages as data. + PROMOTE_SWAP = (PAGE_ERASED | PAGE_SWAP_DIRTY), + + // Tag the swap as data (promote), an erased page as swap and remaining pages as data. + PROMOTE_SWAP_INST = (PAGE_ERASED | PAGE_DATA | PAGE_SWAP_DIRTY), + + // The swap is dirty (written) and there are no erased pages. It is likely that the device + // powered off during GC. It is safe to discard (erase) the swap, since data that was + // swapped out still lies in one of the valid pages. + DISCARD_SWAP = (PAGE_DATA | PAGE_SWAP_DIRTY), + + // Do nothing. + ALREADY_INSTALLED = (PAGE_DATA | PAGE_SWAP_CLEAN), + +} fds_init_opts_t; + + +typedef enum +{ + GC_BEGIN, // Begin GC. + GC_NEXT_PAGE, // GC a page. + GC_FIND_NEXT_RECORD, // Find a valid record to copy. + GC_COPY_RECORD, // Copy a valid record to swap. + GC_ERASE_PAGE, // Erase the page being garbage collected. + GC_DISCARD_SWAP, // Erase (discard) the swap page. + GC_PROMOTE_SWAP, // Tag the swap as valid. + GC_TAG_NEW_SWAP // Tag a freshly erased (GCed) page as swap. +} fds_gc_state_t; + + +// Holds garbage collection status and related data. +typedef struct +{ + fds_gc_state_t state; // The current GC step. + uint16_t cur_page; // The current page being garbage collected. + uint32_t const * p_record_src; // The current record being copied to swap. + uint16_t run_count; // Total number of times GC was run. + bool do_gc_page[FDS_MAX_PAGES]; // Controls which pages to garbage collect. + bool resume; // Whether or not GC should be resumed. +} fds_gc_data_t; + + +// Macros to enable and disable application interrupts. +#if defined (FDS_THREADS) + + #define CRITICAL_SECTION_ENTER() CRITICAL_REGION_ENTER() + #define CRITICAL_SECTION_EXIT() CRITICAL_REGION_EXIT() + +#else + + #define CRITICAL_SECTION_ENTER() + #define CRITICAL_SECTION_EXIT() + +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif // FDS_INTERNAL_DEFS_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fifo/app_fifo.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fifo/app_fifo.c new file mode 100644 index 0000000000000000000000000000000000000000..26c49bc36359abd9e1468d447f8760e1db16f3c4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fifo/app_fifo.c @@ -0,0 +1,214 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_FIFO) +#include "app_fifo.h" + +static __INLINE uint32_t fifo_length(app_fifo_t * p_fifo) +{ + uint32_t tmp = p_fifo->read_pos; + return p_fifo->write_pos - tmp; +} + + +#define FIFO_LENGTH() fifo_length(p_fifo) /**< Macro for calculating the FIFO length. */ + + +/**@brief Put one byte to the FIFO. */ +static __INLINE void fifo_put(app_fifo_t * p_fifo, uint8_t byte) +{ + p_fifo->p_buf[p_fifo->write_pos & p_fifo->buf_size_mask] = byte; + p_fifo->write_pos++; +} + + +/**@brief Look at one byte in the FIFO. */ +static __INLINE void fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte) +{ + *p_byte = p_fifo->p_buf[(p_fifo->read_pos + index) & p_fifo->buf_size_mask]; +} + + +/**@brief Get one byte from the FIFO. */ +static __INLINE void fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte) +{ + fifo_peek(p_fifo, 0, p_byte); + p_fifo->read_pos++; +} + + +uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size) +{ + // Check buffer for null pointer. + if (p_buf == NULL) + { + return NRF_ERROR_NULL; + } + + // Check that the buffer size is a power of two. + if (!IS_POWER_OF_TWO(buf_size)) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_fifo->p_buf = p_buf; + p_fifo->buf_size_mask = buf_size - 1; + p_fifo->read_pos = 0; + p_fifo->write_pos = 0; + + return NRF_SUCCESS; +} + + +uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte) +{ + if (FIFO_LENGTH() <= p_fifo->buf_size_mask) + { + fifo_put(p_fifo, byte); + return NRF_SUCCESS; + } + + return NRF_ERROR_NO_MEM; +} + + +uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte) +{ + if (FIFO_LENGTH() != 0) + { + fifo_get(p_fifo, p_byte); + return NRF_SUCCESS; + } + + return NRF_ERROR_NOT_FOUND; + +} + + +uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte) +{ + if (FIFO_LENGTH() > index) + { + fifo_peek(p_fifo, index, p_byte); + return NRF_SUCCESS; + } + + return NRF_ERROR_NOT_FOUND; +} + + +uint32_t app_fifo_flush(app_fifo_t * p_fifo) +{ + p_fifo->read_pos = p_fifo->write_pos; + return NRF_SUCCESS; +} + + +uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size) +{ + VERIFY_PARAM_NOT_NULL(p_fifo); + VERIFY_PARAM_NOT_NULL(p_size); + + const uint32_t byte_count = fifo_length(p_fifo); + const uint32_t requested_len = (*p_size); + uint32_t index = 0; + uint32_t read_size = MIN(requested_len, byte_count); + + (*p_size) = byte_count; + + // Check if the FIFO is empty. + if (byte_count == 0) + { + return NRF_ERROR_NOT_FOUND; + } + + // Check if application has requested only the size. + if (p_byte_array == NULL) + { + return NRF_SUCCESS; + } + + // Fetch bytes from the FIFO. + while (index < read_size) + { + fifo_get(p_fifo, &p_byte_array[index++]); + } + + (*p_size) = read_size; + + return NRF_SUCCESS; +} + + +uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size) +{ + VERIFY_PARAM_NOT_NULL(p_fifo); + VERIFY_PARAM_NOT_NULL(p_size); + + const uint32_t available_count = p_fifo->buf_size_mask - fifo_length(p_fifo) + 1; + const uint32_t requested_len = (*p_size); + uint32_t index = 0; + uint32_t write_size = MIN(requested_len, available_count); + + (*p_size) = available_count; + + // Check if the FIFO is FULL. + if (available_count == 0) + { + return NRF_ERROR_NO_MEM; + } + + // Check if application has requested only the size. + if (p_byte_array == NULL) + { + return NRF_SUCCESS; + } + + //Fetch bytes from the FIFO. + while (index < write_size) + { + fifo_put(p_fifo, p_byte_array[index++]); + } + + (*p_size) = write_size; + + return NRF_SUCCESS; +} +#endif //NRF_MODULE_ENABLED(APP_FIFO) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fifo/app_fifo.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fifo/app_fifo.h new file mode 100644 index 0000000000000000000000000000000000000000..bf512fb6e1b5b7386778fe20f0051a2758351faa --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fifo/app_fifo.h @@ -0,0 +1,181 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup app_fifo FIFO implementation + * @{ + * @ingroup app_common + * + * @brief FIFO implementation. + */ + +#ifndef APP_FIFO_H__ +#define APP_FIFO_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief A FIFO instance structure. + * @details Keeps track of which bytes to read and write next. + * Also, it keeps the information about which memory is allocated for the buffer + * and its size. This structure must be initialized by app_fifo_init() before use. + */ +typedef struct +{ + uint8_t * p_buf; /**< Pointer to FIFO buffer memory. */ + uint16_t buf_size_mask; /**< Read/write index mask. Also used for size checking. */ + volatile uint32_t read_pos; /**< Next read position in the FIFO buffer. */ + volatile uint32_t write_pos; /**< Next write position in the FIFO buffer. */ +} app_fifo_t; + +/**@brief Function for initializing the FIFO. + * + * @param[out] p_fifo FIFO object. + * @param[in] p_buf FIFO buffer for storing data. The buffer size must be a power of two. + * @param[in] buf_size Size of the FIFO buffer provided. This size must be a power of two. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_NULL If a NULL pointer is provided as buffer. + * @retval NRF_ERROR_INVALID_LENGTH If size of buffer provided is not a power of two. + */ +uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size); + +/**@brief Function for adding an element to the FIFO. + * + * @param[in] p_fifo Pointer to the FIFO. + * @param[in] byte Data byte to add to the FIFO. + * + * @retval NRF_SUCCESS If an element has been successfully added to the FIFO. + * @retval NRF_ERROR_NO_MEM If the FIFO is full. + */ +uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte); + +/**@brief Function for getting the next element from the FIFO. + * + * @param[in] p_fifo Pointer to the FIFO. + * @param[out] p_byte Byte fetched from the FIFO. + * + * @retval NRF_SUCCESS If an element was returned. + * @retval NRF_ERROR_NOT_FOUND If there are no more elements in the queue. + */ +uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte); + +/**@brief Function for looking at an element in the FIFO, without consuming it. + * + * @param[in] p_fifo Pointer to the FIFO. + * @param[in] index Which element to look at. The lower the index, the earlier it was put. + * @param[out] p_byte Byte fetched from the FIFO. + * + * @retval NRF_SUCCESS If an element was returned. + * @retval NRF_ERROR_NOT_FOUND If there are no more elements in the queue, or the index was + * too large. + */ +uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte); + +/**@brief Function for flushing the FIFO. + * + * @param[in] p_fifo Pointer to the FIFO. + * + * @retval NRF_SUCCESS If the FIFO was flushed successfully. + */ +uint32_t app_fifo_flush(app_fifo_t * p_fifo); + +/**@brief Function for reading bytes from the FIFO. + * + * This function can also be used to get the number of bytes in the FIFO. + * + * @param[in] p_fifo Pointer to the FIFO. Must not be NULL. + * @param[out] p_byte_array Memory pointer where the read bytes are fetched from the FIFO. + * Can be NULL. If NULL, the number of bytes that can be read in the FIFO + * are returned in the p_size parameter. + * @param[inout] p_size Address to memory indicating the maximum number of bytes to be read. + * The provided memory is overwritten with the actual number of bytes + * read if the procedure was successful. This field must not be NULL. + * If p_byte_array is set to NULL by the application, this parameter + * returns the number of bytes in the FIFO. + * + * @retval NRF_SUCCESS If the procedure is successful. The actual number of bytes read might + * be less than the requested maximum, depending on how many elements exist + * in the FIFO. Even if less bytes are returned, the procedure is considered + * successful. + * @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not + * be NULL. + * @retval NRF_ERROR_NOT_FOUND If the FIFO is empty. + */ +uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size); + +/**@brief Function for writing bytes to the FIFO. + * + * This function can also be used to get the available size on the FIFO. + * + * @param[in] p_fifo Pointer to the FIFO. Must not be NULL. + * @param[in] p_byte_array Memory pointer containing the bytes to be written to the FIFO. + * Can be NULL. If NULL, this function returns the number of bytes + * that can be written to the FIFO. + * @param[inout] p_size Address to memory indicating the maximum number of bytes to be written. + * The provided memory is overwritten with the number of bytes that were actually + * written if the procedure is successful. This field must not be NULL. + * If p_byte_array is set to NULL by the application, this parameter + * returns the number of bytes available in the FIFO. + * + * @retval NRF_SUCCESS If the procedure is successful. The actual number of bytes written might + * be less than the requested maximum, depending on how much room there is in + * the FIFO. Even if less bytes are written, the procedure is considered + * successful. If the write was partial, the application should use + * subsequent calls to attempt writing the data again. + * @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not + * be NULL. + * @retval NRF_ERROR_NO_MEM If the FIFO is full. + * + */ +uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size); + + +#ifdef __cplusplus +} +#endif + +#endif // APP_FIFO_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fstorage/fstorage.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fstorage/fstorage.c new file mode 100644 index 0000000000000000000000000000000000000000..eec9c0ab9606779786833b9f91ff4beb1531613b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fstorage/fstorage.c @@ -0,0 +1,561 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(FSTORAGE) +#include "fstorage.h" +#include "fstorage_internal_defs.h" + +#include +#include +#include +#include "nrf_error.h" +#include "nrf_soc.h" + + +static uint8_t m_flags; // fstorage status flags. +static fs_op_queue_t m_queue; // Queue of requested operations. +static uint8_t m_retry_count; // Number of times the last flash operation was retried. + +// Sends events to the application. +static void send_event(fs_op_t const * const p_op, fs_ret_t result) +{ + fs_evt_t evt; + memset(&evt, 0x00, sizeof(fs_evt_t)); + + switch (p_op->op_code) + { + case FS_OP_STORE: + evt.id = FS_EVT_STORE; + evt.store.p_data = p_op->store.p_dest; + evt.store.length_words = p_op->store.length_words; + break; + + case FS_OP_ERASE: + evt.id = FS_EVT_ERASE; + evt.erase.first_page = p_op->erase.page - p_op->erase.pages_erased; + evt.erase.last_page = p_op->erase.page; + break; + + default: + // Should not happen. + break; + } + evt.p_context = p_op->p_context; + + p_op->p_config->callback(&evt, result); +} + + +// Checks that a configuration is non-NULL and within section variable bounds. +static bool check_config(fs_config_t const * const config) +{ +#ifndef DFU_SUPPORT_SIGNING + if ((config != NULL) && + ((uint32_t)FS_SECTION_START_ADDR <= (uint32_t)config) && + ((uint32_t)FS_SECTION_END_ADDR > (uint32_t)config)) + { + return true; + } + + return false; +#else + return true; +#endif +} + + +// Executes a store operation. +static uint32_t store_execute(fs_op_t const * const p_op) +{ + uint16_t chunk_len; + + if ((p_op->store.length_words - p_op->store.offset) < FS_MAX_WRITE_SIZE_WORDS) + { + chunk_len = p_op->store.length_words - p_op->store.offset; + } + else + { + chunk_len = FS_MAX_WRITE_SIZE_WORDS; + } + + return sd_flash_write((uint32_t*)p_op->store.p_dest + p_op->store.offset, + (uint32_t*)p_op->store.p_src + p_op->store.offset, + chunk_len); +} + + +// Executes an erase operation. +static uint32_t erase_execute(fs_op_t const * const p_op) +{ + return sd_flash_page_erase(p_op->erase.page); +} + + +// Advances the queue, wrapping around if necessary. +// If no elements are left in the queue, clears the FS_FLAG_PROCESSING flag. +static void queue_advance(void) +{ + if (--m_queue.count == 0) + { + m_flags &= ~FS_FLAG_PROCESSING; + } + + if (++m_queue.rp == FS_QUEUE_SIZE) + { + m_queue.rp = 0; + } +} + + +// Processes the current element in the queue. If the queue is empty, does nothing. +static void queue_process(void) +{ + uint32_t ret; + fs_op_t * const p_op = &m_queue.op[m_queue.rp]; + + if (m_queue.count > 0) + { + switch (p_op->op_code) + { + case FS_OP_STORE: + ret = store_execute(p_op); + break; + + case FS_OP_ERASE: + ret = erase_execute(p_op); + break; + + default: + ret = FS_ERR_INTERNAL; + break; + } + + // There is a pending flash operation which was not initiated by this module. + // Stop processing the queue and wait for a system event. + if (ret == NRF_ERROR_BUSY) + { + m_flags &= ~FS_FLAG_PROCESSING; + m_flags |= FS_FLAG_FLASH_REQ_PENDING; + } + else if (ret != NRF_SUCCESS) + { + // An error has occurred. + send_event(p_op, FS_ERR_INTERNAL); + } + else + { + // Operation is executing. + } + } +} + + +// Starts processing the queue if there are no pending flash operations, both inside and +// outside this module. Returns immediately otherwise. +static void queue_start(void) +{ + if (!(m_flags & FS_FLAG_PROCESSING) && + !(m_flags & FS_FLAG_FLASH_REQ_PENDING)) + { + m_flags |= FS_FLAG_PROCESSING; + queue_process(); + } +} + + +// Flash operation success callback handler. Keeps track of the progress of an operation. +// If it has finished, advances the queue and notifies the application. +static void on_operation_success(fs_op_t * const p_op) +{ + m_retry_count = 0; + + switch (p_op->op_code) + { + case FS_OP_STORE: + { + uint16_t chunk_len; + + if ((p_op->store.length_words - p_op->store.offset) < FS_MAX_WRITE_SIZE_WORDS) + { + chunk_len = p_op->store.length_words - p_op->store.offset; + } + else + { + chunk_len = FS_MAX_WRITE_SIZE_WORDS; + } + + p_op->store.offset += chunk_len; + + if (p_op->store.offset == p_op->store.length_words) + { + // The operation has finished. + send_event(p_op, FS_SUCCESS); + queue_advance(); + } + } + break; + + case FS_OP_ERASE: + { + p_op->erase.page++; + p_op->erase.pages_erased++; + + if (p_op->erase.pages_erased == p_op->erase.pages_to_erase) + { + send_event(p_op, FS_SUCCESS); + queue_advance(); + } + } + break; + + default: + // Should not happen. + break; + } +} + + +// Flash operation failure callback handler. If the maximum number of retries has +// been reached, notifies the application and advances the queue. +static void on_operation_failure(fs_op_t const * const p_op) +{ + if (++m_retry_count > FS_OP_MAX_RETRIES) + { + m_retry_count = 0; + + send_event(p_op, FS_ERR_OPERATION_TIMEOUT); + queue_advance(); + } +} + + +// Retrieves a pointer to the next free element in the queue. +// Additionally, increases the number of elements stored in the queue. +static bool queue_get_next_free(fs_op_t ** p_op) +{ + uint32_t idx; + + if (m_queue.count == FS_QUEUE_SIZE) + { + return false; + } + + idx = ((m_queue.rp + m_queue.count) < FS_QUEUE_SIZE) ? + (m_queue.rp + m_queue.count) : ((m_queue.rp + m_queue.count)-FS_QUEUE_SIZE); + + m_queue.count++; + + // Zero the element so that unassigned fields will be zero. + memset(&m_queue.op[idx], 0x00, sizeof(fs_op_t)); + + *p_op = &m_queue.op[idx]; + + return true; +} + + +fs_ret_t fs_init(void) +{ + uint32_t const total_users = FS_SECTION_ITEM_COUNT; + uint32_t configs_to_init = FS_SECTION_ITEM_COUNT; + uint32_t const * p_current_end = FS_PAGE_END_ADDR; + + if (m_flags & FS_FLAG_INITIALIZED) + { + return FS_SUCCESS; + } + + // Each fstorage user has registered one configuration. + // The total number of users (and thus the total number of configurations) is + // kept in total_users. Some of these users might have specified their flash + // boundaries in their configurations. This function sets the flash boundaries + // for the remaining user configurations without further user interaction. + + // First, determine how many user configurations this function has to initialize, + // out of the total. This number will be kept in configs_to_init. + + for (uint32_t i = 0; i < total_users; i++) + { + fs_config_t const * const p_config = FS_SECTION_ITEM_GET(i); + + if ((p_config->p_start_addr != NULL) && + (p_config->p_end_addr != NULL)) + { + configs_to_init--; + } + } + + // For each configuration to initialize, assign flash space based on the priority + // specified. Higher priority means a higher memory address. + + for (uint32_t i = 0; i < configs_to_init; i++) + { + fs_config_t * p_config_i = FS_SECTION_ITEM_GET(i); + uint8_t max_priority = 0; + uint8_t max_index = i; + + for (uint32_t j = 0; j < total_users; j++) + { + fs_config_t const * const p_config_j = FS_SECTION_ITEM_GET(j); + + #if 0 + if (p_config_j->priority == p_config_i->priority) + { + // Duplicated priorities are not allowed. + return FS_ERR_INVALID_CFG; + } + #endif + + if ((p_config_j->p_start_addr != NULL) && + (p_config_j->p_end_addr != NULL)) + { + // When calculating the configuration with the next highest priority + // skip configurations which were already set during a previous iteration. + // This check needs to be here to prevent re-using the configurations + // with higher priorities which we used in previous iterations. + continue; + } + + if (p_config_j->priority > max_priority) + { + max_priority = p_config_j->priority; + max_index = j; + } + } + + p_config_i = FS_SECTION_ITEM_GET(max_index); + + p_config_i->p_end_addr = p_current_end; + p_config_i->p_start_addr = p_current_end - (p_config_i->num_pages * FS_PAGE_SIZE_WORDS); + + p_current_end = p_config_i->p_start_addr; + } + + m_flags |= FS_FLAG_INITIALIZED; + + return FS_SUCCESS; +} + + +fs_ret_t fs_fake_init(void) +{ + m_flags |= FS_FLAG_INITIALIZED; + return FS_SUCCESS; +} + + +fs_ret_t fs_store(fs_config_t const * const p_config, + uint32_t const * const p_dest, + uint32_t const * const p_src, + uint16_t const length_words, + void * p_context) +{ + fs_op_t * p_op; + + if (!(m_flags & FS_FLAG_INITIALIZED)) + { + return FS_ERR_NOT_INITIALIZED; + } + + if (!check_config(p_config)) + { + return FS_ERR_INVALID_CFG; + } + + if ((p_src == NULL) || (p_dest == NULL)) + { + return FS_ERR_NULL_ARG; + } + + // Check that both pointers are word aligned. + if (((uint32_t)p_src & 0x03) || + ((uint32_t)p_dest & 0x03)) + { + return FS_ERR_UNALIGNED_ADDR; + } + + // Check that the operation doesn't go outside the client's memory boundaries. + if ((p_config->p_start_addr > p_dest) || + (p_config->p_end_addr < (p_dest + length_words))) + { + return FS_ERR_INVALID_ADDR; + } + + if (length_words == 0) + { + return FS_ERR_INVALID_ARG; + } + + if (!queue_get_next_free(&p_op)) + { + return FS_ERR_QUEUE_FULL; + } + + // Initialize the operation. + p_op->p_context = p_context; + p_op->p_config = p_config; + p_op->op_code = FS_OP_STORE; + p_op->store.p_src = p_src; + p_op->store.p_dest = p_dest; + p_op->store.length_words = length_words; + + queue_start(); + + return FS_SUCCESS; +} + + +fs_ret_t fs_erase(fs_config_t const * const p_config, + uint32_t const * const p_page_addr, + uint16_t const num_pages, + void * p_context) +{ + fs_op_t * p_op; + + if (!(m_flags & FS_FLAG_INITIALIZED)) + { + return FS_ERR_NOT_INITIALIZED; + } + + if (!check_config(p_config)) + { + return FS_ERR_INVALID_CFG; + } + + if (p_page_addr == NULL) + { + return FS_ERR_NULL_ARG; + } + + // Check that the page is aligned to a page boundary. + if (((uint32_t)p_page_addr & (FS_PAGE_SIZE-1)) != 0) + { + return FS_ERR_UNALIGNED_ADDR; + } + + // Check that the operation doesn't go outside the client's memory boundaries. + if ((p_page_addr < p_config->p_start_addr) || + (p_page_addr + (FS_PAGE_SIZE_WORDS * num_pages) > p_config->p_end_addr)) + { + return FS_ERR_INVALID_ADDR; + } + + if (num_pages == 0) + { + return FS_ERR_INVALID_ARG; + } + + if (!queue_get_next_free(&p_op)) + { + return FS_ERR_QUEUE_FULL; + } + + // Initialize the operation. + p_op->p_context = p_context; + p_op->p_config = p_config; + p_op->op_code = FS_OP_ERASE; + p_op->erase.page = ((uint32_t)p_page_addr / FS_PAGE_SIZE); + p_op->erase.pages_to_erase = num_pages; + + queue_start(); + + return FS_SUCCESS; +} + + +fs_ret_t fs_queued_op_count_get(uint32_t * const p_op_count) +{ + if (p_op_count == NULL) + { + return FS_ERR_NULL_ARG; + } + + *p_op_count = m_queue.count; + + return FS_SUCCESS; +} + + +void fs_sys_event_handler(uint32_t sys_evt) +{ + fs_op_t * const p_op = &m_queue.op[m_queue.rp]; + + if (m_flags & FS_FLAG_PROCESSING) + { + // A flash operation was initiated by this module. Handle the result. + switch (sys_evt) + { + case NRF_EVT_FLASH_OPERATION_SUCCESS: + on_operation_success(p_op); + break; + + case NRF_EVT_FLASH_OPERATION_ERROR: + on_operation_failure(p_op); + break; + } + } + else if ((m_flags & FS_FLAG_FLASH_REQ_PENDING)) + { + // A flash operation was initiated outside this module. + // A callback which indicates that it has finished was received. + m_flags &= ~FS_FLAG_FLASH_REQ_PENDING; + + // If there are any elements left in the queue, set FS_FLAG_PROCESSING. + if (m_queue.count > 0) + { + m_flags |= FS_FLAG_PROCESSING; + } + } + + // Resume processing the queue, if necessary. + queue_process(); +} + +bool fs_queue_is_full(void) +{ + return (m_queue.count == FS_QUEUE_SIZE); +} + +bool fs_queue_is_empty(void) +{ + return (m_queue.count == 0); +} + +#endif //NRF_MODULE_ENABLED(FSTORAGE) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fstorage/fstorage.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fstorage/fstorage.h new file mode 100644 index 0000000000000000000000000000000000000000..1c7a11e54995cd2f83a85d87cf3983613c50afb9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fstorage/fstorage.h @@ -0,0 +1,297 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef FSTORAGE_H__ +#define FSTORAGE_H__ + +/** + * @defgroup fstorage fstorage + * @ingroup app_common + * @{ + * + * @brief Module which provides functionality to store data to flash and erase flash pages. + */ + +#include +#include +#include "nrf_section.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief fstorage return values. */ +typedef enum +{ + FS_SUCCESS, + FS_ERR_NOT_INITIALIZED, //!< Error. The module is not initialized. + FS_ERR_INVALID_CFG, //!< Error. Invalid fstorage configuration. + FS_ERR_NULL_ARG, //!< Error. Argument is NULL. + FS_ERR_INVALID_ARG, //!< Error. Argument contains invalid data. + FS_ERR_INVALID_ADDR, //!< Error. Address out of bounds. + FS_ERR_UNALIGNED_ADDR, //!< Error. Unaligned address. + FS_ERR_QUEUE_FULL, //!< Error. Queue is full. + FS_ERR_OPERATION_TIMEOUT, //!< Error. The operation has timed out. + FS_ERR_INTERNAL, //!< Error. Internal error. + FS_ERR_FAILURE_SINCE_LAST //!< Error. Uncleared error since last call +} fs_ret_t; + + +/**@brief fstorage event IDs. */ +typedef enum +{ + FS_EVT_STORE, //!< Event for @ref fs_store. + FS_EVT_ERASE //!< Event for @ref fs_erase. +} fs_evt_id_t; + + +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#endif + +/**@brief An fstorage event. */ +typedef struct +{ + fs_evt_id_t id; //!< The event ID. + void * p_context; //!< User-defined context passed to the interrupt handler. + union + { + struct + { + uint32_t const * p_data; //!< Pointer to the data stored in flash. + uint16_t length_words; //!< Length of the data, in 4-byte words. + } store; + struct + { + uint16_t first_page; //!< First page erased. + uint16_t last_page; //!< Last page erased. + } erase; + }; +} fs_evt_t; + +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + /* leave anonymous unions enabled */ +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#endif + + +/**@brief fstorage event handler function prototype. + * + * @param[in] evt The event. + * @param[in] result The result of the operation. + */ +typedef void (*fs_cb_t)(fs_evt_t const * const evt, fs_ret_t result); + + +/**@brief fstorage application-specific configuration. + * + * @details Specifies the callback to invoke when an operation completes, the number of flash pages + * requested by the application and the priority with which these are to be assigned, with + * respect to other applications. Additionally, the configuration specifies the boundaries + * of the flash space assigned to an application. The configuration must be provided as an + * argument when invoking @ref fs_store and @ref fs_erase. + * + * @note The fields @p p_start_addr and @p p_end_address are set by @ref fs_init, based on the + * value of the field @p priority. + */ +typedef struct +{ + /**@brief The beginning of the flash space assigned to the application which registered this + * configuration. This field is set by @ref fs_init. It can also be set manually. + */ + uint32_t const * p_start_addr; + + /**@brief The end of the flash space assigned to the application which registered this + * configuration. This field is set by @ref fs_init. It can also be set manually. + */ + uint32_t const * p_end_addr; + + fs_cb_t const callback; //!< Callback to run when a flash operation has completed. + uint8_t const num_pages; //!< The number of flash pages requested. + + /**@brief The priority with which fstorage should assign flash pages to this application, + * with respect to other applications. Applications with higher priority will be + * assigned flash pages with a higher memory address. The highest priority is + * reserved. Must be unique among configurations. + */ + uint8_t const priority; +} fs_config_t; + + +/**@brief Macro for registering an fstorage configuration variable. + * Applications which use fstorage must register with the module using this macro. + * Registering involves defining a variable which holds the configuration of fstorage + * specific to the application which invokes the macro. + * + * @details This macro places the configuration variable in a section named "fs_data" that + * fstorage uses during initialization and regular operation. + * + * @param[in] cfg_var A @e definition of a @ref fs_config_t variable. + */ +#define FS_REGISTER_CFG(cfg_var) NRF_SECTION_ITEM_REGISTER(fs_data, cfg_var) + + +/**@brief Function for initializing the module. + * + * @details This functions assigns pages in flash according to all registered configurations. + * + * @retval FS_SUCCESS If the module was successfully initialized. + */ +fs_ret_t fs_init(void); + + +fs_ret_t fs_fake_init(void); + + +/**@brief Function for storing data in flash. + * + * @details Copies @p length_words words from @p p_src to the location pointed by @p p_dest. + * If the length of the data exceeds @ref FS_MAX_WRITE_SIZE_WORDS, the data will be + * written down in several chunks, as necessary. Only one event will be sent to the + * application upon completion. Both the source and the destination of the data must be + * word aligned. This function is asynchronous, completion is reported via an event sent + * the the callback function specified in the supplied configuration. + * + * @warning The data to be written to flash has to be kept in memory until the operation has + * terminated, i.e., an event is received. + * + * @param[in] p_config fstorage configuration registered by the application. + * @param[in] p_dest The address in flash memory where to store the data. + * @param[in] p_src Pointer to the data to store in flash. + * @param[in] length_words Length of the data to store, in words. + * @param[in] p_context User-defined context passed to the interrupt handler. + * + * @retval FS_SUCCESS If the operation was queued successfully. + * @retval FS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FS_ERR_INVALID_CFG If @p p_config is NULL or contains invalid data. + * @retval FS_ERR_NULL_ARG If @p p_dest or @p p_src are NULL. + * @retval FS_ERR_INVALID_ARG If @p length_words is zero. + * @retval FS_ERR_INVALID_ADDR If @p p_dest or @p p_src are outside of the flash memory + * boundaries specified in @p p_config. + * @retval FS_ERR_UNALIGNED_ADDR If @p p_dest or @p p_src are not aligned to a word boundary. + * @retval FS_ERR_QUEUE_FULL If the internal operation queue is full. + */ +fs_ret_t fs_store(fs_config_t const * const p_config, + uint32_t const * const p_dest, + uint32_t const * const p_src, + uint16_t length_words, + void * p_context); + + +/**@brief Function for erasing flash pages. + * + * @details Starting from the page at @p p_page_addr, erases @p num_pages flash pages. + * @p p_page_addr must be aligned to a page boundary. All pages to be erased must be + * within the bounds specified in the supplied fstorage configuration. + * This function is asynchronous. Completion is reported via an event. + * + * @param[in] p_config fstorage configuration registered by the application. + * @param[in] p_page_addr Address of the page to erase. Must be aligned to a page boundary. + * @param[in] num_pages Number of pages to erase. May not be zero. + * @param[in] p_context User-defined context passed to the interrupt handler. + * + * @retval FS_SUCCESS If the operation was queued successfully. + * @retval FS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FS_ERR_INVALID_CFG If @p p_config is NULL or contains invalid data. + * @retval FS_ERR_NULL_ARG If @p p_page_addr is NULL. + * @retval FS_ERR_INVALID_ARG If @p num_pages is zero. + * @retval FS_ERR_INVALID_ADDR If the operation would go beyond the flash memory boundaries + * specified in @p p_config. + * @retval FS_ERR_UNALIGNED_ADDR If @p p_page_addr is not aligned to a page boundary. + * @retval FS_ERR_QUEUE_FULL If the internal operation queue is full. + */ +fs_ret_t fs_erase(fs_config_t const * const p_config, + uint32_t const * const p_page_addr, + uint16_t num_pages, + void * p_context); + + +/**@brief Function for retrieving the number of queued flash operations. + * + * @param[out] p_op_count The number of queued flash operations. + * + * @retval FS_SUCCESS If the number of queued operations was retrieved successfully. + * @retval FS_ERR_NULL_ARG If @p p_op_count is NULL. + */ +fs_ret_t fs_queued_op_count_get(uint32_t * const p_op_count); + + +/**@brief Function for checking if the queue for flash operations is full. + * + * @retval true If the queue is full. + * @retval false If there is space for more operations in the queue. + */ +bool fs_queue_is_full(void); + + +/**@brief Function for checking if the queue for flash operations is empty. + * + * @retval true If the queue is empty. + * @retval false If there are flash operations in the queue. + */ +bool fs_queue_is_empty(void); + + +/**@brief Function for handling system events from the SoftDevice. + * + * @details If any of the modules used by the application rely on fstorage, the application should + * dispatch system events to fstorage using this function. + * + * @param[in] sys_evt System event from the SoftDevice. + */ +void fs_sys_event_handler(uint32_t sys_evt); + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif // FSTORAGE_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fstorage/fstorage_internal_defs.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fstorage/fstorage_internal_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..d7b4aca78c88eea12ea12f8d97098cc92b8beb38 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fstorage/fstorage_internal_defs.h @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef FSTORAGE_INTERNAL_DEFS_H__ +#define FSTORAGE_INTERNAL_DEFS_H__ + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define FS_FLAG_INITIALIZED (1 << 0) // The module has been initialized. +#define FS_FLAG_PROCESSING (1 << 1) // The module is processing flash operations. +// The module is waiting for a flash operation initiated by another module to complete. +#define FS_FLAG_FLASH_REQ_PENDING (1 << 2) + +#define FS_ERASED_WORD (0xFFFFFFFF) + +// Helper macros for section variables. +#define FS_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(fs_data, fs_config_t, (i)) +#define FS_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(fs_data, fs_config_t) +#define FS_SECTION_START_ADDR NRF_SECTION_START_ADDR(fs_data) +#define FS_SECTION_END_ADDR NRF_SECTION_END_ADDR(fs_data) + +// Create section 'fs_data'. +//lint -esym(526, fs_dataBase) -esym(526, fs_dataLimit) +NRF_SECTION_DEF(fs_data, fs_config_t); + +// fstorage op-codes. +typedef enum +{ + FS_OP_NONE, // No operation. + FS_OP_STORE, // Store data. + FS_OP_ERASE // Erase one or more flash pages. +} fs_op_code_t; + + +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + // anonymous unions are enabled by default. +#endif + +// fstorage operation. +// Encapsulates details of a flash operation to be executed by this module. +typedef struct +{ + fs_config_t const * p_config; // Application-specific fstorage configuration. + void * p_context; // User-defined context passed to the interrupt handler. + fs_op_code_t op_code; // ID of the operation. + union + { + struct + { + uint32_t const * p_src; // Pointer to the data to be written to flash. + uint32_t const * p_dest; // Destination of the data in flash. + uint16_t length_words; // Length of the data to be written, in words. + uint16_t offset; // Write offset. + } store; + struct + { + uint16_t page; + uint16_t pages_erased; + uint16_t pages_to_erase; + } erase; + }; +} fs_op_t; + +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + // leave anonymous unions enabled. +#elif defined(__GNUC__) + // anonymous unions are enabled by default. +#endif + + +// Queue of requested operations. +// This queue holds flash operations requested to the module. +// The data to be written to flash must be kept in memory until the write operation +// is completed, i.e., an event indicating completion is received. +typedef struct +{ + fs_op_t op[FS_QUEUE_SIZE]; // Queue elements. + uint32_t rp; // Index of the operation being processed. + uint32_t count; // Number of elements in the queue. +} fs_op_queue_t; + + +// Size of a flash page in bytes. +#if defined (NRF51) + #define FS_PAGE_SIZE (1024) +#elif (defined (NRF52) || defined(NRF52840_XXAA)) + #define FS_PAGE_SIZE (4096) +#endif + + +// Size of a flash page in words. +#define FS_PAGE_SIZE_WORDS (FS_PAGE_SIZE / sizeof(uint32_t)) + + +// Function to obtain the end of the flash space available to fstorage. +static uint32_t const * fs_flash_page_end_addr() +{ + uint32_t const bootloader_addr = NRF_UICR->NRFFW[0]; + + return (uint32_t*)((bootloader_addr != FS_ERASED_WORD) ? bootloader_addr : + NRF_FICR->CODESIZE * FS_PAGE_SIZE); +} + + +// Macro to obtain the address of the last page. +// If there is a bootloader present the bootloader address read from UICR +// will act as the page beyond the end of the available flash storage. +#define FS_PAGE_END_ADDR (fs_flash_page_end_addr()) + + + +#ifdef __cplusplus +} +#endif + +#endif //__FSTORAGE_INTERNAL_DEFS_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fstorage/fstorage_nosd.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fstorage/fstorage_nosd.c new file mode 100644 index 0000000000000000000000000000000000000000..cd6f4dbd0a4063b2d53c41097def80d81d9bc1d9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/fstorage/fstorage_nosd.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ \ No newline at end of file diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gfx/nrf_gfx.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gfx/nrf_gfx.c new file mode 100644 index 0000000000000000000000000000000000000000..46a5f13c30f8adb2df3eeca2e2b43484466f6797 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gfx/nrf_gfx.c @@ -0,0 +1,628 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" + +#if NRF_MODULE_ENABLED(NRF_GFX) + +#include "nrf_gfx.h" +#include +#include "app_util_platform.h" +#include "nrf_assert.h" + +#define NRF_LOG_MODULE_NAME "GFX" +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +static inline void pixel_draw(nrf_lcd_t const * p_instance, + uint16_t x, + uint16_t y, + uint32_t color) +{ + uint16_t lcd_width = nrf_gfx_width_get(p_instance); + uint16_t lcd_height = nrf_gfx_height_get(p_instance); + + if ((x >= lcd_width) || (y >= lcd_height)) + { + return; + } + + p_instance->lcd_pixel_draw(x, y, color); +} + +static void rect_draw(nrf_lcd_t const * p_instance, + uint16_t x, + uint16_t y, + uint16_t width, + uint16_t height, + uint32_t color) +{ + uint16_t lcd_width = nrf_gfx_width_get(p_instance); + uint16_t lcd_height = nrf_gfx_height_get(p_instance); + + if ((x >= lcd_width) || (y >= lcd_height)) + { + return; + } + + if (width > (lcd_width - x)) + { + width = lcd_width - x; + } + + if (height > (lcd_height - y)) + { + height = lcd_height - y; + } + + p_instance->lcd_rect_draw(x, y, width, height, color); +} + +static void line_draw(nrf_lcd_t const * p_instance, + uint16_t x_0, + uint16_t y_0, + uint16_t x_1, + int16_t y_1, + uint32_t color) +{ + uint16_t x = x_0; + uint16_t y = y_0; + int16_t d; + int16_t d_1; + int16_t d_2; + int16_t ai; + int16_t bi; + int16_t xi = (x_0 < x_1) ? 1 : (-1); + int16_t yi = (y_0 < y_1) ? 1 : (-1); + bool swapped = false; + + d_1 = abs(x_1 - x_0); + d_2 = abs(y_1 - y_0); + + pixel_draw(p_instance, x, y, color); + + if (d_1 < d_2) + { + d_1 = d_1 ^ d_2; + d_2 = d_1 ^ d_2; + d_1 = d_2 ^ d_1; + swapped = true; + } + + ai = (d_2 - d_1) * 2; + bi = d_2 * 2; + d = bi - d_1; + + while ((y != y_1) || (x != x_1)) + { + if (d >= 0) + { + x += xi; + y += yi; + d += ai; + } + else + { + d += bi; + if (swapped) + { + y += yi; + } + else + { + x += xi; + } + } + pixel_draw(p_instance, x, y, color); + } +} + +static void write_character(nrf_lcd_t const * p_instance, + nrf_gfx_font_desc_t const * p_font, + uint8_t character, + uint16_t * p_x, + uint16_t y, + uint16_t font_color) +{ + uint8_t char_idx = character - p_font->startChar; + uint16_t bytes_in_line = CEIL_DIV(p_font->charInfo[char_idx].widthBits, 8); + + if (character == ' ') + { + *p_x += p_font->height / 2; + return; + } + + for (uint16_t i = 0; i < p_font->height; i++) + { + for (uint16_t j = 0; j < bytes_in_line; j++) + { + for (uint8_t k = 0; k < 8; k++) + { + if ((1 << (7 - k)) & + p_font->data[p_font->charInfo[char_idx].offset + i * bytes_in_line + j]) + { + pixel_draw(p_instance, *p_x + j * 8 + k, y + i, font_color); + } + } + } + } + + *p_x += p_font->charInfo[char_idx].widthBits + p_font->spacePixels; +} + +ret_code_t nrf_gfx_init(nrf_lcd_t const * p_instance) +{ + ASSERT(p_instance != NULL); + ASSERT(p_instance->p_lcd_cb->state == NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_instance->lcd_init != NULL); + ASSERT(p_instance->lcd_uninit != NULL); + ASSERT(p_instance->lcd_pixel_draw != NULL); + ASSERT(p_instance->lcd_rect_draw != NULL); + ASSERT(p_instance->lcd_display != NULL); + ASSERT(p_instance->lcd_rotation_set != NULL); + ASSERT(p_instance->lcd_display_invert != NULL); + ASSERT(p_instance->p_lcd_cb != NULL); + + ret_code_t err_code; + + err_code = p_instance->lcd_init(); + + if (err_code == NRF_SUCCESS) + { + p_instance->p_lcd_cb->state = NRF_DRV_STATE_INITIALIZED; + } + + return err_code; +} + +void nrf_gfx_uninit(nrf_lcd_t const * p_instance) +{ + ASSERT(p_instance != NULL); + ASSERT(p_instance->p_lcd_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + p_instance->p_lcd_cb->state = NRF_DRV_STATE_UNINITIALIZED; + + p_instance->lcd_uninit(); +} + +void nrf_gfx_point_draw(nrf_lcd_t const * p_instance, + nrf_gfx_point_t const * p_point, + uint32_t color) +{ + ASSERT(p_instance != NULL); + ASSERT(p_instance->p_lcd_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_point != NULL); + + pixel_draw(p_instance, p_point->x, p_point->y, color); +} + +ret_code_t nrf_gfx_line_draw(nrf_lcd_t const * p_instance, + nrf_gfx_line_t const * p_line, + uint32_t color) +{ + ASSERT(p_instance != NULL); + ASSERT(p_instance->p_lcd_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_line != NULL); + + uint16_t x_thick = 0; + uint16_t y_thick = 0; + + if (((p_line->x_start > nrf_gfx_width_get(p_instance)) && + (p_line->x_end > nrf_gfx_height_get(p_instance))) || + ((p_line->y_start > nrf_gfx_width_get(p_instance)) && + (p_line->y_end > nrf_gfx_height_get(p_instance)))) + { + return NRF_ERROR_INVALID_PARAM; + } + + if (abs(p_line->x_start - p_line->x_end) > abs(p_line->y_start - p_line->y_end)) + { + y_thick = p_line->thickness; + } + else + { + x_thick = p_line->thickness; + } + + if ((p_line->x_start == p_line->x_end) || (p_line->y_start == p_line->y_end)) + { + rect_draw(p_instance, + p_line->x_start, + p_line->y_start, + abs(p_line->x_end - p_line->x_start) + x_thick, + abs(p_line->y_end - p_line->y_start) + y_thick, + color); + } + else + { + if (x_thick > 0) + { + for (uint16_t i = 0; i < p_line->thickness; i++) + { + line_draw(p_instance, + p_line->x_start + i, + p_line->y_start, + p_line->x_end + i, + p_line->y_end, + color); + } + } + else if (y_thick > 0) + { + for (uint16_t i = 0; i < p_line->thickness; i++) + { + line_draw(p_instance, + p_line->x_start, + p_line->y_start + i, + p_line->x_end, + p_line->y_end + i, + color); + } + } + else + { + line_draw(p_instance, + p_line->x_start + x_thick, + p_line->y_start + y_thick, + p_line->x_end + x_thick, + p_line->y_end + y_thick, + color); + } + } + + return NRF_SUCCESS; +} + +ret_code_t nrf_gfx_circle_draw(nrf_lcd_t const * p_instance, + nrf_gfx_circle_t const * p_circle, + uint32_t color, + bool fill) +{ + ASSERT(p_instance != NULL); + ASSERT(p_instance->p_lcd_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_circle != NULL); + + int16_t y = 0; + int16_t err = 0; + int16_t x = p_circle->r; + + if ((p_circle->x - p_circle->r > nrf_gfx_width_get(p_instance)) || + (p_circle->y - p_circle->r > nrf_gfx_height_get(p_instance))) + { + return NRF_ERROR_INVALID_PARAM; + } + + while (x >= y) + { + if (fill) + { + if ((-y + p_circle->x < 0) || (-x + p_circle->x < 0)) + { + rect_draw(p_instance, 0, (-x + p_circle->y), (y + p_circle->x + 1), 1, color); + rect_draw(p_instance, 0, (-y + p_circle->y), (x + p_circle->x + 1), 1, color); + rect_draw(p_instance, 0, (y + p_circle->y), (x + p_circle->x + 1), 1, color); + rect_draw(p_instance, 0, (x + p_circle->y), (y + p_circle->x + 1), 1, color); + } + else + { + rect_draw(p_instance, (-y + p_circle->x), (-x + p_circle->y), (2 * y + 1), 1, color); + rect_draw(p_instance, (-x + p_circle->x), (-y + p_circle->y), (2 * x + 1), 1, color); + rect_draw(p_instance, (-x + p_circle->x), (y + p_circle->y), (2 * x + 1), 1, color); + rect_draw(p_instance, (-y + p_circle->x), (x + p_circle->y), (2 * y + 1), 1, color); + } + } + else + { + pixel_draw(p_instance, (y + p_circle->x), (x + p_circle->y), color); + pixel_draw(p_instance, (-y + p_circle->x), (x + p_circle->y), color); + pixel_draw(p_instance, (x + p_circle->x), (y + p_circle->y), color); + pixel_draw(p_instance, (-x + p_circle->x), (y + p_circle->y), color); + pixel_draw(p_instance, (-y + p_circle->x), (-x + p_circle->y), color); + pixel_draw(p_instance, (y + p_circle->x), (-x + p_circle->y), color); + pixel_draw(p_instance, (-x + p_circle->x), (-y + p_circle->y), color); + pixel_draw(p_instance, (x + p_circle->x), (-y + p_circle->y), color); + } + + if (err <= 0) + { + y += 1; + err += 2 * y + 1; + } + if (err > 0) + { + x -= 1; + err -= 2 * x + 1; + } + } + + return NRF_SUCCESS; +} + +ret_code_t nrf_gfx_rect_draw(nrf_lcd_t const * p_instance, + nrf_gfx_rect_t const * p_rect, + uint16_t thickness, + uint32_t color, + bool fill) +{ + ASSERT(p_instance != NULL); + ASSERT(p_instance->p_lcd_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_rect != NULL); + + uint16_t rect_width = p_rect->width - thickness; + uint16_t rect_height = p_rect->height - thickness; + + if ((p_rect->width == 1) || + (p_rect->height == 1) || + (thickness * 2 > p_rect->width) || + (thickness * 2 > p_rect->height) || + ((p_rect->x > nrf_gfx_width_get(p_instance)) && + (p_rect->y > nrf_gfx_height_get(p_instance)))) + { + return NRF_ERROR_INVALID_PARAM; + } + + + if (fill) + { + rect_draw(p_instance, + p_rect->x, + p_rect->y, + p_rect->width, + p_rect->height, + color); + } + else + { + nrf_gfx_line_t line; + + // Top horizontal line. + line.x_start = p_rect->x; + line.y_start = p_rect->y; + line.x_end = p_rect->x + p_rect->width; + line.y_end = p_rect->y; + line.thickness = thickness; + (void)nrf_gfx_line_draw(p_instance, &line, color); + // Bottom horizontal line. + line.x_start = p_rect->x; + line.y_start = p_rect->y + rect_height; + line.x_end = p_rect->x + p_rect->width; + line.y_end = p_rect->y + rect_height; + (void)nrf_gfx_line_draw(p_instance, &line, color); + // Left vertical line. + line.x_start = p_rect->x; + line.y_start = p_rect->y + thickness; + line.x_end = p_rect->x; + line.y_end = p_rect->y + rect_height; + (void)nrf_gfx_line_draw(p_instance, &line, color); + // Right vertical line. + line.x_start = p_rect->x + rect_width; + line.y_start = p_rect->y + thickness; + line.x_end = p_rect->x + rect_width; + line.y_end = p_rect->y + rect_height; + (void)nrf_gfx_line_draw(p_instance, &line, color); + } + + return NRF_SUCCESS; +} + +void nrf_gfx_screen_fill(nrf_lcd_t const * p_instance, uint32_t color) +{ + rect_draw(p_instance, 0, 0, nrf_gfx_width_get(p_instance), nrf_gfx_height_get(p_instance), color); +} + +ret_code_t nrf_gfx_bmp565_draw(nrf_lcd_t const * p_instance, + nrf_gfx_rect_t const * p_rect, + uint16_t const * img_buf) +{ + ASSERT(p_instance != NULL); + ASSERT(p_instance->p_lcd_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_rect != NULL); + ASSERT(img_buf != NULL); + + if ((p_rect->x > nrf_gfx_width_get(p_instance)) || (p_rect->y > nrf_gfx_height_get(p_instance))) + { + return NRF_ERROR_INVALID_PARAM; + } + + size_t idx; + uint16_t pixel; + uint8_t padding = p_rect->width % 2; + + for (int32_t i = 0; i < p_rect->height; i++) + { + for (uint32_t j = 0; j < p_rect->width; j++) + { + idx = (uint32_t)((p_rect->height - i - 1) * (p_rect->width + padding) + j); + + pixel = (img_buf[idx] >> 8) | (img_buf[idx] << 8); + + pixel_draw(p_instance, p_rect->x + j, p_rect->y + i, pixel); + } + } + + return NRF_SUCCESS; +} + +void nrf_gfx_background_set(nrf_lcd_t const * p_instance, uint16_t const * img_buf) +{ + ASSERT(p_instance != NULL); + ASSERT(p_instance->p_lcd_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(img_buf != NULL); + + const nrf_gfx_rect_t rectangle = + { + .x = 0, + .y = 0, + .width = nrf_gfx_width_get(p_instance), + .height = nrf_gfx_height_get(p_instance) + }; + + (void)nrf_gfx_bmp565_draw(p_instance, &rectangle, img_buf); +} + +void nrf_gfx_display(nrf_lcd_t const * p_instance) +{ + ASSERT(p_instance != NULL); + + p_instance->lcd_display(); +} + +void nrf_gfx_rotation_set(nrf_lcd_t const * p_instance, nrf_lcd_rotation_t rotation) +{ + ASSERT(p_instance != NULL); + ASSERT(p_instance->p_lcd_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + bool rotated = (bool)(p_instance->p_lcd_cb->rotation % 2); + + uint16_t height = !rotated ? nrf_gfx_height_get(p_instance) : + nrf_gfx_width_get(p_instance); + uint16_t width = !rotated ? nrf_gfx_width_get(p_instance) : + nrf_gfx_height_get(p_instance); + + p_instance->p_lcd_cb->rotation = rotation; + + switch (rotation) { + case NRF_LCD_ROTATE_0: + p_instance->p_lcd_cb->height = height; + p_instance->p_lcd_cb->width = width; + break; + case NRF_LCD_ROTATE_90: + p_instance->p_lcd_cb->height = width; + p_instance->p_lcd_cb->width = height; + break; + case NRF_LCD_ROTATE_180: + p_instance->p_lcd_cb->height = height; + p_instance->p_lcd_cb->width = width; + break; + case NRF_LCD_ROTATE_270: + p_instance->p_lcd_cb->height = width; + p_instance->p_lcd_cb->width = height; + break; + default: + break; + } + + p_instance->lcd_rotation_set(rotation); +} + +void nrf_gfx_invert(nrf_lcd_t const * p_instance, bool invert) +{ + ASSERT(p_instance != NULL); + + p_instance->lcd_display_invert(invert); +} + +ret_code_t nrf_gfx_print(nrf_lcd_t const * p_instance, + nrf_gfx_point_t const * p_point, + uint16_t font_color, + const char * string, + const nrf_gfx_font_desc_t * p_font, + bool wrap) +{ + ASSERT(p_instance != NULL); + ASSERT(p_instance->p_lcd_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_point != NULL); + ASSERT(string != NULL); + ASSERT(p_font != NULL); + + uint16_t x = p_point->x; + uint16_t y = p_point->y; + + if (y > (nrf_gfx_height_get(p_instance) - p_font->height)) + { + // Not enough space to write even single char. + return NRF_ERROR_INVALID_PARAM; + } + + for (size_t i = 0; string[i] != '\0' ; i++) + { + if (string[i] == '\n') + { + x = p_point->x; + y += p_font->height + p_font->height / 10; + } + else + { + write_character(p_instance, p_font, (uint8_t)string[i], &x, y, font_color); + } + + uint8_t char_idx = string[i] - p_font->startChar; + uint16_t char_width = string[i] == ' ' ? (p_font->height / 2) : + p_font->charInfo[char_idx].widthBits; + + if (x > (nrf_gfx_width_get(p_instance) - char_width)) + { + if (wrap) + { + x = p_point->x; + y += p_font->height + p_font->height / 10; + } + else + { + break; + } + + if (y > (nrf_gfx_height_get(p_instance) - p_font->height)) + { + break; + } + } + } + + return NRF_SUCCESS; +} + +uint16_t nrf_gfx_height_get(nrf_lcd_t const * p_instance) +{ + ASSERT(p_instance != NULL); + + return p_instance->p_lcd_cb->height; +} + +uint16_t nrf_gfx_width_get(nrf_lcd_t const * p_instance) +{ + ASSERT(p_instance != NULL); + + return p_instance->p_lcd_cb->width; +} + +#endif //NRF_MODULE_ENABLED(NRF_GFX) + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gfx/nrf_gfx.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gfx/nrf_gfx.h new file mode 100644 index 0000000000000000000000000000000000000000..d06cd3bd5cde3fe4418452f0a2c78a1a44d09e89 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gfx/nrf_gfx.h @@ -0,0 +1,320 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef NRF_GFX_H__ +#define NRF_GFX_H__ + +#include +#include +#include "sdk_errors.h" +#include "nrf_lcd.h" +#include "nrf_font.h" + +/** @file + * + * @addtogroup ili9341_config + * @ingroup ext_drivers + * + * @addtogroup st7735_config + * @ingroup ext_drivers + * + * @defgroup nrf_gfx GFX Library + * @{ + * @ingroup app_common + * + * @brief Module for drawing graphical objects like lines, circles, and rectangles. + Provides support for different fonts. + */ + +/** + * @brief GFX point object structure. + */ +typedef struct +{ + uint16_t x; /**< Horizontal coordinate of the point where to start drawing the object. */ + uint16_t y; /**< Vertical coordinate of the point where to start drawing the object. */ +}nrf_gfx_point_t; + +/** + * @brief GFX line object structure. + */ +typedef struct +{ + uint16_t x_start; /**< Horizontal coordinate of the point where to start drawing the object. */ + uint16_t y_start; /**< Vertical coordinate of the point where to start drawing the object. */ + uint16_t x_end; /**< Horizontal coordinate of the point where to end drawing the object. */ + uint16_t y_end; /**< Vertical coordinate of the point where to end drawing the object. */ + uint16_t thickness; /**< Thickness of the border of the object. */ +}nrf_gfx_line_t; + +/** + * @brief GFX circle object structure. + */ +typedef struct +{ + uint16_t x; /**< Horizontal coordinate of the centre of the object. */ + uint16_t y; /**< Vertical coordinate of the centre of the object. */ + uint16_t r; /**< Radius of the object. */ +}nrf_gfx_circle_t; + +/** + * @brief GFX rectangle object structure. + */ +typedef struct +{ + uint16_t x; /**< Horizontal coordinate of the point where to start drawing the object. */ + uint16_t y; /**< Vertical coordinate of the point where to start drawing the object. */ + uint16_t width; /**< Width of the object. */ + uint16_t height; /**< Height of the object. */ +}nrf_gfx_rect_t; + +/** + * @defgroup nrf_gfx_macros Macros for defining new graphic objects + * @{ + */ +#define NRF_GFX_POINT(_x, _y) \ + { \ + .x = (_x), \ + .y = (_y) \ + } + +#define NRF_GFX_LINE(_x_0, _y_0, _x_1, _y_1, _thickness) \ + { \ + .x_start = (_x_0), \ + .y_start = (_y_0), \ + .x_end = (_x_1), \ + .y_end = (_y_1), \ + .thickness = (_thickness) \ + } + +#define NRF_GFX_CIRCLE(_x, _y, _radius) \ + { \ + .x = (_x), \ + .y = (_y), \ + .r = (_radius) \ + } + +#define NRF_GFX_RECT(_x, _y, _width, _height) \ + { \ + .x = (_x), \ + .y = (_y), \ + .width = (_width), \ + .height = (_height) \ + } +/* @} */ + +/** + * @brief Font descriptor type. + */ +typedef FONT_INFO nrf_gfx_font_desc_t; + +/** + * @brief Function for initializing the GFX library. + * + * @param[in] p_instance Pointer to the LCD instance. + * + * @return Values returned by @ref nrf_lcd_t::lcd_init. + */ +ret_code_t nrf_gfx_init(nrf_lcd_t const * p_instance); + +/** + * @brief Function for uninitializing the GFX library. + * + * @param[in] p_instance Pointer to the LCD instance. + * + * @return Values returned by @ref nrf_lcd_t::lcd_uninit. + */ +void nrf_gfx_uninit(nrf_lcd_t const * p_instance); + +/** + * @brief Function for drawing a point. + * + * @param[in] p_instance Pointer to the LCD instance. + * @param[in] p_point Pointer to the point object. + * @param[in] color Color of the object in the display accepted format. + */ +void nrf_gfx_point_draw(nrf_lcd_t const * p_instance, nrf_gfx_point_t const * p_point, uint32_t color); + +/** + * @brief Function for drawing a line. + * + * @param[in] p_instance Pointer to the LCD instance. + * @param[in] p_line Pointer to the line object. + * @param[in] color Color of the object in the display accepted format. + * + * @retval NRF_ERROR_INVALID_PARAM If object position is not on the screen. + * @retval NRF_SUCCESS If object was successfully drawn. + */ +ret_code_t nrf_gfx_line_draw(nrf_lcd_t const * p_instance, nrf_gfx_line_t const * p_line, uint32_t color); + +/** + * @brief Function for drawing a circle. + * + * @param[in] p_instance Pointer to the LCD instance. + * @param[in] p_circle Pointer to the circle object. + * @param[in] color Color of the object in the display accepted format. + * @param[in] fill If true, the circle will be filled. + * + * @retval NRF_ERROR_INVALID_PARAM If object position is not on the screen. + * @retval NRF_SUCCESS If object was successfully drawn. + * + * @note The height and width of the drawn circle are determined by: radius * 2 + 1. + * + */ +ret_code_t nrf_gfx_circle_draw(nrf_lcd_t const * p_instance, + nrf_gfx_circle_t const * p_circle, + uint32_t color, + bool fill); + +/** + * @brief Function for drawing a rectangle. + * + * @param[in] p_instance Pointer to the LCD instance. + * @param[in] p_rect Pointer to the rectangle object. + * @param[in] thickness Thickness of the rectangle border. + * @param[in] color Color of the object in the display accepted format. + * @param[in] fill If true, the rectangle will be filled. + * + * @retval NRF_ERROR_INVALID_PARAM If object position is not on the screen. + * @retval NRF_SUCCESS If object was successfully drawn. + */ +ret_code_t nrf_gfx_rect_draw(nrf_lcd_t const * p_instance, + nrf_gfx_rect_t const * p_rect, + uint16_t thickness, + uint32_t color, + bool fill); + +/** + * @brief Function for filling the screen with selected color. + * + * @param[in] p_instance Pointer to the LCD instance. + * @param[in] color Color of the screen in the display accepted format. + */ +void nrf_gfx_screen_fill(nrf_lcd_t const * p_instance, uint32_t color); + +/** + * @brief Function for drawing an image from a .bmp file. + * + * Data in img_buf is expected to be stored in 2-byte samples, little endianness, RGB565 format. + * Pointer should skip the header and point to the first byte of data. + * + * @param[in] p_instance Pointer to the LCD instance. + * @param[in] p_rect Pointer to the rectangle object. + * @param[in] img_buf Pointer to data from the .bmp file. + * + * @note Only compatible with displays that accept pixels in RGB565 format. + */ +ret_code_t nrf_gfx_bmp565_draw(nrf_lcd_t const * p_instance, + nrf_gfx_rect_t const * p_rect, + uint16_t const * img_buf); + +/** + * @brief Function for drawing an image from a .bmp file. + * + * Data in img_buf is expected to be stored in 2-byte samples, little endianness, RGB565 format. + * Pointer should skip the header and point to the first byte of data. + * + * @param[in] p_instance Pointer to the LCD instance. + * @param[in] img_buf Pointer to data from the .bmp file. + * + * @note Only compatible with displays that accept pixels in RGB565 format. + */ +void nrf_gfx_background_set(nrf_lcd_t const * p_instance, uint16_t const * img_buf); + +/** + * @brief Function for displaying data from an internal frame buffer. + * + * @param[in] p_instance Pointer to the LCD instance. + */ +void nrf_gfx_display(nrf_lcd_t const * p_instance); + +/** + * @brief Function for setting screen rotation. + * + * @param[in] p_instance Pointer to the LCD instance. + * @param[in] rotation Rotation to be made. + */ +void nrf_gfx_rotation_set(nrf_lcd_t const * p_instance, nrf_lcd_rotation_t rotation); + +/** + * @brief Function for setting inversion of colors. + * + * @param[in] p_instance Pointer to the LCD instance. + * @param[in] invert If true, inversion will be set. + */ +void nrf_gfx_invert(nrf_lcd_t const * p_instance, bool invert); + +/** + * @brief Function for printing a string to the screen. + * + * @param[in] p_instance Pointer to the LCD instance. + * @param[in] p_point Pointer to the point where to start drawing the object. + * @param[in] font_color Color of the font in the display accepted format. + * @param[in] p_string Pointer to the string. + * @param[in] p_font Pointer to the font descriptor. + * @param[in] wrap If true, the string will be wrapped to the new line. + */ +ret_code_t nrf_gfx_print(nrf_lcd_t const * p_instance, + nrf_gfx_point_t const * p_point, + uint16_t font_color, + const char * p_string, + const nrf_gfx_font_desc_t * p_font, + bool wrap); + +/** + * @brief Function for getting the height of the screen. + * + * @param[in] p_instance Pointer to the LCD instance. + * + */ +uint16_t nrf_gfx_height_get(nrf_lcd_t const * p_instance); + +/** + * @brief Function for getting the width of the screen. + * + * @param[in] p_instance Pointer to the LCD instance. + * + */ +uint16_t nrf_gfx_width_get(nrf_lcd_t const * p_instance); + +/* @} */ + +#endif //NRF_GFX_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gfx/nrf_lcd.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gfx/nrf_lcd.h new file mode 100644 index 0000000000000000000000000000000000000000..8e37cae928eade76c5788349a09b1c656d82fdb7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gfx/nrf_lcd.h @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef NRF_LCD_H__ +#define NRF_LCD_H__ + +#include "nrf_drv_common.h" + +/** @file + * + * @defgroup nrf_lcd LCD Library + * @{ + * @ingroup nrf_gfx + * + * @brief This module defines generic API for LCDs. + */ + +/** + * @brief Enumerator with available rotations. + */ +typedef enum{ + NRF_LCD_ROTATE_0 = 0, /**< Rotate 0 degrees, clockwise. */ + NRF_LCD_ROTATE_90, /**< Rotate 90 degrees, clockwise. */ + NRF_LCD_ROTATE_180, /**< Rotate 180 degrees, clockwise. */ + NRF_LCD_ROTATE_270 /**< Rotate 270 degrees, clockwise. */ +}nrf_lcd_rotation_t; + +/** + * @brief LCD instance control block. + */ +typedef struct +{ + nrf_drv_state_t state; /**< State of LCD instance. */ + uint16_t height; /**< LCD height. */ + uint16_t width; /**< LCD width. */ + nrf_lcd_rotation_t rotation; /**< LCD rotation. */ +}lcd_cb_t; + +/** + * @brief LCD instance type. + * + * This structure provides generic API for LCDs. + */ +typedef struct +{ + /** + * @brief Function for initializing the LCD controller. + */ + ret_code_t (* lcd_init)(void); + + /** + * @brief Function for uninitializing the LCD controller. + */ + void (* lcd_uninit)(void); + + /** + * @brief Function for drawing a single pixel. + * + * @param[in] x Horizontal coordinate of the pixel. + * @param[in] y Vertical coordinate of the pixel. + * @param[in] color Color of the pixel in LCD accepted format. + */ + void (* lcd_pixel_draw)(uint16_t x, uint16_t y, uint32_t color); + + /** + * @brief Function for drawing a filled rectangle. + * + * @param[in] x Horizontal coordinate of the point where to start drawing the rectangle. + * @param[in] y Vertical coordinate of the point where to start drawing the rectangle. + * @param[in] width Width of the image. + * @param[in] height Height of the image. + * @param[in] color Color with which to fill the rectangle in LCD accepted format. + */ + void (* lcd_rect_draw)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color); + + /** + * @brief Function for displaying data from an internal frame buffer. + * + * This function may be used when functions for drawing do not write directly to + * LCD but to an internal frame buffer. It could be implemented to write data from this + * buffer to LCD. + */ + void (* lcd_display)(void); + + /** + * @brief Function for rotating the screen. + * + * @param[in] rotation Rotation as enumerated value. + */ + void (* lcd_rotation_set)(nrf_lcd_rotation_t rotation); + + /** + * @brief Function for setting inversion of colors on the screen. + * + * @param[in] invert If true, inversion will be set. + */ + void (* lcd_display_invert)(bool invert); + + /** + * @brief Pointer to the LCD instance control block. + */ + lcd_cb_t * p_lcd_cb; +}nrf_lcd_t; + +/* @} */ + +#endif // NRF_LCD_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gpiote/app_gpiote.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gpiote/app_gpiote.c new file mode 100644 index 0000000000000000000000000000000000000000..6544e66690c264d335bea3f53c7f20ad693fc4ec --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gpiote/app_gpiote.c @@ -0,0 +1,296 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_GPIOTE) +#include "app_gpiote.h" +#include "nrf_drv_gpiote.h" +#include "nrf_bitmask.h" +#define MODULE_INITIALIZED (mp_users != NULL) /**< Macro designating whether the module has been initialized properly. */ + +/**@brief GPIOTE user type. */ +typedef struct +{ + uint32_t pins_mask[GPIO_COUNT]; /**< Mask defining which pins user wants to monitor. */ + uint32_t pins_low_to_high_mask[GPIO_COUNT]; /**< Mask defining which pins will generate events to this user when toggling low->high. */ + uint32_t pins_high_to_low_mask[GPIO_COUNT]; /**< Mask defining which pins will generate events to this user when toggling high->low. */ + uint32_t sense_high_pins[GPIO_COUNT]; /**< Mask defining which pins are configured to generate GPIOTE interrupt on transition to high level. */ + app_gpiote_event_handler_t event_handler; /**< Pointer to function to be executed when an event occurs. */ + bool enabled; /**< Flag indicating whether user is enabled. */ +} gpiote_user_t; + +STATIC_ASSERT(sizeof(gpiote_user_t) <= GPIOTE_USER_NODE_SIZE); +STATIC_ASSERT(sizeof(gpiote_user_t) % 4 == 0); + +static uint8_t m_user_array_size; /**< Size of user array. */ +static uint8_t m_user_count; /**< Number of registered users. */ +static gpiote_user_t * mp_users = NULL; /**< Array of GPIOTE users. */ +static uint32_t m_pins[GPIO_COUNT]; /**< Mask of initialized pins. */ +static uint32_t m_last_pins_state[GPIO_COUNT]; /**< Most recent state of pins. */ + +void gpiote_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) +{ + int i; + uint32_t pin_mask[GPIO_COUNT] = {0}; + uint32_t empty_pin_mask[GPIO_COUNT] = {0}; + nrf_bitmask_bit_set(pin, pin_mask); + bool hitolo = nrf_bitmask_bit_is_set(pin, m_last_pins_state); + nrf_gpio_ports_read(0, GPIO_COUNT, m_last_pins_state); + + for (i = 0; i < m_user_count; i++) + { + if (mp_users[i].enabled && nrf_bitmask_bit_is_set(pin, mp_users[i].pins_mask)) + { + if ( + nrf_bitmask_bit_is_set(pin, mp_users[i].pins_high_to_low_mask) + && hitolo) + { + mp_users[i].event_handler(empty_pin_mask,pin_mask); + } + else if ( + nrf_bitmask_bit_is_set(pin, mp_users[i].pins_low_to_high_mask) + && !hitolo) + { + mp_users[i].event_handler(pin_mask,empty_pin_mask); + } + } + } +} + +uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer) +{ + uint32_t ret_code = NRF_SUCCESS; + + if (p_buffer == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Check that buffer is correctly aligned. + if (!is_word_aligned(p_buffer)) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Initialize file globals. + mp_users = (gpiote_user_t *)p_buffer; + m_user_array_size = max_users; + m_user_count = 0; + memset(m_pins,0, sizeof(m_pins)); + + memset(mp_users, 0, m_user_array_size * sizeof(gpiote_user_t)); + + if (nrf_drv_gpiote_is_init()==false) + { + ret_code = nrf_drv_gpiote_init(); + } + + return ret_code; +} + +uint32_t app_gpiote_user_register(app_gpiote_user_id_t * p_user_id, + uint32_t const * p_pins_low_to_high_mask, + uint32_t const * p_pins_high_to_low_mask, + app_gpiote_event_handler_t event_handler) +{ + uint32_t user_pin_mask[GPIO_COUNT]; + uint32_t ret_val = NRF_SUCCESS; + + // Check state and parameters. + VERIFY_MODULE_INITIALIZED(); + + if (event_handler == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + if (m_user_count >= m_user_array_size) + { + return NRF_ERROR_NO_MEM; + } + + nrf_bitmask_masks_or(p_pins_low_to_high_mask, p_pins_high_to_low_mask, + user_pin_mask, sizeof(user_pin_mask)); + // Allocate new user. + memcpy(mp_users[m_user_count].pins_mask, + user_pin_mask, sizeof(mp_users[m_user_count].pins_mask)); + memcpy(mp_users[m_user_count].pins_low_to_high_mask, + p_pins_low_to_high_mask, sizeof(mp_users[m_user_count].pins_low_to_high_mask)); + memcpy(mp_users[m_user_count].pins_high_to_low_mask, + p_pins_high_to_low_mask, sizeof(mp_users[m_user_count].pins_high_to_low_mask)); + mp_users[m_user_count].event_handler = event_handler; + mp_users[m_user_count].enabled = false; + + *p_user_id = m_user_count++; + + uint32_t i; + const nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); + + uint32_t num_of_pins = NUMBER_OF_PINS ; + for (i = 0; i < num_of_pins; i++) + { + if (nrf_bitmask_bit_is_set(i, user_pin_mask) && + !nrf_bitmask_bit_is_set(i, m_pins)) + { + ret_val = nrf_drv_gpiote_in_init(i, &config, gpiote_handler); + VERIFY_SUCCESS(ret_val); + nrf_bitmask_bit_set(i, m_pins); + } + } + return ret_val; +} + +__STATIC_INLINE uint32_t error_check(app_gpiote_user_id_t user_id) +{ + // Check state and parameters. + VERIFY_MODULE_INITIALIZED(); + + if (user_id >= m_user_count) + { + return NRF_ERROR_INVALID_PARAM; + } + return NRF_SUCCESS; +} +/** + * @brief Function for enabling event on pin (if not yet enabled) or disabling the event if no other + * user requires it. + * + * @param pin Pin to enable + * @param enable If true function will attempt to enable the pin else it will attempt to disable it. + */ +static void pin_event_enable(uint32_t pin, bool enable) +{ + uint32_t i; + bool enabled = false; + //search if any user already enabled given pin + for (i = 0; i < m_user_count; i++) + { + if (mp_users[i].enabled && + nrf_bitmask_bit_is_set(pin, mp_users[i].pins_mask)) + { + enabled = true; + break; + } + } + if (!enabled) + { + if (enable) + { + nrf_gpio_ports_read(0, GPIO_COUNT, m_last_pins_state); + nrf_drv_gpiote_in_event_enable(pin, true); + } + else + { + nrf_drv_gpiote_in_event_disable(pin); + } + } +} + +/** + * @brief Function for enabling or disabling events for pins used by the user. + * + * Function will enable pin events only if they are not yet enabled. Function will disable pin + * events only if there is no other enabled user that is using them. + * + * @param user_id User id. + * @param enable If true function will attempt to enable the pin else it will attempt to disable it. + */ +static uint32_t user_enable(app_gpiote_user_id_t user_id, bool enable) +{ + uint32_t ret_code = error_check(user_id); + + if (ret_code == NRF_SUCCESS) + { + uint32_t i; + for (i = 0; i < NUMBER_OF_PINS; i++) + { + if (nrf_bitmask_bit_is_set(i, mp_users[user_id].pins_mask)) + { + pin_event_enable(i, enable); + } + } + } + return ret_code; +} + +uint32_t app_gpiote_user_enable(app_gpiote_user_id_t user_id) +{ + uint32_t ret_code = NRF_SUCCESS; + + if (mp_users[user_id].enabled == false) + { + ret_code = user_enable(user_id, true); + VERIFY_SUCCESS(ret_code); + + mp_users[user_id].enabled = true; + return ret_code; + } + else + { + return ret_code; + } +} + +uint32_t app_gpiote_user_disable(app_gpiote_user_id_t user_id) +{ + uint32_t ret_code = NRF_SUCCESS; + + if (mp_users[user_id].enabled) + { + mp_users[user_id].enabled = false; + ret_code = user_enable(user_id, false); + } + + return ret_code; +} + +uint32_t app_gpiote_pins_state_get(app_gpiote_user_id_t user_id, uint32_t * p_pins) +{ + gpiote_user_t * p_user; + uint32_t ret_code = error_check(user_id); + + if (ret_code == NRF_SUCCESS) + { + p_user = &mp_users[user_id]; + + nrf_gpio_ports_read(0, GPIO_COUNT, p_pins); + nrf_bitmask_masks_and(p_pins, p_user->pins_mask, p_pins, sizeof(p_user->pins_mask)); + } + return ret_code; +} +#endif //NRF_MODULE_ENABLED(APP_GPIOTE) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gpiote/app_gpiote.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gpiote/app_gpiote.h new file mode 100644 index 0000000000000000000000000000000000000000..5c70da295858d8149781e94cd5e74ca39674d4e9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/gpiote/app_gpiote.h @@ -0,0 +1,205 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup app_gpiote GPIOTE Handler + * @{ + * @ingroup app_common + * + * @brief GPIOTE handler module. + * + * @details The GPIOTE handler allows several modules ("users") to share the GPIOTE interrupt, + * each user defining a set of pins able to generate events to the user. + * When a GPIOTE interrupt occurs, the GPIOTE interrupt handler will call the event handler + * of each user for which at least one of the pins generated an event. + * + * The GPIOTE users are responsible for configuring all their corresponding pins, except + * the SENSE field, which should be initialized to GPIO_PIN_CNF_SENSE_Disabled. + * The SENSE field will be updated by the GPIOTE module when it is enabled or disabled, + * and also while it is enabled. + * + * The module specifies on which pins events should be generated if the pin(s) goes + * from low->high or high->low or both directions. + * + * @note Even if the application is using the @ref app_scheduler, the GPIOTE event handlers will + * be called directly from the GPIOTE interrupt handler. + * + * @warning If multiple users registers for the same pins the behavior for those pins are undefined. + */ + +#ifndef APP_GPIOTE_H__ +#define APP_GPIOTE_H__ + +#include +#include +#include "nrf.h" +#include "app_error.h" +#include "app_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GPIOTE_USER_NODE_SIZE ((4*sizeof(uint32_t)*GPIO_COUNT)+8) /**< Size of app_gpiote.gpiote_user_t (only for use inside APP_GPIOTE_BUF_SIZE()). */ + +/**@brief Compute number of bytes required to hold the GPIOTE data structures. + * + * @param[in] MAX_USERS Maximum number of GPIOTE users. + * + * @retval Required buffer size (in bytes). + */ +#define APP_GPIOTE_BUF_SIZE(MAX_USERS) ((MAX_USERS) * GPIOTE_USER_NODE_SIZE) + +typedef uint8_t app_gpiote_user_id_t; + +/**@brief GPIOTE event handler type. */ +typedef void (*app_gpiote_event_handler_t)(uint32_t const * p_event_pins_low_to_high, + uint32_t const * p_event_pins_high_to_low); + +/**@brief GPIOTE input event handler type. */ +typedef void (*app_gpiote_input_event_handler_t)(void); + +/**@brief Macro for initializing the GPIOTE module. + * + * @details It will handle dimensioning and allocation of the memory buffer required by the module, + * making sure that the buffer is correctly aligned. + * + * @param[in] MAX_USERS Maximum number of GPIOTE users. + * + * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it + * several times as long as it is from the same location, e.g. to do a reinitialization). + */ +/*lint -emacro(506, APP_GPIOTE_INIT) */ /* Suppress "Constant value Boolean */ +#define APP_GPIOTE_INIT(MAX_USERS) \ + do \ + { \ + static uint32_t app_gpiote_buf[CEIL_DIV(APP_GPIOTE_BUF_SIZE(MAX_USERS), sizeof(uint32_t))];\ + uint32_t ERR_CODE = app_gpiote_init((MAX_USERS), app_gpiote_buf); \ + APP_ERROR_CHECK(ERR_CODE); \ + } while (0) + +/**@brief Function for initializing the GPIOTE module. + * + * @note Normally initialization should be done using the APP_GPIOTE_INIT() macro, as that will + * allocate the buffer needed by the GPIOTE module (including aligning the buffer correctly). + * + * @param[in] max_users Maximum number of GPIOTE users. + * @param[in] p_buffer Pointer to memory buffer for internal use in the app_gpiote + * module. The size of the buffer can be computed using the + * APP_GPIOTE_BUF_SIZE() macro. The buffer must be aligned to + * a 4 byte boundary. + * + * @retval NRF_SUCCESS Successful initialization. + * @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte + * boundary). + */ +uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer); + +/**@brief Function for registering a GPIOTE user. + * + * @param[out] p_user_id Id for the new GPIOTE user. + * @param[in] p_pins_low_to_high_mask Pointer to word array with mask defining which pins + * will generate events to this user when state is changed + * from low->high. Size of array depends on number of ports + * in the device. + * @param[in] p_pins_high_to_low_mask Pointer to word array with mask defining which pins + * will generate events to this user when state is changed + * from high->low. Size of array depends on number of ports + * in the device. + * @param[in] event_handler Pointer to function to be executed when an event occurs. + * + * @retval NRF_SUCCESS Successful initialization. + * @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte boundary). + * @retval NRF_ERROR_INALID_STATE If @ref app_gpiote_init has not been called on the GPIOTE + * module. + * @retval NRF_ERROR_NO_MEM Returned if the application tries to register more users + * than defined when the GPIOTE module was initialized in + * @ref app_gpiote_init. + */ +uint32_t app_gpiote_user_register(app_gpiote_user_id_t * p_user_id, + uint32_t const * p_pins_low_to_high_mask, + uint32_t const * p_pins_high_to_low_mask, + app_gpiote_event_handler_t event_handler); + +/**@brief Function for informing the GPIOTE module that the specified user wants to use the GPIOTE module. + * + * @param[in] user_id Id of user to enable. + * + * @retval NRF_SUCCESS On success. + * @retval NRF_ERROR_INVALID_PARAM Invalid user_id provided, No a valid user. + * @retval NRF_ERROR_INALID_STATE If @ref app_gpiote_init has not been called on the GPIOTE + * module. + */ +uint32_t app_gpiote_user_enable(app_gpiote_user_id_t user_id); + +/**@brief Function for informing the GPIOTE module that the specified user is done using the GPIOTE module. + * + * @param[in] user_id Id of user to enable. + * + * @retval NRF_SUCCESS On success. + * @retval NRF_ERROR_INVALID_PARAM Invalid user_id provided, No a valid user. + * @retval NRF_ERROR_INALID_STATE If @ref app_gpiote_init has not been called on the GPIOTE + * module. + */ +uint32_t app_gpiote_user_disable(app_gpiote_user_id_t user_id); + +/**@brief Function for getting the state of the pins which are registered for the specified user. + * + * @param[in] user_id Id of user to check. + * @param[out] p_pins Pointer to array of words with bit mask corresponding to the pins + * configured to generate events to the specified user. All bits + * corresponding to pins in the state 'high' will have value '1', + * all others will have value '0'. Size of array depends on number + * of ports in the device. + * + * @retval NRF_SUCCESS On success. + * @retval NRF_ERROR_INVALID_PARAM Invalid user_id provided, No a valid user. + * @retval NRF_ERROR_INALID_STATE If @ref app_gpiote_init has not been called on the GPIOTE + * module. + */ +uint32_t app_gpiote_pins_state_get(app_gpiote_user_id_t user_id, uint32_t * p_pins); + +#ifdef __cplusplus +} +#endif + +#endif // APP_GPIOTE_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/hardfault.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/hardfault.h new file mode 100644 index 0000000000000000000000000000000000000000..9a081ac8617c79e0b0a00203022d980234cd1b70 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/hardfault.h @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef HARDFAULT_H__ +#define HARDFAULT_H__ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @defgroup hardfault_default HardFault exception + * @{ + * @brief Default HardFault exception implementation. + * @ingroup app_common + */ + +/** + * @brief Contents of the stack. + * + * This structure is used to re-create the stack layout after a HardFault exception was raised. + */ +typedef struct HardFault_stack +{ + uint32_t r0; ///< R0 register. + uint32_t r1; ///< R1 register. + uint32_t r2; ///< R2 register. + uint32_t r3; ///< R3 register. + uint32_t r12; ///< R12 register. + uint32_t lr; ///< Link register. + uint32_t pc; ///< Program counter. + uint32_t psr; ///< Program status register. +} HardFault_stack_t; + +/** + * @brief Function for processing HardFault exceptions. + * + * An application that needs to process HardFault exceptions should provide an implementation of this function. + * It will be called from the HardFault handler. + * If no implementation is provided, the library uses a default one, which just restarts the MCU. + * + * @note If the DEBUG_NRF macro is defined, the software breakpoint is set just before the call + * to this function. + * + * @param p_stack Pointer to the stack bottom. + * This pointer might be NULL if the HardFault was called when the main stack was + * the active stack and a stack overrun is detected. + * In such a situation, the stack pointer is reinitialized to the default position, + * and the stack content is lost. + */ +void HardFault_process(HardFault_stack_t * p_stack); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* HARDFAULT_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/hardfault_implementation.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/hardfault_implementation.c new file mode 100644 index 0000000000000000000000000000000000000000..dd3175ebfa757cf4815e6f9228c8f77dd789eb18 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/hardfault_implementation.c @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include "hardfault.h" +#include "nrf.h" +#include "compiler_abstraction.h" +#include "app_util_platform.h" +#ifdef SOFTDEVICE_PRESENT +#include "nrf_soc.h" +#endif +#define NRF_LOG_MODULE_NAME "HARDFAULT" +#include "nrf_log.h" +#include "nrf_log_ctrl.h" +#if defined(DEBUG_NRF) +/** + * @brief Pointer to the last received stack pointer. + * + * This pointer is set in the debug version of the HardFault handler. + * It helps to debug HardFault reasons. + */ +volatile HardFault_stack_t * HardFault_p_stack; +#endif + +/*lint -save -e14 */ +__WEAK void HardFault_process(HardFault_stack_t * p_stack) +{ + // Restart the system by default + NVIC_SystemReset(); +} +/*lint -restore */ + +void HardFault_c_handler(uint32_t * p_stack_address) +{ + NRF_LOG_ERROR("Hardfault PC:%x\r\n", ((HardFault_stack_t *)p_stack_address)->pc); + NRF_LOG_FINAL_FLUSH(); +#if defined(DEBUG_NRF) + HardFault_p_stack = (HardFault_stack_t *)p_stack_address; + (void)HardFault_p_stack; + + // Debugger detection is only possible on NRF52 (Cortex-M4), on NRF51 + // (Cortex-M0) the processor has no access to CoreDebug registers. + #if __CORTEX_M == 0x04 + // C_DEBUGEN == 1 -> Debugger Connected + if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) + { + /* Generate breakpoint if debugger is connected */ + NRF_BREAKPOINT; + } + #endif // __CORTEX_M == 0x04 +#endif // DEBUG_NRF + HardFault_process((HardFault_stack_t *)p_stack_address); +} +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c new file mode 100644 index 0000000000000000000000000000000000000000..dca1ddd559cd4af13f4116c526108ff221d23707 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include +#include "compiler_abstraction.h" + +void HardFault_Handler(void) __attribute__(( naked )); + +void HardFault_Handler(void) +{ + __ASM volatile( + " .syntax unified \n" + + " ldr r0, =0xFFFFFFFD \n" + " cmp r0, lr \n" + " bne HardFault_Handler_ChooseMSP \n" + /* Reading PSP into R0 */ + " mrs r0, PSP \n" + " b HardFault_Handler_Continue \n" + "HardFault_Handler_ChooseMSP: \n" + /* Reading MSP into R0 */ + " mrs r0, MSP \n" + /* ----------------------------------------------------------------- + * If we have selected MSP check if we may use stack safetly. + * If not - reset the stack to the initial value. */ + " ldr r1, =__StackTop \n" + " ldr r2, =__StackLimit \n" + + /* MSP is in the range of the stack area */ + " cmp r0, r1 \n" + " bhi HardFault_MoveSP \n" + " cmp r0, r2 \n" + " bhi HardFault_Handler_Continue \n" + /* ----------------------------------------------------------------- */ + "HardFault_MoveSP: \n" + " mov SP, r1 \n" + " movs r0, #0 \n" + + "HardFault_Handler_Continue: \n" + " ldr r3, =HardFault_c_handler \n" + " bx r3 \n" + + " .align \n" + ); +} +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c new file mode 100644 index 0000000000000000000000000000000000000000..958376b16692acbeca7e7132fbae8cd75812cb3f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include +#include "compiler_abstraction.h" + +#pragma section = "CSTACK" +extern void HardFault_c_handler( uint32_t * ); + +__stackless void HardFault_Handler(void); + +__stackless void HardFault_Handler(void) +{ + __ASM volatile( + " ldr r0, 100f \n" + " cmp r0, lr \n" + " bne 1f \n" + /* Reading PSP into R0 */ + " mrs r0, PSP \n" + " b 3f \n" + "1: \n" + /* Reading MSP into R0 */ + " mrs r0, MSP \n" + /* ----------------------------------------------------------------- + * If we have selected MSP check if we may use stack safetly. + * If not - reset the stack to the initial value. */ + " ldr r1, 101f \n" + " ldr r2, 102f \n" + + /* MSP is in the range of the stack area */ + " cmp r0, r1 \n" + " bhi 2f \n" + " cmp r0, r2 \n" + " bhi 3f \n" + /* ----------------------------------------------------------------- */ + "2: \n" + " mov SP, r1 \n" + " movs r0, #0 \n" + + "3: \n" + " ldr r3, 103f \n" + " bx r3 \n" + + "100: \n" + " DC32 0xFFFFFFFD \n" + "101: \n" + " DC32 %c0 \n" + "102: \n" + " DC32 %c1 \n" + "103: \n" + " DC32 %c2 \n" + : /* Outputs */ + : /* Inputs */ + "i"(__section_end("CSTACK")), + "i"(__section_begin("CSTACK")), + "i"(&HardFault_c_handler) + ); +} +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c new file mode 100644 index 0000000000000000000000000000000000000000..721e8af2e58162219fb638b5a5c97f4c86a9a853 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include +#include "compiler_abstraction.h" + + +//lint -save -e27 + +__ASM void HardFault_Handler(void) +{ + PRESERVE8 + EXTERN HardFault_c_handler + EXTERN |STACK$$Base| + EXTERN |STACK$$Limit| + + ldr r0, =0xFFFFFFFD + cmp r0, lr + bne HardFault_Handler_ChooseMSP + /* Reading PSP into R0 */ + mrs r0, PSP + b HardFault_Handler_Continue +HardFault_Handler_ChooseMSP + /* Reading MSP into R0 */ + mrs r0, MSP + /* ----------------------------------------------------------------- + * If we have selected MSP, check if we may use stack safely. + * If not - reset the stack to the initial value. */ + ldr r1, =|STACK$$Limit| + ldr r2, =|STACK$$Base| + + /* MSP is in the range of the stack area */ + cmp r0, r1 + bhi HardFault_MoveSP + cmp r0, r2 + bhi HardFault_Handler_Continue + /* ----------------------------------------------------------------- */ +HardFault_MoveSP + mov SP, r1 + movs r0, #0 + +HardFault_Handler_Continue + ldr r3, =HardFault_c_handler + bx r3 + + ALIGN +} + +//lint -restore +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c new file mode 100644 index 0000000000000000000000000000000000000000..7ee4ef68cca752883e4390ad672794a0904c43ca --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include +#include "compiler_abstraction.h" + +void HardFault_Handler(void) __attribute__(( naked )); + +void HardFault_Handler(void) +{ + __ASM volatile( + " ldr r3, =HardFault_c_handler \n" + " tst lr, #4 \n" + + /* PSP is quite simple and does not require additional handler */ + " itt ne \n" + " mrsne r0, psp \n" + /* Jump to the handler, do not store LR - returning from handler just exits exception */ + " bxne r3 \n" + + /* Processing MSP requires stack checking */ + " mrs r0, msp \n" + + " ldr r1, =__StackTop \n" + " ldr r2, =__StackLimit \n" + + /* MSP is in the range of the stack area */ + " cmp r0, r1 \n" + " bhi HardFault_MoveSP \n" + " cmp r0, r2 \n" + " bhi HardFault_Handler_Continue \n" + + "HardFault_MoveSP: \n" + " mov sp, r1 \n" + " mov r0, #0 \n" + + "HardFault_Handler_Continue: \n" + " bx r3 \n" + + " .align \n" + ); +} +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c new file mode 100644 index 0000000000000000000000000000000000000000..b7df679eaef824b217c6d9ba394412a69df4f22b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include +#include "compiler_abstraction.h" + +#pragma section = "CSTACK" +extern void HardFault_c_handler( uint32_t * ); + +__stackless void HardFault_Handler(void); + +__stackless void HardFault_Handler(void) +{ + __ASM volatile( + " ldr.n r3, 103f \n" + " tst lr, #4 \n" + + /* PSP is quite simple and does not require additional handler */ + " itt ne \n" + " mrsne r0, psp \n" + /* Jump to the handler, do not store LR - returning from handler just exits exception */ + " bxne r3 \n" + + /* Processing MSP requires stack checking */ + " mrs r0, msp \n" + + " ldr.n r1, 101f \n" + " ldr.n r2, 102f \n" + + /* MSP is in the range of the stack area */ + " cmp r0, r1 \n" + " bhi.n 1f \n" + " cmp r0, r2 \n" + " bhi.n 2f \n" + + "1: \n" + " mov sp, r1 \n" + " mov r0, #0 \n" + + "2: \n" + " bx r3 \n" + /* Data alignment if required */ + " nop \n" + + "101: \n" + " DC32 %c0 \n" + "102: \n" + " DC32 %c1 \n" + "103: \n" + " DC32 %c2 \n" + : /* Outputs */ + : /* Inputs */ + "i"(__section_end("CSTACK")), + "i"(__section_begin("CSTACK")), + "i"(&HardFault_c_handler) + ); +} +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c new file mode 100644 index 0000000000000000000000000000000000000000..c9437ce1b3883b3b7387f81a5803a30bc4e6d642 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include +#include "compiler_abstraction.h" + + +//lint -save -e27 + +__ASM void HardFault_Handler(void) +{ + PRESERVE8 + EXTERN HardFault_c_handler + EXTERN |STACK$$Base| + EXTERN |STACK$$Limit| + + ldr r3, =HardFault_c_handler + tst lr, #4 + + /* PSP is quite simple and does not require additional handler */ + itt ne + mrsne r0, psp + /* Jump to the handler, do not store LR - returning from handler just exits exception */ + bxne r3 + + /* Processing MSP requires stack checking */ + mrs r0, msp + + ldr r1, =|STACK$$Limit| + ldr r2, =|STACK$$Base| + + /* MSP is in the range of the stack area */ + cmp r0, r1 + bhi HardFault_MoveSP + cmp r0, r2 + bhi HardFault_Handler_Continue + +HardFault_MoveSP + mov sp, r1 + mov r0, #0 + +HardFault_Handler_Continue + bx r3 + + ALIGN +} + +//lint -restore +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_mem_pool.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_mem_pool.c new file mode 100644 index 0000000000000000000000000000000000000000..8c686e7178835fcd291a2681f9848512d1af30aa --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_mem_pool.c @@ -0,0 +1,264 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HCI_MEM_POOL) +#include "hci_mem_pool.h" +#include +#include + +/**@brief RX buffer element instance structure. + */ +typedef struct +{ + uint8_t rx_buffer[HCI_RX_BUF_SIZE]; /**< RX buffer memory array. */ + uint32_t length; /**< Length of the RX buffer memory array. */ +} rx_buffer_elem_t; + +/**@brief RX buffer queue element instance structure. + */ +typedef struct +{ + rx_buffer_elem_t * p_buffer; /**< Pointer to RX buffer element. */ + uint32_t free_window_count; /**< Free space element count. */ + uint32_t free_available_count; /**< Free area element count. */ + uint32_t read_available_count; /**< Read area element count. */ + uint32_t write_index; /**< Write position index. */ + uint32_t read_index; /**< Read position index. */ + uint32_t free_index; /**< Free position index. */ +} rx_buffer_queue_t; + +static bool m_is_tx_allocated; /**< Boolean value to determine if the TX buffer is allocated. */ +static rx_buffer_elem_t m_rx_buffer_elem_queue[HCI_RX_BUF_QUEUE_SIZE]; /**< RX buffer element instances. */ +static rx_buffer_queue_t m_rx_buffer_queue; /**< RX buffer queue element instance. */ + + +uint32_t hci_mem_pool_open(void) +{ + m_is_tx_allocated = false; + m_rx_buffer_queue.p_buffer = m_rx_buffer_elem_queue; + m_rx_buffer_queue.free_window_count = HCI_RX_BUF_QUEUE_SIZE; + m_rx_buffer_queue.free_available_count = 0; + m_rx_buffer_queue.read_available_count = 0; + m_rx_buffer_queue.write_index = 0; + m_rx_buffer_queue.read_index = 0; + m_rx_buffer_queue.free_index = 0; + + return NRF_SUCCESS; +} + + +uint32_t hci_mem_pool_close(void) +{ + return NRF_SUCCESS; +} + + +uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer) +{ + static uint8_t tx_buffer[HCI_TX_BUF_SIZE]; + + uint32_t err_code; + + if (pp_buffer == NULL) + { + return NRF_ERROR_NULL; + } + + if (!m_is_tx_allocated) + { + m_is_tx_allocated = true; + *pp_buffer = tx_buffer; + err_code = NRF_SUCCESS; + } + else + { + err_code = NRF_ERROR_NO_MEM; + } + + return err_code; +} + + +uint32_t hci_mem_pool_tx_free(void) +{ + m_is_tx_allocated = false; + + return NRF_SUCCESS; +} + + +uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer) +{ + uint32_t err_code; + + if (pp_buffer == NULL) + { + return NRF_ERROR_NULL; + } + *pp_buffer = NULL; + + if (m_rx_buffer_queue.free_window_count != 0) + { + if (length <= HCI_RX_BUF_SIZE) + { + --(m_rx_buffer_queue.free_window_count); + ++(m_rx_buffer_queue.read_available_count); + + *pp_buffer = + m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.write_index].rx_buffer; + + m_rx_buffer_queue.free_index |= (1u << m_rx_buffer_queue.write_index); + + // @note: Adjust the write_index making use of the fact that the buffer size is of + // power of two and two's complement arithmetic. For details refer example to book + // "Making embedded systems: Elicia White". + m_rx_buffer_queue.write_index = + (m_rx_buffer_queue.write_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u); + + err_code = NRF_SUCCESS; + } + else + { + err_code = NRF_ERROR_DATA_SIZE; + } + } + else + { + err_code = NRF_ERROR_NO_MEM; + } + + return err_code; +} + + +uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer) +{ + uint32_t err_code; + uint32_t consume_index; + uint32_t start_index; + + if (m_rx_buffer_queue.free_available_count != 0) + { + // Find the buffer that has been freed - + // Start at read_index minus free_available_count and then increment until read index. + err_code = NRF_ERROR_INVALID_ADDR; + consume_index = (m_rx_buffer_queue.read_index - m_rx_buffer_queue.free_available_count) & + (HCI_RX_BUF_QUEUE_SIZE - 1u); + start_index = consume_index; + + do + { + if (m_rx_buffer_queue.p_buffer[consume_index].rx_buffer == p_buffer) + { + m_rx_buffer_queue.free_index ^= (1u << consume_index); + err_code = NRF_SUCCESS; + break; + } + else + { + consume_index = (consume_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u); + } + } + while (consume_index != m_rx_buffer_queue.read_index); + + while (!(m_rx_buffer_queue.free_index & (1 << start_index)) && + (m_rx_buffer_queue.free_available_count != 0)) + { + --(m_rx_buffer_queue.free_available_count); + ++(m_rx_buffer_queue.free_window_count); + start_index = (consume_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u); + } + } + else + { + err_code = NRF_ERROR_NO_MEM; + } + + return err_code; +} + + +uint32_t hci_mem_pool_rx_data_size_set(uint32_t length) +{ + // @note: Adjust the write_index making use of the fact that the buffer size is of power + // of two and two's complement arithmetic. For details refer example to book + // "Making embedded systems: Elicia White". + const uint32_t index = (m_rx_buffer_queue.write_index - 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u); + m_rx_buffer_queue.p_buffer[index].length = length; + + return NRF_SUCCESS; +} + + +uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length) +{ + uint32_t err_code; + + if ((pp_buffer == NULL) || (p_length == NULL)) + { + return NRF_ERROR_NULL; + } + + if (m_rx_buffer_queue.read_available_count != 0) + { + --(m_rx_buffer_queue.read_available_count); + ++(m_rx_buffer_queue.free_available_count); + + *pp_buffer = + m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].rx_buffer; + *p_length = + m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].length; + + // @note: Adjust the write_index making use of the fact that the buffer size is of power + // of two and two's complement arithmetic. For details refer example to book + // "Making embedded systems: Elicia White". + m_rx_buffer_queue.read_index = + (m_rx_buffer_queue.read_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u); + + err_code = NRF_SUCCESS; + } + else + { + err_code = NRF_ERROR_NO_MEM; + } + + return err_code; +} +#endif //NRF_MODULE_ENABLED(HCI_MEM_POOL) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_mem_pool.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_mem_pool.h new file mode 100644 index 0000000000000000000000000000000000000000..95762360429681fd35ce718f71aff213217d3a52 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_mem_pool.h @@ -0,0 +1,168 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup hci_mem_pool Memory pool + * @{ + * @ingroup app_common + * + * @brief Memory pool implementation + * + * Memory pool implementation, based on circular buffer data structure, which supports asynchronous + * processing of RX data. The current default implementation supports 1 TX buffer and 4 RX buffers. + * The memory managed by the pool is allocated from static storage instead of heap. The internal + * design of the circular buffer implementing the RX memory layout is illustrated in the picture + * below. + * + * @image html memory_pool.svg "Circular buffer design" + * + * The expected call order for the RX APIs is as follows: + * - hci_mem_pool_rx_produce + * - hci_mem_pool_rx_data_size_set + * - hci_mem_pool_rx_extract + * - hci_mem_pool_rx_consume + * + * @warning If the above mentioned expected call order is violated the end result can be undefined. + * + * \par Component specific configuration options + * + * The following compile time configuration options are available to suit various implementations: + * - TX_BUF_SIZE TX buffer size in bytes. + * - RX_BUF_SIZE RX buffer size in bytes. + * - RX_BUF_QUEUE_SIZE RX buffer element size. + */ + +#ifndef HCI_MEM_POOL_H__ +#define HCI_MEM_POOL_H__ + +#include +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Function for opening the module. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t hci_mem_pool_open(void); + +/**@brief Function for closing the module. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t hci_mem_pool_close(void); + +/**@brief Function for allocating requested amount of TX memory. + * + * @param[out] pp_buffer Pointer to the allocated memory. + * + * @retval NRF_SUCCESS Operation success. Memory was allocated. + * @retval NRF_ERROR_NO_MEM Operation failure. No memory available for allocation. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + */ +uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer); + +/**@brief Function for freeing previously allocated TX memory. + * + * @note Memory management follows the FIFO principle meaning that free() order must match the + * alloc(...) order, which is the reason for omitting exact memory block identifier as an + * input parameter. + * + * @retval NRF_SUCCESS Operation success. Memory was freed. + */ +uint32_t hci_mem_pool_tx_free(void); + +/**@brief Function for producing a free RX memory block for usage. + * + * @note Upon produce request amount being 0, NRF_SUCCESS is returned. + * + * @param[in] length Amount, in bytes, of free memory to be produced. + * @param[out] pp_buffer Pointer to the allocated memory. + * + * @retval NRF_SUCCESS Operation success. Free RX memory block produced. + * @retval NRF_ERROR_NO_MEM Operation failure. No suitable memory available for allocation. + * @retval NRF_ERROR_DATA_SIZE Operation failure. Request size exceeds limit. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + */ +uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer); + +/**@brief Function for setting the length of the last produced RX memory block. + * + * @warning If call to this API is omitted the end result is that the following call to + * mem_pool_rx_extract will return incorrect data in the p_length output parameter. + * + * @param[in] length Amount, in bytes, of actual memory used. + * + * @retval NRF_SUCCESS Operation success. Length was set. + */ +uint32_t hci_mem_pool_rx_data_size_set(uint32_t length); + +/**@brief Function for extracting a packet, which has been filled with read data, for further + * processing. + * + * @param[out] pp_buffer Pointer to the packet data. + * @param[out] p_length Length of packet data in bytes. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to extract. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + */ +uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length); + +/**@brief Function for freeing previously extracted packet, which has been filled with read data. + * + * @param[in] p_buffer Pointer to consumed buffer. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to free. + * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer. + */ +uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer); + + +#ifdef __cplusplus +} +#endif + +#endif // HCI_MEM_POOL_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_slip.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_slip.c new file mode 100644 index 0000000000000000000000000000000000000000..ca32633ba8c37ba704e80d28fa764d0903155f36 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_slip.c @@ -0,0 +1,457 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HCI_SLIP) +#include "hci_slip.h" +#include +#include "app_uart.h" +#include "nrf_error.h" + +#define APP_SLIP_END 0xC0 /**< SLIP code for identifying the beginning and end of a packet frame.. */ +#define APP_SLIP_ESC 0xDB /**< SLIP escape code. This code is used to specify that the following character is specially encoded. */ +#define APP_SLIP_ESC_END 0xDC /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xC0.. */ +#define APP_SLIP_ESC_ESC 0xDD /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xDB. */ + +/** @brief States for the SLIP state machine. */ +typedef enum +{ + SLIP_OFF, /**< SLIP state OFF. */ + SLIP_READY, /**< SLIP state ON. */ + SLIP_TRANSMITTING, /**< SLIP state is transmitting indicating write() has been called but data transmission has not completed. */ +} slip_states_t; + +static slip_states_t m_current_state = SLIP_OFF; /** Current state for the SLIP TX state machine. */ + +static hci_slip_event_handler_t m_slip_event_handler; /** Event callback function for handling of SLIP events, @ref hci_slip_evt_type_t . */ + +static const uint8_t * mp_tx_buffer; /** Pointer to the current TX buffer that is in transmission. */ +static uint32_t m_tx_buffer_length; /** Length of the current TX buffer that is in transmission. */ +static volatile uint32_t m_tx_buffer_index; /** Current index for next byte to transmit in the mp_tx_buffer. */ + +static uint8_t * mp_rx_buffer; /** Pointer to the current RX buffer where the next SLIP decoded packet will be stored. */ +static uint32_t m_rx_buffer_length; /** Length of the current RX buffer. */ +static uint32_t m_rx_received_count; /** Number of SLIP decoded bytes received and stored in mp_rx_buffer. */ + + +/**@brief Function for parsing bytes received on the UART until a SLIP escape byte is received. + * + * @param[in] byte Byte received in UART module. + */ +static void handle_rx_byte_default(uint8_t byte); + +/**@brief Function for parsing bytes received on the UART until SLIP end byte is received. + * + * @param[in] byte Byte received in UART module. + */ +static void handle_rx_byte_wait_start(uint8_t byte); + +/**@brief Function for decoding a received SLIP escape byte. + * It will ensure correct decoding of the byte following the SLIP escape byte. + * + * @param[in] byte Byte received in UART module. + */ +static void handle_rx_byte_esc(uint8_t byte); + +/**@brief Function pointer for parsing and decoding SLIP bytes from the UART module. + * + * @param[in] byte Byte received in UART module. + */ +static void (*handle_rx_byte) (uint8_t byte) = handle_rx_byte_wait_start; + +/**@brief Function pointer for sending a byte through the UART module. + */ +static uint32_t send_tx_byte_default(void); + +/**@brief Function for transferring a SLIP escape byte (0xDB) when special bytes are transferred, + * that is 0xC0 and 0xDB. + */ +static uint32_t send_tx_byte_esc(void); + +/**@brief Function for transferring a byte when it collides with SLIP commands and follows the SLIP + * escape byte, that is 0xC0 => 0xDC and 0xDB => 0xDD. + */ +static uint32_t send_tx_byte_encoded(void); + +/**@brief Function for transferring the SLIP end frame byte, 0xC0. + */ +static uint32_t send_tx_byte_end(void); + +/**@brief Function pointer for sending a byte through the UART module. + */ +uint32_t (*send_tx_byte) (void) = send_tx_byte_default; + + +static uint32_t send_tx_byte_end(void) +{ + uint32_t err_code = app_uart_put(APP_SLIP_END); + + if ((err_code == NRF_SUCCESS) && (m_tx_buffer_index == 0)) + { + // Packet transmission started. + send_tx_byte = send_tx_byte_default; + } + + return err_code; +} + + +static uint32_t send_tx_byte_default(void) +{ + uint32_t err_code = app_uart_put(mp_tx_buffer[m_tx_buffer_index]); + + if (err_code == NRF_SUCCESS) + { + m_tx_buffer_index++; + } + + return err_code; +} + + +static uint32_t send_tx_byte_encoded(void) +{ + uint32_t err_code; + + switch (mp_tx_buffer[m_tx_buffer_index]) + { + case APP_SLIP_END: + err_code = app_uart_put(APP_SLIP_ESC_END); + break; + + case APP_SLIP_ESC: + err_code = app_uart_put(APP_SLIP_ESC_ESC); + break; + + default: + err_code = NRF_ERROR_NO_MEM; + break; + } + + if (err_code == NRF_SUCCESS) + { + m_tx_buffer_index++; + send_tx_byte = send_tx_byte_default; + } + + return err_code; +} + + +static uint32_t send_tx_byte_esc(void) +{ + uint32_t err_code = app_uart_put(APP_SLIP_ESC); + + if (err_code == NRF_SUCCESS) + { + send_tx_byte = send_tx_byte_encoded; + } + + return err_code; +} + + +/** @brief Function for transferring the content of the mp_tx_buffer to the UART. + * It continues to transfer bytes until the UART buffer is full or the complete buffer is + * transferred. + */ +static void transmit_buffer(void) +{ + uint32_t err_code = NRF_SUCCESS; + + while (m_tx_buffer_index < m_tx_buffer_length) + { + if ((mp_tx_buffer[m_tx_buffer_index] == APP_SLIP_END || + mp_tx_buffer[m_tx_buffer_index] == APP_SLIP_ESC) && + send_tx_byte == send_tx_byte_default) + { + send_tx_byte = send_tx_byte_esc; + } + + err_code = send_tx_byte(); + + if (err_code == NRF_ERROR_NO_MEM || err_code == NRF_ERROR_BUSY) + { + // No memory left in UART TX buffer. Abort and wait for APP_UART_TX_EMPTY to continue. + return; + } + } + + send_tx_byte = send_tx_byte_end; + + err_code = send_tx_byte(); + + if (err_code == NRF_SUCCESS) + { + // Packet transmission ended. Notify higher level. + m_current_state = SLIP_READY; + + if (m_slip_event_handler != NULL) + { + hci_slip_evt_t event = {HCI_SLIP_TX_DONE, mp_tx_buffer, m_tx_buffer_index}; + + m_slip_event_handler(event); + } + } +} + + +/** @brief Function for handling the reception of a SLIP end byte. + * If the number of bytes received is greater than zero it will call m_slip_event_handler + * with number of bytes received and invalidate the mp_rx_buffer to protect against data + * corruption. + * No new bytes can be received until a new RX buffer is supplied. + */ +static void handle_slip_end(void) +{ + if (m_rx_received_count > 0) + { + // Full packet received, push it up. + if (m_slip_event_handler != NULL) + { + hci_slip_evt_t event = {HCI_SLIP_RX_RDY, mp_rx_buffer, m_rx_received_count}; + + m_rx_received_count = 0; + mp_rx_buffer = NULL; + + m_slip_event_handler(event); + } + } +} + + +static void handle_rx_byte_esc(uint8_t byte) +{ + switch (byte) + { + case APP_SLIP_END: + handle_slip_end(); + break; + + case APP_SLIP_ESC_END: + mp_rx_buffer[m_rx_received_count++] = APP_SLIP_END; + break; + + case APP_SLIP_ESC_ESC: + mp_rx_buffer[m_rx_received_count++] = APP_SLIP_ESC; + break; + + default: + mp_rx_buffer[m_rx_received_count++] = byte; + break; + } + + handle_rx_byte = handle_rx_byte_default; +} + + +static void handle_rx_byte_default(uint8_t byte) +{ + switch (byte) + { + case APP_SLIP_END: + handle_slip_end(); + break; + + case APP_SLIP_ESC: + handle_rx_byte = handle_rx_byte_esc; + break; + + default: + mp_rx_buffer[m_rx_received_count++] = byte; + break; + } +} + + +static void handle_rx_byte_wait_start(uint8_t byte) +{ + if (byte == APP_SLIP_END) + { + handle_rx_byte = handle_rx_byte_default; + } +} + + +/** @brief Function for checking the current index and length of the RX buffer to determine if the + * buffer is full. If an event handler has been registered, the callback function will + * be executed.. + * + * @retval true If RX buffer has overflowed. + * @retval false otherwise. + * + */ +static bool rx_buffer_overflowed(void) +{ + if (mp_rx_buffer == NULL || m_rx_received_count >= m_rx_buffer_length) + { + if (m_slip_event_handler != NULL) + { + hci_slip_evt_t event = {HCI_SLIP_RX_OVERFLOW, mp_rx_buffer, m_rx_received_count}; + m_slip_event_handler(event); + } + + return true; + } + + return false; +} + + +/** @brief Function for handling the UART module event. It parses events from the UART when + * bytes are received/transmitted. + * + * @param[in] uart_event Event received from app_uart module. + */ +static void slip_uart_eventhandler(app_uart_evt_t * uart_event) +{ + if (uart_event->evt_type == APP_UART_TX_EMPTY && m_current_state == SLIP_TRANSMITTING) + { + transmit_buffer(); + } + + if ((uart_event->evt_type == APP_UART_DATA) && (!rx_buffer_overflowed())) + { + handle_rx_byte(uart_event->data.value); + } +} + + +/** @brief Function for enabling the UART module when the SLIP layer is opened. + */ +static uint32_t slip_uart_open(void) +{ + uint32_t err_code; + + app_uart_comm_params_t comm_params = + { + HCI_UART_RX_PIN, + HCI_UART_TX_PIN, + HCI_UART_RTS_PIN, + HCI_UART_CTS_PIN, + (app_uart_flow_control_t)HCI_UART_FLOW_CONTROL, + false, + HCI_UART_BAUDRATE + }; + + err_code = app_uart_init(&comm_params, + NULL, + slip_uart_eventhandler, + APP_IRQ_PRIORITY_LOWEST); + + if (err_code == NRF_SUCCESS) + { + m_current_state = SLIP_READY; + } + + return err_code; +} + + +uint32_t hci_slip_evt_handler_register(hci_slip_event_handler_t event_handler) +{ + m_slip_event_handler = event_handler; + + return NRF_SUCCESS; +} + + +uint32_t hci_slip_open() +{ + switch (m_current_state) + { + case SLIP_OFF: + return slip_uart_open(); + + default: + // Do nothing. + break; + } + + return NRF_SUCCESS; +} + + +uint32_t hci_slip_close() +{ + m_current_state = SLIP_OFF; + uint32_t err_code = app_uart_close(); + + return err_code; +} + + +uint32_t hci_slip_write(const uint8_t * p_buffer, uint32_t length) +{ + if (p_buffer == NULL) + { + return NRF_ERROR_INVALID_ADDR; + } + + switch (m_current_state) + { + case SLIP_READY: + m_tx_buffer_index = 0; + m_tx_buffer_length = length; + mp_tx_buffer = p_buffer; + m_current_state = SLIP_TRANSMITTING; + send_tx_byte = send_tx_byte_end; + + transmit_buffer(); + return NRF_SUCCESS; + + case SLIP_TRANSMITTING: + return NRF_ERROR_NO_MEM; + + case SLIP_OFF: + default: + return NRF_ERROR_INVALID_STATE; + } +} + + +uint32_t hci_slip_rx_buffer_register(uint8_t * p_buffer, uint32_t length) +{ + mp_rx_buffer = p_buffer; + m_rx_buffer_length = length; + m_rx_received_count = 0; + handle_rx_byte = handle_rx_byte_wait_start; + return NRF_SUCCESS; +} +#endif //NRF_MODULE_ENABLED(HCI_SLIP) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_slip.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_slip.h new file mode 100644 index 0000000000000000000000000000000000000000..88ce05f26628d1cc5355b20fb21809aadc5a13ac --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_slip.h @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup hci_slip SLIP module + * @{ + * @ingroup app_common + * + * @brief SLIP layer for supporting packet framing in HCI transport. + * + * @details This module implements SLIP packet framing as described in the Bluetooth Core + * Specification 4.0, Volume 4, Part D, Chapter 3 SLIP Layer. + * + * SLIP framing ensures that all packets sent on the UART are framed as: + * <0xC0> SLIP packet 1 <0xC0> <0xC0> SLIP packet 2 <0xC0>. + * + * The SLIP layer uses events to notify the upper layer when data transmission is complete + * and when a SLIP packet is received. + */ + +#ifndef HCI_SLIP_H__ +#define HCI_SLIP_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Event types from the SLIP Layer. */ +typedef enum +{ + HCI_SLIP_RX_RDY, /**< An event indicating that an RX packet is ready to be read. */ + HCI_SLIP_TX_DONE, /**< An event indicating write completion of the TX packet provided in the function call \ref hci_slip_write . */ + HCI_SLIP_RX_OVERFLOW, /**< An event indicating that RX data has been discarded due to lack of free RX memory. */ + HCI_SLIP_ERROR, /**< An event indicating that an unrecoverable error has occurred. */ + HCI_SLIP_EVT_TYPE_MAX /**< Enumeration upper bound. */ +} hci_slip_evt_type_t; + +/**@brief Structure containing an event from the SLIP layer. + */ +typedef struct +{ + hci_slip_evt_type_t evt_type; /**< Type of event. */ + const uint8_t * packet; /**< This field contains a pointer to the packet for which the event relates, i.e. SLIP_TX_DONE: the packet transmitted, SLIP_RX_RDY: the packet received, SLIP_RX_OVERFLOW: The packet which overflow/or NULL if no receive buffer is available. */ + uint32_t packet_length; /**< Packet length, i.e. SLIP_TX_DONE: Bytes transmitted, SLIP_RX_RDY: Bytes received, SLIP_RX_OVERFLOW: index at which the packet overflowed. */ +} hci_slip_evt_t; + +/**@brief Function for the SLIP layer event callback. + */ +typedef void (*hci_slip_event_handler_t)(hci_slip_evt_t event); + +/**@brief Function for registering the event handler provided as parameter and this event handler + * will be used by SLIP layer to send events described in \ref hci_slip_evt_type_t. + * + * @note Multiple registration requests will overwrite any existing registration. + * + * @param[in] event_handler This function is called by the SLIP layer upon an event. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t hci_slip_evt_handler_register(hci_slip_event_handler_t event_handler); + +/**@brief Function for opening the SLIP layer. This function must be called before + * \ref hci_slip_write and before any data can be received. + * + * @note Can be called multiple times. + * + * @retval NRF_SUCCESS Operation success. + * + * The SLIP layer module will propagate errors from underlying sub-modules. + * This implementation is using UART module as a physical transmission layer, and hci_slip_open + * executes \ref app_uart_init . For an extended error list, please refer to \ref app_uart_init . + */ +uint32_t hci_slip_open(void); + +/**@brief Function for closing the SLIP layer. After this function is called no data can be + * transmitted or received in this layer. + * + * @note This function can be called multiple times and also for an unopened channel. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t hci_slip_close(void); + +/**@brief Function for writing a packet with SLIP encoding. Packet transmission is confirmed when + * the HCI_SLIP_TX_DONE event is received by the function caller. + * + * @param[in] p_buffer Pointer to the packet to transmit. + * @param[in] length Packet length, in bytes. + * + * @retval NRF_SUCCESS Operation success. Packet was encoded and added to the + * transmission queue and an event will be sent upon transmission + * completion. + * @retval NRF_ERROR_NO_MEM Operation failure. Transmission queue is full and packet was not + * added to the transmission queue. Application shall wait for + * the \ref HCI_SLIP_TX_DONE event. After HCI_SLIP_TX_DONE this + * function can be executed for transmission of next packet. + * @retval NRF_ERROR_INVALID_ADDR If a NULL pointer is provided. + * @retval NRF_ERROR_INVALID_STATE Operation failure. Module is not open. + */ +uint32_t hci_slip_write(const uint8_t * p_buffer, uint32_t length); + +/**@brief Function for registering a receive buffer. The receive buffer will be used for storage of + * received and SLIP decoded data. + * No data can be received by the SLIP layer until a receive buffer has been registered. + * + * @note The lifetime of the buffer must be valid during complete reception of data. A static + * buffer is recommended. + * + * @warning Multiple registration requests will overwrite any existing registration. + * + * @param[in] p_buffer Pointer to receive buffer. The received and SLIP decoded packet + * will be placed in this buffer. + * @param[in] length Buffer length, in bytes. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t hci_slip_rx_buffer_register(uint8_t * p_buffer, uint32_t length); + + +#ifdef __cplusplus +} +#endif + +#endif // HCI_SLIP_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_transport.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_transport.c new file mode 100644 index 0000000000000000000000000000000000000000..7e1b8bf80b33eb051cc9416432c2cf99b6ec74c9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_transport.c @@ -0,0 +1,808 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HCI_TRANSPORT) +#include "hci_transport.h" +#include "hci_slip.h" +#include "crc16.h" +#include "hci_mem_pool.h" +#include "app_timer.h" +#include "app_error.h" +#include + +#define PKT_HDR_SIZE 4u /**< Packet header size in number of bytes. */ +#define PKT_CRC_SIZE 2u /**< Packet CRC size in number of bytes. */ +#define PKT_TYPE_VENDOR_SPECIFIC 14u /**< Packet type vendor specific. */ +#define PKT_TYPE_ACK 0 /**< Packet type acknowledgement. */ +#define DATA_INTEGRITY_MASK (1u << 6u) /**< Mask for data integrity bit in the packet header. */ +#define RELIABLE_PKT_MASK (1u << 7u) /**< Mask for reliable packet bit in the packet header. */ +#define INITIAL_ACK_NUMBER_EXPECTED 1u /**< Initial acknowledge number expected. */ +#define INITIAL_ACK_NUMBER_TX INITIAL_ACK_NUMBER_EXPECTED /**< Initial acknowledge number transmitted. */ +#define INVALID_PKT_TYPE 0xFFFFFFFFu /**< Internal invalid packet type value. */ +#define HCI_UART_REG_VALUE_TO_BAUDRATE(BAUDRATE) ((BAUDRATE)/268) /**< Estimated relation between UART baudrate register value and actual baudrate */ +#define MAX_TRANSMISSION_TIME \ + (ROUNDED_DIV((HCI_MAX_PACKET_SIZE_IN_BITS * 1000u), \ + HCI_UART_REG_VALUE_TO_BAUDRATE(HCI_UART_BAUDRATE))) /**< Max transmission time of a single application packet over UART in units of mseconds. */ +#define RETRANSMISSION_TIMEOUT_IN_MS (3u * MAX_TRANSMISSION_TIME) /**< Retransmission timeout for application packet in units of mseconds. */ +#define RETRANSMISSION_TIMEOUT_IN_TICKS APP_TIMER_TICKS(RETRANSMISSION_TIMEOUT_IN_MS) /**< Retransmission timeout for application packet in units of timer ticks. */ +#define MAX_RETRY_COUNT 5u /**< Max retransmission retry count for application packets. */ +#define ACK_BUF_SIZE 5u /**< Length of module internal RX buffer which is big enough to hold an acknowledgement packet. */ + +/**@brief States of the TX state machine. */ +typedef enum +{ + TX_STATE_IDLE, /**< State for: no application transmission packet processing in progress. */ + TX_STATE_PENDING, /**< State for: TX in progress in slip layer and TX-done event is waited for to signal the end of transmission. */ + TX_STATE_ACTIVE /**< State for: application packet has been delivered to slip for transmission and peer transport entity acknowledgement packet is waited for. */ +} tx_state_t; + +/**@brief TX state machine events. */ +typedef enum +{ + TX_EVENT_STATE_ENTRY, /**< Event for: state entry use case. */ + TX_EVENT_SLIP_TX_DONE, /**< Event for: HCI_SLIP_TX_DONE event use case. */ + TX_EVENT_TIMEOUT, /**< Event for: retransmission timeout use case. */ + TX_EVENT_VALID_RX_ACK /**< Event for: valid acknowledgement received for TX packet use case. */ +} tx_event_t; + +static void tx_sm_state_change(tx_state_t new_state); + +static tx_state_t m_tx_state; /**< Current TX state. */ +static hci_transport_tx_done_handler_t m_transport_tx_done_handle; /**< TX done event callback function. */ +static hci_transport_event_handler_t m_transport_event_handle; /**< Event handler callback function. */ +static uint8_t * mp_slip_used_rx_buffer; /**< Reference to RX buffer used by the slip layer. */ +static uint32_t m_packet_expected_seq_number; /**< Sequence number counter of the packet expected to be received . */ +static uint32_t m_packet_transmit_seq_number; /**< Sequence number counter of the transmitted packet for which acknowledgement packet is waited for. */ +static uint8_t * mp_tx_buffer; /**< Pointer to TX application buffer to be transmitted. */ +static uint32_t m_tx_buffer_length; /**< Length of application TX packet data to be transmitted in bytes. */ +static bool m_is_slip_decode_ready; /**< Boolean to determine has slip decode been completed or not. */ +APP_TIMER_DEF(m_app_timer_id); /**< Application timer id. */ +static uint32_t m_tx_retry_counter; /**< Application packet retransmission counter. */ +static hci_transport_tx_done_result_t m_tx_done_result_code; /**< TX done event callback function result code. */ +static uint8_t m_rx_ack_buffer[ACK_BUF_SIZE];/**< RX buffer big enough to hold an acknowledgement packet and which is taken in use upon receiving HCI_SLIP_RX_OVERFLOW event. */ + + +/**@brief Function for validating a received packet. + * + * @param[in] p_buffer Pointer to the packet data. + * @param[in] length Length of packet data in bytes. + * + * @return true if received packet is valid, false in other case. + */ +static bool is_rx_pkt_valid(const uint8_t * p_buffer, uint32_t length) +{ + // Executed packet filtering algorithm order: + // - verify packet overall length + // - verify data integrity bit set + // - verify reliable packet bit set + // - verify supported packet type + // - verify header checksum + // - verify payload length field + // - verify CRC + if (length <= PKT_HDR_SIZE) + { + return false; + } + + if (!(p_buffer[0] & DATA_INTEGRITY_MASK)) + { + return false; + } + + if (!(p_buffer[0] & RELIABLE_PKT_MASK)) + { + return false; + } + + if ((p_buffer[1] & 0x0Fu) != PKT_TYPE_VENDOR_SPECIFIC) + { + return false; + } + + const uint32_t expected_checksum = + ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu; + if (expected_checksum != 0) + { + return false; + } + + const uint16_t crc_calculated = crc16_compute(p_buffer, (length - PKT_CRC_SIZE), NULL); + const uint16_t crc_received = uint16_decode(&p_buffer[length - PKT_CRC_SIZE]); + if (crc_calculated != crc_received) + { + return false; + } + + return true; +} + + +/**@brief Function for getting the sequence number of the next reliable packet expected. + * + * @return sequence number of the next reliable packet expected. + */ +static __INLINE uint8_t packet_number_expected_get(void) +{ + return (uint8_t) m_packet_expected_seq_number; +} + + +/**@brief Function for calculating a packet header checksum. + * + * @param[in] p_hdr Pointer to the packet header. + * + * @return Calculated checksum. + */ +static uint8_t header_checksum_calculate(const uint8_t * p_hdr) +{ + // @note: no pointer validation check needed as already checked by calling function. + uint32_t checksum; + + checksum = p_hdr[0]; + checksum += p_hdr[1]; + checksum += p_hdr[2]; + checksum &= 0xFFu; + checksum = (~checksum + 1u); + + return (uint8_t)checksum; +} + + +/**@brief Function for writing an acknowledgment packet for transmission. + */ +static void ack_transmit(void) +{ + static uint8_t ack_packet[PKT_HDR_SIZE]; + + // TX ACK packet format: + // - Unreliable Packet type + // - Payload Length set to 0 + // - Sequence Number set to 0 + // - Header checksum calculated + // - Acknowledge Number set correctly + ack_packet[0] = (packet_number_expected_get() << 3u); + ack_packet[1] = 0; + ack_packet[2] = 0; + ack_packet[3] = header_checksum_calculate(ack_packet); + + // @note: no return value check needed for hci_slip_write(...) call as acknowledgement packets + // are considered to be from system design point of view unreliable packets.Use case where + // underlying slip layer does not accept a packet for transmission is managed either by: + // - acknowledged by possible future application packet as acknowledgement number header field + // is included + // - protocol peer entity will retransmit the packet + UNUSED_VARIABLE(hci_slip_write(ack_packet, sizeof(ack_packet))); +} + + +/**@brief Function for validating a received packet. + * + * @param[in] p_buffer Pointer to the packet data. + * + * @return sequence number field of the packet header with unrelated data masked out. + */ +static __INLINE uint8_t packet_seq_nmbr_extract(const uint8_t * p_buffer) +{ + return (p_buffer[0] & 0x07u); +} + + +/**@brief Function for incrementing the sequence number counter for next reliable packet expected. + */ +static __INLINE void packet_number_expected_inc(void) +{ + ++m_packet_expected_seq_number; + m_packet_expected_seq_number &= 0x07u; +} + + +/**@brief Function for decoding a packet type field. + * + * @param[in] p_buffer Pointer to the packet data. + * @param[in] length Length of packet data in bytes. + * + * @return Packet type field or INVALID_PKT_TYPE in case of decode error. + */ +static __INLINE uint32_t packet_type_decode(const uint8_t * p_buffer, uint32_t length) +{ + // @note: no pointer validation check needed as allready checked by calling function. + uint32_t return_value; + + if (length >= PKT_HDR_SIZE) + { + return_value = (p_buffer[1] & 0x0Fu); + } + else + { + return_value = INVALID_PKT_TYPE; + } + + return return_value; +} + + +/**@brief Function for processing a received vendor specific packet. + * + * @param[in] p_buffer Pointer to the packet data. + * @param[in] length Length of packet data in bytes. + */ +static void rx_vendor_specific_pkt_type_handle(const uint8_t * p_buffer, uint32_t length) +{ + // @note: no pointer validation check needed as allready checked by calling function. + uint32_t err_code; + + if (is_rx_pkt_valid(p_buffer, length)) + { + // RX packet is valid: validate sequence number. + const uint8_t rx_seq_number = packet_seq_nmbr_extract(p_buffer); + if (packet_number_expected_get() == rx_seq_number) + { + // Sequence number is valid: transmit acknowledgement. + packet_number_expected_inc(); + ack_transmit(); + + m_is_slip_decode_ready = true; + + err_code = hci_mem_pool_rx_data_size_set(length); + APP_ERROR_CHECK(err_code); + + err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer); + APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM)); + + // If memory pool RX buffer produce succeeded we register that buffer to slip layer + // otherwise we register the internal acknowledgement buffer. + err_code = hci_slip_rx_buffer_register( + (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer, + (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE); + + APP_ERROR_CHECK(err_code); + + if (m_transport_event_handle != NULL) + { + // Send application event of RX packet reception. + const hci_transport_evt_t evt = {HCI_TRANSPORT_RX_RDY}; + m_transport_event_handle(evt); + } + } + else + { + // RX packet discarded: sequence number not valid, set the same buffer to slip layer in + // order to avoid buffer overrun. + err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE); + APP_ERROR_CHECK(err_code); + + // As packet did not have expected sequence number: send acknowledgement with the + // current expected sequence number. + ack_transmit(); + } + } + else + { + // RX packet discarded: reset the same buffer to slip layer in order to avoid buffer + // overrun. + err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE); + APP_ERROR_CHECK(err_code); + } +} + + +/**@brief Function for getting the sequence number of a reliable TX packet for which peer protocol + * entity acknowledgment is pending. + * + * @return sequence number of a reliable TX packet for which peer protocol entity acknowledgement + * is pending. + */ +static __INLINE uint8_t packet_number_to_transmit_get(void) +{ + return m_packet_transmit_seq_number; +} + + +/**@brief Function for getting the expected acknowledgement number. + * + * @return expected acknowledgement number. + */ +static __INLINE uint8_t expected_ack_number_get(void) +{ + uint8_t seq_nmbr = packet_number_to_transmit_get(); + ++seq_nmbr; + seq_nmbr &= 0x07u; + + return seq_nmbr; +} + + +/**@brief Function for processing a received acknowledgement packet. + * + * Verifies does the received acknowledgement packet has the expected acknowledgement number and + * that the header checksum is correct. + * + * @param[in] p_buffer Pointer to the packet data. + * + * @return true if valid acknowledgement packet received. + */ +static __INLINE bool rx_ack_pkt_type_handle(const uint8_t * p_buffer) +{ + // @note: no pointer validation check needed as allready checked by calling function. + + // Verify header checksum. + const uint32_t expected_checksum = + ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu; + if (expected_checksum != 0) + { + return false; + } + + const uint8_t ack_number = (p_buffer[0] >> 3u) & 0x07u; + + // Verify expected acknowledgment number. + return (ack_number == expected_ack_number_get()); +} + + +/**@brief Function for incrementing the sequence number counter of the TX packet. + */ +static __INLINE void packet_number_tx_inc(void) +{ + ++m_packet_transmit_seq_number; + m_packet_transmit_seq_number &= 0x07u; +} + + +/**@brief Function for TX state machine event processing in a state centric manner. + * + * @param[in] event Type of event occurred. + */ +static void tx_sm_event_handle(tx_event_t event) +{ + uint32_t err_code; + + switch (m_tx_state) + { + case TX_STATE_IDLE: + if (event == TX_EVENT_STATE_ENTRY) + { + err_code = app_timer_stop(m_app_timer_id); + APP_ERROR_CHECK(err_code); + + // Send TX-done event if registered handler exists. + if (m_transport_tx_done_handle != NULL) + { + m_transport_tx_done_handle(m_tx_done_result_code); + } + } + break; + + case TX_STATE_PENDING: + if (event == TX_EVENT_SLIP_TX_DONE) + { + // @note: this call should always succeed as called from HCI_SLIP_TX_DONE context + // and error cases are managed by dedicated error event from the slip layer. + err_code = hci_slip_write(mp_tx_buffer, + (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE)); + APP_ERROR_CHECK(err_code); + tx_sm_state_change(TX_STATE_ACTIVE); + } + break; + + case TX_STATE_ACTIVE: + switch (event) + { + case TX_EVENT_VALID_RX_ACK: + // Tx sequence number counter incremented as packet transmission + // acknowledged by peer transport entity. + packet_number_tx_inc(); + tx_sm_state_change(TX_STATE_IDLE); + break; + + case TX_EVENT_STATE_ENTRY: + m_tx_retry_counter = 0; + err_code = app_timer_start(m_app_timer_id, + RETRANSMISSION_TIMEOUT_IN_TICKS, + NULL); + APP_ERROR_CHECK(err_code); + break; + + case TX_EVENT_TIMEOUT: + if (m_tx_retry_counter != MAX_RETRY_COUNT) + { + ++m_tx_retry_counter; + // @note: no return value check done for hci_slip_write(...) call as current + // system design allows use case where retransmission is not accepted by the + // slip layer due to existing acknowledgement packet transmission in the + // slip layer. + UNUSED_VARIABLE(hci_slip_write(mp_tx_buffer, + (m_tx_buffer_length + + PKT_HDR_SIZE + + PKT_CRC_SIZE))); + } + else + { + // Application packet retransmission count reached: + // - set correct TX done event callback function result code + // - execute state change + // @note: m_tx_retry_counter is reset in TX_STATE_ACTIVE state entry. + m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE; + tx_sm_state_change(TX_STATE_IDLE); + } + break; + + default: + // No implementation needed. + break; + } + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for changing the state of the TX state machine. + * + * @param[in] new_state State TX state machine transits to. + */ +static void tx_sm_state_change(tx_state_t new_state) +{ + m_tx_state = new_state; + tx_sm_event_handle(TX_EVENT_STATE_ENTRY); +} + + +/**@brief Function for handling slip events. + * + * @param[in] event The event structure. + */ +void slip_event_handle(hci_slip_evt_t event) +{ + uint32_t return_code; + uint32_t err_code; + + switch (event.evt_type) + { + case HCI_SLIP_TX_DONE: + tx_sm_event_handle(TX_EVENT_SLIP_TX_DONE); + break; + + case HCI_SLIP_RX_RDY: + return_code = packet_type_decode(event.packet, event.packet_length); + + switch (return_code) + { + case PKT_TYPE_VENDOR_SPECIFIC: + rx_vendor_specific_pkt_type_handle(event.packet, event.packet_length); + break; + + case PKT_TYPE_ACK: + if (rx_ack_pkt_type_handle(event.packet)) + { + // Valid expected acknowledgement packet received: set correct TX done event + // callback function result code and execute state change. + m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_SUCCESS; + tx_sm_event_handle(TX_EVENT_VALID_RX_ACK); + } + + /* fall-through */ + default: + // RX packet dropped: reset memory buffer to slip in order to avoid RX buffer + // overflow. + // If existing mem pool produced RX buffer exists reuse that one. If existing + // mem pool produced RX buffer does not exist try to produce new one. If + // producing fails use the internal acknowledgement buffer. + if (mp_slip_used_rx_buffer != NULL) + { + err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE); + APP_ERROR_CHECK(err_code); + } + else + { + err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, + (void **)&mp_slip_used_rx_buffer); + APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || + (err_code == NRF_ERROR_NO_MEM)); + + err_code = hci_slip_rx_buffer_register( + (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer, + (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE); + APP_ERROR_CHECK(err_code); + } + break; + } + break; + + case HCI_SLIP_RX_OVERFLOW: + err_code = hci_slip_rx_buffer_register(m_rx_ack_buffer, ACK_BUF_SIZE); + APP_ERROR_CHECK(err_code); + break; + + case HCI_SLIP_ERROR: + APP_ERROR_HANDLER(event.evt_type); + break; + + default: + APP_ERROR_HANDLER(event.evt_type); + break; + } +} + + +uint32_t hci_transport_evt_handler_reg(hci_transport_event_handler_t event_handler) +{ + uint32_t err_code; + + m_transport_event_handle = event_handler; + err_code = hci_slip_evt_handler_register(slip_event_handle); + APP_ERROR_CHECK(err_code); + + return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL; +} + + +uint32_t hci_transport_tx_done_register(hci_transport_tx_done_handler_t event_handler) +{ + uint32_t err_code; + + m_transport_tx_done_handle = event_handler; + err_code = hci_slip_evt_handler_register(slip_event_handle); + APP_ERROR_CHECK(err_code); + + return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL; +} + + +/**@brief Function for handling the application packet retransmission timeout. + * + * This function is registered in the @ref app_timer module when a timer is created on + * @ref hci_transport_open. + * + * @note This function must be executed in APP-LO context otherwise retransmission behaviour is + * undefined, see @ref nrf51_system_integration_serialization. + * + * @param[in] p_context The timeout context. + */ +void hci_transport_timeout_handle(void * p_context) +{ + tx_sm_event_handle(TX_EVENT_TIMEOUT); +} + + +uint32_t hci_transport_open(void) +{ + mp_tx_buffer = NULL; + m_tx_buffer_length = 0; + m_tx_retry_counter = 0; + m_is_slip_decode_ready = false; + m_tx_state = TX_STATE_IDLE; + m_packet_expected_seq_number = INITIAL_ACK_NUMBER_EXPECTED; + m_packet_transmit_seq_number = INITIAL_ACK_NUMBER_TX; + m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE; + + uint32_t err_code = app_timer_create(&m_app_timer_id, + APP_TIMER_MODE_REPEATED, + hci_transport_timeout_handle); + if (err_code != NRF_SUCCESS) + { + // @note: conduct required interface adjustment. + return NRF_ERROR_INTERNAL; + } + + err_code = hci_mem_pool_open(); + VERIFY_SUCCESS(err_code); + + err_code = hci_slip_open(); + VERIFY_SUCCESS(err_code); + + err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer); + if (err_code != NRF_SUCCESS) + { + // @note: conduct required interface adjustment. + return NRF_ERROR_INTERNAL; + } + + err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE); + + return err_code; +} + + +uint32_t hci_transport_close(void) +{ + uint32_t err_code; + + m_transport_tx_done_handle = NULL; + m_transport_event_handle = NULL; + + err_code = hci_mem_pool_close(); + APP_ERROR_CHECK(err_code); + err_code = hci_slip_close(); + APP_ERROR_CHECK(err_code); + + // @note: NRF_ERROR_NO_MEM is the only return value which should never be returned. + err_code = app_timer_stop(m_app_timer_id); + APP_ERROR_CHECK_BOOL(err_code != NRF_ERROR_NO_MEM); + + return NRF_SUCCESS; +} + + +uint32_t hci_transport_tx_alloc(uint8_t ** pp_memory) +{ + const uint32_t err_code = hci_mem_pool_tx_alloc((void **)pp_memory); + if (err_code == NRF_SUCCESS) + { + // @note: no need to validate pp_memory against null as validation has already been done + // by hci_mem_pool_tx_alloc(...) and visible to us from the method return code. + //lint -e(413) "Likely use of null pointer" + *pp_memory += PKT_HDR_SIZE; + } + + return err_code; +} + + +uint32_t hci_transport_tx_free(void) +{ + return hci_mem_pool_tx_free(); +} + + +/**@brief Function for constructing 1st byte of the packet header of the packet to be transmitted. + * + * @return 1st byte of the packet header of the packet to be transmitted + */ +static __INLINE uint8_t tx_packet_byte_zero_construct(void) +{ + const uint32_t value = DATA_INTEGRITY_MASK | + RELIABLE_PKT_MASK | + (packet_number_expected_get() << 3u) | + packet_number_to_transmit_get(); + + return (uint8_t) value; +} + + +/**@brief Function for handling the application packet write request in tx-idle state. + */ +static uint32_t pkt_write_handle(void) +{ + uint32_t err_code; + + // Set packet header fields. + + mp_tx_buffer -= PKT_HDR_SIZE; + mp_tx_buffer[0] = tx_packet_byte_zero_construct(); + + const uint16_t type_and_length_fields = ((m_tx_buffer_length << 4u) | PKT_TYPE_VENDOR_SPECIFIC); + // @note: no use case for uint16_encode(...) return value. + UNUSED_VARIABLE(uint16_encode(type_and_length_fields, &(mp_tx_buffer[1]))); + mp_tx_buffer[3] = header_checksum_calculate(mp_tx_buffer); + + // Calculate, append CRC to the packet and write it. + + const uint16_t crc = crc16_compute(mp_tx_buffer, (PKT_HDR_SIZE + m_tx_buffer_length), NULL); + // @note: no use case for uint16_encode(...) return value. + UNUSED_VARIABLE(uint16_encode(crc, &(mp_tx_buffer[PKT_HDR_SIZE + m_tx_buffer_length]))); + err_code = hci_slip_write(mp_tx_buffer, (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE)); + switch (err_code) + { + case NRF_SUCCESS: + tx_sm_state_change(TX_STATE_ACTIVE); + break; + + case NRF_ERROR_NO_MEM: + tx_sm_state_change(TX_STATE_PENDING); + err_code = NRF_SUCCESS; + break; + + default: + // No implementation needed. + break; + } + + return err_code; +} + + +uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t err_code; + + if (p_buffer) + { + switch (m_tx_state) + { + case TX_STATE_IDLE: + mp_tx_buffer = (uint8_t *)p_buffer; + m_tx_buffer_length = length; + err_code = pkt_write_handle(); + break; + + default: + err_code = NRF_ERROR_NO_MEM; + break; + } + } + else + { + err_code = NRF_ERROR_NULL; + } + + return err_code; +} + + +uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length) +{ + uint32_t err_code; + + if (pp_buffer != NULL && p_length != NULL) + { + uint32_t length = 0; + + if (m_is_slip_decode_ready) + { + m_is_slip_decode_ready = false; + err_code = hci_mem_pool_rx_extract(pp_buffer, &length); + length -= (PKT_HDR_SIZE + PKT_CRC_SIZE); + + *p_length = (uint16_t)length; + *pp_buffer += PKT_HDR_SIZE; + } + else + { + err_code = NRF_ERROR_NO_MEM; + } + } + else + { + err_code = NRF_ERROR_NULL; + } + + return err_code; +} + + +uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer) +{ + return (hci_mem_pool_rx_consume(p_buffer - PKT_HDR_SIZE)); +} +#endif //NRF_MODULE_ENABLED(HCI_TRANSPORT) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_transport.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_transport.h new file mode 100644 index 0000000000000000000000000000000000000000..ce490c570b20d5e6e1388154c8ac10f6b73f2f24 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/hci/hci_transport.h @@ -0,0 +1,256 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup hci_transport HCI Transport + * @{ + * @ingroup app_common + * + * @brief HCI transport module implementation. + * + * This module implements certain specific features from the three-wire UART transport layer, + * defined by the Bluetooth specification version 4.0 [Vol 4] part D. + * + * \par Features supported + * - Transmission and reception of Vendor Specific HCI packet type application packets. + * - Transmission and reception of reliable packets: defined by chapter 6 of the specification. + * + * \par Features not supported + * - Link establishment procedure: defined by chapter 8 of the specification. + * - Low power: defined by chapter 9 of the specification. + * + * \par Implementation specific behaviour + * - As Link establishment procedure is not supported following static link configuration parameters + * are used: + * + TX window size is 1. + * + 16 bit CCITT-CRC must be used. + * + Out of frame software flow control not supported. + * + Parameters specific for resending reliable packets are compile time configurable (clarifed + * later in this document). + * + Acknowledgement packet transmissions are not timeout driven , meaning they are delivered for + * transmission within same context which the corresponding application packet was received. + * + * \par Implementation specific limitations + * Current implementation has the following limitations which will have impact to system wide + * behaviour: + * - Delayed acknowledgement scheduling not implemented: + * There exists a possibility that acknowledgement TX packet and application TX packet will collide + * in the TX pipeline having the end result that acknowledgement packet will be excluded from the TX + * pipeline which will trigger the retransmission algorithm within the peer protocol entity. + * - Delayed retransmission scheduling not implemented: + * There exists a possibility that retransmitted application TX packet and acknowledgement TX packet + * will collide in the TX pipeline having the end result that retransmitted application TX packet + * will be excluded from the TX pipeline. + * - Processing of the acknowledgement number from RX application packets: + * Acknowledgement number is not processed from the RX application packets having the end result + * that unnecessary application packet retransmissions can occur. + * + * The application TX packet processing flow is illustrated by the statemachine below. + * + * @image html hci_transport_tx_sm.svg "TX - application packet statemachine" + * + * \par Component specific configuration options + * + * The following compile time configuration options are available, and used to configure the + * application TX packet retransmission interval, in order to suite various application specific + * implementations: + * - MAC_PACKET_SIZE_IN_BITS Maximum size of a single application packet in bits. + * - USED_BAUD_RATE Used uart baudrate. + * + * The following compile time configuration option is available to configure module specific + * behaviour: + * - MAX_RETRY_COUNT Max retransmission retry count for applicaton packets. + */ + +#ifndef HCI_TRANSPORT_H__ +#define HCI_TRANSPORT_H__ + +#include +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Generic event callback function events. */ +typedef enum +{ + HCI_TRANSPORT_RX_RDY, /**< An event indicating that RX packet is ready for read. */ + HCI_TRANSPORT_EVT_TYPE_MAX /**< Enumeration upper bound. */ +} hci_transport_evt_type_t; + +/**@brief Struct containing events from the Transport layer. + */ +typedef struct +{ + hci_transport_evt_type_t evt_type; /**< Type of event. */ +} hci_transport_evt_t; + +/**@brief Transport layer generic event callback function type. + * + * @param[in] event Transport layer event. + */ +typedef void (*hci_transport_event_handler_t)(hci_transport_evt_t event); + +/**@brief TX done event callback function result codes. */ +typedef enum +{ + HCI_TRANSPORT_TX_DONE_SUCCESS, /**< Transmission success, peer transport entity has acknowledged the transmission. */ + HCI_TRANSPORT_TX_DONE_FAILURE /**< Transmission failure. */ +} hci_transport_tx_done_result_t; + +/**@brief Transport layer TX done event callback function type. + * + * @param[in] result TX done event result code. + */ +typedef void (*hci_transport_tx_done_handler_t)(hci_transport_tx_done_result_t result); + +/**@brief Function for registering a generic event handler. + * + * @note Multiple registration requests will overwrite any possible existing registration. + * + * @param[in] event_handler The function to be called by the transport layer upon an event. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + */ +uint32_t hci_transport_evt_handler_reg(hci_transport_event_handler_t event_handler); + +/**@brief Function for registering a handler for TX done event. + * + * @note Multiple registration requests will overwrite any possible existing registration. + * + * @param[in] event_handler The function to be called by the transport layer upon TX done + * event. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + */ +uint32_t hci_transport_tx_done_register(hci_transport_tx_done_handler_t event_handler); + +/**@brief Function for opening the transport channel and initializing the transport layer. + * + * @warning Must not be called for a channel which has been allready opened. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred. + */ +uint32_t hci_transport_open(void); + +/**@brief Function for closing the transport channel. + * + * @note Can be called multiple times and also for not opened channel. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t hci_transport_close(void); + +/**@brief Function for allocating tx packet memory. + * + * @param[out] pp_memory Pointer to the packet data. + * + * @retval NRF_SUCCESS Operation success. Memory was allocated. + * @retval NRF_ERROR_NO_MEM Operation failure. No memory available. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + */ +uint32_t hci_transport_tx_alloc(uint8_t ** pp_memory); + +/**@brief Function for freeing tx packet memory. + * + * @note Memory management works in FIFO principle meaning that free order must match the alloc + * order. + * + * @retval NRF_SUCCESS Operation success. Memory was freed. + */ +uint32_t hci_transport_tx_free(void); + +/**@brief Function for writing a packet. + * + * @note Completion of this method does not guarantee that actual peripheral transmission would + * have completed. + * + * @note In case of 0 byte packet length write request, message will consist of only transport + * module specific headers. + * + * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue + * and an event will be send upon transmission completion. + * @retval NRF_ERROR_NO_MEM Operation failure. Transmission queue is full and packet was not + * added to the transmission queue. User should wait for + * a appropriate event prior issuing this operation again. + * @retval NRF_ERROR_DATA_SIZE Operation failure. Packet size exceeds limit. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_STATE Operation failure. Channel is not open. + */ +uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length); + +/**@brief Function for extracting received packet. + * + * @note Extracted memory can't be reused by the underlying transport layer untill freed by call to + * hci_transport_rx_pkt_consume(). + * + * @param[out] pp_buffer Pointer to the packet data. + * @param[out] p_length Length of packet data in bytes. + * + * @retval NRF_SUCCESS Operation success. Packet was extracted. + * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to extract. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + */ +uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length); + +/**@brief Function for consuming extracted packet described by p_buffer. + * + * RX memory pointed to by p_buffer is freed and can be reused by the underlying transport layer. + * + * @param[in] p_buffer Pointer to the buffer that has been consumed. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to consume. + * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer. + */ +uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer); + + +#ifdef __cplusplus +} +#endif + +#endif // HCI_TRANSPORT_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/led_softblink/led_softblink.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/led_softblink/led_softblink.c new file mode 100644 index 0000000000000000000000000000000000000000..1a43f48b2a343024198d4bf0f181a71419b0c1fd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/led_softblink/led_softblink.c @@ -0,0 +1,232 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(LED_SOFTBLINK) +#include +#include "led_softblink.h" +#include "nrf_gpio.h" +#include "app_timer.h" +#include "nrf_assert.h" +#include "low_power_pwm.h" + +/* Period for LED softblink PWM. */ +#define PWM_PERIOD UINT8_MAX + +/**@bref Structure to handle timer time-outs + * + */ +typedef struct +{ + bool leds_is_on; /**< Flag for indicating if LEDs are on. */ + bool is_counting_up; /**< Flag for indicating if counter is incrementing or decrementing. */ + nrf_drv_state_t led_sb_state; /**< Indicates current state of instance. */ + uint16_t duty_cycle; /**< Current pulse width. */ + uint32_t bit_mask; /**< Mask of used pins. */ + led_sb_init_params_t params; /**< Structure holding initialization parameters. */ + low_power_pwm_config_t pwm_config; /**< Structure holding parameters for initializing low level layer. */ + low_power_pwm_t pwm_instance; /**< Structure holding low-power PWM instance parameters. */ +}led_sb_context_t; + +static led_sb_context_t m_led_sb = {0}; + +/**@brief Timer event handler for softblink. + * + * @param[in] p_context General purpose pointer. Will be passed to the time-out handler + * when the timer expires. + * + */ +static void led_softblink_on_timeout(void * p_context) +{ + static int32_t pause_ticks; + ASSERT(m_led_sb.led_sb_state != NRF_DRV_STATE_UNINITIALIZED); + ret_code_t err_code; + + if (pause_ticks <= 0) + { + if (m_led_sb.is_counting_up) + { + if (m_led_sb.duty_cycle >= (m_led_sb.params.duty_cycle_max - m_led_sb.params.duty_cycle_step)) + { + // Max PWM duty cycle is reached, start decrementing. + m_led_sb.is_counting_up = false; + m_led_sb.duty_cycle = m_led_sb.params.duty_cycle_max; + pause_ticks = m_led_sb.params.on_time_ticks ? m_led_sb.params.on_time_ticks + APP_TIMER_MIN_TIMEOUT_TICKS : 0; + } + else + { + m_led_sb.duty_cycle += m_led_sb.params.duty_cycle_step; + } + } + else + { + if (m_led_sb.duty_cycle <= (m_led_sb.params.duty_cycle_min + m_led_sb.params.duty_cycle_step)) + { + // Min PWM duty cycle is reached, start incrementing. + m_led_sb.is_counting_up = true; + m_led_sb.duty_cycle = m_led_sb.params.duty_cycle_min; + pause_ticks = m_led_sb.params.off_time_ticks ? m_led_sb.params.off_time_ticks + APP_TIMER_MIN_TIMEOUT_TICKS : 0; + } + else + { + m_led_sb.duty_cycle -= m_led_sb.params.duty_cycle_step; + } + } + } + else + { + pause_ticks -= PWM_PERIOD; + } + + err_code = low_power_pwm_duty_set(&m_led_sb.pwm_instance, m_led_sb.duty_cycle); + + APP_ERROR_CHECK(err_code); +} + + +ret_code_t led_softblink_init(led_sb_init_params_t const * p_init_params) +{ + ret_code_t err_code; + + ASSERT(m_led_sb.led_sb_state == NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_init_params); + + if ( (p_init_params->duty_cycle_max == 0) || + (p_init_params->duty_cycle_max <= p_init_params->duty_cycle_min) || + (p_init_params->duty_cycle_step == 0) || + (p_init_params->leds_pin_bm == 0)) + { + return NRF_ERROR_INVALID_PARAM; + } + + + + memset(&m_led_sb, 0, sizeof(led_sb_context_t)); + memcpy(&m_led_sb.params, p_init_params, sizeof(led_sb_init_params_t)); + + m_led_sb.is_counting_up = true; + m_led_sb.duty_cycle = p_init_params->duty_cycle_min + p_init_params->duty_cycle_step; + m_led_sb.leds_is_on = false; + m_led_sb.bit_mask = p_init_params->leds_pin_bm; + + APP_TIMER_DEF(led_softblink_timer); + + m_led_sb.pwm_config.active_high = m_led_sb.params.active_high; + m_led_sb.pwm_config.bit_mask = p_init_params->leds_pin_bm; + m_led_sb.pwm_config.p_port = p_init_params->p_leds_port; + m_led_sb.pwm_config.period = PWM_PERIOD; + m_led_sb.pwm_config.p_timer_id = &led_softblink_timer; + + err_code = low_power_pwm_init( &m_led_sb.pwm_instance, &m_led_sb.pwm_config, led_softblink_on_timeout); + + if (err_code == NRF_SUCCESS) + { + m_led_sb.led_sb_state = NRF_DRV_STATE_INITIALIZED; + } + else + { + return err_code; + } + + err_code = low_power_pwm_duty_set( &m_led_sb.pwm_instance, p_init_params->duty_cycle_min + p_init_params->duty_cycle_step); + + return err_code; +} + + +ret_code_t led_softblink_start(uint32_t leds_pin_bit_mask) +{ + ret_code_t err_code; + + ASSERT(m_led_sb.led_sb_state == NRF_DRV_STATE_INITIALIZED); + + err_code = low_power_pwm_start(&m_led_sb.pwm_instance, leds_pin_bit_mask); + + return err_code; +} + + +ret_code_t led_softblink_stop(void) +{ + ret_code_t err_code; + + err_code = low_power_pwm_stop(&m_led_sb.pwm_instance); + + return err_code; +} + + +void led_softblink_off_time_set(uint32_t off_time_ticks) +{ + ASSERT(m_led_sb.led_sb_state != NRF_DRV_STATE_UNINITIALIZED); + + m_led_sb.params.off_time_ticks = off_time_ticks; +} + + +void led_softblink_on_time_set(uint32_t on_time_ticks) +{ + ASSERT(m_led_sb.led_sb_state != NRF_DRV_STATE_UNINITIALIZED); + + m_led_sb.params.on_time_ticks = on_time_ticks; +} + + +ret_code_t led_softblink_uninit(void) +{ + ASSERT(m_led_sb.led_sb_state != NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code; + + err_code = led_softblink_stop(); + + if (err_code == NRF_SUCCESS) + { + m_led_sb.led_sb_state = NRF_DRV_STATE_UNINITIALIZED; + } + else + { + return err_code; + } + + memset(&m_led_sb, 0, sizeof(m_led_sb)); + + return NRF_SUCCESS; +} +#endif //NRF_MODULE_ENABLED(LED_SOFTBLINK) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/led_softblink/led_softblink.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/led_softblink/led_softblink.h new file mode 100644 index 0000000000000000000000000000000000000000..5277b9cc34fecf1f16aad41bc66fc5dbc65d54a9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/led_softblink/led_softblink.h @@ -0,0 +1,171 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup led_softblink LED softblink + * @{ + * @ingroup app_common + * + * @brief Module for generating a changing pulse-width modulated output signal that is used to smoothly blink LEDs. + * + * @details This module provides an LED softblink implementation using timers and GPIO. + * + * LED softblink needs one timer. It can use any number of output channels that are available. + * + * Only one instance of LED softblink can run at a time. + */ + +#ifndef LED_SOFTBLINK_H__ +#define LED_SOFTBLINK_H__ + +#include +#include +#include "sdk_errors.h" +#include "nrf_gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Structure holding the initialization parameters. + */ +typedef struct +{ + bool active_high; /**< Activate negative polarity. */ + uint8_t duty_cycle_max; /**< Maximum impulse width. */ + uint8_t duty_cycle_min; /**< Minimum impulse width. */ + uint8_t duty_cycle_step; /**< Cycle step. */ + uint32_t off_time_ticks; /**< Ticks to stay in low impulse state. */ + uint32_t on_time_ticks; /**< Ticks to stay in high impulse state. */ + uint32_t leds_pin_bm; /**< Mask of used LEDs. */ + NRF_GPIO_Type * p_leds_port; /**< Port of used LEDs mask. */ +}led_sb_init_params_t; + +/** + * @name Default settings + * @brief Default settings for LED softblink. + * @{ + */ +#define LED_SB_INIT_PARAMS_ACTIVE_HIGH false +#define LED_SB_INIT_PARAMS_DUTY_CYCLE_MAX 220 +#define LED_SB_INIT_PARAMS_DUTY_CYCLE_MIN 0 +#define LED_SB_INIT_PARAMS_DUTY_CYCLE_STEP 5 +#define LED_SB_INIT_PARAMS_OFF_TIME_TICKS 65536 +#define LED_SB_INIT_PARAMS_ON_TIME_TICKS 0 +#define LED_SB_INIT_PARAMS_LEDS_PIN_BM(mask) (mask) +#define LED_SB_INIT_PARAMS_LEDS_PORT NRF_GPIO +/** @} */ + +/** + * @brief LED softblink default configuration. + */ +#define LED_SB_INIT_DEFAULT_PARAMS(mask) \ +{ \ + .active_high = LED_SB_INIT_PARAMS_ACTIVE_HIGH, \ + .duty_cycle_max = LED_SB_INIT_PARAMS_DUTY_CYCLE_MAX, \ + .duty_cycle_min = LED_SB_INIT_PARAMS_DUTY_CYCLE_MIN, \ + .duty_cycle_step = LED_SB_INIT_PARAMS_DUTY_CYCLE_STEP, \ + .off_time_ticks = LED_SB_INIT_PARAMS_OFF_TIME_TICKS, \ + .on_time_ticks = LED_SB_INIT_PARAMS_ON_TIME_TICKS, \ + .leds_pin_bm = LED_SB_INIT_PARAMS_LEDS_PIN_BM(mask), \ + .p_leds_port = LED_SB_INIT_PARAMS_LEDS_PORT \ +} + +/** + * @brief Function for initializing LED softblink. + * + * @param[in] p_init_params Pointer to the initialization structure. + * + * @return Values returned by @ref app_timer_create. + */ +ret_code_t led_softblink_init(led_sb_init_params_t const * p_init_params); + +/** + * @brief Function for starting to blink LEDs. + * + * @param[in] leds_pin_bit_mask Bit mask containing the pins for the LEDs to be blinked. + * + * @return Values returned by @ref app_timer_start. + */ +ret_code_t led_softblink_start(uint32_t leds_pin_bit_mask); + +/** + * @brief Function for stopping to blink LEDs. + * + * @return Values returned by @ref app_timer_stop. + */ +ret_code_t led_softblink_stop(void); + +/** + * @brief Function for setting the off time. + * + * This function configures the time that the LEDs will be off between each blink. + * + * @param[in] off_time_ticks Off time in ticks. + * + */ +void led_softblink_off_time_set(uint32_t off_time_ticks); + +/** + * @brief Function for setting the on time. + * + * This function configures the time that the LEDs will be on between each blink. + * + * @param[in] on_time_ticks On time in ticks. + * + */ +void led_softblink_on_time_set(uint32_t on_time_ticks); + +/** + * @brief Function for uninitializing LED softblink. + * + * @retval NRF_SUCCESS If LED softblink was uninitialized successfully. + */ +ret_code_t led_softblink_uninit(void); + +#ifdef __cplusplus +} +#endif + +#endif // LED_SOFTBLINK_H__ + +/** @} */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/nrf_log.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/nrf_log.h new file mode 100644 index 0000000000000000000000000000000000000000..405f8ede2b23bfa9e2c37360ee99115bad21799e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/nrf_log.h @@ -0,0 +1,220 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup nrf_log Logger module + * @{ + * @ingroup app_common + * + * @brief The nrf_log module interface. + */ + +#ifndef NRF_LOG_H_ +#define NRF_LOG_H_ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_LOG) +#include "nrf_strerror.h" +#define NRF_LOG_ERROR_STRING_GET(code) nrf_strerror_get(code) +#else +#define NRF_LOG_ERROR_STRING_GET(code) "" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Default module name prefix. + * + * The prefix can be defined in a module to override the default. + */ +#ifndef NRF_LOG_MODULE_NAME + #define NRF_LOG_MODULE_NAME "" +#endif + +/** @brief Severity level for the module. + * + * The severity level can be defined in a module to override the default. + */ +#ifndef NRF_LOG_LEVEL + #define NRF_LOG_LEVEL NRF_LOG_DEFAULT_LEVEL +#endif + +/** @brief Color prefix of debug logs for the module. + * + * This color prefix can be defined in a module to override the default. + */ +#ifndef NRF_LOG_DEBUG_COLOR + #define NRF_LOG_DEBUG_COLOR NRF_LOG_COLOR_DEFAULT +#endif + +/** @brief Color prefix of info logs for the module. + * + * This color prefix can be defined in a module to override the default. + */ +#ifndef NRF_LOG_INFO_COLOR + #define NRF_LOG_INFO_COLOR NRF_LOG_COLOR_DEFAULT +#endif + +#include "nrf_log_internal.h" + +/** @def NRF_LOG_ERROR + * @brief Macro for logging error messages. It takes a printf-like, formatted + * string with up to seven arguments. + * + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs. + */ + +/** @def NRF_LOG_WARNING + * @brief Macro for logging error messages. It takes a printf-like, formatted + * string with up to seven arguments. + * + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs. + */ + +/** @def NRF_LOG_INFO + * @brief Macro for logging error messages. It takes a printf-like, formatted + * string with up to seven arguments. + * + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs. + */ + +/** @def NRF_LOG_DEBUG + * @brief Macro for logging error messages. It takes a printf-like, formatted + * string with up to seven arguments. + * + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs. + */ + +#define NRF_LOG_ERROR(...) NRF_LOG_INTERNAL_ERROR(__VA_ARGS__) +#define NRF_LOG_WARNING(...) NRF_LOG_INTERNAL_WARNING( __VA_ARGS__) +#define NRF_LOG_INFO(...) NRF_LOG_INTERNAL_INFO( __VA_ARGS__) +#define NRF_LOG_DEBUG(...) NRF_LOG_INTERNAL_DEBUG( __VA_ARGS__) + +/** + * @brief A macro for logging a formatted string without any prefix or timestamp. + */ +#define NRF_LOG_RAW_INFO(...) NRF_LOG_INTERNAL_RAW_INFO( __VA_ARGS__) + +/** @def NRF_LOG_HEXDUMP_ERROR + * @brief Macro for logging raw bytes. + * @details It is compiled in only if @ref NRF_LOG_LEVEL includes error logs. + * + * @param p_data Pointer to data. + * @param len Data length in bytes. + */ +/** @def NRF_LOG_HEXDUMP_WARNING + * @brief Macro for logging raw bytes. + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs. + * + * @param p_data Pointer to data. + * @param len Data length in bytes. + */ +/** @def NRF_LOG_HEXDUMP_INFO + * @brief Macro for logging raw bytes. + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs. + * + * @param p_data Pointer to data. + * @param len Data length in bytes. + */ +/** @def NRF_LOG_HEXDUMP_DEBUG + * @brief Macro for logging raw bytes. + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs. + * + * @param p_data Pointer to data. + * @param len Data length in bytes. + */ +#define NRF_LOG_HEXDUMP_ERROR(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len) +#define NRF_LOG_HEXDUMP_WARNING(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len) +#define NRF_LOG_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len) +#define NRF_LOG_HEXDUMP_DEBUG(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len) + +/** + * @brief Macro for logging hexdump without any prefix or timestamp. + */ +#define NRF_LOG_RAW_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len) + +/** + * @brief A macro for blocking reading from bidirectional backend used for logging. + * + * Macro call is blocking and returns when single byte is received. + */ +#define NRF_LOG_GETCHAR() NRF_LOG_INTERNAL_GETCHAR() + +/** + * @brief Function for copying a string to the internal logger buffer if logs are deferred. + * + * Use this function to store a string that is volatile (for example allocated + * on stack) or that may change before the deferred logs are processed. Such string is copied + * into the internal logger buffer and is persistent until the log is processed. + * + * @note If the logs are not deferred, then this function returns the input parameter. + * + * @param p_str Pointer to the user string. + * + * @return Address to the location where the string is stored in the internal logger buffer. + */ +uint32_t nrf_log_push(char * const p_str); + +/** + * @brief Macro to be used in a formatted string to a pass float number to the log. + * + * Macro should be used in formatted string instead of the %f specifier together with + * @ref NRF_LOG_FLOAT macro. + * Example: NRF_LOG_INFO("My float number" NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(f))) + */ +#define NRF_LOG_FLOAT_MARKER "%s%d.%02d" + +/** + * @brief Macro for dissecting a float number into two numbers (integer and residuum). + */ +#define NRF_LOG_FLOAT(val) (uint32_t)(((val) < 0 && (val) > -1.0) ? "-" : ""), \ + (int32_t)(val), \ + (int32_t)((((val) > 0) ? (val) - (int32_t)(val) \ + : (int32_t)(val) - (val))*100) + +#ifdef __cplusplus +} +#endif + +#endif // NRF_LOG_H_ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/nrf_log_backend.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/nrf_log_backend.h new file mode 100644 index 0000000000000000000000000000000000000000..05e5b0a34fd5025946e6137301fe7312e638dcdf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/nrf_log_backend.h @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * @addtogroup nrf_log Logger module + * @ingroup app_common + * + * @defgroup nrf_log_backend Backend of nrf_log + * @{ + * @ingroup nrf_log + * @brief The nrf_log backend interface. + */ + + +#ifndef NRF_LOG_BACKEND_H__ +#define NRF_LOG_BACKEND_H__ + +#include "nrf_log_ctrl.h" +#include "sdk_errors.h" +#include + +/** + * @brief Function for initializing the logger backend. + * + * param blocking Set true if handler functions should block until completion. + * + * @return NRF_SUCCESS after successful initialization, error code otherwise. + */ +ret_code_t nrf_log_backend_init(bool blocking); + +/** + * @brief Function for returning a pointer to a function for handling standard + * log entries (@ref NRF_LOG_ERROR, etc.). + * + * @return Pointer to a handler. + */ +nrf_log_std_handler_t nrf_log_backend_std_handler_get(void); + +/** + * @brief Function for returning a pointer to a function for handling + * hexdumps (@ref NRF_LOG_HEXDUMP_ERROR, etc.). + * + * @return Pointer to a handler. + */ +nrf_log_hexdump_handler_t nrf_log_backend_hexdump_handler_get(void); + +/** + * @brief Function for blocking reading of a byte from the backend. + * + * @return Byte. + */ +uint8_t nrf_log_backend_getchar(void); +#endif // NRF_LOG_BACKEND_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/nrf_log_ctrl.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/nrf_log_ctrl.h new file mode 100644 index 0000000000000000000000000000000000000000..3aa91dfa18ce9692fbfa50d89ec6bb082c171f1a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/nrf_log_ctrl.h @@ -0,0 +1,237 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_LOG_CTRL_H +#define NRF_LOG_CTRL_H + +/**@file + * @addtogroup nrf_log Logger module + * @ingroup app_common + * + * @defgroup nrf_log_ctrl Functions for controlling nrf_log + * @{ + * @ingroup nrf_log + * @brief The nrf_log control interface. + */ + +#include "sdk_config.h" +#include "sdk_errors.h" +#include +#include +#include "nrf_log_ctrl_internal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Timestamp function prototype. + * + * @return Timestamp value. + */ +typedef uint32_t (*nrf_log_timestamp_func_t)(void); + +/**@brief Macro for initializing the logs. + * + * @note If timestamps are disabled in the configuration, then the provided pointer + * can be NULL. Otherwise, it is expected that timestamp_getter is not NULL. + * + * @param timestamp_func Function that returns the timestamp. + * + * @return NRF_SUCCESS after successful initialization, otherwise an error code. + */ +#define NRF_LOG_INIT(timestamp_func) NRF_LOG_INTERNAL_INIT(timestamp_func) + + +/**@brief Macro for processing a single log entry from a queue of deferred logs. + * + * You can call this macro from the main context or from the error handler to process + * log entries one by one. + * + * @note If logs are not deferred, this call has no use and is defined as 'false'. + * + * @retval true There are more logs to process in the buffer. + * @retval false No more logs in the buffer. + */ +#define NRF_LOG_PROCESS() NRF_LOG_INTERNAL_PROCESS() + +/** @brief Macro for processing all log entries from the buffer. + * It blocks until all buffered entries are processed by the backend. + * + * @note If logs are not deferred, this call has no use and is empty. + */ +#define NRF_LOG_FLUSH() NRF_LOG_INTERNAL_FLUSH() + +/** @brief Macro for flushing log data before reset. + * + * @note If logs are not deferred, this call has no use and is empty. + * + * @note If RTT is used, then a breakpoint is hit once flushed. + */ +#define NRF_LOG_FINAL_FLUSH() NRF_LOG_INTERNAL_FINAL_FLUSH() + +/** @brief Macro for changing functions that are used to handle log entries. + * + * @param default_handler Function for handling log entries. + * @param bytes_handler Function for handling hexdump entries. + * + */ +#define NRF_LOG_HANDLERS_SET(default_handler, bytes_handler) \ + NRF_LOG_INTERNAL_HANDLERS_SET(default_handler, bytes_handler) + +/** + * @brief Function prototype for handling a log entry. + * + * The backend must implement such prototype. + * + * @param severity_level Severity level of the entry. + * @param p_timestamp Pointer to the timestamp value. No timestamp if NULL. + * @param p_str Pointer to a formatted string. + * @param p_args Pointer to an array of arguments for a formatted string. + * @param nargs Number of arguments in p_args. + * + * @retval true If entry is successfully processed. + * @retval false If entry is not processed. + */ +typedef bool (*nrf_log_std_handler_t)( + uint8_t severity_level, + const uint32_t * const p_timestamp, + const char * const p_str, + uint32_t * p_args, + uint32_t nargs); + +/** + * @brief Function prototype for handling a bytes-dumping log entry. + * + * The backend must implement such prototype. Two buffers are needed because data + * is stored internally in a circular buffer so it can be fragmented into up to + * two pieces. + * + * @param severity_level Severity level of the entry. + * @param p_timestamp Pointer to a timestamp value. No timestamp if NULL. + * @param p_str Prefix string for the bytes dump. + * @param offset Indication of how many bytes have already been processed. + * @param p_buf0 Pointer to the first part of data. + * @param buf0_length Number of bytes in the first part. + * @param p_buf1 Pointer to the second part of data. Optional. + * @param buf1_length Number of bytes in the second part. + * + * @return Number of bytes processed. If all bytes are processed, it should be a sum of + * buf0_length and buf1_length + */ +typedef uint32_t (*nrf_log_hexdump_handler_t)( + uint8_t severity_level, + const uint32_t * const p_timestamp, + const char * const p_str, + uint32_t offset, + const uint8_t * const p_buf0, + uint32_t buf0_length, + const uint8_t * const p_buf1, + uint32_t buf1_length); + + +/** + * @brief Function for initializing the frontend and the default backend. + * + * @ref NRF_LOG_INIT calls this function to initialize the frontend and the backend. + * If custom backend is used, then @ref NRF_LOG_INIT should not be called. + * Instead, frontend and user backend should be verbosely initialized. + * + * @param timestamp_func Function for getting a 32-bit timestamp. + * + * @return Error status. + * + */ +ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func); + +/** + * @brief Function for reinitializing the backend in blocking mode. + */ +ret_code_t nrf_log_blocking_backend_set(void); + +/** + * @brief Function for initializing the logger frontend. + * + * The frontend is initialized with functions for handling log entries. Those + * functions are provided by the backend. + * + * @note This function needs to be called directly only if the @ref NRF_LOG_INIT macro + * is not used to initialize the logger. + * + * @param std_handler Function for handling standard log entries. + * @param hexdump_handler Function for handling hexdump log entries. + * @param timestamp_func Function for getting a timestamp. It cannot be NULL + * unless timestamping is disabled. + */ +void nrf_log_frontend_init(nrf_log_std_handler_t std_handler, + nrf_log_hexdump_handler_t hexdump_handler, + nrf_log_timestamp_func_t timestamp_func); + +/** + * @brief Function for updating functions that handle log entries. + * + * @note Use this feature to change the log handling behavior in certain + * situations, like in a fault handler. + * + * @param std_handler Function for handling standard log entries. + * @param hexdump_handler Function for handling hexdump log entries. + */ +void nrf_log_handlers_set(nrf_log_std_handler_t std_handler, + nrf_log_hexdump_handler_t hexdump_handler); + +/** + * @brief Function for handling a single log entry. + * + * Use this function only if the logs are buffered. It takes a single entry from the + * buffer and attempts to process it. + * + * @retval true If there are more entries to process. + * @retval false If there are no more entries to process. + */ +bool nrf_log_frontend_dequeue(void); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_LOG_CTRL_H + +/** + *@} + **/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/src/nrf_log_backend_serial.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/src/nrf_log_backend_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..23f4e98e05e089e5adceffc9a1ba440a941ca653 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/src/nrf_log_backend_serial.c @@ -0,0 +1,496 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_LOG) +#include "nrf_log_backend.h" +#include "nrf_error.h" +#include +#include +#include +#include + +#if NRF_LOG_BACKEND_SERIAL_USES_RTT +#include +#include +#endif + +#if NRF_LOG_BACKEND_SERIAL_USES_UART +#include "nrf_drv_uart.h" +#endif + +#if NRF_LOG_BACKEND_SERIAL_USES_UART +static char m_uart_buffer[NRF_LOG_BACKEND_MAX_STRING_LENGTH]; +static nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(NRF_LOG_BACKEND_UART_INSTANCE); + +#if !NRF_MODULE_ENABLED(UART) +#error "UART driver must be enabled to use UART in nrf_log." +#endif + +#endif //NRF_LOG_BACKEND_SERIAL_USES_UART + +#define HEXDUMP_BYTES_PER_LINE 16 +#define HEXDUMP_HEXBYTE_AREA 3 // Two bytes for hexbyte and space to separate +#define TIMESTAMP_STR(val) "[%0" STRINGIFY(val) "d]" + +#define RTT_RETRY_COUNTER 10 //Number of retries before skipping processing + +#define HEXDUMP_MAX_STR_LEN (NRF_LOG_BACKEND_MAX_STRING_LENGTH - \ + (HEXDUMP_HEXBYTE_AREA*HEXDUMP_BYTES_PER_LINE +\ + NRF_LOG_TIMESTAMP_DIGITS + \ + 4 +/* Color ANSI Escape Code */ \ + 2)) /* Separators */ + +static bool m_initialized = false; +static bool m_blocking_mode = false; +static const char m_default_color[] = "\x1B[0m"; + +#if (NRF_LOG_BACKEND_SERIAL_USES_UART) +static volatile bool m_rx_done = false; +#endif + +#if (NRF_LOG_BACKEND_SERIAL_USES_UART) +static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context) +{ + // Dummy handler since is_busy feature is used for determining readiness. + if (p_event->type == NRF_DRV_UART_EVT_RX_DONE) + { + m_rx_done = true; + } +} +#endif //NRF_LOG_BACKEND_SERIAL_USES_UART + + +ret_code_t nrf_log_backend_init(bool blocking) +{ + + if (m_initialized && (blocking == m_blocking_mode)) + { + return NRF_SUCCESS; + } +#if (NRF_LOG_BACKEND_SERIAL_USES_RTT) + SEGGER_RTT_Init(); +#endif + +#if (NRF_LOG_BACKEND_SERIAL_USES_UART) + uint32_t ret_code; + nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG; + uart_config.hwfc = + (nrf_uart_hwfc_t)NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL; + uart_config.pseltxd = NRF_LOG_BACKEND_SERIAL_UART_TX_PIN; + uart_config.pselrxd = NRF_LOG_BACKEND_SERIAL_UART_RX_PIN; + uart_config.pselrts = NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN; + uart_config.pselcts = NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN; + uart_config.baudrate = + (nrf_uart_baudrate_t)NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE; + nrf_drv_uart_uninit(&m_uart); + ret_code = nrf_drv_uart_init(&m_uart, &uart_config, + blocking ? NULL : uart_event_handler); + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } +#endif //NRF_LOG_BACKEND_SERIAL_USES_UART + + m_initialized = true; + m_blocking_mode = blocking; + return NRF_SUCCESS; +} + + +static bool serial_is_busy(void) +{ + bool res = false; + +#if (NRF_LOG_BACKEND_SERIAL_USES_UART) + res = nrf_drv_uart_tx_in_progress(&m_uart); +#endif + +#if (NRF_LOG_BACKEND_SERIAL_USES_RTT) + +#endif + + return res; +} + + +static bool serial_tx(uint8_t * p_buf, uint32_t len) +{ + bool ret = true; + +#if NRF_LOG_BACKEND_SERIAL_USES_UART + memcpy(m_uart_buffer, p_buf, len); + uint32_t ret_code = nrf_drv_uart_tx(&m_uart, (uint8_t *)m_uart_buffer, len); + if (ret_code != NRF_SUCCESS) + { + ret = false; + } +#endif //NRF_LOG_BACKEND_SERIAL_USES_UART + +#if NRF_LOG_BACKEND_SERIAL_USES_RTT + uint32_t idx = 0; + uint32_t length = len; + uint32_t processed; + uint32_t watchdog_counter = RTT_RETRY_COUNTER; + do + { + processed = SEGGER_RTT_WriteNoLock(0, &p_buf[idx], length); + idx += processed; + length -= processed; + if (processed == 0) + { + // If RTT is not connected then ensure that logger does not block + watchdog_counter--; + if (watchdog_counter == 0) + { + break; + } + } + } while (length); +#endif //NRF_LOG_BACKEND_SERIAL_USES_RTT + return ret; +} + + +static uint8_t serial_get_byte(void) +{ + uint8_t data; +#if NRF_LOG_BACKEND_SERIAL_USES_UART + if (m_blocking_mode) + { + (void)nrf_drv_uart_rx(&m_uart, &data, 1); + } + else + { + m_rx_done = false; + (void)nrf_drv_uart_rx(&m_uart, &data, 1); + while(!m_rx_done); + } +#elif NRF_LOG_BACKEND_SERIAL_USES_RTT + data = (uint8_t)SEGGER_RTT_WaitKey(); +#endif //NRF_LOG_BACKEND_SERIAL_USES_RTT + return data; +} + + +static bool buf_len_update(uint32_t * p_buf_len, int32_t new_len) +{ + bool ret; + if (new_len < 0) + { + ret = false; + } + else + { + *p_buf_len += (uint32_t)new_len; + ret = true; + } + return ret; +} + + +static bool timestamp_process(const uint32_t * const p_timestamp, char * p_str, uint32_t * p_len) +{ + int32_t len = 0; + bool ret = true; + if (p_timestamp) + { +#if NRF_LOG_USES_COLORS + len = sizeof(m_default_color) - 1; + memcpy(p_str, m_default_color, len); + *p_len += len; +#endif //NRF_LOG_USES_COLORS + len = snprintf(&p_str[len],NRF_LOG_BACKEND_MAX_STRING_LENGTH, TIMESTAMP_STR(NRF_LOG_TIMESTAMP_DIGITS), (int)*p_timestamp); + ret = buf_len_update(p_len, len); + } + else + { + *p_len = 0; + } + return ret; +} + + +static bool nrf_log_backend_serial_std_handler( + uint8_t severity_level, + const uint32_t * const p_timestamp, + const char * const p_str, + uint32_t * p_args, + uint32_t nargs) +{ + char str[NRF_LOG_BACKEND_MAX_STRING_LENGTH]; + int32_t tmp_str_len = 0; + uint32_t buffer_len = 0; + bool status = true; + + if (serial_is_busy()) + { + return false; + } + + if (!timestamp_process(p_timestamp, &str[buffer_len], &buffer_len)) + { + return false; + } + + switch (nargs) + { + case 0: + { + tmp_str_len = strlen(p_str); + if ((tmp_str_len + buffer_len) < NRF_LOG_BACKEND_MAX_STRING_LENGTH) + { + memcpy(&str[buffer_len], p_str, tmp_str_len); + } + break; + } + + case 1: + tmp_str_len = snprintf(&str[buffer_len], NRF_LOG_BACKEND_MAX_STRING_LENGTH-buffer_len, p_str, p_args[0]); + + break; + + case 2: + tmp_str_len = snprintf(&str[buffer_len], NRF_LOG_BACKEND_MAX_STRING_LENGTH-buffer_len, p_str, p_args[0], p_args[1]); + break; + + case 3: + tmp_str_len = snprintf(&str[buffer_len], NRF_LOG_BACKEND_MAX_STRING_LENGTH-buffer_len, p_str, p_args[0], p_args[1], p_args[2]); + break; + + case 4: + tmp_str_len = + snprintf(&str[buffer_len], NRF_LOG_BACKEND_MAX_STRING_LENGTH-buffer_len, p_str, p_args[0], p_args[1], p_args[2], p_args[3]); + break; + + case 5: + tmp_str_len = + snprintf(&str[buffer_len], + NRF_LOG_BACKEND_MAX_STRING_LENGTH-buffer_len, + p_str, + p_args[0], + p_args[1], + p_args[2], + p_args[3], + p_args[4]); + break; + + case 6: + tmp_str_len = + snprintf(&str[buffer_len], + NRF_LOG_BACKEND_MAX_STRING_LENGTH-buffer_len, + p_str, + p_args[0], + p_args[1], + p_args[2], + p_args[3], + p_args[4], + p_args[5]); + break; + + default: + break; + } + status = buf_len_update(&buffer_len, tmp_str_len); + uint32_t full_buff_len = NRF_LOG_USES_COLORS ? + buffer_len + sizeof(m_default_color)-1 : buffer_len; + if (status && (full_buff_len <= NRF_LOG_BACKEND_MAX_STRING_LENGTH)) + { + if (NRF_LOG_USES_COLORS) + { + memcpy(&str[buffer_len], m_default_color, sizeof(m_default_color)-1); + buffer_len = full_buff_len; + } + return serial_tx((uint8_t *)str, buffer_len); + } + else + { + // error, snprintf failed. + return false; + } +} + + +static void byte2hex(const uint8_t c, char * p_out) +{ + uint8_t nibble; + uint32_t i = 2; + + while (i-- != 0) + { + nibble = (c >> (4 * i)) & 0x0F; + p_out[1 - i] = (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble); + } +} + + +static uint32_t nrf_log_backend_serial_hexdump_handler( + uint8_t severity_level, + const uint32_t * const p_timestamp, + const char * const p_str, + uint32_t offset, + const uint8_t * const p_buf0, + uint32_t buf0_length, + const uint8_t * const p_buf1, + uint32_t buf1_length) +{ + char str[NRF_LOG_BACKEND_MAX_STRING_LENGTH]; + uint32_t slen; + char * p_hex_part; + char * p_char_part; + uint8_t c; + uint32_t byte_in_line; + uint32_t buffer_len = 0; + uint32_t byte_cnt = offset; + uint32_t length = buf0_length + buf1_length; + uint32_t timestamp_len = p_timestamp ? + NRF_LOG_TIMESTAMP_DIGITS+2 : 0; //+2 since timestamp is in brackets + + if (serial_is_busy()) + { + return offset; + } + + // If it is the first part of hexdump print the header + if (offset == 0) + { + if (!timestamp_process(p_timestamp, &str[buffer_len], &buffer_len)) + { + return offset; + } + slen = strlen(p_str); + // Saturate string if it's too long. + slen = (slen > HEXDUMP_MAX_STR_LEN) ? HEXDUMP_MAX_STR_LEN : slen; + memcpy(&str[buffer_len], p_str, slen); + buffer_len += slen; + } + + do + { + + uint32_t i; + uint32_t hex_part_offset = buffer_len; + uint32_t char_part_offset = hex_part_offset + + (HEXDUMP_BYTES_PER_LINE * HEXDUMP_HEXBYTE_AREA + 1) + // +1 - separator between hexdump and characters. + timestamp_len; + + p_hex_part = &str[hex_part_offset]; + p_char_part = &str[char_part_offset]; + + // Fill the blanks to align to timestamp print + for (i = 0; i < timestamp_len; i++) + { + *p_hex_part = ' '; + ++p_hex_part; + } + + for (byte_in_line = 0; byte_in_line < HEXDUMP_BYTES_PER_LINE; byte_in_line++) + { + if (byte_cnt >= length) + { + // file the blanks + *p_hex_part++ = ' '; + *p_hex_part++ = ' '; + *p_hex_part++ = ' '; + *p_char_part++ = ' '; + } + else + { + if (byte_cnt < buf0_length) + { + c = p_buf0[byte_cnt]; + } + else + { + c = p_buf1[byte_cnt - buf0_length]; + } + byte2hex(c, p_hex_part); + p_hex_part += 2; // move the pointer since byte in hex was added. + *p_hex_part++ = ' '; + *p_char_part++ = isprint(c) ? c : '.'; + byte_cnt++; + } + } + *p_char_part++ = '\r'; + *p_char_part++ = '\n'; + *p_hex_part++ = ' '; + buffer_len += timestamp_len + + (HEXDUMP_BYTES_PER_LINE * HEXDUMP_HEXBYTE_AREA + 1) + // space for hex dump and separator between hexdump and string + HEXDUMP_BYTES_PER_LINE + // space for stringS dump + 2; // space for new line + if (NRF_LOG_USES_COLORS) + { + memcpy(&str[buffer_len], m_default_color, sizeof(m_default_color)-1); + buffer_len += sizeof(m_default_color)-1; + } + + if (!serial_tx((uint8_t *)str, buffer_len)) + { + return byte_cnt; + } + + if (serial_is_busy()) + { + return byte_cnt; + } + buffer_len = 0; + } + while (byte_cnt < length); + return byte_cnt; +} + + +nrf_log_std_handler_t nrf_log_backend_std_handler_get(void) +{ + return nrf_log_backend_serial_std_handler; +} + + +nrf_log_hexdump_handler_t nrf_log_backend_hexdump_handler_get(void) +{ + return nrf_log_backend_serial_hexdump_handler; +} + + +uint8_t nrf_log_backend_getchar(void) +{ + return serial_get_byte(); +} + +#endif // NRF_MODULE_ENABLED(NRF_LOG) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/src/nrf_log_ctrl_internal.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/src/nrf_log_ctrl_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..3d6d3e514b426910c408598123fe8fec9b38e62f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/src/nrf_log_ctrl_internal.h @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_LOG_CTRL_INTERNAL_H +#define NRF_LOG_CTRL_INTERNAL_H +/** + * @cond (NODOX) + * @defgroup nrf_log_ctrl_internal Auxiliary internal types declarations + * @{ + * @internal + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_LOG) +#include "app_util_platform.h" + +#define NRF_LOG_INTERNAL_INIT(timestamp_func) \ + nrf_log_init(timestamp_func) + +#if (NRF_LOG_DEFERRED == 0) +#define NRF_LOG_INTERNAL_PROCESS() false +#define NRF_LOG_INTERNAL_FLUSH() +#define NRF_LOG_INTERNAL_FINAL_FLUSH() +#else +#define NRF_LOG_INTERNAL_PROCESS() nrf_log_frontend_dequeue() +#define NRF_LOG_INTERNAL_FLUSH() \ + do { \ + while (NRF_LOG_INTERNAL_PROCESS()); \ + } while(0) + +#if NRF_LOG_BACKEND_SERIAL_USES_RTT +#define NRF_LOG_INTERNAL_BACKEND_FINAL NRF_BREAKPOINT_COND +#else +#define NRF_LOG_INTERNAL_BACKEND_FINAL +#endif + +#define NRF_LOG_INTERNAL_FINAL_FLUSH() \ + do { \ + (void)nrf_log_blocking_backend_set(); \ + NRF_LOG_INTERNAL_FLUSH(); \ + NRF_LOG_INTERNAL_BACKEND_FINAL; \ + } while(0) + +#endif + +#define NRF_LOG_INTERNAL_HANDLERS_SET(default_handler, bytes_handler) \ + nrf_log_handlers_set(default_handler, bytes_handler) + +#else // NRF_MODULE_ENABLED(NRF_LOG) +#define NRF_LOG_INTERNAL_PROCESS() false +#define NRF_LOG_INTERNAL_FLUSH() +#define NRF_LOG_INTERNAL_INIT(timestamp_func) NRF_SUCCESS +#define NRF_LOG_INTERNAL_HANDLERS_SET(default_handler, bytes_handler) \ + UNUSED_PARAMETER(default_handler); UNUSED_PARAMETER(bytes_handler) +#define NRF_LOG_INTERNAL_FINAL_FLUSH() +#endif // NRF_MODULE_ENABLED(NRF_LOG) + +/** @} + * @endcond + */ +#endif // NRF_LOG_CTRL_INTERNAL_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/src/nrf_log_frontend.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/src/nrf_log_frontend.c new file mode 100644 index 0000000000000000000000000000000000000000..248fdca13270cbb16ca7aea20afb7f8b40e4c9c6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/src/nrf_log_frontend.c @@ -0,0 +1,826 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_LOG) +#include "app_util.h" +#include "app_util_platform.h" +#include "nrf_log.h" +#include "nrf_log_internal.h" +#include "nrf_log_backend.h" +#include "nrf_log_ctrl.h" +#include + +#if NRF_LOG_DEFERRED +STATIC_ASSERT((NRF_LOG_DEFERRED_BUFSIZE == 0) || IS_POWER_OF_TWO(NRF_LOG_DEFERRED_BUFSIZE)); +#else +#define NRF_LOG_DEFERRED_BUFSIZE 1 +#endif + +/** + * brief An internal control block of the logger + * + * @note Circular buffer is using never cleared indexes and a mask. It means + * that logger may break when indexes overflows. However, it is quite unlikely. + * With rate of 1000 log entries with 2 parameters per second such situation + * would happen after 12 days. + */ +typedef struct +{ + uint32_t wr_idx; // Current write index (never reset) + uint32_t rd_idx; // Current read index (never_reset) + uint32_t mask; // Size of buffer (must be power of 2) presented as mask + uint32_t buffer[NRF_LOG_DEFERRED_BUFSIZE]; + nrf_log_timestamp_func_t timestamp_func; // A pointer to function that returns timestamp + nrf_log_std_handler_t std_handler; // A handler used for processing standard log calls + nrf_log_hexdump_handler_t hexdump_handler; // A handler for processing hex dumps +} log_data_t; + +static log_data_t m_log_data; +#if (NRF_LOG_DEFERRED == 1) +static const char * m_overflow_info = NRF_LOG_ERROR_COLOR_CODE "Overflow\r\n"; +#endif //(NRF_LOG_DEFERRED == 1) + +/** + * Set of macros for encoding and decoding header for log entries. + * There are 3 types of entries: + * 1. Standard entry (STD) + * An entry consists of header, pointer to string and values. Header contains + * severity leveland determines number of arguments and thus size of the entry. + * Since flash address space starts from 0x00000000 and is limited to kB rather + * than MB 22 bits are used to store the address (4MB). It is used that way to + * save one RAM memory. + * + * -------------------------------- + * |TYPE|SEVERITY|NARGS| P_STR | + * |------------------------------| + * | TIMESTAMP (optional) | + * |------------------------------| + * | ARG0 | + * |------------------------------| + * | .... | + * |------------------------------| + * | ARG(nargs-1) | + * -------------------------------- + * + * 2. Hexdump entry (HEXDUMP) is used for dumping raw data. An entry consists of + * header, optional timestamp, pointer to string and data. A header contains + * length (10bit) and offset which is updated after backend processes part of + * data. + * + * -------------------------------- + * |TYPE|SEVERITY|NARGS|OFFSET|LEN| + * |------------------------------| + * | TIMESTAMP (optional) | + * |------------------------------| + * | P_STR | + * |------------------------------| + * | data | + * |------------------------------| + * | data | dummy | + * -------------------------------- + * + * 3. Pushed string. If string is pushed into the logger internal buffer it is + * stored as PUSHED entry. It consists of header, unused data (optional) and + * string. Unused data is present if string does not not fit into a buffer + * without wrapping (and string cannot be wrapped). In that case header + * contains information about offset. + * + * -------------------------------- + * |TYPE| OFFSET | LEN | + * |------------------------------| + * | OFFSET | + * |------------------------------| + * end| OFFSET | + * 0|------------------------------| + * | STRING | + * |------------------------------| + * | STRING | dummy | + * -------------------------------- + */ +#define HEADER_SIZE ((NRF_LOG_USES_TIMESTAMP) ? 2 : 1) + +#define STD_ADDR_MASK ((uint32_t)(1U << 22) - 1U) +#define HEADER_TYPE_STD 1U +#define HEADER_TYPE_HEXDUMP 2U +#define HEADER_TYPE_PUSHED 0U + +typedef struct +{ + uint32_t type : 2; + uint32_t raw : 1; + uint32_t data : 29; +} nrf_log_generic_header_t; + +typedef struct +{ + uint32_t type : 2; + uint32_t raw : 1; + uint32_t severity : 3; + uint32_t nargs : 4; + uint32_t addr : 22; +} nrf_log_std_header_t; + +typedef struct +{ + uint32_t type : 2; + uint32_t raw : 1; + uint32_t severity : 3; + uint32_t offset : 10; + uint32_t reserved : 6; + uint32_t len : 10; +} nrf_log_hexdump_header_t; + +typedef struct +{ + uint32_t type : 2; + uint32_t reserved0 : 4; + uint32_t offset : 10; + uint32_t reserved1 : 6; + uint32_t len : 10; +} nrf_log_pushed_header_t; + +typedef union +{ + nrf_log_generic_header_t generic; + nrf_log_std_header_t std; + nrf_log_hexdump_header_t hexdump; + nrf_log_pushed_header_t pushed; + uint32_t raw; +} nrf_log_header_t; + +/* IAR does not support initialization with non-constant variables */ +#if defined ( __ICCARM__ ) +#define STD_HEADER_DEF(NAME, P_STR, SEVERITY, NARGS) \ + nrf_log_header_t NAME = { \ + .std = { \ + .type = HEADER_TYPE_STD, \ + } \ + }; \ + NAME.std.type = HEADER_TYPE_STD; \ + NAME.std.raw = ((SEVERITY) & NRF_LOG_RAW); \ + NAME.std.severity = (SEVERITY) & NRF_LOG_LEVEL_MASK; \ + NAME.std.nargs = (NARGS); \ + NAME.std.addr = ((uint32_t)(P_STR) & STD_ADDR_MASK) +#else +#define STD_HEADER_DEF(NAME, P_STR, SEVERITY, NARGS) \ + nrf_log_header_t NAME = { \ + .std = { \ + .type = HEADER_TYPE_STD, \ + .raw = ((SEVERITY) & NRF_LOG_RAW), \ + .severity = (SEVERITY) & NRF_LOG_LEVEL_MASK, \ + .nargs = (NARGS), \ + .addr = ((uint32_t)(P_STR) & STD_ADDR_MASK)\ + } \ + } +#endif + +#if defined ( __ICCARM__ ) +#define HEXDUMP_HEADER_DEF(NAME, SEVERITY, LENGTH) \ + nrf_log_header_t NAME = { \ + .hexdump = { \ + .type = HEADER_TYPE_HEXDUMP, \ + .offset = 0, \ + } \ + }; \ + NAME.hexdump.raw = ((SEVERITY) & NRF_LOG_RAW); \ + NAME.hexdump.severity = (SEVERITY) & NRF_LOG_LEVEL_MASK;\ + NAME.hexdump.len = (LENGTH) + +#else +#define HEXDUMP_HEADER_DEF(NAME, SEVERITY, LENGTH) \ + nrf_log_header_t NAME = { \ + .hexdump = { \ + .type = HEADER_TYPE_HEXDUMP, \ + .raw = ((SEVERITY) & NRF_LOG_RAW), \ + .severity = (SEVERITY) & NRF_LOG_LEVEL_MASK, \ + .offset = 0, \ + .len = LENGTH, \ + } \ + } +#endif + +#if defined ( __ICCARM__ ) +#define PUSHED_HEADER_DEF(NAME, OFFSET, LENGTH) \ + nrf_log_header_t NAME = { \ + .pushed = { \ + .type = HEADER_TYPE_PUSHED, \ + } \ + }; \ + NAME.pushed.offset = (OFFSET); \ + NAME.pushed.len = (LENGTH) + +#else +#define PUSHED_HEADER_DEF(NAME, OFFSET, LENGTH) \ + nrf_log_header_t NAME = { \ + .pushed = { \ + .type = HEADER_TYPE_PUSHED, \ + .offset = (OFFSET), \ + .len = (LENGTH), \ + } \ + } + +#endif + +ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func) +{ + if (NRF_LOG_USES_TIMESTAMP && (timestamp_func == NULL)) + { + return NRF_ERROR_INVALID_PARAM; + } + + ret_code_t err_code = nrf_log_backend_init(NRF_LOG_DEFERRED ? false : true); + + if (err_code == NRF_SUCCESS) + { + nrf_log_frontend_init(nrf_log_backend_std_handler_get(), + nrf_log_backend_hexdump_handler_get(), + timestamp_func); + } + return err_code; +} + + +ret_code_t nrf_log_blocking_backend_set(void) +{ + // Return value is ommited because + return nrf_log_backend_init(true); +} + + +void nrf_log_frontend_init(nrf_log_std_handler_t std_handler, + nrf_log_hexdump_handler_t hexdump_handler, + nrf_log_timestamp_func_t timestamp_func) +{ +#if NRF_LOG_DEFERRED + m_log_data.mask = NRF_LOG_DEFERRED_BUFSIZE - 1; + m_log_data.wr_idx = 0; + m_log_data.rd_idx = 0; +#endif //NRF_LOG_DEFERRED +#if NRF_LOG_USES_TIMESTAMP + m_log_data.timestamp_func = timestamp_func; +#endif //NRF_LOG_USES_TIMESTAMP + nrf_log_handlers_set(std_handler, hexdump_handler); +} + + +void nrf_log_handlers_set(nrf_log_std_handler_t std_handler, + nrf_log_hexdump_handler_t hexdump_handler) +{ + m_log_data.std_handler = std_handler; + m_log_data.hexdump_handler = hexdump_handler; +} + +#if (NRF_LOG_DEFERRED == 1) +/** + * @brief Allocates chunk in a buffer for one entry and injects overflow if + * there is no room for requested entry. + * + * @param nargs Number of 32bit arguments. In case of allocating for hex dump it + * is the size of the buffer in 32bit words (ceiled). + * @param p_wr_idx Pointer to write index. + * + * @return True if successful allocation, false otherwise. + * + */ +static inline bool buf_prealloc(uint32_t nargs, uint32_t * p_wr_idx) +{ + nargs += HEADER_SIZE; + uint32_t ovflw_tag_size = HEADER_SIZE; + bool ret = true; + CRITICAL_REGION_ENTER(); + *p_wr_idx = m_log_data.wr_idx; + uint32_t available_words = (m_log_data.mask + 1) - (m_log_data.wr_idx - m_log_data.rd_idx); + uint32_t required_words = nargs + ovflw_tag_size; // room for current entry and overflow + if (required_words > available_words) + { + if (available_words >= HEADER_SIZE) + { + // Overflow entry is injected + STD_HEADER_DEF(header, m_overflow_info, NRF_LOG_LEVEL_INTERNAL, 0); + m_log_data.buffer[m_log_data.wr_idx++ & m_log_data.mask] = + header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[m_log_data.wr_idx++ & m_log_data.mask] = + m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + } + // overflow case + ret = false; + } + else + { + m_log_data.wr_idx += nargs; + } + CRITICAL_REGION_EXIT(); + return ret; +} + + +/** + * @brief Function for preallocating a continuous chunk of memory from circular buffer. + * + * If buffer does not fit starting from current position it will be allocated at + * the beginning of the circular buffer and offset will be returned indicating + * how much memory has been ommited at the end of the buffer. Function is + * using critical section. + * + * @param len32 Length of buffer to allocate. Given in words. + * @param p_offset Offset of the buffer. + * @param p_wr_idx Pointer to write index. + * + * @return A pointer to the allocated buffer. NULL if allocation failed. + */ +static inline uint32_t * cont_buf_prealloc(uint32_t len32, + uint32_t * p_offset, + uint32_t * p_wr_idx) +{ + uint32_t * p_buf = NULL; + + len32++; // Increment because 32bit header is needed to be stored. + + CRITICAL_REGION_ENTER(); + *p_wr_idx = m_log_data.wr_idx; + uint32_t available_words = (m_log_data.mask + 1) - + (m_log_data.wr_idx & m_log_data.mask); + if (len32 <= available_words) + { + // buffer will fit as is + p_buf = &m_log_data.buffer[(m_log_data.wr_idx + 1) & m_log_data.mask]; + m_log_data.wr_idx += len32; + *p_offset = 0; + } + else if (len32 < (m_log_data.rd_idx & m_log_data.mask)) + { + // wraping to the begining of the buffer + m_log_data.wr_idx += (len32 + available_words - 1); + *p_offset = available_words - 1; + p_buf = m_log_data.buffer; + } + available_words = (m_log_data.mask + 1) - (m_log_data.wr_idx - m_log_data.rd_idx); + // If there is no more room for even overflow tag indicate failed allocation. + if (available_words < HEADER_SIZE) + { + p_buf = NULL; + } + CRITICAL_REGION_EXIT(); + + return p_buf; +} +#endif //(NRF_LOG_DEFERRED == 1) + + +#if (NRF_LOG_DEFERRED == 0) +static inline void nrf_log_direct_feed(uint8_t type, + char const * const p_str, + uint32_t * p_args, + uint32_t nargs) +{ + uint32_t timestamp = 0; + uint32_t * p_timestamp = NRF_LOG_USES_TIMESTAMP ? ×tamp : NULL; + +#if NRF_LOG_USES_TIMESTAMP + timestamp = m_log_data.timestamp_func(); +#else //NRF_LOG_USES_TIMESTAMP + UNUSED_VARIABLE(timestamp); +#endif //NRF_LOG_USES_TIMESTAMP + + UNUSED_VARIABLE + (m_log_data.std_handler(type, p_timestamp, (char *)p_str, p_args, nargs)); + +} +#endif //(NRF_LOG_DEFERRED == 0) + + +uint32_t nrf_log_push(char * const p_str) +{ +#if (NRF_LOG_DEFERRED == 0) + return (uint32_t)p_str; +#else //(NRF_LOG_DEFERRED == 0) + uint32_t mask = m_log_data.mask; + uint32_t slen = strlen(p_str) + 1; + uint32_t buflen = CEIL_DIV(slen, 4); + uint32_t offset = 0; + uint32_t wr_idx; + char * p_dst_str = (char *)cont_buf_prealloc(buflen, &offset, &wr_idx); + if (p_dst_str) + { + PUSHED_HEADER_DEF(header, offset, buflen); + m_log_data.buffer[wr_idx++ & mask] = header.raw; + memcpy(p_dst_str, p_str, slen); + } + return (uint32_t)p_dst_str; +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_0(uint8_t severity, char const * const p_str) +{ +#if (NRF_LOG_DEFERRED == 0) + nrf_log_direct_feed(severity, p_str, NULL, 0); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 0; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_1(uint8_t severity, + char const * const p_str, + uint32_t val0) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t args[] = {val0}; + nrf_log_direct_feed(severity, p_str, args, ARRAY_SIZE(args)); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 1; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx & mask] = val0; + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_2(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t args[] = {val0, val1}; + nrf_log_direct_feed(severity, p_str, args, ARRAY_SIZE(args)); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 2; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = val0; + m_log_data.buffer[wr_idx & mask] = val1; + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_3(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t args[] = {val0, val1, val2}; + nrf_log_direct_feed(severity, p_str, args, ARRAY_SIZE(args)); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 3; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = val0; + m_log_data.buffer[wr_idx++ & mask] = val1; + m_log_data.buffer[wr_idx & mask] = val2; + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_4(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2, + uint32_t val3) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t args[] = {val0, val1, val2, val3}; + nrf_log_direct_feed(severity, p_str, args, ARRAY_SIZE(args)); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 4; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = val0; + m_log_data.buffer[wr_idx++ & mask] = val1; + m_log_data.buffer[wr_idx++ & mask] = val2; + m_log_data.buffer[wr_idx & mask] = val3; + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_5(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2, + uint32_t val3, + uint32_t val4) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t args[] = {val0, val1, val2, val3, val4}; + nrf_log_direct_feed(severity, p_str, args, ARRAY_SIZE(args)); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 5; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = val0; + m_log_data.buffer[wr_idx++ & mask] = val1; + m_log_data.buffer[wr_idx++ & mask] = val2; + m_log_data.buffer[wr_idx++ & mask] = val3; + m_log_data.buffer[wr_idx & mask] = val4; + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_6(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2, + uint32_t val3, + uint32_t val4, + uint32_t val5) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t args[] = {val0, val1, val2, val3, val4, val5}; + nrf_log_direct_feed(severity, p_str, args, ARRAY_SIZE(args)); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 6; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = val0; + m_log_data.buffer[wr_idx++ & mask] = val1; + m_log_data.buffer[wr_idx++ & mask] = val2; + m_log_data.buffer[wr_idx++ & mask] = val3; + m_log_data.buffer[wr_idx++ & mask] = val4; + m_log_data.buffer[wr_idx & mask] = val5; + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_hexdump(uint8_t severity, + char const * const p_str, + const void * const p_data, + uint16_t length) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t timestamp = 0; +#if NRF_LOG_USES_TIMESTAMP + timestamp = m_log_data.timestamp_func(); +#else //NRF_LOG_USES_TIMESTAMP + (void) timestamp; +#endif //NRF_LOG_USES_TIMESTAMP + + uint32_t curr_offset = 0; + + do + { + curr_offset = m_log_data.hexdump_handler(severity, + NRF_LOG_USES_TIMESTAMP ? ×tamp : NULL, + p_str, + curr_offset, + p_data, + length, + NULL, + 0); + } + while (curr_offset < length); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t mask = m_log_data.mask; + + uint32_t wr_idx; + if (buf_prealloc(CEIL_DIV(length, 4) + 1, &wr_idx)) + { + HEXDUMP_HEADER_DEF(header, severity, length); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = (uint32_t)p_str; + uint32_t space0 = sizeof(uint32_t) * (m_log_data.mask + 1 - (wr_idx & mask)); + if (length <= space0) + { + memcpy(&m_log_data.buffer[wr_idx & mask], p_data, length); + } + else + { + memcpy(&m_log_data.buffer[wr_idx & mask], p_data, space0); + length -= space0; + memcpy(&m_log_data.buffer[0], &((uint8_t *)p_data)[space0], length); + } + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +bool buffer_is_empty(void) +{ + return (m_log_data.rd_idx == m_log_data.wr_idx); +} + + +bool nrf_log_frontend_dequeue(void) +{ + if (buffer_is_empty()) + { + return false; + } + + uint32_t rd_idx = m_log_data.rd_idx; + uint32_t mask = m_log_data.mask; + uint32_t header_rd_idx = rd_idx; + // uint32_t header = m_log_data.buffer[rd_idx++ & mask]; + nrf_log_header_t header; + header.raw = m_log_data.buffer[rd_idx++ & mask]; + + // Skip any string that is pushed to the circular buffer. + while (header.generic.type == HEADER_TYPE_PUSHED) + { + rd_idx += (header.pushed.len + header.pushed.offset); + header_rd_idx = rd_idx; + header.raw = m_log_data.buffer[rd_idx++ & mask]; + } + + uint32_t * p_timestamp = NRF_LOG_USES_TIMESTAMP ? + &m_log_data.buffer[rd_idx++ & mask] : NULL; + + if (header.generic.raw) + { + p_timestamp = NULL; + } + + bool ret = false; + if (header.generic.type == HEADER_TYPE_HEXDUMP) + { + // buffer + char * p_str = (char *)m_log_data.buffer[rd_idx++ & mask]; + uint32_t length = header.hexdump.len; + uint32_t offset = header.hexdump.offset; + uint32_t space0 = sizeof(uint32_t) * (mask + 1 - (rd_idx & mask)); + if (length > space0) + { + uint8_t * ptr0 = space0 ? + (uint8_t *)&m_log_data.buffer[rd_idx & mask] : + (uint8_t *)&m_log_data.buffer[0]; + uint8_t len0 = space0 ? space0 : length; + uint8_t * ptr1 = space0 ? + (uint8_t *)&m_log_data.buffer[0] : NULL; + uint8_t len1 = space0 ? length - space0 : 0; + + offset = m_log_data.hexdump_handler(header.hexdump.severity, + p_timestamp, p_str, + offset, + ptr0, len0, + ptr1, len1); + } + else + { + offset = m_log_data.hexdump_handler( + header.hexdump.severity, + p_timestamp, + p_str, + offset, + (uint8_t *)&m_log_data.buffer[rd_idx & mask], + length, + NULL, 0); + } + + if (offset == length) + { + rd_idx += CEIL_DIV(length, 4); + ret = true; + } + else + { + // If there is more log to process just updated the offset but + // do not move rd_idx. + header.hexdump.offset = offset; + m_log_data.buffer[header_rd_idx & mask] = header.raw; + } + } + else // standard entry + { + uint32_t args[6]; + uint32_t * p_arg = args; + char * p_str = (char *)((uint32_t)header.std.addr); + uint32_t nargs = header.std.nargs; + + uint32_t i; + + for (i = 0; i < nargs; i++) + { + *p_arg = m_log_data.buffer[rd_idx++ & mask]; + p_arg++; + } + + ret = m_log_data.std_handler(header.std.severity, + p_timestamp, + p_str, args, nargs); + } + if (ret) + { + m_log_data.rd_idx = rd_idx; + } + return buffer_is_empty() ? false : true; + +} + +uint8_t nrf_log_getchar(void) +{ + return nrf_log_backend_getchar(); +} + +#endif // NRF_MODULE_ENABLED(NRF_LOG) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/src/nrf_log_internal.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/src/nrf_log_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..1e91cda9baf0f9833512413b3b4719b0193fbd01 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/log/src/nrf_log_internal.h @@ -0,0 +1,309 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_LOG_INTERNAL_H__ +#define NRF_LOG_INTERNAL_H__ +#include "sdk_common.h" +#include "nrf.h" +#include "nrf_error.h" +#include "app_util.h" +#include +#include + +#ifndef NRF_LOG_DEFAULT_LEVEL +#define NRF_LOG_DEFAULT_LEVEL 0 +#endif + +#ifndef NRF_LOG_USES_COLORS +#define NRF_LOG_USES_COLORS 0 +#endif + +#define NRF_LOG_LEVEL_ERROR 1U +#define NRF_LOG_LEVEL_WARNING 2U +#define NRF_LOG_LEVEL_INFO 3U +#define NRF_LOG_LEVEL_DEBUG 4U +#define NRF_LOG_LEVEL_INTERNAL 5U +#define NRF_LOG_LEVEL_MASK 0x07 +#define NRF_LOG_RAW_POS 4U +#define NRF_LOG_RAW (1U << NRF_LOG_RAW_POS) +#define NRF_LOG_LEVEL_INFO_RAW (NRF_LOG_RAW | NRF_LOG_LEVEL_INFO) + + +#define NRF_LOG_COLOR_CODE_DEFAULT "\x1B[0m" +#define NRF_LOG_COLOR_CODE_BLACK "\x1B[1;30m" +#define NRF_LOG_COLOR_CODE_RED "\x1B[1;31m" +#define NRF_LOG_COLOR_CODE_GREEN "\x1B[1;32m" +#define NRF_LOG_COLOR_CODE_YELLOW "\x1B[1;33m" +#define NRF_LOG_COLOR_CODE_BLUE "\x1B[1;34m" +#define NRF_LOG_COLOR_CODE_MAGENTA "\x1B[1;35m" +#define NRF_LOG_COLOR_CODE_CYAN "\x1B[1;36m" +#define NRF_LOG_COLOR_CODE_WHITE "\x1B[1;37m" + +#define NRF_LOG_COLOR_0 NRF_LOG_COLOR_CODE_DEFAULT +#define NRF_LOG_COLOR_1 NRF_LOG_COLOR_CODE_BLACK +#define NRF_LOG_COLOR_2 NRF_LOG_COLOR_CODE_RED +#define NRF_LOG_COLOR_3 NRF_LOG_COLOR_CODE_GREEN +#define NRF_LOG_COLOR_4 NRF_LOG_COLOR_CODE_YELLOW +#define NRF_LOG_COLOR_5 NRF_LOG_COLOR_CODE_BLUE +#define NRF_LOG_COLOR_6 NRF_LOG_COLOR_CODE_MAGENTA +#define NRF_LOG_COLOR_7 NRF_LOG_COLOR_CODE_CYAN +#define NRF_LOG_COLOR_8 NRF_LOG_COLOR_CODE_WHITE + +#define NRF_LOG_COLOR_DECODE(N) CONCAT_2(NRF_LOG_COLOR_, N) +#if NRF_LOG_USES_COLORS +#define NRF_LOG_ERROR_COLOR_CODE NRF_LOG_COLOR_DECODE(NRF_LOG_ERROR_COLOR) +#define NRF_LOG_WARNING_COLOR_CODE NRF_LOG_COLOR_DECODE(NRF_LOG_WARNING_COLOR) +#define NRF_LOG_INFO_COLOR_CODE NRF_LOG_COLOR_DECODE(NRF_LOG_INFO_COLOR) +#define NRF_LOG_DEBUG_COLOR_CODE NRF_LOG_COLOR_DECODE(NRF_LOG_DEBUG_COLOR) +#else // NRF_LOG_USES_COLORS +#define NRF_LOG_ERROR_COLOR_CODE +#define NRF_LOG_WARNING_COLOR_CODE +#define NRF_LOG_INFO_COLOR_CODE +#define NRF_LOG_DEBUG_COLOR_CODE +#endif // NRF_LOG_USES_COLORS + +#define LOG_INTERNAL_0(type, prefix, str) \ + nrf_log_frontend_std_0(type, prefix str) +#define LOG_INTERNAL_1(type, prefix, str, arg0) \ + nrf_log_frontend_std_1(type, prefix str, arg0) +#define LOG_INTERNAL_2(type, prefix, str, arg0, arg1) \ + nrf_log_frontend_std_2(type, prefix str, arg0, arg1) +#define LOG_INTERNAL_3(type, prefix, str, arg0, arg1, arg2) \ + nrf_log_frontend_std_3(type, prefix str, arg0, arg1, arg2) +#define LOG_INTERNAL_4(type, prefix, str, arg0, arg1, arg2, arg3) \ + nrf_log_frontend_std_4(type, prefix str, arg0, arg1, arg2, arg3) +#define LOG_INTERNAL_5(type, prefix, str, arg0, arg1, arg2, arg3, arg4) \ + nrf_log_frontend_std_5(type, prefix str, arg0, arg1, arg2, arg3, arg4) +#define LOG_INTERNAL_6(type, prefix, str, arg0, arg1, arg2, arg3, arg4, arg5) \ + nrf_log_frontend_std_6(type, prefix str, arg0, arg1, arg2, arg3, arg4, arg5) + +#define LOG_INTERNAL_X(N, ...) CONCAT_2(LOG_INTERNAL_, N) (__VA_ARGS__) +#define LOG_INTERNAL(type, prefix, ...) LOG_INTERNAL_X(NUM_VA_ARGS_LESS_1( \ + __VA_ARGS__), type, prefix, __VA_ARGS__) + +#define NRF_LOG_BREAK ":" + +#define LOG_ERROR_PREFIX NRF_LOG_ERROR_COLOR_CODE NRF_LOG_MODULE_NAME NRF_LOG_BREAK "ERROR:" +#define LOG_WARNING_PREFIX NRF_LOG_WARNING_COLOR_CODE NRF_LOG_MODULE_NAME NRF_LOG_BREAK "WARNING:" +#define LOG_INFO_PREFIX NRF_LOG_INFO_COLOR_CODE NRF_LOG_MODULE_NAME NRF_LOG_BREAK "INFO:" +#define LOG_DEBUG_PREFIX NRF_LOG_DEBUG_COLOR_CODE NRF_LOG_MODULE_NAME NRF_LOG_BREAK "DEBUG:" + +#define NRF_LOG_INTERNAL_ERROR(...) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_ERROR) && \ + (NRF_LOG_LEVEL_ERROR <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + LOG_INTERNAL(NRF_LOG_LEVEL_ERROR, LOG_ERROR_PREFIX, __VA_ARGS__); \ + } +#define NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_ERROR) && \ + (NRF_LOG_LEVEL_ERROR <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + nrf_log_frontend_hexdump(NRF_LOG_LEVEL_ERROR, LOG_ERROR_PREFIX "\r\n", (p_data), (len)); \ + } + +#define NRF_LOG_INTERNAL_WARNING(...) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_WARNING) && \ + (NRF_LOG_LEVEL_WARNING <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + LOG_INTERNAL(NRF_LOG_LEVEL_WARNING, LOG_WARNING_PREFIX, __VA_ARGS__); \ + } +#define NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_WARNING) && \ + (NRF_LOG_LEVEL_WARNING <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + nrf_log_frontend_hexdump(NRF_LOG_LEVEL_WARNING, LOG_WARNING_PREFIX "\r\n", (p_data), (len)); \ + } + +#define NRF_LOG_INTERNAL_INFO(...) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \ + (NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + LOG_INTERNAL(NRF_LOG_LEVEL_INFO, LOG_INFO_PREFIX, __VA_ARGS__); \ + } + +#define NRF_LOG_INTERNAL_RAW_INFO(...) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \ + (NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + LOG_INTERNAL(NRF_LOG_LEVEL_INFO | NRF_LOG_RAW, "", __VA_ARGS__); \ + } + +#define NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \ + (NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + nrf_log_frontend_hexdump(NRF_LOG_LEVEL_INFO, LOG_INFO_PREFIX "\r\n", (p_data), (len)); \ + } + +#define NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \ + (NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + nrf_log_frontend_hexdump(NRF_LOG_LEVEL_INFO | NRF_LOG_RAW, "", (p_data), (len)); \ + } + +#define NRF_LOG_INTERNAL_DEBUG(...) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_DEBUG) && \ + (NRF_LOG_LEVEL_DEBUG <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + LOG_INTERNAL(NRF_LOG_LEVEL_DEBUG, LOG_DEBUG_PREFIX, __VA_ARGS__); \ + } +#define NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_DEBUG) && \ + (NRF_LOG_LEVEL_DEBUG <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + nrf_log_frontend_hexdump(NRF_LOG_LEVEL_DEBUG, LOG_DEBUG_PREFIX "\r\n", (p_data), (len)); \ + } + +#if NRF_MODULE_ENABLED(NRF_LOG) +#define NRF_LOG_INTERNAL_GETCHAR() nrf_log_getchar() +#else +#define NRF_LOG_INTERNAL_GETCHAR() (void) +#endif + +/** + * @brief A function for logging raw string. + * + * @param severity Severity. + * @param p_str A pointer to a string. + */ +void nrf_log_frontend_std_0(uint8_t severity, char const * const p_str); + +/** + * @brief A function for logging a formatted string with one argument. + * + * @param severity Severity. + * @param p_str A pointer to a formatted string. + * @param val0 An argument. + */ +void nrf_log_frontend_std_1(uint8_t severity, + char const * const p_str, + uint32_t val0); + +/** + * @brief A function for logging a formatted string with 2 arguments. + * + * @param severity Severity. + * @param p_str A pointer to a formatted string. + * @param val0, val1 Arguments for formatting string. + */ +void nrf_log_frontend_std_2(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1); + +/** + * @brief A function for logging a formatted string with 3 arguments. + * + * @param severity Severity. + * @param p_str A pointer to a formatted string. + * @param val0, val1, val2 Arguments for formatting string. + */ +void nrf_log_frontend_std_3(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2); + +/** + * @brief A function for logging a formatted string with 4 arguments. + * + * @param severity Severity. + * @param p_str A pointer to a formatted string. + * @param val0, val1, val2, val3 Arguments for formatting string. + */ +void nrf_log_frontend_std_4(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2, + uint32_t val3); + +/** + * @brief A function for logging a formatted string with 5 arguments. + * + * @param severity Severity. + * @param p_str A pointer to a formatted string. + * @param val0, val1, val2, val3, val4 Arguments for formatting string. + */ +void nrf_log_frontend_std_5(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2, + uint32_t val3, + uint32_t val4); + +/** + * @brief A function for logging a formatted string with 6 arguments. + * + * @param severity Severity. + * @param p_str A pointer to a formatted string. + * @param val0, val1, val2, val3, val4, val5 Arguments for formatting string. + */ +void nrf_log_frontend_std_6(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2, + uint32_t val3, + uint32_t val4, + uint32_t val5); + +/** + * @brief A function for logging raw data. + * + * @param severity Severity. + * @param p_str A pointer to a string which is prefixing the data. + * @param p_data A pointer to data to be dumped. + * @param length Length of data (in bytes). + * + */ +void nrf_log_frontend_hexdump(uint8_t severity, + char const * const p_str, + const void * const p_data, + uint16_t length); + +/** + * @brief A function for reading a byte from log backend. + * + * @return Byte. + */ +uint8_t nrf_log_getchar(void); +#endif // NRF_LOG_INTERNAL_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/low_power_pwm/low_power_pwm.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/low_power_pwm/low_power_pwm.c new file mode 100644 index 0000000000000000000000000000000000000000..220f1ec9ea53bbaaa1f2e34ba77bb38a83ca3f83 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/low_power_pwm/low_power_pwm.c @@ -0,0 +1,258 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(LOW_POWER_PWM) +#include +#include "low_power_pwm.h" +#include "nrf_gpio.h" +#include "app_timer.h" +#include "nrf_assert.h" + +/** + * @brief Function for turning on pins. + * + * Sets the pin high state according to active_high parameter. + * + * @param[in] p_pwm_instance Pointer to instance of low-power PWM. + */ +__STATIC_INLINE void pin_on(low_power_pwm_t * p_pwm_instance) +{ + if (p_pwm_instance->active_high) + { + nrf_gpio_port_out_set(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle); + } + else + { + nrf_gpio_port_out_clear(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle); + } + p_pwm_instance->pin_is_on = true; +} + + +/** + * @brief Function for turning off pins. + * + * Sets the pin low state according to active_high parameter. + * + * @param[in] p_pwm_instance Pointer to instance of low-power PWM. + */ +__STATIC_INLINE void pin_off(low_power_pwm_t * p_pwm_instance) +{ + if (p_pwm_instance->active_high) + { + nrf_gpio_port_out_clear(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle); + } + else + { + nrf_gpio_port_out_set(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle); + } + p_pwm_instance->pin_is_on = false; +} + + +/** + * @brief Timer event handler for PWM. + * + * @param[in] p_context General purpose pointer. Will be passed to the time-out handler + * when the timer expires. + * + */ +static void pwm_timeout_handler(void * p_context) +{ + ret_code_t err_code; + uint8_t duty_cycle; + + low_power_pwm_t * p_pwm_instance = (low_power_pwm_t *)p_context; + + if (p_pwm_instance->evt_type == LOW_POWER_PWM_EVENT_PERIOD) + { + if (p_pwm_instance->handler) + { + p_pwm_instance->handler(p_pwm_instance); + + if (p_pwm_instance->pwm_state != NRF_DRV_STATE_POWERED_ON) + { + return; + } + } + + duty_cycle = p_pwm_instance->duty_cycle; + + if (duty_cycle == p_pwm_instance->period) // Process duty cycle 100% + { + pin_on(p_pwm_instance); + p_pwm_instance->timeout_ticks = p_pwm_instance->period + APP_TIMER_MIN_TIMEOUT_TICKS; + } + else if (duty_cycle == 0) // Process duty cycle 0% + { + pin_off(p_pwm_instance); + p_pwm_instance->timeout_ticks = p_pwm_instance->period + APP_TIMER_MIN_TIMEOUT_TICKS; + } + else // Process any other duty cycle than 0 or 100% + { + pin_on(p_pwm_instance); + p_pwm_instance->timeout_ticks = ((duty_cycle * p_pwm_instance->period)>>8) + + APP_TIMER_MIN_TIMEOUT_TICKS; + // setting next state + p_pwm_instance->evt_type = LOW_POWER_PWM_EVENT_DUTY_CYCLE; + } + } + else + { + pin_off(p_pwm_instance); + p_pwm_instance->evt_type = LOW_POWER_PWM_EVENT_PERIOD; + p_pwm_instance->timeout_ticks = (((p_pwm_instance->period - p_pwm_instance->duty_cycle) * + p_pwm_instance->period)>>8) + APP_TIMER_MIN_TIMEOUT_TICKS; + } + + if (p_pwm_instance->pwm_state == NRF_DRV_STATE_POWERED_ON) + { + err_code = app_timer_start(*p_pwm_instance->p_timer_id, p_pwm_instance->timeout_ticks, p_pwm_instance); + APP_ERROR_CHECK(err_code); + } +} + + +ret_code_t low_power_pwm_init(low_power_pwm_t * p_pwm_instance, + low_power_pwm_config_t const * p_pwm_config, + app_timer_timeout_handler_t handler) +{ + ASSERT(p_pwm_instance->pwm_state == NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_pwm_config->bit_mask != 0); + ASSERT(p_pwm_config->p_port != NULL); + ASSERT(p_pwm_config->period != 0); + + ret_code_t err_code; + uint32_t bit_mask; + uint32_t pin_number = 0; + + p_pwm_instance->handler = handler; + + bit_mask = p_pwm_config->bit_mask; + + p_pwm_instance->active_high = p_pwm_config->active_high; + p_pwm_instance->bit_mask = p_pwm_config->bit_mask; + p_pwm_instance->bit_mask_toggle = p_pwm_config->bit_mask; + p_pwm_instance->p_port = p_pwm_config->p_port; + p_pwm_instance->period = p_pwm_config->period; + p_pwm_instance->p_timer_id = p_pwm_config->p_timer_id; + + err_code = app_timer_create(p_pwm_instance->p_timer_id, APP_TIMER_MODE_SINGLE_SHOT, pwm_timeout_handler); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + while (bit_mask) + { + if (bit_mask & 0x1UL) + { + nrf_gpio_cfg_output(pin_number); + } + + pin_number++; + bit_mask >>= 1UL; + } + + pin_off(p_pwm_instance); + p_pwm_instance->pwm_state = NRF_DRV_STATE_INITIALIZED; + + return NRF_SUCCESS; +} + + +ret_code_t low_power_pwm_start(low_power_pwm_t * p_pwm_instance, + uint32_t pin_bit_mask) +{ + ASSERT(p_pwm_instance->pwm_state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(((p_pwm_instance->bit_mask) & pin_bit_mask) != 0x00); + + p_pwm_instance->pwm_state = NRF_DRV_STATE_POWERED_ON; + p_pwm_instance->bit_mask_toggle = pin_bit_mask; + + pin_off(p_pwm_instance); + + p_pwm_instance->bit_mask |= pin_bit_mask; + p_pwm_instance->evt_type = LOW_POWER_PWM_EVENT_PERIOD; + + app_timer_timeout_handler_t handler = p_pwm_instance->handler; + p_pwm_instance->handler = NULL; + pwm_timeout_handler(p_pwm_instance); + p_pwm_instance->handler = handler; + + return NRF_SUCCESS; +} + + +ret_code_t low_power_pwm_stop(low_power_pwm_t * p_pwm_instance) +{ + ASSERT(p_pwm_instance->pwm_state == NRF_DRV_STATE_POWERED_ON); + + ret_code_t err_code; + + err_code = app_timer_stop(*p_pwm_instance->p_timer_id); + + pin_off(p_pwm_instance); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + p_pwm_instance->pwm_state = NRF_DRV_STATE_INITIALIZED; + + + return NRF_SUCCESS; +} + + +ret_code_t low_power_pwm_duty_set(low_power_pwm_t * p_pwm_instance, uint8_t duty_cycle) +{ + if ( p_pwm_instance->period < duty_cycle) + { + return NRF_ERROR_INVALID_PARAM; + } + + p_pwm_instance->duty_cycle = duty_cycle; + + return NRF_SUCCESS; +} +#endif //NRF_MODULE_ENABLED(LOW_POWER_PWM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/low_power_pwm/low_power_pwm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/low_power_pwm/low_power_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..22ee0e66be2fe98353ad1e000c8a861b63a6cab0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/low_power_pwm/low_power_pwm.h @@ -0,0 +1,211 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup low_power_pwm Low-power PWM + * @{ + * @ingroup app_common + * + * @brief Module for generating a low-power pulse-width modulated output signal. + * + * This module provides a low-power PWM implementation using app_timers and GPIO. + * + * Each low-power PWM instance utilizes one app_timer. This means it runs on RTC + * and does not require HFCLK to be running. There can be any number of output + * channels per instance. + */ + +#ifndef LOW_POWER_PWM_H__ +#define LOW_POWER_PWM_H__ + +#include +#include +#include "app_timer.h" +#include "nrf_drv_common.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Event types. + */ +typedef enum +{ + LOW_POWER_PWM_EVENT_PERIOD = 0, + LOW_POWER_PWM_EVENT_DUTY_CYCLE +}low_power_pwm_evt_type_t; + +/**@brief Application time-out handler type. */ +typedef void (*low_power_pwm_timeout_user)(void * p_context, low_power_pwm_evt_type_t evt_type); + +/** + * @brief Structure holding the initialization parameters. + */ +typedef struct +{ + bool active_high; /**< Activate negative polarity. */ + uint8_t period; /**< Width of the low_power_pwm period. */ + NRF_GPIO_Type * p_port; /**< Port used to work on selected mask. */ + uint32_t bit_mask; /**< Pins to be initialized. */ + app_timer_id_t const * p_timer_id; /**< Pointer to the timer ID of low_power_pwm. */ +} low_power_pwm_config_t; + + +/** + * @name Default settings + * @{ + * + * @brief Default parameters for the @ref low_power_pwm_config_t structure. + * + */ +#define LOW_POWER_PWM_CONFIG_ACTIVE_HIGH false +#define LOW_POWER_PWM_CONFIG_PERIOD UINT8_MAX +#define LOW_POWER_PWM_CONFIG_PORT NRF_GPIO +#define LOW_POWER_PWM_CONFIG_BIT_MASK(mask) (mask) +/** @} */ + +/** + * @brief Low-power PWM default configuration. + */ +#define LOW_POWER_PWM_DEFAULT_CONFIG(mask) \ +{ \ + .active_high = LOW_POWER_PWM_CONFIG_ACTIVE_HIGH , \ + .period = LOW_POWER_PWM_CONFIG_PERIOD , \ + .p_port = LOW_POWER_PWM_CONFIG_PORT, \ + .bit_mask = LOW_POWER_PWM_CONFIG_BIT_MASK(mask) \ +} +/** + * @cond (NODOX) + * @defgroup low_power_pwm_internal Auxiliary internal types declarations + * @brief Module for internal usage inside the library only. + * @details These definitions are available to the user, but they should not + * be accessed directly. Use @ref low_power_pwm_duty_set instead. + * @{ + * + */ + + /** + * @brief Structure holding parameters of a given low-power PWM instance. + */ + struct low_power_pwm_s + { + bool active_high; /**< Activate negative polarity. */ + bool pin_is_on; /**< Indicates the current state of the pin. */ + uint8_t period; /**< Width of the low_power_pwm period. */ + uint8_t duty_cycle; /**< Width of high pulse. */ + nrf_drv_state_t pwm_state; /**< Indicates the current state of the PWM instance. */ + uint32_t bit_mask; /**< Pins to be initialized. */ + uint32_t bit_mask_toggle; /**< Pins to be toggled. */ + uint32_t timeout_ticks; /**< Value to start the next app_timer. */ + low_power_pwm_evt_type_t evt_type; /**< Slope that triggered time-out. */ + app_timer_timeout_handler_t handler; /**< User handler to be called in the time-out handler. */ + app_timer_id_t const * p_timer_id; /**< Pointer to the timer ID of low_power_pwm. */ + NRF_GPIO_Type * p_port; /**< Port used with pin bit mask. */ + }; + +/** @} + * @endcond + */ + +/** + * @brief Internal structure holding parameters of a low-power PWM instance. + */ +typedef struct low_power_pwm_s low_power_pwm_t; + + +/** + * @brief Function for initializing a low-power PWM instance. + * + * @param[in] p_pwm_instance Pointer to the instance to be started. + * @param[in] p_pwm_config Pointer to the configuration structure. + * @param[in] handler User function to be called in case of time-out. + * + * @return Values returned by @ref app_timer_create. + */ +ret_code_t low_power_pwm_init(low_power_pwm_t * p_pwm_instance, + low_power_pwm_config_t const * p_pwm_config, + app_timer_timeout_handler_t handler); + + +/** + * @brief Function for starting a low-power PWM instance. + * + * @param[in] p_pwm_instance Pointer to the instance to be started. + * @param[in] pins_bit_mask Bit mask of pins to be started. + * + * @return Values returned by @ref app_timer_start. + */ +ret_code_t low_power_pwm_start(low_power_pwm_t * p_pwm_instance, + uint32_t pins_bit_mask); + + +/** + * @brief Function for stopping a low-power PWM instance. + * + * @param[in] p_pwm_instance Pointer to the instance to be stopped. + * + * @return Values returned by @ref app_timer_stop. + */ +ret_code_t low_power_pwm_stop(low_power_pwm_t * p_pwm_instance); + + +/** + * @brief Function for setting a new high pulse width for a given instance. + * + * This function can be called from the timer handler. + * + * @param[in] p_pwm_instance Pointer to the instance to be changed. + * @param[in] duty_cycle New high pulse width. 0 means that the pin is always off. 255 means that it is always on. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_PARAM If the function returned an error because of invalid parameters. + */ +ret_code_t low_power_pwm_duty_set(low_power_pwm_t * p_pwm_instance, uint8_t duty_cycle); + + +#ifdef __cplusplus +} +#endif + +#endif // LOW_POWER_PWM_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/mem_manager/mem_manager.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/mem_manager/mem_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..0cf086c64ce09f69ed5ec6efe6fe65f9c0368e98 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/mem_manager/mem_manager.c @@ -0,0 +1,921 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(MEM_MANAGER) +#include "mem_manager.h" +#include "nrf_assert.h" +#define NRF_LOG_MODULE_NAME "MEM_MNGR" +#include "nrf_log.h" + +/** + * @defgroup memory_manager_mutex_lock_unlock Module's Mutex Lock/Unlock Macros. + * + * @details Macros used to lock and unlock modules. Currently the SDK does not use mutexes but + * framework is provided in case need arises to use an alternative architecture. + * @{ + */ +#define MM_MUTEX_LOCK() SDK_MUTEX_LOCK(m_mm_mutex) /**< Lock module using mutex. */ +#define MM_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_mm_mutex) /**< Unlock module using mutex. */ +/** @} */ + +#undef NULL_PARAM_CHECK +#undef NULL_PARAM_CHECK_VOID +#undef VERIFY_MODULE_INITIALIZED +#undef VERIFY_MODULE_INITIALIZED_VOID +#undef VERIFY_REQUESTED_SIZE +#undef VERIFY_REQUESTED_SIZE_VOID + +#if (MEM_MANAGER_DISABLE_API_PARAM_CHECK == 0) + +/** + * @brief Macro for verifying NULL parameters. + * Returning with an appropriate error code on failure. + * + * @param[in] PARAM Parameter checked for NULL. + * + * @retval (NRF_ERROR_NULL | NRF_ERROR_MEMORY_MANAGER_ERR_BASE) when @ref PARAM is NULL. + */ +#define NULL_PARAM_CHECK(PARAM) \ + if ((PARAM) == NULL) \ + { \ + return (NRF_ERROR_NULL | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); \ + } + +/** + * @brief Macro for verifying NULL parameters are not passed to API and returning on failure. + * + * @param[in] PARAM Parameter checked for NULL. + */ +#define NULL_PARAM_CHECK_VOID(PARAM) \ + if ((PARAM) == NULL) \ + { \ + return; \ + } + + +/** + * @brief Macro for verifying module's initialization status. + * Returning with an appropriate error code on failure. + * + * @retval (NRF_ERROR_INVALID_STATE | NRF_ERROR_MEMORY_MANAGER_ERR_BASE) module is uninitialized. + */ +#define VERIFY_MODULE_INITIALIZED() \ + do \ + { \ + if (!m_module_initialized) \ + { \ + return (NRF_ERROR_INVALID_STATE | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); \ + } \ + } while (0) + +/** + * @brief Macro for verifying module's initialization status and returning on failure. + */ +#define VERIFY_MODULE_INITIALIZED_VOID() \ + do \ + { \ + if (!m_module_initialized) \ + { \ + return; \ + } \ + } while (0) + + +/** + * @brief Macro for verifying requested size of memory does not exceed maximum block + * size supported by the module. Returning with appropriate error code on failure. + * + * @param[in] SIZE Requested size to be allocated. + * + * @retval (NRF_ERROR_INVALID_PARAM | NRF_ERROR_MEMORY_MANAGER_ERR_BASE) if requested size is greater + * than the largest block size managed by the module. + */ +#define VERIFY_REQUESTED_SIZE(SIZE) \ + do \ + { \ + if (((SIZE) == 0) ||((SIZE) > MAX_MEM_SIZE)) \ + { \ + return (NRF_ERROR_INVALID_PARAM | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); \ + } \ + } while (0) + + +/** + * @brief Macro for verifying requested size of memory does not exceed maximum block + * size supported by the module. Returnson failure. + * + * @param[in] SIZE Requested size to be allocated. + */ +#define VERIFY_REQUESTED_SIZE_VOID(SIZE) \ + do \ + { \ + if (((SIZE) == 0) ||((SIZE) > MAX_MEM_SIZE)) \ + { \ + return; \ + } \ + } while (0) + + +/**@} */ +#else //MEM_MANAGER_DISABLE_API_PARAM_CHECK + +#define NULL_PARAM_CHECK(PARAM) +#define VERIFY_MODULE_INITIALIZED() +#define VERIFY_REQUESTED_SIZE(SIZE) + +#endif //MEM_MANAGER_DISABLE_API_PARAM_CHECK + + +/**@brief Setting defualts in case XXSmall block not used by application. */ +#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_COUNT + #define MEMORY_MANAGER_XXSMALL_BLOCK_COUNT 0 + #define MEMORY_MANAGER_XXSMALL_BLOCK_SIZE 0 + #define XXSMALL_BLOCK_START 0 + #define XXSMALL_BLOCK_END 0 + #define XXSMALL_MEMORY_START 0 +#endif // MEMORY_MANAGER_XXSMALL_BLOCK_SIZE + + +/**@brief Setting defualts in case XSmall block not used by application. */ +#ifndef MEMORY_MANAGER_XSMALL_BLOCK_COUNT + #define MEMORY_MANAGER_XSMALL_BLOCK_COUNT 0 + #define MEMORY_MANAGER_XSMALL_BLOCK_SIZE 0 + #define XSMALL_BLOCK_START 0 + #define XSMALL_BLOCK_END 0 + #define XSMALL_MEMORY_START 0 +#endif // MEMORY_MANAGER_XSMALL_BLOCK_SIZE + + +/**@brief Setting defualts in case Small block not used by application. */ +#ifndef MEMORY_MANAGER_SMALL_BLOCK_COUNT + #define MEMORY_MANAGER_SMALL_BLOCK_COUNT 0 + #define MEMORY_MANAGER_SMALL_BLOCK_SIZE 0 + #define SMALL_BLOCK_START 0 + #define SMALL_BLOCK_END 0 + #define SMALL_MEMORY_START 0 +#endif // MEMORY_MANAGER_SMALL_BLOCK_COUNT + + +/**@brief Setting defualts in case Medium block not used by application. */ +#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_COUNT + #define MEMORY_MANAGER_MEDIUM_BLOCK_COUNT 0 + #define MEMORY_MANAGER_MEDIUM_BLOCK_SIZE 0 + #define MEDIUM_BLOCK_START 0 + #define MEDIUM_BLOCK_END 0 + #define MEDIUM_MEMORY_START 0 +#endif // MEMORY_MANAGER_MEDIUM_BLOCK_COUNT + + +/**@brief Setting defualts in case Large block not used by application. */ +#ifndef MEMORY_MANAGER_LARGE_BLOCK_COUNT + #define MEMORY_MANAGER_LARGE_BLOCK_COUNT 0 + #define MEMORY_MANAGER_LARGE_BLOCK_SIZE 0 + #define LARGE_BLOCK_START 0 + #define LARGE_BLOCK_END 0 + #define LARGE_MEMORY_START 0 +#endif // MEMORY_MANAGER_LARGE_BLOCK_COUNT + + +/**@brief Setting defualts in case XLarge block not used by application. */ +#ifndef MEMORY_MANAGER_XLARGE_BLOCK_COUNT + #define MEMORY_MANAGER_XLARGE_BLOCK_COUNT 0 + #define MEMORY_MANAGER_XLARGE_BLOCK_SIZE 0 + #define XLARGE_BLOCK_START 0 + #define XLARGE_BLOCK_END 0 + #define XLARGE_MEMORY_START 0 +#endif // MEMORY_MANAGER_XLARGE_BLOCK_COUNT + + +/**@brief Setting defualts in case XXLarge block not used by application. */ +#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_COUNT + #define MEMORY_MANAGER_XXLARGE_BLOCK_COUNT 0 + #define MEMORY_MANAGER_XXLARGE_BLOCK_SIZE 0 + #define XXLARGE_BLOCK_START 0 + #define XXLARGE_BLOCK_END 0 + #define XXLARGE_MEMORY_START 0 +#endif // MEMORY_MANAGER_XXLARGE_BLOCK_COUNT + + +/**@brief Based on which blocks are defined, MAX_MEM_SIZE is determined. + * + * @note Also, in case none of these are defined, a compile time error is indicated. + */ +#if (MEMORY_MANAGER_XXLARGE_BLOCK_COUNT != 0) + #define MAX_MEM_SIZE MEMORY_MANAGER_XXLARGE_BLOCK_SIZE +#elif (MEMORY_MANAGER_XLARGE_BLOCK_COUNT != 0) + #define MAX_MEM_SIZE MEMORY_MANAGER_XLARGE_BLOCK_SIZE +#elif (MEMORY_MANAGER_LARGE_BLOCK_COUNT != 0) + #define MAX_MEM_SIZE MEMORY_MANAGER_LARGE_BLOCK_SIZE +#elif (MEMORY_MANAGER_MEDIUM_BLOCK_COUNT != 0) + #define MAX_MEM_SIZE MEMORY_MANAGER_MEDIUM_BLOCK_SIZE +#elif (MEMORY_MANAGER_SMALL_BLOCK_COUNT != 0) + #define MAX_MEM_SIZE MEMORY_MANAGER_SMALL_BLOCK_SIZE +#elif (MEMORY_MANAGER_XSMALL_BLOCK_COUNT != 0) + #define MAX_MEM_SIZE MEMORY_MANAGER_XSMALL_BLOCK_SIZE +#elif (MEMORY_MANAGER_XXSMALL_BLOCK_COUNT != 0) + #define MAX_MEM_SIZE MEMORY_MANAGER_XXSMALL_BLOCK_SIZE +#else + #err "One of MEMORY_MANAGER_SMALL_BLOCK_COUNT, MEMORY_MANAGER_MEDIUM_BLOCK_COUNT or \ + or MEMORY_MANAGER_LARGE_BLOCK_COUNT should be defined." +#endif + +/**@brief XXSmall block start index in case XXSmall Block is defined. */ +#ifndef XXSMALL_BLOCK_START +#define XXSMALL_BLOCK_START 0 +#endif // XXSMALL_BLOCK_START + + +/**@brief XSmall block start index in case XSmall Block is defined. */ +#ifndef XSMALL_BLOCK_START +#define XSMALL_BLOCK_START (XXSMALL_BLOCK_START + MEMORY_MANAGER_XXSMALL_BLOCK_COUNT) +#endif // XSMALL_BLOCK_START + + +/**@brief Small block start index in case Small Block is defined. */ +#ifndef SMALL_BLOCK_START +#define SMALL_BLOCK_START (XSMALL_BLOCK_START + MEMORY_MANAGER_XSMALL_BLOCK_COUNT) +#endif // SMALL_BLOCK_START + + +/**@brief Medium block start index in case Medium Block is defined. */ +#ifndef MEDIUM_BLOCK_START +#define MEDIUM_BLOCK_START (SMALL_BLOCK_START + MEMORY_MANAGER_SMALL_BLOCK_COUNT) +#endif // MEDIUM_BLOCK_START + + +/**@brief Large block start index in case Large Block is defined. */ +#ifndef LARGE_BLOCK_START +#define LARGE_BLOCK_START (MEDIUM_BLOCK_START + MEMORY_MANAGER_MEDIUM_BLOCK_COUNT) +#endif // LARGE_BLOCK_START + + +/**@brief XLarge block start index in case XLarge Block is defined. */ +#ifndef XLARGE_BLOCK_START +#define XLARGE_BLOCK_START (LARGE_BLOCK_START + MEMORY_MANAGER_LARGE_BLOCK_COUNT) +#endif // XLARGE_BLOCK_START + +/**@brief XXLarge block start index in case XXLarge Block is defined. */ +#ifndef XXLARGE_BLOCK_START +#define XXLARGE_BLOCK_START (XLARGE_BLOCK_START + MEMORY_MANAGER_XLARGE_BLOCK_COUNT) +#endif //XXLARGE_BLOCK_START + + +/**@brief XXSmall block end index in case XXSmall Block is defined. */ +#ifndef XXSMALL_BLOCK_END +#define XXSMALL_BLOCK_END (XXSMALL_BLOCK_START + MEMORY_MANAGER_XXSMALL_BLOCK_COUNT) +#endif // XXSMALL_BLOCK_END + +/**@brief XSmall block end index in case XSmall Block is defined. */ +#ifndef XSMALL_BLOCK_END +#define XSMALL_BLOCK_END (XSMALL_BLOCK_START + MEMORY_MANAGER_XSMALL_BLOCK_COUNT) +#endif // XSMALL_BLOCK_END + + +/**@brief Small block end index in case Small Block is defined. */ +#ifndef SMALL_BLOCK_END +#define SMALL_BLOCK_END (SMALL_BLOCK_START + MEMORY_MANAGER_SMALL_BLOCK_COUNT) +#endif // SMALL_BLOCK_END + + +/**@brief Medium block end index in case Medium Block is defined. */ +#ifndef MEDIUM_BLOCK_END +#define MEDIUM_BLOCK_END (MEDIUM_BLOCK_START + MEMORY_MANAGER_MEDIUM_BLOCK_COUNT) +#endif // MEDIUM_BLOCK_END + + +/**@brief Large block end index in case Large Block is defined. */ +#ifndef LARGE_BLOCK_END +#define LARGE_BLOCK_END (LARGE_BLOCK_START + MEMORY_MANAGER_LARGE_BLOCK_COUNT) +#endif // LARGE_BLOCK_END + + +/**@brief XLarge block end index in case XLarge Block is defined. */ +#ifndef XLARGE_BLOCK_END +#define XLARGE_BLOCK_END (XLARGE_BLOCK_START + MEMORY_MANAGER_XLARGE_BLOCK_COUNT) +#endif // XLARGE_BLOCK_END + + +/**@brief XXLarge block end index in case XXLarge Block is defined. */ +#ifndef XXLARGE_BLOCK_END +#define XXLARGE_BLOCK_END (XXLARGE_BLOCK_START + MEMORY_MANAGER_XXLARGE_BLOCK_COUNT) +#endif //XXLARGE_BLOCK_END + + +#define XXSMALL_MEMORY_SIZE (MEMORY_MANAGER_XXSMALL_BLOCK_COUNT * MEMORY_MANAGER_XXSMALL_BLOCK_SIZE) +#define XSMALL_MEMORY_SIZE (MEMORY_MANAGER_XSMALL_BLOCK_COUNT * MEMORY_MANAGER_XSMALL_BLOCK_SIZE) +#define SMALL_MEMORY_SIZE (MEMORY_MANAGER_SMALL_BLOCK_COUNT * MEMORY_MANAGER_SMALL_BLOCK_SIZE) +#define MEDIUM_MEMORY_SIZE (MEMORY_MANAGER_MEDIUM_BLOCK_COUNT * MEMORY_MANAGER_MEDIUM_BLOCK_SIZE) +#define LARGE_MEMORY_SIZE (MEMORY_MANAGER_LARGE_BLOCK_COUNT * MEMORY_MANAGER_LARGE_BLOCK_SIZE) +#define XLARGE_MEMORY_SIZE (MEMORY_MANAGER_XLARGE_BLOCK_COUNT * MEMORY_MANAGER_XLARGE_BLOCK_SIZE) +#define XXLARGE_MEMORY_SIZE (MEMORY_MANAGER_XXLARGE_BLOCK_COUNT * MEMORY_MANAGER_XXLARGE_BLOCK_SIZE) + + +/**@brief XXSmall memory start index in case XXSmall Block is defined. */ +#ifndef XXSMALL_MEMORY_START +#define XXSMALL_MEMORY_START 0 +#endif // XXSMALL_MEMORY_START + + +/**@brief XSmall memory start index in case XSmall Block is defined. */ +#ifndef XSMALL_MEMORY_START +#define XSMALL_MEMORY_START (XXSMALL_MEMORY_START + XXSMALL_MEMORY_SIZE) +#endif // XSMALL_MEMORY_START + + +/**@brief Small memory start index in case Small Block is defined. */ +#ifndef SMALL_MEMORY_START +#define SMALL_MEMORY_START (XSMALL_MEMORY_START + XSMALL_MEMORY_SIZE) +#endif // SMALL_MEMORY_START + + +/**@brief Medium memory start index in case Medium Block is defined. */ +#ifndef MEDIUM_MEMORY_START +#define MEDIUM_MEMORY_START (SMALL_MEMORY_START + SMALL_MEMORY_SIZE) +#endif // MEDIUM_MEMORY_START + + +/**@brief Large memory start index in case Large Block is defined. */ +#ifndef LARGE_MEMORY_START +#define LARGE_MEMORY_START (MEDIUM_MEMORY_START + MEDIUM_MEMORY_SIZE) +#endif // LARGE_MEMORY_START + + +/**@brief XLarge memory start index in case XLarge Block is defined. */ +#ifndef XLARGE_MEMORY_START +#define XLARGE_MEMORY_START (LARGE_MEMORY_START + LARGE_MEMORY_SIZE) +#endif // XLARGE_MEMORY_START + + +/**@brief XXLarge memory start index in case XXLarge Block is defined. */ +#ifndef XXLARGE_MEMORY_START +#define XXLARGE_MEMORY_START (XLARGE_MEMORY_START + XLARGE_MEMORY_SIZE) +#endif // XLARGE_MEMORY_START + + +/**@brief Total count of block managed by the module. */ +#define TOTAL_BLOCK_COUNT (MEMORY_MANAGER_XXSMALL_BLOCK_COUNT + \ + MEMORY_MANAGER_XSMALL_BLOCK_COUNT + \ + MEMORY_MANAGER_SMALL_BLOCK_COUNT + \ + MEMORY_MANAGER_MEDIUM_BLOCK_COUNT + \ + MEMORY_MANAGER_LARGE_BLOCK_COUNT + \ + MEMORY_MANAGER_XLARGE_BLOCK_COUNT + \ + MEMORY_MANAGER_XLARGE_BLOCK_COUNT) + + +/**@brief Total memory managed by the module. */ +#define TOTAL_MEMORY_SIZE (XXSMALL_MEMORY_SIZE + \ + XSMALL_MEMORY_SIZE + \ + SMALL_MEMORY_SIZE + \ + MEDIUM_MEMORY_SIZE + \ + LARGE_MEMORY_SIZE + \ + XLARGE_MEMORY_SIZE + \ + XXLARGE_MEMORY_SIZE) + + +#define BLOCK_CAT_COUNT 7 /**< Block category count is 7 (xxsmall, xsmall, small, medium, large, xlarge, xxlarge). Having one of the block count to zero has no impact on this count. */ +#define BLOCK_CAT_XXS 0 /**< Extra Extra Small category identifier. */ +#define BLOCK_CAT_XS 1 /**< Extra Small category identifier. */ +#define BLOCK_CAT_SMALL 2 /**< Small category identifier. */ +#define BLOCK_CAT_MEDIUM 3 /**< Medium category identifier. */ +#define BLOCK_CAT_LARGE 4 /**< Large category identifier. */ +#define BLOCK_CAT_XL 5 /**< Extra Large category identifier. */ +#define BLOCK_CAT_XXL 6 /**< Extra Extra Large category identifier. */ + +#define BITMAP_SIZE 32 /**< Bitmap size for each word used to contain block information. */ +#define BLOCK_BITMAP_ARRAY_SIZE CEIL_DIV(TOTAL_BLOCK_COUNT, BITMAP_SIZE) /**< Determines number of blocks needed for book keeping availability status of all blocks. */ + + +/**@brief Lookup table for maximum memory size per block category. */ +static const uint32_t m_block_size[BLOCK_CAT_COUNT] = +{ + MEMORY_MANAGER_XXSMALL_BLOCK_SIZE, + MEMORY_MANAGER_XSMALL_BLOCK_SIZE, + MEMORY_MANAGER_SMALL_BLOCK_SIZE, + MEMORY_MANAGER_MEDIUM_BLOCK_SIZE, + MEMORY_MANAGER_LARGE_BLOCK_SIZE, + MEMORY_MANAGER_XLARGE_BLOCK_SIZE, + MEMORY_MANAGER_XXLARGE_BLOCK_SIZE +}; + +/**@brief Lookup table for block start index for each block caetgory. */ +static const uint32_t m_block_start[BLOCK_CAT_COUNT] = +{ + XXSMALL_BLOCK_START, + XSMALL_BLOCK_START, + SMALL_BLOCK_START, + MEDIUM_BLOCK_START, + LARGE_BLOCK_START, + XLARGE_BLOCK_START, + XXLARGE_BLOCK_START +}; + +/**@brief Lookup table for last block index for each block category. */ +static const uint32_t m_block_end[BLOCK_CAT_COUNT] = +{ + XXSMALL_BLOCK_END, + XSMALL_BLOCK_END, + SMALL_BLOCK_END, + MEDIUM_BLOCK_END, + LARGE_BLOCK_END, + XLARGE_BLOCK_END, + XXLARGE_BLOCK_END +}; + +/**@brief Lookup table for memory start range for each block category. */ +static const uint32_t m_block_mem_start[BLOCK_CAT_COUNT] = +{ + XXSMALL_MEMORY_START, + XSMALL_MEMORY_START, + SMALL_MEMORY_START, + MEDIUM_MEMORY_START, + LARGE_MEMORY_START, + XLARGE_MEMORY_START, + XXLARGE_MEMORY_START +}; + +static uint8_t m_memory[TOTAL_MEMORY_SIZE]; /**< Memory managed by the module. */ +static uint32_t m_mem_pool[BLOCK_BITMAP_ARRAY_SIZE]; /**< Bitmap used for book-keeping availability of all blocks managed by the module. */ + +#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS + +/**@brief Lookup table for descriptive strings for each block category. */ +static const char * m_block_desc_str[BLOCK_CAT_COUNT] = +{ + "XXSmall", + "XSmall", + "Small", + "Medium", + "Large", + "XLarge", + "XXLarge" +}; + +/**@brief Table for book keeping smallest size allocated in each block range. */ +static uint32_t m_min_size[BLOCK_CAT_COUNT] = +{ + MEMORY_MANAGER_XXSMALL_BLOCK_SIZE, + MEMORY_MANAGER_XSMALL_BLOCK_SIZE, + MEMORY_MANAGER_SMALL_BLOCK_SIZE, + MEMORY_MANAGER_MEDIUM_BLOCK_SIZE, + MEMORY_MANAGER_LARGE_BLOCK_SIZE, + MEMORY_MANAGER_XLARGE_BLOCK_SIZE, + MEMORY_MANAGER_XXLARGE_BLOCK_SIZE +}; + +/**@brief Table for book keeping largest size allocated in each block range. */ +static uint32_t m_max_size[BLOCK_CAT_COUNT]; + +/**@brief Global pointing to minimum size holder for block type being allocated. */ +static uint32_t * p_min_size; + +/**@brief Global pointing to maximum size holder for block type being allocated. */ +static uint32_t * p_max_size; + +/**@brief Lookup table for count of block available in each block category. */ +static uint32_t m_block_count[BLOCK_CAT_COUNT] = +{ + MEMORY_MANAGER_XXSMALL_BLOCK_COUNT, + MEMORY_MANAGER_XSMALL_BLOCK_COUNT, + MEMORY_MANAGER_SMALL_BLOCK_COUNT, + MEMORY_MANAGER_MEDIUM_BLOCK_COUNT, + MEMORY_MANAGER_LARGE_BLOCK_COUNT, + MEMORY_MANAGER_XLARGE_BLOCK_COUNT, + MEMORY_MANAGER_XXLARGE_BLOCK_COUNT +}; + +#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS + +SDK_MUTEX_DEFINE(m_mm_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */ +#if (MEM_MANAGER_DISABLE_API_PARAM_CHECK == 0) +static bool m_module_initialized = false; /**< State indicating if module is initialized or not. */ +#endif // MEM_MANAGER_DISABLE_API_PARAM_CHECK + + +/**@brief Function to get X and Y coordinates. + * + * @details Function to get X and Y co-ordinates for the block identified by index. + * Here, X determines relevant word for the block. Y determines the actual bit in the word. + * + * @param[in] index Identifies the block. + * @param[out] p_x Points to the word that contains the bit representing the block. + * @param[out] p_y Contains the bitnumber in the the word 'X' relevant to the block. + */ +static __INLINE void get_block_coordinates(uint32_t block_index, uint32_t * p_x, uint32_t * p_y) +{ + // Determine position of the block in the bitmap. + // X determines relevant word for the block. Y determines the actual bit in the word. + const uint32_t x = block_index / BITMAP_SIZE; + const uint32_t y = (block_index - x * BITMAP_SIZE); + + (*p_x) = x; + (*p_y) = y; +} + + +/**@brief Initializes the block by setting it to be free. */ +static void block_init (uint32_t block_index) +{ + uint32_t x; + uint32_t y; + + // Determine position of the block in the bitmap. + // X determines relevant word for the block. Y determines the actual bit in the word. + get_block_coordinates(block_index, &x, &y); + + // Set bit related to the block to indicate that the block is free. + SET_BIT(m_mem_pool[x], y); +} + + +/**@brief Function to get the category of the block of size 'size' or block number 'block_index'.*/ +static __INLINE uint32_t get_block_cat(uint32_t size, uint32_t block_index) +{ + for (uint32_t block_cat = 0; block_cat < BLOCK_CAT_COUNT; block_cat++) + { + if (((size != 0) && (size <= m_block_size[block_cat]) && + (m_block_end[block_cat] != m_block_start[block_cat])) || + (block_index < m_block_end[block_cat])) + { + return block_cat; + } + } + + return 0; +} + + +/**@brief Function to get the size of the block number 'block_index'. */ +static __INLINE uint32_t get_block_size(uint32_t block_index) +{ + const uint32_t block_cat = get_block_cat(0, block_index); + + #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS + p_min_size = &m_min_size[block_cat]; + p_max_size = &m_max_size[block_cat]; + #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS + + return m_block_size[block_cat]; +} + + +/**@brief Function to free the block identified by block number 'block_index'. */ +static bool is_block_free(uint32_t block_index) +{ + uint32_t x; + uint32_t y; + + // Determine position of the block in the bitmap. + // X determines relevant word for the block. Y determines the actual bit in the word. + get_block_coordinates(block_index, &x, &y); + + return IS_SET(m_mem_pool[x], y); +} + + +/**@brief Function to allocate the block identified by block number 'block_index'. */ +static void block_allocate(uint32_t block_index) +{ + uint32_t x; + uint32_t y; + + // Determine position of the block in the bitmap. + // X determines relevant word for the block. Y determines the actual bit in the word. + get_block_coordinates(block_index, &x, &y); + + CLR_BIT(m_mem_pool[x], y); +} + + +uint32_t nrf_mem_init(void) +{ + NRF_LOG_DEBUG("[MM]: >> nrf_mem_init.\r\n"); + + SDK_MUTEX_INIT(m_mm_mutex); + + MM_MUTEX_LOCK(); + + uint32_t block_index = 0; + + for (block_index = 0; block_index < TOTAL_BLOCK_COUNT; block_index++) + { + block_init(block_index); + } + +#if (MEM_MANAGER_DISABLE_API_PARAM_CHECK == 0) + m_module_initialized = true; +#endif // MEM_MANAGER_DISABLE_API_PARAM_CHECK + +#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS + nrf_mem_diagnose(); +#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS + + MM_MUTEX_UNLOCK(); + + NRF_LOG_DEBUG("[MM]: << nrf_mem_init.\r\n"); + + return NRF_SUCCESS; +} + + +uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size) +{ + VERIFY_MODULE_INITIALIZED(); + NULL_PARAM_CHECK(pp_buffer); + NULL_PARAM_CHECK(p_size); + + const uint32_t requested_size = (*p_size); + + VERIFY_REQUESTED_SIZE(requested_size); + + NRF_LOG_DEBUG("[MM]: >> nrf_mem_reserve, size 0x%04lX.\r\n", requested_size); + + MM_MUTEX_LOCK(); + + const uint32_t block_cat = get_block_cat(requested_size, TOTAL_BLOCK_COUNT); + uint32_t block_index = m_block_start[block_cat]; + uint32_t memory_index = m_block_mem_start[block_cat]; + uint32_t err_code = (NRF_ERROR_NO_MEM | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); + + NRF_LOG_DEBUG("[MM]: Start index for the pool = 0x%08lX, total block count 0x%08X\r\n", + block_index, + TOTAL_BLOCK_COUNT); + + for (; block_index < TOTAL_BLOCK_COUNT; block_index++) + { + uint32_t block_size = get_block_size(block_index); + + if (is_block_free(block_index) == true) + { + NRF_LOG_DEBUG("[MM]: Reserving block 0x%08lX\r\n", block_index); + + // Search succeeded, found free block. + err_code = NRF_SUCCESS; + + // Allocate block. + block_allocate(block_index); + + (*pp_buffer) = &m_memory[memory_index]; + (*p_size) = block_size; + + #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS + (*p_min_size) = MIN((*p_min_size), requested_size); + (*p_max_size) = MAX((*p_max_size), requested_size); + #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS + + break; + } + memory_index += block_size; + } + if (err_code != NRF_SUCCESS) + { + NRF_LOG_DEBUG ("[MM]: Memory reservation result %d, memory %p, size %d!", + err_code, + (uint32_t)(*pp_buffer), + (*p_size)); + + #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS + nrf_mem_diagnose(); + #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS + } + + MM_MUTEX_UNLOCK(); + + NRF_LOG_DEBUG("[MM]: << nrf_mem_reserve %p, result 0x%08lX.\r\n", + (uint32_t)(*pp_buffer), err_code); + + return err_code; +} + + +void * nrf_malloc(uint32_t size) +{ + uint8_t * buffer = NULL; + uint32_t allocated_size = size; + + uint32_t retval = nrf_mem_reserve(&buffer, &allocated_size); + + if (retval != NRF_SUCCESS) + { + buffer = NULL; + } + + return buffer; +} + + +void * nrf_calloc(uint32_t count, uint32_t size) +{ + uint8_t * buffer = NULL; + uint32_t allocated_size = (size * count); + + NRF_LOG_DEBUG ("[nrf_calloc]: Requested size %d, count %d\r\n", allocated_size, count); + + uint32_t retval = nrf_mem_reserve(&buffer,&allocated_size); + if (retval == NRF_SUCCESS) + { + NRF_LOG_DEBUG ("[nrf_calloc]: buffer %p, total size %d\r\n", (uint32_t)buffer, allocated_size); + memset(buffer,0, allocated_size); + } + else + { + NRF_LOG_DEBUG("[nrf_calloc]: Failed to allocate memory %d\r\n", allocated_size); + buffer = NULL; + } + + return buffer; +} + + +void nrf_free(void * p_mem) +{ + VERIFY_MODULE_INITIALIZED_VOID(); + NULL_PARAM_CHECK_VOID(p_mem); + + NRF_LOG_DEBUG("[MM]: >> nrf_free %p.\r\n", (uint32_t)p_mem); + + MM_MUTEX_LOCK(); + + uint32_t index; + uint32_t memory_index = 0; + + for (index = 0; index < TOTAL_BLOCK_COUNT; index++) + { + if (&m_memory[memory_index] == p_mem) + { + // Found a free block of memory, assign. + NRF_LOG_DEBUG("[MM]: << Freeing block %d.\r\n", index); + block_init(index); + break; + } + memory_index += get_block_size(index); + } + + MM_MUTEX_UNLOCK(); + + NRF_LOG_DEBUG("[MM]: << nrf_free.\r\n"); + return; +} + + +void * nrf_realloc(void * p_mem, uint32_t size) +{ + return p_mem; +} + + +#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS + +/**@brief Function to format and print information with respect to each block. + * + * @details Internal function that formats and prints information related to the block category + * identified by 'block_cat'. This function also appends the number of bytes in use to + * p_mem_in_use based on current count of block in the category. + * + * @param[in] block_cat Identifies the category of block. + * @param[out] p_mem_in_use Updates the memory in use based on count in use. + */ +void print_block_info(uint32_t block_cat, uint32_t * p_mem_in_use) +{ + #define PRINT_COLUMN_WIDTH 13 + #define PRINT_BUFFER_SIZE 80 + #define ASCII_VALUE_FOR_SPACE 32 + + char print_buffer[PRINT_BUFFER_SIZE]; + const uint32_t total_count = (m_block_start[block_cat] + m_block_count[block_cat]); + uint32_t in_use = 0; + uint32_t num_of_blocks = 0; + uint32_t index = m_block_start[block_cat]; + uint32_t column_number; + + // No statistic provided in case block category is not included. + if (m_block_count[block_cat] != 0) + { + memset(print_buffer, ASCII_VALUE_FOR_SPACE, PRINT_BUFFER_SIZE); + + for (; index < total_count; index++) + { + if (is_block_free(index) == false) + { + num_of_blocks++; + in_use += m_block_size[block_cat]; + } + } + + column_number = 0; + snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH], + PRINT_COLUMN_WIDTH, + "| %s", + m_block_desc_str[block_cat]); + + column_number++; + snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH], + PRINT_COLUMN_WIDTH, + "| %d", + m_block_size[block_cat]); + + column_number++; + snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH], + PRINT_COLUMN_WIDTH, + "| %d", + m_block_count[block_cat]); + + column_number++; + snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH], + PRINT_COLUMN_WIDTH, + "| %d", + num_of_blocks); + + column_number++; + snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH], + PRINT_COLUMN_WIDTH, + "| %d", + m_min_size[block_cat]); + + column_number++; + snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH], + PRINT_COLUMN_WIDTH, + "| %d", + m_max_size[block_cat]); + + column_number++; + const uint32_t column_end = (column_number * PRINT_COLUMN_WIDTH); + + for (int j = 0; j < column_end; j ++) + { + if (print_buffer[j] == 0) + { + print_buffer[j] = 0x20; + } + } + snprintf(&print_buffer[column_end], 2, "|"); + + NRF_LOG_BYTES_DEBUG(print_buffer, strlen(print_buffer)); + + (*p_mem_in_use) += in_use; + } +} + + +void nrf_mem_diagnose(void) +{ + uint32_t in_use = 0; + + NRF_LOG_DEBUG ("\r\n"); + NRF_LOG_DEBUG ("+------------+------------+------------+------------+------------+------------+\r\n"); + NRF_LOG_DEBUG ("| Block | Size | Total | In Use | Min Alloc | Max Alloc |\r\n"); + NRF_LOG_DEBUG ("+------------+------------+------------+------------+------------+------------+\r\n"); + + print_block_info(BLOCK_CAT_XXS, &in_use); + print_block_info(BLOCK_CAT_XS, &in_use); + print_block_info(BLOCK_CAT_SMALL, &in_use); + print_block_info(BLOCK_CAT_MEDIUM, &in_use); + print_block_info(BLOCK_CAT_LARGE, &in_use); + print_block_info(BLOCK_CAT_XL, &in_use); + print_block_info(BLOCK_CAT_XXL, &in_use); + + NRF_LOG_DEBUG ("+------------+------------+------------+------------+------------+------------+\r\n"); + NRF_LOG_DEBUG ("| Total | %d | %d | %d\r\n", + TOTAL_MEMORY_SIZE, TOTAL_BLOCK_COUNT,in_use); + NRF_LOG_DEBUG ("+------------+------------+------------+------------+------------+------------+\r\n"); +} + +#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS +/** @} */ +#endif //NRF_MODULE_ENABLED(MEM_MANAGER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/mem_manager/mem_manager.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/mem_manager/mem_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..109e43358ea4e9d0fdf1dbca97cba8d0355e6138 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/mem_manager/mem_manager.h @@ -0,0 +1,175 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup mem_manager Memory Manager + * @{ + * @ingroup app_common + * @brief Memory Manager for the @nRFXX SDK + * + * @details This module allows for dynamic use of memory. Currently, + * this module can be used only to allocate and free memory in the RAM. + * + * The Memory Manager manages static memory blocks of fixed sizes. These blocks can be requested for + * usage, and freed when the application no longer needs them. A maximum of seven block categories + * can be managed by the module. These block categories are identified by xxsmall, xmall, small, + * medium, large, xlarge, and xxlarge. They are ordered in increasing block sizes. + * The size and the count of each of the block categories can be configured based on the application + * requirements in the configuration file @c sdk_config.h. + * To use fewer than seven buffer pools, do not define the count for the unwanted block + * or explicitly set it to zero. At least one block category must be configured + * for this module to function as expected. + */ + +#ifndef MEM_MANAGER_H__ +#define MEM_MANAGER_H__ + +#include "sdk_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Initializes Memory Manager. + * + * @details API to initialize the Memory Manager. Always call this API before using any of the other + * APIs of the module. This API should be called only once. + * + * @retval NRF_SUCCESS If initialization was successful. + * Otherwise, an error code that indicates the reason for the failure is returned. + * + * @warning If this API fails, the application shall not proceed with using other APIs of this + * module. + */ +uint32_t nrf_mem_init(void); + + +/**@brief Reserves a block of memory for the application. + * + * @details API to request a contiguous memory block of the given length. If + * the memory allocation succeeds, pp_buffer points to the memory block. If + * the memory allocation fails, pp_buffer points to NULL and the return value of + * the API indicates the reason for the failure. The memory block reserved using this API can + * be freed using the @ref nrf_free function. + * + * @param[out] pp_buffer Pointer to the allocated memory block if memory allocation + * succeeds; otherwise points to NULL. + * @param[inout] p_size Requested memory size. This parameter returns the actual size + * allocated. If the procedure was successful, the actual size + * returned is always greater than or equal to requested size, + * never less. + * + * @retval NRF_SUCCESS If memory was successfully allocated. + * Otherwise, an error code indicating the reason for failure. + * @retval NRF_ERROR_INVALID_PARAM If the requested memory size is zero or greater than the + * largest memory block that the module is configured to + * support. + * @retval NRF_ERROR_NO_MEM If there is no memory available of the requested size. + */ +uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size); + + +/**@brief 'malloc' styled memory allocation function. + * + * @details API to allocate memory, same as nrf_mem_reserve but uses malloc signature. + * + * @param[in] size Requested memory size. + * + * @retval Valid memory location if the procedure was successful, else, NULL. + */ +void * nrf_malloc(uint32_t size); + + +/**@brief 'calloc' styled memory allocation function. + * + * @details API to allocate zero-initialized memory of size count*size. + * + * @param[in] nmemb Number of elements of 'size' bytes. + * @param[in] size Size of each element allocated. + * + * @retval Valid, zero-initialized memory location if the procedure was successful, else, NULL. + */ +void * nrf_calloc(uint32_t nmemb, uint32_t size); + + +/**@brief Free allocated memory - standard 'free' styles API. + * + * @details API to resubmit memory allocated, same in functionality nrf_free. + * + * @param[out] p_buffer Pointer to the memory block that is being freed. + */ +void nrf_free(void * p_buffer); + + +/**@brief Memory reallocation (trim) function. + * + * @details API to reallocate memory or to trim it. Trim is mentioned here to avoid use of API to + * request memory size larger than original memory allocated. + * + * @param[in] p_buffer Pointer to the memory block that needs to be trimmed. + * @param[in] size Size of memory at the beginning of the buffer to be left untrimmed. + * + * @retval Pointer to memory location with trimmed size, else, NULL. + */ +void * nrf_realloc(void *p_buffer, uint32_t size); + +#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS + +/**@brief Function to print statstics related to memory blocks managed by memory manager. + * + * @details This API prints information with respects to each block function, including size, total + * block count, number of blocks in use at the time of printing, smallest memory size + * allocated in the block and the largest one. This API is intended to help developers + * tune the block sizes to make optimal use of memory for the application. + * This functionality is never needed in final application and therefore, is disabled by + * default. + */ +void nrf_mem_diagnose(void); + +#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS + + +#ifdef __cplusplus +} +#endif + +#endif // MEM_MANAGER_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/mutex/nrf_mtx.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/mutex/nrf_mtx.h new file mode 100644 index 0000000000000000000000000000000000000000..b2d4735bdb6f6fa29fb18ab64d5fe3761cebd65e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/mutex/nrf_mtx.h @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * @defgroup nrf_mtx nRF Mutex + * @{ + * @ingroup app_common + * @brief Mutex used for protecting resources. + * + * This module provides a mutex that can be used to ensure only one context may enter a critical + * section holding the lock. + */ +#ifndef NRF_MTX_H__ +#define NRF_MTX_H__ + +#include +#include +#include "nrf.h" +#include "nrf_atomic.h" +#include "nrf_assert.h" + +#define NRF_MTX_LOCKED 1 +#define NRF_MTX_UNLOCKED 0 + +/** + * @brief Mutex data type. + * + * All fields in this struct are internal, and should never be modified outside of the nrf_mtx_* + * functions. + */ +typedef nrf_atomic_u32_t nrf_mtx_t; + +/** + * @brief Initialize mutex. + * + * This function _must_ be called before nrf_mtx_trylock() and nrf_mtx_unlock() functions. + * + * @param[out] p_mtx The mutex to be initialized. + */ +__STATIC_INLINE void nrf_mtx_init(nrf_mtx_t * p_mtx); + +/** + * @brief Try to lock a mutex. + * + * If the mutex is already held by another context, this function will return immediately. + * + * @param[in, out] p_mtx The mutex to be locked. + * @return true if lock was acquired, false if not + */ +__STATIC_INLINE bool nrf_mtx_trylock(nrf_mtx_t * p_mtx); + +/** + * @brief Unlock a mutex. + * + * This function _must_ only be called when holding the lock. Unlocking a mutex which you do not + * hold will give undefined behavior. + * + * @param[in, out] p_mtx The mutex to be unlocked. + */ +__STATIC_INLINE void nrf_mtx_unlock(nrf_mtx_t * p_mtx); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_mtx_init(nrf_mtx_t * p_mtx) +{ + ASSERT(p_mtx != NULL); + + *p_mtx = NRF_MTX_UNLOCKED; + __DMB(); +} + +__STATIC_INLINE bool nrf_mtx_trylock(nrf_mtx_t * p_mtx) +{ + ASSERT(p_mtx != NULL); + + uint32_t old_val = nrf_atomic_u32_store_fetch(p_mtx, NRF_MTX_LOCKED); + + return (old_val == NRF_MTX_UNLOCKED); +} + +__STATIC_INLINE void nrf_mtx_unlock(nrf_mtx_t * p_mtx) +{ + ASSERT(p_mtx != NULL); + ASSERT(*p_mtx == NRF_MTX_LOCKED); + + *p_mtx = NRF_MTX_UNLOCKED; + __DMB(); +} + +#endif //SUPPRESS_INLINE_IMPLEMENTATION + +#endif // NRF_MTX_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/pwm/app_pwm.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/pwm/app_pwm.c new file mode 100644 index 0000000000000000000000000000000000000000..a496920099a342a29d45dc24d67871501f2da5bc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/pwm/app_pwm.c @@ -0,0 +1,1010 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_PWM) +#include "app_pwm.h" +#include "nrf_drv_timer.h" +#include "nrf_drv_ppi.h" +#include "nrf_drv_common.h" +#include "nrf_drv_gpiote.h" +#include "nrf_gpiote.h" +#include "nrf_gpio.h" +#include "app_util_platform.h" +#include "nrf_assert.h" + +#define APP_PWM_CHANNEL_INITIALIZED 1 +#define APP_PWM_CHANNEL_UNINITIALIZED 0 + +#define APP_PWM_CHANNEL_ENABLED 1 +#define APP_PWM_CHANNEL_DISABLED 0 + +#define TIMER_PRESCALER_MAX 9 +#define TIMER_MAX_PULSEWIDTH_US_ON_16M 4095 + +#ifndef GPIOTE_SET_CLEAR_TASKS +#define APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE 2 +#endif +#define APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL 2 + +#define UNALLOCATED 0xFFFFFFFFUL +#define BUSY_STATE_CHANGING 0xFE +#define BUSY_STATE_IDLE 0xFF + +#define PWM_MAIN_CC_CHANNEL 2 +#define PWM_SECONDARY_CC_CHANNEL 3 + +#ifdef GPIOTE_SET_CLEAR_TASKS +static bool m_use_ppi_delay_workaround; +#endif + + +/** + * @brief PWM busy status + * + * Stores the number of a channel being currently updated. + * + */ +static volatile uint8_t m_pwm_busy[TIMER_COUNT]; + + +/** + * @brief New duty cycle value + * + * When the channel duty cycle reaches this value, the update process is complete. + */ +static volatile uint32_t m_pwm_target_value[TIMER_COUNT]; + + +/** + * @brief PWM ready counter + * + * The value in this counter is decremented in every PWM cycle after initiating the update. + * If an event handler function was specified by the user, it is being called + * after two cycle events (at least one full PWM cycle). + */ +volatile uint8_t m_pwm_ready_counter[TIMER_COUNT][APP_PWM_CHANNELS_PER_INSTANCE]; + +/** + * @brief Pointers to instances + * + * This array connects any active timer instance number with the pointer to the PWM instance. + * It is used by the interrupt runtime. + */ +static const app_pwm_t * m_instances[TIMER_COUNT]; + +// Macros for getting the polarity of given instance/channel. +#define POLARITY_ACTIVE(INST,CH) (( ((INST)->p_cb)->channels_cb[(CH)].polarity == \ + APP_PWM_POLARITY_ACTIVE_LOW)?(0):(1)) +#define POLARITY_INACTIVE(INST,CH) (( ((INST)->p_cb)->channels_cb[(CH)].polarity == \ + APP_PWM_POLARITY_ACTIVE_LOW)?(1):(0)) + +//lint -save -e534 + + +/** + * @brief Workaround for PAN-73. + * + * @param[in] timer Timer. + * @param[in] enable Enable or disable. + */ +static void pan73_workaround(NRF_TIMER_Type * p_timer, bool enable) +{ +#ifndef GPIOTE_SET_CLEAR_TASKS + if (p_timer == NRF_TIMER0) + { + *(uint32_t *)0x40008C0C = (enable ? 1 : 0); + } + else if (p_timer == NRF_TIMER1) + { + *(uint32_t *)0x40009C0C = (enable ? 1 : 0); + } + else if (p_timer == NRF_TIMER2) + { + *(uint32_t *)0x4000AC0C = (enable ? 1 : 0); + } +#else + UNUSED_PARAMETER(p_timer); + UNUSED_PARAMETER(enable); +#endif +} + +bool app_pwm_busy_check(app_pwm_t const * const p_instance) +{ + uint8_t busy_state = (m_pwm_busy[p_instance->p_timer->instance_id]); + bool busy = true; + if (busy_state != BUSY_STATE_IDLE) + { + if (busy_state != BUSY_STATE_CHANGING) + { + if (nrf_drv_timer_capture_get(p_instance->p_timer, (nrf_timer_cc_channel_t) busy_state) + == m_pwm_target_value[p_instance->p_timer->instance_id]) + { + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; + busy = false; + } + } + } + else + { + busy = false; + } + return busy; +} + + +/** + * @brief Function for enabling the IRQ for a given PWM instance. + * + * @param[in] p_instance PWM instance. + */ +__STATIC_INLINE void pwm_irq_enable(app_pwm_t const * const p_instance) +{ + nrf_drv_timer_compare_int_enable(p_instance->p_timer, PWM_MAIN_CC_CHANNEL); +} + + +/** + * @brief Function for disabling the IRQ for a given PWM instance. + * + * @param[in] p_instance PWM instance. + */ +__STATIC_INLINE void pwm_irq_disable(app_pwm_t const * const p_instance) +{ + nrf_drv_timer_compare_int_disable(p_instance->p_timer, PWM_MAIN_CC_CHANNEL); +} + +#ifndef GPIOTE_SET_CLEAR_TASKS +/** + * @brief Function for disabling PWM channel PPI. + * + * @param[in] p_instance PWM instance. + */ +__STATIC_INLINE void pwm_channel_ppi_disable(app_pwm_t const * const p_instance, uint8_t channel) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + + nrf_drv_ppi_channel_disable(p_cb->channels_cb[channel].ppi_channels[0]); + nrf_drv_ppi_channel_disable(p_cb->channels_cb[channel].ppi_channels[1]); +} + + +/** + * @brief Function for disabling PWM PPI. + * + * @param[in] p_instance PWM instance. + */ +__STATIC_INLINE void pwm_ppi_disable(app_pwm_t const * const p_instance) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + + nrf_drv_ppi_channel_disable(p_cb->ppi_channels[0]); + nrf_drv_ppi_channel_disable(p_cb->ppi_channels[1]); +} +#endif + +/** + * @brief This function is called on interrupt after duty set. + * + * @param[in] timer Timer used by PWM. + * @param[in] timer_instance_id Timer index. + */ +void pwm_ready_tick(nrf_timer_event_t event_type, void * p_context) +{ + uint32_t timer_instance_id = (uint32_t)p_context; + uint8_t disable = 1; + + for (uint8_t channel = 0; channel < APP_PWM_CHANNELS_PER_INSTANCE; ++channel) + { + if (m_pwm_ready_counter[timer_instance_id][channel]) + { + --m_pwm_ready_counter[timer_instance_id][channel]; + if (!m_pwm_ready_counter[timer_instance_id][channel]) + { + app_pwm_cb_t * p_cb = m_instances[timer_instance_id]->p_cb; + p_cb->p_ready_callback(timer_instance_id); + } + else + { + disable = 0; + } + } + } + + if (disable) + { + pwm_irq_disable(m_instances[timer_instance_id]); + } +} + + +/** + * @brief Function for resource de-allocation. + * + * @param[in] p_instance PWM instance. + */ +//lint -e{650} +static void pwm_dealloc(app_pwm_t const * const p_instance) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + +#ifdef GPIOTE_SET_CLEAR_TASKS + nrf_drv_ppi_channel_free(p_cb->ppi_channel); +#else + for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++i) + { + if (p_cb->ppi_channels[i] != (nrf_ppi_channel_t)(uint8_t)(UNALLOCATED)) + { + nrf_drv_ppi_channel_free(p_cb->ppi_channels[i]); + } + } + if (p_cb->ppi_group != (nrf_ppi_channel_group_t)UNALLOCATED) + { + nrf_drv_ppi_group_free(p_cb->ppi_group); + } +#endif //GPIOTE_SET_CLEAR_TASKS + for (uint8_t ch = 0; ch < APP_PWM_CHANNELS_PER_INSTANCE; ++ch) + { + for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL; ++i) + { + if (p_cb->channels_cb[ch].ppi_channels[i] != (nrf_ppi_channel_t)UNALLOCATED) + { + nrf_drv_ppi_channel_free(p_cb->channels_cb[ch].ppi_channels[i]); + p_cb->channels_cb[ch].ppi_channels[i] = (nrf_ppi_channel_t)UNALLOCATED; + } + } + if (p_cb->channels_cb[ch].gpio_pin != UNALLOCATED) + { + nrf_drv_gpiote_out_uninit(p_cb->channels_cb[ch].gpio_pin); + p_cb->channels_cb[ch].gpio_pin = UNALLOCATED; + } + p_cb->channels_cb[ch].initialized = APP_PWM_CHANNEL_UNINITIALIZED; + } + nrf_drv_timer_uninit(p_instance->p_timer); + return; +} + +#ifndef GPIOTE_SET_CLEAR_TASKS +/** + * @brief PWM state transition from (0%, 100%) to 0% or 100%. + * + * @param[in] p_instance PWM instance. + * @param[in] channel PWM channel number. + * @param[in] ticks Number of clock ticks. + */ +static void pwm_transition_n_to_0or100(app_pwm_t const * const p_instance, + uint8_t channel, uint16_t ticks) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; + nrf_ppi_channel_group_t p_ppigrp = p_cb->ppi_group; + + pwm_ppi_disable(p_instance); + nrf_drv_ppi_group_clear(p_ppigrp); + nrf_drv_ppi_channels_include_in_group( + nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[0]) | + nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[1]), + p_ppigrp); + + if (!ticks) + { + nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel), + nrf_drv_ppi_task_addr_group_disable_get(p_ppigrp)); + nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 0, false); + m_pwm_target_value[p_instance->p_timer->instance_id] = + nrf_drv_timer_capture_get(p_instance->p_timer, (nrf_timer_cc_channel_t) channel); + nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel), + nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL)); + } + else + { + ticks = p_cb->period; + nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL), + nrf_drv_ppi_task_addr_group_disable_get(p_ppigrp)); + // Set secondary CC channel to non-zero value: + nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 1, false); + m_pwm_target_value[p_instance->p_timer->instance_id] = 0; + // The captured value will be equal to 0, because timer clear on main PWM CC channel compare is enabled. + nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL), + nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL)); + } + + nrf_drv_ppi_channel_enable(p_cb->ppi_channels[0]); + nrf_drv_ppi_channel_enable(p_cb->ppi_channels[1]); + + p_ch_cb->pulsewidth = ticks; + m_pwm_busy[p_instance->p_timer->instance_id] = PWM_SECONDARY_CC_CHANNEL; +} + + +/** + * @brief PWM state transition from (0%, 100%) to (0%, 100%). + * + * @param[in] p_instance PWM instance. + * @param[in] channel PWM channel number. + * @param[in] ticks Number of clock ticks. + */ +static void pwm_transition_n_to_m(app_pwm_t const * const p_instance, + uint8_t channel, uint16_t ticks) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; + nrf_ppi_channel_group_t p_ppigrp = p_cb->ppi_group; + + pwm_ppi_disable(p_instance); + nrf_drv_ppi_group_clear(p_ppigrp); + nrf_drv_ppi_channels_include_in_group( + nrf_drv_ppi_channel_to_mask(p_cb->ppi_channels[0]) | + nrf_drv_ppi_channel_to_mask(p_cb->ppi_channels[1]), + p_ppigrp); + + nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL), + nrf_drv_timer_capture_task_address_get(p_instance->p_timer, channel)); + + + if (ticks + ((nrf_timer_frequency_get(p_instance->p_timer->p_reg) == NRF_TIMER_FREQ_16MHz) ? 1 : 0) + < p_ch_cb->pulsewidth) + { + // For lower value, we need one more transition. Timer task delay is included. + // If prescaler is disabled, one tick must be added because of 1 PCLK16M clock cycle delay. + nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL), + nrf_drv_gpiote_out_task_addr_get(p_ch_cb->gpio_pin)); + } + else + { + nrf_drv_ppi_channel_remove_from_group(p_cb->ppi_channels[1], p_ppigrp); + } + p_ch_cb->pulsewidth = ticks; + nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, ticks, false); + nrf_drv_ppi_group_enable(p_ppigrp); + + m_pwm_target_value[p_instance->p_timer->instance_id] = ticks; + m_pwm_busy[p_instance->p_timer->instance_id] = channel; +} + + +/** + * @brief PWM state transition from 0% or 100% to (0%, 100%). + * + * @param[in] p_instance PWM instance. + * @param[in] channel PWM channel number. + * @param[in] ticks Number of clock ticks. + */ +static void pwm_transition_0or100_to_n(app_pwm_t const * const p_instance, + uint8_t channel, uint16_t ticks) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; + nrf_ppi_channel_group_t p_ppigrp = p_cb->ppi_group; + nrf_timer_cc_channel_t pwm_ch_cc = (nrf_timer_cc_channel_t)(channel); + + pwm_ppi_disable(p_instance); + pwm_channel_ppi_disable(p_instance, channel); + + nrf_drv_timer_compare(p_instance->p_timer, pwm_ch_cc, ticks, false); + nrf_drv_ppi_group_clear(p_ppigrp); + nrf_drv_ppi_channels_include_in_group( + nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[0])| + nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[1]), + p_ppigrp); + + if (!p_ch_cb->pulsewidth) + { + // Channel is at 0%. + nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel), + nrf_drv_ppi_task_addr_group_enable_get(p_ppigrp)); + nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 0, false); + m_pwm_target_value[p_instance->p_timer->instance_id] = + nrf_drv_timer_capture_get(p_instance->p_timer, (nrf_timer_cc_channel_t) channel); + nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel), + nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL)); + + } + else + { + // Channel is at 100%. + nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL), + nrf_drv_ppi_task_addr_group_enable_get(p_ppigrp)); + // Set secondary CC channel to non-zero value: + nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 1, false); + m_pwm_target_value[p_instance->p_timer->instance_id] = 0; + // The captured value will be equal to 0, because timer clear on main PWM CC channel compare is enabled. + nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL), + nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL)); + } + nrf_drv_ppi_channel_enable(p_cb->ppi_channels[0]); + nrf_drv_ppi_channel_enable(p_cb->ppi_channels[1]); + + p_ch_cb->pulsewidth = ticks; + m_pwm_busy[p_instance->p_timer->instance_id] = PWM_SECONDARY_CC_CHANNEL; +} + + +/** + * @brief PWM state transition from 0% or 100% to 0% or 100%. + * + * @param[in] p_instance PWM instance. + * @param[in] channel PWM channel number. + * @param[in] ticks Number of clock ticks. + */ +static void pwm_transition_0or100_to_0or100(app_pwm_t const * const p_instance, + uint8_t channel, uint16_t ticks) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; + nrf_timer_cc_channel_t pwm_ch_cc = (nrf_timer_cc_channel_t)(channel); + + pwm_ppi_disable(p_instance); + pwm_channel_ppi_disable(p_instance, channel); + if (!ticks) + { + // Set to 0%. + nrf_drv_gpiote_out_task_force(p_ch_cb->gpio_pin, POLARITY_INACTIVE(p_instance, channel)); + } + else if (ticks >= p_cb->period) + { + // Set to 100%. + ticks = p_cb->period; + nrf_drv_gpiote_out_task_force(p_ch_cb->gpio_pin, POLARITY_ACTIVE(p_instance, channel)); + } + nrf_drv_timer_compare(p_instance->p_timer, pwm_ch_cc, ticks, false); + p_ch_cb->pulsewidth = ticks; + + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; + return; +} + +static void pwm_transition(app_pwm_t const * const p_instance, + uint8_t channel, uint16_t ticks) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + app_pwm_channel_cb_t * p_ch_cb = &p_instance->p_cb->channels_cb[channel]; + + // Pulse width change sequence: + if (!p_ch_cb->pulsewidth || p_ch_cb->pulsewidth >= p_cb->period) + { + // Channel is disabled (0%) or at 100%. + if (!ticks || ticks >= p_cb->period) + { + // Set to 0 or 100%. + pwm_transition_0or100_to_0or100(p_instance, channel, ticks); + } + else + { + // Other value. + pwm_transition_0or100_to_n(p_instance, channel, ticks); + } + } + else + { + // Channel is at other value. + if (!ticks || ticks >= p_cb->period) + { + // Disable channel (set to 0%) or set to 100%. + pwm_transition_n_to_0or100(p_instance, channel, ticks); + } + else + { + // Set to any other value. + pwm_transition_n_to_m(p_instance, channel, ticks); + } + } +} +#else //GPIOTE_SET_CLEAR_TASKS +/** + * @brief PWM state transition. + * + * @param[in] p_instance PWM instance. + * @param[in] channel PWM channel number. + * @param[in] ticks Number of clock ticks. + */ +static void pwm_transition(app_pwm_t const * const p_instance, + uint8_t channel, uint16_t ticks) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; + nrf_timer_cc_channel_t pwm_ch_cc = (nrf_timer_cc_channel_t)(channel); + + nrf_drv_ppi_channel_disable(p_cb->ppi_channel); + + if (!ticks) + { + nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[1]); + nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[0]); + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; + } + else if (ticks >= p_cb->period) + { + ticks = p_cb->period; + nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[0]); + nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[1]); + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; + } + else + { + // Set to any other value. + if ((p_ch_cb->pulsewidth != p_cb->period) && (p_ch_cb->pulsewidth != 0) && (ticks < p_ch_cb->pulsewidth)) + { + nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t)PWM_SECONDARY_CC_CHANNEL, p_ch_cb->pulsewidth, false); + nrf_drv_ppi_channel_assign(p_cb->ppi_channel, + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, (nrf_timer_cc_channel_t)PWM_SECONDARY_CC_CHANNEL), + p_ch_cb->polarity ? nrf_drv_gpiote_clr_task_addr_get(p_ch_cb->gpio_pin) : nrf_drv_gpiote_set_task_addr_get(p_ch_cb->gpio_pin)); + nrf_drv_ppi_channel_enable(p_cb->ppi_channel); + m_pwm_busy[p_instance->p_timer->instance_id] = channel; + m_pwm_target_value[p_instance->p_timer->instance_id] = ticks; + } + else + { + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; + } + + nrf_drv_timer_compare(p_instance->p_timer, pwm_ch_cc, ticks, false); + + nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[0]); + nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[1]); + } + p_ch_cb->pulsewidth = ticks; + return; +} +#endif //GPIOTE_SET_CLEAR_TASKS + +ret_code_t app_pwm_channel_duty_ticks_set(app_pwm_t const * const p_instance, + uint8_t channel, + uint16_t ticks) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; + + ASSERT(channel < APP_PWM_CHANNELS_PER_INSTANCE); + ASSERT(p_ch_cb->initialized == APP_PWM_CHANNEL_INITIALIZED); + + if (p_cb->state != NRF_DRV_STATE_POWERED_ON) + { + return NRF_ERROR_INVALID_STATE; + } + if (ticks == p_ch_cb->pulsewidth) + { + if (p_cb->p_ready_callback) + { + p_cb->p_ready_callback(p_instance->p_timer->instance_id); + } + return NRF_SUCCESS; // No action required. + } + if (app_pwm_busy_check(p_instance)) + { + return NRF_ERROR_BUSY; // PPI channels for synchronization are still in use. + } + + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_CHANGING; + + // Set new value. + + pwm_transition(p_instance, channel, ticks); + + if (p_instance->p_cb->p_ready_callback) + { + //PWM ready interrupt handler will be called after one full period. + m_pwm_ready_counter[p_instance->p_timer->instance_id][channel] = 2; + pwm_irq_enable(p_instance); + } + return NRF_SUCCESS; +} + +uint16_t app_pwm_channel_duty_ticks_get(app_pwm_t const * const p_instance, uint8_t channel) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; + + return p_ch_cb->pulsewidth; +} + +uint16_t app_pwm_cycle_ticks_get(app_pwm_t const * const p_instance) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + + return (uint16_t)p_cb->period; +} + +ret_code_t app_pwm_channel_duty_set(app_pwm_t const * const p_instance, + uint8_t channel, app_pwm_duty_t duty) +{ + uint32_t ticks = ((uint32_t)app_pwm_cycle_ticks_get(p_instance) * (uint32_t)duty) / 100UL; + return app_pwm_channel_duty_ticks_set(p_instance, channel, ticks); +} + + +app_pwm_duty_t app_pwm_channel_duty_get(app_pwm_t const * const p_instance, uint8_t channel) +{ + uint32_t value = ((uint32_t)app_pwm_channel_duty_ticks_get(p_instance, channel) * 100UL) \ + / (uint32_t)app_pwm_cycle_ticks_get(p_instance); + + return (app_pwm_duty_t)value; +} + + +/** + * @brief Function for initializing the PWM channel. + * + * @param[in] p_instance PWM instance. + * @param[in] channel Channel number. + * @param[in] pin GPIO pin number. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_NO_MEM If there were not enough free resources. + * @retval NRF_ERROR_INVALID_STATE If the timer is already in use or initialization failed. + */ +static ret_code_t app_pwm_channel_init(app_pwm_t const * const p_instance, uint8_t channel, + uint32_t pin, app_pwm_polarity_t polarity) +{ + ASSERT(channel < APP_PWM_CHANNELS_PER_INSTANCE); + app_pwm_cb_t * p_cb = p_instance->p_cb; + app_pwm_channel_cb_t * p_channel_cb = &p_cb->channels_cb[channel]; + + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + + p_channel_cb->pulsewidth = 0; + p_channel_cb->polarity = polarity; + ret_code_t err_code; + + /* GPIOTE setup: */ + nrf_drv_gpiote_out_config_t out_cfg = GPIOTE_CONFIG_OUT_TASK_TOGGLE( POLARITY_INACTIVE(p_instance, channel) ); + err_code = nrf_drv_gpiote_out_init((nrf_drv_gpiote_pin_t)pin,&out_cfg); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_NO_MEM; + } + p_cb->channels_cb[channel].gpio_pin = pin; + + // Set output to inactive state. + if (polarity) + { + nrf_gpio_pin_clear(pin); + } + else + { + nrf_gpio_pin_set(pin); + } + + /* PPI setup: */ + for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL; ++i) + { + if (nrf_drv_ppi_channel_alloc(&p_channel_cb->ppi_channels[i]) != NRF_SUCCESS) + { + return NRF_ERROR_NO_MEM; // Resource de-allocation is done by callee. + } + } + + nrf_drv_ppi_channel_disable(p_channel_cb->ppi_channels[0]); + nrf_drv_ppi_channel_disable(p_channel_cb->ppi_channels[1]); + +#ifdef GPIOTE_SET_CLEAR_TASKS + uint32_t deactivate_task_addr = polarity ? nrf_drv_gpiote_clr_task_addr_get(p_channel_cb->gpio_pin) : nrf_drv_gpiote_set_task_addr_get(p_channel_cb->gpio_pin); + uint32_t activate_task_addr = polarity ? nrf_drv_gpiote_set_task_addr_get(p_channel_cb->gpio_pin) : nrf_drv_gpiote_clr_task_addr_get(p_channel_cb->gpio_pin); + + nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[0], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel), + deactivate_task_addr); + nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[1], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL), + activate_task_addr); +#else //GPIOTE_SET_CLEAR_TASKS + nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[0], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel), + nrf_drv_gpiote_out_task_addr_get(p_channel_cb->gpio_pin)); + nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[1], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL), + nrf_drv_gpiote_out_task_addr_get(p_channel_cb->gpio_pin)); +#endif //GPIOTE_SET_CLEAR_TASKS + p_channel_cb->initialized = APP_PWM_CHANNEL_INITIALIZED; + m_pwm_ready_counter[p_instance->p_timer->instance_id][channel] = 0; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for calculating target timer frequency, which will allow to set given period length. + * + * @param[in] period_us Desired period in microseconds. + * + * @retval Timer frequency. + */ +__STATIC_INLINE nrf_timer_frequency_t pwm_calculate_timer_frequency(uint32_t period_us) +{ + uint32_t f = (uint32_t) NRF_TIMER_FREQ_16MHz; + uint32_t min = (uint32_t) NRF_TIMER_FREQ_31250Hz; + + while ((period_us > TIMER_MAX_PULSEWIDTH_US_ON_16M) && (f < min)) + { + period_us >>= 1; + ++f; + } + +#ifdef GPIOTE_SET_CLEAR_TASKS + if ((m_use_ppi_delay_workaround) && (f == (uint32_t) NRF_TIMER_FREQ_16MHz)) + { + f = (uint32_t) NRF_TIMER_FREQ_8MHz; + } +#endif // GPIOTE_SET_CLEAR_TASKS + + return (nrf_timer_frequency_t) f; +} + + +ret_code_t app_pwm_init(app_pwm_t const * const p_instance, app_pwm_config_t const * const p_config, + app_pwm_callback_t p_ready_callback) +{ + ASSERT(p_instance); + + if (!p_config) + { + return NRF_ERROR_INVALID_DATA; + } + + app_pwm_cb_t * p_cb = p_instance->p_cb; + + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + + uint32_t err_code = nrf_drv_ppi_init(); + if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED)) + { + return NRF_ERROR_NO_MEM; + } + + + if (!nrf_drv_gpiote_is_init()) + { + err_code = nrf_drv_gpiote_init(); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + } + +#ifdef GPIOTE_SET_CLEAR_TASKS + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) + { + m_use_ppi_delay_workaround = false; + } + else + { + m_use_ppi_delay_workaround = true; + } +#endif + + // Innitialize resource status: +#ifdef GPIOTE_SET_CLEAR_TASKS + p_cb->ppi_channel = (nrf_ppi_channel_t)UNALLOCATED; +#else + p_cb->ppi_channels[0] = (nrf_ppi_channel_t)UNALLOCATED; + p_cb->ppi_channels[1] = (nrf_ppi_channel_t)UNALLOCATED; + p_cb->ppi_group = (nrf_ppi_channel_group_t)UNALLOCATED; +#endif //GPIOTE_SET_CLEAR_TASKS + + for (uint8_t i = 0; i < APP_PWM_CHANNELS_PER_INSTANCE; ++i) + { + p_cb->channels_cb[i].initialized = APP_PWM_CHANNEL_UNINITIALIZED; + p_cb->channels_cb[i].ppi_channels[0] = (nrf_ppi_channel_t)UNALLOCATED; + p_cb->channels_cb[i].ppi_channels[1] = (nrf_ppi_channel_t)UNALLOCATED; + p_cb->channels_cb[i].gpio_pin = UNALLOCATED; + } + + // Allocate PPI channels and groups: + +#ifdef GPIOTE_SET_CLEAR_TASKS + if (nrf_drv_ppi_channel_alloc(&p_cb->ppi_channel) != NRF_SUCCESS) + { + pwm_dealloc(p_instance); + return NRF_ERROR_NO_MEM; + } +#else //GPIOTE_SET_CLEAR_TASKS + if (nrf_drv_ppi_group_alloc(&p_cb->ppi_group) != NRF_SUCCESS) + { + pwm_dealloc(p_instance); + return NRF_ERROR_NO_MEM; + } + + for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++i) + { + if (nrf_drv_ppi_channel_alloc(&p_cb->ppi_channels[i]) != NRF_SUCCESS) + { + pwm_dealloc(p_instance); + return NRF_ERROR_NO_MEM; + } + } +#endif //GPIOTE_SET_CLEAR_TASKS + // Initialize channels: + for (uint8_t i = 0; i < APP_PWM_CHANNELS_PER_INSTANCE; ++i) + { + if (p_config->pins[i] != APP_PWM_NOPIN) + { + err_code = app_pwm_channel_init(p_instance, i, p_config->pins[i], p_config->pin_polarity[i]); + if (err_code != NRF_SUCCESS) + { + pwm_dealloc(p_instance); + return err_code; + } + app_pwm_channel_duty_ticks_set(p_instance, i, 0); + } + } + + // Initialize timer: + nrf_timer_frequency_t timer_freq = pwm_calculate_timer_frequency(p_config->period_us); + nrf_drv_timer_config_t timer_cfg = { + .frequency = timer_freq, + .mode = NRF_TIMER_MODE_TIMER, + .bit_width = NRF_TIMER_BIT_WIDTH_16, + .interrupt_priority = APP_IRQ_PRIORITY_LOWEST, + .p_context = (void *) (uint32_t) p_instance->p_timer->instance_id + }; + err_code = nrf_drv_timer_init(p_instance->p_timer, &timer_cfg, + pwm_ready_tick); + if (err_code != NRF_SUCCESS) + { + pwm_dealloc(p_instance); + return err_code; + } + + uint32_t ticks = nrf_drv_timer_us_to_ticks(p_instance->p_timer, p_config->period_us); + p_cb->period = ticks; + nrf_drv_timer_clear(p_instance->p_timer); + nrf_drv_timer_extended_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_MAIN_CC_CHANNEL, + ticks, NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK, true); + nrf_drv_timer_compare_int_disable(p_instance->p_timer, PWM_MAIN_CC_CHANNEL); + + p_cb->p_ready_callback = p_ready_callback; + m_instances[p_instance->p_timer->instance_id] = p_instance; + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; + p_cb->state = NRF_DRV_STATE_INITIALIZED; + + return NRF_SUCCESS; +} + + +void app_pwm_enable(app_pwm_t const * const p_instance) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + for (uint32_t channel = 0; channel < APP_PWM_CHANNELS_PER_INSTANCE; ++channel) + { + app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; + m_pwm_ready_counter[p_instance->p_timer->instance_id][channel] = 0; + if (p_ch_cb->initialized) + { + nrf_drv_gpiote_out_task_force(p_ch_cb->gpio_pin, POLARITY_INACTIVE(p_instance, channel)); + nrf_drv_gpiote_out_task_enable(p_ch_cb->gpio_pin); + p_ch_cb->pulsewidth = 0; + } + } + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; + + pan73_workaround(p_instance->p_timer->p_reg, true); + + nrf_drv_timer_clear(p_instance->p_timer); + nrf_drv_timer_enable(p_instance->p_timer); + + p_cb->state = NRF_DRV_STATE_POWERED_ON; + return; +} + + +void app_pwm_disable(app_pwm_t const * const p_instance) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_drv_timer_disable(p_instance->p_timer); + pwm_irq_disable(p_instance); + +#ifdef GPIOTE_SET_CLEAR_TASKS + nrf_drv_ppi_channel_disable(p_cb->ppi_channel); +#else + for (uint8_t ppi_channel = 0; ppi_channel < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++ppi_channel) + { + nrf_drv_ppi_channel_disable(p_cb->ppi_channels[ppi_channel]); + } +#endif //GPIOTE_SET_CLEAR_TASKS + + for (uint8_t channel = 0; channel < APP_PWM_CHANNELS_PER_INSTANCE; ++channel) + { + app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; + if (p_ch_cb->initialized) + { + uint8_t polarity = POLARITY_INACTIVE(p_instance, channel); + if (polarity) + { + nrf_gpio_pin_set(p_ch_cb->gpio_pin); + } + else + { + nrf_gpio_pin_clear(p_ch_cb->gpio_pin); + } + nrf_drv_gpiote_out_task_disable(p_ch_cb->gpio_pin); + nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[0]); + nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[1]); + } + } + + pan73_workaround(p_instance->p_timer->p_reg, false); + + p_cb->state = NRF_DRV_STATE_INITIALIZED; + return; +} + + +ret_code_t app_pwm_uninit(app_pwm_t const * const p_instance) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + + if (p_cb->state == NRF_DRV_STATE_POWERED_ON) + { + app_pwm_disable(p_instance); + } + else if (p_cb->state == NRF_DRV_STATE_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + pwm_dealloc(p_instance); + + p_cb->state = NRF_DRV_STATE_UNINITIALIZED; + return NRF_SUCCESS; +} + + +//lint -restore +#endif //NRF_MODULE_ENABLED(APP_PWM) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/pwm/app_pwm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/pwm/app_pwm.h new file mode 100644 index 0000000000000000000000000000000000000000..73487c63f75109c456c6966897f046867e4e2844 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/pwm/app_pwm.h @@ -0,0 +1,339 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup app_pwm Pulse-width modulation (PWM) + * @{ + * @ingroup app_common + * + * @brief Module for generating a pulse-width modulated output signal. + * + * @details This module provides a PWM implementation using timers, GPIOTE, and PPI. + * + * Resource usage: + * - 2 PPI channels per instance + 2 PPI channels per PWM channel. + * - 1 PPI group per instance. + * - 1 GPIOTE channel per PWM channel. + * + * For example, a PWM instance with two channels will consume 2 + 4 PPI channels, 1 PPI group, and 2 GPIOTE channels. + * + * The maximum number of PWM channels per instance is 2. + */ + +#ifndef APP_PWM_H__ +#define APP_PWM_H__ + +#include +#include "sdk_errors.h" +#include "nrf_drv_timer.h" +#include "nrf_drv_common.h" +#include "nrf_drv_ppi.h" +#include "nrf_peripherals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(GPIOTE_FEATURE_SET_PRESENT) && defined(GPIOTE_FEATURE_CLR_PRESENT) +#define GPIOTE_SET_CLEAR_TASKS +#endif + +#define APP_PWM_NOPIN 0xFFFFFFFF + +/** @brief Number of channels for one timer instance (fixed to 2 due to timer properties).*/ +#define APP_PWM_CHANNELS_PER_INSTANCE 2 + +/**@brief Macro for creating a PWM instance. */ +#define APP_PWM_INSTANCE(name, num) \ + const nrf_drv_timer_t m_pwm_##name##_timer = NRF_DRV_TIMER_INSTANCE(num); \ + app_pwm_cb_t m_pwm_##name##_cb; \ + /*lint -e{545}*/ \ + const app_pwm_t name = { \ + .p_cb = &m_pwm_##name##_cb, \ + .p_timer = &m_pwm_##name##_timer, \ + } + + +/**@brief PWM instance default configuration (1 channel). */ +#define APP_PWM_DEFAULT_CONFIG_1CH(period_in_us, pin) \ + { \ + .pins = {pin, APP_PWM_NOPIN}, \ + .pin_polarity = {APP_PWM_POLARITY_ACTIVE_LOW, APP_PWM_POLARITY_ACTIVE_LOW}, \ + .num_of_channels = 1, \ + .period_us = period_in_us \ + } + +/**@brief PWM instance default configuration (2 channels). */ +#define APP_PWM_DEFAULT_CONFIG_2CH(period_in_us, pin0, pin1) \ + { \ + .pins = {pin0, pin1}, \ + .pin_polarity = {APP_PWM_POLARITY_ACTIVE_LOW, APP_PWM_POLARITY_ACTIVE_LOW}, \ + .num_of_channels = 2, \ + .period_us = period_in_us \ + } + +typedef uint16_t app_pwm_duty_t; + +/** + * @brief PWM callback that is executed when a PWM duty change has been completed. + * + * @param[in] pwm_id PWM instance ID. + */ +typedef void (* app_pwm_callback_t)(uint32_t); + +/** + * @brief Channel polarity. + */ +typedef enum +{ + APP_PWM_POLARITY_ACTIVE_LOW = 0, + APP_PWM_POLARITY_ACTIVE_HIGH = 1 +} app_pwm_polarity_t; + +/**@brief PWM configuration structure used for initialization. */ +typedef struct +{ + uint32_t pins[APP_PWM_CHANNELS_PER_INSTANCE]; //!< Pins configured as PWM output. + app_pwm_polarity_t pin_polarity[APP_PWM_CHANNELS_PER_INSTANCE]; //!< Polarity of active state on pin. + uint32_t num_of_channels; //!< Number of channels that can be used. + uint32_t period_us; //!< PWM signal output period to configure (in microseconds). +} app_pwm_config_t; + + +/** + * @cond (NODOX) + * @defgroup app_pwm_internal Auxiliary internal types declarations + * @{ + * @internal + * + * @brief Module for internal usage inside the library only + * + * There are some definitions that must be included in the header file because + * of the way the library is set up. In this way, the are accessible to the user. + * However, any functions and variables defined here may change at any time + * without a warning, so you should not access them directly. + */ + + /** + * @brief PWM channel instance + * + * This structure holds all data needed by a single PWM channel. + */ + typedef struct + { + uint32_t gpio_pin; //!< Pin that is used by this PWM channel. + uint32_t pulsewidth; //!< The copy of duty currently set (in ticks). + nrf_ppi_channel_t ppi_channels[2]; //!< PPI channels used by the PWM channel to clear and set the output. + app_pwm_polarity_t polarity; //!< The active state of the pin. + uint8_t initialized; //!< The internal information if the selected channel was initialized. + } app_pwm_channel_cb_t; + + /** + * @brief Variable part of PWM instance + * + * This structure holds instance data that may change. + */ + typedef struct + { + app_pwm_channel_cb_t channels_cb[APP_PWM_CHANNELS_PER_INSTANCE]; //!< Channels data + uint32_t period; //!< Selected period in ticks + app_pwm_callback_t p_ready_callback; //!< Callback function called on PWM readiness +#ifdef GPIOTE_SET_CLEAR_TASKS + nrf_ppi_channel_t ppi_channel; //!< PPI channel used temporary while changing duty +#else + nrf_ppi_channel_t ppi_channels[2]; //!< PPI channels used temporary while changing duty + nrf_ppi_channel_group_t ppi_group; //!< PPI group used to synchronize changes on channels +#endif + nrf_drv_state_t state; //!< Current driver status + } app_pwm_cb_t; +/** @} + * @endcond + */ + + +/**@brief PWM instance structure. */ +typedef struct +{ + app_pwm_cb_t *p_cb; //!< Pointer to control block internals. + nrf_drv_timer_t const * const p_timer; //!< Timer used by this PWM instance. +} app_pwm_t; + +/** + * @brief Function for checking if the PWM instance is busy updating the duty cycle. + * + * @param[in] p_instance PWM instance. + * + * @retval True If the PWM instance is ready for duty cycle changes. + * @retval False If a change operation is in progress. + */ +bool app_pwm_busy_check(app_pwm_t const * const p_instance); + +/** + * @brief Function for initializing a PWM instance. + * + * @param[in] p_instance PWM instance. + * @param[in] p_config Initial configuration. + * @param[in] p_ready_callback Pointer to ready callback function (or NULL to disable). + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_NO_MEM If there were not enough free resources. + * @retval NRF_ERROR_INVALID_PARAM If an invalid configuration structure was passed. + * @retval NRF_ERROR_INVALID_STATE If the timer/PWM is already in use or if initialization failed. + */ +ret_code_t app_pwm_init(app_pwm_t const * const p_instance, app_pwm_config_t const * const p_config, + app_pwm_callback_t p_ready_callback); + + +/** + * @brief Function for uninitializing a PWM instance and releasing the allocated resources. + * + * @param[in] p_instance PWM instance. + * + * @retval NRF_SUCCESS If uninitialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the given instance was not initialized. + */ +ret_code_t app_pwm_uninit(app_pwm_t const * const p_instance); + +/** + * @brief Function for enabling a PWM instance after initialization. + * + * @param[in] p_instance PWM instance. + */ +void app_pwm_enable(app_pwm_t const * const p_instance); + +/** + * @brief Function for disabling a PWM instance after initialization. + * + * @param[in] p_instance PWM instance. + */ +void app_pwm_disable(app_pwm_t const * const p_instance); + +/** + * @brief Function for setting the PWM channel duty cycle in percents. + * + * A duty cycle change requires one full PWM clock period to finish. + * If another change is attempted for any channel of given instance before + * the current change is complete, the new attempt will result in the error + * NRF_ERROR_BUSY. + * + * @param[in] p_instance PWM instance. + * @param[in] channel Channel number. + * @param[in] duty Duty cycle (0 - 100). + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_BUSY If the PWM is not ready yet. + * @retval NRF_ERROR_INVALID_STATE If the given instance was not initialized. + * + */ +ret_code_t app_pwm_channel_duty_set(app_pwm_t const * const p_instance, + uint8_t channel, app_pwm_duty_t duty); + +/** + * @brief Function for retrieving the PWM channel duty cycle in percents. + * + * @param[in] p_instance PWM instance. + * @param[in] channel Channel number. + * + * @return Duty cycle value. + */ +app_pwm_duty_t app_pwm_channel_duty_get(app_pwm_t const * const p_instance, uint8_t channel); + + +/** + * @name Functions accessing values in ticks + * + * Auxiliary functions that allow to get values in actual timer ticks. + * @{ + */ + + /** + * @brief Function for setting PWM channel duty cycle in clock ticks. + * + * @note Duty cycle changes require one full PWM clock period to finish. + * Until that, the next change attempt (for any channel of given instance) + * will result in an NRF_ERROR_BUSY error. + * + * @param[in] p_instance PWM instance. + * @param[in] channel Channel number. + * @param[in] ticks Number of PWM clock ticks. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_BUSY If PWM is not ready yet. + * @retval NRF_ERROR_INVALID_STATE If the given instance was not initialized. + */ + ret_code_t app_pwm_channel_duty_ticks_set(app_pwm_t const * const p_instance, + uint8_t channel, + uint16_t ticks); + + + /** + * @brief Function for retrieving the PWM channel duty cycle in ticks. + * + * This function retrieves the real, currently set duty cycle in ticks. + * For one full PWM cycle the value might be different than the value set by the last + * @ref app_pwm_channel_duty_ticks_set function call. + * + * @param[in] p_instance PWM instance. + * @param[in] channel Channel number. + * + * @return Number of ticks set for selected channel. + * + */ + uint16_t app_pwm_channel_duty_ticks_get(app_pwm_t const * const p_instance, uint8_t channel); + + /** + * @brief Function for returning the number of ticks in a whole cycle. + * + * @param[in] p_instance PWM instance. + * + * @return Number of ticks that corresponds to 100% of the duty cycle. + */ + uint16_t app_pwm_cycle_ticks_get(app_pwm_t const * const p_instance); +/** @} */ + + + +#ifdef __cplusplus +} +#endif + +#endif + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c new file mode 100644 index 0000000000000000000000000000000000000000..e1d74854c059da499c5cb8c6d22f8170585902e2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c @@ -0,0 +1,464 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_PWR_MGMT) + +#include "nrf_pwr_mgmt.h" +#include "nrf.h" +#include "nrf_mtx.h" +#include "nrf_power.h" +#include "app_error.h" +#include "nrf_assert.h" +#include "nrf_log_ctrl.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "NRF_PWR_MGMT" +#if NRF_PWR_MGMT_CONFIG_LOG_ENABLED + #define NRF_LOG_LEVEL NRF_PWR_MGMT_CONFIG_LOG_LEVEL + #define NRF_LOG_INFO_COLOR NRF_PWR_MGMT_CONFIG_INFO_COLOR + #define NRF_LOG_DEBUG_COLOR NRF_PWR_MGMT_CONFIG_DEBUG_COLOR +#else + #define NRF_LOG_LEVEL 0 +#endif // NRF_PWR_MGMT_CONFIG_LOG_ENABLED +#include "nrf_log.h" + + +#ifdef SOFTDEVICE_PRESENT + #include "nrf_soc.h" + #include "softdevice_handler.h" +#endif // SOFTDEVICE_PRESENT + + +#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER + #if (APP_SCHEDULER_ENABLED != 1) + #error "APP_SCHEDULER is required." + #endif + #include "app_scheduler.h" +#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER + + +// Create section "pwr_mgmt_data". +NRF_SECTION_SET_DEF(pwr_mgmt_data, + nrf_pwr_mgmt_shutdown_handler_t, + NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT); + +static nrf_pwr_mgmt_evt_t m_pwr_mgmt_evt; /**< Event type which will be passed to the shutdown + handlers.*/ +static nrf_mtx_t m_sysoff_mtx; /**< Module API lock.*/ +static bool m_shutdown_started; /**< True if application started the shutdown preparation. */ +static nrf_section_iter_t m_handlers_iter; /**< Shutdown handlers iterator. */ + + +#if NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED + #define PWR_MGMT_FPU_SLEEP_PREPARE() pwr_mgmt_fpu_sleep_prepare() + + __STATIC_INLINE void pwr_mgmt_fpu_sleep_prepare(void) + { + uint32_t fpscr; + CRITICAL_REGION_ENTER(); + fpscr = __get_FPSCR(); + /* + * Clear FPU exceptions. + * Without this step, the FPU interrupt is marked as pending, + * preventing system from sleeping. Exceptions cleared: + * - IOC - Invalid Operation cumulative exception bit. + * - DZC - Division by Zero cumulative exception bit. + * - OFC - Overflow cumulative exception bit. + * - UFC - Underflow cumulative exception bit. + * - IXC - Inexact cumulative exception bit. + * - IDC - Input Denormal cumulative exception bit. + */ + __set_FPSCR(fpscr & ~0x9Fu); + __DMB(); + NVIC_ClearPendingIRQ(FPU_IRQn); + CRITICAL_REGION_EXIT(); + + /* + * Assert no critical FPU exception is signaled: + * - IOC - Invalid Operation cumulative exception bit. + * - DZC - Division by Zero cumulative exception bit. + * - OFC - Overflow cumulative exception bit. + */ + ASSERT((fpscr & 0x07) == 0); + } +#else + #define PWR_MGMT_FPU_SLEEP_PREPARE() +#endif // NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED + + +#if NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED + #undef PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED + #define PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED + + #include "nrf_gpio.h" + #define PWR_MGMT_DEBUG_PINS_INIT() pwr_mgmt_debug_pins_init() + #define PWR_MGMT_DEBUG_PIN_CLEAR() nrf_gpio_pin_clear(NRF_PWR_MGMT_SLEEP_DEBUG_PIN) + #define PWR_MGMT_DEBUG_PIN_SET() nrf_gpio_pin_set(NRF_PWR_MGMT_SLEEP_DEBUG_PIN) + + __STATIC_INLINE void pwr_mgmt_debug_pins_init(void) + { + nrf_gpio_pin_clear(NRF_PWR_MGMT_SLEEP_DEBUG_PIN); + nrf_gpio_cfg_output(NRF_PWR_MGMT_SLEEP_DEBUG_PIN); + } + +#else + #define PWR_MGMT_DEBUG_PIN_CLEAR() + #define PWR_MGMT_DEBUG_PIN_SET() + #define PWR_MGMT_DEBUG_PINS_INIT() +#endif + + +#if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + #undef PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED + #define PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED + + #undef PWR_MGMT_TIMER_REQUIRED + #define PWR_MGMT_TIMER_REQUIRED + #include "app_timer.h" + + #define PWR_MGMT_CPU_USAGE_MONITOR_INIT() pwr_mgmt_cpu_usage_monitor_init() + #define PWR_MGMT_CPU_USAGE_MONITOR_UPDATE() pwr_mgmt_cpu_usage_monitor_update() + #define PWR_MGMT_CPU_USAGE_MONITOR_SUMMARY() NRF_LOG_INFO("Maximum CPU usage: %u%%\r\n", \ + m_max_cpu_usage) + #define PWR_MGMT_CPU_USAGE_MONITOR_SECTION_ENTER() \ + { \ + uint32_t sleep_start = app_timer_cnt_get() + + #define PWR_MGMT_CPU_USAGE_MONITOR_SECTION_EXIT() \ + uint32_t sleep_end = app_timer_cnt_get(); \ + uint32_t sleep_duration; \ + sleep_duration = app_timer_cnt_diff_compute(sleep_end, \ + sleep_start); \ + m_ticks_sleeping += sleep_duration; \ + } + + static uint32_t m_ticks_sleeping; /**< Number of ticks spent in sleep mode (__WFE()). */ + static uint32_t m_ticks_last; /**< Number of ticks from the last CPU usage computation. */ + static uint8_t m_max_cpu_usage; /**< Maximum observed CPU usage (0 - 100%). */ + + __STATIC_INLINE void pwr_mgmt_cpu_usage_monitor_init(void) + { + m_ticks_sleeping = 0; + m_ticks_last = 0; + m_max_cpu_usage = 0; + } + + __STATIC_INLINE void pwr_mgmt_cpu_usage_monitor_update(void) + { + uint32_t delta; + uint32_t ticks; + uint8_t cpu_usage; + + ticks = app_timer_cnt_get(); + delta = app_timer_cnt_diff_compute(ticks, m_ticks_last); + cpu_usage = 100 * (delta - m_ticks_sleeping) / delta; + + NRF_LOG_DEBUG("CPU Usage: %d%%\r\n", cpu_usage); + if (m_max_cpu_usage < cpu_usage) + { + m_max_cpu_usage = cpu_usage; + } + + m_ticks_last = ticks; + m_ticks_sleeping = 0; + } + +#else + #define PWR_MGMT_CPU_USAGE_MONITOR_INIT() + #define PWR_MGMT_CPU_USAGE_MONITOR_UPDATE() + #define PWR_MGMT_CPU_USAGE_MONITOR_SUMMARY() + #define PWR_MGMT_CPU_USAGE_MONITOR_SECTION_ENTER() + #define PWR_MGMT_CPU_USAGE_MONITOR_SECTION_EXIT() +#endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + + +#if NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED + #undef PWR_MGMT_TIMER_REQUIRED + #define PWR_MGMT_TIMER_REQUIRED + + #define PWR_MGMT_STANDBY_TIMEOUT_INIT() pwr_mgmt_standby_timeout_clear() + #define PWR_MGMT_STANDBY_TIMEOUT_CLEAR() pwr_mgmt_standby_timeout_clear() + #define PWR_MGMT_STANDBY_TIMEOUT_CHECK() pwr_mgmt_standby_timeout_check() + + static uint16_t m_standby_counter; /**< Number of seconds from the last activity + (@ref pwr_mgmt_feed). */ + + __STATIC_INLINE void pwr_mgmt_standby_timeout_clear(void) + { + m_standby_counter = 0; + } + + __STATIC_INLINE void pwr_mgmt_standby_timeout_check(void) + { + if (m_standby_counter < NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S) + { + m_standby_counter++; + } + else if (m_shutdown_started == false) + { + nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF); + } + } + +#else + #define PWR_MGMT_STANDBY_TIMEOUT_INIT() + #define PWR_MGMT_STANDBY_TIMEOUT_CLEAR() + #define PWR_MGMT_STANDBY_TIMEOUT_CHECK() +#endif // NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED + + +#if NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY + #undef PWR_MGMT_TIMER_REQUIRED + #define PWR_MGMT_TIMER_REQUIRED + + #define PWR_MGMT_AUTO_SHUTDOWN_RETRY() pwr_mgmt_auto_shutdown_retry() + + __STATIC_INLINE void pwr_mgmt_auto_shutdown_retry(void) + { + if (m_shutdown_started) + { + // Try to continue the shutdown procedure. + nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_CONTINUE); + } + } + +#else + #define PWR_MGMT_AUTO_SHUTDOWN_RETRY() +#endif // NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY + + +#ifdef PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED + #define PWR_MGMT_SLEEP_INIT() pwr_mgmt_sleep_init() + #define PWR_MGMT_SLEEP_LOCK() CRITICAL_REGION_ENTER() + #define PWR_MGMT_SLEEP_RELEASE() CRITICAL_REGION_EXIT() + + __STATIC_INLINE void pwr_mgmt_sleep_init(void) + { + #ifdef SOFTDEVICE_PRESENT + ASSERT(current_int_priority_get() >= APP_IRQ_PRIORITY_LOW); + #endif + SCB->SCR |= SCB_SCR_SEVONPEND_Msk; + } + +#else + #define PWR_MGMT_SLEEP_INIT() + #define PWR_MGMT_SLEEP_LOCK() + #define PWR_MGMT_SLEEP_RELEASE() +#endif // PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED + + +#ifdef PWR_MGMT_TIMER_REQUIRED + #include "app_timer.h" + #define PWR_MGMT_TIMER_CREATE() pwr_mgmt_timer_create() + + APP_TIMER_DEF(m_pwr_mgmt_timer); /**< Timer used by this module. */ + + /**@brief Handle events from m_pwr_mgmt_timer. + */ + static void nrf_pwr_mgmt_timeout_handler(void * p_context) + { + PWR_MGMT_CPU_USAGE_MONITOR_UPDATE(); + PWR_MGMT_AUTO_SHUTDOWN_RETRY(); + PWR_MGMT_STANDBY_TIMEOUT_CHECK(); + } + + __STATIC_INLINE ret_code_t pwr_mgmt_timer_create(void) + { + ret_code_t ret_code = app_timer_create(&m_pwr_mgmt_timer, + APP_TIMER_MODE_REPEATED, + nrf_pwr_mgmt_timeout_handler); + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + return app_timer_start(m_pwr_mgmt_timer, APP_TIMER_TICKS(1000), NULL); + } +#else + #define PWR_MGMT_TIMER_CREATE() NRF_SUCCESS +#endif // PWR_MGMT_TIMER_REQUIRED + +ret_code_t nrf_pwr_mgmt_init(void) +{ + NRF_LOG_INFO("Init\r\n"); + + m_shutdown_started = false; + nrf_mtx_init(&m_sysoff_mtx); + nrf_section_iter_init(&m_handlers_iter, &pwr_mgmt_data); + + PWR_MGMT_SLEEP_INIT(); + PWR_MGMT_DEBUG_PINS_INIT(); + PWR_MGMT_STANDBY_TIMEOUT_INIT(); + PWR_MGMT_CPU_USAGE_MONITOR_INIT(); + + return PWR_MGMT_TIMER_CREATE(); +} + +void nrf_pwr_mgmt_run(void) +{ + PWR_MGMT_FPU_SLEEP_PREPARE(); + PWR_MGMT_SLEEP_LOCK(); + PWR_MGMT_CPU_USAGE_MONITOR_SECTION_ENTER(); + PWR_MGMT_DEBUG_PIN_SET(); + + // Wait for an event. +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + ret_code_t ret_code = sd_app_evt_wait(); + ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED)); + } + else +#endif // SOFTDEVICE_PRESENT + { + // Wait for an event. + __WFE(); + // Clear the internal event register. + __SEV(); + __WFE(); + } + + PWR_MGMT_DEBUG_PIN_CLEAR(); + PWR_MGMT_CPU_USAGE_MONITOR_SECTION_EXIT(); + PWR_MGMT_SLEEP_RELEASE(); +} + +void nrf_pwr_mgmt_feed(void) +{ + NRF_LOG_DEBUG("Feed\r\n"); + // It does not stop started shutdown process. + PWR_MGMT_STANDBY_TIMEOUT_CLEAR(); +} + +/**@brief Function runs the shutdown procedure. + */ +static void shutdown_process(void) +{ + NRF_LOG_INFO("Shutdown started. Type %d\r\n", m_pwr_mgmt_evt); + // Executing all callbacks. + for (/* m_handlers_iter is initialized in nrf_pwr_mgmt_init(). Thanks to that each handler is + called only once.*/; + nrf_section_iter_get(&m_handlers_iter) != NULL; + nrf_section_iter_next(&m_handlers_iter)) + { + nrf_pwr_mgmt_shutdown_handler_t * p_handler = + (nrf_pwr_mgmt_shutdown_handler_t *) nrf_section_iter_get(&m_handlers_iter); + if ((*p_handler)(m_pwr_mgmt_evt)) + { + NRF_LOG_INFO("SysOff handler 0x%08X => ready\r\n", (unsigned int)*p_handler); + } + else + { + // One of the modules is not ready. + NRF_LOG_INFO("SysOff handler 0x%08X => blocking\r\n", (unsigned int)*p_handler); + return; + } + } + + PWR_MGMT_CPU_USAGE_MONITOR_SUMMARY(); + NRF_LOG_WARNING("Shutdown\r\n"); + NRF_LOG_FINAL_FLUSH(); + + if ((m_pwr_mgmt_evt == NRF_PWR_MGMT_EVT_PREPARE_RESET) + || (m_pwr_mgmt_evt == NRF_PWR_MGMT_EVT_PREPARE_DFU)) + { + NVIC_SystemReset(); + } + else + { + // Enter System OFF. +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + ret_code_t ret_code = sd_power_system_off(); + ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED)); + } +#endif // SOFTDEVICE_PRESENT + nrf_power_system_off(); + } +} + +#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER +/**@brief Handle events from app_scheduler. + */ +static void scheduler_shutdown_handler(void * p_event_data, uint16_t event_size) +{ + UNUSED_PARAMETER(p_event_data); + UNUSED_PARAMETER(event_size); + shutdown_process(); +} +#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER + +void nrf_pwr_mgmt_shutdown(nrf_pwr_mgmt_shutdown_t shutdown_type) +{ + // Check if shutdown procedure is not started. + if (!nrf_mtx_trylock(&m_sysoff_mtx)) + { + return; + } + + if (shutdown_type != NRF_PWR_MGMT_SHUTDOWN_CONTINUE) + { + if (m_shutdown_started) + { + nrf_mtx_unlock(&m_sysoff_mtx); + return; + } + else + { + m_pwr_mgmt_evt = (nrf_pwr_mgmt_evt_t)shutdown_type; + m_shutdown_started = true; + } + } + + ASSERT(m_shutdown_started); + NRF_LOG_INFO("Shutdown request %d\r\n", shutdown_type); + +#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER + ret_code_t ret_code = app_sched_event_put(NULL, 0, scheduler_shutdown_handler); + APP_ERROR_CHECK(ret_code); +#else + shutdown_process(); +#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER + + nrf_mtx_unlock(&m_sysoff_mtx); +} + +#endif // NRF_MODULE_ENABLED(NRF_PWR_MGMT) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h new file mode 100644 index 0000000000000000000000000000000000000000..b214291c07b56a3a2288b2b9f4de80a041dab463 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h @@ -0,0 +1,150 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @defgroup nrf_pwr_mgmt Power management + * @ingroup app_common + * @{ + * @brief This module handles power management features. + * + */ +#ifndef NRF_PWR_MGMT_H__ +#define NRF_PWR_MGMT_H__ + +#include +#include +#include +#include "nrf_section_iter.h" + +/**@brief Power management shutdown types. */ +typedef enum +{ + NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF, + //!< Go to System OFF. + + NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF, + //!< Go to System OFF and stay there. + /**< + * Useful when battery level is dangerously low, for example. + */ + + NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU, + //!< Go to DFU mode. + + NRF_PWR_MGMT_SHUTDOWN_RESET, + //!< Reset chip. + + NRF_PWR_MGMT_SHUTDOWN_CONTINUE + //!< Continue shutdown. + /**< + * This should be used by modules that block the shutdown process, when they become ready for + * shutdown. + */ +} nrf_pwr_mgmt_shutdown_t; + +/**@brief Shutdown event types. */ +typedef enum +{ + NRF_PWR_MGMT_EVT_PREPARE_WAKEUP, + //!< Application will prepare the wakeup mechanism. + + NRF_PWR_MGMT_EVT_PREPARE_SYSOFF, + //!< Application will prepare to stay in System OFF state. + + NRF_PWR_MGMT_EVT_PREPARE_DFU, + //!< Application will prepare to enter DFU mode. + + NRF_PWR_MGMT_EVT_PREPARE_RESET, + //!< Application will prepare to chip reset. +} nrf_pwr_mgmt_evt_t; + +/**@brief Shutdown callback. + * @param[in] event Type of shutdown process. + * + * @retval true System OFF / Enter DFU preparation successful. Process will be continued. + * @retval false System OFF / Enter DFU preparation failed. @ref NRF_PWR_MGMT_SHUTDOWN_CONTINUE + * should be used to continue the shutdown process. + */ +typedef bool (*nrf_pwr_mgmt_shutdown_handler_t)(nrf_pwr_mgmt_evt_t event); + +/**@brief Macro for registering a shutdown handler. Modules that want to get events + * from this module must register the handler using this macro. + * + * @details This macro places the handler in a section named "pwr_mgmt_data". + * + * @param[in] _handler Event handler (@ref nrf_pwr_mgmt_shutdown_handler_t). + * @param[in] _priority Priority of the given handler. + */ +#define NRF_PWR_MGMT_HANDLER_REGISTER(_handler, _priority) \ + STATIC_ASSERT(_priority < NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT); \ + NRF_SECTION_SET_ITEM_REGISTER(pwr_mgmt_data, \ + _priority, \ + nrf_pwr_mgmt_shutdown_handler_t const _handler) + +/**@brief Function for initializing power management. + * + * @warning Depending on configuration, this function sets SEVONPEND in System Control Block (SCB). + * This operation is unsafe with the SoftDevice from interrupt priority higher than SVC. + * + * @retval NRF_SUCCESS + */ +ret_code_t nrf_pwr_mgmt_init(void); + +/**@brief Function for running power management. Should run in the main loop. + */ +void nrf_pwr_mgmt_run(void); + +/**@brief Function for indicating activity. + * + * @details Call this function whenever doing something that constitutes "activity". + * For example, whenever sending data, call this function to indicate that the application + * is active and should not disconnect any ongoing communication links. + */ +void nrf_pwr_mgmt_feed(void); + +/**@brief Function for shutting down the system. + * + * @param[in] shutdown_type Type of operation. + * + * @details All callbacks will be executed prior to shutdown. + */ +void nrf_pwr_mgmt_shutdown(nrf_pwr_mgmt_shutdown_t shutdown_type); + +#endif // NRF_PWR_MGMT_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/queue/nrf_queue.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/queue/nrf_queue.c new file mode 100644 index 0000000000000000000000000000000000000000..7eef2b183289221ea5087ebf9baca6ddaaa2e1a6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/queue/nrf_queue.c @@ -0,0 +1,457 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_QUEUE) +#include "nrf_queue.h" +#include "app_util_platform.h" + +/**@brief Get next element index. + * + * @param[in] p_queue Pointer to the queue instance. + * @param[in] idx Current index. + * + * @return Next element index. + */ +__STATIC_INLINE size_t nrf_queue_next_idx(nrf_queue_t const * p_queue, size_t idx) +{ + ASSERT(p_queue != NULL); + return (idx < p_queue->size) ? (idx + 1) : 0; +} + +/**@brief Get current queue utilization. This function assumes that this process will not be interrupted. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return Current queue utilization. + */ +__STATIC_INLINE size_t queue_utilization_get(nrf_queue_t const * p_queue) +{ + size_t front = p_queue->p_cb->front; + size_t back = p_queue->p_cb->back; + return (back >= front) ? (back - front) : (p_queue->size + 1 - front + back); +} + +bool nrf_queue_is_full(nrf_queue_t const * p_queue) +{ + ASSERT(p_queue != NULL); + size_t front = p_queue->p_cb->front; + size_t back = p_queue->p_cb->back; + + return (nrf_queue_next_idx(p_queue, back) == front); +} + +ret_code_t nrf_queue_push(nrf_queue_t const * p_queue, void const * p_element) +{ + ret_code_t status = NRF_SUCCESS; + + ASSERT(p_queue != NULL); + ASSERT(p_element != NULL); + + CRITICAL_REGION_ENTER(); + bool is_full = nrf_queue_is_full(p_queue); + + if (!is_full || (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW)) + { + // Get write position. + size_t write_pos = p_queue->p_cb->back; + p_queue->p_cb->back = nrf_queue_next_idx(p_queue, p_queue->p_cb->back); + if (is_full) + { + // Overwrite the oldest element. + p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->front); + } + + // Write a new element. + switch (p_queue->element_size) + { + case sizeof(uint8_t): + ((uint8_t *)p_queue->p_buffer)[write_pos] = *((uint8_t *)p_element); + break; + + case sizeof(uint16_t): + ((uint16_t *)p_queue->p_buffer)[write_pos] = *((uint16_t *)p_element); + break; + + case sizeof(uint32_t): + ((uint32_t *)p_queue->p_buffer)[write_pos] = *((uint32_t *)p_element); + break; + + case sizeof(uint64_t): + ((uint64_t *)p_queue->p_buffer)[write_pos] = *((uint64_t *)p_element); + break; + + default: + memcpy((void *)((size_t)p_queue->p_buffer + write_pos * p_queue->element_size), + p_element, + p_queue->element_size); + break; + } + + // Update utilization. + size_t utilization = queue_utilization_get(p_queue); + if (p_queue->p_cb->max_utilization < utilization) + { + p_queue->p_cb->max_utilization = utilization; + } + } + else + { + status = NRF_ERROR_NO_MEM; + } + + CRITICAL_REGION_EXIT(); + + return status; +} + +ret_code_t nrf_queue_generic_pop(nrf_queue_t const * p_queue, + void * p_element, + bool just_peek) +{ + ret_code_t status = NRF_SUCCESS; + + ASSERT(p_queue != NULL); + ASSERT(p_element != NULL); + + CRITICAL_REGION_ENTER(); + + if (!nrf_queue_is_empty(p_queue)) + { + // Get read position. + size_t read_pos = p_queue->p_cb->front; + + // Update next read position. + if (!just_peek) + { + p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->front); + } + + // Read element. + switch (p_queue->element_size) + { + case sizeof(uint8_t): + *((uint8_t *)p_element) = ((uint8_t *)p_queue->p_buffer)[read_pos]; + break; + + case sizeof(uint16_t): + *((uint16_t *)p_element) = ((uint16_t *)p_queue->p_buffer)[read_pos]; + break; + + case sizeof(uint32_t): + *((uint32_t *)p_element) = ((uint32_t *)p_queue->p_buffer)[read_pos]; + break; + + case sizeof(uint64_t): + *((uint64_t *)p_element) = ((uint64_t *)p_queue->p_buffer)[read_pos]; + break; + + default: + memcpy(p_element, + (void const *)((size_t)p_queue->p_buffer + read_pos * p_queue->element_size), + p_queue->element_size); + break; + } + } + else + { + status = NRF_ERROR_NOT_FOUND; + } + + CRITICAL_REGION_EXIT(); + + return status; +} + +/**@brief Write elements to the queue. This function assumes that there is enough room in the queue + * to write the requested number of elements and that this process will not be interrupted. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[in] p_data Pointer to the buffer with elements to write. + * @param[in] element_count Number of elements to write. + */ +static void queue_write(nrf_queue_t const * p_queue, void const * p_data, uint32_t element_count) +{ + size_t prev_available = nrf_queue_available_get(p_queue); + size_t continuous = p_queue->size + 1 - p_queue->p_cb->back; + void * p_write_ptr = (void *)((size_t)p_queue->p_buffer + + p_queue->p_cb->back * p_queue->element_size); + if (element_count <= continuous) + { + memcpy(p_write_ptr, + p_data, + element_count * p_queue->element_size); + + p_queue->p_cb->back = ((p_queue->p_cb->back + element_count) <= p_queue->size) + ? (p_queue->p_cb->back + element_count) + : 0; + } + else + { + size_t first_write_length = continuous * p_queue->element_size; + memcpy(p_write_ptr, + p_data, + first_write_length); + + size_t elements_left = element_count - continuous; + memcpy(p_queue->p_buffer, + (void const *)((size_t)p_data + first_write_length), + elements_left * p_queue->element_size); + + p_queue->p_cb->back = elements_left; + if (prev_available < element_count) + { + // Overwrite the oldest elements. + p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->back); + } + } + + // Update utilization. + size_t utilization = queue_utilization_get(p_queue); + if (p_queue->p_cb->max_utilization < utilization) + { + p_queue->p_cb->max_utilization = utilization; + } +} + +ret_code_t nrf_queue_write(nrf_queue_t const * p_queue, + void const * p_data, + size_t element_count) +{ + ret_code_t status = NRF_SUCCESS; + + ASSERT(p_queue != NULL); + ASSERT(p_data != NULL); + ASSERT(element_count <= p_queue->size); + + if (element_count == 0) + { + return NRF_SUCCESS; + } + + CRITICAL_REGION_ENTER(); + + if ((nrf_queue_available_get(p_queue) >= element_count) + || (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW)) + { + queue_write(p_queue, p_data, element_count); + } + else + { + status = NRF_ERROR_NO_MEM; + } + + CRITICAL_REGION_EXIT(); + + return status; +} + + +size_t nrf_queue_in(nrf_queue_t const * p_queue, + void const * p_data, + size_t element_count) +{ + ASSERT(p_queue != NULL); + ASSERT(p_data != NULL); + + if (element_count == 0) + { + return 0; + } + + CRITICAL_REGION_ENTER(); + + if (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW) + { + element_count = MIN(element_count, p_queue->size); + } + else + { + size_t available = nrf_queue_available_get(p_queue); + element_count = MIN(element_count, available); + } + + queue_write(p_queue, p_data, element_count); + + CRITICAL_REGION_EXIT(); + + return element_count; +} + +/**@brief Read elements from the queue. This function assumes that there are enough elements + * in the queue to read and that this process will not be interrupted. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[out] p_data Pointer to the buffer where elements will be copied. + * @param[in] element_count Number of elements to read. + */ +static void queue_read(nrf_queue_t const * p_queue, void * p_data, uint32_t element_count) +{ + size_t front = p_queue->p_cb->front; + size_t back = p_queue->p_cb->back; + size_t continuous = (front <= back) ? (back - front) : (p_queue->size + 1 - front); + void const * p_read_ptr = (void const *)((size_t)p_queue->p_buffer + + front * p_queue->element_size); + + if (element_count <= continuous) + { + memcpy(p_data, + p_read_ptr, + element_count * p_queue->element_size); + + p_queue->p_cb->front = ((front + element_count) <= p_queue->size) + ? (front + element_count) + : 0; + } + else + { + size_t first_read_length = continuous * p_queue->element_size; + memcpy(p_data, + p_read_ptr, + first_read_length); + + size_t elements_left = element_count - continuous; + memcpy((void *)((size_t)p_data + first_read_length), + p_queue->p_buffer, + elements_left * p_queue->element_size); + + p_queue->p_cb->front = elements_left; + } +} + +ret_code_t nrf_queue_read(nrf_queue_t const * p_queue, + void * p_data, + size_t element_count) +{ + ret_code_t status = NRF_SUCCESS; + + ASSERT(p_queue != NULL); + ASSERT(p_data != NULL); + + if (element_count == 0) + { + return NRF_SUCCESS; + } + + CRITICAL_REGION_ENTER(); + + if (element_count <= queue_utilization_get(p_queue)) + { + queue_read(p_queue, p_data, element_count); + } + else + { + status = NRF_ERROR_NOT_FOUND; + } + + CRITICAL_REGION_EXIT(); + + return status; +} + +size_t nrf_queue_out(nrf_queue_t const * p_queue, + void * p_data, + size_t element_count) +{ + ASSERT(p_queue != NULL); + ASSERT(p_data != NULL); + + if (element_count == 0) + { + return 0; + } + + CRITICAL_REGION_ENTER(); + + size_t utilization = queue_utilization_get(p_queue); + element_count = MIN(element_count, utilization); + + queue_read(p_queue, p_data, element_count); + + CRITICAL_REGION_EXIT(); + + return element_count; +} + +void nrf_queue_reset(nrf_queue_t const * p_queue) +{ + ASSERT(p_queue != NULL); + + CRITICAL_REGION_ENTER(); + + memset(p_queue->p_cb, 0, sizeof(nrf_queue_cb_t)); + + CRITICAL_REGION_EXIT(); +} + +size_t nrf_queue_utilization_get(nrf_queue_t const * p_queue) +{ + size_t utilization; + ASSERT(p_queue != NULL); + + CRITICAL_REGION_ENTER(); + + utilization = queue_utilization_get(p_queue); + + CRITICAL_REGION_EXIT(); + + return utilization; +} + +bool nrf_queue_is_empty(nrf_queue_t const * p_queue) +{ + ASSERT(p_queue != NULL); + size_t front = p_queue->p_cb->front; + size_t back = p_queue->p_cb->back; + return (front == back); +} + +size_t nrf_queue_available_get(nrf_queue_t const * p_queue) +{ + ASSERT(p_queue != NULL); + return p_queue->size - nrf_queue_utilization_get(p_queue); +} + +size_t nrf_queue_max_utilization_get(nrf_queue_t const * p_queue) +{ + ASSERT(p_queue != NULL); + return p_queue->p_cb->max_utilization; +} + +#endif // NRF_MODULE_ENABLED(NRF_QUEUE) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/queue/nrf_queue.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/queue/nrf_queue.h new file mode 100644 index 0000000000000000000000000000000000000000..e2e48d88b940d7260759000aeb59fca29ab26b7a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/queue/nrf_queue.h @@ -0,0 +1,399 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** +* @defgroup nrf_queue Queue module +* @{ +* @ingroup app_common +* @brief Functions that handle the queue instances. +*/ + +#ifndef NRF_QUEUE_H__ +#define NRF_QUEUE_H__ + +#include +#include +#include +#include "nrf_assert.h" +#include "sdk_errors.h" +#include "app_util.h" +#include "app_util_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Queue control block. */ +typedef struct +{ + volatile size_t front; //!< Queue front index. + volatile size_t back; //!< Queue back index. + size_t max_utilization; //!< Maximum utilization of the queue. +} nrf_queue_cb_t; + +/**@brief Supported queue modes. */ +typedef enum +{ + NRF_QUEUE_MODE_OVERFLOW, //!< If the queue is full, new element will overwrite the oldest. + NRF_QUEUE_MODE_NO_OVERFLOW, //!< If the queue is full, new element will not be accepted. +} nrf_queue_mode_t; + +/**@brief Instance of the queue. */ +typedef struct +{ + nrf_queue_cb_t * p_cb; //!< Pointer to the instance control block. + void * p_buffer; //!< Pointer to the memory that is used as storage. + size_t size; //!< Size of the queue. + size_t element_size; //!< Size of one element. + nrf_queue_mode_t mode; //!< Mode of the queue. +} nrf_queue_t; + +/**@brief Create a queue instance. + * + * @note This macro reserves memory for the given queue instance. + * + * @param[in] _type Type which is stored. + * @param[in] _name Name of the queue. + * @param[in] _size Size of the queue. + * @param[in] _mode Mode of the queue. + */ +#define NRF_QUEUE_DEF(_type, _name, _size, _mode) \ + static _type _name##_nrf_queue_buffer[(_size) + 1]; \ + static nrf_queue_cb_t _name##_nrf_queue_cb; \ + static const nrf_queue_t _name = \ + { \ + .p_cb = &_name##_nrf_queue_cb, \ + .p_buffer = _name##_nrf_queue_buffer, \ + .size = (_size), \ + .element_size = sizeof(_type), \ + .mode = _mode, \ + } + +/**@brief Declare a queue interface. + * + * @param[in] _type Type which is stored. + * @param[in] _name Name of the queue. + */ +#define NRF_QUEUE_INTERFACE_DEC(_type, _name) \ + ret_code_t _name##_push(_type const * p_element); \ + ret_code_t _name##_pop(_type * p_element); \ + ret_code_t _name##_peek(_type * p_element); \ + ret_code_t _name##_write(_type const * p_data, \ + size_t element_count); \ + ret_code_t _name##_read(_type * p_data, \ + size_t element_count); \ + size_t _name##_out(_type * p_data, \ + size_t element_count); \ + size_t _name##_in(_type const * p_data, \ + size_t element_count); \ + bool _name##_is_full(void); \ + bool _name##_is_empty(void); \ + size_t _name##_utilization_get(void); \ + size_t _name##_available_get(void); \ + size_t _name##_max_utilization_get(void); \ + void _name##_reset(void) + +/**@brief Define a queue interface. + * + * @param[in] _type Type which is stored. + * @param[in] _name Name of the queue. + * @param[in] _p_queue Queue instance. + */ +#define NRF_QUEUE_INTERFACE_DEF(_type, _name, _p_queue) \ + ret_code_t _name##_push(_type const * p_element) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + GCC_PRAGMA("GCC diagnostic pop") \ + return nrf_queue_push((_p_queue), p_element); \ + } \ + ret_code_t _name##_pop(_type * p_element) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + GCC_PRAGMA("GCC diagnostic pop") \ + return nrf_queue_pop((_p_queue), p_element); \ + } \ + ret_code_t _name##_peek(_type * p_element) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + GCC_PRAGMA("GCC diagnostic pop") \ + return nrf_queue_peek((_p_queue), p_element); \ + } \ + ret_code_t _name##_write(_type const * p_data, \ + size_t element_count) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + GCC_PRAGMA("GCC diagnostic pop") \ + return nrf_queue_write((_p_queue), p_data, element_count); \ + } \ + ret_code_t _name##_read(_type * p_data, \ + size_t element_count) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + GCC_PRAGMA("GCC diagnostic pop") \ + return nrf_queue_read((_p_queue), p_data, element_count); \ + } \ + size_t _name##_in(_type const * p_data, \ + size_t element_count) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + GCC_PRAGMA("GCC diagnostic pop") \ + return nrf_queue_in((_p_queue), p_data, element_count); \ + } \ + size_t _name##_out(_type * p_data, \ + size_t element_count) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + GCC_PRAGMA("GCC diagnostic pop") \ + return nrf_queue_out((_p_queue), p_data, element_count); \ + } \ + bool _name##_is_full(void) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + return nrf_queue_is_full(_p_queue); \ + GCC_PRAGMA("GCC diagnostic pop") \ + } \ + bool _name##_is_empty(void) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + GCC_PRAGMA("GCC diagnostic pop") \ + return nrf_queue_is_empty(_p_queue); \ + } \ + size_t _name##_utilization_get(void) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + GCC_PRAGMA("GCC diagnostic pop") \ + return nrf_queue_utilization_get(_p_queue); \ + } \ + size_t _name##_available_get(void) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + GCC_PRAGMA("GCC diagnostic pop") \ + return nrf_queue_available_get(_p_queue); \ + } \ + size_t _name##_max_utilization_get(void) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + GCC_PRAGMA("GCC diagnostic pop") \ + return nrf_queue_max_utilization_get(_p_queue); \ + } \ + void _name##_reset(void) \ + { \ + GCC_PRAGMA("GCC diagnostic push") \ + GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \ + ASSERT((_p_queue) != NULL); \ + GCC_PRAGMA("GCC diagnostic pop") \ + nrf_queue_reset(_p_queue); \ + } + +/**@brief Function for pushing an element to the end of queue. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[in] p_element Pointer to the element that will be stored in the queue. + * + * @return NRF_SUCCESS If an element has been successfully added. + * @return NRF_ERROR_NO_MEM If the queue is full (only in @ref NRF_QUEUE_MODE_NO_OVERFLOW). + */ +ret_code_t nrf_queue_push(nrf_queue_t const * p_queue, void const * p_element); + +/**@brief Generic pop implementation. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[out] p_element Pointer where the element will be copied. + * @param[out] just_peek If true, the returned element will not be removed from queue. + * + * @return NRF_SUCCESS If an element was returned. + * @return NRF_ERROR_NOT_FOUND If there are no more elements in the queue. + */ +ret_code_t nrf_queue_generic_pop(nrf_queue_t const * p_queue, + void * p_element, + bool just_peek); + +/**@brief Pop element from the front of the queue. + * + * @param[in] _p_queue Pointer to the nrf_queue_t instance. + * @param[out] _p_element Pointer where the element will be copied. + * + * @return NRF_SUCCESS If an element was returned. + * @return NRF_ERROR_NOT_FOUND If there are no more elements in the queue. + */ +#define nrf_queue_pop(_p_queue, _p_element) nrf_queue_generic_pop((_p_queue), (_p_element), false) + +/**@brief Peek element from the front of the queue. + * + * @param[in] _p_queue Pointer to the nrf_queue_t instance. + * @param[out] _p_element Pointer where the element will be copied. + * + * @return NRF_SUCCESS If an element was returned. + * @return NRF_ERROR_NOT_FOUND If there are no more elements in the queue. + */ +#define nrf_queue_peek(_p_queue, _p_element) nrf_queue_generic_pop((_p_queue), (_p_element), true) + +/**@brief Function for writing elements to the queue. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[in] p_data Pointer to the buffer with elements to write. + * @param[in] element_count Number of elements to write. + * + * @return NRF_SUCCESS If an element was written. + * @return NRF_ERROR_NO_MEM There is not enough space in the queue. No element was written. + */ +ret_code_t nrf_queue_write(nrf_queue_t const * p_queue, + void const * p_data, + size_t element_count); + +/**@brief Function for writing a portion of elements to the queue. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[in] p_data Pointer to the buffer with elements to write. + * @param[in] element_count Number of elements to write. + * + * @return The number of added elements. + */ +size_t nrf_queue_in(nrf_queue_t const * p_queue, + void const * p_data, + size_t element_count); + +/**@brief Function for reading elements from the queue. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[out] p_data Pointer to the buffer where elements will be copied. + * @param[in] element_count Number of elements to read. + * + * @return NRF_SUCCESS If an element was returned. + * @return NRF_ERROR_NOT_FOUND There is not enough elements in the queue. + */ +ret_code_t nrf_queue_read(nrf_queue_t const * p_queue, + void * p_data, + size_t element_count); + +/**@brief Function for reading a portion of elements from the queue. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[out] p_data Pointer to the buffer where elements will be copied. + * @param[in] element_count Number of elements to read. + * + * @return The number of read elements. + */ +size_t nrf_queue_out(nrf_queue_t const * p_queue, + void * p_data, + size_t element_count); + +/**@brief Function for checking if the queue is full. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return True if the queue is full. + */ +bool nrf_queue_is_full(nrf_queue_t const * p_queue); + +/**@brief Function for checking if the queue is empty. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return True if the queue is empty. + */ +bool nrf_queue_is_empty(nrf_queue_t const * p_queue); + +/**@brief Function for getting the current queue utilization. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return Current queue utilization. + */ +size_t nrf_queue_utilization_get(nrf_queue_t const * p_queue); + +/**@brief Function for getting the size of available space. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return Size of available space. + */ +size_t nrf_queue_available_get(nrf_queue_t const * p_queue); + +/**@brief Function for getting the maximal queue utilization. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return Maximal queue utilization. + */ +size_t nrf_queue_max_utilization_get(nrf_queue_t const * p_queue); + +/**@brief Function for resetting the queue state. + * + * @param[in] p_queue Pointer to the queue instance. + */ +void nrf_queue_reset(nrf_queue_t const * p_queue); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_QUEUE_H__ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/scheduler/app_scheduler.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/scheduler/app_scheduler.c new file mode 100644 index 0000000000000000000000000000000000000000..249818fd67fe10520741bcc7f4070e4138e28807 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/scheduler/app_scheduler.c @@ -0,0 +1,288 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_SCHEDULER) +#include "app_scheduler.h" +#include +#include +#include +#include "nrf_soc.h" +#include "nrf_assert.h" +#include "app_util_platform.h" + +/**@brief Structure for holding a scheduled event header. */ +typedef struct +{ + app_sched_event_handler_t handler; /**< Pointer to event handler to receive the event. */ + uint16_t event_data_size; /**< Size of event data. */ +} event_header_t; + +STATIC_ASSERT(sizeof(event_header_t) <= APP_SCHED_EVENT_HEADER_SIZE); + +static event_header_t * m_queue_event_headers; /**< Array for holding the queue event headers. */ +static uint8_t * m_queue_event_data; /**< Array for holding the queue event data. */ +static volatile uint8_t m_queue_start_index; /**< Index of queue entry at the start of the queue. */ +static volatile uint8_t m_queue_end_index; /**< Index of queue entry at the end of the queue. */ +static uint16_t m_queue_event_size; /**< Maximum event size in queue. */ +static uint16_t m_queue_size; /**< Number of queue entries. */ + +#if APP_SCHEDULER_WITH_PROFILER +static uint16_t m_max_queue_utilization; /**< Maximum observed queue utilization. */ +#endif + +#if APP_SCHEDULER_WITH_PAUSE +static uint32_t m_scheduler_paused_counter = 0; /**< Counter storing the difference between pausing + and resuming the scheduler. */ +#endif + +/**@brief Function for incrementing a queue index, and handle wrap-around. + * + * @param[in] index Old index. + * + * @return New (incremented) index. + */ +static __INLINE uint8_t next_index(uint8_t index) +{ + return (index < m_queue_size) ? (index + 1) : 0; +} + + +static __INLINE uint8_t app_sched_queue_full() +{ + uint8_t tmp = m_queue_start_index; + return next_index(m_queue_end_index) == tmp; +} + +/**@brief Macro for checking if a queue is full. */ +#define APP_SCHED_QUEUE_FULL() app_sched_queue_full() + + +static __INLINE uint8_t app_sched_queue_empty() +{ + uint8_t tmp = m_queue_start_index; + return m_queue_end_index == tmp; +} + +/**@brief Macro for checking if a queue is empty. */ +#define APP_SCHED_QUEUE_EMPTY() app_sched_queue_empty() + + +uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event_buffer) +{ + uint16_t data_start_index = (queue_size + 1) * sizeof(event_header_t); + + // Check that buffer is correctly aligned + if (!is_word_aligned(p_event_buffer)) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Initialize event scheduler + m_queue_event_headers = p_event_buffer; + m_queue_event_data = &((uint8_t *)p_event_buffer)[data_start_index]; + m_queue_end_index = 0; + m_queue_start_index = 0; + m_queue_event_size = event_size; + m_queue_size = queue_size; + +#if APP_SCHEDULER_WITH_PROFILER + m_max_queue_utilization = 0; +#endif + + return NRF_SUCCESS; +} + + +uint16_t app_sched_queue_space_get() +{ + uint16_t start = m_queue_start_index; + uint16_t end = m_queue_end_index; + uint16_t free_space = m_queue_size - ((end >= start) ? + (end - start) : (m_queue_size + 1 - start + end)); + return free_space; +} + + +#if APP_SCHEDULER_WITH_PROFILER +static void queue_utilization_check(void) +{ + uint16_t start = m_queue_start_index; + uint16_t end = m_queue_end_index; + uint16_t queue_utilization = (end >= start) ? (end - start) : + (m_queue_size + 1 - start + end); + + if (queue_utilization > m_max_queue_utilization) + { + m_max_queue_utilization = queue_utilization; + } +} + +uint16_t app_sched_queue_utilization_get(void) +{ + return m_max_queue_utilization; +} +#endif // APP_SCHEDULER_WITH_PROFILER + + +uint32_t app_sched_event_put(void * p_event_data, + uint16_t event_data_size, + app_sched_event_handler_t handler) +{ + uint32_t err_code; + + if (event_data_size <= m_queue_event_size) + { + uint16_t event_index = 0xFFFF; + + CRITICAL_REGION_ENTER(); + + if (!APP_SCHED_QUEUE_FULL()) + { + event_index = m_queue_end_index; + m_queue_end_index = next_index(m_queue_end_index); + + #if APP_SCHEDULER_WITH_PROFILER + // This function call must be protected with critical region because + // it modifies 'm_max_queue_utilization'. + queue_utilization_check(); + #endif + } + + CRITICAL_REGION_EXIT(); + + if (event_index != 0xFFFF) + { + // NOTE: This can be done outside the critical region since the event consumer will + // always be called from the main loop, and will thus never interrupt this code. + m_queue_event_headers[event_index].handler = handler; + if ((p_event_data != NULL) && (event_data_size > 0)) + { + memcpy(&m_queue_event_data[event_index * m_queue_event_size], + p_event_data, + event_data_size); + m_queue_event_headers[event_index].event_data_size = event_data_size; + } + else + { + m_queue_event_headers[event_index].event_data_size = 0; + } + + err_code = NRF_SUCCESS; + } + else + { + err_code = NRF_ERROR_NO_MEM; + } + } + else + { + err_code = NRF_ERROR_INVALID_LENGTH; + } + + return err_code; +} + + +#if APP_SCHEDULER_WITH_PAUSE +void app_sched_pause(void) +{ + CRITICAL_REGION_ENTER(); + + if (m_scheduler_paused_counter < UINT32_MAX) + { + m_scheduler_paused_counter++; + } + CRITICAL_REGION_EXIT(); +} + +void app_sched_resume(void) +{ + CRITICAL_REGION_ENTER(); + + if (m_scheduler_paused_counter > 0) + { + m_scheduler_paused_counter--; + } + CRITICAL_REGION_EXIT(); +} +#endif //APP_SCHEDULER_WITH_PAUSE + + +/**@brief Function for checking if scheduler is paused which means that should break processing + * events. + * + * @return Boolean value - true if scheduler is paused, false otherwise. + */ +static __INLINE bool is_app_sched_paused(void) +{ +#if APP_SCHEDULER_WITH_PAUSE + return (m_scheduler_paused_counter > 0); +#else + return false; +#endif +} + + +void app_sched_execute(void) +{ + while (!is_app_sched_paused() && !APP_SCHED_QUEUE_EMPTY()) + { + // Since this function is only called from the main loop, there is no + // need for a critical region here, however a special care must be taken + // regarding update of the queue start index (see the end of the loop). + uint16_t event_index = m_queue_start_index; + + void * p_event_data; + uint16_t event_data_size; + app_sched_event_handler_t event_handler; + + p_event_data = &m_queue_event_data[event_index * m_queue_event_size]; + event_data_size = m_queue_event_headers[event_index].event_data_size; + event_handler = m_queue_event_headers[event_index].handler; + + event_handler(p_event_data, event_data_size); + + // Event processed, now it is safe to move the queue start index, + // so the queue entry occupied by this event can be used to store + // a next one. + m_queue_start_index = next_index(m_queue_start_index); + } +} +#endif //NRF_MODULE_ENABLED(APP_SCHEDULER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/scheduler/app_scheduler.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/scheduler/app_scheduler.h new file mode 100644 index 0000000000000000000000000000000000000000..01b7c518b8163f9f392f295c4edebd62b818dabd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/scheduler/app_scheduler.h @@ -0,0 +1,211 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup app_scheduler Scheduler + * @{ + * @ingroup app_common + * + * @brief The scheduler is used for transferring execution from the interrupt context to the main + * context. + * + * @details See @ref seq_diagrams_sched for sequence diagrams illustrating the flow of events + * when using the Scheduler. + * + * @section app_scheduler_req Requirements: + * + * @subsection main_context_logic Logic in main context: + * + * - Define an event handler for each type of event expected. + * - Initialize the scheduler by calling the APP_SCHED_INIT() macro before entering the + * application main loop. + * - Call app_sched_execute() from the main loop each time the application wakes up because of an + * event (typically when sd_app_evt_wait() returns). + * + * @subsection int_context_logic Logic in interrupt context: + * + * - In the interrupt handler, call app_sched_event_put() + * with the appropriate data and event handler. This will insert an event into the + * scheduler's queue. The app_sched_execute() function will pull this event and call its + * handler in the main context. + * + * @if (PERIPHERAL) + * For an example usage of the scheduler, see the implementations of + * @ref ble_sdk_app_hids_mouse and @ref ble_sdk_app_hids_keyboard. + * @endif + * + * @image html scheduler_working.svg The high level design of the scheduler + */ + +#ifndef APP_SCHEDULER_H__ +#define APP_SCHEDULER_H__ + +#include "sdk_config.h" +#include +#include "app_error.h" +#include "app_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define APP_SCHED_EVENT_HEADER_SIZE 8 /**< Size of app_scheduler.event_header_t (only for use inside APP_SCHED_BUF_SIZE()). */ + +/**@brief Compute number of bytes required to hold the scheduler buffer. + * + * @param[in] EVENT_SIZE Maximum size of events to be passed through the scheduler. + * @param[in] QUEUE_SIZE Number of entries in scheduler queue (i.e. the maximum number of events + * that can be scheduled for execution). + * + * @return Required scheduler buffer size (in bytes). + */ +#define APP_SCHED_BUF_SIZE(EVENT_SIZE, QUEUE_SIZE) \ + (((EVENT_SIZE) + APP_SCHED_EVENT_HEADER_SIZE) * ((QUEUE_SIZE) + 1)) + +/**@brief Scheduler event handler type. */ +typedef void (*app_sched_event_handler_t)(void * p_event_data, uint16_t event_size); + +/**@brief Macro for initializing the event scheduler. + * + * @details It will also handle dimensioning and allocation of the memory buffer required by the + * scheduler, making sure the buffer is correctly aligned. + * + * @param[in] EVENT_SIZE Maximum size of events to be passed through the scheduler. + * @param[in] QUEUE_SIZE Number of entries in scheduler queue (i.e. the maximum number of events + * that can be scheduled for execution). + * + * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it + * several times as long as it is from the same location, e.g. to do a reinitialization). + */ +#define APP_SCHED_INIT(EVENT_SIZE, QUEUE_SIZE) \ + do \ + { \ + static uint32_t APP_SCHED_BUF[CEIL_DIV(APP_SCHED_BUF_SIZE((EVENT_SIZE), (QUEUE_SIZE)), \ + sizeof(uint32_t))]; \ + uint32_t ERR_CODE = app_sched_init((EVENT_SIZE), (QUEUE_SIZE), APP_SCHED_BUF); \ + APP_ERROR_CHECK(ERR_CODE); \ + } while (0) + +/**@brief Function for initializing the Scheduler. + * + * @details It must be called before entering the main loop. + * + * @param[in] max_event_size Maximum size of events to be passed through the scheduler. + * @param[in] queue_size Number of entries in scheduler queue (i.e. the maximum number of + * events that can be scheduled for execution). + * @param[in] p_evt_buffer Pointer to memory buffer for holding the scheduler queue. It must + * be dimensioned using the APP_SCHED_BUFFER_SIZE() macro. The buffer + * must be aligned to a 4 byte boundary. + * + * @note Normally initialization should be done using the APP_SCHED_INIT() macro, as that will both + * allocate the scheduler buffer, and also align the buffer correctly. + * + * @retval NRF_SUCCESS Successful initialization. + * @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte + * boundary). + */ +uint32_t app_sched_init(uint16_t max_event_size, uint16_t queue_size, void * p_evt_buffer); + +/**@brief Function for executing all scheduled events. + * + * @details This function must be called from within the main loop. It will execute all events + * scheduled since the last time it was called. + */ +void app_sched_execute(void); + +/**@brief Function for scheduling an event. + * + * @details Puts an event into the event queue. + * + * @param[in] p_event_data Pointer to event data to be scheduled. + * @param[in] event_size Size of event data to be scheduled. + * @param[in] handler Event handler to receive the event. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +uint32_t app_sched_event_put(void * p_event_data, + uint16_t event_size, + app_sched_event_handler_t handler); + +/**@brief Function for getting the maximum observed queue utilization. + * + * Function for tuning the module and determining QUEUE_SIZE value and thus module RAM usage. + * + * @note @ref APP_SCHEDULER_WITH_PROFILER must be enabled to use this functionality. + * + * @return Maximum number of events in queue observed so far. + */ +uint16_t app_sched_queue_utilization_get(void); + +/**@brief Function for getting the current amount of free space in the queue. + * + * @details The real amount of free space may be less if entries are being added from an interrupt. + * To get the sxact value, this function should be called from the critical section. + * + * @return Amount of free space in the queue. + */ +uint16_t app_sched_queue_space_get(void); + +/**@brief A function to pause the scheduler. + * + * @details When the scheduler is paused events are not pulled from the scheduler queue for + * processing. The function can be called multiple times. To unblock the scheduler the + * function @ref app_sched_resume has to be called the same number of times. + * + * @note @ref APP_SCHEDULER_WITH_PAUSE must be enabled to use this functionality. + */ +void app_sched_pause(void); + +/**@brief A function to resume a scheduler. + * + * @details To unblock the scheduler this function has to be called the same number of times as + * @ref app_sched_pause function. + * + * @note @ref APP_SCHEDULER_WITH_PAUSE must be enabled to use this functionality. + */ +void app_sched_resume(void); + +#ifdef __cplusplus +} +#endif + +#endif // APP_SCHEDULER_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/scheduler/app_scheduler_serconn.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/scheduler/app_scheduler_serconn.c new file mode 100644 index 0000000000000000000000000000000000000000..3f66b727ec267be37f738cf30ad0514a896f097d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/scheduler/app_scheduler_serconn.c @@ -0,0 +1,298 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "app_scheduler.h" +#include +#include +#include +#include "nrf_soc.h" +#include "nrf_assert.h" +#include "app_util.h" +#include "app_util_platform.h" + +/**@brief Structure for holding a scheduled event header. */ +typedef struct +{ + app_sched_event_handler_t handler; /**< Pointer to event handler to receive the event. */ + uint16_t event_data_size; /**< Size of event data. */ +} event_header_t; + +STATIC_ASSERT(sizeof (event_header_t) <= APP_SCHED_EVENT_HEADER_SIZE); + +static event_header_t * m_queue_event_headers; /**< Array for holding the queue event headers. */ +static uint8_t * m_queue_event_data; /**< Array for holding the queue event data. */ +static volatile uint8_t m_queue_start_index; /**< Index of queue entry at the start of the queue. */ +static volatile uint8_t m_queue_end_index; /**< Index of queue entry at the end of the queue. */ +static uint16_t m_queue_event_size; /**< Maximum event size in queue. */ +static uint16_t m_queue_size; /**< Number of queue entries. */ + +#if APP_SCHEDULER_WITH_PROFILER +static uint16_t m_max_queue_utilization; /**< Maximum observed queue utilization. */ +#endif + +static uint32_t m_scheduler_paused_counter = 0; /**< Counter storing the difference between pausing + and resuming the scheduler. */ + +/**@brief Function for incrementing a queue index, and handle wrap-around. + * + * @param[in] index Old index. + * + * @return New (incremented) index. + */ +static __INLINE uint8_t next_index(uint8_t index) +{ + return (index < m_queue_size) ? (index + 1) : 0; +} + +static __INLINE uint8_t app_sched_queue_full(void) +{ + uint8_t tmp = m_queue_start_index; + return next_index(m_queue_end_index) == tmp; +} + +/**@brief Macro for checking if a queue is full. */ +#define APP_SCHED_QUEUE_FULL() app_sched_queue_full() + +static __INLINE uint8_t app_sched_queue_empty(void) +{ + uint8_t tmp = m_queue_start_index; + return m_queue_end_index == tmp; +} + +/**@brief Macro for checking if a queue is empty. */ +#define APP_SCHED_QUEUE_EMPTY() app_sched_queue_empty() + + +uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event_buffer) +{ + uint16_t data_start_index = (queue_size + 1) * sizeof (event_header_t); + + //Check that buffer is correctly aligned + if (!is_word_aligned(p_event_buffer)) + { + return NRF_ERROR_INVALID_PARAM; + } + + //Initialize event scheduler + m_queue_event_headers = p_event_buffer; + m_queue_event_data = &((uint8_t *)p_event_buffer)[data_start_index]; + m_queue_end_index = 0; + m_queue_start_index = 0; + m_queue_event_size = event_size; + m_queue_size = queue_size; + +#if APP_SCHEDULER_WITH_PROFILER + m_max_queue_utilization = 0; +#endif + + return NRF_SUCCESS; +} + + +uint16_t app_sched_queue_space_get() +{ + uint16_t start = m_queue_start_index; + uint16_t end = m_queue_end_index; + uint16_t free_space = m_queue_size - ((end >= start) ? + (end - start) : (m_queue_size + 1 - start + end)); + return free_space; +} + + +#if APP_SCHEDULER_WITH_PROFILER +static __INLINE void check_queue_utilization(void) +{ + uint16_t start = m_queue_start_index; + uint16_t end = m_queue_end_index; + uint16_t queue_utilization = (end >= start) ? (end - start) : + (m_queue_size + 1 - start + end); + + if (queue_utilization > m_max_queue_utilization) + { + m_max_queue_utilization = queue_utilization; + } +} + +uint16_t app_sched_queue_utilization_get(void) +{ + return m_max_queue_utilization; +} +#endif // APP_SCHEDULER_WITH_PROFILER + + +uint32_t app_sched_event_put(void * p_event_data, + uint16_t event_data_size, + app_sched_event_handler_t handler) +{ + uint32_t err_code; + + if (event_data_size <= m_queue_event_size) + { + uint16_t event_index = 0xFFFF; + + CRITICAL_REGION_ENTER(); + + if (!APP_SCHED_QUEUE_FULL()) + { + event_index = m_queue_end_index; + m_queue_end_index = next_index(m_queue_end_index); + } + + CRITICAL_REGION_EXIT(); + + if (event_index != 0xFFFF) + { + //NOTE: This can be done outside the critical region since the event consumer will + //always be called from the main loop, and will thus never interrupt this code. + m_queue_event_headers[event_index].handler = handler; + + if ((p_event_data != NULL) && (event_data_size > 0)) + { + memcpy(&m_queue_event_data[event_index * m_queue_event_size], + p_event_data, + event_data_size); + m_queue_event_headers[event_index].event_data_size = event_data_size; + } + else + { + m_queue_event_headers[event_index].event_data_size = 0; + } + + #if APP_SCHEDULER_WITH_PROFILER + check_queue_utilization(); + #endif + + err_code = NRF_SUCCESS; + } + else + { + err_code = NRF_ERROR_NO_MEM; + } + } + else + { + err_code = NRF_ERROR_INVALID_LENGTH; + } + + return err_code; +} + + +/**@brief Function for reading the next event from specified event queue. + * + * @param[out] pp_event_data Pointer to pointer to event data. + * @param[out] p_event_data_size Pointer to size of event data. + * @param[out] p_event_handler Pointer to event handler function pointer. + * + * @return NRF_SUCCESS if new event, NRF_ERROR_NOT_FOUND if event queue is empty. + */ +static uint32_t app_sched_event_get(void * * pp_event_data, + uint16_t * p_event_data_size, + app_sched_event_handler_t * p_event_handler) +{ + uint32_t err_code = NRF_ERROR_NOT_FOUND; + + if (!APP_SCHED_QUEUE_EMPTY()) + { + uint16_t event_index; + + //NOTE: There is no need for a critical region here, as this function will only be called + //from app_sched_execute() from inside the main loop, so it will never interrupt + //app_sched_event_put(). Also, updating of (i.e. writing to) the start index will be + //an atomic operation. + event_index = m_queue_start_index; + m_queue_start_index = next_index(m_queue_start_index); + + *pp_event_data = &m_queue_event_data[event_index * m_queue_event_size]; + *p_event_data_size = m_queue_event_headers[event_index].event_data_size; + *p_event_handler = m_queue_event_headers[event_index].handler; + + err_code = NRF_SUCCESS; + } + + return err_code; +} + + +void app_sched_pause(void) +{ + CRITICAL_REGION_ENTER(); + + if (m_scheduler_paused_counter < UINT32_MAX) + { + m_scheduler_paused_counter++; + } + CRITICAL_REGION_EXIT(); +} + + +void app_sched_resume(void) +{ + CRITICAL_REGION_ENTER(); + + if (m_scheduler_paused_counter > 0) + { + m_scheduler_paused_counter--; + } + CRITICAL_REGION_EXIT(); +} + +/**@brief Function for checking if scheduler is paused which means that should break processing + * events. + * + * @return Boolean value - true if scheduler is paused, false otherwise. + */ +static __INLINE bool is_app_sched_paused(void) +{ + return (m_scheduler_paused_counter > 0); +} + +void app_sched_execute(void) +{ + void * p_event_data; + uint16_t event_data_size; + app_sched_event_handler_t event_handler; + + //Get next event (if any), and execute handler + while ((!is_app_sched_paused()) && + (app_sched_event_get(&p_event_data, &event_data_size, &event_handler) == NRF_SUCCESS)) + { + event_handler(p_event_data, event_data_size); + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sdcard/app_sdcard.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sdcard/app_sdcard.c new file mode 100644 index 0000000000000000000000000000000000000000..9b61b7d3774a2d08c2618892440e9d87fa95abf1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sdcard/app_sdcard.c @@ -0,0 +1,1174 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_SDCARD_ENABLED + +#include "app_sdcard.h" +#include "nrf_gpio.h" +#include "nrf_drv_spi.h" +#include "app_error.h" +#include "nrf_assert.h" + +#include "nrf_pt.h" + +#define CMD_MASK 0x40 +#define ACMD_MASK 0x80 +#define CMD0 (CMD_MASK | 0) /**< SDC/MMC command 0: GO_IDLE_STATE. */ +#define CMD1 (CMD_MASK | 1) /**< SDC/MMC command 1: SEND_OP_COND (MMC). */ +#define CMD8 (CMD_MASK | 8) /**< SDC/MMC command 8: SEND_IF_COND. */ +#define CMD9 (CMD_MASK | 9) /**< SDC/MMC command 9: SEND_CSD. */ +#define CMD10 (CMD_MASK | 10) /**< SDC/MMC command 10: SEND_CID. */ +#define CMD12 (CMD_MASK | 12) /**< SDC/MMC command 12: STOP_TRANSMISSION. */ +#define CMD16 (CMD_MASK | 16) /**< SDC/MMC command 16: SET_BLOCKLEN. */ +#define CMD17 (CMD_MASK | 17) /**< SDC/MMC command 17: READ_SINGLE_BLOCK. */ +#define CMD18 (CMD_MASK | 18) /**< SDC/MMC command 18: READ_MULTIPLE_BLOCK. */ +#define CMD23 (CMD_MASK | 23) /**< SDC/MMC command 23: SET_BLOCK_COUNT (MMC). */ +#define CMD24 (CMD_MASK | 24) /**< SDC/MMC command 24: WRITE_BLOCK. */ +#define CMD25 (CMD_MASK | 25) /**< SDC/MMC command 25: WRITE_MULTIPLE_BLOCK. */ +#define CMD32 (CMD_MASK | 32) /**< SDC/MMC command 32: ERASE_ER_BLK_START. */ +#define CMD33 (CMD_MASK | 33) /**< SDC/MMC command 33: ERASE_ER_BLK_END. */ +#define CMD38 (CMD_MASK | 38) /**< SDC/MMC command 38: ERASE. */ +#define CMD55 (CMD_MASK | 55) /**< SDC/MMC command 55: APP_CMD. */ +#define CMD58 (CMD_MASK | 58) /**< SDC/MMC command 58: READ_OCR. */ +#define ACMD13 (ACMD_MASK | CMD_MASK | 13) /**< SDC application command 13: SD_STATUS. */ +#define ACMD23 (ACMD_MASK | CMD_MASK | 23) /**< SDC application command 23: SET_WR_BLK_ERASE_COUNT. */ +#define ACMD41 (ACMD_MASK | CMD_MASK | 41) /**< SDC application command 41: SEND_OP_COND. */ + +#define IS_ACMD(CMD) ((CMD) & ACMD_MASK) /**< Check if command is an application command (ACMD). */ + +#define SDC_COMMAND_LEN 6 /**< Length of a command structure sent to the card. */ +#define SDC_COMMAND_POS 0 /**< Position of a command field inside the command structure. */ +#define SDC_COMMAND_MASK 0x7F /**< Bit mask of a command field. */ +#define SDC_COMMAND_ARG_POS 1 /**< Position of a 32-bit argument inside the command structure. */ +#define SDC_COMMAND_CRC_POS 5 /**< Position of a CRC field inside the command structure. */ + +#define SDC_MAX_NCR 8 /**< Maximum number of "busy" bytes sent before command response. */ +#define SDC_R1_LEN 1 /**< Length of R1 format response. */ +#define SDC_R3_LEN 5 /**< Length of R3 format response. */ +#define SDC_R7_LEN 5 /**< Length of R7 format response. */ +#define SDC_R_MAX_LEN 5 /**< Maximum length of command response. */ + +#define SDC_FLAG_IN_IDLE_STATE 0x01 /**< R1 response flag bit mask: idle state. */ +#define SDC_FLAG_ERASE_RESET 0x02 /**< R1 response flag bit mask: erase reset. */ +#define SDC_FLAG_ILLEGAL_COMMAND 0x04 /**< R1 response flag bit mask: illegal command. */ +#define SDC_FLAG_COM_CRC_ERROR 0x08 /**< R1 response flag bit mask: CRC error. */ +#define SDC_FLAG_ERASE_SEQUENCE_ERROR 0x10 /**< R1 response flag bit mask: erase sequence error. */ +#define SDC_FLAG_ADDRESS_ERROR 0x20 /**< R1 response flag bit mask: address error. */ +#define SDC_FLAG_PARAMETER_ERROR 0x40 /**< R1 response flag bit mask: parameter error. */ + +#define SDC_HCS_FLAG_MASK (1uL << 30) /**< High capacity support bit mask. */ + +#define SDC_EMPTY_BYTE 0xFF /**< Idle state token. */ +#define SDC_BUSY_BYTE 0x00 /**< Busy byte token. */ +#define SDC_TOKEN_START_BLOCK 0xFE /**< Data block start token. */ +#define SDC_TOKEN_START_BLOCK_MULT 0xFC /**< Data block start token for multiple write operation. */ +#define SDC_TOKEN_DATA_RESP_MASK 0x1F /**< Data response token mask. */ +#define SDC_TOKEN_DATA_RESP_ACCEPTED 0x05 /**< Data response message: accepted. */ +#define SDC_TOKEN_DATA_RESP_CRC_ERR 0x0B /**< Data response message: CRC error. */ +#define SDC_TOKEN_DATA_RESP_DATA_ERR 0x0D /**< Data response message: data error. */ +#define SDC_TOKEN_STOP_TRAN 0xFD /**< Stop transmission token. */ + +#define SDC_MAX_RETRY_COUNT_INIT 2000 /**< Maximum number of retries while card is busy (identification stage). */ +#define SDC_MAX_RETRY_COUNT 20000 /**< Maximum number of retries while card is busy. */ +#define SDC_SPI_MTU 240 /**< Maximum number of bytes in one SPI transaction. */ +#define SDC_CRC_CMD0 0x95 /**< Fixed CRC for reset command. */ +#define SDC_CRC_CMD8 0x87 /**< Fixed CRC for CMD8. */ +#define SDC_CRC_DUMMY 0xFF /**< Dummy CRC value. */ + +#define SDC_CMD_BUF_LEN 16 /**< Size of a buffer for storing SDC commands. */ +#define SDC_WORK_BUF_LEN 16 /**< Size of a working buffer. */ +#define SDC_DATA_WAIT_TX_SIZE 16 /**< Number of bytes sent during data / busy wait. */ + +#define SDC_CS_ASSERT() do { nrf_gpio_pin_clear(m_cb.cs_pin); } while (0) /**< Set CS pin to active state. */ +#define SDC_CS_DEASSERT() do { nrf_gpio_pin_set(m_cb.cs_pin); } while (0) /**< Set CS pin to inactive state. */ + +#define SDC_PT &m_cb.state.pt /**< Macro for getting SDC task structure pointer (Protothread). */ +#define SDC_PT_SUB &m_cb.state.pt_sub /**< Macro for getting SDC sub-task structure pointer (Protothread). */ + +/** Break current task (Protothread). */ +#define SDC_BREAK(PT, EXIT_CODE) do { \ + *p_exit_code = (EXIT_CODE); \ + PT_EXIT(PT); \ + } while(0) + +/**< Check the value of R1 response and break current task on error. */ +#define SDC_RESP_CHECK(PT, R1) do { \ + if ((R1) & ~(SDC_FLAG_IN_IDLE_STATE | SDC_FLAG_ERASE_RESET)) \ + { \ + SDC_BREAK((PT), SDC_ERROR_COMMUNICATION); \ + } \ + } while(0) + +/**< Check the result of an SDC operation and break on failure. */ +#define SDC_RESULT_CHECK(PT, RESULT) do { \ + if ((RESULT) != SDC_SUCCESS) \ + { \ + SDC_BREAK((PT), RESULT); \ + } \ + } while(0); + + +static const nrf_drv_spi_t m_spi = NRF_DRV_SPI_INSTANCE(APP_SDCARD_SPI_INSTANCE); /**< SPI instance. */ + +/** + * @brief SDC response type. + */ +typedef enum { + SDC_RNONE = 0, + SDC_R1, + SDC_R3, + SDC_R7 +} sdc_response_t; + +/** + * @brief SDC operation state. + */ +typedef enum { + SDC_UNINITIALIZED = 0, ///< Card not initialized. + SDC_OP_RESET = 1, ///< Reset state. + SDC_OP_IDENTIFICATION = 2, ///< Identification procedure. + SDC_OP_IDLE = 3, ///< Idle state. + SDC_OP_READ = 4, ///< Data read procedure. + SDC_OP_WRITE = 5 ///< Data write procedure. +} sdc_op_t; + +/** + * @brief SDC data bus state. + */ +typedef enum { + SDC_BUS_IDLE = 0, ///< Idle state, no active transfer. + SDC_BUS_CMD = 1, ///< Command is being transfered. + SDC_BUS_ACMD = 2, ///< Application command header transfer. + SDC_BUS_DATA_WAIT = 3, ///< Data wait state. + SDC_BUS_DATA = 4 ///< Data block transfer in progress. +} sdc_bus_state_t; + +/** + * @brief Current read/write operation state structure. + */ +typedef struct { + uint8_t * buffer; ///< Local data buffer. + uint32_t address; ///< Data block address. + uint16_t block_count; ///< Total number of blocks in read/write operation. + uint16_t blocks_left; ///< Blocks left in current read/write operation. + uint16_t position; ///< Number of blocks left to read/write. +} sdc_rw_op_t; + +/** + * @brief SDC state structure. + */ +typedef struct { + sdc_rw_op_t rw_op; ///< Read/write operation state. + pt_t pt; ///< Current task (Protothread) state. + pt_t pt_sub; ///< Current sub-task (Protothread) state. + uint16_t retry_count; ///< Number of retries left. + volatile sdc_op_t op; ///< Current operation. + sdc_bus_state_t bus_state; ///< Current data bud state. + uint8_t rsp_len; ///< Expected response length. +} sdc_state_t; + +/** + * @beirf SDC control block. + */ +typedef struct { + sdc_event_handler_t handler; ///< Event handler. + app_sdc_info_t info; ///< Card information structure. + sdc_state_t state; ///< Card state structure + uint8_t cmd_buf[SDC_CMD_BUF_LEN]; ///< Command buffer. + uint8_t rsp_buf[SDC_CMD_BUF_LEN]; ///< Card response buffer. + uint8_t work_buf[SDC_WORK_BUF_LEN]; ///< Working buffer + uint8_t cs_pin; ///< Chip select pin number. +} sdc_cb_t; + +static sdc_cb_t m_cb; ///< SDC control block. + + +/** + * @brief Function for requesting the SPI transaction. + * + * The SPI bus must be initialized prior to use of this function. + * + * @param[in] p_txb Pointer to the TX buffer. + * @param[in] tx_len TX buffer length. + * @param[out] p_rxb Pointer to the RX buffer. + * @param[in] tx_len RX buffer length. + */ +__STATIC_INLINE void sdc_spi_transfer(uint8_t const * const p_txb, + uint8_t tx_len, + uint8_t * const p_rxb, + uint8_t rx_len) +{ + SDC_CS_ASSERT(); + ret_code_t err_code = nrf_drv_spi_transfer(&m_spi, p_txb, tx_len, p_rxb, rx_len); + APP_ERROR_CHECK(err_code); +} + + +/** + * @brief Function for switching the SPI clock to high speed mode. + */ +__STATIC_INLINE void sdc_spi_hispeed(void) +{ + nrf_spi_frequency_set((NRF_SPI_Type *)m_spi.p_registers, + (nrf_spi_frequency_t) APP_SDCARD_FREQ_DATA); +} + + +/** + * @brief Function for extracting the number of data block from the CSD structure. + * + * @param[in] p_csd Pointer to the card CSD structure. + * + * @return Number of data blocks or 0 if unsupported / invalid structure was provided. + */ +static uint32_t sdc_calculate_size(uint8_t const * const p_csd) +{ + // Values are calculated as stated in SD Specifications, chapter 5.3. + uint8_t csd_version = p_csd[0] >> 6; + + switch(csd_version) + { + case 0: + case 2: + { + // SD Standard Capacity or MMC. + uint32_t c_size = ((uint32_t) p_csd[8] >> 6) + (((uint32_t) p_csd[7]) << 2) + + ((uint32_t)(p_csd[6] & 0x03) << 10); + uint32_t read_bl_len = p_csd[5] & 0x0F; + uint32_t c_size_mult = ((p_csd[10] & 0x80) >> 7) + ((p_csd[9] & 0x03) << 1); + + // Block size in this implementation is set to 512, so the resulting number of bytes + // is divided by 512 (2^9) + return (c_size + 1) << (read_bl_len + c_size_mult + 2 - 9); + } + case 1: + { + // SD High Capacity. + uint32_t c_size = (uint32_t) p_csd[9] + ((uint32_t) p_csd[8] << 8) + + (((uint32_t) p_csd[7] & 0x3F) << 16); + + // According to SD 2.0 Specifications, capacity = (C_SIZE + 1) * 512KByte. + // Block size is equal to 512, so the result is divided by 512. + return (c_size + 1) * 1024uL; + } + default: + break; + } + return 0; +} + + +/** + * @brief Non-blocking function for sending a command to the card. + * + * @param[in] cmd SDC command ID. + * @param[in] arg 32-bit command argument. + * @param[in] rsp_type Expected command response format. + * + * @retval NRF_SUCCESS If command transmission was started successfully. + * @retval NRF_ERROR_BUSY If the card is not in idle state. + */ +static ret_code_t sdc_cmd(uint8_t cmd, uint32_t arg, sdc_response_t rsp_type) +{ + if (m_cb.state.bus_state != SDC_BUS_IDLE) + { + return NRF_ERROR_BUSY; + } + + uint8_t offset = 0; + + m_cb.state.bus_state = SDC_BUS_CMD; + if (IS_ACMD(cmd)) + { + // ACMD is a combination of CMD55 and the requested command, + // which will be placed next in the command buffer. + offset = SDC_COMMAND_LEN; + m_cb.state.bus_state = SDC_BUS_ACMD; + m_cb.cmd_buf[SDC_COMMAND_POS] = CMD55; + m_cb.cmd_buf[SDC_COMMAND_ARG_POS] = 0; + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 1] = 0; + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 2] = 0; + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 3] = 0; + m_cb.cmd_buf[SDC_COMMAND_CRC_POS] = SDC_CRC_DUMMY; + } + + m_cb.cmd_buf[SDC_COMMAND_POS + offset] = cmd & SDC_COMMAND_MASK; + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + offset] = (uint8_t)(arg >> 24); + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 1 + offset] = (uint8_t)(arg >> 16); + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 2 + offset] = (uint8_t)(arg >> 8); + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 3 + offset] = (uint8_t)(arg); + + // Use predefined CRC values and omit the crc calculation if not required. + uint8_t crc; + switch (cmd) + { + case CMD0: + crc = SDC_CRC_CMD0; + break; + case CMD8: + crc = SDC_CRC_CMD8; + break; + default: + crc = SDC_CRC_DUMMY; + break; + } + m_cb.cmd_buf[SDC_COMMAND_CRC_POS + offset] = crc; + + switch (rsp_type) + { + case SDC_R3: + m_cb.state.rsp_len = SDC_R3_LEN; + break; + case SDC_R7: + m_cb.state.rsp_len = SDC_R7_LEN; + break; + default: + m_cb.state.rsp_len = SDC_R1_LEN; + break; + } + + uint8_t response_len = (IS_ACMD(cmd)) ? SDC_R1_LEN : m_cb.state.rsp_len; + sdc_spi_transfer(m_cb.cmd_buf, + SDC_COMMAND_LEN, + m_cb.rsp_buf, + SDC_COMMAND_LEN + SDC_MAX_NCR + response_len); + + return NRF_SUCCESS; +} + + +/** + * @brief Data block read subroutine. + * + * @param[in] p_rx_data Pointer to the data received in last transation. + * @param[in] rx_length Received data length. + * @param[in] block_len Size of a data block to read. + * @param[out] p_exit_code Pointer to the subroutine exit code variable. Valid only if the thread has exited. + * + * @return Protothread exit code. Zero if protothread is running and non-zero if exited. + */ +static PT_THREAD(sdc_pt_sub_data_read(uint8_t * p_rx_data, + uint8_t rx_length, + uint16_t block_len, + sdc_result_t * p_exit_code)) +{ + PT_BEGIN(SDC_PT_SUB); + while (1) + { + ASSERT(block_len); + ASSERT(m_cb.state.rw_op.block_count); + + m_cb.state.rw_op.blocks_left = m_cb.state.rw_op.block_count; + + while (m_cb.state.rw_op.blocks_left) + { + m_cb.state.retry_count = 0; + m_cb.cmd_buf[0] = 0xFF; + m_cb.state.rw_op.position = 0; + m_cb.state.bus_state = SDC_BUS_DATA_WAIT; + + while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT) + { + ++m_cb.state.retry_count; + if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT) + { + SDC_BREAK(SDC_PT_SUB, SDC_ERROR_TIMEOUT); + } + + // Search for the first token. + while(rx_length && p_rx_data[0] == SDC_EMPTY_BYTE) + { + ++p_rx_data; + --rx_length; + } + + if (rx_length) + { + // A token has been found. + if (p_rx_data[0] == SDC_TOKEN_START_BLOCK) + { + // Expected data start token found. + // Copy the data bytes left in rx buffer into user buffer. + ++p_rx_data; + --rx_length; + m_cb.state.bus_state = SDC_BUS_DATA; + uint16_t copy_len = (rx_length > block_len) ? block_len : rx_length; + for (uint32_t i = 0; i < copy_len; ++i) + { + m_cb.state.rw_op.buffer[i] = p_rx_data[i]; + } + m_cb.state.rw_op.position = copy_len; + m_cb.state.rw_op.buffer += copy_len; + } + else + { + // Data error. + SDC_BREAK(SDC_PT_SUB, SDC_ERROR_DATA); + } + } + else + { + // Continue transfer until token is received. + sdc_spi_transfer(m_cb.cmd_buf, 1, m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE); + PT_YIELD(SDC_PT_SUB); + } + } + + while (m_cb.state.rw_op.position < block_len) + { + { + uint16_t chunk_size = block_len - m_cb.state.rw_op.position; + if (chunk_size > SDC_SPI_MTU) + { + chunk_size = SDC_SPI_MTU; + } + + sdc_spi_transfer(m_cb.cmd_buf, 1, + m_cb.state.rw_op.buffer, chunk_size); + m_cb.state.rw_op.buffer += chunk_size; + m_cb.state.rw_op.position += chunk_size; + } + PT_YIELD(SDC_PT_SUB); + } + + // Get the CRC. + --m_cb.state.rw_op.blocks_left; + sdc_spi_transfer(m_cb.cmd_buf, 1, + m_cb.rsp_buf, 2); + PT_YIELD(SDC_PT_SUB); + + + + // Set rx length to 0 to force "busy check" transmission before next data block. + rx_length = 0; + } + + // Send padding bytes. + m_cb.cmd_buf[0] = SDC_EMPTY_BYTE; + sdc_spi_transfer(m_cb.cmd_buf, 1, + m_cb.rsp_buf, 2); + PT_YIELD(SDC_PT_SUB); + + m_cb.state.bus_state = SDC_BUS_IDLE; + SDC_BREAK(SDC_PT_SUB, SDC_SUCCESS); + } + PT_END(SDC_PT_SUB) +} + + +/** + * @brief Card identification co-routine. + * + * @param[in] p_rx_data Pointer to the data received in last transation. + * @param[in] rx_length Received data length. + * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited. + * + * @return Protothread exit code. Zero if protothread is running and non-zero if exited. + */ +static PT_THREAD(sdc_pt_identification(uint8_t * p_rx_data, + uint8_t rx_length, + sdc_result_t * p_exit_code)) +{ + uint8_t r1 = p_rx_data[0]; + uint32_t rsp = ((uint32_t)p_rx_data[1] << 24) + | ((uint32_t)p_rx_data[2] << 16) + | ((uint32_t)p_rx_data[3] << 8) + | ((uint32_t)p_rx_data[4]); + uint32_t arg; + ret_code_t err_code; + sdc_result_t sub_exit_code; + + PT_BEGIN(SDC_PT); + while (1) + { + err_code = sdc_cmd(CMD0, 0, SDC_R1); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + err_code = sdc_cmd(CMD0, 0, SDC_R1); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + + SDC_RESP_CHECK(SDC_PT, r1); + // Send CMD8 with fixed argument - 0x01AA. + err_code = sdc_cmd(CMD8, 0x1AA, SDC_R7); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + + if (!(r1 & SDC_FLAG_ILLEGAL_COMMAND)) + { + // CMD8 was accepted - SD v2 card. + m_cb.info.type.version = SDC_TYPE_SDV2; + SDC_RESP_CHECK(SDC_PT, r1); + } + + m_cb.state.retry_count = 0; + arg = (m_cb.info.type.version == SDC_TYPE_SDV2) ? SDC_HCS_FLAG_MASK : 0; + err_code = sdc_cmd(ACMD41, arg, SDC_R3); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + + if (r1 & SDC_FLAG_ILLEGAL_COMMAND) + { + // ACMD41 was rejected - MMC card. + m_cb.info.type.version = SDC_TYPE_MMCV3; + r1 &= ~SDC_FLAG_ILLEGAL_COMMAND; + + do + { + ++m_cb.state.retry_count; + if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT_INIT) + { + SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT); + } + + err_code = sdc_cmd(CMD1, 0, SDC_R3); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + SDC_RESP_CHECK(SDC_PT, r1); + } + while (r1 & SDC_FLAG_IN_IDLE_STATE); + } + else + { + // SDv1 or SDv2 card. Send CMD58 or retry ACMD41 if not ready. + SDC_RESP_CHECK(SDC_PT, r1); + + while (r1 & SDC_FLAG_IN_IDLE_STATE) + { + ++m_cb.state.retry_count; + if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT_INIT) + { + SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT); + } + + arg = (m_cb.info.type.version == SDC_TYPE_SDV2) ? SDC_HCS_FLAG_MASK : 0; + err_code = sdc_cmd(ACMD41, arg, SDC_R3); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + SDC_RESP_CHECK(SDC_PT, r1); + } + + err_code = sdc_cmd(CMD58, 0, SDC_R3); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + SDC_RESP_CHECK(SDC_PT, r1); + + if (rsp & SDC_HCS_FLAG_MASK) + { + m_cb.info.type.sdhc = 1; + } + } + + if (m_cb.info.type.version != SDC_TYPE_SDV2) + { + // Set block length to 512 (SDv1 and MMC cards only.) + err_code = sdc_cmd(CMD16, SDC_SECTOR_SIZE, SDC_R1); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + SDC_RESP_CHECK(SDC_PT, r1); + } + + // Setup the read operation and get the contents of 128-bit CSD register. + m_cb.state.rw_op.buffer = m_cb.work_buf; + m_cb.state.rw_op.block_count = 1; + + err_code = sdc_cmd(CMD9, 0, SDC_R1); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + SDC_RESP_CHECK(SDC_PT, r1); + + p_rx_data += SDC_R1_LEN; + rx_length -= SDC_R1_LEN; + PT_SPAWN(SDC_PT, SDC_PT_SUB, sdc_pt_sub_data_read(p_rx_data, rx_length, \ + 16, &sub_exit_code)); + SDC_RESULT_CHECK(SDC_PT, sub_exit_code); + + m_cb.info.num_blocks = sdc_calculate_size(m_cb.work_buf); + m_cb.info.block_len = SDC_SECTOR_SIZE; + + SDC_BREAK(SDC_PT, SDC_SUCCESS); + } + PT_END(SDC_PT) +} + + +/** + * @brief Data read co-routine. + * + * @param[in] p_rx_data Pointer to the data received in last transaction. + * @param[in] rx_length Received data length. + * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited. + * + * @return Protothread exit code. Zero if protothread is running and non-zero if exited. + */ +static PT_THREAD(sdc_pt_read(uint8_t * p_rx_data, + uint8_t rx_length, + sdc_result_t * p_exit_code)) +{ + uint8_t r1; + ret_code_t err_code; + sdc_result_t sub_exit_code; + + PT_BEGIN(SDC_PT); + while (1) + { + r1 = p_rx_data[0]; + SDC_RESP_CHECK(SDC_PT, r1); + + p_rx_data += SDC_R1_LEN; + rx_length -= SDC_R1_LEN; + + // Run the block read subroutine. + PT_SPAWN(SDC_PT, SDC_PT_SUB, sdc_pt_sub_data_read(p_rx_data, rx_length, + SDC_SECTOR_SIZE, + &sub_exit_code)); + SDC_RESULT_CHECK(SDC_PT, sub_exit_code); + + if (m_cb.state.rw_op.block_count > 1) + { + // Send the STOP_TRANSMISSION command in multiple block read mode. + err_code = sdc_cmd(CMD12, 0, SDC_R1); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + } + + SDC_BREAK(SDC_PT, SDC_SUCCESS); + } + PT_END(SDC_PT) +} + + +/** + * @brief Data write co-routine. + * + * @param[in] p_rx_data Pointer to the data received in last transation. + * @param[in] rx_length Received data length. + * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited. + * + * @return Protothread exit code. Zero if protothread is running and non-zero if exited. + */ +static PT_THREAD(sdc_pt_write(uint8_t * rx_data, + uint8_t rx_length, + sdc_result_t * p_exit_code)) +{ + ret_code_t err_code; + PT_BEGIN(SDC_PT); + while (1) + { + uint8_t r1; + r1 = rx_data[0]; + SDC_RESP_CHECK(SDC_PT, r1); + if (m_cb.info.type.version != SDC_TYPE_MMCV3 && m_cb.state.rw_op.block_count > 1) + { + err_code = sdc_cmd(CMD25, m_cb.state.rw_op.address, SDC_R1); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + r1 = rx_data[0]; + SDC_RESP_CHECK(SDC_PT, r1); + } + + m_cb.state.rw_op.blocks_left = m_cb.state.rw_op.block_count; + while (m_cb.state.rw_op.blocks_left) + { + m_cb.state.rw_op.position = 0; + m_cb.state.bus_state = SDC_BUS_DATA; + + // Send block start token. + m_cb.cmd_buf[0] = SDC_EMPTY_BYTE; + m_cb.cmd_buf[1] = (m_cb.state.rw_op.block_count > 1) ? SDC_TOKEN_START_BLOCK_MULT + : SDC_TOKEN_START_BLOCK; + sdc_spi_transfer(m_cb.cmd_buf, 2, m_cb.rsp_buf, 2); + PT_YIELD(SDC_PT); + + // Send the data block. + while (m_cb.state.rw_op.position < SDC_SECTOR_SIZE) + { + { + uint16_t chunk_size = SDC_SECTOR_SIZE - m_cb.state.rw_op.position; + if (chunk_size > SDC_SPI_MTU) + { + chunk_size = SDC_SPI_MTU; + } + sdc_spi_transfer(&m_cb.state.rw_op.buffer[m_cb.state.rw_op.position], + chunk_size, + m_cb.rsp_buf, + 1); + m_cb.state.rw_op.position += chunk_size; + } + PT_YIELD(SDC_PT); + } + m_cb.state.rw_op.buffer += SDC_SECTOR_SIZE; + + // Send the dummy CRC (2 bytes) and receive data response token (1 byte). + m_cb.state.bus_state = SDC_BUS_DATA_WAIT; + sdc_spi_transfer(m_cb.cmd_buf, 1, + m_cb.rsp_buf, 3); + PT_YIELD(SDC_PT); + + { + uint8_t token = m_cb.rsp_buf[2] & SDC_TOKEN_DATA_RESP_MASK; + if (token != SDC_TOKEN_DATA_RESP_ACCEPTED) + { + if (token == SDC_TOKEN_DATA_RESP_CRC_ERR + || token == SDC_TOKEN_DATA_RESP_DATA_ERR) + { + SDC_BREAK(SDC_PT, SDC_ERROR_DATA); + } + else + { + SDC_BREAK(SDC_PT, SDC_ERROR_COMMUNICATION); + } + } + } + + // Wait for the card to complete the write process. + m_cb.state.retry_count = 0; + while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT) + { + ++m_cb.state.retry_count; + if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT) + { + SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT); + } + + sdc_spi_transfer(m_cb.cmd_buf, 1, + m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE); + PT_YIELD(SDC_PT); + + for (uint32_t i = 0; i < rx_length; ++i) + { + if (rx_data[i] != 0x00) + { + m_cb.state.bus_state = SDC_BUS_IDLE; + break; + } + } + } + + --m_cb.state.rw_op.blocks_left; + } + + if (m_cb.state.rw_op.block_count > 1) + { + // Send STOP_TRAN token + padding byte when writing multiple blocks. + m_cb.cmd_buf[0] = SDC_EMPTY_BYTE; + m_cb.cmd_buf[1] = SDC_TOKEN_STOP_TRAN; + sdc_spi_transfer(m_cb.cmd_buf, 2, + m_cb.rsp_buf, 3); + PT_YIELD(SDC_PT); + + m_cb.state.retry_count = 0; + m_cb.state.bus_state = SDC_BUS_DATA_WAIT; + + // Wait for the card to complete the write process. + while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT) + { + ++m_cb.state.retry_count; + if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT) + { + SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT); + } + + sdc_spi_transfer(m_cb.cmd_buf, 1, + m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE); + PT_YIELD(SDC_PT); + + for (uint32_t i = 0; i < rx_length; ++i) + { + if (rx_data[i] != 0x00) + { + m_cb.state.bus_state = SDC_BUS_IDLE; + break; + } + } + } + } + + SDC_BREAK(SDC_PT, SDC_SUCCESS); + } + PT_END(SDC_PT) +} + + +/** + * @brief SPI event handler. + * + * @param[in] p_event Pointer to the SPI event structure. + */ +static void spi_handler(nrf_drv_spi_evt_t const * p_event, + void * p_context) +{ + uint8_t * rx_data = p_event->data.done.p_rx_buffer; + uint8_t rx_length = p_event->data.done.rx_length; + + if (!m_cb.state.rw_op.blocks_left) + { + // Deassert CS pin if not in active data transfer. + SDC_CS_DEASSERT(); + } + + if (m_cb.state.bus_state == SDC_BUS_ACMD || m_cb.state.bus_state == SDC_BUS_CMD) + { + // Find the beginning of a response. + ASSERT(rx_length > SDC_COMMAND_LEN); + rx_length -= SDC_COMMAND_LEN; + rx_data += SDC_COMMAND_LEN; + + if (p_event->data.done.p_tx_buffer[0] == CMD12) + { + // Ignore the first byte if CMD12 was sent. + if (rx_length) + { + --rx_length; + ++rx_data; + } + } + + while (rx_length && rx_data[0] == SDC_EMPTY_BYTE) + { + --rx_length; + ++rx_data; + } + if (rx_length == 0) + { + if (p_event->data.done.p_tx_buffer[0] == CMD12) + { + // Ignore invalid reply on CMD12. + ++rx_length; + --rx_data; + } + else + { + rx_data = NULL; + } + } + + if (!rx_data && m_cb.state.op != SDC_OP_RESET) + { + // Command response missing. + sdc_evt_t evt; + evt.result = SDC_ERROR_NOT_RESPONDING; + switch(m_cb.state.op) + { + case SDC_OP_RESET: + case SDC_OP_IDENTIFICATION: + evt.type = SDC_EVT_INIT; + m_cb.state.op = SDC_OP_IDLE; + APP_ERROR_CHECK(app_sdc_uninit()); + break; + case SDC_OP_READ: + evt.type = SDC_EVT_READ; + break; + case SDC_OP_WRITE: + evt.type = SDC_EVT_WRITE; + break; + default: + APP_ERROR_CHECK(NRF_ERROR_INTERNAL); + break; + } + + SDC_CS_DEASSERT(); + m_cb.state.op = SDC_OP_IDLE; + m_cb.handler(&evt); + return; + } + + if (m_cb.state.bus_state == SDC_BUS_ACMD) + { + // Check the status of CMD55 and send the scheduled command if no errors has been reported. + m_cb.state.bus_state = SDC_BUS_CMD; + uint8_t r1 = rx_data[0]; + if (!(r1 & (~SDC_FLAG_IN_IDLE_STATE))) + { + sdc_spi_transfer(m_cb.cmd_buf + SDC_COMMAND_LEN, SDC_COMMAND_LEN, + m_cb.rsp_buf, SDC_COMMAND_LEN + SDC_MAX_NCR + m_cb.state.rsp_len); + return; + } + } + m_cb.state.bus_state = SDC_BUS_IDLE; + } + + sdc_result_t exit_code = SDC_ERROR_INTERNAL; + sdc_evt_t evt; + switch(m_cb.state.op) + { + case SDC_OP_RESET: + m_cb.state.op = SDC_OP_IDENTIFICATION; + PT_INIT(SDC_PT); + //lint -e{616} + case SDC_OP_IDENTIFICATION: + if (!PT_SCHEDULE(sdc_pt_identification(rx_data, rx_length, &exit_code))) + { + evt.type = SDC_EVT_INIT; + evt.result = exit_code; + m_cb.state.op = SDC_OP_IDLE; + SDC_CS_DEASSERT(); + if (exit_code != SDC_SUCCESS) + { + // Initialization process failed. Roll back to uninitialized state. + APP_ERROR_CHECK(app_sdc_uninit()); + } + sdc_spi_hispeed(); + m_cb.handler(&evt); + } + break; + case SDC_OP_READ: + if (!PT_SCHEDULE(sdc_pt_read(rx_data, rx_length, &exit_code))) + { + evt.type = SDC_EVT_READ; + evt.result = exit_code; + m_cb.state.op = SDC_OP_IDLE; + m_cb.state.rw_op.block_count = 0; + m_cb.state.rw_op.blocks_left = 0; + m_cb.state.bus_state = SDC_BUS_IDLE; + SDC_CS_DEASSERT(); + m_cb.handler(&evt); + } + break; + case SDC_OP_WRITE: + if (!PT_SCHEDULE(sdc_pt_write(rx_data, rx_length, &exit_code))) + { + evt.type = SDC_EVT_WRITE; + evt.result = exit_code; + m_cb.state.op = SDC_OP_IDLE; + m_cb.state.bus_state = SDC_BUS_IDLE; + m_cb.state.rw_op.block_count = 0; + m_cb.state.rw_op.blocks_left = 0; + SDC_CS_DEASSERT(); + m_cb.handler(&evt); + } + break; + default: + APP_ERROR_CHECK(NRF_ERROR_INTERNAL); + break; + } + + return; +} + + +ret_code_t app_sdc_block_read(uint8_t * p_buf, uint32_t block_address, uint16_t block_count) +{ + ASSERT(p_buf); + + if (m_cb.state.op == SDC_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + if (m_cb.state.op != SDC_OP_IDLE) + { + return NRF_ERROR_BUSY; + } + if (block_count == 0) + { + return NRF_ERROR_INVALID_PARAM; + } + + m_cb.state.op = SDC_OP_READ; + + if (!m_cb.info.type.sdhc) + { + m_cb.state.rw_op.address = block_address * SDC_SECTOR_SIZE; + } + else + { + m_cb.state.rw_op.address = block_address; + } + m_cb.state.rw_op.buffer = p_buf; + m_cb.state.rw_op.block_count = block_count; + m_cb.state.rw_op.blocks_left = block_count; + + PT_INIT(&m_cb.state.pt); + uint8_t command = (block_count > 1) ? CMD18 : CMD17; + ret_code_t err_code = sdc_cmd(command, m_cb.state.rw_op.address, SDC_R1); + APP_ERROR_CHECK(err_code); + + return NRF_SUCCESS; +} + + +ret_code_t app_sdc_block_write(uint8_t const * p_buf, uint32_t block_address, uint16_t block_count) +{ + ASSERT(p_buf); + + if (m_cb.state.op == SDC_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + if (m_cb.state.op != SDC_OP_IDLE) + { + return NRF_ERROR_BUSY; + } + if (block_count == 0) + { + return NRF_ERROR_INVALID_PARAM; + } + m_cb.state.op = SDC_OP_WRITE; + + if (!m_cb.info.type.sdhc) + { + m_cb.state.rw_op.address = block_address * 512uL; + } + else + { + m_cb.state.rw_op.address = block_address; + } + m_cb.state.rw_op.buffer = (uint8_t *) p_buf; + m_cb.state.rw_op.block_count = block_count; + m_cb.state.rw_op.blocks_left = block_count; + + PT_INIT(&m_cb.state.pt); + + ret_code_t err_code; + if (block_count == 1) + { + err_code = sdc_cmd(CMD24, m_cb.state.rw_op.address, SDC_R1); + + APP_ERROR_CHECK(err_code); + return NRF_SUCCESS; + } + + if (m_cb.info.type.version == SDC_TYPE_MMCV3) + { + // Start multiple block write. + err_code = sdc_cmd(CMD25, m_cb.state.rw_op.address, SDC_R1); + } + else + { + // Set pre-erase for SD cards before sending CMD25. + err_code = sdc_cmd(ACMD23, block_count, SDC_R1); + } + + APP_ERROR_CHECK(err_code); + return NRF_SUCCESS; +} + + +ret_code_t app_sdc_init(app_sdc_config_t const * const p_config, sdc_event_handler_t event_handler) +{ + if (m_cb.state.op != SDC_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + if ((!event_handler) + || (p_config->cs_pin == NRF_DRV_SPI_PIN_NOT_USED) + || (p_config->miso_pin == NRF_DRV_SPI_PIN_NOT_USED) + || (p_config->mosi_pin == NRF_DRV_SPI_PIN_NOT_USED) + || (p_config->sck_pin == NRF_DRV_SPI_PIN_NOT_USED)) + { + return NRF_ERROR_INVALID_PARAM; + } + + ret_code_t err_code; + ASSERT(p_config->cs_pin && p_config->miso_pin + && p_config->mosi_pin && p_config->sck_pin); + + // Configure chip select pin. + m_cb.cs_pin = p_config->cs_pin; + nrf_gpio_cfg_output(m_cb.cs_pin); + SDC_CS_DEASSERT(); + + const nrf_drv_spi_config_t spi_cfg = { + .sck_pin = p_config->sck_pin, + .mosi_pin = p_config->mosi_pin, + .miso_pin = p_config->miso_pin, + .ss_pin = NRF_DRV_SPI_PIN_NOT_USED, + .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY, + .orc = 0xFF, + .frequency = (nrf_drv_spi_frequency_t) APP_SDCARD_FREQ_INIT, + .mode = NRF_DRV_SPI_MODE_0, + .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST, + }; + err_code = nrf_drv_spi_init(&m_spi, &spi_cfg, spi_handler, NULL); + APP_ERROR_CHECK(err_code); + + m_cb.handler = event_handler; + m_cb.state.op = SDC_OP_RESET; + m_cb.info.type.version = SDC_TYPE_UNKNOWN; + m_cb.info.type.sdhc = 0; + m_cb.state.bus_state = SDC_BUS_IDLE; + + // Send 80 clocks with CS inactive to switch into SPI mode. + m_cb.cmd_buf[0] = 0xFF; + err_code = nrf_drv_spi_transfer(&m_spi, m_cb.cmd_buf, 1, + m_cb.rsp_buf, 10); + APP_ERROR_CHECK(err_code); + + return NRF_SUCCESS; +} + + +ret_code_t app_sdc_uninit(void) +{ + if (m_cb.state.op == SDC_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + if (m_cb.state.op != SDC_OP_IDLE) + { + return NRF_ERROR_BUSY; + } + + nrf_drv_spi_uninit(&m_spi); + nrf_gpio_cfg_input(m_cb.cs_pin, NRF_GPIO_PIN_NOPULL); + + m_cb.state.bus_state = SDC_BUS_IDLE; + m_cb.state.op = SDC_UNINITIALIZED; + + return NRF_SUCCESS; +} + + +bool app_sdc_busy_check(void) +{ + return ((m_cb.state.op != SDC_OP_IDLE) && (m_cb.state.op != SDC_UNINITIALIZED)); +} + + +app_sdc_info_t const * app_sdc_info_get(void) +{ + if (m_cb.state.op >= SDC_OP_IDLE) + { + return &m_cb.info; + } + return NULL; +} + +#endif //APP_SDCARD_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sdcard/app_sdcard.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sdcard/app_sdcard.h new file mode 100644 index 0000000000000000000000000000000000000000..ed8fbf4d13680931e129b9f2b6f1c98593bddbfc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sdcard/app_sdcard.h @@ -0,0 +1,209 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup app_sdcard SD card library + * @{ + * @ingroup app_common + * + * @brief Asynchronous Secure Digital card (SDC) and MultiMedia card (MMC) library. + */ + + +#ifndef APP_SDCARD_H_ +#define APP_SDCARD_H_ + +#include "app_util_platform.h" +#include "sdk_config.h" + +#define SDC_SECTOR_SIZE 512 ///< Size of a single SD card block in bytes. + +#define APP_SDCARD_CONFIG(MOSI_PIN, MISO_PIN, SCK_PIN, CS_PIN) { \ + .mosi_pin = MOSI_PIN, \ + .miso_pin = MISO_PIN, \ + .sck_pin = SCK_PIN, \ + .cs_pin = CS_PIN \ + } + +/** + * @brief SDC operation result. + */ +typedef enum { + SDC_SUCCESS = 0, ///< Operation successful. + SDC_ERROR_NOT_RESPONDING, ///< Card is not responding or not present. + SDC_ERROR_TIMEOUT, ///< Card response timeout. + SDC_ERROR_NOT_SUPPORTED, ///< Operation not supported. + SDC_ERROR_COMMUNICATION, ///< Communication error. + SDC_ERROR_DATA, ///< Data read/write error. + SDC_ERROR_INTERNAL, ///< Internal error. +} sdc_result_t; + +/** + * @brief SDC event type. + */ +typedef enum { + SDC_EVT_INIT = 0, ///< Initialization procedure. + SDC_EVT_READ, ///< Data read procedure. + SDC_EVT_WRITE ///< Data write procedure. +} sdc_evt_type_t; + +/** + * @brief SDC event structure. + */ +typedef struct { + sdc_evt_type_t type; ///< Event type. + sdc_result_t result; ///< Operation result. +} sdc_evt_t; + +/** + * @brief SDC type and version. + */ +typedef enum { + SDC_TYPE_UNKNOWN = 0, ///< Unknown / uninitialized card. + SDC_TYPE_MMCV3, ///< MultiMedia card (MMC) version 3. + SDC_TYPE_SDV1, ///< Secure Digital card (SDC) version 1.0. + SDC_TYPE_SDV2 ///< Secure Digital card (SDC) version 2.0. +} sdc_version_t; + +/** + * @brief SDC type information structure. + */ +typedef struct { + sdc_version_t version : 3; ///< Card type and version (SD or MMC). + uint8_t sdhc : 1; ///< Standard Capacity or High Capacity card. +} sdc_type_t; + +/** + * @brief SDC configuration structure. + */ +typedef struct { + uint8_t mosi_pin; ///< Serial data in (MOSI / DI) pin number. + uint8_t miso_pin; ///< Serial data out (MISO / DO) pin number. + uint8_t sck_pin; ///< Serial clock (SCK) pin number. + uint8_t cs_pin; ///< Chip select (CS) pin number. +} app_sdc_config_t; + +/** + * @brief SDC information structure. + */ +typedef struct { + uint32_t num_blocks; ///< Number of available data blocks. + uint16_t block_len; ///< Length (in bytes) of a single data block. + sdc_type_t type; ///< Card type information structure. +} app_sdc_info_t; + +/** + * @brief SDC event handler type. + */ +typedef void (*sdc_event_handler_t)(sdc_evt_t const * p_event); + + +/** + * @brief Function for initializing the card. + * + * @param[in] p_config Pointer to the SDC configuration structure. + * @param[in] event_handler Pointer to the event handler function. + * + * @retval NRF_SUCCESS If initialization process was started succesfully. + * @retval NRF_ERROR_INVALID_STATE If the card is already initialized or the initialization is in progress. + * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified. + */ +ret_code_t app_sdc_init(app_sdc_config_t const * const p_config, sdc_event_handler_t event_handler); + + +/** + * @brief Function for uninitializing the card. + * + * @retval NRF_SUCCESS If card was uninitialized succesfully. + * @retval NRF_ERROR_INVALID_STATE If the card is not initialized. + * @retval NRF_ERROR_BUSY If there is an operation in progress. + */ +ret_code_t app_sdc_uninit(void); + + +/** + * @brief Function for retrieving the card busy state. + * + * @retval true If there is an operation in progress. + * @retval false If the card is in idle state. + */ +bool app_sdc_busy_check(void); + + +/** + * @brief Function for reading the data blocks from the card. + * + * @param[out] p_buf Pointer to the data buffer. Must not be null. + * @param[in] block_address Number of the first block to be read. + * @param[in] block_count Number of blocks to read. Must be greater than 0. + * + * @retval NRF_SUCCESS If block read operation was started succesfully. + * @retval NRF_ERROR_INVALID_STATE If the card is not initialized. + * @retval NRF_ERROR_BUSY If there is already an operation active. + * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified. + */ +ret_code_t app_sdc_block_read(uint8_t * p_buf, uint32_t block_address, uint16_t block_count); + + +/** + * @brief Function for writing the data blocks to the card. + * + * @param[out] p_buf Pointer to the data to be written. Must not be null. + * @param[in] block_address Number of the first block to write. + * @param[in] block_count Number of blocks to write. Must be greater than 0. + * + * @retval NRF_SUCCESS If block write operation was started succesfully. + * @retval NRF_ERROR_INVALID_STATE If the card is not initialized. + * @retval NRF_ERROR_BUSY If there is already an operation active. + * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified. + */ +ret_code_t app_sdc_block_write(uint8_t const * p_buf, uint32_t block_address, uint16_t block_count); + + +/** + * @brief Function for retrieving the card information structure. + * + * @return Pointer to the card information structure or NULL if card is not initialized. + */ +app_sdc_info_t const * app_sdc_info_get(void); + + +#endif //APP_SDC_H_ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sensorsim/sensorsim.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sensorsim/sensorsim.c new file mode 100644 index 0000000000000000000000000000000000000000..be331cbe6b01669fa46acde82be29a2952b9005a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sensorsim/sensorsim.c @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sensorsim.h" + + +void sensorsim_init(sensorsim_state_t * p_state, + const sensorsim_cfg_t * p_cfg) +{ + if (p_cfg->start_at_max) + { + p_state->current_val = p_cfg->max; + p_state->is_increasing = false; + } + else + { + p_state->current_val = p_cfg->min; + p_state->is_increasing = true; + } +} + + +uint32_t sensorsim_measure(sensorsim_state_t * p_state, + const sensorsim_cfg_t * p_cfg) +{ + if (p_state->is_increasing) + { + sensorsim_increment(p_state, p_cfg); + } + else + { + sensorsim_decrement(p_state, p_cfg); + } + return p_state->current_val; +} + +void sensorsim_increment(sensorsim_state_t * p_state, + const sensorsim_cfg_t * p_cfg) +{ + if (p_cfg->max - p_state->current_val > p_cfg->incr) + { + p_state->current_val += p_cfg->incr; + } + else + { + p_state->current_val = p_cfg->max; + p_state->is_increasing = false; + } +} + + +void sensorsim_decrement(sensorsim_state_t * p_state, + const sensorsim_cfg_t * p_cfg) +{ + if (p_state->current_val - p_cfg->min > p_cfg->incr) + { + p_state->current_val -= p_cfg->incr; + } + else + { + p_state->current_val = p_cfg->min; + p_state->is_increasing = true; + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sensorsim/sensorsim.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sensorsim/sensorsim.h new file mode 100644 index 0000000000000000000000000000000000000000..3f8716017991249483617ec876e31b932bf7ae3a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sensorsim/sensorsim.h @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ble_sdk_lib_sensorsim Sensor Data Simulator + * @{ + * @ingroup ble_sdk_lib + * @brief Functions for simulating sensor data. + * + * @details Currently only a triangular waveform simulator is implemented. + */ + +#ifndef SENSORSIM_H__ +#define SENSORSIM_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Triangular waveform sensor simulator configuration. */ +typedef struct +{ + uint32_t min; /**< Minimum simulated value. */ + uint32_t max; /**< Maximum simulated value. */ + uint32_t incr; /**< Increment between each measurement. */ + bool start_at_max; /**< TRUE is measurement is to start at the maximum value, FALSE if it is to start at the minimum. */ +} sensorsim_cfg_t; + +/**@brief Triangular waveform sensor simulator state. */ +typedef struct +{ + uint32_t current_val; /**< Current sensor value. */ + bool is_increasing; /**< TRUE if the simulator is in increasing state, FALSE otherwise. */ +} sensorsim_state_t; + +/**@brief Function for initializing a triangular waveform sensor simulator. + * + * @param[out] p_state Current state of simulator. + * @param[in] p_cfg Simulator configuration. + */ +void sensorsim_init(sensorsim_state_t * p_state, + const sensorsim_cfg_t * p_cfg); + +/**@brief Function for generating a simulated sensor measurement using a triangular waveform generator. + * + * @param[in,out] p_state Current state of simulator. + * @param[in] p_cfg Simulator configuration. + * + * @return Simulator output. + */ +uint32_t sensorsim_measure(sensorsim_state_t * p_state, + const sensorsim_cfg_t * p_cfg); + +/**@brief Function for incrementing a simulated sensor measurement value. + * + * @param[in,out] p_state Current state of simulator. + * @param[in] p_cfg Simulator configuration. + * + * @return Simulator output. + */ +void sensorsim_increment(sensorsim_state_t * p_state, + const sensorsim_cfg_t * p_cfg); + +/**@brief Function for decrementing a simulated sensor measurement value. + * + * @param[in,out] p_state Current state of simulator. + * @param[in] p_cfg Simulator configuration. + * + * @return Simulator output. + */ +void sensorsim_decrement(sensorsim_state_t * p_state, + const sensorsim_cfg_t * p_cfg); + + +#ifdef __cplusplus +} +#endif + +#endif // SENSORSIM_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/serial/nrf_serial.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/serial/nrf_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..8d9f7b82acb075f233895e2d7c807f77c22f0f97 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/serial/nrf_serial.c @@ -0,0 +1,632 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_SERIAL) +#include "nrf_serial.h" +#include "nrf_drv_common.h" + +static void event_handler(nrf_serial_t const * p_serial, + nrf_serial_event_t event) +{ + if (p_serial->p_ctx->p_config->ev_handler) + { + p_serial->p_ctx->p_config->ev_handler(p_serial, event); + } +} + +static void sleep_handler(nrf_serial_t const * p_serial) +{ + if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING) + { + return; + } + + if (p_serial->p_ctx->p_config->sleep_handler) + { + p_serial->p_ctx->p_config->sleep_handler(); + } +} + +static size_t serial_rx(nrf_serial_t const * p_serial, + uint8_t * p_buff, + size_t length) +{ + if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING) + { + size_t rx_len = MIN(length, UINT8_MAX); + size_t len = rx_len; + + while (nrf_drv_uart_rx_ready(&p_serial->instance) && len) + { + ret_code_t ret = nrf_drv_uart_rx(&p_serial->instance, p_buff, 1); + if (ret != NRF_SUCCESS) + { + break; + } + p_buff++; + len--; + } + + return rx_len - len; + } + + nrf_queue_t const * p_rxq = p_serial->p_ctx->p_config->p_queues->p_rxq; + return nrf_queue_out(p_rxq, p_buff, length); +} + +static size_t serial_tx(nrf_serial_t const * p_serial, + uint8_t const * p_buff, + size_t length) +{ + size_t tx_len = 0; + + if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING) + { + tx_len = MIN(length, UINT8_MAX); + ret_code_t ret = nrf_drv_uart_tx(&p_serial->instance, p_buff, tx_len); + ASSERT(ret == NRF_SUCCESS) + return tx_len; + } + + nrf_queue_t const * p_txq = p_serial->p_ctx->p_config->p_queues->p_txq; + nrf_serial_buffers_t const * p_buffs = p_serial->p_ctx->p_config->p_buffers; + + /* Try to enqueue data. */ + size_t queue_in_len = nrf_queue_in(p_txq, p_buff, length); + if (nrf_drv_uart_tx_in_progress(&p_serial->instance)) + { + return queue_in_len; + } + + size_t len = nrf_queue_out(p_txq, p_buffs->p_txb, p_buffs->tx_size); + ASSERT(len > 0); + ret_code_t ret = nrf_drv_uart_tx(&p_serial->instance, p_buffs->p_txb, len); + ASSERT(ret == NRF_SUCCESS); + + return queue_in_len; +} + +static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context) +{ + uint32_t ret; + nrf_serial_t const * p_serial = p_context; + + switch (p_event->type) + { + case NRF_DRV_UART_EVT_RX_DONE: + { + nrf_queue_t const * p_rxq = + p_serial->p_ctx->p_config->p_queues->p_rxq; + size_t len = nrf_queue_in(p_rxq, + p_event->data.rxtx.p_data, + p_event->data.rxtx.bytes); + + if (len < p_event->data.rxtx.bytes) + { + event_handler(p_serial, NRF_SERIAL_EVENT_FIFO_ERR); + break; + } + + event_handler(p_serial, NRF_SERIAL_EVENT_RX_DATA); + nrf_serial_buffers_t const * p_buffs = + p_serial->p_ctx->p_config->p_buffers; + + ret = nrf_drv_uart_rx(&p_serial->instance, + p_buffs->p_rxb, + p_buffs->rx_size); + ASSERT(ret == NRF_SUCCESS); + break; + } + case NRF_DRV_UART_EVT_ERROR: + { + event_handler(p_serial, NRF_SERIAL_EVENT_DRV_ERR); + break; + } + case NRF_DRV_UART_EVT_TX_DONE: + { + nrf_queue_t const * p_txq = + p_serial->p_ctx->p_config->p_queues->p_txq; + nrf_serial_buffers_t const * p_buffs = + p_serial->p_ctx->p_config->p_buffers; + + event_handler(p_serial, NRF_SERIAL_EVENT_TX_DONE); + size_t len = nrf_queue_out(p_txq, p_buffs->p_txb, p_buffs->tx_size); + if (len == 0) + { + break; + } + + ret = nrf_drv_uart_tx(&p_serial->instance, p_buffs->p_txb, len); + ASSERT(ret == NRF_SUCCESS); + break; + } + default: + break; + } +} + +ret_code_t nrf_serial_init(nrf_serial_t const * p_serial, + nrf_drv_uart_config_t const * p_drv_uart_config, + nrf_serial_config_t const * p_config) +{ + ret_code_t ret; + ASSERT(p_serial && p_drv_uart_config && p_config); + + if (p_serial->p_ctx->p_config) + { + /*Already initialized.*/ + return NRF_ERROR_MODULE_ALREADY_INITIALIZED; + } + + if (p_config->mode != NRF_SERIAL_MODE_POLLING) + { + ASSERT(p_config->p_queues && p_config->p_buffers); + } + + nrf_drv_uart_config_t drv_config; + memcpy(&drv_config, p_drv_uart_config, sizeof(nrf_drv_uart_config_t)); + drv_config.p_context = (void *)p_serial; +#ifdef UARTE_PRESENT + drv_config.use_easy_dma = (p_config->mode == NRF_SERIAL_MODE_DMA); +#endif + ret = nrf_drv_uart_init(&p_serial->instance, + &drv_config, + p_config->mode == NRF_SERIAL_MODE_POLLING ? + NULL : uart_event_handler); + if (ret != NRF_SUCCESS) + { + return ret; + } + + p_serial->p_ctx->p_config = p_config; + + if (p_serial->p_ctx->p_config->p_queues) + { + nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_txq); + nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_rxq); + } + + nrf_mtx_init(&p_serial->p_ctx->read_lock); + nrf_mtx_init(&p_serial->p_ctx->write_lock); + + p_serial->p_ctx->flags = NRF_SERIAL_RX_ENABLED_FLAG | + NRF_SERIAL_TX_ENABLED_FLAG; + + if (drv_config.pseltxd == NRF_UART_PSEL_DISCONNECTED) + { + p_serial->p_ctx->flags &= ~NRF_SERIAL_TX_ENABLED_FLAG; + } + + if (drv_config.pselrxd == NRF_UART_PSEL_DISCONNECTED) + { + p_serial->p_ctx->flags &= ~NRF_SERIAL_RX_ENABLED_FLAG; + return NRF_SUCCESS; + } + + if (p_serial->p_ctx->p_config->mode != NRF_SERIAL_MODE_DMA) + { + nrf_drv_uart_rx_enable(&p_serial->instance); + if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING) + { + return NRF_SUCCESS; + } + } + + return nrf_drv_uart_rx(&p_serial->instance, + p_serial->p_ctx->p_config->p_buffers->p_rxb, + p_serial->p_ctx->p_config->p_buffers->rx_size); +} + +ret_code_t nrf_serial_uninit(nrf_serial_t const * p_serial) +{ + ASSERT(p_serial); + + if (!p_serial->p_ctx->p_config) + { + /*Already uninitialized.*/ + return NRF_ERROR_MODULE_NOT_INITIALZED; + } + + if (!nrf_mtx_trylock(&p_serial->p_ctx->write_lock)) + { + return NRF_ERROR_BUSY; + } + if (!nrf_mtx_trylock(&p_serial->p_ctx->read_lock)) + { + nrf_mtx_unlock(&p_serial->p_ctx->write_lock); + return NRF_ERROR_BUSY; + } + + nrf_drv_uart_uninit(&p_serial->instance); + if (p_serial->p_ctx->p_config->p_queues) + { + nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_txq); + nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_rxq); + } + + memset(p_serial->p_ctx, 0, sizeof(nrf_serial_ctx_t)); + return NRF_SUCCESS; +} + +typedef struct { + volatile bool expired; +} nrf_serial_timeout_ctx_t; + +static void serial_timeout_handler(void * p_context) +{ + nrf_serial_timeout_ctx_t * p_tout_ctx = p_context; + p_tout_ctx->expired = true; +} + + +static ret_code_t timeout_setup(nrf_serial_t const * p_serial, + app_timer_id_t const * p_timer_id, + uint32_t timeout_ms, + nrf_serial_timeout_ctx_t * p_tout_ctx) +{ + uint32_t ticks = APP_TIMER_TICKS(timeout_ms); + + if (ticks < APP_TIMER_MIN_TIMEOUT_TICKS) + { + p_tout_ctx->expired = true; + return NRF_SUCCESS; + } + + ret_code_t ret = app_timer_create(p_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + serial_timeout_handler); + if (ret != NRF_SUCCESS) + { + return ret; + } + + return app_timer_start(*p_timer_id, ticks, p_tout_ctx); +} + +ret_code_t nrf_serial_write(nrf_serial_t const * p_serial, + void const * p_data, + size_t size, + size_t * p_written, + uint32_t timeout_ms) +{ + ret_code_t ret; + + ASSERT(p_serial); + if (!p_serial->p_ctx->p_config) + { + return NRF_ERROR_MODULE_NOT_INITIALZED; + } + + if (!(p_serial->p_ctx->flags & NRF_SERIAL_TX_ENABLED_FLAG)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (size == 0) + { + return NRF_SUCCESS; + } + + if (!nrf_drv_is_in_RAM(p_data) && + p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_DMA) + { + return NRF_ERROR_INVALID_ADDR; + } + + if (!nrf_mtx_trylock(&p_serial->p_ctx->write_lock)) + { + return NRF_ERROR_BUSY; + } + + nrf_serial_timeout_ctx_t tout_ctx = { + .expired = false, + }; + + if (timeout_ms != NRF_SERIAL_MAX_TIMEOUT) + { + ret = timeout_setup(p_serial, + p_serial->p_tx_timer, + timeout_ms, + &tout_ctx); + if (ret != NRF_SUCCESS) + { + nrf_mtx_unlock(&p_serial->p_ctx->write_lock); + return ret; + } + } + + size_t left = size; + uint8_t const * p_buff = p_data; + + do + { + size_t wcnt = serial_tx(p_serial, p_buff, left); + left -= wcnt; + p_buff += wcnt; + if (!left) + { + break; + } + + sleep_handler(p_serial); + } while (!tout_ctx.expired); + + if (p_written) + { + *p_written = size - left; + } + + if (!tout_ctx.expired && (timeout_ms != NRF_SERIAL_MAX_TIMEOUT)) + { + (void)app_timer_stop(*p_serial->p_tx_timer); + } + + nrf_mtx_unlock(&p_serial->p_ctx->write_lock); + if (left && tout_ctx.expired) + { + return NRF_ERROR_TIMEOUT; + } + + return NRF_SUCCESS; +} + +ret_code_t nrf_serial_read(nrf_serial_t const * p_serial, + void * p_data, + size_t size, + size_t * p_read, + uint32_t timeout_ms) +{ + ret_code_t ret; + + ASSERT(p_serial); + if (!p_serial->p_ctx->p_config) + { + return NRF_ERROR_MODULE_NOT_INITIALZED; + } + + if (!(p_serial->p_ctx->flags & NRF_SERIAL_RX_ENABLED_FLAG)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (size == 0) + { + return NRF_SUCCESS; + } + + if (!nrf_mtx_trylock(&p_serial->p_ctx->read_lock)) + { + return NRF_ERROR_BUSY; + } + + nrf_serial_timeout_ctx_t tout_ctx = { + .expired = false, + }; + + if (timeout_ms != NRF_SERIAL_MAX_TIMEOUT) + { + ret = timeout_setup(p_serial, + p_serial->p_rx_timer, + timeout_ms, + &tout_ctx); + + if (ret != NRF_SUCCESS) + { + nrf_mtx_unlock(&p_serial->p_ctx->read_lock); + return ret; + } + } + + size_t left = size; + uint8_t * p_buff = p_data; + do + { + size_t rcnt = serial_rx(p_serial, p_buff, left); + left -= rcnt; + p_buff += rcnt; + if (!left) + { + break; + } + + if (tout_ctx.expired) + { + if (p_serial->p_ctx->p_config->mode != NRF_SERIAL_MODE_POLLING) + { + nrf_drv_uart_rx_abort(&p_serial->instance); + } + break; + } + + sleep_handler(p_serial); + } while (1); + + if (p_read) + { + *p_read = size - left; + } + + if (!tout_ctx.expired && (timeout_ms != NRF_SERIAL_MAX_TIMEOUT)) + { + (void)app_timer_stop(*p_serial->p_rx_timer); + } + + nrf_mtx_unlock(&p_serial->p_ctx->read_lock); + if (left && tout_ctx.expired) + { + return NRF_ERROR_TIMEOUT; + } + + return NRF_SUCCESS; +} + +ret_code_t nrf_serial_flush(nrf_serial_t const * p_serial, uint32_t timeout_ms) +{ + + ret_code_t ret; + + ASSERT(p_serial); + if (!p_serial->p_ctx->p_config) + { + return NRF_ERROR_MODULE_NOT_INITIALZED; + } + + if (!(p_serial->p_ctx->flags & NRF_SERIAL_TX_ENABLED_FLAG)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING) + { + return NRF_SUCCESS; + } + + if (!nrf_mtx_trylock(&p_serial->p_ctx->write_lock)) + { + return NRF_ERROR_BUSY; + } + + nrf_serial_timeout_ctx_t tout_ctx = { + .expired = false, + }; + + if (timeout_ms != NRF_SERIAL_MAX_TIMEOUT) + { + ret = timeout_setup(p_serial, + p_serial->p_tx_timer, + timeout_ms, + &tout_ctx); + if (ret != NRF_SUCCESS) + { + nrf_mtx_unlock(&p_serial->p_ctx->write_lock); + return ret; + } + } + + bool empty; + do + { + empty = nrf_queue_is_empty(p_serial->p_ctx->p_config->p_queues->p_txq) + && !nrf_drv_uart_tx_in_progress(&p_serial->instance); + if (empty) + { + break; + } + + sleep_handler(p_serial); + } while (!tout_ctx.expired); + + if (!tout_ctx.expired && (timeout_ms != NRF_SERIAL_MAX_TIMEOUT)) + { + (void)app_timer_stop(*p_serial->p_tx_timer); + } + + nrf_mtx_unlock(&p_serial->p_ctx->write_lock); + if (!empty && tout_ctx.expired) + { + return NRF_ERROR_TIMEOUT; + } + + return NRF_SUCCESS; +} + +ret_code_t nrf_serial_tx_abort(nrf_serial_t const * p_serial) +{ + ASSERT(p_serial); + if (!p_serial->p_ctx->p_config) + { + return NRF_ERROR_MODULE_NOT_INITIALZED; + } + + if (!(p_serial->p_ctx->flags & NRF_SERIAL_TX_ENABLED_FLAG)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (!nrf_mtx_trylock(&p_serial->p_ctx->write_lock)) + { + return NRF_ERROR_BUSY; + } + + nrf_drv_uart_tx_abort(&p_serial->instance); + if (p_serial->p_ctx->p_config->p_queues->p_txq) + { + nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_txq); + } + + nrf_mtx_unlock(&p_serial->p_ctx->write_lock); + return NRF_SUCCESS; +} + +ret_code_t nrf_serial_rx_drain(nrf_serial_t const * p_serial) +{ + ASSERT(p_serial); + if (!p_serial->p_ctx->p_config) + { + return NRF_ERROR_MODULE_NOT_INITIALZED; + } + + if (!(p_serial->p_ctx->flags & NRF_SERIAL_RX_ENABLED_FLAG)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (!nrf_mtx_trylock(&p_serial->p_ctx->read_lock)) + { + return NRF_ERROR_BUSY; + } + + uint8_t c; + /*Drain HW FIFO*/ + while (serial_rx(p_serial, &c, sizeof(c))) + { + + } + + /*Drain SW FIFO*/ + if (p_serial->p_ctx->p_config->p_queues->p_rxq) + { + nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_rxq); + } + nrf_mtx_unlock(&p_serial->p_ctx->read_lock); + return NRF_SUCCESS; +} + +#endif //NRF_MODULE_ENABLED(NRF_SERIAL) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/serial/nrf_serial.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/serial/nrf_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..570181bc8d42fa6e44ae7eec0bd759a8865da52d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/serial/nrf_serial.h @@ -0,0 +1,398 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SERIAL_H__ +#define NRF_SERIAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "nrf_drv_uart.h" +#include "nrf_queue.h" +#include "nrf_mtx.h" +#include "app_timer.h" + + +/**@file + * + * @defgroup nrf_serial Serial port abstraction layer + * @{ + * @ingroup app_common + * + * @brief Serial module interface. + * @details This module is more sophisticated than @ref nrf_drv_uart. It internally uses + * mutex, queues, and app_timer. You can configure it to work in three different modes + * (polling, interrupt, DMA). API can be configured to work in synchronous mode. Both read and write + * methods have a timeout parameter. Asynchronous mode is available by passing 0 as the + * timeout parameter. + * @warning Do not use synchronous API (timeout_ms parameter > 0) in IRQ + * context. It may lead to a deadlock because the timeout interrupt cannot + * preempt the current IRQ context. + */ + +typedef struct nrf_serial_s nrf_serial_t; + +/** + * @brief Serial port mode. + * */ +typedef enum { + NRF_SERIAL_MODE_POLLING, /**< Polling mode.*/ + NRF_SERIAL_MODE_IRQ, /**< Interrupt mode.*/ + NRF_SERIAL_MODE_DMA, /**< DMA mode.*/ +} nrf_serial_mode_t; + + + +/** + * @brief Creates an instance of @ref nrf_drv_uart_config_t. + * + * @param _name Instance name. + * @param _rx_pin RX pin number. + * @param _tx_pin TX pin number. + * @param _rts_pin RTS pin number. + * @param _cts_pin CTS pin number. + * @param _flow_control Flow control enable/disable (@ref nrf_uart_hwfc_t). + * @param _parity Parity enable/disable (@ref nrf_uart_parity_t). + * @param _baud_rate Baud rate (@ref nrf_uart_baudrate_t). + * @param _irq_prio Interrupt priority. + * + * */ +#define NRF_SERIAL_DRV_UART_CONFIG_DEF(_name, \ + _rx_pin, \ + _tx_pin, \ + _rts_pin, \ + _cts_pin, \ + _flow_control, \ + _parity, \ + _baud_rate, \ + _irq_prio) \ + static const nrf_drv_uart_config_t _name = { \ + .pselrxd = _rx_pin, \ + .pseltxd = _tx_pin, \ + .pselrts = _rts_pin, \ + .pselcts = _cts_pin, \ + .hwfc = _flow_control, \ + .parity = _parity, \ + .baudrate = _baud_rate, \ + .interrupt_priority = _irq_prio, \ + } + +/** + * @brief Serial port RX and TX queues. + * + * @note Use the @ref NRF_SERIAL_QUEUES_DEF macro to create an instance of this + * structure. + * */ +typedef struct { + nrf_queue_t const * p_rxq; //!< Receive queue handle. + nrf_queue_t const * p_txq; //!< Transmit queue handle. +} nrf_serial_queues_t; + +/** + * @brief Creates an instance of serial port queues. + * + * @param _name Instance name. + * @param _tx_size TX queue size. + * @param _rx_size RX queue size. + * */ +#define NRF_SERIAL_QUEUES_DEF(_name, _tx_size, _rx_size) \ + NRF_QUEUE_DEF(uint8_t, _name##_rxq, _rx_size, NRF_QUEUE_MODE_NO_OVERFLOW); \ + NRF_QUEUE_DEF(uint8_t, _name##_txq, _tx_size, NRF_QUEUE_MODE_NO_OVERFLOW); \ + static const nrf_serial_queues_t _name = { \ + .p_rxq = &_name##_rxq, \ + .p_txq = &_name##_txq, \ + } + +/** + * @brief Serial buffers. Data slices used by @ref nrf_drv_uart_tx and + * @ref nrf_drv_uart_rx. + * + * @note Use the @ref NRF_SERIAL_BUFFERS_DEF macro to create an instance of this + * structure. + * */ +typedef struct { + void * p_txb; //!< TX buffer. + void * p_rxb; //!< RX buffer. + uint8_t tx_size; //!< TX buffer size. + uint8_t rx_size; //!< RX buffer size. +} nrf_serial_buffers_t; + +/** + * @brief Creates an instance of serial port buffers. + * + * @param _name Instance name. + * @param _tx_size TX buffer size. + * @param _rx_size RX buffer size. + * */ +#define NRF_SERIAL_BUFFERS_DEF(_name, _tx_size, _rx_size) \ + STATIC_ASSERT_MSG((_tx_size) <= UINT8_MAX, NRF_SERIAL_TX_SIZE); \ + STATIC_ASSERT_MSG((_rx_size) <= UINT8_MAX, NRF_SERIAL_RX_SIZE); \ + static uint8_t _name##_txb[_tx_size]; \ + static uint8_t _name##_rxb[_rx_size]; \ + static const nrf_serial_buffers_t _name = { \ + .p_txb = _name##_txb, \ + .p_rxb = _name##_rxb, \ + .tx_size = sizeof(_name##_txb), \ + .rx_size = sizeof(_name##_rxb), \ + } + +/** + * @brief Events generated by this module. + * */ +typedef enum { + NRF_SERIAL_EVENT_TX_DONE, //!< Chunk of data has been sent. + NRF_SERIAL_EVENT_RX_DATA, //!< New chunk of data has been received. + NRF_SERIAL_EVENT_DRV_ERR, //!< Internal driver error. + NRF_SERIAL_EVENT_FIFO_ERR, //!< RX FIFO overrun. +} nrf_serial_event_t; + +/** + * @brief Event handler type. + * */ +typedef void (*nrf_serial_evt_handler_t)(struct nrf_serial_s const * p_serial, + nrf_serial_event_t event); + +/** + * @brief Sleep handler type. + * */ +typedef void (*nrf_serial_sleep_handler_t)(void); + +/** + * @brief Configuration of UART serial interface. + * + * @note Use the @ref NRF_SERIAL_CONFIG_DEF macro to create an instance of this + * structure. + * + */ +typedef struct { + nrf_serial_mode_t mode; //!< Serial port mode. + + nrf_serial_queues_t const * p_queues; //!< Serial port queues. + nrf_serial_buffers_t const * p_buffers; //!< DMA buffers. + nrf_serial_evt_handler_t ev_handler; //!< Event handler. + nrf_serial_sleep_handler_t sleep_handler; //!< Sleep mode handler. +} nrf_serial_config_t; + +/** + * @brief Creates an instance of serial port configuration. + * + * @param _name Instance name. + * @param _mode Serial port mode. + * @param _queues Serial port queues. NULL can be passed in @ref NRF_SERIAL_MODE_POLLING mode. + * @param _buffers Serial port buffers. NULL can be passed in @ref NRF_SERIAL_MODE_POLLING mode. + * @param _ev_handler Serial port event handler. NULL can be passed in any mode. + * @param _sleep Serial port sleep handler. NULL can be passed in any mode. + * */ +#define NRF_SERIAL_CONFIG_DEF(_name, _mode, _queues, _buffers, _ev_handler, _sleep) \ + static const nrf_serial_config_t _name = { \ + .mode = _mode, \ + .p_queues = _queues, \ + .p_buffers = _buffers, \ + .ev_handler = _ev_handler, \ + .sleep_handler = _sleep, \ + } + +#define NRF_SERIAL_RX_ENABLED_FLAG (1u << 0) //!< Receiver enable flag. +#define NRF_SERIAL_TX_ENABLED_FLAG (1u << 1) //!< Transmitter enable flag. + +/** + * @brief Serial port context. Contains all data structures that need + * to be stored in RAM memory. + * */ +typedef struct { + nrf_serial_config_t const * p_config; //!< Serial port configuration. + + nrf_mtx_t write_lock; //!< Write operation lock. + nrf_mtx_t read_lock; //!< Read operation lock. + + uint8_t flags; //!< Transmitter/receiver enable flags. +} nrf_serial_ctx_t; + +/** + * @brief Serial port instance declaration. + * + * @note Use @ref NRF_SERIAL_UART_DEF macro to create an instance of this + * structure. + * */ +struct nrf_serial_s { + nrf_drv_uart_t instance; //!< Driver instance. + nrf_serial_ctx_t * p_ctx; //!< Driver context. + + app_timer_id_t const * p_tx_timer; //!< TX timeout timer. + app_timer_id_t const * p_rx_timer; //!< RX timeout timer. +}; + +/** + * @brief Creates an instance of a serial port. + * + * @param _name Instance name. + * @param _instance_number Driver instance number (@ref NRF_DRV_UART_INSTANCE). + * */ +#define NRF_SERIAL_UART_DEF(_name, _instance_number) \ + APP_TIMER_DEF(_name##_rx_timer); \ + APP_TIMER_DEF(_name##_tx_timer); \ + static nrf_serial_ctx_t _name##_ctx; \ + static const nrf_serial_t _name = { \ + .instance = NRF_DRV_UART_INSTANCE(_instance_number), \ + .p_ctx = &_name##_ctx, \ + .p_tx_timer = &_name##_tx_timer, \ + .p_rx_timer = &_name##_rx_timer, \ + } + + +/** + * @brief Maximum value of timeout. API might be blocked indefinitely if this value is + * not set.*/ +#define NRF_SERIAL_MAX_TIMEOUT UINT32_MAX + +/** + * @brief Function for initializing a serial port. Serial port can be initialized + * in various modes that are defined by nrf_serial_mode_t. + * - NRF_SERIAL_MODE_POLLING - Simple polling mode. API calls will be + * synchronous. There is no need to define queues or buffers. + * No events will be generated. + * - NRF_SERIAL_MODE_IRQ - Interrupt mode. API can be set to work in synchronous or + * asynchronous mode. Queues and buffers must be passed + * during initialization. Events will be generated if + * a non NULL handler is passed as the ev_handler parameter. + * - NRF_SERIAL_MODE_DMA - Similar to @ref NRF_SERIAL_MODE_IRQ. Uses EasyDMA. + * + * + * @param p_serial Serial port instance. + * @param p_drv_uart_config UART driver configuration. Cannot be NULL. + * @param p_config Serial port configuration. Cannot be NULL. This object must be created + * using the @ref NRF_SERIAL_CONFIG_DEF macro. + * + * @return Standard error code. + * */ +ret_code_t nrf_serial_init(nrf_serial_t const * p_serial, + nrf_drv_uart_config_t const * p_drv_uart_config, + nrf_serial_config_t const * p_config); + + +/** + * @brief Function for uninitializing a serial port. + * + * @param p_serial Serial port instance. + * + * @return Standard error code. + * */ +ret_code_t nrf_serial_uninit(nrf_serial_t const * p_serial); + + +/** + * @brief Function for writing to a serial port. + * + * @param p_serial Serial port instance. + * @param p_data Transmit buffer pointer. + * @param size Transmit buffer size. + * @param p_written Amount of data actually written to the serial port. + * NULL pointer can be passed. + * @param timeout_ms Operation timeout, in milliseconds. Pass 0 to operate in + * non blocking mode. + * + * @return Standard error code. + * */ +ret_code_t nrf_serial_write(nrf_serial_t const * p_serial, + void const * p_data, + size_t size, + size_t * p_written, + uint32_t timeout_ms); + +/** + * @brief Function for reading from a serial port. + * + * @param p_serial Serial port instance. + * @param p_data Receive buffer pointer. + * @param size Receive buffer size. + * @param p_read Amount of data actually read from the serial port. + * NULL pointer can be passed. + * @param timeout_ms Operation timeout, in milliseconds. Pass 0 to operate in + * non blocking mode. + * + * @return Standard error code. + * */ +ret_code_t nrf_serial_read(nrf_serial_t const * p_serial, + void * p_data, + size_t size, + size_t * p_read, + uint32_t timeout_ms); + +/** + * @brief Function for flushing a serial port TX queue. + * + * @param p_serial Serial port instance. + * @param timeout_ms Operation timeout, in milliseconds. Pass 0 to operate in + * non blocking mode. + * @return Standard error code. + * */ +ret_code_t nrf_serial_flush(nrf_serial_t const * p_serial, uint32_t timeout_ms); + + +/** + * @brief Function for aborting a serial port transmission. + * Aborts the current ongoing transmission and resets TX FIFO. + * + * @param p_serial Serial port instance. + * + * @return Standard error code. + * */ +ret_code_t nrf_serial_tx_abort(nrf_serial_t const * p_serial); + +/** + * @brief Function for draining the serial port receive RX FIFO. + * Drains HW FIFO and resets RX FIFO. + * + * @param p_serial Serial port instance. + * + * @return Standard error code. + * */ +ret_code_t nrf_serial_rx_drain(nrf_serial_t const * p_serial); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SERIAL_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sha256/sha256.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sha256/sha256.c new file mode 100644 index 0000000000000000000000000000000000000000..66892ed67ccfd5267cfed894aae4f213ce684a01 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sha256/sha256.c @@ -0,0 +1,225 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "sha256.h" +#include "sdk_errors.h" +#include "sdk_common.h" + + +#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) +#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32 - (b)))) + +#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) +#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22)) +#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25)) +#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3)) +#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10)) + + +static const uint32_t k[64] = { + 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, + 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, + 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, + 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, + 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, + 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, + 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, + 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +}; + + +/**@brief Function for calculating the hash of a 64-byte section of data. + * + * @param[in,out] ctx Hash instance. + * @param[in] data Aray with data to be hashed. Assumed to be 64 bytes long. + */ +void sha256_transform(sha256_context_t *ctx, const uint8_t * data) +{ + uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64]; + + for (i = 0, j = 0; i < 16; ++i, j += 4) + m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]); + for ( ; i < 64; ++i) + m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16]; + + a = ctx->state[0]; + b = ctx->state[1]; + c = ctx->state[2]; + d = ctx->state[3]; + e = ctx->state[4]; + f = ctx->state[5]; + g = ctx->state[6]; + h = ctx->state[7]; + + for (i = 0; i < 64; ++i) { + t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i]; + t2 = EP0(a) + MAJ(a,b,c); + h = g; + g = f; + f = e; + e = d + t1; + d = c; + c = b; + b = a; + a = t1 + t2; + } + + ctx->state[0] += a; + ctx->state[1] += b; + ctx->state[2] += c; + ctx->state[3] += d; + ctx->state[4] += e; + ctx->state[5] += f; + ctx->state[6] += g; + ctx->state[7] += h; +} + + +ret_code_t sha256_init(sha256_context_t *ctx) +{ + VERIFY_PARAM_NOT_NULL(ctx); + + ctx->datalen = 0; + ctx->bitlen = 0; + ctx->state[0] = 0x6a09e667; + ctx->state[1] = 0xbb67ae85; + ctx->state[2] = 0x3c6ef372; + ctx->state[3] = 0xa54ff53a; + ctx->state[4] = 0x510e527f; + ctx->state[5] = 0x9b05688c; + ctx->state[6] = 0x1f83d9ab; + ctx->state[7] = 0x5be0cd19; + + return NRF_SUCCESS; +} + + +ret_code_t sha256_update(sha256_context_t *ctx, const uint8_t * data, size_t len) +{ + VERIFY_PARAM_NOT_NULL(ctx); + if (((len > 0) && (data == NULL))) + { + return NRF_ERROR_NULL; + } + + uint32_t i; + + for (i = 0; i < len; ++i) { + ctx->data[ctx->datalen] = data[i]; + ctx->datalen++; + if (ctx->datalen == 64) { + sha256_transform(ctx, ctx->data); + ctx->bitlen += 512; + ctx->datalen = 0; + } + } + + return NRF_SUCCESS; +} + + +ret_code_t sha256_final(sha256_context_t *ctx, uint8_t * hash, uint8_t le) +{ + uint32_t i; + + VERIFY_PARAM_NOT_NULL(ctx); + VERIFY_PARAM_NOT_NULL(hash); + + i = ctx->datalen; + + // Pad whatever data is left in the buffer. + if (ctx->datalen < 56) { + ctx->data[i++] = 0x80; + while (i < 56) + ctx->data[i++] = 0x00; + } + else { + ctx->data[i++] = 0x80; + while (i < 64) + ctx->data[i++] = 0x00; + sha256_transform(ctx, ctx->data); + memset(ctx->data, 0, 56); + } + + // Append to the padding the total message's length in bits and transform. + ctx->bitlen += (uint64_t)ctx->datalen * 8; + ctx->data[63] = ctx->bitlen; + ctx->data[62] = ctx->bitlen >> 8; + ctx->data[61] = ctx->bitlen >> 16; + ctx->data[60] = ctx->bitlen >> 24; + ctx->data[59] = ctx->bitlen >> 32; + ctx->data[58] = ctx->bitlen >> 40; + ctx->data[57] = ctx->bitlen >> 48; + ctx->data[56] = ctx->bitlen >> 56; + sha256_transform(ctx, ctx->data); + + if(le) + { + for (i = 0; i < 4; ++i) { + hash[i] = (ctx->state[7] >> (i * 8)) & 0x000000ff; + hash[i + 4] = (ctx->state[6] >> (i * 8)) & 0x000000ff; + hash[i + 8] = (ctx->state[5] >> (i * 8)) & 0x000000ff; + hash[i + 12] = (ctx->state[4] >> (i * 8)) & 0x000000ff; + hash[i + 16] = (ctx->state[3] >> (i * 8)) & 0x000000ff; + hash[i + 20] = (ctx->state[2] >> (i * 8)) & 0x000000ff; + hash[i + 24] = (ctx->state[1] >> (i * 8)) & 0x000000ff; + hash[i + 28] = (ctx->state[0] >> (i * 8)) & 0x000000ff; + } + } + else + { + + // Since this implementation uses little endian uint8_t ordering and SHA uses big endian, + // reverse all the uint8_ts when copying the final state to the output hash. + for (i = 0; i < 4; ++i) { + hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; + hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; + hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; + hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; + hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; + hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; + hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; + hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; + } + } + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sha256/sha256.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sha256/sha256.h new file mode 100644 index 0000000000000000000000000000000000000000..da188917d3c36eec0a73a3ab76f4449ac05e8548 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/sha256/sha256.h @@ -0,0 +1,127 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup sha256 SHA-256 hash library + * @{ + * @ingroup app_common + * + * @brief This module calculates SHA-256 (SHA-2, FIPS-180) hashes. + * + * @details To use this module, first call @ref sha256_init on a @ref sha256_context_t instance. Then call @ref + * sha256_update with the data to be hashed. This step can optionally be done with multiple + * calls to @ref sha256_update, each with a section of the data (in the correct order). + * After all data has been passed to @ref sha256_update, call @ref sha256_final to finalize + * and extract the hash value. + * + * This code is adapted from code by Brad Conte, retrieved from + * https://github.com/B-Con/crypto-algorithms. + * + */ + +#ifndef SHA256_H +#define SHA256_H + + +#include +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Current state of a hash operation. + */ +typedef struct { + uint8_t data[64]; + uint32_t datalen; + uint64_t bitlen; + uint32_t state[8]; +} sha256_context_t; + + +/**@brief Function for initializing a @ref sha256_context_t instance. + * + * @param[out] ctx Context instance to be initialized. + * + * @retval NRF_SUCCESS If the instance was successfully initialized. + * @retval NRF_ERROR_NULL If the parameter was NULL. + */ +ret_code_t sha256_init(sha256_context_t *ctx); + +/**@brief Function for calculating the hash of an array of uint8_t data. + * + * @details This function can be called multiple times in sequence. This is equivalent to calling + * the function once on a concatenation of the data from the different calls. + * + * @param[in,out] ctx Hash instance. + * @param[in] data Data to be hashed. + * @param[in] len Length of the data to be hashed. + * + * @retval NRF_SUCCESS If the data was successfully hashed. + * @retval NRF_ERROR_NULL If the ctx parameter was NULL or the data parameter was NULL, while the len parameter was not zero. + */ +ret_code_t sha256_update(sha256_context_t *ctx, const uint8_t * data, const size_t len); + +/**@brief Function for extracting the hash value from a hash instance. + * + * @details This function should be called after all data to be hashed has been passed to the hash + * instance (by one or more calls to @ref sha256_update). + * + * Do not call @ref sha256_update again after @ref sha256_final has been called. + * + * @param[in,out] ctx Hash instance. + * @param[out] hash Array to hold the extracted hash value (assumed to be 32 bytes long). + * @param[in] le Store the hash in little-endian. + * + * @retval NRF_SUCCESS If the has value was successfully extracted. + * @retval NRF_ERROR_NULL If a parameter was NULL. + */ +ret_code_t sha256_final(sha256_context_t *ctx, uint8_t * hash, uint8_t le); + + +#ifdef __cplusplus +} +#endif + +#endif // SHA256_H + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/simple_timer/app_simple_timer.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/simple_timer/app_simple_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..69d845fe05c6e8ed6da21f83b00ba8a405660ed8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/simple_timer/app_simple_timer.c @@ -0,0 +1,191 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(SIMPLE_TIMER) +#include "app_simple_timer.h" +#include "nrf.h" +#include "app_util_platform.h" +#include "app_error.h" +#include "nrf_timer.h" +#include "nrf_drv_timer.h" + +/**@brief States of simple timer state machine. + */ +typedef enum +{ + SIMPLE_TIMER_STATE_IDLE = 0, + SIMPLE_TIMER_STATE_INITIALIZED, + SIMPLE_TIMER_STATE_STOPPED, + SIMPLE_TIMER_STATE_STARTED +}simple_timer_states_t; + +static app_simple_timer_mode_t m_mode; /**< Registered timer mode. */ +static app_simple_timer_timeout_handler_t m_timeout_handler = NULL; /**< Registered time-out handler. */ +static void * mp_timeout_handler_context = NULL; /**< Registered time-out handler context. */ +static simple_timer_states_t m_simple_timer_state = SIMPLE_TIMER_STATE_IDLE; /**< State machine state. */ + +const nrf_drv_timer_t SIMPLE_TIMER = NRF_DRV_TIMER_INSTANCE(SIMPLE_TIMER_CONFIG_INSTANCE); + +/** + * @brief Handler for timer events. + */ +static void app_simple_timer_event_handler(nrf_timer_event_t event_type, void * p_context) +{ + switch (event_type) + { + case NRF_TIMER_EVENT_COMPARE0: + if (m_mode == APP_SIMPLE_TIMER_MODE_SINGLE_SHOT) + { + m_simple_timer_state = SIMPLE_TIMER_STATE_STOPPED; + } + + //@note: No NULL check required as performed in timer_start(...). + m_timeout_handler(mp_timeout_handler_context); + break; + + default: + //Do nothing. + break; + } +} + +uint32_t app_simple_timer_init(void) +{ + uint32_t err_code = NRF_SUCCESS; + nrf_drv_timer_config_t t_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG; + t_cfg.mode = NRF_TIMER_MODE_TIMER; + t_cfg.bit_width = NRF_TIMER_BIT_WIDTH_16; + t_cfg.frequency = (nrf_timer_frequency_t)SIMPLE_TIMER_CONFIG_FREQUENCY; + err_code = nrf_drv_timer_init(&SIMPLE_TIMER, &t_cfg, app_simple_timer_event_handler); + + if (NRF_SUCCESS == err_code) + { + m_simple_timer_state = SIMPLE_TIMER_STATE_INITIALIZED; + } + + return err_code; +} + +uint32_t app_simple_timer_start(app_simple_timer_mode_t mode, + app_simple_timer_timeout_handler_t timeout_handler, + uint16_t timeout_ticks, + void * p_context) +{ + uint32_t err_code = NRF_SUCCESS; + nrf_timer_short_mask_t timer_short; + + VERIFY_PARAM_NOT_NULL(timeout_handler); + + if (APP_SIMPLE_TIMER_MODE_REPEATED == mode) + { + timer_short = NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK; + } + else if (APP_SIMPLE_TIMER_MODE_SINGLE_SHOT == mode) + { + timer_short = NRF_TIMER_SHORT_COMPARE0_STOP_MASK; + } + else + { + return NRF_ERROR_INVALID_PARAM; + } + + if (SIMPLE_TIMER_STATE_IDLE == m_simple_timer_state) + { + return NRF_ERROR_INVALID_STATE; + } + + if (SIMPLE_TIMER_STATE_STARTED == m_simple_timer_state) + { + err_code = app_simple_timer_stop(); + APP_ERROR_CHECK(err_code); + } + + if (SIMPLE_TIMER_STATE_STOPPED == m_simple_timer_state) + { + nrf_drv_timer_clear(&SIMPLE_TIMER); + } + + m_mode = mode; + m_timeout_handler = timeout_handler; + mp_timeout_handler_context = p_context; + + nrf_drv_timer_extended_compare( + &SIMPLE_TIMER, NRF_TIMER_CC_CHANNEL0, (uint32_t)timeout_ticks, timer_short, true); + + if (m_simple_timer_state == SIMPLE_TIMER_STATE_STOPPED) + { + nrf_drv_timer_resume(&SIMPLE_TIMER); + } + else + { + nrf_drv_timer_enable(&SIMPLE_TIMER); + } + + + m_simple_timer_state = SIMPLE_TIMER_STATE_STARTED; + + return NRF_SUCCESS; +} + +uint32_t app_simple_timer_stop(void) +{ + if (SIMPLE_TIMER_STATE_STARTED == m_simple_timer_state) + { + nrf_drv_timer_pause(&SIMPLE_TIMER); + + m_simple_timer_state = SIMPLE_TIMER_STATE_STOPPED; + } + + return NRF_SUCCESS; +} + +uint32_t app_simple_timer_uninit(void) +{ + uint32_t err_code = NRF_SUCCESS; + + if (SIMPLE_TIMER_STATE_IDLE != m_simple_timer_state) + { + nrf_drv_timer_uninit(&SIMPLE_TIMER); + m_simple_timer_state = SIMPLE_TIMER_STATE_IDLE; + } + + return err_code; +} +#endif //NRF_MODULE_ENABLED(SIMPLE_TIMER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/simple_timer/app_simple_timer.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/simple_timer/app_simple_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..cfc8d8ed605a36f1d9a4e80c13c87a144dd50d5e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/simple_timer/app_simple_timer.h @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup app_simple_timer Simple Timer + * @{ + * @ingroup app_common + * + * @brief Simple timer module. + * + * Supported features and limitations: + * - Two modes: single shot mode and repeated mode. + * - No more than one timer can run simultaneously. + * - The timer is hard-coded to use the TIMER1 peripheral and compare channel 0. + */ + +#ifndef TIMER_H__ +#define TIMER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Timer time-out handler type. */ +typedef void (*app_simple_timer_timeout_handler_t)(void * p_context); + +/**@brief Timer modes. */ +typedef enum +{ + APP_SIMPLE_TIMER_MODE_SINGLE_SHOT, /**< The timer will expire only once. */ + APP_SIMPLE_TIMER_MODE_REPEATED /**< The timer will restart each time it expires. */ +} app_simple_timer_mode_t; + +/**@brief Function for configuring and setting up the timer hardware. + * + * @note Timer frequency is configured statically. + * + * @retval NRF_SUCCESS If the operation is successful. + * @retval NRF_ERROR_INVALID_STATE If the operation fails because the timer is already initialized. + * @retval NRF_ERROR_INVALID_PARAM If the operation fails because some configuration parameter is + * not valid. + */ +uint32_t app_simple_timer_init(void); + +/**@brief Function for starting a timer. + * + * @note If this function is called for a timer that is already running, the currently running + * timer is stopped before starting the new one. + * + * @param[in] mode Timer mode (see @ref app_simple_timer_mode_t). + * @param[in] timeout_handler Function to be executed when the timer expires + * (see @ref app_simple_timer_timeout_handler_t). + * @param[in] timeout_ticks Number of timer ticks to time-out event. + * @param[in] p_context General purpose pointer. Will be passed to the time-out handler + * when the timer expires. + * + * @retval NRF_SUCCESS If the operation is successful. + * @retval NRF_ERROR_INVALID_STATE If the operation fails because @ref app_simple_timer_init has not + * been called and the operation is not allowed in this state. + * @retval NRF_ERROR_NULL If the operation fails because timeout_handler is NULL. + * @retval NRF_ERROR_INVALID_PARAM If the operation fails because "mode" parameter is not valid. + */ + +uint32_t app_simple_timer_start(app_simple_timer_mode_t mode, + app_simple_timer_timeout_handler_t timeout_handler, + uint16_t timeout_ticks, + void * p_context); + +/**@brief Function for stopping the timer. + * + * @retval NRF_SUCCESS If the operation is successful. + */ +uint32_t app_simple_timer_stop(void); + +/**@brief Function for uninitializing the timer. Should be called also when the timer is not used + * anymore to reach lowest power consumption in system. + * + * @note The function switches off the internal core of the timer to reach lowest power consumption + * in system. The startup time from this state may be longer compared to starting the timer + * from the stopped state. + * + * @retval NRF_SUCCESS If the operation is successful. + */ +uint32_t app_simple_timer_uninit(void); + + +#ifdef __cplusplus +} +#endif + +#endif // TIMER_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/slip/slip.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/slip/slip.c new file mode 100644 index 0000000000000000000000000000000000000000..c55e8d75e160bb5697a095cd303401467a9d1b6c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/slip/slip.c @@ -0,0 +1,150 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(SLIP) +#include "slip.h" + +#include + + +#define SLIP_BYTE_END 0300 /* indicates end of packet */ +#define SLIP_BYTE_ESC 0333 /* indicates byte stuffing */ +#define SLIP_BYTE_ESC_END 0334 /* ESC ESC_END means END data byte */ +#define SLIP_BYTE_ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */ + + +ret_code_t slip_encode(uint8_t * p_output, uint8_t * p_input, uint32_t input_length, uint32_t * p_output_buffer_length) +{ + if (p_output == NULL || p_input == NULL || p_output_buffer_length == NULL) + { + return NRF_ERROR_NULL; + } + + *p_output_buffer_length = 0; + uint32_t input_index; + + for (input_index = 0; input_index < input_length; input_index++) + { + switch (p_input[input_index]) + { + case SLIP_BYTE_END: + p_output[(*p_output_buffer_length)++] = SLIP_BYTE_ESC; + p_output[(*p_output_buffer_length)++] = SLIP_BYTE_ESC_END; + break; + + case SLIP_BYTE_ESC: + p_output[(*p_output_buffer_length)++] = SLIP_BYTE_ESC; + p_output[(*p_output_buffer_length)++] = SLIP_BYTE_ESC_ESC; + break; + + default: + p_output[(*p_output_buffer_length)++] = p_input[input_index]; + } + } + p_output[(*p_output_buffer_length)++] = SLIP_BYTE_END; + + return NRF_SUCCESS; +} + +ret_code_t slip_decode_add_byte(slip_t * p_slip, uint8_t c) +{ + if (p_slip == NULL) + { + return NRF_ERROR_NULL; + } + + if (p_slip->current_index == p_slip->buffer_len) + { + return NRF_ERROR_NO_MEM; + } + + switch (p_slip->state) + { + case SLIP_STATE_DECODING: + switch (c) + { + case SLIP_BYTE_END: + // finished reading packet + return NRF_SUCCESS; + + case SLIP_BYTE_ESC: + // wait for + p_slip->state = SLIP_STATE_ESC_RECEIVED; + break; + + default: + // add byte to buffer + p_slip->p_buffer[p_slip->current_index++] = c; + break; + } + break; + + case SLIP_STATE_ESC_RECEIVED: + switch (c) + { + case SLIP_BYTE_ESC_END: + p_slip->p_buffer[p_slip->current_index++] = SLIP_BYTE_END; + p_slip->state = SLIP_STATE_DECODING; + break; + + case SLIP_BYTE_ESC_ESC: + p_slip->p_buffer[p_slip->current_index++] = SLIP_BYTE_ESC; + p_slip->state = SLIP_STATE_DECODING; + break; + + default: + // protocol violation + p_slip->state = SLIP_STATE_CLEARING_INVALID_PACKET; + return NRF_ERROR_INVALID_DATA; + } + break; + + case SLIP_STATE_CLEARING_INVALID_PACKET: + if (c == SLIP_BYTE_END) + { + p_slip->state = SLIP_STATE_DECODING; + p_slip->current_index = 0; + } + break; + } + + return NRF_ERROR_BUSY; +} +#endif //NRF_MODULE_ENABLED(SLIP) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/slip/slip.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/slip/slip.h new file mode 100644 index 0000000000000000000000000000000000000000..cfe805ec9b0a343a8303c1bae2d80703e7132695 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/slip/slip.h @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SLIP_H__ +#define SLIP_H__ + +#include +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + * + * @defgroup slip SLIP encoding and decoding + * @{ + * @ingroup app_common + * + * @brief This module encodes and decodes SLIP packages. + * + * @details The SLIP protocol is described in @linkSLIP. + */ + +/** @brief Status information that is used while receiving and decoding a packet. */ +typedef enum +{ + SLIP_STATE_DECODING, //!< Ready to receive the next byte. + SLIP_STATE_ESC_RECEIVED, //!< An ESC byte has been received and the next byte must be decoded differently. + SLIP_STATE_CLEARING_INVALID_PACKET //!< The received data is invalid and transfer must be restarted. +} slip_read_state_t; + + /** @brief Representation of a SLIP packet. */ +typedef struct +{ + slip_read_state_t state; //!< Current state of the packet (see @ref slip_read_state_t). + + uint8_t * p_buffer; //!< Decoded data. + uint32_t current_index; //!< Current length of the packet that has been received. + uint32_t buffer_len; //!< Size of the buffer that is available. +} slip_t; + +/**@brief Function for encoding a SLIP packet. + * + * The maximum size of the output data is (2*input size + 1) bytes. Ensure that the provided buffer is large enough. + * + * @param[in,out] p_output The buffer where the encoded SLIP packet is stored. Ensure that it is large enough. + * @param[in,out] p_input The buffer to be encoded. + * @param[in,out] input_length The length of the input buffer. + * @param[out] p_output_buffer_length The length of the output buffer after the input has been encoded. + * + * @retval NRF_SUCCESS If the input was successfully encoded into output. + * @retval NRF_ERROR_NULL If one of the provided parameters is NULL. + */ +ret_code_t slip_encode(uint8_t * p_output, uint8_t * p_input, uint32_t input_length, uint32_t * p_output_buffer_length); + +/**@brief Function for decoding a SLIP packet. + * + * The decoded packet is put into @p p_slip::p_buffer. The index and buffer state is updated. + * + * Ensure that @p p_slip is properly initialized. The initial state must be set to @ref SLIP_STATE_DECODING. + * + * @param[in,out] p_slip State of the decoding process. + * @param[in] c Byte to decode. + * + * @retval NRF_SUCCESS If a packet has been parsed. The received packet can be retrieved from @p p_slip. + * @retval NRF_ERROR_NULL If @p p_slip is NULL. + * @retval NRF_ERROR_NO_MEM If there is no more room in the buffer provided by @p p_slip. + * @retval NRF_ERROR_BUSY If the packet has not been parsed completely yet. + * @retval NRF_ERROR_INVALID_DATA If the packet is encoded wrong. In this case, @p p_slip::state is set to @ref SLIP_STATE_CLEARING_INVALID_PACKET, + * and decoding will stay in this state until the END byte is received. + */ +ret_code_t slip_decode_add_byte(slip_t * p_slip, uint8_t c); + +#ifdef __cplusplus +} +#endif + +#endif // SLIP_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/spi_mngr/nrf_spi_mngr.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/spi_mngr/nrf_spi_mngr.c new file mode 100644 index 0000000000000000000000000000000000000000..c5b898a4e6dd4004531a95c588652220b195e6b5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/spi_mngr/nrf_spi_mngr.c @@ -0,0 +1,360 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" + +#if NRF_MODULE_ENABLED(NRF_SPI_MNGR) +#include "nrf_spi_mngr.h" +#include "nrf_assert.h" +#include "app_util_platform.h" + + +static ret_code_t start_transfer(nrf_spi_mngr_t const * p_nrf_spi_mngr) +{ + ASSERT(p_nrf_spi_mngr != NULL); + + // use a local variable to avoid using two volatile variables in one + // expression + uint8_t curr_transfer_idx = p_nrf_spi_mngr->p_nrf_spi_mngr_cb->current_transfer_idx; + nrf_spi_mngr_transfer_t const * p_transfer = + &p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction->p_transfers[curr_transfer_idx]; + + return nrf_drv_spi_transfer(&p_nrf_spi_mngr->spi, + p_transfer->p_tx_data, p_transfer->tx_length, + p_transfer->p_rx_data, p_transfer->rx_length); +} + + +static void transaction_begin_signal(nrf_spi_mngr_t const * p_nrf_spi_mngr) +{ + ASSERT(p_nrf_spi_mngr != NULL); + + nrf_spi_mngr_transaction_t const * p_current_transaction = + p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction; + + + if (p_current_transaction->begin_callback != NULL) + { + void * p_user_data = p_current_transaction->p_user_data; + p_current_transaction->begin_callback(p_user_data); + } +} + + +static void transaction_end_signal(nrf_spi_mngr_t const * p_nrf_spi_mngr, + ret_code_t result) +{ + ASSERT(p_nrf_spi_mngr != NULL); + + nrf_spi_mngr_transaction_t const * p_current_transaction = + p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction; + + if (p_current_transaction->end_callback != NULL) + { + void * p_user_data = p_current_transaction->p_user_data; + p_current_transaction->end_callback(result, p_user_data); + } +} + + +static void spi_event_handler(nrf_drv_spi_evt_t const * p_event, + void * p_context); + + +// This function starts pending transaction if there is no current one or +// when 'switch_transaction' parameter is set to true. It is important to +// switch to new transaction without setting 'p_nrf_spi_mngr->p_curr_transaction' +// to NULL in between, since this pointer is used to check idle status - see +// 'nrf_spi_mngr_is_idle()'. +static void start_pending_transaction(nrf_spi_mngr_t const * p_nrf_spi_mngr, + bool switch_transaction) +{ + ASSERT(p_nrf_spi_mngr != NULL); + + while (1) + { + bool start_transaction = false; + nrf_spi_mngr_cb_t * p_cb = p_nrf_spi_mngr->p_nrf_spi_mngr_cb; + + CRITICAL_REGION_ENTER(); + if (switch_transaction || nrf_spi_mngr_is_idle(p_nrf_spi_mngr)) + { + if (nrf_queue_pop(p_nrf_spi_mngr->p_queue, + (void *)(&p_cb->p_current_transaction)) + == NRF_SUCCESS) + { + start_transaction = true; + } + else + { + p_cb->p_current_transaction = NULL; + } + } + CRITICAL_REGION_EXIT(); + + if (!start_transaction) + { + return; + } + else + { + ret_code_t result; + + nrf_drv_spi_config_t const * p_instance_cfg; + if (p_cb->p_current_transaction->p_required_spi_cfg == NULL) + { + p_instance_cfg = &p_cb->default_configuration ; + } + else + { + p_instance_cfg = p_cb->p_current_transaction->p_required_spi_cfg; + } + + if (memcmp(p_cb->p_current_configuration, p_instance_cfg, sizeof(*p_instance_cfg)) != 0) + { + ret_code_t err_code; + nrf_drv_spi_uninit(&p_nrf_spi_mngr->spi); + err_code = nrf_drv_spi_init(&p_nrf_spi_mngr->spi, + p_instance_cfg, + spi_event_handler, + (void *)p_nrf_spi_mngr); + ASSERT(err_code == NRF_SUCCESS); + p_cb->p_current_configuration = p_instance_cfg; + } + + // Try to start first transfer for this new transaction. + p_cb->current_transfer_idx = 0; + + // Execute user code if available before starting transaction + transaction_begin_signal(p_nrf_spi_mngr); + result = start_transfer(p_nrf_spi_mngr); + + // If transaction started successfully there is nothing more to do here now. + if (result == NRF_SUCCESS) + { + return; + } + + // Transfer failed to start - notify user that this transaction + // cannot be started and try with next one (in next iteration of + // the loop). + transaction_end_signal(p_nrf_spi_mngr, result); + + switch_transaction = true; + } + } +} + + +// This function shall be called to handle SPI events. It shall be mainly used by SPI IRQ for +// finished tranfer. +static void spi_event_handler(nrf_drv_spi_evt_t const * p_event, + void * p_context) +{ + ASSERT(p_event != NULL); + ASSERT(p_context != NULL); + + ret_code_t result; + nrf_spi_mngr_cb_t * p_cb = ((nrf_spi_mngr_t const *)p_context)->p_nrf_spi_mngr_cb; + + // This callback should be called only during transaction. + ASSERT(p_cb->p_current_transaction != NULL); + + if (p_event->type == NRF_DRV_SPI_EVENT_DONE) + { + result = NRF_SUCCESS; + + // Transfer finished successfully. If there is another one to be + // performed in the current transaction, start it now. + // use a local variable to avoid using two volatile variables in one + // expression + uint8_t curr_transfer_idx = p_cb->current_transfer_idx; + ++curr_transfer_idx; + if (curr_transfer_idx < p_cb->p_current_transaction->number_of_transfers) + { + p_cb->current_transfer_idx = curr_transfer_idx; + + result = start_transfer(((nrf_spi_mngr_t const *)p_context)); + + if (result == NRF_SUCCESS) + { + // The current transaction is running and its next transfer + // has been successfully started. There is nothing more to do. + return; + } + // if the next transfer could not be started due to some error + // we finish the transaction with this error code as the result + } + } + else + { + result = NRF_ERROR_INTERNAL; + } + + // The current transaction has been completed or interrupted by some error. + // Notify the user and start next one (if there is any). + transaction_end_signal(((nrf_spi_mngr_t const *)p_context), result); + // we switch transactions here ('p_nrf_spi_mngr->p_current_transaction' is set + // to NULL only if there is nothing more to do) in order to not generate + // spurious idle status (even for a moment) + start_pending_transaction(((nrf_spi_mngr_t const *)p_context), true); +} + + +ret_code_t nrf_spi_mngr_init(nrf_spi_mngr_t const * p_nrf_spi_mngr, + nrf_drv_spi_config_t const * p_default_spi_config) +{ + ASSERT(p_nrf_spi_mngr != NULL); + ASSERT(p_nrf_spi_mngr->p_queue != NULL); + ASSERT(p_nrf_spi_mngr->p_queue->size > 0); + ASSERT(p_default_spi_config != NULL); + + ret_code_t err_code; + + err_code = nrf_drv_spi_init(&p_nrf_spi_mngr->spi, + p_default_spi_config, + spi_event_handler, + (void *)p_nrf_spi_mngr); + + if (err_code == NRF_SUCCESS) + { + nrf_spi_mngr_cb_t * p_cb = p_nrf_spi_mngr->p_nrf_spi_mngr_cb; + + p_cb->internal_transaction_in_progress = false; + p_cb->p_current_transaction = NULL; + p_cb->default_configuration = *p_default_spi_config; + p_cb->p_current_configuration = &p_cb->default_configuration; + } + + return err_code; +} + + +void nrf_spi_mngr_uninit(nrf_spi_mngr_t const * p_nrf_spi_mngr) +{ + ASSERT(p_nrf_spi_mngr != NULL); + + nrf_drv_spi_uninit(&p_nrf_spi_mngr->spi); + + p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction = NULL; +} + + +ret_code_t nrf_spi_mngr_schedule(nrf_spi_mngr_t const * p_nrf_spi_mngr, + nrf_spi_mngr_transaction_t const * p_transaction) +{ + ASSERT(p_nrf_spi_mngr != NULL); + ASSERT(p_transaction != NULL); + ASSERT(p_transaction->p_transfers != NULL); + ASSERT(p_transaction->number_of_transfers != 0); + + ret_code_t result = nrf_queue_push(p_nrf_spi_mngr->p_queue, (void *)(&p_transaction)); + if (result == NRF_SUCCESS) + { + // New transaction has been successfully added to queue, + // so if we are currently idle it's time to start the job. + start_pending_transaction(p_nrf_spi_mngr, false); + } + + return result; +} + + +static void spi_internal_transaction_cb(ret_code_t result, void * p_user_data) +{ + nrf_spi_mngr_cb_t * p_cb = ((nrf_spi_mngr_t const *)p_user_data)->p_nrf_spi_mngr_cb; + + p_cb->internal_transaction_result = result; + p_cb->internal_transaction_in_progress = false; +} + +ret_code_t nrf_spi_mngr_perform(nrf_spi_mngr_t const * p_nrf_spi_mngr, + nrf_spi_mngr_transfer_t const * p_transfers, + uint8_t number_of_transfers, + void (* user_function)(void)) +{ + ASSERT(p_nrf_spi_mngr != NULL); + ASSERT(p_transfers != NULL); + ASSERT(number_of_transfers != 0); + + ret_code_t err_code = NRF_SUCCESS; + nrf_spi_mngr_cb_t * p_cb = p_nrf_spi_mngr->p_nrf_spi_mngr_cb; + + CRITICAL_REGION_ENTER(); + if (p_cb->internal_transaction_in_progress) + { + err_code = NRF_ERROR_BUSY; + } + else + { + p_cb->internal_transaction_in_progress = true; + } + CRITICAL_REGION_EXIT(); + + if (err_code != NRF_ERROR_BUSY) + { + nrf_spi_mngr_transaction_t internal_transaction = + { + .begin_callback = NULL, + .end_callback = spi_internal_transaction_cb, + .p_user_data = (void *)p_nrf_spi_mngr, + .p_transfers = p_transfers, + .number_of_transfers = number_of_transfers, + }; + + err_code = nrf_spi_mngr_schedule(p_nrf_spi_mngr, &internal_transaction); + + if (err_code == NRF_SUCCESS) + { + while (p_cb->internal_transaction_in_progress) + { + if (user_function) + { + user_function(); + } + } + err_code = p_cb->internal_transaction_result; + } + } + + return err_code; +} + +#endif //NRF_MODULE_ENABLED(NRF_SPI_MNGR) + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/spi_mngr/nrf_spi_mngr.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/spi_mngr/nrf_spi_mngr.h new file mode 100644 index 0000000000000000000000000000000000000000..d0021bda6709fdb9c82e5771d4d2c08bd339af0c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/spi_mngr/nrf_spi_mngr.h @@ -0,0 +1,302 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SPI_MNGR_H__ +#define NRF_SPI_MNGR_H__ + +#include +#include "nrf_drv_spi.h" +#include "sdk_errors.h" +#include "nrf_queue.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_spi_mngr SPI transaction manager + * @{ + * @ingroup app_common + * + * @brief Module for scheduling SPI transactions. + */ + + +/** + * @brief Macro for creating a simple SPI transfer. + * + * @param[in] _p_tx_data Pointer to the data to be sent. + * @param[in] _tx_length Number of bytes to send. + * @param[in] _p_rx_data Pointer to a buffer for received data. + * @param[in] _rx_length Number of bytes to receive. + */ +#define NRF_SPI_MNGR_TRANSFER(_p_tx_data, _tx_length, _p_rx_data, _rx_length) \ +{ \ + .p_tx_data = (uint8_t const *)_p_tx_data, \ + .tx_length = (uint8_t) _tx_length, \ + .p_rx_data = (uint8_t *) _p_rx_data, \ + .rx_length = (uint8_t) _rx_length, \ +} + + +/** + * @brief SPI transaction end callback prototype. + * + * @param result Result of operation (NRF_SUCCESS on success, + * otherwise a relevant error code). + * @param[in] p_user_data Pointer to user data defined in transaction + * descriptor. + */ +typedef void (* nrf_spi_mngr_callback_end_t)(ret_code_t result, void * p_user_data); + +/** + * @brief SPI transaction begin callback prototype. + * + * @param[in] p_user_data Pointer to user data defined in transaction + * descriptor. + */ +typedef void (* nrf_spi_mngr_callback_begin_t)(void * p_user_data); + + +/** + * @brief SPI transfer descriptor. + */ +typedef struct +{ + uint8_t const * p_tx_data; ///< Pointer to the data to be sent. + uint8_t tx_length; ///< Number of bytes to send. + uint8_t * p_rx_data; ///< Pointer to a buffer for received data. + uint8_t rx_length; ///< Number of bytes to receive. +} nrf_spi_mngr_transfer_t; + + +/** + * @brief SPI transaction descriptor. + */ +typedef struct +{ + nrf_spi_mngr_callback_begin_t begin_callback; + ///< User-specified function to be called before the transaction is started. + + nrf_spi_mngr_callback_end_t end_callback; + ///< User-specified function to be called after the transaction is finished. + + void * p_user_data; + ///< Pointer to user data to be passed to the end_callback. + + nrf_spi_mngr_transfer_t const * p_transfers; + ///< Pointer to the array of transfers that make up the transaction. + + uint8_t number_of_transfers; + ///< Number of transfers that make up the transaction. + + nrf_drv_spi_config_t const * p_required_spi_cfg; + ///< Pointer to instance hardware configuration. +} nrf_spi_mngr_transaction_t; + + +/** + * @brief SPI instance control block. + */ +typedef struct +{ + nrf_spi_mngr_transaction_t const * volatile p_current_transaction; + ///< Currently realized transaction. + + nrf_drv_spi_config_t default_configuration; + ///< Default hardware configuration. + + nrf_drv_spi_config_t const * p_current_configuration; + ///< Pointer to current hardware configuration. + + uint8_t volatile current_transfer_idx; + ///< Index of currently performed transfer (within current transaction). + + bool volatile internal_transaction_in_progress; + ///< Informs that an internal transaction is being performed (by nrf_spi_mngr_perform()). + + uint8_t volatile internal_transaction_result; + ///< Used to pass the result of the internal transaction realized by nrf_spi_mngr_perform(). +} nrf_spi_mngr_cb_t; + + +/** + * @brief SPI transaction manager instance. + */ +typedef struct +{ + nrf_spi_mngr_cb_t * p_nrf_spi_mngr_cb; + ///< Control block of instance. + + nrf_queue_t const * p_queue; + ///< Transaction queue. + + nrf_drv_spi_t spi; + ///< Pointer to SPI master driver instance. +} nrf_spi_mngr_t; + + +/** + * @brief Macro for simplifying the defining of an SPI transaction manager + * instance. + * + * This macro allocates a static buffer for the transaction queue. + * Therefore, it should be used in only one place in the code for a given + * instance. + * + * @note The queue size is the maximum number of pending transactions + * not counting the one that is currently realized. This means that + * for an empty queue with size of for example 4 elements, it is + * possible to schedule up to 5 transactions. + * + * @param[in] _nrf_spi_mngr_name Name of instance to be created. + * @param[in] _queue_size Size of the transaction queue (maximum number + * of pending transactions). + * @param[in] _spi_idx Index of hardware SPI instance to be used. + */ +#define NRF_SPI_MNGR_DEF(_nrf_spi_mngr_name, _queue_size, _spi_idx) \ + NRF_QUEUE_DEF(nrf_spi_mngr_transaction_t const *, \ + _nrf_spi_mngr_name##_queue, \ + (_queue_size), \ + NRF_QUEUE_MODE_NO_OVERFLOW); \ + static nrf_spi_mngr_cb_t CONCAT_2(_nrf_spi_mngr_name, _cb); \ + static const nrf_spi_mngr_t _nrf_spi_mngr_name = \ + { \ + .p_nrf_spi_mngr_cb = &CONCAT_2(_nrf_spi_mngr_name, _cb), \ + .p_queue = &_nrf_spi_mngr_name##_queue, \ + .spi = NRF_DRV_SPI_INSTANCE(_spi_idx) \ + } + + + /** + * @brief Function for initializing an SPI transaction manager instance. + * + * @param[in] p_nrf_spi_mngr Pointer to the instance to be initialized. + * @param[in] p_default_spi_config Pointer to the SPI driver configuration. This configuration + * will be used whenever the scheduled transaction will have + * p_spi_config set to NULL value. + * + * @return Values returned by the @ref nrf_drv_spi_init function. + */ +ret_code_t nrf_spi_mngr_init(nrf_spi_mngr_t const * p_nrf_spi_mngr, + nrf_drv_spi_config_t const * p_default_spi_config); + + +/** + * @brief Function for uninitializing an SPI transaction manager instance. + * + * @param[in] p_nrf_spi_mngr Pointer to the instance to be uninitialized. + */ +void nrf_spi_mngr_uninit(nrf_spi_mngr_t const * p_nrf_spi_mngr); + + +/** + * @brief Function for scheduling an SPI transaction. + * + * The transaction is enqueued and started as soon as the SPI bus is + * available, thus when all previously scheduled transactions have been + * finished (possibly immediately). + * + * @note If @ref nrf_spi_mngr_transaction_t::p_required_spi_cfg + * is set to a non-NULL value the module will compare it with + * @ref nrf_spi_mngr_cb_t::p_current_configuration and reinitialize hardware + * SPI instance with new parameters if any differences are found. + * If @ref nrf_spi_mngr_transaction_t::p_required_spi_cfg is set to NULL then + * it will treat it as it would be set to @ref nrf_spi_mngr_cb_t::default_configuration. + * + * @param[in] p_nrf_spi_mngr Pointer to the SPI transaction manager instance. + * @param[in] p_transaction Pointer to the descriptor of the transaction to be + * scheduled. + * + * @retval NRF_SUCCESS If the transaction has been successfully scheduled. + * @retval NRF_ERROR_NO_MEM If the queue is full (Only if queue in + * @ref NRF_QUEUE_MODE_NO_OVERFLOW). + */ +ret_code_t nrf_spi_mngr_schedule(nrf_spi_mngr_t const * p_nrf_spi_mngr, + nrf_spi_mngr_transaction_t const * p_transaction); + + +/** + * @brief Function for scheduling a transaction and waiting until it is finished. + * + * This function schedules a transaction that consists of one or more transfers + * and waits until it is finished. + * + * @param[in] p_nrf_spi_mngr Pointer to the SPI transaction manager instance. + * @param[in] p_transfers Pointer to an array of transfers to be performed. + * @param number_of_transfers Number of transfers to be performed. + * @param user_function User-specified function to be called while + * waiting. NULL if such functionality + * is not needed. + * + * @retval NRF_SUCCESS If the transfers have been successfully realized. + * @retval NRF_ERROR_BUSY If some transfers are already being performed. + * @retval - Other error codes mean that the transaction has failed + * with the error reported by @ref nrf_drv_spi_transfer(). + */ +ret_code_t nrf_spi_mngr_perform(nrf_spi_mngr_t const * p_nrf_spi_mngr, + nrf_spi_mngr_transfer_t const * p_transfers, + uint8_t number_of_transfers, + void (* user_function)(void)); + + +/** + * @brief Function for getting the current state of an SPI transaction manager + * instance. + * + * @param[in] p_nrf_spi_mngr Pointer to the SPI transaction manager instance. + * + * @retval true If all scheduled transactions have been finished. + * @retval false Otherwise. + */ +__STATIC_INLINE bool nrf_spi_mngr_is_idle(nrf_spi_mngr_t const * p_nrf_spi_mngr) +{ + return (p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction == NULL); +} + +/** + *@} + **/ +//typedef int p_current_transaction; + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SPI_MNGR_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/strerror/nrf_strerror.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/strerror/nrf_strerror.c new file mode 100644 index 0000000000000000000000000000000000000000..09e3fb0f20673075dfd5c658ee3c244c424b93d2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/strerror/nrf_strerror.c @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_STRERROR) +#include "nrf_strerror.h" + +/** + * @brief Macro for adding an entity to the description array. + * + * Macro that helps to create a single entity in the description array. + */ +#define NRF_STRERROR_ENTITY(mnemonic) {.code = mnemonic, .name = #mnemonic} + +/** + * @brief Array entity element that describes an error. + */ +typedef struct +{ + ret_code_t code; /**< Error code. */ + char const * name; /**< Descriptive name (the same as the internal error mnemonic). */ +}nrf_strerror_desc_t; + +/** + * @brief Unknown error code. + * + * The constant string used by @ref nrf_strerror_get when the error description was not found. + */ +static char const m_unknown_str[] = "Unknown error code"; + +/** + * @brief Array with error codes. + * + * Array that describes error codes. + * + * @note It is required for this array to have error codes placed in ascending order. + * This condition is checked in automatic unit test before the release. + */ +static nrf_strerror_desc_t const nrf_strerror_array[] = +{ + NRF_STRERROR_ENTITY(NRF_SUCCESS), + NRF_STRERROR_ENTITY(NRF_ERROR_SVC_HANDLER_MISSING), + NRF_STRERROR_ENTITY(NRF_ERROR_SOFTDEVICE_NOT_ENABLED), + NRF_STRERROR_ENTITY(NRF_ERROR_INTERNAL), + NRF_STRERROR_ENTITY(NRF_ERROR_NO_MEM), + NRF_STRERROR_ENTITY(NRF_ERROR_NOT_FOUND), + NRF_STRERROR_ENTITY(NRF_ERROR_NOT_SUPPORTED), + NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_PARAM), + NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_STATE), + NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_LENGTH), + NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_FLAGS), + NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_DATA), + NRF_STRERROR_ENTITY(NRF_ERROR_DATA_SIZE), + NRF_STRERROR_ENTITY(NRF_ERROR_TIMEOUT), + NRF_STRERROR_ENTITY(NRF_ERROR_NULL), + NRF_STRERROR_ENTITY(NRF_ERROR_FORBIDDEN), + NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_ADDR), + NRF_STRERROR_ENTITY(NRF_ERROR_BUSY), + + /* SDK Common errors */ + NRF_STRERROR_ENTITY(NRF_ERROR_MODULE_NOT_INITIALZED), + NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_INIT_FAILED), + NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_LOCK_FAILED), + NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_UNLOCK_FAILED), + NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_COND_INIT_FAILED), + NRF_STRERROR_ENTITY(NRF_ERROR_MODULE_ALREADY_INITIALIZED), + NRF_STRERROR_ENTITY(NRF_ERROR_STORAGE_FULL), + NRF_STRERROR_ENTITY(NRF_ERROR_API_NOT_IMPLEMENTED), + NRF_STRERROR_ENTITY(NRF_ERROR_FEATURE_NOT_ENABLED), + + /* TWI error codes */ + NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_OVERRUN), + NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_ANACK), + NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_DNACK) +}; + + +char const * nrf_strerror_get(ret_code_t code) +{ + char const * p_ret = nrf_strerror_find(code); + return (p_ret == NULL) ? m_unknown_str : p_ret; +} + +char const * nrf_strerror_find(ret_code_t code) +{ + nrf_strerror_desc_t const * p_start; + nrf_strerror_desc_t const * p_end; + p_start = nrf_strerror_array; + p_end = nrf_strerror_array + ARRAY_SIZE(nrf_strerror_array); + + while (p_start < p_end) + { + nrf_strerror_desc_t const * p_mid = p_start + ((p_end - p_start) / 2); + ret_code_t mid_c = p_mid->code; + if (mid_c > code) + { + p_end = p_mid; + } + else if (mid_c < code) + { + p_start = p_mid + 1; + } + else + { + return p_mid->name; + } + } + return NULL; +} + +#endif /* NRF_STRERROR enabled */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/strerror/nrf_strerror.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/strerror/nrf_strerror.h new file mode 100644 index 0000000000000000000000000000000000000000..5c60a5cad95922b12f968298c3ca737b00a50b5a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/strerror/nrf_strerror.h @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/** + * @defgroup nrf_strerror Error code to string converter + * @ingroup app_common + * + * @brief Module for converting error code into a printable string. + * @{ + */ +#ifndef NRF_STRERROR_H__ +#define NRF_STRERROR_H__ + +#include "sdk_errors.h" + +/** + * @brief Function for getting a printable error string. + * + * @param code Error code to convert. + * + * @note This function cannot fail. + * For the function that may fail with error translation, see @ref nrf_strerror_find. + * + * @return Pointer to the printable string. + * If the string is not found, + * it returns a simple string that says that the error is unknown. + */ +char const * nrf_strerror_get(ret_code_t code); + +/** + * @brief Function for finding a printable error string. + * + * This function gets the error string in the same way as @ref nrf_strerror_get, + * but if the string is not found, it returns NULL. + * + * @param code Error code to convert. + * @return Pointer to the printable string. + * If the string is not found, NULL is returned. + */ +char const * nrf_strerror_find(ret_code_t code); + +/** @} */ + +#endif /* NRF_STRERROR_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/svc/nrf_svc_function.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/svc/nrf_svc_function.h new file mode 100644 index 0000000000000000000000000000000000000000..1424249a299130ade00abcbbc8fb17eb98610f44 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/svc/nrf_svc_function.h @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SVC_FUNCTION_H__ +#define NRF_SVC_FUNCTION_H__ + +#include +#include "nrf_section.h" +#include "app_util.h" +#include "nrf_svci.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Function to be called from an SVC handler. + * + * @warning The function prototype must be limited to a maximum of four arguments, due to the nature of SVC calls. + */ +typedef uint32_t (*nrf_svc_func_t)(); + +/** @brief Type holding the SVC number and the pointer to the corresponding function. + * + * Not that the function that is pointed to must not change version. + */ +typedef struct +{ + uint32_t svc_num; /**< Supervisor call number (actually 8-bit, padded for alignment). */ + uint32_t svci_num; /**< Supervisor call indirect number. */ + nrf_svc_func_t func_ptr; +} nrf_svc_func_reg_t; + + +// Verify that the size of nrf_svc_func_t is aligned. +STATIC_ASSERT(sizeof(nrf_svc_func_reg_t) % 4 == 0); + + +/** @brief Macro for registering a structure holding SVC number and function pointer. + * + * @details This macro places the variable in a section named "svc_data" that + the SVC handler uses during regular operation. + */ +#define SVC_REGISTER_FUNCTION(svc_var) NRF_SECTION_ITEM_REGISTER(svc_data, svc_var) + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SVC_FUNCTION_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/svc/nrf_svc_handler.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/svc/nrf_svc_handler.c new file mode 100644 index 0000000000000000000000000000000000000000..932bb8188272faa62a9171129e737d745c309abf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/svc/nrf_svc_handler.c @@ -0,0 +1,176 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "nrf_svc_function.h" +#include "nrf_error.h" + +#include "nrf_log.h" + +NRF_SECTION_DEF(svc_data, const nrf_svc_func_t); +#define SVC_DATA_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(svc_data, nrf_svc_func_reg_t, (i)) +#define SVC_DATA_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(svc_data, nrf_svc_func_reg_t) + + +/**@brief Function for handling second stage of SuperVisor Calls (SVC). +* +* @details The function will use loop through the registered svc functions stored +* in the named section "svc_data" and will call the registered function +* if the svn_num corresponds with the registration. +* +* @param[in] svc_num SVC number for function to be executed +* @param[in] p_svc_args Argument list for the SVC. +* +* @return This function returns by updating p_svc_arsg[0]. This will be reported back to the caller of SVC +* @ref NRF_ERROR_SVC_HANDLER_MISSING is returned if no SVC handler is implemented for the +* provided svc_num. +*/ +void nrf_svc_handler_c(uint8_t svc_num, uint32_t * p_svc_args) +{ + uint32_t const num_funcs = SVC_DATA_SECTION_ITEM_COUNT; + bool handled = false; + uint32_t svci_num = NRF_SVCI_SVC_NUM_INVALID; + + if(svc_num == NRF_SVCI_SVC_NUM) + { + /* load the stacked R12 as the svci_num */ + svci_num = p_svc_args[4]; + } + + for (int i = 0; i < num_funcs; i++) + { + nrf_svc_func_reg_t const * func_reg = SVC_DATA_SECTION_ITEM_GET(i); + if (func_reg->svc_num != svc_num) + { + continue; + } + + if(svci_num != NRF_SVCI_SVC_NUM_INVALID && func_reg->svci_num != svci_num) + { + continue; + } + + p_svc_args[0] = func_reg->func_ptr(p_svc_args[0], p_svc_args[1], p_svc_args[2], p_svc_args[3]); + handled = true; + } + + if (handled == false) + { + p_svc_args[0] = NRF_ERROR_SVC_HANDLER_MISSING; + } +} + +/**@brief Function for handling the first stage of SuperVisor Calls (SVC) in assembly. +* +* @details The function will use the link register (LR) to determine the stack (PSP or MSP) to be +* used and then decode the SVC number afterwards. After decoding the SVC number then +* @ref C_SVC_Handler is called for further processing of the SVC. +*/ +#if defined ( __CC_ARM ) +__ASM void SVC_Handler(void) +{ +EXC_RETURN_CMD_PSP EQU 0xFFFFFFFD ; EXC_RETURN using PSP for ARM Cortex.If Link register contains this value it indicates the PSP was used before the SVC, otherwise the MSP was used. + + IMPORT nrf_svc_handler_c + LDR R0, =EXC_RETURN_CMD_PSP ; Load the EXC_RETURN into R0 to be able to compare against LR to determine stack pointer used. + CMP R0, LR ; Compare the link register with R0.If equal then PSP was used, otherwise MSP was used before SVC. + BNE UseMSP ; Branch to code fetching SVC arguments using MSP. + MRS R1, PSP ; Move PSP into R1. + B Call_nrf_svc_handler_c ; Branch to call_nrf_svc_handler_c below. +UseMSP ; + MRS R1, MSP ; MSP was used, therefore Move MSP into R1. +Call_nrf_svc_handler_c ; + LDR R0, [R1, #24] ; The arguments for the SVC was stacked.R1 contains Stack Pointer, the values stacked before SVC are R0, R1, R2, R3, R12, LR, PC(Return address), xPSR. + ; R1 contains current SP so the PC of the stacked frame is at SP + 6 words(24 bytes).We load the PC into R0. + SUBS R0, #2 ; The PC before the SVC is in R0.We subtract 2 to get the address prior to the instruction executed where the SVC number is located. + LDRB R0, [R0] ; SVC instruction low octet : Load the byte at the address before the PC to fetch the SVC number. + LDR R2, =nrf_svc_handler_c ; Load address of C implementation of SVC handler. + BX R2 ; Branch to C implementation of SVC handler.R0 is now the SVC number, R1 is the StackPointer where the arguments(R0 - R3) of the original SVC are located. + ALIGN +} +#elif defined ( __GNUC__ ) +void __attribute__((naked)) SVC_Handler(void) +{ + const uint32_t exc_return = 0xFFFFFFFD; // EXC_RETURN using PSP for ARM Cortex. If Link register contains this value it indicates the PSP was used before the SVC, otherwise the MSP was used. + + __ASM volatile( + "cmp lr, %0\t\n" // Compare the link register with argument 0 (%0), which is exc_return. If equal then PSP was used, otherwise MSP was used before SVC. + "bne UseMSP\t\n" // Branch to code fetching SVC arguments using MSP. + "mrs r1, psp\t\n" // Move PSP into R1. + "b Call_nrf_svc_handler_c\t\n" // Branch to Call_nrf_svc_handler_c below. + "UseMSP:\t\n" // + "mrs r1, msp\t\n" // MSP was used, therefore Move MSP into R1. + "Call_nrf_svc_handler_c:\t\n" // + "ldr r0, [r1, #24]\t\n" // The arguments for the SVC was stacked. R1 contains Stack Pointer, the values stacked before SVC are R0, R1, R2, R3, R12, LR, PC (Return address), xPSR. + // R1 contains current SP so the PC of the stacked frame is at SP + 6 words (24 bytes). We load the PC into R0. + "sub r0, r0, #2\t\n" // The PC before the SVC is in R0. We subtract 2 to get the address prior to the instruction executed where the SVC number is located. + "ldrb r0, [r0]\t\n" // SVC instruction low octet: Load the byte at the address before the PC to fetch the SVC number. + "bx %1\t\n" // Branch to C implementation of SVC handler, argument 1 (%1). R0 is now the SVC number, R1 is the StackPointer where the arguments (R0-R3) of the original SVC are located. + ".align\t\n" // + :: "r" (exc_return), "r" (nrf_svc_handler_c) // Argument list for the gcc assembly. exc_return is %0, nrf_svc_handler_c is %1. + : "r0", "r1" // List of register maintained manually. + ); +} +#elif defined ( __ICCARM__ ) +void SVC_Handler(void) +{ + __ASM("movs r0, #0x02\n" // Load 0x02 into R6 to prepare for exec return test. + "mvns r0, r0\n" // Invert R0 to obtain exec return code using PSP for ARM Cortex. + "cmp lr, r0\n" // Compare the link register with argument 0 (%0), which is exc_return. If equal then PSP was used, otherwise MSP was used before SVC. + "bne.n UseMSP\n" // Branch to code fetching SVC arguments using MSP. + "mrs r1, psp\n" // Move PSP into R1. + "b.n Call_nrf_svc_handler_c\t\n" // Branch to Call_nrf_svc_handler_c below. + "UseMSP: \n" // + "mrs r1, msp\n" // MSP was used, therefore Move MSP into R1. + "Call_nrf_svc_handler_c: \n" // + "ldr r0, [r1, #24]\n" // The arguments for the SVC was stacked. R1 contains Stack Pointer, the values stacked before SVC are R0, R1, R2, R3, R12, LR, PC (Return address), xPSR. + // R1 contains current SP so the PC of the stacked frame is at SP + 6 words (24 bytes). We load the PC into R0. + "subs r0, #0x02\n" // The PC before the SVC is in R0. We subtract 2 to get the address prior to the instruction executed where the SVC number is located. + "ldrb r0, [r0]\n" // SVC instruction low octet: Load the byte at the address before the PC to fetch the SVC number. + "bx %0\n" // Branch to C implementation of SVC handler, argument 1 (%1). R0 is now the SVC number, R1 is the StackPointer where the arguments (R0-R3) of the original SVC are located. + :: "r" (nrf_svc_handler_c) // Argument list for the gcc assembly. nrf_svc_handler_c is %0. + : "r0", "r1" // List of register maintained manually. + ); +} +#else + +#error Compiler not supported. + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/svc/nrf_svci.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/svc/nrf_svci.h new file mode 100644 index 0000000000000000000000000000000000000000..30c3866d0bfbfb8d4cdd6afb37a603c666a944c6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/svc/nrf_svci.h @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef NRF_SVCI_H__ +#define NRF_SVCI_H__ + +#include "stdint.h" +#include "compiler_abstraction.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_SVCI_SVC_NUM 0 /**< SVC number used for all SVCI functions. */ +#define NRF_SVCI_SVC_NUM_INVALID (0xFFFFFFFF) /**< Invalid SVCI number. */ + + +#if defined (__CC_ARM) + + #define SVCI_DECL(svci_num, return_type, function_name, ...) \ + return_type __svc_indirect(NRF_SVCI_SVC_NUM) svci_##function_name(uint32_t _svci_num, ##__VA_ARGS__); + +#elif defined (__GNUC__) + + #ifdef __cplusplus + #define GCC_CAST_CPP (uint8_t) + #else + #define GCC_CAST_CPP + #endif + + #define SVCI_DECL(svci_num, return_type, function_name, ...) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ + __attribute__((naked, unused)) \ + static return_type function_name(uint32_t svci_num, \ + __VA_ARGS__) \ + { \ + __asm __volatile ( \ + "mov r12, %1\n\t" \ + "svc %0\n\t" \ + "bx r14\n\t" \ + : /* no output */ \ + : "I" (GCC_CAST_CPP NRF_SVCI_SVC_NUM), "r" (svci_num) \ + : "r12" /* do we need to clobber? */ \ + ); \ + } \ + _Pragma("GCC diagnostic pop") + +#elif defined (__ICCARM__) + + #define SVCI_DECL(svci_num, return_type, function_name, ...) \ + /* Suppress return value warming. */ \ + _Pragma("diag_suppress=Pe940") \ + static return_type function_name(uint32_t svci_num, \ + __VA_ARGS__) \ + { \ + __asm volatile ( \ + "mov r12, %1\n\t" \ + "svc %0\n\t" \ + "bx r14\n\t" \ + : /* no output */ \ + : "I" (NRF_SVCI_SVC_NUM), "r" (svci_num) \ + : "r12" /* do we need to clobber? */ \ + ); \ + } + +#else + + #define SVCI_DECL(svci_number, return_type, function_name, ...) + +#endif + +#define VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, N, ...) N +#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 4, 4, 3, 3, 2, 2, 1, 1, 0) + +#ifdef SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION + +#define SVCI_0(svci_num, return_type, function_name) \ + return_type function_name(void) +#define SVCI_1(svci_num, return_type, function_name, p0t, p0n) \ + return_type function_name(p0t p0n) +#define SVCI_2(svci_num, return_type, function_name, p0t, p0n, p1t, p1n) \ + return_type function_name(p0t p0n, p1t p1n) +#define SVCI_3(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n) \ + return_type function_name(p0t p0n, p1t p1n, p2t p2n) +#define SVCI_4(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n, p3t, p3n) \ + return_type function_name(p0t p0n, p1t p1n, p2t p2n, p3t p3n) + +#else + +#define SVCI_0(svci_num, return_type, function_name) \ + SVCI_DECL(svci_num, return_type, function_name) \ + static __INLINE return_type function_name(void) {return svci_##function_name(svci_num);} + +#define SVCI_1(svci_num, return_type, function_name, p0t, p0n) \ + SVCI_DECL(svci_num, return_type, function_name, p0t p0n) \ + static __INLINE return_type function_name(p0t p0n) {return svci_##function_name(svci_num, p0n);} + +#define SVCI_2(svci_num, return_type, function_name, p0t, p0n, p1t, p1n) \ + SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n) \ + static __INLINE return_type function_name(p0t p0n, p1t p1n) {return svci_##function_name(svci_num, p0n, p1n);} + +#define SVCI_3(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n) \ + SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n) \ + static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n) {return svci_##function_name(svci_num, p0n, p1n, p2n);} + +#define SVCI_4(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n, p3t, p3n) \ + SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n, p3t p3n) \ + static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n, p3t p3n) {return svci_##function_name(svci_num, p0n, p1n, p2n, p3n);} + +#endif // SVCALL_AS_NORMAL_FUNCTION + +#define SVCI_IMPLI(count, svci_num, return_type, function_name, ...) SVCI##_##count (svci_num, return_type, function_name, ##__VA_ARGS__) +#define SVCI_IMPL(count, svci_num, return_type, function_name, ...) SVCI_IMPLI(count, svci_num, return_type, function_name, ##__VA_ARGS__) +#define SVCI(svci_num, return_type, function_name, ...) SVCI_IMPL(VA_NARGS(__VA_ARGS__), svci_num, return_type, function_name, ##__VA_ARGS__) + + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SVCI_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..826d19261faccbad462773d90a2c1ced3271806a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer.c @@ -0,0 +1,1070 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_TIMER) +#include "app_timer.h" +#include +#include "nrf.h" +#include "nrf_soc.h" +#include "app_error.h" +#include "nrf_delay.h" +#include "app_util_platform.h" +#if APP_TIMER_CONFIG_USE_SCHEDULER +#include "app_scheduler.h" +#endif + +#define RTC1_IRQ_PRI APP_TIMER_CONFIG_IRQ_PRIORITY /**< Priority of the RTC1 interrupt (used for checking for timeouts and executing timeout handlers). */ +#define SWI_IRQ_PRI APP_TIMER_CONFIG_IRQ_PRIORITY /**< Priority of the SWI interrupt (used for updating the timer list). */ + +// The current design assumes that both interrupt handlers run at the same interrupt level. +// If this is to be changed, protection must be added to prevent them from interrupting each other +// (e.g. by using guard/trigger flags). +STATIC_ASSERT(RTC1_IRQ_PRI == SWI_IRQ_PRI); + +#define MAX_RTC_COUNTER_VAL 0x00FFFFFF /**< Maximum value of the RTC counter. */ + +#define RTC_COMPARE_OFFSET_MIN 3 /**< Minimum offset between the current RTC counter value and the Capture Compare register. Although the nRF51 Series User Specification recommends this value to be 2, we use 3 to be safer.*/ + +#define MAX_RTC_TASKS_DELAY 47 /**< Maximum delay until an RTC task is executed. */ + +#if (APP_TIMER_CONFIG_SWI_NUMBER == 0) +#define SWI_IRQn SWI0_IRQn +#define SWI_IRQHandler SWI0_IRQHandler +#elif (APP_TIMER_CONFIG_SWI_NUMBER == 1) +#define SWI_IRQn SWI1_IRQn +#define SWI_IRQHandler SWI1_IRQHandler +#else +#error "Unsupported SWI number." +#endif + +#define MODULE_INITIALIZED (m_op_queue.size != 0) /**< Macro designating whether the module has been initialized properly. */ + +/**@brief Timer node type. The nodes will be used form a linked list of running timers. */ +typedef struct +{ + uint32_t ticks_to_expire; /**< Number of ticks from previous timer interrupt to timer expiry. */ + uint32_t ticks_at_start; /**< Current RTC counter value when the timer was started. */ + uint32_t ticks_first_interval; /**< Number of ticks in the first timer interval. */ + uint32_t ticks_periodic_interval; /**< Timer period (for repeating timers). */ + bool is_running; /**< True if timer is running, False otherwise. */ + app_timer_mode_t mode; /**< Timer mode. */ + app_timer_timeout_handler_t p_timeout_handler; /**< Pointer to function to be executed when the timer expires. */ + void * p_context; /**< General purpose pointer. Will be passed to the timeout handler when the timer expires. */ + void * next; /**< Pointer to the next node. */ +} timer_node_t; + +STATIC_ASSERT(sizeof(timer_node_t) == APP_TIMER_NODE_SIZE); + +/**@brief Set of available timer operation types. */ +typedef enum +{ + TIMER_USER_OP_TYPE_NONE, /**< Invalid timer operation type. */ + TIMER_USER_OP_TYPE_START, /**< Timer operation type Start. */ + TIMER_USER_OP_TYPE_STOP, /**< Timer operation type Stop. */ + TIMER_USER_OP_TYPE_STOP_ALL /**< Timer operation type Stop All. */ +} timer_user_op_type_t; + +/**@brief Structure describing a timer start operation. */ +typedef struct +{ + uint32_t ticks_at_start; /**< Current RTC counter value when the timer was started. */ + uint32_t ticks_first_interval; /**< Number of ticks in the first timer interval. */ + uint32_t ticks_periodic_interval; /**< Timer period (for repeating timers). */ + void * p_context; /**< General purpose pointer. Will be passed to the timeout handler when the timer expires. */ +} timer_user_op_start_t; + +/**@brief Structure describing a timer operation. */ +typedef struct +{ + timer_user_op_type_t op_type; /**< Id of timer on which the operation is to be performed. */ + timer_node_t * p_node; + union + { + timer_user_op_start_t start; /**< Structure describing a timer start operation. */ + } params; +} timer_user_op_t; + +/**@brief Structure describing a timer operations queue. + * + * @details This queue will hold timer operations issued by the application + * until the timer interrupt handler processes these operations. + */ +typedef struct +{ + uint8_t first; /**< Index of first entry to have been inserted in the queue (i.e. the next entry to be executed). */ + uint8_t last; /**< Index of last entry to have been inserted in the queue. */ + uint8_t size; /**< Queue size. */ + timer_user_op_t user_op_queue[APP_TIMER_CONFIG_OP_QUEUE_SIZE+1]; /**< Queue buffer. */ +} timer_op_queue_t; + +STATIC_ASSERT(sizeof(timer_op_queue_t) % 4 == 0); + +#define CONTEXT_QUEUE_SIZE_MAX (2) + +static timer_op_queue_t m_op_queue; /**< Timer operations queue. */ +static timer_node_t * mp_timer_id_head; /**< First timer in list of running timers. */ +static uint32_t m_ticks_latest; /**< Last known RTC counter value. */ +static uint32_t m_ticks_elapsed[CONTEXT_QUEUE_SIZE_MAX]; /**< Timer internal elapsed ticks queue. */ +static uint8_t m_ticks_elapsed_q_read_ind; /**< Timer internal elapsed ticks queue read index. */ +static uint8_t m_ticks_elapsed_q_write_ind; /**< Timer internal elapsed ticks queue write index. */ +static bool m_rtc1_running; /**< Boolean indicating if RTC1 is running. */ +static bool m_rtc1_reset; /**< Boolean indicating if RTC1 counter has been reset due to last timer removed from timer list during the timer list handling. */ + +#if APP_TIMER_WITH_PROFILER +static uint8_t m_max_user_op_queue_utilization; /**< Maximum observed timer user operations queue utilization. */ +#endif + +/**@brief Function for initializing the RTC1 counter. + * + * @param[in] prescaler Value of the RTC1 PRESCALER register. Set to 0 for no prescaling. + */ +static void rtc1_init(uint32_t prescaler) +{ + NRF_RTC1->PRESCALER = prescaler; + NVIC_SetPriority(RTC1_IRQn, RTC1_IRQ_PRI); +} + + +/**@brief Function for starting the RTC1 timer. + */ +static void rtc1_start(void) +{ + NRF_RTC1->EVTENSET = RTC_EVTEN_COMPARE0_Msk; + NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk; + + NVIC_ClearPendingIRQ(RTC1_IRQn); + NVIC_EnableIRQ(RTC1_IRQn); + + NRF_RTC1->TASKS_START = 1; + nrf_delay_us(MAX_RTC_TASKS_DELAY); + + m_rtc1_running = true; +} + + +/**@brief Function for stopping the RTC1 timer. + */ +static void rtc1_stop(void) +{ + NVIC_DisableIRQ(RTC1_IRQn); + + NRF_RTC1->EVTENCLR = RTC_EVTEN_COMPARE0_Msk; + NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk; + + NRF_RTC1->TASKS_STOP = 1; + nrf_delay_us(MAX_RTC_TASKS_DELAY); + + NRF_RTC1->TASKS_CLEAR = 1; + m_ticks_latest = 0; + nrf_delay_us(MAX_RTC_TASKS_DELAY); + + m_rtc1_running = false; +} + + +/**@brief Function for returning the current value of the RTC1 counter. + * + * @return Current value of the RTC1 counter. + */ +static __INLINE uint32_t rtc1_counter_get(void) +{ + return NRF_RTC1->COUNTER; +} + + +/**@brief Function for computing the difference between two RTC1 counter values. + * + * @return Number of ticks elapsed from ticks_old to ticks_now. + */ +static __INLINE uint32_t ticks_diff_get(uint32_t ticks_now, uint32_t ticks_old) +{ + return ((ticks_now - ticks_old) & MAX_RTC_COUNTER_VAL); +} + + +/**@brief Function for setting the RTC1 Capture Compare register 0, and enabling the corresponding + * event. + * + * @param[in] value New value of Capture Compare register 0. + */ +static __INLINE void rtc1_compare0_set(uint32_t value) +{ + NRF_RTC1->CC[0] = value; +} + + +/**@brief Function for inserting a timer in the timer list. + * + * @param[in] timer_id Id of timer to insert. + */ +static void timer_list_insert(timer_node_t * p_timer) +{ + if (mp_timer_id_head == NULL) + { + mp_timer_id_head = p_timer; + } + else + { + if (p_timer->ticks_to_expire <= mp_timer_id_head->ticks_to_expire) + { + mp_timer_id_head->ticks_to_expire -= p_timer->ticks_to_expire; + + p_timer->next = mp_timer_id_head; + mp_timer_id_head = p_timer; + } + else + { + timer_node_t * p_previous; + timer_node_t * p_current; + uint32_t ticks_to_expire; + + ticks_to_expire = p_timer->ticks_to_expire; + p_previous = mp_timer_id_head; + p_current = mp_timer_id_head; + + while ((p_current != NULL) && (ticks_to_expire > p_current->ticks_to_expire)) + { + ticks_to_expire -= p_current->ticks_to_expire; + p_previous = p_current; + p_current = p_current->next; + } + + if (p_current != NULL) + { + p_current->ticks_to_expire -= ticks_to_expire; + } + + p_timer->ticks_to_expire = ticks_to_expire; + p_timer->next = p_current; + p_previous->next = p_timer; + } + } +} + + +/**@brief Function for removing a timer from the timer queue. + * + * @param[in] timer_id Id of timer to remove. + * + * @return TRUE if Capture Compare register must be updated, FALSE otherwise. + */ +static bool timer_list_remove(timer_node_t * p_timer) +{ + timer_node_t * p_old_head; + timer_node_t * p_previous; + timer_node_t * p_current; + uint32_t timeout; + + // Find the timer's position in timer list. + p_old_head = mp_timer_id_head; + p_previous = mp_timer_id_head; + p_current = p_previous; + + while (p_current != NULL) + { + if (p_current == p_timer) + { + break; + } + p_previous = p_current; + p_current = p_current->next; + } + + // Timer not in active list. + if (p_current == NULL) + { + return false; + } + + // Timer is the first in the list + if (p_previous == p_current) + { + mp_timer_id_head = mp_timer_id_head->next; + + // No more timers in the list. Reset RTC1 in case Start timer operations are present in the queue. + if (mp_timer_id_head == NULL) + { + NRF_RTC1->TASKS_CLEAR = 1; + m_ticks_latest = 0; + m_rtc1_reset = true; + nrf_delay_us(MAX_RTC_TASKS_DELAY); + } + } + + // Remaining timeout between next timeout. + timeout = p_current->ticks_to_expire; + + // Link previous timer with next of this timer, i.e. removing the timer from list. + p_previous->next = p_current->next; + + // If this is not the last timer, increment the next timer by this timer timeout. + p_current = p_previous->next; + if (p_current != NULL) + { + p_current->ticks_to_expire += timeout; + } + + return (p_old_head != mp_timer_id_head); +} + + +/**@brief Function for scheduling a check for timeouts by generating a RTC1 interrupt. + */ +static void timer_timeouts_check_sched(void) +{ + NVIC_SetPendingIRQ(RTC1_IRQn); +} + + +/**@brief Function for scheduling a timer list update by generating a SWI interrupt. + */ +static void timer_list_handler_sched(void) +{ + NVIC_SetPendingIRQ(SWI_IRQn); +} + +#if APP_TIMER_CONFIG_USE_SCHEDULER +static void timeout_handler_scheduled_exec(void * p_event_data, uint16_t event_size) +{ + APP_ERROR_CHECK_BOOL(event_size == sizeof(app_timer_event_t)); + app_timer_event_t const * p_timer_event = (app_timer_event_t *)p_event_data; + + p_timer_event->timeout_handler(p_timer_event->p_context); +} +#endif + +/**@brief Function for executing an application timeout handler, either by calling it directly, or + * by passing an event to the @ref app_scheduler. + * + * @param[in] p_timer Pointer to expired timer. + */ +static void timeout_handler_exec(timer_node_t * p_timer) +{ +#if APP_TIMER_CONFIG_USE_SCHEDULER + app_timer_event_t timer_event; + + timer_event.timeout_handler = p_timer->p_timeout_handler; + timer_event.p_context = p_timer->p_context; + uint32_t err_code = app_sched_event_put(&timer_event, sizeof(timer_event), timeout_handler_scheduled_exec); + APP_ERROR_CHECK(err_code); +#else + p_timer->p_timeout_handler(p_timer->p_context); +#endif +} + + +/**@brief Function for checking for expired timers. + */ +static void timer_timeouts_check(void) +{ + // Handle expired of timer + if (mp_timer_id_head != NULL) + { + timer_node_t * p_timer; + timer_node_t * p_previous_timer; + uint32_t ticks_elapsed; + uint32_t ticks_expired; + + // Initialize actual elapsed ticks being consumed to 0. + ticks_expired = 0; + + // ticks_elapsed is collected here, job will use it. + ticks_elapsed = ticks_diff_get(rtc1_counter_get(), m_ticks_latest); + + // Auto variable containing the head of timers expiring. + p_timer = mp_timer_id_head; + + // Expire all timers within ticks_elapsed and collect ticks_expired. + while (p_timer != NULL) + { + // Do nothing if timer did not expire. + if (ticks_elapsed < p_timer->ticks_to_expire) + { + break; + } + + // Decrement ticks_elapsed and collect expired ticks. + ticks_elapsed -= p_timer->ticks_to_expire; + ticks_expired += p_timer->ticks_to_expire; + + // Move to next timer. + p_previous_timer = p_timer; + p_timer = p_timer->next; + + // Execute Task. + if (p_previous_timer->is_running) + { + p_previous_timer->is_running = false; + timeout_handler_exec(p_previous_timer); + } + } + + // Prepare to queue the ticks expired in the m_ticks_elapsed queue. + if (m_ticks_elapsed_q_read_ind == m_ticks_elapsed_q_write_ind) + { + // The read index of the queue is equal to the write index. This means the new + // value of ticks_expired should be stored at a new location in the m_ticks_elapsed + // queue (which is implemented as a double buffer). + + // Check if there will be a queue overflow. + if (++m_ticks_elapsed_q_write_ind == CONTEXT_QUEUE_SIZE_MAX) + { + // There will be a queue overflow. Hence the write index should point to the start + // of the queue. + m_ticks_elapsed_q_write_ind = 0; + } + } + + // Queue the ticks expired. + m_ticks_elapsed[m_ticks_elapsed_q_write_ind] = ticks_expired; + + timer_list_handler_sched(); + } +} + + +/**@brief Function for acquiring the number of ticks elapsed. + * + * @param[out] p_ticks_elapsed Number of ticks elapsed. + * + * @return TRUE if elapsed ticks was read from queue, FALSE otherwise. + */ +static bool elapsed_ticks_acquire(uint32_t * p_ticks_elapsed) +{ + // Pick the elapsed value from queue. + if (m_ticks_elapsed_q_read_ind != m_ticks_elapsed_q_write_ind) + { + // Dequeue elapsed value. + m_ticks_elapsed_q_read_ind++; + if (m_ticks_elapsed_q_read_ind == CONTEXT_QUEUE_SIZE_MAX) + { + m_ticks_elapsed_q_read_ind = 0; + } + + *p_ticks_elapsed = m_ticks_elapsed[m_ticks_elapsed_q_read_ind]; + + m_ticks_latest += *p_ticks_elapsed; + m_ticks_latest &= MAX_RTC_COUNTER_VAL; + + return true; + } + else + { + // No elapsed value in queue. + *p_ticks_elapsed = 0; + return false; + } +} + + +/**@brief Function for updating the timer list for expired timers. + * + * @param[in] ticks_elapsed Number of elapsed ticks. + * @param[in] ticks_previous Previous known value of the RTC counter. + * @param[out] p_restart_list_head List of repeating timers to be restarted. + */ +static void expired_timers_handler(uint32_t ticks_elapsed, + uint32_t ticks_previous, + timer_node_t ** p_restart_list_head) +{ + uint32_t ticks_expired = 0; + + while (mp_timer_id_head != NULL) + { + timer_node_t * p_timer; + timer_node_t * p_timer_expired; + + // Auto variable for current timer node. + p_timer = mp_timer_id_head; + + // Do nothing if timer did not expire + if (ticks_elapsed < p_timer->ticks_to_expire) + { + p_timer->ticks_to_expire -= ticks_elapsed; + break; + } + + // Decrement ticks_elapsed and collect expired ticks. + ticks_elapsed -= p_timer->ticks_to_expire; + ticks_expired += p_timer->ticks_to_expire; + + // Timer expired, set ticks_to_expire zero. + p_timer->ticks_to_expire = 0; + + // Remove the expired timer from head. + p_timer_expired = mp_timer_id_head; + mp_timer_id_head = p_timer->next; + + // Timer will be restarted if periodic. + if (p_timer->ticks_periodic_interval != 0) + { + p_timer->ticks_at_start = (ticks_previous + ticks_expired) & MAX_RTC_COUNTER_VAL; + p_timer->ticks_first_interval = p_timer->ticks_periodic_interval; + p_timer->next = *p_restart_list_head; + *p_restart_list_head = p_timer_expired; + } + } +} + + +/**@brief Function for handling timer list insertions. + * + * @param[in] p_restart_list_head List of repeating timers to be restarted. + * + * @return TRUE if Capture Compare register must be updated, FALSE otherwise. + */ +static bool list_insertions_handler(timer_node_t * p_restart_list_head) +{ + bool compare_update = false; + + timer_node_t * p_timer_id_old_head; + + // Remember the old head, so as to decide if new compare needs to be set. + p_timer_id_old_head = mp_timer_id_head; + + // Handle insertions of timers. + while ((p_restart_list_head != NULL) || (m_op_queue.first != m_op_queue.last)) + { + timer_node_t * p_timer; + + if (p_restart_list_head != NULL) + { + p_timer = p_restart_list_head; + p_restart_list_head = p_timer->next; + } + else + { + timer_user_op_t * p_user_op = &m_op_queue.user_op_queue[m_op_queue.first]; + + m_op_queue.first++; + if (m_op_queue.first == m_op_queue.size) + { + m_op_queue.first = 0; + } + + p_timer = p_user_op->p_node; + + switch (p_user_op->op_type) + { + case TIMER_USER_OP_TYPE_STOP: + // Delete node if timer is running. + if (timer_list_remove(p_user_op->p_node)) + { + compare_update = true; + } + + p_timer->is_running = false; + continue; + + case TIMER_USER_OP_TYPE_STOP_ALL: + // Delete list of running timers, and mark all timers as not running. + while (mp_timer_id_head != NULL) + { + timer_node_t * p_head = mp_timer_id_head; + + p_head->is_running = false; + mp_timer_id_head = p_head->next; + } + continue; + case TIMER_USER_OP_TYPE_START: + break; + default: + // No implementation needed. + continue; + } + + if (p_timer->is_running) + { + continue; + } + + p_timer->ticks_at_start = p_user_op->params.start.ticks_at_start; + p_timer->ticks_first_interval = p_user_op->params.start.ticks_first_interval; + p_timer->ticks_periodic_interval = p_user_op->params.start.ticks_periodic_interval; + p_timer->p_context = p_user_op->params.start.p_context; + + if (m_rtc1_reset) + { + p_timer->ticks_at_start = 0; + } + } + + // Prepare the node to be inserted. + if ( + ((p_timer->ticks_at_start - m_ticks_latest) & MAX_RTC_COUNTER_VAL) + < + (MAX_RTC_COUNTER_VAL / 2) + ) + { + p_timer->ticks_to_expire = ticks_diff_get(p_timer->ticks_at_start, m_ticks_latest) + + p_timer->ticks_first_interval; + } + else + { + uint32_t delta_current_start; + + delta_current_start = ticks_diff_get(m_ticks_latest, p_timer->ticks_at_start); + if (p_timer->ticks_first_interval > delta_current_start) + { + p_timer->ticks_to_expire = p_timer->ticks_first_interval - delta_current_start; + } + else + { + p_timer->ticks_to_expire = 0; + } + } + + p_timer->ticks_at_start = 0; + p_timer->ticks_first_interval = 0; + p_timer->is_running = true; + p_timer->next = NULL; + + // Insert into list + timer_list_insert(p_timer); + } + + return (compare_update || (mp_timer_id_head != p_timer_id_old_head)); +} + + +/**@brief Function for updating the Capture Compare register. + */ +static void compare_reg_update(timer_node_t * p_timer_id_head_old) +{ + // Setup the timeout for timers on the head of the list + if (mp_timer_id_head != NULL) + { + uint32_t ticks_to_expire = mp_timer_id_head->ticks_to_expire; + uint32_t pre_counter_val = rtc1_counter_get(); + uint32_t cc = m_ticks_latest; + uint32_t ticks_elapsed = ticks_diff_get(pre_counter_val, cc) + RTC_COMPARE_OFFSET_MIN; + + if (!m_rtc1_running) + { + // No timers were already running, start RTC + rtc1_start(); + } + + cc += (ticks_elapsed < ticks_to_expire) ? ticks_to_expire : ticks_elapsed; + cc &= MAX_RTC_COUNTER_VAL; + + rtc1_compare0_set(cc); + + uint32_t post_counter_val = rtc1_counter_get(); + + if ( + (ticks_diff_get(post_counter_val, pre_counter_val) + RTC_COMPARE_OFFSET_MIN) + > + ticks_diff_get(cc, pre_counter_val) + ) + { + // When this happens the COMPARE event may not be triggered by the RTC. + // The nRF51 Series User Specification states that if the COUNTER value is N + // (i.e post_counter_val = N), writing N or N + 1 to a CC register may not trigger a + // COMPARE event. Hence the RTC interrupt is forcefully pended by calling the following + // function. + rtc1_compare0_set(rtc1_counter_get()); // this should prevent CC to fire again in the background while the code is in RTC-ISR + nrf_delay_us(MAX_RTC_TASKS_DELAY); + timer_timeouts_check_sched(); + } + } + else + { +#if (APP_TIMER_KEEPS_RTC_ACTIVE == 0) + // No timers are running, stop RTC + rtc1_stop(); +#endif //(APP_TIMER_KEEPS_RTC_ACTIVE == 0) + } +} + + +/**@brief Function for handling changes to the timer list. + */ +static void timer_list_handler(void) +{ + timer_node_t * p_restart_list_head = NULL; + + uint32_t ticks_elapsed; + uint32_t ticks_previous; + bool ticks_have_elapsed; + bool compare_update = false; + timer_node_t * p_timer_id_head_old; + +#if APP_TIMER_WITH_PROFILER + { + uint8_t size = m_op_queue.size; + uint8_t first = m_op_queue.first; + uint8_t last = m_op_queue.last; + uint8_t utilization = (first <= last) ? (last - first) : (size + 1 - first + last); + + if (utilization > m_max_user_op_queue_utilization) + { + m_max_user_op_queue_utilization = utilization; + } + } +#endif + + // Back up the previous known tick and previous list head + ticks_previous = m_ticks_latest; + p_timer_id_head_old = mp_timer_id_head; + + // Get number of elapsed ticks + ticks_have_elapsed = elapsed_ticks_acquire(&ticks_elapsed); + + // Handle expired timers + if (ticks_have_elapsed) + { + expired_timers_handler(ticks_elapsed, ticks_previous, &p_restart_list_head); + compare_update = true; + } + + + // Handle list insertions + if (list_insertions_handler(p_restart_list_head)) + { + compare_update = true; + } + + // Update compare register if necessary + if (compare_update) + { + compare_reg_update(p_timer_id_head_old); + } + m_rtc1_reset = false; +} + + +/**@brief Function for enqueueing a new operations queue entry. + * + * @param[in] last_index Index of the next last index to be enqueued. + */ +static void user_op_enque(uint8_t last_index) +{ + m_op_queue.last = last_index; +} + + +/**@brief Function for allocating a new operations queue entry. + * + * @param[out] p_last_index Index of the next last index to be enqueued. + * + * @return Pointer to allocated queue entry, or NULL if queue is full. + */ +static timer_user_op_t * user_op_alloc( uint8_t * p_last_index) +{ + uint8_t last; + timer_user_op_t * p_user_op; + + last = m_op_queue.last + 1; + if (last == m_op_queue.size) + { + // Overflow case. + last = 0; + } + if (last == m_op_queue.first) + { + // Queue is full. + return NULL; + } + + *p_last_index = last; + p_user_op = &m_op_queue.user_op_queue[m_op_queue.last]; + + return p_user_op; +} + + +/**@brief Function for scheduling a Timer Start operation. + * + * @param[in] timer_id Id of timer to start. + * @param[in] timeout_initial Time (in ticks) to first timer expiry. + * @param[in] timeout_periodic Time (in ticks) between periodic expiries. + * @param[in] p_context General purpose pointer. Will be passed to the timeout handler when + * the timer expires. + * @return NRF_SUCCESS on success, otherwise an error code. + */ + +static uint32_t timer_start_op_schedule(timer_node_t * p_node, + uint32_t timeout_initial, + uint32_t timeout_periodic, + void * p_context) +{ + uint8_t last_index; + uint32_t err_code = NRF_SUCCESS; + + CRITICAL_REGION_ENTER(); + timer_user_op_t * p_user_op = user_op_alloc(&last_index); + if (p_user_op == NULL) + { + err_code = NRF_ERROR_NO_MEM; + } + else + { + p_user_op->op_type = TIMER_USER_OP_TYPE_START; + p_user_op->p_node = p_node; + p_user_op->params.start.ticks_at_start = rtc1_counter_get(); + p_user_op->params.start.ticks_first_interval = timeout_initial; + p_user_op->params.start.ticks_periodic_interval = timeout_periodic; + p_user_op->params.start.p_context = p_context; + + user_op_enque(last_index); + } + CRITICAL_REGION_EXIT(); + + if (err_code == NRF_SUCCESS) + { + timer_list_handler_sched(); + } + + return err_code; +} + + +/**@brief Function for scheduling a Timer Stop operation. + * + * @param[in] timer_id Id of timer to stop. + * @param[in] op_type Type of stop operation + * + * @return NRF_SUCCESS on successful scheduling a timer stop operation. NRF_ERROR_NO_MEM when there + * is no memory left to schedule the timer stop operation. + */ +static uint32_t timer_stop_op_schedule(timer_node_t * p_node, + timer_user_op_type_t op_type) +{ + uint8_t last_index; + uint32_t err_code = NRF_SUCCESS; + + CRITICAL_REGION_ENTER(); + timer_user_op_t * p_user_op = user_op_alloc(&last_index); + if (p_user_op == NULL) + { + err_code = NRF_ERROR_NO_MEM; + } + else + { + p_user_op->op_type = op_type; + p_user_op->p_node = p_node; + + user_op_enque(last_index); + } + CRITICAL_REGION_EXIT(); + + if (err_code == NRF_SUCCESS) + { + timer_list_handler_sched(); + } + + return err_code; +} + +/**@brief Function for handling the RTC1 interrupt. + * + * @details Checks for timeouts, and executes timeout handlers for expired timers. + */ +void RTC1_IRQHandler(void) +{ + // Clear all events (also unexpected ones) + NRF_RTC1->EVENTS_COMPARE[0] = 0; + NRF_RTC1->EVENTS_COMPARE[1] = 0; + NRF_RTC1->EVENTS_COMPARE[2] = 0; + NRF_RTC1->EVENTS_COMPARE[3] = 0; + NRF_RTC1->EVENTS_TICK = 0; + NRF_RTC1->EVENTS_OVRFLW = 0; + + // Check for expired timers + timer_timeouts_check(); +} + + +/**@brief Function for handling the SWI interrupt. + * + * @details Performs all updates to the timer list. + */ +void SWI_IRQHandler(void) +{ + timer_list_handler(); +} + + +ret_code_t app_timer_init(void) +{ + // Stop RTC to prevent any running timers from expiring (in case of reinitialization) + rtc1_stop(); + + // Initialize operation queue + m_op_queue.first = 0; + m_op_queue.last = 0; + m_op_queue.size = APP_TIMER_CONFIG_OP_QUEUE_SIZE+1; + + mp_timer_id_head = NULL; + m_ticks_elapsed_q_read_ind = 0; + m_ticks_elapsed_q_write_ind = 0; + +#if APP_TIMER_WITH_PROFILER + m_max_user_op_queue_utilization = 0; +#endif + + NVIC_ClearPendingIRQ(SWI_IRQn); + NVIC_SetPriority(SWI_IRQn, SWI_IRQ_PRI); + NVIC_EnableIRQ(SWI_IRQn); + + rtc1_init(APP_TIMER_CONFIG_RTC_FREQUENCY); + + m_ticks_latest = rtc1_counter_get(); + + return NRF_SUCCESS; +} + + +ret_code_t app_timer_create(app_timer_id_t const * p_timer_id, + app_timer_mode_t mode, + app_timer_timeout_handler_t timeout_handler) +{ + // Check state and parameters + VERIFY_MODULE_INITIALIZED(); + + if (timeout_handler == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + if (p_timer_id == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + if (((timer_node_t*)*p_timer_id)->is_running) + { + return NRF_ERROR_INVALID_STATE; + } + + timer_node_t * p_node = (timer_node_t *)*p_timer_id; + p_node->is_running = false; + p_node->mode = mode; + p_node->p_timeout_handler = timeout_handler; + return NRF_SUCCESS; +} + +ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context) +{ + uint32_t timeout_periodic; + timer_node_t * p_node = (timer_node_t*)timer_id; + + // Check state and parameters + VERIFY_MODULE_INITIALIZED(); + + if (timer_id == 0) + { + return NRF_ERROR_INVALID_STATE; + } + if (timeout_ticks < APP_TIMER_MIN_TIMEOUT_TICKS) + { + return NRF_ERROR_INVALID_PARAM; + } + if (p_node->p_timeout_handler == NULL) + { + return NRF_ERROR_INVALID_STATE; + } + + // Schedule timer start operation + timeout_periodic = (p_node->mode == APP_TIMER_MODE_REPEATED) ? timeout_ticks : 0; + + return timer_start_op_schedule(p_node, + timeout_ticks, + timeout_periodic, + p_context); +} + + +ret_code_t app_timer_stop(app_timer_id_t timer_id) +{ + timer_node_t * p_node = (timer_node_t*)timer_id; + // Check state and parameters + VERIFY_MODULE_INITIALIZED(); + + if ((timer_id == NULL) || (p_node->p_timeout_handler == NULL)) + { + return NRF_ERROR_INVALID_STATE; + } + + p_node->is_running = false; + + // Schedule timer stop operation + return timer_stop_op_schedule(p_node, TIMER_USER_OP_TYPE_STOP); +} + + +ret_code_t app_timer_stop_all(void) +{ + // Check state + VERIFY_MODULE_INITIALIZED(); + + return timer_stop_op_schedule(NULL, TIMER_USER_OP_TYPE_STOP_ALL); +} + + +uint32_t app_timer_cnt_get(void) +{ + return rtc1_counter_get(); +} + + +uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to, + uint32_t ticks_from) +{ + return ticks_diff_get(ticks_to, ticks_from); +} + +#if APP_TIMER_WITH_PROFILER +uint8_t app_timer_op_queue_utilization_get(void) +{ + return m_max_user_op_queue_utilization; +} +#endif + +void app_timer_pause(void) +{ + NRF_RTC1->TASKS_STOP = 1; +} + +void app_timer_resume(void) +{ + NRF_RTC1->TASKS_START = 1; +} + +#endif //NRF_MODULE_ENABLED(APP_TIMER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..1bd1d9470a83f0d4c7bc7494253922a0241a3492 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer.h @@ -0,0 +1,269 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup app_timer Application Timer + * @{ + * @ingroup app_common + * + * @brief Application timer functionality. + * + * @details This module enables the application to create multiple timer instances based on the RTC1 + * peripheral. Checking for time-outs and invocation of user time-out handlers is performed + * in the RTC1 interrupt handler. List handling is done using a software interrupt (SWI0). + * Both interrupt handlers are running in APP_LOW priority level. + * + * @details When calling app_timer_start() or app_timer_stop(), the timer operation is just queued, + * and the software interrupt is triggered. The actual timer start/stop operation is + * executed by the SWI0 interrupt handler. Since the SWI0 interrupt is running in APP_LOW, + * if the application code calling the timer function is running in APP_LOW or APP_HIGH, + * the timer operation will not be performed until the application handler has returned. + * This will be the case, for example, when stopping a timer from a time-out handler when not using + * the scheduler. + * + * @details Use the USE_SCHEDULER parameter of the APP_TIMER_INIT() macro to select if the + * @ref app_scheduler should be used or not. Even if the scheduler is + * not used, app_timer.h will include app_scheduler.h, so when + * compiling, app_scheduler.h must be available in one of the compiler include paths. + */ + +#ifndef APP_TIMER_H__ +#define APP_TIMER_H__ +#include "sdk_config.h" +#include "app_error.h" +#include "app_util.h" +#include "compiler_abstraction.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define APP_TIMER_CLOCK_FREQ 200 /**< Clock frequency of the RTC timer used to implement the app timer module. */ +#define APP_TIMER_MIN_TIMEOUT_TICKS 1 /**< Minimum value of the timeout_ticks parameter of app_timer_start(). */ + +#ifdef RTX +#define APP_TIMER_NODE_SIZE 40 /**< Size of app_timer.timer_node_t (used to allocate data). */ +#elif defined(RTTHREAD) +#define APP_TIMER_NODE_SIZE 12 +#else +#define APP_TIMER_NODE_SIZE 32 /**< Size of app_timer.timer_node_t (used to allocate data). */ +#endif // RTX + +#define APP_TIMER_SCHED_EVENT_DATA_SIZE sizeof(app_timer_event_t) /**< Size of event data when scheduler is used. */ + +/**@brief Convert milliseconds to timer ticks. + * + * This macro uses 64-bit integer arithmetic, but as long as the macro parameters are + * constants (i.e. defines), the computation will be done by the preprocessor. + * + * @param[in] MS Milliseconds. + * + * @return Number of timer ticks. + */ +#ifndef FREERTOS +#ifndef RTTHREAD +#define APP_TIMER_TICKS(MS) \ + ((uint32_t)ROUNDED_DIV( \ + (MS) * (uint64_t)APP_TIMER_CLOCK_FREQ, \ + 1000 * (APP_TIMER_CONFIG_RTC_FREQUENCY + 1))) +#else +#define APP_TIMER_TICKS(MS) rt_tick_from_millisecond(MS) +#endif +#else +#include "FreeRTOSConfig.h" +#define APP_TIMER_TICKS(MS) (uint32_t)ROUNDED_DIV((MS)*configTICK_RATE_HZ,1000) +#endif +typedef struct app_timer_t { uint32_t data[CEIL_DIV(APP_TIMER_NODE_SIZE, sizeof(uint32_t))]; } app_timer_t; + +/**@brief Timer ID type. + * Never declare a variable of this type, but use the macro @ref APP_TIMER_DEF instead.*/ +typedef app_timer_t * app_timer_id_t; + +/** + * @brief Create a timer identifier and statically allocate memory for the timer. + * + * @param timer_id Name of the timer identifier variable that will be used to control the timer. + */ +#define APP_TIMER_DEF(timer_id) \ + static app_timer_t timer_id##_data = { {0} }; \ + static const app_timer_id_t timer_id = &timer_id##_data + + +/**@brief Application time-out handler type. */ +typedef void (*app_timer_timeout_handler_t)(void * p_context); + +/**@brief Structure passed to app_scheduler. */ +typedef struct +{ + app_timer_timeout_handler_t timeout_handler; + void * p_context; +} app_timer_event_t; + +/**@brief Timer modes. */ +typedef enum +{ + APP_TIMER_MODE_SINGLE_SHOT, /**< The timer will expire only once. */ + APP_TIMER_MODE_REPEATED /**< The timer will restart each time it expires. */ +} app_timer_mode_t; + +/**@brief Function for initializing the timer module. + * + * @retval NRF_SUCCESS If the module was initialized successfully. + */ +ret_code_t app_timer_init(void); + +/**@brief Function for creating a timer instance. + * + * @param[in] p_timer_id Pointer to timer identifier. + * @param[in] mode Timer mode. + * @param[in] timeout_handler Function to be executed when the timer expires. + * + * @retval NRF_SUCCESS If the timer was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid. + * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized or + * the timer is running. + * + * @note This function does the timer allocation in the caller's context. It is also not protected + * by a critical region. Therefore care must be taken not to call it from several interrupt + * levels simultaneously. + * @note The function can be called again on the timer instance and will re-initialize the instance if + * the timer is not running. + * @attention The FreeRTOS and RTX app_timer implementation does not allow app_timer_create to + * be called on the previously initialized instance. + */ +ret_code_t app_timer_create(app_timer_id_t const * p_timer_id, + app_timer_mode_t mode, + app_timer_timeout_handler_t timeout_handler); + +/**@brief Function for starting a timer. + * + * @param[in] timer_id Timer identifier. + * @param[in] timeout_ticks Number of ticks (of RTC1, including prescaling) to time-out event + * (minimum 5 ticks). + * @param[in] p_context General purpose pointer. Will be passed to the time-out handler when + * the timer expires. + * + * @retval NRF_SUCCESS If the timer was successfully started. + * @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid. + * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized or the timer + * has not been created. + * @retval NRF_ERROR_NO_MEM If the timer operations queue was full. + * + * @note The minimum timeout_ticks value is 5. + * @note For multiple active timers, time-outs occurring in close proximity to each other (in the + * range of 1 to 3 ticks) will have a positive jitter of maximum 3 ticks. + * @note When calling this method on a timer that is already running, the second start operation + * is ignored. + */ +ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context); + +/**@brief Function for stopping the specified timer. + * + * @param[in] timer_id Timer identifier. + * + * @retval NRF_SUCCESS If the timer was successfully stopped. + * @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid. + * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized or the timer + * has not been created. + * @retval NRF_ERROR_NO_MEM If the timer operations queue was full. + */ +ret_code_t app_timer_stop(app_timer_id_t timer_id); + +/**@brief Function for stopping all running timers. + * + * @retval NRF_SUCCESS If all timers were successfully stopped. + * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized. + * @retval NRF_ERROR_NO_MEM If the timer operations queue was full. + */ +ret_code_t app_timer_stop_all(void); + +/**@brief Function for returning the current value of the RTC1 counter. + * + * @return Current value of the RTC1 counter. + */ +uint32_t app_timer_cnt_get(void); + +/**@brief Function for computing the difference between two RTC1 counter values. + * + * @param[in] ticks_to Value returned by app_timer_cnt_get(). + * @param[in] ticks_from Value returned by app_timer_cnt_get(). + * + * @return Number of ticks from ticks_from to ticks_to. + */ +uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to, + uint32_t ticks_from); + + +/**@brief Function for getting the maximum observed operation queue utilization. + * + * Function for tuning the module and determining OP_QUEUE_SIZE value and thus module RAM usage. + * + * @note APP_TIMER_WITH_PROFILER must be enabled to use this functionality. + * + * @return Maximum number of events in queue observed so far. + */ +uint8_t app_timer_op_queue_utilization_get(void); + +/** + * @brief Function for pausing RTC activity which drives app_timer. + * + * @note This function can be used for debugging purposes to ensure + * that application is halted when entering a breakpoint. + */ +void app_timer_pause(void); + +/** + * @brief Function for resuming RTC activity which drives app_timer. + * + * @note This function can be used for debugging purposes to resume + * application activity. + */ +void app_timer_resume(void); + +#ifdef __cplusplus +} +#endif + +#endif // APP_TIMER_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer_freertos.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer_freertos.c new file mode 100644 index 0000000000000000000000000000000000000000..9d5c8400b9ae3eb6480ce39af5f02edc30190bb8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer_freertos.c @@ -0,0 +1,241 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_TIMER) +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" + +#include "app_timer.h" +#include +#include +#include "nrf.h" +#include "app_error.h" + +/** + * Note that this implementation is made only for enable SDK components which interacts with app_timer to work with FreeRTOS. + * It is more suitable to use native FreeRTOS timer for other purposes. + */ +/* Check if RTC FreeRTOS version is used */ +#if configTICK_SOURCE != FREERTOS_USE_RTC +#error app_timer in FreeRTOS variant have to be used with RTC tick source configuration. Default configuration have to be used in other case. +#endif + +/** + * @brief Waiting time for the timer queue + * + * Number of system ticks to wait for the timer queue to put the message. + * It is strongly recommended to set this to the value bigger than 1. + * In other case if timer message queue is full - any operation on timer may fail. + * @note + * Timer functions called from interrupt context would never wait. + */ +#define APP_TIMER_WAIT_FOR_QUEUE 2 + +/**@brief This structure keeps information about osTimer.*/ +typedef struct +{ + void * argument; + TimerHandle_t osHandle; + app_timer_timeout_handler_t func; + /** + * This member is to make sure that timer function is only called if timer is running. + * FreeRTOS may have timer running even after stop function is called, + * because it processes commands in Timer task and stopping function only puts command into the queue. */ + bool active; +}app_timer_info_t; + + +/* Check if freeRTOS timers are activated */ +#if configUSE_TIMERS == 0 + #error app_timer for freeRTOS requires configUSE_TIMERS option to be activated. +#endif + +/* Check if app_timer_t variable type can held our app_timer_info_t structure */ +STATIC_ASSERT(sizeof(app_timer_info_t) <= sizeof(app_timer_t)); + + +/** + * @brief Internal callback function for the system timer + * + * Internal function that is called from the system timer. + * It gets our parameter from timer data and sends it to user function. + * @param[in] xTimer Timer handler + */ +static void app_timer_callback(TimerHandle_t xTimer) +{ + app_timer_info_t * pinfo = (app_timer_info_t*)(pvTimerGetTimerID(xTimer)); + ASSERT(pinfo->osHandle == xTimer); + ASSERT(pinfo->func != NULL); + + if (pinfo->active) + pinfo->func(pinfo->argument); +} + + +uint32_t app_timer_init(void) +{ + return NRF_SUCCESS; +} + + +uint32_t app_timer_create(app_timer_id_t const * p_timer_id, + app_timer_mode_t mode, + app_timer_timeout_handler_t timeout_handler) +{ + app_timer_info_t * pinfo = (app_timer_info_t*)(*p_timer_id); + uint32_t err_code = NRF_SUCCESS; + unsigned long timer_mode; + + if ((timeout_handler == NULL) || (p_timer_id == NULL)) + { + return NRF_ERROR_INVALID_PARAM; + } + if (pinfo->active) + { + return NRF_ERROR_INVALID_STATE; + } + + if (pinfo->osHandle == NULL) + { + /* New timer is created */ + memset(pinfo, 0, sizeof(app_timer_info_t)); + + if (mode == APP_TIMER_MODE_SINGLE_SHOT) + timer_mode = pdFALSE; + else + timer_mode = pdTRUE; + + pinfo->func = timeout_handler; + pinfo->osHandle = xTimerCreate(" ", 1000, timer_mode, pinfo, app_timer_callback); + + if (pinfo->osHandle == NULL) + err_code = NRF_ERROR_NULL; + } + else + { + /* Timer cannot be reinitialized using FreeRTOS API */ + return NRF_ERROR_INVALID_STATE; + } + + return err_code; +} + + +uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context) +{ + app_timer_info_t * pinfo = (app_timer_info_t*)(timer_id); + TimerHandle_t hTimer = pinfo->osHandle; + + if (hTimer == NULL) + { + return NRF_ERROR_INVALID_STATE; + } + if (pinfo->active && (xTimerIsTimerActive(hTimer) != pdFALSE)) + { + // Timer already running - exit silently + return NRF_SUCCESS; + } + + pinfo->argument = p_context; + + if (__get_IPSR() != 0) + { + BaseType_t yieldReq = pdFALSE; + if (xTimerChangePeriodFromISR(hTimer, timeout_ticks, &yieldReq) != pdPASS) + { + return NRF_ERROR_NO_MEM; + } + + if ( xTimerStartFromISR(hTimer, &yieldReq) != pdPASS ) + { + return NRF_ERROR_NO_MEM; + } + + portYIELD_FROM_ISR(yieldReq); + } + else + { + if (xTimerChangePeriod(hTimer, timeout_ticks, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS) + { + return NRF_ERROR_NO_MEM; + } + + if (xTimerStart(hTimer, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS) + { + return NRF_ERROR_NO_MEM; + } + } + + pinfo->active = true; + return NRF_SUCCESS; +} + + +uint32_t app_timer_stop(app_timer_id_t timer_id) +{ + app_timer_info_t * pinfo = (app_timer_info_t*)(timer_id); + TimerHandle_t hTimer = pinfo->osHandle; + if (hTimer == NULL) + { + return NRF_ERROR_INVALID_STATE; + } + + if (__get_IPSR() != 0) + { + BaseType_t yieldReq = pdFALSE; + if (xTimerStopFromISR(hTimer, &yieldReq) != pdPASS) + { + return NRF_ERROR_NO_MEM; + } + portYIELD_FROM_ISR(yieldReq); + } + else + { + if (xTimerStop(hTimer, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS) + { + return NRF_ERROR_NO_MEM; + } + } + + pinfo->active = false; + return NRF_SUCCESS; +} +#endif //NRF_MODULE_ENABLED(APP_TIMER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer_rtthread.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer_rtthread.c new file mode 100644 index 0000000000000000000000000000000000000000..ea03eb6ec34f22c296af3485341b53159a022bb0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer_rtthread.c @@ -0,0 +1,171 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_TIMER) +#include "app_timer.h" +#include +#include "nrf.h" +#include "nrf_soc.h" +#include "app_error.h" +#include "app_util_platform.h" + +#include + +/**@brief This structure keeps information about osTimer.*/ +typedef struct +{ + rt_timer_t id; + app_timer_timeout_handler_t callback; + void *parameter; +}app_timer_info_t; + + +ret_code_t app_timer_init(void) +{ + return NRF_SUCCESS; +} + +static void _timeout_entry(void *paramter) +{ + app_timer_info_t * p_timer_info; + + p_timer_info = (app_timer_info_t *)paramter; + + if (p_timer_info->callback != RT_NULL) + { + p_timer_info->callback(p_timer_info->parameter); + } +} + +ret_code_t app_timer_create(app_timer_id_t const * p_timer_id, + app_timer_mode_t mode, + app_timer_timeout_handler_t timeout_handler) +{ + app_timer_info_t * p_timer_info; + + if ((timeout_handler == NULL) || (p_timer_id == NULL)) + { + return NRF_ERROR_INVALID_PARAM; + } + + p_timer_info = (app_timer_info_t *)*p_timer_id; + p_timer_info->callback = timeout_handler; + + if (mode == APP_TIMER_MODE_SINGLE_SHOT) + { + p_timer_info->id = rt_timer_create("apptimer", _timeout_entry, p_timer_info, + 0, RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT); + } + else + { + p_timer_info->id = rt_timer_create("apptimer", _timeout_entry, p_timer_info, + 0, RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_PERIODIC); + } + + if (p_timer_info->id != RT_NULL) + { + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INVALID_PARAM; // This error is unspecified by rtx + } +} + +ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context) +{ + app_timer_info_t * p_timer_info = (app_timer_info_t *)timer_id; + + if ((timeout_ticks < APP_TIMER_MIN_TIMEOUT_TICKS)) + { + return NRF_ERROR_INVALID_PARAM; + } + + if (p_timer_info->id == RT_NULL) + return NRF_ERROR_INVALID_PARAM; + + if (p_timer_info->id->parent.flag & RT_TIMER_FLAG_ACTIVATED) + { + return NRF_SUCCESS; + } + + p_timer_info->parameter = p_context; + + rt_timer_control(p_timer_info->id, RT_TIMER_CTRL_SET_TIME, &timeout_ticks); + + switch (rt_timer_start(p_timer_info->id)) + { + case RT_EOK: + return NRF_SUCCESS; + + default: + return NRF_ERROR_INVALID_PARAM; + } +} + +ret_code_t app_timer_stop(app_timer_id_t timer_id) +{ + app_timer_info_t * p_timer_info = (app_timer_info_t *)timer_id; + + if (p_timer_info != RT_NULL && p_timer_info->id != RT_NULL) + { + // if (p_timer_info->id->parent.flag & RT_TIMER_FLAG_ACTIVATED) + { + rt_timer_stop(p_timer_info->id); + return NRF_SUCCESS; + } + } + + return NRF_ERROR_INVALID_PARAM; +} + +uint32_t app_timer_cnt_get(void) +{ + return rt_tick_get(); +} + +uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to, + uint32_t ticks_from) +{ + return ((ticks_to - ticks_from) & RT_TICK_MAX); +} + +#endif //NRF_MODULE_ENABLED(APP_TIMER) + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer_rtx.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer_rtx.c new file mode 100644 index 0000000000000000000000000000000000000000..ae16e75e83694312cf5fcdc879e6cf844a523ac3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/timer/app_timer_rtx.c @@ -0,0 +1,278 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_TIMER) +#include "app_timer.h" +#include +#include "nrf.h" +#include "nrf_soc.h" +#include "app_error.h" +#include "cmsis_os.h" +#include "app_util_platform.h" + +#define RTC1_IRQ_PRI APP_IRQ_PRIORITY_LOWEST /**< Priority of the RTC1 interrupt. */ + +#define MAX_RTC_COUNTER_VAL 0x00FFFFFF /**< Maximum value of the RTC counter. */ + +/**@brief This structure keeps information about osTimer.*/ +typedef struct +{ + osTimerDef_t timerDef; + uint32_t buffer[6]; + osTimerId id; +}app_timer_info_t; + +/**@brief Store an array of timers with configuration. */ +typedef struct +{ + uint8_t max_timers; /**< The maximum number of timers*/ + uint32_t prescaler; + app_timer_info_t * app_timers; /**< Pointer to table of timers*/ +}app_timer_control_t; + +app_timer_control_t app_timer_control; + +/**@brief This structure is defined by RTX. It keeps information about created osTimers. It is used in app_timer_start(). */ +typedef struct os_timer_cb_ +{ + struct os_timer_cb_ * next; /**< Pointer to next active Timer */ + uint8_t state; /**< Timer State */ + uint8_t type; /**< Timer Type (Periodic/One-shot). */ + uint16_t reserved; /**< Reserved. */ + uint32_t tcnt; /**< Timer Delay Count. */ + uint32_t icnt; /**< Timer Initial Count. */ + void * arg; /**< Timer Function Argument. */ + const osTimerDef_t * timer; /**< Pointer to Timer definition. */ +} os_timer_cb; + +/**@brief This functions are defined by RTX.*/ +//lint --save -e10 -e19 -e526 +extern osStatus svcTimerStop(osTimerId timer_id); /**< Used in app_timer_stop(). */ +extern osStatus svcTimerStart(osTimerId timer_id, uint32_t millisec); /**< Used in app_timer_start(). */ +// lint --restore +static void * rt_id2obj (void *id) /**< Used in app_timer_start(). This function gives information if osTimerID is valid */ +{ + if ((uint32_t)id & 3U) + { + return NULL; + } + +#ifdef OS_SECTIONS_LINK_INFO + + if ((os_section_id$$Base != 0U) && (os_section_id$$Limit != 0U)) + { + if (id < (void *)os_section_id$$Base) + { + return NULL; + } + + if (id >= (void *)os_section_id$$Limit) + { + return NULL; + } + } +#endif + + return id; +} + + + +ret_code_t app_timer_init(void) +{ + if (p_buffer == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + app_timer_control.app_timers = p_buffer; + NVIC_SetPriority(RTC1_IRQn, RTC1_IRQ_PRI); + + return NRF_SUCCESS; +} + + +ret_code_t app_timer_create(app_timer_id_t const * p_timer_id, + app_timer_mode_t mode, + app_timer_timeout_handler_t timeout_handler) +{ + + if ((timeout_handler == NULL) || (p_timer_id == NULL)) + { + return NRF_ERROR_INVALID_PARAM; + } + + app_timer_info_t * p_timer_info = (app_timer_info_t *)*p_timer_id; + p_timer_info->timerDef.timer = p_timer_info->buffer; + p_timer_info->timerDef.ptimer = (os_ptimer)timeout_handler; + + p_timer_info->id = osTimerCreate(&(p_timer_info->timerDef), (os_timer_type)mode, NULL); + + if (p_timer_info->id) + return NRF_SUCCESS; + else + { + return NRF_ERROR_INVALID_PARAM; // This error is unspecified by rtx + } +} + +#define osTimerRunning 2 +ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context) +{ + if ((timeout_ticks < APP_TIMER_MIN_TIMEOUT_TICKS)) + { + return NRF_ERROR_INVALID_PARAM; + } + uint32_t timeout_ms = + ((uint32_t)ROUNDED_DIV(timeout_ticks * 1000 * (APP_TIMER_CONFIG_RTC_FREQUENCY + 1), + (uint32_t)APP_TIMER_CLOCK_FREQ)); + + app_timer_info_t * p_timer_info = (app_timer_info_t *)timer_id; + if (rt_id2obj((void *)p_timer_info->id) == NULL) + return NRF_ERROR_INVALID_PARAM; + + // Pass p_context to timer_timeout_handler + ((os_timer_cb *)(p_timer_info->id))->arg = p_context; + + if (((os_timer_cb *)(p_timer_info->id))->state == osTimerRunning) + { + return NRF_SUCCESS; + } + // osTimerStart() returns osErrorISR if it is called in interrupt routine. + switch (osTimerStart((osTimerId)p_timer_info->id, timeout_ms) ) + { + case osOK: + return NRF_SUCCESS; + + case osErrorISR: + break; + + case osErrorParameter: + return NRF_ERROR_INVALID_PARAM; + + default: + return NRF_ERROR_INVALID_PARAM; + } + + // Start timer without svcCall + switch (svcTimerStart((osTimerId)p_timer_info->id, timeout_ms)) + { + case osOK: + return NRF_SUCCESS; + + case osErrorISR: + return NRF_ERROR_INVALID_STATE; + + case osErrorParameter: + return NRF_ERROR_INVALID_PARAM; + + default: + return NRF_ERROR_INVALID_PARAM; + } +} + +ret_code_t app_timer_stop(app_timer_id_t timer_id) +{ + app_timer_info_t * p_timer_info = (app_timer_info_t *)timer_id; + switch (osTimerStop((osTimerId)p_timer_info->id) ) + { + case osOK: + return NRF_SUCCESS; + + case osErrorISR: + break; + + case osErrorParameter: + return NRF_ERROR_INVALID_PARAM; + + case osErrorResource: + return NRF_SUCCESS; + + default: + return NRF_ERROR_INVALID_PARAM; + } + + // Stop timer without svcCall + switch (svcTimerStop((osTimerId)p_timer_info->id)) + { + case osOK: + return NRF_SUCCESS; + + case osErrorISR: + return NRF_ERROR_INVALID_STATE; + + case osErrorParameter: + return NRF_ERROR_INVALID_PARAM; + + case osErrorResource: + return NRF_SUCCESS; + + default: + return NRF_ERROR_INVALID_PARAM; + } +} + + +ret_code_t app_timer_stop_all(void) +{ + for (int i = 0; i < app_timer_control.max_timers; i++) + { + if (app_timer_control.app_timers[i].id) + { + (void)app_timer_stop((app_timer_id_t)app_timer_control.app_timers[i].id); + } + } + return 0; +} + + +extern uint32_t os_tick_val(void); +uint32_t app_timer_cnt_get(void) +{ + return os_tick_val(); +} + + +uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to, + uint32_t ticks_from) +{ + return ((ticks_to - ticks_from) & MAX_RTC_COUNTER_VAL); +} +#endif //NRF_MODULE_ENABLED(APP_TIMER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/twi/app_twi.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/twi/app_twi.c new file mode 100644 index 0000000000000000000000000000000000000000..d63a4ff26fe447559256a03eacea6347b8b041b0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/twi/app_twi.c @@ -0,0 +1,369 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_TWI) +#include "app_twi.h" +#include "nrf_assert.h" +#include "app_util_platform.h" + +static ret_code_t start_transfer(app_twi_t const * p_app_twi) +{ + ASSERT(p_app_twi != NULL); + + // [use a local variable to avoid using two volatile variables in one + // expression] + uint8_t current_transfer_idx = p_app_twi->p_app_twi_cb->current_transfer_idx; + app_twi_transfer_t const * p_transfer = + &p_app_twi->p_app_twi_cb->p_current_transaction->p_transfers[current_transfer_idx]; + uint8_t address = APP_TWI_OP_ADDRESS(p_transfer->operation); + + nrf_drv_twi_xfer_desc_t xfer_desc; + uint32_t flags; + + xfer_desc.address = address; + xfer_desc.p_primary_buf = p_transfer->p_data; + xfer_desc.primary_length = p_transfer->length; + + /* If it is possible try to bind two transfers together. They can be combined if: + * - there is no stop condition after current transfer. + * - current transfer is TX. + * - there is at least one more transfer in the transaction. + * - address of next trnasfer is the same as current transfer. + */ + if ((p_transfer->flags & APP_TWI_NO_STOP) && + !APP_TWI_IS_READ_OP(p_transfer->operation) && + ((current_transfer_idx + 1) + < p_app_twi->p_app_twi_cb->p_current_transaction->number_of_transfers) && + (APP_TWI_OP_ADDRESS(p_transfer->operation) == + APP_TWI_OP_ADDRESS(p_app_twi->p_app_twi_cb->p_current_transaction-> + p_transfers[current_transfer_idx + 1].operation))) + { + app_twi_transfer_t const * p_second_transfer = + &p_app_twi->p_app_twi_cb->p_current_transaction->p_transfers[current_transfer_idx + 1]; + xfer_desc.p_secondary_buf = p_second_transfer->p_data; + xfer_desc.secondary_length = p_second_transfer->length; + xfer_desc.type = APP_TWI_IS_READ_OP(p_second_transfer->operation) ? NRF_DRV_TWI_XFER_TXRX : + NRF_DRV_TWI_XFER_TXTX; + flags = (p_second_transfer->flags & APP_TWI_NO_STOP) ? NRF_DRV_TWI_FLAG_TX_NO_STOP : 0; + p_app_twi->p_app_twi_cb->current_transfer_idx++; + } + else + { + xfer_desc.type = APP_TWI_IS_READ_OP(p_transfer->operation) ? NRF_DRV_TWI_XFER_RX : + NRF_DRV_TWI_XFER_TX; + xfer_desc.p_secondary_buf = NULL; + xfer_desc.secondary_length = 0; + flags = (p_transfer->flags & APP_TWI_NO_STOP) ? NRF_DRV_TWI_FLAG_TX_NO_STOP : 0; + } + + return nrf_drv_twi_xfer(&p_app_twi->twi, &xfer_desc, flags); +} + + +static void transaction_end_signal(app_twi_t const * p_app_twi, + ret_code_t result) +{ + ASSERT(p_app_twi != NULL); + + if (p_app_twi->p_app_twi_cb->p_current_transaction->callback) + { + // [use a local variable to avoid using two volatile variables in one + // expression] + void * p_user_data = p_app_twi->p_app_twi_cb->p_current_transaction->p_user_data; + p_app_twi->p_app_twi_cb->p_current_transaction->callback(result, p_user_data); + } +} + +static void twi_event_handler(nrf_drv_twi_evt_t const * p_event, + void * p_context); + +// This function starts pending transaction if there is no current one or +// when 'switch_transaction' parameter is set to true. It is important to +// switch to new transaction without setting 'p_app_twi->p_current_transaction' +// to NULL in between, since this pointer is used to check idle status - see +// 'app_twi_is_idle()'. +static void start_pending_transaction(app_twi_t const * p_app_twi, + bool switch_transaction) +{ + ASSERT(p_app_twi != NULL); + + for (;;) + { + bool start_transaction = false; + + CRITICAL_REGION_ENTER(); + if (switch_transaction || app_twi_is_idle(p_app_twi)) + { + if (nrf_queue_pop(p_app_twi->p_queue, + (void *)(&p_app_twi->p_app_twi_cb->p_current_transaction)) + == NRF_SUCCESS) + { + start_transaction = true; + } + else + { + p_app_twi->p_app_twi_cb->p_current_transaction = NULL; + } + } + CRITICAL_REGION_EXIT(); + + if (!start_transaction) + { + return; + } + else + { + ret_code_t result; + + nrf_drv_twi_config_t const * p_instance_cfg = + p_app_twi->p_app_twi_cb->p_current_transaction->p_required_twi_cfg == NULL ? + &p_app_twi->p_app_twi_cb->default_configuration : + p_app_twi->p_app_twi_cb->p_current_transaction->p_required_twi_cfg; + + if (memcmp(p_app_twi->p_app_twi_cb->p_current_configuration, + p_instance_cfg, + sizeof(*p_instance_cfg)) != 0) + { + ret_code_t err_code; + nrf_drv_twi_uninit(&p_app_twi->twi); + err_code = nrf_drv_twi_init(&p_app_twi->twi, + p_instance_cfg, + twi_event_handler, + (void *)p_app_twi); + ASSERT(err_code == NRF_SUCCESS); + nrf_drv_twi_enable(&p_app_twi->twi); + + p_app_twi->p_app_twi_cb->p_current_configuration = p_instance_cfg; + } + + // Try to start first transfer for this new transaction. + p_app_twi->p_app_twi_cb->current_transfer_idx = 0; + result = start_transfer(p_app_twi); + + // If transaction started successfully there is nothing more to do here now. + if (result == NRF_SUCCESS) + { + return; + } + + // Transfer failed to start - notify user that this transaction + // cannot be started and try with next one (in next iteration of + // the loop). + transaction_end_signal(p_app_twi, result); + + switch_transaction = true; + } + } +} + + +static void twi_event_handler(nrf_drv_twi_evt_t const * p_event, + void * p_context) +{ + ASSERT(p_event != NULL); + + app_twi_t * p_app_twi = (app_twi_t *)p_context; + ret_code_t result; + + // This callback should be called only during transaction. + ASSERT(p_app_twi->p_app_twi_cb->p_current_transaction != NULL); + + if (p_event->type == NRF_DRV_TWI_EVT_DONE) + { + result = NRF_SUCCESS; + + // Transfer finished successfully. If there is another one to be + // performed in the current transaction, start it now. + // [use a local variable to avoid using two volatile variables in one + // expression] + uint8_t current_transfer_idx = p_app_twi->p_app_twi_cb->current_transfer_idx; + ++current_transfer_idx; + if (current_transfer_idx < + p_app_twi->p_app_twi_cb->p_current_transaction->number_of_transfers) + { + p_app_twi->p_app_twi_cb->current_transfer_idx = current_transfer_idx; + + result = start_transfer(p_app_twi); + + if (result == NRF_SUCCESS) + { + // The current transaction goes on and we've successfully + // started its next transfer -> there is nothing more to do. + return; + } + + // [if the next transfer could not be started due to some error + // we finish the transaction with this error code as the result] + } + } + else + { + result = NRF_ERROR_INTERNAL; + } + + // The current transaction has been completed or interrupted by some error. + // Notify the user and start next one (if there is any). + transaction_end_signal(p_app_twi, result); + // [we switch transactions here ('p_app_twi->p_current_transaction' is set + // to NULL only if there is nothing more to do) in order to not generate + // spurious idle status (even for a moment)] + start_pending_transaction(p_app_twi, true); +} + + +ret_code_t app_twi_init(app_twi_t const * p_app_twi, + nrf_drv_twi_config_t const * p_default_twi_config) +{ + ASSERT(p_app_twi != NULL); + ASSERT(p_app_twi->p_queue != NULL); + ASSERT(p_app_twi->p_queue->size > 0); + ASSERT(p_default_twi_config != NULL); + + ret_code_t err_code; + + err_code = nrf_drv_twi_init(&p_app_twi->twi, + p_default_twi_config, + twi_event_handler, + (void *)p_app_twi); + VERIFY_SUCCESS(err_code); + + nrf_drv_twi_enable(&p_app_twi->twi); + + p_app_twi->p_app_twi_cb->internal_transaction_in_progress = false; + p_app_twi->p_app_twi_cb->p_current_transaction = NULL; + p_app_twi->p_app_twi_cb->default_configuration = *p_default_twi_config; + p_app_twi->p_app_twi_cb->p_current_configuration = + &p_app_twi->p_app_twi_cb->default_configuration; + + return NRF_SUCCESS; +} + + +void app_twi_uninit(app_twi_t const * p_app_twi) +{ + ASSERT(p_app_twi != NULL); + + nrf_drv_twi_uninit(&p_app_twi->twi); + + p_app_twi->p_app_twi_cb->p_current_transaction = NULL; +} + + +ret_code_t app_twi_schedule(app_twi_t const * p_app_twi, + app_twi_transaction_t const * p_transaction) +{ + ASSERT(p_app_twi != NULL); + ASSERT(p_transaction != NULL); + ASSERT(p_transaction->p_transfers != NULL); + ASSERT(p_transaction->number_of_transfers != 0); + + ret_code_t result = NRF_SUCCESS; + + result = nrf_queue_push(p_app_twi->p_queue, (void *)(&p_transaction)); + if (result == NRF_SUCCESS) + { + // New transaction has been successfully added to queue, + // so if we are currently idle it's time to start the job. + start_pending_transaction(p_app_twi, false); + } + + return result; +} + + +static void internal_transaction_cb(ret_code_t result, void * p_user_data) +{ + app_twi_t * p_app_twi = (app_twi_t *)p_user_data; + + p_app_twi->p_app_twi_cb->internal_transaction_result = result; + p_app_twi->p_app_twi_cb->internal_transaction_in_progress = false; +} + + +ret_code_t app_twi_perform(app_twi_t const * p_app_twi, + app_twi_transfer_t const * p_transfers, + uint8_t number_of_transfers, + void (* user_function)(void)) +{ + ASSERT(p_app_twi != NULL); + ASSERT(p_transfers != NULL); + ASSERT(number_of_transfers != 0); + + bool busy = false; + + CRITICAL_REGION_ENTER(); + if (p_app_twi->p_app_twi_cb->internal_transaction_in_progress) + { + busy = true; + } + else + { + p_app_twi->p_app_twi_cb->internal_transaction_in_progress = true; + } + CRITICAL_REGION_EXIT(); + + if (busy) + { + return NRF_ERROR_BUSY; + } + else + { + app_twi_transaction_t internal_transaction = + { + .callback = internal_transaction_cb, + .p_user_data = (void *)p_app_twi, + .p_transfers = p_transfers, + .number_of_transfers = number_of_transfers, + }; + ret_code_t result = app_twi_schedule(p_app_twi, &internal_transaction); + VERIFY_SUCCESS(result); + + while (p_app_twi->p_app_twi_cb->internal_transaction_in_progress) + { + if (user_function) + { + user_function(); + } + } + + return p_app_twi->p_app_twi_cb->internal_transaction_result; + } +} +#endif //NRF_MODULE_ENABLED(APP_TWI) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/twi/app_twi.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/twi/app_twi.h new file mode 100644 index 0000000000000000000000000000000000000000..be9f6b0ec33b80fa0d69253b328abf05c0c99d61 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/twi/app_twi.h @@ -0,0 +1,321 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_TWI_H__ +#define APP_TWI_H__ + +#include +#include "nrf_drv_twi.h" +#include "sdk_errors.h" +#include "nrf_queue.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup app_twi TWI transaction manager + * @{ + * @ingroup app_common + * + * @brief Module for scheduling TWI transactions. + */ + +/** + * @brief Flag indicating that a given transfer should not be ended + * with a stop condition. + * + * Use this flag when a stop condition is undesirable between two transfers, + * for example, when the first transfer is a write that sets an address in the slave + * device and the second one is a read that fetches certain data using this + * address. In this case, the second transfer should follow directly after the + * first transfer, with a repeated start condition instead of a stop and then + * a new start condition. + */ +#define APP_TWI_NO_STOP 0x01 + +/** + * @brief Macro for creating a write transfer. + * + * @param[in] address Slave address. + * @param[in] p_data Pointer to the data to be sent. + * @param[in] length Number of bytes to transfer. + * @param[in] flags Transfer flags (see @ref APP_TWI_NO_STOP). + */ +#define APP_TWI_WRITE(address, p_data, length, flags) \ + APP_TWI_TRANSFER(APP_TWI_WRITE_OP(address), p_data, length, flags) + +/** + * @brief Macro for creating a read transfer. + * + * @param address Slave address. + * @param[in] p_data Pointer to the buffer where received data should be placed. + * @param length Number of bytes to transfer. + * @param flags Transfer flags (see @ref APP_TWI_NO_STOP). + */ +#define APP_TWI_READ(address, p_data, length, flags) \ + APP_TWI_TRANSFER(APP_TWI_READ_OP(address), p_data, length, flags) + +/** + * @brief Helper macro, should not be used directly. + */ +#define APP_TWI_TRANSFER(_operation, _p_data, _length, _flags) \ +{ \ + .p_data = (uint8_t *)(_p_data), \ + .length = _length, \ + .operation = _operation, \ + .flags = _flags \ +} +/** + * @brief Helper macro, should not be used directly. + */ +#define APP_TWI_WRITE_OP(address) (((address) << 1) | 0) +/** + * @brief Helper macro, should not be used directly. + */ +#define APP_TWI_READ_OP(address) (((address) << 1) | 1) +/** + * @brief Helper macro, should not be used directly. + */ +#define APP_TWI_IS_READ_OP(operation) ((operation) & 1) +/** + * @brief Helper macro, should not be used directly. + */ +#define APP_TWI_OP_ADDRESS(operation) ((operation) >> 1) + +/** + * @brief TWI transaction callback prototype. + * + * @param result Result of operation (NRF_SUCCESS on success, + * otherwise a relevant error code). + * @param[in] p_user_data Pointer to user data defined in transaction + * descriptor. + */ +typedef void (* app_twi_callback_t)(ret_code_t result, void * p_user_data); + +/** + * @brief TWI transfer descriptor. + */ +typedef struct { + uint8_t * p_data; ///< Pointer to the buffer holding the data. + uint8_t length; ///< Number of bytes to transfer. + uint8_t operation; ///< Device address combined with transfer direction. + uint8_t flags; ///< Transfer flags (see @ref APP_TWI_NO_STOP). +} app_twi_transfer_t; + +/** + * @brief TWI transaction descriptor. + */ +typedef struct { + app_twi_callback_t callback; + ///< User-specified function to be called after the transaction is finished. + + void * p_user_data; + ///< Pointer to user data to be passed to the callback. + + app_twi_transfer_t const * p_transfers; + ///< Pointer to the array of transfers that make up the transaction. + + uint8_t number_of_transfers; + ///< Number of transfers that make up the transaction. + + nrf_drv_twi_config_t const * p_required_twi_cfg; + ///< Pointer to instance hardware configuration. +} app_twi_transaction_t; + +/** + * @brief TWI instance control block. + */ +typedef struct { + app_twi_transaction_t const * volatile p_current_transaction; + ///< Currently realized transaction. + + nrf_drv_twi_config_t default_configuration; + ///< Default hardware configuration. + + nrf_drv_twi_config_t const * p_current_configuration; + ///< Pointer to current hardware configuration. + + uint8_t volatile current_transfer_idx; + ///< Index of currently performed transfer (within current transaction). + + bool volatile internal_transaction_in_progress; + ///< Informs that an internal transaction is being performed (by app_twi_perform()). + + uint8_t volatile internal_transaction_result; + ///< Used to pass the result of the internal transaction realized by app_twi_perform(). +}app_twi_cb_t; + +/** + * @brief TWI transaction manager instance. + */ +typedef struct { + app_twi_cb_t * p_app_twi_cb; + ///< Control block of instance. + + nrf_queue_t const * p_queue; + ///< Transaction queue. + + nrf_drv_twi_t twi; + ///< Pointer to TWI master driver instance. +} app_twi_t; + +/** + * @brief Macro that simplifies defining a TWI transaction manager + * instance. + * + * This macro allocates a static buffer for the transaction queue. + * Therefore, it should be used in only one place in the code for a given + * instance. + * + * @note The queue size is the maximum number of pending transactions + * not counting the one that is currently realized. This means that + * for an empty queue with size of, for example, 4 elements, it is + * possible to schedule up to 5 transactions. + * + * @param[in] _app_twi_name Name of instance to be created. + * @param[in] _queue_size Size of the transaction queue (maximum number + * of pending transactions). + * @param[in] _twi_idx Index of hardware TWI instance to be used. + */ +#define APP_TWI_DEF(_app_twi_name, _queue_size, _twi_idx) \ + NRF_QUEUE_DEF(app_twi_transaction_t const *, \ + _app_twi_name##_queue, \ + (_queue_size), \ + NRF_QUEUE_MODE_NO_OVERFLOW); \ + static app_twi_cb_t CONCAT_2(_app_twi_name, _cb); \ + static const app_twi_t _app_twi_name = \ + { \ + .p_app_twi_cb = &CONCAT_2(_app_twi_name, _cb), \ + .p_queue = &_app_twi_name##_queue, \ + .twi = NRF_DRV_TWI_INSTANCE(_twi_idx) \ + } + +/** + * @brief Function for initializing a TWI transaction manager instance. + * + * @param[in] p_app_twi Pointer to the instance to be initialized. + * @param[in] p_default_twi_config Pointer to the TWI master driver configuration. This configuration + * will be used whenever the scheduled transaction will have + * p_twi_configuration set to NULL value. + * + * @return Values returned by the @ref nrf_drv_twi_init function. + */ +ret_code_t app_twi_init(app_twi_t const * p_app_twi, + nrf_drv_twi_config_t const * p_default_twi_config); + +/** + * @brief Function for uninitializing a TWI transaction manager instance. + * + * @param[in] p_app_twi Pointer to the instance to be uninitialized. + */ +void app_twi_uninit(app_twi_t const * p_app_twi); + +/** + * @brief Function for scheduling a TWI transaction. + * + * The transaction is enqueued and started as soon as the TWI bus is + * available, thus when all previously scheduled transactions have been + * finished (possibly immediately). + * + * @note If @ref app_twi_transaction_t::p_required_twi_cfg + * is set to a non-NULL value the module will compare it with + * @ref app_twi_cb_t::p_current_configuration and reinitialize hardware + * TWI instance with new parameters if any differences are found. + * If @ref app_twi_transaction_t::p_required_twi_cfg is set to NULL then + * it will treat it as it would be set to @ref app_twi_cb_t::default_configuration. + * + * @param[in] p_app_twi Pointer to the TWI transaction manager instance. + * @param[in] p_transaction Pointer to the descriptor of the transaction to be + * scheduled. + * + * @retval NRF_SUCCESS If the transaction has been successfully scheduled. + * @retval NRF_ERROR_NO_MEM If the queue is full (Only if queue in + * @ref NRF_QUEUE_MODE_NO_OVERFLOW). + */ +ret_code_t app_twi_schedule(app_twi_t const * p_app_twi, + app_twi_transaction_t const * p_transaction); + +/** + * @brief Function for scheduling a transaction and waiting until it is finished. + * + * This function schedules a transaction that consists of one or more transfers + * and waits until it is finished. + * + * @param[in] p_app_twi Pointer to the TWI transaction manager instance. + * @param[in] p_transfers Pointer to an array of transfers to be performed. + * @param number_of_transfers Number of transfers to be performed. + * @param user_function User-specified function to be called while + * waiting. NULL if such functionality + * is not needed. + * + * @retval NRF_SUCCESS If the transfers have been successfully realized. + * @retval NRF_ERROR_BUSY If some transfers are already being performed. + * @retval - Other error codes mean that the transaction has ended + * with the error that is specified in the error code. + */ +ret_code_t app_twi_perform(app_twi_t const * p_app_twi, + app_twi_transfer_t const * p_transfers, + uint8_t number_of_transfers, + void (* user_function)(void)); + +/** + * @brief Function for getting the current state of a TWI transaction manager + * instance. + * + * @param[in] p_app_twi Pointer to the TWI transaction manager instance. + * + * @retval true If all scheduled transactions have been finished. + * @retval false Otherwise. + */ +__STATIC_INLINE bool app_twi_is_idle(app_twi_t const * p_app_twi) +{ + return (p_app_twi->p_app_twi_cb->p_current_transaction == NULL); +} + +/** + *@} + **/ + + +#ifdef __cplusplus +} +#endif + +#endif // APP_TWI_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/uart/app_uart.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/uart/app_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..d98741221f4d9221adabcac06102fcf66ea76a8d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/uart/app_uart.c @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_UART) +#include "app_uart.h" +#include "nrf_drv_uart.h" +#include "nrf_assert.h" + +static uint8_t tx_buffer[1]; +static uint8_t rx_buffer[1]; +static volatile bool rx_done; +static app_uart_event_handler_t m_event_handler; /**< Event handler function. */ +static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(APP_UART_DRIVER_INSTANCE); + +static void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context) +{ + if (p_event->type == NRF_DRV_UART_EVT_RX_DONE) + { + app_uart_evt_t app_uart_event; + app_uart_event.evt_type = APP_UART_DATA; + app_uart_event.data.value = p_event->data.rxtx.p_data[0]; + (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1); + rx_done = true; + m_event_handler(&app_uart_event); + } + else if (p_event->type == NRF_DRV_UART_EVT_ERROR) + { + app_uart_evt_t app_uart_event; + app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR; + app_uart_event.data.error_communication = p_event->data.error.error_mask; + (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1); + m_event_handler(&app_uart_event); + } + else if (p_event->type == NRF_DRV_UART_EVT_TX_DONE) + { + // Last byte from FIFO transmitted, notify the application. + // Notify that new data is available if this was first byte put in the buffer. + app_uart_evt_t app_uart_event; + app_uart_event.evt_type = APP_UART_TX_EMPTY; + m_event_handler(&app_uart_event); + } +} + +uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params, + app_uart_buffers_t * p_buffers, + app_uart_event_handler_t event_handler, + app_irq_priority_t irq_priority) +{ + nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG; + config.baudrate = (nrf_uart_baudrate_t)p_comm_params->baud_rate; + config.hwfc = (p_comm_params->flow_control == APP_UART_FLOW_CONTROL_DISABLED) ? + NRF_UART_HWFC_DISABLED : NRF_UART_HWFC_ENABLED; + config.interrupt_priority = irq_priority; + config.parity = p_comm_params->use_parity ? NRF_UART_PARITY_INCLUDED : NRF_UART_PARITY_EXCLUDED; + config.pselcts = p_comm_params->cts_pin_no; + config.pselrts = p_comm_params->rts_pin_no; + config.pselrxd = p_comm_params->rx_pin_no; + config.pseltxd = p_comm_params->tx_pin_no; + + m_event_handler = event_handler; + + rx_done = false; + + uint32_t err_code = nrf_drv_uart_init(&app_uart_inst, &config, uart_event_handler); + VERIFY_SUCCESS(err_code); + + // Turn on receiver if RX pin is connected + if (p_comm_params->rx_pin_no != UART_PIN_DISCONNECTED) + { +#ifdef UARTE_PRESENT + if (!config.use_easy_dma) +#endif + { + nrf_drv_uart_rx_enable(&app_uart_inst); + } + + return nrf_drv_uart_rx(&app_uart_inst, rx_buffer,1); + } + else + { + return NRF_SUCCESS; + } +} + + +uint32_t app_uart_get(uint8_t * p_byte) +{ + ASSERT(p_byte); + uint32_t err_code = NRF_SUCCESS; + if (rx_done) + { + *p_byte = rx_buffer[0]; + rx_done = false; + } + else + { + err_code = NRF_ERROR_NOT_FOUND; + } + return err_code; +} + +uint32_t app_uart_put(uint8_t byte) +{ + tx_buffer[0] = byte; + ret_code_t ret = nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1); + if (NRF_ERROR_BUSY == ret) + { + return NRF_ERROR_NO_MEM; + } + else if (ret != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + else + { + return NRF_SUCCESS; + } +} + +uint32_t app_uart_flush(void) +{ + return NRF_SUCCESS; +} + +uint32_t app_uart_close(void) +{ + nrf_drv_uart_uninit(&app_uart_inst); + return NRF_SUCCESS; +} +#endif //NRF_MODULE_ENABLED(APP_UART) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/uart/app_uart.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/uart/app_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..2614faf17749734ba643f584e52270c2eb097ca9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/uart/app_uart.h @@ -0,0 +1,262 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup app_uart UART module + * @{ + * @ingroup app_common + * + * @brief UART module interface. + */ + +#ifndef APP_UART_H__ +#define APP_UART_H__ + +#include +#include +#include "app_util_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UART_PIN_DISCONNECTED 0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */ + +/**@brief UART Flow Control modes for the peripheral. + */ +typedef enum +{ + APP_UART_FLOW_CONTROL_DISABLED, /**< UART Hw Flow Control is disabled. */ + APP_UART_FLOW_CONTROL_ENABLED, /**< Standard UART Hw Flow Control is enabled. */ +} app_uart_flow_control_t; + +/**@brief UART communication structure holding configuration settings for the peripheral. + */ +typedef struct +{ + uint32_t rx_pin_no; /**< RX pin number. */ + uint32_t tx_pin_no; /**< TX pin number. */ + uint32_t rts_pin_no; /**< RTS pin number, only used if flow control is enabled. */ + uint32_t cts_pin_no; /**< CTS pin number, only used if flow control is enabled. */ + app_uart_flow_control_t flow_control; /**< Flow control setting, if flow control is used, the system will use low power UART mode, based on CTS signal. */ + bool use_parity; /**< Even parity if TRUE, no parity if FALSE. */ + uint32_t baud_rate; /**< Baud rate configuration. */ +} app_uart_comm_params_t; + +/**@brief UART buffer for transmitting/receiving data. + */ +typedef struct +{ + uint8_t * rx_buf; /**< Pointer to the RX buffer. */ + uint32_t rx_buf_size; /**< Size of the RX buffer. */ + uint8_t * tx_buf; /**< Pointer to the TX buffer. */ + uint32_t tx_buf_size; /**< Size of the TX buffer. */ +} app_uart_buffers_t; + +/**@brief Enumeration which defines events used by the UART module upon data reception or error. + * + * @details The event type is used to indicate the type of additional information in the event + * @ref app_uart_evt_t. + */ +typedef enum +{ + APP_UART_DATA_READY, /**< An event indicating that UART data has been received. The data is available in the FIFO and can be fetched using @ref app_uart_get. */ + APP_UART_FIFO_ERROR, /**< An error in the FIFO module used by the app_uart module has occured. The FIFO error code is stored in app_uart_evt_t.data.error_code field. */ + APP_UART_COMMUNICATION_ERROR, /**< An communication error has occured during reception. The error is stored in app_uart_evt_t.data.error_communication field. */ + APP_UART_TX_EMPTY, /**< An event indicating that UART has completed transmission of all available data in the TX FIFO. */ + APP_UART_DATA, /**< An event indicating that UART data has been received, and data is present in data field. This event is only used when no FIFO is configured. */ +} app_uart_evt_type_t; + +/**@brief Struct containing events from the UART module. + * + * @details The app_uart_evt_t is used to notify the application of asynchronous events when data + * are received on the UART peripheral or in case an error occured during data reception. + */ +typedef struct +{ + app_uart_evt_type_t evt_type; /**< Type of event. */ + union + { + uint32_t error_communication; /**< Field used if evt_type is: APP_UART_COMMUNICATION_ERROR. This field contains the value in the ERRORSRC register for the UART peripheral. The UART_ERRORSRC_x defines from nrf5x_bitfields.h can be used to parse the error code. See also the \nRFXX Series Reference Manual for specification. */ + uint32_t error_code; /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */ + uint8_t value; /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */ + } data; +} app_uart_evt_t; + +/**@brief Function for handling app_uart event callback. + * + * @details Upon an event in the app_uart module this callback function will be called to notify + * the application about the event. + * + * @param[in] p_app_uart_event Pointer to UART event. + */ +typedef void (* app_uart_event_handler_t) (app_uart_evt_t * p_app_uart_event); + +/**@brief Macro for safe initialization of the UART module in a single user instance when using + * a FIFO together with UART. + * + * @param[in] P_COMM_PARAMS Pointer to a UART communication structure: app_uart_comm_params_t + * @param[in] RX_BUF_SIZE Size of desired RX buffer, must be a power of 2 or ZERO (No FIFO). + * @param[in] TX_BUF_SIZE Size of desired TX buffer, must be a power of 2 or ZERO (No FIFO). + * @param[in] EVT_HANDLER Event handler function to be called when an event occurs in the + * UART module. + * @param[in] IRQ_PRIO IRQ priority, app_irq_priority_t, for the UART module irq handler. + * @param[out] ERR_CODE The return value of the UART initialization function will be + * written to this parameter. + * + * @note Since this macro allocates a buffer and registers the module as a GPIOTE user when flow + * control is enabled, it must only be called once. + */ +#define APP_UART_FIFO_INIT(P_COMM_PARAMS, RX_BUF_SIZE, TX_BUF_SIZE, EVT_HANDLER, IRQ_PRIO, ERR_CODE) \ + do \ + { \ + app_uart_buffers_t buffers; \ + static uint8_t rx_buf[RX_BUF_SIZE]; \ + static uint8_t tx_buf[TX_BUF_SIZE]; \ + \ + buffers.rx_buf = rx_buf; \ + buffers.rx_buf_size = sizeof (rx_buf); \ + buffers.tx_buf = tx_buf; \ + buffers.tx_buf_size = sizeof (tx_buf); \ + ERR_CODE = app_uart_init(P_COMM_PARAMS, &buffers, EVT_HANDLER, IRQ_PRIO); \ + } while (0) + +/**@brief Macro for safe initialization of the UART module in a single user instance. + * + * @param[in] P_COMM_PARAMS Pointer to a UART communication structure: app_uart_comm_params_t + * @param[in] EVT_HANDLER Event handler function to be called when an event occurs in the + * UART module. + * @param[in] IRQ_PRIO IRQ priority, app_irq_priority_t, for the UART module irq handler. + * @param[out] ERR_CODE The return value of the UART initialization function will be + * written to this parameter. + * + * @note Since this macro allocates registers the module as a GPIOTE user when flow control is + * enabled, it must only be called once. + */ +#define APP_UART_INIT(P_COMM_PARAMS, EVT_HANDLER, IRQ_PRIO, ERR_CODE) \ + do \ + { \ + ERR_CODE = app_uart_init(P_COMM_PARAMS, NULL, EVT_HANDLER, IRQ_PRIO); \ + } while (0) + +/**@brief Function for initializing the UART module. Use this initialization when several instances of the UART + * module are needed. + * + * + * @note Normally single initialization should be done using the APP_UART_INIT() or + * APP_UART_INIT_FIFO() macro depending on whether the FIFO should be used by the UART, as + * that will allocate the buffers needed by the UART module (including aligning the buffer + * correctly). + + * @param[in] p_comm_params Pin and communication parameters. + * @param[in] p_buffers RX and TX buffers, NULL is FIFO is not used. + * @param[in] error_handler Function to be called in case of an error. + * @param[in] irq_priority Interrupt priority level. + * + * @retval NRF_SUCCESS If successful initialization. + * @retval NRF_ERROR_INVALID_LENGTH If a provided buffer is not a power of two. + * @retval NRF_ERROR_NULL If one of the provided buffers is a NULL pointer. + * + * The below errors are propagated by the UART module to the caller upon registration when Hardware + * Flow Control is enabled. When Hardware Flow Control is not used, these errors cannot occur. + * @retval NRF_ERROR_INVALID_STATE The GPIOTE module is not in a valid state when registering + * the UART module as a user. + * @retval NRF_ERROR_INVALID_PARAM The UART module provides an invalid callback function when + * registering the UART module as a user. + * Or the value pointed to by *p_uart_uid is not a valid + * GPIOTE number. + * @retval NRF_ERROR_NO_MEM GPIOTE module has reached the maximum number of users. + */ +uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params, + app_uart_buffers_t * p_buffers, + app_uart_event_handler_t error_handler, + app_irq_priority_t irq_priority); + +/**@brief Function for getting a byte from the UART. + * + * @details This function will get the next byte from the RX buffer. If the RX buffer is empty + * an error code will be returned and the app_uart module will generate an event upon + * reception of the first byte which is added to the RX buffer. + * + * @param[out] p_byte Pointer to an address where next byte received on the UART will be copied. + * + * @retval NRF_SUCCESS If a byte has been received and pushed to the pointer provided. + * @retval NRF_ERROR_NOT_FOUND If no byte is available in the RX buffer of the app_uart module. + */ +uint32_t app_uart_get(uint8_t * p_byte); + +/**@brief Function for putting a byte on the UART. + * + * @details This call is non-blocking. + * + * @param[in] byte Byte to be transmitted on the UART. + * + * @retval NRF_SUCCESS If the byte was successfully put on the TX buffer for transmission. + * @retval NRF_ERROR_NO_MEM If no more space is available in the TX buffer. + * NRF_ERROR_NO_MEM may occur if flow control is enabled and CTS signal + * is high for a long period and the buffer fills up. + * @retval NRF_ERROR_INTERNAL If UART driver reported error. + */ +uint32_t app_uart_put(uint8_t byte); + +/**@brief Function for flushing the RX and TX buffers (Only valid if FIFO is used). + * This function does nothing if FIFO is not used. + * + * @retval NRF_SUCCESS Flushing completed (Current implementation will always succeed). + */ +uint32_t app_uart_flush(void); + +/**@brief Function for closing the UART module. + * + * @retval NRF_SUCCESS If successfully closed. + * @retval NRF_ERROR_INVALID_PARAM If an invalid user id is provided or the user id differs from + * the current active user. + */ +uint32_t app_uart_close(void); + + + +#ifdef __cplusplus +} +#endif + +#endif //APP_UART_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/uart/app_uart_fifo.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/uart/app_uart_fifo.c new file mode 100644 index 0000000000000000000000000000000000000000..d8c8eea4dc5a26c4fbd3183a7d7ab8ac15b7adb7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/uart/app_uart_fifo.c @@ -0,0 +1,251 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_UART) +#include "app_uart.h" +#include "app_fifo.h" +#include "nrf_drv_uart.h" +#include "nrf_assert.h" + +static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(APP_UART_DRIVER_INSTANCE); + +static __INLINE uint32_t fifo_length(app_fifo_t * const fifo) +{ + uint32_t tmp = fifo->read_pos; + return fifo->write_pos - tmp; +} + +#define FIFO_LENGTH(F) fifo_length(&F) /**< Macro to calculate length of a FIFO. */ + + +static app_uart_event_handler_t m_event_handler; /**< Event handler function. */ +static uint8_t tx_buffer[1]; +static uint8_t rx_buffer[1]; +static bool m_rx_ovf; + +static app_fifo_t m_rx_fifo; /**< RX FIFO buffer for storing data received on the UART until the application fetches them using app_uart_get(). */ +static app_fifo_t m_tx_fifo; /**< TX FIFO buffer for storing data to be transmitted on the UART when TXD is ready. Data is put to the buffer on using app_uart_put(). */ + +static void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context) +{ + app_uart_evt_t app_uart_event; + uint32_t err_code; + + switch (p_event->type) + { + case NRF_DRV_UART_EVT_RX_DONE: + // Write received byte to FIFO. + err_code = app_fifo_put(&m_rx_fifo, p_event->data.rxtx.p_data[0]); + if (err_code != NRF_SUCCESS) + { + app_uart_event.evt_type = APP_UART_FIFO_ERROR; + app_uart_event.data.error_code = err_code; + m_event_handler(&app_uart_event); + } + // Notify that there are data available. + else if (FIFO_LENGTH(m_rx_fifo) != 0) + { + app_uart_event.evt_type = APP_UART_DATA_READY; + m_event_handler(&app_uart_event); + } + + // Start new RX if size in buffer. + if (FIFO_LENGTH(m_rx_fifo) <= m_rx_fifo.buf_size_mask) + { + (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1); + } + else + { + // Overflow in RX FIFO. + m_rx_ovf = true; + } + + break; + + case NRF_DRV_UART_EVT_ERROR: + app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR; + app_uart_event.data.error_communication = p_event->data.error.error_mask; + (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1); + m_event_handler(&app_uart_event); + break; + + case NRF_DRV_UART_EVT_TX_DONE: + // Get next byte from FIFO. + if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS) + { + (void)nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1); + } + else + { + // Last byte from FIFO transmitted, notify the application. + app_uart_event.evt_type = APP_UART_TX_EMPTY; + m_event_handler(&app_uart_event); + } + break; + + default: + break; + } +} + + +uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params, + app_uart_buffers_t * p_buffers, + app_uart_event_handler_t event_handler, + app_irq_priority_t irq_priority) +{ + uint32_t err_code; + + m_event_handler = event_handler; + + if (p_buffers == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Configure buffer RX buffer. + err_code = app_fifo_init(&m_rx_fifo, p_buffers->rx_buf, p_buffers->rx_buf_size); + VERIFY_SUCCESS(err_code); + + // Configure buffer TX buffer. + err_code = app_fifo_init(&m_tx_fifo, p_buffers->tx_buf, p_buffers->tx_buf_size); + VERIFY_SUCCESS(err_code); + + nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG; + config.baudrate = (nrf_uart_baudrate_t)p_comm_params->baud_rate; + config.hwfc = (p_comm_params->flow_control == APP_UART_FLOW_CONTROL_DISABLED) ? + NRF_UART_HWFC_DISABLED : NRF_UART_HWFC_ENABLED; + config.interrupt_priority = irq_priority; + config.parity = p_comm_params->use_parity ? NRF_UART_PARITY_INCLUDED : NRF_UART_PARITY_EXCLUDED; + config.pselcts = p_comm_params->cts_pin_no; + config.pselrts = p_comm_params->rts_pin_no; + config.pselrxd = p_comm_params->rx_pin_no; + config.pseltxd = p_comm_params->tx_pin_no; + + err_code = nrf_drv_uart_init(&app_uart_inst, &config, uart_event_handler); + VERIFY_SUCCESS(err_code); + m_rx_ovf = false; + + // Turn on receiver if RX pin is connected + if (p_comm_params->rx_pin_no != UART_PIN_DISCONNECTED) + { +#ifdef UARTE_PRESENT + if (!config.use_easy_dma) +#endif + { + nrf_drv_uart_rx_enable(&app_uart_inst); + } + + return nrf_drv_uart_rx(&app_uart_inst, rx_buffer,1); + } + else + { + return NRF_SUCCESS; + } +} + + +uint32_t app_uart_flush(void) +{ + uint32_t err_code; + + err_code = app_fifo_flush(&m_rx_fifo); + VERIFY_SUCCESS(err_code); + + err_code = app_fifo_flush(&m_tx_fifo); + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} + + +uint32_t app_uart_get(uint8_t * p_byte) +{ + ASSERT(p_byte); + bool rx_ovf = m_rx_ovf; + + ret_code_t err_code = app_fifo_get(&m_rx_fifo, p_byte); + + // If FIFO was full new request to receive one byte was not scheduled. Must be done here. + if(rx_ovf) + { + m_rx_ovf = false; + uint32_t uart_err_code = nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1); + + // RX resume should never fail. + APP_ERROR_CHECK(uart_err_code); + } + + return err_code; +} + + +uint32_t app_uart_put(uint8_t byte) +{ + uint32_t err_code; + err_code = app_fifo_put(&m_tx_fifo, byte); + if (err_code == NRF_SUCCESS) + { + // The new byte has been added to FIFO. It will be picked up from there + // (in 'uart_event_handler') when all preceding bytes are transmitted. + // But if UART is not transmitting anything at the moment, we must start + // a new transmission here. + if (!nrf_drv_uart_tx_in_progress(&app_uart_inst)) + { + // This operation should be almost always successful, since we've + // just added a byte to FIFO, but if some bigger delay occurred + // (some heavy interrupt handler routine has been executed) since + // that time, FIFO might be empty already. + if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS) + { + err_code = nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1); + } + } + } + return err_code; +} + + +uint32_t app_uart_close(void) +{ + nrf_drv_uart_uninit(&app_uart_inst); + return NRF_SUCCESS; +} +#endif //NRF_MODULE_ENABLED(APP_UART) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/uart/retarget.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/uart/retarget.c new file mode 100644 index 0000000000000000000000000000000000000000..65374f8071eaf17a308e63d0f3469095bf592b81 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/uart/retarget.c @@ -0,0 +1,138 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +/** @file + * + * @defgroup retarget Retarget layer for stdio functions + * @{ + * @ingroup app_common + * @} */ +#if NRF_MODULE_ENABLED(RETARGET) +#if !defined(NRF_LOG_USES_RTT) || NRF_LOG_USES_RTT != 1 +#if !defined(HAS_SIMPLE_UART_RETARGET) + + +#include +#include +#include "app_uart.h" +#include "nrf_error.h" + +#if !defined(__ICCARM__) +struct __FILE +{ + int handle; +}; +#endif + +FILE __stdout; +FILE __stdin; + + +#if defined(__CC_ARM) || defined(__ICCARM__) +int fgetc(FILE * p_file) +{ + uint8_t input; + while (app_uart_get(&input) == NRF_ERROR_NOT_FOUND) + { + // No implementation needed. + } + return input; +} + + +int fputc(int ch, FILE * p_file) +{ + UNUSED_PARAMETER(p_file); + + UNUSED_VARIABLE(app_uart_put((uint8_t)ch)); + return ch; +} + +#elif defined(__GNUC__) + + +int _write(int file, const char * p_char, int len) +{ + int i; + + UNUSED_PARAMETER(file); + + for (i = 0; i < len; i++) + { + UNUSED_VARIABLE(app_uart_put(*p_char++)); + } + + return len; +} + + +int _read(int file, char * p_char, int len) +{ + UNUSED_PARAMETER(file); + while (app_uart_get((uint8_t *)p_char) == NRF_ERROR_NOT_FOUND) + { + // No implementation needed. + } + + return 1; +} +#endif + +#if defined(__ICCARM__) + +__ATTRIBUTES size_t __write(int file, const unsigned char * p_char, size_t len) +{ + int i; + + UNUSED_PARAMETER(file); + + for (i = 0; i < len; i++) + { + UNUSED_VARIABLE(app_uart_put(*p_char++)); + } + + return len; +} + +#endif + +#endif // !defined(HAS_SIMPLE_UART_RETARGET) +#endif // NRF_LOG_USES_RTT != 1 +#endif //NRF_MODULE_ENABLED(RETARGET) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd.c new file mode 100644 index 0000000000000000000000000000000000000000..94f25ba3d34d31922fdb96263362976123beb46d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd.c @@ -0,0 +1,919 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" +#if APP_USBD_ENABLED +#include "sdk_common.h" +#include "app_usbd.h" +#include "app_usbd_core.h" + +/* Base variables tests */ + +/* Check event of app_usbd_event_type_t enumerator */ +STATIC_ASSERT((int32_t)APP_USBD_EVT_FIRST_APP == (int32_t)NRF_DRV_USBD_EVT_CNT); +STATIC_ASSERT(sizeof(app_usbd_event_type_t) == sizeof(nrf_drv_usbd_event_type_t)); + +STATIC_ASSERT(sizeof(app_usbd_descriptor_header_t) == 2); +STATIC_ASSERT(sizeof(app_usbd_descriptor_device_t) == 18); +STATIC_ASSERT(sizeof(app_usbd_descriptor_configuration_t) == 9); +STATIC_ASSERT(sizeof(app_usbd_descriptor_iface_t) == 9); +STATIC_ASSERT(sizeof(app_usbd_descriptor_ep_t) == 7); +STATIC_ASSERT(sizeof(app_usbd_descriptor_iad_t) == 8); + +STATIC_ASSERT(sizeof(app_usbd_setup_t) == sizeof(nrf_drv_usbd_setup_t)); + +/** + * @internal + * @defgroup app_usbd_internals USBD library internals + * @ingroup app_usbd + * + * Internal variables, auxiliary macros and functions of USBD library. + * @{ + */ + +/** + * @brief Variable type for endpoint configuration + * + * Each endpoint would have assigned this type of configuration structure. + */ +typedef struct +{ + /** + * @brief The class instance + * + * The pointer to the class instance that is connected to the endpoint. + */ + app_usbd_class_inst_t const * p_cinst; + + /** + * @brief Endpoint event handler. + * + * Event handler for the endpoint. + * It is set to event handler for the class instance during connection by default, + * but it can be then updated for as a reaction for @ref APP_USBD_EVT_ATTACHED event. + * This way we can speed up the interpretation of endpoint related events. + */ + app_usbd_ep_event_handler_t event_handler; +}app_usbd_ep_conf_t; + +/** + * @brief Instances connected with IN endpoints + * + * Array of instance pointers connected with every IN endpoint. + * @sa m_epout_instances + */ +static app_usbd_ep_conf_t m_epin_conf[NRF_USBD_EPIN_CNT]; + +/** + * @brief Instances connected with OUT endpoints + * + * Array of instance pointers connected with every OUT endpoint. + * @sa m_epin_instances + */ +static app_usbd_ep_conf_t m_epout_conf[NRF_USBD_EPIN_CNT]; + +/** + * @brief Beginning of classes list + * + * All enabled in current configuration instances are connected into + * a single linked list chain. + * This variable points to first element. + * Core class instance (connected to endpoint 0) is not listed here. + */ +static app_usbd_class_inst_t const * m_p_first_cinst; + +/** + * @brief Classes list that requires SOF events + * + * @todo RK Implement and documentation + */ +static app_usbd_class_inst_t const * m_p_first_sof_cinst; + +/** + * @brief Default configuration (when NULL is passed to @ref app_usbd_init). + */ +static const app_usbd_config_t m_default_conf = { + .ev_handler = NULL +}; + +/** + * @brief Current configuration. + */ +static app_usbd_config_t m_current_conf; + +/** + * @brief Class interface call: event handler + * + * @ref app_usbd_class_interface_t::event_handler + * + * @param[in] p_cinst Class instance + * @param[in] p_event Event passed to class instance + * + * @return Standard error code @ref ret_code_t + * @retval NRF_SUCCESS event handled successfully + * @retval NRF_ERROR_NOT_SUPPORTED unsupported event + * */ +static inline ret_code_t class_event_handler(app_usbd_class_inst_t const * const p_cinst, + app_usbd_complex_evt_t const * const p_event) +{ + ASSERT(p_cinst != NULL); + ASSERT(p_cinst->p_class_methods != NULL); + ASSERT(p_cinst->p_class_methods->event_handler != NULL); + return p_cinst->p_class_methods->event_handler(p_cinst, p_event); +} + +/** + * @brief User event handler call (passed via configuration). + * + * @param event Event type. + */ +static inline void user_event_handler(app_usbd_event_type_t event) +{ + if ((m_current_conf.ev_handler) != NULL) + { + m_current_conf.ev_handler(event); + } +} + +/** + * @brief Class interface call: get descriptors + * + * @ref app_usbd_class_interface_t::get_descriptors + * + * @param[in] p_inst Class instance + * @param[out] p_size Descriptors size + * + * @return Class descriptors start address + * */ +static inline const void * class_get_descriptors(app_usbd_class_inst_t const * const p_cinst, + size_t * p_size) +{ + ASSERT(p_cinst != NULL); + ASSERT(p_cinst->p_class_methods != NULL); + ASSERT(p_cinst->p_class_methods->get_descriptors != NULL); + return p_cinst->p_class_methods->get_descriptors(p_cinst, p_size); +} + +const void * app_usbd_class_descriptor_find(app_usbd_class_inst_t const * const p_cinst, + uint8_t desc_type, + uint8_t desc_index, + size_t * p_desc_len) +{ + app_usbd_descriptor_header_t const * p_header; + uint8_t const * p_raw = class_get_descriptors(p_cinst, p_desc_len); + if (p_raw == NULL) + { + return NULL; + } + + size_t pos = 0; + uint8_t index = 0; + while (pos < *p_desc_len) + { + p_header = (app_usbd_descriptor_header_t const *)(p_raw + pos); + if (p_header->bDescriptorType == desc_type) + { + if (desc_index == index) + { + *p_desc_len = p_header->bLength; + return p_header; + } + + index++; + } + + pos += p_header->bLength; + } + + return NULL; +} + +/** + * @brief Access into selected endpoint configuration structure + * + * @param ep Endpoint address + * @return A pointer to the endpoint configuration structure + * + * @note This function would assert when endpoint number is not correct and debugging is enabled. + */ +static app_usbd_ep_conf_t * app_usbd_ep_conf_access(nrf_drv_usbd_ep_t ep) +{ + if (NRF_USBD_EPIN_CHECK(ep)) + { + uint8_t nr = NRF_USBD_EP_NR_GET(ep); + ASSERT(nr < NRF_USBD_EPIN_CNT); + return &m_epin_conf[nr]; + } + else + { + uint8_t nr = NRF_USBD_EP_NR_GET(ep); + ASSERT(nr < NRF_USBD_EPOUT_CNT); + return &m_epout_conf[nr]; + } +} + +/** + * @brief Accessing instance connected with selected endpoint + * + * @param ep Endpoint number + * + * @return The pointer to the instance connected with endpoint + */ +static inline app_usbd_class_inst_t const * app_usbd_ep_instance_get(nrf_drv_usbd_ep_t ep) +{ + return app_usbd_ep_conf_access(ep)->p_cinst; +} + +/** + * @brief Connect instance with selected endpoint + * + * This function configures instance connected to endpoint but also sets + * default event handler function pointer. + * + * @param ep Endpoint number + * @param p_cinst The instance to connect into the selected endpoint. + * NULL if endpoint is going to be disconnected. + * + * @note Disconnecting EP0 is not allowed and protected by assertion. + */ +static void app_usbd_ep_instance_set(nrf_drv_usbd_ep_t ep, app_usbd_class_inst_t const * p_cinst) +{ + app_usbd_ep_conf_t * p_ep_conf = app_usbd_ep_conf_access(ep); + /* Set instance and default event handler */ + p_ep_conf->p_cinst = p_cinst; + if (p_cinst == NULL) + { + ASSERT((ep != NRF_DRV_USBD_EPOUT0) && (ep != NRF_DRV_USBD_EPIN0)); /* EP0 should never be disconnected */ + p_ep_conf->event_handler = NULL; + } + else + { + p_ep_conf->event_handler = p_cinst->p_class_methods->event_handler; + } +} + +/** + * @brief Call the core handler + * + * Core instance is special kind of instance that is connected only to endpoint 0. + * It is not present in instance list. + * This auxiliary function makes future changes easier. + * Just call the event instance for core module here. + */ +static inline ret_code_t app_usbd_core_handler_call(nrf_drv_usbd_evt_t const * const p_event) +{ + return m_epout_conf[0].event_handler( + m_epout_conf[0].p_cinst, + (app_usbd_complex_evt_t const *)p_event); +} + +/** + * @brief USBD event handler + * + * + */ +static void app_usbd_event_handler(nrf_drv_usbd_evt_t const * const p_event) +{ + ASSERT(NULL != m_p_first_cinst); + + /* Note - there should never be situation that event is generated on disconnected endpoint */ + switch(p_event->type) + { + case NRF_DRV_USBD_EVT_SOF: + { + app_usbd_class_inst_t const * p_inst = app_usbd_class_sof_first_get(); + ASSERT(NULL != p_inst); /* This should not happen - when no SOF instances are in the list, SOF event is disabled */ + + while (NULL != p_inst) + { + ret_code_t r = class_event_handler(p_inst, (app_usbd_complex_evt_t const *)p_event); + UNUSED_VARIABLE(r); + p_inst = app_usbd_class_sof_next_get(p_inst); + } + break; + } + + /* Reset and */ + case NRF_DRV_USBD_EVT_RESET: + case NRF_DRV_USBD_EVT_RESUME: + { + /* Processing core interface (connected only to EP0) and then all instances from the list */ + UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event)); + app_usbd_all_call((app_usbd_complex_evt_t const *)p_event); + break; + } + case NRF_DRV_USBD_EVT_SUSPEND: + { + /* Processing all instances from the list and then core interface (connected only to EP0) */ + app_usbd_all_call((app_usbd_complex_evt_t const *)p_event); + UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event)); + break; + } + + case NRF_DRV_USBD_EVT_SETUP: + { + UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event)); + break; + } + + case NRF_DRV_USBD_EVT_EPTRANSFER: + { + app_usbd_ep_conf_t const * p_ep_conf = + app_usbd_ep_conf_access(p_event->data.eptransfer.ep); + ASSERT(NULL != p_ep_conf->p_cinst); + ASSERT(NULL != p_ep_conf->event_handler); + + if (NRF_SUCCESS != p_ep_conf->event_handler(p_ep_conf->p_cinst, + (app_usbd_complex_evt_t const *)p_event)) + { + /* If error returned, every bulk/interrupt endpoint would be stalled */ + if (!(0 == NRF_USBD_EP_NR_GET(p_event->data.eptransfer.ep) || + NRF_USBD_EPISO_CHECK(p_event->data.eptransfer.ep))) + { + nrf_drv_usbd_ep_stall(p_event->data.eptransfer.ep); + } + } + break; + } + + default: + ASSERT(0); + break; + } + + user_event_handler((app_usbd_event_type_t)p_event->type); +} + +/** @} */ + + +ret_code_t app_usbd_init(app_usbd_config_t const * p_config) +{ + ret_code_t ret; + + ret = nrf_drv_usbd_init(app_usbd_event_handler); + if (NRF_SUCCESS != ret) + { + return ret; + } + + if (p_config == NULL) + { + m_current_conf = m_default_conf; + } + else + { + m_current_conf = *p_config; + } + + /* Clear variables */ + m_p_first_cinst = NULL; + m_p_first_sof_cinst = NULL; + memset(m_epin_conf , 0, sizeof(m_epin_conf )); + memset(m_epout_conf, 0, sizeof(m_epout_conf)); + + /*Pin core class to required endpoints*/ + uint8_t iface_idx; + app_usbd_class_iface_conf_t const * p_iface; + app_usbd_class_inst_t const * const p_inst = app_usbd_core_instance_access(); + iface_idx = 0; + while ((p_iface = app_usbd_class_iface_get(p_inst, iface_idx++)) != NULL) + { + uint8_t ep_idx = 0; + app_usbd_class_ep_conf_t const * p_ep; + while ((p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++)) != NULL) + { + app_usbd_ep_instance_set(app_usbd_class_ep_address_get(p_ep), p_inst); + } + } + + /* Successfully attached */ + const app_usbd_evt_t evt_data = { + .type = APP_USBD_EVT_INST_APPEND + }; + + return class_event_handler(p_inst, (app_usbd_complex_evt_t const *)(&evt_data)); +} + + +ret_code_t app_usbd_uninit(void) +{ + ret_code_t ret; + + ret = nrf_drv_usbd_uninit(); + if(NRF_SUCCESS != ret) + return ret; + + /* Unchain instance list */ + app_usbd_class_inst_t const * * pp_inst; + pp_inst = &m_p_first_cinst; + while (NULL != (*pp_inst)) + { + app_usbd_class_inst_t const * * pp_next = &app_usbd_class_data_access(*pp_inst)->p_next; + (*pp_inst) = NULL; + pp_inst = pp_next; + } + + /* Unchain SOF list */ + pp_inst = &m_p_first_sof_cinst; + while (NULL != (*pp_inst)) + { + app_usbd_class_inst_t const * * pp_next = &app_usbd_class_data_access(*pp_inst)->p_sof_next; + (*pp_inst) = NULL; + pp_inst = pp_next; + } + + /* Clear all endpoints configurations */ + memset(m_epin_conf , 0, sizeof(m_epin_conf )); + memset(m_epout_conf, 0, sizeof(m_epout_conf)); + /* Clear current configuration */ + memset(&m_current_conf, 0, sizeof(m_current_conf)); + + return ret; +} + + +void app_usbd_enable(void) +{ + nrf_drv_usbd_enable(); + while (!app_usbd_core_power_regulator_is_ready()) + { + /* Just waiting */ + } +} + + +void app_usbd_disable(void) +{ + if (nrf_drv_usbd_is_started()) + { + app_usbd_stop(); + } + nrf_drv_usbd_disable(); +} + + +void app_usbd_start(void) +{ + const app_usbd_evt_t evt_data = { + .type = APP_USBD_EVT_START + }; + + /* Enable all connected endpoints */ + uint8_t n; + for (n = 1; n < ARRAY_SIZE(m_epin_conf); ++n) + { + if (NULL != m_epin_conf[n].p_cinst) + { + nrf_drv_usbd_ep_enable(NRF_DRV_USBD_EPIN(n)); + } + } + for (n = 1; n < ARRAY_SIZE(m_epout_conf); ++n) + { + if (NULL != m_epout_conf[n].p_cinst) + { + nrf_drv_usbd_ep_enable(NRF_DRV_USBD_EPOUT(n)); + } + } + + /* Send event to all classes */ + UNUSED_RETURN_VALUE(app_usbd_core_handler_call((nrf_drv_usbd_evt_t const * )&evt_data)); + app_usbd_all_call((app_usbd_complex_evt_t const *)&evt_data); + user_event_handler(APP_USBD_EVT_START); + + nrf_drv_usbd_start(NULL != m_p_first_sof_cinst); +} + + +void app_usbd_stop(void) +{ + const app_usbd_evt_t evt_data = { + .type = APP_USBD_EVT_STOP + }; + + nrf_drv_usbd_stop(); + + /* Send event to all classes */ + app_usbd_all_call((app_usbd_complex_evt_t const * )&evt_data); + UNUSED_RETURN_VALUE(app_usbd_core_handler_call((nrf_drv_usbd_evt_t const *)&evt_data)); + user_event_handler(APP_USBD_EVT_STOP); +} + + +ret_code_t app_usbd_class_append(app_usbd_class_inst_t const * p_cinst) +{ + ASSERT(NULL != p_cinst); + ASSERT(NULL != p_cinst->p_class_methods); + ASSERT(NULL != p_cinst->p_class_methods->event_handler); + ASSERT(NULL == app_usbd_class_data_access(p_cinst)->p_next); + + /* This should be only called if USBD is disabled + * We simply assume that USBD is enabled if its interrupts are */ + ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized()); + + /* Check if all required endpoints are available + * Checking is splitted from setting to avoid situation that anything + * is modified and then operation finishes with error */ + uint8_t iface_idx; + app_usbd_class_iface_conf_t const * p_iface; + + iface_idx = 0; + while (NULL != (p_iface = app_usbd_class_iface_get(p_cinst, iface_idx++))) + { + uint8_t ep_idx = 0; + app_usbd_class_ep_conf_t const * p_ep; + while (NULL != (p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++))) + { + if (NULL != app_usbd_ep_instance_get(app_usbd_class_ep_address_get(p_ep))) + { + return NRF_ERROR_BUSY; + } + } + } + + /* Connecting all required endpoints */ + iface_idx = 0; + while (NULL != (p_iface = app_usbd_class_iface_get(p_cinst, iface_idx++))) + { + uint8_t ep_idx = 0; + app_usbd_class_ep_conf_t const * p_ep; + while (NULL != (p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++))) + { + app_usbd_ep_instance_set(app_usbd_class_ep_address_get(p_ep), p_cinst); + } + } + + /* Adding pointer to this instance to the end of the chain */ + app_usbd_class_inst_t const * * pp_last = &m_p_first_cinst; + while (NULL != (*pp_last)) + { + ASSERT((*pp_last) != p_cinst); + pp_last = &(app_usbd_class_data_access(*pp_last)->p_next); + } + (*pp_last) = p_cinst; + + /* Successfully attached */ + const app_usbd_evt_t evt_data = {.type = APP_USBD_EVT_INST_APPEND }; + return class_event_handler(p_cinst, (app_usbd_complex_evt_t const *)(&evt_data)); +} + + +ret_code_t app_usbd_class_remove(app_usbd_class_inst_t const * p_cinst) +{ + ASSERT(NULL != p_cinst); + ASSERT(NULL != p_cinst->p_class_methods); + ASSERT(NULL != p_cinst->p_class_methods->event_handler); + /** This function should be only called if USBD is disabled */ + ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized()); + ret_code_t ret; + /* Remove this class from the chain */ + app_usbd_class_inst_t const * * pp_last = &m_p_first_cinst; + while (NULL != (*pp_last)) + { + if ((*pp_last) == p_cinst) + { + /* Inform class instance that removing process is going to be started */ + const app_usbd_evt_t evt_data = { + .type = APP_USBD_EVT_INST_REMOVE + }; + ret = class_event_handler(p_cinst, (app_usbd_complex_evt_t const *)(&evt_data)); + if (ret != NRF_SUCCESS) + { + return ret; + } + + /* Breaking chain */ + (*pp_last) = (app_usbd_class_data_access(p_cinst)->p_next); + app_usbd_class_data_access(p_cinst)->p_next = NULL; + + /* Disconnecting endpoints */ + uint8_t ep_idx; + for (ep_idx = 0; ep_idx < NRF_USBD_EPIN_CNT; ++ep_idx) + { + nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPIN(ep_idx); + if (app_usbd_ep_instance_get(ep) == p_cinst) + { + app_usbd_ep_instance_set(ep, NULL); + } + } + for (ep_idx = 0; ep_idx < NRF_USBD_EPOUT_CNT; ++ep_idx) + { + nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPOUT(ep_idx); + if (app_usbd_ep_instance_get(ep) == p_cinst) + { + app_usbd_ep_instance_set(ep, NULL); + } + } + + return NRF_SUCCESS; + } + pp_last = &(app_usbd_class_data_access(*pp_last)->p_next); + } + + return NRF_ERROR_NOT_FOUND; +} + + +ret_code_t app_usbd_class_remove_all(void) +{ + ret_code_t ret = NRF_SUCCESS; + while (NULL != m_p_first_cinst) + { + ret = app_usbd_class_remove(m_p_first_cinst); + if (ret != NRF_SUCCESS) + { + break; + } + } + + return ret; +} + + +ret_code_t app_usbd_ep_handler_set(app_usbd_class_inst_t const * const p_cinst, + nrf_drv_usbd_ep_t ep, + app_usbd_ep_event_handler_t handler) +{ + ASSERT(NULL != p_cinst); + ASSERT(NULL != handler); + /** This function should be only called if USBD is disabled */ + ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized()); + + if (p_cinst != app_usbd_ep_instance_get(ep)) + { + return NRF_ERROR_INVALID_PARAM; + } + + (app_usbd_ep_conf_access(ep))->event_handler = handler; + return NRF_SUCCESS; +} + + +ret_code_t app_usbd_class_sof_register(app_usbd_class_inst_t const * p_cinst) +{ + ASSERT(NULL != p_cinst); + ASSERT(NULL != p_cinst->p_class_methods); + ASSERT(NULL != p_cinst->p_class_methods->event_handler); + /** This function should be only called if USBD is disabled */ + ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized()); + + /* Next SOF event requiring instance have to be null now */ + ASSERT(NULL == (app_usbd_class_data_access(p_cinst)->p_sof_next)); + + /* Adding pointer to this instance to the end of the chain */ + app_usbd_class_inst_t const * * pp_last = &m_p_first_sof_cinst; + while (NULL != (*pp_last)) + { + + ASSERT((*pp_last) != p_cinst); + pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next); + } + (*pp_last) = p_cinst; + + return NRF_SUCCESS; +} + + +ret_code_t app_usbd_class_sof_unregister(app_usbd_class_inst_t const * p_cinst) +{ + ASSERT(NULL != p_cinst); + /** This function should be only called if USBD is disabled */ + ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized()); + + app_usbd_class_inst_t const * * pp_last = &m_p_first_sof_cinst; + while (NULL != (*pp_last)) + { + if ((*pp_last) == p_cinst) + { + /* Breaking chain */ + (*pp_last) = (app_usbd_class_data_access(p_cinst)->p_sof_next); + app_usbd_class_data_access(p_cinst)->p_sof_next = NULL; + + return NRF_SUCCESS; + } + pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next); + } + return NRF_ERROR_NOT_FOUND; +} + +ret_code_t app_usbd_interface_std_req_handle(app_usbd_setup_evt_t const * p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_GET_STATUS: + { + size_t tx_size; + uint16_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size); + + p_tx_buff[0] = 0; + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint16_t)); + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +ret_code_t app_usbd_endpoint_std_req_handle(app_usbd_setup_evt_t const * p_setup_ev) +{ + nrf_drv_usbd_ep_t ep_addr = (nrf_drv_usbd_ep_t)(p_setup_ev->setup.wIndex.lb); + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_GET_STATUS: + { + size_t tx_size; + uint16_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size); + + p_tx_buff[0] = nrf_drv_usbd_ep_stall_check(ep_addr) ? 1 : 0; + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint16_t)); + } + case APP_USBD_SETUP_STDREQ_SET_FEATURE: + { + if (p_setup_ev->setup.wValue.w != APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + nrf_drv_usbd_ep_stall(ep_addr); + return NRF_SUCCESS; + } + case APP_USBD_SETUP_STDREQ_CLEAR_FEATURE: + { + if (p_setup_ev->setup.wValue.w != APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if (nrf_usbd_dtoggle_get(ep_addr) != NRF_USBD_DTOGGLE_DATA0) + { + nrf_usbd_dtoggle_set(ep_addr, NRF_USBD_DTOGGLE_DATA0); + } + + if (NRF_USBD_EPISO_CHECK(ep_addr) == 0) + { + nrf_drv_usbd_ep_stall_clear(ep_addr); + } + + return NRF_SUCCESS; + } + default: + return NRF_ERROR_NOT_SUPPORTED; + } +} + +ret_code_t app_usbd_req_std_set_interface(app_usbd_class_inst_t const * const p_cinst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + uint8_t iface_count = app_usbd_class_iface_count_get(p_cinst); + + app_usbd_class_iface_conf_t const * p_iface = NULL; + for (uint8_t j = 0; j < iface_count; ++j) + { + p_iface = app_usbd_class_iface_get(p_cinst, j); + if (p_iface->number == p_setup_ev->setup.wIndex.lb) + { + break; + } + } + + if (p_iface == NULL) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface); + + for (uint8_t j = 0; j < ep_count; ++j) + { + /*Clear stall for every endpoint*/ + app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, j); + + if (nrf_usbd_dtoggle_get(p_ep->address) != NRF_USBD_DTOGGLE_DATA0) + { + nrf_usbd_dtoggle_set(p_ep->address, NRF_USBD_DTOGGLE_DATA0); + } + + if (NRF_USBD_EPISO_CHECK(p_ep->address) == 0) + { + nrf_drv_usbd_ep_stall_clear(p_ep->address); + } + + } + + return NRF_SUCCESS; +} + +app_usbd_class_inst_t const * app_usbd_class_first_get(void) +{ + return m_p_first_cinst; +} + +app_usbd_class_inst_t const * app_usbd_class_sof_first_get(void) +{ + return m_p_first_sof_cinst; +} + +ret_code_t app_usbd_iface_call(uint8_t iface, app_usbd_complex_evt_t const * const p_event) +{ + ASSERT(NULL != m_p_first_cinst); + /*Iterate over classes*/ + app_usbd_class_inst_t const * p_inst = app_usbd_class_first_get(); + while (p_inst != NULL) + { + uint8_t iface_count = app_usbd_class_iface_count_get(p_inst); + /*Iterate over interfaces*/ + for (uint8_t i = 0; i < iface_count; ++i) + { + app_usbd_class_iface_conf_t const * p_iface; + p_iface = app_usbd_class_iface_get(p_inst, i); + if (app_usbd_class_iface_number_get(p_iface) == iface) + { + return class_event_handler(p_inst, p_event); + } + } + p_inst = app_usbd_class_next_get(p_inst); + } + + return NRF_ERROR_INVALID_ADDR; +} + +ret_code_t app_usbd_ep_call(nrf_drv_usbd_ep_t ep, app_usbd_complex_evt_t const * const p_event) +{ + app_usbd_class_inst_t const * p_inst = app_usbd_ep_conf_access(ep)->p_cinst; + if (p_inst != NULL) + { + return class_event_handler(p_inst, p_event); + } + + return NRF_ERROR_INVALID_ADDR; +} + +void app_usbd_all_call(app_usbd_complex_evt_t const * const p_event) +{ + app_usbd_class_inst_t const * p_inst; + for (p_inst = app_usbd_class_first_get(); NULL != p_inst; + p_inst = app_usbd_class_next_get(p_inst)) + { + UNUSED_RETURN_VALUE(class_event_handler(p_inst, p_event)); + } +} + +ret_code_t app_usbd_all_until_served_call(app_usbd_complex_evt_t const * const p_event) +{ + app_usbd_class_inst_t const * p_inst; + ret_code_t ret = NRF_ERROR_NOT_SUPPORTED; + /* Try to process via every instance */ + for (p_inst = app_usbd_class_first_get(); NULL != p_inst; + p_inst = app_usbd_class_next_get(p_inst)) + { + + ret = class_event_handler(p_inst, p_event); + if (NRF_ERROR_NOT_SUPPORTED != ret) + { + /* Processing finished */ + break; + } + } + + return ret; +} + +#endif // APP_USBD_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd.h new file mode 100644 index 0000000000000000000000000000000000000000..1610b228509f817b5deb7c0fb7cc320a1c05d495 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd.h @@ -0,0 +1,395 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef APP_USBD_H__ +#define APP_USBD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf_drv_usbd.h" +#include "app_usbd_types.h" +#include "app_usbd_class_base.h" + +/** + * @defgroup app_usbd USB Device high level library + * @ingroup app_common + * + * @brief @tagAPI52840 Module for easy support for any USB device configuration. + * + * This module manages class instances that would create the USB device, + * manages endpoints and interfaces transactions. + * @{ + */ + +/** + * @brief Configuration passed to @ref app_usbd_init. + */ +typedef struct { + /** + * @brief User defined event handler. + * + * @param event Event type. + */ + void (*ev_handler)(app_usbd_event_type_t event); +} app_usbd_config_t; + +/** + * @brief USB library initialization. + * + * Call this function before any configuration or class attachment. + * USBD peripheral would be ready to accept commands, and library would be ready, + * but it would not be connected to the bus. + * Call @ref app_usbd_enable to enable USBD communication with the host. + * + * @param p_config Configuration. NULL pointer might be passed here and default + * configuration will be applied then. + */ +ret_code_t app_usbd_init(app_usbd_config_t const * p_config); + +/** + * @brief USB library un-initialization + * + * @note Currently not supported + */ +ret_code_t app_usbd_uninit(void); + +/** + * @brief Enable USBD + * + * USBD is enabled and starts requiring High Frequency Clock and power regulator. + */ +void app_usbd_enable(void); + +/** + * @brief Disable USBD + * + * Disabled USDB peripheral cannot be accessed but also stops requesting + * High Frequency clock and releases power regulator. + */ +void app_usbd_disable(void); + +/** + * @brief Start USB to work + * + * Start library to work. + * Enable interrupts. + * Enable USB pull-ups. + * After calling this function USB device is visible to a HOST. + */ +void app_usbd_start(void); + +/** + * @brief Stop USB to work + * + * This function disables interrupts and USB pull-ups. + * The peripheral itself is left enabled so it can be programmed, + * but it a HOST sees it as a peripheral disconnection. + */ +void app_usbd_stop(void); + +/** + * @brief Add class instance + * + * This function connects given instance into internal class instance chain and + * into all required endpoints. + * The instance event handler would be connected into endpoint by default, + * but this can be overwritten by @ref app_usbd_ep_handler_set. + * + * After successful attachment @ref APP_USBD_EVT_INST_APPEND would be passed to class instance. + * + * @note This function can only be called after USBD library is initialized but still disabled. + * Assertion would be generated otherwise. + * + * @param[in,out] p_cinst Instance to connect. Chain data would be written into writable instance data. + */ +ret_code_t app_usbd_class_append(app_usbd_class_inst_t const * p_cinst); + +/** + * @brief Remove class instance + * + * Instance is removed from instance chain. + * Instance and event handlers are removed also from endpoints. + * Endpoints used by by the class instance are left disabled. + * + * @note This function can only be called after USBD library is initialized but still disabled. + * Assertion would be generated otherwise. + * + * @param p_cinst Instance pointer to remove. + * + * @retval NRF_SUCCESS Instance successfully removed. + * @retval NRF_ERROR_NOT_FOUND Instance not found in the instance chain. + */ +ret_code_t app_usbd_class_remove(app_usbd_class_inst_t const * p_cinst); + +/** + * @brief Remove all class instances + * + * This function basically calls @ref app_usbd_class_remove + * on instances chain as long as there is any element left. + * + * @note This function can only be called after USBD library is initialized but still disabled. + * Assertion would be generated otherwise. + * + * @sa app_usbd_class_remove + * + * @return Is should always return @ref NRF_SUCCESS. + * Any error value returned would mean there is an error inside the library. + */ +ret_code_t app_usbd_class_remove_all(void); + +/** + * @brief Change endpoint handler + * + * This function may be called for the endpoint only if the class instance is + * already properly attached by the @ref app_usbd_class_append function. + * + * The endpoint event handler function can be only overwritten by the class instance + * that was connected into the endpoint. + * + * @note This function can only be called after USBD library is initialized but still disabled. + * Assertion would be generated otherwise. + * + * @param[in] p_cinst Instance of a class that wish to set new event handler. + * It has to match currently configured instance for the selected endpoint. + * In other situation error would be returned. + * @param[in] ep Endpoint address to configure. + * @param[in] handler Event handler function to set. + * + * @retval NRF_SUCCESS New handler successfully set + * @retval NRF_ERROR_INVALID_PARAM p_cinst is not the same as currently set for the endpoint + */ +ret_code_t app_usbd_ep_handler_set(app_usbd_class_inst_t const * p_cinst, + nrf_drv_usbd_ep_t ep, + app_usbd_ep_event_handler_t handler); + +/** + * @brief Register class instance as the one that requires SOF events + * + * This function should be called in reaction on APP_USBD_EVT_INST_APPEND event. + * Connect the class instance to the list of instances that requires SOF processing. + * If none of the appended instances requires SOF event - it is disabled. + * + * @param p_cinst Instance that requires SOF event. + * + * @retval NRF_SUCCESS Instance linked into SOF processing list. + * + * @sa app_usbd_class_sof_unregister + */ +ret_code_t app_usbd_class_sof_register(app_usbd_class_inst_t const * p_cinst); + +/** + * @brief Unregister class instance from SOF processing instances list + * + * Every class that calls @ref app_usbd_class_sof_register have to call also unregistering function + * in reaction to @ref APP_USBD_EVT_INST_REMOVE event. + * + * @param p_cinst Instance to be unregistered from SOF event processing list. + * + * @retval NRF_SUCCESS Instance linked into SOF processing list. + * @retval NRF_ERROR_NOT_FOUND Instance not found in the SOF processing list. + * + * @sa app_usbd_class_sof_register + */ +ret_code_t app_usbd_class_sof_unregister(app_usbd_class_inst_t const * p_cinst); + +/** + * @brief Function finds a given descriptor type in class descriptors payload + * + * @param[in] p_cinst Instance of a class + * @param[in] desc_type Descriptor type (@ref APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR) + * @param[in] desc_index Descriptor index (@ref APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR) + * @param[out] p_desc_len Descriptor length + * + * @return Address of the descriptor (NULL if not found) + * */ +const void * app_usbd_class_descriptor_find(app_usbd_class_inst_t const * const p_cinst, + uint8_t desc_type, + uint8_t desc_index, + size_t * p_desc_len); + +/** + * @brief Standard interface request handle + * + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * */ +ret_code_t app_usbd_interface_std_req_handle(app_usbd_setup_evt_t const * p_setup_ev); + +/** + * @brief Standard endpoint request handle + * + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * */ +ret_code_t app_usbd_endpoint_std_req_handle(app_usbd_setup_evt_t const * p_setup_ev); + + +/** + * @brief Standard interface set request handle + * + * @param[in] p_cinst Instance of a class + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * */ +ret_code_t app_usbd_req_std_set_interface(app_usbd_class_inst_t const * const p_cinst, + app_usbd_setup_evt_t const * const p_setup_ev); + +/** + * @name Iterate through classes lists + * + * Functions that helps to iterate through internally chained classes. + * @{ + */ + /** + * @brief Get first class instance in the list + * + * Get first instance from the list of active class instances. + * That instance may be used then in @ref app_usbd_class_next_get function. + * + * @return First instance in the list or NULL if there are no instances available. + */ + app_usbd_class_inst_t const * app_usbd_class_first_get(void); + + /** + * @brief Get next instance in the list + * + * Get the next instance from the list of active instances. + * Used to iterate through all instances. + * + * @param[in] p_cinst The current instance from with next one is required. + * + * @return Next instance to the given one or NULL if there is no more instances in the list. + */ + static inline app_usbd_class_inst_t const * app_usbd_class_next_get( + app_usbd_class_inst_t const * const p_cinst) + { + ASSERT(NULL != p_cinst); + return app_usbd_class_data_access(p_cinst)->p_next; + } + + /** + * @brief Get first instance in SOF list + * + * Start iteration through the list of instances that requires SOF event processing. + * + * @return First instance in the list or NULL if the list is empty + * + * @sa app_usbd_class_first_get + */ + app_usbd_class_inst_t const * app_usbd_class_sof_first_get(void); + + /** + * @brief Get next instance in the SOF list + * + * Get the next instance from the list of instances requiring SOF event processing. + * Used to iterate through all SOF instances. + * + * @param p_cinst The current instance from with next one is required. + * + * @return Next instance to the given one or NULL if there is no more instances in the list. + */ + static inline app_usbd_class_inst_t const * app_usbd_class_sof_next_get( + app_usbd_class_inst_t const * const p_cinst) + { + ASSERT(NULL != p_cinst); + return app_usbd_class_data_access(p_cinst)->p_sof_next; + } +/** @} */ + +/** + * @name Communicate with interfaces, endpoints and instances inside usbd library + * + * @{ + */ + + /** + * @brief Call interface event handler + * + * Call event handler for selected interface. + * @param[in] iface Target interface number + * @param[in] p_event Event structure to send + * + * @return Operation status + */ + ret_code_t app_usbd_iface_call(uint8_t iface, app_usbd_complex_evt_t const * const p_event); + + /** + * @brief Call endpoint event handler + * + * Call event handler for the selected endpoint. + * @param[in] ep Endpoint number + * @param[in] p_event Event structure to send + * + * @return Operation status + */ + ret_code_t app_usbd_ep_call(nrf_drv_usbd_ep_t ep, app_usbd_complex_evt_t const * const p_event); + + /** + * @brief Auxiliary function that process event by every instance in the list + * + * This function ignores the result of called handler. + * + * @param p_event Event to pass to every instance + */ + void app_usbd_all_call(app_usbd_complex_evt_t const * const p_event); + + /** + * @brief Call interface event handlers and stop when served + * + * Call event handlers from instances as long as we get result different than @ref NRF_ERROR_NOT_SUPPORTED + * @param[in] p_event Event structure to send + * + * @return Operation status or @ref NRF_ERROR_NOT_SUPPORTED if none of instances in the list can support given event. + */ + ret_code_t app_usbd_all_until_served_call(app_usbd_complex_evt_t const * const p_event); +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_class_base.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_class_base.h new file mode 100644 index 0000000000000000000000000000000000000000..cb21a7c4348cbfce6c8b8331d53562611e9a8e0d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_class_base.h @@ -0,0 +1,839 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef APP_USBD_CLASS_BASE_H__ +#define APP_USBD_CLASS_BASE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "app_usbd_types.h" +#include "nrf_drv_usbd.h" +#include "nrf_assert.h" +#include "app_util.h" + +/** + * @defgroup app_usbd_class_base USBD Class Base module + * @ingroup app_usbd + * + * @brief @tagAPI52840 The base for any class instance is defined in this module. + * + * @details Any class instance must start from base class instance structure. + * This makes them compatible with USBD library independently of the + * implementation details. + * @{ + */ + +/** + * @brief Endpoint configuration + */ +typedef struct +{ + nrf_drv_usbd_ep_t address; //!< Endpoint address +} app_usbd_class_ep_conf_t; + +/** + * @brief Interface configuration + */ +typedef struct +{ + uint8_t number; //!< Interface number + uint8_t ep_cnt; //!< Endpoint number + uint8_t ep_offset; //!< Offset of the first endpoint + /**< Offset in bytes of the first endpoint. + * The offset is calculated from the address of this interface structure + */ +} app_usbd_class_iface_conf_t; + +/** + * @brief Instance variable data + */ +typedef struct +{ + app_usbd_class_inst_t const * p_next; //!< Pointer to the next instance + app_usbd_class_inst_t const * p_sof_next; //!< Pointer to the next SOF event requiring instance +} app_usbd_class_data_t; + + +/** + * @brief Class interface function set + * */ +typedef struct { + /** + * @brief Instance callback function + * + * The function used by every class instance. + * @param[in,out] p_inst Instance of the class + * @param[in] p_event Event to process + * + * @note If given event is not supported by class, return @ref NRF_ERROR_NOT_SUPPORTED + */ + ret_code_t (* event_handler)(app_usbd_class_inst_t const * const p_inst, + app_usbd_complex_evt_t const * const p_event); + + /** + * @brief Instance get descriptors + * + * The function used by every class instance. + * @param[in,out] p_inst Instance of the class + * @param[out] p_size Descriptor size + * + * @return Class descriptors start address + */ + const void * (* get_descriptors)(app_usbd_class_inst_t const * const p_inst, + size_t * p_size); +} app_usbd_class_methods_t; + +/** + * @brief The instance structure itself + * + * The structure of base class instance + */ +struct app_usbd_class_inst_s +{ + app_usbd_class_data_t * p_data; //!< Pointer to non-constant data + app_usbd_class_methods_t const * p_class_methods; //!< Class interface methods + struct + { + uint8_t cnt; //!< Number of defined interfaces + uint8_t config[]; //!< Interface configuration data followed by endpoint data + } iface; //!< Interface structure +}; + + +/** + * @brief Get total number of interfaces + * + * + */ +static inline uint8_t app_usbd_class_iface_count_get(app_usbd_class_inst_t const * const p_inst) +{ + return p_inst->iface.cnt; +} + +/** + * @brief Interface accessing function + * + * Get interface pointer. + * Interfaces creates continuous array in the memory so it is possible to get + * interface with index 0 and the just iterate to the next one. + * + * @param p_inst Pointer to the class instance + * @param iface_idx Index of the instance to get. + * This is not the interface identifier. + * Technically it is the index of the interface in the class description array. + * @return Pointer to the interface configuration parameters or NULL if given index is out of interface scope for given class. + */ +static inline app_usbd_class_iface_conf_t const * app_usbd_class_iface_get( + app_usbd_class_inst_t const * const p_inst, + uint8_t iface_idx) +{ + ASSERT(NULL != p_inst); + if (iface_idx >= (app_usbd_class_iface_count_get(p_inst))) + { + return NULL; + } + + app_usbd_class_iface_conf_t const * p_interface = + (app_usbd_class_iface_conf_t const * )(p_inst->iface.config); + return &(p_interface[iface_idx]); +} + +/** + * @brief Get interface number + * + * @param p_iface Pointer to interface structure + * + * @return Interface number from interface configuration structure + */ +static inline uint8_t app_usbd_class_iface_number_get( + app_usbd_class_iface_conf_t const * const p_iface) +{ + return p_iface->number; +} + +/** + * @brief Get number of endpoints in interface + * + * @param p_iface Pointer to interface structure + * + * @return Number of endpoints used by given interface + */ +static inline uint8_t app_usbd_class_iface_ep_count_get( + app_usbd_class_iface_conf_t const * const p_iface) +{ + return p_iface->ep_cnt; +} + +/** + * @brief Interface Endpoint accessing function + * + * @param p_iface Interface configuration pointer + * @param ep_idx Endpoint index + * + * @return Endpoint information structure pointer or NULL if given index is outside of endpoints for selected interface. + * + * @sa app_usbd_class_iface_get + */ +static inline app_usbd_class_ep_conf_t const * app_usbd_class_iface_ep_get( + app_usbd_class_iface_conf_t const * const p_iface, + uint8_t ep_idx) +{ + ASSERT(NULL != p_iface); + if (ep_idx >= p_iface->ep_cnt) + { + return NULL; + } + + app_usbd_class_ep_conf_t const * p_ep = + (app_usbd_class_ep_conf_t const * )(((uint8_t const *)p_iface) + p_iface->ep_offset); + return &(p_ep[ep_idx]); +} + +/** + * @brief Translate endpoint address to class index + * + * @param p_iface Interface configuration pointer + * @param ep_address Endpoint address + * + * @return Endpoint index or number of endpoints if not found + * + */ +static inline uint8_t app_usbd_class_iface_ep_idx_get( + app_usbd_class_iface_conf_t const * const p_iface, + nrf_drv_usbd_ep_t ep_address) +{ + ASSERT(NULL != p_iface); + app_usbd_class_ep_conf_t const * p_ep = + (app_usbd_class_ep_conf_t const * )(((uint8_t const *)p_iface) + p_iface->ep_offset); + + uint8_t i; + for (i = 0; i < p_iface->ep_cnt; ++i) + { + if (ep_address == p_ep[i].address) + { + break; + } + } + + return i; +} + +/** + * @brief Get the selected endpoint address + * + * @param p_ep Endpoint configuration structure + * + * @return Endpoint address + */ +static inline nrf_drv_usbd_ep_t app_usbd_class_ep_address_get(app_usbd_class_ep_conf_t const * p_ep) +{ + return (nrf_drv_usbd_ep_t)p_ep->address; +} + +/** + * @brief Get the pointer to the writable instance data + * + * @param p_inst Instance pointer + * @return Pointer to writable instance data + */ +static inline app_usbd_class_data_t * app_usbd_class_data_access( + app_usbd_class_inst_t const * const p_inst) +{ + return p_inst->p_data; +} + +/** + * @name Internal macros for argument mapping + * + * Functions to be used as a mapping macro for @ref MACRO_MAP, @ref MACRO_MAP_FOR or @ref MACRO_MAP_FOR_PARAM + * @{ + */ + /** + * @brief Count the number of endpoints in given configuration + * + * Config should be given as a interface configuration in a brackets: + * @code + * (interface_nr, ep1, ep2, ep3) + * @endcode + * Number of endpoints may vary from 0 to a few (technically up to 16, but it seems not to make sense to use more than 4). + * Interface number is always present. + * + * @param iface_config Single interface configuration (in brackets) + * + * @return Number of endpoints in interface. This is computed value - can be used by compiler but not by preprocessor. + */ + #define APP_USBD_CLASS_CONF_IFACE_EP_COUNT_(iface_config) \ + (NUM_VA_ARGS(BRACKET_EXTRACT(iface_config)) - 1) + + /** + * @brief Adds the number of endpoints in given config to the current value + * + * This is basically @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_ with plus sign added. + * + * @param iface_config See parameters documentation in @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_ + * + * @return Plus sign followed by number of endpoints in interface. + * + * @sa APP_USBD_CLASS_CONF_IFACE_EP_COUNT_ + */ + #define APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_(iface_config) \ + + APP_USBD_CLASS_CONF_IFACE_EP_COUNT_(iface_config) + + /** + * @brief Create variable for endpoint + */ + + /** + * @brief Extract endpoints given interface configuration + * + * This macro gets single endpoint configuration and extracts all the endpoints. + * It also adds comma on the end of extracted endpoints. + * This way when this macro is called few times it generates nice list of all endpoints + * that may be used to array initialization. + * + * @param iface_config Single interface configuration in brackets. + * The format should be similar like described in @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_. + */ + #define APP_USBD_CLASS_IFACE_EP_EXTRACT_(iface_config) \ + CONCAT_2(APP_USBD_CLASS_IFACE_EP_EXTRACT_, \ + NUM_VA_ARGS_IS_MORE_THAN_1(BRACKET_EXTRACT(iface_config))) \ + (BRACKET_EXTRACT(iface_config)) + + /** + * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_EP_EXTRACT_ + * + * This macro is called when interface has no endpoints + */ + #define APP_USBD_CLASS_IFACE_EP_EXTRACT_0(iface_nr) + + /** + * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_EP_EXTRACT_ + * + * This macro is called when interface has at least one endpoint + */ + #define APP_USBD_CLASS_IFACE_EP_EXTRACT_1(...) \ + APP_USBD_CLASS_IFACE_EP_EXTRACT_1_(__VA_ARGS__) + + #define APP_USBD_CLASS_IFACE_EP_EXTRACT_1_(iface_nr, ...) \ + MACRO_MAP_REC(PARAM_CBRACE, __VA_ARGS__) + + /** + * @brief Generate configuration for single interface + * + * This macro extract configuration for single interface. + * The configuration is inside curly brackets and comma is added on the end. + * This mean it can be directly used to init array of interface configurations. + * + * @param iface_config Single interface configuration + * @param N Currently processed configuration + * @param iface_configs All interfaces configuration in brackets + */ + #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_(iface_config, N, iface_configs) \ + CONCAT_2(APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_, \ + NUM_VA_ARGS_IS_MORE_THAN_1(BRACKET_EXTRACT(iface_config))) \ + (N, iface_configs, BRACKET_EXTRACT(iface_config)) + + #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_x(iface_config, N, iface_configs) \ + [N] = !!!iface_config!!! + /** + * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_ + * + * This macro is called when interface has no endpoints + */ + #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0(N, iface_configs, iface_nr) \ + APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0_(N, iface_configs, iface_nr) + #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0_(N, iface_configs, iface_nr) \ + { .number = iface_nr, .ep_cnt = 0, .ep_offset = 0 }, + + /** + * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_ + * + * This macro is called when interface has at last one endpoint + */ + #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1(N, iface_configs, ...) \ + APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1_(N, iface_configs, __VA_ARGS__) + #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1_(N, iface_configs, iface_nr, ...) \ + { .number = iface_nr, .ep_cnt = NUM_VA_ARGS(__VA_ARGS__), \ + .ep_offset = APP_USBD_CLASS_CONF_TOTAL_EP_COUNT_N(N, iface_configs) * \ + sizeof(app_usbd_class_ep_conf_t) \ + + ((NUM_VA_ARGS(BRACKET_EXTRACT(iface_configs)) - N) * \ + sizeof(app_usbd_class_iface_conf_t)) \ + }, + +/** @} */ + + +/** + * @name Macros that uses mapping macros internally + * + * Auxiliary macros that uses mapping macros to make some calculations or realize other functionality. + * Mapped here for easier unit testing and to hide complex mapping functions calling. + * @{ + */ + +/** + * @brief Count total number of endpoints + * + * @param iface_configs List of interface configurations like explained + * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF + * + * @return The equation to calculate the number of endpoints by compiler. + */ +#define APP_USBD_CLASS_CONF_TOTAL_EP_COUNT(iface_configs) \ + (0 MACRO_MAP(APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_, BRACKET_EXTRACT(iface_configs))) + +/** + * @brief Count total number of endpoint up-to interface index + * + * The version of @ref APP_USBD_CLASS_CONF_TOTAL_EP_COUNT macro witch takes the + * number of interfaces to analyze. + * + * @param N Number of interfaces to analyze + * @param iface_configs List of interface configurations like explained + * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF + * + * @return The equation to calculate the number of endpoints by compiler. + */ +#define APP_USBD_CLASS_CONF_TOTAL_EP_COUNT_N(N, iface_configs) \ + (0 MACRO_MAP_N(N, APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_, BRACKET_EXTRACT(iface_configs))) + +/** + * @brief Extract configurations for interfaces + * + * This macro extracts the configurations for every interface. + * Basically uses the @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_ macro on every + * configuration found. + * + * This should generate interface configuration initialization data + * in comma separated initializers in curly braces. + * + * @param iface_configs List of interface configurations like explained + * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF + * + * @return Comma separated initialization data for all interfaces. + */ +#define APP_USBD_CLASS_IFACES_CONFIG_EXTRACT(iface_configs) \ + MACRO_MAP_FOR_PARAM(iface_configs, \ + APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_, \ + BRACKET_EXTRACT(iface_configs)) + +/** + * @brief Extract all endpoints + * + * Macro that extracts all endpoints from every interface + * + * @param iface_configs List of interface configurations like explained + * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF + * + * @return Comma separated list of endpoints + */ +#define APP_USBD_CLASS_IFACES_EP_EXTRACT(iface_configs) \ + MACRO_MAP(APP_USBD_CLASS_IFACE_EP_EXTRACT_, BRACKET_EXTRACT(iface_configs)) + + +/** @} */ + + +/** + * @brief USBD instance of class mnemonic + * + * Macro that generates mnemonic for the name of the structure that describes instance for selected class. + * + * @param type_name The name of the instance without _t postfix + * + * @return The name with the right postfix to create the name for the type for the class. + */ +#define APP_USBD_CLASS_INSTANCE_TYPE(type_name) CONCAT_2(type_name, _t) + +/** + * @brief USBD data for instance class mnemonic + * + * The mnemonic of the variable type that holds writable part of the class instance. + * + * @param type_name The name of the instance without _t postfix + * + * @return The name with the right postfix to create the name for the data type for the class. + */ +#define APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(type_name, _data_t) + +/** + * @brief Declare class specific member of class instance + * + * @param type Type of the attached class configuration. + * + * @sa APP_USBD_CLASS_INSTANCE_TYPEDEF + */ +#define APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC(type) type class_part; + +/** + * @brief Used if there is no class specific configuration + * + * This constant can be used if there is no specific configuration inside created instance + * + * @sa APP_USBD_CLASS_INSTANCE_TYPEDEF + */ +#define APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE + +/** + * @brief Declare class specific member of class data + * + * @param type Type of the attached class data. + * + * @sa APP_USBD_CLASS_DATA_TYPEDEF + */ +#define APP_USBD_CLASS_DATA_SPECIFIC_DEC(type) APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC(type) + +/** + * @brief Used if there is no class specific data + * + * This constant can be used if there is no specific writable data inside created instance + * + * @sa APP_USBD_CLASS_DATA_TYPEDEF + */ +#define APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE + + + + +/** + * @brief Instance structure declaration + * + * The macro that declares a variable type that would be used to store given class instance. + * Class instance stores all the data from @ref app_usbd_class_inst_t and overlaid data for specified class. + * + * The structure of interface configuration data: + * @code + * ( + * (iface1_nr, (ep1, ep2, ep3)), + (iface2_nr), + (iface3_nr, (ep4)) + * ) + * @endcode + * + * @param type_name The name of the instance without _t postfix. + * @param interfaces_configs List of interface configurations like explained above. + * @param class_config_dec Result of the macro + * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC or + * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE + * + * @return The definition of the structure type that holds all the required data. + * + * @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_DATA_TYPEDEF instead. + * + * @note APP_USBD_CLASS_DATA_TYPEDEF has to be called first for the compilation to success. + * + * @sa APP_USBD_CLASS_TYPEDEF + */ +#define APP_USBD_CLASS_INSTANCE_TYPEDEF(type_name, interfaces_configs, class_config_dec) \ + typedef union CONCAT_2(type_name, _u) \ + { \ + app_usbd_class_inst_t base; \ + struct \ + { \ + APP_USBD_CLASS_DATA_TYPE(type_name) * p_data; \ + app_usbd_class_methods_t const * p_class_methods; \ + struct \ + { \ + uint8_t cnt; \ + app_usbd_class_iface_conf_t \ + config[NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs))]; \ + app_usbd_class_ep_conf_t \ + ep[APP_USBD_CLASS_CONF_TOTAL_EP_COUNT(interfaces_configs)]; \ + } iface; \ + class_config_dec \ + } specific; \ + } APP_USBD_CLASS_INSTANCE_TYPE(type_name) + +/** + * @brief Writable data structure declaration + * + * The macro that declares a variable type that would be used to store given class writable data. + * Writable data contains base part of the type @ref app_usbd_class_data_t followed by + * class specific data. + * + * @param type_name The name of the type without _t postfix. + * @param class_data_dec Result of the macro + * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC or + * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE + * + * @return The definition of the structure type that holds all the required writable data + * + * @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_DATA_TYPEDEF instead. + * + * @sa APP_USBD_CLASS_TYPEDEF + */ +#define APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec) \ + typedef struct \ + { \ + app_usbd_class_data_t base; \ + class_data_dec \ + }APP_USBD_CLASS_DATA_TYPE(type_name) + + +/** + * @brief Declare all data types required by the class instance + * + * Macro that declares data type first and then instance type. + * + * @param type_name The name of the type without _t postfix. + * @param interface_configs List of interface configurations like in @ref APP_USBD_CLASS_INSTANCE_TYPEDEF. + * @param class_config_dec Result of the macro + * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC or + * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE + * @param class_data_dec Result of the macro + * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC or + * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE + * + * @return Declaration of the data type for the instance and instance itself. + * + * @sa APP_USBD_CLASS_DATA_TYPEDEF + * @sa APP_USBD_CLASS_INSTANCE_TYPEDEF + */ +#define APP_USBD_CLASS_TYPEDEF(type_name, interface_configs, class_config_dec, class_data_dec) \ + APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec); \ + APP_USBD_CLASS_INSTANCE_TYPEDEF(type_name, interface_configs, class_config_dec) + +/** + * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF + * + * @param type_name The name of the type without _t postfix. + * */ +#define APP_USBD_CLASS_FORWARD(type_name) union CONCAT_2(type_name, _u) + +/** + * @brief Generate the initialization data for + * + * Macro that generates the initialization data for instance. + * + * @param p_ram_data Pointer to writable instance data structure + * @param class_methods Class methods + * @param interfaces_configs Exactly the same interface config data that in @ref APP_USBD_CLASS_INSTANCE_TYPEDEF + * @param class_config_part Configuration part. The data should be inside brackets. + * Any data here would be removed from brackets and then put as an initialization + * data for class_part member of instance structure. + * + * @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_INST_DEF instead. + */ +#define APP_USBD_CLASS_INSTANCE_INITVAL(p_ram_data, \ + class_methods, \ + interfaces_configs, \ + class_config_part) \ + { \ + .specific = { \ + .p_data = p_ram_data, \ + .p_class_methods = class_methods, \ + .iface = { \ + .cnt = NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs)), \ + .config = { APP_USBD_CLASS_IFACES_CONFIG_EXTRACT(interfaces_configs) }, \ + .ep = { APP_USBD_CLASS_IFACES_EP_EXTRACT(interfaces_configs) } \ + }, \ + BRACKET_EXTRACT(class_config_part) \ + } \ + } + + +/** + * @brief Define the base class instance + * + * Macro that defines whole instance variable and fill it with initialization data. + * + * The tricky part is @c class_config_part. + * The configuration data here has to be placed inside brackets. + * Then any type of values can be used depending on the type used in @ref APP_USBD_CLASS_TYPEDEF. + * If instance does not have any specyfic data, use just empty bracket here. + * @code + * APP_USBD_CLASS_TYPEDEF( + * some_base_class, + * CLASS_BASE_CONFIGURATION, + * APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE, + * APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE + * ); + * APP_USBD_CLASS_INST_DEF( + * some_base_class_inst, + * some_base_class, + * base_class_event_handler, + * CLASS_BASE_CONFIGURATION, + * () // Empty configuration + * ); + * @endcode + * + * If the type of instance configuration is simple type, just provide initialization value: + * @code + * APP_USBD_CLASS_TYPEDEF( + * some_base_class, + * CLASS_BASE_CONFIGURATION, + * APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE, + * APP_USBD_CLASS_DATA_SPECIFIC_DEC(uint8_t) + * ); + * APP_USBD_CLASS_INST_DEF( + * some_base_class_inst, + * some_base_class, + * base_class_event_handler, + * CLASS_BASE_CONFIGURATION, + * (12) // Example values + * ); + * @endcode + * + * If the type of instance configuration is structure, provide initialization value for the whole structure: + * @code + * typedef structure + * { + * uint32_t p1; + * uint8_t p2; + * }my_config_t; + * + * APP_USBD_CLASS_TYPEDEF( + * some_base_class, + * CLASS_BASE_CONFIGURATION, + * APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE, + * APP_USBD_CLASS_DATA_SPECIFIC_DEC(my_config_t) + * ); + * APP_USBD_CLASS_INST_DEF( + * some_base_class_inst, + * some_base_class, + * base_class_event_handler, + * CLASS_BASE_CONFIGURATION, + * ({12, 3}) // Example values + * ); + * @endcode + * + * @param instance_name The name of created instance variable. + * It would be constant variable and its type would be app_usbd_class_inst_t. + * @param type_name The name of the variable type. It has to be the same type that was passed to + * @ref APP_USBD_CLASS_TYPEDEF + * @param class_methods Class unified interface. + * @param interfaces_configs The same configuration data that the one passed to @ref APP_USBD_CLASS_TYPEDEF + * @param class_config_part Configuration data to the type that was declared by class_data_dec when calling + * @ref APP_USBD_CLASS_TYPEDEF. + * Configuration data has to be provided in brackets. + * It would be extracted from brackets and placed in initialization part of configuration structure. + * See detailed description of this macro for more informations. + */ +#define APP_USBD_CLASS_INST_DEF(instance_name, \ + type_name, \ + class_methods, \ + interfaces_configs, \ + class_config_part) \ + static APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(instance_name, _data); \ + static const APP_USBD_CLASS_INSTANCE_TYPE(type_name) instance_name = \ + APP_USBD_CLASS_INSTANCE_INITVAL( \ + &CONCAT_2(instance_name, _data), \ + class_methods, \ + interfaces_configs, \ + class_config_part) + + +/** + * @brief Define the base class instance in global scope + * + * This is the same macro like @ref APP_USBD_CLASS_INST_DEF but it creates the instance + * without static keyword. + * + * @param instance_name See documentation for @ref APP_USBD_CLASS_INST_DEF + * @param type_name See documentation for @ref APP_USBD_CLASS_INST_DEF + * @param class_methods See documentation for @ref APP_USBD_CLASS_INST_DEF + * @param interfaces_configs See documentation for @ref APP_USBD_CLASS_INST_DEF + * @param class_config_part See documentation for @ref APP_USBD_CLASS_INST_DEF + */ +#define APP_USBD_CLASS_INST_GLOBAL_DEF(instance_name, \ + type_name, \ + class_methods, \ + interfaces_configs, \ + class_config_part) \ + static APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(instance_name, _data); \ + const APP_USBD_CLASS_INSTANCE_TYPE(type_name) instance_name = \ + APP_USBD_CLASS_INSTANCE_INITVAL( \ + &CONCAT_2(instance_name, _data), \ + class_methods, \ + interfaces_configs, \ + class_config_part) + +/** + * @brief Access class specific configuration + * + * Macro that returns class specific configuration. + * + * @param[in] p_inst Instance pointer + * + * @return A pointer for class specific part of the instance + * + * @note If macro is used on the instance that has no class specific configuration + * an error would be generated during compilation. + */ +#define APP_USBD_CLASS_GET_SPECIFIC_CONFIG(p_inst) (&((p_inst)->specific.class_part)) + +/** + * @brief Access class specific data + * + * @param[in] p_inst Instance pointer + * + * @return A pointer for class specific part of writable data + * + * @note If macro is used on the instance that has no class specific data + * an error would be generated during compilation. + */ +#define APP_USBD_CLASS_GET_SPECIFIC_DATA(p_inst) (&(((p_inst)->specific.p_data)->class_part)) + +/** + * @brief Macro to get base instance from class specific instance + * + * This macro may be used on class specific instance to get base instance that + * can be processed by base instance access functions. + * Class specific instance can be just casted to class base instance, + * but then we would totally lost type safety. + * + * A little more safe is to use pointer to base member of class instance. + * This would generate an error when used on any variable that have no base member + * and would generate also error if this base member is wrong type. + */ +#define APP_USBD_CLASS_BASE_INSTANCE(p_inst) (&((p_inst)->base)) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_CLASS_BASE_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_core.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_core.c new file mode 100644 index 0000000000000000000000000000000000000000..2f7476037ef08ba8c397ea3f711de936ba232216 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_core.c @@ -0,0 +1,1137 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" +#if APP_USBD_ENABLED +#include "app_usbd_core.h" +#include "app_usbd.h" +#include "app_usbd_request.h" +#include "app_usbd_string_desc.h" +#include "nrf.h" +#include "nrf_atomic.h" +#include "app_util_platform.h" +#include "app_usbd.h" +#include "app_usbd_class_base.h" + +/* Test if VID was configured */ +#ifndef APP_USBD_VID +#error APP_USBD_VID not properly defined. +#endif + +/* USBD device version creating if defined in major/minor form */ +#ifndef APP_USBD_DEVICE_VER + #if defined(APP_USBD_DEVICE_VER_MAJOR) && defined(APP_USBD_DEVICE_VER_MINOR) + #if ((APP_USBD_DEVICE_VER_MAJOR)) > 99 || ((APP_USBD_DEVICE_VER_MINOR) > 99) + #error Major and minor device version value have to be limited to 99. + #endif + #define APP_USBD_DEVICE_VER (((APP_USBD_DEVICE_VER_MAJOR)*100UL) + (APP_USBD_DEVICE_VER_MINOR)) + #else + #error The definition of APP_USBD_DEVICE_VER or a pair APP_USBD_DEVICE_VER_MAJOR and APP_USBD_DEVICE_VER_MINOR required. + #endif +#endif + +/** + * @internal + * @defgroup app_usbd_core_internals USB Device high level library core module internals + * @ingroup app_usbd_core + * + * Internal variables, auxiliary macros and functions of USBD high level core module. + * @{ + */ + +/** @brief Make USB BCD version */ +#define APP_USBD_VERSION_BCD_MAKE(major, minor) (((0x##major) << 8) | (0x##minor)) + +/** @brief Make USB power value */ +#define APP_USBD_POWER_MAKE(ma) (((ma) + 1) / 2) + +/** @brief Convert device version to BCD notation */ +#define APP_USBD_BCD_DEVICE ( \ + ((((APP_USBD_DEVICE_VER) % 10000) / 1000) * 0x1000) + \ + ((((APP_USBD_DEVICE_VER) % 1000) / 100) * 0x100) + \ + ((((APP_USBD_DEVICE_VER) % 100) / 10) * 0x10) + \ + ((((APP_USBD_DEVICE_VER) % 10) / 1) * 0x1) \ + ) + +/** + @brief Default device descriptor initializer @ref app_usbd_descriptor_device_t +* */ +#define APP_USBD_CORE_DEVICE_DESCRIPTOR { \ + .bLength = sizeof(app_usbd_descriptor_device_t), /* descriptor size */ \ + .bDescriptorType = APP_USBD_DESCRIPTOR_DEVICE, /* descriptor type */ \ + .bcdUSB = APP_USBD_VERSION_BCD_MAKE(2,0), /* USB BCD version: 2.0 */ \ + .bDeviceClass = 0, /* device class: 0 - specified by interface */ \ + .bDeviceSubClass = 0, /* device subclass: 0 - specified by interface */ \ + .bDeviceProtocol = 0, /* device protocol: 0 - specified by interface */ \ + .bMaxPacketSize0 = NRF_DRV_USBD_EPSIZE, /* endpoint size: fixed to: NRF_DRV_USBD_EPSIZE*/ \ + .idVendor = APP_USBD_VID, /* Vendor ID*/ \ + .idProduct = APP_USBD_PID, /* Product ID*/ \ + .bcdDevice = APP_USBD_BCD_DEVICE, /* Device version BCD */ \ + .iManufacturer = APP_USBD_STRING_ID_MANUFACTURER, /* String ID: manufacturer */ \ + .iProduct = APP_USBD_STRING_ID_PRODUCT, /* String ID: product */ \ + .iSerialNumber = APP_USBD_STRING_ID_SERIAL, /* String ID: serial */ \ + .bNumConfigurations = 1, /* Fixed value: only one configuration supported*/ \ +} + + +#define APP_USBD_CORE_CONFIGURATION_DESCRIPTOR { \ + .bLength = sizeof(app_usbd_descriptor_configuration_t), \ + .bDescriptorType = APP_USBD_DESCRIPTOR_CONFIGURATION, \ + .wTotalLength = 0, /*Calculated dynamically*/ \ + .bNumInterfaces = 0, /*Calculated dynamically*/ \ + .bConfigurationValue = 1, /*Value passed to set configuration*/ \ + .iConfiguration = 0, /*Configuration ID: fixed to 0*/ \ + .bmAttributes = APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_ALWAYS_SET_MASK | \ + APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK, \ + .bMaxPower = APP_USBD_POWER_MAKE(500), \ +} + +/** + * @brief Device descriptor instance. + * + * @note + * Constant part of the device descriptor. + * Values that must be calculated are updated directly in the buffer + * just before the transmission. + */ +static const app_usbd_descriptor_device_t m_device_dsc = + APP_USBD_CORE_DEVICE_DESCRIPTOR; + +/** + * @brief Configuration descriptor instance. + * + * @note + * Constant part of the device descriptor. + * Values that must be calculated are updated directly in the buffer + * just before the transmission. + */ +static const app_usbd_descriptor_configuration_t m_configuration_dsc = + APP_USBD_CORE_CONFIGURATION_DESCRIPTOR; + +/* Required early declaration of event handler function */ +static ret_code_t app_usbd_core_event_handler(app_usbd_class_inst_t const * const p_inst, + app_usbd_complex_evt_t const * const p_event); + +/** + * @brief Current USB device state + * + * This variable is updated automatically by core library. + */ +static app_usbd_state_t app_usbd_state = APP_USBD_STATE_Disabled; + +/** + * @brief Active device features + * + * @note Only @ref APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP is supported for device + */ +static uint8_t m_device_features_state; + +/** + * @brief Remote wake-up register/unregister + * + * Counter incremented when appended instance required remote wake-up functionality. + * It should be decremented when the class is removed. + * When this counter is not zero, remote wake-up functionality is activated inside core. + */ +static uint8_t m_rwu_counter; + +/** + * @brief Remote wake-up pending flag + */ +static nrf_atomic_flag_t m_rwu_pending; + + +/** + * @brief Core class methods + * + * Base methods interface for core class. + * This is quite specific class - it would be only connected into endpoint 0. + * Not connected into instances list. + */ +static const app_usbd_class_methods_t m_core_methods = { + .event_handler = app_usbd_core_event_handler, + .get_descriptors = NULL, +}; + +/** + * @brief Setup transfer buffer + */ +static uint8_t m_setup_transfer_buff[NRF_DRV_USBD_EPSIZE]; + + +/** + * @brief Handler for outgoing setup data + * + * @todo RK documentation + */ +static app_usbd_core_setup_data_handler_desc_t m_ep0_handler_desc; + +#define APP_USBD_CORE_CLASS_INSTANCE_CONFIG () + + +/*lint -u -save -e26 -e40 -e64 -e123 -e505 -e651*/ + +/** + * @brief Core instance + * + * Create instance that would be connected into endpoints in USBD library. + */ +APP_USBD_CLASS_INST_GLOBAL_DEF( + app_usbd_core_inst, + app_usbd_core, + &m_core_methods, + APP_USBD_CORE_CLASS_CONFIGURATION, + () ); +/*lint -restore*/ + + + +/** + * @brief Check current USBD power connection status + * + */ +static inline bool usbd_core_power_is_detected(void) +{ + return 0 != ( (NRF_POWER->USBREGSTATUS) & POWER_USBREGSTATUS_VBUSDETECT_Msk); +} + + +/** + * @brief Safely call EP0 handler + * + * Function calls EP0 handler only if its pointer is non-zero. + * + * @param status Status to send as a handler parameter. + */ +static inline ret_code_t usbd_core_ep0_handler_call_and_clear(nrf_drv_usbd_ep_status_t status) +{ + app_usbd_core_setup_data_handler_t handler = m_ep0_handler_desc.handler; + if (NULL != handler) + { + m_ep0_handler_desc.handler = NULL; + return handler(status, m_ep0_handler_desc.p_context); + } + + return NRF_ERROR_NULL; +} + +/** + * @brief Check if EP0 handler is configured + * + * EP0 handler is configured is any instance that has processed SETUP command + * expects some incoming / outgoing data. + * + * EP0 handler should be cleared automatically just before it is called + * (see @ref usbd_core_ep0_handler_call_and_clear). + * If instance requires more data - it has to setup EP0 handler once more time + * (see @ref app_usbd_core_setup_data_handler_set). + * + * This function adds small layer of abstraction for checking if EP0 handler + * is already configured. + * + * @retval true EP0 handler is set + * @retval false EP0 handler is cleared + */ +static inline bool usb_core_ep0_handler_check(void) +{ + return (NULL != m_ep0_handler_desc.handler); +} + +/** + * @brief Empty data handler + * + * Data handler used only to mark that there is requested data during SETUP. + * + * @return Always NRF_SUCCESS + * @sa setup_empty_data_handler_desc + */ +static ret_code_t setup_data_handler_empty(nrf_drv_usbd_ep_status_t status, void * p_contex) +{ + UNUSED_PARAMETER(status); + UNUSED_PARAMETER(p_contex); + return NRF_SUCCESS; +} + +/** + * @brief + * + * @todo RK Documentation + */ +static app_usbd_core_setup_data_handler_desc_t const m_setup_data_handler_empty_desc = +{ + .handler = setup_data_handler_empty, + .p_context = NULL +}; + +/** + * @brief Structure used as a context for descriptor feeder + * + * Structure with all the data required to process instances to generate descriptor + * data chunk. + */ +typedef struct +{ + app_usbd_class_inst_t const * p_cinst; //!< The class instance that is to be processed next. + const uint8_t * p_desc; //!< Pointer at current descriptor or NULL if finished. + /**< + * If we get NULL on transfer function enter it means that ZLP is required. + * Or it is time to finish the transfer (depending on @c total_left). + */ + size_t desc_left; //!< Number of bytes left in the current class descriptor to send + size_t total_left; //!< Number of bytes left that was requested by the host +} app_usbd_core_descriptor_conf_feed_data_t; + +/** + * @brief Default data used by the feeder + * + * + */ +static app_usbd_core_descriptor_conf_feed_data_t m_descriptor_conf_feed_data; + +/** + * @brief Descriptor feeder + * + * Descriptor feeder is used as an callback function when descriptors are + * transfered and buffer is ready for next data. + * It prepares next chunk of data to be sent. + * + * @param p_next See @ref nrf_drv_usbd_next_transfer_handler_t documentation. + * @param p_context Pointer to @ref app_usbd_core_descriptor_feed_data_t data type. + * @param ep_size The size of the endpoint. + * + * @return See @ref nrf_drv_usbd_next_transfer_handler_t documentation. + */ +static bool usbd_descriptor_conf_feeder( + nrf_drv_usbd_ep_transfer_t * p_next, + void * p_context, + size_t ep_size) +{ + bool continue_req = true; + + app_usbd_core_descriptor_conf_feed_data_t * p_data = p_context; + if (NULL == p_data->p_desc) + { + /* ZLP */ + continue_req = false; + p_next->p_data.tx = NULL; + p_next->size = 0; + } + else + { + ASSERT(ep_size <= NRF_DRV_USBD_FEEDER_BUFFER_SIZE); + uint8_t * p_tx_buff = nrf_drv_usbd_feeder_buffer_get(); + size_t size = 0; /* Currently added number of bytes */ + size_t tx_size; /* Number of bytes to send right now */ + + /* Feeder function can use the USBD driver internal buffer */ + p_tx_buff = nrf_drv_usbd_feeder_buffer_get(); + + tx_size = MIN(ep_size, p_data->total_left); + while (0 != tx_size) + { + /* Process transfer */ + if (0 < p_data->desc_left) + { + size_t to_copy = MIN(tx_size, p_data->desc_left); + memcpy(p_tx_buff+size, p_data->p_desc, to_copy); + p_data->desc_left -= to_copy; + p_data->total_left -= to_copy; + tx_size -= to_copy; + size += to_copy; + p_data->p_desc += to_copy; + } + + if (0 == p_data->total_left) + { + continue_req = false; + } + else if (0 == p_data->desc_left) + { + if (NULL == p_data->p_cinst) + { + p_data->p_desc = NULL; + /* No more data - check if ZLP is required */ + if (size > 0) + { + if (size < ep_size) + { + continue_req = false; + } + } + break; + } + else + { + /* Prepare next descriptor */ + p_data->p_desc = + p_data->p_cinst->p_class_methods->get_descriptors( + p_data->p_cinst, + &p_data->desc_left); + /* Get next descriptor */ + p_data->p_cinst = app_usbd_class_next_get(p_data->p_cinst); + } + } + else + { + /* Nothing to do */ + } + } + p_next->p_data.tx = p_tx_buff; + p_next->size = size; + } + return continue_req; +} + +/** + * @brief + * + * @todo RK Documentation + */ +static const nrf_drv_usbd_handler_desc_t usbd_descriptor_feeder_desc = +{ + .handler = { .feeder = usbd_descriptor_conf_feeder }, + .p_context = &m_descriptor_conf_feed_data +}; + +static ret_code_t setup_req_get_status(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + size_t max_size; + uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size); + ASSERT(sizeof(uint16_t) <= max_size); + + memset(p_trans_buff, 0, sizeof(uint16_t)); + if (m_configuration_dsc.bmAttributes & + APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK) + { + SET_BIT(p_trans_buff[0], 0); + } + if (IS_SET(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP)) + { + SET_BIT(p_trans_buff[0], 1); + } + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, sizeof(uint16_t)); +} + +static ret_code_t setup_req_get_descriptor(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + switch (p_setup_ev->setup.wValue.hb) + { + case APP_USBD_DESCRIPTOR_DEVICE: + { + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), + &m_device_dsc, + sizeof(m_device_dsc)); + } + case APP_USBD_DESCRIPTOR_CONFIGURATION: + { + /* The size equals the size of configuration descriptor and all classes descriptors */ + const size_t size = MIN( + sizeof(app_usbd_descriptor_configuration_t), + p_setup_ev->setup.wLength.w); + size_t total_length = sizeof(app_usbd_descriptor_configuration_t); + uint8_t iface_count = 0; + + /* Iterate over all registered classes count descriptors and total size */ + app_usbd_class_inst_t const * p_class; + for (p_class = app_usbd_class_first_get(); p_class != NULL; + p_class = app_usbd_class_next_get(p_class)) + { + ASSERT(NULL != (p_class->p_class_methods)); + ASSERT(NULL != (p_class->p_class_methods->get_descriptors)); + size_t dsc_size; + const void * dsc = p_class->p_class_methods->get_descriptors(p_class, &dsc_size); + UNUSED_VARIABLE(dsc); + total_length += dsc_size; + iface_count += app_usbd_class_iface_count_get(p_class); + } + + /* Access transmission buffer */ + size_t max_size; + app_usbd_descriptor_configuration_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size); + /* Copy the configuration descriptor and update the fields that require it */ + ASSERT(size <= max_size); + memcpy(p_trans_buff, &m_configuration_dsc, size); + + p_trans_buff->bNumInterfaces = iface_count; + p_trans_buff->wTotalLength = total_length; + if (m_rwu_counter) + { + p_trans_buff->bmAttributes |= + APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_REMOTE_WAKEUP_MASK; + } + + m_descriptor_conf_feed_data.p_cinst = app_usbd_class_first_get(); + m_descriptor_conf_feed_data.p_desc = (void *)p_trans_buff; + m_descriptor_conf_feed_data.desc_left = size; + m_descriptor_conf_feed_data.total_left = p_setup_ev->setup.wLength.w; + + /* Start first transfer */ + ret_code_t ret; + CRITICAL_REGION_ENTER(); + + ret = app_usbd_setup_data_handled_transfer( + NRF_DRV_USBD_EPIN0, + &usbd_descriptor_feeder_desc); + + if (NRF_SUCCESS == ret) + { + ret = app_usbd_core_setup_data_handler_set( + NRF_DRV_USBD_EPIN0, + &m_setup_data_handler_empty_desc); + } + CRITICAL_REGION_EXIT(); + + return ret; + } + case APP_USBD_DESCRIPTOR_STRING: + { + app_usbd_string_desc_idx_t id = + (app_usbd_string_desc_idx_t)(p_setup_ev->setup.wValue.lb); + uint16_t langid = p_setup_ev->setup.wIndex.w; + uint16_t const * p_string_dsc = app_usbd_string_desc_get(id, langid); + if (p_string_dsc == NULL) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return app_usbd_core_setup_rsp( + &p_setup_ev->setup, + p_string_dsc, + app_usbd_string_desc_length(p_string_dsc)); + } + default: + break; + } + + + return NRF_ERROR_NOT_SUPPORTED; +} + +static ret_code_t setup_req_get_configuration(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + size_t max_size; + uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size); + if (APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Configured) + { + p_trans_buff[0] = 1; + } + else if (APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Addressed) + { + p_trans_buff[0] = 0; + } + else + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return app_usbd_core_setup_rsp(&p_setup_ev->setup, p_trans_buff, sizeof(p_trans_buff[0])); +} + +/** + * @brief Internal SETUP standard IN request handler + * @param[in] p_inst Instance of the class + * @param[in] p_setup_ev Setup request + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_GET_STATUS: + { + return setup_req_get_status(p_inst, p_setup_ev); + } + case APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR: + { + return setup_req_get_descriptor(p_inst, p_setup_ev); + } + case APP_USBD_SETUP_STDREQ_GET_CONFIGURATION: + { + return setup_req_get_configuration(p_inst, p_setup_ev); + } + default: + /*Not supported*/ + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + + +static ret_code_t setup_req_std_set_configuration(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + if (!((app_usbd_state == APP_USBD_STATE_Configured) || + (app_usbd_state == APP_USBD_STATE_Addressed))) + { + return NRF_ERROR_INVALID_STATE; + } + + app_usbd_state_t new_state = app_usbd_state; + + if (p_setup_ev->setup.wValue.lb == 0) + { + new_state = APP_USBD_STATE_Addressed; + } + else if (p_setup_ev->setup.wValue.lb == 1) + { + new_state = APP_USBD_STATE_Configured; + /*Clear all bulk/interrupt endpoint status and set toggle to DATA0*/ + + app_usbd_class_inst_t const * p_inst_it = app_usbd_class_first_get(); + while (p_inst_it != NULL) + { + uint8_t iface_count = app_usbd_class_iface_count_get(p_inst_it); + for (uint8_t i = 0; i < iface_count; ++i) + { + app_usbd_class_iface_conf_t const * p_iface; + p_iface = app_usbd_class_iface_get(p_inst_it, i); + uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface); + + for (uint8_t j = 0; j < ep_count; ++j) + { + /*Clear stall for every endpoint*/ + app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, j); + + + if (nrf_usbd_dtoggle_get(p_ep->address) != NRF_USBD_DTOGGLE_DATA0) + { + nrf_usbd_dtoggle_set(p_ep->address, NRF_USBD_DTOGGLE_DATA0); + } + + if (NRF_USBD_EPISO_CHECK(p_ep->address) == 0) + { + nrf_drv_usbd_ep_stall_clear(p_ep->address); + } + + } + } + p_inst_it = p_inst_it->p_data->p_next; + } + + } + else + { + /*In this driver only one configuration is supported.*/ + return NRF_ERROR_INVALID_PARAM; + } + + + + if (app_usbd_state != new_state) + { + app_usbd_state = new_state; + /** @todo RK A way to notify class that state was changed */ + } + + return NRF_SUCCESS; +} + +/** + * @brief Internal SETUP standard OUT request handler + * @param[in] p_inst Instance of the class + * @param[in] p_setup_ev Setup request + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_SET_ADDRESS: + { + if ((app_usbd_state != APP_USBD_STATE_Default) && + (app_usbd_state != APP_USBD_STATE_Addressed) && + (app_usbd_state != APP_USBD_STATE_Configured)) + { + return NRF_ERROR_INVALID_STATE; + } + + app_usbd_state = APP_USBD_STATE_Addressed; + return NRF_SUCCESS; + } + case APP_USBD_SETUP_STDREQ_SET_FEATURE: + { + if (p_setup_ev->setup.wValue.w != APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + SET_BIT(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP); + return NRF_SUCCESS; + } + case APP_USBD_SETUP_STDREQ_CLEAR_FEATURE: + { + if (p_setup_ev->setup.wValue.w != APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + CLR_BIT(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP); + return NRF_SUCCESS; + } + case APP_USBD_SETUP_STDREQ_SET_CONFIGURATION: + { + return setup_req_std_set_configuration(p_inst, p_setup_ev); + } + case APP_USBD_SETUP_STDREQ_SET_DESCRIPTOR: + { + /*Not supported yet.*/ + break; + } + default: + /*Not supported*/ + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP event handler + * @param[in] p_inst Instance of the class + * @param[in] p_setup_ev Setup request + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_device_event_handler(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + ASSERT(p_inst != NULL); + ASSERT(p_setup_ev != NULL); + + if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN) + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_in(p_inst, p_setup_ev); + default: + break; + } + } + else /*APP_USBD_SETUP_REQDIR_OUT*/ + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_out(p_inst, p_setup_ev); + default: + break; + } + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Process SETUP command + * + * Auxiliary function for SETUP command processing + */ +static inline ret_code_t app_usbd_core_setup_req_handler(app_usbd_class_inst_t const * const p_inst, + nrf_drv_usbd_evt_t const * const p_event) +{ + app_usbd_setup_evt_t setup_ev; + ret_code_t ret = NRF_ERROR_INTERNAL; /* Final result of request processing function */ + + /* This handler have to be cleared when SETUP is entered */ + // ASSERT(!usb_core_ep0_handler_check()); + + setup_ev.type = APP_USBD_EVT_DRV_SETUP; + nrf_drv_usbd_setup_get((nrf_drv_usbd_setup_t *)&(setup_ev.setup)); + + switch (app_usbd_setup_req_rec(setup_ev.setup.bmRequestType)) + { + case APP_USBD_SETUP_REQREC_DEVICE: + { + /* Endpoint 0 has core instance (that process device requests) connected */ + ret = setup_device_event_handler(p_inst, &setup_ev); + + app_usbd_setup_reqtype_t req_type = + app_usbd_setup_req_typ(setup_ev.setup.bmRequestType); + if (ret == NRF_ERROR_NOT_SUPPORTED && + req_type == APP_USBD_SETUP_REQTYPE_VENDOR) + { + ret = app_usbd_all_until_served_call((app_usbd_complex_evt_t const *)&setup_ev); + } + + break; + } + case APP_USBD_SETUP_REQREC_INTERFACE: + { + uint8_t iface_number = setup_ev.setup.wIndex.lb; + ret = app_usbd_iface_call(iface_number, (app_usbd_complex_evt_t const *)&setup_ev); + if (ret == NRF_SUCCESS || ret != NRF_ERROR_NOT_SUPPORTED) + { + break; + } + + ret = app_usbd_interface_std_req_handle(&setup_ev); + break; + } + case APP_USBD_SETUP_REQREC_ENDPOINT: + { + nrf_drv_usbd_ep_t ep = (nrf_drv_usbd_ep_t)setup_ev.setup.wIndex.lb; + + if ((ep == NRF_DRV_USBD_EPOUT0) || (ep == NRF_DRV_USBD_EPIN0)) + { + ret = app_usbd_endpoint_std_req_handle(&setup_ev); + break; + } + + ret = app_usbd_ep_call(ep, (app_usbd_complex_evt_t const *)&setup_ev); + if (ret == NRF_SUCCESS || ret != NRF_ERROR_NOT_SUPPORTED) + { + break; + } + + ret = app_usbd_endpoint_std_req_handle(&setup_ev); + break; + } + case APP_USBD_SETUP_REQREC_OTHER: + { + /* Try to process via every instance */ + ret = app_usbd_all_until_served_call((app_usbd_complex_evt_t *)&setup_ev); + break; + } + default: + break; + } + + /* Processing result */ + if (ret == NRF_SUCCESS) + { + if (usb_core_ep0_handler_check()) + { + /* Request processed successfully and requires SETUP data */ + nrf_drv_usbd_setup_data_clear(); + } + else + { + /* Request processed successfully */ + nrf_drv_usbd_setup_clear(); + } + } + else + { + /* Request finished with error */ + nrf_drv_usbd_setup_stall(); + } + return ret; +} + +/** + * @brief Event handler for core module + * + * The event handler that would process all events directed to device. + * + */ +static ret_code_t app_usbd_core_event_handler(app_usbd_class_inst_t const * const p_inst, + app_usbd_complex_evt_t const * const p_event) +{ + ret_code_t ret = NRF_ERROR_NOT_SUPPORTED; + switch(p_event->type) + { + case APP_USBD_EVT_DRV_RESET: + { + app_usbd_state = APP_USBD_STATE_Default; + break; + } + case APP_USBD_EVT_DRV_SUSPEND: + { + ASSERT(app_usbd_state >= APP_USBD_STATE_Unattached); + app_usbd_state |= APP_USBD_STATE_SuspendedMask; + ret = NRF_SUCCESS; + break; + } + case APP_USBD_EVT_DRV_RESUME: + { + if (nrf_atomic_flag_clear_fetch(&m_rwu_pending) != 0) + { + nrf_usbd_task_trigger(NRF_USBD_TASK_NODRIVEDPDM); + } + + ASSERT(APP_USB_STATE_BASE(app_usbd_state) >= APP_USBD_STATE_Unattached); + app_usbd_state &= (app_usbd_state_t)(~APP_USBD_STATE_SuspendedMask); + ret = NRF_SUCCESS; + break; + } + case APP_USBD_EVT_DRV_SETUP: + { + ret = app_usbd_core_setup_req_handler(p_inst, &(p_event->drv_evt)); + break; + } + case APP_USBD_EVT_INST_APPEND: + { + ASSERT(app_usbd_state == APP_USBD_STATE_Disabled); + app_usbd_state = APP_USBD_STATE_Unattached; + ret = NRF_SUCCESS; + break; + } + case APP_USBD_EVT_INST_REMOVE: + { + ASSERT(app_usbd_state == APP_USBD_STATE_Unattached); + app_usbd_state = APP_USBD_STATE_Disabled; + ret = NRF_SUCCESS; + break; + } + case APP_USBD_EVT_START: + { + app_usbd_state = APP_USBD_STATE_Powered; + if (usbd_core_power_is_detected()) + { + app_usbd_state = APP_USBD_STATE_Default; + } + ret = NRF_SUCCESS; + break; + } + case APP_USBD_EVT_STOP: + { + ASSERT(APP_USB_STATE_BASE(app_usbd_state) > APP_USBD_STATE_Powered); + if (app_usbd_state & APP_USBD_STATE_SuspendedMask) + { + app_usbd_state = APP_USBD_STATE_SuspendedPowered; + } + else + { + app_usbd_state = APP_USBD_STATE_Powered; + } + ret = NRF_SUCCESS; + break; + } + /* Data transfer on endpoint 0 */ + case APP_USBD_EVT_DRV_EPTRANSFER: + { + /* This EPTRANSFER event has to be called only for EP0 */ + ASSERT((p_event->drv_evt.data.eptransfer.ep == NRF_DRV_USBD_EPOUT0) || + (p_event->drv_evt.data.eptransfer.ep == NRF_DRV_USBD_EPIN0)); + ret = usbd_core_ep0_handler_call_and_clear(p_event->drv_evt.data.eptransfer.status); + /* Processing result */ + if(ret == NRF_SUCCESS) + { + if(usb_core_ep0_handler_check()) + { + /* Request processed successfully and requires SETUP data */ + nrf_drv_usbd_setup_data_clear(); + } + else + { + /* Request processed successfully */ + /* Clear setup only for a write transfer - for a read transfer, + * it is cleared inside the driver */ + if(p_event->drv_evt.data.eptransfer.ep == NRF_DRV_USBD_EPOUT0) + { + nrf_drv_usbd_setup_clear(); + } + } + } + else + { + /* Request finished with error */ + nrf_drv_usbd_setup_stall(); + } + break; + } + default: + break; + } + + return ret; +} + +ret_code_t app_usbd_core_setup_rsp(app_usbd_setup_t const * p_setup, + void const * p_data, + size_t size) +{ + size_t req_size = p_setup->wLength.w; + size_t tx_size = MIN(req_size, size); + bool zlp_required = (size < req_size) && + (0 == (size % nrf_drv_usbd_ep_max_packet_size_get(NRF_DRV_USBD_EPIN0))); + + NRF_DRV_USBD_TRANSFER_IN_FLAGS( + transfer, + p_data, + tx_size, + zlp_required ? NRF_DRV_USBD_TRANSFER_ZLP_FLAG : 0); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_setup_data_transfer(NRF_DRV_USBD_EPIN0, + &transfer); + if (NRF_SUCCESS == ret) + { + ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPIN0, + &m_setup_data_handler_empty_desc); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +ret_code_t app_usbd_core_setup_data_handler_set( + nrf_drv_usbd_ep_t ep, + app_usbd_core_setup_data_handler_desc_t const * const p_handler_desc) +{ + if (nrf_drv_usbd_last_setup_dir_get() != ep) + { + return NRF_ERROR_INVALID_ADDR; + } + + m_ep0_handler_desc = *p_handler_desc; + return NRF_SUCCESS; +} + +ret_code_t app_usbd_core_ep_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_transfer_t const * const p_transfer) +{ + if (APP_USB_STATE_BASE(app_usbd_state) != APP_USBD_STATE_Configured) + { + return NRF_ERROR_INVALID_STATE; + } + return nrf_drv_usbd_ep_transfer(ep, p_transfer); +} + +ret_code_t app_usbd_core_setup_data_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_transfer_t const * const p_transfer) +{ + ASSERT(0 == NRF_USBD_EP_NR_GET(ep)); + + if (!((APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Configured) || + (APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Addressed ) || + (APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Default ) )) + { + return NRF_ERROR_INVALID_STATE; + } + return nrf_drv_usbd_ep_transfer(ep, p_transfer); +} + +ret_code_t app_usbd_ep_handled_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_handler_desc_t const * const p_handler) +{ + if (APP_USB_STATE_BASE(app_usbd_state) != APP_USBD_STATE_Configured) + { + return NRF_ERROR_INVALID_STATE; + } + return nrf_drv_usbd_ep_handled_transfer(ep, p_handler); +} + +ret_code_t app_usbd_setup_data_handled_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_handler_desc_t const * const p_handler) +{ + ASSERT(0 == NRF_USBD_EP_NR_GET(ep)); + + if (!((APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Configured) || + (APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Addressed ) || + (APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Default ) )) + { + return NRF_ERROR_INVALID_STATE; + } + return nrf_drv_usbd_ep_handled_transfer(ep, p_handler); +} + +void * app_usbd_core_setup_transfer_buff_get(size_t * p_size) +{ + if (p_size != NULL) + *p_size = sizeof(m_setup_transfer_buff); + + return m_setup_transfer_buff; +} + +app_usbd_state_t app_usbd_core_state_get(void) +{ + return app_usbd_state; +} + +void app_usbd_core_class_rwu_register(app_usbd_class_inst_t const * const p_inst) +{ + ASSERT(p_inst != NULL); + ++m_rwu_counter; + /*Overflow check*/ + ASSERT(m_rwu_counter != 0); +} + +void app_usbd_core_class_rwu_unregister(app_usbd_class_inst_t const * const p_inst) +{ + ASSERT(p_inst != NULL); + /* Usage validation. If counter is 0 unregister is not possible.*/ + ASSERT(m_rwu_counter != 0); + --m_rwu_counter; +} + +void app_usbd_core_class_rwu_pend(void) +{ + if (m_rwu_counter == 0) + { + /* No class registered on remote wake-up */ + return; + } + + if (IS_SET(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP) == 0) + { + /* Feature remote wake-up hasn't been set by host*/ + return; + } + + if (nrf_atomic_flag_set_fetch(&m_rwu_pending) != 0) + { + /* Remote wake-up pending */ + return; + } + + nrf_usbd_dpdmvalue_set(NRF_USBD_DPDMVALUE_RESUME); + nrf_usbd_task_trigger(NRF_USBD_TASK_DRIVEDPDM); +} + +/** @} */ +#endif // APP_USBD_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_core.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_core.h new file mode 100644 index 0000000000000000000000000000000000000000..e022aa8e5411d09d7125b6e37b92de7764f04eb5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_core.h @@ -0,0 +1,306 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef APP_USBD_CORE_H__ +#define APP_USBD_CORE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "sdk_common.h" +#include "nrf_drv_usbd.h" +#include "app_usbd_types.h" +#include "app_usbd_class_base.h" + + +/** + * @defgroup app_usbd_core USB Device high level library core module + * @ingroup app_usbd + * + * @brief @tagAPI52840 Core module that manages current USB state and process device requests. + * @{ + */ + +/** + * @brief USB Device state + * + * Possible USB Device states according to specification. + */ +typedef enum +{ + APP_USBD_STATE_Disabled = 0x00, /**< The whole USBD library is disabled */ + APP_USBD_STATE_Unattached = 0x01, /**< Device is currently not connected to the host */ + APP_USBD_STATE_Powered = 0x02, /**< Device is connected to the host but has not been enumerated */ + APP_USBD_STATE_Default = 0x03, /**< USB Reset condition detected, waiting for the address */ + APP_USBD_STATE_Addressed = 0x04, /**< Device has been addressed but have not been configured */ + APP_USBD_STATE_Configured = 0x05, /**< Device is addressed and configured */ + + APP_USBD_STATE_SuspendedMask = 0x10, /**< Mask used to mark suspended state, suspended state remembers also the target state after wake up */ + + APP_USBD_STATE_SuspendedPowered = APP_USBD_STATE_SuspendedMask | APP_USBD_STATE_Powered, /**< Device is Suspended and on wakeup it will return to Powered state */ + APP_USBD_STATE_SuspendedDefault = APP_USBD_STATE_SuspendedMask | APP_USBD_STATE_Default, /**< Device is Suspended and on wakeup it will return to Default state */ + APP_USBD_STATE_SuspendedAddressed = APP_USBD_STATE_SuspendedMask | APP_USBD_STATE_Addressed, /**< Device is Suspended and on wakeup it will return to Addressed state */ + APP_USBD_STATE_SuspendedConfigured = APP_USBD_STATE_SuspendedMask | APP_USBD_STATE_Configured /**< Device is Suspended and on wakeup it will return to Configured state */ +}app_usbd_state_t; + +/** + * @brief Remove @ref APP_USBD_STATE_SuspendedMask bit from core state + */ +#define APP_USB_STATE_BASE(state) ((state) & (~APP_USBD_STATE_SuspendedMask)) + +/** + * @brief Core interface configuration + * + * Core instance would have 2 endpoints (IN0 and OUT0). + * The interface number does not care because it would not be used. + */ +#define APP_USBD_CORE_CLASS_CONFIGURATION ((0, NRF_DRV_USBD_EPOUT0, NRF_DRV_USBD_EPIN0)) + +/** + * @brief EP0 handler function pointer + * + * Type of the variable that would hold the pointer to the handler for + * endpoint 0 messages processing. + * + * @param p_contex Context variable configured with the transmission request. + */ +typedef ret_code_t (*app_usbd_core_setup_data_handler_t)(nrf_drv_usbd_ep_status_t status, + void * p_context); + +/** + * @brief Variable type used to register EP0 transfer handler + * + * EP0 messages are processed by core instance. + * Another class can register itself to receive messages from EP0 when requesting + * for Setup data transfer. + */ +typedef struct +{ + app_usbd_core_setup_data_handler_t handler; //!< Event handler to be called when transmission is ready + void * p_context; //!< Context pointer to be send to every called event. +} app_usbd_core_setup_data_handler_desc_t; + +/*lint -save -e10 -e26 -e93 -e123 -e505 */ +/** + * @brief Declare Core instance type + * + * USBD core instance type definition. + */ +APP_USBD_CLASS_TYPEDEF(app_usbd_core, + APP_USBD_CORE_CLASS_CONFIGURATION, + APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE, + APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE); +/*lint -restore*/ + +/** + * @brief Access to core instance + * + * Function that returns pointer to the USBD core instance. + * + * @return pointer to the core instance + */ +static inline app_usbd_class_inst_t const * app_usbd_core_instance_access(void) +{ + extern const APP_USBD_CLASS_INSTANCE_TYPE(app_usbd_core) app_usbd_core_inst; + return (app_usbd_class_inst_t const *)&app_usbd_core_inst; +} + +/** + * @brief Default simple response to setup command + * + * This function generates default simple response. + * It sends ZLP when required and on takes care on allowing status stage when + * transfer is finished. + * + * @param p_setup Pointer to original setup message + * @param p_data Pointer to the response. This has to be globaly aviable data. + * @param size Total size of the answer - The function takes care about + * limiting the size of transfered data to the size required + * by setup command. + */ +ret_code_t app_usbd_core_setup_rsp(app_usbd_setup_t const * p_setup, + void const * p_data, + size_t size); + +/** + * @brief Configure the handler for the nearest setup data endpoint transfer + * + * This function would be called on incomming setup data. + * The correct place to set the handler for a data is when SETUP command + * was received. + * + * @param ep Endpoint number (only IN0 and OUT0) are supported. + * @param p_handler_desc Descriptor of the handler to be called. + * + * @retval NRF_SUCCESS Successfully configured + * @retval NRF_ERROR_INVALID_ADDR Last received setup direction does not match + * configured endpoint. + */ +ret_code_t app_usbd_core_setup_data_handler_set( + nrf_drv_usbd_ep_t ep, + app_usbd_core_setup_data_handler_desc_t const * const p_handler_desc); + +/** + * @brief Endpoint transfer + * + * @param ep Endpoint number + * @param p_transfer Description of the transfer to be performed. + * The direction of the transfer is determined by the + * endpoint number. + * + * @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow + * data transfer on the endpoint. + * + * @return Values returned by @ref nrf_drv_usbd_ep_transfer + * + * @note This function can work only if the USB is in Configured state. + * See @ref app_usbd_core_setup_data_transfer for transfers before + * device configuration is done. + * @sa app_usbd_core_setup_data_transfer + */ +ret_code_t app_usbd_core_ep_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_transfer_t const * const p_transfer); + +/** + * @brief Setup data transfer + * + * Function similar to @ref app_usbd_core_ep_transfer. + * The only technical diference is that it should be used with setup transfers + * that are going to be performed before device is configured. + * + * @param ep See @ref app_usbd_core_ep_transfer. + * @param p_transfer See @ref app_usbd_core_ep_transfer. + * + * @return The same values like @ref app_usbd_core_ep_transfer + */ +ret_code_t app_usbd_core_setup_data_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_transfer_t const * const p_transfer); + +/** + * @brief Set up an endpoint-handled transfer. + * + * Configures a transfer handled by the feedback function. + * + * @param ep Endpoint number. + * @param p_handler Function called when the next chunk of data is requested. + * + * @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow + * data transfer on the endpoint. + * + * @return Values returned by @ref nrf_drv_usbd_ep_handled_transfer. + */ +ret_code_t app_usbd_ep_handled_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_handler_desc_t const * const p_handler); + +/** + * @brief Set up a data-handled transfer. + * + * Function similar to @ref app_usbd_ep_handled_transfer. + * The only technical diference is that it should be used with setup transfers + * that are performed before the device is configured. + * + * @param ep Endpoint number + * @param p_handler Function called when the next chunk of data is requested. + * + * @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow + * data transfer on the endpoint. + * + * @return Values returned by @ref nrf_drv_usbd_ep_handled_transfer. + */ +ret_code_t app_usbd_setup_data_handled_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_handler_desc_t const * const p_handler); + +/** + * @brief Set up a data transfer buffer. + * + * Returns special internal buffer that can be used in setup transfer. + * @return Internal buffer pointer + */ +void * app_usbd_core_setup_transfer_buff_get(size_t * p_size); + + +/**@brief Return internal USBD core state + * + * @return Check @ref app_usbd_state_t to find possible USBD core states + */ +app_usbd_state_t app_usbd_core_state_get(void); + + +/** + * @brief Check current USBD regulator status + * + * @return true when regulator is ready + */ +static inline bool app_usbd_core_power_regulator_is_ready(void) +{ + return 0 != ( (NRF_POWER->USBREGSTATUS) & POWER_USBREGSTATUS_OUTPUTRDY_Msk); +} + +/** + * @brief Register class on remote wake-up feature + * @param[in] p_inst Instance of the class + */ +void app_usbd_core_class_rwu_register(app_usbd_class_inst_t const * const p_inst); + +/** + * @brief Unregister class from remote wake-up feature + * @param[in] p_inst Instance of the class + */ +void app_usbd_core_class_rwu_unregister(app_usbd_class_inst_t const * const p_inst); + +/** + * @brief Set remote wake-up pending + * */ +void app_usbd_core_class_rwu_pend(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_CORE_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_descriptor.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_descriptor.h new file mode 100644 index 0000000000000000000000000000000000000000..741a42364f3998c20b9e6e51375a30e2e50d5399 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_descriptor.h @@ -0,0 +1,335 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef APP_USBD_DESCRIPTOR_H__ +#define APP_USBD_DESCRIPTOR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf.h" +#include "nrf_drv_usbd.h" +#include "app_usbd_langid.h" +#include "app_util_platform.h" + +/* Compiler support for anonymous unions */ +ANON_UNIONS_ENABLE + +/** + * @defgroup app_usbd_descriptor USB standard descriptors + * @ingroup app_usbd + * + * @brief @tagAPI52840 Module with types definitions used for standard descriptors. + * @{ + */ + +/** + * @brief Helper macro for translating unsigned 24 bit value to 2 byte raw descriptor + * */ +#define APP_USBD_U16_TO_RAW_DSC(val) (uint8_t)(val), \ + (uint8_t)(((val) / (256))) + +/** + * @brief Helper macro for translating unsigned 24 bit value to 3 byte raw descriptor + * */ +#define APP_USBD_U24_TO_RAW_DSC(val) (uint8_t)(val), \ + (uint8_t)(((val) / (256))), \ + (uint8_t)(((val) / (256 * 256))) + +/** + * @brief Helper macro for translating unsigned 32 bit value to 4 byte raw descriptor + * */ +#define APP_USBD_U32_TO_RAW_DSC(val) (uint8_t)(val), \ + (uint8_t)(((val) / (256))), \ + (uint8_t)(((val) / (256 * 256))) \ + (uint8_t)(((val) / (256 * 256 * 256))) +/** + * @brief Descriptor types + * + * Descriptor types used in two situations: + * - when processing @ref APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR SETUP request, + * the required descriptor type may be placed in wValue in HighByte. + * - As a descriptor identifier itself inside descriptor stream. + * + * According to chapter 9.6 of USB 2.0 specification, following descriptors may + * be requested directly by GetDescriptor method: + * - @ref APP_USBD_DESCRIPTOR_DEVICE + * - @ref APP_USBD_DESCRIPTOR_DEVICE_QUALIFIER (not used for FullSpeed only device) + * - @ref APP_USBD_DESCRIPTOR_CONFIGURATION + * - @ref APP_USBD_DESCRIPTOR_STRING + */ +typedef enum +{ + APP_USBD_DESCRIPTOR_DEVICE = 1, /**< Device descriptor. */ + APP_USBD_DESCRIPTOR_CONFIGURATION = 2, /**< + * Specific configuration descriptor. + * Configuration descriptor is always followed by all the related interface + * and endpoints descriptors. + */ + APP_USBD_DESCRIPTOR_STRING = 3, /**< String descriptor. */ + APP_USBD_DESCRIPTOR_INTERFACE = 4, /**< + * Interface descriptor followed by all the related endpoints descriptors. + * + * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION. + * Cannot be accessed by GetDescriptor or SetDescriptor + */ + APP_USBD_DESCRIPTOR_ENDPOINT = 5, /**< + * Endpoint descriptor. + * + * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION. + * Cannot be accessed by GetDescriptor or SetDescriptor + */ + APP_USBD_DESCRIPTOR_DEVICE_QUALIFIER = 6, /**< @note Not supported - used only in HighSpeed capable devices. */ + APP_USBD_DESCRIPTOR_OTHER_SPEED_CONFIGURATION = 7, /**< @note Not supported - our USB implementation supports only one speed. */ + APP_USBD_DESCRIPTOR_INTERFACE_POWER = 8, /**< @note Not supported */ + APP_USBD_DESCRIPTOR_OTG = 9, /**< @note Not supported - Our USB have not OTG functionality */ + APP_USBD_DESCRIPTOR_DEBUG = 10, /**< Debug channel descriptor if available, can be only reached by GetDescriptor */ + APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION = 11 /**< + * Descriptor used to describe that two or more interfaces are associated to the same function. + * + * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION. + * Cannot be accessed by GetDescriptor or SetDescriptor + */ + +} app_usbd_descriptor_t; + +/* Make all descriptors packed */ +#pragma pack(push, 1) + +/** + * @brief Common descriptor header + * + * The header that we can find on the beginning of all descriptors that contains + * the descriptor length and type. + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal one of @ref app_usbd_descriptor_t. + /** Class specific descriptors values are defined inside classes. */ +} app_usbd_descriptor_header_t; + +/** + * @brief Device descriptor + * + * Descriptor used for the whole device + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_DEVICE. + uint16_t bcdUSB; //!< USB Specification Release Number in Binary-Coded Decimal + uint8_t bDeviceClass; //!< Device class code. + /**< If 0, each interface specifies its own class information. + * 0xFF for vendor-specific. + */ + uint8_t bDeviceSubClass; //!< Subclass code. + /**< If bDevice Class is set to value other than 0xFF, + * all values here are reserved for assignment by USB-IF. + */ + uint8_t bDeviceProtocol; //!< Subclass code. + /**< If 0, no specific protocol is defined on device basis. + * Each interface may define its own protocol then. + * If set to 0xFF, vendor-specific protocol is used. + */ + uint8_t bMaxPacketSize0; //!< Maximum packet size for endpoint zero. + uint16_t idVendor; //!< Vendor ID (Assigned by the USB-IF). + uint16_t idProduct; //!< Product ID (assigned by manufacturer). + uint16_t bcdDevice; //!< Device release number in binary-coded decimal. + uint8_t iManufacturer; //!< Index of string descriptor in describing manufacturer. + uint8_t iProduct; //!< Index of string descriptor in describing product. + uint8_t iSerialNumber; //!< Index of string descriptor in describing the device's serial number. + uint8_t bNumConfigurations; //!< Number of possible configurations. +} app_usbd_descriptor_device_t; + +/** + * @brief Attributes masks + * + * Masks used for attributes in configuration. + */ +typedef enum +{ + /** This is reserved descriptor that has always to be set */ + APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_ALWAYS_SET_MASK = 1U << 7, + /** Attribute that informs that device is self powered */ + APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK = 1U << 6, + /** Attribute that informs that device has Remove Wakeup functionality */ + APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_REMOTE_WAKEUP_MASK = 1U << 5 +} app_usbd_descriptor_configuration_attributes_t; + +/** + * @brief Configuration descriptor + * + * Descriptor used at the beginning of configuration response. + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_DEVICE. + uint16_t wTotalLength; //!< Total length of configuration data, including all descriptors returned after configuration itself. + uint8_t bNumInterfaces; //!< Number of interfaces supportedf by this configuration + uint8_t bConfigurationValue; //!< Value to use as an argument to the SetConfiguration request. + uint8_t iConfiguration; //!< Index of string descriptor describing this configuration. + uint8_t bmAttributes; //!< Configuration characteristics. + uint8_t bMaxPower; //!< Maximum power consumption. Expressed in 2 mA units. +} app_usbd_descriptor_configuration_t; + +/** + * @brief Raw descriptor - String descriptor zero + * + * String descriptor sent only as a response for GetDescriptor. + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_STRING. + uint16_t wLANGID[]; //!< The array of LANGID codes supported by the device. +} app_usbd_descriptor_string0_t; + +/** + * @brief Raw descriptor - Any normal string + * + * String descriptor sent only as a response for GetDescriptor. + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_STRING. + uint16_t bString[]; //!< UNICODE encoded string. +} app_usbd_descriptor_string_t; + + +/** + * @brief Interface descriptor + * + * Interface descriptor, returned as a part of configuration descriptor. + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_INTERFACE. + uint8_t bInterfaceNumber; //!< Number of this interface. + uint8_t bAlternateSetting; //!< Value used to select this alternate setting. + uint8_t bNumEndpoints; //!< Number of endpoints used by this interface. + uint8_t bInterfaceClass; //!< Class code (assigned by the USB-IF). 0xff for vendor specific. + uint8_t bInterfaceSubClass; //!< Subclass code (assigned by the USB-IF). + uint8_t bInterfaceProtocol; //!< Protocol code (assigned by the USB-IF). 0xff for vendor specific. + uint8_t iInterface; //!< Index of string descriptor describing this interface. +} app_usbd_descriptor_iface_t; + +/** Offset of endpoint type attribute bits */ +#define APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET 0 +/** Mask of endpoint type attribute bits */ +#define APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET) + +/** Offset of endpoint synchronization type attribute bits */ +#define APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET 2 +/** Mask of endpoint synchronization type attribute bits */ +#define APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET) + +/** Offset of endpoint usage type attribute bits */ +#define APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET 4 +/** Mask of endpoint usage type attribute bits */ +#define APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET) + +/** + * @brief Endpoint attributes mnemonics + * + * @sa APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_MASK + * @sa APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_MASK + * @sa APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_MASK + */ +typedef enum +{ + APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_CONTROL = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT = 3 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET, + + APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_NONE = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_ASYNCHRONOUS = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_ADAPTIVE = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_SYNCHRONOUS = 3 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET, + + APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_DATA = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_FEEDBACK = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_IMPLICIT = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET +} app_usbd_descriptor_ep_attr_bitmap_t; + +/** + * @brief Endpoint descriptor + * + * Endpoint descriptor, returned as a part of configuration descriptor. + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_ENDPOINT. + uint8_t bEndpointAddress; //!< Endpoint address + uint8_t bmAttributes; //!< Endpoint attributes + uint16_t wMaxPacketSize; //!< Maximum packet size this endpoint is capable of handling. + uint8_t bInterval; //!< Interval for pooling endpoint for data transfers. +} app_usbd_descriptor_ep_t; + +/** + * @brief Interface association descriptor + */ +typedef struct +{ + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} app_usbd_descriptor_iad_t; + +#pragma pack(pop) +ANON_UNIONS_DISABLE + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* APP_USBD_DESCRIPTOR_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_langid.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_langid.h new file mode 100644 index 0000000000000000000000000000000000000000..23c23700ca23286205f0956fda8449fda7f2b824 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_langid.h @@ -0,0 +1,286 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef APP_USBD_LANGID_H__ +#define APP_USBD_LANGID_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * @brief This file contains LANGID variable type with all defined values + * + * This file was created using Language Identifiers (LANGIDs) 3/29/00 Version 1.0, + * available on USB web page: + * http://www.usb.org/developers/docs/USB_LANGIDs.pdf + * + * @note + * Do not include this file directly to the project. + * It is included by @file app_usbd_request.h. + */ + +/** + * Offset of the lowest bit of primary language identifier + * @sa app_usbd_langid_t + */ +#define APP_USB_LANG_OFFSET 0 + +/** + * Bitmask for a primary language identifier + * @sa app_usbd_langid_t + */ +#define APP_USB_LANG_MASK BF_MASK(10, APP_USB_LANG_OFFSET) + +/** + * Offset of the lowest bit of sub-language identifier + * @sa app_usbd_langid_t + */ +#define APP_USB_SUBLANG_OFFSET 10 + +/** + * Bitmask for a sub-language identifier + * @sa app_usbd_langid_t + */ +#define APP_USB_SUBLANG_MASK BF_MASK(6, APP_USB_SUBLANG_OFFSET) + +/** + * @brief Primary language identifiers + * + * Mnemonics for primary language identifiers. + * This mnemonics can be combined using logical OR operator with @ref app_usbd_langid_sub_t. + */ +typedef enum +{ + APP_USBD_LANG_ARABIC = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Arabic */ + APP_USBD_LANG_BULGARIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Bulgarian */ + APP_USBD_LANG_CATALAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Catalan */ + APP_USBD_LANG_CHINESE = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Chinese */ + APP_USBD_LANG_CZECH = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Czech */ + APP_USBD_LANG_DANISH = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Danish */ + APP_USBD_LANG_GERMAN = 0x07U << ( APP_USB_LANG_OFFSET ), /**< German */ + APP_USBD_LANG_GREEK = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Greek */ + APP_USBD_LANG_ENGLISH = 0x09U << ( APP_USB_LANG_OFFSET ), /**< English */ + APP_USBD_LANG_SPANISH = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< Spanish */ + APP_USBD_LANG_FINNISH = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< Finnish */ + APP_USBD_LANG_FRENCH = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< French */ + APP_USBD_LANG_HEBREW = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< Hebrew */ + APP_USBD_LANG_HUNGARIAN = 0x0eU << ( APP_USB_LANG_OFFSET ), /**< Hungarian */ + APP_USBD_LANG_ICELANDIC = 0x0fU << ( APP_USB_LANG_OFFSET ), /**< Icelandic */ + APP_USBD_LANG_ITALIAN = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Italian */ + APP_USBD_LANG_JAPANESE = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Japanese */ + APP_USBD_LANG_KOREAN = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Korean */ + APP_USBD_LANG_DUTCH = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Dutch */ + APP_USBD_LANG_NORWEGIAN = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Norwegian */ + APP_USBD_LANG_POLISH = 0x15U << ( APP_USB_LANG_OFFSET ), /**< Polish */ + APP_USBD_LANG_PORTUGUESE = 0x16U << ( APP_USB_LANG_OFFSET ), /**< Portuguese */ + APP_USBD_LANG_ROMANIAN = 0x18U << ( APP_USB_LANG_OFFSET ), /**< Romanian */ + APP_USBD_LANG_RUSSIAN = 0x19U << ( APP_USB_LANG_OFFSET ), /**< Russian */ + APP_USBD_LANG_CROATIAN = 0x1aU << ( APP_USB_LANG_OFFSET ), /**< Croatian */ + APP_USBD_LANG_SERBIAN = 0x1aU << ( APP_USB_LANG_OFFSET ), /**< Serbian */ + APP_USBD_LANG_SLOVAK = 0x1bU << ( APP_USB_LANG_OFFSET ), /**< Slovak */ + APP_USBD_LANG_ALBANIAN = 0x1cU << ( APP_USB_LANG_OFFSET ), /**< Albanian */ + APP_USBD_LANG_SWEDISH = 0x1dU << ( APP_USB_LANG_OFFSET ), /**< Swedish */ + APP_USBD_LANG_THAI = 0x1eU << ( APP_USB_LANG_OFFSET ), /**< Thai */ + APP_USBD_LANG_TURKISH = 0x1fU << ( APP_USB_LANG_OFFSET ), /**< Turkish */ + APP_USBD_LANG_URDU = 0x20U << ( APP_USB_LANG_OFFSET ), /**< Urdu */ + APP_USBD_LANG_INDONESIAN = 0x21U << ( APP_USB_LANG_OFFSET ), /**< Indonesian */ + APP_USBD_LANG_UKRANIAN = 0x22U << ( APP_USB_LANG_OFFSET ), /**< Ukrainian */ + APP_USBD_LANG_BELARUSIAN = 0x23U << ( APP_USB_LANG_OFFSET ), /**< Belarusian */ + APP_USBD_LANG_SLOVENIAN = 0x24U << ( APP_USB_LANG_OFFSET ), /**< Slovenian */ + APP_USBD_LANG_ESTONIAN = 0x25U << ( APP_USB_LANG_OFFSET ), /**< Estonian */ + APP_USBD_LANG_LATVIAN = 0x26U << ( APP_USB_LANG_OFFSET ), /**< Latvian */ + APP_USBD_LANG_LITHUANIAN = 0x27U << ( APP_USB_LANG_OFFSET ), /**< Lithuanian */ + APP_USBD_LANG_FARSI = 0x29U << ( APP_USB_LANG_OFFSET ), /**< Farsi */ + APP_USBD_LANG_VIETNAMESE = 0x2aU << ( APP_USB_LANG_OFFSET ), /**< Vietnamese */ + APP_USBD_LANG_ARMENIAN = 0x2bU << ( APP_USB_LANG_OFFSET ), /**< Armenian */ + APP_USBD_LANG_AZERI = 0x2cU << ( APP_USB_LANG_OFFSET ), /**< Azeri */ + APP_USBD_LANG_BASQUE = 0x2dU << ( APP_USB_LANG_OFFSET ), /**< Basque */ + APP_USBD_LANG_MACEDONIAN = 0x2fU << ( APP_USB_LANG_OFFSET ), /**< Macedonian */ + APP_USBD_LANG_AFRIKAANS = 0x36U << ( APP_USB_LANG_OFFSET ), /**< Afrikaans */ + APP_USBD_LANG_GEORGIAN = 0x37U << ( APP_USB_LANG_OFFSET ), /**< Georgian */ + APP_USBD_LANG_FAEROESE = 0x38U << ( APP_USB_LANG_OFFSET ), /**< Faeroese */ + APP_USBD_LANG_HINDI = 0x39U << ( APP_USB_LANG_OFFSET ), /**< Hindi */ + APP_USBD_LANG_MALAY = 0x3eU << ( APP_USB_LANG_OFFSET ), /**< Malay */ + APP_USBD_LANG_KAZAK = 0x3fU << ( APP_USB_LANG_OFFSET ), /**< Kazak */ + APP_USBD_LANG_SWAHILI = 0x41U << ( APP_USB_LANG_OFFSET ), /**< Swahili */ + APP_USBD_LANG_UZBEK = 0x43U << ( APP_USB_LANG_OFFSET ), /**< Uzbek */ + APP_USBD_LANG_TATAR = 0x44U << ( APP_USB_LANG_OFFSET ), /**< Tatar */ + APP_USBD_LANG_BENGALI = 0x45U << ( APP_USB_LANG_OFFSET ), /**< Bengali */ + APP_USBD_LANG_PUNJABI = 0x46U << ( APP_USB_LANG_OFFSET ), /**< Punjabi */ + APP_USBD_LANG_GUJARATI = 0x47U << ( APP_USB_LANG_OFFSET ), /**< Gujarati */ + APP_USBD_LANG_ORIYA = 0x48U << ( APP_USB_LANG_OFFSET ), /**< Oriya */ + APP_USBD_LANG_TAMIL = 0x49U << ( APP_USB_LANG_OFFSET ), /**< Tamil */ + APP_USBD_LANG_TELUGU = 0x4aU << ( APP_USB_LANG_OFFSET ), /**< Telugu */ + APP_USBD_LANG_KANNADA = 0x4bU << ( APP_USB_LANG_OFFSET ), /**< Kannada */ + APP_USBD_LANG_MALAYALAM = 0x4cU << ( APP_USB_LANG_OFFSET ), /**< Malayalam */ + APP_USBD_LANG_ASSAMESE = 0x4dU << ( APP_USB_LANG_OFFSET ), /**< Assamese */ + APP_USBD_LANG_MARATHI = 0x4eU << ( APP_USB_LANG_OFFSET ), /**< Marathi */ + APP_USBD_LANG_SANSKRIT = 0x4fU << ( APP_USB_LANG_OFFSET ), /**< Sanskrit */ + APP_USBD_LANG_KONKANI = 0x57U << ( APP_USB_LANG_OFFSET ), /**< Konkani */ + APP_USBD_LANG_MANIPURI = 0x58U << ( APP_USB_LANG_OFFSET ), /**< Manipuri */ + APP_USBD_LANG_SINDHI = 0x59U << ( APP_USB_LANG_OFFSET ), /**< Sindhi */ + APP_USBD_LANG_KASHMIRI = 0x60U << ( APP_USB_LANG_OFFSET ), /**< Kashmiri */ + APP_USBD_LANG_NEPALI = 0x61U << ( APP_USB_LANG_OFFSET ), /**< Nepali */ + APP_USBD_LANG_HID = 0xffU << ( APP_USB_LANG_OFFSET ), /**< Reserved for USB HID Class use */ +}app_usbd_langid_primary_t; + +/** + * @brief Sublanguage identifiers + * + * Mnemonics with sublanguage values. + * Use them in combination with @ref app_usbd_langid_primary_t. + */ +typedef enum +{ + APP_USBD_SUBLANG_ARABIC_SAUDI_ARABIA = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Saudi Arabia) */ + APP_USBD_SUBLANG_ARABIC_IRAQ = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Iraq) */ + APP_USBD_SUBLANG_ARABIC_EGYPT = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Egypt) */ + APP_USBD_SUBLANG_ARABIC_LIBYA = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Libya) */ + APP_USBD_SUBLANG_ARABIC_ALGERIA = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Algeria) */ + APP_USBD_SUBLANG_ARABIC_MOROCCO = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Morocco) */ + APP_USBD_SUBLANG_ARABIC_TUNISIA = 0x07U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Tunisia) */ + APP_USBD_SUBLANG_ARABIC_OMAN = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Oman) */ + APP_USBD_SUBLANG_ARABIC_YEMEN = 0x09U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Yemen) */ + APP_USBD_SUBLANG_ARABIC_SYRIA = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Syria) */ + APP_USBD_SUBLANG_ARABIC_JORDAN = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Jordan) */ + APP_USBD_SUBLANG_ARABIC_LEBANON = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Lebanon) */ + APP_USBD_SUBLANG_ARABIC_KUWAIT = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Kuwait) */ + APP_USBD_SUBLANG_ARABIC_UAE = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Arabic (U.A.E.) */ + APP_USBD_SUBLANG_ARABIC_BAHRAIN = 0x15U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Bahrain) */ + APP_USBD_SUBLANG_ARABIC_QATAR = 0x16U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Qatar) */ + APP_USBD_SUBLANG_AZERI_CYRILLIC = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Azeri (Cyrillic) */ + APP_USBD_SUBLANG_AZERI_LATIN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Azeri (Latin) */ + APP_USBD_SUBLANG_CHINESE_TRADITIONAL = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Traditional) */ + APP_USBD_SUBLANG_CHINESE_SIMPLIFIED = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Simplified) */ + APP_USBD_SUBLANG_CHINESE_HONGKONG = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Hong Kong SAR, PRC) */ + APP_USBD_SUBLANG_CHINESE_SINGAPORE = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Singapore) */ + APP_USBD_SUBLANG_CHINESE_MACAU = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Macau SAR) */ + APP_USBD_SUBLANG_DUTCH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Dutch */ + APP_USBD_SUBLANG_DUTCH_BELGIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Dutch (Belgian) */ + APP_USBD_SUBLANG_ENGLISH_US = 0x01U << ( APP_USB_LANG_OFFSET ), /**< English (US) */ + APP_USBD_SUBLANG_ENGLISH_UK = 0x02U << ( APP_USB_LANG_OFFSET ), /**< English (UK) */ + APP_USBD_SUBLANG_ENGLISH_AUS = 0x03U << ( APP_USB_LANG_OFFSET ), /**< English (Australian) */ + APP_USBD_SUBLANG_ENGLISH_CAN = 0x04U << ( APP_USB_LANG_OFFSET ), /**< English (Canadian) */ + APP_USBD_SUBLANG_ENGLISH_NZ = 0x05U << ( APP_USB_LANG_OFFSET ), /**< English (New Zealand) */ + APP_USBD_SUBLANG_ENGLISH_EIRE = 0x06U << ( APP_USB_LANG_OFFSET ), /**< English (Ireland) */ + APP_USBD_SUBLANG_ENGLISH_SOUTH_AFRICA = 0x07U << ( APP_USB_LANG_OFFSET ), /**< English (South Africa) */ + APP_USBD_SUBLANG_ENGLISH_JAMAICA = 0x08U << ( APP_USB_LANG_OFFSET ), /**< English (Jamaica) */ + APP_USBD_SUBLANG_ENGLISH_CARIBBEAN = 0x09U << ( APP_USB_LANG_OFFSET ), /**< English (Caribbean) */ + APP_USBD_SUBLANG_ENGLISH_BELIZE = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< English (Belize) */ + APP_USBD_SUBLANG_ENGLISH_TRINIDAD = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< English (Trinidad) */ + APP_USBD_SUBLANG_ENGLISH_PHILIPPINES = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< English (Zimbabwe) */ + APP_USBD_SUBLANG_ENGLISH_ZIMBABWE = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< English (Philippines) */ + APP_USBD_SUBLANG_FRENCH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< French */ + APP_USBD_SUBLANG_FRENCH_BELGIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< French (Belgian) */ + APP_USBD_SUBLANG_FRENCH_CANADIAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< French (Canadian) */ + APP_USBD_SUBLANG_FRENCH_SWISS = 0x04U << ( APP_USB_LANG_OFFSET ), /**< French (Swiss) */ + APP_USBD_SUBLANG_FRENCH_LUXEMBOURG = 0x05U << ( APP_USB_LANG_OFFSET ), /**< French (Luxembourg) */ + APP_USBD_SUBLANG_FRENCH_MONACO = 0x06U << ( APP_USB_LANG_OFFSET ), /**< French (Monaco) */ + APP_USBD_SUBLANG_GERMAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< German */ + APP_USBD_SUBLANG_GERMAN_SWISS = 0x02U << ( APP_USB_LANG_OFFSET ), /**< German (Swiss) */ + APP_USBD_SUBLANG_GERMAN_AUSTRIAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< German (Austrian) */ + APP_USBD_SUBLANG_GERMAN_LUXEMBOURG = 0x04U << ( APP_USB_LANG_OFFSET ), /**< German (Luxembourg) */ + APP_USBD_SUBLANG_GERMAN_LIECHTENSTEIN = 0x05U << ( APP_USB_LANG_OFFSET ), /**< German (Liechtenstein) */ + APP_USBD_SUBLANG_ITALIAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Italian */ + APP_USBD_SUBLANG_ITALIAN_SWISS = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Italian (Swiss) */ + APP_USBD_SUBLANG_KASHMIRI_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Kashmiri (India) */ + APP_USBD_SUBLANG_KOREAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Korean */ + APP_USBD_SUBLANG_LITHUANIAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Lithuanian */ + APP_USBD_SUBLANG_MALAY_MALAYSIA = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Malay (Malaysia) */ + APP_USBD_SUBLANG_MALAY_BRUNEI_DARUSSALAM = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Malay (Brunei Darassalam) */ + APP_USBD_SUBLANG_NEPALI_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Nepali (India) */ + APP_USBD_SUBLANG_NORWEGIAN_BOKMAL = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Norwegian (Bokmal) */ + APP_USBD_SUBLANG_NORWEGIAN_NYNORSK = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Norwegian (Nynorsk) */ + APP_USBD_SUBLANG_PORTUGUESE = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Portuguese (Brazilian) */ + APP_USBD_SUBLANG_PORTUGUESE_BRAZILIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Portuguese */ + APP_USBD_SUBLANG_SERBIAN_LATIN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Serbian (Latin) */ + APP_USBD_SUBLANG_SERBIAN_CYRILLIC = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Serbian (Cyrillic) */ + APP_USBD_SUBLANG_SPANISH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Castilian) */ + APP_USBD_SUBLANG_SPANISH_MEXICAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Mexican) */ + APP_USBD_SUBLANG_SPANISH_MODERN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Modern) */ + APP_USBD_SUBLANG_SPANISH_GUATEMALA = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Guatemala) */ + APP_USBD_SUBLANG_SPANISH_COSTA_RICA = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Costa Rica) */ + APP_USBD_SUBLANG_SPANISH_PANAMA = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Panama) */ + APP_USBD_SUBLANG_SPANISH_DOMINICAN_REPUBLIC = 0x07U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Dominican Republic) */ + APP_USBD_SUBLANG_SPANISH_VENEZUELA = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Venezuela) */ + APP_USBD_SUBLANG_SPANISH_COLOMBIA = 0x09U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Colombia) */ + APP_USBD_SUBLANG_SPANISH_PERU = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Peru) */ + APP_USBD_SUBLANG_SPANISH_ARGENTINA = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Argentina) */ + APP_USBD_SUBLANG_SPANISH_ECUADOR = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Ecuador) */ + APP_USBD_SUBLANG_SPANISH_CHILE = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Chile) */ + APP_USBD_SUBLANG_SPANISH_URUGUAY = 0x0eU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Uruguay) */ + APP_USBD_SUBLANG_SPANISH_PARAGUAY = 0x0fU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Paraguay) */ + APP_USBD_SUBLANG_SPANISH_BOLIVIA = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Bolivia) */ + APP_USBD_SUBLANG_SPANISH_EL_SALVADOR = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Spanish (El Salvador) */ + APP_USBD_SUBLANG_SPANISH_HONDURAS = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Honduras) */ + APP_USBD_SUBLANG_SPANISH_NICARAGUA = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Nicaragua) */ + APP_USBD_SUBLANG_SPANISH_PUERTO_RICO = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Puerto Rico) */ + APP_USBD_SUBLANG_SWEDISH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Swedish */ + APP_USBD_SUBLANG_SWEDISH_FINLAND = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Swedish (Finland) */ + APP_USBD_SUBLANG_URDU_PAKISTAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Urdu (Pakistan) */ + APP_USBD_SUBLANG_URDU_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Urdu (India) */ + APP_USBD_SUBLANG_UZBEK_LATIN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Uzbek (Latin) */ + APP_USBD_SUBLANG_UZBEK_CYRILLIC = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Uzbek (Cyrillic) */ + APP_USBD_SUBLANG_HID_USAGE_DATA_DESCRIPTOR = 0x01U << ( APP_USB_LANG_OFFSET ), /**< HID (Usage Data Descriptor) */ + APP_USBD_SUBLANG_HID_VENDOR_DEFINED_1 = 0x3cU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 1) */ + APP_USBD_SUBLANG_HID_VENDOR_DEFINED_2 = 0x3dU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 2) */ + APP_USBD_SUBLANG_HID_VENDOR_DEFINED_3 = 0x3eU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 3) */ + APP_USBD_SUBLANG_HID_VENDOR_DEFINED_4 = 0x3fU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 4) */ +}app_usbd_langid_sub_t; + +/** + * @brief LANGID variable + * + * The LANGID value is composed from: + * - 10-bit (9-0) of Primary Language Identifiers + * - 6-bit (15-10) of Sublanguage Identifiers. + * + * @sa app_usbd_langid_primary_t + * @sa app_usbd_langid_sub_t + */ +typedef uint16_t app_usbd_langid_t; + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_LANGID_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_request.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_request.h new file mode 100644 index 0000000000000000000000000000000000000000..4325d0d326ead96f9c935ac71ba9b9378f3ca794 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_request.h @@ -0,0 +1,355 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef APP_USBD_REQUEST_H__ +#define APP_USBD_REQUEST_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sdk_common.h" +#include "nrf.h" +#include "nrf_drv_usbd.h" +#include "app_usbd_descriptor.h" +#include "app_util_platform.h" + +/* Compiler support for anonymous unions */ +ANON_UNIONS_ENABLE + +#pragma pack(push, 1) + +/** + * @defgroup app_usbd_request USB standard requests + * @ingroup app_usbd + * + * @brief @tagAPI52840 Module with types definitions used for standard requests processing. + * @{ + */ + +/** + * @brief Recipient bit-field in request type + * + * Bits 4...0 + */ +#define APP_USBD_SETUP_REQ_BF_REC BF_CX(5, 0) + +/** + * @brief Type bit-field in request type + * + * Bits 6...5 + */ +#define APP_USBD_SETUP_REQ_BF_TYP BF_CX(2, 5) + +/** + * @brief Direction bit-field in request type + * + * Bit 7 + */ +#define APP_USBD_SETUP_REQ_BF_DIR BF_CX(1, 7) + +/** + * @brief Recipient enumerator. + * + * @note It is part of @ref app_usbd_setup_reqtype_t variable type. + */ +typedef enum { + APP_USBD_SETUP_REQREC_DEVICE = 0x0, /**< The whole device is a request target */ + APP_USBD_SETUP_REQREC_INTERFACE = 0x1, /**< Selected interface is a request target */ + APP_USBD_SETUP_REQREC_ENDPOINT = 0x2, /**< Selected endpoint is a request target */ + APP_USBD_SETUP_REQREC_OTHER = 0x3 /**< Other element is a request target */ +} app_usbd_setup_reqrec_t; + +/** + * @brief Request type enumerator. + * + * @note It is part of @ref app_usbd_setup_reqtype_t variable type. + */ +typedef enum { + APP_USBD_SETUP_REQTYPE_STD = 0x0, /**< Standard request */ + APP_USBD_SETUP_REQTYPE_CLASS = 0x1, /**< Class specific request */ + APP_USBD_SETUP_REQTYPE_VENDOR = 0x2 /**< Vendor specific request */ +} app_usbd_setup_reqtype_t; + +/** + * @brief Direction of setup command + * + * @note It is part of @ref app_usbd_setup_reqtype_t variable type. + */ +typedef enum { + APP_USBD_SETUP_REQDIR_OUT = 0x0, /**< Host to device */ + APP_USBD_SETUP_REQDIR_IN = 0x1, /**< Device to host */ +} app_usbd_setup_reqdir_t; + + +/** + * @brief Standard requests + * + * Enumerator for standard requests values + */ +typedef enum { + APP_USBD_SETUP_STDREQ_GET_STATUS = 0x00, /**< + * Targets: Device, Interface, Endpoint + * Expected SETUP frame format: + * - wValue: Zero + * - wIndex: Zero, (lb): Interface or Endpoint + * - wLength: 2 + * - Data:2 bytes of data, depending on targets + * - Device: + * - D15..D2: Reserved (Reset to zero) + * - D1: Remove Wakeup + * - D0: Self Powered + * - Interface: + * - D15..D0: Reserved (Reset to zero) + * - Endpoint: + * - D15..D1: Reserved (Reset to zero) + * - D0: Halt + */ + APP_USBD_SETUP_STDREQ_CLEAR_FEATURE = 0x01, /**< + * Targets: Device, Interface, Endpoint + * Expected SETUP frame format: + * - wValue: Feature selector (@ref app_usbd_setup_stdfeature_t) + * - wIndex: Zero, Interface or Endpoint + * - wLength: 0 + * - Data: None + */ + APP_USBD_SETUP_STDREQ_SET_FEATURE = 0x03, /**< + * Targets: Device, Interface, Endpoint + * Expected SETUP frame format: + * - wValue: Feature selector (@ref app_usbd_setup_stdfeature_t) + * - wIndex: Zero, Interface or Endpoint + * - wLength: 0 + * - Data: None + */ + APP_USBD_SETUP_STDREQ_SET_ADDRESS = 0x05, /**< + * @note This SETUP request is processed in hardware. + * Use it only to mark current USB state. + * + * Targets: Device + * Expected SETUP frame format: + * - wValue: New device address + * - wIndex: 0 + * - wLength: 0 + * - Data: None + */ + APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR = 0x06, /**< + * Targets: Device + * - wValue: (hb): Descriptor Type and (lb): Descriptor Index + * - wIndex: Zero of Language ID + * - wLength: Descriptor Length + * - Data: Descriptor + */ + APP_USBD_SETUP_STDREQ_SET_DESCRIPTOR = 0x07, /**< + * Not supported - Stall when called. + */ + APP_USBD_SETUP_STDREQ_GET_CONFIGURATION = 0x08, /**< + * Target: Device + * Expected SETUP frame format: + * - wValue: 0 + * - wIndex: 0 + * - wLength: 1 + * - Data: Configuration value + */ + APP_USBD_SETUP_STDREQ_SET_CONFIGURATION = 0x09, /**< + * Target: Device + * Expected SETUP frame format: + * - wValue: (lb): Configuration value + * - wIndex: 0 + * - wLength: 0 + * - Data: None + */ + APP_USBD_SETUP_STDREQ_GET_INTERFACE = 0x0A, /**< + * Target: Interface + * Expected SETUP frame format: + * - wValue: 0 + * - wIndex: Interface + * - wLength: 1 + * - Data: Alternate setting + */ + APP_USBD_SETUP_STDREQ_SET_INTERFACE = 0x0B, /**< + * Target: Interface + * Expected SETUP frame format: + * - wValue: Alternate setting + * - wIndex: Interface + * - wLength: 0 + * - Data: None + */ + APP_USBD_SETUP_STDREQ_SYNCH_FRAME = 0x0C /**< + * Target: Endpoint + * Expected SETUP frame format: + * - wValue: 0 + * - wIndex: Endpoint + * - wLength: 2 + * - Data: Frame Number + * + * @note + * This request is used only in connection with isochronous endpoints. + * This is rarely used and probably we would not need to support it. + */ +} app_usbd_setup_stdrequest_t; + +/** + * @brief Standard feature selectors + * + * Standard features that may be disabled or enabled by + * @ref APP_USBD_SETUP_STDREQ_CLEAR_FEATURE or @ref APP_USBD_SETUP_STDREQ_SET_FEATURE + */ +typedef enum { + APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP = 1, /**< Remote wakeup feature. + * + * Target: Device only + */ + APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT = 0, /**< Stall or clear the endpoint. + * + * Target: Endpoint different than default (0) + */ + APP_USBD_SETUP_STDFEATURE_TEST_MODE = 2 /**< Upstream port test mode. + * Power has to be cycled to exit test mode. + * This feature cannot be cleared. + * + * Target: Device only + * + * @note + * It should only be supported by HighSpeed capable devices. + * Not supported in this library. + */ +} app_usbd_setup_stdfeature_t; + + +/** + * @brief Universal way to access 16 bit values and its parts + */ +typedef union { + uint16_t w; //!< 16 bit access + struct + { + uint8_t lb; //!< Low byte access + uint8_t hb; //!< High byte access + }; +} app_usbd_setup_w_t; + +/** + * @brief Internal redefinition of setup structure + * + * Redefinition of the structure to simplify changes in the future + * if required - app_usbd API would present setup data using app_usbd_setup_t. + * + * The structure layout is always the same like @ref nrf_drv_usbd_setup_t + */ +typedef struct { + uint8_t bmRequestType; //!< Setup type bitfield + uint8_t bmRequest; //!< One of @ref app_usbd_setup_stdrequest_t values or class dependent one. + app_usbd_setup_w_t wValue; //!< byte 2, 3 + app_usbd_setup_w_t wIndex; //!< byte 4, 5 + app_usbd_setup_w_t wLength; //!< byte 6, 7 +} app_usbd_setup_t; + +#pragma pack(pop) + + +/** + * @brief Extract recipient from request type + * + * @param[in] bmRequestType + * + * @return Extracted recipient field from request type value + */ +static inline app_usbd_setup_reqrec_t app_usbd_setup_req_rec(uint8_t bmRequestType) +{ + return (app_usbd_setup_reqrec_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_REC); +} + +/** + * @brief Extract type from request type + * + * @param[in] bmRequestType + * + * @return Extracted type field from request type value + */ +static inline app_usbd_setup_reqtype_t app_usbd_setup_req_typ(uint8_t bmRequestType) +{ + return (app_usbd_setup_reqtype_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_TYP); +} + + +/** + * @brief Extract direction from request type + * + * @param[in] bmRequestType + * + * @return Extracted direction field from request type value + */ +static inline app_usbd_setup_reqdir_t app_usbd_setup_req_dir(uint8_t bmRequestType) +{ + return (app_usbd_setup_reqdir_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_DIR); +} + +/** + * @brief Make request type value + * + * @param[in] rec Recipient + * @param[in] typ Request type + * @param[in] dir Direction + * + * @return Assembled request type value + */ +static inline uint8_t app_usbd_setup_req_val(app_usbd_setup_reqrec_t rec, + app_usbd_setup_reqtype_t typ, + app_usbd_setup_reqdir_t dir) +{ + uint32_t bmRequestType = ( + BF_CX_VAL(rec, APP_USBD_SETUP_REQ_BF_REC) | + BF_CX_VAL(typ, APP_USBD_SETUP_REQ_BF_TYP) | + BF_CX_VAL(dir, APP_USBD_SETUP_REQ_BF_DIR) + ); + + ASSERT(bmRequestType < 256U); + return (uint8_t)bmRequestType; +} + + +ANON_UNIONS_DISABLE +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_REQUEST_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_string_desc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_string_desc.c new file mode 100644 index 0000000000000000000000000000000000000000..f9fad43e221b7302a0e758da9767ec95d8a90dd1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_string_desc.c @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_ENABLED +#include "app_usbd_string_desc.h" +#include "app_usbd_langid.h" +#include "app_usbd_core.h" +#include "nordic_common.h" + +/** + * @defgroup app_usbd_string_desc + * @ingroup app_usbd + * + * USBD string descriptors management + * @{ + */ + +/** + * @brief Array with language identifiers + * + * This array would be used to search the proper string for selected language. + */ +static const uint16_t m_langids[] = { APP_USBD_STRINGS_LANGIDS }; + +/** + * @brief Language ID descriptor + * + * Language + */ + + +/** + * @brief Mnemonics for the string positions in the array + * + * The mnemonics for the indexes of the strings inside the string array. + */ +enum { + APP_USBD_STRING_ID_LANGIDS_ARRAY_POS = 0, /**< Supported language identifiers */ + APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS, /**< Manufacturer name */ + APP_USBD_STRING_ID_PRODUCT_ARRAY_POS, /**< Product name */ + APP_USBD_STRING_ID_SERIAL_ARRAY_POS, /**< Serial number */ +#define X(mnemonic, str_idx, ...) CONCAT_2(mnemonic, _ARRAY_POS), + APP_USBD_STRINGS_USER +#undef X +}; + +/** + * @brief String index into internal array index conversion table + * + * The array that transforms the USB string indexes into internal array position. + * @note Value 0 used to mark non-existing string. + */ +static const uint8_t m_string_translation[APP_USBD_STRING_ID_CNT] = +{ + [APP_USBD_STRING_ID_LANGIDS ] = APP_USBD_STRING_ID_LANGIDS_ARRAY_POS, + [APP_USBD_STRING_ID_MANUFACTURER] = APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS, + [APP_USBD_STRING_ID_PRODUCT ] = APP_USBD_STRING_ID_PRODUCT_ARRAY_POS, + [APP_USBD_STRING_ID_SERIAL ] = APP_USBD_STRING_ID_SERIAL_ARRAY_POS, +#define X(mnemonic, str_idx, ...) [mnemonic] = CONCAT_2(mnemonic, _ARRAY_POS), + APP_USBD_STRINGS_USER +#undef X +}; + +#ifndef APP_USBD_STRINGS_MANUFACTURER_EXTERN +#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0 +#endif + +#ifndef APP_USBD_STRINGS_PRODUCT_EXTERN +#define APP_USBD_STRINGS_PRODUCT_EXTERN 0 +#endif + +#ifndef APP_USBD_STRING_SERIAL_EXTERN +#define APP_USBD_STRING_SERIAL_EXTERN 0 +#endif + +#if APP_USBD_STRINGS_MANUFACTURER_EXTERN +extern uint16_t APP_USBD_STRINGS_MANUFACTURER[]; +#endif + +#if APP_USBD_STRINGS_PRODUCT_EXTERN +extern uint16_t APP_USBD_STRINGS_PRODUCT[]; +#endif + +#if APP_USBD_STRING_SERIAL_EXTERN +extern uint16_t APP_USBD_STRING_SERIAL[]; +#endif + + +/** + * @brief String descriptors table + * */ +static const uint16_t * m_string_dsc[APP_USBD_STRING_ID_CNT][ARRAY_SIZE(m_langids)] = +{ + [APP_USBD_STRING_ID_LANGIDS_ARRAY_POS] = { APP_USBD_STRING_DESC(APP_USBD_STRINGS_LANGIDS) }, + [APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS] = { APP_USBD_STRINGS_MANUFACTURER }, + [APP_USBD_STRING_ID_PRODUCT_ARRAY_POS] = { APP_USBD_STRINGS_PRODUCT }, + [APP_USBD_STRING_ID_SERIAL_ARRAY_POS] = { APP_USBD_STRING_SERIAL }, +#define X(mnemonic, str_idx, ...) [CONCAT_2(mnemonic, _ARRAY_POS)] = { __VA_ARGS__ }, + APP_USBD_STRINGS_USER +#undef X +}; + + + +uint16_t const * app_usbd_string_desc_get(app_usbd_string_desc_idx_t idx, uint16_t langid) +{ + /* LANGID string */ + if (APP_USBD_STRING_ID_LANGIDS == idx) + { + return m_string_dsc[APP_USBD_STRING_ID_LANGIDS_ARRAY_POS][0]; + } + + /* Searching for the language */ + uint8_t lang_idx = 0; + if (ARRAY_SIZE(m_langids) > 1) + { + while(m_langids[lang_idx] != langid) + { + if(++lang_idx >= ARRAY_SIZE(m_langids)) + { + return NULL; + } + } + } + + /* Get the string index in array */ + if (idx >= ARRAY_SIZE(m_string_translation)) + { + return NULL; + } + + uint8_t str_pos = m_string_translation[idx]; + if (str_pos == 0) + { + return NULL; + } + + uint16_t const * p_str = m_string_dsc[str_pos][lang_idx]; + if ((ARRAY_SIZE(m_langids) > 1) && (lang_idx != 0)) + { + if (p_str == NULL) + { + p_str = m_string_dsc[str_pos][0]; + } + } + + return p_str; +} + +/** @} */ +#endif // APP_USBD_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_string_desc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_string_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..8a633f98de6694fb5126bd24154cd57826ede0c3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_string_desc.h @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_STRING_DESC_H__ +#define APP_USBD_STRING_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "sdk_common.h" +#include "app_usbd.h" +#include "app_usbd_string_config.h" + +/** + * @defgroup app_usbd_string_desc USBD string descriptors + * @ingroup app_usbd + * + * @brief @tagAPI52840 USBD string descriptors management. + * @{ + */ + +/** + * @brief USB string initialization + * + * Macro that creates initialization values for USB string. + * The format contains header and string itself. + * The string should be declared as an array of uint16_t type. + * + * @param[in] ... Comma separated string letters or language ID. + * @return String descriptor initialization data. + */ +#define APP_USBD_STRING_DESC(...) (const uint16_t[]){ \ + (0xff & (sizeof((uint16_t[]){__VA_ARGS__}) + 2)) | \ + ((uint16_t)APP_USBD_DESCRIPTOR_STRING) << 8, \ + __VA_ARGS__ } + +/** + * @brief USB string descriptors ID's + */ +typedef enum { + APP_USBD_STRING_ID_LANGIDS = 0, /**< Supported language identifiers */ + APP_USBD_STRING_ID_MANUFACTURER, /**< Manufacturer name */ + APP_USBD_STRING_ID_PRODUCT, /**< Product name */ + APP_USBD_STRING_ID_SERIAL, /**< Serial number */ + +#define X(mnemonic, str_idx, ...) mnemonic str_idx, + APP_USBD_STRINGS_USER +#undef X + + APP_USBD_STRING_ID_CNT /**< Total number of identifiers */ +} app_usbd_string_desc_idx_t; + +/** + * @brief Get string descriptor + * + * @param[in] idx String descriptor index + * @param[in] langid Selected language for the string + * @return String descriptor or NULL if not exist + * */ +uint16_t const * app_usbd_string_desc_get(app_usbd_string_desc_idx_t idx, uint16_t langid); + +/** + * @brief Get string length + * + * Function to get string length from descriptor (descriptor returned by @ref app_usbd_string_desc_get) + * + * @param[in] p_str String descriptor pointer + * @return Total descriptor length in bytes + */ +static inline size_t app_usbd_string_desc_length(uint16_t const * p_str) +{ + return ((const app_usbd_descriptor_string_t *)p_str)->bLength; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_STRING_DESC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_types.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_types.h new file mode 100644 index 0000000000000000000000000000000000000000..11d89dcdd24e0c0ba08a7620f474b0e594f80e03 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/app_usbd_types.h @@ -0,0 +1,175 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef APP_USBD_TYPES_H__ +#define APP_USBD_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "sdk_errors.h" +#include "nrf_drv_usbd.h" +#include "app_usbd_request.h" + +/** + * @defgroup app_usbd_types USB Device high level library variable types definition + * @ingroup app_usbd + * + * @brief @tagAPI52840 All types used by @ref app_usbd are defined here. + * This helps to avoid cross referencing into types in different files. + * @{ + */ + +/** + * @brief Events codes + * + * Redefined application event codes + */ +typedef enum +{ + APP_USBD_EVT_DRV_SOF = NRF_DRV_USBD_EVT_SOF, /**< See documentation for @ref NRF_DRV_USBD_EVT_SOF */ + APP_USBD_EVT_DRV_RESET = NRF_DRV_USBD_EVT_RESET, /**< See documentation for @ref NRF_DRV_USBD_EVT_RESET */ + APP_USBD_EVT_DRV_SUSPEND = NRF_DRV_USBD_EVT_SUSPEND, /**< See documentation for @ref NRF_DRV_USBD_EVT_SUSPEND */ + APP_USBD_EVT_DRV_RESUME = NRF_DRV_USBD_EVT_RESUME, /**< See documentation for @ref NRF_DRV_USBD_EVT_RESUME */ + APP_USBD_EVT_DRV_SETUP = NRF_DRV_USBD_EVT_SETUP, /**< This event type has special structure. See @ref app_usbd_setup_evt_t */ + APP_USBD_EVT_DRV_EPTRANSFER = NRF_DRV_USBD_EVT_EPTRANSFER, /**< See documentation for @ref NRF_DRV_USBD_EVT_EPTRANSFER */ + + APP_USBD_EVT_FIRST_APP, /**< First application event code - for internal static assert checking */ + + APP_USBD_EVT_INST_APPEND = APP_USBD_EVT_FIRST_APP, /**< The instance was attached to the library, any configuration action can be done now */ + APP_USBD_EVT_INST_REMOVE, /**< The instance is going to be removed, this event is called just before removing the instance. + * This removing cannot be stopped. */ + APP_USBD_EVT_START, /**< USBD library has just been started and functional - event passed to all instances, before USBD interrupts have been enabled */ + APP_USBD_EVT_STOP, /**< USBD library has just been stopped and is not functional - event passed to all instances, after USBD interrupts have been disabled*/ + APP_USBD_EVT_STATE /**< USBD state has been changed */ +} app_usbd_event_type_t; + +/** + * @brief Specific application event structure + * + * All the data required by the events that comes from the application level + */ +typedef struct +{ + app_usbd_event_type_t type; //!< Event type +} app_usbd_evt_t; + +/** + * @brief Specific application event structure with setup structure included + * + * This event structure would be used when @ref APP_USBD_EVT_DRV_SETUP + * is passed to instance event handler + */ +typedef struct +{ + app_usbd_event_type_t type; //!< Event type + app_usbd_setup_t setup; //!< Setup structure +} app_usbd_setup_evt_t; + + +/** + * @brief Complex event variable type + * + * A variable that can store any kind of event. + */ +typedef union +{ + app_usbd_event_type_t type; //!< Event type + nrf_drv_usbd_evt_t drv_evt; //!< Events that comes directly from the driver. + /**< Use this event structure only for event + * type < @ref APP_USBD_EVT_FIRST_APP + */ + app_usbd_setup_evt_t setup_evt; //!< Event structure with SETUP structure included. + /**< This structure is used in connection with + * @ref APP_USBD_EVT_DRV_SETUP + */ + app_usbd_evt_t app_evt; //!< Events that comes from the application driver. + /**< Use this event structure only for event + * type >= @ref APP_USBD_EVT_FIRST_APP + */ + +} app_usbd_complex_evt_t; + + +#ifdef DOXYGEN +/** + * @brief Base instance of a USBD class + * + * Any USBD class instance have to begin with this instance. + * This may then be followed by any implementation dependent data. + * + * For an instance it should be possible to put whole structure into FLASH. + * + * @note This type is early defined as incomplete type. + * This is required for function declaration that takes the pointer + * to this structure but in second hand - it is also placed inside + * the instance structure. + * @note The structure is defined in @file app_usbd_class_base.h. + */ +typedef struct {} app_usbd_class_inst_t; +#else +typedef struct app_usbd_class_inst_s app_usbd_class_inst_t; +#endif +/** + * @brief Endpoint callback function + * + * The function used by every class instance. + * @param[in,out] p_inst Instance of the class + * @param[in] p_event Event to process + * + * @note If given event is not supported by class, return @ref NRF_ERROR_NOT_SUPPORTED + */ +typedef ret_code_t (*app_usbd_ep_event_handler_t)( + app_usbd_class_inst_t const * const p_inst, + app_usbd_complex_evt_t const * const p_event + ); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_TYPES_H__ */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio.c new file mode 100644 index 0000000000000000000000000000000000000000..03c6bb72fd9fe4cbfba0d0446ad56982e66c5075 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio.c @@ -0,0 +1,594 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_CLASS_AUDIO_ENABLED +#include "app_usbd_audio.h" +#include "app_util_platform.h" + +/** + * @defgroup app_usbd_audio_internals USBD Audio internals + * @{ + * @ingroup app_usbd_audio + * @internal + */ + +STATIC_ASSERT(sizeof(app_usbd_audio_ac_iface_header_desc_t) == 8); +STATIC_ASSERT(sizeof(app_usbd_audio_input_terminal_desc_t) == 12); +STATIC_ASSERT(sizeof(app_usbd_audio_output_terminal_desc_t) == 9); +STATIC_ASSERT(sizeof(app_usbd_audio_feature_unit_desc_t) == 6); +STATIC_ASSERT(sizeof(app_usbd_audio_as_iface_desc_t) == 7); +STATIC_ASSERT(sizeof(app_usbd_audio_as_format_type_one_desc_t) == 8); +STATIC_ASSERT(sizeof(app_usbd_audio_as_format_type_two_desc_t) == 9); +STATIC_ASSERT(sizeof(app_usbd_audio_as_format_type_three_desc_t) == 8); +STATIC_ASSERT(sizeof(app_usbd_audio_as_endpoint_desc_t) == 7); + +#define APP_USBD_AUDIO_CONTROL_IFACE_IDX 0 /**< Audio class control interface index */ +#define APP_USBD_AUDIO_STREAMING_IFACE_IDX 1 /**< Audio class streaming interface index */ + +#define APP_USBD_CDC_AUDIO_STREAMING_EP_IDX 0 /**< Audio streaming isochronous endpoint index */ + +/** + * @brief Auxiliary function to access audio class instance data + * + * @param[in] p_inst Class instance data + * @return Audio class instance data @ref app_usbd_audio_t + */ +static inline app_usbd_audio_t const * audio_get(app_usbd_class_inst_t const * p_inst) +{ + ASSERT(p_inst != NULL); + return (app_usbd_audio_t const *)p_inst; +} + +/** + * @brief Auxiliary function to access audio class context data + * + * @param[in] p_audio Audio class instance data + * @return Audio class context data @ref app_usbd_audio_ctx_t + */ +static inline app_usbd_audio_ctx_t * audio_ctx_get(app_usbd_audio_t const * p_audio) +{ + ASSERT(p_audio != NULL); + ASSERT(p_audio->specific.p_data != NULL); + return &p_audio->specific.p_data->ctx; +} + + +/** + * @brief User event handler + * + * @param[in] p_inst Class instance + * @param[in] event user Event type @ref app_usbd_audio_user_event_t + * */ +static inline void user_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_audio_user_event_t event) +{ + app_usbd_audio_t const * p_audio = audio_get(p_inst); + if (p_audio->specific.inst.user_ev_handler != NULL) + { + p_audio->specific.inst.user_ev_handler(p_inst, event); + } +} + +/** + * @brief Internal SETUP standard IN request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR: + { + size_t dsc_len = 0; + + /* Try to find descriptor in class internals*/ + void const * p_dsc = app_usbd_class_descriptor_find(p_inst, + p_setup_ev->setup.wValue.hb, + p_setup_ev->setup.wValue.lb, + &dsc_len); + if (p_dsc != NULL) + { + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_dsc, dsc_len); + } + + break; + } + case APP_USBD_SETUP_STDREQ_GET_INTERFACE: + { + + size_t tx_maxsize; + uint8_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_maxsize); + + p_tx_buff[0] = p_audio_ctx->streaming ? 1 : 0; + + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + p_tx_buff, + sizeof(uint8_t)); + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP standard OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_SET_INTERFACE: + { + uint8_t iface_count = app_usbd_class_iface_count_get(p_inst); + app_usbd_class_iface_conf_t const * p_iface = NULL; + for (uint8_t j = 0; j < iface_count; ++j) + { + p_iface = app_usbd_class_iface_get(p_inst, j); + if (p_iface->number == p_setup_ev->setup.wIndex.w) + { + break; + } + } + + if (p_iface == NULL) + { + break; + } + + p_audio_ctx->streaming = (p_iface->ep_cnt > 0) && + (p_setup_ev->setup.wValue.w == 1); + + return app_usbd_req_std_set_interface(p_inst, p_setup_ev); + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP class IN request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_AUDIO_REQ_GET_CUR: + case APP_USBD_AUDIO_REQ_GET_MIN: + case APP_USBD_AUDIO_REQ_GET_MAX: + case APP_USBD_AUDIO_REQ_SET_RES: + case APP_USBD_AUDIO_REQ_GET_MEM: + { + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + + + p_audio_ctx->request.req_type = (app_usbd_audio_req_type_t)p_setup_ev->setup.bmRequest; + p_audio_ctx->request.control = p_setup_ev->setup.wValue.hb; + p_audio_ctx->request.channel = p_setup_ev->setup.wValue.lb; + p_audio_ctx->request.interface = p_setup_ev->setup.wIndex.hb; + p_audio_ctx->request.entity = p_setup_ev->setup.wIndex.lb; + + p_audio_ctx->request.length = p_setup_ev->setup.wLength.w; + + p_audio_ctx->request.req_target = APP_USBD_AUDIO_CLASS_REQ_IN; + + app_usbd_setup_reqrec_t rec = app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType); + if (rec == APP_USBD_SETUP_REQREC_ENDPOINT) + { + p_audio_ctx->request.req_target = APP_USBD_AUDIO_EP_REQ_IN; + } + + user_event_handler((app_usbd_class_inst_t const *)p_audio, + APP_USBD_AUDIO_USER_EVT_CLASS_REQ); + + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + p_audio_ctx->request.payload, + p_audio_ctx->request.length); + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +static ret_code_t audio_req_out_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context) +{ + if(status == NRF_USBD_EP_OK) + { + app_usbd_audio_t const * p_audio = p_context; + + user_event_handler((app_usbd_class_inst_t const *)p_audio, + APP_USBD_AUDIO_USER_EVT_CLASS_REQ); + } + + return NRF_SUCCESS; +} + +static ret_code_t audio_req_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + + + p_audio_ctx->request.req_type = (app_usbd_audio_req_type_t)p_setup_ev->setup.bmRequest; + p_audio_ctx->request.control = p_setup_ev->setup.wValue.hb; + p_audio_ctx->request.channel = p_setup_ev->setup.wValue.lb; + p_audio_ctx->request.interface = p_setup_ev->setup.wIndex.hb; + p_audio_ctx->request.entity = p_setup_ev->setup.wIndex.lb; + + p_audio_ctx->request.length = p_setup_ev->setup.wLength.w; + + p_audio_ctx->request.req_target = APP_USBD_AUDIO_CLASS_REQ_OUT; + if (app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_ENDPOINT) + { + p_audio_ctx->request.req_target = APP_USBD_AUDIO_EP_REQ_OUT; + } + + /*Request setup data*/ + NRF_DRV_USBD_TRANSFER_OUT(transfer, p_audio_ctx->request.payload, p_audio_ctx->request.length); + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_setup_data_transfer(NRF_DRV_USBD_EPOUT0, &transfer); + if (ret == NRF_SUCCESS) + { + app_usbd_core_setup_data_handler_desc_t desc = { + .handler = audio_req_out_data_cb, + .p_context = (void*)p_audio + }; + + ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +/** + * @brief Internal SETUP class OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_AUDIO_REQ_SET_CUR: + case APP_USBD_AUDIO_REQ_SET_MIN: + case APP_USBD_AUDIO_REQ_SET_MAX: + case APP_USBD_AUDIO_REQ_SET_RES: + case APP_USBD_AUDIO_REQ_SET_MEM: + return audio_req_out(p_inst, p_setup_ev); + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Control endpoint handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + ASSERT(p_inst != NULL); + ASSERT(p_setup_ev != NULL); + + if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN) + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_in(p_inst, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_in(p_inst, p_setup_ev); + default: + break; + } + } + else /*APP_USBD_SETUP_REQDIR_OUT*/ + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_out(p_inst, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_out(p_inst, p_setup_ev); + default: + break; + } + } + + return NRF_ERROR_NOT_SUPPORTED; +} + + +/** + * @brief Endpoint IN event handler + * + * @param[in] p_inst Generic class instance + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t endpoint_in_event_handler(app_usbd_class_inst_t const * p_inst) +{ + user_event_handler(p_inst, APP_USBD_AUDIO_USER_EVT_TX_DONE); + return NRF_SUCCESS; +} + + +/** + * @brief Endpoint OUT event handler + * + * @param[in] p_inst Generic class instance + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t endpoint_out_event_handler(app_usbd_class_inst_t const * p_inst) +{ + user_event_handler(p_inst, APP_USBD_AUDIO_USER_EVT_RX_DONE); + return NRF_SUCCESS; +} + +/** +* @brief Auxiliary function to access isochronous endpoint address +* +* @param[in] p_inst Class instance data +* +* @return ISO endpoint address +*/ +static inline nrf_drv_usbd_ep_t ep_iso_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_AUDIO_STREAMING_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_AUDIO_STREAMING_EP_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +static ret_code_t sof_event_handler(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + + nrf_drv_usbd_ep_t ep_addr = ep_iso_addr_get(p_inst); + + if (app_usbd_core_state_get() != APP_USB_STATE_BASE(APP_USBD_STATE_Configured)) + { + return NRF_SUCCESS; + } + + if (!p_audio_ctx->streaming) + { + return NRF_SUCCESS; + } + + /*OUT transfers*/ + if (p_audio_ctx->rx_size && NRF_USBD_EPOUT_CHECK(ep_addr)) + { + + ASSERT(NRF_USBD_EPISO_CHECK(ep_addr)); + + uint32_t isoout = nrf_usbd_epout_size_get(ep_addr); + if (isoout) + { + ASSERT(isoout == p_audio_ctx->rx_size); + NRF_DRV_USBD_TRANSFER_OUT(transfer, p_audio_ctx->p_rx_buff, p_audio_ctx->rx_size); + return app_usbd_core_ep_transfer(ep_addr, &transfer); + } + } + + /*IN transfers*/ + if (p_audio_ctx->tx_size && NRF_USBD_EPIN_CHECK(ep_addr)) + { + ASSERT(NRF_USBD_EPISO_CHECK(ep_addr)); + NRF_DRV_USBD_TRANSFER_IN(transfer, p_audio_ctx->p_tx_buff, p_audio_ctx->tx_size); + return app_usbd_core_ep_transfer(ep_addr, &transfer); + } + + return NRF_SUCCESS; +} + + + + +/** + * @brief @ref app_usbd_class_methods_t::event_handler + */ +static ret_code_t audio_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + ASSERT(p_inst != NULL); + ASSERT(p_event != NULL); + + ret_code_t ret = NRF_SUCCESS; + switch (p_event->app_evt.type) + { + case APP_USBD_EVT_DRV_SOF: + ret = sof_event_handler(p_inst); + break; + case APP_USBD_EVT_DRV_RESET: + break; + case APP_USBD_EVT_DRV_SETUP: + ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event); + break; + case APP_USBD_EVT_DRV_EPTRANSFER: + if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep)) + { + ret = endpoint_in_event_handler(p_inst); + } + else + { + ret = endpoint_out_event_handler(p_inst); + } + break; + case APP_USBD_EVT_DRV_SUSPEND: + break; + case APP_USBD_EVT_DRV_RESUME: + break; + case APP_USBD_EVT_INST_APPEND: + { + ret = app_usbd_class_sof_register(p_inst); + break; + } + case APP_USBD_EVT_INST_REMOVE: + { + ret = app_usbd_class_sof_unregister(p_inst); + break; + } + case APP_USBD_EVT_START: + break; + case APP_USBD_EVT_STOP: + break; + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + return ret; +} + +/** + * @brief @ref app_usbd_class_methods_t::get_descriptors + */ +static const void * audio_get_descriptors(app_usbd_class_inst_t const * p_inst, + size_t * p_size) +{ + ASSERT(p_size != NULL); + app_usbd_audio_t const * p_audio = audio_get(p_inst); + + *p_size = p_audio->specific.inst.raw_desc_size; + return p_audio->specific.inst.p_raw_desc; +} + +/** @} */ + +const app_usbd_class_methods_t app_usbd_audio_class_methods = { + .event_handler = audio_event_handler, + .get_descriptors = audio_get_descriptors, +}; + +void app_usbd_audio_class_tx_buf_set(app_usbd_class_inst_t const * p_inst, + const void * p_buff, + size_t size) +{ + ASSERT(p_inst != NULL); + + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + CRITICAL_REGION_ENTER(); + + p_audio_ctx->p_tx_buff = p_buff; + p_audio_ctx->tx_size = size; + + CRITICAL_REGION_EXIT(); +} + +void app_usbd_audio_class_rx_buf_set(app_usbd_class_inst_t const * p_inst, + void * p_buff, + size_t size) +{ + ASSERT(p_inst != NULL); + + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + CRITICAL_REGION_ENTER(); + + p_audio_ctx->p_rx_buff = p_buff; + p_audio_ctx->rx_size = size; + + CRITICAL_REGION_EXIT(); +} + +#endif //APP_USBD_CLASS_AUDIO_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio.h new file mode 100644 index 0000000000000000000000000000000000000000..0f9463b428c40969a0a8cbcffe885e1fe2decd44 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio.h @@ -0,0 +1,202 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_AUDIO_H__ +#define APP_USBD_AUDIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "nrf_drv_usbd.h" +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_class_base.h" +#include "app_usbd_descriptor.h" + +#include "app_usbd_audio_types.h" +#include "app_usbd_audio_desc.h" +#include "app_usbd_audio_internal.h" + + +/** + * @defgroup app_usbd_audio USB AUDIO class + * @ingroup app_usbd + * + * @brief @tagAPI52840 Module with types, definitions, and API used by USB Audio class. + * + * @details Reference specifications: + * - "Universal Serial Bus Device Class Definition for Audio Devices" + * Release 1.0, March 18, 1998. + * - "Universal Serial Bus Device Class Definition for Audio Data Formats" + * Release 1.0, March 18, 1998. + * - "Universal Serial Bus Device Class Definition for Terminal Types" + * Release 1.0, March 18, 1998. + * + * @{ + */ + + +#ifdef DOXYGEN +/** + * @brief Audio class instance type + * + * @ref APP_USBD_CLASS_TYPEDEF + */ +typedef struct { } app_usbd_audio_t; +#else +/*lint -save -e10 -e26 -e123 -e505 */ +APP_USBD_CLASS_TYPEDEF(app_usbd_audio, \ + APP_USBD_AUDIO_CONFIG(0, 1), \ + APP_USBD_AUDIO_INSTANCE_SPECIFIC_DEC, \ + APP_USBD_AUDIO_DATA_SPECIFIC_DEC \ +); +/*lint -restore*/ +#endif + + +/*lint -save -e407 */ + +/** + * @brief Events passed to user event handler + * + * @note Example prototype of user event handler: + * + * @code + void audio_user_ev_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_audio_user_event_t event); + * @endcode + */ +typedef enum app_usbd_audio_user_event_e { + APP_USBD_AUDIO_USER_EVT_CLASS_REQ, /**< User event CLASS_REQ */ + APP_USBD_AUDIO_USER_EVT_RX_DONE, /**< User event RX_DONE */ + APP_USBD_AUDIO_USER_EVT_TX_DONE, /**< User event TX_DONE */ +} app_usbd_audio_user_event_t; + +/*lint -restore*/ + + +/** + * @brief Global definition of app_usbd_audio_t class instance + * + * @param instance_name Name of global instance + * @param interfaces_configs Interfaces configurations + * @param user_ev_handler User event handler (optional) + * @param raw_descriptors Raw descriptor table + * + * @note This macro is just simplified version of @ref APP_USBD_AUDIO_GLOBAL_DEF_INTERNAL + * + */ +#define APP_USBD_AUDIO_GLOBAL_DEF(instance_name, \ + interfaces_configs, \ + user_ev_handler, \ + raw_descriptors) \ + APP_USBD_AUDIO_GLOBAL_DEF_INTERNAL(instance_name, \ + interfaces_configs, \ + user_ev_handler, \ + raw_descriptors) + +/** + * @@brief Helper function to get class instance from Audio class + * + * @param[in] p_audio Audio class instance (declared by @ref APP_USBD_AUDIO_GLOBAL_DEF) + * @return Base class instance + */ +static inline app_usbd_class_inst_t const * +app_usbd_audio_class_inst_get(app_usbd_audio_t const * p_audio) +{ + return &p_audio->base; +} + +/** + * @brief Helper function to get audio specific request from audio class + * + * @param[in] p_audio Audio class instance (declared by @ref APP_USBD_AUDIO_GLOBAL_DEF) + * @return Audio class specific request + */ +static inline app_usbd_audio_req_t * +app_usbd_audio_class_request_get(app_usbd_audio_t const * p_audio) +{ + return &p_audio->specific.p_data->ctx.request; +} + +/** + * @brief Helper function to get audio from base class instance + * + * @param[in] p_inst Base class instance + * @return Audio class handle + */ +static inline app_usbd_audio_t const * +app_usbd_audio_class_get(app_usbd_class_inst_t const * p_inst) +{ + return (app_usbd_audio_t const *)p_inst; +} + +/** + * @brief Set transmit buffer + * + * @param[in] p_inst Base class instance + * @param[in] p_buff Transmit buffer + * @param[in] size Transmit buffer size + * */ +void app_usbd_audio_class_tx_buf_set(app_usbd_class_inst_t const * p_inst, + const void * p_buff, + size_t size); + +/** + * @brief Set receive buffer + * + * @param[in] p_inst Base class instance + * @param[in] p_buff Receive buffer + * @param[in] size Receive buffer size + * */ +void app_usbd_audio_class_rx_buf_set(app_usbd_class_inst_t const * p_inst, + void * p_buff, + size_t size); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_AUDIO_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio_desc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..7f2b18d23750a73a93cbed938f7de19c766476c1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio_desc.h @@ -0,0 +1,318 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_AUDIO_DESC_H__ +#define APP_USBD_AUDIO_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_usbd_descriptor.h" + +/** + * @defgroup app_usbd_audio_dsc USB Audio descriptors + * @brief @tagAPI52840 Descriptors used in the USB Audio class. + * @ingroup app_usbd_audio + * @{ + */ + +/** + * @brief Initializer of interface descriptor for AUDIO class + * + * @param interface_number Interface number + * @param alt_setting Interface alternate setting + * @param ep_num Number of endpoints + * @param subclass Audio subclass @ref app_usbd_audio_subclass_t + * */ +#define APP_USBD_AUDIO_INTERFACE_DSC(interface_number, alt_setting, ep_num, subclass) \ + /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \ + /*.bInterfaceNumber = */ (interface_number), \ + /*.bAlternateSetting = */ (alt_setting), \ + /*.bNumEndpoints = */ (ep_num), \ + /*.bInterfaceClass = */ APP_USBD_AUDIO_CLASS, \ + /*.bInterfaceSubClass = */ (subclass), \ + /*.bInterfaceProtocol = */ APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED, \ + /*.iInterface = 0, */ 0x00, \ + +/** + * @brief Initializer of isochronous endpoint descriptors for audio class + * + * @param ep ISO endpoint id: @ref NRF_DRV_USBD_EPIN8, @ref NRF_DRV_USBD_EPOUT8 + * @param ep_size Endpoint size (bytes) + * @param interval Endpoint interval (milliseconds) + * @param refresh Refresh value (usually 0) + * @param synch_addr Synch address (usually 0) + * */ +#define APP_USBD_AUDIO_ISO_EP_DSC(ep, ep_size, interval, refresh, synch_addr) \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t) + 2, \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ ep, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ (interval), \ + /*.bRefresh = */ (refresh), \ + /*.bInterval = */ (synch_addr), \ + +/** + * @brief Simplified version of @ref APP_USBD_AUDIO_ISO_EP_DSC for ISO IN endpoint + */ +#define APP_USBD_AUDIO_ISO_EP_IN_DSC(ep_size) \ + APP_USBD_AUDIO_ISO_EP_DSC(NRF_DRV_USBD_EPIN8, ep_size, 1, 0, 0) + +/** + * @brief Simplified version of @ref APP_USBD_AUDIO_ISO_EP_DSC for ISO OUT endpoint + */ +#define APP_USBD_AUDIO_ISO_EP_OUT_DSC(ep_size) \ + APP_USBD_AUDIO_ISO_EP_DSC(NRF_DRV_USBD_EPOUT8, ep_size, 1, 0, 0) + +/** + * @brief Initializer of @ref app_usbd_audio_ac_iface_header_desc_t + * + * @param descriptor_list Descriptor list following audio interface header descriptor + * @param ... List of interfaces following audio control interface + * */ +#define APP_USBD_AUDIO_AC_IFACE_HEADER_DSC(descriptor_list, ...) \ + /*.bLength = */ sizeof(app_usbd_audio_ac_iface_header_desc_t) + \ + (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER, \ + /*.bcdADC = */ APP_USBD_U16_TO_RAW_DSC(0x0100), \ + /*.wTotalLength = */ APP_USBD_U16_TO_RAW_DSC( \ + sizeof((uint8_t[]){BRACKET_EXTRACT(descriptor_list)}) + \ + sizeof(app_usbd_audio_ac_iface_header_desc_t) + \ + (NUM_VA_ARGS(__VA_ARGS__))), \ + /*.bInCollection = */ (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.baInterfaceNr[] = */ __VA_ARGS__, \ + + +/** + * @brief Initializer of @ref app_usbd_audio_input_terminal_desc_t + * + * @param terminal_id Terminal ID + * @param terminal_type Terminal type @ref app_usbd_audio_terminal_type_t + * @param nr_channels Number of channels + * @param ch_config CHannel config bitmask + * */ +#define APP_USBD_AUDIO_INPUT_TERMINAL_DSC(terminal_id, terminal_type, nr_channels, ch_config) \ + /*.bLength = */ sizeof(app_usbd_audio_input_terminal_desc_t), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL, \ + /*.bTerminalID = */ (terminal_id), \ + /*.wTerminalType = */ APP_USBD_U16_TO_RAW_DSC(terminal_type), \ + /*.bAssocTerminal = */ 0, \ + /*.bNrChannels = */ (nr_channels), \ + /*.wChannelConfig = */ APP_USBD_U16_TO_RAW_DSC(ch_config), \ + /*.iChannelNames = */ 0, \ + /*.iTerminal = */ 0, \ + + +/** + * @brief Initializer of @ref app_usbd_audio_output_terminal_desc_t + * + * @param terminal_id Terminal ID + * @param terminal_type Terminal type @ref app_usbd_audio_terminal_type_t + * @param source_id Source ID + * */ +#define APP_USBD_AUDIO_OUTPUT_TERMINAL_DSC(terminal_id, terminal_type, source_id) \ + /*.bLength = */ sizeof(app_usbd_audio_output_terminal_desc_t), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL, \ + /*.bTerminalID = */ (terminal_id), \ + /*.wTerminalType = */ APP_USBD_U16_TO_RAW_DSC(terminal_type), \ + /*.bAssocTerminal = */ 0, \ + /*.bSourceID = */ (source_id), \ + /*.iTerminal = */ 0, \ + + +/** + * @brief Initializer of @ref app_usbd_audio_feature_unit_desc_t + * + * @param unit_id Unit ID + * @param source_id Source ID + * @param ... List of controls + * */ +#define APP_USBD_AUDIO_FEATURE_UNIT_DSC(unit_id, source_id, ...) \ + /*.bLength = */ sizeof(app_usbd_audio_feature_unit_desc_t) + \ + 1 + (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT, \ + /*.bUnitID = */ (unit_id), \ + /*.bSourceID = */ (source_id), \ + /*.bControlSize = */ sizeof(uint16_t), \ + /*.bmaControls[] = */ __VA_ARGS__, \ + /*.iFeature = */ 0, \ + + +/** + * @brief Initializer of @ref app_usbd_audio_as_iface_desc_t + * + * @param terminal_link Terminal link + * @param delay Delay + * @param format_tag Format TAG + * */ +#define APP_USBD_AUDIO_AS_IFACE_DSC(terminal_link, delay, format_tag) \ + /*.bLength = */ sizeof(app_usbd_audio_as_iface_desc_t), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_GENERAL, \ + /*.bTerminalLink = */ (terminal_link), \ + /*.bDelay = */ (delay), \ + /*.wFormatTag = */ APP_USBD_U16_TO_RAW_DSC(format_tag), \ + +/** + * @brief Initializer of @ref app_usbd_audio_as_format_type_one_desc_t + * + * @param nr_channels Number of channels + * @param subframe_size Subframe size + * @param resolution Bit resolution + * @param freq_type Frequency type + * @param ... List of frequencies + * */ +#define APP_USBD_AUDIO_AS_FORMAT_I_DSC(nr_channels, subframe_size, resolution, freq_type, ...) \ + /*.bLength = */ sizeof(app_usbd_audio_as_format_type_one_desc_t) + \ + (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \ + /*.bFormatType = */ (1), \ + /*.bNrChannels = */ (nr_channels), \ + /*.bSubframeSize = */ (subframe_size), \ + /*.bBitResolution = */ (resolution), \ + /*.bSamFreqType = */ (freq_type), \ + /*.tSamFreq = */ __VA_ARGS__, \ + +/** + * @brief Initializer of @ref app_usbd_audio_as_format_type_two_desc_t + * + * @param max_bitrate Maximum bitrate + * @param samples_per_frame Samples per frame + * @param freq_type Frequency type + * @param ... List of frequencies + * */ +#define APP_USBD_AUDIO_AS_FORMAT_II_DSC(max_bitrate, samples_per_frame, freq_type, ...) \ + /*.bLength = */ sizeof(app_usbd_audio_as_format_type_two_desc_t) + \ + (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \ + /*.bFormatType = */ (2), \ + /*.wMaxBitRate = */ APP_USBD_U16_TO_RAW_DSC(max_bitrate), \ + /*.wSamplesPerFrame = */ APP_USBD_U16_TO_RAW_DSC(samples_per_frame), \ + /*.bSamFreqType = */ (freq_type), \ + /*.tSamFreq = */ __VA_ARGS__, \ + +/** +* @brief Initializer of @ref app_usbd_audio_as_format_type_three_desc_t + * + * @param nr_channels Number of channels + * @param subframe_size Subframe size + * @param resolution Bit resolution + * @param freq_type Frequency type + * @param ... List of frequencies + * */ +#define APP_USBD_AUDIO_AS_FORMAT_III_DSC(nr_channels, subframe_size, resolution, freq_type, ...) \ + /*.bLength = */ sizeof(app_usbd_audio_as_format_type_three_desc_t) + \ + (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \ + /*.bFormatType = */ (3), \ + /*.bNrChannels = */ (nr_channels), \ + /*.bSubframeSize = */ (subframe_size), \ + /*.bBitResolution = */ (resolution), \ + /*.bSamFreqType = */ (freq_type), \ + /*.tSamFreq = */ __VA_ARGS__, \ + + +/** + * @brief Initializer of @ref app_usbd_audio_as_endpoint_desc_t + * + * @param attributes Endpoint attributes + * @param lock_delay_units Lock delay units + * @param lock_delay Lock delay + * */ +#define APP_USBD_AUDIO_EP_GENERAL_DSC(attributes, lock_delay_units, lock_delay) \ + /*.bLength = */ sizeof(app_usbd_audio_as_endpoint_desc_t), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_EP_SUBTYPE_GENERAL, \ + /*.bmAttributes = */ (attributes), \ + /*.bLockDelayUnits = */ (lock_delay_units), \ + /*.wLockDelay = */ APP_USBD_U16_TO_RAW_DSC(lock_delay), \ + +/** + * @brief Macro to configure Audio Class control descriptor + * + * @param interface_number Interface number + * @param descriptor_list List of descriptors after Audio interface header descriptor + * @param interface_list List of interfaces passed to @ref APP_USBD_AUDIO_AC_IFACE_HEADER_DSC + * */ +#define APP_USBD_AUDIO_CONTROL_DSC(interface_number, descriptor_list, interface_list) \ + APP_USBD_AUDIO_INTERFACE_DSC(interface_number, 0, 0, APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL) \ + APP_USBD_AUDIO_AC_IFACE_HEADER_DSC(descriptor_list, BRACKET_EXTRACT(interface_list)) \ + BRACKET_EXTRACT(descriptor_list) + + +/** + * @brief Macro to configure Audio Class streaming descriptor + * + * @param interface_number Interface number + * @param alt_setting Alternate interface setting + * @param ep_num Number of endpoints + */ +#define APP_USBD_AUDIO_STREAMING_DSC(interface_number, alt_setting, ep_num) \ + APP_USBD_AUDIO_INTERFACE_DSC(interface_number, alt_setting, ep_num, \ + APP_USBD_AUDIO_SUBCLASS_AUDIOSTREAMING) + +/** + * @brief Macro to configure Audio Class MIDI streaming descriptor + * + * @param interface_number Interface number + * @param alt_setting Alternate interface setting + * @param ep_num Number of endpoints + */ +#define APP_USBD_AUDIO_MIDI_STREAMING_DSC(interface_number, alt_setting, ep_num) \ + APP_USBD_AUDIO_INTERFACE_DSC(interface_number, alt_setting, ep_num, \ + APP_USBD_AUDIO_SUBCLASS_MIDISTREAMING) + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_AUDIO_DESC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio_internal.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..cd6880d6c21b268594ad0570063f2c95fc7bb606 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio_internal.h @@ -0,0 +1,237 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_AUDIO_INTERNAL_H__ +#define APP_USBD_AUDIO_INTERNAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup app_usbd_audio_internal USB Audio internals + * @brief @tagAPI52840 USB Audio class internals. + * @ingroup app_usbd_audio + * @{ + */ + +/** + * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF in audio class + * + */ +APP_USBD_CLASS_FORWARD(app_usbd_audio); + +/*lint -save -e165*/ +/** + * @brief Forward declaration of @ref app_usbd_audio_user_event_e + * + */ +enum app_usbd_audio_user_event_e; + +/*lint -restore*/ + +/** + * @brief User event handler + * + * @param[in] p_inst Class instance + * @param[in] event User event + * + * */ +typedef void (*app_usbd_audio_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst, + enum app_usbd_audio_user_event_e event); + +/** + * @brief Audio class part of class instance data + */ +typedef struct { + uint8_t const * p_raw_desc; //!< Audio class descriptors + size_t raw_desc_size; //!< Audio class descriptors size + + app_usbd_audio_user_ev_handler_t user_ev_handler; //!< User event handler +} app_usbd_audio_inst_t; + +/** + * @brief Audio class request target + */ +typedef enum { + APP_USBD_AUDIO_CLASS_REQ_IN, /**< Audio class request IN */ + APP_USBD_AUDIO_CLASS_REQ_OUT, /**< Audio class request OUT */ + APP_USBD_AUDIO_EP_REQ_IN, /**< Audio class endpoint request IN */ + APP_USBD_AUDIO_EP_REQ_OUT, /**< Audio class endpoint request OUT */ +} app_usbd_audio_class_req_target_t; + +/** + * @brief Audio class specific request handled via control endpoint + * */ +typedef struct { + app_usbd_audio_class_req_target_t req_target; //!< Request target + app_usbd_audio_req_type_t req_type; //!< Request type + + uint8_t control; //!< Request control field + uint8_t channel; //!< Channel ID + uint8_t interface; //!< Interface ID + uint8_t entity; //!< Entity ID + uint16_t length; //!< Request payload length + + uint8_t payload[64]; //!< Request payload +} app_usbd_audio_req_t; + + +/** + * @brief Audio class context + * + * */ +typedef struct { + app_usbd_audio_req_t request; //!< Audio class request + + const void * p_tx_buff; //!< Transfer buffer (IN endpoint transfers) + void * p_rx_buff; //!< Transfer buffer (OUT endpoint transfers) + + size_t tx_size; //!< Transfer buffer size (IN endpoint transfers) + size_t rx_size; //!< Transfer buffer size (OUT endpoint transfers) + bool streaming; //!< Streaming flag +} app_usbd_audio_ctx_t; + + +/** + * @brief Audio class configuration macro + * + * Used by @ref APP_USBD_AUDIO_GLOBAL_DEF + * + * @param iface_control Interface number of audio control + * @param iface_stream Interface number of audio stream + * */ +#define APP_USBD_AUDIO_CONFIG(iface_control, iface_stream) \ + ((iface_control), \ + (iface_stream, 0)) + +/** + * @brief Only IN audio stream configuration + * + * @param iface_control Interface number of audio control + * @param iface_stream_in Interface number of audio stream on IN endpoint + * */ +#define APP_USBD_AUDIO_CONFIG_IN(iface_control, iface_stream_in) \ + ((iface_control), (iface_stream_in, NRF_DRV_USBD_EPIN8)) + + +/** + * @brief Only OUT audio stream configuration + * + * @param iface_control Interface number of audio control + * @param iface_stream_out Interface number of audio stream on OUT endpoint + * */ +#define APP_USBD_AUDIO_CONFIG_OUT(iface_control, iface_stream_out) \ + ((iface_control), (iface_stream_out, NRF_DRV_USBD_EPOUT8)) + +/** + * @brief Specific class constant data for audio class + * + * @ref app_usbd_audio_inst_t + */ +#define APP_USBD_AUDIO_INSTANCE_SPECIFIC_DEC app_usbd_audio_inst_t inst; + + +/** + * @brief Configures audio class instance + * + * @param descriptors Mass storage class descriptors (raw table) + * @param user_event_handler User event handler + */ +#define APP_USBD_AUDIO_INST_CONFIG(descriptors, user_event_handler) \ + .inst = { \ + .p_raw_desc = descriptors, \ + .raw_desc_size = sizeof(descriptors), \ + .user_ev_handler = user_event_handler, \ + } + +/** + * @brief Specific class data for audio class + * + * @ref app_usbd_audio_ctx_t + * */ +#define APP_USBD_AUDIO_DATA_SPECIFIC_DEC app_usbd_audio_ctx_t ctx; + + +/** + * @brief Audio class descriptors config macro + * + * @param interface_number Interface number + * @param ... Extracted endpoint list + * */ +#define APP_USBD_AUDIO_DSC_CONFIG(interface_number, ...) { \ + APP_USBD_AUDIO_INTERFACE_DSC(interface_number, \ + 0, \ + 0, \ + APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL) \ + } + +/** + * @brief Public audio class interface + * + * */ +extern const app_usbd_class_methods_t app_usbd_audio_class_methods; + +/** + * @brief Global definition of @ref app_usbd_audio_t class + * + */ +#define APP_USBD_AUDIO_GLOBAL_DEF_INTERNAL(instance_name, \ + interfaces_configs, \ + user_ev_handler, \ + raw_descriptors) \ + APP_USBD_CLASS_INST_GLOBAL_DEF( \ + instance_name, \ + app_usbd_audio, \ + &app_usbd_audio_class_methods, \ + interfaces_configs, \ + (APP_USBD_AUDIO_INST_CONFIG(raw_descriptors, \ + user_ev_handler)) \ + ) + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_AUDIO_INTERNAL_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio_types.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio_types.h new file mode 100644 index 0000000000000000000000000000000000000000..4a935b0fd8b830067c2f83b475b0f89a77549f1c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/audio/app_usbd_audio_types.h @@ -0,0 +1,382 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_AUDIO_TYPES_H__ +#define APP_USBD_AUDIO_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_util.h" + +/** + * @defgroup app_usbd_audio_types USB Audio types + * @brief @tagAPI52840 Type definitions for the USB Audio class. + * @ingroup app_usbd_audio + * @{ + */ + +/** @brief Audio class definition in interface descriptor + * + * Fixed value, @ref app_usbd_descriptor_iface_t::bInterfaceClass + * */ +#define APP_USBD_AUDIO_CLASS 0x01 + +/** @brief Audio class protocol definition in interface descriptor + * + * Fixed value, @ref app_usbd_descriptor_iface_t::bInterfaceProtocol + * */ +#define APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED 0x00 + +/** + * @brief Audio subclass possible values + * + * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass + */ +typedef enum { + APP_USBD_AUDIO_SUBCLASS_UNDEFINED = 0x00, /**< UNDEFINED subclass */ + APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL, /**< AUDIOCONTROL subclass */ + APP_USBD_AUDIO_SUBCLASS_AUDIOSTREAMING, /**< AUDIOSTREAMING subclass */ + APP_USBD_AUDIO_SUBCLASS_MIDISTREAMING /**< MIDISTREAMING subclass */ +} app_usbd_audio_subclass_t; + + +/** + * @brief Audio class specific descriptor types + */ +typedef enum { + APP_USBD_AUDIO_DESCRIPTOR_UNDEFINED = 0x20, /**< UNDEFINED descriptor type */ + APP_USBD_AUDIO_DESCRIPTOR_DEVICE = 0x21, /**< DEVICE descriptor type */ + APP_USBD_AUDIO_DESCRIPTOR_CONFIGURATION = 0x22, /**< CONFIGURATION descriptor type */ + APP_USBD_AUDIO_DESCRIPTOR_STRING = 0x23, /**< STRING descriptor type */ + APP_USBD_AUDIO_DESCRIPTOR_INTERFACE = 0x24, /**< INTERFACE descriptor type */ + APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT = 0x25, /**< ENDPOINT descriptor type */ +} app_usbd_audio_descriptor_type_t; + + +/** + * @brief Audio control interface subtype + */ +typedef enum { + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_UNDEFINED = 0x00, /**< Audio control interface subtype UNDEFINED */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER, /**< Audio control interface subtype HEADER */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL, /**< Audio control interface subtype INPUT_TERMINAL */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL, /**< Audio control interface subtype OUTPUT_TERNINAL */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_MIXER_UNIT, /**< Audio control interface subtype MIXER_UNIT */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_SELECTOR_UNIT, /**< Audio control interface subtype SELECTOR_UNIT */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT, /**< Audio control interface subtype FEATURE_UNIT */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_PROCESSING_UNIT, /**< Audio control interface subtype PROCESSING_UNIT */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_EXTENSION_UNIT, /**< Audio control interface subtype EXTENSION_UNIT */ +} app_usbd_audio_ac_iface_subtype_t; + +/** + * @brief Audio streaming interface subtype + */ +typedef enum { + APP_USBD_AUDIO_AS_IFACE_SUBTYPE_UNDEFINED = 0x00, /**< Audio streaming interface subtype UNDEFINED */ + APP_USBD_AUDIO_AS_IFACE_SUBTYPE_GENERAL, /**< Audio streaming interface subtype GENERAL */ + APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, /**< Audio streaming interface subtype FORMAT_TYPE */ + APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_SPECIFIC, /**< Audio streaming interface subtype FORMAT_SPECIFIC*/ +} app_usbd_audio_as_iface_subtype_t; + + +/** + * @brief Audio class specific endpoint subtypes + */ +typedef enum { + APP_USBD_AUDIO_EP_SUBTYPE_UNDEFINED = 0x00, /**< APP_USBD_AUDIO_EP_SUBTYPE_UNDEFINED */ + APP_USBD_AUDIO_EP_SUBTYPE_GENERAL, /**< APP_USBD_AUDIO_EP_SUBTYPE_GENERAL */ +} app_usbd_audio_ep_subtype_t; + +/** + * @brief Audio class specific requests + * + * @ref nrf_drv_usbd_setup_t::bmRequestType + */ +typedef enum { + APP_USBD_AUDIO_REQ_UNDEFINED = 0x00, /**< UNDEFINED request*/ + + APP_USBD_AUDIO_REQ_SET_CUR = 0x01, /**< SET_CUR request */ + APP_USBD_AUDIO_REQ_SET_MIN = 0x02, /**< SET_MIN request */ + APP_USBD_AUDIO_REQ_SET_MAX = 0x03, /**< SET_MAX request */ + APP_USBD_AUDIO_REQ_SET_RES = 0x04, /**< SET_RES request */ + APP_USBD_AUDIO_REQ_SET_MEM = 0x05, /**< SET_MEM request */ + + APP_USBD_AUDIO_REQ_GET_CUR = 0x81, /**< GET_CUR request */ + APP_USBD_AUDIO_REQ_GET_MIN = 0x82, /**< GET_MIN request */ + APP_USBD_AUDIO_REQ_GET_MAX = 0x83, /**< GET_MAX request */ + APP_USBD_AUDIO_REQ_GET_RES = 0x84, /**< GET_RES request */ + APP_USBD_AUDIO_REQ_GET_MEM = 0x85, /**< GET_MEM request */ + + APP_USBD_AUDIO_REQ_GET_STAT = 0xFF, /**< GET_STAT request */ +} app_usbd_audio_req_type_t; + +/** + * @brief Audio class terminal types + * */ +typedef enum { + /*USB terminals*/ + APP_USBD_AUDIO_TERMINAL_USB_UNDEFINED = 0x0100, /**< USB_UNDEFINED*/ + APP_USBD_AUDIO_TERMINAL_USB_STREAMING = 0x0101, /**< USB_STREAMING */ + APP_USBD_AUDIO_TERMINAL_USB_VENDOR_SPEC = 0x01FF, /**< USB_VENDOR_SPEC*/ + + /*Input terminals*/ + APP_USBD_AUDIO_TERMINAL_IN_UNDEFINED = 0x0200, /**< UNDEFINED */ + APP_USBD_AUDIO_TERMINAL_IN_MICROPHONE = 0x0201, /**< MICROPHONE */ + APP_USBD_AUDIO_TERMINAL_IN_DESKTOP_MIC = 0x0202, /**< DESKTOP_MIC */ + APP_USBD_AUDIO_TERMINAL_IN_PERSONAL_MIC = 0x0203, /**< PERSONAL_MIC */ + APP_USBD_AUDIO_TERMINAL_IN_OM_DIR_MIC = 0x0204, /**< OM_DIR_MIC */ + APP_USBD_AUDIO_TERMINAL_IN_MIC_ARRAY = 0x0205, /**< MIC_ARRAY */ + APP_USBD_AUDIO_TERMINAL_IN_PROC_MIC_ARRAY = 0x0205, /**< PROC_MIC_ARRAY */ + + /*Output terminals*/ + APP_USBD_AUDIO_TERMINAL_OUT_UNDEFINED = 0x0300, /**< UNDEFINED */ + APP_USBD_AUDIO_TERMINAL_OUT_SPEAKER = 0x0301, /**< SPEAKER */ + APP_USBD_AUDIO_TERMINAL_OUT_HEADPHONES = 0x0302, /**< HEADPHONES */ + APP_USBD_AUDIO_TERMINAL_OUT_HEAD_AUDIO = 0x0303, /**< HEAD_AUDIO */ + APP_USBD_AUDIO_TERMINAL_OUT_DESKTOP_SPEAKER = 0x0304, /**< DESKTOP_SPEAKER */ + APP_USBD_AUDIO_TERMINAL_OUT_ROOM_SPEAKER = 0x0305, /**< ROOM_SPEAKER */ + APP_USBD_AUDIO_TERMINAL_OUT_COMM_SPEAKER = 0x0306, /**< COMM_SPEAKER */ + APP_USBD_AUDIO_TERMINAL_OUT_LOW_FREQ_SPEAKER = 0x0307, /**< LOW_FREQ_SPEAKER */ + + /*Input/Output terminals*/ + APP_USBD_AUDIO_TERMINAL_IO_UNDEFINED = 0x0400, /**< UNDEFINED */ + APP_USBD_AUDIO_TERMINAL_IO_HANDSET = 0x0401, /**< HANDSET */ + APP_USBD_AUDIO_TERMINAL_IO_HEADSET = 0x0402, /**< HEADSET */ + APP_USBD_AUDIO_TERMINAL_IO_SPEAKERPHONE_ECHO_NONE = 0x0403, /**< SPEAKERPHONE_ECHO_NONE */ + APP_USBD_AUDIO_TERMINAL_IO_SPEAKERPHONE_ECHO_SUP = 0x0404, /**< SPEAKERPHONE_ECHO_SUP */ + APP_USBD_AUDIO_TERMINAL_IO_SPEAKERPHONE_ECHO_CAN = 0x0405, /**< SPEAKERPHONE_ECHO_CAN */ +} app_usbd_audio_terminal_type_t; + +/** + * @brief Audio class control interface header descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER + uint8_t bcdADC[2]; //!< BCD ADC + uint8_t wTotalLength[2]; //!< Total interfaces length + uint8_t bInCollection; //!< Input collection + uint8_t baInterfaceNr[]; //!< Interface number list +} app_usbd_audio_ac_iface_header_desc_t; + + +/** + * @brief Possible values of input terminal channel config + * + * @ref app_usbd_audio_input_terminal_desc_t::wChannelConfig + * */ +typedef enum { + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_FRONT = (1u << 0), /**< Channel config bit LEFT_FRONT */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_FRONT = (1u << 1), /**< Channel config bit RIGHT_FRONT */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_CENTER_FRONT = (1u << 2), /**< Channel config bit CENTER_FRONT */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LOW_FREQ_ENH = (1u << 3), /**< Channel config bit LOW_FREQ_ENH */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_SURROUND = (1u << 4), /**< Channel config bit LEFT_SURROUND */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_SURROUND = (1u << 5), /**< Channel config bit RIGHT_SURROUND */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_OF_CENTER = (1u << 6), /**< Channel config bit LEFT_OF_CENTER */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_OF_CENTER = (1u << 7), /**< Channel config bit RIGHT_OF_CENTER */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_SURROUND = (1u << 8), /**< Channel config bit SURROUND */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_SIDE_LEFT = (1u << 9), /**< Channel config bit SIDE_LEFT */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_SIDE_RIGHT = (1u << 10), /**< Channel config bit SIDE_RIGHT */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_TOP = (1u << 11), /**< Channel config bit TOP */ +} app_usbd_audio_in_term_ch_config_t; + +/** + * @brief Audio class input terminal descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL + uint8_t bTerminalID; //!< Terminal ID + uint8_t wTerminalType[2]; //!< Terminal type + uint8_t bAssocTerminal; //!< Association terminal + uint8_t bNrChannels; //!< Number of channels + uint8_t wChannelConfig[2]; //!< Channel config + uint8_t iChannelNames; //!< Channel names + uint8_t iTerminal; //!< Terminal string ID +} app_usbd_audio_input_terminal_desc_t; + +/** + * @brief Audio class output terminal descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL + uint8_t bTerminalID; //!< Terminal ID + uint8_t wTerminalType[2]; //!< Terminal type + uint8_t bAssocTerminal; //!< Association terminal + uint8_t bSourceID; //!< Source ID + uint8_t iTerminal; //!< Terminal string ID +} app_usbd_audio_output_terminal_desc_t; + +/** + * @brief Possible values of feature unit control field*/ +typedef enum { + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MUTE = (1u << 0), /**< Feature unit control bit MUTE */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_VOLUME = (1u << 1), /**< Feature unit control bit VOLUME */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_BASS = (1u << 2), /**< Feature unit control bit BASS */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MID = (1u << 3), /**< Feature unit control bit MID */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_TREBLE = (1u << 4), /**< Feature unit control bit TREBLE */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_GRAPH_EQ = (1u << 5), /**< Feature unit control bit GRAPH_EQ */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_AUTO_GAIN = (1u << 6), /**< Feature unit control bit AUTO_GAIN */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_DELAY = (1u << 7), /**< Feature unit control bit DELAY */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_BASS_BOOST = (1u << 8), /**< Feature unit control bit BASS_BOOST*/ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_LOUDNESS = (1u << 9), /**< Feature unit control bit LOUDNESS */ +} app_usbd_audio_feature_unit_control_t; + +/** + * @brief Audio class feature unit descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT + uint8_t bUnitID; //!< Unit ID + uint8_t bSourceID; //!< Source ID + uint8_t bControlSize; //!< Control size + uint8_t bmaControls[]; //!< Controls array +} app_usbd_audio_feature_unit_desc_t; + +/** + * @brief Format tag in audio streaming interface descriptor + * + * @ref app_usbd_audio_as_iface_desc_t::wFormatTag + * */ +typedef enum { + APP_USBD_AUDIO_AS_IFACE_FORMAT_TYPE_I_UNDEFINED = 0x0000, /**< AS format TYPE_I_UNDEFINED */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_PCM = 0x0001, /**< AS format PCM */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_PCM8 = 0x0002, /**< AS format PCM8 */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEEE_FLOAT = 0x0003, /**< AS format IEEE_FLOAT */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_ALAW = 0x0004, /**< AS format ALAW */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_MULAW = 0x0005, /**< AS format MULAW */ + + APP_USBD_AUDIO_AS_IFACE_FORMAT_TYPE_II_UNDEFINED = 0x1000, /**< AS format TYPE_II_UNDEFINED */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_MPEG = 0x1001, /**< AS format MPEG */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_AC3 = 0x1002, /**< AS format AC3 */ + + APP_USBD_AUDIO_AS_IFACE_FORMAT_TYPE_III_UNDEFINED = 0x2000, /**< AS format TYPE_III_UNDEFINED */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_AC_3 = 0x2001, /**< AS format IEC1937_AC_3 */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_1_LAYER1 = 0x2002, /**< AS format IEC1937_MPEG_1_LAYER1 */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_NOEXT = 0x2003, /**< AS format IEC1937_MPEG_2_NOEXT */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_EXT = 0x2004, /**< AS format IEC1937_MPEG_2_EXT */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_LAYER1_LS = 0x2005, /**< AS format IEC1937_MPEG_2_LAYER1_LS */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_LAYER23_LS = 0x2005, /**< AS format IEC1937_MPEG_2_LAYER23_LS */ +} app_usbd_audio_as_iface_format_tag_t; + +/** + * @brief Audio class audio streaming interface descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_ac_iface_subtype_t + uint8_t bTerminalLink; //!< Terminal link + uint8_t bDelay; //!< Delay + uint8_t wFormatTag[2]; //!< Format TAG +} app_usbd_audio_as_iface_desc_t; + +/** + * @brief Audio class audio streaming format type I descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_as_iface_subtype_t + uint8_t bFormatType; //!< Format type: fixed value 1 + uint8_t bNrChannels; //!< Number of channels + uint8_t bSubframeSize; //!< Subframe size + uint8_t bBitResolution; //!< Bit resolution + uint8_t bSamFreqType; //!< Number of supported sampling frequencies + uint8_t tSamFreq[]; //!< Number of supported sampling frequencies table (24 bit entries) +} app_usbd_audio_as_format_type_one_desc_t; + + +/** + * @brief Audio class audio streaming format type II descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_as_iface_subtype_t + uint8_t bFormatType; //!< Format type: fixed value 2 + uint8_t wMaxBitRate[2]; //!< Maximum bitrate + uint8_t wSamplesPerFrame[2]; //!< Samples per frame + uint8_t bSamFreqType; //!< Number of supported sampling frequencies + uint8_t tSamFreq[]; //!< Number of supported sampling frequencies table (24 bit entries) +} app_usbd_audio_as_format_type_two_desc_t; + +/** + * @brief Audio class audio streaming format type III descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_as_iface_subtype_t + uint8_t bFormatType; //!< Format type: fixed value 1 + uint8_t bNrChannels; //!< Number of channels + uint8_t bSubframeSize; //!< Subframe size + uint8_t bBitResolution; //!< Bit resolution + uint8_t bSamFreqType; //!< Number of supported sampling frequencies + uint8_t tSamFreq[]; //!< Number of supported sampling frequencies table (24 bit entries) +} app_usbd_audio_as_format_type_three_desc_t; + +/** + * @brief Audio class audio endpoint descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_EP_SUBTYPE_GENERAL + uint8_t bmAttributes; //!< Audio endpoint attributes + uint8_t bLockDelayUnits; //!< Lock delay units + uint8_t wLockDelay[2]; //!< Lock delay value +} app_usbd_audio_as_endpoint_desc_t; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_AUDIO_TYPES_H__ */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c new file mode 100644 index 0000000000000000000000000000000000000000..35e969ff85d5625c82b71219155ba69c2fb4df1f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c @@ -0,0 +1,731 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_CLASS_CDC_ACM_ENABLED +#include "app_usbd_cdc_acm.h" +#include + +/** + * @defgroup app_usbd_cdc_acm_internal CDC ACM internals + * @{ + * @ingroup app_usbd_cdc + * @internal + */ + + +#define NRF_LOG_MODULE_NAME "CDC_ACM" +#if APP_USBD_CDC_ACM_LOG_ENABLED +#else //APP_USBD_CDC_ACM_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //APP_USBD_CDC_ACM_LOG_ENABLED +#include "nrf_log.h" + + +#define APP_USBD_CDC_ACM_COMM_IFACE_IDX 0 /**< CDC ACM class comm interface index. */ +#define APP_USBD_CDC_ACM_DATA_IFACE_IDX 1 /**< CDC ACM class data interface index. */ + +#define APP_USBD_CDC_ACM_COMM_EPIN_IDX 0 /**< CDC ACM comm class endpoint IN index. */ +#define APP_USBD_CDC_ACM_DATA_EPIN_IDX 0 /**< CDC ACM data class endpoint IN index. */ +#define APP_USBD_CDC_ACM_DATA_EPOUT_IDX 1 /**< CDC ACM data class endpoint OUT index. */ + +/** + * @brief Auxiliary function to access cdc_acm class instance data. + * + * @param[in] p_inst Class instance data. + * + * @return CDC ACM class instance. + */ +static inline app_usbd_cdc_acm_t const * cdc_acm_get(app_usbd_class_inst_t const * p_inst) +{ + ASSERT(p_inst != NULL); + return (app_usbd_cdc_acm_t const *)p_inst; +} + +/** + * @brief Auxiliary function to access cdc_acm class context data. + * + * @param[in] p_cdc_acm CDC ACM class instance data. + * + * @return CDC ACM class instance context. + */ +static inline app_usbd_cdc_acm_ctx_t * cdc_acm_ctx_get(app_usbd_cdc_acm_t const * p_cdc_acm) +{ + ASSERT(p_cdc_acm != NULL); + ASSERT(p_cdc_acm->specific.p_data != NULL); + return &p_cdc_acm->specific.p_data->ctx; +} + +/** + * @brief User event handler. + * + * @param[in] p_inst Class instance. + * @param[in] event user Event type. + */ +static inline void user_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_cdc_acm_user_event_t event) +{ + app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst); + if (p_cdc_acm->specific.inst.user_ev_handler != NULL) + { + p_cdc_acm->specific.inst.user_ev_handler(p_inst, event); + } +} + +/** + * @brief Auxiliary function to access CDC ACM COMM IN endpoint address. + * + * @param[in] p_inst Class instance data. + * + * @return IN endpoint address. + */ +static inline nrf_drv_usbd_ep_t comm_ep_in_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_COMM_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_COMM_EPIN_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** + * @brief Auxiliary function to access CDC ACM DATA IN endpoint address. + * + * @param[in] p_inst Class instance data. + * + * @return IN endpoint address. + */ +static inline nrf_drv_usbd_ep_t data_ep_in_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_DATA_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPIN_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** + * @brief Auxiliary function to access CDC ACM DATA OUT endpoint address. + * + * @param[in] p_inst Class instance data. + * + * @return OUT endpoint address. + */ +static inline nrf_drv_usbd_ep_t data_ep_out_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_DATA_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPOUT_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** + * @brief Internal SETUP standard IN request handler. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR: + { + size_t dsc_len = 0; + + /* Try to find descriptor in class internals*/ + void const * p_dsc = app_usbd_class_descriptor_find(p_inst, + p_setup_ev->setup.wValue.hb, + p_setup_ev->setup.wValue.lb, + &dsc_len); + if (p_dsc != NULL) + { + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_dsc, dsc_len); + } + + break; + } + case APP_USBD_SETUP_STDREQ_GET_INTERFACE: + { + + size_t tx_maxsize; + uint8_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_maxsize); + + p_tx_buff[0] = 0; + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + p_tx_buff, + sizeof(uint8_t)); + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP standard OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code. + */ +static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + + switch (p_setup_ev->setup.bmRequest) + { + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP class IN request handler. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst); + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_CDC_REQ_GET_LINE_CODING: + { + if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + &p_cdc_acm_ctx->line_coding, + sizeof(app_usbd_cdc_line_coding_t)); + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Class specific OUT request data callback. + * + * @param status Endpoint status. + * @param p_context Context of transfer (set by @ref app_usbd_core_setup_data_handler_set). + * + * @return Standard error code. + */ +static ret_code_t cdc_acm_req_out_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context) +{ + if (status != NRF_USBD_EP_OK) + { + return NRF_ERROR_INTERNAL; + } + + app_usbd_cdc_acm_t const * p_cdc_acm = p_context; + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + switch (p_cdc_acm_ctx->request.type) + { + case APP_USBD_CDC_REQ_SET_LINE_CODING: + { + memcpy(&p_cdc_acm_ctx->line_coding, + &p_cdc_acm_ctx->request.payload.line_coding, + sizeof(app_usbd_cdc_line_coding_t)); + + NRF_LOG_INFO("REQ_SET_LINE_CODING: baudrate: %"PRIu32", databits: %u, " + "format: %u, parity: %u\r\n", + uint32_decode(p_cdc_acm_ctx->line_coding.dwDTERate), + p_cdc_acm_ctx->line_coding.bDataBits, + p_cdc_acm_ctx->line_coding.bCharFormat, + p_cdc_acm_ctx->line_coding.bParityType); + break; + } + default: + return NRF_ERROR_NOT_SUPPORTED; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Class specific request data stage setup. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t cdc_acm_req_out_datastage(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst); + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + p_cdc_acm_ctx->request.type = p_setup_ev->setup.bmRequest; + p_cdc_acm_ctx->request.len = p_setup_ev->setup.wLength.w; + + /*Request setup data*/ + NRF_DRV_USBD_TRANSFER_OUT(transfer, + &p_cdc_acm_ctx->request.payload, + p_cdc_acm_ctx->request.len); + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_setup_data_transfer(NRF_DRV_USBD_EPOUT0, &transfer); + if (ret == NRF_SUCCESS) + { + const app_usbd_core_setup_data_handler_desc_t desc = { + .handler = cdc_acm_req_out_data_cb, + .p_context = (void*)p_cdc_acm + }; + + ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +/** + * @brief Internal SETUP class OUT request handler. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst); + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_CDC_REQ_SET_LINE_CODING: + { + if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return cdc_acm_req_out_datastage(p_inst, p_setup_ev); + } + case APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE: + { + if (p_setup_ev->setup.wLength.w != 0) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + NRF_LOG_INFO("REQ_SET_CONTROL_LINE_STATE: 0x%x\r\n", p_setup_ev->setup.wValue.w); + + bool old_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ? + true : false; + p_cdc_acm_ctx->line_state = p_setup_ev->setup.wValue.w; + + bool new_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ? + true : false; + + if (old_dtr == new_dtr) + { + return NRF_SUCCESS; + } + + const app_usbd_cdc_acm_user_event_t ev = new_dtr ? + APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN : APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE; + + user_event_handler(p_inst, ev); + + if (!new_dtr) + { + /*Abort DATA endpoints on port close */ + nrf_drv_usbd_ep_t ep; + ep = data_ep_in_addr_get(p_inst); + usbd_drv_ep_abort(ep); + ep = data_ep_out_addr_get(p_inst); + usbd_drv_ep_abort(ep); + } + + return NRF_SUCCESS; + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Control endpoint handler. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + ASSERT(p_inst != NULL); + ASSERT(p_setup_ev != NULL); + + if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN) + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_in(p_inst, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_in(p_inst, p_setup_ev); + default: + break; + } + } + else /*APP_USBD_SETUP_REQDIR_OUT*/ + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_out(p_inst, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_out(p_inst, p_setup_ev); + default: + break; + } + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Class specific endpoint transfer handler. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t cdc_acm_endpoint_ev(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + if (comm_ep_in_addr_get(p_inst) == p_event->drv_evt.data.eptransfer.ep) + { + NRF_LOG_INFO("EPIN_COMM: notify\r\n"); + return NRF_SUCCESS; + } + + if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep)) + { + switch (p_event->drv_evt.data.eptransfer.status) + { + case NRF_USBD_EP_OK: + NRF_LOG_INFO("EPIN_DATA: %02x done\r\n", p_event->drv_evt.data.eptransfer.ep); + user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_TX_DONE); + return NRF_SUCCESS; + case NRF_USBD_EP_ABORTED: + return NRF_SUCCESS; + default: + return NRF_ERROR_INTERNAL; + } + } + + if (NRF_USBD_EPOUT_CHECK(p_event->drv_evt.data.eptransfer.ep)) + { + switch (p_event->drv_evt.data.eptransfer.status) + { + case NRF_USBD_EP_OK: + NRF_LOG_INFO("EPOUT_DATA: %02x done\r\n", p_event->drv_evt.data.eptransfer.ep); + user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_RX_DONE); + return NRF_SUCCESS; + case NRF_USBD_EP_WAITING: + case NRF_USBD_EP_ABORTED: + return NRF_SUCCESS; + default: + return NRF_ERROR_INTERNAL; + } + } + + return NRF_ERROR_NOT_SUPPORTED; +} + + +/** + * @brief @ref app_usbd_class_methods_t::event_handler + */ +static ret_code_t cdc_acm_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + ASSERT(p_inst != NULL); + ASSERT(p_event != NULL); + + ret_code_t ret = NRF_SUCCESS; + switch (p_event->app_evt.type) + { + case APP_USBD_EVT_DRV_SOF: + break; + case APP_USBD_EVT_DRV_RESET: + break; + case APP_USBD_EVT_DRV_SETUP: + ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event); + break; + case APP_USBD_EVT_DRV_EPTRANSFER: + ret = cdc_acm_endpoint_ev(p_inst, p_event); + break; + case APP_USBD_EVT_DRV_SUSPEND: + break; + case APP_USBD_EVT_DRV_RESUME: + break; + case APP_USBD_EVT_INST_APPEND: + { + ret = app_usbd_class_sof_register(p_inst); + break; + } + case APP_USBD_EVT_INST_REMOVE: + { + ret = app_usbd_class_sof_unregister(p_inst); + break; + } + case APP_USBD_EVT_START: + break; + case APP_USBD_EVT_STOP: + break; + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + return ret; +} + +/** + * @brief @ref app_usbd_class_methods_t::get_descriptors + */ +static const void * cdc_acm_get_descriptors(app_usbd_class_inst_t const * p_inst, + size_t * p_size) +{ + ASSERT(p_size != NULL); + app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst); + + *p_size = p_cdc_acm->specific.inst.raw_desc_size; + return p_cdc_acm->specific.inst.p_raw_desc; +} + +/** + * @brief Public cdc_acm class interface + * + */ +const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods = { + .event_handler = cdc_acm_event_handler, + .get_descriptors = cdc_acm_get_descriptors, +}; + + +ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm, + const void * p_buf, + size_t length) +{ + app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm); + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + bool dtr_state = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ? + true : false; + if (!dtr_state) + { + /*Port is not opened*/ + return NRF_ERROR_INVALID_STATE; + } + + nrf_drv_usbd_ep_t ep = data_ep_in_addr_get(p_inst); + NRF_DRV_USBD_TRANSFER_IN(transfer, p_buf, length); + return app_usbd_core_ep_transfer(ep, &transfer); +} + +size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm) +{ + app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm); + nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(p_inst); + + size_t size; + ret_code_t ret = nrf_drv_usbd_ep_status_get(ep, &size); + if (ret != NRF_SUCCESS) + { + return 0; + } + + return size; +} + +ret_code_t app_usbd_cdc_acm_read(app_usbd_cdc_acm_t const * p_cdc_acm, + void * p_buf, + size_t length) +{ + ASSERT((length % NRF_DRV_USBD_EPSIZE) == 0); + app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm); + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + bool dtr_state = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ? + true : false; + if (!dtr_state) + { + /*Port is not opened*/ + return NRF_ERROR_INVALID_STATE; + } + + nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(p_inst); + NRF_DRV_USBD_TRANSFER_OUT(transfer, p_buf, length); + return app_usbd_core_ep_transfer(ep, &transfer); +} + +static ret_code_t cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm) +{ + app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm); + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + nrf_drv_usbd_ep_t ep = comm_ep_in_addr_get(p_inst); + + NRF_DRV_USBD_TRANSFER_OUT(transfer, + &p_cdc_acm_ctx->request.payload, + sizeof(app_usbd_cdc_acm_notify_t)); + return app_usbd_core_ep_transfer(ep, &transfer); +} + +ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm, + app_usbd_cdc_acm_serial_state_t serial_state, + bool value) +{ + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = NRF_SUCCESS; + switch (serial_state) + { + case APP_USBD_CDC_ACM_SERIAL_STATE_DCD: + case APP_USBD_CDC_ACM_SERIAL_STATE_DSR: + case APP_USBD_CDC_ACM_SERIAL_STATE_BREAK: + case APP_USBD_CDC_ACM_SERIAL_STATE_RING: + case APP_USBD_CDC_ACM_SERIAL_STATE_FRAMING: + case APP_USBD_CDC_ACM_SERIAL_STATE_PARITY: + case APP_USBD_CDC_ACM_SERIAL_STATE_OVERRUN: + + if (value) + { + p_cdc_acm_ctx->serial_state |= serial_state; + } + else + { + p_cdc_acm_ctx->serial_state &= ~serial_state; + } + + break; + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + if (ret == NRF_SUCCESS) + { + app_usbd_cdc_acm_notify_t * notify = &p_cdc_acm_ctx->request.payload.notify; + notify->cdc_notify.bmRequestType = app_usbd_setup_req_val(APP_USBD_SETUP_REQREC_INTERFACE, + APP_USBD_SETUP_REQTYPE_CLASS, + APP_USBD_SETUP_REQDIR_IN); + notify->cdc_notify.bmRequest = APP_USBD_CDC_NOTIF_SERIAL_STATE; + notify->cdc_notify.wValue = 0; + notify->cdc_notify.wIndex = 0; + notify->cdc_notify.wLength = sizeof(notify->serial_state); + + notify->serial_state = p_cdc_acm_ctx->serial_state; + + ret = cdc_acm_serial_state_notify(p_cdc_acm); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_acm, + app_usbd_cdc_acm_line_state_t line_state, + uint32_t * value) +{ + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = NRF_SUCCESS; + switch (line_state) + { + case APP_USBD_CDC_ACM_LINE_STATE_DTR: + case APP_USBD_CDC_ACM_LINE_STATE_RTS: + *value = (p_cdc_acm_ctx->line_state & line_state) != 0; + break; + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +#endif /* APP_USBD_CLASS_CDC_ACM_ENABLED */ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h new file mode 100644 index 0000000000000000000000000000000000000000..dc6ebbf21d9c877b7b5dfbd46f8c0e2a7fada0b8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h @@ -0,0 +1,295 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_CDC_ACM_H__ +#define APP_USBD_CDC_ACM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "nrf_drv_usbd.h" +#include "app_usbd_class_base.h" +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_descriptor.h" + +#include "app_usbd_cdc_desc.h" +#include "app_usbd_cdc_types.h" +#include "app_usbd_cdc_acm_internal.h" + +/** + * @defgroup app_usbd_cdc_acm USB CDC ACM class + * @ingroup app_usbd + * + * @brief @tagAPI52840 Module with types, definitions and API used by CDC ACM class. + * + * @details References: + * - "Universal Serial Bus Class Definitions for Communications Devices" + * Revision 1.2, November 3, 2010 + * - "Universal Serial Bus Communications Class Subclass Specification for PSTN Devices" + * Revision 1.2, February 9, 2007 + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief CDC ACM class instance type + * + * @ref APP_USBD_CLASS_TYPEDEF + */ +typedef struct { } app_usbd_cdc_acm_t; +#else +/*lint -save -e10 -e26 -e123 -e505 */ +APP_USBD_CLASS_TYPEDEF(app_usbd_cdc_acm, \ + APP_USBD_CDC_ACM_CONFIG(0, 0, 0, 0, 0), \ + APP_USBD_CDC_ACM_INSTANCE_SPECIFIC_DEC, \ + APP_USBD_CDC_ACM_DATA_SPECIFIC_DEC \ +); +/*lint -restore*/ +#endif + + +/*lint -save -e407 */ + +/** + * @brief Events passed to user event handler. + * + * @note Example prototype of user event handler: + * + * @code + void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_cdc_acm_user_event_t event); + * @endcode + */ +typedef enum app_usbd_cdc_acm_user_event_e { + APP_USBD_CDC_ACM_USER_EVT_RX_DONE, /**< User event RX_DONE. */ + APP_USBD_CDC_ACM_USER_EVT_TX_DONE, /**< User event TX_DONE. */ + + APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN, /**< User event PORT_OPEN. */ + APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE, /**< User event PORT_CLOSE. */ +} app_usbd_cdc_acm_user_event_t; + +/*lint -restore*/ + +/** + * @brief Default CDC ACM descriptors. + * + * @param comm_interface COMM interface number. + * @param comm_epin COMM interface IN endpoint. + * @param data_interface DATA interface number. + * @param data_epin DATA interface IN endpoint. + * @param data_epout DATA interface OUT endpoint. + */ +#define APP_USBD_CDC_ACM_DEFAULT_DESC(comm_interface, \ + comm_epin, \ + data_interface, \ + data_epin, \ + data_epout) \ + APP_USBD_CDC_IAD_DSC(comm_interface, \ + APP_USBD_CDC_SUBCLASS_ACM, \ + APP_USBD_CDC_COMM_PROTOCOL_AT_V250) \ + APP_USBD_CDC_COMM_INTERFACE_DSC(comm_interface, \ + APP_USBD_CDC_SUBCLASS_ACM, \ + APP_USBD_CDC_COMM_PROTOCOL_AT_V250) \ + APP_USBD_CDC_HEADER_DSC(0x0110) \ + APP_USBD_CDC_CALL_MGMT_DSC(0x03, data_interface) \ + APP_USBD_CDC_ACM_DSC(0x02) \ + APP_USBD_CDC_UNION_DSC(comm_interface, data_interface) \ + APP_USBD_CDC_COM_EP_DSC(comm_epin, NRF_DRV_USBD_EPSIZE) \ + APP_USBD_CDC_DATA_INTERFACE_DSC(data_interface, 0, 0) \ + APP_USBD_CDC_DATA_EP_DSC(data_epin, data_epout, NRF_DRV_USBD_EPSIZE) + +/** + * @brief Global definition of app_usbd_cdc_acm_t class instance. + * + * @param instance_name Name of global instance. + * @param interfaces_configs Interfaces configurations. + * @param user_ev_handler User event handler (optional). + * @param raw_descriptors Raw descriptor table. + * + * @note This macro is just simplified version of @ref APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL. + * + */ +#define APP_USBD_CDC_ACM_GLOBAL_DEF(instance_name, \ + interfaces_configs, \ + user_ev_handler, \ + raw_descriptors) \ + APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \ + interfaces_configs, \ + user_ev_handler, \ + raw_descriptors) + +/** + * @brief Helper function to get class instance from CDC ACM class. + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF). + * + * @return Base class instance. + */ +static inline app_usbd_class_inst_t const * +app_usbd_cdc_acm_class_inst_get(app_usbd_cdc_acm_t const * p_cdc_acm) +{ + return &p_cdc_acm->base; +} + +/** + * @brief Helper function to get cdc_acm specific request from cdc_acm class. + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF). + * + * @return CDC ACM class specific request. + */ +static inline app_usbd_cdc_acm_req_t * +app_usbd_cdc_acm_class_request_get(app_usbd_cdc_acm_t const * p_cdc_acm) +{ + return &p_cdc_acm->specific.p_data->ctx.request; +} + +/** + * @brief Helper function to get cdc_acm from base class instance. + * + * @param[in] p_inst Base class instance. + * + * @return CDC ACM class handle. + */ +static inline app_usbd_cdc_acm_t const * +app_usbd_cdc_acm_class_get(app_usbd_class_inst_t const * p_inst) +{ + return (app_usbd_cdc_acm_t const *)p_inst; +} + + +/** + * @brief Writes data to CDC ACM serial port. + * + * This is asynchronous call. User should wait for @ref APP_USBD_CDC_ACM_USER_EVT_TX_DONE event + * to be sure that all data has been sent and input buffer could be accessed again. + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF). + * @param[in] p_buf Input buffer. + * @param[in] length Input buffer length. + * + * @return Standard error code. + */ +ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm, + const void * p_buf, + size_t length); + +/** + * @brief Returns the amount of data to be read. + * + * This function should be used on @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event to get + * information how many bytes have been transfered. + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF). + * + * @return Amount of data transfered. + */ +size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm); + +/** + * @brief Reads data from CDC ACM serial port. + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF). + * @param[out] p_buf Output buffer. + * @param[in] length Output buffer length (must by multiple of @ref NRF_DRV_USBD_EPSIZE). + * + * @return Standard error code. + */ +ret_code_t app_usbd_cdc_acm_read(app_usbd_cdc_acm_t const * p_cdc_acm, + void * p_buf, + size_t length); +/** + * @brief Serial state notifications. + * */ +typedef enum { + APP_USBD_CDC_ACM_SERIAL_STATE_DCD = (1u << 0), /**< Notification bit DCD. */ + APP_USBD_CDC_ACM_SERIAL_STATE_DSR = (1u << 1), /**< Notification bit DSR. */ + APP_USBD_CDC_ACM_SERIAL_STATE_BREAK = (1u << 2), /**< Notification bit BREAK. */ + APP_USBD_CDC_ACM_SERIAL_STATE_RING = (1u << 3), /**< Notification bit RING. */ + APP_USBD_CDC_ACM_SERIAL_STATE_FRAMING = (1u << 4), /**< Notification bit FRAMING.*/ + APP_USBD_CDC_ACM_SERIAL_STATE_PARITY = (1u << 5), /**< Notification bit PARITY. */ + APP_USBD_CDC_ACM_SERIAL_STATE_OVERRUN = (1u << 6), /**< Notification bit OVERRUN.*/ +} app_usbd_cdc_acm_serial_state_t; + +/** + * @brief Serial line state. + */ +typedef enum { + APP_USBD_CDC_ACM_LINE_STATE_DTR = (1u << 0), /**< Line state bit DTR.*/ + APP_USBD_CDC_ACM_LINE_STATE_RTS = (1u << 1), /**< Line state bit RTS.*/ +} app_usbd_cdc_acm_line_state_t; + +/** + * @brief Serial state notification via IN interrupt endpoint. + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF). + * @param[in] serial_state Serial state notification type. + * @param[in] value Serial state value. + * + * @return Standard error code. + */ +ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm, + app_usbd_cdc_acm_serial_state_t serial_state, + bool value); + +/** + * @brief Control line value get. + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF). + * @param[in] line_state Line control value type. + * @param[out] value Line control value. + * + * @return Standard error code. + */ +ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_acm, + app_usbd_cdc_acm_line_state_t line_state, + uint32_t * value); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_CDC_ACM_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..9ffa5afa5815c93f047dd86dd76d039a219341ec --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h @@ -0,0 +1,221 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_CDC_ACM_INTERNAL_H__ +#define APP_USBD_CDC_ACM_INTERNAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "app_util.h" + +/** + * @defgroup app_usbd_cdc_acm_internal USB CDC ACM internals + * @ingroup app_usbd_cdc_acm + * @brief @tagAPI52840 Internals of the USB ACM class implementation. + * @{ + */ + +/** + * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF in cdc_acm class. + * + */ +APP_USBD_CLASS_FORWARD(app_usbd_cdc_acm); + +/*lint -save -e165*/ +/** + * @brief Forward declaration of @ref app_usbd_cdc_acm_user_event_e. + * + */ +enum app_usbd_cdc_acm_user_event_e; + +/*lint -restore*/ + +/** + * @brief User event handler. + * + * @param[in] p_inst Class instance. + * @param[in] event User event. + * + */ +typedef void (*app_usbd_cdc_acm_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst, + enum app_usbd_cdc_acm_user_event_e event); + +/** + * @brief CDC ACM class part of class instance data. + */ +typedef struct { + uint8_t const * p_raw_desc; //!< CDC ACM class descriptors. + size_t raw_desc_size; //!< CDC ACM class descriptors size. + + app_usbd_cdc_acm_user_ev_handler_t user_ev_handler; //!< User event handler. +} app_usbd_cdc_acm_inst_t; + + +/** + * @brief CDC ACM serial state class notify + */ +typedef struct { + app_usbd_cdc_notify_t cdc_notify; //!< CDC notify. + uint16_t serial_state; //!< Serial port state. +} app_usbd_cdc_acm_notify_t; + +/** + * @brief CDC ACM class specific request handled via control endpoint. + */ +typedef struct { + uint8_t type; //!< Request type. + uint8_t len; //!< Request length. + + union { + app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding. + app_usbd_cdc_acm_notify_t notify; //!< CDC ACM class notify. + } payload; +} app_usbd_cdc_acm_req_t; + + +/** + * @brief CDC ACM class context + */ +typedef struct { + app_usbd_cdc_acm_req_t request; //!< CDC ACM class request. + app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding. + + uint16_t line_state; //!< CDC ACM line state bitmap, DTE side. + uint16_t serial_state; //!< CDC ACM serial state bitmap, DCE side. +} app_usbd_cdc_acm_ctx_t; + + +/** + * @brief CDC ACM class configuration macro. + * + * Used by @ref APP_USBD_CDC_ACM_GLOBAL_DEF + * + * @param iface_comm Interface number of cdc_acm control. + * @param epin_comm COMM subclass IN endpoint. + * @param iface_data Interface number of cdc_acm DATA. + * @param epin_data COMM subclass IN endpoint. + * @param epout_data COMM subclass OUT endpoint. + * + */ +#define APP_USBD_CDC_ACM_CONFIG(iface_comm, epin_comm, iface_data, epin_data, epout_data) \ + ((iface_comm, epin_comm), \ + (iface_data, epin_data, epout_data)) + + +/** + * @brief Specific class constant data for cdc_acm class. + * + * @ref app_usbd_cdc_acm_inst_t + */ +#define APP_USBD_CDC_ACM_INSTANCE_SPECIFIC_DEC app_usbd_cdc_acm_inst_t inst; + + +/** + * @brief Configures cdc_acm class instance. + * + * @param descriptors Mass storage class descriptors (raw table). + * @param user_event_handler User event handler. + */ +#define APP_USBD_CDC_ACM_INST_CONFIG(descriptors, user_event_handler) \ + .inst = { \ + .p_raw_desc = descriptors, \ + .raw_desc_size = sizeof(descriptors), \ + .user_ev_handler = user_event_handler, \ + } + +/** + * @brief Specific class data for cdc_acm class. + * + * @ref app_usbd_cdc_acm_ctx_t + */ +#define APP_USBD_CDC_ACM_DATA_SPECIFIC_DEC app_usbd_cdc_acm_ctx_t ctx; + + +/** + * @brief CDC ACM class descriptors config macro. + * + * @param interface_number Interface number. + * @param ... Extracted endpoint list. + */ +#define APP_USBD_CDC_ACM_DSC_CONFIG(interface_number, ...) { \ + APP_USBD_CDC_ACM_INTERFACE_DSC(interface_number, \ + 0, \ + 0, \ + APP_USBD_CDC_ACM_SUBCLASS_CDC_ACMCONTROL) \ +} + +/** + * @brief Public cdc_acm class interface. + * + */ +extern const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods; + +/** + * @brief Global definition of @ref app_usbd_cdc_acm_t class. + * + * @param instance_name Name of global instance. + * @param interfaces_configs Interfaces configurations. + * @param user_ev_handler User event handler (optional). + * @param raw_descriptors Raw descriptor table. + */ +#define APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \ + interfaces_configs, \ + user_ev_handler, \ + raw_descriptors) \ + APP_USBD_CLASS_INST_GLOBAL_DEF( \ + instance_name, \ + app_usbd_cdc_acm, \ + &app_usbd_cdc_acm_class_methods, \ + interfaces_configs, \ + (APP_USBD_CDC_ACM_INST_CONFIG(raw_descriptors, user_ev_handler)) \ + ) + + +/** @} */ + + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_CDC_ACM_INTERNAL_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..9154c3098a8958c0436034b074fa950f0c4cb425 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h @@ -0,0 +1,208 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_CDC_DESC_H__ +#define APP_USBD_CDC_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "app_usbd_descriptor.h" +#include "app_usbd_cdc_types.h" + +/** + * @defgroup app_usbd_cdc_desc CDC class descriptors + * @brief @tagAPI52840 Descriptors used in the USB CDC class implementation. + * @ingroup app_usbd_cdc_acm + * + * A group of macros used to initialize CDC descriptors + * @{ + */ + +/** + * @brief Initializer of IAD descriptor for CDC class. + * + * @param interface_number Interface number. + * @param subclass Subclass, @ref app_usbd_cdc_subclass_t. + * @param protocol Protocol, @ref app_usbd_cdc_comm_protocol_t. + */ +#define APP_USBD_CDC_IAD_DSC(interface_number, subclass, protocol) \ + /*.bLength = */ sizeof(app_usbd_descriptor_iad_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION, \ + /*.bFirstInterface = */ interface_number, \ + /*.bInterfaceCount = */ 2, \ + /*.bFunctionClass = */ APP_USBD_CDC_COMM_CLASS, \ + /*.bFunctionSubClass = */ subclass, \ + /*.bFunctionProtocol = */ protocol, \ + /*.iFunction = */ 0, \ + +/** + * @brief Initializer of interface descriptor for CDC COMM class. + * + * @param interface_number Interface number. + * @param subclass Subclass, @ref app_usbd_cdc_subclass_t. + * @param protocol Protocol, @ref app_usbd_cdc_comm_protocol_t. + */ +#define APP_USBD_CDC_COMM_INTERFACE_DSC(interface_number, subclass, protocol) \ + /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \ + /*.bInterfaceNumber = */ interface_number, \ + /*.bAlternateSetting = */ 0x00, \ + /*.bNumEndpoints = */ 1, \ + /*.bInterfaceClass = */ APP_USBD_CDC_COMM_CLASS, \ + /*.bInterfaceSubClass = */ subclass, \ + /*.bInterfaceProtocol = */ protocol, \ + /*.iInterface = 0, */ 0x00, \ + + +/** + * @brief Initializer of interface descriptor for CDC DATA class. + * + * @param interface_number Interface number. + * @param subclass Subclass, @ref app_usbd_cdc_subclass_t. + * @param protocol Protocol, @ref app_usbd_cdc_data_protocol_t. + */ +#define APP_USBD_CDC_DATA_INTERFACE_DSC(interface_number, subclass, protocol) \ + /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \ + /*.bInterfaceNumber = */ interface_number, \ + /*.bAlternateSetting = */ 0x00, \ + /*.bNumEndpoints = */ 2, \ + /*.bInterfaceClass = */ APP_USBD_CDC_DATA_CLASS, \ + /*.bInterfaceSubClass = */ subclass, \ + /*.bInterfaceProtocol = */ protocol, \ + /*.iInterface = 0, */ 0x00, \ + + + +/** + * @brief Initializer of endpoint descriptor for CDC COM class. + * + * @param endpoint_in IN endpoint. + * @param ep_size Endpoint size. + */ +#define APP_USBD_CDC_COM_EP_DSC(endpoint_in, ep_size) \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ endpoint_in, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ 16, \ + +/** + * @brief Initializer of endpoint descriptors for CDC DATA class. + * + * @param endpoint_in IN endpoint. + * @param endpoint_out OUT endpoint. + * @param ep_size Endpoint size. + */ +#define APP_USBD_CDC_DATA_EP_DSC(endpoint_in, endpoint_out, ep_size) \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ endpoint_in, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ 0, \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ endpoint_out, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ 0, \ + +/** + * @brief Initializer of endpoint descriptors for CDC header descriptor. + * + * @param bcd_cdc BCD CDC version. + */ +#define APP_USBD_CDC_HEADER_DSC(bcd_cdc) \ + /*.bLength = */ sizeof(app_usbd_cdc_desc_header_t), \ + /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_HEADER, \ + /*.bcdCDC = */ APP_USBD_U16_TO_RAW_DSC(bcd_cdc), \ + +/** + * @brief Initializer of endpoint descriptors for CDC call management descriptor. + * + * @param capabilities Capabilities. + * @param data_interface Data interface. + */ +#define APP_USBD_CDC_CALL_MGMT_DSC(capabilities, data_interface) \ + /*.bLength = */ sizeof(app_usbd_cdc_desc_call_mgmt_t), \ + /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_CALL_MGMT, \ + /*.bmCapabilities = */ capabilities, \ + /*.bDataInterface = */ data_interface, \ + + +/** + * @brief Initializer of endpoint descriptors for CDC DATA class. + * + * @param capabilities Capabilities. + */ +#define APP_USBD_CDC_ACM_DSC(capabilities) \ + /*.bLength = */ sizeof(app_usbd_cdc_desc_acm_t), \ + /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_ACM, \ + /*.bmCapabilities = */ capabilities, \ + +/** + * @brief Initializer of endpoint descriptors for CDC DATA class. + * + * @param control_interface Control interface. + * @param ... Subordinate interfaces list. + */ +#define APP_USBD_CDC_UNION_DSC(control_interface, ...) \ + /*.bLength = */ sizeof(app_usbd_cdc_desc_union_t) + (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_UNION, \ + /*.bControlInterface = */ control_interface, \ + /*.bSubordinateInterface = */ __VA_ARGS__, \ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_CDC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h new file mode 100644 index 0000000000000000000000000000000000000000..5f0a70a6acad2ffd403ad71f877c16f97469a9c1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h @@ -0,0 +1,360 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_CDC_TYPES_H__ +#define APP_USBD_CDC_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + +/** + * @defgroup app_usbd_cdc_types CDC class types + * @ingroup app_usbd_cdc_acm + * + * @brief @tagAPI52840 Variable types used by the CDC class implementation. + * @{ + */ + +/** + * @brief Communications Interface Class code. + * + * Used for control interface in communication class. + * @ref app_usbd_descriptor_iface_t::bInterfaceClass + */ +#define APP_USBD_CDC_COMM_CLASS 0x02 + +/** + * @brief Data Class Interface code. + * + * Used for data interface in communication class. + * @ref app_usbd_descriptor_iface_t::bInterfaceClass + */ +#define APP_USBD_CDC_DATA_CLASS 0x0A + +/** + * @brief CDC subclass possible values. + * + * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass + */ +typedef enum { + APP_USBD_CDC_SUBCLASS_RESERVED = 0x00, /**< Reserved in documentation. */ + APP_USBD_CDC_SUBCLASS_DLCM = 0x01, /**< Direct Line Control Model. */ + APP_USBD_CDC_SUBCLASS_ACM = 0x02, /**< Abstract Control Model. */ + APP_USBD_CDC_SUBCLASS_TCM = 0x03, /**< Telephone Control Model. */ + APP_USBD_CDC_SUBCLASS_MCCM = 0x04, /**< Multi-Channel Control Model. */ + APP_USBD_CDC_SUBCLASS_CAPI = 0x05, /**< CAPI Control Model. */ + APP_USBD_CDC_SUBCLASS_ENCM = 0x06, /**< Ethernet Networking Control Model. */ + APP_USBD_CDC_SUBCLASS_ATM = 0x07, /**< ATM Networking Control Model. */ + APP_USBD_CDC_SUBCLASS_WHCM = 0x08, /**< Wireless Handset Control Model. */ + APP_USBD_CDC_SUBCLASS_DM = 0x09, /**< Device Management. */ + APP_USBD_CDC_SUBCLASS_MDLM = 0x0A, /**< Mobile Direct Line Model. */ + APP_USBD_CDC_SUBCLASS_OBEX = 0x0B, /**< OBEX. */ + APP_USBD_CDC_SUBCLASS_EEM = 0x0C, /**< Ethernet Emulation Model. */ + APP_USBD_CDC_SUBCLASS_NCM = 0x0D /**< Network Control Model. */ +} app_usbd_cdc_subclass_t; + +/** + * @brief CDC protocol possible values. + * + * @ref app_usbd_descriptor_iface_t::bInterfaceProtocol + */ +typedef enum { + APP_USBD_CDC_COMM_PROTOCOL_NONE = 0x00, /**< No class specific protocol required. */ + APP_USBD_CDC_COMM_PROTOCOL_AT_V250 = 0x01, /**< AT Commands: V.250 etc. */ + APP_USBD_CDC_COMM_PROTOCOL_AT_PCCA101 = 0x02, /**< AT Commands defined by PCCA-101. */ + APP_USBD_CDC_COMM_PROTOCOL_AT_PCCA101_ANNEXO = 0x03, /**< AT Commands defined by PCCA-101 & Annex O. */ + APP_USBD_CDC_COMM_PROTOCOL_AT_GSM707 = 0x04, /**< AT Commands defined by GSM 07.07. */ + APP_USBD_CDC_COMM_PROTOCOL_AT_3GPP_27007 = 0x05, /**< AT Commands defined by 3GPP 27.007. */ + APP_USBD_CDC_COMM_PROTOCOL_AT_CDMA = 0x06, /**< AT Commands defined by TIA for CDMA. */ + APP_USBD_CDC_COMM_PROTOCOL_EEM = 0x07, /**< Ethernet Emulation Model. */ + APP_USBD_CDC_COMM_PROTOCOL_EXTERNAL = 0xFE, /**< External Protocol: Commands defined by Command Set Functional Descriptor. */ + APP_USBD_CDC_COMM_PROTOCOL_VENDOR = 0xFF /**< Vendor-specific. */ +} app_usbd_cdc_comm_protocol_t; + +/** + * @brief CDC data interface protocols possible values. + */ +typedef enum { + APP_USBD_CDC_DATA_PROTOCOL_NONE = 0x00, /**< No class specific protocol required. */ + APP_USBD_CDC_DATA_PROTOCOL_NTB = 0x01, /**< Network Transfer Block. */ + APP_USBD_CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, /**< Physical interface protocol for ISDN BRI. */ + APP_USBD_CDC_DATA_PROTOCOL_HDLC = 0x31, /**< HDLC. */ + APP_USBD_CDC_DATA_PROTOCOL_TRANSPARENT = 0x32, /**< Transparent. */ + APP_USBD_CDC_DATA_PROTOCOL_Q921M = 0x50, /**< Management protocol for Q.921 data link protocol. */ + APP_USBD_CDC_DATA_PROTOCOL_Q921 = 0x51, /**< Data link protocol for Q.921. */ + APP_USBD_CDC_DATA_PROTOCOL_Q921TM = 0x52, /**< TEI-multiplexor for Q.921 data link protocol. */ + APP_USBD_CDC_DATA_PROTOCOL_V42BIS = 0x90, /**< Data compression procedures. */ + APP_USBD_CDC_DATA_PROTOCOL_Q931 = 0x91, /**< Euro-ISDN protocol control. */ + APP_USBD_CDC_DATA_PROTOCOL_V120 = 0x92, /**< V.24 rate adaptation to ISDN. */ + APP_USBD_CDC_DATA_PROTOCOL_CAPI20 = 0x93, /**< CAPI Commands. */ + APP_USBD_CDC_DATA_PROTOCOL_HOST = 0xFD, /**< Host based driver. + * @note This protocol code should only be used in messages + * between host and device to identify the host driver portion + * of a protocol stack. + */ + APP_USBD_CDC_DATA_PROTOCOL_EXTERNAL = 0xFE, /**< The protocol(s) are described using a Protocol Unit Functional + * Descriptors on Communications Class Interface. + */ + APP_USBD_CDC_DATA_PROTOCOL_VENDOR = 0xFF /**< Vendor-specific. */ +} app_usbd_cdc_data_protocol_t; + +/** + * @brief CDC Functional Descriptor types. + */ +typedef enum { + APP_USBD_CDC_CS_INTERFACE = 0x24, /**< Class specific interface descriptor type.*/ + APP_USBD_CDC_CS_ENDPOINT = 0x25 /**< Class specific endpoint descriptor type.*/ +} app_usbd_cdc_func_type_t; + +/** + * @brief CDC Functional Descriptor subtypes + */ +typedef enum { + APP_USBD_CDC_SCS_HEADER = 0x00, /**< Header Functional Descriptor, which marks the beginning of the concatenated set of functional descriptors for the interface. */ + APP_USBD_CDC_SCS_CALL_MGMT = 0x01, /**< Call Management Functional Descriptor. */ + APP_USBD_CDC_SCS_ACM = 0x02, /**< Abstract Control Management Functional Descriptor. */ + APP_USBD_CDC_SCS_DLM = 0x03, /**< Direct Line Management Functional Descriptor. */ + APP_USBD_CDC_SCS_TEL_R = 0x04, /**< Telephone Ringer Functional Descriptor. */ + APP_USBD_CDC_SCS_TEL_CAP = 0x05, /**< Telephone Call and Line State Reporting Capabilities Functional Descriptor. */ + APP_USBD_CDC_SCS_UNION = 0x06, /**< Union Functional Descriptor. */ + APP_USBD_CDC_SCS_COUNTRY_SEL = 0x07, /**< Country Selection Functional Descriptor. */ + APP_USBD_CDC_SCS_TEL_OM = 0x08, /**< Telephone Operational Modes Functional Descriptor. */ + APP_USBD_CDC_SCS_USB_TERM = 0x09, /**< USB Terminal Functional Descriptor. */ + APP_USBD_CDC_SCS_NCT = 0x0A, /**< Network Channel Terminal Descriptor. */ + APP_USBD_CDC_SCS_PU = 0x0B, /**< Protocol Unit Functional Descriptor. */ + APP_USBD_CDC_SCS_EU = 0x0C, /**< Extension Unit Functional Descriptor. */ + APP_USBD_CDC_SCS_MCM = 0x0D, /**< Multi-Channel Management Functional Descriptor. */ + APP_USBD_CDC_SCS_CAPI = 0x0E, /**< CAPI Control Management Functional Descriptor. */ + APP_USBD_CDC_SCS_ETH = 0x0F, /**< Ethernet Networking Functional Descriptor. */ + APP_USBD_CDC_SCS_ATM = 0x10, /**< ATM Networking Functional Descriptor. */ + APP_USBD_CDC_SCS_WHCM = 0x11, /**< Wireless Handset Control Model Functional Descriptor. */ + APP_USBD_CDC_SCS_MDLM = 0x12, /**< Mobile Direct Line Model Functional Descriptor. */ + APP_USBD_CDC_SCS_MDLM_DET = 0x13, /**< MDLM Detail Functional Descriptor. */ + APP_USBD_CDC_SCS_DMM = 0x14, /**< Device Management Model Functional Descriptor. */ + APP_USBD_CDC_SCS_OBEX = 0x15, /**< OBEX Functional Descriptor. */ + APP_USBD_CDC_SCS_CS = 0x16, /**< Command Set Functional Descriptor. */ + APP_USBD_CDC_SCS_CS_DET = 0x17, /**< Command Set Detail Functional Descriptor. */ + APP_USBD_CDC_SCS_TEL_CM = 0x18, /**< Telephone Control Model Functional Descriptor. */ + APP_USBD_CDC_SCS_OBEX_SI = 0x19, /**< OBEX Service Identifier Functional Descriptor. */ + APP_USBD_CDC_SCS_NCM = 0x1A /**< NCM Functional Descriptor. */ +} app_usbd_cdc_func_subtype_t; + +/* Make all descriptors packed */ +#pragma pack(push, 1) + +/** + * @brief Header Functional Descriptor + */ +typedef struct { + uint8_t bFunctionLength; //!< Size of this descriptor in bytes. + uint8_t bDescriptorType; //!< @ref APP_USBD_CDC_CS_INTERFACE descriptor type. + uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_HEADER. + uint8_t bcdCDC[2]; //!< USB Class Definitions for Communications Devices Specification release number in binary-coded decimal. +} app_usbd_cdc_desc_header_t; + +/** + * @brief Call management capabilities. + * + * @ref app_usbd_cdc_desc_call_mgmt_t::bmCapabilities bit + * */ +typedef enum { + APP_USBD_CDC_CALL_MGMT_SUPPORTED = (1 << 0), /**< Call management capability bit 0.*/ + APP_USBD_CDC_CALL_MGMT_OVER_DCI = (1 << 1), /**< Call management capability bit 1.*/ +} app_subd_cdc_call_mgmt_cap_t; + +/** + * @brief CDC Call Management Functional Descriptor. + */ +typedef struct { + uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes. + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE. + uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_CALL_MGMT. + uint8_t bmCapabilities; //!< Capabilities @ref app_subd_cdc_call_mgmt_cap_t. + uint8_t bDataInterface; //!< Data interface number. +} app_usbd_cdc_desc_call_mgmt_t; + +/** + * @brief ACM capabilities. + * + * @ref app_usbd_cdc_desc_acm_t::bmCapabilities bit + * */ +typedef enum { + APP_USBD_CDC_ACM_FEATURE_REQUESTS = (1 << 0), /**< ACM capability bit FEATURE_REQUESTS. */ + APP_USBD_CDC_ACM_LINE_REQUESTS = (1 << 1), /**< ACM capability bit LINE_REQUESTS. */ + APP_USBD_CDC_ACM_SENDBREAK_REQUESTS = (1 << 2), /**< ACM capability bit SENDBREAK_REQUESTS.*/ + APP_USBD_CDC_ACM_NOTIFY_REQUESTS = (1 << 3), /**< ACM capability bit NOTIFY_REQUESTS. */ +} app_subd_cdc_acm_cap_t; + +/** + * @brief CDC ACM Functional Descriptor. + */ +typedef struct { + uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes. + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE. + uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_ACM. + uint8_t bmCapabilities; //!< Capabilities @ref app_subd_cdc_acm_cap_t. +} app_usbd_cdc_desc_acm_t; + +/** + * @brief Union Functional Descriptor. + */ +typedef struct { + uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes. + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE. + uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_UNION. + uint8_t bControlInterface; //!< The interface number of the Communications or Data Class interface, designated as the controlling interface for the union. + uint8_t bSubordinateInterface[]; //!< Interface number of subordinate interfaces in the union. Number of interfaced depends on descriptor size. +} app_usbd_cdc_desc_union_t; + +/** + * @brief Country Selection Functional Descriptor. + */ +typedef struct { + uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes. + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE. + uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_COUNTRY_SEL. + uint8_t iCountryCodeRelDate; //!< Index of a string giving the release date for the implemented ISO 3166 Country Codes. +} app_usbd_cdc_desc_country_sel_t; + +/** + * @brief CDC Requests + * + */ +typedef enum { + /* CDC General */ + APP_USBD_CDC_REQ_SEND_ENCAPSULATED_COMMAND = 0x00, /**< This request is used to issue a command in the format of the supported control protocol of the Communications Class interface. */ + APP_USBD_CDC_REQ_GET_ENCAPSULATED_RESPONSE = 0x01, /**< This request is used to request a response in the format of the supported control protocol of the Communications Class interface. */ + /* CDC PSTN */ + APP_USBD_CDC_REQ_SET_COMM_FEATURE = 0x02, /**< This request controls the settings for a particular communications feature of a particular target. */ + APP_USBD_CDC_REQ_GET_COMM_FEATURE = 0x03, /**< This request returns the current settings for the communications feature as selected. */ + APP_USBD_CDC_REQ_CLEAR_COMM_FEATURE = 0x04, /**< This request controls the settings for a particular communications feature of a particular target, setting the selected feature to its default state. */ + APP_USBD_CDC_REQ_SET_AUX_LINE_STATE = 0x10, /**< This request is used to connect or disconnect a secondary jack to POTS circuit or CODEC, depending on hook state. */ + APP_USBD_CDC_REQ_SET_HOOK_STATE = 0x11, /**< This request is used to set the necessary PSTN line relay code for on-hook, off-hook, and caller ID states. */ + APP_USBD_CDC_REQ_PULSE_SETUP = 0x12, /**< This request is used to prepare for a pulse-dialing cycle. */ + APP_USBD_CDC_REQ_SEND_PULSE = 0x13, /**< This request is used to generate a specified number of make/break pulse cycles. */ + APP_USBD_CDC_REQ_SET_PULSE_TIME = 0x14, /**< This request sets the timing of the make and break periods for pulse dialing. */ + APP_USBD_CDC_REQ_RING_AUX_JACK = 0x15, /**< This request is used to generate a ring signal on a secondary phone jack. */ + APP_USBD_CDC_REQ_SET_LINE_CODING = 0x20, /**< This request allows the host to specify typical asynchronous line-character formatting properties. */ + APP_USBD_CDC_REQ_GET_LINE_CODING = 0x21, /**< This request allows the host to find out the currently configured line coding. */ + APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE = 0x22, /**< This request generates RS-232/V.24 style control signals. */ + APP_USBD_CDC_REQ_SEND_BREAK = 0x23, /**< This request sends special carrier modulation that generates an RS-232 style break. */ + APP_USBD_CDC_REQ_SET_RINGER_PARMS = 0x30, /**< This request configures the ringer for the communications device. */ + APP_USBD_CDC_REQ_GET_RINGER_PARMS = 0x31, /**< This request returns the ringer capabilities of the device and the current status of the device’s ringer. */ + APP_USBD_CDC_REQ_SET_OPERATION_PARMS = 0x32, /**< Sets the operational mode for the device, between a simple mode, standalone mode and a host centric mode. */ + APP_USBD_CDC_REQ_GET_OPERATION_PARMS = 0x33, /**< This request gets the current operational mode for the device. */ + APP_USBD_CDC_REQ_SET_LINE_PARMS = 0x34, /**< This request is used to change the state of the line, corresponding to the interface or master interface of a union to which the command was sent. */ + APP_USBD_CDC_REQ_GET_LINE_PARMS = 0x35, /**< This request is used to report the state of the line that corresponds to the interface or master interface of a union to which the command was sent. */ + APP_USBD_CDC_REQ_DIAL_DIGITS = 0x36, /**< This request dials the DTMF digits over the specified line. */ +} app_usbd_cdc_req_id_t; + +/** + * @brief CDC Notifications. + */ +typedef enum { + /* CDC General */ + APP_USBD_CDC_NOTIF_NETWORK_CONNECTION = 0x00, /**< This notification allows the device to notify the host about network connection status. */ + APP_USBD_CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, /**< This notification allows the device to notify the host that a response is available. + * This response can be retrieved with a subsequent GetEncapsulatedResponse request. + _ */ + APP_USBD_CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A, /**< This notification allows the device to inform the host-networking driver + * that a change in either the up-link or the down-link bit rate of the connection has occurred. + */ + /* CDC PSTN */ + APP_USBD_CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, /**< (DLM) This notification indicates the loop has changed on the auxiliary phone interface of the USB device. */ + APP_USBD_CDC_NOTIF_RING_DETECT = 0x09, /**< (DLM) This notification indicates ring voltage on the POTS line interface of the USB device. */ + APP_USBD_CDC_NOTIF_SERIAL_STATE = 0x20, /**< (ACM) This notification sends asynchronous notification of UART status. */ + APP_USBD_CDC_NOTIF_CALL_STATE_CHANGE = 0x28, /**< (TCM) This notification identifies that a change has occurred to the state of a call on the line corresponding to the interface or union for the line. */ + APP_USBD_CDC_NOTIF_LINE_STATE_CHANGE = 0x29 /**< (TCM) This notification identifies that a change has occurred to the state of the line corresponding to the interface or master interface of a union sending the notification message. */ +} app_usbd_cdc_notify_id_t; + +/** + * @brief Notification sent via CDC COMM endpoint. + * */ +typedef struct { + uint8_t bmRequestType; //!< Request type. + uint8_t bmRequest; //!< Request ID @ref app_usbd_cdc_req_id_t. + uint16_t wValue; //!< Value field. + uint16_t wIndex; //!< Index field. + uint16_t wLength; //!< Length of payload following. +} app_usbd_cdc_notify_t; + +/** + * @brief CDC line coding structure. + */ +typedef struct { + uint8_t dwDTERate[4]; //!< Line baudrate. + uint8_t bCharFormat; //!< Character format @ref app_usbd_cdc_line_stopbit_t. + uint8_t bParityType; //!< Parity bits @ref app_usbd_cdc_line_parity_t. + uint8_t bDataBits; //!< Number of data bits. +} app_usbd_cdc_line_coding_t; + +/** + * @brief Possible values of @ref app_usbd_cdc_line_coding_t::bCharFormat. + */ +typedef enum { + APP_USBD_CDC_LINE_STOPBIT_1 = 0, /**< 1 stop bit. */ + APP_USBD_CDC_LINE_STOPBIT_1_5 = 1, /**< 1.5 stop bits. */ + APP_USBD_CDC_LINE_STOPBIT_2 = 2, /**< 2 stop bits. */ +} app_usbd_cdc_line_stopbit_t; + +/** + * @brief Possible values of @ref app_usbd_cdc_line_coding_t::bParityType. + */ +typedef enum { + APP_USBD_CDC_LINE_PARITY_NONE = 0, /**< No parity. */ + APP_USBD_CDC_LINE_PARITY_ODD = 1, /**< Odd parity. */ + APP_USBD_CDC_LINE_PARITY_EVEN = 2, /**< Even parity. */ + APP_USBD_CDC_LINE_PARITY_MARK = 3, /**< Parity forced to 0 (space).*/ + APP_USBD_CDC_LINE_PARITY_SPACE = 4, /**< Parity forced to 1 (mark). */ +} app_usbd_cdc_line_parity_t; + + +#pragma pack(pop) + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_TYPES_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/app_usbd_hid.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/app_usbd_hid.c new file mode 100644 index 0000000000000000000000000000000000000000..9e44c41a73bec1ccde58483136ec1fabc9db3e61 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/app_usbd_hid.c @@ -0,0 +1,481 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_CLASS_HID_ENABLED +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_hid.h" + +/** + * @ingroup app_usbd_hid_internals USBD HID internals + * @{ + * @ingroup app_usbd_hid + * @internal + */ + +/** + * @brief Test whether SOF HID transfer is required. + * + * This function handles idle period IN transfer. + * + * @param[in,out] p_hid_ctx Internal HID context. + * @param framecnt SOF event frame counter. + * + * @retval true Idle transfer is required. + * @retval false Idle transfer is not required. + */ +static bool hid_sof_required(app_usbd_hid_ctx_t * p_hid_ctx, uint16_t framecnt) +{ + if (p_hid_ctx->idle_rate == 0) + { + /* Infinite idle rate */ + return false; + } + + /*Idle rate has 4ms units. Every SOF event is generated with 1ms period.*/ + uint16_t rate_ms = p_hid_ctx->idle_rate * 4; + if ((framecnt % rate_ms) != 0) + { + /* Idle transfer not required yet*/ + return false; + } + + if (p_hid_ctx->access_lock) + { + /* Access to internal data locked. Buffer is BUSY. + * Don't send anything. Clear transfer flag. Next transfer will be triggered + * from API context.*/ + app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + return false; + } + + if (app_usbd_hid_trans_required(p_hid_ctx)) + { + /*New transfer need to be triggered*/ + return true; + } + + return false; +} + +/** + * @brief User event handler. + * + * @param[in] p_inst Class instance. + * @param[in] p_hinst HID class instance. + * @param[in] event user Event type. + */ +static inline void user_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_user_event_t event) +{ + if (p_hinst->user_event_handler != NULL) + { + p_hinst->user_event_handler(p_inst, event); + } +} + +/** + * @brief Internal SETUP standard IN request handler. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_hinst HID class instance. + * @param[in,out] p_hid_ctx HID context. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_setup_evt_t const * p_setup_ev) +{ + /*Only Get Descriptor standard IN request is supported by HID class*/ + if (p_setup_ev->setup.bmRequest != APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + + size_t dsc_len = 0; + + /* Try to find descriptor in class internals*/ + void const * p_dsc = app_usbd_class_descriptor_find(p_inst, + p_setup_ev->setup.wValue.hb, + p_setup_ev->setup.wValue.lb, + &dsc_len); + if (p_dsc != NULL) + { + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_dsc, dsc_len); + } + + + /* HID specific descriptors*/ + switch (p_setup_ev->setup.wValue.hb) + { + case APP_USBD_HID_DESCRIPTOR_REPORT: + { + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + p_hinst->p_report_dsc, + p_hinst->report_dsc_size); + } + case APP_USBD_HID_DESCRIPTOR_PHYSICAL: + /*Not supported*/ + break; + default: + /*Not supported*/ + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP standard OUT request handler. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_hinst HID class instance. + * @param[in,out] p_hid_ctx HID context. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_setup_evt_t const * p_setup_ev) +{ + /*Only Set Descriptor standard OUT request is supported by HID class. However, it is optional + * and useless in HID cases.*/ + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP class IN request handler. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_hinst HID class instance. + * @param[in,out] p_hid_ctx HID context. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_setup_evt_t const * p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_HID_REQ_GET_REPORT: + { + /*Only input report is supported. Same format as over IN pipe.*/ + if (p_setup_ev->setup.wValue.hb != APP_USBD_HID_REPORT_TYPE_INPUT) + { + break; + } + + return p_hinst->p_hid_methods->on_get_report(p_inst, p_setup_ev); + } + case APP_USBD_HID_REQ_GET_IDLE: + { + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + &p_hid_ctx->idle_rate, + sizeof(p_hid_ctx->idle_rate)); + } + case APP_USBD_HID_REQ_GET_PROTOCOL: + { + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + &p_hid_ctx->protocol, + sizeof(p_hid_ctx->protocol)); + } + default: + break; + + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP class OUT request handler. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_hinst HID class instance. + * @param[in,out] p_hid_ctx HID context. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_setup_evt_t const * p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_HID_REQ_SET_REPORT: + if (p_setup_ev->setup.wValue.hb != APP_USBD_HID_REPORT_TYPE_OUTPUT) + { + break; + } + + if (p_hinst->p_hid_methods->on_get_report == NULL) + { + break; + } + + return p_hinst->p_hid_methods->on_set_report(p_inst, p_setup_ev); + case APP_USBD_HID_REQ_SET_IDLE: + p_hid_ctx->idle_rate = p_setup_ev->setup.wValue.hb; + return NRF_SUCCESS; + case APP_USBD_HID_REQ_SET_PROTOCOL: + p_hid_ctx->protocol = p_setup_ev->setup.wValue.w; + { + app_usbd_hid_user_event_t ev = (p_hid_ctx->protocol == 0) ? + APP_USBD_HID_USER_EVT_SET_BOOT_PROTO : + APP_USBD_HID_USER_EVT_SET_REPORT_PROTO; + + user_event_handler(p_inst, p_hinst, ev); + } + return NRF_SUCCESS; + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP event handler. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_hinst HID class instance. + * @param[in,out] p_hid_ctx HID context. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_setup_evt_t const * p_setup_ev) +{ + ASSERT(p_hinst != NULL); + ASSERT(p_hid_ctx != NULL); + ASSERT(p_setup_ev != NULL); + + if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN) + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_in(p_inst, p_hinst, p_hid_ctx, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_in(p_inst, p_hinst, p_hid_ctx, p_setup_ev); + default: + break; + } + } + else /*APP_USBD_SETUP_REQDIR_OUT*/ + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_out(p_inst, p_hinst, p_hid_ctx, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_out(p_inst, p_hinst, p_hid_ctx, p_setup_ev); + default: + break; + } + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Endpoint IN event handler. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_hinst HID class instance. + * @param[in,out] p_hid_ctx HID context. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t endpoint_in_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_complex_evt_t const * p_event) +{ + + if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_OK) + { + /* Notify user about last successful transfer. */ + user_event_handler(p_inst, p_hinst, APP_USBD_HID_USER_EVT_IN_REPORT_DONE); + } + + if (app_usbd_hid_access_lock_test(p_hid_ctx)) + { + /* Access to internal data locked. Buffer is BUSY. + * Don't send anything. Clear transfer flag. Next transfer will be triggered + * from main loop context.*/ + app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + return NRF_SUCCESS; + } + + return p_hinst->p_hid_methods->ep_transfer_in(p_inst); +} + +/** + * @brief Endpoint OUT event handler. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_hinst HID class instance. + * @param[in,out] p_hid_ctx HID context. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ +static ret_code_t endpoint_out_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_complex_evt_t const * p_event) +{ + if (p_hinst->p_hid_methods->ep_transfer_out == NULL) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_OK) + { + /* Notify user about last successful transfer. */ + user_event_handler(p_inst, p_hinst, APP_USBD_HID_USER_EVT_OUT_REPORT_READY); + } + + return p_hinst->p_hid_methods->ep_transfer_out(p_inst); +} + +/** @} */ + + +ret_code_t app_usbd_hid_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_complex_evt_t const * p_event) +{ + ret_code_t ret = NRF_SUCCESS; + switch (p_event->app_evt.type) + { + case APP_USBD_EVT_DRV_SOF: + if (!hid_sof_required(p_hid_ctx, p_event->drv_evt.data.sof.framecnt)) + { + break; + } + ret = p_hinst->p_hid_methods->ep_transfer_in(p_inst); + break; + case APP_USBD_EVT_DRV_RESET: + app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + break; + case APP_USBD_EVT_DRV_SETUP: + ret = setup_event_handler(p_inst, p_hinst, p_hid_ctx, &p_event->setup_evt); + break; + case APP_USBD_EVT_DRV_EPTRANSFER: + if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep)) + { + ret = endpoint_in_event_handler(p_inst, p_hinst, p_hid_ctx, p_event); + } + else + { + ret = endpoint_out_event_handler(p_inst, p_hinst, p_hid_ctx, p_event); + } + break; + case APP_USBD_EVT_DRV_SUSPEND: + app_usbd_hid_state_flag_set(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED); + break; + case APP_USBD_EVT_DRV_RESUME: + app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED); + + /* Always try to trigger transfer on resume event*/ + ret = p_hinst->p_hid_methods->ep_transfer_in(p_inst); + break; + case APP_USBD_EVT_INST_APPEND: + /*SOF register: GetIdle/SetIdle support*/ + ret = app_usbd_class_sof_register(p_inst); + if (ret != NRF_SUCCESS) + { + break; + } + app_usbd_core_class_rwu_register(p_inst); + app_usbd_hid_state_flag_set(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED); + break; + case APP_USBD_EVT_INST_REMOVE: + /*SOF unregister: GetIdle/SetIdle support*/ + ret = app_usbd_class_sof_unregister(p_inst); + if (ret != NRF_SUCCESS) + { + break; + } + + app_usbd_core_class_rwu_unregister(p_inst); + app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED); + break; + case APP_USBD_EVT_START: + app_usbd_hid_state_flag_set(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED); + break; + case APP_USBD_EVT_STOP: + app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED); + break; + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + return ret; +} + +app_usbd_hid_report_buffer_t * app_usbd_hid_rep_buff_in_get(app_usbd_hid_inst_t const * p_hinst) +{ + ASSERT(p_hinst); + return p_hinst->p_rep_buffer_in; +} + + +#endif // APP_USBD_CLASS_HID_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/app_usbd_hid.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/app_usbd_hid.h new file mode 100644 index 0000000000000000000000000000000000000000..6806bf433f1bf7b6c52bf215caae9dc992df69d0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/app_usbd_hid.h @@ -0,0 +1,447 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_HID_H__ +#define APP_USBD_HID_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "sdk_common.h" +#include "nrf_atomic.h" +#include "app_usbd_hid_types.h" +#include "app_usbd_core.h" + +/** + * @defgroup app_usbd_hid USB HID class + * @ingroup app_usbd + * + * @brief @tagAPI52840 Module with generic HID event data processing. + * @{ + */ + +#define APP_USBD_HID_IFACE_IDX 0 /**< HID instance interface index. */ +#define APP_USBD_HID_EPIN_IDX 0 /**< HID instance endpoint IN index. */ +#define APP_USBD_HID_EPOUT_IDX 1 /**< HID instance endpoint OUT index.*/ + +/** + * @brief HID context state flags. + * + * Bit numbers in @ref app_usbd_hid_ctx_t::state_flags. + */ +typedef enum { + APP_USBD_HID_STATE_FLAG_APPENDED = 0, /**< State flag APPENDED. */ + APP_USBD_HID_STATE_FLAG_STARTED = 1, /**< State flag STARTED. */ + APP_USBD_HID_STATE_FLAG_SUSPENDED = 2, /**< State flag SUSPENDED. */ + APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS = 3, /**< State flag TRANS_IN_PROGRESS. */ +} app_usbd_hid_state_flag_t; + + +/** + * @brief Events passed to user event handler. + * + * @note Example prototype of user event handler: + @code + void hid_user_ev_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_mouse_user_event_t event); + @endcode + */ +typedef enum { + APP_USBD_HID_USER_EVT_SET_BOOT_PROTO, /**< Event SET_BOOT_PROTOCOL. */ + APP_USBD_HID_USER_EVT_SET_REPORT_PROTO, /**< Event SET_REPORT_PROTOCOL.*/ + APP_USBD_HID_USER_EVT_OUT_REPORT_READY, /**< Event OUT_REPORT_READY. */ + APP_USBD_HID_USER_EVT_IN_REPORT_DONE, /**< Event IN_REPORT_DONE. */ +} app_usbd_hid_user_event_t; + +/** + * @brief User event handler. + * + * @param[in] p_inst Class instance. + * @param[in] event User event. + */ +typedef void (*app_usbd_hid_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_user_event_t event); + +/**@brief HID unified interface*/ +typedef struct { + + /** + * @brief Function called on HID specific, GetReport request. + * + * This function should trigger data write to control pipe. + * + * @param[in] p_inst Class instance. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ + ret_code_t (*on_get_report)(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev); + + /** + * @brief Function called on HID specific, SetReport request. + * + * This function should trigger data read from control pipe. This function is not required and + * NULL could be pinned to this handler when output report is not defined in report descriptor. + * + * @param[in] p_inst Class instance. + * @param[in] p_setup_ev Setup event. + * + * @return Standard error code. + */ + ret_code_t (*on_set_report)(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev); + + /** + * @brief Function called on IN endpoint transfer. + * + * This function should trigger next endpoint IN transfer if required. + * + * @param[in] p_inst Class instance. + * + * @return Standard error code. + */ + ret_code_t (*ep_transfer_in)(app_usbd_class_inst_t const * p_inst); + + /** + * @brief Function called on OUT endpoint transfer. + * + * This function should should read data from OUT endpoint. This function is not required and + * NULL could be pinned to this handler when class doesn't have OUT endpoint. + * + * @param[in] p_inst Class instance. + * + * @return Standard error code. + */ + ret_code_t (*ep_transfer_out)(app_usbd_class_inst_t const * p_inst); +} app_usbd_hid_methods_t; + +/** + * @brief HID report buffers. + */ +typedef struct { + uint8_t * p_buff; + size_t size; +} app_usbd_hid_report_buffer_t; + + + +/**@brief Define OUT report buffer structure @ref app_usbd_hid_report_buffer_t. + * + * @param name Instance name. + * @param rep_size Output report size. + */ +#define APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(name, rep_size) \ + static uint8_t CONCAT_2(name, _buf)[(rep_size)]; \ + const app_usbd_hid_report_buffer_t name = { \ + .p_buff = CONCAT_2(name, _buf), \ + .size = sizeof(CONCAT_2(name, _buf)), \ + } + + +/** + * @brief USB HID instance. + */ +typedef struct { + uint8_t const * p_raw_desc; //!< HID class descriptors, raw array. + size_t raw_desc_size; //!< HID class descriptors size, raw array size. + uint8_t const * p_report_dsc; //!< Report descriptor, raw array. + size_t report_dsc_size; //!< Report descriptor, raw array size. + + app_usbd_hid_report_buffer_t * p_rep_buffer_in; //!< Report buffer IN. + app_usbd_hid_report_buffer_t const * p_rep_buffer_out; //!< Report buffer OUT (only one instance). + app_usbd_hid_methods_t const * p_hid_methods; //!< Hid interface methods. + app_usbd_hid_user_ev_handler_t user_event_handler; //!< User event handler. +} app_usbd_hid_inst_t; + + +/** + * @brief USB HID instance initializer @ref app_usbd_hid_inst_t. + * + * @param descriptors Interface, hid, endpoint packed descriptor structure. + * @param report_dsc Report descriptor (raw uint8_t array). + * @param report_buff_in Input report buffer list. + * @param report_buff_out Output report buffer. + * @param user_ev_handler @ref app_usbd_hid_user_ev_handler_t. + @param hid_methods @ref app_usbd_hid_methods_t. + * */ +#define APP_USBD_HID_INST_CONFIG(descriptors, \ + report_dsc, \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler, \ + hid_methods) \ + { \ + .p_raw_desc = descriptors, \ + .raw_desc_size = ARRAY_SIZE(descriptors), \ + .p_report_dsc = report_dsc, \ + .report_dsc_size = ARRAY_SIZE(report_dsc), \ + .p_rep_buffer_in = report_buff_in, \ + .p_rep_buffer_out = report_buff_out, \ + .user_event_handler = user_ev_handler, \ + .p_hid_methods = hid_methods, \ + } + +/** + * @brief HID internal context. + * */ +typedef struct { + nrf_atomic_u32_t state_flags; //!< HID state flags @ref app_usbd_hid_state_flag_t. + nrf_atomic_flag_t access_lock; //!< Lock flag to internal data. + uint8_t idle_rate; //!< HID idle rate (4ms units). + uint8_t protocol; //!< HID protocol type. +} app_usbd_hid_ctx_t; + + +/** + * @brief Locks internal hid context. + * + * Simple semaphore functionality to prevent concurrent access from application and + * interrupt to internal mouse data. + * + * @param[in] p_hid_ctx Internal hid context + */ +static inline void app_usbd_hid_access_lock(app_usbd_hid_ctx_t * p_hid_ctx) +{ + UNUSED_RETURN_VALUE(nrf_atomic_flag_set(&p_hid_ctx->access_lock)); + __DSB(); +} + + +/** + * @brief Unlocks internal hid context. + * + * Simple semaphore functionality to prevent concurrent access from application and + * interrupt to internal mouse data. + * + * @param[in] p_hid_ctx Internal hid context. + */ +static inline void app_usbd_hid_access_unlock(app_usbd_hid_ctx_t * p_hid_ctx) +{ + UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_hid_ctx->access_lock)); + __DSB(); +} + +/** + * @brief Tests whether internal lock is acquired. + * + * @param[in] p_hid_ctx Internal HID context. + * + * @retval true Locked. + * @retval false Unlocked. + */ +static inline bool app_usbd_hid_access_lock_test(app_usbd_hid_ctx_t * p_hid_ctx) +{ + return p_hid_ctx->access_lock != 0; +} + +/** + * @brief Set one of the HID internal state flags. + * + * @param[in] p_hid_ctx Internal HID context. + * @param[in] flag Flag to set. + */ +static inline void app_usbd_hid_state_flag_set(app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_hid_state_flag_t flag) +{ + UNUSED_RETURN_VALUE(nrf_atomic_u32_or(&p_hid_ctx->state_flags, 1u << flag)); +} + +/** + * @brief Clear one of the HID internal state flags. + * + * @param[in] p_hid_ctx Internal HID context. + * @param[in] flag Flag to clear. + */ +static inline void app_usbd_hid_state_flag_clr(app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_hid_state_flag_t flag) +{ + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&p_hid_ctx->state_flags, ~(1u << flag))); +} + + +/** + * @brief Test one of the HID internal state flags. + * + * @param[in] p_hid_ctx Internal HID context. + * @param[in] flag Flag to test. + * + * @retval true Flag is set. + * @retval false Flag is not set. + */ +static inline bool app_usbd_hid_state_flag_test(app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_hid_state_flag_t flag) +{ + return ((p_hid_ctx->state_flags >> flag) & 1) == 1; +} + +/** + * @brief Checks whether HID endpoint transfer required. + * + * @param[in] p_hid_ctx Internal HID context. + * + * @retval true Input endpoint transfer required. + * @retval false Transfer in progress or not allowed. + */ +static inline bool app_usbd_hid_trans_required(app_usbd_hid_ctx_t * p_hid_ctx) +{ + if (app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED) != 0) + { + app_usbd_core_class_rwu_pend(); + return false; + } + + return app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS) == 0; +} + +/** + * @brief Validates internal hid state. + * + * HID Mouse has to receive some USBD events before functions from this module could be used. + * + * @param[in] p_hid_ctx Internal hid context. + * + * @retval true State is valid. + * @retval false State is invalid. + */ +static inline bool app_usbd_hid_state_valid(app_usbd_hid_ctx_t * p_hid_ctx) +{ + /*Check whether internal flags allow to enable mouse*/ + if ((app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED) == 0) || + (app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED) == 0)) + { + return false; + } + + return true; +} + +/** + * @brief HID generic event handler. + * + * This handler should process every class event after specific class handler. + * This approach allow to handle some events in the same way in all HID sub-classes. + * + * @param[in] p_inst Generic class instance. + * @param[in] p_hinst HID class instance. + * @param[in] p_hid_ctx HID context. + * @param[in] p_event Complex event structure. + * + * @return Standard error code. + */ +ret_code_t app_usbd_hid_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_complex_evt_t const * p_event); + + +/** + * @brief Returns IN report buffer. + * + * @param[in] p_hinst HID class instance. + * + * @return Report buffer handle or NULL if report doesn't exist. + */ +app_usbd_hid_report_buffer_t * app_usbd_hid_rep_buff_in_get(app_usbd_hid_inst_t const * p_hinst); + +/** + * @brief Returns OUT report buffer. + * + * Output reports are handled in interrupt handler so only one buffer is required. Buffer returned by + * this function has predefined size, which should be equal (maximum OUTPUT report size + 1). To receive + * OUT report this function should be called on @ref APP_USBD_HID_USER_EVT_OUT_REPORT_READY event. + * + * @param[in] p_hinst HID class instance. + * + * @return Report buffer handle or NULL if report doesn't exist. + */ +static inline app_usbd_hid_report_buffer_t const * +app_usbd_hid_rep_buff_out_get(app_usbd_hid_inst_t const * p_hinst) +{ + ASSERT(p_hinst); + return p_hinst->p_rep_buffer_out; +} + +/** + * @brief Auxiliary function to access to HID IN endpoint address. + * + * @param[in] p_inst Class instance data. + * + * @return IN endpoint address. + */ +static inline nrf_drv_usbd_ep_t app_usbd_hid_epin_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_HID_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_HID_EPIN_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** + * @brief Auxiliary function to access to HID generic OUT endpoint address. + * + * @param[in] p_inst Class instance data. + * + * @return OUT endpoint address. + */ +static inline nrf_drv_usbd_ep_t app_usbd_hid_epout_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_HID_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_HID_EPOUT_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/app_usbd_hid_types.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/app_usbd_hid_types.h new file mode 100644 index 0000000000000000000000000000000000000000..3313725c2a05f79df3bc61c59552f85b5817baae --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/app_usbd_hid_types.h @@ -0,0 +1,276 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_HID_TYPES_H__ +#define APP_USBD_HID_TYPES_H__ + +#include + +#include "sdk_common.h" + +/** + * @defgroup app_usbd_hid_types USB HID class types + * @ingroup app_usbd_hid + * + * @brief @tagAPI52840 Module with types and definitions used by HID modules. + * @{ + */ + +/** + * @brief HID class definition in interface descriptor. + * + * @ref app_usbd_descriptor_iface_t::bInterfaceClass + * */ +#define APP_USBD_HID_CLASS 0x03 + +/** + * @brief HID subclass definition. + * + * @see HID 1.11 specification: Chapter 4.2 Subclass. + * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass + * */ +typedef enum { + APP_USBD_HID_SUBCLASS_NONE = 0x00, /**< Undefined subclass. */ + APP_USBD_HID_SUBCLASS_BOOT = 0x01, /**< Boot subclass. */ +} app_usbd_hid_subclass_t; + +/** + * @brief HID protocol types defined by specification. + * + * Value need to be filled in interface descriptor. + * @ref app_usbd_descriptor_iface_t::bInterfaceProtocol + */ +typedef enum { + APP_USBD_HID_PROTO_GENERIC = 0x00, /**< GENERIC protocol. */ + APP_USBD_HID_PROTO_KEYBOARD = 0x01, /**< KEYBOARD protocol. */ + APP_USBD_HID_PROTO_MOUSE = 0x02, /**< MOUSE protocol. */ + APP_USBD_HID_PROTO_MULTITOUCH = 0x03, /**< MULTITOUCH protocol. */ +} app_usbd_hid_protocol_t; + + +/** + * @brief HID country code ID. + * + * Look into @ref app_usbd_hid_descriptor_t::bCountryCode. + */ +typedef enum { + APP_USBD_HID_COUNTRY_NOT_SUPPORTED = 0 , /**< NOT_SUPPORTED */ + APP_USBD_HID_COUNTRY_ARABIC = 1 , /**< ARABIC */ + APP_USBD_HID_COUNTRY_BELGIAN = 2 , /**< BELGIAN */ + APP_USBD_HID_COUNTRY_CANADIAN_BILINGUAL= 3 , /**< CANADIAN_BILINGUAL */ + APP_USBD_HID_COUNTRY_CANADIAN_FRENCH = 4 , /**< CANADIAN_FRENCH */ + APP_USBD_HID_COUNTRY_CZECH_REPUBLIC = 5 , /**< CZECH_REPUBLIC */ + APP_USBD_HID_COUNTRY_DANISH = 6 , /**< DANISH */ + APP_USBD_HID_COUNTRY_FINNISH = 7 , /**< FINNISH */ + APP_USBD_HID_COUNTRY_FRENCH = 8 , /**< FRENCH */ + APP_USBD_HID_COUNTRY_GERMAN = 9 , /**< GERMAN */ + APP_USBD_HID_COUNTRY_GREEK = 10, /**< GREEK */ + APP_USBD_HID_COUNTRY_HEBREW = 11, /**< HEBREW */ + APP_USBD_HID_COUNTRY_HUNGARY = 12, /**< HUNGARY */ + APP_USBD_HID_COUNTRY_INTERNATIONAL_ISO = 13, /**< INTERNATIONAL_ISO */ + APP_USBD_HID_COUNTRY_ITALIAN = 14, /**< ITALIAN */ + APP_USBD_HID_COUNTRY_JAPAN_KATAKANA = 15, /**< JAPAN_KATAKANA */ + APP_USBD_HID_COUNTRY_KOREAN = 16, /**< KOREAN */ + APP_USBD_HID_COUNTRY_LATIN_AMERICAN = 17, /**< LATIN_AMERICAN */ + APP_USBD_HID_COUNTRY_NETHERLANDS_DUTCH = 18, /**< NETHERLANDS_DUTCH */ + APP_USBD_HID_COUNTRY_NORWEGIAN = 19, /**< NORWEGIAN */ + APP_USBD_HID_COUNTRY_PERSIAN_FARSI = 20, /**< PERSIAN_FARSI */ + APP_USBD_HID_COUNTRY_POLAND = 21, /**< POLAND */ + APP_USBD_HID_COUNTRY_PORTUGUESE = 22, /**< PORTUGUESE */ + APP_USBD_HID_COUNTRY_RUSSIA = 23, /**< RUSSIA */ + APP_USBD_HID_COUNTRY_SLOVAKIA = 24, /**< SLOVAKIA */ + APP_USBD_HID_COUNTRY_SPANISH = 25, /**< SPANISH */ + APP_USBD_HID_COUNTRY_SWEDISH = 26, /**< SWEDISH */ + APP_USBD_HID_COUNTRY_SWISS_FRENCH = 27, /**< SWISS_FRENCH */ + APP_USBD_HID_COUNTRY_SWISS_GERMAN = 28, /**< SWISS_GERMAN */ + APP_USBD_HID_COUNTRY_SWITZERLAND = 29, /**< SWITZERLAND */ + APP_USBD_HID_COUNTRY_TAIWAN = 30, /**< TAIWAN */ + APP_USBD_HID_COUNTRY_TURKISH_Q = 31, /**< TURKISH_Q */ + APP_USBD_HID_COUNTRY_UK = 32, /**< UK */ + APP_USBD_HID_COUNTRY_US = 33, /**< US */ + APP_USBD_HID_COUNTRY_YUGOSLAVIA = 34, /**< YUGOSLAVIA */ + APP_USBD_HID_COUNTRY_TURKISH_F = 35, /**< TURKISH_F */ +} app_usbd_hid_country_code_t; + +/** + * @brief HID descriptor types. + * + * @ref app_usbd_hid_descriptor_t::bRDescriptorType + */ +typedef enum { + APP_USBD_HID_DESCRIPTOR_HID = 0x21, /**< HID descriptor. */ + APP_USBD_HID_DESCRIPTOR_REPORT = 0x22, /**< REPORT descriptor. */ + APP_USBD_HID_DESCRIPTOR_PHYSICAL = 0x23, /**< PHYSICAL descriptor. */ +} app_usbd_hid_descriptor_type_t; + +#pragma pack(push, 1) + +/** + * @brief HID report descriptor entry at the end of HID descriptor. + * + * @param size Report descriptor size. + */ +#define APP_USBD_HID_REPORT_ITEM(size) \ + APP_USBD_HID_DESCRIPTOR_REPORT, ((size) & 0xFF), ((size) / 256) + + +/** + * @brief HID physical descriptor entry at the end of HID descriptor. + * + * @param size Physical descriptor size. + */ +#define APP_USBD_HID_PHYSICAL_ITEM(size) \ + APP_USBD_HID_DESCRIPTOR_PHYSICAL, ((size) & 0xFF), ((size) / 256) + + +/** + * @brief HID descriptor, binary layout. + */ +typedef union { + struct { + uint8_t bLength; //!< Length of descriptor. + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_HID_DESCRIPTOR_HID. + uint16_t bcdHID; //!< HID release number (BCD format, little endian). + uint8_t bCountryCode; //!< Country code. + uint8_t bNumDescriptors; //!< Number of class descriptors. + struct { + uint8_t bRDescriptorType; //!< Class descriptor type. + uint16_t wDescriptorLength; //!< Class descriptor length (little endian). + } reports[]; + } raw; +} app_usbd_hid_descriptor_t; + +#pragma pack(pop) + + +/** + * @brief HID requests defined by specification. + */ +typedef enum { + APP_USBD_HID_REQ_GET_REPORT = 0x01, /**< REPORT: device -> host (required). */ + APP_USBD_HID_REQ_GET_IDLE = 0x02, /**< IDLE: device -> host (not required). */ + APP_USBD_HID_REQ_GET_PROTOCOL = 0x03, /**< PROTOCOL: device -> host (required for boot protocol). */ + APP_USBD_HID_REQ_SET_REPORT = 0x09, /**< REPORT: host -> device (not required). */ + APP_USBD_HID_REQ_SET_IDLE = 0x0A, /**< IDLE: no data stage (required for boot protocol). */ + APP_USBD_HID_REQ_SET_PROTOCOL = 0x0B, /**< PROTOCOL: no data stage(required for boot protocol). */ +} app_usbd_hid_req_t; + +/** + * @brief HID report type. + */ +typedef enum { + APP_USBD_HID_REPORT_TYPE_INPUT = 0x01,/**< INPUT report type */ + APP_USBD_HID_REPORT_TYPE_OUTPUT = 0x02,/**< OUTPUT report type */ + APP_USBD_HID_REPORT_TYPE_FEATURE = 0x03,/**< FEATURE report type */ +} app_usbd_hid_report_type_t; + + + +/** + * @brief Helper macro for HID BCD release. + * + * @param major Hid release number major. + * @param minor Hid release number minor. + * + * @ref app_usbd_hid_descriptor_t::bcdHID + * @ref APP_USBD_HID_BCD_V1_11 + */ +#define APP_USBD_HID_BCD_MAKE(major, minor) 0x##minor, 0x##major + +/** + * @brief HID 1.11 BCD value definition. + * + * @ref app_usbd_hid_descriptor_t::bcdHID + */ +#define APP_USBD_HID_BCD_V1_11 APP_USBD_HID_BCD_MAKE(1, 11) + +/** + * @brief Initializer of interface descriptor for HID classes. + * + * @param interface_number Interface number. + * @param endpoints_num Number of endpoints. + * @param subclass Subclass type @ref app_usbd_hid_subclass_t. + * @param protocol Protocol type @ref app_usbd_hid_protocol_t. + */ +#define APP_USBD_HID_INTERFACE_DSC(interface_number, endpoints_num, subclass, protocol) \ + /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \ + /*.bInterfaceNumber = */ interface_number, \ + /*.bAlternateSetting = */ 0x00, \ + /*.bNumEndpoints = */ endpoints_num, \ + /*.bInterfaceClass = */ APP_USBD_HID_CLASS, \ + /*.bInterfaceSubClass = */ subclass, \ + /*.bInterfaceProtocol = */ protocol, \ + /*.iInterface = 0, */ 0x00, \ + + +/** + * @brief Initializer of HID descriptor for HID classes. + * + * @param ... Report/physical item list. + */ +#define APP_USBD_HID_HID_DSC(...) \ + /*.bLength = */ sizeof(app_usbd_hid_descriptor_t) + 3 * (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_HID_DESCRIPTOR_HID, \ + /*.bcdHID = */ APP_USBD_HID_BCD_V1_11, \ + /*.bCountryCode = */ APP_USBD_HID_COUNTRY_NOT_SUPPORTED, \ + /*.bNumDescriptors = */ (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bRDescriptorType = */ APP_USBD_HID_REPORT_ITEM(sizeof(GET_VA_ARG_1_(__VA_ARGS__))), \ + /*.wDescriptorLength = */ + +/** + * @brief Initializer of endpoint descriptor for HID classes. + * + * @param endpoint Endpoint number. + * @param ep_size Endpoint size. + * @param ep_interval Endpoint interval (milliseconds). + */ +#define APP_USBD_HID_EP_DSC(endpoint, ep_size, ep_interval) \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ endpoint, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ ep_interval, \ + + + +/** @} */ + +#endif /* APP_USBD_HID_TYPES_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c new file mode 100644 index 0000000000000000000000000000000000000000..53a1dfd6f23af1b1f7aaa7f8de9318a0468df98f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c @@ -0,0 +1,343 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_HID_GENERIC_ENABLED +#include + +#include "sdk_common.h" +#include "app_usbd_hid_generic.h" +#include "app_util_platform.h" + + +/** + * @ingroup app_usbd_hid_generic + * + * Module with types, definitions and API used by HID generic. + * @{ + */ + +/** + * @brief Auxiliary function to access HID generic context data. + * + * @param[in] p_generic HID generic instance. + * + * @return HID generic class instance data context. + */ +static inline app_usbd_hid_generic_ctx_t * +hid_generic_ctx_get(app_usbd_hid_generic_t const * p_generic) +{ + ASSERT(p_generic != NULL); + ASSERT(p_generic->specific.p_data != NULL); + return &p_generic->specific.p_data->ctx; +} + +/** + * @brief Auxiliary function to access HID generic instance data. + * + * @param[in] p_inst Class instance data. + * + * @return HID generic class instance data. + */ +static inline app_usbd_hid_generic_t const * +hid_generic_get(app_usbd_class_inst_t const * p_inst) +{ + ASSERT(p_inst != NULL); + return (app_usbd_hid_generic_t const *)p_inst; +} + + +/** + * @brief Returns report ID buffer descriptor. + * + * @param[in] p_generic Internal HID generic context. + * + * @return HID report buffer. + */ +static inline app_usbd_hid_report_buffer_t * +hid_generic_rep_buffer_get(app_usbd_hid_generic_t const * p_generic) +{ + ASSERT(p_generic != NULL); + app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst; + + return app_usbd_hid_rep_buff_in_get(p_hinst); +} + +/** + * @brief Auxiliary function to prepare report transfer buffer to next transfer. + * + * @param[in] p_generic HID generic instance. + * + * @retval true Next transfer required. + * @retval false Next transfer not required. + */ +static inline bool hid_generic_transfer_next(app_usbd_hid_generic_t const * p_generic) +{ + nrf_queue_t const * p_rep_in_queue = p_generic->specific.inst.p_rep_in_queue; + return !nrf_queue_is_empty(p_rep_in_queue); +} + + +/** + * @brief Triggers IN endpoint transfer. + * + * @param[in] p_generic HID generic instance. + * + * @return Standard error code. + */ +static inline ret_code_t hid_generic_transfer_set(app_usbd_hid_generic_t const * p_generic) +{ + app_usbd_class_inst_t const * p_inst = (app_usbd_class_inst_t const *)p_generic; + app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic); + + nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epin_addr_get(p_inst); + app_usbd_hid_state_flag_clr(&p_generic_ctx->hid_ctx, + APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + + if (!hid_generic_transfer_next(p_generic)) + { + return NRF_SUCCESS; + } + + app_usbd_hid_report_buffer_t * p_rep_buff = hid_generic_rep_buffer_get(p_generic); + nrf_queue_t const * p_rep_in_queue = p_generic->specific.inst.p_rep_in_queue; + + ret_code_t ret = nrf_queue_pop(p_rep_in_queue, p_rep_buff); + ASSERT(ret == NRF_SUCCESS); + + NRF_DRV_USBD_TRANSFER_IN(transfer, p_rep_buff->p_buff, p_rep_buff->size); + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_ep_transfer(ep_addr, &transfer); + if (ret == NRF_SUCCESS) + { + app_usbd_hid_state_flag_set(&p_generic_ctx->hid_ctx, + APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +ret_code_t app_usbd_hid_generic_in_report_set(app_usbd_hid_generic_t const * p_generic, + const void * p_buff, + size_t size) +{ + app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic); + nrf_queue_t const * p_rep_in_queue = p_generic->specific.inst.p_rep_in_queue; + const app_usbd_hid_report_buffer_t rep_buff = { + .p_buff = (void *)p_buff, + .size = size, + }; + + if (nrf_queue_push(p_rep_in_queue, &rep_buff) != NRF_SUCCESS) + { + return NRF_ERROR_BUSY; + } + + ret_code_t ret = NRF_SUCCESS; + if (app_usbd_hid_trans_required(&p_generic_ctx->hid_ctx)) + { + ret = hid_generic_transfer_set(p_generic); + } + + return ret; +} + +const void * app_usbd_hid_generic_in_report_get(app_usbd_hid_generic_t const * p_generic, + size_t * p_size) +{ + app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst; + *p_size = p_hinst->p_rep_buffer_in->size; + return p_hinst->p_rep_buffer_in->p_buff; +} + +const void * app_usbd_hid_generic_out_report_get(app_usbd_hid_generic_t const * p_generic, + size_t * p_size) +{ + app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst; + *p_size = p_hinst->p_rep_buffer_out->size; + return p_hinst->p_rep_buffer_out->p_buff; +} + +/** + * @brief @ref app_usbd_hid_interface_t::on_get_report + */ +static ret_code_t hid_generic_on_get_report(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + return NRF_ERROR_NOT_SUPPORTED; +} + + +static ret_code_t hid_generic_on_set_report_data_cb(nrf_drv_usbd_ep_status_t status, + void * p_context) +{ + app_usbd_hid_user_ev_handler_t handler; + app_usbd_hid_generic_t const * p_generic = (app_usbd_hid_generic_t const *)p_context; + + if (status != NRF_USBD_EP_OK) + { + return NRF_ERROR_INTERNAL; + } + + handler = p_generic->specific.inst.hid_inst.user_event_handler; + handler((app_usbd_class_inst_t const *)p_generic, + APP_USBD_HID_USER_EVT_OUT_REPORT_READY); + return NRF_SUCCESS; +} + + + +/** + * @brief @ref app_usbd_hid_interface_t::on_set_report + */ +static ret_code_t hid_generic_on_set_report(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst); + + /*Request setup data*/ + app_usbd_hid_report_buffer_t const * p_rep_buff; + p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_generic->specific.inst.hid_inst); + + p_rep_buff->p_buff[0] = p_setup_ev->setup.wValue.lb; + NRF_DRV_USBD_TRANSFER_OUT(transfer, p_rep_buff->p_buff + 1, p_rep_buff->size - 1); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_setup_data_transfer(NRF_DRV_USBD_EPOUT0, &transfer); + if (ret == NRF_SUCCESS) + { + app_usbd_core_setup_data_handler_desc_t desc = { + .handler = hid_generic_on_set_report_data_cb, + .p_context = (void*)p_generic + }; + + ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +/** + * @brief @ref app_usbd_hid_interface_t::ep_transfer_in + */ +static ret_code_t hid_generic_ep_transfer_in(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst); + app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic); + + nrf_queue_t const * p_rep_in_queue = p_generic->specific.inst.p_rep_in_queue; + + if (nrf_queue_is_empty(p_rep_in_queue)) + { + app_usbd_hid_state_flag_clr(&p_generic_ctx->hid_ctx, + APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + return NRF_SUCCESS; + } + + /* Get next report to send */ + return hid_generic_transfer_set((app_usbd_hid_generic_t const *)p_inst); +} + +/** + * @brief @ref app_usbd_hid_interface_t::ep_transfer_out + */ +static ret_code_t hid_generic_ep_transfer_out(app_usbd_class_inst_t const * p_inst) +{ + + app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst); + nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epout_addr_get(p_inst); + + /*Request setup data*/ + app_usbd_hid_report_buffer_t const * p_rep_buff; + p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_generic->specific.inst.hid_inst); + NRF_DRV_USBD_TRANSFER_OUT(transfer, p_rep_buff->p_buff, p_rep_buff->size); + + return app_usbd_core_ep_transfer(ep_addr, &transfer); +} + +/** + * @brief @ref app_usbd_class_interface_t::event_handler + */ +static ret_code_t hid_generic_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + ASSERT(p_inst != NULL); + ASSERT(p_event != NULL); + + app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst); + app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst; + app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic); + app_usbd_hid_ctx_t * p_hid_ctx = &p_generic_ctx->hid_ctx; + + /*Try handle event by generic HID event handler*/ + return app_usbd_hid_event_handler(p_inst, p_hinst, p_hid_ctx, p_event); +} + +/** + * @brief @ref app_usbd_class_interface_t::get_descriptors + */ +static const void * hid_generic_get_descriptors(app_usbd_class_inst_t const * p_inst, + size_t * p_size) +{ + ASSERT(p_size != NULL); + app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst); + app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst; + + *p_size = p_hinst->raw_desc_size; + return p_hinst->p_raw_desc; +} + +/** @} */ + +const app_usbd_hid_methods_t app_usbd_hid_generic_methods = { + .on_get_report = hid_generic_on_get_report, + .on_set_report = hid_generic_on_set_report, + .ep_transfer_in = hid_generic_ep_transfer_in, + .ep_transfer_out = hid_generic_ep_transfer_out, +}; + +const app_usbd_class_methods_t app_usbd_generic_class_methods = { + .event_handler = hid_generic_event_handler, + .get_descriptors = hid_generic_get_descriptors, +}; + +#endif // APP_USBD_HID_GENERIC_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h new file mode 100644 index 0000000000000000000000000000000000000000..09b5c530ce9035af60f206e56987a688155bef64 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h @@ -0,0 +1,221 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_HID_GENERIC_H__ +#define APP_USBD_HID_GENERIC_H__ + + + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "nrf_drv_usbd.h" +#include "app_usbd_class_base.h" +#include "app_usbd_hid_types.h" +#include "app_usbd_hid.h" +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_descriptor.h" +#include "app_usbd_hid_generic_desc.h" +#include "app_usbd_hid_generic_internal.h" + +/** + * @defgroup app_usbd_hid_generic USB HID generic + * @ingroup app_usbd_hid + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID generic class. + * @{ + */ + + +#ifdef DOXYGEN +/** + * @brief HID generic class instance type + * + * @ref APP_USBD_CLASS_TYPEDEF + */ +typedef struct { } app_usbd_hid_generic_t; +#else +/*lint -save -e10 -e26 -e123 -e505 */ +APP_USBD_CLASS_TYPEDEF(app_usbd_hid_generic, \ + APP_USBD_HID_GENERIC_CONFIG(0, (NRF_DRV_USBD_EPIN1, NRF_DRV_USBD_EPOUT1)), \ + APP_USBD_HID_GENERIC_INSTANCE_SPECIFIC_DEC, \ + APP_USBD_HID_GENERIC_DATA_SPECIFIC_DEC \ +); +/*lint -restore*/ +#endif + +/** + * @brief Global definition of app_usbd_hid_generic_t class. + * + * @param instance_name Name of global instance. + * @param interface_number Unique interface index. + * @param user_ev_handler User event handler (optional). + * @param endpoint_list Input endpoint list (@ref nrf_drv_usbd_ep_t). + * @param class_descriptors HID class descriptors. + * @param report_descriptor Report descriptor. + * @param report_in_queue_size IN report queue size. + * @param report_out_maxsize Maximum output report size. + * + * @note This macro is just simplified version of @ref APP_USBD_HID_GENERIC_GLOBAL_DEF_INTERNAL. + * + * Example class definition: + * @code + + static uint8_t m_generic_rep_dsc[] = APP_USBD_HID_MOUSE_REPORT_DSC_BUTTON(2); + + #define HID_DESCRIPTOR_ITEM_LIST \ + ( \ + m_generic_rep_dsc, \ + ) + + #define ENDPOINT_LIST \ + ( \ + NRF_DRV_USBD_EPIN1 \ + ) + + #define REPORT_COUNT 1 + #define REPORT_OUT_MAXSIZE 0 + + APP_USBD_HID_GENERIC_GLOBAL_DEF(m_app_hid_generic, + 0, + hid_user_ev_handler, + ENDPOINT_LIST, + HID_DESCRIPTOR_ITEM_LIST, + REPORT_IN_QUEUE_SIZE, + REPORT_OUT_MAXSIZE); + @endcode + * + */ +#define APP_USBD_HID_GENERIC_GLOBAL_DEF(instance_name, \ + interface_number, \ + user_ev_handler, \ + endpoint_list, \ + class_descriptors, \ + report_descriptor, \ + report_in_queue_size, \ + report_out_maxsize) \ + APP_USBD_HID_GENERIC_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + user_ev_handler, \ + endpoint_list, \ + class_descriptors, \ + report_descriptor, \ + report_in_queue_size, \ + report_out_maxsize) + + +/** + * @brief Helper function to get class instance from HID generic class. + * + * @param[in] p_generic HID generic class instance. + * + * @return Base class instance. + */ +static inline app_usbd_class_inst_t const * +app_usbd_hid_generic_class_inst_get(app_usbd_hid_generic_t const * p_generic) +{ + return &p_generic->base; +} + +/** + * @brief Helper function to get HID generic from base class instance. + * + * @param[in] p_inst Base class instance. + * + * @return HID generic class handle. + */ +static inline app_usbd_hid_generic_t const * +app_usbd_hid_generic_class_get(app_usbd_class_inst_t const * p_inst) +{ + return (app_usbd_hid_generic_t const *)p_inst; +} + +/** + * @brief New IN report trigger + * + * + * @param[in] p_generic HID generic class instance. + * @param[in] p_buff Report buffer. + * @param[in] size Report size. + * + * @return Standard error code. + */ +ret_code_t app_usbd_hid_generic_in_report_set(app_usbd_hid_generic_t const * p_generic, + const void * p_buff, + size_t size); + +/** + * @brief Returns last successful transfered IN report. + * + * @note Use this call only on @ref APP_USBD_HID_USER_EVT_IN_REPORT_DONE event. + * + * @param[in] p_generic HID generic class instance. + * @param[out] p_size Last transfered IN report size. + * + * @return Last transfered report ID. + */ +const void * app_usbd_hid_generic_in_report_get(app_usbd_hid_generic_t const * p_generic, + size_t * p_size); + +/** + * @brief Returns last successful transfered OUT report. + * + * @warning Use this call only on @ref APP_USBD_HID_USER_EVT_OUT_REPORT_READY event. + * + * @param[in] p_generic HID generic class instance. + * @param[out] p_size Last transfered OUT report size. + * + * @return Last transfered OUT report. + */ +const void * app_usbd_hid_generic_out_report_get(app_usbd_hid_generic_t const * p_generic, + size_t * p_size); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_GENERIC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..c694348d0b83fcbfd874c9d632b5935871dbcb08 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_HID_GENERIC_DESC_H__ +#define APP_USBD_HID_GENERIC_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup app_usbd_hid_generic_desc USB HID generic descriptors + * @ingroup app_usbd_hid_generic + * + * @brief @tagAPI52840 Module with descriptors used by the HID generic class. + * @{ + */ + +/** + * @brief Initializer of interface descriptor for HID generic class. + * + * @param interface_number Interface number. + * @param endpoints_num Number of endpoints. + * @param subclass Subclass type @ref app_usbd_hid_subclass_t. + * @param protocol Protocol type @ref app_usbd_hid_protocol_t. + */ +#define APP_USBD_HID_GENERIC_INTERFACE_DSC(interface_number, \ + endpoints_num, \ + subclass, \ + protocol) \ + APP_USBD_HID_INTERFACE_DSC(interface_number, \ + endpoints_num, \ + subclass, \ + protocol) \ + +/** + * @brief Initializer of HID descriptor for HID generic class. + * + * @param ... Report descriptor item. + */ +#define APP_USBD_HID_GENERIC_HID_DSC(...) \ + APP_USBD_HID_HID_DSC(__VA_ARGS__) +/** + * @brief Initializer of endpoint descriptor for HID generic class. + * + * @param endpoint Endpoint number. + */ +#define APP_USBD_HID_GENERIC_EP_DSC(endpoint) \ + APP_USBD_HID_EP_DSC(endpoint, NRF_DRV_USBD_EPSIZE, 1) + + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_GENERIC_DESC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..70ba104fa6e000a41a0bb565f60b30f66a5c8178 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h @@ -0,0 +1,182 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_HID_GENERIC_INTERNAL_H__ +#define APP_USBD_HID_GENERIC_INTERNAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_usbd_hid.h" +#include "nrf_queue.h" + +/** + * @defgroup app_usbd_hid_generic_internal USB HID generic internals + * @ingroup app_usbd_hid_generic + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID generic protocol. + * @{ + */ + + +/** + * @brief Forward declaration of HID generic class type. + * + */ +APP_USBD_CLASS_FORWARD(app_usbd_hid_generic); + +/** + * @brief HID generic part of class instance data. + * + */ +typedef struct { + app_usbd_hid_inst_t hid_inst; //!< HID instance data. + nrf_queue_t const * p_rep_in_queue; //!< Input report queue. +} app_usbd_hid_generic_inst_t; + +/** + * @brief HID generic context + * + */ +typedef struct { + app_usbd_hid_ctx_t hid_ctx; //!< HID class context. +} app_usbd_hid_generic_ctx_t; + + +/** + * @brief HID generic configuration macro. + * + * Used by @ref APP_USBD_HID_GENERIC_GLOBAL_DEF. + * + * @param iface Interface number. + * @param endpoints Endpoint list. + */ +#define APP_USBD_HID_GENERIC_CONFIG(iface, endpoints) ((iface, BRACKET_EXTRACT(endpoints))) + + +/** + * @brief Specific class constant data for HID generic class. + */ +#define APP_USBD_HID_GENERIC_INSTANCE_SPECIFIC_DEC app_usbd_hid_generic_inst_t inst; + +/** + * @brief Specific class data for HID generic class. + */ +#define APP_USBD_HID_GENERIC_DATA_SPECIFIC_DEC app_usbd_hid_generic_ctx_t ctx; + + +/** + * @brief Configure internal part of HID generic instance. + * + * @param descriptors Raw descriptors buffer. + * @param report_buff_in Input report buffers array. + * @param report_buff_out Output report buffer. + * @param user_ev_handler User event handler. + * @param in_report_queue IN report queue. + * @param ... Hid descriptors list. + */ +#define APP_USBD_HID_GENERIC_INST_CONFIG(descriptors, \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler, \ + in_report_queue, \ + ...) \ + .inst = { \ + .hid_inst = APP_USBD_HID_INST_CONFIG(descriptors, \ + GET_VA_ARG_1(__VA_ARGS__), \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler, \ + &app_usbd_hid_generic_methods), \ + .p_rep_in_queue = in_report_queue, \ + } + +/** + * @brief Public HID generic interface. + */ +extern const app_usbd_hid_methods_t app_usbd_hid_generic_methods; + +/** + * @brief Public HID generic class interface. + */ +extern const app_usbd_class_methods_t app_usbd_generic_class_methods; + +/** + * @brief Global definition of @ref app_usbd_hid_generic_t class. + * + * @ref APP_USBD_HID_GENERIC_GLOBAL_DEF + */ +#define APP_USBD_HID_GENERIC_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + user_ev_handler, \ + endpoint_list, \ + class_descriptors, \ + report_descriptor, \ + report_in_queue_size, \ + report_out_maxsize) \ + static app_usbd_hid_report_buffer_t CONCAT_2(instance_name, _in); \ + APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(CONCAT_2(instance_name, _out), \ + report_out_maxsize + 1); \ + NRF_QUEUE_DEF(app_usbd_hid_report_buffer_t, \ + instance_name##_queue, \ + report_in_queue_size, \ + NRF_QUEUE_MODE_OVERFLOW); \ + APP_USBD_CLASS_INST_GLOBAL_DEF( \ + instance_name, \ + app_usbd_hid_generic, \ + &app_usbd_generic_class_methods, \ + APP_USBD_HID_GENERIC_CONFIG(interface_number, endpoint_list), \ + (APP_USBD_HID_GENERIC_INST_CONFIG(class_descriptors, \ + &CONCAT_2(instance_name, _in), \ + &CONCAT_2(instance_name, _out), \ + user_ev_handler, \ + &instance_name##_queue, \ + report_descriptor)) \ + ) + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_GENERIC_INTERNAL_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c new file mode 100644 index 0000000000000000000000000000000000000000..d4e9762cd2d87e2c7aaccd3799513c568b481308 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c @@ -0,0 +1,392 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_HID_KBD_ENABLED +#include + +#include "sdk_common.h" +#include "app_usbd_hid_kbd.h" +#include "app_util_platform.h" + + +/** + * @defgroup app_usbd_hid_kbd_internals USB HID keyboard internals + * @{ + * @ingroup app_usbd_hid_kbd + * @internal + */ + +STATIC_ASSERT(sizeof(app_usbd_hid_descriptor_t) == 6); + +/** + * @brief Auxiliary function to access HID keyboard context data. + * + * @param[in] p_inst class instance data. + * + * @return HID keyboard instance data context. + */ +static inline app_usbd_hid_kbd_ctx_t * hid_kbd_ctx_get(app_usbd_hid_kbd_t const * p_kbd) +{ + ASSERT(p_kbd != NULL); + ASSERT(p_kbd->specific.p_data != NULL); + return &p_kbd->specific.p_data->ctx; +} + +/** + * @brief Auxiliary function to access HID keyboard instance data. + * + * @param[in] p_inst class instance data. + * + * @return HID keyboard instance data. + */ +static inline app_usbd_hid_kbd_t const * hid_kbd_get(app_usbd_class_inst_t const * p_inst) +{ + ASSERT(p_inst != NULL); + return (app_usbd_hid_kbd_t const *)p_inst; +} + +/** + * @brief Returns keyboard report buffer handle. + * + * @param[in] p_kbd HID keyboard instance. + * + * @return HID report buffer. + */ +static inline +app_usbd_hid_report_buffer_t const * hid_kbd_rep_buffer_get(app_usbd_hid_kbd_t const * p_kbd) +{ + ASSERT(p_kbd != NULL); + app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst; + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + app_usbd_hid_report_buffer_t * p_rep_buff = app_usbd_hid_rep_buff_in_get(p_hinst); + + p_rep_buff->p_buff = p_kbd_ctx->report_buff; + p_rep_buff->size = sizeof(p_kbd_ctx->report_buff); + + /*Keyboard has only one report input/output report buffer */ + return p_rep_buff; +} + + +/** + * @brief Auxiliary function to prepare report transfer buffer to next transfer. + * + * @param[in] p_kbd HID keyboard instance. + * + * @retval true Next transfer is required. + * @retval false Next transfer is not required. + */ +static inline bool hid_kbd_transfer_next(app_usbd_hid_kbd_t const * p_kbd) +{ + /*Send report only when state has changed*/ + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_kbd_rep_buffer_get(p_kbd); + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + + if (memcmp(p_rep_buffer->p_buff, &p_kbd_ctx->rep, p_rep_buffer->size)) + { + memcpy(p_rep_buffer->p_buff, &p_kbd_ctx->rep, p_rep_buffer->size); + return true; + } + + return false; +} + + +/** + * @brief Triggers IN endpoint transfer. + * + * @param[in] p_kbd HID keyboard instance. + * + * @return Standard error code. + */ +static inline ret_code_t hid_kbd_transfer_set(app_usbd_hid_kbd_t const * p_kbd) +{ + app_usbd_class_inst_t const * p_inst = (app_usbd_class_inst_t const *)p_kbd; + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + + nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epin_addr_get(p_inst); + + app_usbd_hid_state_flag_clr(&p_kbd_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + + if (!hid_kbd_transfer_next(p_kbd)) + { + /* Transfer buffer hasn't changed since last transfer. No need to setup + * next transfer. + * */ + return NRF_SUCCESS; + } + + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_kbd_rep_buffer_get(p_kbd); + NRF_DRV_USBD_TRANSFER_IN(transfer, p_rep_buffer->p_buff, p_rep_buffer->size); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_ep_transfer(ep_addr, &transfer); + if (ret == NRF_SUCCESS) + { + app_usbd_hid_state_flag_set(&p_kbd_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +ret_code_t app_usbd_hid_kbd_modifier_state_set(app_usbd_hid_kbd_t const * p_kbd, + app_usbd_hid_kbd_modifier_t modifier, + bool state) +{ + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + bool actual_state = (p_kbd_ctx->rep.modifier & modifier) != 0; + + if (actual_state == state) + { + /*Modifier has already the same state*/ + return NRF_SUCCESS; + } + + app_usbd_hid_access_lock(&p_kbd_ctx->hid_ctx); + + if (state) + { + p_kbd_ctx->rep.modifier |= modifier; + } + else + { + p_kbd_ctx->rep.modifier &= ~modifier; + } + app_usbd_hid_access_unlock(&p_kbd_ctx->hid_ctx); + + if (app_usbd_hid_trans_required(&p_kbd_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_kbd_transfer_set(p_kbd); + } + + return NRF_SUCCESS; +} + + +ret_code_t app_usbd_hid_kbd_key_control(app_usbd_hid_kbd_t const * p_kbd, + app_usbd_hid_kbd_codes_t key, + bool press) +{ + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + uint8_t * destination = NULL; + if (press) + { + for (size_t i = 0; i < ARRAY_SIZE(p_kbd_ctx->rep.key_table); ++i) { + if (p_kbd_ctx->rep.key_table[i] == key) + { + /*Already pressed*/ + return NRF_SUCCESS; + } + + if ((destination == NULL) && (p_kbd_ctx->rep.key_table[i] == 0)) + { + destination = &p_kbd_ctx->rep.key_table[i]; + } + } + + if (destination == NULL) + { + return NRF_ERROR_BUSY; + } + } + else + { + /*Find if key is pressed*/ + for (size_t i = 0; i < ARRAY_SIZE(p_kbd_ctx->rep.key_table); ++i) { + if (p_kbd_ctx->rep.key_table[i] == key) + { + destination = &p_kbd_ctx->rep.key_table[i]; + break; + } + } + + if (destination == NULL) + { + /*Key hasn't been pressed*/ + return NRF_SUCCESS; + } + } + + /*Save destination*/ + app_usbd_hid_access_lock(&p_kbd_ctx->hid_ctx); + *destination = press ? key : 0; + app_usbd_hid_access_unlock(&p_kbd_ctx->hid_ctx); + + if (app_usbd_hid_trans_required(&p_kbd_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_kbd_transfer_set(p_kbd); + } + + return NRF_SUCCESS; +} + +bool app_usbd_hid_kbd_led_state_get(app_usbd_hid_kbd_t const * p_kbd, + app_usbd_hid_kbd_led_t led) +{ + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + + return (p_kbd_ctx->leds_state & led) != 0; +} + +/** + * @brief @ref app_usbd_hid_interface_t::on_get_report + */ +static ret_code_t hid_kbd_on_get_report(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst); + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_kbd_rep_buffer_get(p_kbd); + + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_rep_buffer->p_buff, p_rep_buffer->size); +} + + +static ret_code_t hid_kbd_on_set_report_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context) +{ + if (status != NRF_USBD_EP_OK) + { + return NRF_ERROR_INTERNAL; + } + + app_usbd_hid_kbd_t const * p_kbd = p_context; + app_usbd_hid_report_buffer_t const * p_rep_buff; + p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_kbd->specific.inst.hid_inst); + + /*Update LEDs state*/ + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + p_kbd_ctx->leds_state = p_rep_buff->p_buff[1]; + + app_usbd_hid_user_ev_handler_t handler = p_kbd->specific.inst.hid_inst.user_event_handler; + handler((app_usbd_class_inst_t const *)(p_kbd), APP_USBD_HID_USER_EVT_OUT_REPORT_READY); + return NRF_SUCCESS; +} + +/** + * @brief @ref app_usbd_hid_interface_t::hid_kbd_on_set_report + */ +static ret_code_t hid_kbd_on_set_report(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst); + + /*Request setup data*/ + app_usbd_hid_report_buffer_t const * p_rep_buff; + p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_kbd->specific.inst.hid_inst); + + p_rep_buff->p_buff[0] = 0; + NRF_DRV_USBD_TRANSFER_OUT(transfer, p_rep_buff->p_buff + 1, p_rep_buff->size - 1); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_setup_data_transfer(NRF_DRV_USBD_EPOUT0, &transfer); + if (ret == NRF_SUCCESS) + { + app_usbd_core_setup_data_handler_desc_t desc = { + .handler = hid_kbd_on_set_report_data_cb, + .p_context = (app_usbd_hid_kbd_t *)p_kbd + }; + + ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +/** + * @brief @ref app_usbd_hid_interface_t::hid_kbd_ep_transfer_in + */ +static ret_code_t hid_kbd_ep_transfer_in(app_usbd_class_inst_t const * p_inst) +{ + return hid_kbd_transfer_set((app_usbd_hid_kbd_t const *)p_inst); +} + +/** + * @brief @ref app_usbd_class_interface_t::event_handler + */ +static ret_code_t hid_kbd_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + ASSERT(p_inst != NULL); + ASSERT(p_event != NULL); + + app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst); + app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst; + + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + app_usbd_hid_ctx_t * p_hid_ctx = &p_kbd_ctx->hid_ctx; + + /*Try handle event by generic HID event handler*/ + return app_usbd_hid_event_handler(p_inst, p_hinst, p_hid_ctx, p_event); +} + +/** + * @brief @ref app_usbd_class_interface_t::get_descriptors + */ +static const void * hid_kbd_get_descriptors(app_usbd_class_inst_t const * p_inst, + size_t * p_size) +{ + ASSERT(p_size != NULL); + app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst); + app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst; + + *p_size = p_hinst->raw_desc_size; + return p_hinst->p_raw_desc; +} + +/** @} */ + +const app_usbd_hid_methods_t app_usbd_hid_kbd_methods = { + .on_get_report = hid_kbd_on_get_report, + .on_set_report = hid_kbd_on_set_report, + .ep_transfer_in = hid_kbd_ep_transfer_in, + .ep_transfer_out = NULL, +}; + +const app_usbd_class_methods_t app_usbd_hid_kbd_class_methods = { + .event_handler = hid_kbd_event_handler, + .get_descriptors = hid_kbd_get_descriptors, +}; + +#endif // APP_USBD_HID_KBD_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h new file mode 100644 index 0000000000000000000000000000000000000000..e0cb469a4d5e2048acfd0f513255169fbe00efd2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h @@ -0,0 +1,305 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_HID_KBD_H__ +#define APP_USBD_HID_KBD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "nrf_drv_usbd.h" +#include "app_usbd_class_base.h" +#include "app_usbd_hid_types.h" +#include "app_usbd_hid.h" +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_descriptor.h" +#include "app_usbd_hid_kbd_desc.h" +#include "app_usbd_hid_kbd_internal.h" + + +/** + * @defgroup app_usbd_hid_kbd USB HID keyboard + * @ingroup app_usbd_hid + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID keyboard class. + * @{ + */ + +/** + * @brief HID keyboard codes. + */ +typedef enum { + APP_USBD_HID_KBD_A = 4, /**base; +} + +/** + * @brief Helper function to get HID keyboard from base class instance. + * + * @param[in] p_inst Base class instance. + * + * @return HID keyboard class handle. + */ +static inline app_usbd_hid_kbd_t const * +app_usbd_hid_kbd_class_get(app_usbd_class_inst_t const * p_inst) +{ + return (app_usbd_hid_kbd_t const *)p_inst; +} + +/** + * @brief Set HID keyboard modifier state. + * + * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF). + * @param[in] modifier Type of modifier. + * @param[in] state State, true active, false inactive. + * + * @return Standard error code. + */ +ret_code_t app_usbd_hid_kbd_modifier_state_set(app_usbd_hid_kbd_t const * p_kbd, + app_usbd_hid_kbd_modifier_t modifier, + bool state); + + +/** + * @brief Press/release HID keyboard key. + * + * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF). + * @param[in] key Keyboard key code. + * @param[in] press True -> key press, false -> release. + * + * @return Standard error code. + */ +ret_code_t app_usbd_hid_kbd_key_control(app_usbd_hid_kbd_t const * p_kbd, + app_usbd_hid_kbd_codes_t key, + bool press); +/** + * @brief HID Keyboard LEDs state get. + * + * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF). + * @param[in] led LED code. + * + * @retval true LED is set. + * @retval false LED is not set. + */ +bool app_usbd_hid_kbd_led_state_get(app_usbd_hid_kbd_t const * p_kbd, + app_usbd_hid_kbd_led_t led); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_KBD_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..05bf4fff4f23cfc4e89df5f7a84d939d7b13de73 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h @@ -0,0 +1,128 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_HID_KBD_DESC_H__ +#define APP_USBD_HID_KBD_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup app_usbd_hid_kbd_desc USB HID keyboard descriptors + * @ingroup app_usbd_hid_kbd + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID keyboard class. + * @{ + */ + +/** + * @brief Initializer of interface descriptor for HID keyboard class. + * + * @param interface_number Interface number. + */ +#define APP_USBD_HID_KBD_INTERFACE_DSC(interface_number) \ + APP_USBD_HID_INTERFACE_DSC(interface_number, \ + 1, \ + APP_USBD_HID_SUBCLASS_BOOT, \ + APP_USBD_HID_PROTO_KEYBOARD) + +/** + * @brief Initializer of HID descriptor for HID keyboard class. + * + * @param ... Report descriptor item. + */ +#define APP_USBD_HID_KBD_HID_DSC(...) \ + APP_USBD_HID_HID_DSC(__VA_ARGS__) +/** + * @brief Initializer of endpoint descriptor for HID keyboard class. + * + * @param endpoint Endpoint number. + */ +#define APP_USBD_HID_KBD_EP_DSC(endpoint) \ + APP_USBD_HID_EP_DSC(endpoint, 8, 1) + + +/** + * @brief Example of USB HID keyboard report descriptor. + * + */ +#define APP_USBD_HID_KBD_REPORT_DSC() { \ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */\ + 0x09, 0x06, /* USAGE (Keyboard) */\ + 0xa1, 0x01, /* COLLECTION (Application) */\ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */\ + 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */\ + 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */\ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */\ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */\ + 0x75, 0x01, /* REPORT_SIZE (1) */\ + 0x95, 0x08, /* REPORT_COUNT (8) */\ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */\ + 0x95, 0x01, /* REPORT_COUNT (1) */\ + 0x75, 0x08, /* REPORT_SIZE (8) */\ + 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */\ + 0x95, 0x05, /* REPORT_COUNT (5) */\ + 0x75, 0x01, /* REPORT_SIZE (1) */\ + 0x05, 0x08, /* USAGE_PAGE (LEDs) */\ + 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */\ + 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */\ + 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */\ + 0x95, 0x01, /* REPORT_COUNT (1) */\ + 0x75, 0x03, /* REPORT_SIZE (3) */\ + 0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */\ + 0x95, 0x06, /* REPORT_COUNT (6) */\ + 0x75, 0x08, /* REPORT_SIZE (8) */\ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */\ + 0x25, 0x65, /* LOGICAL_MAXIMUM (101) */\ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */\ + 0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated))*/\ + 0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */\ + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */\ + 0xc0 /* END_COLLECTION */\ +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_KBD_DESC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..5a81b5d161a3d588ccb93a315ff6c88e53d118fc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h @@ -0,0 +1,196 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_HID_KBD_INTERNAL_H__ +#define APP_USBD_HID_KBD_INTERNAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup app_usbd_hid_kbd_internal USB HID keyboard internals + * @ingroup app_usbd_hid_kbd + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID keyboard class. + * @{ + */ + +/** + * @brief Forward declaration of HID keyboard class type. + * + */ +APP_USBD_CLASS_FORWARD(app_usbd_hid_kbd); + + +/** + * @brief HID keyboard part of class instance data. + * + */ +typedef struct { + app_usbd_hid_inst_t hid_inst; //!< HID instance data. +} app_usbd_hid_kbd_inst_t; + +/** + * @brief HID keyboard context + * + */ +typedef struct { + app_usbd_hid_ctx_t hid_ctx; //!< HID class context. + + struct app_usbd_hid_kbd_ctx_internal_s { + uint8_t modifier; //!< Keyboard modifier state @ref app_usbd_hid_kbd_modifier_t. + uint8_t reserved; //!< Reserved value. + uint8_t key_table[6]; //!< Keyboard keys table @ref app_usbd_hid_kbd_codes_t. + } rep; + + uint8_t report_buff[8]; //!< Raw report buffer. + uint8_t leds_state; //!< Output report LEDs state. + uint8_t set_report; //!< Set report flag. +} app_usbd_hid_kbd_ctx_t; + +/** + * @brief HID keyboard configuration macro. + * + * Used by @ref APP_USBD_HID_KBD_GLOBAL_DEF. + * + * + */ +#define APP_USBD_HID_KBD_CONFIG(iface, ep) ((iface, ep)) + + +/** + * @brief Specific class constant data for HID keyboard class. + */ +#define APP_USBD_HID_KBD_INSTANCE_SPECIFIC_DEC app_usbd_hid_kbd_inst_t inst; + +/** + * @brief Specific class data for HID keyboard class. + */ +#define APP_USBD_HID_KBD_DATA_SPECIFIC_DEC app_usbd_hid_kbd_ctx_t ctx; + + +/** + * @brief HID keyboard descriptors config macro. + * + * @ref app_usbd_hid_kbd_inst_t + * + * @param interface_number Interface number. + * @param endpoint Endpoint number. + * @param rep_descriptor Keyboard report descriptor. + */ +#define APP_USBD_HID_KBD_DSC_CONFIG(interface_number, endpoint, rep_descriptor) { \ + APP_USBD_HID_KBD_INTERFACE_DSC(interface_number) \ + APP_USBD_HID_KBD_HID_DSC(rep_descriptor) \ + APP_USBD_HID_KBD_EP_DSC(endpoint) \ +} + +/** + * @brief Configure internal part of HID keyboard instance. + * + * @param descriptors Raw descriptors buffer. + * @param report_desc Report descriptor. + * @param report_buff_in Input report buffers array. + * @param report_buff_out Output report buffer. + * @param user_ev_handler User event handler. + */ +#define APP_USBD_HID_KBD_INST_CONFIG(descriptors, \ + report_desc, \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler) \ + .inst = { \ + .hid_inst = APP_USBD_HID_INST_CONFIG(descriptors, \ + report_desc, \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler, \ + &app_usbd_hid_kbd_methods), \ +} + + +/** + * @brief Public HID keyboard interface. + */ +extern const app_usbd_hid_methods_t app_usbd_hid_kbd_methods; + +/** + * @brief Public HID keyboard class interface. + */ +extern const app_usbd_class_methods_t app_usbd_hid_kbd_class_methods; + +/** + * @brief Global definition of @ref app_usbd_hid_kbd_t class. + * + * @ref APP_USBD_HID_KBD_GLOBAL_DEF + */ +#define APP_USBD_HID_KBD_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + endpoint, \ + user_ev_handler) \ + static const uint8_t CONCAT_2(instance_name, _rep_dsc)[] = \ + APP_USBD_HID_KBD_REPORT_DSC(); \ + static const uint8_t CONCAT_2(instance_name, _dsc)[] = \ + APP_USBD_HID_KBD_DSC_CONFIG(interface_number, \ + endpoint, \ + CONCAT_2(instance_name, _rep_dsc)); \ + APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(CONCAT_2(instance_name, _out), 1 + 1); \ + static app_usbd_hid_report_buffer_t CONCAT_2(instance_name, _in)[1]; \ + APP_USBD_CLASS_INST_GLOBAL_DEF( \ + instance_name, \ + app_usbd_hid_kbd, \ + &app_usbd_hid_kbd_class_methods, \ + APP_USBD_HID_KBD_CONFIG(interface_number, endpoint), \ + (APP_USBD_HID_KBD_INST_CONFIG(CONCAT_2(instance_name, _dsc), \ + CONCAT_2(instance_name, _rep_dsc), \ + CONCAT_2(instance_name, _in), \ + &CONCAT_2(instance_name, _out), \ + user_ev_handler)) \ + ) + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_KBD_INTERNAL_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c new file mode 100644 index 0000000000000000000000000000000000000000..bfd0ce6ed1d86013d0e6b36f5b59ba8b7b725ea6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c @@ -0,0 +1,473 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_HID_MOUSE_ENABLED +#include + +#include "sdk_common.h" +#include "app_usbd_hid_mouse.h" +#include "app_util_platform.h" + + +/** + * @defgroup app_usbd_hid_mouse_internal USBD HID Mouse internals + * @{ + * @ingroup app_usbd_hid_mouse + * @internal + */ + +/** + * @brief Auxiliary function to access HID mouse context data. + * + * @param[in] p_inst class instance data. + * + * @return HID mouse instance data context. + */ +static inline app_usbd_hid_mouse_ctx_t * hid_mouse_ctx_get(app_usbd_hid_mouse_t const * p_mouse) +{ + ASSERT(p_mouse != NULL); + ASSERT(p_mouse->specific.p_data != NULL); + return &p_mouse->specific.p_data->ctx; +} + +/** + * @brief Auxiliary function to access HID mouse instance data. + * + * @param[in] p_inst class instance data. + * + * @return HID mouse instance. + */ +static inline app_usbd_hid_mouse_t const * hid_mouse_get(app_usbd_class_inst_t const * p_inst) +{ + ASSERT(p_inst != NULL); + return (app_usbd_hid_mouse_t const *)p_inst; +} + +/** + * @brief Returns mouse report buffer handle. + * + * @param[in] p_kbd HID keyboard instance. + * + * @return HID report buffer. + */ +static inline +app_usbd_hid_report_buffer_t const * hid_mouse_rep_buffer_get(app_usbd_hid_mouse_t const * p_mouse) +{ + ASSERT(p_mouse != NULL); + app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst; + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + app_usbd_hid_report_buffer_t * p_rep_buff = app_usbd_hid_rep_buff_in_get(p_hinst); + + p_rep_buff->p_buff = p_mouse_ctx->report_buff; + p_rep_buff->size = sizeof(p_mouse_ctx->report_buff); + + /*Mouse has only one report input report buffer */ + return app_usbd_hid_rep_buff_in_get(p_hinst); +} + +/**@brief Auxiliary function to get report value from internal accumulated value. + * + * @param[in] acc Accumulated XY axis or scroll. + * + * @return Offset value that could be written directly to report buffer. + */ +static inline int8_t hid_mouse_axis_acc_get(int16_t acc) +{ + if (acc > INT8_MAX) + { + return INT8_MAX; + } + + if (acc < INT8_MIN) + { + return INT8_MIN; + } + + return acc; +} + +/**@brief Auxiliary function to prepare report transfer buffer to next transfer. + * + * @param[in] p_mouse_ctx Mouse internal context. + * + * @retval true Next transfer is required. + * @retval false Next transfer is not required. + */ +static inline bool hid_mouse_transfer_next(app_usbd_hid_mouse_t const * p_mouse) +{ + + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_mouse_rep_buffer_get(p_mouse); + + uint8_t * p_buff = p_rep_buffer->p_buff; + + /*Save last buttons state*/ + uint8_t last_button_state = p_buff[0]; + + /*Button state*/ + p_buff[0] = p_mouse_ctx->button_state; + + /*Axis X*/ + int8_t val_x = hid_mouse_axis_acc_get(p_mouse_ctx->acc_x_axis); + p_mouse_ctx->acc_x_axis -= val_x; + p_buff[1] = val_x; + + /*Axis Y*/ + int8_t val_y = hid_mouse_axis_acc_get(p_mouse_ctx->acc_y_axis); + p_mouse_ctx->acc_y_axis -= val_y; + p_buff[2] = val_y; + + /*Scroll*/ + int8_t val_scroll = hid_mouse_axis_acc_get(p_mouse_ctx->acc_scroll); + p_mouse_ctx->acc_scroll -= val_scroll; + p_buff[3] = val_scroll; + + if (val_x || val_y || val_scroll) + { + /*New transfer is required if any of mouse relative position is not zero*/ + return true; + } + + if (last_button_state != p_buff[0]) + { + /*New transfer is required if button state has changed*/ + return true; + } + + return false; +} + +/** + * @brief Triggers IN endpoint transfer. + * + * @param[in] p_mouse HID mouse instance. + * + * @return Standard error code. + */ +static inline ret_code_t hid_mouse_transfer_set(app_usbd_hid_mouse_t const * p_mouse) +{ + app_usbd_class_inst_t const * p_inst = (app_usbd_class_inst_t const *)p_mouse; + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + + nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epin_addr_get(p_inst); + + app_usbd_hid_state_flag_clr(&p_mouse_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + if (!hid_mouse_transfer_next(p_mouse)) + { + /* Transfer buffer hasn't changed since last transfer. No need to setup + * next transfer. + * */ + return NRF_SUCCESS; + } + + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_mouse_rep_buffer_get(p_mouse); + + NRF_DRV_USBD_TRANSFER_IN(transfer, p_rep_buffer->p_buff, p_rep_buffer->size); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_ep_transfer(ep_addr, &transfer); + if (ret == NRF_SUCCESS) + { + app_usbd_hid_state_flag_set(&p_mouse_ctx->hid_ctx, + APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +/** + * @brief Checks if adding would cause 16 bit signed integer overflow. + * + * @param[in] acc Signed 16 bit accumulator to test. + * @param[in] value Value to add to accumulator. + * + * @retval true Overflow detected. + * @retval false No overflow detected. + */ +static inline bool hid_mouse_acc_overflow_check(int16_t acc, int8_t val) +{ + if (((int32_t)acc + val) > INT16_MAX) + { + return true; + } + + if (((int32_t)acc + val) < INT16_MIN) + { + return true; + } + + return false; +} + +ret_code_t app_usbd_hid_mouse_x_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset) +{ + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (offset == 0) + { + /*No position change*/ + return NRF_SUCCESS; + } + + if (hid_mouse_acc_overflow_check(p_mouse_ctx->acc_y_axis, offset)) + { + /*Overflow detected*/ + return NRF_ERROR_BUSY; + } + + app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx); + p_mouse_ctx->acc_x_axis += offset; + app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx); + + if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_mouse_transfer_set(p_mouse); + } + + return NRF_SUCCESS; +} + +ret_code_t app_usbd_hid_mouse_y_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset) +{ + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (offset == 0) + { + /*No position change*/ + return NRF_SUCCESS; + } + + if (hid_mouse_acc_overflow_check(p_mouse_ctx->acc_y_axis, offset)) + { + /*Overflow detected*/ + return NRF_ERROR_BUSY; + } + + app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx); + p_mouse_ctx->acc_y_axis += offset; + app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx); + + if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_mouse_transfer_set(p_mouse); + } + + return NRF_SUCCESS; +} + +ret_code_t app_usbd_hid_mouse_scroll_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset) +{ + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (offset == 0) + { + /*No position change*/ + return NRF_SUCCESS; + } + + if (hid_mouse_acc_overflow_check(p_mouse_ctx->acc_scroll, offset)) + { + /*Overflow detected*/ + return NRF_ERROR_BUSY; + } + + app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx); + p_mouse_ctx->acc_scroll += offset; + app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx); + + if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_mouse_transfer_set(p_mouse); + } + + return NRF_SUCCESS; +} + +ret_code_t app_usbd_hid_mouse_button_state(app_usbd_hid_mouse_t const * p_mouse, + uint8_t button_id, + bool state) +{ + ASSERT(button_id < 8); + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + + if (button_id >= p_mouse->specific.inst.button_count) + { + return NRF_ERROR_INVALID_PARAM; + } + + if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (IS_SET(p_mouse_ctx->button_state, button_id) == (state ? 1 : 0)) + { + return NRF_SUCCESS; + } + + app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx); + if (state) + { + SET_BIT(p_mouse_ctx->button_state, button_id); + } + else + { + CLR_BIT(p_mouse_ctx->button_state, button_id); + } + app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx); + + if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_mouse_transfer_set(p_mouse); + } + + return NRF_SUCCESS; +} + +/** + * @brief @ref app_usbd_hid_interface_t::on_get_report + */ +static ret_code_t hid_mouse_on_get_report(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst); + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_mouse_rep_buffer_get(p_mouse); + + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_rep_buffer->p_buff, p_rep_buffer->size); +} + +/** + * @brief @ref app_usbd_hid_interface_t::on_set_report + */ +static ret_code_t hid_mouse_on_set_report(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief @ref app_usbd_hid_interface_t::ep_transfer_set + */ +static ret_code_t hid_mouse_ep_transfer_in(app_usbd_class_inst_t const * p_inst) +{ + return hid_mouse_transfer_set((app_usbd_hid_mouse_t const *)p_inst); +} + +/** + * @brief @ref app_usbd_class_interface_t::event_handler + */ +static ret_code_t hid_mouse_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + ASSERT(p_inst != NULL); + ASSERT(p_event != NULL); + + app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst); + app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst; + + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + app_usbd_hid_ctx_t * p_hid_ctx = &p_mouse_ctx->hid_ctx; + + + ret_code_t ret = NRF_SUCCESS; + switch (p_event->app_evt.type) + { + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + if (ret != NRF_ERROR_NOT_SUPPORTED) + { + /* Event was processed by specific handler */ + return ret; + } + + /*Try handle event by generic HID event handler*/ + return app_usbd_hid_event_handler(p_inst, p_hinst, p_hid_ctx, p_event); +} + +/** + * @brief @ref app_usbd_class_interface_t::get_descriptors + */ +static const void * hid_mouse_get_descriptors(app_usbd_class_inst_t const * p_inst, + size_t * p_size) +{ + ASSERT(p_size != NULL); + app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst); + app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst; + + *p_size = p_hinst->raw_desc_size; + return p_hinst->p_raw_desc; +} + +/** @} */ + +const app_usbd_hid_methods_t app_usbd_hid_mouse_methods = { + .on_get_report = hid_mouse_on_get_report, + .on_set_report = hid_mouse_on_set_report, + .ep_transfer_in = hid_mouse_ep_transfer_in, + .ep_transfer_out = NULL, +}; + +const app_usbd_class_methods_t app_usbd_hid_mouse_class_methods = { + .event_handler = hid_mouse_event_handler, + .get_descriptors = hid_mouse_get_descriptors, +}; + +#endif // APP_USBD_HID_MOUSE_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h new file mode 100644 index 0000000000000000000000000000000000000000..06aa4f55e75782e8685739bfe8c1df28415b39fc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h @@ -0,0 +1,179 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_HID_MOUSE_H__ +#define APP_USBD_HID_MOUSE_H__ + +#include +#include + +#include "nrf_drv_usbd.h" +#include "app_usbd_class_base.h" +#include "app_usbd_hid_types.h" +#include "app_usbd_hid.h" +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_descriptor.h" +#include "app_usbd_hid_mouse_desc.h" +#include "app_usbd_hid_mouse_internal.h" + +/** + * @defgroup app_usbd_hid_mouse USB HID mouse + * @ingroup app_usbd_hid + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID mouse class. + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief HID mouse class instance type + * + * @ref APP_USBD_CLASS_TYPEDEF + */ +typedef struct { } app_usbd_hid_mouse_t; +#else +/*lint -save -e10 -e26 -e123 -e505 */ +APP_USBD_CLASS_TYPEDEF(app_usbd_hid_mouse, \ + APP_USBD_HID_MOUSE_CONFIG(0, NRF_DRV_USBD_EPIN1), \ + APP_USBD_HID_MOUSE_INSTANCE_SPECIFIC_DEC, \ + APP_USBD_HID_MOUSE_DATA_SPECIFIC_DEC \ +); +/*lint -restore*/ +#endif + +/** + * @brief Global definition macro of app_usbd_hid_mouse_t class. + * + * @param instance_name Name of global instance. + * @param interface_number Unique interface number. + * @param endpoint Input endpoint (@ref nrf_drv_usbd_ep_t). + * @param bcnt Mouse button count (from 1 to 8). + * @param user_ev_handler User event handler (optional). + * + * @note This macro is just simplified version of @ref APP_USBD_HID_MOUSE_GLOBAL_DEF_INTERNAL. + * + * @code + APP_USBD_HID_MOUSE_GLOBAL_DEF(my_awesome_mouse, 0, NRF_DRV_USBD_EPIN1, 3, NULL); + * @endcode + */ +#define APP_USBD_HID_MOUSE_GLOBAL_DEF(instance_name, \ + interface_number, \ + endpoint, \ + bcnt, \ + user_ev_handler) \ + APP_USBD_HID_MOUSE_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + endpoint, \ + bcnt, \ + user_ev_handler) + + +/** + * @brief Helper function to get class instance from HID mouse internals. + * + * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF). + * + * @return Base class instance. + */ +static inline app_usbd_class_inst_t const * +app_usbd_hid_mouse_class_inst_get(app_usbd_hid_mouse_t const * p_mouse) +{ + return &p_mouse->base; +} + +/** + * @brief Helper function to get HID mouse from base class instance. + * + * @param[in] p_inst Base class instance. + * + * @return HID mouse class handle. + */ +static inline app_usbd_hid_mouse_t const * +app_usbd_hid_mouse_class_get(app_usbd_class_inst_t const * p_inst) +{ + return (app_usbd_hid_mouse_t const *)p_inst; +} + +/** + * @brief Move mouse X axis. + * + * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF). + * @param[in] offset Relative mouse position: allowed full int8_t range. + * + * @return Standard error code. + */ +ret_code_t app_usbd_hid_mouse_x_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset); + +/** + * @brief Move mouse Y axis. + * + * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF). + * @param[in] offset Relative mouse position: allowed full int8_t range. + * + * @return Standard error code. + */ +ret_code_t app_usbd_hid_mouse_y_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset); + +/** + * @brief Move mouse scroll. + * + * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF). + * @param[in] offset Relative mouse position: allowed full int8_t range. + * + * @return Standard error code. + */ +ret_code_t app_usbd_hid_mouse_scroll_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset); + +/** + * @brief Set mouse button state. + * + * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF). + * @param[in] button_id Button number (0...7). + * @param[in] state Button state: true -> PRESSED, false -> RELEASED. + * + * @return Standard error code. + */ +ret_code_t app_usbd_hid_mouse_button_state(app_usbd_hid_mouse_t const * p_mouse, + uint8_t button_id, + bool state); + +/** @} */ + +#endif /* APP_USBD_HID_MOUSE_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..dc22f70e7a0359505bab1efaee24a9a7d87fc54a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_HID_MOUSE_DESC_H__ +#define APP_USBD_HID_MOUSE_DESC_H__ + +/** + * @defgroup app_usbd_hid_mouse_desc USB HID mouse descriptors + * @ingroup app_usbd_hid_mouse + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID mouse class. + * @{ + */ + +/** + * @brief Initializer of interface descriptor for HID mouse class. + * + * @param interface_number Interface number. + */ +#define APP_USBD_HID_MOUSE_INTERFACE_DSC(interface_number) \ + APP_USBD_HID_INTERFACE_DSC(interface_number, \ + 1, \ + APP_USBD_HID_SUBCLASS_BOOT, \ + APP_USBD_HID_PROTO_MOUSE) + +/** + * @brief Initializer of HID descriptor for HID mouse class. + * + * @param ... Descriptor list. + */ +#define APP_USBD_HID_MOUSE_HID_DSC(...) \ + APP_USBD_HID_HID_DSC(__VA_ARGS__) + +/** + * @brief Initializer of endpoint descriptor for HID mouse class. + * + * @param endpoint_number Endpoint number. + */ +#define APP_USBD_HID_MOUSE_EP_DSC(endpoint_number) \ + APP_USBD_HID_EP_DSC(endpoint_number, 8, 1) + + + +/** + * @brief Example of USB HID mouse report descriptor for n button mouse. + * + * @param bcnt Button count. Allowed values from 1 to 8. + */ +#define APP_USBD_HID_MOUSE_REPORT_DSC_BUTTON(bcnt) { \ + 0x05, 0x01, /* Usage Page (Generic Desktop), */ \ + 0x09, 0x02, /* Usage (Mouse), */ \ + 0xA1, 0x01, /* Collection (Application), */ \ + 0x09, 0x01, /* Usage (Pointer), */ \ + 0xA1, 0x00, /* Collection (Physical), */ \ + 0x05, 0x09, /* Usage Page (Buttons), */ \ + 0x19, 0x01, /* Usage Minimum (01), */ \ + 0x29, bcnt, /* Usage Maximum (bcnt), */ \ + 0x15, 0x00, /* Logical Minimum (0), */ \ + 0x25, 0x01, /* Logical Maximum (1), */ \ + 0x75, 0x01, /* Report Size (1), */ \ + 0x95, bcnt, /* Report Count (bcnt), */ \ + 0x81, 0x02, /* Input (Data, Variable, Absolute)*/ \ + 0x75, (8-(bcnt)), /* Report Size (8-(bcnt)), */ \ + 0x95, 0x01, /* Report Count (1), */ \ + 0x81, 0x01, /* Input (Constant), */ \ + 0x05, 0x01, /* Usage Page (Generic Desktop), */ \ + 0x09, 0x30, /* Usage (X), */ \ + 0x09, 0x31, /* Usage (Y), */ \ + 0x09, 0x38, /* Usage (Scroll), */ \ + 0x15, 0x81, /* Logical Minimum (-127), */ \ + 0x25, 0x7F, /* Logical Maximum (127), */ \ + 0x75, 0x08, /* Report Size (8), */ \ + 0x95, 0x03, /* Report Count (3), */ \ + 0x81, 0x06, /* Input (Data, Variable, Relative)*/ \ + 0xC0, /* End Collection, */ \ + 0xC0, /* End Collection */ \ +} + + /** @} */ + +#endif /* APP_USBD_HID_MOUSE_DESC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..1902382b9da4e99585163a205f2960776278b8d4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h @@ -0,0 +1,182 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_HID_MOUSE_INTERNAL_H__ +#define APP_USBD_HID_MOUSE_INTERNAL_H__ + +/** + * @defgroup app_usbd_hid_mouse_internals USB HID mouse internals + * @ingroup app_usbd_hid_mouse + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID mouse class. + * @{ + */ + +/** + * @brief Forward declaration of HID mouse class type. + */ +APP_USBD_CLASS_FORWARD(app_usbd_hid_mouse); + + +/** + * @brief HID mouse part of class instance data. + */ +typedef struct { + app_usbd_hid_inst_t hid_inst; //!< HID instance data. + const uint8_t button_count; //!< Number of buttons mouse specific. +} app_usbd_hid_mouse_inst_t; + +/** + * @brief HID mouse context. + */ +typedef struct { + app_usbd_hid_ctx_t hid_ctx; //!< HID class context. + + int16_t acc_x_axis; //!< Mouse specific. Accumulated x axis offset. + int16_t acc_y_axis; //!< Mouse specific. Accumulated y axis offset. + int16_t acc_scroll; //!< Mouse specific. Accumulated scroll offset. + uint8_t button_state; //!< Mouse specific. Actual button state. Bitfield of maximum 8 buttons states. + uint8_t report_buff[4]; +} app_usbd_hid_mouse_ctx_t; + + +/** + * @brief HID mouse configuration macro. + * + * Used by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF. + * + */ +#define APP_USBD_HID_MOUSE_CONFIG(iface, ep) ((iface, ep)) + + +/** + * @brief Specific class constant data for HID mouse class. + */ +#define APP_USBD_HID_MOUSE_INSTANCE_SPECIFIC_DEC app_usbd_hid_mouse_inst_t inst; + +/** + * @brief Specific class data for HID mouse class. + */ +#define APP_USBD_HID_MOUSE_DATA_SPECIFIC_DEC app_usbd_hid_mouse_ctx_t ctx; + + +/** + * @brief HID mouse descriptors config macro + * + * @ref app_usbd_hid_mouse_inst_t + * + */ +#define APP_USBD_HID_MOUSE_DSC_CONFIG(interface_number, endpoint, rep_desc) { \ + APP_USBD_HID_MOUSE_INTERFACE_DSC(interface_number) \ + APP_USBD_HID_MOUSE_HID_DSC(rep_desc) \ + APP_USBD_HID_MOUSE_EP_DSC(endpoint) \ +} + + +/** + * @brief Configure internal part of HID mouse instance. + * + * @param descriptors Raw descriptors buffer. + * @param report_desc Report descriptor. + * @param report_buff_in Input report buffers array. + * @param report_buff_out Output report buffer. + * @param user_ev_handler User event handler. + * @param bcnt Mouse button count. + */ +#define APP_USBD_HID_MOUSE_INST_CONFIG(descriptors, \ + report_desc, \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler, \ + bcnt) \ + .inst = { \ + .hid_inst = APP_USBD_HID_INST_CONFIG(descriptors, \ + report_desc, \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler, \ + &app_usbd_hid_mouse_methods), \ + .button_count = bcnt, \ + } + +/** + * @brief Public HID mouse interface. + */ +extern const app_usbd_hid_methods_t app_usbd_hid_mouse_methods; + +/** + * @brief Public HID mouse class interface. + */ +extern const app_usbd_class_methods_t app_usbd_hid_mouse_class_methods; + +/** + * @brief Global definition of app_usbd_hid_mouse_t class. + * + * @ref APP_USBD_HID_MOUSE_GLOBAL_DEF + */ +#define APP_USBD_HID_MOUSE_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + endpoint, \ + bcnt, \ + user_ev_handler) \ + static const uint8_t CONCAT_2(instance_name, _rep_dsc)[] = \ + APP_USBD_HID_MOUSE_REPORT_DSC_BUTTON(bcnt); \ + static const uint8_t CONCAT_2(instance_name, _dsc)[] = \ + APP_USBD_HID_MOUSE_DSC_CONFIG(interface_number, \ + endpoint, \ + CONCAT_2(instance_name, \ + _rep_dsc)); \ + static app_usbd_hid_report_buffer_t CONCAT_2(instance_name, _in)[1]; \ + APP_USBD_CLASS_INST_GLOBAL_DEF( \ + instance_name, \ + app_usbd_hid_mouse, \ + &app_usbd_hid_mouse_class_methods, \ + APP_USBD_HID_MOUSE_CONFIG(interface_number, endpoint), \ + (APP_USBD_HID_MOUSE_INST_CONFIG(CONCAT_2(instance_name, _dsc), \ + CONCAT_2(instance_name, _rep_dsc), \ + CONCAT_2(instance_name, _in), \ + NULL, \ + user_ev_handler, \ + bcnt)) \ + ) + + +/** @} */ + +#endif /* APP_USBD_HID_MOUSE_INTERNAL_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc.c new file mode 100644 index 0000000000000000000000000000000000000000..5d4b6963999a5bf21cec97a4b42b6777ae13202e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc.c @@ -0,0 +1,2056 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_CLASS_MSC_ENABLED +#include +#include + +#include "app_usbd.h" +#include "sdk_common.h" +#include "app_usbd_msc.h" +#include "app_usbd_string_desc.h" + +/** + * @defgroup app_usbd_msc_internal USBD MSC internals + * @{ + * @ingroup app_usbd_msc + * @internal + */ + +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_requestsense_t) == 6); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_requestsense_resp_t) == 18); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_inquiry_t) == 6); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_inquiry_resp_t) == 36); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_read6_t) == 6); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_write6_t) == 6); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense6_t) == 6); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense6_resp_t) == 4); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_readcapacity10_t) == 10); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_readcapacity10_resp_t) == 8); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_read10_t) == 10); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_write10_t) == 10); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense10_t) == 10); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense10_resp_t) == 8); + +STATIC_ASSERT(sizeof(app_usbd_msc_cbw_t) == 31); +STATIC_ASSERT(sizeof(app_usbd_msc_csw_t) == 13); + +#define NRF_LOG_MODULE_NAME "USBD MSC" +#if APP_USBD_MSC_CLASS_LOG_ENABLED +#else //APP_USBD_MSC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //APP_USBD_MSC_CONFIG_LOG_ENABLED +#include "nrf_log.h" + +#define APP_USBD_MSC_IFACE_IDX 0 /**< Mass storage class interface index */ +#define APP_USBD_MSC_EPIN_IDX 0 /**< Mass storage class endpoint IN index */ +#define APP_USBD_MSC_EPOUT_IDX 1 /**< Mass storage class endpoint OUT index */ + +/** + * @brief Set request buffer busy flag + * + * @param[in] val Bitmask to set + * @param[in] id Buffer id + * */ +#define APP_USBD_MSC_REQ_BUSY_SET(val, id) SET_BIT(val, id) + +/** + * @brief Clear request buffer busy flag + * + * @param[in] val Bitmask to set + * @param[in] id Buffer id + * */ +#define APP_USBD_MSC_REQ_BUSY_CLR(val, id) CLR_BIT(val, id) + +#define APP_USBD_MSC_REQ_BUSY_FULL_MASK (0x03) /**< Request busy mask */ + +static void msc_blockdev_ev_handler(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_event_t const * p_event); + +/** + * @brief Auxiliary function to access MSC instance data + * + * @param[in] p_inst Class instance data + * + * @return MSC instance data @ref app_usbd_msc_t + */ +static inline app_usbd_msc_t const * msc_get(app_usbd_class_inst_t const * p_inst) +{ + ASSERT(p_inst != NULL); + return (app_usbd_msc_t const *)p_inst; +} + +/** + * @brief Auxiliary function to access MSC context data + * + * @param[in] p_msc MSC instance data + * @return MSC context data @ref app_usbd_msc_ctx_t + */ +static inline app_usbd_msc_ctx_t * msc_ctx_get(app_usbd_msc_t const * p_msc) +{ + ASSERT(p_msc != NULL); + ASSERT(p_msc->specific.p_data != NULL); + return &p_msc->specific.p_data->ctx; +} + +/** + * @brief Auxiliary function to access MSC IN endpoint address + * + * @param[in] p_inst Class instance data + * + * @return IN endpoint address + */ +static inline nrf_drv_usbd_ep_t ep_in_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_MSC_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_MSC_EPIN_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** + * @brief Auxiliary function to access MSC OUT endpoint address + * + * @param[in] p_inst Class instance data + * + * @return OUT endpoint address + */ +static inline nrf_drv_usbd_ep_t ep_out_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_MSC_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_MSC_EPOUT_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** + * @brief Command Block Wrapper trigger + * + * @param[in] p_inst Generic class instance + * @param[in] state Next state transition + * + * @return Standard error code + * */ +static ret_code_t cbw_wait_start(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + nrf_drv_usbd_ep_t ep_addr_out = ep_out_addr_get(p_inst); + + NRF_LOG_DEBUG("cbw_wait_start\r\n"); + memset(&p_msc_ctx->cbw, 0, sizeof(app_usbd_msc_cbw_t)); + NRF_DRV_USBD_TRANSFER_OUT(cbw, &p_msc_ctx->cbw, sizeof(app_usbd_msc_cbw_t)); + ret_code_t ret = app_usbd_core_ep_transfer(ep_addr_out, &cbw); + if (ret == NRF_SUCCESS) + { + p_msc_ctx->state = APP_USBD_MSC_STATE_CBW; + } + + return ret; +} + +/** + * @brief Command Status Wrapper trigger + * + * @param[in] p_inst Generic class instance + * @param[in] state Next state transition + * + * @return Standard error code + * */ +static ret_code_t csw_wait_start(app_usbd_class_inst_t const * p_inst, uint8_t status) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + nrf_drv_usbd_ep_t ep_addr_in = ep_in_addr_get(p_inst); + + memset(&p_msc_ctx->csw, 0, sizeof(app_usbd_msc_csw_t)); + memcpy(p_msc_ctx->csw.signature, APP_USBD_MSC_CSW_SIGNATURE, sizeof(p_msc_ctx->csw.signature)); + memcpy(p_msc_ctx->csw.tag, p_msc_ctx->cbw.tag, sizeof(p_msc_ctx->csw.tag)); + memcpy(p_msc_ctx->csw.residue, &p_msc_ctx->current.residue, sizeof(uint32_t)); + p_msc_ctx->csw.status = status; + + NRF_DRV_USBD_TRANSFER_IN(csw, &p_msc_ctx->csw, sizeof(app_usbd_msc_csw_t)); + ret_code_t ret = app_usbd_core_ep_transfer(ep_addr_in, &csw); + if (ret == NRF_SUCCESS) + { + p_msc_ctx->state = APP_USBD_MSC_STATE_CSW; + } + + return ret; +} + +/** + * @brief IN transfer trigger + * + * @param[in] p_inst Generic class instance + * @param[in] p_buff IN transfer data buffer + * @param[in] size IN transfer size + * @param[in] state Next state transition + * + * @return Standard error code + * */ +static ret_code_t transfer_in_start(app_usbd_class_inst_t const * p_inst, + void const * p_buff, + size_t size, + app_usbd_msc_state_t state) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + NRF_LOG_DEBUG("transfer_in_start: p_buff: %p, size: %u\r\n", (uint32_t)p_buff, size); + + nrf_drv_usbd_ep_t ep_addr_in = ep_in_addr_get(p_inst); + + NRF_DRV_USBD_TRANSFER_IN(resp, p_buff, size); + ret_code_t ret = app_usbd_core_ep_transfer(ep_addr_in, &resp); + if (ret == NRF_SUCCESS) + { + p_msc_ctx->state = state; + } + return ret; +} + +/** + * @brief MSC reset request handler @ref APP_USBD_MSC_REQ_BULK_RESET + * + * @param[in] p_inst Generic class instance + * + * */ +static void bulk_ep_reset(app_usbd_class_inst_t const * p_inst) +{ + nrf_drv_usbd_ep_t ep_addr_in = ep_in_addr_get(p_inst); + nrf_drv_usbd_ep_t ep_addr_out = ep_out_addr_get(p_inst); + + usbd_drv_ep_abort(ep_addr_in); + usbd_drv_ep_abort(ep_addr_out); +} + + +/** + * @brief OUT transfer trigger + * + * @param[in] p_inst Generic class instance + * @param[in] p_buff OUT transfer data buffer + * @param[in] size OUT transfer size + * @param[in] state Next state transition + * + * @return Standard error code + * */ +static ret_code_t transfer_out_start(app_usbd_class_inst_t const * p_inst, + void * p_buff, + size_t size, + app_usbd_msc_state_t state) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + NRF_LOG_DEBUG("transfer_out_start: p_buff: %p, size: %u\r\n", (uint32_t)p_buff, size); + nrf_drv_usbd_ep_t ep_addr_out = ep_out_addr_get(p_inst); + + NRF_DRV_USBD_TRANSFER_OUT(resp, p_buff, size); + ret_code_t ret = app_usbd_core_ep_transfer(ep_addr_out, &resp); + if (ret == NRF_SUCCESS) + { + p_msc_ctx->state = state; + } + return ret; +} + +/** + * @brief Start status stage of unsupported SCSI command + * + * @param[in] p_inst Generic class instance + * + * @return Standard error code + * */ +static ret_code_t unsupported_start(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + if (p_msc_ctx->cbw.flags & APP_USBD_MSC_CBW_DIRECTION_IN) + { + return transfer_in_start(p_inst, NULL, 0, APP_USBD_MSC_STATE_UNSUPPORTED); + } + + p_msc_ctx->state = APP_USBD_MSC_STATE_UNSUPPORTED; + return NRF_ERROR_NOT_SUPPORTED; +} + + + +/** + * @brief Internal SETUP standard IN request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + /*Only Get Descriptor standard IN request is supported by MSC class*/ + if (p_setup_ev->setup.bmRequest != APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + size_t dsc_len = 0; + + /* Try to find descriptor in class internals*/ + void const * p_dsc = app_usbd_class_descriptor_find(p_inst, + p_setup_ev->setup.wValue.hb, + p_setup_ev->setup.wValue.lb, + &dsc_len); + if (p_dsc != NULL) + { + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_dsc, dsc_len); + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP standard OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP class IN request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_MSC_REQ_GET_MAX_LUN: + { + + if (p_setup_ev->setup.wValue.w != 0) + { + break; + } + + if (p_setup_ev->setup.wLength.w != 1) + { + break; + } + + size_t tx_size; + uint16_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size); + ASSERT(p_msc->specific.inst.block_devs_count != 0); + p_tx_buff[0] = p_msc->specific.inst.block_devs_count - 1; + + ret_code_t ret = cbw_wait_start(p_inst); + UNUSED_VARIABLE(ret); + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint8_t)); + } + default: + break; + + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP class OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_MSC_REQ_BULK_RESET: + { + if (p_setup_ev->setup.wValue.w != 0) + { + break; + } + + if (p_setup_ev->setup.wLength.w != 0) + { + break; + } + + /* + * Reset internal state to be ready for next CBW + */ + NRF_LOG_DEBUG("bulk ep reset\r\n"); + bulk_ep_reset(p_inst); + + if (p_msc_ctx->state == APP_USBD_MSC_STATE_DISABLED) + { + ret_code_t ret = cbw_wait_start(p_inst); + UNUSED_VARIABLE(ret); + } + + return NRF_SUCCESS; + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Control endpoint handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + ASSERT(p_inst != NULL); + ASSERT(p_setup_ev != NULL); + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + app_usbd_setup_reqrec_t req_rec = app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType); + app_usbd_setup_reqtype_t req_type = app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType); + if (req_rec == APP_USBD_SETUP_REQREC_ENDPOINT && + req_type == APP_USBD_SETUP_REQTYPE_STD) + { + + ret_code_t ret = app_usbd_endpoint_std_req_handle(p_setup_ev); + if (ret != NRF_SUCCESS) + { + return ret; + } + + if ((p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_CLEAR_FEATURE) && + (p_msc_ctx->state == APP_USBD_MSC_STATE_UNSUPPORTED)) + { + /*Unsupported command handle: status stage*/ + ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL); + } + + return ret; + } + + if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN) + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_in(p_inst, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_in(p_inst, p_setup_ev); + default: + break; + } + } + else /*APP_USBD_SETUP_REQDIR_OUT*/ + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_out(p_inst, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_out(p_inst, p_setup_ev); + default: + break; + } + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Handle read6/read10 command data stage + * + * @param[in] p_inst Generic class instance + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t state_data_in_handle(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + ret_code_t ret = NRF_SUCCESS; + + p_msc_ctx->current.trans_in_progress = false; + APP_USBD_MSC_REQ_BUSY_CLR(p_msc_ctx->current.req_busy_mask, p_msc_ctx->current.trans_req_id); + + if (p_msc_ctx->current.blk_datasize == 0 && p_msc_ctx->current.req_busy_mask == 0) + { + p_msc_ctx->current.blk_idx = p_msc_ctx->current.blk_size = 0; + ret = csw_wait_start(p_inst, p_msc_ctx->current.csw_status); + return ret; + } + + ASSERT(p_msc_ctx->current.blk_size != 0); + + if (p_msc_ctx->current.req_busy_mask == 0) + { + nrf_block_dev_t const * p_blkd = + p_msc->specific.inst.pp_block_devs[p_msc_ctx->current.lun]; + + /*Trigger new block read request*/ + p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size; + uint32_t req_pos = p_msc_ctx->current.workbuff_pos != 0 ? 1 : 0; + APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, req_pos); + + NRF_BLOCK_DEV_REQUEST(req, + p_msc_ctx->current.blk_idx, + p_msc_ctx->current.blk_count, + ((uint8_t *)p_msc->specific.inst.p_block_buff + + p_msc_ctx->current.workbuff_pos)); + + NRF_LOG_DEBUG("nrf_blk_dev_read_req 3: id: %u, count: %u, left: %u, ptr: %p\r\n", + req.blk_id, + req.blk_count, + p_msc_ctx->current.blk_datasize, + (uint32_t)req.p_buff); + + ret = nrf_blk_dev_read_req(p_blkd, &req); + NRF_LOG_DEBUG("nrf_blk_dev_read_req 3: ret: %u\r\n", ret); + return ret; + } + + uint32_t blk_size = p_msc_ctx->current.blk_size; + p_msc_ctx->current.trans_req_id ^= 1; + + nrf_block_req_t * p_req = &p_msc_ctx->current.req; + if (p_req->p_buff == NULL) + { + p_msc_ctx->current.trans_req_id ^= 1; + return NRF_SUCCESS; + } + + ret = transfer_in_start(p_inst, + p_req->p_buff, + p_req->blk_count * blk_size, + APP_USBD_MSC_STATE_DATA_IN); + + if (ret == NRF_SUCCESS) + { + /*Clear processed block request.*/ + memset(p_req, 0, sizeof(nrf_block_req_t)); + p_msc_ctx->current.trans_in_progress = true; + } + + return ret; +} + +/** + * @brief Endpoint IN event handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t endpoint_in_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + NRF_LOG_DEBUG("state: %d, ep in event, status: %d\r\n", + p_msc_ctx->state, + p_event->drv_evt.data.eptransfer.status); + + if (p_event->drv_evt.data.eptransfer.status != NRF_USBD_EP_OK) + { + return NRF_SUCCESS; + } + + ret_code_t ret = NRF_SUCCESS; + switch (p_msc_ctx->state) { + case APP_USBD_MSC_STATE_CMD_IN: + { + ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); + break; + } + case APP_USBD_MSC_STATE_DATA_IN: + { + CRITICAL_REGION_ENTER(); + ret = state_data_in_handle(p_inst); + CRITICAL_REGION_EXIT(); + + break; + } + case APP_USBD_MSC_STATE_CSW: + { + break; + } + case APP_USBD_MSC_STATE_DATA_OUT: + { + break; + } + case APP_USBD_MSC_STATE_UNSUPPORTED: + { + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + default: + { + ret = NRF_ERROR_INTERNAL; + break; + } + } + + return ret; +} + + +/** + * @brief Helper function to calculate next block transfer block count + * + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * + * @return Blocks to transfer + * */ +static uint32_t next_transfer_blkcnt_calc(app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + uint32_t blkcnt = p_msc->specific.inst.block_buff_size / p_msc_ctx->current.blk_size; + if (blkcnt > (p_msc_ctx->current.blk_datasize / p_msc_ctx->current.blk_size)) + { + blkcnt = p_msc_ctx->current.blk_datasize / p_msc_ctx->current.blk_size; + } + + return blkcnt; +} + +/** + * @brief Helper function to calculate next transfer size + * + * @param[in] p_msc_ctx MSC context + * + * @return Blocks to transfer + * */ +static uint32_t next_transfer_size_calc(app_usbd_msc_ctx_t * p_msc_ctx) +{ + uint32_t blk_cnt = p_msc_ctx->current.blk_count; + uint32_t blk_size = p_msc_ctx->current.blk_size; + + return p_msc_ctx->current.blk_datasize > blk_size * blk_cnt ? + blk_size * blk_cnt : p_msc_ctx->current.blk_datasize; +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_TESTUNITREADY handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_testunitready(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: TESTUNITREADY\r\n"); + if (uint32_decode(p_msc_ctx->cbw.datlen) != 0) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.cdb_length != APP_USBD_SCSI_CMD_TESTUNITREADY_LEN) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_REQUESTSENSE handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_requestsense(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: REQUESTSENSE\r\n"); + app_usbd_scsi_cmd_requestsense_t const * p_reqs = (const void *)p_msc_ctx->cbw.cdb; + UNUSED_VARIABLE(p_reqs); + + if ((p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_requestsense_t))) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->resp_len = MIN(p_msc_ctx->resp_len, + sizeof(app_usbd_scsi_cmd_requestsense_resp_t)); + + if (p_msc_ctx->resp_len == 0) + { + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); + } + + memset(&p_msc_ctx->scsi_resp, 0, sizeof(app_usbd_scsi_cmd_requestsense_resp_t)); + p_msc_ctx->scsi_resp.requestsense.code = APP_USBD_SCSI_CMD_REQSENSE_CODE_VALID | + APP_USBD_SCSI_CMD_REQSENSE_CODE_CURRENT; + + p_msc_ctx->scsi_resp.requestsense.len = sizeof(app_usbd_scsi_cmd_requestsense_resp_t) - + offsetof(app_usbd_scsi_cmd_requestsense_resp_t, len); + + return transfer_in_start(p_inst, + &p_msc_ctx->scsi_resp, + p_msc_ctx->resp_len, + APP_USBD_MSC_STATE_CMD_IN); +} + + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_FORMAT_UNIT handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_formatunit(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: FORMAT_UNIT\r\n"); + return unsupported_start(p_inst); +} + +static ret_code_t cmd_read_start(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + + p_msc_ctx->current.trans_in_progress = false; + p_msc_ctx->current.req_busy_mask = 0; + p_msc_ctx->current.workbuff_pos = 0; + + APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, 0); + NRF_BLOCK_DEV_REQUEST(req, + p_msc_ctx->current.blk_idx, + p_msc_ctx->current.blk_count, + ((uint8_t *)p_msc->specific.inst.p_block_buff + + p_msc_ctx->current.workbuff_pos)); + + NRF_LOG_DEBUG("cmd_read_start\r\n"); + NRF_LOG_DEBUG("nrf_blk_dev_read_req 1: id: %u, count: %u, left: %u, ptr: %p\r\n", + req.blk_id, + req.blk_count, + p_msc_ctx->current.blk_datasize, + (uint32_t)req.p_buff); + + ret_code_t ret = nrf_blk_dev_read_req(p_blkd, &req); + NRF_LOG_DEBUG("nrf_blk_dev_read_req 1: ret: %u\r\n", ret); + + return ret; +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_READ6 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_read6(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: READ6\r\n"); + app_usbd_scsi_cmd_read6_t const * p_read6 = (const void *)p_msc_ctx->cbw.cdb; + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_read6_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + + p_msc_ctx->current.lun = p_msc_ctx->cbw.lun; + p_msc_ctx->current.blk_idx = ((p_read6->mslba & 0x1F) << 16) | + uint16_big_decode(p_read6->lslba); + p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size; + p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx); + + if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * p_read6->xfrlen) + { + p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize - + p_msc_ctx->current.blk_size * p_read6->xfrlen; + } + + return cmd_read_start(p_inst, p_msc, p_msc_ctx); +} + +static ret_code_t cmd_write_start(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("cmd_write_start\r\n"); + ret_code_t ret = transfer_out_start(p_inst, + ((uint8_t *)p_msc->specific.inst.p_block_buff + + p_msc_ctx->current.workbuff_pos), + next_transfer_size_calc(p_msc_ctx), + APP_USBD_MSC_STATE_DATA_OUT); + + if (ret == NRF_SUCCESS) + { + p_msc_ctx->current.trans_req_id = 0; + APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, + p_msc_ctx->current.trans_req_id); + p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size; + p_msc_ctx->current.trans_in_progress = true; + } + + return ret; +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_WRITE6 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_write6(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: WRITE6\r\n"); + app_usbd_scsi_cmd_write6_t const * p_write6 = (const void *)p_msc_ctx->cbw.cdb; + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_write6_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + + p_msc_ctx->current.lun = p_msc_ctx->cbw.lun; + p_msc_ctx->current.blk_idx = (p_write6->mslba & 0x1F << 16) | + uint16_big_decode(p_write6->lslba); + p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size; + p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx); + + if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * p_write6->xfrlen) + { + p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize - + p_msc_ctx->current.blk_size * p_write6->xfrlen; + } + + return cmd_write_start(p_inst, p_msc, p_msc_ctx); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_INQUIRY handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_inquiry(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: INQUIRY\r\n"); + app_usbd_scsi_cmd_inquiry_t const * p_inq = (const void *)p_msc_ctx->cbw.cdb; + if (p_inq->pagecode != 0) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->resp_len = MIN(p_msc_ctx->resp_len, + sizeof(app_usbd_scsi_cmd_inquiry_resp_t)); + + if (p_msc_ctx->resp_len == 0) + { + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); + } + + + p_msc_ctx->scsi_resp.inquiry.qualtype = APP_USBD_MSC_SCSI_INQ_QUAL_CONNECTED | + APP_USBD_MSC_SCSI_INQ_TYPE_DIR_ACCESS; + p_msc_ctx->scsi_resp.inquiry.flags1 = APP_USBD_MSC_SCSI_INQ_FLAG1_RMB; + p_msc_ctx->scsi_resp.inquiry.version = APP_USBD_SCSI_INQ_VER_SPC4; + p_msc_ctx->scsi_resp.inquiry.flags2 = APP_USBD_MSC_SCSI_INQ_FLAG2_RSP_SPC2 | + APP_USBD_MSC_SCSI_INQ_FLAG2_HISUP; + p_msc_ctx->scsi_resp.inquiry.len = sizeof(app_usbd_scsi_cmd_inquiry_resp_t) - + offsetof(app_usbd_scsi_cmd_inquiry_resp_t, len); + + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + nrf_block_dev_info_strings_t * p_strings = NULL; + UNUSED_RETURN_VALUE(nrf_blk_dev_ioctl(p_blkd, + NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS, + &p_strings)); + + if (p_strings) + { + UNUSED_RETURN_VALUE(strncpy((char *)p_msc_ctx->scsi_resp.inquiry.vendorid, + p_strings->p_vendor, + sizeof(p_msc_ctx->scsi_resp.inquiry.vendorid))); + + UNUSED_RETURN_VALUE(strncpy((char *)p_msc_ctx->scsi_resp.inquiry.productid, + p_strings->p_product, + sizeof(p_msc_ctx->scsi_resp.inquiry.productid))); + + UNUSED_RETURN_VALUE(strncpy((char *)p_msc_ctx->scsi_resp.inquiry.revision, + p_strings->p_revision, + sizeof(p_msc_ctx->scsi_resp.inquiry.revision))); + } + else { + memset(p_msc_ctx->scsi_resp.inquiry.vendorid, + 0, + sizeof(p_msc_ctx->scsi_resp.inquiry.vendorid)); + memset(p_msc_ctx->scsi_resp.inquiry.productid, + 0, + sizeof(p_msc_ctx->scsi_resp.inquiry.productid)); + memset(p_msc_ctx->scsi_resp.inquiry.revision, + 0, + sizeof(p_msc_ctx->scsi_resp.inquiry.revision)); + } + + return transfer_in_start(p_inst, + &p_msc_ctx->scsi_resp, + p_msc_ctx->resp_len, + APP_USBD_MSC_STATE_CMD_IN); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESELECT6 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_modeselect6(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: MODESELECT6\r\n"); + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); +} + + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESENSE6 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_modesense6(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: MODESENSE6\r\n"); + app_usbd_scsi_cmd_modesense6_t const * p_sense6 = (const void *)p_msc_ctx->cbw.cdb; + UNUSED_VARIABLE(p_sense6); + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_modesense6_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->resp_len = MIN(p_msc_ctx->resp_len, + sizeof(app_usbd_scsi_cmd_modesense6_resp_t)); + + app_usbd_scsi_cmd_modesense6_resp_t * p_resp = &p_msc_ctx->scsi_resp.modesense6; + p_resp->mdlen = sizeof(app_usbd_scsi_cmd_modesense6_resp_t) - 1; + p_resp->type = 0; + p_resp->param = 0; + p_resp->bdlen = 0; + + return transfer_in_start(p_inst, + &p_msc_ctx->scsi_resp, + p_msc_ctx->resp_len, + APP_USBD_MSC_STATE_CMD_IN); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_STARTSTOPUNIT handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_startstopunit(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: STARTSTOPUNIT\r\n"); + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); +} + + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_SENDDIAGNOSTIC handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_senddiagnostic(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: SENDDIAGNOSTIC\r\n"); + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_PREVENTMEDIAREMOVAL handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_preventremoval(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: PREVENTMEDIAREMOVAL\r\n"); + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_READCAPACITY10 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_readcapacity10(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: READCAPACITY10\r\n"); + + app_usbd_scsi_cmd_readcapacity10_t const * p_cap10 = (const void *)p_msc_ctx->cbw.cdb; + UNUSED_VARIABLE(p_cap10); + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_readcapacity10_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->resp_len = MIN(p_msc_ctx->resp_len, + sizeof(app_usbd_scsi_cmd_readcapacity10_resp_t)); + + if (p_msc_ctx->resp_len == 0) + { + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); + } + + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + nrf_block_dev_geometry_t const * p_geometry = nrf_blk_dev_geometry(p_blkd); + + (void)uint32_big_encode(p_geometry->blk_count - 1, p_msc_ctx->scsi_resp.readcapacity10.lba); + (void)uint32_big_encode(p_geometry->blk_size, p_msc_ctx->scsi_resp.readcapacity10.blklen); + + return transfer_in_start(p_inst, + &p_msc_ctx->scsi_resp, + p_msc_ctx->resp_len, + APP_USBD_MSC_STATE_CMD_IN); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_READ10 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_read10(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: READ10\r\n"); + app_usbd_scsi_cmd_read10_t const * p_read10 = (const void *)p_msc_ctx->cbw.cdb; + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_read10_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + if (uint32_decode(p_msc_ctx->cbw.datlen) == 0) + { + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL); + } + + if ((p_msc_ctx->cbw.flags & APP_USBD_MSC_CBW_DIRECTION_IN) == 0) + { + return unsupported_start(p_inst); + } + + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + + p_msc_ctx->current.lun = p_msc_ctx->cbw.lun; + p_msc_ctx->current.blk_idx = uint32_big_decode(p_read10->lba); + p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size; + p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx); + + uint16_t blocks = uint16_big_decode(p_read10->xfrlen); + p_msc_ctx->current.csw_status = + uint32_decode(p_msc_ctx->cbw.datlen) < p_msc_ctx->current.blk_size * blocks ? + APP_USBD_MSC_CSW_STATUS_FAIL : APP_USBD_MSC_CSW_STATUS_PASS; + + if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * blocks) + { + p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize - + p_msc_ctx->current.blk_size * blocks; + } + + return cmd_read_start(p_inst, p_msc, p_msc_ctx); +} + + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_WRITE10 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_write10(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: WRITE10\r\n"); + app_usbd_scsi_cmd_write10_t const * p_write10 = (const void *)p_msc_ctx->cbw.cdb; + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_write10_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + if (uint32_decode(p_msc_ctx->cbw.datlen) == 0) + { + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL); + } + + + if ((p_msc_ctx->cbw.flags & APP_USBD_MSC_CBW_DIRECTION_IN) != 0) + { + return unsupported_start(p_inst); + } + + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + + p_msc_ctx->current.lun = p_msc_ctx->cbw.lun; + p_msc_ctx->current.blk_idx = uint32_big_decode(p_write10->lba); + p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size; + p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx); + + uint16_t blocks = uint16_big_decode(p_write10->xfrlen); + p_msc_ctx->current.csw_status = + uint32_decode(p_msc_ctx->cbw.datlen) < p_msc_ctx->current.blk_size * blocks ? + APP_USBD_MSC_CSW_STATUS_FAIL : APP_USBD_MSC_CSW_STATUS_PASS; + + if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * blocks) + { + p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize - + p_msc_ctx->current.blk_size * blocks; + } + + return cmd_write_start(p_inst, p_msc, p_msc_ctx); +} + + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESELECT10 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_modeselect10(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: MODESELECT10\r\n"); + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESENSE10 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_modesense10(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: MODESENSE10\r\n"); + app_usbd_scsi_cmd_modesense10_t const * p_sense10 = (const void *)p_msc_ctx->cbw.cdb; + UNUSED_VARIABLE(p_sense10); + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_modesense10_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->resp_len = MIN(p_msc_ctx->resp_len, + sizeof(app_usbd_scsi_cmd_modesense6_resp_t)); + + app_usbd_scsi_cmd_modesense10_resp_t * p_resp = &p_msc_ctx->scsi_resp.modesense10; + + memset(p_resp, 0, sizeof(app_usbd_scsi_cmd_modesense10_resp_t)); + uint16_t len = sizeof(app_usbd_scsi_cmd_modesense10_resp_t) - sizeof(p_resp->mdlen); + p_resp->mdlen[1] = len & 0xff; + p_resp->mdlen[0] = (len >> 8) & 0xff; + + return transfer_in_start(p_inst, + &p_msc_ctx->scsi_resp, + p_msc_ctx->resp_len, + APP_USBD_MSC_STATE_CMD_IN); +} + + +/** + * @brief SCSI Command Block Wrapper handler + * + * @param[in] p_inst Generic class instance + * @return Standard error code + * */ +static ret_code_t state_cbw(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + memset(&p_msc_ctx->current, 0, sizeof(p_msc_ctx->current)); + + /*Verify CBW signature*/ + if (memcmp(p_msc_ctx->cbw.signature, + APP_USBD_MSC_CBW_SIGNATURE, + sizeof(p_msc_ctx->cbw.signature)) != 0) + { + NRF_LOG_DEBUG("CMD: header error: 0x%02x%02x%02x%02x\r\n", + p_msc_ctx->cbw.signature[0], p_msc_ctx->cbw.signature[1], + p_msc_ctx->cbw.signature[2], p_msc_ctx->cbw.signature[3]); + + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); + } + + ret_code_t ret = NRF_SUCCESS; + switch (p_msc_ctx->cbw.cdb[0]) + { + case APP_USBD_SCSI_CMD_TESTUNITREADY: + ret = cmd_testunitready(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_REQUESTSENSE: + ret = cmd_requestsense(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_FORMAT_UNIT: + ret = cmd_formatunit(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_READ6: + ret = cmd_read6(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_WRITE6: + ret = cmd_write6(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_INQUIRY: + ret = cmd_inquiry(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_MODESELECT6: + ret = cmd_modeselect6(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_MODESENSE6: + ret = cmd_modesense6(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_STARTSTOPUNIT: + ret = cmd_startstopunit(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_SENDDIAGNOSTIC: + ret = cmd_senddiagnostic(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_PREVENTMEDIAREMOVAL: + ret = cmd_preventremoval(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_READCAPACITY10: + ret = cmd_readcapacity10(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_READ10: + ret = cmd_read10(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_WRITE10: + ret = cmd_write10(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_MODESELECT10: + ret = cmd_modeselect10(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_MODESENSE10: + ret = cmd_modesense10(p_inst, p_msc, p_msc_ctx); + break; + default: + NRF_LOG_DEBUG("CMD: UNSUPPORTED\r\n"); + if (uint32_decode(p_msc_ctx->cbw.datlen) != 0) + { + ret = unsupported_start(p_inst); + } + else + { + ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL); + } + break; + } + + return ret; +} + + +/** + * @brief Handle write6/write10 command data stage + * + * @param[in] p_inst Generic class instance + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t state_data_out_handle(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + ret_code_t ret = NRF_SUCCESS; + uint32_t blk_size = p_msc_ctx->current.blk_size; + + NRF_LOG_DEBUG("APP_USBD_MSC_STATE_DATA_OUT\r\n"); + + p_msc_ctx->current.trans_in_progress = false; + if ((p_msc_ctx->current.req_busy_mask != APP_USBD_MSC_REQ_BUSY_FULL_MASK) && + (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_count * blk_size)) + { + size_t size = p_msc_ctx->current.blk_datasize - p_msc_ctx->current.blk_count * blk_size; + if (size > p_msc_ctx->current.blk_count * blk_size) + { + size = p_msc_ctx->current.blk_count * blk_size; + } + + if (size) + { + ret = transfer_out_start(p_inst, + ((uint8_t *)p_msc->specific.inst.p_block_buff + + p_msc_ctx->current.workbuff_pos), + size, + APP_USBD_MSC_STATE_DATA_OUT); + if (ret == NRF_SUCCESS) + { + p_msc_ctx->current.trans_req_id ^= 1; + APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, + p_msc_ctx->current.trans_req_id); + p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size; + p_msc_ctx->current.trans_in_progress = true; + } + } + } + + if (!p_msc_ctx->current.block_req_in_progress) + { + nrf_block_dev_t const * p_blkd = + p_msc->specific.inst.pp_block_devs[p_msc_ctx->current.lun]; + + size_t pos = p_msc_ctx->current.workbuff_pos; + if (p_msc_ctx->current.req_busy_mask != APP_USBD_MSC_REQ_BUSY_FULL_MASK) + { + pos ^= p_msc->specific.inst.block_buff_size; + } + + NRF_BLOCK_DEV_REQUEST(req, + p_msc_ctx->current.blk_idx, + p_msc_ctx->current.blk_count, + ((uint8_t *)p_msc->specific.inst.p_block_buff + pos)); + + NRF_LOG_DEBUG("nrf_blk_dev_write_req 1: id: %u, count: %u, left: %u, ptr: %p\r\n", + req.blk_id, + req.blk_count, + p_msc_ctx->current.blk_datasize, + (uint32_t)req.p_buff); + + p_msc_ctx->current.block_req_in_progress = true; + ret = nrf_blk_dev_write_req(p_blkd, &req); + NRF_LOG_DEBUG("nrf_blk_dev_write_req 1: ret: %u\r\n", ret); + } + + return ret; +} + +/** + * @brief Endpoint OUT event handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t endpoint_out_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + NRF_LOG_DEBUG("state: %d, ep out event, status: %d\r\n", + p_msc_ctx->state, + p_event->drv_evt.data.eptransfer.status); + + ret_code_t ret = NRF_SUCCESS; + if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_WAITING) + { + if (p_msc_ctx->state == APP_USBD_MSC_STATE_DATA_OUT) + { + NRF_LOG_DEBUG("NRF_USBD_EP_WAITING\r\n"); + } + else if (p_msc_ctx->state == APP_USBD_MSC_STATE_CSW || + p_msc_ctx->state == APP_USBD_MSC_STATE_IDLE) + { + ret = cbw_wait_start(p_inst); + } + + return ret; + } + else if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_ABORTED) + { + p_msc_ctx->state = APP_USBD_MSC_STATE_IDLE; + return NRF_SUCCESS; + } + else if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_OVERLOAD) + { + nrf_drv_usbd_transfer_out_drop(p_event->drv_evt.data.eptransfer.ep); + return NRF_SUCCESS; + } + else /*NRF_USBD_EP_OK*/ + { + switch (p_msc_ctx->state) + { + case APP_USBD_MSC_STATE_CBW: + { + ret = state_cbw(p_inst); + break; + } + case APP_USBD_MSC_STATE_CMD_OUT: + { + ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); + break; + } + case APP_USBD_MSC_STATE_DATA_OUT: + { + CRITICAL_REGION_ENTER(); + ret = state_data_out_handle(p_inst); + CRITICAL_REGION_EXIT(); + break; + } + case APP_USBD_MSC_STATE_UNSUPPORTED: + { + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + case APP_USBD_MSC_STATE_CSW: + break; + default: + { + ASSERT(0); + break; + } + } + } + + return ret; +} + + +/** + * @brief @ref app_usbd_class_methods_t::event_handler + */ +static ret_code_t msc_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + ASSERT(p_inst != NULL); + ASSERT(p_event != NULL); + + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + UNUSED_VARIABLE(p_msc); + UNUSED_VARIABLE(p_msc_ctx); + + ret_code_t ret = NRF_SUCCESS; + switch (p_event->app_evt.type) + { + case APP_USBD_EVT_DRV_SOF: + break; + case APP_USBD_EVT_DRV_RESET: + break; + case APP_USBD_EVT_DRV_SETUP: + ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event); + break; + case APP_USBD_EVT_DRV_EPTRANSFER: + if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep)) + { + ret = endpoint_in_event_handler(p_inst, p_event); + } + else + { + ret = endpoint_out_event_handler(p_inst, p_event); + } + break; + case APP_USBD_EVT_DRV_SUSPEND: + { + /*Flush all block devices cache on suspend*/ + + for (size_t i = 0; i < p_msc->specific.inst.block_devs_count; ++i) + { + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[i]; + (void)nrf_blk_dev_ioctl(p_blkd, NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH, NULL); + } + + break; + } + case APP_USBD_EVT_DRV_RESUME: + break; + case APP_USBD_EVT_INST_APPEND: + { + /*Verify serial number string*/ + uint16_t const * p_serial_str = app_usbd_string_desc_get(APP_USBD_STRING_ID_SERIAL, 0); + if (p_serial_str == NULL) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + size_t len = app_usbd_string_desc_length(p_serial_str) / sizeof(uint16_t); + if (len < APP_USBD_MSC_MINIMAL_SERIAL_STRING_SIZE) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + for (size_t i = 1; i < len; ++i) + { + if (isxdigit(p_serial_str[i]) == 0) + { + return NRF_ERROR_NOT_SUPPORTED; + } + } + + ret = app_usbd_class_sof_register(p_inst); + if (ret != NRF_SUCCESS) + { + break; + } + + break; + } + case APP_USBD_EVT_INST_REMOVE: + { + ret = app_usbd_class_sof_unregister(p_inst); + break; + } + case APP_USBD_EVT_START: + { + /*Initialize all block devices*/ + ASSERT(p_msc->specific.inst.block_devs_count <= 16); + for (size_t i = 0; i < p_msc->specific.inst.block_devs_count; ++i) + { + nrf_block_dev_t const * p_blk_dev = p_msc->specific.inst.pp_block_devs[i]; + ret = nrf_blk_dev_init(p_blk_dev, msc_blockdev_ev_handler, p_msc); + if (ret != NRF_SUCCESS) + { + continue; + } + + p_msc_ctx->blk_dev_init_mask |= 1u << i; + ASSERT(nrf_blk_dev_geometry(p_blk_dev)->blk_size <= + p_msc->specific.inst.block_buff_size); + } + + break; + } + case APP_USBD_EVT_STOP: + { + /*Un-initialize all block devices*/ + ASSERT(p_msc->specific.inst.block_devs_count <= 16); + size_t i; + for (i = 0; i < p_msc->specific.inst.block_devs_count; ++i) + { + nrf_block_dev_t const * p_blk_dev = p_msc->specific.inst.pp_block_devs[i]; + ret = nrf_blk_dev_uninit(p_blk_dev); + if (ret != NRF_SUCCESS) + { + continue; + } + + p_msc_ctx->blk_dev_init_mask &= ~(1u << i); + } + + break; + } + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + return ret; +} + +/** + * @brief @ref app_usbd_class_methods_t::get_descriptors + */ +static const void * msc_get_descriptors(app_usbd_class_inst_t const * p_inst, size_t * p_size) +{ + ASSERT(p_size != NULL); + app_usbd_msc_t const * p_msc = msc_get(p_inst); + + *p_size = p_msc->specific.inst.raw_desc_size; + return p_msc->specific.inst.p_raw_desc; +} + +const app_usbd_class_methods_t app_usbd_msc_class_methods = { + .event_handler = msc_event_handler, + .get_descriptors = msc_get_descriptors, +}; + + +/** + * @brief Block device read done event handler. + * + * @ref NRF_BLOCK_DEV_EVT_BLK_READ_DONE + * + * @param p_blk_dev Block device handle + * @param p_event Block device event + * + * */ +static void msc_blockdev_read_done_handler(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_event_t const * p_event) +{ + ret_code_t ret; + + app_usbd_class_inst_t const * p_inst = p_event->p_context; + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + uint32_t blk_cnt = p_msc_ctx->current.blk_count; + uint32_t blk_size = p_msc_ctx->current.blk_size; + + /*Save actual request*/ + size_t req_pos = (p_msc_ctx->current.workbuff_pos != 0) ? 1 : 0; + p_msc_ctx->current.req = *p_event->p_blk_req; + + p_msc_ctx->current.block_req_in_progress = false; + + /*Decrement transfer counter*/ + p_msc_ctx->current.blk_idx += blk_cnt; + if (p_msc_ctx->current.blk_datasize > blk_size * blk_cnt) + { + p_msc_ctx->current.blk_datasize -= blk_size * blk_cnt; + } + else + { + p_msc_ctx->current.blk_datasize = 0; + } + + NRF_LOG_DEBUG("read_done_handler: p_buff: %p, size: %u data size: %u req_pos: %u\r\n", + (uint32_t)p_event->p_blk_req->p_buff, + p_event->p_blk_req->blk_count, + p_msc_ctx->current.blk_datasize, + req_pos); + + /*Calculate next block request size*/ + p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx); + + if (!p_msc_ctx->current.trans_in_progress) + { + /*Trigger new transfer.*/ + p_msc_ctx->current.trans_req_id = req_pos; + nrf_block_req_t * p_req = &p_msc_ctx->current.req; + + ret = transfer_in_start(p_inst, + p_req->p_buff, + p_req->blk_count * blk_size, + APP_USBD_MSC_STATE_DATA_IN); + if (ret != NRF_SUCCESS) + { + UNUSED_RETURN_VALUE(unsupported_start(p_inst)); + } + else + { + /*Clear processed block request.*/ + memset(p_req, 0, sizeof(nrf_block_req_t)); + p_msc_ctx->current.trans_in_progress = true; + } + + } + + if (p_msc_ctx->current.req_busy_mask == APP_USBD_MSC_REQ_BUSY_FULL_MASK) + { + /* No need to perform next block read request. USB transfers need to catch-up + * block device readings */ + return; + } + + if (p_msc_ctx->current.blk_count == 0) + { + /*All data has been read. No need to trigger new block request.*/ + return; + } + + /*Trigger new block read request*/ + p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size; + req_pos = p_msc_ctx->current.workbuff_pos != 0 ? 1 : 0; + + APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, req_pos); + + NRF_BLOCK_DEV_REQUEST(req, + p_msc_ctx->current.blk_idx, + p_msc_ctx->current.blk_count, + ((uint8_t *)p_msc->specific.inst.p_block_buff + + p_msc_ctx->current.workbuff_pos)); + + + NRF_LOG_DEBUG("nrf_blk_dev_read_req 2: id: %u, count: %u, left: %u, ptr: %p\r\n", + req.blk_id, + req.blk_count, + p_msc_ctx->current.blk_datasize, + (uint32_t)req.p_buff); + + ret = nrf_blk_dev_read_req(p_blk_dev, &req); + NRF_LOG_DEBUG("nrf_blk_dev_read_req 2: ret: %u\r\n", ret); + + if (ret != NRF_SUCCESS) + { + UNUSED_RETURN_VALUE(unsupported_start(p_inst)); + } +} + +/** + * @brief Block device write done event handler. + * + * @ref NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE + * + * @param p_blk_dev Block device handle + * @param p_event Block device event + * + * */ +static void msc_blockdev_write_done_handler(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_event_t const * p_event) +{ + app_usbd_class_inst_t const * p_inst = p_event->p_context; + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + uint32_t blk_cnt = p_msc_ctx->current.blk_count; + uint32_t blk_size = p_msc_ctx->current.blk_size; + + /*Save actual request*/ + size_t req_pos = (p_event->p_blk_req->p_buff == p_msc->specific.inst.p_block_buff) ? 0 : 1; + p_msc_ctx->current.req = *p_event->p_blk_req; + + APP_USBD_MSC_REQ_BUSY_CLR(p_msc_ctx->current.req_busy_mask, req_pos); + p_msc_ctx->current.block_req_in_progress = false; + + p_msc_ctx->current.blk_idx += blk_cnt; + + if (p_msc_ctx->current.blk_datasize > blk_size * blk_cnt) + { + p_msc_ctx->current.blk_datasize -= blk_size * blk_cnt; + } + else + { + p_msc_ctx->current.blk_datasize = 0; + } + + NRF_LOG_DEBUG("write_done_handler: p_buff: %p, size: %u data size: %u req_pos: %u\r\n", + (uint32_t)p_event->p_blk_req->p_buff, + p_event->p_blk_req->blk_count, + p_msc_ctx->current.blk_datasize, + req_pos); + + if (p_msc_ctx->current.blk_datasize == 0) + { + p_msc_ctx ->current.blk_idx = p_msc_ctx ->current.blk_size = 0; + UNUSED_RETURN_VALUE(csw_wait_start(p_inst, p_msc_ctx->current.csw_status)); + return; + } + + if (p_msc_ctx->current.blk_datasize <= p_msc_ctx->current.blk_count * blk_size) + { + size_t pos = p_msc_ctx->current.workbuff_pos; + if (p_msc_ctx->current.req_busy_mask != APP_USBD_MSC_REQ_BUSY_FULL_MASK) + { + pos ^= p_msc->specific.inst.block_buff_size; + } + + NRF_BLOCK_DEV_REQUEST(req, + p_msc_ctx->current.blk_idx, + p_msc_ctx->current.blk_count, + ((uint8_t *)p_msc->specific.inst.p_block_buff + pos)); + + NRF_LOG_DEBUG("nrf_blk_dev_write_req 2: id: %u, count: %u, left: %u, ptr: %p\r\n", + req.blk_id, + req.blk_count, + p_msc_ctx->current.blk_datasize, + (uint32_t)req.p_buff); + + p_msc_ctx->current.block_req_in_progress = true; + ret_code_t ret = nrf_blk_dev_write_req(p_blk_dev, &req); + NRF_LOG_DEBUG("nrf_blk_dev_write_req 2: ret: %u\r\n", ret); + + if (ret != NRF_SUCCESS) + { + UNUSED_RETURN_VALUE(unsupported_start(p_inst)); + } + + return; + } + + if (!p_msc_ctx->current.trans_in_progress && + (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_count * blk_size)) + { + size_t size = p_msc_ctx->current.blk_datasize - p_msc_ctx->current.blk_count * blk_size; + if (size > p_msc_ctx->current.blk_count * blk_size) + { + size = p_msc_ctx->current.blk_count * blk_size; + } + + if (size > 0) + { + /*Trigger new transfer.*/ + p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx); + ret_code_t ret = transfer_out_start(p_inst, + ((uint8_t *)p_msc->specific.inst.p_block_buff + + p_msc_ctx->current.workbuff_pos), + size, + APP_USBD_MSC_STATE_DATA_OUT); + if (ret == NRF_SUCCESS) + { + p_msc_ctx->current.trans_req_id ^= 1; + APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, + p_msc_ctx->current.trans_req_id); + p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size; + p_msc_ctx->current.trans_in_progress = true; + } + else + { + UNUSED_RETURN_VALUE(unsupported_start(p_inst)); + } + } + } +} + + +/** + * @brief Block device event handler. + * + * Mass storage block device event handler. Need to be pined to all block devices + * from initializer list. + * + * @param p_blk_dev Block device handle + * @param p_event Block device event + * + * */ +static void msc_blockdev_ev_handler(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_event_t const * p_event) +{ + switch (p_event->ev_type) { + case NRF_BLOCK_DEV_EVT_INIT: + break; + case NRF_BLOCK_DEV_EVT_UNINIT: + break; + case NRF_BLOCK_DEV_EVT_BLK_READ_DONE: + CRITICAL_REGION_ENTER(); + msc_blockdev_read_done_handler(p_blk_dev, p_event); + CRITICAL_REGION_EXIT(); + break; + case NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE: + CRITICAL_REGION_ENTER(); + msc_blockdev_write_done_handler(p_blk_dev, p_event); + CRITICAL_REGION_EXIT(); + break; + default: + break; + } +} + + +bool app_usbd_msc_sync(app_usbd_msc_t const * p_msc) +{ + bool rc = true; + ret_code_t ret = NRF_SUCCESS; + + for (size_t i = 0; i < p_msc->specific.inst.block_devs_count; ++i) + { + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[i]; + bool flush_in_progress = true; + + ret = nrf_blk_dev_ioctl(p_blkd, + NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH, + &flush_in_progress); + + if ((ret != NRF_SUCCESS) || flush_in_progress) + { + rc = false; + } + } + + return rc; +} + +/** @} */ + +#endif // APP_USBD_CLASS_MSC_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc.h new file mode 100644 index 0000000000000000000000000000000000000000..e1548455dce13ec01b27ca383de59681b18c337d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc.h @@ -0,0 +1,193 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_MSC_H__ +#define APP_USBD_MSC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "nrf_drv_usbd.h" +#include "nrf_block_dev.h" +#include "app_usbd_class_base.h" +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_descriptor.h" + +#include "app_usbd_msc_types.h" +#include "app_usbd_msc_desc.h" +#include "app_usbd_msc_scsi.h" +#include "app_usbd_msc_internal.h" + + +/** + * @defgroup app_usbd_msc USB MSC class + * @ingroup app_usbd + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the USB MSC class. + * + * @details References: + * - "Universal Serial Bus Mass Storage Class, Specification Overview," + * Revision 1.2, USB Implementer's Forum, June 23, 2003. + * - "Universal Serial Bus Mass Storage Class, Bulk-Only Transport," + * Revision 1.0, USB Implementer's Forum, September 31, 1999. + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief Mass storage class instance type + * + * @ref APP_USBD_CLASS_TYPEDEF + */ +typedef struct { } app_usbd_msc_t; +#else +/*lint -save -e10 -e26 -e123 -e505 */ +APP_USBD_CLASS_TYPEDEF(app_usbd_msc, \ + APP_USBD_MSC_CONFIG(0, (NRF_DRV_USBD_EPIN1, NRF_DRV_USBD_EPOUT1)), \ + APP_USBD_MSC_INSTANCE_SPECIFIC_DEC, \ + APP_USBD_MSC_DATA_SPECIFIC_DEC \ +); +#endif + +/*lint -restore*/ + + +/*lint -save -e407 */ + +/** + * @brief Events passed to user event handler + * + * @note Example prototype of user event handler: + * + * void msc_user_ev_handler(app_usbd_class_inst_t const * p_inst, + * app_usbd_msc_user_event_t event); + */ +typedef enum app_usbd_msc_user_event_e { + APP_USBD_MSC_USER_EVT_NONE, /**< Dummy event to satisfy compilers. */ +} app_usbd_msc_user_event_t; + +/*lint -restore*/ + +/** + * @brief Helper macro for defining MSC endpoints + * + * @param in_number Input endpoint number + * @param out_number Output endpoint number + * */ +#define APP_USBD_MSC_ENDPOINT_LIST(in_number, out_number) ( \ + CONCAT_2(NRF_DRV_USBD_EPIN, in_number), \ + CONCAT_2(NRF_DRV_USBD_EPOUT, out_number) \ +) + +/** + * @brief Global definition of app_usbd_msc_t class + * + * @param instance_name Name of global instance + * @param interface_number Unique interface number + * @param user_ev_handler User event handler (optional) + * @param endpoint_list Input endpoint list (@ref nrf_drv_usbd_ep_t) + * @param blockdev_list Block device list + * @param workbuffer_size Work buffer size (need to fit into all block devices from + * block device list) + * + * @note This macro is just simplified version of @ref APP_USBD_MSC_GLOBAL_DEF_INTERNAL + * + */ +#define APP_USBD_MSC_GLOBAL_DEF(instance_name, \ + interface_number, \ + user_ev_handler, \ + endpoint_list, \ + blockdev_list, \ + workbuffer_size) \ + APP_USBD_MSC_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + user_ev_handler, \ + endpoint_list, \ + blockdev_list, \ + workbuffer_size) + + +/** + * @@brief Helper function to get class instance from MSC + * + * @param[in] p_msc MSC instance (declared by @ref APP_USBD_MSC_GLOBAL_DEF) + * + * @return Base class instance + */ +static inline app_usbd_class_inst_t const * +app_usbd_msc_class_inst_get(app_usbd_msc_t const * p_msc) +{ + return &p_msc->base; +} + +/** + * @brief Helper function to get MSC from base class instance + * + * @param[in] p_inst Base class instance + * + * @return MSC class handle + */ +static inline app_usbd_msc_t const * app_usbd_msc_class_get(app_usbd_class_inst_t const * p_inst) +{ + return (app_usbd_msc_t const *)p_inst; +} + +/** + * @brief Synchronization of all block devices pined to MSC + * + * @param[in] p_msc MSC instance (declared by @ref APP_USBD_MSC_GLOBAL_DEF) + * + * @retval true All block devices flushed data + * @retval false At least one block device has not flushed data + */ +bool app_usbd_msc_sync(app_usbd_msc_t const * p_msc); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_MSC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc_desc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..ebea8c96c346bc5ff3ffc806e9acc7e0e4778d42 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc_desc.h @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_MSC_DESC_H__ +#define APP_USBD_MSC_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_usbd_descriptor.h" + +/** + * @defgroup app_usbd_msc_desc USB MSC descriptors + * @ingroup app_usbd_msc + * + * @brief @tagAPI52840 Descriptors for the USB MSC class. + * @{ + */ + +/** + * @brief Initializer of interface descriptor for MSC class + * + * @param interface_number Interface number + * @param subclass Subclass, @ref app_usbd_msc_subclass_t + * @param protocol Protocol, @ref app_usbd_msc_protocol_t + * */ +#define APP_USBD_MSC_INTERFACE_DSC(interface_number, subclass, protocol) \ + /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \ + /*.bInterfaceNumber = */ interface_number, \ + /*.bAlternateSetting = */ 0x00, \ + /*.bNumEndpoints = */ 2, \ + /*.bInterfaceClass = */ APP_USBD_MSC_CLASS, \ + /*.bInterfaceSubClass = */ subclass, \ + /*.bInterfaceProtocol = */ protocol, \ + /*.iInterface = 0, */ 0x00, \ + + +/** + * @brief Initializer of endpoint descriptors for MSC class + * + * @param endpoint_in IN endpoint + * @param endpoint_out OUT endpoint + * @param ep_size Endpoint size + * */ +#define APP_USBD_MSC_EP_DSC(endpoint_in, endpoint_out, ep_size) \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ endpoint_in, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ 0, \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ endpoint_out, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ 0, \ + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_MSC_DESC_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc_internal.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc_internal.h new file mode 100644 index 0000000000000000000000000000000000000000..81335943227043fa4800616795f56581fd00432f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc_internal.h @@ -0,0 +1,259 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_MSC_INTERNAL_H__ +#define APP_USBD_MSC_INTERNAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup app_usbd_msc_internals USB MSC internals + * @ingroup app_usbd_msc + * + * @brief @tagAPI52840 Internals of the USB MSC class. + * @{ + */ + +/** + * @brief Minimal serial string descriptor length + * */ +#define APP_USBD_MSC_MINIMAL_SERIAL_STRING_SIZE (12 + 1) + +/** + * @brief Forward declaration of Mass Storage Class type + * + */ +APP_USBD_CLASS_FORWARD(app_usbd_msc); + +/*lint -save -e165*/ +/** + * @brief Forward declaration of @ref app_usbd_msc_user_event_e + * + */ +enum app_usbd_msc_user_event_e; + +/*lint -restore*/ + +/** + * @brief User event handler + * + * @param[in] p_inst Class instance + * @param[in] event User event + * + * */ +typedef void (*app_usbd_msc_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst, + enum app_usbd_msc_user_event_e event); + +/** + * @brief MSC part of class instance data + */ +typedef struct { + uint8_t const * p_raw_desc; //!< MSC descriptors + size_t raw_desc_size; //!< MSC descriptors size + void * p_block_buff; //!< Block buffer + size_t block_buff_size; //!< Block buffer size (typically 512 bytes) + + nrf_block_dev_t const ** pp_block_devs; //!< Block devices list + size_t block_devs_count; //!< Block device list size + + app_usbd_msc_user_ev_handler_t user_ev_handler; //!< User event handler +} app_usbd_msc_inst_t; + +/** + * @brief Internal module state + */ +typedef enum { + APP_USBD_MSC_STATE_DISABLED, /**< Internal module state DISABLED */ + APP_USBD_MSC_STATE_IDLE, /**< Internal module state IDLE */ + APP_USBD_MSC_STATE_CBW, /**< Internal module state CBW */ + APP_USBD_MSC_STATE_CMD_IN, /**< Internal module state CMD_IN */ + APP_USBD_MSC_STATE_CMD_OUT, /**< Internal module state CMD_OUT */ + APP_USBD_MSC_STATE_DATA_IN, /**< Internal module state DATA_IN */ + APP_USBD_MSC_STATE_DATA_OUT, /**< Internal module state DATA_OUT */ + APP_USBD_MSC_STATE_DATA_OUT_WAIT, /**< Internal module state DATA_OUT_WAIT */ + APP_USBD_MSC_STATE_CSW, /**< Internal module state CSW */ + APP_USBD_MSC_STATE_UNSUPPORTED, /**< Internal module state UNSUPPORTED */ +} app_usbd_msc_state_t; + +/** + * @brief MSC context + * + * */ +typedef struct { + app_usbd_msc_cbw_t cbw; //!< SCSI command block wrapper + app_usbd_msc_csw_t csw; //!< SCSI Command status wrapper + + app_usbd_msc_state_t state; //!< Internal module state + + struct { + uint8_t lun; //!< Current transfer blocks: logical unit + uint8_t csw_status; //!< Current CSW status + uint32_t blk_idx; //!< Current transfer: block index + uint32_t blk_datasize; //!< Current transfer: data size to transfer + uint32_t blk_size; //!< Current transfer: block size + uint32_t blk_count; //!< Current transfer: block count + uint32_t residue; //!< @ref app_usbd_msc_csw_t::residue + + bool trans_in_progress; //!< Transfer in progress flag + bool block_req_in_progress; //!< Block request in progress flag + size_t workbuff_pos; //!< Current buffer offset (double buffering mode) + uint8_t req_busy_mask; //!< Request bust mask (double buffering mode) + uint8_t trans_req_id; //!< Current transfered request (double buffering mode) + + nrf_block_req_t req; //!< Last processed block req (double buffering mode) + } current; + + size_t resp_len; //!< Response length + + /*SCSI response container*/ + union { + app_usbd_scsi_cmd_inquiry_resp_t inquiry; //!< @ref APP_USBD_SCSI_CMD_INQUIRY response + app_usbd_scsi_cmd_requestsense_resp_t requestsense; //!< @ref APP_USBD_SCSI_CMD_REQUESTSENSE response + app_usbd_scsi_cmd_readcapacity10_resp_t readcapacity10; //!< @ref APP_USBD_SCSI_CMD_READCAPACITY10 response + app_usbd_scsi_cmd_modesense6_resp_t modesense6; //!< @ref APP_USBD_SCSI_CMD_MODESENSE6 response + app_usbd_scsi_cmd_modesense10_resp_t modesense10; //!< @ref APP_USBD_SCSI_CMD_MODESENSE10 response + } scsi_resp; + + uint16_t blk_dev_init_mask; //!< Block devices init mask +} app_usbd_msc_ctx_t; + + +/** + * @brief MSC configuration macro + * + * Used by @ref APP_USBD_MSC_GLOBAL_DEF + * + * @param iface Interface number + * @param endpoints Endpoint list + * */ +#define APP_USBD_MSC_CONFIG(iface, endpoints) ((iface, BRACKET_EXTRACT(endpoints))) + + +/** + * @brief Specific class constant data for MSC + * + * @ref app_usbd_msc_inst_t + */ +#define APP_USBD_MSC_INSTANCE_SPECIFIC_DEC app_usbd_msc_inst_t inst; + + +/** + * @brief Configures MSC instance + * + * @param descriptors Mass storage class descriptors (raw table) + * @param block_devs Block devices list + * @param block_buff Block buffer + * @param user_event_handler User event handler + */ +#define APP_USBD_MSC_INST_CONFIG(descriptors, block_devs, block_buff, user_event_handler) \ + .inst = { \ + .p_raw_desc = descriptors, \ + .raw_desc_size = sizeof(descriptors), \ + .pp_block_devs = block_devs, \ + .block_devs_count = ARRAY_SIZE(block_devs), \ + .p_block_buff = block_buff, \ + .block_buff_size = sizeof(block_buff) / 2, \ + .user_ev_handler = user_event_handler, \ + } + +/** + * @brief Specific class data for MSC + * + * @ref app_usbd_msc_ctx_t + * */ +#define APP_USBD_MSC_DATA_SPECIFIC_DEC app_usbd_msc_ctx_t ctx; + + +/** + * @brief MSC descriptors config macro + * + * @param interface_number Interface number + * @param ... Extracted endpoint list + * */ +#define APP_USBD_MSC_DSC_CONFIG(interface_number, ...) { \ + APP_USBD_MSC_INTERFACE_DSC(interface_number, \ + APP_USBD_MSC_SUBCLASS_TRANSPARENT, \ + APP_USBD_MSC_PROTOCOL_BULK) \ + APP_USBD_MSC_EP_DSC(GET_VA_ARG_1(__VA_ARGS__), \ + GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__)), \ + 64) \ +} + +/** + * @brief Public MSC class interface + * + * */ +extern const app_usbd_class_methods_t app_usbd_msc_class_methods; + +/** + * @brief Global definition of mass storage class instance + */ +#define APP_USBD_MSC_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + user_ev_handler, \ + endpoint_list, \ + blockdev_list, \ + workbuffer_size) \ + static const uint8_t CONCAT_2(instance_name, _dsc)[] = \ + APP_USBD_MSC_DSC_CONFIG(interface_number, BRACKET_EXTRACT(endpoint_list)); \ + static const nrf_block_dev_t * CONCAT_2(instance_name, _blkdevs)[] = \ + { BRACKET_EXTRACT(blockdev_list) }; \ + static uint32_t CONCAT_2(instance_name, _block)[2 *(workbuffer_size) / sizeof(uint32_t)]; \ + APP_USBD_CLASS_INST_GLOBAL_DEF( \ + instance_name, \ + app_usbd_msc, \ + &app_usbd_msc_class_methods, \ + APP_USBD_MSC_CONFIG(interface_number, endpoint_list), \ + (APP_USBD_MSC_INST_CONFIG(CONCAT_2(instance_name, _dsc), \ + CONCAT_2(instance_name, _blkdevs), \ + CONCAT_2(instance_name, _block), \ + user_ev_handler)) \ + ) + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_MSC_INTERNAL_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h new file mode 100644 index 0000000000000000000000000000000000000000..27d7ea57bdbfed54aa210ed58bce57b86ec7fdce --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h @@ -0,0 +1,329 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_MSC_SCSI_H__ +#define APP_USBD_MSC_SCSI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_util.h" + +/** + * @defgroup app_usbd_msc_scsi USB MSC SCSI data structures + * @ingroup app_usbd_msc + * + * @brief @tagAPI52840 USB MSC SCSI data structures. + * + * @details Reference specifications: + * - "Reduced Block Commands (Revision 10a)" American National Standard + * for Information Technology, August 18, 1999 + * - "SCSI Primary Commands - 4 (SPC-4)," American National Standard + * for Information Technology, July 19, 2008 + * - "SCSI Block Commands -2 (SBC-2)," American National Standard + * for Information Technology, November 13, 2004 + * - NuttX source code - Real-time Operating System: http://nuttx.org/ + * Gregory Nutt + * + * @{ + */ + +/** + * @brief SCSI command set + * + * Mandatory (and some optional) commands required by SBC-2. + * + */ +typedef enum { + APP_USBD_SCSI_CMD_TESTUNITREADY = 0x00, /**< TESTUNITREADY */ + APP_USBD_SCSI_CMD_REQUESTSENSE = 0x03, /**< REQUESTSENSE */ + APP_USBD_SCSI_CMD_FORMAT_UNIT = 0x04, /**< FORMAT_UNIT */ + APP_USBD_SCSI_CMD_READ6 = 0x08, /**< READ6 */ + APP_USBD_SCSI_CMD_WRITE6 = 0x0a, /**< WRITE6 */ + APP_USBD_SCSI_CMD_INQUIRY = 0x12, /**< INQUIRY */ + APP_USBD_SCSI_CMD_MODESELECT6 = 0x15, /**< MODESELECT6 */ + APP_USBD_SCSI_CMD_MODESENSE6 = 0x1a, /**< MODESENSE6 */ + APP_USBD_SCSI_CMD_STARTSTOPUNIT = 0x1b, /**< STARTSTOPUNIT */ + APP_USBD_SCSI_CMD_SENDDIAGNOSTIC = 0x1d, /**< SENDDIAGNOSTIC */ + APP_USBD_SCSI_CMD_PREVENTMEDIAREMOVAL = 0x1e, /**< PREVENTMEDIAREMOVAL */ + APP_USBD_SCSI_CMD_READCAPACITY10 = 0x25, /**< READCAPACITY10 */ + APP_USBD_SCSI_CMD_READ10 = 0x28, /**< READ10 */ + APP_USBD_SCSI_CMD_WRITE10 = 0x2a, /**< WRITE10 */ + APP_USBD_SCSI_CMD_MODESELECT10 = 0x55, /**< MODESELECT10 */ + APP_USBD_SCSI_CMD_MODESENSE10 = 0x5a, /**< MODESENSE10 */ +} app_usbd_scsi_cmd_t; + + +#pragma pack(push, 1) + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_REQUESTSENSE command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_REQUESTSENSE + uint8_t flags; //!< Flags + uint8_t reserved[2]; //!< Reserved + uint8_t alloclen; //!< Allocation length + uint8_t control; //!< Control +} app_usbd_scsi_cmd_requestsense_t; + +#define APP_USBD_SCSI_CMD_REQSENSE_CODE_VALID 0x80 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */ +#define APP_USBD_SCSI_CMD_REQSENSE_CODE_CURRENT 0x70 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */ +#define APP_USBD_SCSI_CMD_REQSENSE_CODE_DEFERRED 0x71 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */ +#define APP_USBD_SCSI_CMD_REQSENSE_CODE_CURRENTDESC 0x72 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */ +#define APP_USBD_SCSI_CMD_REQSENSE_CODE_DEFERREDDESC 0x73 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */ + +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_FILEMARK 0x80 /**< Bits 7 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_EOM 0x40 /**< Bits 6 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_ILI 0x20 /**< Bits 5 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_RESERVED 0x10 /**< Bits 4 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ + +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_NOSENSE 0x00 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_RECOVEREDERROR 0x01 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_NOTREADY 0x02 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_MEDIUMERROR 0x03 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_HARDWAREERROR 0x04 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_ILLEGALREQUEST 0x05 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_UNITATTENTION 0x06 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_DATAPROTECT 0x07 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_BLANKCHECK 0x08 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_VENDORSPECIFIC 0x09 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_ABORTEDCOMMAND 0x0b /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ + + +#define APP_USBD_SCSI_CMD_TESTUNITREADY_LEN 6 /**< @ref APP_USBD_SCSI_CMD_TESTUNITREADY command length*/ + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_REQUESTSENSE response + */ +typedef struct { + uint8_t code; //!< Response code: APP_USBD_SCSI_CMD_REQSENSE_CODE_* + uint8_t obsolete; //!< Obsolete + uint8_t flags; //!< APP_USBD_SCSI_CMD_REQSENSE_FLAG_* + uint8_t info[4]; //!< Information + uint8_t len; //!< Additional length + uint8_t cmdinfo[4]; //!< Command-specific information + uint8_t code2; //!< Additional sense code + uint8_t qual2; //!< Additional sense code qualifier + uint8_t fru; //!< Field replacement unit code + uint8_t key[3]; //!< Sense key specific +} app_usbd_scsi_cmd_requestsense_resp_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_INQUIRY command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_INQUIRY + uint8_t flags; //!< Command flags + uint8_t pagecode; //!< Page code + uint8_t alloclen[2]; //!< Allocation length + uint8_t control; //!< Control +} app_usbd_scsi_cmd_inquiry_t; + +#define APP_USBD_MSC_SCSI_INQ_QUAL_CONNECTED 0x00 /**< Peripheral connected */ +#define APP_USBD_MSC_SCSI_INQ_QUAL_NOT_CONN 0x20 /**< Peripheral not connected */ +#define APP_USBD_MSC_SCSI_INQ_QUAL_NOT_SUPP 0x60 /**< Peripheral not supported */ + +#define APP_USBD_MSC_SCSI_INQ_TYPE_DIR_ACCESS 0x00 /**< Direct Access (SBC) */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_SEQ_ACCESS 0x01 /**< Sequential Access */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_PRINTER 0x02 /**< Printer */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_PROCESSOR 0x03 /**< Processor device */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_WRITE_ONCE 0x04 /**< Write-once device */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_CD_DVD 0x05 /**< CD/DVD device */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_OPTICAL 0x07 /**< Optical Memory */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_MC 0x08 /**< Medium Changer */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_ARRAY 0x0c /**< Storage Array Controller */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_ENCLOSURE 0x0d /**< Enclosure Services */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_RBC 0x0e /**< Simplified Direct Access */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_OCRW 0x0f /**< Optical card reader/writer */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_BCC 0x10 /**< Bridge Controller Commands */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_OSD 0x11 /**< Object-based Storage */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_NONE 0x1f /**< No Peripheral */ + + +#define APP_USBD_MSC_SCSI_INQ_FLAG1_RMB 0x80 /**< Removable Medium */ + +#define APP_USBD_SCSI_INQ_VER_NONE 0x00 /**< No standards conformance */ +#define APP_USBD_SCSI_INQ_VER_SPC 0x03 /**< SCSI Primary Commands (link to SBC) */ +#define APP_USBD_SCSI_INQ_VER_SPC2 0x04 /**< SCSI Primary Commands - 2 (link to SBC-2)*/ +#define APP_USBD_SCSI_INQ_VER_SPC3 0x05 /**< SCSI Primary Commands - 3 (link to SBC-2)*/ +#define APP_USBD_SCSI_INQ_VER_SPC4 0x06 /**< SCSI Primary Commands - 4 (link to SBC-3)*/ + +#define APP_USBD_MSC_SCSI_INQ_FLAG2_NORMACA 0x20 /**< Normal ACA Supported */ +#define APP_USBD_MSC_SCSI_INQ_FLAG2_HISUP 0x10 /**< Hierarchal LUN addressing */ +#define APP_USBD_MSC_SCSI_INQ_FLAG2_RSP_SPC2 0x02 /**< SPC-2 / SPC-3 response format*/ +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_INQUIRY response + */ +typedef struct { + uint8_t qualtype; //!< Bits 5-7: Peripheral qualifier; Bits 0-4: Peripheral device type + uint8_t flags1; //!< Flags 1 + uint8_t version; //!< Version + uint8_t flags2; //!< Flags 2 + uint8_t len; //!< Additional length + uint8_t flags3; //!< Flags 3 + uint8_t flags4; //!< Flags 4 + uint8_t flags5; //!< Flags 5 + uint8_t vendorid[8]; //!< T10 Vendor Identification + uint8_t productid[16]; //!< Product Identification + uint8_t revision[4]; //!< Product Revision Level +} app_usbd_scsi_cmd_inquiry_resp_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_READ6 command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_READ6 + uint8_t mslba; //!< Bits 5-7: reserved; Bits 0-6: MS Logical Block Address (LBA) + uint8_t lslba[2]; //!< LS Logical Block Address (LBA) + uint8_t xfrlen; //!< Transfer length (in contiguous logical blocks) + uint8_t control; //!< Control +} app_usbd_scsi_cmd_read6_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_WRITE6 command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_WRITE6 + uint8_t mslba; //!< Bits 5-7: reserved; Bits 0-6: MS Logical Block Address (LBA) + uint8_t lslba[2]; //!< LS Logical Block Address (LBA) + uint8_t xfrlen; //!< Transfer length (in contiguous logical blocks) + uint8_t control; //!< Control +} app_usbd_scsi_cmd_write6_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE6 command + */ +typedef struct { + uint8_t opcode; //!<* @ref APP_USBD_SCSI_CMD_MODESENSE6 + uint8_t flags; //!<* Flags + uint8_t pcpgcode; //!<* Bits 6-7: PC, bits 0-5: page code + uint8_t subpgcode; //!<* subpage code + uint8_t alloclen; //!<* Allocation length + uint8_t control; //!<* Control +} app_usbd_scsi_cmd_modesense6_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE6 response + */ +typedef struct { + uint8_t mdlen; //!< Mode data length + uint8_t type; //!< Medium type + uint8_t param; //!< Device-specific parameter + uint8_t bdlen; //!< Block descriptor length +} app_usbd_scsi_cmd_modesense6_resp_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_READCAPACITY10 command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_READCAPACITY10 + uint8_t reserved1; //!< Reserved field + uint8_t lba[4]; //!< Logical block address (LBA) + uint8_t reserved2[2]; //!< Reserved field + uint8_t pmi; //!< Bits 1-7 Reserved; Bit 0: PMI + uint8_t control; //!< Control +} app_usbd_scsi_cmd_readcapacity10_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_READCAPACITY10 response + */ +typedef struct { + uint8_t lba[4]; //!< Returned logical block address (LBA) + uint8_t blklen[4]; //!< Logical block length (in bytes) +} app_usbd_scsi_cmd_readcapacity10_resp_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_READ10 command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_READ10 + uint8_t flags; //!< Command flags + uint8_t lba[4]; //!< Logical Block Address (LBA) + uint8_t groupno; //!< Bits 5-7: reserved; Bits 0-6: group number + uint8_t xfrlen[2]; //!< Transfer length (in contiguous logical blocks) + uint8_t control; //!< Control +} app_usbd_scsi_cmd_read10_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_WRITE10 command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_WRITE10 + uint8_t flags; //!< Command flags + uint8_t lba[4]; //!< Logical Block Address (LBA) + uint8_t groupno; //!< Bits 5-7: reserved; Bits 0-6: group number + uint8_t xfrlen[2]; //!< Transfer length (in contiguous logical blocks) + uint8_t control; //!< Control +} app_usbd_scsi_cmd_write10_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE10 command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_MODESENSE10 + uint8_t flags; //!< Flags + uint8_t pcpgcode; //!< Bits 6-7: PC, bits 0-5: page code + uint8_t subpgcode; //!< Subpage code + uint8_t reserved[3]; //!< Reserved + uint8_t alloclen[2]; //!< Allocation length + uint8_t control; //!< Control +} app_usbd_scsi_cmd_modesense10_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE10 response + */ +typedef struct { + uint8_t mdlen[2]; //!< Mode data length + uint8_t type; //!< Medium type + uint8_t param; //!< Device-specific parameter + uint8_t reserved[2]; //!< Reserved + uint8_t bdlen[2]; //!< Block descriptor length +} app_usbd_scsi_cmd_modesense10_resp_t; + +#pragma pack(pop) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_MSC_SCSI_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc_types.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc_types.h new file mode 100644 index 0000000000000000000000000000000000000000..00063e5a7469251d8102765995e86fb7d840d875 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/class/msc/app_usbd_msc_types.h @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_MSC_TYPES_H__ +#define APP_USBD_MSC_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_util.h" + +/** + * @defgroup app_usbd_msc_types USB MSC types + * @ingroup app_usbd_msc + * + * @brief @tagAPI52840 Types used in the USB MSC class. + * @{ + */ + +/** @brief MSC class definition in interface descriptor + * + * @ref app_usbd_descriptor_iface_t::bInterfaceClass + * */ +#define APP_USBD_MSC_CLASS 0x08 + +/** + * @brief MSC subclass possible value + */ +typedef enum { + APP_USBD_MSC_SUBCLASS_RBC = 0x01, /**< Reduced Block Commands */ + APP_USBD_MSC_SUBCLASS_ATAPI = 0x02, /**< CD/DVD devices */ + APP_USBD_MSC_SUBCLASS_QIC_157 = 0x03, /**< Tape devices */ + APP_USBD_MSC_SUBCLASS_UFI = 0x04, /**< Floppy disk drives */ + APP_USBD_MSC_SUBCLASS_SFF_8070I = 0x05, /**< Floppy disk drives */ + APP_USBD_MSC_SUBCLASS_TRANSPARENT = 0x06, /**< Determined by INQUIRY */ +} app_usbd_msc_subclass_t; + +/** + * @brief MSC protocol possible value + * + * @note The USB Mass Storage Class Control/Bulk/Interrupt (CBI) Transport specification is approved + * for use only with full-speed floppy disk drives. CBI shall not be used in high-speed + * capable devices. + */ +typedef enum { + APP_USBD_MSC_PROTOCOL_CBI = 0x00, /**< Command/Bulk/Interrupt */ + APP_USBD_MSC_PROTOCOL_CBI_ALT = 0x01, /**< W/o command completion */ + APP_USBD_MSC_PROTOCOL_BULK = 0x50, /**< Bulk-only */ +} app_usbd_msc_protocol_t; + +/** + * @brief MSC USB requests @ref nrf_drv_usbd_setup_t::bmRequestType + * + * @note Requests are limited only to @ref APP_USBD_MSC_PROTOCOL_BULK protocol type. + */ +typedef enum { + APP_USBD_MSC_REQ_BULK_RESET = 0xFF, /**< Mass Storage Reset */ + APP_USBD_MSC_REQ_GET_MAX_LUN = 0xFE, /**< Get Max LUN */ +} app_usbd_msc_req_t; + +#pragma pack(push, 1) + +#define APP_USBD_MSC_CBW_SIGNATURE "USBC" /**< CBW signature */ +#define APP_USBD_MSC_CBW_DIRECTION_IN (1u <<7) /**< CBW direction flag */ + +/** + * @brief Command Block Wrapper (CBW) + */ +typedef struct { + uint8_t signature[4]; /**< "USBC" (hex: 0x43425355 little-endian) */ + uint8_t tag[4]; /**< Unique command tag */ + uint8_t datlen[4]; /**< Number of bytes that host expects to transfer */ + uint8_t flags; /**< Bit 7: Direction=IN */ + uint8_t lun; /**< Logical Unit Number, equals to @ref app_usbd_msc_inst_t :: block_devs_count*/ + uint8_t cdb_length; /**< Length of cdb field */ + uint8_t cdb[16]; /**< Command Data Block payload */ +} app_usbd_msc_cbw_t; + +#define APP_USBD_MSC_CSW_SIGNATURE "USBS" /**< CSW signature */ + +#define APP_USBD_MSC_CSW_STATUS_PASS 0x00 /**< CSW status: Command Passed */ +#define APP_USBD_MSC_CSW_STATUS_FAIL 0x01 /**< CSW status: Command Failed */ +#define APP_USBD_MSC_CSW_STATUS_PE 0x02 /**< CSW status: Phase Error */ + +/** + * @brief Command Status Wrapper (CSW) + */ +typedef struct { + uint8_t signature[4]; /**< "USBS" (hex: 0x53425355 little-endian) */ + uint8_t tag[4]; /**< Unique command tag (@ref app_usbd_msc_cbw_t :: tag) */ + uint8_t residue[4]; /**< Amount not transferred */ + uint8_t status; /**< Status of transfer */ +} app_usbd_msc_csw_t; + +#pragma pack(pop) + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_MSC_TYPES_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/config/app_usbd_string_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/config/app_usbd_string_config.h new file mode 100644 index 0000000000000000000000000000000000000000..34a815f85a72b574a8be59d4bad457e33ec4846a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/usbd/config/app_usbd_string_config.h @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_USBD_STRING_CONFIG_H +#define APP_USBD_STRING_CONFIG_H + +/** + * @defgroup app_usbd_string_conf USBD string configuration + * @ingroup app_usbd_string_desc + * + * @brief @tagAPI52840 Configuration of the string module that can be easily affected by the final + * user. + * @{ + */ + +/** + * @brief Supported languages identifiers + * + * Comma separated list of supported languages. + */ +#define APP_USBD_STRINGS_LANGIDS \ + ((uint16_t)APP_USBD_LANG_ENGLISH | (uint16_t)APP_USBD_SUBLANG_ENGLISH_US) + +/** + * @brief Manufacturer name string descriptor + * + * Comma separated list of manufacturer names for each defined language. + * Use @ref APP_USBD_STRING_DESC macro to create string descriptor. + * + * The order of manufacturer names has to be the same like in + * @ref APP_USBD_STRINGS_LANGIDS. + */ +#define APP_USBD_STRINGS_MANUFACTURER \ + APP_USBD_STRING_DESC('N', 'o', 'r', 'd', 'i', 'c', ' ', 'S', 'e', 'm', 'i', 'c', 'o', 'n', 'd', 'u', 'c', 't', 'o', 'r') + +/** + * @brief Define whether @ref APP_USBD_STRINGS_MANUFACTURER is created by @ref APP_USBD_STRING_DESC + * or declared as global variable. + * */ +#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0 + +/** + * @brief Product name string descriptor + * + * List of product names defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER + */ +#define APP_USBD_STRINGS_PRODUCT \ + APP_USBD_STRING_DESC('n', 'R', 'F', '5', '2', ' ', 'U', 'S', 'B', ' ', 'D', 'e', 'm', 'o') + + +/** + * @brief Define whether @ref APP_USBD_STRINGS_PRODUCT is created by @ref APP_USBD_STRING_DESC + * or declared as global variable. + * */ +#define APP_USBD_STRINGS_PRODUCT_EXTERN 0 + +/** + * @brief Serial number string descriptor + * + * Create serial number string descriptor using @ref APP_USBD_STRING_DESC, + * or configure it to point to any internal variable pointer filled with descriptor. + * + * @note + * There is only one SERIAL number inside the library and it is Language independent. + */ +#define APP_USBD_STRING_SERIAL \ + APP_USBD_STRING_DESC('0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0') + +/** + * @brief Define whether @ref APP_USBD_STRING_SERIAL is created by @ref APP_USBD_STRING_DESC + * or declared as global variable. + * */ +#define APP_USBD_STRING_SERIAL_EXTERN 0 + +/** + * @brief User strings default values + * + * This value stores all application specific user strings with its default initialization. + * The setup is done by X-macros. + * Expected macro parameters: + * @code + * X(mnemonic, [=str_idx], ...) + * @endcode + * - @c mnemonic: Mnemonic of the string descriptor that would be added to + * @ref app_usbd_string_desc_idx_t enumerator. + * - @c str_idx : String index value, may be set or left empty. + * For example WinUSB driver requires descriptor to be present on 0xEE index. + * Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...))) + * - @c ... : List of string descriptors for each defined language. + */ +#define APP_USBD_STRINGS_USER \ + X(APP_USER_1, , APP_USBD_STRING_DESC('U', 's', 'e', 'r', ' ', '1')) + +/** @} */ +#endif /* APP_USBD_STRING_CONFIG_H */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_error.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_error.c new file mode 100644 index 0000000000000000000000000000000000000000..6f55e8451e9d73755d55fc2838194b541d9c4fa3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_error.c @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup app_error Common application error handler + * @{ + * @ingroup app_common + * + * @brief Common application error handler. + */ + +#include "nrf.h" +#include +#include "app_error.h" +#include "nordic_common.h" +#include "sdk_errors.h" +#include "nrf_log.h" +#include "nrf_log_ctrl.h" +/**@brief Function for error handling, which is called when an error has occurred. + * + * @warning This handler is an example only and does not fit a final product. You need to analyze + * how your product is supposed to react in case of error. + * + * @param[in] error_code Error code supplied to the handler. + * @param[in] line_num Line number where the handler is called. + * @param[in] p_file_name Pointer to the file name. + */ + +/*lint -save -e14 */ +void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name) +{ + error_info_t error_info = + { + .line_num = line_num, + .p_file_name = p_file_name, + .err_code = error_code, + }; + app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info)); + + UNUSED_VARIABLE(error_info); +} + +/*lint -save -e14 */ +void app_error_handler_bare(ret_code_t error_code) +{ + error_info_t error_info = + { + .line_num = 0, + .p_file_name = NULL, + .err_code = error_code, + }; + + app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info)); + + UNUSED_VARIABLE(error_info); +} + + +void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info) +{ + /* static error variables - in order to prevent removal by optimizers */ + static volatile struct + { + uint32_t fault_id; + uint32_t pc; + uint32_t error_info; + assert_info_t * p_assert_info; + error_info_t * p_error_info; + ret_code_t err_code; + uint32_t line_num; + const uint8_t * p_file_name; + } m_error_data = {0}; + + // The following variable helps Keil keep the call stack visible, in addition, it can be set to + // 0 in the debugger to continue executing code after the error check. + volatile bool loop = true; + UNUSED_VARIABLE(loop); + + m_error_data.fault_id = id; + m_error_data.pc = pc; + m_error_data.error_info = info; + + switch (id) + { + case NRF_FAULT_ID_SDK_ASSERT: + m_error_data.p_assert_info = (assert_info_t *)info; + m_error_data.line_num = m_error_data.p_assert_info->line_num; + m_error_data.p_file_name = m_error_data.p_assert_info->p_file_name; + break; + + case NRF_FAULT_ID_SDK_ERROR: + m_error_data.p_error_info = (error_info_t *)info; + m_error_data.err_code = m_error_data.p_error_info->err_code; + m_error_data.line_num = m_error_data.p_error_info->line_num; + m_error_data.p_file_name = m_error_data.p_error_info->p_file_name; + break; + } + + UNUSED_VARIABLE(m_error_data); + + // If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger. + __disable_irq(); + while (loop); + + __enable_irq(); +} + +/*lint -restore */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_error.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_error.h new file mode 100644 index 0000000000000000000000000000000000000000..9abd6b6f32ce795f7b501c8e050e1c3b9ab3dae0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_error.h @@ -0,0 +1,239 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup app_error Common application error handler + * @{ + * @ingroup app_common + * + * @brief Common application error handler and macros for utilizing a common error handler. + */ + +#ifndef APP_ERROR_H__ +#define APP_ERROR_H__ + +#include +#include +#include +#include "nrf.h" +#include "sdk_errors.h" +#include "nordic_common.h" +#include "app_error_weak.h" +#ifdef ANT_STACK_SUPPORT_REQD +#include "ant_error.h" +#endif // ANT_STACK_SUPPORT_REQD + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_FAULT_ID_SDK_RANGE_START 0x00004000 /**< The start of the range of error IDs defined in the SDK. */ + +/**@defgroup APP_ERROR_FAULT_IDS Fault ID types + * @{ */ +#define NRF_FAULT_ID_SDK_ERROR NRF_FAULT_ID_SDK_RANGE_START + 1 /**< An error stemming from a call to @ref APP_ERROR_CHECK or @ref APP_ERROR_CHECK_BOOL. The info parameter is a pointer to an @ref error_info_t variable. */ +#define NRF_FAULT_ID_SDK_ASSERT NRF_FAULT_ID_SDK_RANGE_START + 2 /**< An error stemming from a call to ASSERT (nrf_assert.h). The info parameter is a pointer to an @ref assert_info_t variable. */ +/**@} */ + +/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ERROR. + */ +typedef struct +{ + uint16_t line_num; /**< The line number where the error occurred. */ + uint8_t const * p_file_name; /**< The file in which the error occurred. */ + uint32_t err_code; /**< The error code representing the error that occurred. */ +} error_info_t; + +/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ASSERT. + */ +typedef struct +{ + uint16_t line_num; /**< The line number where the error occurred. */ + uint8_t const * p_file_name; /**< The file in which the error occurred. */ +} assert_info_t; + +/**@brief Function for error handling, which is called when an error has occurred. + * + * @param[in] error_code Error code supplied to the handler. + * @param[in] line_num Line number where the handler is called. + * @param[in] p_file_name Pointer to the file name. + */ +void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name); + +/**@brief Function for error handling, which is called when an error has occurred. + * + * @param[in] error_code Error code supplied to the handler. + */ +void app_error_handler_bare(ret_code_t error_code); + +/**@brief Function for saving the parameters and entering an eternal loop, for debug purposes. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if + * unavailable. + * @param[in] info Optional additional information regarding the fault. Refer to each fault + * identifier for details. + */ +void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info); + +/**@brief Function for printing all error info (using nrf_log). + * + * @details Nrf_log library must be initialized using NRF_LOG_INIT macro before calling + * this function. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if + * unavailable. + * @param[in] info Optional additional information regarding the fault. Refer to each fault + * identifier for details. + */ +static __INLINE void app_error_log(uint32_t id, uint32_t pc, uint32_t info) +{ + switch (id) + { + case NRF_FAULT_ID_SDK_ASSERT: + //NRF_LOG_INFO(NRF_LOG_COLOR_RED "\r\n*** ASSERTION FAILED ***\r\n"); + if (((assert_info_t *)(info))->p_file_name) + { + // NRF_LOG_INFO(NRF_LOG_COLOR_WHITE "Line Number: %u\r\n", (unsigned int) ((assert_info_t *)(info))->line_num); + //NRF_LOG_INFO("File Name: %s\r\n", ((assert_info_t *)(info))->p_file_name); + } + //NRF_LOG_INFO(NRF_LOG_COLOR_DEFAULT "\r\n"); + break; + + case NRF_FAULT_ID_SDK_ERROR: + //NRF_LOG_INFO(NRF_LOG_COLOR_RED "\r\n*** APPLICATION ERROR *** \r\n" NRF_LOG_COLOR_WHITE); + if (((error_info_t *)(info))->p_file_name) + { + //NRF_LOG_INFO("Line Number: %u\r\n", (unsigned int) ((error_info_t *)(info))->line_num); + //NRF_LOG_INFO("File Name: %s\r\n", ((error_info_t *)(info))->p_file_name); + } + //NRF_LOG_INFO("Error Code: 0x%X\r\n" NRF_LOG_COLOR_DEFAULT "\r\n", (unsigned int) ((error_info_t *)(info))->err_code); + break; + } +} + +/**@brief Function for printing all error info (using printf). + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if + * unavailable. + * @param[in] info Optional additional information regarding the fault. Refer to each fault + * identifier for details. + */ +//lint -save -e438 +static __INLINE void app_error_print(uint32_t id, uint32_t pc, uint32_t info) +{ + unsigned int tmp = id; + printf("app_error_print():\r\n"); + printf("Fault identifier: 0x%X\r\n", tmp); + printf("Program counter: 0x%X\r\n", tmp = pc); + printf("Fault information: 0x%X\r\n", tmp = info); + + switch (id) + { + case NRF_FAULT_ID_SDK_ASSERT: + printf("Line Number: %u\r\n", tmp = ((assert_info_t *)(info))->line_num); + printf("File Name: %s\r\n", ((assert_info_t *)(info))->p_file_name); + break; + + case NRF_FAULT_ID_SDK_ERROR: + printf("Line Number: %u\r\n", tmp = ((error_info_t *)(info))->line_num); + printf("File Name: %s\r\n", ((error_info_t *)(info))->p_file_name); + printf("Error Code: 0x%X\r\n", tmp = ((error_info_t *)(info))->err_code); + break; + } +} +//lint -restore + + +/**@brief Macro for calling error handler function. + * + * @param[in] ERR_CODE Error code supplied to the error handler. + */ +#ifdef DEBUG +#define APP_ERROR_HANDLER(ERR_CODE) \ + do \ + { \ + app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__); \ + } while (0) +#else +#define APP_ERROR_HANDLER(ERR_CODE) \ + do \ + { \ + app_error_handler_bare((ERR_CODE)); \ + } while (0) +#endif +/**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS. + * + * @param[in] ERR_CODE Error code supplied to the error handler. + */ +#define APP_ERROR_CHECK(ERR_CODE) \ + do \ + { \ + const uint32_t LOCAL_ERR_CODE = (ERR_CODE); \ + if (LOCAL_ERR_CODE != NRF_SUCCESS) \ + { \ + APP_ERROR_HANDLER(LOCAL_ERR_CODE); \ + } \ + } while (0) + +/**@brief Macro for calling error handler function if supplied boolean value is false. + * + * @param[in] BOOLEAN_VALUE Boolean value to be evaluated. + */ +#define APP_ERROR_CHECK_BOOL(BOOLEAN_VALUE) \ + do \ + { \ + const uint32_t LOCAL_BOOLEAN_VALUE = (BOOLEAN_VALUE); \ + if (!LOCAL_BOOLEAN_VALUE) \ + { \ + APP_ERROR_HANDLER(0); \ + } \ + } while (0) + + +#ifdef __cplusplus +} +#endif + +#endif // APP_ERROR_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_error_weak.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_error_weak.c new file mode 100644 index 0000000000000000000000000000000000000000..cbc7e83759b39d73bca332b068bae0abb08c4f7e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_error_weak.c @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "app_error.h" + +//#define NRF_LOG_MODULE_NAME "APP_ERROR" +#include "nrf_log.h" +#include "nrf_log_ctrl.h" +/*lint -save -e14 */ + +#include + +/** + * Function is implemented as weak so that it can be overwritten by custom application error handler + * when needed. + */ +__WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) +{ + static volatile struct + { + uint32_t fault_id; + uint32_t pc; + uint32_t error_info; + assert_info_t * p_assert_info; + error_info_t * p_error_info; + ret_code_t err_code; + uint32_t line_num; + const uint8_t * p_file_name; + } m_error_data = {0}; + + // The following variable helps Keil keep the call stack visible, in addition, it can be set to + // 0 in the debugger to continue executing code after the error check. + volatile bool loop = true; + UNUSED_VARIABLE(loop); + m_error_data.fault_id = id; + m_error_data.pc = pc; + m_error_data.error_info = info; + switch (id) + { + case NRF_FAULT_ID_SDK_ASSERT: + m_error_data.p_assert_info = (assert_info_t *)info; + m_error_data.line_num = m_error_data.p_assert_info->line_num; + m_error_data.p_file_name = m_error_data.p_assert_info->p_file_name; + rt_kprintf("app Assert fault handler:Line(%d)-File(%s)\n", + m_error_data.line_num, m_error_data.p_file_name); + break; + case NRF_FAULT_ID_SDK_ERROR: + m_error_data.p_error_info = (error_info_t *)info; + m_error_data.err_code = m_error_data.p_error_info->err_code; + m_error_data.line_num = m_error_data.p_error_info->line_num; + m_error_data.p_file_name = m_error_data.p_error_info->p_file_name; + rt_kprintf("app error fault handler:Line(%d)-File(%s)\n", + m_error_data.line_num, m_error_data.p_file_name); + break; + } + + NRF_LOG_ERROR("Fatal\r\n"); + NRF_LOG_FINAL_FLUSH(); + + // On assert, the system can only recover with a reset. +#ifndef DEBUG + NRF_LOG_INFO("Hit weak handler\r\n"); + NVIC_SystemReset(); +#else + app_error_save_and_stop(id, pc, info); +#endif // DEBUG +} + +/*lint -restore */ + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_error_weak.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_error_weak.h new file mode 100644 index 0000000000000000000000000000000000000000..fa49dc3f0146bbd7f2b7e52948474294be038d87 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_error_weak.h @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_ERROR_WEAK_H__ +#define APP_ERROR_WEAK_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + * + * @defgroup app_error Common application error handler + * @{ + * @ingroup app_common + * + * @brief Common application error handler. + */ + +/**@brief Callback function for errors, asserts, and faults. + * + * @details This function is called every time an error is raised in app_error, nrf_assert, or + * in the SoftDevice. Information about the error can be found in the @p info + * parameter. + * + * See also @ref nrf_fault_handler_t for more details. + * + * @note The function is implemented as weak so that it can be redefined by a custom error + * handler when needed. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if + * unavailable. + * @param[in] info Optional additional information regarding the fault. The value of the @p id + * parameter dictates how to interpret this parameter. Refer to the documentation + * for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for + * details about interpreting @p info. + */ +void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info); + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif // APP_ERROR_WEAK_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_util.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_util.h new file mode 100644 index 0000000000000000000000000000000000000000..3657f3906e7d9ed6bbe0ec62ff852d718c2d08fb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_util.h @@ -0,0 +1,1080 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup app_util Utility Functions and Definitions + * @{ + * @ingroup app_common + * + * @brief Various types and definitions available to all applications. + */ + +#ifndef APP_UTIL_H__ +#define APP_UTIL_H__ + +#include +#include +#include "compiler_abstraction.h" +#include "nordic_common.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//lint -save -e27 -e10 -e19 +#if defined ( __CC_ARM ) +extern char STACK$$Base; +extern char STACK$$Length; +#define STACK_BASE &STACK$$Base +#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&STACK$$Length)) +#elif defined ( __ICCARM__ ) +extern char CSTACK$$Base; +extern char CSTACK$$Length; +#define STACK_BASE &CSTACK$$Base +#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&CSTACK$$Length)) +#elif defined ( __GNUC__ ) +extern uint32_t __StackTop; +extern uint32_t __StackLimit; +#define STACK_BASE &__StackLimit +#define STACK_TOP &__StackTop +#endif +//lint -restore + +enum +{ + UNIT_0_625_MS = 625, /**< Number of microseconds in 0.625 milliseconds. */ + UNIT_1_25_MS = 1250, /**< Number of microseconds in 1.25 milliseconds. */ + UNIT_10_MS = 10000 /**< Number of microseconds in 10 milliseconds. */ +}; + + +/**@brief Implementation specific macro for delayed macro expansion used in string concatenation +* +* @param[in] lhs Left hand side in concatenation +* @param[in] rhs Right hand side in concatenation +*/ +#define STRING_CONCATENATE_IMPL(lhs, rhs) lhs ## rhs + + +/**@brief Macro used to concatenate string using delayed macro expansion +* +* @note This macro will delay concatenation until the expressions have been resolved +* +* @param[in] lhs Left hand side in concatenation +* @param[in] rhs Right hand side in concatenation +*/ +#define STRING_CONCATENATE(lhs, rhs) STRING_CONCATENATE_IMPL(lhs, rhs) + + +// Disable lint-warnings/errors for STATIC_ASSERT_MSG +//lint --emacro(10, STATIC_ASSERT_MSG) +//lint --emacro(18, STATIC_ASSERT_MSG) +//lint --emacro(19, STATIC_ASSERT_MSG) +//lint --emacro(30, STATIC_ASSERT_MSG) +//lint --emacro(37, STATIC_ASSERT_MSG) +//lint --emacro(42, STATIC_ASSERT_MSG) +//lint --emacro(26, STATIC_ASSERT_MSG) +//lint --emacro(102,STATIC_ASSERT_MSG) +//lint --emacro(533,STATIC_ASSERT_MSG) +//lint --emacro(534,STATIC_ASSERT_MSG) +//lint --emacro(132,STATIC_ASSERT_MSG) +//lint --emacro(414,STATIC_ASSERT_MSG) +//lint --emacro(578,STATIC_ASSERT_MSG) +//lint --emacro(628,STATIC_ASSERT_MSG) +//lint --emacro(648,STATIC_ASSERT_MSG) +//lint --emacro(830,STATIC_ASSERT_MSG) + + +/**@brief Macro for doing static (i.e. compile time) assertion. +* +* @note If the EXPR isn't resolvable, then the error message won't be shown. +* +* @note The output of STATIC_ASSERT_MSG will be different across different compilers. +* +* @param[in] EXPR Constant expression to be verified. +* @param[in] MSG Name of the static assert. +*/ +#if defined(__COUNTER__) + + #define STATIC_ASSERT_MSG(EXPR, MSG) \ + ;enum { STRING_CONCATENATE(MSG, __COUNTER__) = 1 / (!!(EXPR)) } + +#else + + #define STATIC_ASSERT_MSG(EXPR, MSG) \ + ;enum { STRING_CONCATENATE(MSG, __LINE__) = 1 / (!!(EXPR)) } + +#endif + + +/**@brief Macro for doing static (i.e. compile time) assertion. +* +* @note If the EXPR isn't resolvable, then the error message won't be shown. +* +* @note The output of STATIC_ASSERT will be different across different compilers. +* +* @param[in] EXPR Constant expression to be verified. +*/ +#define STATIC_ASSERT(EXPR) STATIC_ASSERT_MSG((EXPR), static_assert_) + + +/**@brief Implementation details for NUM_VAR_ARGS */ +#define NUM_VA_ARGS_IMPL( \ + _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ + _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \ + _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \ + _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ + _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \ + _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \ + _61, _62, N, ...) N + + +/**@brief Macro to get the number of arguments in a call variadic macro call + * + * param[in] ... List of arguments + * + * @retval Number of variadic arguments in the argument list + */ +#define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__, 63, 62, 61, \ + 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \ + 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \ + 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \ + 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \ + 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \ + 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) + +/**@brief Implementation details for NUM_VAR_ARGS */ +#define NUM_VA_ARGS_LESS_1_IMPL( \ + _ignored, \ + _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ + _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \ + _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \ + _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ + _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \ + _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \ + _61, _62, N, ...) N + +/**@brief Macro to get the number of arguments in a call variadic macro call. + * First argument is not counted. + * + * param[in] ... List of arguments + * + * @retval Number of variadic arguments in the argument list + */ +#define NUM_VA_ARGS_LESS_1(...) NUM_VA_ARGS_LESS_1_IMPL(__VA_ARGS__, 63, 62, 61, \ + 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \ + 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \ + 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \ + 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \ + 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \ + 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, ~) + + +/**@brief type for holding an encoded (i.e. little endian) 16 bit unsigned integer. */ +typedef uint8_t uint16_le_t[2]; + +/**@brief Type for holding an encoded (i.e. little endian) 32 bit unsigned integer. */ +typedef uint8_t uint32_le_t[4]; + +/**@brief Byte array type. */ +typedef struct +{ + uint16_t size; /**< Number of array entries. */ + uint8_t * p_data; /**< Pointer to array entries. */ +} uint8_array_t; + + +/**@brief Macro for performing rounded integer division (as opposed to truncating the result). + * + * @param[in] A Numerator. + * @param[in] B Denominator. + * + * @return Rounded (integer) result of dividing A by B. + */ +#define ROUNDED_DIV(A, B) (((A) + ((B) / 2)) / (B)) + + +/**@brief Macro for checking if an integer is a power of two. + * + * @param[in] A Number to be tested. + * + * @return true if value is power of two. + * @return false if value not power of two. + */ +#define IS_POWER_OF_TWO(A) ( ((A) != 0) && ((((A) - 1) & (A)) == 0) ) + + +/**@brief Macro for converting milliseconds to ticks. + * + * @param[in] TIME Number of milliseconds to convert. + * @param[in] RESOLUTION Unit to be converted to in [us/ticks]. + */ +#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) + + +/**@brief Macro for performing integer division, making sure the result is rounded up. + * + * @details One typical use for this is to compute the number of objects with size B is needed to + * hold A number of bytes. + * + * @param[in] A Numerator. + * @param[in] B Denominator. + * + * @return Integer result of dividing A by B, rounded up. + */ +#define CEIL_DIV(A, B) \ + (((A) + (B) - 1) / (B)) + + +/**@brief Macro for creating a buffer aligned to 4 bytes. + * + * @param[in] NAME Name of the buffor. + * @param[in] MIN_SIZE Size of this buffor (it will be rounded up to multiples of 4 bytes). + */ +#define WORD_ALIGNED_MEM_BUFF(NAME, MIN_SIZE) static uint32_t NAME[CEIL_DIV(MIN_SIZE, sizeof(uint32_t))] + + +/**@brief Macro for calculating the number of words that are needed to hold a number of bytes. + * + * @details Adds 3 and divides by 4. + * + * @param[in] n_bytes The number of bytes. + * + * @return The number of words that @p n_bytes take up (rounded up). + */ +#define BYTES_TO_WORDS(n_bytes) (((n_bytes) + 3) >> 2) + + +/**@brief The number of bytes in a word. + */ +#define BYTES_PER_WORD (4) + + +/**@brief Macro for increasing a number to the nearest (larger) multiple of another number. + * + * @param[in] alignment The number to align to. + * @param[in] number The number to align (increase). + * + * @return The aligned (increased) @p number. + */ +#define ALIGN_NUM(alignment, number) ((number - 1) + alignment - ((number - 1) % alignment)) + +/**@brief Macro for getting first of 2 parameters. + * + * @param[in] a1 First parameter. + * @param[in] a2 Second parameter. + */ +#define GET_ARG_1(a1, a2) a1 + +/**@brief Macro for getting second of 2 parameters. + * + * @param[in] a1 First parameter. + * @param[in] a2 Second parameter. + */ +#define GET_ARG_2(a1, a2) a2 + + +/**@brief Container of macro (borrowed from Linux kernel). + * + * This macro returns parent structure address basing on child member address. + * + * @param ptr Address of child type. + * @param type Type of parent structure. + * @param member Name of child field in parent structure. + * + * @return Parent structure address. + * */ +#define CONTAINER_OF(ptr, type, member) \ + (type *)((char *)ptr - offsetof(type, member)) + + +/** + * @brief Define Bit-field mask + * + * Macro that defined the mask with selected number of bits set, starting from + * provided bit number. + * + * @param[in] bcnt Number of bits in the bit-field + * @param[in] boff Lowest bit number + */ +#define BF_MASK(bcnt, boff) ( ((1U << (bcnt)) - 1U) << (boff) ) + +/** + * @brief Get bit-field + * + * Macro that extracts selected bit-field from provided value + * + * @param[in] val Value from witch selected bit-field would be extracted + * @param[in] bcnt Number of bits in the bit-field + * @param[in] boff Lowest bit number + * + * @return Value of the selected bits + */ +#define BF_GET(val, bcnt, boff) ( ( (val) & BF_MASK((bcnt), (boff)) ) >> (boff) ) + +/** + * @brief Create bit-field value + * + * Value is masked and shifted to match given bit-field + * + * @param[in] val Value to set on bit-field + * @param[in] bcnt Number of bits for bit-field + * @param[in] boff Offset of bit-field + * + * @return Value positioned of given bit-field. + */ +#define BF_VAL(val, bcnt, boff) ( (((uint32_t)(val)) << (boff)) & BF_MASK(bcnt, boff) ) + +/** + * @name Configuration of complex bit-field + * + * @sa BF_CX + * @{ + */ +/** @brief Position of bit count in complex bit-field value */ +#define BF_CX_BCNT_POS 0U +/** @brief Mask of bit count in complex bit-field value */ +#define BF_CX_BCNT_MASK (0xffU << BF_CX_BCNT_POS) +/** @brief Position of bit position in complex bit-field value */ +#define BF_CX_BOFF_POS 8U +/** @brief Mask of bit position in complex bit-field value */ +#define BF_CX_BOFF_MASK (0xffU << BF_CX_BOFF_POS) +/** @} */ + +/** + * @brief Define complex bit-field + * + * Complex bit-field would contain its position and size in one number. + * @sa BF_CX_MASK + * @sa BF_CX_POS + * @sa BF_CX_GET + * + * @param[in] bcnt Number of bits in the bit-field + * @param[in] boff Lowest bit number + * + * @return The single number that describes the bit-field completely. + */ +#define BF_CX(bcnt, boff) ( ((((uint32_t)(bcnt)) << BF_CX_BCNT_POS) & BF_CX_BCNT_MASK) | ((((uint32_t)(boff)) << BF_CX_BOFF_POS) & BF_CX_BOFF_MASK) ) + +/** + * @brief Get number of bits in bit-field + * + * @sa BF_CX + * + * @param bf_cx Complex bit-field + * + * @return Number of bits in given bit-field + */ +#define BF_CX_BCNT(bf_cx) ( ((bf_cx) & BF_CX_BCNT_MASK) >> BF_CX_BCNT_POS ) + +/** + * @brief Get lowest bit number in the field + * + * @sa BF_CX + * + * @param[in] bf_cx Complex bit-field + * + * @return Lowest bit number in given bit-field + */ +#define BF_CX_BOFF(bf_cx) ( ((bf_cx) & BF_CX_BOFF_MASK) >> BF_CX_BOFF_POS ) + +/** + * @brief Get bit mask of the selected field + * + * @sa BF_CX + * + * @param[in] bf_cx Complex bit-field + * + * @return Mask of given bit-field + */ +#define BF_CX_MASK(bf_cx) BF_MASK(BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx)) + +/** + * @brief Get bit-field + * + * Macro that extracts selected bit-field from provided value. + * Bit-field is given as a complex value. + * + * @sa BF_CX + * @sa BF_GET + * + * @param[in] val Value from witch selected bit-field would be extracted + * @param[in] bf_cx Complex bit-field + * + * @return Value of the selected bits. + */ +#define BF_CX_GET(val, bf_cx) BF_GET(val, BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx)) + +/** + * @brief Create bit-field value + * + * Value is masked and shifted to match given bit-field. + * + * @param[in] val Value to set on bit-field + * @param[in] bf_cx Complex bit-field + * + * @return Value positioned of given bit-field. + */ +#define BF_CX_VAL(val, bf_cx) BF_VAL(val, BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx)) + +/** + * @brief Extracting data from the brackets + * + * This macro get rid of brackets around the argument. + * It can be used to pass multiple arguments in logical one argument to a macro. + * Call it with arguments inside brackets: + * @code + * #define ARGUMENTS (a, b, c) + * BRACKET_EXTRACT(ARGUMENTS) + * @endcode + * It would produce: + * @code + * a, b, c + * @endcode + * + * @param a Argument with anything inside brackets + * @return Anything that appears inside the brackets of the argument + * + * @note + * The argument of the macro have to be inside brackets. + * In other case the compilation would fail. + */ +#define BRACKET_EXTRACT(a) BRACKET_EXTRACT_(a) +#define BRACKET_EXTRACT_(a) BRACKET_EXTRACT__ a +#define BRACKET_EXTRACT__(...) __VA_ARGS__ + + +/** + * @brief Check if number of parameters is more than 1 + * + * @param ... Arguments to count + * + * @return 0 If argument count is <= 1 + * @return 1 If argument count is > 1 + * + * @sa NUM_VA_ARGS + * @sa NUM_IS_MORE_THAN_1 + */ +#define NUM_VA_ARGS_IS_MORE_THAN_1(...) NUM_IS_MORE_THAN_1(NUM_VA_ARGS(__VA_ARGS__)) + +/** + * @brief Check if given numeric value is bigger than 1 + * + * This macro accepts numeric value, that may be the result of argument expansion. + * This numeric value is then converted to 0 if it is lover than 1 or to 1 if + * its value is higher than 1. + * The generated result can be used to glue it into other macro mnemonic name. + * + * @param N Numeric value to check + * + * @return 0 If argument is <= 1 + * @return 1 If argument is > 1 + * + * @note Any existing definition of a form NUM_IS_MORE_THAN_1_PROBE_[N] can + * broke the result of this macro + */ +#define NUM_IS_MORE_THAN_1(N) NUM_IS_MORE_THAN_1_(N) +#define NUM_IS_MORE_THAN_1_(N) NUM_IS_MORE_THAN_1_PROBE_(NUM_IS_MORE_THAN_1_PROBE_ ## N, 1) +#define NUM_IS_MORE_THAN_1_PROBE_(...) GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__)) +#define NUM_IS_MORE_THAN_1_PROBE_0 ~, 0 +#define NUM_IS_MORE_THAN_1_PROBE_1 ~, 0 + +/** + * @brief Get the first argument + * + * @param ... Arguments to select + * + * @return First argument or empty if no arguments are provided + */ +#define GET_VA_ARG_1(...) GET_VA_ARG_1_(__VA_ARGS__, ) // Make sure that also for 1 argument it works +#define GET_VA_ARG_1_(a1, ...) a1 + +/** + * @brief Get all the arguments but the first one + * + * @param ... Arguments to select + * + * @return All arguments after the first one or empty if less than 2 arguments are provided + */ +#define GET_ARGS_AFTER_1(...) GET_ARGS_AFTER_1_(__VA_ARGS__, ) // Make sure that also for 1 argument it works +#define GET_ARGS_AFTER_1_(a1, ...) __VA_ARGS__ + +/** + * @brief Size of a field in declared structure + * + * Macro that returns the size of the structure field. + * @param struct_type Variable type to get the field size from + * @param field Field name to analyze. It can be even field inside field (field.somethingelse.and_another). + * + * @return Size of the field + */ +#define FIELD_SIZE(struct_type, field) sizeof(((struct struct_type*)NULL)->field) + +/** + * @brief Number of elements in field array in declared structure + * + * Macro that returns number of elementy in structure field. + * @param struct_type Variable type to get the field size from + * @param field Field name to analyze. + * + * @return Number of elements in field array + * + * @sa FIELD_SIZE + */ +#define FIELD_ARRAY_SIZE(struct_type, field) (FIELD_SIZE(struct_type, field) / FIELD_SIZE(struct_type, field[0])) + +/** + * @brief Mapping macro + * + * Macro that process all arguments using given macro + * + * @param ... Macro name to be used for argument processing followed by arguments to process. + * Macro should have following form: MACRO(argument) + * + * @return All arguments processed by given macro + */ +#define MACRO_MAP(...) MACRO_MAP_(__VA_ARGS__) +#define MACRO_MAP_(...) MACRO_MAP_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) // To make sure it works also for 2 arguments in total + +/** + * @brief Mapping macro, recursive version + * + * Can be used in @ref MACRO_MAP macro + */ +#define MACRO_MAP_REC(...) MACRO_MAP_REC_(__VA_ARGS__) +#define MACRO_MAP_REC_(...) MACRO_MAP_REC_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) // To make sure it works also for 2 arguments in total +/** + * @brief Mapping N arguments macro + * + * Macro similar to @ref MACRO_MAP but maps exact number of arguments. + * If there is more arguments given, the rest would be ignored. + * + * @param N Number of arguments to map + * @param ... Macro name to be used for argument processing followed by arguments to process. + * Macro should have following form: MACRO(argument) + * + * @return Selected number of arguments processed by given macro + */ +#define MACRO_MAP_N(N, ...) MACRO_MAP_N_(N, __VA_ARGS__) +#define MACRO_MAP_N_(N, ...) CONCAT_2(MACRO_MAP_, N)(__VA_ARGS__, ) + +/** + * @brief Mapping N arguments macro, recursive version + * + * Can be used in @ref MACRO_MAP_N macro + */ +#define MACRO_MAP_REC_N(N, ...) MACRO_MAP_REC_N_(N, __VA_ARGS__) +#define MACRO_MAP_REC_N_(N, ...) CONCAT_2(MACRO_MAP_REC_, N)(__VA_ARGS__, ) + +#define MACRO_MAP_0( ...) +#define MACRO_MAP_1( macro, a, ...) macro(a) +#define MACRO_MAP_2( macro, a, ...) macro(a) MACRO_MAP_1 (macro, __VA_ARGS__, ) +#define MACRO_MAP_3( macro, a, ...) macro(a) MACRO_MAP_2 (macro, __VA_ARGS__, ) +#define MACRO_MAP_4( macro, a, ...) macro(a) MACRO_MAP_3 (macro, __VA_ARGS__, ) +#define MACRO_MAP_5( macro, a, ...) macro(a) MACRO_MAP_4 (macro, __VA_ARGS__, ) +#define MACRO_MAP_6( macro, a, ...) macro(a) MACRO_MAP_5 (macro, __VA_ARGS__, ) +#define MACRO_MAP_7( macro, a, ...) macro(a) MACRO_MAP_6 (macro, __VA_ARGS__, ) +#define MACRO_MAP_8( macro, a, ...) macro(a) MACRO_MAP_7 (macro, __VA_ARGS__, ) +#define MACRO_MAP_9( macro, a, ...) macro(a) MACRO_MAP_8 (macro, __VA_ARGS__, ) +#define MACRO_MAP_10(macro, a, ...) macro(a) MACRO_MAP_9 (macro, __VA_ARGS__, ) +#define MACRO_MAP_11(macro, a, ...) macro(a) MACRO_MAP_10(macro, __VA_ARGS__, ) +#define MACRO_MAP_12(macro, a, ...) macro(a) MACRO_MAP_11(macro, __VA_ARGS__, ) +#define MACRO_MAP_13(macro, a, ...) macro(a) MACRO_MAP_12(macro, __VA_ARGS__, ) +#define MACRO_MAP_14(macro, a, ...) macro(a) MACRO_MAP_13(macro, __VA_ARGS__, ) +#define MACRO_MAP_15(macro, a, ...) macro(a) MACRO_MAP_14(macro, __VA_ARGS__, ) + +#define MACRO_MAP_REC_0( ...) +#define MACRO_MAP_REC_1( macro, a, ...) macro(a) +#define MACRO_MAP_REC_2( macro, a, ...) macro(a) MACRO_MAP_REC_1 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_3( macro, a, ...) macro(a) MACRO_MAP_REC_2 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_4( macro, a, ...) macro(a) MACRO_MAP_REC_3 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_5( macro, a, ...) macro(a) MACRO_MAP_REC_4 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_6( macro, a, ...) macro(a) MACRO_MAP_REC_5 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_7( macro, a, ...) macro(a) MACRO_MAP_REC_6 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_8( macro, a, ...) macro(a) MACRO_MAP_REC_7 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_9( macro, a, ...) macro(a) MACRO_MAP_REC_8 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_10(macro, a, ...) macro(a) MACRO_MAP_REC_9 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_11(macro, a, ...) macro(a) MACRO_MAP_REC_10(macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_12(macro, a, ...) macro(a) MACRO_MAP_REC_11(macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_13(macro, a, ...) macro(a) MACRO_MAP_REC_12(macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_14(macro, a, ...) macro(a) MACRO_MAP_REC_13(macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_15(macro, a, ...) macro(a) MACRO_MAP_REC_14(macro, __VA_ARGS__, ) + +/** + * @brief Mapping macro with current index + * + * Basically macro similar to @ref MACRO_MAP, but the processing function would get an argument + * and current argument index (beginning from 0). + * + * @param ... Macro name to be used for argument processing followed by arguments to process. + * Macro should have following form: MACRO(argument, index) + * @return All arguments processed by given macro + */ +#define MACRO_MAP_FOR(...) MACRO_MAP_FOR_(__VA_ARGS__) +#define MACRO_MAP_FOR_N_LIST 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +#define MACRO_MAP_FOR_(...) MACRO_MAP_FOR_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) + +/** + * @brief Mapping N arguments macro with current index + * + * Macro is similar to @ref MACRO_MAP_FOR but maps exact number of arguments. + * If there is more arguments given, the rest would be ignored. + * + * @param N Number of arguments to map + * @param ... Macro name to be used for argument processing followed by arguments to process. + * Macro should have following form: MACRO(argument, index) + * + * @return Selected number of arguments processed by given macro + */ +#define MACRO_MAP_FOR_N(N, ...) MACRO_MAP_FOR_N_(N, __VA_ARGS__) +#define MACRO_MAP_FOR_N_(N, ...) CONCAT_2(MACRO_MAP_FOR_, N)((MACRO_MAP_FOR_N_LIST), __VA_ARGS__, ) + +#define MACRO_MAP_FOR_0( n_list, ...) +#define MACRO_MAP_FOR_1( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) +#define MACRO_MAP_FOR_2( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_1 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_3( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_2 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_4( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_3 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_5( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_4 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_6( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_5 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_7( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_6 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_8( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_7 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_9( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_8 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_10(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_9 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_11(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_12(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_13(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_14(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_15(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) + + +/** + * @brief Mapping macro with current index and parameter + * + * Version of @ref MACRO_MAP_FOR that passes also the same parameter to all macros. + * + * @param param Parameter that would be passed to each macro call during mapping. + * @param ... Macro name to be used for argument processing followed by arguments to process. + * Macro should have following form: MACRO(argument, index, param) + * + * @return All arguments processed by given macro + */ +#define MACRO_MAP_FOR_PARAM(param, ...) MACRO_MAP_FOR_PARAM_(param, __VA_ARGS__) +#define MACRO_MAP_FOR_PARAM_(param, ...) MACRO_MAP_FOR_PARAM_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), param, __VA_ARGS__) + +/** + * @brief Mapping N arguments macro with with current index and parameter + * + * @param N Number of arguments to map + * @param param Parameter that would be passed to each macro call during mapping. + * @param ... Macro name to be used for argument processing followed by arguments to process. + * Macro should have following form: MACRO(argument, index, param) + * + * @return All arguments processed by given macro + */ +#define MACRO_MAP_FOR_PARAM_N(N, param, ...) MACRO_MAP_FOR_PARAM_N_(N, param, __VA_ARGS__) +#define MACRO_MAP_FOR_PARAM_N_(N, param, ...) CONCAT_2(MACRO_MAP_FOR_PARAM_, N)((MACRO_MAP_FOR_N_LIST), param, __VA_ARGS__, ) + + +#define MACRO_MAP_FOR_PARAM_0( n_list, param, ...) +#define MACRO_MAP_FOR_PARAM_1( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) +#define MACRO_MAP_FOR_PARAM_2( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_1 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_3( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_2 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_4( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_3 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_5( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_4 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_6( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_5 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_7( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_6 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_8( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_7 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_9( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_8 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_10(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_9 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_11(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_12(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_13(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_14(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_15(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) + + +/** + * @brief Repeating macro. + * + * @param count Count of repeats. + * @param macro Macro must have the following form: MACRO(arguments). + * @param ... Arguments passed to the macro. + * + * @return All arguments processed by the given macro. + */ +#define MACRO_REPEAT(count, macro, ...) MACRO_REPEAT_(count, macro, __VA_ARGS__) +#define MACRO_REPEAT_(count, macro, ...) CONCAT_2(MACRO_REPEAT_, count)(macro, __VA_ARGS__) + +#define MACRO_REPEAT_0(macro, ...) +#define MACRO_REPEAT_1(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_0(macro, __VA_ARGS__) +#define MACRO_REPEAT_2(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_1(macro, __VA_ARGS__) +#define MACRO_REPEAT_3(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_2(macro, __VA_ARGS__) +#define MACRO_REPEAT_4(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_3(macro, __VA_ARGS__) +#define MACRO_REPEAT_5(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_4(macro, __VA_ARGS__) +#define MACRO_REPEAT_6(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_5(macro, __VA_ARGS__) +#define MACRO_REPEAT_7(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_6(macro, __VA_ARGS__) +#define MACRO_REPEAT_8(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_7(macro, __VA_ARGS__) +#define MACRO_REPEAT_9(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_8(macro, __VA_ARGS__) +#define MACRO_REPEAT_10(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_9(macro, __VA_ARGS__) +#define MACRO_REPEAT_11(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_10(macro, __VA_ARGS__) +#define MACRO_REPEAT_12(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_11(macro, __VA_ARGS__) +#define MACRO_REPEAT_13(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_12(macro, __VA_ARGS__) +#define MACRO_REPEAT_14(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_13(macro, __VA_ARGS__) +#define MACRO_REPEAT_15(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_14(macro, __VA_ARGS__) + + +/** + * @brief Repeating macro with current index. + * + * Macro similar to @ref MACRO_REPEAT but the processing function gets the arguments + * and the current argument index (beginning from 0). + + * @param count Count of repeats. + * @param macro Macro must have the following form: MACRO(index, arguments). + * @param ... Arguments passed to the macro. + * + * @return All arguments processed by the given macro. + */ +#define MACRO_REPEAT_FOR(count, macro, ...) MACRO_REPEAT_FOR_(count, macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_(count, macro, ...) CONCAT_2(MACRO_REPEAT_FOR_, count)((MACRO_MAP_FOR_N_LIST), macro, __VA_ARGS__) + +#define MACRO_REPEAT_FOR_0(n_list, macro, ...) +#define MACRO_REPEAT_FOR_1(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_0((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_2(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_1((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_3(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_2((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_4(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_3((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_5(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_4((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_6(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_5((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_7(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_6((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_8(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_7((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_9(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_8((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_10(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_9((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_11(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_12(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_13(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_14(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) +#define MACRO_REPEAT_FOR_15(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__) + +/**@brief Adding curly brace to the macro parameter. + * + * Useful in array of structures initialization. + * + * @param p Parameter to put into the curly brace. */ +#define PARAM_CBRACE(p) { p }, + + +/**@brief Function for changing the value unit. + * + * @param[in] value Value to be rescaled. + * @param[in] old_unit_reversal Reversal of the incoming unit. + * @param[in] new_unit_reversal Reversal of the desired unit. + * + * @return Number of bytes written. + */ +static __INLINE uint64_t value_rescale(uint32_t value, uint32_t old_unit_reversal, uint16_t new_unit_reversal) +{ + return (uint64_t)ROUNDED_DIV((uint64_t)value * new_unit_reversal, old_unit_reversal); +} + +/**@brief Function for encoding a uint16 value. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint16_encode(uint16_t value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((value & 0x00FF) >> 0); + p_encoded_data[1] = (uint8_t) ((value & 0xFF00) >> 8); + return sizeof(uint16_t); +} + +/**@brief Function for encoding a three-byte value. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint24_encode(uint32_t value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16); + return 3; +} + +/**@brief Function for encoding a uint32 value. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint32_encode(uint32_t value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16); + p_encoded_data[3] = (uint8_t) ((value & 0xFF000000) >> 24); + return sizeof(uint32_t); +} + +/**@brief Function for encoding a uint48 value. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint48_encode(uint64_t value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((value & 0x0000000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((value & 0x00000000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((value & 0x000000FF0000) >> 16); + p_encoded_data[3] = (uint8_t) ((value & 0x0000FF000000) >> 24); + p_encoded_data[4] = (uint8_t) ((value & 0x00FF00000000) >> 32); + p_encoded_data[5] = (uint8_t) ((value & 0xFF0000000000) >> 40); + return 6; +} + +/**@brief Function for decoding a uint16 value. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. + */ +static __INLINE uint16_t uint16_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint16_t)((uint8_t *)p_encoded_data)[0])) | + (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 )); +} + +/**@brief Function for decoding a uint16 value in big-endian format. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. + */ +static __INLINE uint16_t uint16_big_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint16_t)((uint8_t *)p_encoded_data)[0]) << 8 ) | + (((uint16_t)((uint8_t *)p_encoded_data)[1])) ); +} + +/**@brief Function for decoding a three-byte value. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value (uint32_t). + */ +static __INLINE uint32_t uint24_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16)); +} + +/**@brief Function for decoding a uint32 value. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. + */ +static __INLINE uint32_t uint32_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) | + (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 )); +} + +/**@brief Function for decoding a uint32 value in big-endian format. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. + */ +static __INLINE uint32_t uint32_big_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 24) | + (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 16) | + (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 8) | + (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 0) ); +} + +/** + * @brief Function for encoding an uint16 value in big-endian format. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data will be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint16_big_encode(uint16_t value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) (value >> 8); + p_encoded_data[1] = (uint8_t) (value & 0xFF); + + return sizeof(uint16_t); +} + +/**@brief Function for encoding a uint32 value in big-endian format. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data will be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint32_big_encode(uint32_t value, uint8_t * p_encoded_data) +{ + *(uint32_t *)p_encoded_data = __REV(value); + return sizeof(uint32_t); +} + +/**@brief Function for decoding a uint48 value. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. (uint64_t) + */ +static __INLINE uint64_t uint48_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) | + (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24) | + (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32) | + (((uint64_t)((uint8_t *)p_encoded_data)[5]) << 40 )); +} + +/** @brief Function for converting the input voltage (in milli volts) into percentage of 3.0 Volts. + * + * @details The calculation is based on a linearized version of the battery's discharge + * curve. 3.0V returns 100% battery level. The limit for power failure is 2.1V and + * is considered to be the lower boundary. + * + * The discharge curve for CR2032 is non-linear. In this model it is split into + * 4 linear sections: + * - Section 1: 3.0V - 2.9V = 100% - 42% (58% drop on 100 mV) + * - Section 2: 2.9V - 2.74V = 42% - 18% (24% drop on 160 mV) + * - Section 3: 2.74V - 2.44V = 18% - 6% (12% drop on 300 mV) + * - Section 4: 2.44V - 2.1V = 6% - 0% (6% drop on 340 mV) + * + * These numbers are by no means accurate. Temperature and + * load in the actual application is not accounted for! + * + * @param[in] mvolts The voltage in mV + * + * @return Battery level in percent. +*/ +static __INLINE uint8_t battery_level_in_percent(const uint16_t mvolts) +{ + uint8_t battery_level; + + if (mvolts >= 3000) + { + battery_level = 100; + } + else if (mvolts > 2900) + { + battery_level = 100 - ((3000 - mvolts) * 58) / 100; + } + else if (mvolts > 2740) + { + battery_level = 42 - ((2900 - mvolts) * 24) / 160; + } + else if (mvolts > 2440) + { + battery_level = 18 - ((2740 - mvolts) * 12) / 300; + } + else if (mvolts > 2100) + { + battery_level = 6 - ((2440 - mvolts) * 6) / 340; + } + else + { + battery_level = 0; + } + + return battery_level; +} + +/**@brief Function for checking if a pointer value is aligned to a 4 byte boundary. + * + * @param[in] p Pointer value to be checked. + * + * @return TRUE if pointer is aligned to a 4 byte boundary, FALSE otherwise. + */ +static __INLINE bool is_word_aligned(void const* p) +{ + return (((uintptr_t)p & 0x03) == 0); +} + +/** + * @brief Function for checking if provided address is located in stack space. + * + * @param[in] ptr Pointer to be checked. + * + * @return true if address is in stack space, false otherwise. + */ +static __INLINE bool is_address_from_stack(void * ptr) +{ + if (((uint32_t)ptr >= (uint32_t)STACK_BASE) && + ((uint32_t)ptr < (uint32_t)STACK_TOP) ) + { + return true; + } + else + { + return false; + } +} + + +#ifdef __cplusplus +} +#endif + +#endif // APP_UTIL_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_util_bds.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_util_bds.h new file mode 100644 index 0000000000000000000000000000000000000000..e88069322f5bc9de0832da8f9852d50501fa2834 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_util_bds.h @@ -0,0 +1,449 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup app_util Utility Functions and Definitions + * @{ + * @ingroup app_common + * + * @brief Various types and definitions available to all applications. + */ + +#ifndef APP_UTIL_BDS_H__ +#define APP_UTIL_BDS_H__ + +#include +#include +#include +#include "compiler_abstraction.h" +#include "app_util.h" +#include "ble_srv_common.h" +#include "nordic_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint8_t nibble_t; +typedef uint32_t uint24_t; +typedef uint64_t uint40_t; + +/**@brief IEEE 11073-20601 Regulatory Certification Data List Structure */ +typedef struct +{ + uint8_t * p_list; /**< Pointer the byte array containing the encoded opaque structure based on IEEE 11073-20601 specification. */ + uint8_t list_len; /**< Length of the byte array. */ +} regcertdatalist_t; + +/**@brief SFLOAT format (IEEE-11073 16-bit FLOAT, meaning 4 bits for exponent (base 10) and 12 bits mantissa) */ +typedef struct +{ + int8_t exponent; /**< Base 10 exponent, should be using only 4 bits */ + int16_t mantissa; /**< Mantissa, should be using only 12 bits */ +} sfloat_t; + +/**@brief Date and Time structure. */ +typedef struct +{ + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hours; + uint8_t minutes; + uint8_t seconds; +} ble_date_time_t; + + +/**@brief Function for encoding a uint16 value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t bds_uint16_encode(const uint16_t * p_value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((*p_value & 0x00FF) >> 0); + p_encoded_data[1] = (uint8_t) ((*p_value & 0xFF00) >> 8); + return sizeof(uint16_t); +} + +static __INLINE uint8_t bds_int16_encode(const int16_t * p_value, uint8_t * p_encoded_data) +{ + uint16_t tmp = *p_value; + return bds_uint16_encode(&tmp, p_encoded_data); +} + +/**@brief Function for encoding a uint24 value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t bds_uint24_encode(const uint32_t * p_value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((*p_value & 0x000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((*p_value & 0x0000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((*p_value & 0x00FF0000) >> 16); + return (3); +} + + +/**@brief Function for encoding a uint32 value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t bds_uint32_encode(const uint32_t * p_value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((*p_value & 0x000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((*p_value & 0x0000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((*p_value & 0x00FF0000) >> 16); + p_encoded_data[3] = (uint8_t) ((*p_value & 0xFF000000) >> 24); + return sizeof(uint32_t); +} + + +/**@brief Function for encoding a uint40 value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t bds_uint40_encode(const uint64_t * p_value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((*p_value & 0x00000000000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((*p_value & 0x000000000000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((*p_value & 0x0000000000FF0000) >> 16); + p_encoded_data[3] = (uint8_t) ((*p_value & 0x00000000FF000000) >> 24); + p_encoded_data[4] = (uint8_t) ((*p_value & 0x000000FF00000000) >> 32); + return 5; +} + +/**@brief Function for encoding a sfloat value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t bds_sfloat_encode(const sfloat_t * p_value, uint8_t * p_encoded_data) +{ + uint16_t encoded_val; + + encoded_val = ((p_value->exponent << 12) & 0xF000) | + ((p_value->mantissa << 0) & 0x0FFF); + + return(bds_uint16_encode(&encoded_val, p_encoded_data)); +} + + +/**@brief Function for encoding a uint8_array value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + */ +static __INLINE uint8_t bds_uint8_array_encode(const uint8_array_t * p_value, + uint8_t * p_encoded_data) +{ + memcpy(p_encoded_data, p_value->p_data, p_value->size); + return p_value->size; +} + + +/**@brief Function for encoding a utf8_str value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + + */ +static __INLINE uint8_t bds_ble_srv_utf8_str_encode(const ble_srv_utf8_str_t * p_value, + uint8_t * p_encoded_data) +{ + memcpy(p_encoded_data, p_value->p_str, p_value->length); + return p_value->length; +} + +/**@brief Function for encoding a regcertdatalist value. + * + * @param[in] p_value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + + */ +static __INLINE uint8_t bds_regcertdatalist_encode(const regcertdatalist_t * p_value, + uint8_t * p_encoded_data) +{ + memcpy(p_encoded_data, p_value->p_list, p_value->list_len); + return p_value->list_len; +} + + +/**@brief Function for decoding a date_time value. + * + * @param[in] p_date_time pointer to the date_time structure to encode. + * @param[in] p_encoded_data pointer to the encoded data + * @return length of the encoded field. + */ +static __INLINE uint8_t bds_ble_date_time_encode(const ble_date_time_t * p_date_time, + uint8_t * p_encoded_data) +{ + uint8_t len = bds_uint16_encode(&p_date_time->year, &p_encoded_data[0]); + + p_encoded_data[len++] = p_date_time->month; + p_encoded_data[len++] = p_date_time->day; + p_encoded_data[len++] = p_date_time->hours; + p_encoded_data[len++] = p_date_time->minutes; + p_encoded_data[len++] = p_date_time->seconds; + + return len; +} + + +/**@brief Function for decoding a uint16 value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_uint16_decode(const uint8_t len, + const uint8_t * p_encoded_data, + uint16_t * p_decoded_val) +{ + UNUSED_VARIABLE(len); + *p_decoded_val = (((uint16_t)((uint8_t *)p_encoded_data)[0])) | + (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 ); + return (sizeof(uint16_t)); +} + + +/**@brief Function for decoding a int16 value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_int16_decode(const uint8_t len, + const uint8_t * p_encoded_data, + int16_t * p_decoded_val) +{ + UNUSED_VARIABLE(len); + uint16_t tmp = 0; + uint8_t retval = bds_uint16_decode(len, p_encoded_data, &tmp); + *p_decoded_val = (int16_t)tmp; + return retval; +} + + +/**@brief Function for decoding a uint24 value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_uint24_decode(const uint8_t len, + const uint8_t * p_encoded_data, + uint32_t * p_decoded_val) +{ + UNUSED_VARIABLE(len); + *p_decoded_val = (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16); + return (3); +} + + +/**@brief Function for decoding a uint32 value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_uint32_decode(const uint8_t len, + const uint8_t * p_encoded_data, + uint32_t * p_decoded_val) +{ + UNUSED_VARIABLE(len); + *p_decoded_val = (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) | + (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 ); + return (sizeof(uint32_t)); +} + + +/**@brief Function for decoding a uint40 value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_uint40_decode(const uint8_t len, + const uint8_t * p_encoded_data, + uint64_t * p_decoded_val) +{ + UNUSED_VARIABLE(len); + *p_decoded_val = (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) | + (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24 )| + (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32 ); + return (40); +} + + +/**@brief Function for decoding a sfloat value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + + */ +static __INLINE uint8_t bds_sfloat_decode(const uint8_t len, + const uint8_t * p_encoded_data, + sfloat_t * p_decoded_val) +{ + + p_decoded_val->exponent = 0; + bds_uint16_decode(len, p_encoded_data, (uint16_t*)&p_decoded_val->mantissa); + p_decoded_val->exponent = (uint8_t)((p_decoded_val->mantissa & 0xF000) >> 12); + p_decoded_val->mantissa &= 0x0FFF; + return len; +} + + +/**@brief Function for decoding a uint8_array value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_uint8_array_decode(const uint8_t len, + const uint8_t * p_encoded_data, + uint8_array_t * p_decoded_val) +{ + memcpy(p_decoded_val->p_data, p_encoded_data, len); + p_decoded_val->size = len; + return p_decoded_val->size; +} + + +/**@brief Function for decoding a utf8_str value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_ble_srv_utf8_str_decode(const uint8_t len, + const uint8_t * p_encoded_data, + ble_srv_utf8_str_t * p_decoded_val) +{ + p_decoded_val->p_str = (uint8_t*)p_encoded_data; + p_decoded_val->length = len; + return p_decoded_val->length; +} + + +/**@brief Function for decoding a regcertdatalist value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_decoded_val pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_regcertdatalist_decode(const uint8_t len, + const uint8_t * p_encoded_data, + regcertdatalist_t * p_decoded_val) +{ + memcpy(p_decoded_val->p_list, p_encoded_data, len); + p_decoded_val->list_len = len; + return p_decoded_val->list_len; +} + + +/**@brief Function for decoding a date_time value. + * + * @param[in] len length of the field to be decoded. + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * @param[in] p_date_time pointer to the decoded value + * + * @return length of the decoded field. + */ +static __INLINE uint8_t bds_ble_date_time_decode(const uint8_t len, + const uint8_t * p_encoded_data, + ble_date_time_t * p_date_time) +{ + UNUSED_VARIABLE(len); + uint8_t pos = bds_uint16_decode(len, &p_encoded_data[0], &p_date_time->year); + p_date_time->month = p_encoded_data[pos++]; + p_date_time->day = p_encoded_data[pos++]; + p_date_time->hours = p_encoded_data[pos++]; + p_date_time->minutes = p_encoded_data[pos++]; + p_date_time->seconds = p_encoded_data[pos++]; + + return pos; +} + + +#ifdef __cplusplus +} +#endif + +#endif // APP_UTIL_BDS_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_util_platform.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_util_platform.c new file mode 100644 index 0000000000000000000000000000000000000000..740d42233b317e94e62ea4c6cef1db3bd470d97a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_util_platform.c @@ -0,0 +1,127 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "app_util_platform.h" + +#ifdef SOFTDEVICE_PRESENT +/* Global nvic state instance, required by nrf_nvic.h */ +nrf_nvic_state_t nrf_nvic_state; +#endif + +static uint32_t m_in_critical_region = 0; + +void app_util_disable_irq(void) +{ + __disable_irq(); + m_in_critical_region++; +} + +void app_util_enable_irq(void) +{ + m_in_critical_region--; + if (m_in_critical_region == 0) + { + __enable_irq(); + } +} + +void app_util_critical_region_enter(uint8_t *p_nested) +{ +#if __CORTEX_M == (0x04U) + ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get()) +#endif + +#if defined(SOFTDEVICE_PRESENT) + /* return value can be safely ignored */ + (void) sd_nvic_critical_region_enter(p_nested); +#else + app_util_disable_irq(); +#endif +} + +void app_util_critical_region_exit(uint8_t nested) +{ +#if __CORTEX_M == (0x04U) + ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get()) +#endif + +#if defined(SOFTDEVICE_PRESENT) + /* return value can be safely ignored */ + (void) sd_nvic_critical_region_exit(nested); +#else + app_util_enable_irq(); +#endif +} + + +uint8_t privilege_level_get(void) +{ +#if __CORTEX_M == (0x00U) || defined(_WIN32) || defined(__unix) || defined(__APPLE__) + /* the Cortex-M0 has no concept of privilege */ + return APP_LEVEL_PRIVILEGED; +#elif __CORTEX_M == (0x04U) + uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ; + if (0 == isr_vector_num) + { + /* Thread Mode, check nPRIV */ + int32_t control = __get_CONTROL(); + return control & CONTROL_nPRIV_Msk ? APP_LEVEL_UNPRIVILEGED : APP_LEVEL_PRIVILEGED; + } + else + { + /* Handler Mode, always privileged */ + return APP_LEVEL_PRIVILEGED; + } +#endif +} + + +uint8_t current_int_priority_get(void) +{ + uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ; + if (isr_vector_num > 0) + { + int32_t irq_type = ((int32_t)isr_vector_num - EXTERNAL_INT_VECTOR_OFFSET); + return (NVIC_GetPriority((IRQn_Type)irq_type) & 0xFF); + } + else + { + return APP_IRQ_PRIORITY_THREAD; + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_util_platform.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_util_platform.h new file mode 100644 index 0000000000000000000000000000000000000000..e5f15066b50d7433c2693fab1501d6f9d6a658f2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/app_util_platform.h @@ -0,0 +1,270 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup app_util_platform Utility Functions and Definitions (Platform) + * @{ + * @ingroup app_common + * + * @brief Various types and definitions available to all applications when using SoftDevice. + */ + +#ifndef APP_UTIL_PLATFORM_H__ +#define APP_UTIL_PLATFORM_H__ + +#include +#include "compiler_abstraction.h" +#include "nrf.h" +#ifdef SOFTDEVICE_PRESENT +#include "nrf_soc.h" +#include "nrf_nvic.h" +#endif +#include "nrf_assert.h" +#include "app_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if __CORTEX_M == (0x00U) +#define _PRIO_SD_HIGH 0 +#define _PRIO_APP_HIGH 1 +#define _PRIO_APP_MID 1 +#define _PRIO_SD_LOW 2 +#define _PRIO_APP_LOW 3 +#define _PRIO_APP_LOWEST 3 +#define _PRIO_THREAD 4 +#elif __CORTEX_M == (0x04U) && !defined(S1XX) +#define _PRIO_SD_HIGH 0 +#define _PRIO_SD_MID 1 +#define _PRIO_APP_HIGH 2 +#define _PRIO_APP_MID 3 +#define _PRIO_SD_LOW 4 +#define _PRIO_SD_LOWEST 5 +#define _PRIO_APP_LOW 6 +#define _PRIO_APP_LOWEST 7 +#define _PRIO_THREAD 15 +#elif defined(S1XX) +#define _PRIO_SD_HIGH 0 +#define _PRIO_APP_HIGH 1 +#define _PRIO_APP_MID 1 +#define _PRIO_SD_LOW 2 +#define _PRIO_APP_LOW 3 +#define _PRIO_APP_LOWEST 3 +#define _PRIO_THREAD 4 +#else + #error "No platform defined" +#endif + + +//lint -save -e113 -e452 +/**@brief The interrupt priorities available to the application while the SoftDevice is active. */ +typedef enum +{ +#ifndef SOFTDEVICE_PRESENT + APP_IRQ_PRIORITY_HIGHEST = _PRIO_SD_HIGH, +#else + APP_IRQ_PRIORITY_HIGHEST = _PRIO_APP_HIGH, +#endif + APP_IRQ_PRIORITY_HIGH = _PRIO_APP_HIGH, +#ifndef SOFTDEVICE_PRESENT + APP_IRQ_PRIORITY_MID = _PRIO_SD_LOW, +#else + APP_IRQ_PRIORITY_MID = _PRIO_APP_MID, +#endif + APP_IRQ_PRIORITY_LOW = _PRIO_APP_LOW, + APP_IRQ_PRIORITY_LOWEST = _PRIO_APP_LOWEST, + APP_IRQ_PRIORITY_THREAD = _PRIO_THREAD /**< "Interrupt level" when running in Thread Mode. */ +} app_irq_priority_t; +//lint -restore + + +/*@brief The privilege levels available to applications in Thread Mode */ +typedef enum +{ + APP_LEVEL_UNPRIVILEGED, + APP_LEVEL_PRIVILEGED +} app_level_t; + +/**@cond NO_DOXYGEN */ +#define EXTERNAL_INT_VECTOR_OFFSET 16 +/**@endcond */ + +/**@brief Macro for setting a breakpoint. + */ +#if defined(__GNUC__) +#define NRF_BREAKPOINT __builtin_trap() +#else +#define NRF_BREAKPOINT __BKPT(0) +#endif + +/** @brief Macro for setting a breakpoint. + * + * If it is possible to detect debugger presence then it is set only in that case. + * + */ +#if __CORTEX_M == 0x04 +#define NRF_BREAKPOINT_COND do { \ + /* C_DEBUGEN == 1 -> Debugger Connected */ \ + if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) \ + { \ + /* Generate breakpoint if debugger is connected */ \ + NRF_BREAKPOINT; \ + } \ + }while (0) +#else +#define NRF_BREAKPOINT_COND NRF_BREAKPOINT +#endif // __CORTEX_M == 0x04 + +#if defined ( __CC_ARM ) +#define PACKED(TYPE) __packed TYPE +#define PACKED_STRUCT PACKED(struct) +#elif defined ( __GNUC__ ) +#define PACKED __attribute__((packed)) +#define PACKED_STRUCT struct PACKED +#elif defined (__ICCARM__) +#define PACKED_STRUCT __packed struct +#endif + +void app_util_critical_region_enter (uint8_t *p_nested); +void app_util_critical_region_exit (uint8_t nested); + +/**@brief Macro for entering a critical region. + * + * @note Due to implementation details, there must exist one and only one call to + * CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located + * in the same scope. + */ +#ifdef SOFTDEVICE_PRESENT +#define CRITICAL_REGION_ENTER() \ + { \ + uint8_t __CR_NESTED = 0; \ + app_util_critical_region_enter(&__CR_NESTED); +#else +#define CRITICAL_REGION_ENTER() app_util_critical_region_enter(NULL) +#endif + +/**@brief Macro for leaving a critical region. + * + * @note Due to implementation details, there must exist one and only one call to + * CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located + * in the same scope. + */ +#ifdef SOFTDEVICE_PRESENT +#define CRITICAL_REGION_EXIT() \ + app_util_critical_region_exit(__CR_NESTED); \ + } +#else +#define CRITICAL_REGION_EXIT() app_util_critical_region_exit(0) +#endif + +/* Workaround for Keil 4 */ +#ifndef IPSR_ISR_Msk +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ +#endif + + + +/**@brief Macro to enable anonymous unions from a certain point in the code. + */ +#if defined(__CC_ARM) + #define ANON_UNIONS_ENABLE _Pragma("push") \ + _Pragma("anon_unions") +#elif defined(__ICCARM__) + #define ANON_UNIONS_ENABLE _Pragma("language=extended") +#else + #define ANON_UNIONS_ENABLE + // No action will be taken. + // For GCC anonymous unions are enabled by default. +#endif + +/**@brief Macro to disable anonymous unions from a certain point in the code. + * @note Call only after first calling @ref ANON_UNIONS_ENABLE. + */ +#if defined(__CC_ARM) + #define ANON_UNIONS_DISABLE _Pragma("pop") +#elif defined(__ICCARM__) + #define ANON_UNIONS_DISABLE + // for IAR leave anonymous unions enabled +#else + #define ANON_UNIONS_DISABLE + // No action will be taken. + // For GCC anonymous unions are enabled by default. +#endif + +/**@brief Macro for adding pragma directive only for GCC. + */ +#ifdef __GNUC__ +#define GCC_PRAGMA(v) _Pragma(v) +#else +#define GCC_PRAGMA(v) +#endif + +/* Workaround for Keil 4 */ +#ifndef CONTROL_nPRIV_Msk +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ +#endif + +/**@brief Function for finding the current interrupt level. + * + * @return Current interrupt level. + * @retval APP_IRQ_PRIORITY_HIGH We are running in Application High interrupt level. + * @retval APP_IRQ_PRIORITY_LOW We are running in Application Low interrupt level. + * @retval APP_IRQ_PRIORITY_THREAD We are running in Thread Mode. + */ +uint8_t current_int_priority_get(void); + + +/**@brief Function for finding out the current privilege level. + * + * @return Current privilege level. + * @retval APP_LEVEL_UNPRIVILEGED We are running in unprivileged level. + * @retval APP_LEVEL_PRIVILEGED We are running in privileged level. + */ +uint8_t privilege_level_get(void); + + +#ifdef __cplusplus +} +#endif + +#endif // APP_UTIL_PLATFORM_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/nordic_common.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/nordic_common.h new file mode 100644 index 0000000000000000000000000000000000000000..319ff630c747b7774ede28643b20ba3efaa4ab87 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/nordic_common.h @@ -0,0 +1,211 @@ +/** + * Copyright (c) 2008 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * @brief Common defines and macros for firmware developed by Nordic Semiconductor. + */ + +#ifndef NORDIC_COMMON_H__ +#define NORDIC_COMMON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Check if selected module is enabled + * + * This is save function for driver enable checking. + * Correct from Lint point of view (not using default of undefined value). + * + * Usage: + * @code + #if NRF_MODULE_ENABLED(UART) + ... + #endif + * @endcode + * + * @param module The module name. + * + * @retval 1 The macro _ENABLE is defined and is non-zero. + * @retval 0 The macro _ENABLE is not defined or it equals zero. + * + * @note + * This macro intentionally does not implement second expansion level. + * The name of the module to be checked has to be given directly as a parameter. + * And given parameter would be connected with @c _ENABLED postfix directly + * without evaluating its value. + */ +//lint -emacro(491,NRF_MODULE_ENABLED) // Suppers warning 491 "non-standard use of 'defined' preprocessor operator" +#define NRF_MODULE_ENABLED(module) \ + ((defined(module ## _ENABLED) && (module ## _ENABLED)) ? 1 : 0) + +/** The upper 8 bits of a 32 bit value */ +//lint -emacro(572,MSB_32) // Suppress warning 572 "Excessive shift value" +#define MSB_32(a) (((a) & 0xFF000000) >> 24) +/** The lower 8 bits (of a 32 bit value) */ +#define LSB_32(a) ((a) & 0x000000FF) + +/** The upper 8 bits of a 16 bit value */ +//lint -emacro(572,MSB_16) // Suppress warning 572 "Excessive shift value" +#define MSB_16(a) (((a) & 0xFF00) >> 8) +/** The lower 8 bits (of a 16 bit value) */ +#define LSB_16(a) ((a) & 0x00FF) + +/** Leaves the minimum of the two 32-bit arguments */ +/*lint -emacro(506, MIN) */ /* Suppress "Constant value Boolean */ +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +/** Leaves the maximum of the two 32-bit arguments */ +/*lint -emacro(506, MAX) */ /* Suppress "Constant value Boolean */ +#define MAX(a, b) ((a) < (b) ? (b) : (a)) + +/**@brief Concatenates two parameters. + * + * It realizes two level expansion to make it sure that all the parameters + * are actually expanded before gluing them together. + * + * @param p1 First parameter to concatenating + * @param p2 Second parameter to concatenating + * + * @return Two parameters glued together. + * They have to create correct C mnemonic in other case + * preprocessor error would be generated. + * + * @sa CONCAT_3 + */ +#define CONCAT_2(p1, p2) CONCAT_2_(p1, p2) +/** Auxiliary macro used by @ref CONCAT_2 */ +#define CONCAT_2_(p1, p2) p1##p2 + +/**@brief Concatenates three parameters. + * + * It realizes two level expansion to make it sure that all the parameters + * are actually expanded before gluing them together. + * + * @param p1 First parameter to concatenating + * @param p2 Second parameter to concatenating + * @param p3 Third parameter to concatenating + * + * @return Three parameters glued together. + * They have to create correct C mnemonic in other case + * preprocessor error would be generated. + * + * @sa CONCAT_2 + */ +#define CONCAT_3(p1, p2, p3) CONCAT_3_(p1, p2, p3) +/** Auxiliary macro used by @ref CONCAT_3 */ +#define CONCAT_3_(p1, p2, p3) p1##p2##p3 + +#define STRINGIFY_(val) #val +/** Converts a macro argument into a character constant. + */ +#define STRINGIFY(val) STRINGIFY_(val) + +/** Counts number of elements inside the array + */ +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +/**@brief Set a bit in the uint32 word. + * + * @param[in] W Word whose bit is being set. + * @param[in] B Bit number in the word to be set. + */ +#define SET_BIT(W,B) ((W) |= (uint32_t)(1U << (B))) + + +/**@brief Clears a bit in the uint32 word. + * + * @param[in] W Word whose bit is to be cleared. + * @param[in] B Bit number in the word to be cleared. + */ +#define CLR_BIT(W, B) ((W) &= (~((uint32_t)1U << (B)))) + + +/**@brief Checks if a bit is set. + * + * @param[in] W Word whose bit is to be checked. + * @param[in] B Bit number in the word to be checked. + * + * @retval 1 if bit is set. + * @retval 0 if bit is not set. + */ +#define IS_SET(W,B) (((W) >> (B)) & 1) + +#define BIT_0 0x01 /**< The value of bit 0 */ +#define BIT_1 0x02 /**< The value of bit 1 */ +#define BIT_2 0x04 /**< The value of bit 2 */ +#define BIT_3 0x08 /**< The value of bit 3 */ +#define BIT_4 0x10 /**< The value of bit 4 */ +#define BIT_5 0x20 /**< The value of bit 5 */ +#define BIT_6 0x40 /**< The value of bit 6 */ +#define BIT_7 0x80 /**< The value of bit 7 */ +#define BIT_8 0x0100 /**< The value of bit 8 */ +#define BIT_9 0x0200 /**< The value of bit 9 */ +#define BIT_10 0x0400 /**< The value of bit 10 */ +#define BIT_11 0x0800 /**< The value of bit 11 */ +#define BIT_12 0x1000 /**< The value of bit 12 */ +#define BIT_13 0x2000 /**< The value of bit 13 */ +#define BIT_14 0x4000 /**< The value of bit 14 */ +#define BIT_15 0x8000 /**< The value of bit 15 */ +#define BIT_16 0x00010000 /**< The value of bit 16 */ +#define BIT_17 0x00020000 /**< The value of bit 17 */ +#define BIT_18 0x00040000 /**< The value of bit 18 */ +#define BIT_19 0x00080000 /**< The value of bit 19 */ +#define BIT_20 0x00100000 /**< The value of bit 20 */ +#define BIT_21 0x00200000 /**< The value of bit 21 */ +#define BIT_22 0x00400000 /**< The value of bit 22 */ +#define BIT_23 0x00800000 /**< The value of bit 23 */ +#define BIT_24 0x01000000 /**< The value of bit 24 */ +#define BIT_25 0x02000000 /**< The value of bit 25 */ +#define BIT_26 0x04000000 /**< The value of bit 26 */ +#define BIT_27 0x08000000 /**< The value of bit 27 */ +#define BIT_28 0x10000000 /**< The value of bit 28 */ +#define BIT_29 0x20000000 /**< The value of bit 29 */ +#define BIT_30 0x40000000 /**< The value of bit 30 */ +#define BIT_31 0x80000000 /**< The value of bit 31 */ + +#define UNUSED_VARIABLE(X) ((void)(X)) +#define UNUSED_PARAMETER(X) UNUSED_VARIABLE(X) +#define UNUSED_RETURN_VALUE(X) UNUSED_VARIABLE(X) + +#ifdef __cplusplus +} +#endif + +#endif // NORDIC_COMMON_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/nrf_assert.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/nrf_assert.c new file mode 100644 index 0000000000000000000000000000000000000000..6255ba920cfc4f0b532cd7faee543e0c6aa2afbd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/nrf_assert.c @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2006 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_assert.h" +#include "app_error.h" +#include "nordic_common.h" + +__WEAK void assert_nrf_callback(uint16_t line_num, const uint8_t * file_name) +{ + assert_info_t assert_info = + { + .line_num = line_num, + .p_file_name = file_name, + }; + app_error_fault_handler(NRF_FAULT_ID_SDK_ASSERT, 0, (uint32_t)(&assert_info)); + + UNUSED_VARIABLE(assert_info); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/nrf_assert.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/nrf_assert.h new file mode 100644 index 0000000000000000000000000000000000000000..bbf872941e661b7d79abe22cf2cf23ba8c32876b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/nrf_assert.h @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2006 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * @brief Utilities for verifying program logic + */ + +#ifndef NRF_ASSERT_H_ +#define NRF_ASSERT_H_ + +#include +#include "nrf.h" +#include "app_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for handling assertions. + * + * + * @note + * This function is called when an assertion has triggered. + * + * @note + * This function is deprecated and will be removed in future releases. + * Use app_error_fault_handler instead. + * + * + * @post + * All hardware is put into an idle non-emitting state (in particular the radio is highly + * important to switch off since the radio might be in a state that makes it send + * packets continiously while a typical final infinit ASSERT loop is executing). + * + * + * @param line_num The line number where the assertion is called + * @param file_name Pointer to the file name + */ +//lint -save -esym(14, assert_nrf_callback) +void assert_nrf_callback(uint16_t line_num, const uint8_t *file_name); +//lint -restore + +#if (defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)) +#define NRF_ASSERT_PRESENT 1 +#else +#define NRF_ASSERT_PRESENT 0 +#endif + +//#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER) + +/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */ +/*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \ + +/** @brief Function for checking intended for production code. + * + * Check passes if "expr" evaluates to true. */ + +#ifdef _lint +#define ASSERT(expr) \ +if (expr) \ +{ \ +} \ +else \ +{ \ + while(1); \ +} +#else //_lint +#define ASSERT(expr) \ +if (NRF_ASSERT_PRESENT) \ +{ \ + if (expr) \ + { \ + } \ + else \ + { \ + assert_nrf_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \ + } \ +} +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_ASSERT_H_ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/nrf_bitmask.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/nrf_bitmask.h new file mode 100644 index 0000000000000000000000000000000000000000..72f531f1a7ec4c3ecbd4b78efe591f51fb5ce7d8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/nrf_bitmask.h @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2006 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_BITMASK_H +#define NRF_BITMASK_H + +#include "compiler_abstraction.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BITMASK_BYTE_GET(abs_bit) ((abs_bit)/8) +#define BITMASK_RELBIT_GET(abs_bit) ((abs_bit) & 0x00000007) + +/** + * Function for checking if bit in the multi-byte bit mask is set. + * + * @param bit Bit index. + * @param p_mask A pointer to mask with bit fields. + * + * @return 0 if bit is not set, positive value otherwise. + */ +__STATIC_INLINE uint32_t nrf_bitmask_bit_is_set(uint32_t bit, void const * p_mask) +{ + uint8_t const * p_mask8 = (uint8_t const *)p_mask; + uint32_t byte_idx = BITMASK_BYTE_GET(bit); + bit = BITMASK_RELBIT_GET(bit); + return (1 << bit) & p_mask8[byte_idx]; +} + +/** + * Function for setting a bit in the multi-byte bit mask. + * + * @param bit Bit index. + * @param p_mask A pointer to mask with bit fields. + */ +__STATIC_INLINE void nrf_bitmask_bit_set(uint32_t bit, void * p_mask) +{ + uint8_t * p_mask8 = (uint8_t *)p_mask; + uint32_t byte_idx = BITMASK_BYTE_GET(bit); + bit = BITMASK_RELBIT_GET(bit); + p_mask8[byte_idx] |= (1 << bit); +} + +/** + * Function for clearing a bit in the multi-byte bit mask. + * + * @param bit Bit index. + * @param p_mask A pointer to mask with bit fields. + */ +__STATIC_INLINE void nrf_bitmask_bit_clear(uint32_t bit, void * p_mask) +{ + uint8_t * p_mask8 = (uint8_t *)p_mask; + uint32_t byte_idx = BITMASK_BYTE_GET(bit); + bit = BITMASK_RELBIT_GET(bit); + p_mask8[byte_idx] &= ~(1 << bit); +} + +/** + * Function for performing bitwise OR operation on two multi-byte bit masks. + * + * @param p_mask1 A pointer to the first bit mask. + * @param p_mask2 A pointer to the second bit mask. + * @param p_mask_out A pointer to the output bit mask. + * @param length Length of output mask in bytes. + */ +__STATIC_INLINE void nrf_bitmask_masks_or(void const * p_mask1, + void const * p_mask2, + void * p_out_mask, + uint32_t length) +{ + uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1; + uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2; + uint8_t * p_mask8_out = (uint8_t *)p_out_mask; + uint32_t i; + for (i = 0; i < length; i++) + { + p_mask8_out[i] = p_mask8_1[i] | p_mask8_2[i]; + } +} + +/** + * Function for performing bitwise AND operation on two multi-byte bit masks. + * + * @param p_mask1 A pointer to the first bit mask. + * @param p_mask2 A pointer to the second bit mask. + * @param p_mask_out A pointer to the output bit mask. + * @param length Length of output mask in bytes. + */ +__STATIC_INLINE void nrf_bitmask_masks_and(void const * p_mask1, + void const * p_mask2, + void * p_out_mask, + uint32_t length) +{ + uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1; + uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2; + uint8_t * p_mask8_out = (uint8_t *)p_out_mask; + uint32_t i; + for (i = 0; i < length; i++) + { + p_mask8_out[i] = p_mask8_1[i] & p_mask8_2[i]; + } +} + +#ifdef __cplusplus +} +#endif + +#endif //NRF_BITMASK_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_common.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_common.h new file mode 100644 index 0000000000000000000000000000000000000000..54ef51c4f1e2b2755e540a5dce45a25a5970bbab --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_common.h @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @cond */ +/**@file + * + * @ingroup experimental_api + * @defgroup sdk_common SDK Common Header + * @brief All common headers needed for SDK examples will be included here so that application + * developer does not have to include headers on him/herself. + * @{ + */ + +#ifndef SDK_COMMON_H__ +#define SDK_COMMON_H__ + +#include +#include +#include +#include "sdk_config.h" +#include "nordic_common.h" +#include "compiler_abstraction.h" +#include "sdk_os.h" +#include "sdk_errors.h" +#include "app_util.h" +#include "sdk_macros.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @} */ +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +#endif // SDK_COMMON_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_errors.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_errors.h new file mode 100644 index 0000000000000000000000000000000000000000..b669820725ed03fc38bdc417e585595d5d6a5917 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_errors.h @@ -0,0 +1,152 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup sdk_error SDK Error codes + * @{ + * @ingroup app_common + * @{ + * @details Error codes are 32-bit unsigned integers with the most significant 16-bit reserved for + * identifying the module where the error occurred while the least least significant LSB + * are used to provide the cause or nature of error. Each module is assigned a 16-bit + * unsigned integer. Which it will use to identify all errors that occurred in it. 16-bit + * LSB range is with module id as the MSB in the 32-bit error code is reserved for the + * module. As an example, if 0x8800 identifies a certain SDK module, all values from + * 0x88000000 - 0x8800FFFF are reserved for this module. + * It should be noted that common error reasons have been assigned values to make it + * possible to decode error reason easily. As an example, lets module uninitialized has + * been assigned an error code 0x000A0. Then, if application encounters an error code + * 0xZZZZ00A0, it knows that it accessing a certain module without initializing it. + * Apart from this, each module is allowed to define error codes that are not covered by + * the common ones, however, these values are defined in a range that does not conflict + * with common error values. For module, specific error however, it is possible that the + * same error value is used by two different modules to indicated errors of very different + * nature. If error is already defined by the NRF common error codes, these are reused. + * A range is reserved for application as well, it can use this range for defining + * application specific errors. + * + * @note Success code, NRF_SUCCESS, does not include any module identifier. + + */ + +#ifndef SDK_ERRORS_H__ +#define SDK_ERRORS_H__ + +#include +#include "nrf_error.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup sdk_err_base Base defined for SDK Modules + * @{ + */ +#define NRF_ERROR_SDK_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x8000) /**< Base value defined for SDK module identifiers. */ +#define NRF_ERROR_SDK_COMMON_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x0080) /**< Base error value to be used for SDK error values. */ +/** @} */ + +/** + * @defgroup sdk_module_codes Codes reserved as identification for module where the error occurred. + * @{ + */ +#define NRF_ERROR_MEMORY_MANAGER_ERR_BASE (0x8100) +#define NRF_ERROR_PERIPH_DRIVERS_ERR_BASE (0x8200) +#define NRF_ERROR_GAZELLE_ERR_BASE (0x8300) +/** @} */ + + +/** + * @defgroup sdk_iot_errors Codes reserved as identification for IoT errors. + * @{ + */ +#define NRF_ERROR_IOT_ERR_BASE_START (0xA000) +#define NRF_ERROR_IOT_ERR_BASE_STOP (0xAFFF) +/** @} */ + + +/** + * @defgroup sdk_common_errors Codes reserved as identification for common errors. + * @{ + */ +#define NRF_ERROR_MODULE_NOT_INITIALZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0000) +#define NRF_ERROR_MUTEX_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0001) +#define NRF_ERROR_MUTEX_LOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0002) +#define NRF_ERROR_MUTEX_UNLOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0003) +#define NRF_ERROR_MUTEX_COND_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0004) +#define NRF_ERROR_MODULE_ALREADY_INITIALIZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0005) +#define NRF_ERROR_STORAGE_FULL (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0006) +#define NRF_ERROR_API_NOT_IMPLEMENTED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0010) +#define NRF_ERROR_FEATURE_NOT_ENABLED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0011) +/** @} */ + + +/** + * @defgroup drv_specific_errors Error / status codes specific to drivers. + * @{ + */ +#define NRF_ERROR_DRV_TWI_ERR_OVERRUN (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0000) +#define NRF_ERROR_DRV_TWI_ERR_ANACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0001) +#define NRF_ERROR_DRV_TWI_ERR_DNACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0002) +/** @} */ + +/** + * @brief API Result. + * + * @details Indicates success or failure of an API procedure. In case of failure, a comprehensive + * error code indicating cause or reason for failure is provided. + * + * Though called an API result, it could used in Asynchronous notifications callback along + * with asynchronous callback as event result. This mechanism is employed when an event + * marks the end of procedure initiated using API. API result, in this case, will only be + * an indicative of whether the procedure has been requested successfully. + */ +typedef uint32_t ret_code_t; + +/** @} */ +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // SDK_ERRORS_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_macros.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_macros.h new file mode 100644 index 0000000000000000000000000000000000000000..01dcdf5d4c04dab268ba19f0957c2539404da3fc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_macros.h @@ -0,0 +1,191 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + + * @defgroup sdk_common_macros SDK Common Header + * @ingroup app_common + * @brief Macros for parameter checking and similar tasks + * @{ + */ + +#ifndef SDK_MACROS_H__ +#define SDK_MACROS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Macro for verifying statement to be true. It will cause the exterior function to return + * err_code if the statement is not true. + * + * @param[in] statement Statement to test. + * @param[in] err_code Error value to return if test was invalid. + * + * @retval nothing, but will cause the exterior function to return @p err_code if @p statement + * is false. + */ +#define VERIFY_TRUE(statement, err_code) \ +do \ +{ \ + if (!(statement)) \ + { \ + return err_code; \ + } \ +} while (0) + + +/**@brief Macro for verifying statement to be true. It will cause the exterior function to return + * if the statement is not true. + * + * @param[in] statement Statement to test. + */ +#define VERIFY_TRUE_VOID(statement) VERIFY_TRUE((statement), ) + + +/**@brief Macro for verifying statement to be false. It will cause the exterior function to return + * err_code if the statement is not false. + * + * @param[in] statement Statement to test. + * @param[in] err_code Error value to return if test was invalid. + * + * @retval nothing, but will cause the exterior function to return @p err_code if @p statement + * is true. + */ +#define VERIFY_FALSE(statement, err_code) \ +do \ +{ \ + if ((statement)) \ + { \ + return err_code; \ + } \ +} while (0) + + +/**@brief Macro for verifying statement to be false. It will cause the exterior function to return + * if the statement is not false. + * + * @param[in] statement Statement to test. + */ +#define VERIFY_FALSE_VOID(statement) VERIFY_FALSE((statement), ) + + +/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior + * function to return err_code if the err_code is not @ref NRF_SUCCESS. + * + * @param[in] err_code The error code to check. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_SUCCESS() +#else +#define VERIFY_SUCCESS(err_code) VERIFY_TRUE((err_code) == NRF_SUCCESS, (err_code)) +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior + * function to return if the err_code is not @ref NRF_SUCCESS. + * + * @param[in] err_code The error code to check. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_SUCCESS_VOID() +#else +#define VERIFY_SUCCESS_VOID(err_code) VERIFY_TRUE_VOID((err_code) == NRF_SUCCESS) +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to + * return @ref NRF_ERROR_INVALID_STATE if not. + * + * @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED + * should be true if the module is initialized, false if not. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_MODULE_INITIALIZED() +#else +#define VERIFY_MODULE_INITIALIZED() VERIFY_TRUE((MODULE_INITIALIZED), NRF_ERROR_INVALID_STATE) +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to + * return if not. + * + * @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED + * should be true if the module is initialized, false if not. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_MODULE_INITIALIZED_VOID() +#else +#define VERIFY_MODULE_INITIALIZED_VOID() VERIFY_TRUE_VOID((MODULE_INITIALIZED)) +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to + * return if not. + * + * @param[in] param The variable to check if is NULL. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_PARAM_NOT_NULL() +#else +#define VERIFY_PARAM_NOT_NULL(param) VERIFY_FALSE(((param) == NULL), NRF_ERROR_NULL) +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to + * return if not. + * + * @param[in] param The variable to check if is NULL. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_PARAM_NOT_NULL_VOID() +#else +#define VERIFY_PARAM_NOT_NULL_VOID(param) VERIFY_FALSE_VOID(((param) == NULL)) +#endif /* DISABLE_PARAM_CHECK */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // SDK_MACROS_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_mapped_flags.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_mapped_flags.c new file mode 100644 index 0000000000000000000000000000000000000000..123e1610cf4b766844a3d132d2b1aab310208da1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_mapped_flags.c @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_mapped_flags.h" +#include +#include +#include +#include "compiler_abstraction.h" + + +/**@brief Function for setting the state of a flag to true. + * + * @note This function does not check whether the index is valid. + * + * @param[in] p_flags The collection of flags to modify. + * @param[in] index The index of the flag to modify. + */ +static __INLINE void sdk_mapped_flags_set_by_index(sdk_mapped_flags_t * p_flags, uint16_t index) +{ + *p_flags |= (1U << index); +} + + +/**@brief Function for setting the state of a flag to false. + * + * @note This function does not check whether the index is valid. + * + * @param[in] p_flags The collection of flags to modify. + * @param[in] index The index of the flag to modify. + */ +static __INLINE void sdk_mapped_flags_clear_by_index(sdk_mapped_flags_t * p_flags, uint16_t index) +{ + *p_flags &= ~(1U << index); +} + + +/**@brief Function for getting the state of a flag. + * + * @note This function does not check whether the index is valid. + * + * @param[in] p_flags The collection of flags to read. + * @param[in] index The index of the flag to get. + */ +static __INLINE bool sdk_mapped_flags_get_by_index(sdk_mapped_flags_t flags, uint16_t index) +{ + return ((flags & (1 << index)) != 0); +} + + + +uint16_t sdk_mapped_flags_first_key_index_get(sdk_mapped_flags_t flags) +{ + for (uint16_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + { + if (sdk_mapped_flags_get_by_index(flags, i)) + { + return i; + } + } + return SDK_MAPPED_FLAGS_INVALID_INDEX; +} + + +void sdk_mapped_flags_update_by_key(uint16_t * p_keys, + sdk_mapped_flags_t * p_flags, + uint16_t key, + bool value) +{ + sdk_mapped_flags_bulk_update_by_key(p_keys, p_flags, 1, key, value); +} + + +void sdk_mapped_flags_bulk_update_by_key(uint16_t * p_keys, + sdk_mapped_flags_t * p_flags, + uint32_t n_flag_collections, + uint16_t key, + bool value) +{ + if ((p_keys != NULL) && (p_flags != NULL) && (n_flag_collections > 0)) + { + for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + { + if (p_keys[i] == key) + { + for (uint32_t j = 0; j < n_flag_collections; j++) + { + if (value) + { + sdk_mapped_flags_set_by_index(&p_flags[j], i); + } + else + { + sdk_mapped_flags_clear_by_index(&p_flags[j], i); + } + } + return; + } + } + } +} + + +bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key) +{ + if (p_keys != NULL) + { + for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + { + if (p_keys[i] == key) + { + return sdk_mapped_flags_get_by_index(flags, i); + } + } + } + return false; +} + + +sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t * p_keys, + sdk_mapped_flags_t flags) +{ + sdk_mapped_flags_key_list_t key_list; + key_list.len = 0; + + if (p_keys != NULL) + { + for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + { + if (sdk_mapped_flags_get_by_index(flags, i)) + { + key_list.flag_keys[key_list.len++] = p_keys[i]; + } + } + } + + return key_list; +} + + +uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags) +{ + uint32_t n_flags_set = 0; + + for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + { + if (sdk_mapped_flags_get_by_index(flags, i)) + { + n_flags_set += 1; + } + } + return n_flags_set; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_mapped_flags.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_mapped_flags.h new file mode 100644 index 0000000000000000000000000000000000000000..423a78f41697b1f306fd76a71f4199a274fdd290 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_mapped_flags.h @@ -0,0 +1,189 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SDK_MAPPED_FLAGS_H__ +#define SDK_MAPPED_FLAGS_H__ + +#include +#include +#include "app_util.h" +#include "compiler_abstraction.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * @defgroup sdk_mapped_flags Mapped flags + * @ingroup app_common + * @{ + * @brief Module for writing and reading flags that are associated + * with keys. + * + * @details The flags are represented as bits in a bitmap called a flag collection. The keys + * are uint16_t. Each flag collection contains all flags of the same type, one flag for + * each key. + * + * The mapped flags module does not keep the flag states, nor the list of keys. These are + * provided in the API calls. A key's index in the key list determines which bit in the + * flag collection is associated with it. This module does not ever edit the key list, and + * does not edit flags except in function calls that take the flag collection as a pointer. + * + */ + +#define SDK_MAPPED_FLAGS_N_KEYS 32 /**< The number of keys to keep flags for. This is also the number of flags in a flag collection. If changing this value, you might also need change the width of the sdk_mapped_flags_t type. */ +#define SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE 8 /**< The number of flags that fit in one byte. */ +#define SDK_MAPPED_FLAGS_INVALID_INDEX 0xFFFF /**< A flag index guaranteed to be invalid. */ + +typedef uint32_t sdk_mapped_flags_t; /**< The bitmap to hold flags. Each flag is one bit, and each bit represents the flag state associated with one key. */ + + +// Test whether the flag collection type is large enough to hold all the flags. If this fails, +// reduce SDK_MAPPED_FLAGS_N_KEYS or increase the size of sdk_mapped_flags_t. +STATIC_ASSERT(( + sizeof(sdk_mapped_flags_t) * SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE) >= SDK_MAPPED_FLAGS_N_KEYS); + + +/**@brief Type used to present a subset of the registered keys. + */ +typedef struct +{ + uint32_t len; /**< The length of the list. */ + uint16_t flag_keys[SDK_MAPPED_FLAGS_N_KEYS]; /**< The list of keys. */ +} sdk_mapped_flags_key_list_t; + + +/**@brief Function for getting the first index at which the flag is true in the provided + * collection. + * + * @param[in] flags The flag collection to search for a flag set to true. + * + * @return The first index that has its flag set to true. If none were found, the + * function returns @ref SDK_MAPPED_FLAGS_INVALID_INDEX. + */ +uint16_t sdk_mapped_flags_first_key_index_get(sdk_mapped_flags_t flags); + + +/**@brief Function for updating the state of a flag. + * + * @param[in] p_keys The list of associated keys (assumed to have a length of + * @ref SDK_MAPPED_FLAGS_N_KEYS). + * @param[out] p_flags The flag collection to modify. + * @param[in] key The key to modify the flag of. + * @param[in] value The state to set the flag to. + */ +void sdk_mapped_flags_update_by_key(uint16_t * p_keys, + sdk_mapped_flags_t * p_flags, + uint16_t key, + bool value); + + +/**@brief Function for updating the state of the same flag in multiple flag collections. + * + * @details The key and value are the same for all flag collections in the p_flags array. + * + * @param[in] p_keys The list of associated keys (assumed to have a length of + * @ref SDK_MAPPED_FLAGS_N_KEYS). + * @param[out] p_flags The flag collections to modify. + * @param[out] n_flag_collections The number of flag collections in p_flags. + * @param[in] key The key to modify the flag of. + * @param[in] value The state to set the flag to. + */ +void sdk_mapped_flags_bulk_update_by_key(uint16_t * p_keys, + sdk_mapped_flags_t * p_flags, + uint32_t n_flag_collections, + uint16_t key, + bool value); + + +/**@brief Function for getting the state of a specific flag. + * + * @param[in] p_keys The list of associated keys (assumed to have a length of + * @ref SDK_MAPPED_FLAGS_N_KEYS). + * @param[in] flags The flag collection to read from. + * @param[in] key The key to get the flag for. + * + * @return The state of the flag. + */ +bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key); + + +/**@brief Function for getting a list of all keys that have a specific flag set to true. + * + * @param[in] p_keys The list of associated keys (assumed to have a length of + * @ref SDK_MAPPED_FLAGS_N_KEYS). + * @param[in] flags The flag collection to search. + * + * @return The list of keys. + */ +sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t * p_keys, + sdk_mapped_flags_t flags); + + +/**@brief Function for getting the number of keys that have a specific flag set to true. + * + * @param[in] flags The flag collection to search. + * + * @return The number of keys. + */ +uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags); + + +/**@brief Function for querying whether any flags in the collection are set. + * + * @param[in] flags The flag collection to query. + * + * @retval true If one or more flags are set to true. + * @retval false Otherwise. + */ +static __INLINE bool sdk_mapped_flags_any_set(sdk_mapped_flags_t flags) +{ + return (flags != 0); +} + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* SDK_MAPPED_FLAGS_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_os.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_os.h new file mode 100644 index 0000000000000000000000000000000000000000..c1660070b95b166586af09f523055061f5868631 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_os.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @cond */ +/**@file + * + * @defgroup sdk_os SDK OS Abstraction + * @ingroup experimental_api + * @details In order to made SDK modules independent of use of an embedded OS, and permit + * application with varied task architecture, SDK abstracts the OS specific + * elements here in order to make all other modules agnostic to the OS or task + * architecture. + * @{ + */ + +#ifndef SDK_OS_H__ +#define SDK_OS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SDK_MUTEX_DEFINE(X) +#define SDK_MUTEX_INIT(X) +#define SDK_MUTEX_LOCK(X) +#define SDK_MUTEX_UNLOCK(X) + +/** + * @defgroup os_data_type Data types. + */ + +/** @} */ +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +#endif // SDK_OS_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_resources.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_resources.h new file mode 100644 index 0000000000000000000000000000000000000000..91d2af1294c0254807d762e17863384957b08b08 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/libraries/util/sdk_resources.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * @brief Definition file for resource usage by SoftDevice, ESB and Gazell. + */ + +#ifndef APP_RESOURCES_H__ +#define APP_RESOURCES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SOFTDEVICE_PRESENT + #include "nrf_sd_def.h" +#else + #define SD_PPI_RESTRICTED 0uL /**< 1 if PPI peripheral is restricted, 0 otherwise. */ + #define SD_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */ + #define SD_PPI_GROUPS_USED 0uL /**< PPI groups utilized by SotfDevice (not available to th spplication). */ + #define SD_TIMERS_USED 0uL /**< Timers used by SoftDevice. */ + #define SD_SWI_USED 0uL /**< Software interrupts used by SoftDevice. */ +#endif + +#ifdef GAZELL_PRESENT + #include "nrf_gzll_resources.h" +#else + #define GZLL_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by Gazell (not available to th spplication). */ + #define GZLL_TIMERS_USED 0uL /**< Timers used by Gazell. */ + #define GZLL_SWI_USED 0uL /**< Software interrupts used by Gazell */ +#endif + +#ifdef ESB_PRESENT + #include "nrf_esb_resources.h" +#else + #define ESB_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by ESB (not available to th spplication). */ + #define ESB_TIMERS_USED 0uL /**< Timers used by ESB. */ + #define ESB_SWI_USED 0uL /**< Software interrupts used by ESB */ +#endif + +#define NRF_PPI_CHANNELS_USED (SD_PPI_CHANNELS_USED | GZLL_PPI_CHANNELS_USED | ESB_PPI_CHANNELS_USED) +#define NRF_PPI_GROUPS_USED (SD_PPI_GROUPS_USED) +#define NRF_SWI_USED (SD_SWI_USED | GZLL_SWI_USED | ESB_SWI_USED) +#define NRF_TIMERS_USED (SD_TIMERS_USED | GZLL_TIMERS_USED | ESB_TIMERS_USED) + +#ifdef __cplusplus +} +#endif + +#endif // APP_RESOURCES_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.c new file mode 100644 index 0000000000000000000000000000000000000000..0ae94cb6d3558312284c78ed1fe3c41edce93f2a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.c @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nfc_ac_rec_parser.h" +#include "sdk_macros.h" + +/** + * @brief Function for parsing Data Reference field inside Alternative Carrier record payload. + * + * This function parses Data Reference field inside Alternative Carrier record payload and extracts + * its descriptor. + * + * @param[in,out] pp_buff Pointer to pointer to the remaining payload data. + * @param[in,out] p_len Pointer to the length of remaining payload data. + * @param[in,out] p_ref_field Pointer to the structure that will be used to hold + * parsed data. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NULL If provided buffer for Data Reference in \p p_ref_field is + * null. + * @retval NRF_ERROR_NO_MEM If the buffer provided for Data Reference in \p p_ref_field + * does not have enough space to store it. + * @retval NRF_ERROR_INVALID_LENGTH If Data Reference length exceeds record payload. + */ +static ret_code_t ac_rec_reference_field_parse(uint8_t ** const pp_buff, + uint32_t * const p_len, + nfc_ac_rec_data_ref_t * const p_ref_field) +{ + if (p_ref_field->length < **pp_buff) + { + return NRF_ERROR_NO_MEM; + } + p_ref_field->length = **pp_buff; + *pp_buff += AC_REC_DATA_REF_LEN_SIZE; + (*p_len) -= AC_REC_DATA_REF_LEN_SIZE; + + if (*p_len < p_ref_field->length) + { + return NRF_ERROR_INVALID_LENGTH; + } + VERIFY_PARAM_NOT_NULL(p_ref_field->p_data); + memcpy( p_ref_field->p_data, + *pp_buff, + p_ref_field->length ); + *pp_buff += p_ref_field->length; + (*p_len) -= p_ref_field->length; + + return NRF_SUCCESS; +} + +/** + * @brief Function for parsing Alternative Carrier record payload. + * + * This function parses Alternative Carrier record payload and extracts its payload descriptor. + * + * @param[in] p_buff Pointer to the record payload. + * @param[in] p_len Pointer to the record payload length. + * @param[in,out] p_ac_rec_payload_data Pointer to the structure that will be used to hold + * parsed data. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NULL If any provided arguments or any needed buffers stored in + * \p p_ac_rec_payload_data are nulls. + * @retval NRF_ERROR_NO_MEM If any from provided buffers does not have enough space + * to store its data. + * @retval NRF_ERROR_INVALID_LENGTH If any length field exceeds record payload. + * @retval NRF_ERROR_INVALID_PARAM If Carrier Power State field has incorrect value. + */ +static ret_code_t nfc_ac_payload_parse(uint8_t * p_buff, + uint32_t * const p_len, + nfc_ac_rec_payload_desc_t * const p_ac_rec_payload_data) +{ + if ( (p_buff == NULL) || (p_len == NULL) || (p_ac_rec_payload_data == NULL) ) + { + return NRF_ERROR_NULL; + } + + if (*p_len < AC_REC_CPS_BYTE_SIZE + AC_REC_DATA_REF_LEN_SIZE + AC_REC_AUX_DATA_REF_COUNT_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Copy CPS to ac record payload descriptor. + if (*p_buff & ~NFC_AC_CPS_MASK) + { + return NRF_ERROR_INVALID_PARAM; + } + + p_ac_rec_payload_data->cps = (nfc_ac_rec_cps_t) *p_buff; + p_buff += AC_REC_CPS_BYTE_SIZE; + (*p_len) -= AC_REC_CPS_BYTE_SIZE; + + // Copy Carrier Data Reference to ac record payload descriptor. + ret_code_t err_code = ac_rec_reference_field_parse(&p_buff, + p_len, + &p_ac_rec_payload_data->carrier_data_ref); + VERIFY_SUCCESS(err_code); + + // Copy Auxiliary Data Reference to ac record payload descriptor. + if ( p_ac_rec_payload_data->aux_data_ref_count < *p_buff) + { + return NRF_ERROR_NO_MEM; + } + p_ac_rec_payload_data->aux_data_ref_count = *p_buff; + p_buff += AC_REC_AUX_DATA_REF_COUNT_SIZE; + (*p_len) -= AC_REC_AUX_DATA_REF_COUNT_SIZE; + + if (p_ac_rec_payload_data->aux_data_ref_count != 0) + { + VERIFY_PARAM_NOT_NULL(p_ac_rec_payload_data->p_aux_data_ref); + } + + for (uint8_t i = 0; i < p_ac_rec_payload_data->aux_data_ref_count; i++) + { + err_code = ac_rec_reference_field_parse(&p_buff, + p_len, + &(p_ac_rec_payload_data->p_aux_data_ref[i])); + VERIFY_SUCCESS(err_code); + } + + // Check if all payload data were parsed. + if (*p_len != 0) + { + return NRF_ERROR_INVALID_LENGTH; + } + + return NRF_SUCCESS; +} + +ret_code_t nfc_ac_rec_parse(nfc_ndef_record_desc_t const * const p_rec_desc, + nfc_ac_rec_payload_desc_t * const p_ac_rec_payload_data) +{ + ret_code_t err_code; + + if (p_rec_desc->tnf != TNF_WELL_KNOWN) + { + return NRF_ERROR_INVALID_DATA; + } + + if (p_rec_desc->type_length != sizeof(nfc_ac_rec_type_field)) + { + return NRF_ERROR_INVALID_DATA; + } + + if (memcmp(p_rec_desc->p_type, nfc_ac_rec_type_field, sizeof(nfc_ac_rec_type_field)) != 0) + { + return NRF_ERROR_INVALID_DATA; + } + + if (p_rec_desc->payload_constructor != (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint8_t const * p_payload = + ((nfc_ndef_bin_payload_desc_t *)(p_rec_desc->p_payload_descriptor))->p_payload; + uint32_t payload_length = + ((nfc_ndef_bin_payload_desc_t *)(p_rec_desc->p_payload_descriptor))->payload_length; + + err_code = nfc_ac_payload_parse((uint8_t *) p_payload, + &payload_length, + p_ac_rec_payload_data); + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..a92c119db375a3408b5b0a8d9f03509617980802 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.h @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup nfc_ac_rec_parser Alternative Carrier records parser + * @{ + * @ingroup nfc_ble_pair_msg + * @brief Functions for parsing and decoding Alternative Carrier records. + */ + +#ifndef __NFC_AC_REC_PARSER_H__ +#define __NFC_AC_REC_PARSER_H__ + +#include "nfc_ndef_record.h" +#include "nfc_ac_rec.h" + +/** + * @brief Function for parsing general record description as Alternative Carrier record. + * + * This function checks if record description matches the Alternative Carrier record and extracts + * its payload structure. It is required for the record description to use binary payload + * descriptor. + * + * @param[in] p_rec_desc Pointer to the record descriptor. + * @param[in,out] p_ac_rec_payload_data Pointer to the structure that will be used to hold + * parsed data. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_DATA If the NDEF record type or TNF is incorrect. + * @retval NRF_ERROR_NOT_SUPPORTED If the payload descriptor is not binary. + * @retval NRF_ERROR_NULL If any provided arguments or any needed buffers stored in + * \p p_ac_rec_payload_data are nulls. + * @retval NRF_ERROR_NO_MEM If any from provided buffers does not have enough space + * to store its data. + * @retval NRF_ERROR_INVALID_LENGTH If any length field exceeds record payload. + * @retval NRF_ERROR_INVALID_PARAM If Carrier Power State field has incorrect value. + */ +ret_code_t nfc_ac_rec_parse(nfc_ndef_record_desc_t const * const p_rec_desc, + nfc_ac_rec_payload_desc_t * const p_ac_rec_payload_data); + +#endif // __NFC_AC_REC_PARSER_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.c new file mode 100644 index 0000000000000000000000000000000000000000..da5d938cc0be33b44d5ea7ef76b1dad4e6aba890 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.c @@ -0,0 +1,548 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nfc_ble_oob_advdata_parser.h" +#include "app_util.h" +#include "sdk_common.h" +#include "nrf_log.h" + +#define BLE_GAP_AD_TYPE_LESC_CONFIRM_VALUE 0x22 +#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 + +#define EARLY_TERMINATOR 0 /* Value of AD Structure Length field indicating an early + termination of Advertising or Scan Response Data. */ +#define FIELD_LEN_INC_VAL 1 /* Incorrect Value of AD Structure Length field. */ + +/** @brief Values used with @ref ad_type_counter_t. */ +typedef enum +{ + AD_TYPE_NOT_PRESENT = 0, /* Value indicating that AD type is not present. */ + AD_TYPE_OCCUR_THRES = 1 /* Maximal occurance number of any AD type within the buffer */ +} ad_type_counter_values_t; + +/**@brief Internal module structure indicating how many BLE AD fields of the same type are in the buffer. */ +typedef struct +{ + uint8_t name_type; /* Number of Short and Full Device Name AD Structures. */ + uint8_t addr_type; /* Number of LE Bluetooth Device Address AD Structures. */ + uint8_t appear_type; /* Number of Appearance AD Structures. */ + uint8_t flags_type; /* Number of Flags AD Structures. */ + uint8_t le_role_type; /* Number of LE Role AD Structures. */ + uint8_t tk_type; /* Number of Security Manager TK AD Structures. */ + uint8_t sec_mgr_oob_flags_type; /* Number of Security Manager OOB Flags AD Structures. */ + uint8_t lesc_confirm_type; /* Number of LESC OOB Confirmation Value AD Structures. */ + uint8_t lesc_random_type; /* Number of LESC OOB Random Value AD Structures. */ +} ad_type_counter_t; + +/**@brief Decodes and stores AD Data from Flags AD Structure. */ +__STATIC_INLINE ret_code_t flags_decode(uint8_t const * p_flags_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_FLAGS_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_nfc_ble_pairing_data->flags = *p_flags_data; + + return NRF_SUCCESS; +} + +void nfc_oob_data_printout(nfc_ble_oob_pairing_data_t const * const p_pairing_data) +{ + NRF_LOG_RAW_INFO("\r\n"); + NRF_LOG_INFO("BLE Advertising data contents\r\n"); + NRF_LOG_INFO("Device name: %s\r\n", nrf_log_push((char *)p_pairing_data->device_name.p_name)); + NRF_LOG_INFO("Device Address: "); + + for (int i=0; i < BLE_GAP_ADDR_LEN; ++i) + { + NRF_LOG_RAW_INFO("%02X ", p_pairing_data->p_device_addr->addr[i]); + } + NRF_LOG_RAW_INFO("\r\n"); + + if(p_pairing_data->p_tk_value != NULL) + { + NRF_LOG_INFO("Device Temporary Key: "); + for(int i=0; i < BLE_GAP_SEC_KEY_LEN; ++i) + { + NRF_LOG_RAW_INFO("%02X ", p_pairing_data->p_tk_value->tk[i]); + } + NRF_LOG_RAW_INFO("\r\n"); + } + else + { + NRF_LOG_INFO("Device Temporary Key not present.\r\n"); + } + + if(p_pairing_data->p_lesc_confirm_value != NULL && p_pairing_data->p_lesc_random_value) + { + NRF_LOG_INFO("LESC Confirmation Value: "); + for(int i=0; i < BLE_GAP_SEC_KEY_LEN; ++i) + { + NRF_LOG_RAW_INFO("%02X ", p_pairing_data->p_lesc_confirm_value[i]); + } + NRF_LOG_RAW_INFO("\r\n"); + + NRF_LOG_INFO("LESC Random Value: "); + for(int i=0; i < BLE_GAP_SEC_KEY_LEN; ++i) + { + NRF_LOG_RAW_INFO("%02X ", p_pairing_data->p_lesc_random_value[i]); + } + NRF_LOG_RAW_INFO("\r\n"); + } + else + { + NRF_LOG_INFO("LESC data not present.\r\n"); + } + + NRF_LOG_RAW_INFO("\r\n"); +} + +/**@brief Decodes and stores AD Data that is common for Short and Full Device Name AD Structures. */ +static ret_code_t name_decode(uint8_t const * p_name_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + uint8_t * p_name = p_nfc_ble_pairing_data->device_name.p_name; + uint8_t * p_name_len = &p_nfc_ble_pairing_data->device_name.len; + + VERIFY_PARAM_NOT_NULL(p_name); + if (*p_name_len < len) + { + return NRF_ERROR_NO_MEM; + } + + memcpy(p_name, p_name_data, len); + *p_name_len = len; + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from Short Device Name AD Structure. */ +__STATIC_INLINE ret_code_t short_name_decode(uint8_t const * p_short_name_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + p_nfc_ble_pairing_data->device_name.name_type = BLE_ADVDATA_SHORT_NAME; + + return name_decode(p_short_name_data, len, p_nfc_ble_pairing_data); +} + +/**@brief Decodes and stores AD Data from Full Device Name AD Structure. */ +__STATIC_INLINE ret_code_t full_name_decode(uint8_t const * p_full_name_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + p_nfc_ble_pairing_data->device_name.name_type = BLE_ADVDATA_FULL_NAME; + + return name_decode(p_full_name_data, len, p_nfc_ble_pairing_data); +} + +/**@brief Decodes and stores AD Data from Security Manager TK AD Structure. */ +static ret_code_t tk_value_decode(uint8_t const * p_tk_value_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_TK_VALUE_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + ble_advdata_tk_value_t * p_tk_value = p_nfc_ble_pairing_data->p_tk_value; + VERIFY_PARAM_NOT_NULL(p_tk_value); + + memcpy(p_tk_value->tk, p_tk_value_data, AD_TYPE_TK_VALUE_DATA_SIZE); + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from Security Manager TK AD Structure. */ +static ret_code_t lesc_confirm_value_decode(uint8_t const * p_lesc_confirm_value_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_CONFIRM_VALUE_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + uint8_t * p_lesc_confirm_data = p_nfc_ble_pairing_data->p_lesc_confirm_value; + VERIFY_PARAM_NOT_NULL(p_lesc_confirm_data); + + memcpy(p_lesc_confirm_data, p_lesc_confirm_value_data, AD_TYPE_CONFIRM_VALUE_DATA_SIZE); + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from Security Manager TK AD Structure. */ +static ret_code_t lesc_random_value_decode(uint8_t const * p_lesc_random_value_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_RANDOM_VALUE_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + uint8_t * p_lesc_random_data = p_nfc_ble_pairing_data->p_lesc_random_value; + VERIFY_PARAM_NOT_NULL(p_lesc_random_data); + + memcpy(p_lesc_random_data, p_lesc_random_value_data, AD_TYPE_RANDOM_VALUE_DATA_SIZE); + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from Security Manager OOB Flags AD Structure. */ +static ret_code_t sec_mgr_oob_flags_decode(uint8_t const * p_sec_mgr_oob_flags_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_OOB_FLAGS_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + VERIFY_PARAM_NOT_NULL(p_nfc_ble_pairing_data->p_sec_mgr_oob_flags); + *(p_nfc_ble_pairing_data->p_sec_mgr_oob_flags) = *(p_sec_mgr_oob_flags_data); + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from Appearance AD Structure. */ +static ret_code_t appearance_decode(uint8_t const * p_appearance_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_APPEARANCE_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_nfc_ble_pairing_data->appearance = uint16_decode(p_appearance_data); + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from LE Bluetooth Device Address AD Structure. */ +static ret_code_t ble_device_addr_decode(uint8_t const * p_dev_addr_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + ble_gap_addr_t * p_device_addr = p_nfc_ble_pairing_data->p_device_addr; + VERIFY_PARAM_NOT_NULL(p_device_addr); + + memcpy(p_device_addr->addr, p_dev_addr_data, BLE_GAP_ADDR_LEN); + p_device_addr->addr_type = *(p_dev_addr_data + BLE_GAP_ADDR_LEN); + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from LE Role AD Structure. */ +static ret_code_t le_role_decode(uint8_t const * p_le_role_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_LE_ROLE_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + uint8_t le_role = *p_le_role_data; + switch (le_role) + { + case NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_PERIPH: + p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_ONLY_PERIPH; + break; + + case NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_CENTRAL: + p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_ONLY_CENTRAL; + break; + + case NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_PERIPH_PREFERRED: + p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED; + break; + + case NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_CENTRAL_PREFERRED: + p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED; + break; + + default: + return NRF_ERROR_INVALID_PARAM; + } + + return NRF_SUCCESS; +} + +/**@brief Validates if Length field of AD structure is correct. */ +__STATIC_INLINE ret_code_t field_length_validate(uint8_t field_length, uint8_t index, uint8_t len) +{ + if ( (field_length == FIELD_LEN_INC_VAL) || (index + field_length >= len) ) + { + return NRF_ERROR_INVALID_LENGTH; + } + else + { + return NRF_SUCCESS; + } +} + +/**@brief Validates which AD types were not present in parsed data and checks if any + * AD Type occured more than once. + */ +__STATIC_INLINE ret_code_t field_type_validate(nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data, + ad_type_counter_t * ad_type_counter) +{ + /* Reset AD type fields which were not present in parsed buffer. */ + if (ad_type_counter->name_type == AD_TYPE_NOT_PRESENT) + { + p_nfc_ble_pairing_data->device_name.p_name = NULL; + p_nfc_ble_pairing_data->device_name.len = 0; + p_nfc_ble_pairing_data->device_name.name_type = BLE_ADVDATA_NO_NAME; + } + if ( (ad_type_counter->addr_type == AD_TYPE_NOT_PRESENT) && + (p_nfc_ble_pairing_data->p_device_addr != NULL) ) + { + p_nfc_ble_pairing_data->p_device_addr = NULL; + } + if ( (ad_type_counter->tk_type == AD_TYPE_NOT_PRESENT) && + (p_nfc_ble_pairing_data->p_tk_value != NULL) ) + { + p_nfc_ble_pairing_data->p_tk_value = NULL; + } + if ( (ad_type_counter->lesc_confirm_type == AD_TYPE_NOT_PRESENT) && + (p_nfc_ble_pairing_data->p_lesc_confirm_value != NULL) ) + { + p_nfc_ble_pairing_data->p_lesc_confirm_value = NULL; + } + if ( (ad_type_counter->lesc_random_type == AD_TYPE_NOT_PRESENT) && + (p_nfc_ble_pairing_data->p_lesc_random_value != NULL) ) + { + p_nfc_ble_pairing_data->p_lesc_random_value = NULL; + } + if ( (ad_type_counter->sec_mgr_oob_flags_type == AD_TYPE_NOT_PRESENT) && + (p_nfc_ble_pairing_data->p_sec_mgr_oob_flags != NULL) ) + { + p_nfc_ble_pairing_data->p_sec_mgr_oob_flags = NULL; + } + if (ad_type_counter->appear_type == AD_TYPE_NOT_PRESENT) + { + p_nfc_ble_pairing_data->appearance = BLE_ADVDATA_APPEARANCE_NOT_PRESENT; + } + if (ad_type_counter->flags_type == AD_TYPE_NOT_PRESENT) + { + p_nfc_ble_pairing_data->flags = 0; + } + if (ad_type_counter->le_role_type == AD_TYPE_NOT_PRESENT) + { + p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_NOT_PRESENT; + } + + /* Check if any AD Type was doubled. */ + if ( (ad_type_counter->name_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->addr_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->tk_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->sec_mgr_oob_flags_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->appear_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->flags_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->le_role_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->lesc_confirm_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->lesc_random_type > AD_TYPE_OCCUR_THRES) ) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return NRF_SUCCESS; +} + +ret_code_t nfc_ble_oob_advdata_parse(uint8_t const * p_advdata, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + ret_code_t err_code = NRF_SUCCESS; + uint8_t index = 0; + + ad_type_counter_t ad_type_counter; + memset(&ad_type_counter, AD_TYPE_NOT_PRESENT, sizeof(ad_type_counter_t)); + + if ( (p_nfc_ble_pairing_data == NULL) || (p_advdata == NULL) ) + { + return NRF_ERROR_NULL; + } + + while (index < len) + { + uint8_t field_length = p_advdata[index]; + if (field_length == EARLY_TERMINATOR) + { + return NRF_SUCCESS; + } + err_code = field_length_validate(field_length, index, len); + VERIFY_SUCCESS(err_code); + + uint8_t field_type = p_advdata[index + ADV_LENGTH_FIELD_SIZE]; + uint8_t const * p_field_data = &p_advdata[index + ADV_AD_DATA_OFFSET]; + uint8_t field_data_len = field_length - ADV_AD_TYPE_FIELD_SIZE; + + switch (field_type) + { + case BLE_GAP_AD_TYPE_FLAGS: + ++ad_type_counter.flags_type; + err_code = flags_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME: + ++ad_type_counter.name_type; + err_code = short_name_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME: + ++ad_type_counter.name_type; + err_code = full_name_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE: + ++ad_type_counter.tk_type; + err_code = tk_value_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_LESC_CONFIRM_VALUE: + ++ad_type_counter.lesc_confirm_type; + err_code = lesc_confirm_value_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE: + ++ad_type_counter.lesc_random_type; + err_code = lesc_random_value_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS: + ++ad_type_counter.sec_mgr_oob_flags_type; + err_code = sec_mgr_oob_flags_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_APPEARANCE: + ++ad_type_counter.appear_type; + err_code = appearance_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS: + ++ad_type_counter.addr_type; + err_code = ble_device_addr_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_LE_ROLE: + ++ad_type_counter.le_role_type; + err_code = le_role_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + default: + /* AD Structure Type field unknown for parser. */ + return NRF_ERROR_NOT_SUPPORTED; + } + + VERIFY_SUCCESS(err_code); + + index += field_length + ADV_LENGTH_FIELD_SIZE; + } + + err_code = field_type_validate(p_nfc_ble_pairing_data, &ad_type_counter); + return err_code; +} + +ret_code_t nfc_ble_oob_advdata_parser_field_find(uint8_t type, + uint8_t * p_advdata, + uint8_t * p_len, + uint8_t ** pp_field_data) +{ + uint8_t index = 0; + ret_code_t err_code = NRF_SUCCESS; + + if ( (pp_field_data == NULL) || (p_len == NULL) || (p_advdata == NULL) ) + { + return NRF_ERROR_NULL; + } + + while (index < *p_len) + { + uint8_t field_length = p_advdata[index]; + if (field_length == EARLY_TERMINATOR) + { + return NRF_ERROR_NOT_FOUND; + } + err_code = field_length_validate(field_length, index, *p_len); + VERIFY_SUCCESS(err_code); + + uint8_t field_type = p_advdata[index + ADV_LENGTH_FIELD_SIZE]; + if (field_type == type) + { + *pp_field_data = &p_advdata[index + ADV_AD_DATA_OFFSET]; + *p_len = field_length - ADV_AD_TYPE_FIELD_SIZE; + return NRF_SUCCESS; + } + index += field_length + ADV_LENGTH_FIELD_SIZE; + } + return NRF_ERROR_NOT_FOUND; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..0e2062964cc1876550cc7bc91a8e003e1c32dcf2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.h @@ -0,0 +1,152 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup nfc_ble_oob_advdata_parser Advertising and Scan Response Data Parser for NFC OOB pairing + * @{ + * @ingroup nfc_ble_pair_msg + * @brief Functions for parsing and decoding data in the Advertising and Scan Response + * Data format for NFC OOB pairing. + */ + +#ifndef NFC_BLE_OOB_ADVDATA_PARSER_H_ +#define NFC_BLE_OOB_ADVDATA_PARSER_H_ + +#include "nfc_ble_oob_advdata.h" +#include "sdk_errors.h" + +#define BLE_ADVDATA_APPEARANCE_NOT_PRESENT 0 /**< Appearance AD structure not present. */ + +/**@brief Bluetooth Low Energy GAP device name. */ +typedef struct +{ + ble_advdata_name_type_t name_type; /**< See @ref ble_advdata_name_type_t. */ + uint8_t len; /**< Length of device name. */ + uint8_t * p_name; /**< Pointer to the buffer with device name. */ +} ble_gap_dev_name_t; + +/**@brief BLE Advertising data that is relevant for OOB pairing. */ +typedef struct +{ + ble_gap_dev_name_t device_name; /**< See @ref ble_gap_dev_name_t. */ + ble_gap_addr_t * p_device_addr; /**< See @ref ble_gap_addr_t. */ + ble_advdata_tk_value_t * p_tk_value; /**< See @ref ble_advdata_tk_value_t. */ + uint8_t * p_lesc_confirm_value; /**< LESC OOB confirmation data. */ + uint8_t * p_lesc_random_value; /**< LESC OOB random data. */ + ble_advdata_le_role_t le_role; /**< See @ref ble_advdata_le_role_t. */ + uint16_t appearance; /**< Advertising data Appearance field. */ + uint8_t flags; /**< Advertising data Flags field. */ + uint8_t * p_sec_mgr_oob_flags; /**< Security Manager Out Of Band Flags data field. */ +} nfc_ble_oob_pairing_data_t; + +/**@brief Function for parsing BLE data encoded in AD Type format. + * + * @details This function parses BLE data encoded in Advertising Data Type format which + * can be generated with @ref adv_data_encode function. The result of the parsing is + * stored within @ref nfc_ble_oob_pairing_data_t structure. + * + * @note Currently, module can be used to parse BLE AD Type data, which contains + * AD Structures with following GAP AD Types: Flags, Shortened and Complete Device + * Name, Security Manager TK Value and OOB Flags, Appearance, LE Bluetooth Device + * Address and LE Role. + * + * @warning Before passing \p p_nfc_ble_pairing_data structure to this function, + * it is necessary to provide buffers for AD Structures Data, which are expected to be + * found within parsed buffer. This applies to following GAP AD Types with corresponding + * structures: Shortened and Complete Device Name - @ref ble_gap_dev_name_t, + * LE Bluetooth Device Address - @ref ble_gap_addr_t, Security Manager TK Value - + * @ref ble_advdata_tk_value_t and Security Manager OOB Flags - uint8_t. + * + * @param[in] p_advdata Pointer to the data to be parsed. + * @param[in] len Size of the data to be parsed. + * @param[out] p_nfc_ble_pairing_data Pointer to the structure that will be used + * to hold parsed data. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the provided buffer for device name is + * too small to hold parsed data. + * @retval NRF_ERROR_INVALID_LENGTH If any AD Structure Length field contains + * different value than expected. + * @retval NRF_ERROR_INVALID_PARAM If any AD Structure Data field contains + * invalid parameters. + * @retval NRF_ERROR_NULL If any function pointer parameter is NULL or + * any expected buffer in \p p_nfc_ble_pairing_data + * was not provided. + * @retval NRF_ERROR_NOT_SUPPORTED If any AD Structure Type field contains + * type which is not supported or any AD + * Structure Type occurs more than once. + */ +ret_code_t nfc_ble_oob_advdata_parse(uint8_t const * p_advdata, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data); + +/**@brief Function for finding BLE AD Type data within buffer encoded in AD Type format. + * + * @details This function finds BLE AD Type data within buffer encoded in AD Type format + * The AD Data to be found can be specified by its AD Type - \p type. + * + * @param[in] type AD Type of AD Structure to be found + * within \p p_advdata. + * @param[in] p_advdata Pointer to the data to be parsed. + * @param[in,out] p_len As input: size of the data to be parsed. + * As output: size of the AD Data within + * found AD structure. + * @param[out] pp_field_data Pointer to AD Data within found AD Structure. + * + * @retval NRF_SUCCESS If chosen AD Type was found successfully. + * @retval NRF_ERROR_INVALID_LENGTH If any AD Structure Length field value indicates + * that AD Structure exceeds provided buffer. + * @retval NRF_ERROR_NULL If any function pointer parameter is NULL. + * @retval NRF_ERROR_NOT_FOUND If chosen AD Type - \p type was not found. + */ +ret_code_t nfc_ble_oob_advdata_parser_field_find(uint8_t type, + uint8_t * p_advdata, + uint8_t * p_len, + uint8_t ** pp_field_data); + +/**@brief Function for displaying values of basic BLE OOB Advertising data types. + * + * @param[in] p_pairing_data Structure containing parsed data. + */ +void nfc_oob_data_printout(nfc_ble_oob_pairing_data_t const * const p_pairing_data); + +#endif //NFC_BLE_OOB_ADVDATA_PARSER_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.c new file mode 100644 index 0000000000000000000000000000000000000000..74b45cbbaf1b0932d799232055074c984314ed4c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.c @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nfc_le_oob_rec_parser.h" +#include "sdk_errors.h" + +/** + * @brief Function for parsing LE OOB record payload. + * + * This function parses LE OOB record payload and extracts BLE OOB Advertising data structure. + * + * @param[in] p_buff Pointer to the record payload. + * @param[in] p_len Pointer to the record payload length. + * @param[in,out] p_nfc_ble_oob_pairing_data Pointer to the structure that will be used to hold + * parsed data. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval Other An error code that might have been returned by + * @ref nfc_ble_oob_advdata_parse function. + */ +static ret_code_t nfc_le_oob_payload_parse(uint8_t * p_buff, + uint32_t * const p_len, + nfc_ble_oob_pairing_data_t * const p_nfc_ble_oob_pairing_data) +{ + ret_code_t err_code = nfc_ble_oob_advdata_parse(p_buff, + *p_len, + p_nfc_ble_oob_pairing_data); + return err_code; +} + +ret_code_t nfc_le_oob_rec_parse(nfc_ndef_record_desc_t const * const p_rec_desc, + nfc_ble_oob_pairing_data_t * const p_nfc_ble_oob_pairing_data) +{ + ret_code_t err_code; + + if (p_rec_desc->tnf != TNF_MEDIA_TYPE) + { + return NRF_ERROR_INVALID_DATA; + } + + if (p_rec_desc->type_length != sizeof(le_oob_rec_type_field)) + { + return NRF_ERROR_INVALID_DATA; + } + + if (memcmp(p_rec_desc->p_type, le_oob_rec_type_field, sizeof(le_oob_rec_type_field)) != 0) + { + return NRF_ERROR_INVALID_DATA; + } + + if (p_rec_desc->payload_constructor != (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint8_t const * p_payload = ((nfc_ndef_bin_payload_desc_t*)(p_rec_desc->p_payload_descriptor))->p_payload; + uint32_t payload_lenght = ((nfc_ndef_bin_payload_desc_t*)(p_rec_desc->p_payload_descriptor))->payload_length; + + err_code = nfc_le_oob_payload_parse((uint8_t *) p_payload, + &payload_lenght, + p_nfc_ble_oob_pairing_data); + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..188a4072a06275e3fc475ce9c2333a81ff609713 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.h @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup nfc_le_oob_rec_parser LE OOB records parser + * @{ + * @ingroup nfc_ble_pair_msg + * @brief Functions for parsing and decoding LE OOB records. + */ + +#ifndef __NFC_LE_OOB_REC_PARSER_H__ +#define __NFC_LE_OOB_REC_PARSER_H__ + +#include "nfc_ndef_record.h" +#include "nfc_ble_oob_advdata_parser.h" +#include "nfc_ble_pair_common.h" + +/** + * @brief Function for parsing general record description as LE OOB record. + * + * This function checks if record description matches the LE OOB record pattern and extracts BLE + * OOB Advertising data structure. It is required for the record description to use binary payload + * descriptor. + * + * @param[in] p_rec_desc Pointer to the record descriptor. + * @param[in,out] p_nfc_ble_oob_pairing_data Pointer to the structure that will be used to hold + * parsed data. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_DATA If the NDEF record type or TNF is incorrect. + * @retval NRF_ERROR_NOT_SUPPORTED If the payload descriptor is not binary. + * @retval Other An error code that might have been returned by + * @ref nfc_ble_oob_advdata_parse function. + */ +ret_code_t nfc_le_oob_rec_parse(nfc_ndef_record_desc_t const * const p_rec_desc, + nfc_ble_oob_pairing_data_t * const p_nfc_ble_oob_pairing_data); + +#endif // __NFC_LE_OOB_REC_PARSER_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c new file mode 100644 index 0000000000000000000000000000000000000000..4a350bef0437a3706ada997803f258aedc6cd290 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nfc_ac_rec.h" +#include +#include "nrf_error.h" +#include "nrf.h" + +#define AC_REC_CPS_BYTE_SIZE 1 ///< Size of the field with CPS data. +#define AC_REC_DATA_REF_LEN_SIZE 1 ///< Size of the Data Reference Length field. +#define AC_REC_AUX_DATA_REF_COUNT_SIZE 1 ///< Size of the Data Reference Length field. + +const uint8_t nfc_ac_rec_type_field[2] = {'a', 'c'}; ///< Alternative Carrier Record type. + +/** + * @brief Function for calculating the payload length of the NFC NDEF Alternative Carrier record. + */ +static uint32_t nfc_ac_rec_payload_size_get(nfc_ac_rec_payload_desc_t const * p_ac_rec_payload_desc) +{ + int32_t i = 0; + // Initialize with size of byte with CPS. + uint32_t payload_size = AC_REC_CPS_BYTE_SIZE; + + // Add Carrier Data Reference size. + payload_size += p_ac_rec_payload_desc->carrier_data_ref.length + AC_REC_DATA_REF_LEN_SIZE; + + // Add Auxiliary Data Reference Count size. + payload_size += AC_REC_AUX_DATA_REF_COUNT_SIZE; + + for (i = 0; i < p_ac_rec_payload_desc->aux_data_ref_count; i++) + { + // Add Auxiliary Data Reference size. + payload_size += p_ac_rec_payload_desc->p_aux_data_ref[i].length + AC_REC_DATA_REF_LEN_SIZE; + } + + return payload_size; +} + + +ret_code_t nfc_ac_rec_payload_constructor(nfc_ac_rec_payload_desc_t * p_nfc_rec_ac_payload_desc, + uint8_t * p_buff, + uint32_t * p_len) +{ + int32_t i = 0; + uint32_t payload_size = nfc_ac_rec_payload_size_get(p_nfc_rec_ac_payload_desc); + + if (p_buff != NULL) + { + // Not enough space in the buffer, return an error. + if (payload_size > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + // Invalid CPS value. + if ( p_nfc_rec_ac_payload_desc->cps & ~NFC_AC_CPS_MASK ) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Copy CPS. + *p_buff = p_nfc_rec_ac_payload_desc->cps; + p_buff += AC_REC_CPS_BYTE_SIZE; + + // Copy Carrier Data Reference. + *p_buff = p_nfc_rec_ac_payload_desc->carrier_data_ref.length; + p_buff += AC_REC_DATA_REF_LEN_SIZE; + + memcpy( p_buff, + p_nfc_rec_ac_payload_desc->carrier_data_ref.p_data, + p_nfc_rec_ac_payload_desc->carrier_data_ref.length ); + p_buff += p_nfc_rec_ac_payload_desc->carrier_data_ref.length; + + // Copy Auxiliary Data Reference. + *p_buff = p_nfc_rec_ac_payload_desc->aux_data_ref_count; + p_buff += AC_REC_AUX_DATA_REF_COUNT_SIZE; + + for (i = 0; i < p_nfc_rec_ac_payload_desc->aux_data_ref_count; i++) + { + *p_buff = p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].length; + p_buff += AC_REC_DATA_REF_LEN_SIZE; + + memcpy( p_buff, + p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].p_data, + p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].length ); + p_buff += p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].length; + } + } + + // Assign payload size to the return buffer. + *p_len = payload_size; + + return NRF_SUCCESS; +} + + +void nfc_ac_rec_auxiliary_data_ref_clear(nfc_ndef_record_desc_t * p_ac_rec) +{ + nfc_ac_rec_payload_desc_t * p_ac_rec_payload = + (nfc_ac_rec_payload_desc_t*)p_ac_rec->p_payload_descriptor; + + p_ac_rec_payload->aux_data_ref_count = 0; +} + + +ret_code_t nfc_ac_rec_auxiliary_data_ref_add(nfc_ndef_record_desc_t * p_ac_rec, + uint8_t * p_aux_data, + uint8_t aux_length) +{ + nfc_ac_rec_payload_desc_t * p_ac_rec_payload = + (nfc_ac_rec_payload_desc_t *)p_ac_rec->p_payload_descriptor; + + if (p_ac_rec_payload->aux_data_ref_count >= p_ac_rec_payload->max_aux_data_ref) + { + return NRF_ERROR_NO_MEM; + } + + p_ac_rec_payload->p_aux_data_ref[p_ac_rec_payload->aux_data_ref_count].p_data = p_aux_data; + p_ac_rec_payload->p_aux_data_ref[p_ac_rec_payload->aux_data_ref_count].length = aux_length; + p_ac_rec_payload->aux_data_ref_count++; + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h new file mode 100644 index 0000000000000000000000000000000000000000..987274a25eb817de9374089797656ad8825f9802 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h @@ -0,0 +1,195 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_AC_REC_H__ +#define NFC_AC_REC_H__ + +/**@file + * + * @defgroup nfc_ac_rec ac (Alternative carrier) records + * @{ + * @ingroup nfc_ble_pair_msg + * + * @brief Generation of NFC NDEF Alternative Carrier records for NDEF messages. + * + */ + +#include +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AC_REC_CPS_BYTE_SIZE 1 ///< Size of the field with CPS data. +#define AC_REC_DATA_REF_LEN_SIZE 1 ///< Size of the Data Reference Length field. +#define AC_REC_AUX_DATA_REF_COUNT_SIZE 1 ///< Size of the Data Reference Length field. + +/** + * @brief Carrier Power State. + * + * Possible Carrier Power State field values in an Alternative Carrier record. + */ +typedef enum +{ + NFC_AC_CPS_INACTIVE = 0x00, ///< Alternative Carrier inactive. + NFC_AC_CPS_ACTIVE = 0x01, ///< Alternative Carrier active. + NFC_AC_CPS_ACTIVATING = 0x02, ///< Alternative Carrier activating. + NFC_AC_CPS_UNKNOWN = 0x03 ///< Alternative Carrier power status unknown. +} nfc_ac_rec_cps_t; + +#define NFC_AC_CPS_MASK (NFC_AC_CPS_UNKNOWN) ///< Mask of Carrier Power State bits in a first ac record byte. + +/** + * @brief Carrier Data Reference and Auxiliary Data Reference descriptor. + */ +typedef struct +{ + uint8_t length; ///< Length of the data field. + uint8_t * p_data; ///< Pointer to the Data Reference characters. Not relevant if length is 0. +} nfc_ac_rec_data_ref_t; + +/** + * @brief Alternative Carrier record payload descriptor. + */ +typedef struct +{ + nfc_ac_rec_cps_t cps; ///< Carrier Power State value. + nfc_ac_rec_data_ref_t carrier_data_ref; ///< Carrier Data Reference. + uint8_t const max_aux_data_ref; ///< Maximum number of Auxiliary Data Reference fields. + uint8_t aux_data_ref_count; ///< Number of Auxiliary Data Reference fields. + nfc_ac_rec_data_ref_t * p_aux_data_ref; ///< Pointer to the Auxiliary Data Reference fields. +} nfc_ac_rec_payload_desc_t; + + +/** + * @brief Constructor for an NFC NDEF Alternative Carrier record payload. + * + * This function encodes the payload of an Alternative Carrier record as specified in the Connection + * Handover standard. It implements an API compatible with @ref p_payload_constructor_t. + */ +ret_code_t nfc_ac_rec_payload_constructor(nfc_ac_rec_payload_desc_t * p_nfc_rec_ac_payload_desc, + uint8_t * p_buff, + uint32_t * p_len); + +/** + * @brief External reference to the type field of the Alternative Carrier record, defined in the + * file @c nfc_ac_rec.c. It is used in the @ref NFC_NDEF_AC_RECORD_DESC_DEF macro. + */ +extern const uint8_t nfc_ac_rec_type_field[2]; + +/** + * @brief Size of the type field of the Alternative Carrier record, defined in the + * file @c nfc_ac_rec.c. It is used in the @ref NFC_NDEF_AC_RECORD_DESC_DEF macro. + */ +#define NFC_AC_REC_TYPE_LENGTH 2 + +/** + *@brief Macro for creating and initializing an NFC NDEF record descriptor for an Alternative Carrier record. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t and + * a static instance of type @ref nfc_ac_rec_payload_desc_t, which together constitute an instance of an Alternative Carrier record. + * + * Use the macro @ref NFC_NDEF_AC_RECORD_DESC to access the NDEF Alternative Carrier record descriptor instance. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] CPS Carrier Power State value. + * @param[in] CARR_DATA_REF_LEN Length of the Carrier Data Reference field. + * @param[in] P_CARR_DATA_REF Pointer to the Carrier Data Reference field. + * @param[in] MAX_AUX_DATA_REF Maximum number of Auxiliary Data Reference fields. + */ +#define NFC_NDEF_AC_RECORD_DESC_DEF(NAME, \ + CPS, \ + CARR_DATA_REF_LEN, \ + P_CARR_DATA_REF, \ + MAX_AUX_DATA_REF) \ + static nfc_ac_rec_data_ref_t NAME##_nfc_ac_rec_aux_data_ref_array[MAX_AUX_DATA_REF]; \ + static nfc_ac_rec_payload_desc_t NAME##_nfc_ac_rec_payload_desc = \ + { \ + .cps = CPS, \ + .carrier_data_ref = {CARR_DATA_REF_LEN, P_CARR_DATA_REF}, \ + .max_aux_data_ref = MAX_AUX_DATA_REF, \ + .aux_data_ref_count = 0, \ + .p_aux_data_ref = NAME##_nfc_ac_rec_aux_data_ref_array \ + }; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF_WELL_KNOWN, \ + 0, \ + 0, \ + nfc_ac_rec_type_field, \ + NFC_AC_REC_TYPE_LENGTH, \ + nfc_ac_rec_payload_constructor, \ + &(NAME##_nfc_ac_rec_payload_desc)) + +/** + * @brief Macro for accessing the NFC NDEF Alternative Carrier record descriptor + * instance that was created with @ref NFC_NDEF_AC_RECORD_DESC_DEF. + */ +#define NFC_NDEF_AC_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** + * @brief Function for clearing an Auxiliary Data Reference in an NFC NDEF Alternative Carrier record. + * + * This function clears the Auxiliary Data References from the Alternative Carrier record. + * + * @param[in, out] p_ac_rec Pointer to the Alternative Carrier record descriptor. + */ +void nfc_ac_rec_auxiliary_data_ref_clear(nfc_ndef_record_desc_t * p_ac_rec); + +/** + * @brief Function for adding an Auxiliary Data Reference to an NFC NDEF Alternative Carrier record. + * + * @param[in, out] p_ac_rec Pointer to an ac record. + * @param[in] p_aux_data Pointer to the Auxiliary Data Reference data buffer. + * @param[in] aux_length Length of the Auxiliary Data Reference data. + * + * @retval NRF_SUCCESS If the Auxiliary Data Reference was added successfully. + * @retval NRF_ERROR_NO_MEM If the record already contains the maximum number of Auxiliary Data References. + */ +ret_code_t nfc_ac_rec_auxiliary_data_ref_add(nfc_ndef_record_desc_t * p_ac_rec, + uint8_t * p_aux_data, + uint8_t aux_length); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_AC_REC_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c new file mode 100644 index 0000000000000000000000000000000000000000..27b352d21257c82622adc66a412cd6fdf3556a84 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c @@ -0,0 +1,392 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nfc_ble_oob_advdata.h" +#include "sdk_common.h" +#include "nfc_ble_pair_msg.h" + +// LESC OOB data AD_TYPE values. +#define BLE_GAP_AD_TYPE_LESC_CONFIRM_VALUE 0x22 +#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 + +/** + * @brief Macro for verifying basic parameters used for encoding single BLE AD Type. + * + * It verifies if provided buffer is NULL and if there is enough space for the encoded data. + * In case of NULL pointer buffer, necessary space for current AD Type is calculated. + * + * @param[in] P_ENCODED_DATA Buffer for the encoded data. + * @param[in] P_OFFSET Pointer to index of the first free cell in the buffer. + * @param[in] AD_TYPE_SIZE Size of the single AD Type. + * @param[in] MAX_SIZE Maximal size of the provided buffer. + */ +#define NFC_BLE_OOB_ADVDATA_INPUT_VERIFY( P_ENCODED_DATA, P_OFFSET, AD_TYPE_SIZE, MAX_SIZE) \ + if ( (P_ENCODED_DATA) == NULL ) \ + { \ + *(P_OFFSET) += (AD_TYPE_SIZE); \ + return NRF_SUCCESS; \ + } \ + if ( *(P_OFFSET) + (AD_TYPE_SIZE) > (MAX_SIZE) ) \ + { \ + return NRF_ERROR_DATA_SIZE; \ + } + +/**@brief Function for encoding data of Security Manager OOB Flags AD Type. + * + * @param[in] oob_flags Security Manager OOB Flags AD Type payload. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding. + * \c out: Offset of \p p_encoded_data buffer after this AD type encoding. + * @param[in] max_size Size of \p p_encoded_data buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small. + */ +static ret_code_t sec_mgr_oob_flags_encode(uint8_t oob_flags, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_OOB_FLAGS_SIZE, max_size); + + // Encode flags. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_OOB_FLAGS_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + p_encoded_data[*p_offset] = oob_flags; + *p_offset += AD_TYPE_OOB_FLAGS_DATA_SIZE; + + return NRF_SUCCESS; +} + +/**@brief Function for encoding data of Security Manager TK Value AD Type. + * + * @param[in] p_tk_value Security Manager TK Value AD Type payload. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding. + * \c out: Offset of \p p_encoded_data buffer after this AD type encoding. + * @param[in] max_size Size of \p p_encoded_data buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small. + */ +static ret_code_t tk_value_encode(ble_advdata_tk_value_t * p_tk_value, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + ret_code_t err_code; + + NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_TK_VALUE_SIZE, max_size); + + // Encode TK Value. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_TK_VALUE_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + + // Remember location of TK in the buffer if this feature was enabled. + err_code = nfc_tk_to_group_add(&p_encoded_data[*p_offset]); + VERIFY_SUCCESS(err_code); + + nfc_tk_value_payload_encode(p_tk_value, &p_encoded_data[*p_offset]); + (*p_offset) += AD_TYPE_TK_VALUE_DATA_SIZE; + + return NRF_SUCCESS; +} + +/**@brief Function for encoding LESC OOB data in the CH NDEF message. + * + * @param[in] p_lesc_value Pointer to the LESC OOB values to be encoded. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding. + * \c out: Offset of \p p_encoded_data buffer after this AD type encoding. + * @param[in] max_size Size of \p p_encoded_data buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small. + */ +static ret_code_t lesc_value_encode(ble_gap_lesc_oob_data_t * p_lesc_value, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + ret_code_t err_code; + + NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_LESC_SIZE, max_size); + + // Encode LESC Confirm Value. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_CONFIRM_VALUE_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LESC_CONFIRM_VALUE; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + + memcpy(&p_encoded_data[*p_offset], p_lesc_value->c, sizeof(p_lesc_value->c)); + + uint8_t *p_confirm = &p_encoded_data[*p_offset]; + + (*p_offset) += AD_TYPE_CONFIRM_VALUE_DATA_SIZE; + + // Encode LESC Random Value. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_RANDOM_VALUE_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + + memcpy(&p_encoded_data[*p_offset], p_lesc_value->r, sizeof(p_lesc_value->r)); + + uint8_t *p_random = &p_encoded_data[*p_offset]; + + (*p_offset) += AD_TYPE_RANDOM_VALUE_DATA_SIZE; + + // Remember location of LESC OOB data in the buffer in case of key changes. + err_code = nfc_lesc_pos_set(p_confirm, p_random); + + return err_code; +} + +/**@brief Function for encoding data of LE Role AD Type. + * + * @param[in] le_role LE Role AD Type payload. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding. + * \c out: Offset of \p p_encoded_data buffer after this AD type encoding. + * @param[in] max_size Size of \p p_encoded_data buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small. + * @retval NRF_ERROR_INVALID_PARAM If \p le_role parameter has invalid value. + */ +static ret_code_t le_role_encode(ble_advdata_le_role_t le_role, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_LE_ROLE_SIZE, max_size); + + // Encode LE Role. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_LE_ROLE_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_ROLE; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + switch (le_role) + { + case BLE_ADVDATA_ROLE_ONLY_PERIPH: + p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_PERIPH; + break; + case BLE_ADVDATA_ROLE_ONLY_CENTRAL: + p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_CENTRAL; + break; + case BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED: + p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_PERIPH_PREFERRED; + break; + case BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED: + p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_CENTRAL_PREFERRED; + break; + default: + return NRF_ERROR_INVALID_PARAM; + } + *p_offset += AD_TYPE_LE_ROLE_DATA_SIZE; + + return NRF_SUCCESS; +} + +/**@brief Function for calculating the size of Local Name AD Type. + * + * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data. + * @param[out] p_len Size of the buffer that is necessary to encode Local Name AD Type. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval Other Other error codes might be returned depending on + * @ref sd_ble_gap_device_name_get function. + */ +__STATIC_INLINE ret_code_t nfc_ble_oob_name_size_calc(ble_advdata_t const * const p_advdata, + uint16_t * const p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + uint16_t device_len; + + if (p_advdata->name_type == BLE_ADVDATA_SHORT_NAME) + { + device_len = p_advdata->short_name_len; + } + else + { + err_code = sd_ble_gap_device_name_get(NULL, &device_len); + } + + *p_len += ADV_LENGTH_FIELD_SIZE + ADV_AD_TYPE_FIELD_SIZE + device_len; + return err_code; +} + +/**@brief Function for calculating the size of AD Types which are encoded by @ref adv_data_encode function. + * + * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data. + * @param[out] p_len Size of the buffer that is necessary to encode AD Types. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval Other Other error codes might be returned depending on + * @ref nfc_ble_oob_name_size_calc function. + */ +static ret_code_t nfc_ble_oob_adv_data_size_calc(ble_advdata_t const * const p_advdata, + uint16_t * const p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (p_advdata->include_ble_device_addr) + { + *p_len += AD_TYPE_BLE_DEVICE_ADDR_SIZE; + } + if (p_advdata->include_appearance) + { + *p_len += AD_TYPE_APPEARANCE_SIZE; + } + if (p_advdata->flags != 0) + { + *p_len += AD_TYPE_FLAGS_SIZE; + } + if (p_advdata->name_type != BLE_ADVDATA_NO_NAME) + { + err_code = nfc_ble_oob_name_size_calc(p_advdata, p_len); + } + return err_code; +} + +/**@brief Function for verifying if BLE advertising data structure contains only supported AD Types + * by this encoding module. + * + * @param[in] advdata Structure with BLE advertising data. + * + * @retval NRF_SUCCESS If the verification was successful. + * @retval NRF_ERROR_INVALID_PARAM If there is any AD type which is not supported by this + * module. + */ +static ret_code_t nfc_ble_oob_adv_data_check(ble_advdata_t advdata) +{ + advdata.p_sec_mgr_oob_flags = NULL; + advdata.p_tk_value = NULL; + advdata.le_role = BLE_ADVDATA_ROLE_NOT_PRESENT; + advdata.include_ble_device_addr = false; + advdata.include_appearance = false; + advdata.flags = 0; + advdata.name_type = BLE_ADVDATA_NO_NAME; + advdata.short_name_len = 0; + advdata.p_lesc_data = NULL; + + ble_advdata_t pattern_advdata; + memset(&pattern_advdata, 0, sizeof(ble_advdata_t)); + + if ( memcmp( &pattern_advdata, &advdata, sizeof(ble_advdata_t)) == 0 ) + { + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INVALID_PARAM; + } +} + +ret_code_t nfc_ble_oob_adv_data_encode(ble_advdata_t const * const p_advdata, + uint8_t * const p_encoded_data, + uint16_t * const p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + uint16_t max_size = *p_len; + uint16_t offset = 0; + + // Verify ADV data structure. + err_code = nfc_ble_oob_adv_data_check(*p_advdata); + VERIFY_SUCCESS(err_code); + + // Encode Security Manager OOB Flags. + if (p_advdata->p_sec_mgr_oob_flags != NULL) + { + err_code = sec_mgr_oob_flags_encode(*p_advdata->p_sec_mgr_oob_flags, + p_encoded_data, + &offset, + max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode LESC keys + if (p_advdata->p_lesc_data != NULL) + { + err_code = lesc_value_encode(p_advdata->p_lesc_data, p_encoded_data, &offset, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode Security Manager TK value. + if (p_advdata->p_tk_value != NULL) + { + err_code = tk_value_encode(p_advdata->p_tk_value, p_encoded_data, &offset, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode LE Role. + if (BLE_ADVDATA_ROLE_NOT_PRESENT != p_advdata->le_role) + { + err_code = le_role_encode(p_advdata->le_role, p_encoded_data, &offset, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode remaining AD Types or precalculate necessary buffer space. + if (p_encoded_data != NULL) + { + uint16_t adv_data_size = max_size - offset; + err_code = adv_data_encode(p_advdata, p_encoded_data + offset, &adv_data_size); + *p_len = offset + adv_data_size; + } + else + { + err_code = nfc_ble_oob_adv_data_size_calc(p_advdata, &offset); + *p_len = offset; + } + + return err_code; +} + +void nfc_tk_value_payload_encode(ble_advdata_tk_value_t * p_tk_value, + uint8_t * p_tk_payload_data) +{ + for (uint8_t i = 0; i < AD_TYPE_TK_VALUE_DATA_SIZE; i++) + { + *(p_tk_payload_data++) = p_tk_value->tk[i]; + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h new file mode 100644 index 0000000000000000000000000000000000000000..823e47b9964dd65187e9643930415f1a21beaf3b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup nfc_ble_oob_advdata Advertising and Scan Response Data Encoder for NFC OOB pairing + * @{ + * @ingroup nfc_ble_pair_msg + * @brief Function for encoding data in the Advertising and Scan Response Data format, which + * can be used to create payload of NFC message intended for initiating the Out-of-Band + * pairing. + */ + +#ifndef NFC_BLE_OOB_ADVDATA_H__ +#define NFC_BLE_OOB_ADVDATA_H__ + +#include +#include "ble_advdata.h" +#include "app_util.h" +#include "sdk_errors.h" + + +#define AD_TYPE_LE_ROLE_DATA_SIZE 1UL /**< Data size (in octets) of the LE Bluetooth Device Address AD type. */ +#define AD_TYPE_LE_ROLE_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_LE_ROLE_DATA_SIZE) /**< Size (in octets) of the LE Bluetooth Device Address AD type. */ +#define AD_TYPE_TK_VALUE_DATA_SIZE (sizeof(ble_advdata_tk_value_t)) /**< Data size (in octets) of the Security Manager TK value AD type. */ +#define AD_TYPE_TK_VALUE_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_TK_VALUE_DATA_SIZE) /**< Size (in octets) of the Security Manager TK value AD type. */ +#define AD_TYPE_OOB_FLAGS_DATA_SIZE 1UL /**< Data size (in octets) of the Security Manager OOB Flags AD type. */ +#define AD_TYPE_OOB_FLAGS_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_OOB_FLAGS_DATA_SIZE) /**< Size (in octets) of the Security Manager OOB Flags AD type. */ + +#define AD_TYPE_CONFIRM_VALUE_DATA_SIZE 16UL /**< Data size (in octets) of the LESC Confirmation value. */ +#define AD_TYPE_CONFIRM_VALUE_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_CONFIRM_VALUE_DATA_SIZE) /**< Size (in octets) of the LESC Confirmation value AD type. */ +#define AD_TYPE_RANDOM_VALUE_DATA_SIZE 16UL /**< Data size (in octets) of the LESC Random value. */ +#define AD_TYPE_RANDOM_VALUE_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_RANDOM_VALUE_DATA_SIZE) /**< Size (in octets) of the LESC Random value AD type. */ +#define AD_TYPE_LESC_SIZE (AD_TYPE_RANDOM_VALUE_SIZE + \ + AD_TYPE_CONFIRM_VALUE_SIZE) /**< Size (in octets) of the LESC OOB AD data field in NDEF message. */ + +#define AD_TYPE_SEC_MGR_OOB_FLAG_SET 1U /**< Security Manager OOB Flag set. Flag selection is done using _POS defines */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_CLEAR 0U /**< Security Manager OOB Flag clear. Flag selection is done using _POS defines */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_DATA_PRESENT_POS 0UL /**< Security Manager OOB Data Present Flag position. */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_LE_SUPPORTED_POS 1UL /**< Security Manager OOB Low Energy Supported Flag position. */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_SIM_LE_AND_EP_POS 2UL /**< Security Manager OOB Simultaneous LE and BR/EDR to Same Device Capable Flag position. */ +#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_PUBLIC 0UL /**< Security Manager OOB Public Address type. */ +#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_RANDOM 1UL /**< Security Manager OOB Random Address type. */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_ADDRESS_TYPE_POS 3UL /**< Security Manager OOB Address type Flag (0 = Public Address, 1 = Random Address) position. */ + +/**@brief Payload field values of LE Role BLE GAP AD Type. Corresponds with @ref ble_advdata_le_role_t enum. */ +typedef enum +{ + NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_PERIPH = 0, /**< Only Peripheral Role supported. */ + NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_CENTRAL, /**< Only Central Role supported. */ + NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_PERIPH_PREFERRED, /**< Peripheral and Central Role supported. Peripheral Role preferred for connection establishment. */ + NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_CENTRAL_PREFERRED /**< Peripheral and Central Role supported. Central Role preferred for connection establishment */ +} nfc_ble_advdata_le_role_encoded_t; + +/**@brief Function for encoding data in the Advertising and Scan Response data format, which + * is used for NFC OOB pairing. + * + * + * @details This function encodes data into the Advertising and Scan Response data format (AD structures). + * Encoding is based on the selections in the supplied structures. This function uses + * @ref adv_data_encode to encode regular data and adds additional AD Structures which are specific + * for NFC OOB pairing: Security Manager TK Value, LESC OOB values, OOB Flags, and LE Role. + * + * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_len \c in: Size of \p p_encoded_data buffer. + * \c out: Length of encoded data. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in \p p_advdata. + * @retval NRF_ERROR_DATA_SIZE If the operation failed because not all the requested data could fit into the + * provided buffer or some encoded AD structure is too long and its + * length cannot be encoded with one octet. + */ +ret_code_t nfc_ble_oob_adv_data_encode(ble_advdata_t const * const p_advdata, + uint8_t * const p_encoded_data, + uint16_t * const p_len); + +/**@brief Function for encoding payload field of Security Manager TK Value AD Type. + * + * @param[in] p_tk_value Security Manager TK Value AD Type payload. + * @param[out] p_tk_payload_data Pointer to the buffer where TK payload data will be stored. + * + */ +void nfc_tk_value_payload_encode(ble_advdata_tk_value_t * p_tk_value, + uint8_t * p_tk_payload_data); + +#endif // NFC_BLE_OOB_ADVDATA_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.c new file mode 100644 index 0000000000000000000000000000000000000000..28400e12e41ee4c525bb4ed0cd5686a5aebad9a5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.c @@ -0,0 +1,601 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + + #include "sdk_config.h" + #if NFC_BLE_PAIR_LIB_ENABLED + +#include "nfc_ble_pair_lib.h" +#include "sdk_macros.h" +#include "app_error.h" +#include "nrf_drv_rng.h" +#include "nfc_t2t_lib.h" +#include "nfc_ble_pair_msg.h" +#include "ble_advertising.h" +#include "peer_manager.h" +#include "ecc.h" + +#define NRF_LOG_MODULE_NAME "NFC_BLE_PAIR" +#if NFC_BLE_PAIR_LIB_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_BLE_PAIR_LIB_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_BLE_PAIR_LIB_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR NFC_BLE_PAIR_LIB_DEBUG_COLOR +#else // NFC_BLE_PAIR_LIB_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_BLE_PAIR_LIB_LOG_ENABLED +#include "nrf_log.h" + +// Verify bonding and keys distribution settings. +#if ((BLE_NFC_SEC_PARAM_BOND) && \ + !(BLE_NFC_SEC_PARAM_KDIST_OWN_ENC) && \ + !(BLE_NFC_SEC_PARAM_KDIST_OWN_ID) && \ + !(BLE_NFC_SEC_PARAM_KDIST_PEER_ENC) && \ + !(BLE_NFC_SEC_PARAM_KDIST_PEER_ID)) + #error "At least one of the BLE_NFC_SEC_PARAM_KDIST flags must be set to 1 when bonding is enabled." +#endif + +// Macro for verifying if the pairing mode argument is valid +#define VERIFY_PAIRING_MODE(arg) \ + if((arg) >= NFC_PAIRING_MODE_CNT) \ + { \ + return NRF_ERROR_INVALID_PARAM; \ + } + +#define BLE_GAP_LESC_P256_SK_LEN 32 /**< GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Secret Key Length. */ +#define TK_MAX_NUM 1 /**< Maximal number of TK locations in NDEF message buffer. */ +#define NDEF_MSG_BUFF_SIZE 256 /**< Size of buffer for the NDEF pairing message */ + +#define BLE_NFC_SEC_PARAM_KEYPRESS 0 /**< Keypress notifications not enabled. */ +#define BLE_NFC_SEC_PARAM_IO_CAPS BLE_GAP_IO_CAPS_NONE /**< No I/O capabilities. */ + +typedef struct +{ + uint8_t sk[BLE_GAP_LESC_P256_SK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Secret Key */ +} ble_gap_lesc_p256_sk_t; + +static uint8_t m_ndef_msg_buf[NDEF_MSG_BUFF_SIZE]; /**< NFC tag NDEF message buffer. */ +static ble_advdata_tk_value_t m_oob_auth_key; /**< Temporary Key buffer used in OOB legacy pairing mode. */ +static uint8_t * m_tk_group[TK_MAX_NUM]; /**< Locations of TK in NDEF message. */ +static nfc_pairing_mode_t m_pairing_mode; /**< Current pairing mode. */ +static ble_gap_lesc_oob_data_t m_ble_lesc_oob_data; /**< LESC OOB data used in LESC OOB pairing mode */ + +static bool m_connected = false; /**< Indicates if device is connected */ +static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection */ +static bool m_pending_advertise = false; /**< Flag used to indicate pending advertising that will be start after disconnection */ + +__ALIGN(4) static ble_gap_lesc_p256_pk_t m_lesc_pk; /**< LESC ECC Public Key */ +__ALIGN(4) static ble_gap_lesc_p256_sk_t m_lesc_sk; /**< LESC ECC Secret Key */ +__ALIGN(4) static ble_gap_lesc_dhkey_t m_lesc_dhkey; /**< LESC ECC DH Key */ +__ALIGN(4) static ble_gap_lesc_p256_pk_t m_lesc_peer_pk; /**< LESC Peer ECC Public Key */ + +/** + * @brief Generates random values to a given buffer + * + * @param[out] p_buff Buffer for random values + * @param[in] size Number of bytes to generate + * + * @returns Number of generated bytes + */ +static uint8_t random_vector_generate(uint8_t * p_buff, uint8_t size) +{ + uint8_t available; + ret_code_t err_code = NRF_SUCCESS; + + nrf_drv_rng_bytes_available(&available); + + uint8_t length = (size < available) ? size : available; + err_code = nrf_drv_rng_rand(p_buff, length); + APP_ERROR_CHECK(err_code); + return length; +} + +/** + * @brief Prints generated key to the log console + * + * @param[in] lenght TK value length + */ +static void random_vector_log(uint8_t length) +{ + NRF_LOG_INFO("TK Random Value:"); + for (uint8_t i = 0; i < length; i++) + { + NRF_LOG_RAW_INFO(" %02X",(int)m_oob_auth_key.tk[i]); + } + NRF_LOG_RAW_INFO("\r\n"); +} + +/** + * @brief Function for handling NFC events. + * + * @details Starts advertising and generates new OOB keys on the NFC_T2T_EVENT_FIELD_ON event. + * + * @param[in] p_context Context for callback execution, not used in this callback implementation. + * @param[in] event Event generated by hal NFC lib. + * @param[in] p_data Received/transmitted data or NULL, not used in this callback implementation. + * @param[in] data_length Size of the received/transmitted packet, not used in this callback implementation. + */ +static void nfc_callback(void * p_context, + nfc_t2t_event_t event, + const uint8_t * p_data, + size_t data_length) +{ + UNUSED_PARAMETER(p_context); + UNUSED_PARAMETER(p_data); + UNUSED_PARAMETER(data_length); + + ret_code_t err_code = NRF_SUCCESS; + nfc_pairing_mode_t pairing_mode; + + switch (event) + { + case NFC_T2T_EVENT_FIELD_ON: + NRF_LOG_DEBUG("NFC_EVENT_FIELD_ON\r\n"); + + pairing_mode = nfc_ble_pair_mode_get(); + + if (pairing_mode == NFC_PAIRING_MODE_OOB) + { + // Generate Authentication OOB Key and update NDEF message content. + uint8_t length = random_vector_generate(m_oob_auth_key.tk, BLE_GAP_SEC_KEY_LEN); + random_vector_log(length); + err_code = nfc_tk_group_modifier_update(&m_oob_auth_key); + APP_ERROR_CHECK(err_code); + } + + // If device is connected, terminate connection and start advertising on BLE_GAP_EVT_DISCONNECTED event. + if(m_connected) + { + m_pending_advertise = true; + + err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + APP_ERROR_CHECK(err_code); + } + else + { + // Start advertising when NFC field is sensed. + err_code = ble_advertising_start(BLE_ADV_MODE_FAST); + if (err_code != NRF_ERROR_INVALID_STATE) + { + APP_ERROR_CHECK(err_code); + } + } + + break; + + case NFC_T2T_EVENT_FIELD_OFF: + NRF_LOG_DEBUG("NFC_EVENT_FIELD_OFF\r\n"); + break; + + default: + break; + } +} + +/** + * @brief Function for setting the Peer Manager secure mode used in device pairing. + * + * @param[in] mode NFC pairing mode, this is the value of @ref nfc_pairing_mode_t enum + * + * @retval NRF_SUCCESS If new secure mode has been set correctly. + * @retval NRF_ERROR_INVALID_PARAM If pairing mode is invalid. + * @retval Other Other error codes might be returned depending on used modules. + */ +static ret_code_t pm_secure_mode_set(nfc_pairing_mode_t mode) +{ + ble_gap_sec_params_t sec_param; + ret_code_t err_code = NRF_SUCCESS; + + // Check if pairing mode is valid. + VERIFY_PAIRING_MODE(mode); + + memset(&sec_param, 0x00, sizeof(sec_param)); + + // Pairing mode specific security parameters. + switch (mode) + { + case NFC_PAIRING_MODE_JUST_WORKS: + // Disable pairing with OOB data. + sec_param.mitm = 0; + sec_param.oob = 0; + sec_param.lesc = 0; + break; + + case NFC_PAIRING_MODE_OOB: + // Enable legacy pairing with OOB data - TK value. + sec_param.mitm = 1; + sec_param.oob = 1; + sec_param.lesc = 0; + break; + + case NFC_PAIRING_MODE_LESC_OOB: + case NFC_PAIRING_MODE_LESC_JUST_WORKS: + // Enable LESC pairing - OOB and MITM flags are cleared because it is the central device + // who decides if the connection will be authorized with LESC OOB data. + sec_param.mitm = 0; + sec_param.oob = 0; + sec_param.lesc = 1; + break; + + default: + return NRF_ERROR_INVALID_PARAM; + } + + // Common security parameters to be used for all security procedures. + sec_param.min_key_size = BLE_NFC_SEC_PARAM_MIN_KEY_SIZE; + sec_param.max_key_size = BLE_NFC_SEC_PARAM_MAX_KEY_SIZE; + sec_param.keypress = BLE_NFC_SEC_PARAM_KEYPRESS; + sec_param.io_caps = BLE_NFC_SEC_PARAM_IO_CAPS; + sec_param.bond = BLE_NFC_SEC_PARAM_BOND; + +#if (BLE_NFC_SEC_PARAM_BOND) + // If bonding is enabled, set key distribution flags. + sec_param.kdist_own.enc = BLE_NFC_SEC_PARAM_KDIST_OWN_ENC; + sec_param.kdist_own.id = BLE_NFC_SEC_PARAM_KDIST_OWN_ID; + sec_param.kdist_peer.enc = BLE_NFC_SEC_PARAM_KDIST_PEER_ENC; + sec_param.kdist_peer.id = BLE_NFC_SEC_PARAM_KDIST_PEER_ID; +#else + // If bonding is not enabled, no keys can be distributed. + sec_param.kdist_own.enc = 0; + sec_param.kdist_own.id = 0; + sec_param.kdist_peer.enc = 0; + sec_param.kdist_peer.id = 0; +#endif + + // Update Peer Manager security parameter settings. + err_code = pm_sec_params_set(&sec_param); + + return err_code; +} + + + /**@brief Function for preparing the BLE pairing data for the NFC tag. + * + * @details This function does not stop and start the NFC tag data emulation. + * + * @param[in] mode Pairing mode for which the tag data will be prepared. + * + * @retval NRF_SUCCESS If new tag pairing data has been set correctly. + * @retval NRF_ERROR_INVALID_PARAM If pairing mode is invalid. + * @retval Other Other error codes might be returned depending on used modules. + */ +ret_code_t nfc_ble_pair_data_set(nfc_pairing_mode_t mode) +{ + ret_code_t err_code = NRF_SUCCESS; + + // Check if pairing mode is valid + VERIFY_PAIRING_MODE(mode); + + // Provide information about available buffer size to encoding function. + uint32_t ndef_msg_len = sizeof(m_ndef_msg_buf); + + switch (mode) + { + case NFC_PAIRING_MODE_OOB: + // Encode NDEF message with Secure Simple Pairing OOB optional data - TK value. + err_code = nfc_ble_pair_msg_updatable_tk_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, + &m_oob_auth_key, + NULL, + m_ndef_msg_buf, + &ndef_msg_len, + m_tk_group, + TK_MAX_NUM); + break; + + case NFC_PAIRING_MODE_JUST_WORKS: + // Encode NDEF message with Secure Simple Pairing OOB data. + err_code = nfc_ble_pair_default_msg_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, + NULL, + NULL, + m_ndef_msg_buf, + &ndef_msg_len); + break; + + case NFC_PAIRING_MODE_LESC_OOB: + // Generate LESC OOB data + err_code = sd_ble_gap_lesc_oob_data_get(BLE_CONN_HANDLE_INVALID, + &m_lesc_pk, + &m_ble_lesc_oob_data); + VERIFY_SUCCESS(err_code); + + // Encode NDEF message with BLE LESC OOB pairing data - LESC random and confirmation values. + err_code = nfc_ble_pair_default_msg_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, + NULL, + &m_ble_lesc_oob_data, + m_ndef_msg_buf, + &ndef_msg_len); + break; + + case NFC_PAIRING_MODE_LESC_JUST_WORKS: + err_code = nfc_ble_pair_default_msg_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, + NULL, + NULL, + m_ndef_msg_buf, + &ndef_msg_len); + break; + + default: + return NRF_ERROR_INVALID_PARAM; + } + + VERIFY_SUCCESS(err_code); + + // Update NFC tag data + err_code = nfc_t2t_payload_set(m_ndef_msg_buf, ndef_msg_len); + + return err_code; +} + +ret_code_t nfc_ble_pair_init(nfc_pairing_mode_t mode) +{ + ret_code_t err_code = NRF_SUCCESS; + + // Check if pairing mode is valid + VERIFY_PAIRING_MODE(mode); + + m_pairing_mode = mode; + + // Initialize RNG peripheral for authentication OOB data generation + err_code = nrf_drv_rng_init(NULL); + if (err_code != NRF_ERROR_INVALID_STATE) + { + VERIFY_SUCCESS(err_code); + } + + // Initialize encryption module with random number generator use + ecc_init(true); + + // Start NFC + err_code = nfc_t2t_setup(nfc_callback, NULL); + VERIFY_SUCCESS(err_code); + + // Set Peer Manager pairing mode + err_code = pm_secure_mode_set(mode); + VERIFY_SUCCESS(err_code); + + if ((mode == NFC_PAIRING_MODE_LESC_OOB) || (mode == NFC_PAIRING_MODE_LESC_JUST_WORKS)) + { + // Generate new LESC keys + err_code = ecc_p256_keypair_gen(m_lesc_sk.sk, m_lesc_pk.pk); + VERIFY_SUCCESS(err_code); + + // Update Peer Manager with new LESC Public Key + err_code = pm_lesc_public_key_set(&m_lesc_pk); + VERIFY_SUCCESS(err_code); + } + + // Set proper NFC data according to the pairing mode + err_code = nfc_ble_pair_data_set(mode); + VERIFY_SUCCESS(err_code); + + // Turn on tag emulation + err_code = nfc_t2t_emulation_start(); + + return err_code; +} + +ret_code_t nfc_ble_pair_mode_set(nfc_pairing_mode_t mode) +{ + ret_code_t err_code = NRF_SUCCESS; + + // Check if pairing mode is valid + VERIFY_PAIRING_MODE(mode); + + if (mode != m_pairing_mode) + { + m_pairing_mode = mode; + + if ((mode == NFC_PAIRING_MODE_LESC_OOB) || (mode == NFC_PAIRING_MODE_LESC_JUST_WORKS)) + { + // Generate new LESC keys + err_code = ecc_p256_keypair_gen(m_lesc_sk.sk, m_lesc_pk.pk); + VERIFY_SUCCESS(err_code); + + // Update Peer Manager with new LESC Public Key + err_code = pm_lesc_public_key_set(&m_lesc_pk); + VERIFY_SUCCESS(err_code); + } + + // Update Peer Manager settings according to the new pairing mode + err_code = pm_secure_mode_set(mode); + VERIFY_SUCCESS(err_code); + + // NFC tag emulation must be turned off during changes in payload + err_code = nfc_t2t_emulation_stop(); + VERIFY_SUCCESS(err_code); + + // Update NFC tag data + err_code = nfc_ble_pair_data_set(mode); + VERIFY_SUCCESS(err_code); + + // Turn on tag emulation after changes + err_code = nfc_t2t_emulation_start(); + VERIFY_SUCCESS(err_code); + } + + return NRF_SUCCESS; +} + +nfc_pairing_mode_t nfc_ble_pair_mode_get(void) +{ + return m_pairing_mode; +} + +/** + * @brief Generates new key pair for LESC pairing. + * + * @details If device is in @ref NFC_PAIRING_MODE_LESC_OOB mode, + * NFC Connection Handover message is also updated with + * newly generated LESC OOB data. + * + * @retval NRF_SUCCESS If new tag pairing data has been set correctly. + * @retval Other Other error codes might be returned depending on used modules. + */ +static ret_code_t generate_lesc_keys(void) +{ + ret_code_t err_code = NRF_SUCCESS; + + // Generate new LESC keys + err_code = ecc_p256_keypair_gen(m_lesc_sk.sk, m_lesc_pk.pk); + VERIFY_SUCCESS(err_code); + + // Update Peer Manager with new LESC Public Key + err_code = pm_lesc_public_key_set(&m_lesc_pk); + VERIFY_SUCCESS(err_code); + + if (m_pairing_mode == NFC_PAIRING_MODE_LESC_OOB) + { + // Generate LESC OOB data. + err_code = sd_ble_gap_lesc_oob_data_get(BLE_CONN_HANDLE_INVALID, + &m_lesc_pk, + &m_ble_lesc_oob_data); + VERIFY_SUCCESS(err_code); + + // Update NDEF message with new LESC OOB data. + err_code = nfc_lesc_data_update(&m_ble_lesc_oob_data); + VERIFY_SUCCESS(err_code); + } + + return NRF_SUCCESS; +} + +void on_nfc_ble_pair_evt(const ble_evt_t * const p_ble_evt) +{ + ret_code_t err_code = NRF_SUCCESS; + + switch (p_ble_evt->header.evt_id) + { + // Upon authorization key request, reply with Temporary Key that was read from the NFC tag + case BLE_GAP_EVT_AUTH_KEY_REQUEST: + NRF_LOG_DEBUG("BLE_GAP_EVT_AUTH_KEY_REQUEST\r\n"); + + err_code = sd_ble_gap_auth_key_reply(p_ble_evt->evt.gap_evt.conn_handle, + BLE_GAP_AUTH_KEY_TYPE_OOB, + m_oob_auth_key.tk); + APP_ERROR_CHECK(err_code); + break; + + // Upon LESC Diffie_Hellman key request, reply with key computed from device secret key and peer public key + case BLE_GAP_EVT_LESC_DHKEY_REQUEST: + NRF_LOG_INFO("BLE_GAP_EVT_LESC_DHKEY_REQUEST\r\n"); + + // If LESC OOB pairing is on, perform authentication with OOB data + if (p_ble_evt->evt.gap_evt.params.lesc_dhkey_request.oobd_req) + { + err_code = sd_ble_gap_lesc_oob_data_set(p_ble_evt->evt.gap_evt.conn_handle, + &m_ble_lesc_oob_data, + NULL); + APP_ERROR_CHECK(err_code); + } + + // Buffer peer Public Key because ECC module arguments must be word aligned + memcpy(&m_lesc_peer_pk.pk[0], + &p_ble_evt->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer->pk[0], + BLE_GAP_LESC_P256_PK_LEN); + + // Compute D-H key + err_code = ecc_p256_shared_secret_compute(&m_lesc_sk.sk[0], + &m_lesc_peer_pk.pk[0], + &m_lesc_dhkey.key[0]); + APP_ERROR_CHECK(err_code); + + // Reply with obtained result + err_code = sd_ble_gap_lesc_dhkey_reply(p_ble_evt->evt.gap_evt.conn_handle, + &m_lesc_dhkey); + APP_ERROR_CHECK(err_code); + break; + + case BLE_GAP_EVT_CONNECTED: + // Stop advertising if device is connected + err_code = ble_advertising_start(BLE_ADV_MODE_IDLE); + APP_ERROR_CHECK(err_code); + + m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + m_connected = true; + break; + + case BLE_GAP_EVT_AUTH_STATUS: + // Generate new LESC key pair and OOB data + if ((m_pairing_mode == NFC_PAIRING_MODE_LESC_OOB) || + (m_pairing_mode == NFC_PAIRING_MODE_LESC_JUST_WORKS)) + { + err_code = generate_lesc_keys(); + APP_ERROR_CHECK(err_code); + } + break; + + case BLE_GAP_EVT_DISCONNECTED: + // Start directed advertising if connection timeout occured + if (p_ble_evt->evt.gap_evt.params.disconnected.reason == BLE_HCI_CONNECTION_TIMEOUT) + { + err_code = ble_advertising_start(BLE_ADV_MODE_DIRECTED); + APP_ERROR_CHECK(err_code); + } + + m_connected = false; + m_conn_handle = BLE_CONN_HANDLE_INVALID; + + if(m_pending_advertise) + { + m_pending_advertise = false; + + // Start advertising when NFC field is sensed. + err_code = ble_advertising_start(BLE_ADV_MODE_FAST); + if (err_code != NRF_ERROR_INVALID_STATE) + { + APP_ERROR_CHECK(err_code); + } + } + else + { + // Generate new LESC key pair and OOB data only when connection is not terminated because of reading a new tag + if ((m_pairing_mode == NFC_PAIRING_MODE_LESC_OOB) || + (m_pairing_mode == NFC_PAIRING_MODE_LESC_JUST_WORKS)) + { + err_code = generate_lesc_keys(); + APP_ERROR_CHECK(err_code); + } + } + break; + + default: + break; + } +} + +#endif // NFC_BLE_PAIR_LIB_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..91ad663befd46497eeb0c65f04370d16312ae06d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.h @@ -0,0 +1,128 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_BLE_PAIR_LIB_H__ +#define NFC_BLE_PAIR_LIB_H__ + +#include +#include "sdk_errors.h" +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@file + * + * @addtogroup nfc_api + * + * @defgroup nfc_ble_pair_lib NFC BLE Pairing Lib + * @ingroup nfc_api + * @brief @tagAPI52 High level library for BLE Connection Handover pairing using NFC. + * @{ + */ + +/** + * @brief NFC pairing types + */ +typedef enum { + NFC_PAIRING_MODE_JUST_WORKS, /**< Legacy Just Works pairing without security key */ + NFC_PAIRING_MODE_OOB, /**< Legacy OOB pairing with Temporary Key shared through NFC tag data */ + NFC_PAIRING_MODE_LESC_JUST_WORKS, /**< LESC pairing without authentication data */ + NFC_PAIRING_MODE_LESC_OOB, /**< LESC pairing with OOB authentication data */ + NFC_PAIRING_MODE_CNT /**< Number of available pairing modes */ +} nfc_pairing_mode_t; + +/** + * @brief Initializes NFC tag data and turns on tag emulation. + * + * @warning It is assumed that Peer Manager has already been initialized before calling this function. + * It is also assumed that BLE advertising has already been initialized and it is configured + * to run in the BLE_ADV_MODE_FAST mode. + * + * @note This library also controls BLE advertising, so @ref ble_advertising_on_ble_evt should not + * be called on BLE events. + * + * @param[in] mode Pairing mode, this is value of the @ref nfc_pairing_mode_t enum. + * + * @retval NRF_SUCCESS If NFC has been initialized properly. + * @retval NRF_ERROR_INVALID_PARAM If pairing mode is invalid. + * @retval Other Other error codes might be returned depending on used modules. + */ +ret_code_t nfc_ble_pair_init(nfc_pairing_mode_t mode); + +/** + * @brief Sets pairing data and BLE security mode. + * + * @param[in] mode New pairing mode, this is value of the @ref nfc_pairing_mode_t enum. + * + * @retval NRF_SUCCESS If new pairing mode has been set correctly. + * @retval NRF_ERROR_INVALID_PARAM If pairing mode is invalid. + * @retval Other Other error codes might be returned depending on used modules. + */ +ret_code_t nfc_ble_pair_mode_set(nfc_pairing_mode_t mode); + +/** + * @brief Funtion to obtain current pairing mode. + * + * @return Current pairing mode. + */ +nfc_pairing_mode_t nfc_ble_pair_mode_get(void); + +/** + * @brief NFC pairing BLE events handler + * + * @details Handles BLE authorization events, replying with OOB data. + * + * @note This function should be called inside BLE event dispatcher as it response to the + * @ref BLE_GAP_EVT_AUTH_KEY_REQUEST and @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST events. + * It also manages BLE advertising module based on @ref BLE_GAP_EVT_CONNECTED and + * @ref BLE_GAP_EVT_DISCONNECTED events. + * + * @param[in] p_ble_evt Bluetooth stack event. + */ +void on_nfc_ble_pair_evt(const ble_evt_t * const p_ble_evt); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_BLE_PAIR_LIB_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c new file mode 100644 index 0000000000000000000000000000000000000000..ef6731d1f33dc364258d19f941be782bba4de547 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c @@ -0,0 +1,556 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nfc_ble_pair_msg.h" +#include "nfc_hs_rec.h" +#include "nfc_ac_rec.h" +#include "nfc_le_oob_rec.h" +#include "nfc_ep_oob_rec.h" +#include "nfc_ndef_msg.h" +#include "sdk_macros.h" + +/** + * @brief Descriptor of TK value locations in Connection Handover NDEF message. + */ +typedef struct +{ + uint8_t ** pp_tk_group; /**< Pointer to array of pointer with TK locations in CH NDEF message. */ + uint8_t tk_num; /**< Number of valid TK locations. */ + uint8_t tk_max_num; /**< Maximal number of possible TK locations. */ +} nfc_ble_tk_group_t; + +/** + * @brief Descriptor of LESC OOB data in Connection Handover NDEF message. + */ +typedef struct +{ + uint8_t * confirm; /**< Pointer to the LESC OOB confirmation value in the CH NDEF message. */ + uint8_t * random; /**< Pointer to the LESC OOB random value in the CH NDEF message. */ +} nfc_ble_lesc_data_pos_t; + +static nfc_ble_lesc_data_pos_t m_lesc_pos = {NULL, NULL}; /**< Descriptor used to update LESC keys in the NDEF Message */ +static nfc_ble_tk_group_t m_tk_group; /**< Descriptor used to find TK locations in the NDEF Message which require update. */ +static bool m_tk_modifier_on = false; /**< Flag indicating that TK modifier feature is on. */ + +/* Default value for Security Manager Out Of Band Flags field in BLE AD structure */ +/* which is used for EP OOB Record payload */ +static const uint8_t sec_mgr_oob_flags = + (AD_TYPE_SEC_MGR_OOB_FLAG_SET << AD_TYPE_SEC_MGR_OOB_FLAG_OOB_DATA_PRESENT_POS) | + (AD_TYPE_SEC_MGR_OOB_FLAG_SET << AD_TYPE_SEC_MGR_OOB_FLAG_OOB_LE_SUPPORTED_POS) | + (AD_TYPE_SEC_MGR_OOB_FLAG_CLEAR << AD_TYPE_SEC_MGR_OOB_FLAG_SIM_LE_AND_EP_POS) | + (AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_RANDOM << AD_TYPE_SEC_MGR_OOB_FLAG_ADDRESS_TYPE_POS); + +/**@brief Function for configuring TK group modifier feature. + * + * @details This function configures the structure which is responsible for tracking TK locations. + * These locations can be afterwards easily accessed with @ref nfc_tk_group_modifier_update + * and modified. + * + * @param[in] pp_tk_group Pointer to array of TK locations that should be modified with + * @ref nfc_tk_group_modifier_update function. + * @param[in] max_group_size Maximal number of TK locations that can added to \p pp_tk_group. + */ +__STATIC_INLINE void nfc_tk_group_modifier_config(uint8_t ** pp_tk_group, uint8_t max_group_size) +{ + m_tk_group.pp_tk_group = pp_tk_group; + m_tk_group.tk_num = 0; + m_tk_group.tk_max_num = max_group_size; +} + +/** @brief Function for generating a description of a simplified LE OOB message according to the BLE + * AD structure. + * + * This function declares and initializes a static instance of a simplified LE OOB message + * with Bluetooth Carrier Configuration LE record. Payload of this record can be configured + * via AD structure. + * + * @param[in] p_le_advdata Pointer to the AD for LE OOB record. + * @param[out] pp_le_oob_msg_desc Pointer to pointer to the NDEF message instance. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +static ret_code_t nfc_ble_simplified_le_oob_msg_declare(ble_advdata_t const * const p_le_advdata, + nfc_ndef_msg_desc_t ** pp_le_oob_msg_desc) +{ + ret_code_t err_code; + nfc_ndef_record_desc_t * p_nfc_le_oob_record; + + /* Create NFC NDEF message description, capacity - 1 record */ + NFC_NDEF_MSG_DEF(nfc_le_oob_msg, 1); + + /* The message description is static, therefore */ + /* you must clear the message (needed for supporting multiple calls) */ + nfc_ndef_msg_clear(&NFC_NDEF_MSG(nfc_le_oob_msg)); + + if (p_le_advdata != NULL) + { + /* Create NFC NDEF LE OOB Record description without record ID field */ + p_nfc_le_oob_record = nfc_le_oob_rec_declare(0 , p_le_advdata); + + /* Add LE OOB Record as lone record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_le_oob_msg), p_nfc_le_oob_record); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else + { + return NRF_ERROR_INVALID_PARAM; + } + + *pp_le_oob_msg_desc = &NFC_NDEF_MSG(nfc_le_oob_msg); + + return NRF_SUCCESS; +} + +/** @brief Function for generating a description of a simplified EP OOB message according to the BLE + * AD structure. + * + * This function declares and initializes a static instance of a simplified EP OOB message + * with Bluetooth Carrier Configuration EP record. Payload of this record can be configured + * via AD structure. + * + * @param[in] p_ep_advdata Pointer to the AD structure for EP OOB record. + * @param[out] pp_ep_oob_msg_desc Pointer to pointer to the NDEF message instance. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +static ret_code_t nfc_ble_simplified_ep_oob_msg_declare(ble_advdata_t const * const p_ep_advdata, + nfc_ndef_msg_desc_t ** pp_ep_oob_msg_desc) +{ + ret_code_t err_code; + nfc_ndef_record_desc_t * p_nfc_ep_oob_record; + + /* Create NFC NDEF message description, capacity - 1 record */ + NFC_NDEF_MSG_DEF(nfc_ep_oob_msg, 1); + + /* The message description is static, therefore */ + /* you must clear the message (needed for supporting multiple calls) */ + nfc_ndef_msg_clear(&NFC_NDEF_MSG(nfc_ep_oob_msg)); + + if (p_ep_advdata != NULL) + { + /* Create NFC NDEF EP OOB Record description without record ID field */ + p_nfc_ep_oob_record = nfc_ep_oob_rec_declare(0 , p_ep_advdata); + + /* Add EP OOB Record as lone record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_ep_oob_msg), p_nfc_ep_oob_record); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else + { + return NRF_ERROR_INVALID_PARAM; + } + + *pp_ep_oob_msg_desc = &NFC_NDEF_MSG(nfc_ep_oob_msg); + + return NRF_SUCCESS; +} + +/** @brief Function for generating a description of a Handover Select NDEF message according to + * the BLE AD structures. + * + * This function declares and initializes a static instance of an NFC NDEF message description + * of a Handover Select NDEF message with a Hs record and two OOB records (LE and EP with + * modifications for Windows). Payload of these records can be configured via AD structures. + * + * @warning The order of LE and EP records cannot be changed. Android devices are able to pair + * correctly only when the LE record appears before the EP record. + * + * @param[in] p_le_advdata Pointer to the AD structure for LE OOB record. + * @param[in] p_ep_advdata Pointer to the AD structure for EP OOB record. + * @param[out] pp_bt_oob_full_msg Pointer to a pointer to the NDEF message instance. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +static ret_code_t nfc_ble_full_handover_select_msg_declare(ble_advdata_t const * const p_le_advdata, + ble_advdata_t const * const p_ep_advdata, + nfc_ndef_msg_desc_t ** pp_bt_oob_full_msg) +{ + ret_code_t err_code = NRF_SUCCESS; + + // Carrier reference buffers for ac records. + static uint8_t carrier_le_reference = '0'; + static uint8_t carrier_ep_reference = '1'; + + // Create ac records for both message types. + NFC_NDEF_AC_RECORD_DESC_DEF(ac_rec_le, NFC_AC_CPS_ACTIVE, 1, &carrier_le_reference, 1); + NFC_NDEF_AC_RECORD_DESC_DEF(ac_rec_ep, NFC_AC_CPS_ACTIVE, 1, &carrier_ep_reference, 1); + + // Create a Hs record and assign existing ac records to it. + NFC_NDEF_HS_RECORD_DESC_DEF(hs_rec, 1, 3, 2); + + nfc_ndef_record_desc_t * p_nfc_hs_record = &NFC_NDEF_HS_RECORD_DESC(hs_rec); + + // Clear the record before assigning local records to it (in case this function has already been called). + nfc_hs_rec_local_record_clear(p_nfc_hs_record); + + err_code = nfc_hs_rec_local_record_add(p_nfc_hs_record, &NFC_NDEF_AC_RECORD_DESC(ac_rec_le)); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = nfc_hs_rec_local_record_add(p_nfc_hs_record, &NFC_NDEF_AC_RECORD_DESC(ac_rec_ep)); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Create le and ep records. + nfc_ndef_record_desc_t * p_nfc_le_oob_record = + nfc_le_oob_rec_declare(carrier_le_reference , p_le_advdata); + + nfc_ndef_record_desc_t * p_nfc_ep_oob_record = + nfc_ep_oob_rec_declare(carrier_ep_reference , p_ep_advdata); + + // Create full NDEF Handover Select message for Connection Handover and assign Hs, le and ep records to it. + NFC_NDEF_MSG_DEF(hs_full_msg, 3); + + // Clear the message before assigning records to it (in case this function has already been called). + nfc_ndef_msg_clear(&NFC_NDEF_MSG(hs_full_msg)); + + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(hs_full_msg), p_nfc_hs_record); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(hs_full_msg), p_nfc_le_oob_record); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(hs_full_msg), p_nfc_ep_oob_record); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + *pp_bt_oob_full_msg = &NFC_NDEF_MSG(hs_full_msg); + + return err_code; +} + +/** @brief Function for creating an AD structure with common configuration for EP and LE OOB records. + * + * This function creates an AD structure and initializes its fields with default content. Only + * fields that are common for both EP and LE OOB records are filled. + * + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK field of the returned AD structure is empty. + * @param[out] p_adv_data Pointer to BLE AD structure with common configuration for EP and + * LE OOB records. + */ +static void common_adv_data_create(ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + ble_advdata_t * const p_adv_data) +{ + memset((uint8_t *) p_adv_data, 0, sizeof(ble_advdata_t)); + + /* Set common configuration of AD structure for both Bluetooth EP and LE record */ + p_adv_data->include_appearance = true; + p_adv_data->name_type = BLE_ADVDATA_FULL_NAME; + p_adv_data->p_tk_value = NULL; + if (p_tk_value != NULL) + { + p_adv_data->p_tk_value = p_tk_value; + } + + p_adv_data->p_lesc_data = p_lesc_data; +} + +/** @brief Function for creating an AD structure with default configuration for an LE OOB record. + * + * This function creates an AD structure and initializes its fields with default content for + * LE OOB record payload. + * + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK field of the returned AD structure is empty. + * @param[out] p_le_adv_data Pointer to BLE AD structure with default configuration + * for LE OOB record. + */ +static void le_oob_specific_adv_data_create(ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + ble_advdata_t * const p_le_adv_data) +{ + /* Create default configuration which is common for both EP and LE OOB Records */ + common_adv_data_create(p_tk_value, p_lesc_data, p_le_adv_data); + + /* LE specific configuration */ + p_le_adv_data->include_ble_device_addr = true; + p_le_adv_data->le_role = BLE_ADVDATA_ROLE_ONLY_PERIPH; + p_le_adv_data->flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; +} + +/** @brief Function for creating an AD structure with default configuration for an EP OOB record. + * + * This function creates an AD structure and initializes its fields with default content for + * EP OOB record payload. + * + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK field of the returned AD structure is empty. + * @param[out] p_ep_adv_data Pointer to BLE AD structure with default configuration + * for EP OOB record. + */ +static void ep_oob_specific_adv_data_create(ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + ble_advdata_t * const p_ep_adv_data) +{ + /* Create default configuration which is common for both EP and LE OOB Records */ + common_adv_data_create(p_tk_value, p_lesc_data, p_ep_adv_data); + + /* EP specific configuration */ + p_ep_adv_data->p_sec_mgr_oob_flags = (uint8_t *) &sec_mgr_oob_flags; +} + +ret_code_t nfc_ble_simplified_le_oob_msg_encode(ble_advdata_t const * const p_le_advdata, + uint8_t * p_buf, + uint32_t * p_len) +{ + nfc_ndef_msg_desc_t * p_le_oob_msg_desc; + ret_code_t err_code; + + err_code = nfc_ble_simplified_le_oob_msg_declare(p_le_advdata, &p_le_oob_msg_desc); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!m_tk_modifier_on) + { + nfc_tk_group_modifier_config(NULL, 0); + } + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(p_le_oob_msg_desc, + p_buf, + p_len); + + return err_code; +} + +ret_code_t nfc_ble_simplified_ep_oob_msg_encode(ble_advdata_t const * const p_ep_advdata, + uint8_t * p_buf, + uint32_t * p_len) +{ + nfc_ndef_msg_desc_t * p_ep_oob_msg_desc; + ret_code_t err_code; + + err_code = nfc_ble_simplified_ep_oob_msg_declare(p_ep_advdata, &p_ep_oob_msg_desc); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!m_tk_modifier_on) + { + nfc_tk_group_modifier_config(NULL, 0); + } + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(p_ep_oob_msg_desc, + p_buf, + p_len); + + return err_code; +} + +ret_code_t nfc_ble_full_handover_select_msg_encode(ble_advdata_t const * const p_le_advdata, + ble_advdata_t const * const p_ep_advdata, + uint8_t * p_buf, + uint32_t * p_len) +{ + nfc_ndef_msg_desc_t * p_full_hs_msg_desc; + ret_code_t err_code; + + err_code = nfc_ble_full_handover_select_msg_declare(p_le_advdata, + p_ep_advdata, + &p_full_hs_msg_desc); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!m_tk_modifier_on) + { + nfc_tk_group_modifier_config(NULL, 0); + } + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(p_full_hs_msg_desc, + p_buf, + p_len); + + return err_code; +} + +ret_code_t nfc_ble_pair_default_msg_encode(nfc_ble_pair_type_t nfc_ble_pair_type, + ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + uint8_t * p_buf, + uint32_t * p_len) +{ + ble_advdata_t le_adv_data; + ble_advdata_t ep_adv_data; + ret_code_t err_code = NRF_SUCCESS; + + switch (nfc_ble_pair_type) + { + + case NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT: + le_oob_specific_adv_data_create(p_tk_value, p_lesc_data, &le_adv_data); + err_code = nfc_ble_simplified_le_oob_msg_encode(&le_adv_data, p_buf, p_len); + break; + + case NFC_BLE_PAIR_MSG_BLUETOOTH_EP_SHORT: + ep_oob_specific_adv_data_create(p_tk_value, NULL, &ep_adv_data); + err_code = nfc_ble_simplified_ep_oob_msg_encode(&ep_adv_data, p_buf, p_len); + break; + + case NFC_BLE_PAIR_MSG_FULL: + le_oob_specific_adv_data_create(p_tk_value, p_lesc_data, &le_adv_data); + ep_oob_specific_adv_data_create(p_tk_value, NULL, &ep_adv_data); + err_code = nfc_ble_full_handover_select_msg_encode(&le_adv_data, + &ep_adv_data, + p_buf, + p_len); + break; + + } + + return err_code; +} + +ret_code_t nfc_ble_pair_msg_updatable_tk_encode(nfc_ble_pair_type_t nfc_ble_pair_type, + ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + uint8_t * p_buf, + uint32_t * p_len, + uint8_t ** pp_tk_group, + uint8_t max_group_size) +{ + ret_code_t err_code = NRF_SUCCESS; + + m_tk_modifier_on = true; + nfc_tk_group_modifier_config(pp_tk_group, max_group_size); + err_code = nfc_ble_pair_default_msg_encode(nfc_ble_pair_type, p_tk_value, + p_lesc_data, p_buf, p_len); + m_tk_modifier_on = false; + + return err_code; +} + +ret_code_t nfc_tk_group_modifier_update(ble_advdata_tk_value_t * p_tk_value) +{ + VERIFY_PARAM_NOT_NULL(m_tk_group.pp_tk_group); + for (uint8_t tk_index = 0; tk_index < m_tk_group.tk_num; ++tk_index) + { + uint8_t * p_tk_payload_data = m_tk_group.pp_tk_group[tk_index]; + nfc_tk_value_payload_encode(p_tk_value, p_tk_payload_data); + } + return NRF_SUCCESS; +} + +ret_code_t nfc_tk_to_group_add(uint8_t * p_tk_location) +{ + // Feature was disabled. + if (m_tk_group.pp_tk_group == NULL) + { + return NRF_SUCCESS; + } + + if (m_tk_group.tk_num < m_tk_group.tk_max_num) + { + m_tk_group.pp_tk_group[m_tk_group.tk_num++] = p_tk_location; + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_NO_MEM; + } +} + +ret_code_t nfc_lesc_pos_set(uint8_t * p_confirm, uint8_t * p_random) +{ + if((p_confirm != NULL) && (p_random != NULL)) + { + m_lesc_pos.confirm = p_confirm; + m_lesc_pos.random = p_random; + + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_NULL; + } +} + +ret_code_t nfc_lesc_data_update(ble_gap_lesc_oob_data_t * ble_lesc_oob_data) +{ + if(ble_lesc_oob_data != NULL) + { + if((ble_lesc_oob_data->c != NULL) && (ble_lesc_oob_data->r != NULL)) + { + memcpy(m_lesc_pos.confirm, ble_lesc_oob_data->c, AD_TYPE_CONFIRM_VALUE_DATA_SIZE); + memcpy(m_lesc_pos.random, ble_lesc_oob_data->r, AD_TYPE_RANDOM_VALUE_DATA_SIZE); + + return NRF_SUCCESS; + } + + return NRF_ERROR_INVALID_STATE; + } + else + { + return NRF_ERROR_NULL; + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h new file mode 100644 index 0000000000000000000000000000000000000000..178e24eaa050371511b54616a1a9683aa4d144bd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h @@ -0,0 +1,279 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_BLE_PAIR_MSG_H__ +#define NFC_BLE_PAIR_MSG_H__ + +/**@file + * + * @defgroup nfc_modules NDEF message modules + * @ingroup nfc_api + * @brief Implementation of NDEF messages. + * + * @defgroup nfc_ndef_messages Predefined NDEF messages + * @ingroup nfc_modules + * @brief Predefined NDEF messages for standard use. + * + * @defgroup nfc_ble_pair_msg BLE pairing messages + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF messages used for BLE pairing. + * + */ + +#include +#include "ble_advdata.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Types of BLE pairing message. + * + * Use one of these values to choose the type of NDEF BLE pairing message. + */ +typedef enum +{ + NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, ///< Simplified LE OOB message. + NFC_BLE_PAIR_MSG_BLUETOOTH_EP_SHORT, ///< Simplified EP OOB message. + NFC_BLE_PAIR_MSG_FULL ///< BLE Handover Select Message. +} nfc_ble_pair_type_t; + +/** @brief Function for encoding simplified LE OOB messages. + * + * This function encodes a simplified LE OOB message into a buffer. The payload of the LE OOB record + * inside the message can be configured via the advertising data structure. + * + * This function was implemented partially according to "Bluetooth Secure Simple Pairing Using NFC" + * (denotation "NFCForum-AD-BTSSP_1_1" published on 2014-01-09) chapters 3.1, 3.2, 4.3.2, + * and according to "Supplement to the Bluetooth Core Specification" (Version 5, adoption date: + * Dec 02 2014). + * + * @note To be able to encode the message, a SoftDevice must be enabled and configured. + * + * @param[in] p_le_advdata Pointer to the BLE advertising data structure for the LE OOB record. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_simplified_le_oob_msg_encode(ble_advdata_t const * const p_le_advdata, + uint8_t * p_buf, + uint32_t * p_len); + +/** @brief Function for encoding simplified EP OOB messages. + * + * This function encodes a simplified EP OOB message into a buffer. The payload of the EP OOB record + * inside the message can be configured via the advertising data structure. + * + * This function was implemented partially according to "Bluetooth Secure Simple Pairing Using NFC" + * (denotation "NFCForum-AD-BTSSP_1_1" published on 2014-01-09) chapters 3.1, 3.2, 4.3.1, + * and according to "Supplement to the Bluetooth Core Specification" (Version 5, adoption date: + * Dec 02 2014). + * + * @note To be able to encode the message, a SoftDevice must be enabled and configured. + * + * @param[in] p_ep_advdata Pointer to the BLE advertising data structure for the EP OOB record. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_simplified_ep_oob_msg_encode(ble_advdata_t const * const p_ep_advdata, + uint8_t * p_buf, + uint32_t * p_len); + +/** @brief Function for encoding BLE Handover Select Messages. + * + * This function encodes a BLE Handover Select Message into a buffer. The payload of the LE OOB record + * and the EP OOB record inside the message can be configured via the advertising data structures. + * + * This function was implemented partially according to "Bluetooth Secure Simple Pairing Using NFC" + * (denotation "NFCForum-AD-BTSSP_1_1" published on 2014-01-09) chapters 3.1, 3.2, 4.1.1 + * and 4.1.2 (combined), and according to "Supplement to the Bluetooth Core Specification" (Version 5, + * adoption date: Dec 02 2014). + * + * @note To be able to encode the message, a SoftDevice must be enabled and configured. + * + * @param[in] p_le_advdata Pointer to the BLE advertising data structure for the LE OOB record. + * @param[in] p_ep_advdata Pointer to the BLE advertising data structure for the EP OOB record. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_full_handover_select_msg_encode(ble_advdata_t const * const p_le_advdata, + ble_advdata_t const * const p_ep_advdata, + uint8_t * p_buf, + uint32_t * p_len); + +/** @brief Function for encoding any type of BLE pairing messages with default BLE + * advertising data structures. + * + * This function encodes a BLE pairing message into a buffer. The message can be encoded as + * one of the three message types (using @ref nfc_ble_simplified_le_oob_msg_encode, + * @ref nfc_ble_simplified_ep_oob_msg_encode, or @ref nfc_ble_full_handover_select_msg_encode), + * according to the @p nfc_ble_pair_type parameter. LE and EP OOB records use the default + * advertising data structure configuration. Only one field ('Security Manager TK') in the BLE + * advertising data can be configured for both records by specifying the @p p_tk_value parameter. + * + * For LE OOB records, the default BLE advertising data structure configuration fills the required + * fields 'LE Bluetooth Device Address' and 'LE Role' and the optional fields 'Appearance', + * 'Local Name', and 'Flags'. + * + * For EP OOB records, the default BLE advertising data structure configuration fills the required + * field 'Security Manager Out Of Band Flags' and the optional fields 'Appearance', + * 'Local Name', and 'Flags'. + * + * @note To be able to encode the message, a SoftDevice must be enabled and configured. + * + * @param[in] nfc_ble_pair_type Type of BLE pairing message. + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK value field is not encoded in the NDEF message. + * @param[in] p_lesc_data Pointer to the LESC OOB data. If NULL, LESC OOB fields are + * not encoded in the NDEF message. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_pair_default_msg_encode(nfc_ble_pair_type_t nfc_ble_pair_type, + ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + uint8_t * p_buf, + uint32_t * p_len); + +/** @brief Function for encoding any type of BLE pairing messages with default BLE + * advertising data structures and with TK modifier feature. + * + * This function is very similar to @ref nfc_ble_pair_default_msg_encode function, but + * additionaly it enables to track TK locations which were encoded in Connection Handover + * NDEF message. After using this function, you can update TK value in NDEF by calling + * @ref nfc_tk_group_modifier_update. + * + * @param[in] nfc_ble_pair_type Type of BLE pairing message. + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK value field is not encoded in the NDEF message. + * @param[in] p_lesc_data Pointer to the LESC OOB data. If NULL, LESC OOB values are + * not encoded in the NDEF message. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * @param[in] pp_tk_group Pointer to array of TK locations that should be modified with + * @ref nfc_tk_group_modifier_update function. + * @param[in] max_group_size Maximal number of TK locations that can added to \p pp_tk_group. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_pair_msg_updatable_tk_encode(nfc_ble_pair_type_t nfc_ble_pair_type, + ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + uint8_t * p_buf, + uint32_t * p_len, + uint8_t ** pp_tk_group, + uint8_t max_group_size); + +/**@brief Function for updating the Connection Handover NDEF message with new TK value. + * + * @details This function updates NDEF message with new TK value. This update is applied to all of + * TK locations in the Connection Handover NDEF message. This function can only be used + * after calling @ref nfc_ble_pair_msg_updatable_tk_encode, which is used to encode + * Connection Handover NDEF message. + * + * @param[in] p_tk_value Pointer to the new TK value. The NDEF message will be updated with this + * value. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If pointer to TK locations was NULL. + */ +ret_code_t nfc_tk_group_modifier_update(ble_advdata_tk_value_t * p_tk_value); + +/**@brief Function for adding new location of TK value to the location description structure. + * + * @param[in] p_tk_location New location of TK value in the Connection Handover NDEF message. + * + * @retval NRF_SUCCESS If the operation was successful or if buffer used for holding TK + * locations is NULL. + * @retval NRF_ERROR_NO_MEM If there is no place in the buffer for the new TK value location. + */ +ret_code_t nfc_tk_to_group_add(uint8_t * p_tk_location); + +/**@brief Function for updating the Connection Handover NDEF message with a new LESC OOB values. + * + * @details Updates LESC Confirmation and Random Values based on its locations set by the @ref nfc_lesc_pos_set function. + * + * @param[in] ble_lesc_oob_data Pointer to the new LESC OOB data. The NDEF message will be updated with this data. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If pointer to the new LESC OOB data is NULL. + * @retval NRF_ERROR_INVALID_STATE If pointer to the LESC OOB data location in NDEF message is NULL. + */ +ret_code_t nfc_lesc_data_update(ble_gap_lesc_oob_data_t * ble_lesc_oob_data); + +/**@brief Function for storing pointers to the LESC OOB data inside NDEF message. + * + * @details It allows LESC OOB data update without regenerating entire CH NDEF message. + * + * @param[in] p_confirm Pointer to the LESC Confirmation Value position in the NDEF message. + * @param[in] p_random Pointer to the LESC Random Value position in the NDEF message. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If either of pointers is set to NULL. + */ +ret_code_t nfc_lesc_pos_set(uint8_t * p_confirm, uint8_t * p_random); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_BLE_PAIR_MSG_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c new file mode 100644 index 0000000000000000000000000000000000000000..fc59ab941a943a0710a551dc257f7c52c87480ea --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include + +/* Record Payload Type for Bluetooth Carrier Configuration LE record */ +const uint8_t le_oob_rec_type_field[] = +{ + 'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', '/', 'v', 'n', 'd', '.', + 'b', 'l', 'u', 'e', 't', 'o', 'o', 't', 'h', '.', 'l', 'e', '.', 'o', 'o', 'b' +}; diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h new file mode 100644 index 0000000000000000000000000000000000000000..f4b9aee7fa747d3ee138451609c540e5b4648d52 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include + +/* Record Payload Type for Bluetooth Carrier Configuration LE record */ +extern const uint8_t le_oob_rec_type_field[32]; diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c new file mode 100644 index 0000000000000000000000000000000000000000..f305f7f387d28fc1415c88306e65e68395a5cd31 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c @@ -0,0 +1,237 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nfc_ep_oob_rec.h" +#include "sdk_errors.h" +#include "ble_gap.h" +#include "app_util.h" + +/* NFC OOB EP definitions */ +#define NFC_EP_OOB_REC_GAP_ADDR_LEN BLE_GAP_ADDR_LEN +#define NFC_EP_OOB_REC_OOB_DATA_LEN_SIZE 2UL +#define NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN (NFC_EP_OOB_REC_GAP_ADDR_LEN + \ + NFC_EP_OOB_REC_OOB_DATA_LEN_SIZE) + +/* Record Payload Type for Bluetooth Carrier Configuration EP record */ +static const uint8_t ep_oob_rec_type_field[] = +{ + 'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', '/', 'v', 'n', 'd', '.', + 'b', 'l', 'u', 'e', 't', 'o', 'o', 't', 'h', '.', 'e', 'p', '.', 'o', 'o', 'b' +}; + +/** + * @brief Function for validating AD structure content for a Bluetooth Carrier Configuration EP record. + * + * This function validates AD structure content. LE Bluetooth Device Address and LE Role + * fields must not be included. Security Manager OOB Flags structure is required. + * + * @param[in] p_ble_advdata Pointer to the description of the payload. + * + * @retval NRF_SUCCESS If the validation was successful. + * @retval NRF_ERROR_INVALID_PARAM Otherwise. + */ +static ret_code_t nfc_ep_oob_adv_data_check(ble_advdata_t const * const p_ble_advdata) +{ + if ((true == p_ble_advdata->include_ble_device_addr) || + (BLE_ADVDATA_ROLE_NOT_PRESENT != p_ble_advdata->le_role) || + (NULL == p_ble_advdata->p_sec_mgr_oob_flags)) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* If Flags field in AD structure is present, the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag + must be set. */ + if ((0 != p_ble_advdata->flags) && + ((p_ble_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0)) + { + return NRF_ERROR_INVALID_PARAM; + } + return NRF_SUCCESS; +} + +/** + * @brief Function for encoding device address to Bluetooth Carrier Configuration EP record. + * + * This fuction is used to encode device address to Bluetooth Carrier Configuration EP record. + * + * @param[in] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in] max_len Available memory in the buffer. + * + * @retval NRF_SUCCESS If the encoding was successful. + * @retval NRF_ERROR_NO_MEM If available memory was not enough. + * @retval NRF_ERROR_xxx If any other error occured. + */ +static ret_code_t nfc_ep_oob_bluetooth_device_address_encode(uint8_t * const p_encoded_data, + uint16_t max_len) +{ + ret_code_t err_code = NRF_SUCCESS; + ble_gap_addr_t device_address; + + memset(&device_address, 0x00, sizeof(device_address)); + + if (NFC_EP_OOB_REC_GAP_ADDR_LEN > max_len) + { + return NRF_ERROR_NO_MEM; + } + + /* Get BLE address */ + #if (NRF_SD_BLE_API_VERSION <= 2) + err_code = sd_ble_gap_address_get(&device_address); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + #endif + + #if (NRF_SD_BLE_API_VERSION >= 3) + err_code = sd_ble_gap_addr_get(&device_address); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + #endif + + /* Encode Bluetooth EP device address */ + memcpy(p_encoded_data, device_address.addr, NFC_EP_OOB_REC_GAP_ADDR_LEN); + + return NRF_SUCCESS; +} + +/** + * @brief Function for constructing the payload for a Bluetooth Carrier Configuration EP record. + * + * This function encodes the record payload according to the BLE AD structure. It implements + * an API compatible with @ref p_payload_constructor_t. + * + * @param[in] p_ble_advdata Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS If the record payload was encoded successfully. + * @retval NRF_ERROR_NO_MEM If available memory was not enough for record payload to be encoded. + * @retval Other If any other error occurred during record payload encoding. + */ +static ret_code_t nfc_ep_oob_payload_constructor(ble_advdata_t * p_ble_advdata, + uint8_t * p_buff, + uint32_t * p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + uint8_t * p_ad_data = NULL; + uint16_t payload_len, ad_data_len; + + /* Check correctness of the configuration structure */ + err_code = nfc_ep_oob_adv_data_check(p_ble_advdata); + if (NRF_SUCCESS != err_code) + { + return err_code; + } + + if (p_buff != NULL) + { + /* Validate if there is enough memory for OOB payload length field and BLE device address */ + if (NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + /* Set proper memory offset in payload buffer for AD structure and count available memory. + * Bluetooth EP device address and OOB payload length field must be inserted before the AD payload */ + p_ad_data = (uint8_t *) (p_buff + NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN); + ad_data_len = *p_len - NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN; + if ( *p_len - NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN > UINT16_MAX ) + { + ad_data_len = UINT16_MAX; + } + } + + /* Encode AD structures into NFC record payload */ + err_code = nfc_ble_oob_adv_data_encode(p_ble_advdata, p_ad_data, &ad_data_len); + if (NRF_SUCCESS != err_code) + { + return err_code; + } + + /* Now as the final payload length is known OOB payload length field, and Bluetooth device + * address can be encoded */ + payload_len = ad_data_len + NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN; + if (p_buff != NULL) + { + p_buff += uint16_encode(payload_len, p_buff); + err_code = nfc_ep_oob_bluetooth_device_address_encode(p_buff, p_ad_data - p_buff); + if (NRF_SUCCESS != err_code) + { + return err_code; + } + } + + /* Update total payload length */ + *p_len = payload_len; + + return err_code; +} + + +nfc_ndef_record_desc_t * nfc_ep_oob_rec_declare(uint8_t rec_payload_id, + ble_advdata_t const * const p_ble_advdata) +{ + static uint8_t payload_id = 0; + + NFC_NDEF_GENERIC_RECORD_DESC_DEF( nfc_ep_oob_rec, + TNF_MEDIA_TYPE, + &payload_id, // memory for possible ID value + 0, // no ID by default + (ep_oob_rec_type_field), + sizeof(ep_oob_rec_type_field), + nfc_ep_oob_payload_constructor, + NULL); + + nfc_ndef_record_desc_t * nfc_ep_oob_rec = &NFC_NDEF_GENERIC_RECORD_DESC( nfc_ep_oob_rec); + + /* Update record descriptor */ + nfc_ep_oob_rec->p_payload_descriptor = (void *) p_ble_advdata; + + /* Handle record ID configuration */ + payload_id = rec_payload_id; + nfc_ep_oob_rec->id_length = (rec_payload_id != 0) ? 1 : 0; + + return nfc_ep_oob_rec; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h new file mode 100644 index 0000000000000000000000000000000000000000..1ecb2ba9aa0e7e7991097514734022eeb96fbbaa --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_EP_OOB_REC_H__ +#define NFC_EP_OOB_REC_H__ + +/**@file + * + * @defgroup nfc_ep_oob_rec EP OOB records + * @{ + * @ingroup nfc_ble_pair_msg + * + * @brief Generation of NFC NDEF EP OOB records for NDEF messages. + * + */ + +#include +#include "nfc_ndef_record.h" +#include "nfc_ble_oob_advdata.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for generating a description of an NFC NDEF Bluetooth Carrier Configuration EP record. + * + * This function declares and initializes a static instance of an NFC NDEF record description + * for a Bluetooth Carrier Configuration EP record. + * + * @note The record payload data (@p p_ble_advdata) should be declared as static. If it is + * declared as automatic, the NDEF message encoding (see @ref nfc_ble_simplified_ep_oob_msg_encode) + * must be done in the same variable scope. + * + * @param[in] rec_payload_id NDEF record header Payload ID field (limited to one byte). + * If 0, no ID is present in the record description. + * @param[in] p_ble_advdata Pointer to the encoded BLE advertising data structure. This + * data is used to create the record payload. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_ep_oob_rec_declare(uint8_t rec_payload_id, + ble_advdata_t const * const p_ble_advdata); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_EP_OOB_REC_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c new file mode 100644 index 0000000000000000000000000000000000000000..7a2583d6ea795005b6621ace8e5ec33a8ce84bac --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nfc_hs_rec.h" +#include "nfc_ac_rec.h" +#include "nrf_error.h" + +#define HS_REC_VERSION_SIZE 1 + +const uint8_t nfc_hs_rec_type_field[] = {'H', 's'}; ///< Handover Select record type. + + +ret_code_t nfc_hs_rec_payload_constructor(nfc_hs_rec_payload_desc_t * p_nfc_hs_rec_payload_desc, + uint8_t * p_buff, + uint32_t * p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (p_buff != NULL) + { + // There must be at least 1 free byte in buffer for version byte. + if (*p_len < HS_REC_VERSION_SIZE) + { + return NRF_ERROR_NO_MEM; + } + + // Major/minor version byte. + *p_buff = ( (p_nfc_hs_rec_payload_desc->major_version << 4) & 0xF0) | + ( p_nfc_hs_rec_payload_desc->minor_version & 0x0F); + p_buff += HS_REC_VERSION_SIZE; + + // Decrement remaining buffer size. + *p_len -= HS_REC_VERSION_SIZE; + } + + // Encode local records encapsulated in a message. + err_code = nfc_ndef_msg_encode(p_nfc_hs_rec_payload_desc->p_local_records, p_buff, p_len); + if (err_code!= NRF_SUCCESS) + { + return err_code; + } + + // Add version byte to the total record size. + *p_len += HS_REC_VERSION_SIZE; + + return NRF_SUCCESS; +} + + +void nfc_hs_rec_local_record_clear(nfc_ndef_record_desc_t * p_hs_rec) +{ + nfc_hs_rec_payload_desc_t* p_hs_payload = + (nfc_hs_rec_payload_desc_t*)p_hs_rec->p_payload_descriptor; + + nfc_ndef_msg_clear(p_hs_payload->p_local_records); +} + + +ret_code_t nfc_hs_rec_local_record_add(nfc_ndef_record_desc_t * p_hs_rec, + nfc_ndef_record_desc_t * p_local_rec) +{ + nfc_hs_rec_payload_desc_t* p_hs_payload = + (nfc_hs_rec_payload_desc_t*)p_hs_rec->p_payload_descriptor; + + return nfc_ndef_msg_record_add(p_hs_payload->p_local_records, p_local_rec); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h new file mode 100644 index 0000000000000000000000000000000000000000..04ccfcedc230ccab5087885d2d4ac954b0d13ac3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h @@ -0,0 +1,161 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_HS_REC_H__ +#define NFC_HS_REC_H__ + +/**@file + * + * @defgroup nfc_hs_rec Hs (Handover Select) records + * @{ + * @ingroup nfc_ble_pair_msg + * + * @brief Generation of NFC NDEF Handover Select records for NDEF messages. + * + */ + +#include +#include "nfc_ndef_record.h" +#include "nfc_ndef_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Handover Select record payload descriptor. + */ +typedef struct +{ + uint8_t major_version; ///< Major version number of the supported Connection Handover specification. + uint8_t minor_version; ///< Minor version number of the supported Connection Handover specification. + nfc_ndef_msg_desc_t * p_local_records; ///< Pointer to a message encapsulating local records. +} nfc_hs_rec_payload_desc_t; + + +/** + * @brief Constructor for an NFC NDEF Handover Select record payload. + * + * This function encodes the payload of a Handover Select record as specified in the Connection + * Handover standard. It implements an API compatible with @ref p_payload_constructor_t. + */ + +ret_code_t nfc_hs_rec_payload_constructor(nfc_hs_rec_payload_desc_t * p_nfc_hs_rec_payload_desc, + uint8_t * p_buff, + uint32_t * p_len); + +/** + * @brief An external reference to the type field of the Handover Select record, defined in the + * file @c nfc_hs_rec.c. It is used in the @ref NFC_NDEF_HS_RECORD_DESC_DEF macro. + */ +extern const uint8_t nfc_hs_rec_type_field[]; + +/** + * @brief Size of the type field of the Handover Select record, defined in the + * file @c nfc_hs_rec.c. It is used in the @ref NFC_NDEF_HS_RECORD_DESC_DEF macro. + */ +#define NFC_HS_REC_TYPE_LENGTH 2 + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor for a Handover Select record. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t and + * a static instance of type @ref nfc_hs_rec_payload_desc_t, which together constitute an instance of a Handover Select record. + * + * Use the macro @ref NFC_NDEF_HS_RECORD_DESC to access the NDEF Handover Select record descriptor instance. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] MAJOR_VERSION Major version number of the supported Connection Handover specification. + * @param[in] MINOR_VERSION Minor version number of the supported Connection Handover specification. + * @param[in] MAX_RECORDS Maximum number of local records (ac records plus optional err record). + */ +#define NFC_NDEF_HS_RECORD_DESC_DEF(NAME, \ + MAJOR_VERSION, \ + MINOR_VERSION, \ + MAX_RECORDS) \ + NFC_NDEF_MSG_DEF(NAME, MAX_RECORDS); \ + static nfc_hs_rec_payload_desc_t NAME##_nfc_hs_rec_payload_desc = \ + { \ + .major_version = MAJOR_VERSION, \ + .minor_version = MINOR_VERSION, \ + .p_local_records = &NFC_NDEF_MSG(NAME) \ + }; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF_WELL_KNOWN, \ + 0, \ + 0, \ + nfc_hs_rec_type_field , \ + NFC_HS_REC_TYPE_LENGTH, \ + nfc_hs_rec_payload_constructor, \ + &(NAME##_nfc_hs_rec_payload_desc)) + +/** + * @brief Macro for accessing the NFC NDEF Handover Select record descriptor + * instance that was created with @ref NFC_NDEF_HS_RECORD_DESC_DEF. + */ +#define NFC_NDEF_HS_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** + * @brief Function for clearing local records in the NFC NDEF Handover Select record. + * + * This function clears local records from the Handover Select record. + * + * @param[in, out] p_hs_rec Pointer to the Handover Select record descriptor. + */ +void nfc_hs_rec_local_record_clear(nfc_ndef_record_desc_t * p_hs_rec); + +/** + * @brief Function for adding a local record to an NFC NDEF Handover Select record. + * + * @param[in, out] p_hs_rec Pointer to a Handover Select record. + * @param[in] p_local_rec Pointer to a local record to add. + * + * @retval NRF_SUCCESS If the local record was added successfully. + * @retval NRF_ERROR_NO_MEM If the Handover Select record already contains the maximum number of local records. + */ +ret_code_t nfc_hs_rec_local_record_add(nfc_ndef_record_desc_t * p_hs_rec, + nfc_ndef_record_desc_t * p_local_rec); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_HS_REC_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c new file mode 100644 index 0000000000000000000000000000000000000000..b60c2132a7072db4f958fab0c426d2d168cdf59a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c @@ -0,0 +1,143 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nfc_le_oob_rec.h" +#include "sdk_errors.h" +#include "ble_gap.h" +#include "nfc_ble_pair_common.h" + +/** + * @brief Function for validating AD structure content for a Bluetooth Carrier Configuration LE record. + * + * This function validates AD structure content. LE Bluetooth Device Address and LE Role + * fields are required. Security Manager Out Of Band Flags structure must not be included. + * + * @param[in] p_ble_advdata Pointer to the description of the payload. + * + * @retval NRF_SUCCESS If the validation was successful. + * @retval NRF_ERROR_INVALID_PARAM Otherwise. + */ +static ret_code_t nfc_le_oob_adv_data_check(ble_advdata_t const * const p_ble_advdata) +{ + if ((false == p_ble_advdata->include_ble_device_addr) || + (BLE_ADVDATA_ROLE_NOT_PRESENT == p_ble_advdata->le_role) || + (NULL != p_ble_advdata->p_sec_mgr_oob_flags)) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* If Flags field in AD structure is present, the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag + must be set. */ + if ((0 != p_ble_advdata->flags) && + ((p_ble_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0)) + { + return NRF_ERROR_INVALID_PARAM; + } + + return NRF_SUCCESS; +} + +/** + * @brief Function for constructing the payload for a Bluetooth Carrier Configuration LE record. + * + * This function encodes the record payload according to the BLE AD structure. It implements + * an API compatible with @ref p_payload_constructor_t + * + * @param[in] p_ble_advdata Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS If the record payload was encoded successfully. + * @retval Other If the record payload encoding failed. + */ +static ret_code_t nfc_le_oob_payload_constructor(ble_advdata_t * p_ble_advdata, + uint8_t * p_buff, + uint32_t * p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + + /* Check correctness of the configuration structure */ + err_code = nfc_le_oob_adv_data_check(p_ble_advdata); + if (NRF_SUCCESS != err_code) + { + return err_code; + } + + /* Encode AD structures into NFC record payload */ + uint16_t buff_len = *p_len; + if (*p_len > UINT16_MAX) + { + buff_len = UINT16_MAX; + } + err_code = nfc_ble_oob_adv_data_encode(p_ble_advdata, p_buff, &buff_len); + + /* Update total payload length */ + *p_len = (uint32_t) buff_len; + + return err_code; +} + +nfc_ndef_record_desc_t * nfc_le_oob_rec_declare(uint8_t rec_payload_id, + ble_advdata_t const * const p_ble_advdata) +{ + static uint8_t payload_id = 0; + + NFC_NDEF_GENERIC_RECORD_DESC_DEF( nfc_le_oob_rec, + TNF_MEDIA_TYPE, + &payload_id, // memory for possible ID value + 0, // no ID by default + (le_oob_rec_type_field), + sizeof(le_oob_rec_type_field), + nfc_le_oob_payload_constructor, + NULL); + + nfc_ndef_record_desc_t * nfc_le_oob_rec = &NFC_NDEF_GENERIC_RECORD_DESC( nfc_le_oob_rec); + + /* Update record descriptor */ + nfc_le_oob_rec->p_payload_descriptor = (void *) p_ble_advdata; + + /* Handle record ID configuration */ + payload_id = rec_payload_id; + nfc_le_oob_rec->id_length = (rec_payload_id != 0) ? 1 : 0; + + return nfc_le_oob_rec; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h new file mode 100644 index 0000000000000000000000000000000000000000..dc34461005d7bb79d11b42d385e5ae0d494cabf5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_LE_OOB_REC_H__ +#define NFC_LE_OOB_REC_H__ + +/**@file + * + * @defgroup nfc_le_oob_rec LE OOB records + * @{ + * @ingroup nfc_ble_pair_msg + * + * @brief Generation of NFC NDEF LE OOB records for NDEF messages. + * + */ + +#include +#include "nfc_ndef_record.h" +#include "nfc_ble_oob_advdata.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for generating a description of an NFC NDEF Bluetooth Carrier Configuration LE Record. + * + * This function declares and initializes a static instance of an NFC NDEF record description + * for a Bluetooth Carrier Configuration LE record. + * + * @note The record payload data (@p p_ble_advdata) should be declared as static. If it is + * declared as automatic, the NDEF message encoding (see @ref nfc_ble_simplified_le_oob_msg_encode) + * must be done in the same variable scope. + * + * @param[in] rec_payload_id NDEF record header Payload ID field (Limited to one byte). + * If 0, no ID is present in the record description. + * @param[in] p_ble_advdata Pointer to the encoded BLE advertising data structure. This + * data is used to create the record payload. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_le_oob_rec_declare(uint8_t rec_payload_id, + ble_advdata_t const * const p_ble_advdata); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_LE_OOB_REC_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/generic/message/nfc_ndef_msg.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/generic/message/nfc_ndef_msg.c new file mode 100644 index 0000000000000000000000000000000000000000..2b74b570cccb77513d093d63206e13f2572a110d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/generic/message/nfc_ndef_msg.c @@ -0,0 +1,185 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if NFC_NDEF_MSG_ENABLED + +#include "app_util.h" +#include "nfc_ndef_msg.h" +#include "nordic_common.h" +#include "nrf.h" + +#define TYPE_4_TAG 4U ///< Type 4 Tag identifier. +#define NLEN_FIELD_SIZE 2U ///< Size of NLEN field, used to encode NDEF message for Type 4 Tag. + +/** + * @brief Resolve the value of record location flags of the NFC NDEF record within an NFC NDEF message. + */ +__STATIC_INLINE nfc_ndef_record_location_t record_location_get(uint32_t index, + uint32_t record_count) +{ + nfc_ndef_record_location_t record_location; + + if (index == 0) + { + if (record_count == 1) + { + record_location = NDEF_LONE_RECORD; + } + else + { + record_location = NDEF_FIRST_RECORD; + } + } + else if (record_count == index + 1) + { + record_location = NDEF_LAST_RECORD; + } + else + { + record_location = NDEF_MIDDLE_RECORD; + } + + return record_location; +} + + +ret_code_t nfc_ndef_msg_encode(nfc_ndef_msg_desc_t const * p_ndef_msg_desc, + uint8_t * p_msg_buffer, + uint32_t * const p_msg_len) +{ + nfc_ndef_record_location_t record_location; + uint32_t temp_len; + uint32_t i; + uint32_t err_code; + + uint32_t sum_of_len = 0; + + if ((p_ndef_msg_desc == NULL) || p_msg_len == NULL) + { + return NRF_ERROR_NULL; + } + + nfc_ndef_record_desc_t * * pp_record_rec_desc = p_ndef_msg_desc->pp_record; + + if (p_ndef_msg_desc->pp_record == NULL) + { + return NRF_ERROR_NULL; + } + +#if NFC_NDEF_MSG_TAG_TYPE == TYPE_4_TAG + uint8_t * p_root_msg_buffer = p_msg_buffer; + + if (p_msg_buffer != NULL) + { + if (*p_msg_len < NLEN_FIELD_SIZE) + { + return NRF_ERROR_NO_MEM; + } + + p_msg_buffer += NLEN_FIELD_SIZE; + } + sum_of_len += NLEN_FIELD_SIZE; +#endif + + for (i = 0; i < p_ndef_msg_desc->record_count; i++) + { + record_location = record_location_get(i, p_ndef_msg_desc->record_count); + + temp_len = *p_msg_len - sum_of_len; + + err_code = nfc_ndef_record_encode(*pp_record_rec_desc, + record_location, + p_msg_buffer, + &temp_len); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + sum_of_len += temp_len; + if (p_msg_buffer != NULL) + { + p_msg_buffer += temp_len; + } + + /* next record */ + pp_record_rec_desc++; + } + +#if NFC_NDEF_MSG_TAG_TYPE == TYPE_4_TAG + if (p_msg_buffer != NULL) + { + if (sum_of_len - NLEN_FIELD_SIZE > UINT16_MAX) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + UNUSED_RETURN_VALUE(uint16_big_encode(sum_of_len - NLEN_FIELD_SIZE, p_root_msg_buffer)); + } +#endif + + *p_msg_len = sum_of_len; + + return NRF_SUCCESS; +} + + +void nfc_ndef_msg_clear(nfc_ndef_msg_desc_t * p_msg) +{ + p_msg->record_count = 0; +} + + +ret_code_t nfc_ndef_msg_record_add(nfc_ndef_msg_desc_t * const p_msg, + nfc_ndef_record_desc_t * const p_record) +{ + if (p_msg->record_count >= p_msg->max_record_count) + { + return NRF_ERROR_NO_MEM; + } + + p_msg->pp_record[p_msg->record_count] = p_record; + p_msg->record_count++; + + return NRF_SUCCESS; +} + +#endif // NFC_NDEF_MSG_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/generic/message/nfc_ndef_msg.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/generic/message/nfc_ndef_msg.h new file mode 100644 index 0000000000000000000000000000000000000000..650363080ab81e1cfe2029ec24ac802b8f90be0c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/generic/message/nfc_ndef_msg.h @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_NDEF_MSG_H__ +#define NFC_NDEF_MSG_H__ + +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif +/**@file + * + * @defgroup nfc_ndef_msg Custom NDEF messages + * @{ + * @ingroup nfc_modules + * + * @brief Generation of NFC NDEF messages for the NFC tag. + * + */ + + /** + * @brief NDEF message descriptor. + */ + typedef struct { + nfc_ndef_record_desc_t ** pp_record; ///< Pointer to an array of pointers to NDEF record descriptors. + uint32_t max_record_count; ///< Number of elements in the allocated pp_record array, which defines the maximum number of records within the NDEF message. + uint32_t record_count; ///< Number of records in the NDEF message. + } nfc_ndef_msg_desc_t; + + /** + * @brief Function for encoding an NDEF message. + * + * This function encodes an NDEF message according to the provided message descriptor. + * + * @note The way of encoding an NDEF message may vary depending on tag's platform, which + * can be chosen with @ref NFC_NDEF_MSG_TAG_TYPE in @c sdk_config.h. + * + * @param[in] p_ndef_msg_desc Pointer to the message descriptor. + * @param[out] p_msg_buffer Pointer to the message destination. If NULL, function will + * calculate the expected size of the message. + * @param[in,out] p_msg_len Size of the available memory for the message as input. Size of + * the generated message as output. + * + * @return Return value from @ref nfc_ndef_record_encode. + */ +ret_code_t nfc_ndef_msg_encode(nfc_ndef_msg_desc_t const * p_ndef_msg_desc, + uint8_t * p_msg_buffer, + uint32_t * const p_msg_len); + +/** + * @brief Function for clearing an NDEF message. + * + * This function clears an NDEF message descriptor, thus empties the NDEF message. + * + * @param[in,out] p_msg Pointer to the message descriptor. + */ +void nfc_ndef_msg_clear( nfc_ndef_msg_desc_t * p_msg); + +/** + * @brief Function for adding a record to an NDEF message. + * + * @param[in] p_record Pointer to the record descriptor. + * @param[in,out] p_msg Pointer to the message descriptor. + * + * @retval NRF_SUCCESS If the record was added successfully. + * @retval NRF_ERROR_NO_MEM If the message already contains the maximum number of records and the operation is not allowed. + */ +ret_code_t nfc_ndef_msg_record_add(nfc_ndef_msg_desc_t * const p_msg, + nfc_ndef_record_desc_t * const p_record); + + +/**@brief Macro for creating and initializing an NFC NDEF message descriptor. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_msg_desc_t + * and a static array of pointers to record descriptors (@ref nfc_ndef_record_desc_t) used + * by the message. + * + * Use the macro @ref NFC_NDEF_MSG to access the NDEF message descriptor instance. + * + * @param[in] NAME Name of the related instance. + * @param[in] MAX_RECORD_CNT Maximal count of records in the message. + */ +#define NFC_NDEF_MSG_DEF(NAME, MAX_RECORD_CNT) \ + static nfc_ndef_record_desc_t * NAME##_nfc_ndef_p_record_desc_array[MAX_RECORD_CNT]; \ + static nfc_ndef_msg_desc_t NAME##_nfc_ndef_msg_desc = \ + { \ + .pp_record = NAME##_nfc_ndef_p_record_desc_array, \ + .record_count = 0, \ + .max_record_count = MAX_RECORD_CNT \ + } + +/** @brief Macro for accessing the NFC NDEF message descriptor instance + * that you created with @ref NFC_NDEF_MSG_DEF. + */ +#define NFC_NDEF_MSG(NAME) (NAME##_nfc_ndef_msg_desc) + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor with an encapsulated NDEF message. + + * This macro creates and initializes a static instance of type + * @ref nfc_ndef_record_desc_t that contains an encapsulated NDEF message as + * payload. @ref nfc_ndef_msg_encode is used as payload constructor to encode + * the message. The encoded message is then used as payload for the record. + * + * Use the macro @ref NFC_NDEF_NESTED_NDEF_MSG_RECORD to access the NDEF record descriptor instance. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] TNF Type Name Format (TNF) value for the record. + * @param[in] P_ID Pointer to the ID string. + * @param[in] ID_LEN Length of the ID string. + * @param[in] P_TYPE Pointer to the type string. + * @param[in] TYPE_LEN Length of the type string. + * @param[in] P_NESTED_MESSAGE Pointer to the message descriptor to encapsulate + * as the record's payload. + */ +#define NFC_NDEF_NESTED_NDEF_MSG_RECORD_DEF( NAME, \ + TNF, \ + P_ID, \ + ID_LEN, \ + P_TYPE, \ + TYPE_LEN, \ + P_NESTED_MESSAGE ) \ + static nfc_ndef_record_desc_t NAME##_ndef_record_nested_desc = \ + { \ + .tnf = TNF, \ + \ + .id_length = ID_LEN, \ + .p_id = P_ID, \ + \ + .type_length = TYPE_LEN, \ + .p_type = P_TYPE, \ + \ + .payload_constructor = (p_payload_constructor_t)(nfc_ndef_msg_encode), \ + .p_payload_descriptor = (void*) (P_NESTED_MESSAGE) \ + } + +/** @brief Macro for accessing the NFC NDEF record descriptor instance + * that you created with @ref NFC_NDEF_NESTED_NDEF_MSG_RECORD_DEF. + */ +#define NFC_NDEF_NESTED_NDEF_MSG_RECORD(NAME) (NAME##_ndef_record_nested_desc) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + #endif + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/generic/record/nfc_ndef_record.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/generic/record/nfc_ndef_record.c new file mode 100644 index 0000000000000000000000000000000000000000..1f6fd00c09e1a9eb95112c8cf58c70b9db2b9486 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/generic/record/nfc_ndef_record.c @@ -0,0 +1,187 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "nfc_ndef_record.h" +#include "app_util.h" +#include "nrf.h" + + +/* Sum of sizes of fields: TNF-flags, Type Length, Payload Length in long NDEF record. */ +#define NDEF_RECORD_BASE_LONG_SIZE (2 + NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE) + +__STATIC_INLINE uint32_t record_header_size_calc(nfc_ndef_record_desc_t const * p_ndef_record_desc) +{ + uint32_t len = NDEF_RECORD_BASE_LONG_SIZE; + + len += p_ndef_record_desc->id_length + p_ndef_record_desc->type_length; + + if (p_ndef_record_desc->id_length > 0) + { + len++; + } + + return len; +} + + +ret_code_t nfc_ndef_record_encode(nfc_ndef_record_desc_t const * p_ndef_record_desc, + nfc_ndef_record_location_t record_location, + uint8_t * p_record_buffer, + uint32_t * p_record_len) +{ + uint8_t * p_flags; // use as pointer to TNF + flags field + uint8_t * p_payload_len = NULL; // use as pointer to payload length field + uint32_t record_payload_len; + + if (p_ndef_record_desc == NULL) + { + return NRF_ERROR_NULL; + } + + // count record length without payload + uint32_t record_header_len = record_header_size_calc(p_ndef_record_desc); + uint32_t err_code = NRF_SUCCESS; + + if (p_record_buffer != NULL) + { + /* verify location range */ + if ((record_location & (~NDEF_RECORD_LOCATION_MASK)) != 0x00) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* verify if there is enough available memory */ + if (record_header_len > *p_record_len) + { + return NRF_ERROR_NO_MEM; + } + + p_flags = p_record_buffer; + p_record_buffer++; + + // set location bits and clear other bits in 1st byte. + *p_flags = record_location; + + *p_flags |= p_ndef_record_desc->tnf; + + /* TYPE LENGTH */ + *(p_record_buffer++) = p_ndef_record_desc->type_length; + + // use always long record and remember payload len field memory offset. + p_payload_len = p_record_buffer; + p_record_buffer += NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE; + + /* ID LENGTH - option */ + if (p_ndef_record_desc->id_length > 0) + { + *(p_record_buffer++) = p_ndef_record_desc->id_length; + + /* IL flag */ + *p_flags |= NDEF_RECORD_IL_MASK; + } + + /* TYPE */ + memcpy(p_record_buffer, p_ndef_record_desc->p_type, p_ndef_record_desc->type_length); + p_record_buffer += p_ndef_record_desc->type_length; + + /* ID */ + if (p_ndef_record_desc->id_length > 0) + { + memcpy(p_record_buffer, p_ndef_record_desc->p_id, p_ndef_record_desc->id_length); + p_record_buffer += p_ndef_record_desc->id_length; + } + + // count how much memory is left in record buffer for payload field. + record_payload_len = (*p_record_len - record_header_len); + } + + /* PAYLOAD */ + if (p_ndef_record_desc->payload_constructor != NULL) + { + err_code = + p_ndef_record_desc->payload_constructor(p_ndef_record_desc->p_payload_descriptor, + p_record_buffer, + &record_payload_len); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else + { + return NRF_ERROR_NULL; + } + + if (p_record_buffer != NULL) + { + /* PAYLOAD LENGTH */ + (void) uint32_big_encode(record_payload_len, p_payload_len); + } + + *p_record_len = record_header_len + record_payload_len; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_ndef_bin_payload_memcopy(nfc_ndef_bin_payload_desc_t * p_payload_descriptor, + uint8_t * p_buffer, + uint32_t * p_len) +{ + + if (p_buffer != NULL) + { + if ( *p_len < p_payload_descriptor->payload_length) + { + return NRF_ERROR_NO_MEM; + } + + memcpy(p_buffer, + p_payload_descriptor->p_payload, + p_payload_descriptor->payload_length); + } + + *p_len = p_payload_descriptor->payload_length; + + return NRF_SUCCESS; +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/generic/record/nfc_ndef_record.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/generic/record/nfc_ndef_record.h new file mode 100644 index 0000000000000000000000000000000000000000..cd9185d7428c811af563225947853ecba34d70aa --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/generic/record/nfc_ndef_record.h @@ -0,0 +1,305 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_NDEF_RECORD_H__ +#define NFC_NDEF_RECORD_H__ + +#include +#include +#include "compiler_abstraction.h" +#include "sdk_errors.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@file + * + * @defgroup nfc_ndef_record Custom NDEF records + * @{ + * @ingroup nfc_ndef_msg + * + * @brief Generation of NFC NDEF records for NFC messages. + * + */ + + +#define NDEF_RECORD_IL_MASK 0x08 ///< Mask of the ID field presence bit in the flags byte of an NDEF record. +#define NDEF_RECORD_TNF_MASK 0x07 ///< Mask of the TNF value field in the first byte of an NDEF record. +#define NDEF_RECORD_SR_MASK 0x10 ///< Mask of the SR flag. If set, this flag indicates that the PAYLOAD_LENGTH field has a size of 1 byte. Otherwise, PAYLOAD_LENGTH has 4 bytes. +#define NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE 4 ///< Size of the Payload Length field in a long NDEF record. +#define NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE 1 ///< Size of the Payload Length field in a short NDEF record. +#define NDEF_RECORD_ID_LEN_SIZE 1 ///< Size of the ID Length field in an NDEF record. + + +/** + * @brief Payload constructor type. + + * A payload constructor is a function for constructing the payload of an NDEF + * record. + * + * @param[in] p_payload_descriptor Pointer to the input data for the constructor. + * @param[out] p_buffer Pointer to the payload destination. If NULL, function will + * calculate the expected size of the record payload. + * + * @param[in,out] p_len Size of the available memory to write as input. Size of the generated + * record payload as output. The implementation must check if the payload + * will fit in the provided buffer. This must be checked by the caller function. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +typedef ret_code_t (* p_payload_constructor_t)(void * p_payload_descriptor, + uint8_t * p_buffer, + uint32_t * p_len); + + +/** + * @brief Type Name Format (TNF) Field Values. + * + * Values to specify the TNF of a record. + */ +typedef enum +{ + TNF_EMPTY = 0x00, ///< The value indicates that there is no type or payload associated with this record. + TNF_WELL_KNOWN = 0x01, ///< NFC Forum well-known type [NFC RTD]. + TNF_MEDIA_TYPE = 0x02, ///< Media-type as defined in RFC 2046 [RFC 2046]. + TNF_ABSOLUTE_URI = 0x03, ///< Absolute URI as defined in RFC 3986 [RFC 3986]. + TNF_EXTERNAL_TYPE = 0x04, ///< NFC Forum external type [NFC RTD]. + TNF_UNKNOWN_TYPE = 0x05, ///< The value indicates that there is no type associated with this record. + TNF_UNCHANGED = 0x06, ///< The value is used for the record chunks used in chunked payload. + TNF_RESERVED = 0x07, ///< The value is reserved for future use. +} nfc_ndef_record_tnf_t; + + +/** + * @brief NDEF record descriptor. + */ +typedef struct +{ + nfc_ndef_record_tnf_t tnf; ///< Value of the Type Name Format (TNF) field. + + uint8_t id_length; ///< Length of the ID field. If 0, a record format without ID field is assumed. + uint8_t const * p_id; ///< Pointer to the ID field data. Not relevant if id_length is 0. + + uint8_t type_length; ///< Length of the type field. + uint8_t const * p_type; ///< Pointer to the type field data. Not relevant if type_length is 0. + + p_payload_constructor_t payload_constructor; ///< Pointer to the payload constructor function. + void * p_payload_descriptor; ///< Pointer to the data for the payload constructor function. + +} nfc_ndef_record_desc_t; + +/** + * @brief Record position within the NDEF message. + * + * Values to specify the location of a record within the NDEF message. + */ +typedef enum +{ + NDEF_FIRST_RECORD = 0x80, ///< First record. + NDEF_MIDDLE_RECORD = 0x00, ///< Middle record. + NDEF_LAST_RECORD = 0x40, ///< Last record. + NDEF_LONE_RECORD = 0xC0 ///< Only one record in the message. +} nfc_ndef_record_location_t; + +#define NDEF_RECORD_LOCATION_MASK (NDEF_LONE_RECORD) ///< Mask of the Record Location bits in the NDEF record's flags byte. + +/** + * @brief Binary data descriptor containing the payload for the record. + */ +typedef struct +{ + uint8_t const * p_payload; ///< Pointer to the buffer with the data. + uint32_t payload_length; ///< Length of data in bytes. +} nfc_ndef_bin_payload_desc_t; + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor for a generic record. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t. + * + * Use the macro @ref NFC_NDEF_GENERIC_RECORD_DESC to access the NDEF record descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] TNF Type Name Format (TNF) value for the record. + * @param[in] P_ID Pointer to the ID string. + * @param[in] ID_LEN Length of the ID string. + * @param[in] P_TYPE Pointer to the type string. + * @param[in] TYPE_LEN Length of the type string. + * @param[in] P_PAYLOAD_CONSTRUCTOR Pointer to the payload constructor function. + * The constructor must be of type @ref p_payload_constructor_t. + * @param[in] P_PAYLOAD_DESCRIPTOR Pointer to the data for the payload constructor. + */ +#define NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF, \ + P_ID, \ + ID_LEN, \ + P_TYPE, \ + TYPE_LEN, \ + P_PAYLOAD_CONSTRUCTOR, \ + P_PAYLOAD_DESCRIPTOR) \ + static nfc_ndef_record_desc_t NAME##_ndef_generic_record_desc = \ + { \ + .tnf = TNF, \ + \ + .id_length = ID_LEN, \ + .p_id = P_ID, \ + \ + .type_length = TYPE_LEN, \ + .p_type = P_TYPE, \ + \ + .payload_constructor = (p_payload_constructor_t)P_PAYLOAD_CONSTRUCTOR, \ + .p_payload_descriptor = (void *) P_PAYLOAD_DESCRIPTOR \ + } + + +/** @brief Macro for accessing the NFC NDEF record descriptor instance + * that you created with @ref NFC_NDEF_GENERIC_RECORD_DESC_DEF. + */ +#define NFC_NDEF_GENERIC_RECORD_DESC(NAME) (NAME##_ndef_generic_record_desc) + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor for a record with + * binary payload. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t and a binary data descriptor containing the payload data. + * + * Use the macro @ref NFC_NDEF_RECORD_BIN_DATA to access the NDEF record descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] TNF Type Name Format (TNF) value for the record. + * @param[in] P_ID Pointer to the ID string. + * @param[in] ID_LEN Length of the ID string. + * @param[in] P_TYPE Pointer to the type string. + * @param[in] TYPE_LEN Length of the type string. + * @param[in] P_PAYLOAD Pointer to the payload data that will be copied to the payload field. + * @param[in] PAYLOAD_LEN Length of the payload. + */ +#define NFC_NDEF_RECORD_BIN_DATA_DEF(NAME, \ + TNF, \ + P_ID, ID_LEN, \ + P_TYPE, \ + TYPE_LEN, \ + P_PAYLOAD, \ + PAYLOAD_LEN) \ + static nfc_ndef_bin_payload_desc_t NAME##_nfc_ndef_bin_payload_desc = \ + { \ + .p_payload = P_PAYLOAD, \ + .payload_length = PAYLOAD_LEN \ + }; \ + \ + static nfc_ndef_record_desc_t NAME##_nfc_ndef_bin_record_desc = \ + { \ + .tnf = TNF, \ + \ + .id_length = ID_LEN, \ + .p_id = P_ID, \ + \ + .type_length = TYPE_LEN, \ + .p_type = P_TYPE, \ + \ + .payload_constructor = (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy, \ + .p_payload_descriptor = (void *) &NAME##_nfc_ndef_bin_payload_desc \ + } + + +/** @brief Macro for accessing the NFC NDEF record descriptor instance + * that you created with @ref NFC_NDEF_RECORD_BIN_DATA_DEF. + */ +#define NFC_NDEF_RECORD_BIN_DATA(NAME) (NAME##_nfc_ndef_bin_record_desc) + +/** @brief Macro for accessing the binary data descriptor that contains + * the payload of the record that you created with @ref NFC_NDEF_RECORD_BIN_DATA_DEF. + */ +#define NFC_NDEF_BIN_PAYLOAD_DESC(NAME) (NAME##_nfc_ndef_bin_payload_desc) + +/** + * @brief Function for encoding an NDEF record. + * + * This function encodes an NDEF record according to the provided record descriptor. + * + * @param[in] p_ndef_record_desc Pointer to the record descriptor. + * @param[in] record_location Location of the record within the NDEF message. + * @param[out] p_record_buffer Pointer to the record destination. If NULL, function will + * calculate the expected size of the record. + * @param[in,out] p_record_len Size of the available memory for the record as input. Size of the generated + * record as output. + * + * @retval NRF_SUCCESS If the record was encoded successfully. + * @retval NRF_ERROR_NO_MEM If the predicted record size is bigger than the provided buffer space. + * @retval NRF_ERROR_INVALID_PARAM If the location of the record is erroneous. + * @retval Other Other codes might be returned depending on the NDEF record payload constructor implementation. + */ +ret_code_t nfc_ndef_record_encode(nfc_ndef_record_desc_t const * p_ndef_record_desc, + nfc_ndef_record_location_t record_location, + uint8_t * p_record_buffer, + uint32_t * p_record_len); + +/** + * @brief Function for constructing the payload for an NFC NDEF record from binary data. + * + * This function copies data from a binary buffer to the payload field of the NFC NDEF record. + * + * @param[in] p_payload_descriptor Pointer to the descriptor of the binary data location and size. + * + * @param[out] p_buffer Pointer to the payload destination. If NULL, function will + * calculate the expected size of the record payload. + * @param[in,out] p_len Size of the available memory for the payload as input. Size of the copied payload + * as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the payload size is bigger than the provided buffer space. + */ +ret_code_t nfc_ndef_bin_payload_memcopy(nfc_ndef_bin_payload_desc_t * p_payload_descriptor, + uint8_t * p_buffer, + uint32_t * p_len); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NFC_NDEF_RECORD_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/launchapp/nfc_launchapp_msg.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/launchapp/nfc_launchapp_msg.c new file mode 100644 index 0000000000000000000000000000000000000000..5f958672a317ad2bec707c2838c7b79a61d3f1cc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/launchapp/nfc_launchapp_msg.c @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "nfc_launchapp_rec.h" +#include "nfc_launchapp_msg.h" +#include "nrf_error.h" + +/** @brief Function for generating a description of an NFC NDEF launch application message. + * + * This function declares and initializes a static instance of an NFC NDEF message description + * and the NFC NDEF record descriptions that are referenced by this message description. + * + * @param[in] p_android_package_name Pointer to the Android package name string. + * If NULL, the Android Application Record will be skipped. + * @param[in] android_package_name_length Length of the Android package name. + * @param[in] p_win_app_id Pointer to the Windows application ID string (GUID). + * If NULL, the Windows LaunchApp Record will be skipped. + * @param[in] win_app_id_length Length of the Windows application ID. + * @param[out] pp_launchapp_msg_desc Pointer to pointer to the NDEF message description. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If both p_android_package_name and windows_application_id were + * invalid (equal to NULL). + */ +__STATIC_INLINE ret_code_t nfc_launchapp_msg_declare(uint8_t const * p_android_package_name, + uint8_t android_package_name_length, + uint8_t const * p_win_app_id, + uint8_t win_app_id_length, + nfc_ndef_msg_desc_t ** pp_launchapp_msg_desc) +{ + + uint32_t err_code; + + nfc_ndef_record_desc_t * p_win_rec, * p_android_rec; + + /* Create NFC NDEF message description, capacity - 2 records */ + NFC_NDEF_MSG_DEF(nfc_launchapp_msg, 2); + + /* The message description is static, therefore you must */ + /* clear the message (needed for supporting multiple calls). */ + nfc_ndef_msg_clear(&NFC_NDEF_MSG(nfc_launchapp_msg)); + + if (p_win_app_id != NULL) + { + /* Create NFC NDEF Windows Phone LaunchApp Record description */ + p_win_rec = nfc_windows_launchapp_rec_declare(p_win_app_id, + win_app_id_length); + + /* Add Windows LaunchApp record as first record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_launchapp_msg), p_win_rec); + + if (err_code != NRF_SUCCESS) + return err_code; + } + + if (p_android_package_name != NULL) + { + /* Create NFC NDEF Android Application Record description */ + p_android_rec = nfc_android_application_rec_declare(p_android_package_name, + android_package_name_length); + + /* Add Android App Record as second record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_launchapp_msg), p_android_rec); + + if (err_code != NRF_SUCCESS) + return err_code; + } + + if (NFC_NDEF_MSG(nfc_launchapp_msg).record_count == 0) + { + return NRF_ERROR_INVALID_PARAM; + } + + *pp_launchapp_msg_desc = &NFC_NDEF_MSG(nfc_launchapp_msg); + + return NRF_SUCCESS; +} + + +ret_code_t nfc_launchapp_msg_encode(uint8_t const * p_android_package_name, + uint8_t android_package_name_length, + uint8_t const * p_win_app_id, + uint8_t win_app_id_length, + uint8_t * p_buf, + uint32_t * p_len) +{ + nfc_ndef_msg_desc_t * p_launchapp_msg_desc; + ret_code_t err_code; + + err_code = nfc_launchapp_msg_declare(p_android_package_name, + android_package_name_length, + p_win_app_id, + win_app_id_length, + &p_launchapp_msg_desc); + + if (err_code != NRF_SUCCESS) + return err_code; + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(p_launchapp_msg_desc, + p_buf, + p_len); + + return err_code; +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/launchapp/nfc_launchapp_msg.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/launchapp/nfc_launchapp_msg.h new file mode 100644 index 0000000000000000000000000000000000000000..294e6d86afa4cedfaf6777c9289fcb6d8dc2b6ac --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/launchapp/nfc_launchapp_msg.h @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_LAUNCHAPP_MSG_H__ +#define NFC_LAUNCHAPP_MSG_H__ + +/** @file + * + * @defgroup nfc_launch_app_msg Launch app messages + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF messages that can be used to launch apps. + * + */ + +#include +#include "nfc_ndef_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Function for encoding an NFC NDEF launch app message. + * + * This function encodes an NFC NDEF message into a buffer. + * + * @param[in] p_android_package_name Pointer to the Android package name string. + * If NULL, the Android Application Record will be skipped. + * @param[in] android_package_name_length Length of the Android package name. + * @param[in] p_win_app_id Pointer to the Windows application ID string (GUID). + * If NULL, the Windows LaunchApp record will be skipped. + * @param[in] win_app_id_length Length of the Windows application ID. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If both p_android_package_name and windows_application_id were + * invalid (equal to NULL). + * @retval NRF_ERROR_NO_MEM If the predicted message size is bigger than the provided + * buffer space. + * @retval Other Other codes might be returned depending on + * the function @ref nfc_ndef_msg_encode + */ +ret_code_t nfc_launchapp_msg_encode(uint8_t const * p_android_package_name, + uint8_t android_package_name_length, + uint8_t const * p_win_app_id, + uint8_t win_app_id_length, + uint8_t * p_buf, + uint32_t * p_len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + #endif // NFC_LAUNCHAPP_MSG_H__ + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/launchapp/nfc_launchapp_rec.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/launchapp/nfc_launchapp_rec.c new file mode 100644 index 0000000000000000000000000000000000000000..b4bb8d0d2a53ac5d89ccc0452ea309e9ec7fc860 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/launchapp/nfc_launchapp_rec.c @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "nrf_error.h" +#include "app_util.h" +#include "nfc_ndef_record.h" + +/** + * @brief Type of description of payload of Windows LaunchApp record. + */ +typedef struct +{ + const uint8_t * platform; + uint8_t platform_length; + const uint8_t * app_id; + uint8_t app_id_length; +} win_launchapp_payload_desc_t; + +/** @brief Description of payload of Windows LaunchApp record. */ +static win_launchapp_payload_desc_t m_win_launchapp_dsc; + +static const uint8_t launchapp_type_str[] = {'a', 'n', 'd', 'r', 'o', 'i', 'd', '.', 'c', 'o', 'm', + ':', 'p', 'k', 'g'}; + +static const uint8_t win_launchapp_type_str[] = {'w', 'i', 'n', 'd', 'o', 'w', 's', '.', 'c', 'o', + 'm', '/', 'L', 'a', 'u', 'n', 'c', 'h', 'A', 'p', + 'p'}; + +static const uint8_t win_phone_str[] = {'W', 'i', 'n', 'd', 'o', 'w', 's', 'P', 'h', 'o', 'n', 'e'}; + +nfc_ndef_record_desc_t * nfc_android_application_rec_declare(uint8_t const * p_package_name, + uint8_t package_name_length) +{ + NFC_NDEF_RECORD_BIN_DATA_DEF(android_app_rec, + TNF_EXTERNAL_TYPE, // tnf <- external + NULL, // no id + 0, // no id + launchapp_type_str, + sizeof(launchapp_type_str), + NULL, + 0); + + NFC_NDEF_BIN_PAYLOAD_DESC(android_app_rec).p_payload = p_package_name; + NFC_NDEF_BIN_PAYLOAD_DESC(android_app_rec).payload_length = package_name_length; + + return &NFC_NDEF_RECORD_BIN_DATA(android_app_rec); +} + +#define WIN_LAUNCHAPP_EMPTY_PARAMETER 0x20 ///< The empty parameter value for the Windows LaunchApp Record. + +/** + * @brief Function for constructing the payload for a Windows LaunchApp record. + * + * This function encodes the payload according to the LaunchApp record definition. It implements an API + * compatible with p_payload_constructor_t. + * + * @param[in] p_input Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the LaunchApp record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS Always success. + */ +static ret_code_t nfc_win_launchapp_payload_constructor(win_launchapp_payload_desc_t * p_input, + uint8_t * p_buff, + uint32_t * p_len) +{ + + win_launchapp_payload_desc_t * launch_desc = (win_launchapp_payload_desc_t *) p_input; + + uint32_t temp_len = (uint32_t)launch_desc->platform_length + launch_desc->app_id_length + 7; + + if (p_buff != NULL) + { + if (temp_len > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + *p_buff++ = 0x00; // platform count: 1 + *p_buff++ = 0x01; // -||- + + *p_buff++ = launch_desc->platform_length; + memcpy(p_buff, launch_desc->platform, launch_desc->platform_length); // platform + p_buff += launch_desc->platform_length; + + + *p_buff++ = launch_desc->app_id_length; + memcpy(p_buff, launch_desc->app_id, launch_desc->app_id_length); + p_buff += launch_desc->app_id_length; + + *p_buff++ = 0x00; // parameters length 1B + *p_buff++ = 0x01; // -||- + *p_buff++ = WIN_LAUNCHAPP_EMPTY_PARAMETER; // empty parameter + } + + *p_len = temp_len; + + return NRF_SUCCESS; +} + + +nfc_ndef_record_desc_t * nfc_windows_launchapp_rec_declare(const uint8_t * p_win_app_id, + uint8_t win_app_id_length) +{ + + NFC_NDEF_GENERIC_RECORD_DESC_DEF(win_launchapp, + TNF_ABSOLUTE_URI, + NULL, + 0, + win_launchapp_type_str, + sizeof(win_launchapp_type_str), + nfc_win_launchapp_payload_constructor, + &m_win_launchapp_dsc); + + m_win_launchapp_dsc.platform = win_phone_str; + m_win_launchapp_dsc.platform_length = sizeof(win_phone_str); + + m_win_launchapp_dsc.app_id = p_win_app_id; + m_win_launchapp_dsc.app_id_length = win_app_id_length; + + return &NFC_NDEF_GENERIC_RECORD_DESC(win_launchapp); +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/launchapp/nfc_launchapp_rec.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/launchapp/nfc_launchapp_rec.h new file mode 100644 index 0000000000000000000000000000000000000000..de6624741a21fb5544046d899bab7d51e8ef84a5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/launchapp/nfc_launchapp_rec.h @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_LAUNCHAPP_REC_H__ +#define NFC_LAUNCHAPP_REC_H__ + +/**@file + * + * @defgroup nfc_launch_app_rec Launch app records + * @{ + * @ingroup nfc_launch_app_msg + * + * @brief Generation of NFC NDEF record descriptions that launch apps. + * + */ + +#include +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for generating a description of an NFC NDEF Android Application Record (AAR). + * + * This function declares and initializes a static instance of an NFC NDEF record description + * of an Android Application Record (AAR). + * + * @note The record payload data (@p p_package_name) should be declared as + * static. If it is declared as automatic, the NDEF message encoding + * (see @ref nfc_ndef_msg_encode) must be done in the same variable + * scope. + * + * @param[in] p_package_name Pointer to the Android package name string. + * @param[in] package_name_length Length of the Android package name. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_android_application_rec_declare(uint8_t const * p_package_name, + uint8_t package_name_length); + +/** @brief Function for generating a description of an NFC NDEF Windows LaunchApp record. + * + * This function declares and initializes a static instance of an NFC NDEF record description + * of a Windows LaunchApp record. + * + * @note The record payload data (@p p_win_app_id) should be declared as + * static. If it is declared as automatic, the NDEF message encoding + * (see @ref nfc_ndef_msg_encode) must be done in the same variable + * scope. + * + * @param[in] p_win_app_id Pointer to the Windows application ID string (GUID). + * @param[in] win_app_id_length Length of the Windows application ID. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_windows_launchapp_rec_declare(const uint8_t * p_win_app_id, + uint8_t win_app_id_length); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_LAUNCHAPP_REC diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c new file mode 100644 index 0000000000000000000000000000000000000000..cab2492ed4281a73c70c2ca36c4c20d555934c4e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER) + +#include "nfc_ndef_msg_parser.h" +#include "nrf_delay.h" + +#define NRF_LOG_MODULE_NAME "NFC_NDEF_MSG_PARSER" +#if NFC_NDEF_MSG_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_NDEF_MSG_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_NDEF_MSG_PARSER_INFO_COLOR +#else // NFC_NDEF_MSG_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_NDEF_MSG_PARSER_LOG_ENABLED +#include "nrf_log.h" + +ret_code_t ndef_msg_parser(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + uint8_t * const p_nfc_data, + uint32_t * const p_nfc_data_len) +{ + ret_code_t ret_code; + nfc_ndef_parser_memo_desc_t parser_memory_helper; + + ret_code = ndef_parser_memo_resolve(p_result_buf, + p_result_buf_len, + &parser_memory_helper); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + ret_code = internal_ndef_msg_parser(&parser_memory_helper, + p_nfc_data, + p_nfc_data_len); + + return ret_code; +} + + +void ndef_msg_printout(nfc_ndef_msg_desc_t * const p_msg_desc) +{ + uint32_t i; + + nrf_delay_ms(100); + NRF_LOG_INFO("NDEF message contains %d record(s)\r\n\r\n", p_msg_desc->record_count); + + for (i = 0; i < p_msg_desc->record_count; i++) + { + ndef_record_printout(i, p_msg_desc->pp_record[i]); + } +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..6b1f8eb295e12d952cfee06b0524e2042cab7de3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h @@ -0,0 +1,123 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_NDEF_MSG_PARSER_H__ +#define NFC_NDEF_MSG_PARSER_H__ + +/**@file + * + * @defgroup nfc_ndef_parser NDEF message parser + * @{ + * @ingroup nfc_modules + * + * @brief Parser for NFC NDEF messages and records. + * + * @defgroup nfc_ndef_msg_parser Parser for NDEF messages + * @{ + * @ingroup nfc_ndef_parser + * + * @brief Parser for NFC NDEF messages. + * + */ + +#include +#include "nfc_ndef_msg_parser_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Macro for calculating the memory size required for holding the + * description of a message that consists of a certain number of NDEF records. + * + * @param[in] max_count_of_records Maximum number of records to hold. + */ +#define NFC_NDEF_PARSER_REQIRED_MEMO_SIZE_CALC(max_count_of_records) \ + ((uint32_t)(max_count_of_records) <= 1) ? \ + (sizeof(parsed_ndef_msg_1_t) * (uint32_t)(max_count_of_records)) : \ + (sizeof(parsed_ndef_msg_1_t) + ((NFC_PARSER_M_DELTA) *((uint32_t)(max_count_of_records) - 1))) + +/** + * @brief Function for parsing NFC NDEF messages. + * + * This function parses NDEF messages using NDEF binary record descriptors. + * + * @param[out] p_result_buf Pointer to the buffer that will be used to hold + * the NDEF message descriptor. After parsing is completed successfully, the first address + * in the buffer is filled by the NDEF message descriptor + * (@ref nfc_ndef_msg_desc_t), which provides a full description of + * the parsed NDEF message. + * @param[in,out] p_result_buf_len As input: size of the buffer specified by @p p_result_buf. + * As output: size of the reserved (used) part of the buffer specified by + * @p p_result_buf. + * @param[in] p_nfc_data Pointer to the data to be parsed. + * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. As output: size of the parsed message. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the provided buffer is too small to hold a one-record message or + * the buffer is too small to hold the actual result of the parsing. + * @retval NRF_ERROR_INVALID_LENGTH If the expected message length is bigger than the amount of the provided input data. + * @retval NRF_ERROR_INVALID_DATA If the message is not a valid NDEF message. + */ +ret_code_t ndef_msg_parser(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + uint8_t * const p_nfc_data, + uint32_t * const p_nfc_data_len); + +/** + * @brief Function for printing the parsed contents of an NDEF message. + * + * @param[in] p_msg_desc Pointer to the descriptor of the message that should be printed. + */ +void ndef_msg_printout(nfc_ndef_msg_desc_t * const p_msg_desc); + +/** + * @} + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NFC_NDEF_MSG_PARSER_H__ + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c new file mode 100644 index 0000000000000000000000000000000000000000..8817fb6559a447e44e890fcb33d0949b0181aa2d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c @@ -0,0 +1,163 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER) + +#include "nfc_ndef_msg_parser_local.h" + +ret_code_t internal_ndef_msg_parser(nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc, + uint8_t const * p_nfc_data, + uint32_t * const p_nfc_data_len) +{ + nfc_ndef_record_location_t record_location; + + ret_code_t ret_code; + + uint32_t nfc_data_left = *p_nfc_data_len; + uint32_t temp_nfc_data_len = 0; + + // want to modify -> use local copy + nfc_ndef_bin_payload_desc_t * p_bin_pay_desc = p_parser_memo_desc->p_bin_pay_desc; + nfc_ndef_record_desc_t * p_rec_desc = p_parser_memo_desc->p_rec_desc; + + + while (nfc_data_left > 0) + { + temp_nfc_data_len = nfc_data_left; + + ret_code = ndef_record_parser(p_bin_pay_desc, + p_rec_desc, + &record_location, + p_nfc_data, + &temp_nfc_data_len); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + // verify the records location flags + if (p_parser_memo_desc->p_msg_desc->record_count == 0) + { + if ((record_location != NDEF_FIRST_RECORD) && (record_location != NDEF_LONE_RECORD)) + { + return NRF_ERROR_INVALID_DATA; + } + } + else + { + if ((record_location != NDEF_MIDDLE_RECORD) && (record_location != NDEF_LAST_RECORD)) + { + return NRF_ERROR_INVALID_DATA; + } + } + + ret_code = nfc_ndef_msg_record_add(p_parser_memo_desc->p_msg_desc, p_rec_desc); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + nfc_data_left -= temp_nfc_data_len; + + if ((record_location == NDEF_LAST_RECORD) || (record_location == NDEF_LONE_RECORD)) + { + *p_nfc_data_len = *p_nfc_data_len - nfc_data_left; + return NRF_SUCCESS; + } + else + { + if (p_parser_memo_desc->p_msg_desc->record_count == + p_parser_memo_desc->p_msg_desc->max_record_count) + { + return NRF_ERROR_NO_MEM; + } + + p_nfc_data += temp_nfc_data_len; + p_bin_pay_desc++; + p_rec_desc++; + } + } + + return NRF_ERROR_INVALID_DATA; + +} + + +ret_code_t ndef_parser_memo_resolve(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc) +{ + + uint32_t max_rec_num; + uint32_t memory_last; + uint8_t * p_end; + nfc_ndef_record_desc_t * * pp_record_desc_array; + + if (*p_result_buf_len < sizeof(parsed_ndef_msg_1_t)) + { + return NRF_ERROR_NO_MEM; + } + + memory_last = (*p_result_buf_len) - sizeof(parsed_ndef_msg_1_t); + max_rec_num = (memory_last / (NFC_PARSER_M_DELTA)) + 1; + + p_parser_memo_desc->p_msg_desc = (nfc_ndef_msg_desc_t *) p_result_buf; + pp_record_desc_array = + (nfc_ndef_record_desc_t * *) &p_parser_memo_desc->p_msg_desc[1]; + p_parser_memo_desc->p_bin_pay_desc = + (nfc_ndef_bin_payload_desc_t *) &pp_record_desc_array[max_rec_num]; + p_parser_memo_desc->p_rec_desc = + (nfc_ndef_record_desc_t *) &p_parser_memo_desc->p_bin_pay_desc[max_rec_num]; + + // initialize message description + p_parser_memo_desc->p_msg_desc->pp_record = pp_record_desc_array; + p_parser_memo_desc->p_msg_desc->max_record_count = max_rec_num; + p_parser_memo_desc->p_msg_desc->record_count = 0; + + p_end = (uint8_t *) &p_parser_memo_desc->p_rec_desc[max_rec_num]; + + *p_result_buf_len = p_end - p_result_buf; + + return NRF_SUCCESS; +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h new file mode 100644 index 0000000000000000000000000000000000000000..c8c575f998bc1e836a215d0d103a9c84965e335e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_NDEF_MSG_PARSER_LOCAL_H__ +#define NFC_NDEF_MSG_PARSER_LOCAL_H__ + +/**@file + * + * @defgroup nfc_ndef_msg_parser_local NDEF message parser (internal) + * @{ + * @ingroup nfc_ndef_msg_parser + * + * @brief Internal part of the parser for NFC NDEF messages. + * + */ + +#include +#include "nfc_ndef_msg.h" +#include "nfc_ndef_record_parser.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type for holding descriptors that are used by the NDEF parser. + */ +typedef struct +{ + nfc_ndef_msg_desc_t * p_msg_desc; ///< Pointer to the message descriptor. + nfc_ndef_bin_payload_desc_t * p_bin_pay_desc; ///< Pointer to the array of binary payload descriptors. + nfc_ndef_record_desc_t * p_rec_desc; ///< Pointer to the array of record descriptors. +} nfc_ndef_parser_memo_desc_t; + +/** + * @brief Memory allocated for a one-record message. + */ +typedef struct +{ + nfc_ndef_msg_desc_t msg_desc; + nfc_ndef_record_desc_t * p_record_desc_array[1]; + nfc_ndef_bin_payload_desc_t bin_pay_desc[1]; + nfc_ndef_record_desc_t rec_desc[1]; +} parsed_ndef_msg_1_t; + +/** + * @brief Memory allocated for a two-record message. + */ +typedef struct +{ + nfc_ndef_msg_desc_t msg_desc; + nfc_ndef_record_desc_t * p_record_desc_array[2]; + nfc_ndef_bin_payload_desc_t bin_pay_desc[2]; + nfc_ndef_record_desc_t rec_desc[2]; +} parsed_ndef_msg_2_t; + +/** + * @brief Amount of memory that is required per record in addition to the memory allocated for the message descriptor. + */ +#define NFC_PARSER_M_DELTA (sizeof(parsed_ndef_msg_2_t) - sizeof(parsed_ndef_msg_1_t)) + + +/** + * @brief Function for resolving data instances in the provided buffer according + * to requirements of the function @ref internal_ndef_msg_parser. + * + * This internal function distributes the provided memory between certain data instances that are required + * by @ref internal_ndef_msg_parser. + * + * This function should not be used directly. + * + * @param[in] p_result_buf Pointer to the buffer that will be used to allocate + * data instances. + * @param[in,out] p_result_buf_len As input: size of the buffer specified by @p p_result_buf. + * As output: size of the reserved (used) part of the buffer specified by + * @p p_result_buf. + * @param[out] p_parser_memo_desc Pointer to the structure for holding descriptors of the allocated data + * instances. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the provided buffer is too small to hold a one-record message. + */ +ret_code_t ndef_parser_memo_resolve(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc); + + +/** + * @brief Function for parsing NFC NDEF messages. + * + * This internal function parses NDEF messages into certain data instances. + * + * This function should not be used directly. + * + * @param[in,out] p_parser_memo_desc Pointer to the structure that holds descriptors of the allocated data + * instances for the parser. This structure contains the following fields: @n + * .p_msg_desc Pointer to the message descriptor that will + * be filled with parsed data. @n + * .p_bin_pay_desc Pointer to the array of binary payload + * descriptors that will be filled with parsed + * data. @n + * .p_rec_desc Pointer to the array of record descriptors + * that will be filled with parsed data. @n + * The arrays specified by @p .p_bin_pay_desc and @p .p_rec_desc must not + * contain more elements than the message descriptor + * specified by \p .p_msg_desc can hold. + * + * @param[in] p_nfc_data Pointer to the data to be parsed. + * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. + * As output: size of the parsed message. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_LENGTH If the expected message length is bigger than the amount of provided input data. + * @retval NRF_ERROR_INVALID_DATA If the message is not a valid NDEF message. + * @retval NRF_ERROR_NO_MEM If the provided memory resources are too small to hold the parsing result. + */ +ret_code_t internal_ndef_msg_parser(nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc, + uint8_t const * p_nfc_data, + uint32_t * const p_nfc_data_len); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NFC_NDEF_MSG_PARSER_LOCAL_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c new file mode 100644 index 0000000000000000000000000000000000000000..ab149416cb28ad8778a5126fd76df865c9daaa85 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c @@ -0,0 +1,218 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_RECORD_PARSER) + +#include +#include +#include "nfc_ndef_record_parser.h" +#include "app_util.h" +#include "nordic_common.h" +#include "nrf_delay.h" + +#define NRF_LOG_MODULE_NAME "NFC_NDEF_PARSER" +#if NFC_NDEF_RECORD_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_NDEF_RECORD_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_NDEF_RECORD_PARSER_INFO_COLOR +#else // NFC_NDEF_RECORD_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_NDEF_RECORD_PARSER_LOG_ENABLED +#include "nrf_log.h" + +/* Sum of sizes of fields: TNF-flags, Type Length, Payload Length in short NDEF record. */ +#define NDEF_RECORD_BASE_LONG_SHORT (2 + NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE) + + +ret_code_t ndef_record_parser(nfc_ndef_bin_payload_desc_t * p_bin_pay_desc, + nfc_ndef_record_desc_t * p_rec_desc, + nfc_ndef_record_location_t * p_record_location, + uint8_t const * p_nfc_data, + uint32_t * p_nfc_data_len) +{ + uint32_t expected_rec_size = NDEF_RECORD_BASE_LONG_SHORT; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_rec_desc->tnf = (nfc_ndef_record_tnf_t) ((*p_nfc_data) & NDEF_RECORD_TNF_MASK); + + /* An NDEF parser that receives an NDEF record with an unknown or unsupported TNF field value + SHOULD treat it as Unknown. See NFCForum-TS-NDEF_1.0 */ + if (p_rec_desc->tnf == TNF_RESERVED) + { + p_rec_desc->tnf = TNF_UNKNOWN_TYPE; + } + + *p_record_location = (nfc_ndef_record_location_t) ((*p_nfc_data) & NDEF_RECORD_LOCATION_MASK); + + uint8_t flags = *(p_nfc_data++); + + p_rec_desc->type_length = *(p_nfc_data++); + + uint32_t payload_lenght; + + if (flags & NDEF_RECORD_SR_MASK) + { + payload_lenght = *(p_nfc_data++); + } + else + { + expected_rec_size += + NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE - NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + payload_lenght = uint32_big_decode(p_nfc_data); + p_nfc_data += NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE; + } + + if (flags & NDEF_RECORD_IL_MASK) + { + expected_rec_size += NDEF_RECORD_ID_LEN_SIZE; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_rec_desc->id_length = *(p_nfc_data++); + } + else + { + p_rec_desc->id_length = 0; + p_rec_desc->p_id = NULL; + } + + expected_rec_size += p_rec_desc->type_length + p_rec_desc->id_length + payload_lenght; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (p_rec_desc->type_length > 0) + { + p_rec_desc->p_type = p_nfc_data; + + p_nfc_data += p_rec_desc->type_length; + } + else + { + p_rec_desc->p_type = NULL; + } + + if (p_rec_desc->id_length > 0) + { + p_rec_desc->p_id = p_nfc_data; + + p_nfc_data += p_rec_desc->id_length; + } + + if (payload_lenght == 0) + { + p_bin_pay_desc->p_payload = NULL; + } + else + { + p_bin_pay_desc->p_payload = p_nfc_data; + } + + p_bin_pay_desc->payload_length = payload_lenght; + + p_rec_desc->p_payload_descriptor = p_bin_pay_desc; + p_rec_desc->payload_constructor = (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy; + + *p_nfc_data_len = expected_rec_size; + + return NRF_SUCCESS; +} + +char const * const tnf_strings[] = +{ + "Empty\r\n", + "NFC Forum well-known type\r\n", + "Media-type (RFC 2046)\r\n", + "Absolute URI (RFC 3986)\r\n", + "NFC Forum external type (NFC RTD)\r\n", + "Unknown\r\n", + "Unchanged\r\n", + "Reserved\r\n" +}; + +void ndef_record_printout(uint32_t num, nfc_ndef_record_desc_t * const p_rec_desc) +{ + NRF_LOG_INFO("NDEF record %d content:\r\n", num); + NRF_LOG_INFO("TNF: %s",(uint32_t)tnf_strings[p_rec_desc->tnf]); + + if (p_rec_desc->p_id != NULL) + { + NRF_LOG_INFO("ID:\r\n"); + NRF_LOG_HEXDUMP_INFO((uint8_t *)p_rec_desc->p_id, p_rec_desc->id_length); + } + + if (p_rec_desc->p_type != NULL) + { + NRF_LOG_INFO("type:\r\n"); + NRF_LOG_HEXDUMP_INFO((uint8_t *)p_rec_desc->p_type, p_rec_desc->type_length); + } + + if (p_rec_desc->payload_constructor == (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy) + { + nfc_ndef_bin_payload_desc_t * p_bin_pay_desc = p_rec_desc->p_payload_descriptor; + + if (p_bin_pay_desc->p_payload != NULL) + { + NRF_LOG_INFO("Payload data (%d bytes):\r\n", p_bin_pay_desc->payload_length); + NRF_LOG_HEXDUMP_INFO((uint8_t *)p_bin_pay_desc->p_payload, p_bin_pay_desc->payload_length); + } + else + { + NRF_LOG_INFO("No payload\r\n"); + } + } + NRF_LOG_INFO("\r\n\r\n"); +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_RECORD_PARSER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..3403c9c3b934c7e8f11ac8c4287e6ecaed4a982b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_NDEF_RECORD_PARSER_H__ +#define NFC_NDEF_RECORD_PARSER_H__ + +#include +#include "sdk_errors.h" +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@file + * + * @defgroup nfc_ndef_record_parser Parser for NDEF records + * @{ + * @ingroup nfc_ndef_parser + * + * @brief Parser for NFC NDEF records. + * + */ + + +/** + * @brief Function for parsing NDEF records. + * + * This parsing implementation uses the binary payload descriptor (@ref nfc_ndef_bin_payload_desc_t) to describe the payload for the record. + * + * @param[out] p_bin_pay_desc Pointer to the binary payload descriptor that will be filled and referenced by the record descriptor. + * @param[out] p_rec_desc Pointer to the record descriptor that will be filled with parsed data. + * @param[out] p_record_location Pointer to the record location. + * @param[in] p_nfc_data Pointer to the raw data to be parsed. + * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. As output: size of the parsed record. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_LENGTH If the expected record length is bigger than the provided input data amount. + */ +ret_code_t ndef_record_parser(nfc_ndef_bin_payload_desc_t * p_bin_pay_desc, + nfc_ndef_record_desc_t * p_rec_desc, + nfc_ndef_record_location_t * p_record_location, + uint8_t const * p_nfc_data, + uint32_t * p_nfc_data_len); + +/** + * @brief Function for printing the parsed contents of the NDEF record. + * + * @param[in] num Sequence number of the record within the NDEF message. + * @param[in] p_rec_desc Pointer to the descriptor of the record that should be printed. + * + */ +void ndef_record_printout(uint32_t num, nfc_ndef_record_desc_t * const p_rec_desc); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NFC_NDEF_RECORD_PARSER_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/text/nfc_text_rec.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/text/nfc_text_rec.c new file mode 100644 index 0000000000000000000000000000000000000000..72f6e7c15a8e3a9727c83b118e4fa9cc6541999b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/text/nfc_text_rec.c @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "nfc_text_rec.h" +#include "nrf_error.h" + +#define TEXT_REC_STATUS_SIZE 1 ///< Size of the status. +#define TEXT_REC_STATUS_UTF_POS 7 ///< Position of a character encoding type. +#define TEXT_REC_RESERVED_POS 6 ///< Reserved position. + +const uint8_t nfc_text_rec_type_field[] = {'T'}; + + +/** + * @brief Function for calculating payload size. + */ +__STATIC_INLINE uint32_t nfc_text_rec_payload_size_get(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc) +{ + return (TEXT_REC_STATUS_SIZE + + p_nfc_rec_text_payload_desc->lang_code_len + + p_nfc_rec_text_payload_desc->data_len); +} + +ret_code_t nfc_text_rec_payload_constructor(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc, + uint8_t * p_buff, + uint32_t * p_len) +{ + if ((p_nfc_rec_text_payload_desc->lang_code_len == 0) + || (p_nfc_rec_text_payload_desc->lang_code_len & (1 << TEXT_REC_RESERVED_POS)) + || (p_nfc_rec_text_payload_desc->lang_code_len & (1 << TEXT_REC_STATUS_UTF_POS)) + || (p_nfc_rec_text_payload_desc->p_lang_code == NULL) + || (p_nfc_rec_text_payload_desc->data_len == 0) + || (p_nfc_rec_text_payload_desc->p_data == NULL) + || (p_len == NULL)) + { + return NRF_ERROR_INVALID_PARAM; + } + + uint32_t payload_size = nfc_text_rec_payload_size_get(p_nfc_rec_text_payload_desc); + + if (p_buff != NULL) + { + if (payload_size > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + *p_buff = (p_nfc_rec_text_payload_desc->lang_code_len + + (p_nfc_rec_text_payload_desc->utf << TEXT_REC_STATUS_UTF_POS)); + p_buff += TEXT_REC_STATUS_SIZE; + + memcpy(p_buff, + p_nfc_rec_text_payload_desc->p_lang_code, + p_nfc_rec_text_payload_desc->lang_code_len); + p_buff += p_nfc_rec_text_payload_desc->lang_code_len; + + memcpy(p_buff, + p_nfc_rec_text_payload_desc->p_data, + p_nfc_rec_text_payload_desc->data_len); + } + + *p_len = payload_size; + + return NRF_SUCCESS; +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/text/nfc_text_rec.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/text/nfc_text_rec.h new file mode 100644 index 0000000000000000000000000000000000000000..6d6c1433ce78342e74fbda140f5895a54ce04de4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/text/nfc_text_rec.h @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_TEXT_REC_H__ +#define NFC_TEXT_REC_H__ + +/**@file + * + * @defgroup nfc_text_rec Text records + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF Text record descriptions. + * + */ + +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type of the Unicode Transformation Format. + * + * Values to specify the type of UTF for an NFC NDEF Text record. + */ +typedef enum +{ + UTF_8 = 0, ///< Unicode Transformation Format 8. + UTF_16 = 1, ///< Unicode Transformation Format 16. +} nfc_text_rec_utf_type_t; + +/** + * @brief Text record payload descriptor. + */ +typedef struct +{ + nfc_text_rec_utf_type_t utf; ///< Type of the Unicode Transformation Format. + + uint8_t const * p_lang_code; ///< Pointer to the IANA language code. + uint8_t lang_code_len; ///< Length of the IANA language code. + + uint8_t const * p_data; ///< Pointer to the user text. + uint32_t data_len; ///< Length of the user text. +} nfc_text_rec_payload_desc_t; + +/** + * @brief Constructor for an NFC NDEF Text record payload. + * + * @param[in] p_nfc_rec_text_payload_desc Pointer to the Text record description. + * @param[out] p_buff Pointer to the payload destination. If NULL, function will + * calculate the expected size of the Text record payload. + * + * @param[in,out] p_len Size of the available memory to write as input. + * Size of the generated record payload as output. + */ +ret_code_t nfc_text_rec_payload_constructor(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc, + uint8_t * p_buff, + uint32_t * p_len); + +/** + * @brief External reference to the type field of the Text record, defined in the + * file @c nfc_text_rec.c. It is used in the @ref NFC_NDEF_TEXT_RECORD_DESC_DEF macro. + */ +extern const uint8_t nfc_text_rec_type_field[]; + +/** + * @brief Size of the type field of the Text record, defined in the + * file @c nfc_text_rec.c. It is used in the @ref NFC_NDEF_TEXT_RECORD_DESC_DEF macro. + */ +#define NFC_TEXT_REC_TYPE_LENGTH 1 + +/** + *@brief Macro for creating and initializing an NFC NDEF record descriptor for a Text record. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t and + * a static instance of type @ref nfc_text_rec_payload_desc_t, which together constitute + * an instance of a Text record. + * + * Use the macro @ref NFC_NDEF_TEXT_RECORD_DESC to access the NDEF Text record descriptor instance. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] UTF Unicode Transformation Format. + * @param[in] P_LANG_CODE Pointer to the IANA language code. + * @param[in] LANG_CODE_LEN Length of the IANA language code. + * @param[in] P_DATA Pointer to the user text. + * @param[in] DATA_LEN Length of the user text. + */ +#define NFC_NDEF_TEXT_RECORD_DESC_DEF(NAME, \ + UTF, \ + P_LANG_CODE, \ + LANG_CODE_LEN, \ + P_DATA, \ + DATA_LEN) \ + static nfc_text_rec_payload_desc_t NAME##_nfc_text_rec_payload_desc; \ + NAME##_nfc_text_rec_payload_desc = (nfc_text_rec_payload_desc_t) \ + { \ + .utf = UTF, \ + .p_lang_code = P_LANG_CODE, \ + .lang_code_len = LANG_CODE_LEN, \ + .p_data = P_DATA, \ + .data_len = DATA_LEN, \ + }; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF_WELL_KNOWN, \ + 0, \ + 0, \ + nfc_text_rec_type_field, \ + NFC_TEXT_REC_TYPE_LENGTH, \ + nfc_text_rec_payload_constructor, \ + &(NAME##_nfc_text_rec_payload_desc)) + +/** + * @brief Macro for accessing the NFC NDEF Text record descriptor + * instance that was created with @ref NFC_NDEF_TEXT_RECORD_DESC_DEF. + */ +#define NFC_NDEF_TEXT_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_TEXT_REC_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/uri/nfc_uri_msg.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/uri/nfc_uri_msg.c new file mode 100644 index 0000000000000000000000000000000000000000..799ee5db546065102da3117734f38967510fa269 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/uri/nfc_uri_msg.c @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "nfc_uri_msg.h" + +/** @brief Function for generating a description of an NFC NDEF URI message. + * + * This function declares and initializes a static instance of an NFC NDEF message description + * and NFC NDEF records descriptions. + * + * @param[in] uri_id_code URI identifier code that defines the protocol field of the URI. + * @param[in] p_uri_data Pointer to the URI string. + * This string should not contain the protocol field if the protocol + * was specified in @p uri_id_code + * @param[in] uri_data_len Length of the URI string. + * @param[out] pp_uri_msg_desc Pointer to pointer to the NDEF message description. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If the URI string was invalid (equal to NULL). + */ +static ret_code_t nfc_uri_msg_declare( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len, + nfc_ndef_msg_desc_t ** pp_uri_msg_desc) +{ + ret_code_t err_code; + nfc_ndef_record_desc_t * p_uri_rec; + + /* Create NFC NDEF message description, capacity - 1 record */ + NFC_NDEF_MSG_DEF(nfc_uri_msg, 1); + + /* The message description is static, therefore */ + /* you must clear the message (needed for supporting multiple calls) */ + nfc_ndef_msg_clear(&NFC_NDEF_MSG(nfc_uri_msg)); + + if (p_uri_data != NULL) + { + /* Create NFC NDEF URI Record description */ + p_uri_rec = nfc_uri_rec_declare(uri_id_code, + p_uri_data, + uri_data_len); + + /* Add URI record as lone record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_uri_msg), p_uri_rec); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else + { + return NRF_ERROR_INVALID_PARAM; + } + + *pp_uri_msg_desc = &NFC_NDEF_MSG(nfc_uri_msg); + + return NRF_SUCCESS; +} + +ret_code_t nfc_uri_msg_encode( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len, + uint8_t * p_buf, + uint32_t * p_len) +{ + ret_code_t err_code; + nfc_ndef_msg_desc_t * p_uri_msg_desc; + + /* Create NFC NDEF message description with URI record */ + err_code = nfc_uri_msg_declare( uri_id_code, + p_uri_data, + uri_data_len, + &p_uri_msg_desc); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(p_uri_msg_desc, + p_buf, + p_len); + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/uri/nfc_uri_msg.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/uri/nfc_uri_msg.h new file mode 100644 index 0000000000000000000000000000000000000000..314c6a6b17cf619ca0dfe7cb19c5cf7871f2f2d5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/uri/nfc_uri_msg.h @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_URI_MSG_H__ +#define NFC_URI_MSG_H__ + +/**@file + * + * @defgroup nfc_uri_msg URI messages + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF messages with a URI record. + * + */ + +#include "nfc_ndef_msg.h" +#include "nfc_uri_rec.h" +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for encoding an NFC NDEF URI message. + * + * This function encodes an NFC NDEF message into a buffer. + * + * @param[in] uri_id_code URI identifier code that defines the protocol field of the URI. + * @param[in] p_uri_data Pointer to the URI string. + * The string should not contain the protocol field if the protocol + * was specified in @p uri_id_code. + * @param[in] uri_data_len Length of the URI string. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If the URI string was invalid (equal to NULL). + * @retval NRF_ERROR_NO_MEM If the predicted message size is bigger than the provided + * buffer space. + * @retval Other Other codes might be returned depending on + * the function @ref nfc_ndef_msg_encode. + */ +ret_code_t nfc_uri_msg_encode( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len, + uint8_t * p_buf, + uint32_t * p_len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_URI_MSG_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/uri/nfc_uri_rec.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/uri/nfc_uri_rec.c new file mode 100644 index 0000000000000000000000000000000000000000..8fea850553ca672541ce43ae10670626edc114a7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/uri/nfc_uri_rec.c @@ -0,0 +1,114 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "nfc_uri_rec.h" +#include "nrf_error.h" + +/** + * @brief Type of description of the payload of a URI record. + */ +typedef struct +{ + nfc_uri_id_t uri_id_code; ///< URI identifier code. + uint8_t const * p_uri_data; ///< Pointer to a URI string. + uint8_t uri_data_len; ///< Length of the URI string. +} uri_payload_desc_t; + +/** + * @brief Function for constructing the payload for a URI record. + * + * This function encodes the payload according to the URI record definition. It implements an API + * compatible with @ref p_payload_constructor_t. + * + * @param[in] p_input Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the URI record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS If the payload was encoded successfully. + * @retval NRF_ERROR_NO_MEM If the predicted payload size is bigger than the provided buffer space. + */ +static ret_code_t nfc_uri_payload_constructor( uri_payload_desc_t * p_input, + uint8_t * p_buff, + uint32_t * p_len) +{ + if (p_buff != NULL) + { + /* Verify if there is enough available memory */ + if (p_input->uri_data_len >= *p_len) + { + return NRF_ERROR_NO_MEM; + } + + /* Copy descriptor content into the buffer */ + *(p_buff++) = p_input->uri_id_code; + memcpy(p_buff, p_input->p_uri_data, p_input->uri_data_len ); + } + + *p_len = p_input->uri_data_len + 1; + + return NRF_SUCCESS; +} + +nfc_ndef_record_desc_t * nfc_uri_rec_declare( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len) +{ + static uri_payload_desc_t uri_payload_desc; + static const uint8_t static_uri_type = 'U'; + + NFC_NDEF_GENERIC_RECORD_DESC_DEF( uri_rec, + TNF_WELL_KNOWN, // tnf <- well-known + NULL, + 0, // no id + &static_uri_type, + 1, // type size 1B + nfc_uri_payload_constructor, + &uri_payload_desc); + + uri_payload_desc.uri_id_code = uri_id_code; + uri_payload_desc.p_uri_data = p_uri_data; + uri_payload_desc.uri_data_len = uri_data_len; + + return &NFC_NDEF_GENERIC_RECORD_DESC( uri_rec); +} + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/uri/nfc_uri_rec.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/uri/nfc_uri_rec.h new file mode 100644 index 0000000000000000000000000000000000000000..fad1246ac87fef177e6d68be3d288e3756dcfd9a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/ndef/uri/nfc_uri_rec.h @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_URI_REC_H__ +#define NFC_URI_REC_H__ + +/**@file + * + * @defgroup nfc_uri_rec URI records + * @{ + * @ingroup nfc_uri_msg + * + * @brief Generation of NFC NDEF URI record descriptions. + * + */ + +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @enum nfc_uri_id_t + * @brief URI identifier codes according to "URI Record Type Definition" + * (denotation "NFCForum-TS-RTD_URI_1.0" published on 2006-07-24) chapter 3.2.2. + */ +typedef enum +{ + NFC_URI_NONE = 0x00, /**< No prepending is done. */ + NFC_URI_HTTP_WWW = 0x01, /**< "http://www." */ + NFC_URI_HTTPS_WWW = 0x02, /**< "https://www." */ + NFC_URI_HTTP = 0x03, /**< "http:" */ + NFC_URI_HTTPS = 0x04, /**< "https:" */ + NFC_URI_TEL = 0x05, /**< "tel:" */ + NFC_URI_MAILTO = 0x06, /**< "mailto:" */ + NFC_URI_FTP_ANONYMOUS = 0x07, /**< "ftp://anonymous:anonymous@" */ + NFC_URI_FTP_FTP = 0x08, /**< "ftp://ftp." */ + NFC_URI_FTPS = 0x09, /**< "ftps://" */ + NFC_URI_SFTP = 0x0A, /**< "sftp://" */ + NFC_URI_SMB = 0x0B, /**< "smb://" */ + NFC_URI_NFS = 0x0C, /**< "nfs://" */ + NFC_URI_FTP = 0x0D, /**< "ftp://" */ + NFC_URI_DAV = 0x0E, /**< "dav://" */ + NFC_URI_NEWS = 0x0F, /**< "news:" */ + NFC_URI_TELNET = 0x10, /**< "telnet://" */ + NFC_URI_IMAP = 0x11, /**< "imap:" */ + NFC_URI_RTSP = 0x12, /**< "rtsp://" */ + NFC_URI_URN = 0x13, /**< "urn:" */ + NFC_URI_POP = 0x14, /**< "pop:" */ + NFC_URI_SIP = 0x15, /**< "sip:" */ + NFC_URI_SIPS = 0x16, /**< "sips:" */ + NFC_URI_TFTP = 0x17, /**< "tftp:" */ + NFC_URI_BTSPP = 0x18, /**< "btspp://" */ + NFC_URI_BTL2CAP = 0x19, /**< "btl2cap://" */ + NFC_URI_BTGOEP = 0x1A, /**< "btgoep://" */ + NFC_URI_TCPOBEX = 0x1B, /**< "tcpobex://" */ + NFC_URI_IRDAOBEX = 0x1C, /**< "irdaobex://" */ + NFC_URI_FILE = 0x1D, /**< "file://" */ + NFC_URI_URN_EPC_ID = 0x1E, /**< "urn:epc:id:" */ + NFC_URI_URN_EPC_TAG = 0x1F, /**< "urn:epc:tag:" */ + NFC_URI_URN_EPC_PAT = 0x20, /**< "urn:epc:pat:" */ + NFC_URI_URN_EPC_RAW = 0x21, /**< "urn:epc:raw:" */ + NFC_URI_URN_EPC = 0x22, /**< "urn:epc:" */ + NFC_URI_URN_NFC = 0x23, /**< "urn:nfc:" */ + NFC_URI_RFU = 0xFF /**< No prepending is done. Reserved for future use. */ +} nfc_uri_id_t; + +/** @brief Function for generating a description of a URI record. + * + * This function declares and initializes a static instance of an NFC NDEF record description + * of a URI record. + * + * @note The record payload data (@p uri_id_code, @p p_uri_data, and @p + * uri_data_len) should be declared as static. If it is declared as + * automatic, the NDEF message encoding (see @ref nfc_uri_msg_encode) + * must be done in the same variable scope. + * + * @param[in] uri_id_code URI identifier code that defines the protocol field of the URI. + * @param[in] p_uri_data Pointer to the URI string. + * The string should not contain the protocol field if the protocol + * was specified in @p uri_id_code. + * @param[in] uri_data_len Length of the URI string. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_uri_rec_declare( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_URI_REC_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c new file mode 100644 index 0000000000000000000000000000000000000000..76486f54395165b2df7342c570200030f000934e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c @@ -0,0 +1,738 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" +#if NFC_HAL_ENABLED + +#include "hal_nfc_t2t.h" +#include +#include +#include "nfc_t2t_lib.h" +#include "nfc_fixes.h" +#include "nrf.h" +#include "app_util_platform.h" +#include "nordic_common.h" +#include "nrf_drv_clock.h" + +#define NRF_LOG_MODULE_NAME "HAL_NFC" +#if HAL_NFC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL HAL_NFC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR HAL_NFC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR HAL_NFC_CONFIG_DEBUG_COLOR +#else // HAL_NFC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // HAL_NFC_CONFIG_LOG_ENABLED +#include "nrf_log.h" + + +#if HAL_NFC_CONFIG_DEBUG_PIN_ENABLED + #include "nrf_gpio.h" + + #define HAL_NFC_DEBUG_PIN_CONFIG(pin_num) nrf_gpio_cfg_output(pin_num) + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) nrf_gpio_pin_clear(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) nrf_gpio_pin_set(pin_num) + + #define HAL_NFC_DEBUG_PINS_INITIALIZE() \ + do{ \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_NFC_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \ + } while(0) +#else + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) + #define HAL_NFC_DEBUG_PINS_INITIALIZE() +#endif // HAL_NFC_CONFIG_DEBUG_PIN_ENABLED + + +/* NFC library version history: + * #define NFC_LIB_VERSION 0x00 first experimental version intended for nRF52 IC rev. Engineering A (PCA10036, part of nRF52 Preview Development Kit) + * #define NFC_LIB_VERSION 0x01 experimental version intended for nRF52 IC rev. Engineering B (PCA10040, part of nRF52 Development Kit) + * #define NFC_LIB_VERSION 0x02 experimental version intended for fix IC-12826 and fix: not released HFCLK in SENSE mode + * #define NFC_LIB_VERSION 0x03 experimental version intended for support logging module + * #define NFC_LIB_VERSION 0x04 experimental version intended for nRF52840 IC rev. Engineering A (PCA10056, part of nRF52840 Preview Development Kit). Removed PCA10036 support. + */ + +#define NFC_LIB_VERSION 0x03u /**< Internal: current NFC lib. version */ + +#define T2T_INTERNAL_BYTES_NR 10u /**< Number of internal bytes defined by Type 2 Tag Operation Technical Specification */ +#define T2T_INTERNAL_BYTE_SN0_SHIFT 0u /**< Internal Byte SN0, NRF_FICR->NFC.TAGHEADER0.MFGID which is Manufacturer ID */ +#define T2T_INTERNAL_BYTE_SN1_SHIFT 8u /**< Internal Byte SN1, NRF_FICR->NFC.TAGHEADER0.UID0 */ +#define T2T_INTERNAL_BYTE_SN2_SHIFT 16u /**< Internal Byte SN2, NRF_FICR->NFC.TAGHEADER0.UID1 */ +#define T2T_INTERNAL_BYTE_SN3_SHIFT 0u /**< Internal Byte SN3, NRF_FICR->NFC.TAGHEADER1.UID3 */ +#define T2T_INTERNAL_BYTE_SN4_SHIFT 8u /**< Internal Byte SN4, NRF_FICR->NFC.TAGHEADER1.UID4 */ +#define T2T_INTERNAL_BYTE_SN5_SHIFT 16u /**< Internal Byte SN5, NRF_FICR->NFC.TAGHEADER1.UID5 */ +#define T2T_INTERNAL_BYTE_SN6_SHIFT 24u /**< Internal Byte SN6, NRF_FICR->NFC.TAGHEADER1.UID6 */ +#define CASCADE_TAG_BYTE 0x88u /**< Constant defined by ISO/EIC 14443-3 */ + +#define NFCID1_2ND_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_2ND_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_2ND_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ +#define NFCID1_LAST_BYTE3_SHIFT 24u /**< Shift value for NFC ID byte 3 */ +#define NFCID1_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ + +#define NFC_RX_BUFFER_SIZE 16u /**< NFC Rx data buffer size */ +#define T2T_READ_CMD 0x30u /**< Type 2 Tag Read command identifier */ +#define NFC_SLP_REQ_CMD 0x50u /**< NFC SLP_REQ command identifier */ +#define NFC_CRC_SIZE 2u /**< CRC size in bytes */ + +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#else + #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Msk | \ + NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Msk | \ + NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#endif // HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + +#define NRF_NFCT_FRAMESTATUS_RX_MSK (NFCT_FRAMESTATUS_RX_OVERRUN_Msk | \ + NFCT_FRAMESTATUS_RX_PARITYSTATUS_Msk | \ + NFCT_FRAMESTATUS_RX_CRCERROR_Msk) /**< Mask for clearing all flags in NFCT_FRAMESTATUS_RX register */ +#define NFC_FIELD_ON_MASK NFCT_FIELDPRESENT_LOCKDETECT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD ON. */ +#define NFC_FIELD_OFF_MASK NFCT_FIELDPRESENT_FIELDPRESENT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD OFF. */ + +typedef enum +{ + NFC_FIELD_STATE_NONE, /**< Initial value indicating no NFCT Field events. */ + NFC_FIELD_STATE_OFF, /**< NFCT FIELDLOST Event has been set. */ + NFC_FIELD_STATE_ON, /**< NFCT FIELDDETECTED Event has been set. */ + NFC_FIELD_STATE_UNKNOWN /**< Both NFCT Field Events have been set - ambiguous state. */ +}nfct_field_sense_state_t; + +/* Static function declarations */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event); +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event); +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state); + +/* Static data */ +static hal_nfc_callback_t m_nfc_lib_callback = (hal_nfc_callback_t) NULL; /**< Callback to nfc_lib layer */ +static void * m_nfc_lib_context; /**< Callback execution context */ +static volatile uint8_t m_nfc_rx_buffer[NFC_RX_BUFFER_SIZE] = {0}; /**< Buffer for NFC Rx data */ +static volatile bool m_slp_req_received = false; /**< Flag indicating that SLP_REQ Command was received */ +static volatile bool m_field_on = false; /**< Flag indicating that NFC Tag field is present */ +static nrf_drv_clock_handler_item_t m_clock_handler_item; /**< Clock event handler item structure */ + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + static volatile uint32_t m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; /**< Mask used for NFC Field polling in NFCT_FIELDPRESENT register */ +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#define NRF_NFCT_POWER (*(uint32_t volatile *)(0x40005FFC)) + +#define NFC_HAL_FIELDPRESENT_MASK (NFCT_FIELDPRESENT_LOCKDETECT_Msk | \ + NFCT_FIELDPRESENT_FIELDPRESENT_Msk) + +#define NFC_HAL_FIELDPRESENT_IS_LOST ((NFCT_FIELDPRESENT_FIELDPRESENT_NoField << \ + NFCT_FIELDPRESENT_FIELDPRESENT_Pos) | \ + (NFCT_FIELDPRESENT_LOCKDETECT_NotLocked << \ + NFCT_FIELDPRESENT_LOCKDETECT_Pos)) + +#ifndef HAL_NFC_FIELD_TIMER_PERIOD + #define HAL_NFC_FIELD_TIMER_PERIOD 100 /* unit - us */ +#endif + +static inline void hal_nfc_re_setup(void); +static void hal_nfc_field_check(void); + +static void field_timer_with_callback_config() +{ + NRF_TIMER4->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos; + NRF_TIMER4->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos; + NRF_TIMER4->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos; + NRF_TIMER4->CC[0] = HAL_NFC_FIELD_TIMER_PERIOD << TIMER_CC_CC_Pos; + NRF_TIMER4->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; + NRF_TIMER4->INTENSET = TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos; + + NVIC_ClearPendingIRQ(TIMER4_IRQn); + NVIC_SetPriority(TIMER4_IRQn, NFCT_CONFIG_IRQ_PRIORITY); + NVIC_EnableIRQ(TIMER4_IRQn); +} + +void TIMER4_IRQHandler(void) +{ + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); + hal_nfc_field_check(); + NRF_TIMER4->EVENTS_COMPARE[0] = 0; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +/** + * @brief Common part of setup used for NFCT initialization and reinitialization. + */ +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static void hal_nfc_common_hw_setup(uint8_t * const nfc_internal) +#else +static inline void hal_nfc_common_hw_setup(uint8_t * const nfc_internal) +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +{ + uint32_t nfc_tag_header0 = NRF_FICR->NFC.TAGHEADER0; + uint32_t nfc_tag_header1 = NRF_FICR->NFC.TAGHEADER1; + +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND +/* Begin: Bugfix for FTPAN-98 */ + *(volatile uint32_t *) 0x4000568C = 0x00038148; +/* End: Bugfix for FTPAN-98 */ +/* Begin: Bugfix for FTPAN-144 */ + *(volatile uint32_t *) 0x4000561c = 0x01; + *(volatile uint32_t *) 0x4000562c = 0x3F; + *(volatile uint32_t *) 0x4000563c = 0x0; +/* End: Bugfix for FTPAN-144 */ +#endif // HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos); +#else + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos) | + (NFCT_INTENSET_FIELDLOST_Enabled << NFCT_INTENSET_FIELDLOST_Pos); +#endif + + NRF_NFCT->INTENSET = (NFCT_INTENSET_ERROR_Enabled << NFCT_INTENSET_ERROR_Pos) | + (NFCT_INTENSET_SELECTED_Enabled << NFCT_INTENSET_SELECTED_Pos); + + /* According to ISO/IEC 14443-3 */ + nfc_internal[0] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN0_SHIFT)); //SN0 + nfc_internal[1] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN1_SHIFT)); //SN1 + nfc_internal[2] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN2_SHIFT)); //SN2 + nfc_internal[3] = (uint8_t) ((CASCADE_TAG_BYTE) ^ nfc_internal[0] ^ + nfc_internal[1] ^ nfc_internal[2]); //BCC0 = CASCADE_TAG_BYTE ^ SN0 ^ SN1 ^ SN2 + nfc_internal[4] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN3_SHIFT)); //SN3 + nfc_internal[5] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN4_SHIFT)); //SN4 + nfc_internal[6] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN5_SHIFT)); //SN5 + nfc_internal[7] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN6_SHIFT)); //SN6 + nfc_internal[8] = (uint8_t) (nfc_internal[4] ^ nfc_internal[5] ^ + nfc_internal[6] ^ nfc_internal[7]); //BCC1 = SN3 ^ SN4 ^ SN5 ^ SN6 + nfc_internal[9] = (uint8_t) (NFC_LIB_VERSION); //For internal use + + + /* MSB of NFCID1_2ND_LAST register is not used - always 0 */ + NRF_NFCT->NFCID1_2ND_LAST = ((uint32_t) nfc_internal[0] << NFCID1_2ND_LAST_BYTE2_SHIFT) | + ((uint32_t) nfc_internal[1] << NFCID1_2ND_LAST_BYTE1_SHIFT) | + ((uint32_t) nfc_internal[2] << NFCID1_2ND_LAST_BYTE0_SHIFT); + + NRF_NFCT->NFCID1_LAST = ((uint32_t) nfc_internal[4] << NFCID1_LAST_BYTE3_SHIFT) | + ((uint32_t) nfc_internal[5] << NFCID1_LAST_BYTE2_SHIFT) | + ((uint32_t) nfc_internal[6] << NFCID1_LAST_BYTE1_SHIFT) | + ((uint32_t) nfc_internal[7] << NFCID1_LAST_BYTE0_SHIFT); + + /* Begin: Bugfix for FTPAN-25 (IC-9929) */ + /* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used + because it's required to operate with Windows Phone */ + NRF_NFCT->SENSRES = + (NFCT_SENSRES_NFCIDSIZE_NFCID1Double << NFCT_SENSRES_NFCIDSIZE_Pos) | + (NFCT_SENSRES_BITFRAMESDD_SDD00100 << NFCT_SENSRES_BITFRAMESDD_Pos); + /* End: Bugfix for FTPAN-25 (IC-9929)*/ +} + + +ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context) +{ + uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR]; + + m_nfc_lib_callback = callback; + m_nfc_lib_context = p_context; + + hal_nfc_common_hw_setup(nfc_internal); + + (void) nfc_t2t_internal_set((uint8_t *) nfc_internal, sizeof(nfc_internal)); + + /* Initialize SDK Clock module for handling high precission clock requests */ + m_clock_handler_item.event_handler = nrf_nfct_clock_event_handler; + m_clock_handler_item.p_next = NULL; + + ret_code_t err_code = nrf_drv_clock_init(); + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + field_timer_with_callback_config(); +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + NRF_LOG_INFO("Init\r\n"); + HAL_NFC_DEBUG_PINS_INITIALIZE(); + + if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_MODULE_ALREADY_INITIALIZED)) + { + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INTERNAL; + } +} + +/**@brief Function for clearing an event flag in NRF_NFCT registers. + * + * @param[in] p_event Pointer to event register. + * + */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event) +{ + *p_event = 0; + + /* Perform read to ensure clearing is effective */ + volatile uint32_t dummy = *p_event; + (void)dummy; +} + +/**@brief Function for handling events from Clock Module. + * + * @param[in] event Clock event. + * + */ +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event) +{ + switch(event) + { + case NRF_DRV_CLOCK_EVT_HFCLK_STARTED: + /* Activate NFCT only when HFXO is running */ + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + NRF_NFCT->TASKS_ACTIVATE = 1; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static inline void nrf_nfct_field_lost_hfclk_handle(void) +{ + /* Begin: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + // reset the NFC for release HFCLK + __DMB(); + NRF_NFCT_POWER = 0; + __DMB(); + NRF_NFCT_POWER = 1; + /* END: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +/**@brief Function for evaluating and handling NFC field events. + * + * @param[in] field_state Current field state. + * + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ + if (field_state == NFC_FIELD_STATE_UNKNOWN) + { + /* Probe NFC field */ + uint32_t field_present = NRF_NFCT->FIELDPRESENT; + + if (field_present & m_nfc_fieldpresent_mask) + { + field_state = NFC_FIELD_STATE_ON; + } + else + { + field_state = NFC_FIELD_STATE_OFF; + } + } + + /* Field event service */ + switch(field_state) + { + case NFC_FIELD_STATE_ON: + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + } + m_field_on = true; + break; + + case NFC_FIELD_STATE_OFF: + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG! + +/* Begin: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + *(volatile uint32_t *)0x40005010 = 1; +#endif // HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND +/* END: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + + NRF_NFCT->TASKS_SENSE = 1; + nrf_drv_clock_hfclk_release(); + m_field_on = false; + + NRF_NFCT->INTENCLR = + (NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos) | + (NFCT_INTENCLR_RXERROR_Clear << NFCT_INTENCLR_RXERROR_Pos); + + /* Change mask to FIELD_OFF state - trigger FIELD_ON even if HW has not locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; + + if ((m_nfc_lib_callback != NULL) ) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +/* This function is used by nfc_lib for unit testing only */ +ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length) +{ + (void)id; + (void)p_data; + (void)data_length; + + return NRF_SUCCESS; +} + +/* This function is used by nfc_lib for unit testing only */ +ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length) +{ + (void)id; + (void)p_data; + (void)p_max_data_length; + + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_start(void) +{ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + NRF_NFCT->TASKS_SENSE = 1; + + NVIC_ClearPendingIRQ(NFCT_IRQn); + NVIC_SetPriority(NFCT_IRQn, NFCT_CONFIG_IRQ_PRIORITY); + NVIC_EnableIRQ(NFCT_IRQn); + + NRF_LOG_INFO("Start\r\n"); + return NRF_SUCCESS; +} + +ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length) +{ + if (data_length == 0) + { + return NRF_ERROR_DATA_SIZE; + } + + /* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + NRF_NFCT->PACKETPTR = (uint32_t) p_data; + NRF_NFCT->TXD.AMOUNT = (data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); + NRF_NFCT->TASKS_STARTTX = 1; + + NRF_LOG_INFO("Send\r\n"); + return NRF_SUCCESS; +} + +ret_code_t hal_nfc_stop(void) +{ + NRF_NFCT->TASKS_DISABLE = 1; + + NRF_LOG_INFO("Stop\r\n"); + return NRF_SUCCESS; +} + +ret_code_t hal_nfc_done(void) +{ + m_nfc_lib_callback = (hal_nfc_callback_t) NULL; + + return NRF_SUCCESS; +} + +void NFCT_IRQHandler(void) +{ + nfct_field_sense_state_t current_field = NFC_FIELD_STATE_NONE; + + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_NFC_EVENT_DEBUG_PIN); //DEBUG! + + if (NRF_NFCT->EVENTS_FIELDDETECTED && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDDETECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDDETECTED); + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_DETECT_EVENT_DEBUG_PIN); //DEBUG! + current_field = NFC_FIELD_STATE_ON; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); //DEBUG! + + NRF_LOG_DEBUG("Field detected\r\n"); + } + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + if (NRF_NFCT->EVENTS_FIELDLOST && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDLOST_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDLOST); + current_field = + (current_field == NFC_FIELD_STATE_NONE) ? NFC_FIELD_STATE_OFF : NFC_FIELD_STATE_UNKNOWN; + + NRF_LOG_DEBUG("Field lost\r\n"); + } +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + /* Perform actions if any FIELD event is active */ + if (current_field != NFC_FIELD_STATE_NONE) + { + nrf_nfct_field_event_handler(current_field); + } + + if (NRF_NFCT->EVENTS_RXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_RXFRAMEEND_Msk)) + { + /* Take into account only number of whole bytes */ + uint32_t rx_data_size = ((NRF_NFCT->RXD.AMOUNT & NFCT_RXD_AMOUNT_RXDATABYTES_Msk) >> + NFCT_RXD_AMOUNT_RXDATABYTES_Pos) - NFC_CRC_SIZE; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + + /* Look for Tag 2 Type READ Command */ + if (m_nfc_rx_buffer[0] == T2T_READ_CMD) + { + if(m_nfc_lib_callback != NULL) + { + /* This callback should trigger transmission of READ Response */ + m_nfc_lib_callback(m_nfc_lib_context, + HAL_NFC_EVENT_DATA_RECEIVED, + (void*)m_nfc_rx_buffer, + rx_data_size); + } + } + else + { + /* Indicate that SLP_REQ was received - this will cause FRAMEDELAYTIMEOUT error */ + if(m_nfc_rx_buffer[0] == NFC_SLP_REQ_CMD) + { + m_slp_req_received = true; + } + /* Not a READ Command, so wait for next frame reception */ + NRF_NFCT->TASKS_ENABLERXDATA = 1; + } + + NRF_LOG_DEBUG("Rx fend\r\n"); + } + + if (NRF_NFCT->EVENTS_TXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMEEND_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + /* Disable TX END event to ignore frame transmission other than READ response */ + NRF_NFCT->INTENCLR = (NFCT_INTENCLR_TXFRAMEEND_Clear << NFCT_INTENCLR_TXFRAMEEND_Pos); + + /* Set up for reception */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_DATA_TRANSMITTED, 0, 0); + } + + NRF_LOG_DEBUG("Tx fend\r\n"); + } + + if (NRF_NFCT->EVENTS_SELECTED && (NRF_NFCT->INTEN & NFCT_INTEN_SELECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_SELECTED); + /* Clear also RX END and RXERROR events because SW does not take care of commands which were received before selecting the tag */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + /* Set up registers for EasyDMA and start receiving packets */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + + NRF_NFCT->INTENSET = (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) | + (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos); + + /* At this point any previous error status can be ignored */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + /* Change mask to FIELD_ON state - trigger FIELD_ON only if HW has locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_ON_MASK; +#endif + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_ON, 0, 0); + } + + NRF_LOG_DEBUG("Selected\r\n"); + } + + if (NRF_NFCT->EVENTS_RXERROR && (NRF_NFCT->INTEN & NFCT_INTEN_RXERROR_Msk)) + { + uint32_t rx_status = NRF_NFCT->FRAMESTATUS.RX; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + NRF_LOG_DEBUG("Rx error (0x%x)\r\n", (unsigned int) rx_status); + (void) rx_status; + + /* Clear rx frame status */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + } + + if (NRF_NFCT->EVENTS_ERROR && (NRF_NFCT->INTEN & NFCT_INTEN_ERROR_Msk)) + { + uint32_t err_status = NRF_NFCT->ERRORSTATUS; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_ERROR); + + /* Clear FRAMEDELAYTIMEOUT error (expected HW behaviour) when SLP_REQ command was received */ + if ((err_status & NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) && m_slp_req_received) + { + NRF_NFCT->ERRORSTATUS = NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + m_slp_req_received = false; + + NRF_LOG_DEBUG("Error (SLP_REQ)\r\n"); + } + /* Report any other error */ + err_status &= ~NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + if (err_status) + { + NRF_LOG_DEBUG("Error (0x%x)\r\n", (unsigned int) err_status); + } + + /* Clear error status */ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + } + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); //DEBUG! +} + + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + #error Wrong workaround combination +#endif + +static uint32_t field_state_cnt = 0; +/** + * @brief Function for evaluating and handling NFC fieldlost event. + */ +static void hal_nfc_field_check(void) +{ + uint32_t nfc_fieldpresen_masked; + + nfc_fieldpresen_masked = NRF_NFCT->FIELDPRESENT & NFC_HAL_FIELDPRESENT_MASK; + + if (nfc_fieldpresen_masked == NFC_HAL_FIELDPRESENT_IS_LOST) + { + ++field_state_cnt; + if (field_state_cnt > 7) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG! + + NRF_TIMER4->TASKS_SHUTDOWN = 1; + + nrf_drv_clock_hfclk_release(); + + nrf_nfct_field_lost_hfclk_handle(); + + if ((m_nfc_lib_callback != NULL)) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + m_field_on = false; + + /* Begin: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + // resume the NFCT to initialized state + hal_nfc_re_setup(); + /* End: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG! + } + + return; + } + + field_state_cnt = 0; +} + +/** + * @brief Function for enablinge hight precision clock and start eveluating fieldlost event. + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + + NRF_TIMER4->TASKS_CLEAR = 1; + NRF_TIMER4->TASKS_START = 1; + field_state_cnt = 0; + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + } + m_field_on = true; +} + +/** + * @brief Function for resume the NFCT to initialized state after software's reset. + */ +static inline void hal_nfc_re_setup(void) +{ + uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR]; + + hal_nfc_common_hw_setup(nfc_internal); + + NRF_LOG_INFO("Reinitialize\r\n"); +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#endif // NFC_HAL_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h new file mode 100644 index 0000000000000000000000000000000000000000..cdd62777cad6e6b48b47c5116ede48bf6d6b5d57 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2015 - 2017, Telit Communications Cyprus Ltd + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef HAL_NFC_H__ +#define HAL_NFC_H__ + +/** @file + * @defgroup nfc_t2t_hal NFC Type 2 Tag HAL + * @{ + * @ingroup nfc_t2t + * @brief @tagAPI52 Hardware abstraction layer for the NFC Type 2 Tag library. + * + * @note Before the NFCT peripheral enters ACTIVATED state, the HFXO must be running. + * To fulfill this requirement and allow other software modules to also request the HFXO, the NFC Type 4 Tag HAL uses @ref nrf_drv_clock module. + * + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Events passed to the upper-layer callback function. */ +typedef enum { + HAL_NFC_EVENT_FIELD_ON, ///< Field is detected. + HAL_NFC_EVENT_FIELD_OFF, ///< Field is lost. + HAL_NFC_EVENT_DATA_RECEIVED, ///< Data is received. + HAL_NFC_EVENT_DATA_TRANSMITTED ///< Data is Transmitted. +} hal_nfc_event_t; + + +/** @brief Parameter IDs for set/get function. */ +typedef enum { + HAL_NFC_PARAM_ID_TESTING, ///< Used for unit tests. + HAL_NFC_PARAM_ID_UNKNOWN +} hal_nfc_param_id_t; + + +/** @brief Callback from HAL_NFC layer into the upper layer. + * + * If event == HAL_NFC_EVENT_DATA_RECEIVED: + * p_data points to the received packet. The memory belongs to the HAL_NFC layer and + * is guaranteed to be valid only until the callback returns. + * + * If event == HAL_NFC_EVENT_DATA_TRANSMITTED: + * p_data points to the transmitted packet. The memory belongs to the application. + * + * If event == \: + * p_data definition is event-specific (to be defined). + * + * @param[in] p_context Context for callback execution. + * @param[in] event The event that occurred. + * @param[in] p_data Received/transmitted data or NULL. + * @param[in] data_length Size of the received/transmitted packet. + */ +typedef void (* hal_nfc_callback_t)(void * p_context, + hal_nfc_event_t event, + const uint8_t * p_data, + size_t data_length); + + +/** @brief Function for initializing the NFC layer. + * + * This function provides a pointer to a callback function and the callback context + * to the NFC layer. + * + * @param[in] callback Pointer to the callback function. + * @param[in] p_context Context of callback. + * + * @retval NRF_SUCCESS If the NFC layer was initialized successfully. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context); + + +/** @brief Function for setting a HAL_NFC parameter. + * + * This function allows to set any parameter defined as available by HAL_NFC. + * + * @param[in] id ID of the parameter to set. + * @param[in] p_data Pointer to the buffer containing the data to set. + * @param[in] data_length Size of the buffer containing the data to set. + * + * @retval NRF_SUCCESS If the parameter was set successfully. If one of the arguments + * was invalid (for example, wrong data length), an error code + * is returned. + */ +ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length); + + +/** @brief Function for querying a HAL_NFC parameter value. + * + * The queried value will be placed into the passed data buffer. If the buffer + * is too small, maxDataLength will contain the required buffer size. + * + * @param[in] id ID of the parameter to query. + * @param[in] p_data Pointer to a buffer receiving the queried data. + * @param[in, out] p_max_data_length Size of the buffer. It receives the required size if buffer is too small. + * + * @retval NRF_SUCCESS If the parameter was received successfully. If one of the arguments + * was invalid (for example, the buffer was too small), an error code + * is returned. + */ +ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length); + + +/** @brief Function for starting the NFC subsystem. + * + * After this function completes, NFC readers will be able to detect the chip. + * + * @retval NRF_SUCCESS If the NFC subsystem was started successfully. If the NFC + * subsystem could not be started, an error code is returned. + */ +ret_code_t hal_nfc_start(void); + + +/** @brief Function for sending a packet to the connected NFC reader. + * + * The provided data buffer belongs to the caller and is guaranteed to be + * valid until the HAL_NFC_EVENT_DATA_TRANSMITTED event is received by the + * callback. + * + * @param[in] p_data The data packet to send. + * @param[in] data_length Size of the packet in bytes. + * + * @retval NRF_SUCCESS If the packet was sent. Otherwise, an error code is returned. + */ +ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length); + + +/** @brief Function for stopping the NFC subsystem. + * + * After this function returns, NFC readers will no longer be able to connect + * to the chip. + * + * @retval NRF_SUCCESS If the NFC subsystem was stopped. Otherwise, an error code + * is returned. + */ +ret_code_t hal_nfc_stop(void); + + +/** @brief Function for releasing resources. + * + * After this call returns, the callback is considered invalid and no more + * events will be posted to it. + * + * @retval NRF_SUCCESS This function always succeeds. + */ +ret_code_t hal_nfc_done(void); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* HAL_NFC_H__ */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/license.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/license.txt new file mode 100644 index 0000000000000000000000000000000000000000..fb8b8526b797d604569979df4799445c2105e694 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/license.txt @@ -0,0 +1,36 @@ +Copyright (c) 2015 - 2017, Telit Communications Cyprus Ltd + +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, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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 Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/nfc_fixes.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/nfc_fixes.h new file mode 100644 index 0000000000000000000000000000000000000000..d2e759b406ca0bdcf53806fda64afc9a7688c230 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/nfc_fixes.h @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef NFC_FIXES_H__ +#define NFC_FIXES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + * @defgroup nfc_fixes NFC fixes and workarounds + * @{ + * @ingroup nfc_t2t + * @brief @tagAPI52 Fixes for hardware-related anomalies. + * + * If you are using PCA10040 (part of nRF52 Development Kit), + * you must define the macro HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 79. NFCT: A false EVENTS_FIELDDETECTED event occurs after the field is lost. + * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode. + * + * If you are using PCA10056 (part of nRF52840 Development Kit), + * you must define the macro HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 98. NFCT: The NFCT is not able to communicate with the peer. + * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode. + * + * The current code contains a patch for anomaly 25 (NFCT: Reset value of + * SENSRES register is incorrect), so that it now works on Windows Phone. + */ + +#ifdef BOARD_PCA10040 // assume nRF52832 chip in IC rev. Engineering B or Engineering C + #define HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +#elif defined(BOARD_PCA10056) // assume nRF52840 chip in IC rev. Engineering A + #define HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_FIXES_H__ */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/nfc_t2t_lib.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/nfc_t2t_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..70c54efa232c8419a26ab2c94dc492dbc87a5f17 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_lib/nfc_t2t_lib.h @@ -0,0 +1,267 @@ +/** + * Copyright (c) 2015 - 2017, Telit Communications Cyprus Ltd + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef NFC_T2T_LIB_H__ +#define NFC_T2T_LIB_H__ + +/** @file + * + * @addtogroup nfc_api + * + * @defgroup nfc_t2t NFC Type 2 Tag + * @ingroup nfc_api + * @brief Implementation of NFC Type 2 Tag. + * + * @defgroup nfc_t2t_lib NFC tag 2 type emulation library + * @{ + * @ingroup nfc_t2t + * @brief The T2T emulation library interface. + */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define NFC_T2T_SIZEOF_INTERNAL_BYTES 10 ///< T2T internal byte size. +#define NFC_T2T_MAX_PAYLOAD_SIZE 988 ///< Maximum NDEF message size. +#define NFC_T2T_MAX_PAYLOAD_SIZE_RAW 1008 ///< No NDEF-TLV and no implicit lock bytes at the end. + +/** @brief Events passed to the callback function. */ +typedef enum +{ + NFC_T2T_EVENT_NONE, + ///< Not used. + + NFC_T2T_EVENT_FIELD_ON, + ///< NFC tag has detected external NFC field and was selected by an NFC polling device. + + NFC_T2T_EVENT_FIELD_OFF, + ///< External NFC field has been removed. + + NFC_T2T_EVENT_DATA_READ, + ///< NFC polling device has read all tag data. + /**< + * Repeated reading in the same session i.e. before @ref NFC_T2T_EVENT_FIELD_OFF event, + * will not trigger another @ref NFC_T2T_EVENT_DATA_READ event. + */ + + NFC_T2T_EVENT_STOPPED + ///< Reference to the application NFC callback has been released using @ref nfc_t2t_done. +} nfc_t2t_event_t; + +typedef enum +{ + NFC_T2T_PARAM_TESTING ///< Used for unit tests. +} nfc_t2t_param_id_t; + +/** @brief Callback to pass events from NFC T2T Library to application. + * + * @param[in] p_context Application context for callback execution. + * @param[in] event The event that occurred. + * @param[in] p_data Data to send to the application (event specific). + * @param[in] data_length Length of the data. + */ +typedef void (*nfc_t2t_callback_t)(void * p_context, + nfc_t2t_event_t event, + const uint8_t * p_data, + size_t data_length); + +/** @brief Function for registering the application callback for event signaling. + * + * The callback will be called by NFC T2T Library to notify the application of relevant + * events. It will be called from the HAL_NFC callback context. + * + * @param[in] callback Function pointer to the callback. + * @param[in] p_context Pointer to a memory area used by the callback for execution (optional). + * + * @retval NRF_SUCCESS If the application callback was registered successfully. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t nfc_t2t_setup(nfc_t2t_callback_t callback, void * p_context); + +/** @brief Function for setting an NFC parameter. + * + * @note Not implemented. For future use. + * + * This function allows to set any parameter defined as available by HAL_NFC. + * + * @param[in] id ID of the parameter to set. + * @param[in] p_data Pointer to a buffer containing the data to set. + * @param[in] data_length Size of the buffer containing the data to set. + * + * @retval NRF_SUCCESS If the parameter was set successfully. If one of the arguments + * was invalid (for example, a wrong data length), an error code + * is returned. + */ +ret_code_t nfc_t2t_parameter_set(nfc_t2t_param_id_t id, void * p_data, size_t data_length); + +/** @brief Function for querying an NFC parameter value. + * + * @note Not implemented. For future use. + * + * The queried value will be placed into the passed data buffer. If the buffer + * is too small, p_max_data_length will contain the required buffer size. If the + * buffer is big enough, p_max_data_length will contain the actual size of the + * data. + * + * @param[in] id ID of the parameter to query. + * @param[in] p_data Pointer to a buffer receiving the queried data. + * @param[in, out] p_max_data_length Size of the buffer, receives actual size of queried data. + * + * @retval NRF_SUCCESS If the parameter was received successfully. If one of the arguments + * was invalid (for example, the buffer was too small), an error code + * is returned. + */ +ret_code_t nfc_t2t_parameter_get(nfc_t2t_param_id_t id, void * p_data, size_t * p_max_data_length); + +/** @brief Function for registering the payload to send on reception of a READ request. + * + * The payload is considered to only contain the NDEF message to deliver to a + * reader. The required NDEF TLV will be created implicitly by NFC T2T Library. + * + * The pointer to the payload must stay valid for the duration of the library + * execution, or until it is explicitly released. + * + * If the pointer is not NULL, but the length is zero, the paypload is + * considered to be an empty NDEF message. + * + * If a new payload is registered, the previously registered one is considered + * released. + * + * Passing a NULL pointer releases the current payload without registering a + * new one. + * + * If an invalid size is given (too big), the function returns with an error + * and the currently registered payload is left unchanged. + * + * @param[in] p_payload Pointer to the memory area containing the payload to send. + * @param[in] payload_length Size of the payload in bytes. + * + * @retval NRF_SUCCESS If the operation was successful. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t nfc_t2t_payload_set(const uint8_t * p_payload, size_t payload_length); + +/** @brief Function for registering the raw payload to send on reception of a READ request. + * + * The payload will be delivered directly as-is to the reader, without + * implicitly adding an NDEF TLV container. This can be used if the + * application wants to define the TLVs itself, for example, to provide a different + * memory layout. + * + * The pointer to the payload must stay valid for the duration of the library + * execution, or until it is explicitly released. + * + * If a new payload is registered, the previously registered one is considered + * released. + * + * Passing a NULL pointer releases the current payload, without registering a + * new one. + * + * If an invalid size is given (too big), the function returns with an error + * and the currently registered payload is left unchanged. + * + * @param[in] p_payload Pointer to the memory area containing the payload to send. + * @param[in] payload_length Size of the payload in bytes. + * + * @retval NRF_SUCCESS If the operation was successful. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t nfc_t2t_payload_raw_set(const uint8_t * p_payload, size_t payload_length); + +/** @brief Function for registering the sequence of internal bytes. + * + * This refers to the first 10 bytes of the tag memory. The library will set + * a sensible default for these bytes. The application can use this function + * to override the default. + * + * Passing a NULL pointer reverts back to the default sequence. + * The data will be copied by NFC T2T Library, so the memory does not have to remain valid + * after the function returns. + * + * @note When modifying the internal bytes, remember that they must be consistent + * with the NFC hardware register settings (see @ref nfc_t2t_format_internal). + * + * @param[in] p_data Pointer to the memory area containing the data. + * @param[in] data_length Size of the data in bytes. + * + * @retval NRF_SUCCESS If the operation was successful. If the data was not NULL and the + * data length was not 10, an error code is returned. + */ +ret_code_t nfc_t2t_internal_set(const uint8_t * p_data, size_t data_length); + +/** @brief Function for activating the NFC frontend. + * + * You must call this function so that events are posted to the application + * callback. + * + * @retval NRF_SUCCESS If the NFC frontend was activated successfully. If the lower layer + * could not be started, an error code is returned. + */ +ret_code_t nfc_t2t_emulation_start(void); + +/** @brief Function for deactivating the NFC frontend. + * + * After calling this function, no more events will be posted to the + * application callback. + * + * @retval NRF_SUCCESS If the NFC frontend was deactivated successfully. If the lower layer + * could not be stopped, an error code is returned. + */ +ret_code_t nfc_t2t_emulation_stop(void); + +/** @brief Function for releasing the reference to the application callback. + * + * After calling this function, the passed callback pointer is no longer + * considered valid. + * + * @retval NRF_SUCCESS This function always succeeds. + */ +ret_code_t nfc_t2t_done(void); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif // NFC_T2T_LIB_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_parser/nfc_t2t_parser.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_parser/nfc_t2t_parser.c new file mode 100644 index 0000000000000000000000000000000000000000..c129f2ff4cd79e15f1f394819c6e8e823d21f721 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_parser/nfc_t2t_parser.c @@ -0,0 +1,678 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_T2T_PARSER) + +#include +#include +#include "nrf_delay.h" +#include "nfc_t2t_parser.h" + +#define NRF_LOG_MODULE_NAME "NFC_T2T_PARSER" +#if NFC_T2T_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T2T_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T2T_PARSER_INFO_COLOR +#else // NFC_T2T_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_T2T_PARSER_LOG_ENABLED +#include "nrf_log.h" + +/// Gets least significant nibble (a 4-bit value) from a byte. +#define LSN_GET(val) (val & 0x0F) + +/// Gets most significant nibble (a 4-bit value) from a byte. +#define MSN_GET(val) ((val >> 4) & 0x0F) + +/** + * @brief Function for inserting the TLV block into a @ref type_2_tag_t structure. + * + * The content of a TLV block structure pointed by the p_tlv_block is copied into a TLV block + * array within the structure pointed by the p_type_2_tag. + * + * @param[in,out] p_type_2_tag Pointer to the structure that contains the TLV blocks array. + * @param[in] p_tlv_block Pointer to the TLV block to insert. + * + * @retval NRF_SUCCESS If the block was inserted successfully. + * @retval NRF_ERROR_NO_MEM If there is already maximum number of blocks stored in the array. + * + */ +static ret_code_t type_2_tag_tlv_block_insert(type_2_tag_t * p_type_2_tag, + tlv_block_t * p_tlv_block) +{ + if (p_type_2_tag->tlv_count == p_type_2_tag->max_tlv_blocks) + { + return NRF_ERROR_NO_MEM; + } + + // Copy contents of the source block. + p_type_2_tag->p_tlv_block_array[p_type_2_tag->tlv_count] = *p_tlv_block; + p_type_2_tag->tlv_count++; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for checking if the TLV block length is correct. + * + * Some TLV block has predefined length: + * TLV_NULL and TLV_TERMINATOR always have a length of 1 byte. + * TLV_LOCK_CONTROL and TLV_MEMORY_CONTROL always have a length of 3 bytes. + * + * @param[in] p_block_to_check Pointer to the structure that contains the TLV block length. + * + * @retval TRUE If the length is correct. + * @retval FALSE Otherwise. + * + */ +static bool tlv_block_is_data_length_correct(tlv_block_t * p_block_to_check) +{ + switch (p_block_to_check->tag) + { + case TLV_NULL: + case TLV_TERMINATOR: + if (p_block_to_check->length != TLV_NULL_TERMINATOR_LEN) + { + return false; + } + break; + + case TLV_LOCK_CONTROL: + case TLV_MEMORY_CONTROL: + if (p_block_to_check->length != TLV_LOCK_MEMORY_CTRL_LEN) + { + return false; + } + break; + + case TLV_NDEF_MESSAGE: + case TLV_PROPRIETARY: + default: + // Any length will do. + break; + } + + return true; +} + +/** + * @brief Function for checking if the end of the tag data area was reached. + * + * @param[in] p_type_2_tag Pointer to the structure that contains the data area size. + * @param[in] offset Current byte offset. + * + * @retval TRUE If the offset indicates the end of the data area. + * @retval FALSE Otherwise. + * + */ +static bool type_2_tag_is_end_reached(type_2_tag_t * p_type_2_tag, uint16_t offset) +{ + return offset == (p_type_2_tag->cc.data_area_size + T2T_FIRST_DATA_BLOCK_OFFSET); +} + + +/** + * @brief Function for checking if version of Type 2 Tag specification read from a tag is supported. + * + * @param[in] p_type_2_tag Pointer to the structure that contains the tag version. + * + * @retval TRUE If the version is supported and tag data can be parsed. + * @retval FALSE Otherwise. + * + */ +static bool type_2_tag_is_version_supported(type_2_tag_t * p_type_2_tag) +{ + // Simple check atm, as only 1 major version has been issued so far, so no backward compatibility + // is needed, tags with newer version implemented shall be rejected according to the doc. + return p_type_2_tag->cc.major_version == T2T_SUPPORTED_MAJOR_VERSION; +} + + +/** + * @brief Function for checking if the field fits into the data area specified in + * the Capability Container. + * + * @param[in] p_type_2_tag Pointer to the structure that contains the data area size. + * @param[in] offset As Offset of the field to check. + * @param[in] field_length Length of the field to check. + * + * @retval TRUE If the field fits into the data area. + * @retval FALSE If the field exceeds the data area. + * + */ +static bool type_2_tag_is_field_within_data_range(type_2_tag_t * p_type_2_tag, + uint16_t offset, + uint16_t field_length) +{ + // Invalid argument, return false. + if (field_length == 0) + { + return false; + } + return ( (offset + field_length - 1) < + (p_type_2_tag->cc.data_area_size + T2T_FIRST_DATA_BLOCK_OFFSET) ) + && ( offset >= T2T_FIRST_DATA_BLOCK_OFFSET ); +} + + +/** + * @brief Function for reading the tag field of a TLV block from the p_raw_data buffer. + * + * This function reads the tag field containing a TLV block type and inserts its value into + * a structure pointed by the p_tlv_buf pointer. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_t_offset As input: offset of the tag field to read. As output: offset of + * the first byte after the tag field. + * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the tag type will be + * inserted. + * + * @retval NRF_SUCCESS If the tag field at specified offset is correct. + * @retval NRF_ERROR_INVALID_DATA If the tag field at specified offset exceeds the data + * area specified in the Capability Container. + * + */ +static ret_code_t type_2_tag_type_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_t_offset, + tlv_block_t * p_tlv_buf) +{ + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_t_offset, TLV_T_LENGTH)) + { + return NRF_ERROR_INVALID_DATA; + } + + p_tlv_buf->tag = p_raw_data[*p_t_offset]; + *p_t_offset += TLV_T_LENGTH; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for reading the length field of a TLV block from the p_raw_data buffer. + * + * This function reads the length field of a TLV block and inserts its value into a structure + * pointed by the p_tlv_buf pointer. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_l_offset As input: offset of the length field to read. As output: offset of + * the first byte after the length field. + * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the length will be + * inserted. + * + * @retval NRF_SUCCESS If the length field at specified offset is correct. + * @retval NRF_ERROR_INVALID_DATA If the length field at specified offset exceeds the data + * area specified in the Capability Container or has + * incorrect format. + * + */ +static ret_code_t type_2_tag_length_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_l_offset, + tlv_block_t * p_tlv_buf) +{ + uint16_t length; + + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_l_offset, TLV_L_SHORT_LENGTH)) + { + return NRF_ERROR_INVALID_DATA; + } + + length = p_raw_data[*p_l_offset]; + + if (length == TLV_L_FORMAT_FLAG) + { + // Check another two bytes. + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_l_offset, TLV_L_LONG_LENGTH)) + { + return NRF_ERROR_INVALID_DATA; + } + + length = uint16_big_decode(&p_raw_data[*p_l_offset + 1]); + + // Long length value cannot be lower than 0xFF. + if (length < 0xFF) + { + return NRF_ERROR_INVALID_DATA; + } + + p_tlv_buf->length = length; + *p_l_offset += TLV_L_LONG_LENGTH; + + } + else + { + p_tlv_buf->length = length; + *p_l_offset += TLV_L_SHORT_LENGTH; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for reading a pointer to the value field of a TLV block from the p_raw_data buffer. + * + * This function reads a pointer to the value field of a TLV block and inserts it into + * a structure pointed by the p_tlv_buf pointer. If there is no value field present in the + * TLV block, NULL is inserted. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_v_offset As input: offset of the value field to read. As output: offset of + * the first byte after the value field. + * @param[in,out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the value field + * pointer will be inserted. + * + * @retval NRF_SUCCESS If the value field at specified offset is correct. + * @retval NRF_ERROR_INVALID_DATA If the value field at specified offset exceeds the data + * area specified in the Capability Container. + * + */ +static ret_code_t type_2_tag_value_ptr_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_v_offset, + tlv_block_t * p_tlv_buf) +{ + if (p_tlv_buf->length == 0) + { + // Clear the value pointer, don't touch the offset. + p_tlv_buf->p_value = NULL; + } + else + { + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_v_offset, p_tlv_buf->length)) + { + return NRF_ERROR_INVALID_DATA; + } + + p_tlv_buf->p_value = p_raw_data + *p_v_offset; + *p_v_offset += p_tlv_buf->length; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for reading a single TLV block from the p_raw_data buffer. + * + * This function reads a single TLV block from the p_raw_data buffer and stores its contents in a + * structure pointed by the p_tlv_buf. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_tlv_offset As input: offset of the TLV block to read. As output: offset of the + * next TLV block, 0 if it was the last block. + * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure that will be filled with + * the data read. + * + * @retval NRF_SUCCESS If the parsing operation of the block succeeded. Otherwise, an error + * code is returned. + * + */ +static ret_code_t type_2_tag_tlv_block_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_offset, + tlv_block_t * p_tlv_buf) +{ + ret_code_t err_code; + memset(p_tlv_buf, 0, sizeof(tlv_block_t)); + + // TLV Tag field. + err_code = type_2_tag_type_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Further processing depends on tag field value. + switch (p_tlv_buf->tag) + { + case TLV_NULL: + // Simply ignore NULL blocks, leave the incremented offset. + break; + + case TLV_TERMINATOR: + // Write 0 to the offset variable, indicating that last TLV block was found. + *p_offset = 0; + break; + + case TLV_LOCK_CONTROL: + case TLV_MEMORY_CONTROL: + case TLV_NDEF_MESSAGE: + case TLV_PROPRIETARY: + default: + // Unknown blocks should also be extracted. + err_code = type_2_tag_length_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (p_tlv_buf->length > 0) + { + err_code = type_2_tag_value_ptr_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + break; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for checking the checksum bytes of the UID stored in internal area. + * + * This function calculates the block check character (BCC) bytes based on the parsed serial number + * and compares them with bytes read from the Type 2 Tag. + * + * @param[in] p_sn Pointer to the @ref type_2_tag_serial_number_t structure to check. + * + * @retval TRUE If the calculated BCC matched the BCC from the tag. + * @retval FALSE Otherwise. + * + */ +static bool type_2_tag_is_bcc_correct(type_2_tag_serial_number_t * p_sn) +{ + uint8_t bcc1 = (uint8_t)T2T_UID_BCC_CASCADE_BYTE ^ + (uint8_t)p_sn->manufacturer_id ^ + (uint8_t)((p_sn->serial_number_part_1 >> 8) & 0xFF) ^ + (uint8_t)(p_sn->serial_number_part_1 & 0xFF); + + uint8_t bcc2 = (uint8_t)((p_sn->serial_number_part_2 >> 24) & 0xFF) ^ + (uint8_t)((p_sn->serial_number_part_2 >> 16) & 0xFF) ^ + (uint8_t)((p_sn->serial_number_part_2 >> 8) & 0xFF) ^ + (uint8_t)( p_sn->serial_number_part_2 & 0xFF); + + return (bcc1 == p_sn->check_byte_0) && (bcc2 == p_sn->check_byte_1); +} + + +/** + * @brief Function for parsing an internal area of a Type 2 Tag. + * + * This function reads data from an internal area in the raw data buffer and fills the + * @ref type_2_tag_serial_number_t structure within @ref type_2_tag_t. + * + * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag. + * + * @retval NRF_SUCCESS If the parsing operation of the internal area succeeded. + * Otherwise, an error code is returned. + * + */ +static ret_code_t type_2_tag_internal_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data) +{ + p_type_2_tag->sn.manufacturer_id = p_raw_data[0]; + p_type_2_tag->sn.serial_number_part_1 = uint16_big_decode(&p_raw_data[1]); + p_type_2_tag->sn.check_byte_0 = p_raw_data[3]; + p_type_2_tag->sn.serial_number_part_2 = uint32_big_decode(&p_raw_data[4]); + p_type_2_tag->sn.check_byte_1 = p_raw_data[8]; + p_type_2_tag->sn.internal = p_raw_data[9]; + + p_type_2_tag->lock_bytes = uint16_big_decode(&p_raw_data[10]); + + if (!type_2_tag_is_bcc_correct(&p_type_2_tag->sn)) + { + NRF_LOG_WARNING("Warning! BCC of the serial number is not correct!\r\n"); + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for parsing a Capabiliy Container area of a Type 2 Tag. + * + * This function reads data from a Capability Container area in the raw data buffer and fills the + * @ref type_2_tag_capability_container_t structure within @ref type_2_tag_t. + * + * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag. + * + * @retval NRF_SUCCESS If the parsing operation of the Capability Container succeeded. + * Otherwise, an error code is returned. + * + */ +static ret_code_t type_2_tag_cc_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data) +{ + uint8_t * p_cc_block = p_raw_data + T2T_CC_BLOCK_OFFSET; + + if (p_cc_block[0] != T2T_NFC_FORUM_DEFINED_DATA) + { + return NRF_ERROR_INVALID_DATA; + } + + p_type_2_tag->cc.major_version = MSN_GET(p_cc_block[1]); + p_type_2_tag->cc.minor_version = LSN_GET(p_cc_block[1]); + p_type_2_tag->cc.data_area_size = p_cc_block[2] * 8; + p_type_2_tag->cc.read_access = MSN_GET(p_cc_block[3]); + p_type_2_tag->cc.write_access = LSN_GET(p_cc_block[3]); + + return NRF_SUCCESS; +} + + +/** + * @brief Function for parsing a single TLV block. + * + * This function reads a single TLV block from the raw data buffer, from the position indicated by + * the p_tlv_offset, and adds it to the @ref type_2_tag_t structure. + * + * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag. + * @param[in,out] p_tlv_offset As input: offset of the TLV block to parse. As output: offset of the + * next TLV block, 0 if it was the last block. + * + * @retval NRF_SUCCESS If the parsing operation of the block succeeded. Otherwise, an error + * code is returned. + * + */ +static ret_code_t type_2_tag_tlv_parse(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_tlv_offset) +{ + ret_code_t err_code; + tlv_block_t new_block; + + // Get tag field. + err_code = type_2_tag_tlv_block_extract(p_type_2_tag, p_raw_data, p_tlv_offset, &new_block); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!tlv_block_is_data_length_correct(&new_block)) + { + return NRF_ERROR_INVALID_DATA; + } + + // Further action depends on tag type. + switch (new_block.tag) + { + case TLV_NULL: + case TLV_TERMINATOR: + // Ignore them. + break; + + case TLV_LOCK_CONTROL: + case TLV_MEMORY_CONTROL: + case TLV_NDEF_MESSAGE: + case TLV_PROPRIETARY: + default: + // Unknown tag types are also added. + err_code = type_2_tag_tlv_block_insert(p_type_2_tag, &new_block); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_WARNING("Warning! Not enough memory to insert all of the blocks!\r\n"); + return err_code; + } + break; + } + + return NRF_SUCCESS; +} + + +void type_2_tag_clear(type_2_tag_t * p_type_2_tag) +{ + p_type_2_tag->tlv_count = 0; + memset(&p_type_2_tag->cc, 0, sizeof(p_type_2_tag->cc)); + memset(&p_type_2_tag->sn, 0, sizeof(p_type_2_tag->sn)); +} + + +ret_code_t type_2_tag_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data) +{ + ret_code_t err_code; + + type_2_tag_clear(p_type_2_tag); + + err_code = type_2_tag_internal_parse(p_type_2_tag, p_raw_data); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = type_2_tag_cc_parse(p_type_2_tag, p_raw_data); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!type_2_tag_is_version_supported(p_type_2_tag)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint16_t offset = T2T_FIRST_DATA_BLOCK_OFFSET; + + while (offset > 0) + { + // Check if end of tag is reached (no terminator block was present). + if (type_2_tag_is_end_reached(p_type_2_tag, offset)) + { + NRF_LOG_DEBUG("No terminator block was found in the tag!\r\n"); + break; + } + + err_code = type_2_tag_tlv_parse(p_type_2_tag, p_raw_data, &offset); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +void type_2_tag_printout(type_2_tag_t * p_type_2_tag) +{ + uint32_t i; + NRF_LOG_INFO("Type 2 Tag contents:\r\n\r\n"); + NRF_LOG_INFO("Number of TLV blocks: %d\r\n\r\n", p_type_2_tag->tlv_count); + + NRF_LOG_INFO("Internal data:\r\n"); + NRF_LOG_INFO(" Manufacturer ID: 0x%02x\r\n", p_type_2_tag->sn.manufacturer_id); + NRF_LOG_INFO(" Serial number part 1: 0x%04x\r\n", p_type_2_tag->sn.serial_number_part_1); + NRF_LOG_INFO(" Check byte 0: 0x%02x\r\n", p_type_2_tag->sn.check_byte_0); + NRF_LOG_INFO(" Serial number part 2: 0x%08lx\r\n", p_type_2_tag->sn.serial_number_part_2); + NRF_LOG_INFO(" Check byte 1: 0x%02x\r\n", p_type_2_tag->sn.check_byte_1); + NRF_LOG_INFO(" Internal byte: 0x%02x\r\n", p_type_2_tag->sn.internal); + NRF_LOG_INFO(" Lock bytes: 0x%04x\r\n\r\n", p_type_2_tag->lock_bytes); + + NRF_LOG_INFO("Capability Container data:\r\n"); + NRF_LOG_INFO(" Major version number: %d\r\n", p_type_2_tag->cc.major_version); + NRF_LOG_INFO(" Minor version number: %d\r\n", p_type_2_tag->cc.minor_version); + NRF_LOG_INFO(" Data area size: %d\r\n", p_type_2_tag->cc.data_area_size); + NRF_LOG_INFO(" Read access: 0x%02X\r\n", p_type_2_tag->cc.read_access); + NRF_LOG_INFO(" Write access: 0x%02X\r\n\r\n", p_type_2_tag->cc.write_access); + + for (i = 0; i < p_type_2_tag->tlv_count; i++) + { + NRF_LOG_INFO("TLV block 0x%02X: \r\n", p_type_2_tag->p_tlv_block_array[i].tag); + switch (p_type_2_tag->p_tlv_block_array[i].tag) + { + case TLV_LOCK_CONTROL: + NRF_LOG_INFO("Lock Control\r\n\r\n"); + break; + case TLV_MEMORY_CONTROL: + NRF_LOG_INFO("Memory Control\r\n\r\n"); + break; + case TLV_NDEF_MESSAGE: + NRF_LOG_INFO("NDEF Message\r\n\r\n"); + break; + case TLV_PROPRIETARY: + NRF_LOG_INFO("Proprietary\r\n\r\n"); + break; + case TLV_NULL: + NRF_LOG_INFO("Null\r\n\r\n"); + break; + case TLV_TERMINATOR: + NRF_LOG_INFO("Terminator\r\n\r\n"); + break; + default: + NRF_LOG_INFO("Unknown\r\n\r\n"); + break; + } + + NRF_LOG_INFO(" Length: %d\r\n", p_type_2_tag->p_tlv_block_array[i].length); + + if (p_type_2_tag->p_tlv_block_array[i].length > 0) + { + NRF_LOG_INFO(" Data:\r\n"); + NRF_LOG_HEXDUMP_INFO(p_type_2_tag->p_tlv_block_array[i].p_value, + p_type_2_tag->p_tlv_block_array[i].length); + } + NRF_LOG_INFO("\r\n\r\n"); + } +} + +#endif // NRF_MODULE_ENABLED(NFC_T2T_PARSER) diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_parser/nfc_t2t_parser.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_parser/nfc_t2t_parser.h new file mode 100644 index 0000000000000000000000000000000000000000..5502aeb8a8f6699f6b5414977be9b3ae09bb788d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_parser/nfc_t2t_parser.h @@ -0,0 +1,195 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_TYPE_2_TAG_PARSER_H__ +#define NFC_TYPE_2_TAG_PARSER_H__ + +#include +#include "nfc_tlv_block.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nfc_type_2_tag Type 2 Tag + * @{ + * @ingroup nfc_type_2_tag_parser + * + * @brief Descriptor for a Type 2 Tag. + * + */ + +/** + * @brief Descriptor for the internal bytes of a Type 2 Tag. + */ +typedef struct +{ + uint8_t manufacturer_id; ///< Manufacturer ID (the most significant byte of the UID/serial number). + uint16_t serial_number_part_1; ///< Bytes 5-4 of the tag UID. + uint8_t check_byte_0; ///< First block check character byte (XOR of the cascade tag byte, manufacturer ID byte, and the serial_number_part_1 bytes). + uint32_t serial_number_part_2; ///< Bytes 3-0 of the tag UID. + uint8_t check_byte_1; ///< Second block check character byte (XOR of the serial_number_part_2 bytes). + uint8_t internal; ///< Tag internal bytes. +} type_2_tag_serial_number_t; + +/** + * @brief Descriptor for the Capability Container (CC) bytes of a Type 2 Tag. + */ +typedef struct +{ + uint8_t major_version; ///< Major version of the supported Type 2 Tag specification. + uint8_t minor_version; ///< Minor version of the supported Type 2 Tag specification. + uint16_t data_area_size; ///< Size of the data area in bytes. + uint8_t read_access; ///< Read access for the data area. + uint8_t write_access; ///< Write access for the data area. +} type_2_tag_capability_container_t; + +/** + * @brief Type 2 Tag descriptor. + */ +typedef struct +{ + type_2_tag_serial_number_t sn; ///< Values within the serial number area of the tag. + uint16_t lock_bytes; ///< Value of the lock bytes. + type_2_tag_capability_container_t cc; ///< Values within the Capability Container area of the tag. + + uint16_t const max_tlv_blocks; ///< Maximum number of TLV blocks that can be stored. + tlv_block_t * p_tlv_block_array; ///< Pointer to the array for TLV blocks. + uint16_t tlv_count; ///< Number of TLV blocks stored in the Type 2 Tag. + +} type_2_tag_t; + +/** + * @brief Macro for creating and initializing a Type 2 Tag descriptor. + * + * This macro creates and initializes a static instance of a @ref type_2_tag_t structure and + * an array of @ref tlv_block_t descriptors. + * + * Use the macro @ref NFC_TYPE_2_TAG_DESC to access the Type 2 Tag descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] MAX_BLOCKS Maximum number of @ref tlv_block_t descriptors that can be stored in the array. + * + */ +#define NFC_TYPE_2_TAG_DESC_DEF(NAME, MAX_BLOCKS) \ + static tlv_block_t NAME##_tlv_block_array[MAX_BLOCKS]; \ + static type_2_tag_t NAME##_type_2_tag = \ + { \ + .max_tlv_blocks = MAX_BLOCKS, \ + .p_tlv_block_array = NAME##_tlv_block_array, \ + .tlv_count = 0 \ + } + +/** + * @brief Macro for accessing the @ref type_2_tag_t instance that was created + * with @ref NFC_TYPE_2_TAG_DESC_DEF. + */ +#define NFC_TYPE_2_TAG_DESC(NAME) (NAME##_type_2_tag) + + +#define T2T_NFC_FORUM_DEFINED_DATA 0xE1 ///< Value indicating that the Type 2 Tag contains NFC Forum defined data. +#define T2T_UID_BCC_CASCADE_BYTE 0x88 ///< Value used for calculating the first BCC byte of a Type 2 Tag serial number. + +#define T2T_SUPPORTED_MAJOR_VERSION 1 ///< Supported major version of the Type 2 Tag specification. +#define T2T_SUPPORTED_MINOR_VERSION 2 ///< Supported minor version of the Type 2 Tag specification. + +#define T2T_BLOCK_SIZE 4 ///< Type 2 Tag block size in bytes. + +#define T2T_CC_BLOCK_OFFSET 12 ///< Offset of the Capability Container area in the Type 2 Tag. +#define T2T_FIRST_DATA_BLOCK_OFFSET 16 ///< Offset of the data area in the Type 2 Tag. + +/** + * @} + */ + + +/** + * @defgroup nfc_type_2_tag_parser NFC Type 2 Tag parser + * @{ + * @ingroup nfc_t2t + * + * @brief Parser for Type 2 Tag data. + * + */ + +/** + * @brief Function for clearing the @ref type_2_tag_t structure. + * + * @param[in,out] p_type_2_tag Pointer to the structure that should be cleared. + * + */ +void type_2_tag_clear(type_2_tag_t * p_type_2_tag); + +/** + * @brief Function for parsing raw data read from a Type 2 Tag. + * + * This function parses the header and the following TLV blocks of a Type 2 Tag. The data is read + * from a buffer and stored in a @ref type_2_tag_t structure. + * + * @param[out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag (should + * point at the first byte of the first block of the tag). + * + * @retval NRF_SUCCESS If the data was parsed successfully. + * @retval NRF_ERROR_NO_MEM If there is not enough memory to store all of the TLV blocks. + * @retval Other If an error occurred during the parsing operation. + * + */ +ret_code_t type_2_tag_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data); + +/** + * @brief Function for printing parsed contents of the Type 2 Tag. + * + * @param[in] p_type_2_tag Pointer to the structure that should be printed. + * + */ +void type_2_tag_printout(type_2_tag_t * p_type_2_tag); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_TYPE_2_TAG_PARSER_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_parser/nfc_tlv_block.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_parser/nfc_tlv_block.h new file mode 100644 index 0000000000000000000000000000000000000000..308789bac2f052dcf80c15877de079e29568c8a5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t2t_parser/nfc_tlv_block.h @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_TLV_BLOCK_H__ +#define NFC_TLV_BLOCK_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@file + * + * @defgroup nfc_type_2_tag_tlv_block Type 2 Tag TLV blocks + * @{ + * @ingroup nfc_type_2_tag_parser + * + * @brief Descriptor for a Type 2 Tag TLV block. + * + */ + +/** + * @brief Tag field values. + * + * Possible values for the tag field in a TLV block. + */ +typedef enum +{ + TLV_NULL = 0x00, ///< Might be used for padding of memory areas. + TLV_LOCK_CONTROL = 0x01, ///< Defines details of the lock bits. + TLV_MEMORY_CONTROL = 0x02, ///< Identifies reserved memory areas. + TLV_NDEF_MESSAGE = 0x03, ///< Contains an NDEF message. + TLV_PROPRIETARY = 0xFD, ///< Tag proprietary information. + TLV_TERMINATOR = 0xFE ///< Last TLV block in the data area. +} tlv_block_types_t; + +/** + * @brief TLV block descriptor. + */ +typedef struct +{ + uint8_t tag; ///< Type of the TLV block. + uint16_t length; ///< Length of the value field. + uint8_t * p_value; ///< Pointer to the value field (NULL if no value field is present in the block). +} tlv_block_t; + +#define TLV_T_LENGTH 1 ///< Length of a tag field. + +#define TLV_L_SHORT_LENGTH 1 ///< Length of a short length field. +#define TLV_L_LONG_LENGTH 3 ///< Length of an extended length field. +#define TLV_L_FORMAT_FLAG 0xFF ///< Value indicating the use of an extended length field. + +#define TLV_NULL_TERMINATOR_LEN 0 ///< Predefined length of the NULL and TERMINATOR TLV blocks. +#define TLV_LOCK_MEMORY_CTRL_LEN 3 ///< Predefined length of the LOCK CONTROL and MEMORY CONTROL blocks. + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_TLV_BLOCK_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.c new file mode 100644 index 0000000000000000000000000000000000000000..59e06c195b3b964d136d59f0487207419aec08e6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.c @@ -0,0 +1,968 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" +#if NFC_HAL_ENABLED + +#include "hal_nfc_t4t.h" +#include +#include +#include "nfc_t4t_lib.h" +#include "nfc_fixes.h" +#include "nrf.h" +#include "app_util_platform.h" +#include "nordic_common.h" +#include "nrf_drv_clock.h" + +#define NRF_LOG_MODULE_NAME "HAL_NFC" +#if HAL_NFC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL HAL_NFC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR HAL_NFC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR HAL_NFC_CONFIG_DEBUG_COLOR +#else // HAL_NFC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // HAL_NFC_CONFIG_LOG_ENABLED +#include "nrf_log.h" + +#if HAL_NFC_CONFIG_DEBUG_PIN_ENABLED + #include "nrf_gpio.h" + + #define HAL_NFC_DEBUG_PIN_CONFIG(pin_num) nrf_gpio_cfg_output(pin_num) + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) nrf_gpio_pin_clear(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) nrf_gpio_pin_set(pin_num) + + #define HAL_NFC_DEBUG_PINS_INITIALIZE() \ + do{ \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_NFC_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \ + } while(0) +#else + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) + #define HAL_NFC_DEBUG_PINS_INITIALIZE() +#endif // HAL_NFC_DEBUG_PIN_ENABLE + + +/* NFC library version history: + * #define NFC_LIB_VERSION 0x00 first experimental version intended for nRF52840 IC rev. Engineering A (PCA10056, part of nRF52840 Preview Development Kit) + */ + +#define NFC_LIB_VERSION 0x00u /**< Internal: current NFC lib. version */ + +#define T2T_INTERNAL_BYTES_NR 10u /**< Number of internal bytes defined by Type 2 Tag Operation Technical Specification */ +#define T2T_INTERNAL_BYTE_SN0_SHIFT 0u /**< Internal Byte SN0, NRF_FICR->NFC.TAGHEADER0.MFGID which is Manufacturer ID */ +#define T2T_INTERNAL_BYTE_SN1_SHIFT 8u /**< Internal Byte SN1, NRF_FICR->NFC.TAGHEADER0.UID0 */ +#define T2T_INTERNAL_BYTE_SN2_SHIFT 16u /**< Internal Byte SN2, NRF_FICR->NFC.TAGHEADER0.UID1 */ +#define T2T_INTERNAL_BYTE_SN3_SHIFT 0u /**< Internal Byte SN3, NRF_FICR->NFC.TAGHEADER1.UID3 */ +#define T2T_INTERNAL_BYTE_SN4_SHIFT 8u /**< Internal Byte SN4, NRF_FICR->NFC.TAGHEADER1.UID4 */ +#define T2T_INTERNAL_BYTE_SN5_SHIFT 16u /**< Internal Byte SN5, NRF_FICR->NFC.TAGHEADER1.UID5 */ +#define T2T_INTERNAL_BYTE_SN6_SHIFT 24u /**< Internal Byte SN6, NRF_FICR->NFC.TAGHEADER1.UID6 */ +#define CASCADE_TAG_BYTE 0x88u /**< Constant defined by ISO/EIC 14443-3 */ +#define NFCID1_2ND_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_2ND_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_2ND_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ +#define NFCID1_LAST_BYTE3_SHIFT 24u /**< Shift value for NFC ID byte 3 */ +#define NFCID1_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ +#define NFC_RX_BUFFER_SIZE 256u /**< NFC Rx data buffer size */ +#define NFC_SLP_REQ_CMD 0x50u /**< NFC SLP_REQ command identifier */ +#define NFC_CRC_SIZE 2u /**< CRC size in bytes */ +#define NFC_T4T_SELRES_PROTOCOL 1u /**< Type 4A Tag PROTOCOL bit setup (b7:b6) for SEL_RES Response frame */ +#define NFC_T4T_SELRES_PROTOCOL_MSK 0x03u /**< PROTOCOL bits mask for SEL_RES Response frame */ +#define NFC_T4T_FWI_MAX 4u /**< Maximum FWI parameter value */ +#define NFC_T4T_RATS_CMD 0xE0u /**< RATS Command Byte */ +#define NFC_T4T_S_DESELECT 0xC2u /**< S(DESELECT) Block identifier */ +#define NFC_T4T_S_WTX 0xF2u /**< S(WTX)Block identifier */ +#define NFC_T4T_I_BLOCK 0x02u /**< I- Block identifier (static bits) */ +#define NFC_T4T_BLOCK_MSK 0xEEu /**< I/R- block mask (DID and NAD not supported, expect these bit equal 0) */ +#define NFC_T4T_R_BLOCK 0xA2u /**< R- Block identifier (static bits) */ +#define NFC_T4T_WTXM_MAX 0x16u /**< WTXM maximum value based on 'NFC Forum Digital Protocol Specification Version 1.1, Requirement 15.2.2.9', and FRAMEDELAYMAX maximum register setting */ +#define NFCT_INTEN_MSK 0x1C5CFFu /**< Mask for all NFCT interrupts */ + + +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#else + #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Msk | \ + NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Msk | \ + NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#endif // HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + +#define NRF_NFCT_FRAMESTATUS_RX_MSK (NFCT_FRAMESTATUS_RX_OVERRUN_Msk | \ + NFCT_FRAMESTATUS_RX_PARITYSTATUS_Msk | \ + NFCT_FRAMESTATUS_RX_CRCERROR_Msk) /**< Mask for clearing all flags in NFCT_FRAMESTATUS_RX register */ +#define NFC_FIELD_ON_MASK NFCT_FIELDPRESENT_LOCKDETECT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD ON. */ +#define NFC_FIELD_OFF_MASK NFCT_FIELDPRESENT_FIELDPRESENT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD OFF. */ + +#define NFC_T4T_FWI_TO_FWT(FWI) (256u * 16u * (1 << (FWI))) /**< Macro for calculating FWT (in number of NFC carrier periods) from FWI parameter. */ + +/* Begin: Bugfix for FTPAN-xx (AUTOCOLRESCONFIG) */ +#define NRF_NFCT_AUTOCOLRESCONFIG (*(uint32_t volatile *)(0x4000559C)) +#define NRF_NFCT_AUTOCOLRESCONFIG_Pos 0 +/* End: Bugfix for FTPAN-xx */ + +typedef enum +{ + NFC_FIELD_STATE_NONE, /**< Initial value indicating no NFCT Field events. */ + NFC_FIELD_STATE_OFF, /**< NFCT FIELDLOST Event has been set. */ + NFC_FIELD_STATE_ON, /**< NFCT FIELDDETECTED Event has been set. */ + NFC_FIELD_STATE_UNKNOWN /**< Both NFCT Field Events have been set - ambiguous state. */ +}nfct_field_sense_state_t; + +/* Static function declarations */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event); +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event); +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state); + +/* Static data */ +static hal_nfc_callback_t m_nfc_lib_callback = (hal_nfc_callback_t) NULL; /**< Callback to nfc_lib layer */ +static void * m_nfc_lib_context; /**< Callback execution context */ +static volatile uint8_t m_nfc_rx_buffer[NFC_RX_BUFFER_SIZE] = {0}; /**< Buffer for NFC Rx data */ +static volatile bool m_slp_req_received = false; /**< Flag indicating that SLP_REQ Command was received */ +static volatile bool m_field_on = false; /**< Flag indicating that NFC Tag field is present */ +static nrf_drv_clock_handler_item_t m_clock_handler_item; /**< Clock event handler item structure */ +static volatile uint8_t m_fwi; /**< FWI parameter */ +static uint8_t m_wtx_data[2]; /**< Tx buffer for an S(WTX) block */ +static volatile bool m_deselect = false; /**< Flag indicating reception of DESELECT command */ +static volatile bool m_swtx_sent = false; /**< Flag indicating that SWTX command has been sended. */ +static volatile bool m_pending_msg = false; /**< Flag signaling pending message during SWTX command execution. */ +static volatile const uint8_t * m_pending_msg_ptr = NULL; /**< Pointer to pending message buffer. */ +static volatile size_t m_pending_data_length = 0; /**< Length of pending message data. */ +static volatile bool m_t4t_tx_waiting = false; /**< Indicates if HAL is waiting for upper layer response to received command */ + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static volatile uint32_t m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; /**< Mask used for NFC Field polling in NFCT_FIELDPRESENT register */ +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +static inline void hal_nfc_re_setup(void); +static void hal_nfc_field_check(void); + +#define NRF_NFCT_POWER (*(uint32_t volatile *)(0x40005FFC)) + +#define NFC_HAL_FIELDPRESENT_MASK (NFCT_FIELDPRESENT_LOCKDETECT_Msk | \ + NFCT_FIELDPRESENT_FIELDPRESENT_Msk) + +#define NFC_HAL_FIELDPRESENT_IS_LOST ((NFCT_FIELDPRESENT_FIELDPRESENT_NoField << \ + NFCT_FIELDPRESENT_FIELDPRESENT_Pos) | \ + (NFCT_FIELDPRESENT_LOCKDETECT_NotLocked << \ + NFCT_FIELDPRESENT_LOCKDETECT_Pos)) + +static void field_timer_with_callback_config() +{ + NRF_TIMER4->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos; + NRF_TIMER4->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos; + NRF_TIMER4->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos; + NRF_TIMER4->CC[0] = HAL_NFC_FIELD_TIMER_PERIOD << TIMER_CC_CC_Pos; + NRF_TIMER4->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; + NRF_TIMER4->INTENSET = TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos; + + NVIC_ClearPendingIRQ(TIMER4_IRQn); + NVIC_SetPriority(TIMER4_IRQn, NFCT_CONFIG_IRQ_PRIORITY); + NVIC_EnableIRQ(TIMER4_IRQn); +} + + +void TIMER4_IRQHandler(void) +{ + HAL_NFC_DEBUG_PIN_SET(TIMER4_EVENT_PIN); + hal_nfc_field_check(); + NRF_TIMER4->EVENTS_COMPARE[0] = 0; + HAL_NFC_DEBUG_PIN_CLEAR(TIMER4_EVENT_PIN); +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +/** + * @brief Common part of setup used for NFCT initialization and reinitialization. + */ +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static void hal_nfc_common_hw_setup(uint8_t * const nfc_internal) +#else +static inline void hal_nfc_common_hw_setup(uint8_t * const nfc_internal) +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +{ + uint32_t nfc_tag_header0 = NRF_FICR->NFC.TAGHEADER0; + uint32_t nfc_tag_header1 = NRF_FICR->NFC.TAGHEADER1; + +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND +/* Begin: Bugfix for FTPAN-98 */ + *(volatile uint32_t *) 0x4000568C = 0x00038148; +/* End: Bugfix for FTPAN-98 */ +/* Begin: Bugfix for FTPAN-144 */ + *(volatile uint32_t *) 0x4000561c = 0x01; + *(volatile uint32_t *) 0x4000562c = 0x3F; + *(volatile uint32_t *) 0x4000563c = 0x0; +/* End: Bugfix for FTPAN-144 */ +#endif // HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + +/* Begin: Bugfix for FTPAN-17 */ +/* fixed by avoiding usage of FIELDLOST event */ +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos); +#else + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos) | + (NFCT_INTENSET_FIELDLOST_Enabled << NFCT_INTENSET_FIELDLOST_Pos); +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +/* End: Bugfix for FTPAN-17 */ + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMESTART_Enabled << NFCT_INTENSET_TXFRAMESTART_Pos); + + NRF_NFCT->INTENSET = (NFCT_INTENSET_ERROR_Enabled << NFCT_INTENSET_ERROR_Pos) | + (NFCT_INTENSET_SELECTED_Enabled << NFCT_INTENSET_SELECTED_Pos); + + /* According to ISO/IEC 14443-3 */ + nfc_internal[0] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN0_SHIFT)); // SN0 + nfc_internal[1] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN1_SHIFT)); // SN1 + nfc_internal[2] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN2_SHIFT)); // SN2 + nfc_internal[3] = (uint8_t) ((CASCADE_TAG_BYTE) ^ nfc_internal[0] ^ + nfc_internal[1] ^ nfc_internal[2]); // BCC0 = CASCADE_TAG_BYTE ^ SN0 ^ SN1 ^ SN2 + nfc_internal[4] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN3_SHIFT)); // SN3 + nfc_internal[5] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN4_SHIFT)); // SN4 + nfc_internal[6] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN5_SHIFT)); // SN5 + nfc_internal[7] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN6_SHIFT)); // SN6 + nfc_internal[8] = (uint8_t) (nfc_internal[4] ^ nfc_internal[5] ^ + nfc_internal[6] ^ nfc_internal[7]); // BCC1 = SN3 ^ SN4 ^ SN5 ^ SN6 + nfc_internal[9] = (uint8_t) (NFC_LIB_VERSION); // For internal use + + /* MSB of NFCID1_2ND_LAST register is not used - always 0 */ + NRF_NFCT->NFCID1_2ND_LAST = ((uint32_t) nfc_internal[0] << NFCID1_2ND_LAST_BYTE2_SHIFT) | + ((uint32_t) nfc_internal[1] << NFCID1_2ND_LAST_BYTE1_SHIFT) | + ((uint32_t) nfc_internal[2] << NFCID1_2ND_LAST_BYTE0_SHIFT); + + NRF_NFCT->NFCID1_LAST = ((uint32_t) nfc_internal[4] << NFCID1_LAST_BYTE3_SHIFT) | + ((uint32_t) nfc_internal[5] << NFCID1_LAST_BYTE2_SHIFT) | + ((uint32_t) nfc_internal[6] << NFCID1_LAST_BYTE1_SHIFT) | + ((uint32_t) nfc_internal[7] << NFCID1_LAST_BYTE0_SHIFT); + + /* Set FRAMEDELAYMAX to maximum available setting, corresponding to FWI = 4 */ + NRF_NFCT->FRAMEDELAYMAX = NFCT_FRAMEDELAYMAX_FRAMEDELAYMAX_Msk; + m_fwi = 4; + + /* Set PROTOCOL bits for Type 4A Tag */ + NRF_NFCT->SELRES = + (NFC_T4T_SELRES_PROTOCOL << NFCT_SELRES_PROTOCOL_Pos) & NFCT_SELRES_PROTOCOL_Msk; + + /* Begin: Bugfix for FTPAN-25 (IC-9929) */ + /* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used + because it's required to operate with Windows Phone */ + NRF_NFCT->SENSRES = + (NFCT_SENSRES_NFCIDSIZE_NFCID1Double << NFCT_SENSRES_NFCIDSIZE_Pos) | + (NFCT_SENSRES_BITFRAMESDD_SDD00100 << NFCT_SENSRES_BITFRAMESDD_Pos); + /* End: Bugfix for FTPAN-25 (IC-9929)*/ + + m_swtx_sent = false; + m_pending_msg = false; + m_pending_msg_ptr = NULL; + m_pending_data_length = 0; +} + + +ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context) +{ + uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR]; + + m_nfc_lib_callback = callback; + m_nfc_lib_context = p_context; + + hal_nfc_common_hw_setup(nfc_internal); + + /* Initialize SDK Clock module for handling high precission clock requests */ + m_clock_handler_item.event_handler = nrf_nfct_clock_event_handler; + m_clock_handler_item.p_next = NULL; + + ret_code_t err_code = nrf_drv_clock_init(); + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + field_timer_with_callback_config(); +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + NRF_LOG_INFO("Init\r\n"); + HAL_NFC_DEBUG_PINS_INITIALIZE(); + + if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_MODULE_ALREADY_INITIALIZED)) + { + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INTERNAL; + } +} + + +/**@brief Function for clearing an event flag in NRF_NFCT registers. + * + * @param[in] p_event Pointer to event register. + * + */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event) +{ + *p_event = 0; + + /* Perform read to ensure clearing is effective */ + volatile uint32_t dummy = *p_event; + (void)dummy; +} + + +/**@brief Function for handling events from Clock Module. + * + * @param[in] event Clock event. + * + */ +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event) +{ + switch (event) + { + case NRF_DRV_CLOCK_EVT_HFCLK_STARTED: + /* Activate NFCT only when HFXO is running */ + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + NRF_NFCT->TASKS_ACTIVATE = 1; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} + + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static inline void nrf_nfct_field_lost_hfclk_handle(void) +{ + /* Begin: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + // reset the NFC for release HFCLK + __DMB(); + NRF_NFCT_POWER = 0; + __DMB(); + NRF_NFCT_POWER = 1; + /* END: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +/**@brief Function for evaluating and handling NFC field events. + * + * @param[in] field_state Current field state. + * + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ + if (field_state == NFC_FIELD_STATE_UNKNOWN) + { + /* Probe NFC field */ + uint32_t field_present = NRF_NFCT->FIELDPRESENT; + + if (field_present & m_nfc_fieldpresent_mask) + { + field_state = NFC_FIELD_STATE_ON; + } + else + { + field_state = NFC_FIELD_STATE_OFF; + } + } + + /* Field event service */ + switch (field_state) + { + case NFC_FIELD_STATE_ON: + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + } + m_field_on = true; + break; + + case NFC_FIELD_STATE_OFF: + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG! + +/* Begin: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + *(volatile uint32_t *)0x40005010 = 1; +#endif // HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND +/* END: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + + NRF_NFCT->TASKS_SENSE = 1; + nrf_drv_clock_hfclk_release(); + m_field_on = false; + + NRF_NFCT->INTENCLR = + (NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos) | + (NFCT_INTENCLR_RXERROR_Clear << NFCT_INTENCLR_RXERROR_Pos); + + /* Change mask to FIELD_OFF state - trigger FIELD_ON even if HW has not locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; + + if ((m_nfc_lib_callback != NULL) ) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + + /* Re-enable Auto Collision Resolution */ + NRF_NFCT_AUTOCOLRESCONFIG = NRF_NFCT_AUTOCOLRESCONFIG & + ~(1u << NRF_NFCT_AUTOCOLRESCONFIG_Pos); + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length) +{ + /* Parameter validation is done in upper-layer */ + + if (id == HAL_NFC_PARAM_FWI) + { + /* Update Frame Wait Time setting; possible settings are limited by NFCT hardware */ + m_fwi = *((uint8_t *)p_data); + + if (data_length != sizeof(uint8_t)) + { + return NRF_ERROR_DATA_SIZE; + } + if (m_fwi > NFC_T4T_FWI_MAX) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* Set FRAMEDELAYTIME */ + if (m_fwi == NFC_T4T_FWI_MAX) + { + NRF_NFCT->FRAMEDELAYMAX = NFCT_FRAMEDELAYMAX_FRAMEDELAYMAX_Msk; + } + else + { + NRF_NFCT->FRAMEDELAYMAX = NFC_T4T_FWI_TO_FWT(m_fwi); + } + } + else if (id == HAL_NFC_PARAM_SELRES) + { + /* Update SEL_RES 'Protocol' bits setting */ + uint8_t sel_res = *((uint8_t *)p_data); + + if (data_length != sizeof(uint8_t)) + { + return NRF_ERROR_DATA_SIZE; + } + if (sel_res > NFC_T4T_SELRES_PROTOCOL_MSK) + { + return NRF_ERROR_INVALID_PARAM; + } + + NRF_NFCT->SELRES = + (sel_res << NFCT_SELRES_PROTOCOL_Pos) & NFCT_SELRES_PROTOCOL_Msk; + } + else + { + /* No implementation needed */ + } + + return NRF_SUCCESS; +} + + +/* This function is used by nfc_lib for unit testing only */ +ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length) +{ + if (*p_max_data_length < 1) + { + *p_max_data_length = 1; + return NRF_ERROR_DATA_SIZE; + } + + if (id == HAL_NFC_PARAM_FWI) + { + *((uint8_t *) p_data) = m_fwi; + *p_max_data_length = sizeof(m_fwi); + } + else if (id == HAL_NFC_PARAM_SELRES) + { + /* Update SEL_RES 'Protocol' bits setting */ + uint8_t sel_res = (NRF_NFCT->SELRES & NFCT_SELRES_PROTOCOL_Msk) >> + NFCT_SELRES_PROTOCOL_Pos; + *((uint8_t *) p_data) = sel_res; + *p_max_data_length = sizeof(sel_res); + } + else + { + /* No implementation needed */ + } + + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_start(void) +{ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + NRF_NFCT->TASKS_SENSE = 1; + + NVIC_ClearPendingIRQ(NFCT_IRQn); + NVIC_SetPriority(NFCT_IRQn, NFCT_CONFIG_IRQ_PRIORITY); + NVIC_EnableIRQ(NFCT_IRQn); + + NRF_LOG_INFO("Start\r\n"); + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length) +{ + if (data_length == 0) + { + return NRF_ERROR_DATA_SIZE; + } + + if(m_swtx_sent) + { + m_pending_msg_ptr = p_data; + m_pending_data_length = data_length; + m_pending_msg = true; + + NRF_LOG_DEBUG("Pending message.\r\n"); + return NRF_SUCCESS; + } + + m_t4t_tx_waiting = false; + + /* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); //Moved to the end in T4T to avoid delaying TASKS_STARTX + NRF_NFCT->PACKETPTR = (uint32_t) p_data; + NRF_NFCT->TXD.AMOUNT = (data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos; + NRF_NFCT->TASKS_STARTTX = 1; + + NRF_LOG_INFO("Send\r\n"); + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_stop(void) +{ + NRF_NFCT->TASKS_DISABLE = 1; + + NRF_LOG_INFO("Stop\r\n"); + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_done(void) +{ + m_nfc_lib_callback = (hal_nfc_callback_t) NULL; + + return NRF_SUCCESS; +} + + +void NFCT_IRQHandler(void) +{ + nfct_field_sense_state_t current_field = NFC_FIELD_STATE_NONE; + + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_NFC_EVENT_DEBUG_PIN); // DEBUG! + + if (NRF_NFCT->EVENTS_FIELDDETECTED && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDDETECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDDETECTED); + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_DETECT_EVENT_DEBUG_PIN); // DEBUG! + current_field = NFC_FIELD_STATE_ON; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); // DEBUG! + + NRF_LOG_DEBUG("Field detected\r\n"); + } + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + if (NRF_NFCT->EVENTS_FIELDLOST && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDLOST_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDLOST); + current_field = + (current_field == NFC_FIELD_STATE_NONE) ? NFC_FIELD_STATE_OFF : NFC_FIELD_STATE_UNKNOWN; + + NRF_LOG_DEBUG("Field lost\r\n"); + } +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + /* Perform actions if any FIELD event is active */ + if (current_field != NFC_FIELD_STATE_NONE) + { + nrf_nfct_field_event_handler(current_field); + } + + if (NRF_NFCT->EVENTS_RXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_RXFRAMEEND_Msk)) + { + /* Take into account only number of whole bytes */ + uint32_t rx_data_size = ((NRF_NFCT->RXD.AMOUNT & NFCT_RXD_AMOUNT_RXDATABYTES_Msk) >> + NFCT_RXD_AMOUNT_RXDATABYTES_Pos) - NFC_CRC_SIZE; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + + /* Look for Tag 4 Type Commands */ + if (m_nfc_rx_buffer[0] == NFC_T4T_RATS_CMD) + { + /* Disable Auto Collision Resolution */ + NRF_NFCT_AUTOCOLRESCONFIG = NRF_NFCT_AUTOCOLRESCONFIG | + (1u << NRF_NFCT_AUTOCOLRESCONFIG_Pos); + NRF_LOG_DEBUG("RX: T4T Activate\r\n"); + } + else if (m_nfc_rx_buffer[0] == NFC_T4T_S_DESELECT) + { + m_deselect = true; + NRF_LOG_DEBUG("RX: T4T Go to sleep\r\n"); + } + else if (m_swtx_sent && m_nfc_rx_buffer[0] == NFC_T4T_S_WTX) + { + m_swtx_sent = false; + + NRF_LOG_DEBUG("RX: S(WTX) reponse\r\n"); + + if(m_pending_msg) + { + m_pending_msg = false; + + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); + NRF_NFCT->PACKETPTR = (uint32_t) m_pending_msg_ptr; + NRF_NFCT->TXD.AMOUNT = (m_pending_data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos; + NRF_NFCT->TASKS_STARTTX = 1; + + m_t4t_tx_waiting = false; + NRF_LOG_DEBUG("Sending pending message!\r\n"); + } + } + else if ((m_nfc_rx_buffer[0] & NFC_T4T_BLOCK_MSK) == NFC_T4T_I_BLOCK) + { + /* Set up default transmission of S(WTX) block. Tx will be executed only if FDT timer expires (FrameDelayMode-ExactVal) before + * hal_nfc_send is called */ + m_wtx_data[0] = NFC_T4T_S_WTX; + m_wtx_data[1] = NFC_T4T_WTXM_MAX; + NRF_NFCT->PACKETPTR = (uint32_t) m_wtx_data; + NRF_NFCT->TXD.AMOUNT = (sizeof(m_wtx_data) << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_ExactVal << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos; + NRF_NFCT->TASKS_STARTTX = 1; + m_t4t_tx_waiting = true; + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); + } + else + { + /* Indicate that SLP_REQ was received - this will cause FRAMEDELAYTIMEOUT error */ + if (m_nfc_rx_buffer[0] == NFC_SLP_REQ_CMD) + { + m_slp_req_received = true; + NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos; // disable RX here (will enable at SELECTED) + } + /* Not a READ Command, so wait for next frame reception */ + NRF_NFCT->TASKS_ENABLERXDATA = 1; + } + + if (m_nfc_lib_callback != NULL) + { + /* This callback should trigger transmission of READ Response */ + m_nfc_lib_callback(m_nfc_lib_context, + HAL_NFC_EVENT_DATA_RECEIVED, + (void *)m_nfc_rx_buffer, + rx_data_size); + } + /* Clear TXFRAMESTART EVENT so it can be checked in hal_nfc_send */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMESTART); + NRF_LOG_DEBUG("Rx fend\r\n"); + } + + if (NRF_NFCT->EVENTS_TXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMEEND_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + /* Disable TX END event to ignore frame transmission other than READ response */ + NRF_NFCT->INTENCLR = (NFCT_INTENCLR_TXFRAMEEND_Clear << NFCT_INTENCLR_TXFRAMEEND_Pos); + + if (m_deselect) + { + /* Re-enable Auto Collision Resolution */ + NRF_NFCT_AUTOCOLRESCONFIG = NRF_NFCT_AUTOCOLRESCONFIG & + ~(1u << NRF_NFCT_AUTOCOLRESCONFIG_Pos); + NRF_NFCT->TASKS_GOSLEEP = 1; + /* Disable RX here (will be enabled at SELECTED) */ + NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear << + NFCT_INTENCLR_RXFRAMEEND_Pos; + m_deselect = false; + } + else + { + /* Set up for reception */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + NRF_NFCT->INTENSET = + (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) | + (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos); + } + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_DATA_TRANSMITTED, 0, 0); + } + + NRF_LOG_DEBUG("Tx fend\r\n"); + } + + if (NRF_NFCT->EVENTS_SELECTED && (NRF_NFCT->INTEN & NFCT_INTEN_SELECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_SELECTED); + + /* Clear also RX END and RXERROR events because SW does not take care of commands which were received before selecting the tag */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + /* Set up registers for EasyDMA and start receiving packets */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + + NRF_NFCT->INTENSET = (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) | + (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos); + + /* At this point any previous error status can be ignored */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + /* Change mask to FIELD_ON state - trigger FIELD_ON only if HW has locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_ON_MASK; +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_ON, 0, 0); + } + + m_swtx_sent = false; + m_pending_msg = false; + m_pending_msg_ptr = NULL; + m_pending_data_length = 0; + + NRF_LOG_DEBUG("Selected\r\n"); + } + + if (NRF_NFCT->EVENTS_RXERROR && (NRF_NFCT->INTEN & NFCT_INTEN_RXERROR_Msk)) + { + uint32_t rx_status = NRF_NFCT->FRAMESTATUS.RX; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + NRF_LOG_DEBUG("Rx error (0x%x)\r\n", (unsigned int) rx_status); + (void) rx_status; + + m_swtx_sent = false; + + if(m_pending_msg) + { + m_pending_msg = false; + m_t4t_tx_waiting = false; + + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); + NRF_NFCT->PACKETPTR = (uint32_t) m_pending_msg_ptr; + NRF_NFCT->TXD.AMOUNT = (m_pending_data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos; + NRF_NFCT->TASKS_STARTTX = 1; + + NRF_LOG_DEBUG("Sending pending message!\r\n"); + } + + /* Clear rx frame status */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + } + + if (NRF_NFCT->EVENTS_ERROR && (NRF_NFCT->INTEN & NFCT_INTEN_ERROR_Msk)) + { + uint32_t err_status = NRF_NFCT->ERRORSTATUS; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_ERROR); + + /* Clear FRAMEDELAYTIMEOUT error (expected HW behaviour) when SLP_REQ command was received */ + if ((err_status & NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) && m_slp_req_received) + { + NRF_NFCT->ERRORSTATUS = NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + m_slp_req_received = false; + + NRF_LOG_DEBUG("RX: SLP_REQ\r\n"); + } + /* Report any other error */ + err_status &= ~NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + + if (err_status) + { + NRF_LOG_DEBUG("Error (0x%x)\r\n", (unsigned int) err_status); + } + + /* Clear error status */ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + } + + if (NRF_NFCT->EVENTS_TXFRAMESTART && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMESTART_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMESTART); + + if (m_t4t_tx_waiting) + { + m_t4t_tx_waiting = false; + m_swtx_sent = true; + + NRF_LOG_DEBUG("Response timeout, sending WTX!\r\n"); + } + } + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); // DEBUG! +} + + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + #error Wrong workaround combination +#endif + +static uint32_t field_state_cnt = 0; +/** + * @brief Function for evaluating and handling NFC fieldlost event. + */ +static void hal_nfc_field_check(void) +{ + uint32_t nfc_fieldpresen_masked; + + nfc_fieldpresen_masked = NRF_NFCT->FIELDPRESENT & NFC_HAL_FIELDPRESENT_MASK; + + if (nfc_fieldpresen_masked == NFC_HAL_FIELDPRESENT_IS_LOST) + { + ++field_state_cnt; + if (field_state_cnt > 7) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG! + + NRF_TIMER4->TASKS_SHUTDOWN = 1; + + nrf_drv_clock_hfclk_release(); + + nrf_nfct_field_lost_hfclk_handle(); + + if ((m_nfc_lib_callback != NULL) ) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + m_field_on = false; + + /* Begin: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + // resume the NFCT to initialized state + hal_nfc_re_setup(); + /* End: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG! + } + + return; + } + + field_state_cnt = 0; +} + + +/** + * @brief Function for enablinge hight precision clock and start eveluating fieldlost event. + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + + NRF_TIMER4->TASKS_CLEAR = 1; + NRF_TIMER4->TASKS_START = 1; + field_state_cnt = 0; + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + } + m_field_on = true; +} + + +/** + * @brief Function for resume the NFCT to initialized state after software's reset. + */ +static inline void hal_nfc_re_setup(void) +{ + uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR]; + + hal_nfc_common_hw_setup(nfc_internal); + + NRF_LOG_INFO("Reinitialize\r\n"); +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#endif // NFC_HAL_ENABLED diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.h new file mode 100644 index 0000000000000000000000000000000000000000..b044acc0b927369b646b809b6995ed6ef8cb9d7b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.h @@ -0,0 +1,199 @@ +/** + * Copyright (c) 2016 - 2017, Telit Communications Cyprus Ltd + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef HAL_NFC_H__ +#define HAL_NFC_H__ + +/** @file + * @defgroup nfc_t4t_hal NFC Type 4 Tag HAL + * @{ + * @ingroup nfc_t4t + * @brief @tagAPI52 Hardware abstraction layer for the NFC Type 4 Tag library. + * + * @note Before the NFCT peripheral enters ACTIVATED state, the HFXO must be running. + * To fulfill this requirement and allow other software modules to also request the HFXO, the NFC Type 4 Tag HAL uses @ref nrf_drv_clock module. + * + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Events passed to the upper-layer callback function. */ +typedef enum { + HAL_NFC_EVENT_FIELD_ON, ///< Field is detected. + HAL_NFC_EVENT_FIELD_OFF, ///< Field is lost. + HAL_NFC_EVENT_DATA_RECEIVED, ///< Data is received. + HAL_NFC_EVENT_DATA_TRANSMITTED ///< Data is transmitted. +} hal_nfc_event_t; + + +/** @brief Parameter IDs for the set/get function. */ +typedef enum { + HAL_NFC_PARAM_ID_TESTING, ///< Used for unit tests. + HAL_NFC_PARAM_FWI, ///< Frame Wait Time parameter. + HAL_NFC_PARAM_SELRES, ///< Parameter for setting the 'Protocol' bits for SEL_RES packet. + HAL_NFC_PARAM_ID_UNKNOWN +} hal_nfc_param_id_t; + + +/** @brief Callback from HAL_NFC layer into the upper layer. + * + * If event == HAL_NFC_EVENT_DATA_RECEIVED: + * p_data points to the received packet. The memory belongs to the HAL_NFC layer and + * is guaranteed to be valid only until the callback returns. + * + * If event == HAL_NFC_EVENT_DATA_TRANSMITTED: + * p_data points to the transmitted packet. The memory belongs to the application. + * + * If event == \: + * p_data definition is event-specific (to be defined). + * + * @param[in] p_context Context for callback execution. + * @param[in] event The event that occurred. + * @param[in] p_data Received/transmitted data or NULL. + * @param[in] data_length Size of the received/transmitted packet. + */ +typedef void (* hal_nfc_callback_t)(void * p_context, + hal_nfc_event_t event, + const uint8_t * p_data, + size_t data_length); + + +/** @brief Function for initializing the NFC layer. + * + * This function provides a pointer to a callback function and the callback context + * to the NFC layer. + * + * @param[in] callback Pointer to the callback function. + * @param[in] p_context Context of callback. + * + * @retval NRF_SUCCESS If the NFC layer was initialized successfully. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context); + + +/** @brief Function for setting a HAL_NFC parameter. + * + * This function allows to set any parameter defined as available by HAL_NFC. + * + * @param[in] id ID of the parameter to set. + * @param[in] p_data Pointer to the buffer containing the data to set. + * @param[in] data_length Size of the buffer containing the data to set. + * + * @retval NRF_SUCCESS If the parameter was set successfully. If one of the arguments + * was invalid (for example, wrong data length), an error code + * is returned. + */ +ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length); + + +/** @brief Function for querying a HAL_NFC parameter value. + * + * The queried value will be placed into the passed data buffer. If the buffer + * is too small, p_max_data_length will contain the required buffer size. + * + * @param[in] id ID of the parameter to query. + * @param[in, out] p_data Pointer to a buffer receiving the queried data. + * @param[in, out] p_max_data_length Size of the buffer. It receives the required size if buffer is too small. + * + * @retval NRF_SUCCESS If the parameter was received successfully. If one of the arguments + * was invalid (for example, the buffer was too small), an error code + * is returned. + */ +ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length); + + +/** @brief Function for starting the NFC subsystem. + * + * After this function completes, NFC readers will be able to detect the chip. + * + * @retval NRF_SUCCESS If the NFC subsystem was started successfully. If the NFC + * subsystem could not be started, an error code is returned. + */ +ret_code_t hal_nfc_start(void); + + +/** @brief Function for sending a packet to the connected NFC reader. + * + * The provided data buffer belongs to the caller and is guaranteed to be + * valid until the HAL_NFC_EVENT_DATA_TRANSMITTED event is received by the + * callback. + * + * @param[in] p_data The data packet to send. + * @param[in] data_length Size of the packet in bytes. + * + * @retval NRF_SUCCESS If the packet was sent. Otherwise, an error code is returned. + */ +ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length); + + +/** @brief Function for stopping the NFC subsystem. + * + * After this function returns, NFC readers will no longer be able to connect + * to the chip. + * + * @retval NRF_SUCCESS If the NFC subsystem was stopped. Otherwise, an error code + * is returned. + */ +ret_code_t hal_nfc_stop(void); + + +/** @brief Function for releasing resources. + * + * After this call returns, the callback is considered invalid and no more + * events will be posted to it. + * + * @retval NRF_SUCCESS This function always succeeds. + */ +ret_code_t hal_nfc_done(void); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* HAL_NFC_H__ */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/license.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/license.txt new file mode 100644 index 0000000000000000000000000000000000000000..d629f64dd84e7109c2caaed65aa969ba616c0c07 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/license.txt @@ -0,0 +1,36 @@ +Copyright (c) 2016 - 2017, Telit Communications Cyprus Ltd + +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, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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 Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/nfc_fixes.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/nfc_fixes.h new file mode 100644 index 0000000000000000000000000000000000000000..3093f842503105c4b447e228ffd092f5773d25fd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/nfc_fixes.h @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef NFC_FIXES_H__ +#define NFC_FIXES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + * @defgroup nfc_fixes NFC fixes and workarounds + * @{ + * @ingroup nfc_t4t + * @brief @tagAPI52 Fixes for hardware-related anomalies. + * + * If you are using PCA10040 (part of nRF52 Development Kit), + * you must define the macro HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 79. NFCT: A false EVENTS_FIELDDETECTED event occurs after the field is lost. + * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode. + * + * If you are using PCA10056 (part of nRF52840 Development Kit), + * you must define the macro HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 98. NFCT: The NFCT is not able to communicate with the peer. + * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode. + * + * The current code contains a patch for anomaly 25 (NFCT: Reset value of + * SENSRES register is incorrect), so that it now works on Windows Phone. + */ + +#ifdef BOARD_PCA10040 // assume nRF52832 chip in IC rev. Engineering B or Engineering C + #define HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +#elif defined(BOARD_PCA10056) // assume nRF52840 chip in IC rev. Engineering A + #define HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_FIXES_H__ */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/nfc_t4t_lib.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/nfc_t4t_lib.h new file mode 100644 index 0000000000000000000000000000000000000000..beba06e37344b0db1f97125916d98600fd230e8c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_lib/nfc_t4t_lib.h @@ -0,0 +1,319 @@ +/** + * Copyright (c) 2016 - 2017, Telit Communications Cyprus Ltd + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef NFC_T4T_LIB_H__ +#define NFC_T4T_LIB_H__ + +/** @file + * + * @addtogroup nfc_api + * + * @defgroup nfc_t4t NFC Type 4 Tag + * @ingroup nfc_api + * @brief Implementation of NFC Type 4 Tag. + * + * @defgroup nfc_t4t_lib NFC tag 4 type emulation library + * @{ + * @ingroup nfc_t4t + * @brief The T4T emulation library interface + * + * This is the NFC Forum NDEF tag 4 type emulation library. It implements the ISO14443-4A protocol + * (ISO-DEP) and additionally can emulate a read-writable NDEF content. If the emulation of the NDEF + * content is not needed, the library works in a raw mode where all APDUs are delivered to the user, + * who is then responsible to generate a timely RPDU as a response. + * + * The sequence of initializing functions determines whether the NDEF emulation will run or whether + * the raw mode is used. + * + * - E.g. NDEF emulation + * * @ref nfc_t4t_setup + * * @ref nfc_t4t_ndef_rwpayload_set or @ref nfc_t4t_ndef_staticpayload_set + * * @ref nfc_t4t_emulation_start + * * ... running in NDEF emulation mode ... + * - E.g. RAW mode + * * @ref nfc_t4t_setup + * * @ref nfc_t4t_emulation_start + * * ... running in RAW emulation mode ... + */ + +#include +#include +#include +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NFC_T4T_MAX_PAYLOAD_SIZE 0xFFF0U + +/**< @brief Emulation mode. */ +typedef enum +{ + NFC_T4T_EMUMODE_NDEF, ///< Emulated NDEF AID and EF-Files. + NFC_T4T_EMUMODE_PICC ///< Run just ISO-DEP, deliver I-Frames up. +} nfc_t4t_emu_mode_t; + + +/**< @brief Event identifiers used by the @ref nfc_t4t_callback_t */ +typedef enum +{ + NFC_T4T_EVENT_NONE, + ///< This ID is never used. Dummy value for completeness. + + NFC_T4T_EVENT_FIELD_ON, + ///< External Reader polling detected. + + NFC_T4T_EVENT_FIELD_OFF, + ///< External Reader polling ended. + + NFC_T4T_EVENT_NDEF_READ, + ///< External Reader has read static NDEF-Data from Emulation. + /**< + * A Read operation happened on last byte of NDEF-Data. + */ + + NFC_T4T_EVENT_NDEF_UPDATED, + ///< External Reader has written to length information of NDEF-Data from Emulation. + /**< + * The usual behavior of a Reader-Writer that accesses NDEF information for update is to set + * the length to zero at the beginning of the update process. It then writes the content + * of NDEF-Data. When all content is written it will update the length information inside + * the NDEF file. This event will be generated every time an update to the length is happening. + * This length information is residing in the first 2 bytes of the NDEF-Content container and is called 'NLEN'. + * Since this callback is triggered on any access to these bytes the returned data_length + * information might not be consistent (e.g. in case of only a single byte write to the length). + * + * @param[out] data_length Current value of NDEF content length + * information i.e. 'NLEN' field. + */ + + NFC_T4T_EVENT_DATA_TRANSMITTED, + ///< In Raw mode it signals that the data from @ref nfc_t4t_response_pdu_send have been sent out. + + NFC_T4T_EVENT_DATA_IND, + ///< In Raw mode delivers the APDU fragments + /**< + * All @ref NFC_T4T_EVENT_DATA_IND events that have the @ref NFC_T4T_DI_FLAG_MORE flag set + * belong to the same APDU. The first @ref NFC_T4T_EVENT_DATA_IND without @ref NFC_T4T_DI_FLAG_MORE + * flag signals the completeness of the APDU. The Application then has to reply with a call + * to @ref nfc_t4t_response_pdu_send. The library will handle internally the fragmentation of + * the response towards the Reader-Writer. The data of the response PDU must be kept + * valid until the next callback from the library happens (e.g. next @ref NFC_T4T_EVENT_DATA_IND + * or @ref NFC_T4T_EVENT_FIELD_OFF). + * + * @param[out] p_data Pointer to the fragment of APDU. + * @param[out] data_length Length of data. + * @param[out] flags @ref nfc_t4t_data_ind_flags_t. + */ +} nfc_t4t_event_t; + +/**< @brief Flags coming with nfc_t4t_callback_t at @ref NFC_T4T_EVENT_DATA_IND event.*/ +typedef enum +{ + NFC_T4T_DI_FLAG_NONE = 0x00, ///< Dummy value. + NFC_T4T_DI_FLAG_MORE = 0x01 ///< This signals that more data is expected to be received. +} nfc_t4t_data_ind_flags_t; + +/**< @brief Parameter IDs that can be set/get with @ref nfc_t4t_parameter_set or + * @ref nfc_t4t_parameter_get. + */ +typedef enum +{ + NFC_T4T_PARAM_TESTING, ///< Internal usage only for Unit-Testing. + NFC_T4T_PARAM_FWI, ///< Frame Wait Time parameter + NFC_T4T_PARAM_SELRES ///< Parameter for setting 'Protocol' bits for SEL_RES packet +} nfc_t4t_param_id_t; + +/** @brief Callback to pass events from NFCLib to application. + * + * @param[out] p_context Application context for callback execution. + * @param[out] event The event that occurred. see @ref nfc_t4t_event_t. + * @param[out] p_data Data to send to the application (event specific). + * @param[out] data_length Length of the data. In case of @ref NFC_T4T_EVENT_NDEF_UPDATED, this parameter + * contains the value of the 'NLEN' field of the NDEF File; + * if the value is non-zero, it corresponds to the new size of the NDEF Message in the updated NDEF File. + * @param[out] flags Some events deliver flags. see @ref nfc_t4t_event_t for details. + */ +typedef void (*nfc_t4t_callback_t)(void * p_context, + nfc_t4t_event_t event, + const uint8_t * p_data, + size_t data_length, + uint32_t flags); + +/** @brief Register the application callback for event signaling. + * + * The callback will be called by NFCLib to notify the application of relevant events. It will be + * called from the HAL_NFC callback context. The library support 3 different Modes of Emulation: + * - Raw ISO-Dep exchanges. All PDUs are signaled through the callback. + * - Read-Only T4T NDEF-Tag. A static buffer is served. Only Field-Status callbacks. + * - Read-Write T4T NDEF-Tag. A mutable buffer is used. Only Field-Status callbacks. + * + * The default mode is Raw ISO-Dep mode. The two other NDEF T4T modes are activated through + * the corresponding @ref nfc_t4t_ndef_rwpayload_set/ @ref nfc_t4t_ndef_staticpayload_set functions. + * The mode is locked in with a call to @ref nfc_t4t_emulation_start. + * + * @param[in] callback Function pointer to the callback. + * @param[in] p_context Pointer to a memory area used by the callback for execution (optional). + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_STATE If emulation is in running state. + */ +ret_code_t nfc_t4t_setup(nfc_t4t_callback_t callback, void * p_context); + +/** @brief Set emulation buffer and content for a NDEF Tag emulation that is Read/Writable. + * + * The buffer needs to be kept accessible for the lifetime of the emulation. + * If an external Reader-Writer changes the NDEF content it is signaled through the app-callback. + * + * @param[in] p_emulation_buffer Buffer pointer + * @param[in] buffer_length Length of buffer (maximum writable NDEF size) + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + * @retval NRF_ERROR_INVALID_STATE If emulation is in running state. + */ +ret_code_t nfc_t4t_ndef_rwpayload_set(uint8_t * p_emulation_buffer, size_t buffer_length); + +/** @brief Set emulationBuffer and Content for a NDEF Tag emulation that is Read-Only. + * + * The buffer needs to be kept accessible for the lifetime of the emulation. + * Since no write access is done to the buffer, the content could reside in flash memory. + * + * @param[in] p_emulation_buffer Const buffer pointer + * @param[in] buffer_length Length of contained NDEF payload message + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + * @retval NRF_ERROR_INVALID_STATE Emulation is in running stated. + */ +ret_code_t nfc_t4t_ndef_staticpayload_set(const uint8_t * p_emulation_buffer, size_t buffer_length); + +/** @brief Send a raw response PDU after getting a Request PDU callback. + * + * When the library works in raw ISO-DEP mode it will signal request PDUs through the callback. + * The application then has to answer with a response PDU. It will use this function to send back + * the response PDU. This function can not be used in T4T NDEF (RW / STATIC) emulation modes. + * + * The lower ISODEP layer will handle the defragmentation of a long response PDU into smaller + * pieces that the PCD can understand. + * + * @param[in] p_pdu Const PDU pointer. + * @param[in] pdu_length Length of PDU. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + * @retval NRF_ERROR_INVALID_STATE Emulation is in running state. + */ +ret_code_t nfc_t4t_response_pdu_send(const uint8_t * p_pdu, size_t pdu_length); + +/** @brief Set an NFC parameter. + * + * Allows to set any parameter defined as available by HAL_NFC. + * + * @param[in] id ID of the parameter to set. + * @param[in] p_data Pointer to a buffer containing the data to set. + * @param[in] data_length Size of the buffer containing the data to set. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + */ +ret_code_t nfc_t4t_parameter_set(nfc_t4t_param_id_t id, void * p_data, size_t data_length); + +/** @brief Query an NFC parameter value. + * + * The queried value will be placed into the passed data buffer. + * If the buffer is too small, p_max_data_length will contain the required buffer size. + * If the buffer is big enough, p_max_data_length will contain the actual size of the data. + * + * @param[in] id ID of the parameter to query. + * @param[out] p_data Pointer to a buffer receiving the queried data. + * @param[out] p_max_data_length Size of the buffer, receives actual size of queried data. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + */ +ret_code_t nfc_t4t_parameter_get(nfc_t4t_param_id_t id, void * p_data, size_t * p_max_data_length); + +/** @brief Activate the NFC frontend. + * + * Only after calling this function, events will be posted to the application callback. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_STATE Already started. + */ +ret_code_t nfc_t4t_emulation_start(void); + +/** + * @brief Deactivate the NFC frontend. + * + * After calling this function, no more events will be posted to the application callback. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_STATE Emulation was already stopped + */ +ret_code_t nfc_t4t_emulation_stop(void); + +/** + * @brief Release reference to application callback. + * + * After calling this function, the passed callback pointer is no longer considered valid. + * After calling this function, the passed p_ndef pointer is no longer considered valid. + * + * You need to restart with @ref nfc_t4t_setup to run a new Emulation. + * + * @retval NRF_SUCCESS Always succeeds. + */ +ret_code_t nfc_t4t_done(void); + +#ifdef __cplusplus +} +#endif + +/** + @} +*/ + +#endif // NFC_T4T_LIB_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c new file mode 100644 index 0000000000000000000000000000000000000000..2617ccbf1d3829a768836863d2fec8a406c81538 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c @@ -0,0 +1,259 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if NFC_T4T_APDU_ENABLED + +#include "nfc_t4t_apdu.h" +#include "sdk_macros.h" +#include "nordic_common.h" +#include "app_util.h" + +#define NRF_LOG_MODULE_NAME "NFC_T4T_APDU" +#if NFC_T4T_APDU_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T4T_APDU_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T4T_APDU_LOG_COLOR +#else // NFC_T4T_APDU_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_T4T_APDU_LOG_ENABLED +#include "nrf_log.h" + +/** + * @brief Field sizes that can be present in CAPDU. + */ +#define CLASS_TYPE_SIZE 1U +#define INSTRUCTION_TYPE_SIZE 1U +#define PARAMETER_SIZE 2U +#define LC_SHORT_FORMAT_SIZE 1U +#define LC_LONG_FORMAT_SIZE 3U +#define LE_SHORT_FORMAT_SIZE 1U +#define LE_LONG_FORMAT_SIZE 2U + +/** + * @brief Values used to encode Lc field in CAPDU. + */ +#define LC_LONG_FORMAT_TOKEN 0x00 +#define LC_LONG_FORMAT_THR 0xFF + +/** + * @brief Values used to encode Le field in CAPDU. + */ +#define LE_FIELD_ABSENT 0U +#define LE_LONG_FORMAT_THR 0x0100 +#define LE_ENCODED_VAL_256 0x00 + + +#define STATUS_SIZE 2U ///< Size of Status field contained in RAPDU. + +/** + * @brief Function for calculating size of CAPDU. + */ +__STATIC_INLINE uint16_t nfc_t4t_comm_apdu_size_calc(nfc_t4t_comm_apdu_t const * const p_cmd_apdu) +{ + uint16_t res = CLASS_TYPE_SIZE + INSTRUCTION_TYPE_SIZE + PARAMETER_SIZE; + if (p_cmd_apdu->data.p_buff != NULL) + { + if (p_cmd_apdu->data.len > LC_LONG_FORMAT_THR) + { + res += LC_LONG_FORMAT_SIZE; + } + else + { + res += LC_SHORT_FORMAT_SIZE; + } + } + res += p_cmd_apdu->data.len; + if (p_cmd_apdu->resp_len != LE_FIELD_ABSENT) + { + if (p_cmd_apdu->resp_len > LE_LONG_FORMAT_THR) + { + res += LE_LONG_FORMAT_SIZE; + } + else + { + res += LE_SHORT_FORMAT_SIZE; + } + } + return res; +} + + +/** + * @brief Function for validating arguments used by CAPDU encoding procedure. + */ +__STATIC_INLINE ret_code_t nfc_t4t_comm_apdu_args_validate(nfc_t4t_comm_apdu_t const * const p_cmd_apdu, + uint8_t * p_raw_data, + uint16_t * const p_len) +{ + if((p_cmd_apdu == NULL) || (p_raw_data == NULL) || (p_len == NULL)) + { + return NRF_ERROR_NULL; + } + + if ((p_cmd_apdu->data.p_buff != NULL) && (p_cmd_apdu->data.len == 0)) + { + return NRF_ERROR_INVALID_PARAM; + } + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_comm_apdu_encode(nfc_t4t_comm_apdu_t const * const p_cmd_apdu, + uint8_t * p_raw_data, + uint16_t * const p_len) +{ + // Validate passed arguments. + ret_code_t err_code = nfc_t4t_comm_apdu_args_validate(p_cmd_apdu, p_raw_data, p_len); + VERIFY_SUCCESS(err_code); + + // Check if there is enough memory in the provided buffer to store described CAPDU. + uint16_t comm_apdu_len = nfc_t4t_comm_apdu_size_calc(p_cmd_apdu); + if (comm_apdu_len > *p_len) + { + return NRF_ERROR_NO_MEM; + } + *p_len = comm_apdu_len; + + // Start to encode described CAPDU in the buffer. + *p_raw_data++ = p_cmd_apdu->class_byte; + *p_raw_data++ = p_cmd_apdu->instruction; + *p_raw_data++ = MSB_16(p_cmd_apdu->parameter); + *p_raw_data++ = LSB_16(p_cmd_apdu->parameter); + + // Check if optional data field should be included. + if (p_cmd_apdu->data.p_buff != NULL) + { + if (p_cmd_apdu->data.len > LC_LONG_FORMAT_THR) // Use long data length encoding. + { + *p_raw_data++ = LC_LONG_FORMAT_TOKEN; + *p_raw_data++ = MSB_16(p_cmd_apdu->data.len); + *p_raw_data++ = LSB_16(p_cmd_apdu->data.len); + } + else // Use short data length encoding. + { + *p_raw_data++ = LSB_16(p_cmd_apdu->data.len); + } + memcpy(p_raw_data, p_cmd_apdu->data.p_buff, p_cmd_apdu->data.len); + p_raw_data += p_cmd_apdu->data.len; + } + + // Check if optional response length field present (Le) should be included. + if (p_cmd_apdu->resp_len != LE_FIELD_ABSENT) + { + if (p_cmd_apdu->resp_len > LE_LONG_FORMAT_THR) // Use long response length encoding. + { + *p_raw_data++ = MSB_16(p_cmd_apdu->resp_len); + *p_raw_data++ = LSB_16(p_cmd_apdu->resp_len); + } + else // Use short response length encoding. + { + if (p_cmd_apdu->resp_len == LE_LONG_FORMAT_THR) + { + *p_raw_data++ = LE_ENCODED_VAL_256; + } + else + { + *p_raw_data++ = LSB_16(p_cmd_apdu->resp_len); + } + } + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for validating arguments used by RAPDU decoding procedure. + */ +__STATIC_INLINE ret_code_t nfc_t4t_resp_apdu_args_validate(nfc_t4t_resp_apdu_t const * const p_resp_apdu, + uint8_t const * const p_raw_data, + uint16_t len) +{ + if ((p_resp_apdu == NULL) || (p_raw_data == NULL)) + { + return NRF_ERROR_NULL; + } + + if (len < STATUS_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_resp_apdu_decode(nfc_t4t_resp_apdu_t * const p_resp_apdu, + uint8_t const * const p_raw_data, + uint16_t len) +{ + // Validate passed arguments. + ret_code_t err_code = nfc_t4t_resp_apdu_args_validate(p_resp_apdu, p_raw_data, len); + VERIFY_SUCCESS(err_code); + + nfc_t4t_resp_apdu_clear(p_resp_apdu); + if (len != STATUS_SIZE) // Optional data field is present in RAPDU. + { + p_resp_apdu->data.len = len - STATUS_SIZE; + p_resp_apdu->data.p_buff = (uint8_t *) p_raw_data; + } + p_resp_apdu->status = uint16_big_decode(p_raw_data + p_resp_apdu->data.len); + + return NRF_SUCCESS; +} + + +void nfc_t4t_resp_apdu_printout(nfc_t4t_resp_apdu_t * p_resp_apdu) +{ + NRF_LOG_INFO("R-APDU status: %4X \r\n", p_resp_apdu->status); + if (p_resp_apdu->data.p_buff != NULL) + { + NRF_LOG_INFO("R-APDU data: \r\n"); + NRF_LOG_HEXDUMP_INFO(p_resp_apdu->data.p_buff, p_resp_apdu->data.len); + } + else + { + NRF_LOG_INFO("R-APDU no data field present.\r\n"); + } +} + + +#endif // NFC_T4T_APDU_ENABLED + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h new file mode 100644 index 0000000000000000000000000000000000000000..d5976610b5dcd429a96ed91e0f296f1e9420f211 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h @@ -0,0 +1,221 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_T4T_APDU_H__ +#define NFC_T4T_APDU_H__ + +/**@file + * + * @defgroup nfc_t4t_apdu APDU reader/writer + * @{ + * @ingroup nfc_t4t_parser + * + * @brief APDU reader/writer for Type 4 Tag communication. + * + */ + +#include +#include +#include "sdk_errors.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CLASS_BYTE_NO_SECURE_MSG 0x00 ///< Class byte indicating no secure messaging, used in C-APDU. + +/** + * @name Parameters used when selecting instruction code in C-APDU. + * @{ + */ +#define SELECT_BY_FILE_ID 0x000C ///< Select by file identifier, first or only occurence. +#define SELECT_BY_NAME 0x0400 ///< Select by name, first or only occurence. +/** @} */ + +/** + * @name Status codes contained in R-APDU. + * @{ + */ +#define RAPDU_STATUS_CMD_COMPLETED 0x9000 ///< Command completed successfully. +#define RAPDU_STATUS_SEL_ITEM_NOT_FOUND 0x6A82 ///< Selected item has not been found. +/** @} */ + +/** + * @brief Possible instruction codes in C-APDU. + */ +typedef enum +{ + NFC_T4T_CAPDU_SELECT_INS = 0xA4, ///< Code used for selecting EF or NDEF application. + NFC_T4T_CAPDU_READ_INS = 0xB0, ///< Code used for selecting EF or NDEF application. + NFC_T4T_CAPDU_UPDATE_INS = 0xD6 ///< Code used for selecting EF or NDEF application. +} nfc_t4t_comm_apdu_ins_type_t; + +/** + * @brief APDU data field descriptor. + */ +typedef struct +{ + uint16_t len; ///< Data field length. + uint8_t * p_buff; ///< Pointer to data field. +} nfc_t4t_apdu_data_t; + +/** + * @brief Command Application Protocol Data Unit (C-APDU) descriptor. + */ +typedef struct +{ + uint8_t class_byte; ///< Class byte. + nfc_t4t_comm_apdu_ins_type_t instruction; ///< The chosen code of instruction. + uint16_t parameter; ///< Parameters associated with the instruction code. + nfc_t4t_apdu_data_t data; ///< Optional data fields (Lc + data bytes). + uint16_t resp_len; ///< Optional response length field (Le). +} nfc_t4t_comm_apdu_t; + +/** + * @brief Response Application Protocol Data Unit (R-APDU) descriptor. + */ +typedef struct +{ + uint16_t status; ///< Mandatory status field. + nfc_t4t_apdu_data_t data; ///< Optional data field. +} nfc_t4t_resp_apdu_t; + +/** + * @brief Macro for verifying R-APDU descriptor status. + * + * This macro verifies R-APDU descriptor status. It will cause the exterior + * function to return nrf_error translated from R-APDU status, if the status is + * not equal to @ref RAPDU_STATUS_CMD_COMPLETED. + * + * @param[in] P_RAPDU Pointer to R-APDU descriptor. + * + * @retval NRF_ERROR_NOT_FOUND If C-APDU select command could not find the selected item. + * @retval NRF_ERROR_INTERNAL Unknown R-APDU error. + */ +#define VERIFY_RAPDU_SUCCESS(P_RAPDU) \ + if (P_RAPDU->status == RAPDU_STATUS_SEL_ITEM_NOT_FOUND) \ + { \ + return NRF_ERROR_NOT_FOUND; \ + } \ + if (P_RAPDU->status != RAPDU_STATUS_CMD_COMPLETED) \ + { \ + return NRF_ERROR_INTERNAL; \ + } + +/** + * @brief Function for clearing C-APDU descriptor and restoring its default values. + * + * @param[in] p_cmd_apdu Pointer to C-APDU descriptor. + */ +__STATIC_INLINE void nfc_t4t_comm_apdu_clear(nfc_t4t_comm_apdu_t * const p_cmd_apdu); + +/** + * @brief Function for clearing R-APDU descriptor and restoring its default values. + * + * @param[in] p_resp_apdu Pointer to R-APDU descriptor. + */ +__STATIC_INLINE void nfc_t4t_resp_apdu_clear(nfc_t4t_resp_apdu_t * const p_resp_apdu); + +/** + * @brief Function for encoding C-APDU. + * + * This function encodes C-APDU according to the provided descriptor. + * + * @param[in] p_cmd_apdu Pointer to the C-APDU descriptor. + * @param[out] p_raw_data Pointer to the buffer with encoded C-APDU. + * @param[in,out] p_len Size of the available memory for the C-APDU as input. + * Size of the generated C-APDU as output. + * + * @retval NRF_SUCCESS If C-APDU was encoded successfully. + * @retval NRF_ERROR_NO_MEM If the predicted C-APDU size is bigger than the provided buffer space. + * @retval NRF_ERROR_INVALID_PARAM If C-APDU descriptor is invalid. + * @retval NRF_ERROR_NULL If any passed argument is NULL. + */ +ret_code_t nfc_t4t_comm_apdu_encode(nfc_t4t_comm_apdu_t const * const p_cmd_apdu, + uint8_t * p_raw_data, + uint16_t * const p_len); + +/** + * @brief Function for decoding R-APDU. + * + * This function decodes buffer with encoded R-APDU and stores results in the R-APDU descriptor. + * + * @param[out] p_resp_apdu Pointer to the R-APDU descriptor. + * @param[in] p_raw_data Pointer to the buffer with encoded R-APDU. + * @param[in] len Size of of the buffer with encoded R-APDU. + * + * @retval NRF_SUCCESS If R-APDU was encoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH If the buffer is too small to hold a valid R-APDU. + * @retval NRF_ERROR_NULL If any passed argument is NULL. + */ +ret_code_t nfc_t4t_resp_apdu_decode(nfc_t4t_resp_apdu_t * const p_resp_apdu, + uint8_t const * const p_raw_data, + uint16_t len); + +/** + * @brief Function for printing a R-APDU descriptor. + * + * This function prints a R-APDU descriptor. + * + * @param[in] p_resp_apdu Pointer to the R-APDU descriptor. + */ +void nfc_t4t_resp_apdu_printout(nfc_t4t_resp_apdu_t * p_resp_apdu); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nfc_t4t_comm_apdu_clear(nfc_t4t_comm_apdu_t * const p_cmd_apdu) +{ + memset(p_cmd_apdu, 0, sizeof(nfc_t4t_comm_apdu_t)); +} + +__STATIC_INLINE void nfc_t4t_resp_apdu_clear(nfc_t4t_resp_apdu_t * const p_resp_apdu) +{ + memset(p_resp_apdu, 0, sizeof(nfc_t4t_resp_apdu_t)); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_T4T_APDU_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c new file mode 100644 index 0000000000000000000000000000000000000000..8cd8289ae5086e0f19b7881e8019812577486686 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c @@ -0,0 +1,265 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if NFC_T4T_CC_FILE_PARSER_ENABLED + +#include +#include "nfc_t4t_cc_file.h" +#include "sdk_macros.h" +#include "nordic_common.h" +#include "app_util.h" + +#define NRF_LOG_MODULE_NAME "NFC_T4T_CC_FILE_PARSER" +#if NFC_T4T_CC_FILE_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T4T_CC_FILE_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T4T_CC_FILE_PARSER_INFO_COLOR +#else // NFC_T4T_CC_FILE_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_T4T_CC_FILE_PARSER_LOG_ENABLED +#include "nrf_log.h" + +/** + * @brief Valid value range for CCLEN field. + */ +#define CC_LEN_MIN_VALUE 0x000F +#define CC_LEN_MAX_VALUE 0xFFFE + +/** + * @brief Valid major versions of Type 4 Tag specification. + */ +#define NFC_T4T_EXTENDED_MAJOR_VER 0x03 ///< Major version number allowing first TLV block to be Extended NDEF File Control TLV +#define NFC_T4T_REGULAR_MAJOR_VER 0x02 ///< Major version number allowing first TLV block to be NDEF File Control TLV + +/** + * @brief Valid value range for MLe field. + */ +#define MLE_LEN_MIN_VALUE 0x000F +#define MLE_LEN_MAX_VALUE 0xFFFF + +/** + * @brief Valid value range for MLc field. + */ +#define MLC_LEN_MIN_VALUE 0x0001 +#define MLC_LEN_MAX_VALUE 0xFFFF + +/** + * @brief Field sizes that are present in CC file. + */ +#define CC_LEN_FIELD_SIZE 2U +#define MAP_VER_FIELD_SIZE 1U +#define MLE_FIELD_SIZE 2U +#define MLC_FIELD_SIZE 2U + +/// Gets least significant nibble (a 4-bit value) from a byte. +#define LSN_GET(val) (val & 0x0F) + +/// Gets most significant nibble (a 4-bit value) from a byte. +#define MSN_GET(val) ((val >> 4) & 0x0F) + +/** + * @brief Function for validating arguments used by CC file parsing procedure. + */ +__STATIC_INLINE ret_code_t nfc_t4t_cc_args_validate(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint8_t * p_raw_data, + uint16_t len) +{ + if ( (p_t4t_cc_file == NULL) + || (p_t4t_cc_file->p_tlv_block_array == NULL) + || (p_raw_data == NULL) ) + { + return NRF_ERROR_NULL; + } + + if ( (len < CC_LEN_MIN_VALUE) || (len > CC_LEN_MAX_VALUE) ) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (p_t4t_cc_file->max_tlv_blocks == 0) + { + return NRF_ERROR_NO_MEM; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for validating CC file descriptor content. + */ +__STATIC_INLINE ret_code_t nfc_t4t_cc_file_validate(nfc_t4t_capability_container_t * p_t4t_cc_file) +{ + uint16_t type = p_t4t_cc_file->p_tlv_block_array[0].type; + + if ( (p_t4t_cc_file->major_version == NFC_T4T_EXTENDED_MAJOR_VER + && type == EXTENDED_NDEF_FILE_CONTROL_TLV) || + (p_t4t_cc_file->major_version == NFC_T4T_REGULAR_MAJOR_VER + && type == NDEF_FILE_CONTROL_TLV) ) + { + return NRF_SUCCESS; + } + + return NRF_ERROR_INVALID_DATA; +} + + +/** + * @brief Function for clearing all TLV blocks from CC file descriptor. + */ +__STATIC_INLINE void nfc_t4t_cc_file_clear(nfc_t4t_capability_container_t * p_t4t_cc_file) +{ + p_t4t_cc_file->tlv_count = 0; +} + + +/** + * @brief Function for adding a TLV block to the CC file descriptor. + */ +static ret_code_t nfc_t4t_tlv_block_insert(nfc_t4t_capability_container_t * p_t4t_cc_file, + nfc_t4t_tlv_block_t * p_tlv_block) +{ + if (p_t4t_cc_file->tlv_count == p_t4t_cc_file->max_tlv_blocks) + { + return NRF_ERROR_NO_MEM; + } + + // Copy contents of the source block. + p_t4t_cc_file->p_tlv_block_array[p_t4t_cc_file->tlv_count] = *p_tlv_block; + p_t4t_cc_file->tlv_count++; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_cc_file_parse(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint8_t * p_raw_data, + uint16_t len) +{ + ret_code_t err_code = nfc_t4t_cc_args_validate(p_t4t_cc_file, p_raw_data, len); + VERIFY_SUCCESS(err_code); + + uint8_t * p_offset = p_raw_data; + nfc_t4t_cc_file_clear(p_t4t_cc_file); + + p_t4t_cc_file->len = uint16_big_decode(p_offset); + p_offset += CC_LEN_FIELD_SIZE; + + p_t4t_cc_file->major_version = MSN_GET(*p_offset); + p_t4t_cc_file->minor_version = LSN_GET(*p_offset); + p_offset += MAP_VER_FIELD_SIZE; + + p_t4t_cc_file->max_rapdu_size = uint16_big_decode(p_offset); + p_offset += MLE_FIELD_SIZE; + + p_t4t_cc_file->max_capdu_size = uint16_big_decode(p_offset); + p_offset += MLC_FIELD_SIZE; + + nfc_t4t_tlv_block_t new_block; + len -= (p_offset - p_raw_data); + while (len > 0) + { + uint16_t tlv_len = len; + err_code = nfc_t4t_file_control_tlv_parse(&new_block, p_offset, &tlv_len); + VERIFY_SUCCESS(err_code); + p_offset += tlv_len; + len -= tlv_len; + + err_code = nfc_t4t_tlv_block_insert(p_t4t_cc_file, &new_block); + VERIFY_SUCCESS(err_code); + } + + return nfc_t4t_cc_file_validate(p_t4t_cc_file); +} + + +nfc_t4t_tlv_block_t * nfc_t4t_file_content_get(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint16_t file_id) +{ + nfc_t4t_tlv_block_t * p_tlv_array = p_t4t_cc_file->p_tlv_block_array; + for (uint8_t i = 0; i < p_t4t_cc_file->tlv_count; i++) + { + nfc_t4t_file_control_val_t * p_tlv_value = &p_tlv_array[i].value; + if (p_tlv_value->file_id == file_id) + { + return (p_tlv_array + i); + } + } + return NULL; +} + + +ret_code_t nfc_t4t_file_content_set(nfc_t4t_capability_container_t * p_t4t_cc_file, + nfc_t4t_file_t file, + uint16_t file_id) +{ + nfc_t4t_tlv_block_t * p_tlv_block; + + p_tlv_block = nfc_t4t_file_content_get(p_t4t_cc_file, file_id); + if (p_tlv_block != NULL) + { + p_tlv_block->value.file = file; + return NRF_SUCCESS; + } + return NRF_ERROR_NOT_FOUND; +} + + +void nfc_t4t_cc_file_printout(nfc_t4t_capability_container_t * p_t4t_cc_file) +{ + NRF_LOG_INFO("Capability Container File content: \r\n") + NRF_LOG_INFO("CCLEN: %d \r\n", p_t4t_cc_file->len); + NRF_LOG_INFO("Mapping Version: %d.%d \r\n", + p_t4t_cc_file->major_version, + p_t4t_cc_file->minor_version); + NRF_LOG_INFO("MLe: %d \r\n", p_t4t_cc_file->max_rapdu_size) + NRF_LOG_INFO("MLc: %d \r\n\r\n", p_t4t_cc_file->max_capdu_size) + + NRF_LOG_INFO("Capability Container File contains %d File Control TLV block(s).\r\n", + p_t4t_cc_file->tlv_count); + for (uint8_t i = 0; i < p_t4t_cc_file->tlv_count; i++) + { + nfc_t4t_file_control_tlv_printout(i, &p_t4t_cc_file->p_tlv_block_array[i]); + } + NRF_LOG_RAW_INFO("\r\n"); +} + + +#endif // NFC_T4T_CC_FILE_PARSER_ENABLED + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h new file mode 100644 index 0000000000000000000000000000000000000000..8403b0a4657db637e83bc9f2d301739ea76eee20 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h @@ -0,0 +1,177 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_T4T_CC_FILE_H__ +#define NFC_T4T_CC_FILE_H__ + +/**@file + * + * @defgroup nfc_t4t_cc_file CC file parser + * @{ + * @ingroup nfc_t4t_parser + * + * @brief Capability Container file parser for Type 4 Tag. + * + */ + +#include +#include "sdk_errors.h" +#include "nfc_t4t_tlv_block.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Descriptor for the Capability Container (CC) file of Type 4 Tag. + */ +typedef struct +{ + nfc_t4t_tlv_block_t * p_tlv_block_array; ///< Pointer to the array for TLV blocks. + uint16_t tlv_count; ///< Number of TLV blocks stored in the Type 4 Tag. + uint16_t const max_tlv_blocks; ///< Maximum number of TLV blocks. + uint16_t len; ///< Size (bytes) of a Capability Container including this field. + uint16_t max_rapdu_size; ///< MLe field - maximum R-APDU data size (bytes). + uint16_t max_capdu_size; ///< MLc field - maximum C-APDU data size (bytes). + uint8_t major_version; ///< Major version of the supported Type 4 Tag specification. + uint8_t minor_version; ///< Minor version of the supported Type 4 Tag specification. +} nfc_t4t_capability_container_t; + +/** + * @brief Macro for creating and initializing a Type 4 Tag Capability Container descriptor. + * + * This macro creates and initializes a static instance of a @ref nfc_t4t_capability_container_t + * structure and an array of @ref nfc_t4t_tlv_block_t descriptors. + * + * Use the macro @ref NFC_T4T_CC_DESC to access the Type 4 Tag descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] MAX_BLOCKS Maximum number of @ref nfc_t4t_tlv_block_t descriptors that can be + * stored in the array. + * + */ +#define NFC_T4T_CC_DESC_DEF(NAME, MAX_BLOCKS) \ + static nfc_t4t_tlv_block_t NAME##_tlv_block_array[MAX_BLOCKS]; \ + static nfc_t4t_capability_container_t NAME##_type_4_tag = \ + { \ + .max_tlv_blocks = MAX_BLOCKS, \ + .p_tlv_block_array = NAME##_tlv_block_array, \ + .tlv_count = 0 \ + } + +/** + * @brief Macro for accessing the @ref nfc_t4t_capability_container_t instance that was created + * with @ref NFC_T4T_CC_DESC_DEF. + * + * @param[in] NAME Name of the created descriptor instance. + */ +#define NFC_T4T_CC_DESC(NAME) (NAME##_type_4_tag) + +/** + * @brief Function for parsing raw data of a CC file, read from a Type 4 Tag. + * + * This function parses raw data of a Capability Container file and stores the results in its + * descriptor. + * + * @param[in,out] p_t4t_cc_file Pointer to the CC file descriptor that will be filled with + * parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data. + * @param[in] len Buffer length. + * + * @retval NRF_SUCCESS If operation was successful. + * @retval NRF_ERROR_NULL If any of the provided pointer arguments is NULL. + * @retval NRF_ERROR_INVALID_LENGTH If provided buffer exceeds a valid CC file length range. + * @retval NRF_ERROR_INVALID_DATA If mapping version of Type 4 Tag specification is not a + * compatible CC file structure. + * @retval Other Other error codes might be returned depending on + * @ref nfc_t4t_file_control_tlv_parse function. + */ +ret_code_t nfc_t4t_cc_file_parse(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint8_t * p_raw_data, + uint16_t len); + +/** + * @brief Function for finding File Control TLV block within the CC file descriptor. + * + * This function finds File Control TLV block that matches + * the specified file ID within the CC file descriptor. + * + * @param[in] p_t4t_cc_file Pointer to the CC file descriptor. + * @param[in] file_id File identifier. + * + * @retval TLV Pointer to the File Control TLV. + * @retval NULL If TLV with the specified File ID was not found. + */ +nfc_t4t_tlv_block_t * nfc_t4t_file_content_get(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint16_t file_id); + +/** + * @brief Function for binding a file with its File Control TLV block. + * + * This function binds file content with its File Control TLV block, in which + * maximal file size and access conditions are stored. + * + * @param[in,out] p_t4t_cc_file Pointer to the CC file descriptor. + * @param[in] file File descriptor. + * @param[in] file_id File identifier. + * + * @retval NRF_SUCCESS If operation was successful. + * @retval NRF_ERROR_NOT_FOUND If the provided file ID does not match any ID stored in TLV blocks + * of the CC file. + */ +ret_code_t nfc_t4t_file_content_set(nfc_t4t_capability_container_t * p_t4t_cc_file, + nfc_t4t_file_t file, + uint16_t file_id); + +/** + * @brief Function for printing the CC file descriptor. + * + * This function prints the CC file descriptor. + * + * @param[in] p_t4t_cc_file Pointer to the CC file. + */ +void nfc_t4t_cc_file_printout(nfc_t4t_capability_container_t * p_t4t_cc_file); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_T4T_CC_FILE_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c new file mode 100644 index 0000000000000000000000000000000000000000..baf4452249579b3811794a7f6fddab5ceef5f5e4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c @@ -0,0 +1,399 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED + +#include "nfc_t4t_hl_detection_procedures.h" +#include "nfc_t4t_apdu.h" +#include "adafruit_pn532.h" +#include "sdk_macros.h" +#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "NFC_T4T_HL_DETECTION_PROCEDURES" +#if NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T4T_HL_DETECTION_PROCEDURES_INFO_COLOR +#else // NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED +#include "nrf_log.h" + +#define CC_FILE_ID 0xE103 ///< File Identifier of Capability Container. +#define FILE_ID_SIZE 2 ///< Size of File Identifier field in CC file. +#define MIN_MAX_RAPDU_SIZE 0x0F ///< Minimal value of maximal RAPDU data field size. +#define NDEF_FILE_NLEN_FIELD_SIZE 2 ///< Size of NLEN field in NDEF file. +#define NDEF_APP_PROC_RESP_LEN 256 ///< Maximal size of RAPDU data in the NDEF Tag Application Select Procedure. + +// Adafruit library limitations. +#define MAX_ADAFRUIT_RAPDU_SIZE 242 ///< Maximal value of RAPDU data field size +#define MAX_ADAFRUIT_CAPDU_SIZE 56 ///< Maximal value of CAPDU data field size + +static uint8_t m_file_id[FILE_ID_SIZE]; ///< Buffer for selected EF ID storage. +static const uint8_t m_nfc_t4t_select_ndef_app_data[] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01}; ///< NDEF Tag Application name. +static const uint8_t m_nlen_update_value[] = {0x00, 0x00}; ///< NLEN value used in NDEF Update Procedure. + +/** + * @brief Function for performing APDU exchanges with Adafruit library. + */ +static ret_code_t nfc_t4t_apdu_exchange(nfc_t4t_comm_apdu_t * const p_capdu, + nfc_t4t_resp_apdu_t * const p_rapdu, + uint8_t * const p_apdu_buff, + uint8_t resp_len) +{ + if (resp_len > APDU_BUFF_SIZE) + { + return NRF_ERROR_NO_MEM; + } + + uint16_t apdu_buff_len = APDU_BUFF_SIZE; + ret_code_t err_code = nfc_t4t_comm_apdu_encode(p_capdu, + p_apdu_buff, + &apdu_buff_len); + VERIFY_SUCCESS(err_code); + + err_code = adafruit_pn532_in_data_exchange(p_apdu_buff, apdu_buff_len, p_apdu_buff, &resp_len); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_resp_apdu_decode(p_rapdu, p_apdu_buff, resp_len); + VERIFY_SUCCESS(err_code); + + nfc_t4t_resp_apdu_printout(p_rapdu); + VERIFY_RAPDU_SUCCESS(p_rapdu); + + return err_code; +} + +/** + * @brief Function for performing APDU exchanges with Adafruit library with default response length. + */ +static ret_code_t nfc_t4t_apdu_default_exchange(nfc_t4t_comm_apdu_t * const p_capdu, + nfc_t4t_resp_apdu_t * const p_rapdu, + uint8_t * const p_apdu_buff) +{ + if (p_capdu->resp_len + sizeof(p_rapdu->status) > UINT8_MAX) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint8_t resp_len = (uint8_t) (p_capdu->resp_len + sizeof(p_rapdu->status)); + ret_code_t err_code = nfc_t4t_apdu_exchange(p_capdu, p_rapdu, p_apdu_buff, resp_len); + + return err_code; +} + + +/** + * @brief Function for saving part of EF (contained in RAPDU) in storage buffer. + */ +static ret_code_t nfc_t4t_file_chunk_save(nfc_t4t_resp_apdu_t const * const p_rapdu, + uint8_t * const p_storage_buff, + uint16_t storage_buff_len, + uint16_t * const p_file_offset) +{ + if (p_rapdu->data.p_buff == NULL) + { + return NRF_ERROR_NULL; + } + if ((*p_file_offset) + p_rapdu->data.len > storage_buff_len) + { + return NRF_ERROR_NO_MEM; + } + + memcpy(p_storage_buff + (*p_file_offset), p_rapdu->data.p_buff, p_rapdu->data.len); + *p_file_offset += p_rapdu->data.len; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for updating the remaining length of the read file. + */ +static ret_code_t nfc_t4t_file_len_update(nfc_t4t_resp_apdu_t const * const p_rapdu, + uint16_t * const p_len) +{ + if (*p_len < p_rapdu->data.len) + { + return NRF_ERROR_INVALID_DATA; + } + *p_len -= p_rapdu->data.len; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_ndef_tag_app_select(void) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint8_t apdu_buff[APDU_BUFF_SIZE]; + + NRF_LOG_INFO("NDEF Tag Application Select Procedure \r\n"); + + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_SELECT_INS; + capdu.parameter = SELECT_BY_NAME; + capdu.data.p_buff = (uint8_t *) m_nfc_t4t_select_ndef_app_data; + capdu.data.len = sizeof(m_nfc_t4t_select_ndef_app_data); + capdu.resp_len = NDEF_APP_PROC_RESP_LEN; + + err_code = nfc_t4t_apdu_exchange(&capdu, &rapdu, apdu_buff, sizeof(rapdu.status)); + NRF_LOG_RAW_INFO("\r\n"); + return err_code; +} + + +ret_code_t nfc_t4t_file_select(uint16_t file_id) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint8_t apdu_buff[APDU_BUFF_SIZE]; + + if (file_id != CC_FILE_ID) + { + NRF_LOG_INFO("File (ID = %4X) Select Procedure \r\n", file_id); + } + UNUSED_RETURN_VALUE(uint16_big_encode(file_id, m_file_id)); + + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_SELECT_INS; + capdu.parameter = SELECT_BY_FILE_ID; + capdu.data.p_buff = m_file_id; + capdu.data.len = sizeof(m_file_id); + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + NRF_LOG_RAW_INFO("\r\n"); + return err_code; +} + + +ret_code_t nfc_t4t_cc_select(void) +{ + NRF_LOG_INFO("Capability Container Select Procedure \r\n"); + + return nfc_t4t_file_select(CC_FILE_ID); +} + + +ret_code_t nfc_t4t_cc_read(nfc_t4t_capability_container_t * const p_cc_file) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint16_t clen; + uint16_t file_offset = 0; + uint8_t storage_buff[CC_STORAGE_BUFF_SIZE]; + uint8_t apdu_buff[APDU_BUFF_SIZE]; + + NRF_LOG_INFO("Capability Container Read Procedure \r\n"); + + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_READ_INS; + capdu.parameter = file_offset; + capdu.resp_len = MIN_MAX_RAPDU_SIZE; + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_chunk_save(&rapdu, storage_buff, CC_STORAGE_BUFF_SIZE, &file_offset); + VERIFY_SUCCESS(err_code); + + clen = uint16_big_decode(storage_buff); + err_code = nfc_t4t_file_len_update(&rapdu, &clen); + VERIFY_SUCCESS(err_code); + + while (clen > 0) + { + capdu.parameter = file_offset; + capdu.resp_len = MIN(MIN_MAX_RAPDU_SIZE, MIN(clen, MAX_ADAFRUIT_RAPDU_SIZE)); + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_chunk_save(&rapdu, storage_buff, CC_STORAGE_BUFF_SIZE, &file_offset); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_len_update(&rapdu, &clen); + VERIFY_SUCCESS(err_code); + } + + err_code = nfc_t4t_cc_file_parse(p_cc_file, storage_buff, file_offset); + + NRF_LOG_RAW_INFO("\r\n"); + return err_code; +} + + +ret_code_t nfc_t4t_ndef_read(nfc_t4t_capability_container_t * const p_cc_file, + uint8_t * p_ndef_file_buff, + uint8_t ndef_file_buff_len) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint16_t len; + uint16_t file_offset = 0; + uint8_t apdu_buff[APDU_BUFF_SIZE]; + + NRF_LOG_INFO("NDEF Read Procedure \r\n"); + + // Read the NLEN (NDEF length) field of NDEF file. + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_READ_INS; + capdu.parameter = file_offset; + capdu.resp_len = NDEF_FILE_NLEN_FIELD_SIZE; + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_chunk_save(&rapdu, p_ndef_file_buff, ndef_file_buff_len, &file_offset); + VERIFY_SUCCESS(err_code); + + len = uint16_big_decode(p_ndef_file_buff) + NDEF_FILE_NLEN_FIELD_SIZE; + err_code = nfc_t4t_file_len_update(&rapdu, &len); + VERIFY_SUCCESS(err_code); + + // Read the NDEF message. + while (len > 0) + { + capdu.parameter = file_offset; + capdu.resp_len = MIN(len, MIN(p_cc_file->max_rapdu_size, MAX_ADAFRUIT_RAPDU_SIZE)); + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_chunk_save(&rapdu, p_ndef_file_buff, ndef_file_buff_len, &file_offset); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_len_update(&rapdu, &len); + VERIFY_SUCCESS(err_code); + } + + // Bind NDEF File Control TLV with NDEF file. + nfc_t4t_file_t file = + { + .p_content = p_ndef_file_buff, + .len = file_offset + }; + uint16_t file_id = uint16_big_decode(m_file_id); + err_code = nfc_t4t_file_content_set(p_cc_file, file, file_id); + + NRF_LOG_RAW_INFO("\r\n"); + return err_code; +} + + +ret_code_t nfc_t4t_ndef_update(nfc_t4t_capability_container_t * const p_cc_file, + uint8_t * p_ndef_file_buff, + uint8_t ndef_file_buff_len) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint16_t len; + uint16_t file_offset = 0; + uint16_t file_id = uint16_big_decode(m_file_id); + uint8_t apdu_buff[APDU_BUFF_SIZE]; + nfc_t4t_tlv_block_t * p_tlv_block; + + NRF_LOG_INFO("NDEF Update Procedure \r\n"); + + if (ndef_file_buff_len < NDEF_FILE_NLEN_FIELD_SIZE) + { + return NRF_ERROR_INVALID_DATA; + } + + // Check if selected NDEF file is registered in CC file descriptor. + p_tlv_block = nfc_t4t_file_content_get(p_cc_file, file_id); + if (p_tlv_block == NULL) + { + return NRF_ERROR_NULL; + } + + // Check NDEF file capacity before writing anything to it. + len = uint16_big_decode(p_ndef_file_buff); + if ((len + NDEF_FILE_NLEN_FIELD_SIZE != ndef_file_buff_len) || + (ndef_file_buff_len > p_tlv_block->value.max_file_size)) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Write the value 0000h in the NLEN field. + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_UPDATE_INS; + capdu.parameter = file_offset; + capdu.data.p_buff = (uint8_t *) m_nlen_update_value; + capdu.data.len = NDEF_FILE_NLEN_FIELD_SIZE; + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + file_offset += NDEF_FILE_NLEN_FIELD_SIZE; + + // Write the NDEF message in the NDEF message field. + while (len > 0) + { + capdu.parameter = file_offset; + capdu.data.p_buff = p_ndef_file_buff + file_offset; + capdu.data.len = MIN(len, MIN(p_cc_file->max_capdu_size, MAX_ADAFRUIT_CAPDU_SIZE)); + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + file_offset += capdu.data.len; + len -= capdu.data.len; + } + + // Write the length of the NDEF message in the NLEN field. + capdu.parameter = 0; + capdu.data.p_buff = p_ndef_file_buff; + capdu.data.len = NDEF_FILE_NLEN_FIELD_SIZE; + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + NRF_LOG_RAW_INFO("\r\n"); + return NRF_SUCCESS; +} + + +#endif // NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h new file mode 100644 index 0000000000000000000000000000000000000000..1dc56e83b40d1ea47665794bf503df113b8a04ac --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h @@ -0,0 +1,184 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_H__ +#define NFC_T4T_HL_DETECTION_PROCEDURES_H__ + +/**@file + * + * @defgroup nfc_t4t_parser NFC Type 4 Tag parser + * @ingroup nfc_t4t + * @brief Parser for Type 4 Tag data. + * + * @defgroup nfc_t4t_hl_detection_procedures High-level NDEF Detection Procedure + * @{ + * @ingroup nfc_t4t_parser + * + * @brief High-level NDEF Detection Procedure for Type 4 Tag communication. + * + */ + +#include +#include "sdk_errors.h" +#include "nfc_t4t_cc_file.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Function for performing NDEF Tag Application Select Procedure. + * + * This function performs NDEF Tag Application Select Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.2. + * + * @retval NRF_SUCCESS If NDEF Tag Application was successfully selected. + * @retval NRF_ERROR_NOT_FOUND If NDEF Tag Application was not found. + * @retval NRF_ERROR_NO_MEM If the APDU buffer is too small. + * @retval Other Other error codes may be returned depending on function + * @ref adafruit_pn532_in_data_exchange and on @ref nfc_t4t_apdu + * module functions. + */ +ret_code_t nfc_t4t_ndef_tag_app_select(void); + +/** + * @brief Function for performing Capability Container Select Procedure. + * + * This function performs Capability Container Select Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.3. + * + * @retval NRF_SUCCESS If the Capability Container file was successfully selected. + * @retval NRF_ERROR_NOT_FOUND If the Capability Container file was not found. + * @retval NRF_ERROR_NO_MEM If the APDU buffer is too small. + * @retval Other Other error codes might be returned depending on function + * @ref adafruit_pn532_in_data_exchange and on @ref nfc_t4t_apdu + * module functions. + */ +ret_code_t nfc_t4t_cc_select(void); + +/** + * @brief Function for performing Capability Container Read Procedure. + * + * This function performs Capability Container Read Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.4. + * + * @param[out] p_cc_file Pointer to the Capability Container descriptor. + * + * @retval NRF_SUCCESS If Capability Container file was successfully read. + * @retval NRF_ERROR_NO_MEM If APDU buffer or CC file storage buffer is too small. + * @retval NRF_ERROR_NOT_SUPPORTED If the requested response length in C-APDU is too big. + * @retval NRF_ERROR_NULL If R-APDU did not return any data bytes. + * @retval NRF_ERROR_INVALID_DATA If CCLEN field is not coherent with R-APDU data length. + * @retval Other Other error codes may be returned depending on functions + * @ref adafruit_pn532_in_data_exchange, @ref nfc_t4t_cc_file_parse, + * and on @ref nfc_t4t_apdu module functions. + */ +ret_code_t nfc_t4t_cc_read(nfc_t4t_capability_container_t * const p_cc_file); + +/** + * @brief Function for performing NDEF Select Procedure. + * + * This function performs NDEF Select Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.5. + * + * @param[in] file_id File Identifier to choose the correct file. + * + * @retval NRF_SUCCESS If NDEF file was successfully selected. + * @retval NRF_ERROR_NOT_FOUND If NDEF file was not found. + * @retval NRF_ERROR_NO_MEM If APDU buffer is too small. + * @retval Other Other error codes may be returned depending on function + * @ref adafruit_pn532_in_data_exchange and on @ref nfc_t4t_apdu + * module functions. + */ +ret_code_t nfc_t4t_file_select(uint16_t file_id); + +/** + * @brief Function for performing NDEF Read Procedure. + * + * This function performs NDEF Read Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.6. + * + * @param[in,out] p_cc_file Pointer to the Capability Container descriptor. + * @param[out] p_ndef_file_buff Pointer to the buffer where the NDEF file will be stored. + * @param[in] ndef_file_buff_len Length of the provided NDEF file buffer. + * + * @retval NRF_SUCCESS If NDEF file was successfully read. + * @retval NRF_ERROR_NO_MEM If APDU buffer or NDEF file buffer is too small. + * @retval NRF_ERROR_NOT_SUPPORTED If requested response length in C-APDU is too big. + * @retval NRF_ERROR_NULL If R-APDU did not return any data bytes. + * @retval NRF_ERROR_INVALID_DATA If NLEN field is not coherent with R-APDU data length. + * @retval Other Other error codes may be returned depending on function + * @ref adafruit_pn532_in_data_exchange, @ref nfc_t4t_file_content_set, + * and on @ref nfc_t4t_apdu module functions. + */ +ret_code_t nfc_t4t_ndef_read(nfc_t4t_capability_container_t * const p_cc_file, + uint8_t * p_ndef_file_buff, + uint8_t ndef_file_buff_len); + +/** + * @brief Function for performing NDEF Update Procedure. + * + * This function performs NDEF Update Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.7. + * + * @param[in] p_cc_file Pointer to the Capability Container descriptor. + * @param[in] p_ndef_file_buff Pointer to the buffer with NDEF file. + * @param[in] ndef_file_buff_len Length of the provided NDEF file. + * + * @retval NRF_SUCCESS If NDEF file was successfully updated. + * @retval NRF_ERROR_NO_MEM If APDU buffer or NDEF file buffer is too small. + * @retval NRF_ERROR_NOT_SUPPORTED If the requested response length in C-APDU is too big. + * @retval NRF_ERROR_INVALID_DATA If NDEF file buffer is smaller than NLEN field size. + * @retval NRF_ERROR_INVALID_LENGTH If NLEN value is not coherent with NDEF file buffer length + * or if buffer length is bigger than maximal file size. + * @retval Other Other error codes may be returned depending on function + * @ref adafruit_pn532_in_data_exchange, @ref nfc_t4t_file_content_get, + * and on @ref nfc_t4t_apdu module functions. + */ +ret_code_t nfc_t4t_ndef_update(nfc_t4t_capability_container_t * const p_cc_file, + uint8_t * p_ndef_file_buff, + uint8_t ndef_file_buff_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_T4T_HL_DETECTION_PROCEDURES_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c new file mode 100644 index 0000000000000000000000000000000000000000..7f0ca693be0958c1588eea2fff87429b70494a2d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c @@ -0,0 +1,326 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if NFC_T4T_TLV_BLOCK_PARSER_ENABLED + +#include +#include "nfc_t4t_tlv_block.h" +#include "app_util.h" +#include "sdk_macros.h" +#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "NFC_T4T_TLV_BLOCK_PARSER" +#if NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T4T_TLV_BLOCK_PARSER_INFO_COLOR +#else // NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED +#include "nrf_log.h" + +#define TLV_TYPE_FIELD_LEN 1U ///< Length of a type field. + +/** + * @brief TLV length field related defines. + */ +#define TLV_LEN_SHORT_FIELD_LEN 1U ///< Length of a short length field. +#define TLV_LEN_LONG_FIELD_LEN 3U ///< Length of an extended length field. +#define TLV_LEN_LONG_FORMAT_TOKEN 0xFF ///< Value indicating the use of an extended length field. +#define TLV_LEN_LONG_FORMAT_TOKEN_SIZE 1U ///< Size of long format token. +#define TLV_LEN_LONG_FORMAT_MIN_VALUE 0xFF ///< The minimal value of length field that can be used in long format. + +/** + * @brief Possible sizes of TLV block. + */ +#define TLV_MIN_TL_FIELD_LEN (TLV_TYPE_FIELD_LEN + TLV_LEN_SHORT_FIELD_LEN) +#define TLV_MIN_LONG_FORMAT_TL_FIELD_LEN (TLV_TYPE_FIELD_LEN + TLV_LEN_LONG_FIELD_LEN) +#define TLV_MIN_VALUE_FIELD_SIZE 6U + +/** + * @brief Field sizes that are present in TLV block. + */ +#define FILE_CONTROL_FILE_ID_FIELD_SIZE 2U +#define FILE_CONTROL_READ_ACCESS_FIELD_SIZE 1U +#define FILE_CONTROL_WRITE_ACCESS_FIELD_SIZE 1U +#define FILE_CONTROL_COMMON_FIELDS_SIZE (FILE_CONTROL_FILE_ID_FIELD_SIZE \ + + FILE_CONTROL_READ_ACCESS_FIELD_SIZE \ + + FILE_CONTROL_WRITE_ACCESS_FIELD_SIZE) + +/** + * @brief Invalid values for File Identifier field. + */ +#define FILE_ID_INVALID_VALUE_0 0x0000 +#define FILE_ID_INVALID_VALUE_1 0xE102 +#define FILE_ID_INVALID_VALUE_2 0xE103 +#define FILE_ID_INVALID_VALUE_3 0x3F00 +#define FILE_ID_INVALID_VALUE_4 0x3FFF +#define FILE_ID_INVALID_VALUE_5 0xFFFF + +/** + * @brief NDEF file related defines. + */ +#define NDEF_FILE_MAX_SIZE_FIELD_SIZE 2U +#define NDEF_FILE_MAX_SIZE_MIN_VAL 0x0005 +#define NDEF_FILE_MAX_SIZE_MAX_VAL 0xFFFE +#define NDEF_FILE_CONTROL_TLV_LEN (FILE_CONTROL_COMMON_FIELDS_SIZE \ + + NDEF_FILE_MAX_SIZE_FIELD_SIZE) + +/** + * @brief Proprietary file related defines. + */ +#define PROPRIETARY_FILE_MAX_SIZE_FIELD_SIZE 2U +#define PROPRIETARY_FILE_MAX_SIZE_MIN_VAL 0x0003 +#define PROPRIETARY_FILE_MAX_SIZE_MAX_VAL 0xFFFE +#define PROPRIETARY_FILE_CONTROL_TLV_LEN (FILE_CONTROL_COMMON_FIELDS_SIZE \ + + PROPRIETARY_FILE_MAX_SIZE_FIELD_SIZE) + +/** + * @brief Extended NDEF file related defines. + */ +#define EXTENDED_NDEF_FILE_MAX_SIZE_FIELD_SIZE 4U +#define EXTENDED_NDEF_FILE_MAX_SIZE_MIN_VAL 0x0000FFFF +#define EXTENDED_NDEF_FILE_MAX_SIZE_MAX_VAL 0xFFFFFFFE +#define EXTENDED_NDEF_FILE_CONTROL_TLV_LEN (FILE_CONTROL_COMMON_FIELDS_SIZE \ + + EXTENDED_NDEF_FILE_MAX_SIZE_FIELD_SIZE) + +/** + * @brief Validates maximum file size field range. This field is present in every File Control TLV. + */ +#define NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(VALUE, MIN, MAX) \ + if ( ( (VALUE) < (MIN) ) || ( (VALUE) > (MAX) ) ) \ + { \ + return NRF_ERROR_INVALID_DATA; \ + } + + +/** + * @brief Function for validating all possible types of File Control TLV. + */ +__STATIC_INLINE ret_code_t nfc_t4t_file_control_tl_validate(nfc_t4t_tlv_block_t * p_file_control_tlv) +{ + switch (p_file_control_tlv->type) + { + case NDEF_FILE_CONTROL_TLV: + VERIFY_TRUE(p_file_control_tlv->length == NDEF_FILE_CONTROL_TLV_LEN, + NRF_ERROR_INVALID_DATA); + return NRF_SUCCESS; + + case PROPRIETARY_FILE_CONTROL_TLV: + VERIFY_TRUE(p_file_control_tlv->length == PROPRIETARY_FILE_CONTROL_TLV_LEN, + NRF_ERROR_INVALID_DATA); + return NRF_SUCCESS; + + case EXTENDED_NDEF_FILE_CONTROL_TLV: + VERIFY_TRUE(p_file_control_tlv->length == EXTENDED_NDEF_FILE_CONTROL_TLV_LEN, + NRF_ERROR_INVALID_DATA); + return NRF_SUCCESS; + + default: + return NRF_ERROR_INVALID_DATA; + } +} + + +/** + * @brief Function for parsing value field of File Control TLV. + */ +static ret_code_t nfc_t4t_file_control_value_parse(nfc_t4t_tlv_block_t * p_file_control_tlv, + uint8_t * p_value_buff) +{ + nfc_t4t_file_control_val_t * p_control_tlv_val; + + // Handle File Identifier field. + p_control_tlv_val = &p_file_control_tlv->value; + p_control_tlv_val->file_id = uint16_big_decode(p_value_buff); + p_value_buff += FILE_CONTROL_FILE_ID_FIELD_SIZE; + + switch (p_control_tlv_val->file_id) + { + case FILE_ID_INVALID_VALUE_0: + case FILE_ID_INVALID_VALUE_1: + case FILE_ID_INVALID_VALUE_2: + case FILE_ID_INVALID_VALUE_3: + case FILE_ID_INVALID_VALUE_4: + case FILE_ID_INVALID_VALUE_5: + return NRF_ERROR_INVALID_DATA; + + default: + break; + } + + // Handle Max file size field. + switch (p_file_control_tlv->type) + { + case NDEF_FILE_CONTROL_TLV: + p_control_tlv_val->max_file_size = uint16_big_decode(p_value_buff); + p_value_buff += NDEF_FILE_MAX_SIZE_FIELD_SIZE; + NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(p_control_tlv_val->max_file_size, + NDEF_FILE_MAX_SIZE_MIN_VAL, + NDEF_FILE_MAX_SIZE_MAX_VAL); + break; + + case PROPRIETARY_FILE_CONTROL_TLV: + p_control_tlv_val->max_file_size = uint16_big_decode(p_value_buff); + p_value_buff += PROPRIETARY_FILE_MAX_SIZE_FIELD_SIZE; + NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(p_control_tlv_val->max_file_size, + PROPRIETARY_FILE_MAX_SIZE_MIN_VAL, + PROPRIETARY_FILE_MAX_SIZE_MAX_VAL); + break; + + case EXTENDED_NDEF_FILE_CONTROL_TLV: + p_control_tlv_val->max_file_size = uint32_big_decode(p_value_buff); + p_value_buff += EXTENDED_NDEF_FILE_MAX_SIZE_FIELD_SIZE; + NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(p_control_tlv_val->max_file_size, + EXTENDED_NDEF_FILE_MAX_SIZE_MIN_VAL, + EXTENDED_NDEF_FILE_MAX_SIZE_MAX_VAL); + break; + } + + // Handle read access condition field. + p_control_tlv_val->read_access = *p_value_buff; + p_value_buff += FILE_CONTROL_READ_ACCESS_FIELD_SIZE; + + // Handle write access condition field. + p_control_tlv_val->write_access = *p_value_buff; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_file_control_tlv_parse(nfc_t4t_tlv_block_t * p_file_control_tlv, + uint8_t * p_raw_data, + uint16_t * p_len) +{ + ret_code_t err_code; + uint8_t * p_offset = p_raw_data; + + if (*p_len < TLV_MIN_TL_FIELD_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + memset(p_file_control_tlv, 0, sizeof(nfc_t4t_tlv_block_t)); + + // Handle type field of TLV block. + p_file_control_tlv->type = *p_offset; + p_offset += TLV_TYPE_FIELD_LEN; + + // Handle length field of TLV block. + if (*p_offset == TLV_LEN_LONG_FORMAT_TOKEN) + { + if (*p_len < TLV_MIN_LONG_FORMAT_TL_FIELD_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_file_control_tlv->length = uint16_big_decode(p_offset + TLV_LEN_LONG_FORMAT_TOKEN_SIZE); + p_offset += TLV_LEN_LONG_FIELD_LEN; + + if (p_file_control_tlv->length < TLV_LEN_LONG_FORMAT_MIN_VALUE) + { + return NRF_ERROR_INVALID_DATA; + } + } + else + { + p_file_control_tlv->length = *p_offset; + p_offset += TLV_LEN_SHORT_FIELD_LEN; + } + + // Calculate the total TLV block size. + uint16_t tlv_block_len = (p_offset - p_raw_data) + p_file_control_tlv->length; + if (*p_len < tlv_block_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + *p_len = tlv_block_len; + + // Validate if type and length fields contain values supported by Type 4 Tag. + err_code = nfc_t4t_file_control_tl_validate(p_file_control_tlv); + VERIFY_SUCCESS(err_code); + + // Handle value field of TLV block. + err_code = nfc_t4t_file_control_value_parse(p_file_control_tlv, p_offset); + return err_code; +} + + +void nfc_t4t_file_control_tlv_printout(uint8_t num, nfc_t4t_tlv_block_t * p_t4t_tlv_block) +{ + NRF_LOG_INFO("%d file Control TLV\r\n", num); + switch (p_t4t_tlv_block->type) + { + case NDEF_FILE_CONTROL_TLV: + NRF_LOG_INFO("Type: NDEF File Control (0x%02x)\r\n", p_t4t_tlv_block->type); + break; + + case PROPRIETARY_FILE_CONTROL_TLV: + NRF_LOG_INFO("Type: Proprietary File Control (0x%02x)\r\n", p_t4t_tlv_block->type); + break; + + case EXTENDED_NDEF_FILE_CONTROL_TLV: + NRF_LOG_INFO("Type: Extended NDEF File Control (0x%02x)\r\n", p_t4t_tlv_block->type); + break; + + default: + NRF_LOG_INFO("Type: Unknown (0x%02x)\r\n", p_t4t_tlv_block->type); + } + NRF_LOG_INFO("Length (in bytes): %d\r\n", p_t4t_tlv_block->length); + + nfc_t4t_file_control_val_t * p_tlv_val = &p_t4t_tlv_block->value; + NRF_LOG_INFO("File Identifier: 0x%04X \r\n", p_tlv_val->file_id); + NRF_LOG_INFO("Maximum file size: %d \r\n", p_tlv_val->max_file_size); + NRF_LOG_INFO("Read access condition: 0x%02X \r\n", p_tlv_val->read_access); + NRF_LOG_INFO("Write access condition: 0x%02x \r\n\r\n", p_tlv_val->write_access); + + if (p_tlv_val->file.p_content != NULL) + { + NRF_LOG_INFO("NDEF file content present. Length: %d \r\n", p_tlv_val->file.len); + NRF_LOG_HEXDUMP_INFO(p_tlv_val->file.p_content, p_tlv_val->file.len); + } + else + { + NRF_LOG_INFO("NDEF file content is not present \r\n"); + } + NRF_LOG_RAW_INFO("\r\n"); +} + + +#endif // NFC_T4T_TLV_BLOCK_PARSER_ENABLED + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h new file mode 100644 index 0000000000000000000000000000000000000000..9e62bd90511448e16a736bcf9574def9796772de --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NFC_T4T_TLV_BLOCK_H__ +#define NFC_T4T_TLV_BLOCK_H__ + +/**@file + * + * @defgroup nfc_t4t_tlv_block File Control TLV block parser for Type 4 Tag. + * @{ + * @ingroup nfc_t4t_cc_file + * + * @brief File Control TLV block parser for Type 4 Tag (T4T). + * + */ + +#include +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CONTROL_FILE_READ_ACCESS_GRANTED 0x00 ///< Read access granted without any security. + +/** + * @name Possible values of file write access condition field. + * @{ + */ +#define CONTROL_FILE_WRITE_ACCESS_GRANTED 0x00 ///< Write access granted without any security. +#define CONTROL_FILE_WRITE_ACCESS_DISABLED 0xFF ///< No write access granted without any security (read-only). +/** @} */ + +/** + * @brief Possible types of File Control TLV for Type 4 Tag. + */ +typedef enum +{ + NDEF_FILE_CONTROL_TLV = 0x04, ///< Control information concerning the EF file with short NDEF message. + PROPRIETARY_FILE_CONTROL_TLV = 0x05, ///< Control information concerning the Proprietary file with proprietary data. + EXTENDED_NDEF_FILE_CONTROL_TLV = 0x06 ///< Control information concerning the EF file with long NDEF message. +} nfc_t4t_tlv_block_types_t; + +/** + * @brief File content descriptor. + */ +typedef struct +{ + uint8_t * p_content; ///< Pointer to the file content. + uint16_t len; ///< Length of file content. +} nfc_t4t_file_t; + +/** + * @brief Extended NDEF/NDEF/Proprietary File Control Value descriptor. + */ +typedef struct +{ + nfc_t4t_file_t file; ///< Pointer to the described file content. + uint32_t max_file_size; ///< Maximum size (in bytes) of the file. + uint16_t file_id; ///< File identifier. + uint8_t read_access; ///< File read access condition. + uint8_t write_access; ///< File write access condition. +} nfc_t4t_file_control_val_t; + +/** + * @brief File Control TLV block descriptor. + */ +typedef struct +{ + nfc_t4t_file_control_val_t value; ///< Value field descriptor. + uint16_t length; ///< Length of the value field. + uint8_t type; ///< Type of the TLV block. +} nfc_t4t_tlv_block_t; + +/** + * @brief Function for parsing raw data of File Control TLV, read from a Type 4 Tag. + * + * This function parses raw data of File Control TLV and stores the results in its + * descriptor. + * + * @param[in,out] p_file_control_tlv Pointer to the File Control TLV that will be filled with + * parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw TLV data. + * @param[in,out] p_len In: Buffer length with TLV blocks. + * Out: Total length of first identified TLV within the buffer. + * + * @retval NRF_SUCCESS If operation was successful. + * @retval NRF_ERROR_INVALID_LENGTH If provided buffer length is too small for TLV block. + * @retval NRF_ERROR_INVALID_DATA If any TLV block field contains invalid data. + */ +ret_code_t nfc_t4t_file_control_tlv_parse(nfc_t4t_tlv_block_t * p_file_control_tlv, + uint8_t * p_raw_data, + uint16_t * p_len); + +/** + * @brief Function for printing TLV block descriptor. + * + * This function prints TLV block descriptor. + * + * @param[in] num TLV block number. + * @param[in] p_t4t_tlv_block Pointer to the TLV block descriptor. + */ +void nfc_t4t_file_control_tlv_printout(uint8_t num, nfc_t4t_tlv_block_t * p_t4t_tlv_block); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_T4T_TLV_BLOCK_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/esb/nrf_esb.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/esb/nrf_esb.c new file mode 100644 index 0000000000000000000000000000000000000000..d4c151fef53df6a63eb87f6c68e830b4b03b35e1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/esb/nrf_esb.c @@ -0,0 +1,1299 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_error.h" +#include "nrf_esb.h" +#include "nrf_esb_error_codes.h" +#include "nrf_gpio.h" +#include +#include +#include "sdk_common.h" +#include "sdk_macros.h" +#include "app_util.h" +#include "nrf_log.h" + +#define BIT_MASK_UINT_8(x) (0xFF >> (8 - (x))) +#define NRF_ESB_PIPE_COUNT 9 + +// Constant parameters +#define RX_WAIT_FOR_ACK_TIMEOUT_US_2MBPS (48) /**< 2 Mb RX wait for acknowledgment time-out value. Smallest reliable value - 43. */ +#define RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS (64) /**< 1 Mb RX wait for acknowledgment time-out value. Smallest reliable value - 59. */ +#define RX_WAIT_FOR_ACK_TIMEOUT_US_250KBPS (250) /**< 250 Kb RX wait for acknowledgment time-out value. */ +#define RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS_BLE (64) /**< 1 Mb RX wait for acknowledgment time-out (combined with BLE). */ + +// Interrupt flags +#define NRF_ESB_INT_TX_SUCCESS_MSK 0x01 /**< Interrupt mask value for TX success. */ +#define NRF_ESB_INT_TX_FAILED_MSK 0x02 /**< Interrupt mask value for TX failure. */ +#define NRF_ESB_INT_RX_DATA_RECEIVED_MSK 0x04 /**< Interrupt mask value for RX_DR. */ + +#define NRF_ESB_PID_RESET_VALUE 0xFF /**< Invalid PID value which is guaranteed to not collide with any valid PID value. */ +#define NRF_ESB_PID_MAX 3 /**< Maximum value for PID. */ +#define NRF_ESB_CRC_RESET_VALUE 0xFFFF /**< CRC reset value. */ + +// Internal Enhanced ShockBurst module state. +typedef enum { + NRF_ESB_STATE_IDLE, /**< Module idle. */ + NRF_ESB_STATE_PTX_TX, /**< Module transmitting without acknowledgment. */ + NRF_ESB_STATE_PTX_TX_ACK, /**< Module transmitting with acknowledgment. */ + NRF_ESB_STATE_PTX_RX_ACK, /**< Module transmitting with acknowledgment and reception of payload with the acknowledgment response. */ + NRF_ESB_STATE_PRX, /**< Module receiving packets without acknowledgment. */ + NRF_ESB_STATE_PRX_SEND_ACK, /**< Module transmitting acknowledgment in RX mode. */ +} nrf_esb_mainstate_t; + + +#define DISABLE_RF_IRQ() NVIC_DisableIRQ(RADIO_IRQn) +#define ENABLE_RF_IRQ() NVIC_EnableIRQ(RADIO_IRQn) + +#define RADIO_SHORTS_COMMON ( RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | \ + RADIO_SHORTS_ADDRESS_RSSISTART_Msk | RADIO_SHORTS_DISABLED_RSSISTOP_Msk ) + +#define VERIFY_PAYLOAD_LENGTH(p) \ +do \ +{ \ + if (p->length == 0 || \ + p->length > NRF_ESB_MAX_PAYLOAD_LENGTH || \ + (m_config_local.protocol == NRF_ESB_PROTOCOL_ESB && \ + p->length > m_config_local.payload_length)) \ + { \ + return NRF_ERROR_INVALID_LENGTH; \ + } \ +}while (0) + + +/* @brief Structure holding pipe info PID and CRC and acknowledgment payload. */ +typedef struct +{ + uint16_t crc; /**< CRC value of the last received packet (Used to detect retransmits). */ + uint8_t pid; /**< Packet ID of the last received packet (Used to detect retransmits). */ + bool ack_payload; /**< Flag indicating the state of the transmission of acknowledgment payloads. */ +} pipe_info_t; + + +/* @brief First-in, first-out queue of payloads to be transmitted. */ +typedef struct +{ + nrf_esb_payload_t * p_payload[NRF_ESB_TX_FIFO_SIZE]; /**< Pointer to the actual queue. */ + uint32_t entry_point; /**< Current start of queue. */ + uint32_t exit_point; /**< Current end of queue. */ + uint32_t count; /**< Current number of elements in the queue. */ +} nrf_esb_payload_tx_fifo_t; + + +/* @brief First-in, first-out queue of received payloads. */ +typedef struct +{ + nrf_esb_payload_t * p_payload[NRF_ESB_RX_FIFO_SIZE]; /**< Pointer to the actual queue. */ + uint32_t entry_point; /**< Current start of queue. */ + uint32_t exit_point; /**< Current end of queue. */ + uint32_t count; /**< Current number of elements in the queue. */ +} nrf_esb_payload_rx_fifo_t; + + +/**@brief Enhanced ShockBurst address. + * + * Enhanced ShockBurst addresses consist of a base address and a prefix + * that is unique for each pipe. See @ref esb_addressing in the ESB user + * guide for more information. +*/ +typedef struct +{ + uint8_t base_addr_p0[4]; /**< Base address for pipe 0 encoded in big endian. */ + uint8_t base_addr_p1[4]; /**< Base address for pipe 1-7 encoded in big endian. */ + uint8_t pipe_prefixes[8]; /**< Address prefix for pipe 0 to 7. */ + uint8_t num_pipes; /**< Number of pipes available. */ + uint8_t addr_length; /**< Length of the address including the prefix. */ + uint8_t rx_pipes_enabled; /**< Bitfield for enabled pipes. */ + uint8_t rf_channel; /**< Channel to use (must be between 0 and 100). */ +} nrf_esb_address_t; + + +// Module state +static bool m_esb_initialized = false; +static nrf_esb_mainstate_t m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; +static nrf_esb_payload_t * mp_current_payload; + +static nrf_esb_event_handler_t m_event_handler; + +// Address parameters +static nrf_esb_address_t m_esb_addr = NRF_ESB_ADDR_DEFAULT; + +// RF parameters +static nrf_esb_config_t m_config_local; + +// TX FIFO +static nrf_esb_payload_t m_tx_fifo_payload[NRF_ESB_TX_FIFO_SIZE]; +static nrf_esb_payload_tx_fifo_t m_tx_fifo; + +// RX FIFO +static nrf_esb_payload_t m_rx_fifo_payload[NRF_ESB_RX_FIFO_SIZE]; +static nrf_esb_payload_rx_fifo_t m_rx_fifo; + +// Payload buffers +static uint8_t m_tx_payload_buffer[NRF_ESB_MAX_PAYLOAD_LENGTH + 2]; +static uint8_t m_rx_payload_buffer[NRF_ESB_MAX_PAYLOAD_LENGTH + 2]; + +// Run time variables +static volatile uint32_t m_interrupt_flags = 0; +static uint8_t m_pids[NRF_ESB_PIPE_COUNT]; +static pipe_info_t m_rx_pipe_info[NRF_ESB_PIPE_COUNT]; +static volatile uint32_t m_retransmits_remaining; +static volatile uint32_t m_last_tx_attempts; +static volatile uint32_t m_wait_for_ack_timeout_us; + +// These function pointers are changed dynamically, depending on protocol configuration and state. +static void (*on_radio_disabled)(void) = 0; +static void (*on_radio_end)(void) = 0; +static void (*update_rf_payload_format)(uint32_t payload_length) = 0; + + +// The following functions are assigned to the function pointers above. +static void on_radio_disabled_tx_noack(void); +static void on_radio_disabled_tx(void); +static void on_radio_disabled_tx_wait_for_ack(void); +static void on_radio_disabled_rx(void); +static void on_radio_disabled_rx_ack(void); + + +#define NRF_ESB_ADDR_UPDATE_MASK_BASE0 (1 << 0) /*< Mask value to signal updating BASE0 radio address. */ +#define NRF_ESB_ADDR_UPDATE_MASK_BASE1 (1 << 1) /*< Mask value to signal updating BASE1 radio address. */ +#define NRF_ESB_ADDR_UPDATE_MASK_PREFIX (1 << 2) /*< Mask value to signal updating radio prefixes. */ + + +// Function to do bytewise bit-swap on an unsigned 32-bit value +static uint32_t bytewise_bit_swap(uint8_t const * p_inp) +{ + uint32_t inp = (*(uint32_t*)p_inp); +#if __CORTEX_M == (0x04U) + return __REV((uint32_t)__RBIT(inp)); //lint -esym(628, __rev) -esym(526, __rev) -esym(628, __rbit) -esym(526, __rbit) */ +#else + inp = (inp & 0xF0F0F0F0) >> 4 | (inp & 0x0F0F0F0F) << 4; + inp = (inp & 0xCCCCCCCC) >> 2 | (inp & 0x33333333) << 2; + inp = (inp & 0xAAAAAAAA) >> 1 | (inp & 0x55555555) << 1; + return inp; +#endif +} + + +// Internal function to convert base addresses from nRF24L type addressing to nRF51 type addressing +static uint32_t addr_conv(uint8_t const* p_addr) +{ + return __REV(bytewise_bit_swap(p_addr)); //lint -esym(628, __rev) -esym(526, __rev) */ +} + + +static void update_rf_payload_format_esb_dpl(uint32_t payload_length) +{ +#if (NRF_ESB_MAX_PAYLOAD_LENGTH <= 32) + // Using 6 bits for length + NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S0LEN_Pos) | + (6 << RADIO_PCNF0_LFLEN_Pos) | + (3 << RADIO_PCNF0_S1LEN_Pos) ; +#else + // Using 8 bits for length + NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S0LEN_Pos) | + (8 << RADIO_PCNF0_LFLEN_Pos) | + (3 << RADIO_PCNF0_S1LEN_Pos) ; +#endif + NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | + (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | + ((m_esb_addr.addr_length - 1) << RADIO_PCNF1_BALEN_Pos) | + (0 << RADIO_PCNF1_STATLEN_Pos) | + (NRF_ESB_MAX_PAYLOAD_LENGTH << RADIO_PCNF1_MAXLEN_Pos); +} + + +static void update_rf_payload_format_esb(uint32_t payload_length) +{ + NRF_RADIO->PCNF0 = (1 << RADIO_PCNF0_S0LEN_Pos) | + (0 << RADIO_PCNF0_LFLEN_Pos) | + (1 << RADIO_PCNF0_S1LEN_Pos); + + NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | + (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | + ((m_esb_addr.addr_length - 1) << RADIO_PCNF1_BALEN_Pos) | + (payload_length << RADIO_PCNF1_STATLEN_Pos) | + (payload_length << RADIO_PCNF1_MAXLEN_Pos); +} + + +static void update_radio_addresses(uint8_t update_mask) +{ + if ((update_mask & NRF_ESB_ADDR_UPDATE_MASK_BASE0) != 0) + { + NRF_RADIO->BASE0 = addr_conv(m_esb_addr.base_addr_p0); + } + + if ((update_mask & NRF_ESB_ADDR_UPDATE_MASK_BASE1) != 0) + { + NRF_RADIO->BASE1 = addr_conv(m_esb_addr.base_addr_p1); + } + + if ((update_mask & NRF_ESB_ADDR_UPDATE_MASK_PREFIX) != 0) + { + NRF_RADIO->PREFIX0 = bytewise_bit_swap(&m_esb_addr.pipe_prefixes[0]); + NRF_RADIO->PREFIX1 = bytewise_bit_swap(&m_esb_addr.pipe_prefixes[4]); + } +} + + +static void update_radio_tx_power() +{ + NRF_RADIO->TXPOWER = m_config_local.tx_output_power << RADIO_TXPOWER_TXPOWER_Pos; +} + + +static void update_radio_bitrate() +{ + NRF_RADIO->MODE = m_config_local.bitrate << RADIO_MODE_MODE_Pos; + + switch (m_config_local.bitrate) + { + case NRF_ESB_BITRATE_2MBPS: + m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_2MBPS; + break; + + case NRF_ESB_BITRATE_1MBPS: + m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS; + break; + + case NRF_ESB_BITRATE_250KBPS: + m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_250KBPS; + break; + + case NRF_ESB_BITRATE_1MBPS_BLE: + m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS_BLE; + break; + + default: + // Should not be reached + break; + } +} + + +static void update_radio_protocol() +{ + switch (m_config_local.protocol) + { + case NRF_ESB_PROTOCOL_ESB_DPL: + update_rf_payload_format = update_rf_payload_format_esb_dpl; + break; + + case NRF_ESB_PROTOCOL_ESB: + update_rf_payload_format = update_rf_payload_format_esb; + break; + + default: + // Should not be reached + break; + } +} + + +static void update_radio_crc() +{ + NRF_RADIO->CRCCNF = m_config_local.crc << RADIO_CRCCNF_LEN_Pos; + + if (m_config_local.crc == RADIO_CRCCNF_LEN_Two) + { + NRF_RADIO->CRCINIT = 0xFFFFUL; // Initial value + NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16+x^12^x^5+1 + } + else if (m_config_local.crc == RADIO_CRCCNF_LEN_One) + { + NRF_RADIO->CRCINIT = 0xFFUL; // Initial value + NRF_RADIO->CRCPOLY = 0x107UL; // CRC poly: x^8+x^2^x^1+1 + } +} + + +static void update_radio_parameters() +{ + update_radio_tx_power(); + update_radio_bitrate(); + update_radio_protocol(); + update_radio_crc(); + update_rf_payload_format(m_config_local.payload_length); +} + + +static void reset_fifos() +{ + m_tx_fifo.entry_point = 0; + m_tx_fifo.exit_point = 0; + m_tx_fifo.count = 0; + + m_rx_fifo.entry_point = 0; + m_rx_fifo.exit_point = 0; + m_rx_fifo.count = 0; +} + + +static void initialize_fifos() +{ + reset_fifos(); + + for (int i = 0; i < NRF_ESB_TX_FIFO_SIZE; i++) + { + m_tx_fifo.p_payload[i] = &m_tx_fifo_payload[i]; + } + + for (int i = 0; i < NRF_ESB_RX_FIFO_SIZE; i++) + { + m_rx_fifo.p_payload[i] = &m_rx_fifo_payload[i]; + } +} + + +static void tx_fifo_remove_last() +{ + if (m_tx_fifo.count > 0) + { + DISABLE_RF_IRQ(); + + m_tx_fifo.count--; + if (++m_tx_fifo.exit_point >= NRF_ESB_TX_FIFO_SIZE) + { + m_tx_fifo.exit_point = 0; + } + + ENABLE_RF_IRQ(); + } +} + +/** @brief Function to push the content of the rx_buffer to the RX FIFO. + * + * The module will point the register NRF_RADIO->PACKETPTR to a buffer for receiving packets. + * After receiving a packet the module will call this function to copy the received data to + * the RX FIFO. + * + * @param pipe Pipe number to set for the packet. + * @param pid Packet ID. + * + * @retval true Operation successful. + * @retval false Operation failed. + */ +static bool rx_fifo_push_rfbuf(uint8_t pipe, uint8_t pid) +{ + if (m_rx_fifo.count < NRF_ESB_RX_FIFO_SIZE) + { + if (m_config_local.protocol == NRF_ESB_PROTOCOL_ESB_DPL) + { + if (m_rx_payload_buffer[0] > NRF_ESB_MAX_PAYLOAD_LENGTH) + { + return false; + } + + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->length = m_rx_payload_buffer[0]; + } + else if (m_config_local.mode == NRF_ESB_MODE_PTX) + { + // Received packet is an acknowledgment + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->length = 0; + } + else + { + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->length = m_config_local.payload_length; + } + + memcpy(m_rx_fifo.p_payload[m_rx_fifo.entry_point]->data, &m_rx_payload_buffer[2], + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->length); + + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->pipe = pipe; + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->rssi = NRF_RADIO->RSSISAMPLE; + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->pid = pid; + if (++m_rx_fifo.entry_point >= NRF_ESB_RX_FIFO_SIZE) + { + m_rx_fifo.entry_point = 0; + } + m_rx_fifo.count++; + + return true; + } + + return false; +} + + +static void sys_timer_init() +{ + // Configure the system timer with a 1 MHz base frequency + NRF_ESB_SYS_TIMER->PRESCALER = 4; + NRF_ESB_SYS_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit; + NRF_ESB_SYS_TIMER->SHORTS = TIMER_SHORTS_COMPARE1_CLEAR_Msk | TIMER_SHORTS_COMPARE1_STOP_Msk; +} + + +static void ppi_init() +{ + NRF_PPI->CH[NRF_ESB_PPI_TIMER_START].EEP = (uint32_t)&NRF_RADIO->EVENTS_READY; + NRF_PPI->CH[NRF_ESB_PPI_TIMER_START].TEP = (uint32_t)&NRF_ESB_SYS_TIMER->TASKS_START; + + NRF_PPI->CH[NRF_ESB_PPI_TIMER_STOP].EEP = (uint32_t)&NRF_RADIO->EVENTS_ADDRESS; + NRF_PPI->CH[NRF_ESB_PPI_TIMER_STOP].TEP = (uint32_t)&NRF_ESB_SYS_TIMER->TASKS_STOP; + + NRF_PPI->CH[NRF_ESB_PPI_RX_TIMEOUT].EEP = (uint32_t)&NRF_ESB_SYS_TIMER->EVENTS_COMPARE[0]; + NRF_PPI->CH[NRF_ESB_PPI_RX_TIMEOUT].TEP = (uint32_t)&NRF_RADIO->TASKS_DISABLE; + + NRF_PPI->CH[NRF_ESB_PPI_TX_START].EEP = (uint32_t)&NRF_ESB_SYS_TIMER->EVENTS_COMPARE[1]; + NRF_PPI->CH[NRF_ESB_PPI_TX_START].TEP = (uint32_t)&NRF_RADIO->TASKS_TXEN; +} + + +static void start_tx_transaction() +{ + bool ack; + + m_last_tx_attempts = 1; + // Prepare the payload + mp_current_payload = m_tx_fifo.p_payload[m_tx_fifo.exit_point]; + + + switch (m_config_local.protocol) + { + case NRF_ESB_PROTOCOL_ESB: + update_rf_payload_format(mp_current_payload->length); + m_tx_payload_buffer[0] = mp_current_payload->pid; + m_tx_payload_buffer[1] = 0; + memcpy(&m_tx_payload_buffer[2], mp_current_payload->data, mp_current_payload->length); + + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_RXEN_Msk; + NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk | RADIO_INTENSET_READY_Msk; + + // Configure the retransmit counter + m_retransmits_remaining = m_config_local.retransmit_count; + on_radio_disabled = on_radio_disabled_tx; + m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX_ACK; + break; + + case NRF_ESB_PROTOCOL_ESB_DPL: + ack = !mp_current_payload->noack || !m_config_local.selective_auto_ack; + m_tx_payload_buffer[0] = mp_current_payload->length; + m_tx_payload_buffer[1] = mp_current_payload->pid << 1; + m_tx_payload_buffer[1] |= ack ? 0x00 : 0x01; + memcpy(&m_tx_payload_buffer[2], mp_current_payload->data, mp_current_payload->length); + + // Handling ack if noack is set to false or if selective auto ack is turned off + if (ack) + { + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_RXEN_Msk; + NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk | RADIO_INTENSET_READY_Msk; + + // Configure the retransmit counter + m_retransmits_remaining = m_config_local.retransmit_count; + on_radio_disabled = on_radio_disabled_tx; + m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX_ACK; + } + else + { + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON; + NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk; + on_radio_disabled = on_radio_disabled_tx_noack; + m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX; + } + break; + + default: + // Should not be reached + break; + } + + NRF_RADIO->TXADDRESS = mp_current_payload->pipe; + NRF_RADIO->RXADDRESSES = 1 << mp_current_payload->pipe; + + NRF_RADIO->FREQUENCY = m_esb_addr.rf_channel; + NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer; + + NVIC_ClearPendingIRQ(RADIO_IRQn); + NVIC_EnableIRQ(RADIO_IRQn); + + NRF_RADIO->EVENTS_ADDRESS = 0; + NRF_RADIO->EVENTS_PAYLOAD = 0; + NRF_RADIO->EVENTS_DISABLED = 0; + + DEBUG_PIN_SET(DEBUGPIN4); + NRF_RADIO->TASKS_TXEN = 1; +} + + +static void on_radio_disabled_tx_noack() +{ + m_interrupt_flags |= NRF_ESB_INT_TX_SUCCESS_MSK; + tx_fifo_remove_last(); + + if (m_tx_fifo.count == 0) + { + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + NVIC_SetPendingIRQ(ESB_EVT_IRQ); + } + else + { + NVIC_SetPendingIRQ(ESB_EVT_IRQ); + start_tx_transaction(); + } +} + + +static void on_radio_disabled_tx() +{ + // Remove the DISABLED -> RXEN shortcut, to make sure the radio stays + // disabled after the RX window + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON; + + // Make sure the timer is started the next time the radio is ready, + // and that it will disable the radio automatically if no packet is + // received by the time defined in m_wait_for_ack_timeout_us + NRF_ESB_SYS_TIMER->CC[0] = m_wait_for_ack_timeout_us; + NRF_ESB_SYS_TIMER->CC[1] = m_config_local.retransmit_delay - 130; + NRF_ESB_SYS_TIMER->TASKS_CLEAR = 1; + NRF_ESB_SYS_TIMER->EVENTS_COMPARE[0] = 0; + NRF_ESB_SYS_TIMER->EVENTS_COMPARE[1] = 0; + + NRF_PPI->CHENSET = (1 << NRF_ESB_PPI_TIMER_START) | + (1 << NRF_ESB_PPI_RX_TIMEOUT) | + (1 << NRF_ESB_PPI_TIMER_STOP); + NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TX_START); + NRF_RADIO->EVENTS_END = 0; + + if (m_config_local.protocol == NRF_ESB_PROTOCOL_ESB) + { + update_rf_payload_format(0); + } + + NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; + on_radio_disabled = on_radio_disabled_tx_wait_for_ack; + m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_RX_ACK; +} + + +static void on_radio_disabled_tx_wait_for_ack() +{ + // This marks the completion of a TX_RX sequence (TX with ACK) + + // Make sure the timer will not deactivate the radio if a packet is received + NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TIMER_START) | + (1 << NRF_ESB_PPI_RX_TIMEOUT) | + (1 << NRF_ESB_PPI_TIMER_STOP); + + // If the radio has received a packet and the CRC status is OK + if (NRF_RADIO->EVENTS_END && NRF_RADIO->CRCSTATUS != 0) + { + NRF_ESB_SYS_TIMER->TASKS_STOP = 1; + NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TX_START); + m_interrupt_flags |= NRF_ESB_INT_TX_SUCCESS_MSK; + m_last_tx_attempts = m_config_local.retransmit_count - m_retransmits_remaining + 1; + + tx_fifo_remove_last(); + + if (m_config_local.protocol != NRF_ESB_PROTOCOL_ESB && m_rx_payload_buffer[0] > 0) + { + if (rx_fifo_push_rfbuf((uint8_t)NRF_RADIO->TXADDRESS, 0)) + { + m_interrupt_flags |= NRF_ESB_INT_RX_DATA_RECEIVED_MSK; + } + } + + if ((m_tx_fifo.count == 0) || (m_config_local.tx_mode == NRF_ESB_TXMODE_MANUAL)) + { + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + NVIC_SetPendingIRQ(ESB_EVT_IRQ); + } + else + { + NVIC_SetPendingIRQ(ESB_EVT_IRQ); + start_tx_transaction(); + } + } + else + { + if (m_retransmits_remaining-- == 0) + { + NRF_ESB_SYS_TIMER->TASKS_STOP = 1; + NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TX_START); + // All retransmits are expended, and the TX operation is suspended + m_last_tx_attempts = m_config_local.retransmit_count + 1; + m_interrupt_flags |= NRF_ESB_INT_TX_FAILED_MSK; + + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + NVIC_SetPendingIRQ(ESB_EVT_IRQ); + } + else + { + // There are still more retransmits left, TX mode should be + // entered again as soon as the system timer reaches CC[1]. + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_RXEN_Msk; + update_rf_payload_format(mp_current_payload->length); + NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer; + on_radio_disabled = on_radio_disabled_tx; + m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX_ACK; + NRF_ESB_SYS_TIMER->TASKS_START = 1; + NRF_PPI->CHENSET = (1 << NRF_ESB_PPI_TX_START); + if (NRF_ESB_SYS_TIMER->EVENTS_COMPARE[1]) + { + NRF_RADIO->TASKS_TXEN = 1; + } + } + } +} + +static void clear_events_restart_rx(void) +{ + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON; + update_rf_payload_format(m_config_local.payload_length); + NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; + NRF_RADIO->EVENTS_DISABLED = 0; + NRF_RADIO->TASKS_DISABLE = 1; + + while (NRF_RADIO->EVENTS_DISABLED == 0); + + NRF_RADIO->EVENTS_DISABLED = 0; + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_TXEN_Msk; + NRF_RADIO->TASKS_RXEN = 1; +} + +static void on_radio_disabled_rx(void) +{ + bool ack = false; + bool retransmit_payload = false; + bool send_rx_event = true; + pipe_info_t * p_pipe_info; + + if (NRF_RADIO->CRCSTATUS == 0) + { + clear_events_restart_rx(); + return; + } + + if (m_rx_fifo.count >= NRF_ESB_RX_FIFO_SIZE) + { + clear_events_restart_rx(); + return; + } + + p_pipe_info = &m_rx_pipe_info[NRF_RADIO->RXMATCH]; + if (NRF_RADIO->RXCRC == p_pipe_info->crc && + (m_rx_payload_buffer[1] >> 1) == p_pipe_info->pid + ) + { + retransmit_payload = true; + send_rx_event = false; + } + + p_pipe_info->pid = m_rx_payload_buffer[1] >> 1; + p_pipe_info->crc = NRF_RADIO->RXCRC; + + if (m_config_local.selective_auto_ack == false || ((m_rx_payload_buffer[1] & 0x01) == 0)) + { + ack = true; + } + + if (ack) + { + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_RXEN_Msk; + + switch (m_config_local.protocol) + { + case NRF_ESB_PROTOCOL_ESB_DPL: + { + if (m_tx_fifo.count > 0 && + (m_tx_fifo.p_payload[m_tx_fifo.exit_point]->pipe == NRF_RADIO->RXMATCH) + ) + { + // Pipe stays in ACK with payload until TX FIFO is empty + // Do not report TX success on first ack payload or retransmit + if (p_pipe_info->ack_payload == true && !retransmit_payload) + { + if (++m_tx_fifo.exit_point >= NRF_ESB_TX_FIFO_SIZE) + { + m_tx_fifo.exit_point = 0; + } + + m_tx_fifo.count--; + + // ACK payloads also require TX_DS + // (page 40 of the 'nRF24LE1_Product_Specification_rev1_6.pdf'). + m_interrupt_flags |= NRF_ESB_INT_TX_SUCCESS_MSK; + } + + p_pipe_info->ack_payload = true; + + mp_current_payload = m_tx_fifo.p_payload[m_tx_fifo.exit_point]; + + update_rf_payload_format(mp_current_payload->length); + m_tx_payload_buffer[0] = mp_current_payload->length; + memcpy(&m_tx_payload_buffer[2], + mp_current_payload->data, + mp_current_payload->length); + } + else + { + p_pipe_info->ack_payload = false; + update_rf_payload_format(0); + m_tx_payload_buffer[0] = 0; + } + + m_tx_payload_buffer[1] = m_rx_payload_buffer[1]; + } + break; + + case NRF_ESB_PROTOCOL_ESB: + { + update_rf_payload_format(0); + m_tx_payload_buffer[0] = m_rx_payload_buffer[0]; + m_tx_payload_buffer[1] = 0; + } + break; + } + + m_nrf_esb_mainstate = NRF_ESB_STATE_PRX_SEND_ACK; + NRF_RADIO->TXADDRESS = NRF_RADIO->RXMATCH; + NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer; + on_radio_disabled = on_radio_disabled_rx_ack; + } + else + { + clear_events_restart_rx(); + } + + if (send_rx_event) + { + // Push the new packet to the RX buffer and trigger a received event if the operation was + // successful. + if (rx_fifo_push_rfbuf(NRF_RADIO->RXMATCH, p_pipe_info->pid)) + { + m_interrupt_flags |= NRF_ESB_INT_RX_DATA_RECEIVED_MSK; + NVIC_SetPendingIRQ(ESB_EVT_IRQ); + } + } +} + + +static void on_radio_disabled_rx_ack(void) +{ + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_TXEN_Msk; + update_rf_payload_format(m_config_local.payload_length); + + NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; + on_radio_disabled = on_radio_disabled_rx; + + m_nrf_esb_mainstate = NRF_ESB_STATE_PRX; +} + + +/**@brief Function for clearing pending interrupts. + * + * @param[in,out] p_interrupts Pointer to the value that holds the current interrupts. + * + * @retval NRF_SUCCESS If the interrupts were cleared successfully. + * @retval NRF_ERROR_NULL If the required parameter was NULL. + * @retval NRF_INVALID_STATE If the module is not initialized. + */ +static uint32_t nrf_esb_get_clear_interrupts(uint32_t * p_interrupts) +{ + VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE); + VERIFY_PARAM_NOT_NULL(p_interrupts); + + DISABLE_RF_IRQ(); + + *p_interrupts = m_interrupt_flags; + m_interrupt_flags = 0; + + ENABLE_RF_IRQ(); + + return NRF_SUCCESS; +} + + +void RADIO_IRQHandler() +{ + if (NRF_RADIO->EVENTS_READY && (NRF_RADIO->INTENSET & RADIO_INTENSET_READY_Msk)) + { + NRF_RADIO->EVENTS_READY = 0; + DEBUG_PIN_SET(DEBUGPIN1); + } + + if (NRF_RADIO->EVENTS_END && (NRF_RADIO->INTENSET & RADIO_INTENSET_END_Msk)) + { + NRF_RADIO->EVENTS_END = 0; + DEBUG_PIN_SET(DEBUGPIN2); + + // Call the correct on_radio_end function, depending on the current protocol state + if (on_radio_end) + { + on_radio_end(); + } + } + + if (NRF_RADIO->EVENTS_DISABLED && (NRF_RADIO->INTENSET & RADIO_INTENSET_DISABLED_Msk)) + { + NRF_RADIO->EVENTS_DISABLED = 0; + DEBUG_PIN_SET(DEBUGPIN3); + + // Call the correct on_radio_disable function, depending on the current protocol state + if (on_radio_disabled) + { + on_radio_disabled(); + } + } + + DEBUG_PIN_CLR(DEBUGPIN1); + DEBUG_PIN_CLR(DEBUGPIN2); + DEBUG_PIN_CLR(DEBUGPIN3); + DEBUG_PIN_CLR(DEBUGPIN4); +} + + +uint32_t nrf_esb_init(nrf_esb_config_t const * p_config) +{ + uint32_t err_code; + + VERIFY_PARAM_NOT_NULL(p_config); + + if (m_esb_initialized) + { + err_code = nrf_esb_disable(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + m_event_handler = p_config->event_handler; + + memcpy(&m_config_local, p_config, sizeof(nrf_esb_config_t)); + + m_interrupt_flags = 0; + + memset(m_rx_pipe_info, 0, sizeof(m_rx_pipe_info)); + memset(m_pids, 0, sizeof(m_pids)); + + update_radio_parameters(); + + initialize_fifos(); + + sys_timer_init(); + + ppi_init(); + + NVIC_SetPriority(RADIO_IRQn, m_config_local.radio_irq_priority & 0x03); + NVIC_SetPriority(ESB_EVT_IRQ, m_config_local.event_irq_priority & 0x03); + NVIC_EnableIRQ(ESB_EVT_IRQ); + + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + m_esb_initialized = true; + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_suspend(void) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + + // Clear PPI + NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TIMER_START) | + (1 << NRF_ESB_PPI_TIMER_STOP) | + (1 << NRF_ESB_PPI_RX_TIMEOUT) | + (1 << NRF_ESB_PPI_TX_START); + + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_disable(void) +{ + // Clear PPI + NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TIMER_START) | + (1 << NRF_ESB_PPI_TIMER_STOP) | + (1 << NRF_ESB_PPI_RX_TIMEOUT) | + (1 << NRF_ESB_PPI_TX_START); + + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + + reset_fifos(); + + memset(m_rx_pipe_info, 0, sizeof(m_rx_pipe_info)); + memset(m_pids, 0, sizeof(m_pids)); + + // Disable the radio + NVIC_DisableIRQ(ESB_EVT_IRQ); + NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos | + RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos; + + return NRF_SUCCESS; +} + + +bool nrf_esb_is_idle(void) +{ + return m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE; +} + + +void ESB_EVT_IRQHandler(void) +{ + ret_code_t err_code; + uint32_t interrupts; + nrf_esb_evt_t event; + + event.tx_attempts = m_last_tx_attempts; + + err_code = nrf_esb_get_clear_interrupts(&interrupts); + if (err_code == NRF_SUCCESS && m_event_handler != 0) + { + if (interrupts & NRF_ESB_INT_TX_SUCCESS_MSK) + { + event.evt_id = NRF_ESB_EVENT_TX_SUCCESS; + m_event_handler(&event); + } + if (interrupts & NRF_ESB_INT_TX_FAILED_MSK) + { + event.evt_id = NRF_ESB_EVENT_TX_FAILED; + m_event_handler(&event); + } + if (interrupts & NRF_ESB_INT_RX_DATA_RECEIVED_MSK) + { + event.evt_id = NRF_ESB_EVENT_RX_RECEIVED; + m_event_handler(&event); + } + } +} + +uint32_t nrf_esb_write_payload(nrf_esb_payload_t const * p_payload) +{ + VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE); + VERIFY_PARAM_NOT_NULL(p_payload); + VERIFY_PAYLOAD_LENGTH(p_payload); + VERIFY_FALSE(m_tx_fifo.count >= NRF_ESB_TX_FIFO_SIZE, NRF_ERROR_NO_MEM); + + if (m_config_local.mode == NRF_ESB_MODE_PTX && + p_payload->noack && !m_config_local.selective_auto_ack ) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + DISABLE_RF_IRQ(); + + memcpy(m_tx_fifo.p_payload[m_tx_fifo.entry_point], p_payload, sizeof(nrf_esb_payload_t)); + + m_pids[p_payload->pipe] = (m_pids[p_payload->pipe] + 1) % (NRF_ESB_PID_MAX + 1); + m_tx_fifo.p_payload[m_tx_fifo.entry_point]->pid = m_pids[p_payload->pipe]; + + if (++m_tx_fifo.entry_point >= NRF_ESB_TX_FIFO_SIZE) + { + m_tx_fifo.entry_point = 0; + } + + m_tx_fifo.count++; + + ENABLE_RF_IRQ(); + + + if (m_config_local.mode == NRF_ESB_MODE_PTX && + m_config_local.tx_mode == NRF_ESB_TXMODE_AUTO && + m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE) + { + start_tx_transaction(); + } + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_read_rx_payload(nrf_esb_payload_t * p_payload) +{ + VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE); + VERIFY_PARAM_NOT_NULL(p_payload); + + if (m_rx_fifo.count == 0) + { + return NRF_ERROR_NOT_FOUND; + } + + DISABLE_RF_IRQ(); + + p_payload->length = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->length; + p_payload->pipe = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->pipe; + p_payload->rssi = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->rssi; + p_payload->pid = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->pid; + memcpy(p_payload->data, m_rx_fifo.p_payload[m_rx_fifo.exit_point]->data, p_payload->length); + + if (++m_rx_fifo.exit_point >= NRF_ESB_RX_FIFO_SIZE) + { + m_rx_fifo.exit_point = 0; + } + + m_rx_fifo.count--; + + ENABLE_RF_IRQ(); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_start_tx(void) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + + if (m_tx_fifo.count == 0) + { + return NRF_ERROR_BUFFER_EMPTY; + } + + start_tx_transaction(); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_start_rx(void) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + + NRF_RADIO->INTENCLR = 0xFFFFFFFF; + NRF_RADIO->EVENTS_DISABLED = 0; + on_radio_disabled = on_radio_disabled_rx; + + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_TXEN_Msk; + NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk; + m_nrf_esb_mainstate = NRF_ESB_STATE_PRX; + + NRF_RADIO->RXADDRESSES = m_esb_addr.rx_pipes_enabled; + NRF_RADIO->FREQUENCY = m_esb_addr.rf_channel; + NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; + + NVIC_ClearPendingIRQ(RADIO_IRQn); + NVIC_EnableIRQ(RADIO_IRQn); + + NRF_RADIO->EVENTS_ADDRESS = 0; + NRF_RADIO->EVENTS_PAYLOAD = 0; + NRF_RADIO->EVENTS_DISABLED = 0; + + NRF_RADIO->TASKS_RXEN = 1; + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_stop_rx(void) +{ + if (m_nrf_esb_mainstate == NRF_ESB_STATE_PRX) + { + NRF_RADIO->SHORTS = 0; + NRF_RADIO->INTENCLR = 0xFFFFFFFF; + on_radio_disabled = NULL; + NRF_RADIO->EVENTS_DISABLED = 0; + NRF_RADIO->TASKS_DISABLE = 1; + while (NRF_RADIO->EVENTS_DISABLED == 0); + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + + return NRF_SUCCESS; + } + + return NRF_ESB_ERROR_NOT_IN_RX_MODE; +} + + +uint32_t nrf_esb_flush_tx(void) +{ + VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE); + + DISABLE_RF_IRQ(); + + m_tx_fifo.count = 0; + m_tx_fifo.entry_point = 0; + m_tx_fifo.exit_point = 0; + + ENABLE_RF_IRQ(); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_pop_tx(void) +{ + VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE); + VERIFY_TRUE(m_tx_fifo.count > 0, NRF_ERROR_BUFFER_EMPTY); + + DISABLE_RF_IRQ(); + + if (++m_tx_fifo.entry_point >= NRF_ESB_TX_FIFO_SIZE) + { + m_tx_fifo.entry_point = 0; + } + m_tx_fifo.count--; + + ENABLE_RF_IRQ(); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_flush_rx(void) +{ + VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE); + + DISABLE_RF_IRQ(); + + m_rx_fifo.count = 0; + m_rx_fifo.entry_point = 0; + m_rx_fifo.exit_point = 0; + + memset(m_rx_pipe_info, 0, sizeof(m_rx_pipe_info)); + + ENABLE_RF_IRQ(); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_set_address_length(uint8_t length) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + VERIFY_TRUE(length > 2 && length < 6, NRF_ERROR_INVALID_PARAM); + + m_esb_addr.addr_length = length; + + update_rf_payload_format(m_config_local.payload_length); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_set_base_address_0(uint8_t const * p_addr) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + VERIFY_PARAM_NOT_NULL(p_addr); + + memcpy(m_esb_addr.base_addr_p0, p_addr, 4); + + update_radio_addresses(NRF_ESB_ADDR_UPDATE_MASK_BASE0); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_set_base_address_1(uint8_t const * p_addr) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + VERIFY_PARAM_NOT_NULL(p_addr); + + memcpy(m_esb_addr.base_addr_p1, p_addr, 4); + + update_radio_addresses(NRF_ESB_ADDR_UPDATE_MASK_BASE1); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_set_prefixes(uint8_t const * p_prefixes, uint8_t num_pipes) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + VERIFY_PARAM_NOT_NULL(p_prefixes); + VERIFY_TRUE(num_pipes < 9, NRF_ERROR_INVALID_PARAM); + + memcpy(m_esb_addr.pipe_prefixes, p_prefixes, num_pipes); + m_esb_addr.num_pipes = num_pipes; + m_esb_addr.rx_pipes_enabled = BIT_MASK_UINT_8(num_pipes); + + update_radio_addresses(NRF_ESB_ADDR_UPDATE_MASK_PREFIX); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_update_prefix(uint8_t pipe, uint8_t prefix) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + VERIFY_TRUE(pipe < 8, NRF_ERROR_INVALID_PARAM); + + m_esb_addr.pipe_prefixes[pipe] = prefix; + + update_radio_addresses(NRF_ESB_ADDR_UPDATE_MASK_PREFIX); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_enable_pipes(uint8_t enable_mask) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + + m_esb_addr.rx_pipes_enabled = enable_mask; + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_set_rf_channel(uint32_t channel) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + VERIFY_TRUE(channel <= 100, NRF_ERROR_INVALID_PARAM); + + m_esb_addr.rf_channel = channel; + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_get_rf_channel(uint32_t * p_channel) +{ + VERIFY_PARAM_NOT_NULL(p_channel); + + *p_channel = m_esb_addr.rf_channel; + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_set_tx_power(nrf_esb_tx_power_t tx_output_power) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + + if ( m_config_local.tx_output_power != tx_output_power ) + { + m_config_local.tx_output_power = tx_output_power; + update_radio_tx_power(); + } + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/esb/nrf_esb.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/esb/nrf_esb.h new file mode 100644 index 0000000000000000000000000000000000000000..a1e6aa6653194a324d7b4ac392404a531e567cc9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/esb/nrf_esb.h @@ -0,0 +1,525 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef __NRF_ESB_H +#define __NRF_ESB_H + +#include +#include +#include "nrf.h" +#include "app_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup nrf_esb Enhanced ShockBurst + * @{ + * @ingroup proprietary_api + * + * @brief Enhanced ShockBurst (ESB) is a basic protocol that supports two-way data + * packet communication including packet buffering, packet acknowledgment, + * and automatic retransmission of lost packets. + */ + +#define DEBUGPIN1 12 +#define DEBUGPIN2 13 +#define DEBUGPIN3 14 +#define DEBUGPIN4 15 + + +#ifdef NRF_ESB_DEBUG +#define DEBUG_PIN_SET(a) (NRF_GPIO->OUTSET = (1 << (a))) +#define DEBUG_PIN_CLR(a) (NRF_GPIO->OUTCLR = (1 << (a))) +#else +#define DEBUG_PIN_SET(a) +#define DEBUG_PIN_CLR(a) +#endif + + +// Hardcoded parameters - change if necessary +#ifndef NRF_ESB_MAX_PAYLOAD_LENGTH +#define NRF_ESB_MAX_PAYLOAD_LENGTH 32 /**< The maximum size of the payload. Valid values are 1 to 252. */ +#endif + +#define NRF_ESB_TX_FIFO_SIZE 8 /**< The size of the transmission first-in, first-out buffer. */ +#define NRF_ESB_RX_FIFO_SIZE 8 /**< The size of the reception first-in, first-out buffer. */ + +// 252 is the largest possible payload size according to the nRF5 architecture. +STATIC_ASSERT(NRF_ESB_MAX_PAYLOAD_LENGTH <= 252); + +#define NRF_ESB_SYS_TIMER NRF_TIMER2 /**< The timer that is used by the module. */ +#define NRF_ESB_SYS_TIMER_IRQ_Handler TIMER2_IRQHandler /**< The handler that is used by @ref NRF_ESB_SYS_TIMER. */ + +#define NRF_ESB_PPI_TIMER_START 10 /**< The PPI channel used for timer start. */ +#define NRF_ESB_PPI_TIMER_STOP 11 /**< The PPI channel used for timer stop. */ +#define NRF_ESB_PPI_RX_TIMEOUT 12 /**< The PPI channel used for RX time-out. */ +#define NRF_ESB_PPI_TX_START 13 /**< The PPI channel used for starting TX. */ + +// Interrupt flags +#define NRF_ESB_INT_TX_SUCCESS_MSK 0x01 /**< The flag used to indicate a success since the last event. */ +#define NRF_ESB_INT_TX_FAILED_MSK 0x02 /**< The flag used to indicate a failure since the last event. */ +#define NRF_ESB_INT_RX_DR_MSK 0x04 /**< The flag used to indicate that a packet was received since the last event. */ + +#define NRF_ESB_PID_RESET_VALUE 0xFF /**< Invalid PID value that is guaranteed to not collide with any valid PID value. */ +#define NRF_ESB_PID_MAX 3 /**< The maximum value for PID. */ +#define NRF_ESB_CRC_RESET_VALUE 0xFFFF /**< The CRC reset value. */ + +#define ESB_EVT_IRQ SWI0_IRQn /**< The ESB event IRQ number when running on an nRF5x device. */ +#define ESB_EVT_IRQHandler SWI0_IRQHandler /**< The handler for @ref ESB_EVT_IRQ when running on an nRF5x device. */ + +/** Default address configuration for ESB. Roughly equal to the nRF24Lxx default (except for the number of pipes, because more pipes are supported). */ +#define NRF_ESB_ADDR_DEFAULT \ +{ \ + .base_addr_p0 = { 0xE7, 0xE7, 0xE7, 0xE7 }, \ + .base_addr_p1 = { 0xC2, 0xC2, 0xC2, 0xC2 }, \ + .pipe_prefixes = { 0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8 }, \ + .addr_length = 5, \ + .num_pipes = 8, \ + .rf_channel = 2, \ + .rx_pipes_enabled = 0xFF \ +} + + +/** Default radio parameters. Roughly equal to the nRF24Lxx default parameters (except for CRC, which is set to 16 bit, and protocol, which is set to DPL). */ +#define NRF_ESB_DEFAULT_CONFIG {.protocol = NRF_ESB_PROTOCOL_ESB_DPL, \ + .mode = NRF_ESB_MODE_PTX, \ + .event_handler = 0, \ + .bitrate = NRF_ESB_BITRATE_2MBPS, \ + .crc = NRF_ESB_CRC_16BIT, \ + .tx_output_power = NRF_ESB_TX_POWER_0DBM, \ + .retransmit_delay = 250, \ + .retransmit_count = 3, \ + .tx_mode = NRF_ESB_TXMODE_AUTO, \ + .radio_irq_priority = 1, \ + .event_irq_priority = 2, \ + .payload_length = 32, \ + .selective_auto_ack = false \ +} + + +/** Default legacy radio parameters, identical to the nRF24Lxx defaults. */ +#define NRF_ESB_LEGACY_CONFIG {.protocol = NRF_ESB_PROTOCOL_ESB, \ + .mode = NRF_ESB_MODE_PTX, \ + .event_handler = 0, \ + .bitrate = NRF_ESB_BITRATE_2MBPS, \ + .crc = NRF_ESB_CRC_8BIT, \ + .tx_output_power = NRF_ESB_TX_POWER_0DBM, \ + .retransmit_delay = 600, \ + .retransmit_count = 3, \ + .tx_mode = NRF_ESB_TXMODE_AUTO, \ + .radio_irq_priority = 1, \ + .event_irq_priority = 2, \ + .payload_length = 32, \ + .selective_auto_ack = false \ +} + + +/**Macro to create an initializer for a TX data packet. + * + * @details This macro generates an initializer. Using the initializer is more efficient + * than setting the individual parameters dynamically. + * + * @param[in] _pipe The pipe to use for the data packet. + * @param[in] ... Comma separated list of character data to put in the TX buffer. + * Supported values consist of 1 to 63 characters. + * + * @return Initializer that sets up the pipe, length, and byte array for content of the TX data. + */ +#define NRF_ESB_CREATE_PAYLOAD(_pipe, ...) \ + {.pipe = _pipe, .length = NUM_VA_ARGS(__VA_ARGS__), .data = {__VA_ARGS__}}; \ + STATIC_ASSERT(NUM_VA_ARGS(__VA_ARGS__) > 0 && NUM_VA_ARGS(__VA_ARGS__) <= 63) + + +/**@brief Enhanced ShockBurst protocols. */ +typedef enum { + NRF_ESB_PROTOCOL_ESB, /*< Enhanced ShockBurst with fixed payload length. */ + NRF_ESB_PROTOCOL_ESB_DPL /*< Enhanced ShockBurst with dynamic payload length. */ +} nrf_esb_protocol_t; + + +/**@brief Enhanced ShockBurst modes. */ +typedef enum { + NRF_ESB_MODE_PTX, /*< Primary transmitter mode. */ + NRF_ESB_MODE_PRX /*< Primary receiver mode. */ +} nrf_esb_mode_t; + + +/**@brief Enhanced ShockBurst bitrate modes. */ +typedef enum { + NRF_ESB_BITRATE_2MBPS = RADIO_MODE_MODE_Nrf_2Mbit, /**< 2 Mb radio mode. */ + NRF_ESB_BITRATE_1MBPS = RADIO_MODE_MODE_Nrf_1Mbit, /**< 1 Mb radio mode. */ + NRF_ESB_BITRATE_250KBPS = RADIO_MODE_MODE_Nrf_250Kbit, /**< 250 Kb radio mode. */ + NRF_ESB_BITRATE_1MBPS_BLE = RADIO_MODE_MODE_Ble_1Mbit /**< 1 Mb radio mode using @e Bluetooth low energy radio parameters. */ +} nrf_esb_bitrate_t; + + +/**@brief Enhanced ShockBurst CRC modes. */ +typedef enum { + NRF_ESB_CRC_16BIT = RADIO_CRCCNF_LEN_Two, /**< Use two-byte CRC. */ + NRF_ESB_CRC_8BIT = RADIO_CRCCNF_LEN_One, /**< Use one-byte CRC. */ + NRF_ESB_CRC_OFF = RADIO_CRCCNF_LEN_Disabled /**< Disable CRC. */ +} nrf_esb_crc_t; + + +/**@brief Enhanced ShockBurst radio transmission power modes. */ +typedef enum { + NRF_ESB_TX_POWER_4DBM = RADIO_TXPOWER_TXPOWER_Pos4dBm, /**< 4 dBm radio transmit power. */ + NRF_ESB_TX_POWER_0DBM = RADIO_TXPOWER_TXPOWER_0dBm, /**< 0 dBm radio transmit power. */ + NRF_ESB_TX_POWER_NEG4DBM = RADIO_TXPOWER_TXPOWER_Neg4dBm, /**< -4 dBm radio transmit power. */ + NRF_ESB_TX_POWER_NEG8DBM = RADIO_TXPOWER_TXPOWER_Neg8dBm, /**< -8 dBm radio transmit power. */ + NRF_ESB_TX_POWER_NEG12DBM = RADIO_TXPOWER_TXPOWER_Neg12dBm, /**< -12 dBm radio transmit power. */ + NRF_ESB_TX_POWER_NEG16DBM = RADIO_TXPOWER_TXPOWER_Neg16dBm, /**< -16 dBm radio transmit power. */ + NRF_ESB_TX_POWER_NEG20DBM = RADIO_TXPOWER_TXPOWER_Neg20dBm, /**< -20 dBm radio transmit power. */ + NRF_ESB_TX_POWER_NEG30DBM = RADIO_TXPOWER_TXPOWER_Neg30dBm /**< -30 dBm radio transmit power. */ +} nrf_esb_tx_power_t; + + +/**@brief Enhanced ShockBurst transmission modes. */ +typedef enum { + NRF_ESB_TXMODE_AUTO, /*< Automatic TX mode: When the TX FIFO contains packets and the radio is idle, packets are sent automatically. */ + NRF_ESB_TXMODE_MANUAL, /*< Manual TX mode: Packets are not sent until @ref nrf_esb_start_tx is called. This mode can be used to ensure consistent packet timing. */ + NRF_ESB_TXMODE_MANUAL_START /*< Manual start TX mode: Packets are not sent until @ref nrf_esb_start_tx is called. Then, transmission continues automatically until the TX FIFO is empty. */ +} nrf_esb_tx_mode_t; + + +/**@brief Enhanced ShockBurst event IDs used to indicate the type of the event. */ +typedef enum +{ + NRF_ESB_EVENT_TX_SUCCESS, /**< Event triggered on TX success. */ + NRF_ESB_EVENT_TX_FAILED, /**< Event triggered on TX failure. */ + NRF_ESB_EVENT_RX_RECEIVED /**< Event triggered on RX received. */ +} nrf_esb_evt_id_t; + + +/**@brief Enhanced ShockBurst payload. + * + * @details The payload is used both for transmissions and for acknowledging a + * received packet with a payload. +*/ +typedef struct +{ + uint8_t length; /**< Length of the packet (maximum value is NRF_ESB_MAX_PAYLOAD_LENGTH). */ + uint8_t pipe; /**< Pipe used for this payload. */ + int8_t rssi; /**< RSSI for the received packet. */ + uint8_t noack; /**< Flag indicating that this packet will not be acknowledged. */ + uint8_t pid; /**< PID assigned during communication. */ + uint8_t data[NRF_ESB_MAX_PAYLOAD_LENGTH]; /**< The payload data. */ +} nrf_esb_payload_t; + + +/**@brief Enhanced ShockBurst event. */ +typedef struct +{ + nrf_esb_evt_id_t evt_id; /**< Enhanced ShockBurst event ID. */ + uint32_t tx_attempts; /**< Number of TX retransmission attempts. */ +} nrf_esb_evt_t; + + +/**@brief Definition of the event handler for the module. */ +typedef void (* nrf_esb_event_handler_t)(nrf_esb_evt_t const * p_event); + + +/**@brief Main configuration structure for the module. */ +typedef struct +{ + nrf_esb_protocol_t protocol; /**< Enhanced ShockBurst protocol. */ + nrf_esb_mode_t mode; /**< Enhanced ShockBurst mode. */ + nrf_esb_event_handler_t event_handler; /**< Enhanced ShockBurst event handler. */ + + // General RF parameters + nrf_esb_bitrate_t bitrate; /**< Enhanced ShockBurst bitrate mode. */ + nrf_esb_crc_t crc; /**< Enhanced ShockBurst CRC modes. */ + + nrf_esb_tx_power_t tx_output_power; /**< Enhanced ShockBurst radio transmission power mode.*/ + + uint16_t retransmit_delay; /**< The delay between each retransmission of unacknowledged packets. */ + uint16_t retransmit_count; /**< The number of retransmissions attempts before transmission fail. */ + + // Control settings + nrf_esb_tx_mode_t tx_mode; /**< Enhanced ShockBurst transmission mode. */ + + uint8_t radio_irq_priority; /**< nRF radio interrupt priority. */ + uint8_t event_irq_priority; /**< ESB event interrupt priority. */ + uint8_t payload_length; /**< Length of the payload (maximum length depends on the platforms that are used on each side). */ + + bool selective_auto_ack; /**< Enable or disable selective auto acknowledgment. */ +} nrf_esb_config_t; + + +/**@brief Function for initializing the Enhanced ShockBurst module. + * + * @param p_config Parameters for initializing the module. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_NULL If the @p p_config argument was NULL. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_init(nrf_esb_config_t const * p_config); + + +/**@brief Function for suspending the Enhanced ShockBurst module. + * + * Calling this function stops ongoing communications without changing the queues. + * + * @retval NRF_SUCCESS If Enhanced ShockBurst was suspended. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_suspend(void); + + +/**@brief Function for disabling the Enhanced ShockBurst module. + * + * Calling this function disables the Enhanced ShockBurst module immediately. + * Doing so might stop ongoing communications. + * + * @note All queues are flushed by this function. + * + * @retval NRF_SUCCESS If Enhanced ShockBurst was disabled. + */ +uint32_t nrf_esb_disable(void); + + +/**@brief Function for checking if the Enhanced ShockBurst module is idle. + * + * @retval true If the module is idle. + * @retval false If the module is busy. + */ +bool nrf_esb_is_idle(void); + + +/**@brief Function for writing a payload for transmission or acknowledgment. + * + * This function writes a payload that is added to the queue. When the module is in PTX mode, the + * payload is queued for a regular transmission. When the module is in PRX mode, the payload + * is queued for when a packet is received that requires an acknowledgment with payload. + * + * @param[in] p_payload Pointer to the structure that contains information and state of the payload. + * + * @retval NRF_SUCCESS If the payload was successfully queued for writing. + * @retval NRF_ERROR_NULL If the required parameter was NULL. + * @retval NRF_INVALID_STATE If the module is not initialized. + * @retval NRF_ERROR_NOT_SUPPORTED If @p p_payload->noack was false, but selective acknowledgment is not enabled. + * @retval NRF_ERROR_NO_MEM If the TX FIFO is full. + * @retval NRF_ERROR_INVALID_LENGTH If the payload length was invalid (zero or larger than the allowed maximum). + */ +uint32_t nrf_esb_write_payload(nrf_esb_payload_t const * p_payload); + + +/**@brief Function for reading an RX payload. + * + * @param[in,out] p_payload Pointer to the structure that contains information and state of the payload. + * + * @retval NRF_SUCCESS If the data was read successfully. + * @retval NRF_ERROR_NULL If the required parameter was NULL. + * @retval NRF_INVALID_STATE If the module is not initialized. + */ +uint32_t nrf_esb_read_rx_payload(nrf_esb_payload_t * p_payload); + + +/**@brief Function for starting transmission. + * + * @retval NRF_SUCCESS If the TX started successfully. + * @retval NRF_ERROR_BUFFER_EMPTY If the TX does not start because the FIFO buffer is empty. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_start_tx(void); + + +/**@brief Function for starting to transmit data from the FIFO buffer. + * + * @retval NRF_SUCCESS If the transmission was started successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_start_rx(void); + + +/** @brief Function for stopping data reception. + * + * @retval NRF_SUCCESS If data reception was stopped successfully. + * @retval NRF_ESB_ERROR_NOT_IN_RX_MODE If the function failed because the module is not in RX mode. + */ +uint32_t nrf_esb_stop_rx(void); + + +/**@brief Function for removing remaining items from the TX buffer. + * + * This function clears the TX FIFO buffer. + * + * @retval NRF_SUCCESS If pending items in the TX buffer were successfully cleared. + * @retval NRF_INVALID_STATE If the module is not initialized. + */ +uint32_t nrf_esb_flush_tx(void); + + +/**@brief Function for removing the first item from the TX buffer. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_INVALID_STATE If the module is not initialized. + * @retval NRF_ERROR_BUFFER_EMPTY If there are no items in the queue to remove. + */ +uint32_t nrf_esb_pop_tx(void); + + +/**@brief Function for removing remaining items from the RX buffer. + * + * @retval NRF_SUCCESS If the pending items in the RX buffer were successfully cleared. + * @retval NRF_INVALID_STATE If the module is not initialized. + */ +uint32_t nrf_esb_flush_rx(void); + + + +/**@brief Function for setting the length of the address. + * + * @param[in] length Length of the ESB address (in bytes). + * + * @retval NRF_SUCCESS If the address length was set successfully. + * @retval NRF_ERROR_INVALID_PARAM If the address length was invalid. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_set_address_length(uint8_t length); + + +/**@brief Function for setting the base address for pipe 0. + * + * @param[in] p_addr Pointer to the address data. + * + * @retval NRF_SUCCESS If the base address was set successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + * @retval NRF_ERROR_NULL If the required parameter was NULL. + */ +uint32_t nrf_esb_set_base_address_0(uint8_t const * p_addr); + + +/**@brief Function for setting the base address for pipe 1 to pipe 7. + * + * @param[in] p_addr Pointer to the address data. + * + * @retval NRF_SUCCESS If the base address was set successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + * @retval NRF_ERROR_NULL If the required parameter was NULL. + */ +uint32_t nrf_esb_set_base_address_1(uint8_t const * p_addr); + + +/**@brief Function for setting the number of pipes and the pipe prefix addresses. + * + * This function configures the number of available pipes, enables the pipes, + * and sets their prefix addresses. + * + * @param[in] p_prefixes Pointer to a char array that contains the prefix for each pipe. + * @param[in] num_pipes Number of pipes. + * + * @retval NRF_SUCCESS If the prefix addresses were set successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + * @retval NRF_ERROR_NULL If a required parameter was NULL. + * @retval NRF_ERROR_INVALID_PARAM If an invalid number of pipes was given. + */ +uint32_t nrf_esb_set_prefixes(uint8_t const * p_prefixes, uint8_t num_pipes); + + +/**@brief Function for enabling pipes. + * + * The @p enable_mask parameter must contain the same number of pipes as has been configured + * with @ref nrf_esb_set_prefixes. + * + * @param enable_mask Bitfield mask to enable or disable pipes. Setting a bit to + * 0 disables the pipe. Setting a bit to 1 enables the pipe. + * + * @retval NRF_SUCCESS If the pipes were enabled and disabled successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_enable_pipes(uint8_t enable_mask); + + +/**@brief Function for updating the prefix for a pipe. + * + * @param pipe Pipe for which to set the prefix. + * @param prefix Prefix to set for the pipe. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + * @retval NRF_ERROR_INVALID_PARAM If the given pipe number was invalid. + */ +uint32_t nrf_esb_update_prefix(uint8_t pipe, uint8_t prefix); + + +/** @brief Function for setting the channel to use for the radio. + * + * The module must be in an idle state to call this function. As a PTX, the + * application must wait for an idle state and as a PRX, the application must stop RX + * before changing the channel. After changing the channel, operation can be resumed. + * + * @param[in] channel Channel to use for radio. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_INVALID_STATE If the module is not initialized. + * @retval NRF_ERROR_BUSY If the module was not in idle state. + * @retval NRF_ERROR_INVALID_PARAM If the channel is invalid (larger than 100). + */ +uint32_t nrf_esb_set_rf_channel(uint32_t channel); + + +/**@brief Function for getting the current radio channel. + * + * @param[in, out] p_channel Pointer to the channel data. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_ERROR_NULL If the required parameter was NULL. + */ +uint32_t nrf_esb_get_rf_channel(uint32_t * p_channel); + + +/**@brief Function for setting the radio output power. + * + * @param[in] tx_output_power Output power. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_set_tx_power(nrf_esb_tx_power_t tx_output_power); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_ESB diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/esb/nrf_esb_error_codes.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/esb/nrf_esb_error_codes.h new file mode 100644 index 0000000000000000000000000000000000000000..c594151ce3c3f4495c63603865147a6dbd33a8a3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/esb/nrf_esb_error_codes.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef __NRF_ESB_ERROR_CODES_H__ +#define __NRF_ESB_ERROR_CODES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_ERROR_BUFFER_EMPTY (0x0100) + +#define NRF_ESB_ERROR_NOT_IN_RX_MODE (0x0101) + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/esb/nrf_esb_resources.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/esb/nrf_esb_resources.h new file mode 100644 index 0000000000000000000000000000000000000000..dc065097f9763ad91383fe505b7dc05421dd559e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/esb/nrf_esb_resources.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_ESB_RESOURCES_H__ +#define NRF_ESB_RESOURCES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_esb_resources ESB resources + * @{ + * @ingroup nrf_esb + */ + +#ifndef ESB_ALTERNATIVE_RESOURCES + #define ESB_PPI_CHANNELS_USED 0x00000007uL /**< PPI channels used by ESB (not available to the application). */ + #define ESB_TIMERS_USED 0x00000004uL /**< Timers used by ESB. */ + #define ESB_SWI_USED 0x00000001uL /**< Software interrupts used by ESB. */ +#else + #define ESB_PPI_CHANNELS_USED 0x00000700uL /**< PPI channels used by ESB (not available to the application). */ + #define ESB_TIMERS_USED 0x00000001uL /**< Timers used by ESB. */ + #define ESB_SWI_USED 0x00000002uL /**< Software interrupts used by ESB. */ +#endif + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_ESB_RESOURCES_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/arm/license.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/arm/license.txt new file mode 100644 index 0000000000000000000000000000000000000000..3a9e590c211963568f2b56f761aa7253760e3ab9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/arm/license.txt @@ -0,0 +1,37 @@ +Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + +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, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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 Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/config/nrf_gzp_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/config/nrf_gzp_config.h new file mode 100644 index 0000000000000000000000000000000000000000..f6398213d8a8e841c360e3de7a95af9fb968dcb6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/config/nrf_gzp_config.h @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2008 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef __GZP_CONFIG_H +#define __GZP_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Definition of "secret key" used during "Host ID exchange". + */ + +#define GZP_SECRET_KEY {1, 23, 45, 57, 26, 68, 12, 64, 13, 73, 13, 62, 26, 45, 12, 77} + +//----------------------------------------------------------------------------- + +/** + Definition of the first static selected pairing channel. Should be located in + the lower Nth of the channel range, where N is the size if the channel subset + selected by the application. +*/ +#define GZP_CHANNEL_LOW 2 + +/** + Definition of the second static selected pairing channel. Should be located in + the upper Nth of the channel range, where N is the size if the channel subset + selected by the application. +*/ +#define GZP_CHANNEL_HIGH 79 + +/** + Definition of the static "global" pairing address. +*/ +#define GZP_ADDRESS 4, 6, 8, 10 + +/** + Reduced TX power for use during close proximity pairing. + */ +#define GZP_POWER NRF_GZLL_TX_POWER_N16_DBM + +/** + Definition of pairing request timeout. +*/ +#define GZP_REQ_TX_TIMEOUT 200 + +/** + Definition of the maximimum number of "backoff" packets (step 0) to be transmitted. +*/ +#define GZP_MAX_BACKOFF_PACKETS 100 + +/** + Definition of the period a device shall wait before attempting to send the packet for + fetching the pairing response (step 1). +*/ +#define GZP_TX_ACK_WAIT_TIMEOUT (GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT + 50) + +/** + Definition of the period a device in close proximity shall back off on the pairing + address after a backoff packet has been received. +*/ +#define GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT ((GZP_REQ_TX_TIMEOUT / 2) + 50) + +/** + Definition of the period a device NOT in close proximity shall back off on the pairing + address after a backoff packet has been received. +*/ +#define GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT (GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT + GZP_STEP1_RX_TIMEOUT) + +/** + Definition of the time the host waits for a device to complete + transmission of the pairing request step 1 packet. +*/ +#define GZP_STEP1_RX_TIMEOUT (((GZP_REQ_TX_TIMEOUT / 2) + GZP_TX_ACK_WAIT_TIMEOUT) + 50) + +/** + Definition of the lowest boundary for the channel range to be used. +*/ +#define GZP_CHANNEL_MIN 2 + +/** + Definition of the upper boundary for the channel range to be used. +*/ +#define GZP_CHANNEL_MAX 80 + +/** + Definition of the minimum channel spacing for the channel subset generated + during pairing. +*/ +#define GZP_CHANNEL_SPACING_MIN 5 + +/** + Non volatile memory (Flash or OTP) storage address. A device will + require GZP_DEVICE_PARAMS_STORAGE_SIZE bytes of memory, and + Host 11 bytes. When using flash memory, storage address should + be a multiple of chip page size. +*/ +#define GZP_PARAMS_STORAGE_ADR 0x00001000 + +/** + Number of bytes available for parameter storage in Device. + It is equal to flash page size on nRF5x chips. +*/ +#if defined (NRF51) + #define GZP_DEVICE_PARAMS_STORAGE_SIZE 1024 +#elif defined (NRF52) + #define GZP_DEVICE_PARAMS_STORAGE_SIZE 4096 +#endif + +/** + Maximum Device TX payload length [bytes]. + */ +#define GZP_MAX_FW_PAYLOAD_LENGTH 17 + +/** + Maximum Host ACK payload length [bytes]. + */ +#define GZP_MAX_ACK_PAYLOAD_LENGTH 10 + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/gcc/license.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/gcc/license.txt new file mode 100644 index 0000000000000000000000000000000000000000..3a9e590c211963568f2b56f761aa7253760e3ab9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/gcc/license.txt @@ -0,0 +1,37 @@ +Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + +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, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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 Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/iar/license.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/iar/license.txt new file mode 100644 index 0000000000000000000000000000000000000000..3a9e590c211963568f2b56f761aa7253760e3ab9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/iar/license.txt @@ -0,0 +1,37 @@ +Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + +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, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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 Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzll.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzll.h new file mode 100644 index 0000000000000000000000000000000000000000..fccde2574fc4e032eb16ddb60a5cd5bc524e8bf2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzll.h @@ -0,0 +1,930 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief Gazell Link Layer API. + */ + +#ifndef NRF_GZLL_H__ +#define NRF_GZLL_H__ + +#include +#include "nrf.h" +#include "nrf_gzll_constants.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** +* @defgroup gzll_02_api Gazell Link Layer +* @{ +* @ingroup modules_01_gzll +* @brief Gazell Link Layer Application Programming Interface (API). +*/ + + +/** + * @enum nrf_gzll_mode_t + * @brief Enumerator used for selecting Gazell mode. + */ +typedef enum +{ + NRF_GZLL_MODE_DEVICE, ///< Device mode + NRF_GZLL_MODE_HOST, ///< Host mode + NRF_GZLL_MODE_SUSPEND, ///< Suspend mode ("disabled with timer running") +} nrf_gzll_mode_t; + + +/** + * @enum nrf_gzll_device_channel_selection_policy_t + * @brief Enumerator used for selecting Gazell Device channel + * selection policy. + */ +typedef enum +{ + NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_SUCCESSFUL, ///< Start on previous successful channel + NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_CURRENT, ///< Start on channel currently monitored by Host +} nrf_gzll_device_channel_selection_policy_t; + + +/** + * @enum nrf_gzll_tx_power_t + * @brief Enumerator used for selecting the transmit (TX) power. + */ +typedef enum +{ + NRF_GZLL_TX_POWER_4_DBM, ///< 4 dBm transmit power. + NRF_GZLL_TX_POWER_0_DBM, ///< 0 dBm transmit power. + NRF_GZLL_TX_POWER_N4_DBM, ///< -4 dBm transmit power. + NRF_GZLL_TX_POWER_N8_DBM, ///< -8 dBm transmit power. + NRF_GZLL_TX_POWER_N12_DBM, ///< -12 dBm transmit power. + NRF_GZLL_TX_POWER_N16_DBM, ///< -16 dBm transmit power. + NRF_GZLL_TX_POWER_N20_DBM ///< -20 dBm transmit power. +} nrf_gzll_tx_power_t; + + +/** + * @enum nrf_gzll_datarate_t + * @brief Enumerator used for selecting the radio datarate. + */ +typedef enum +{ + NRF_GZLL_DATARATE_250KBIT, ///< 250 Kbps datarate. + NRF_GZLL_DATARATE_1MBIT, ///< 1 Mbps datarate. + NRF_GZLL_DATARATE_2MBIT ///< 2 Mbps datarate. +} nrf_gzll_datarate_t; + + +/** + * @enum nrf_gzll_xosc_ctl_t + * @brief Enumerator used for specifying whether switching the + * external 16 MHz oscillator on/off shall be handled automatically + * inside Gazell or manually by the application. + */ +typedef enum +{ + NRF_GZLL_XOSC_CTL_AUTO, ///< Switch XOSC on/off automatically + NRF_GZLL_XOSC_CTL_MANUAL ///< Switch XOSC on/off manually +} nrf_gzll_xosc_ctl_t; + +/** + * @enum nrf_gzll_error_code_t + * @brief Enumerator used for error codes for Gazell API functions + */ +typedef enum +{ + NRF_GZLL_ERROR_CODE_NO_ERROR = 0, + ///< No error has been detected. + NRF_GZLL_ERROR_CODE_FAILED_TO_INITIALIZE = 1, + ///< The function NRF_GZLL_init failed. + NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_CONFIGURE_WHEN_ENABLED = 2, + ///< A call to a configuration 'set' function was made while Gazell was + ///< enabled. + NRF_GZLL_ERROR_CODE_POINTER_IS_NULL = 3, + ///< A null pointer was given as an input to a function. + NRF_GZLL_ERROR_CODE_INVALID_PIPE = 4, + ///< An invalid pipe number was given as an input to a function. + NRF_GZLL_ERROR_CODE_INVALID_MODE = 5, + ///< An invalid value for the nrf_gzll_mode_t enumerator was given as input + ///< to a function. + NRF_GZLL_ERROR_CODE_INVALID_PAYLOAD_LENGTH = 6, + ///< An invalid payload length was given as an input to a function. + NRF_GZLL_ERROR_CODE_INVALID_CHANNEL_TABLE_SIZE = 7, + ///< An invalid channel table size was given as an input to a function. + NRF_GZLL_ERROR_CODE_INSUFFICIENT_PACKETS_AVAILABLE = 8, + ///< There are insufficient packets in the Gazell memory pool to + ///< successfully execute the operation. + NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_ADD_TO_FULL_FIFO = 9, + ///< There is insufficient space in the TX FIFO for the data packet. + NRF_GZLL_ERROR_CODE_NO_SPACE_IN_RX_FIFO_FOR_ACK = 10, + ///< There is insufficient space in the RX FIFO for the ACK. + NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_FETCH_FROM_EMPTY_FIFO = 11, + ///< Attempted to fetch a packet from an empty FIFO. Use the functions nrf_gzll_get_tx_fifo_packet_count() or nrf_gzll_get_rx_fifo_packet_count() + NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_FLUSH_WHEN_ENABLED = 12, + ///< Attempted to fetch a packet from an empty FIFO. Use the functions nrf_gzll_get_tx_fifo_packet_count() or nrf_gzll_get_rx_fifo_packet_count() + NRF_GZLL_ERROR_CODE_INVALID_PARAMETER = 14, + ///< Attempted to set a variable which was not valid. + NRF_GZLL_ERROR_CODE_INTERNAL_ASSERT_OCCURRED = 15, + ///< An internal assert occurred. + NRF_GZLL_ERROR_CODE_CALLBACK_NOT_IMPLEMENTED = 16, + ///< A callback was called but not implemented by the application. + NRF_GZLL_ERROR_CODE_NUMBER_OF_ERROR_CODES = 17, + ///< Number of possible error codes. +} nrf_gzll_error_code_t; + + +/** + * @struct nrf_gzll_device_tx_info_t; + * @brief Data structure containing information about the last packet + * transmission. + */ +typedef struct +{ + bool payload_received_in_ack; + ///< A payload was received in the ACK. + uint16_t num_tx_attempts; + ///< Number of attempts used on previous Device packet transmission. + uint16_t num_channel_switches; + ///< Number of channel switches needed during previous packet transmission. + int16_t rssi; + ///< Received signal strength indicator in dBm. @sa nrf_gzll_enable_rssi(). +} nrf_gzll_device_tx_info_t; + +/** + * @struct nrf_gzll_host_rx_info_t; + * @brief Data structure containing information about the last packet + * received. + */ +typedef struct +{ + bool packet_removed_from_tx_fifo; + ///< A payload was received in the ACK. + int16_t rssi; + ///< Received signal strength indicator in dBm. @sa nrf_gzll_enable_rssi(). +} nrf_gzll_host_rx_info_t; + + + + +/******************************************************************************/ +/** @name General API functions + * @{ */ +/******************************************************************************/ + + +/** + * @brief Initialize Gazell. + * + * @param mode The mode to initialize Gazell in. + * + * @retval true if Gazell initialized. + * @retval false if Gazell failed to initialize. + */ +bool nrf_gzll_init(nrf_gzll_mode_t mode); + + +/** + * @brief Enable Gazell. + * + * When enabled the behaviour described for the current Gazell Link Layer mode + * will apply. + * + * @retval false if nrf_gzll_init has not previously been called. + */ +bool nrf_gzll_enable(void); + +/** + * @brief Disable Gazell. + * + * When calling this function the Gazell Link Layer will begin disabling, + * and will be fully disabled when Gazell calls nrf_gzll_disabled(). + * If there are any pending notifications, or if any new notifications are + * being added to the internal notification queue while Gazell is disabling, + * these will be sent to the application before Gazell is fully disabled. + * + * After Gazell has been fully disabled, no more notifications will be sent to + * the application. + */ +void nrf_gzll_disable(void); + + +/** Check whether Gazell is enabled or disabled. + * + * @retval true If Gazell is enabled. + * @retval false If Gazell is disabled. + */ +bool nrf_gzll_is_enabled(void); + +/** @} */ + + +/******************************************************************************/ +/** @name Device mode callback functions + * @{ */ +/******************************************************************************/ + + +/** + * @brief ACK received callback (Device mode only). + * + * This callback is made when the Device receives an ACK (acknowledgement) + * packet. + * @sa nrf_gzll_ack_payload_received. + * + * @param pipe is the pipe on which an ACK packet was received. + * @param tx_info struct used to indicate whether a payload was received in the + * ack, as well as the number of TX attempts and channel switches required. + */ +void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info); + + +/** + * @brief Transmission failed callback (Device mode only). + * + * This callback is made when a packet does not receive an ACK after + * nrf_gzll_max_retries is reached. The packet is deleted by Gazell. + * + * @param pipe is the pipe on which the transmission failed. + * @param tx_info struct used to indicate whether a payload was received + * in the ack, as well as RSSI and the number of TX attempts and + * channel switches required. + */ +void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info); + + +/** @} */ + + + +/******************************************************************************/ +/** @name Host mode callback functions + * @{ */ +/******************************************************************************/ + +/** + * @brief Data packet received callback (Host mode only). + * + * This callback is made when a Host receives a data packet from a Device. + * + * @param pipe is the pipe on which the data packet was received. + * @param rx_info struct used to indicate whether a payload was removed from the + * pipe's TX FIFO, as well as RSSI. + */ +void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info); + + +/** @} */ + +/******************************************************************************/ +/** @name Callback functions for both Device and Host mode + * @{ */ +/******************************************************************************/ + + +/** + * @brief Disabled callback. + * + * This is called after Gazell enters the disabled state. + * There is no further CPU use by Gazell, the radio is disabled and the timer is + * powered down. + */ +void nrf_gzll_disabled(void); + + +/** + * @brief Mode changed callbackl. + * + * This function is called after the Gazell mode has been changed. + * This function can only be called when Gazell is enabled. + */ +void nrf_gzll_mode_changed(void); + + +/** @} */ + + +/******************************************************************************/ +/** @name Packet transmission and receiving functions + * @{ */ +/******************************************************************************/ + +/** + * @brief Add a packet to the tail of the TX FIFO. + * + * In Device mode, the packet will be added. + * In Host mode, the payload will be piggybacked onto an ACK. + * + * @param pipe Pipe to which to add the payload. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @param payload Pointer to the payload. + * @param length Number of bytes of the payload to transmit + * (0 to NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH). + * + * @retval true if the packet was successfully added to the TX FIFO. + * @retval false if unsuccessful, check nrf_gzll_error_code_t for more information. + */ +bool nrf_gzll_add_packet_to_tx_fifo(uint32_t pipe, uint8_t * payload, uint32_t length); + + +/** + * @brief Fetch a packet from the head of the RX FIFO. + * + * @param pipe Pipe from which to fetch the payload. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @param payload Pointer to copy the payload to. + * @param length Length must be at least as large as the the number of bytes + * in the received payload length. + * + * @retval true If the fetch was successful. + * @retval false If unsuccessful, check nrf_gzll_error_code_t for more information. + */ +bool nrf_gzll_fetch_packet_from_rx_fifo(uint32_t pipe, uint8_t * payload, uint32_t* length); + + +/** + * @brief Get the number of packets in the TX FIFO on a specific pipe. + * + * @param pipe The pipe for which to check. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * + * @retval >=0 The number of packets in the TX FIFO for the pipe. + * @retval -1 If the pipe number is invalid. + */ +int32_t nrf_gzll_get_tx_fifo_packet_count(uint32_t pipe); + + +/** + * @brief Get the number of packets in the RX FIFO on a specific pipe. + * + * @param pipe The pipe for which to check. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @retval >=0 The number of packets in the RX FIFO for the pipe. + * @retval -1 If the pipe number is invalid. + */ +int32_t nrf_gzll_get_rx_fifo_packet_count(uint32_t pipe); + + +/** + * @brief Get the total number of packets residing in all TX and RX FIFOs. + * + * Can be used to check against NRF_GZLL_CONST_MAX_TOTAL_PACKETS to + * determine if there is free space in the memory pool for more packets. + * + * @return The number of packets residing in all TX and RX FIFOs. + */ +uint32_t nrf_gzll_get_total_allocated_packet_count(void); + + +/** + * @brief Check if adding a packet to a pipe's TX FIFO should be successful. + * + * Checks if there is another space in the pipe's TX and RX FIFOs + * as well as enough overall space in the packet pool. + * + * @param pipe The pip for which to check. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * + * @retval true If there is another space. + * @retval false If there is not enough space, or the pipe is invalid. + */ +bool nrf_gzll_ok_to_add_packet_to_tx_fifo(uint32_t pipe); + +/** + * @brief Flush the RX FIFO for a specific pipe. + * + * Delete all the packets and free the memory of the TX FIFO for a + * specific pipe. + * + * Note that it is not allowed to flush a TX FIFO when + * Gazell is enabled. + * + * @param pipe is the pipe for which to flush. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @retval true if the pipe was flushed. + * @retval false if the pipe was not flushed. + */ +bool nrf_gzll_flush_tx_fifo(uint32_t pipe); + + +/** + * @brief Flush the RX FIFO for a specific pipe. + * + * Delete all the packets and free the memory of the RX FIFO for a + * specific pipe. + * + * @param pipe is the pipe for which to flush. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @retval true if the pipe was flushed. + * @retval false if the pipe was not flushed. + */ +bool nrf_gzll_flush_rx_fifo(uint32_t pipe); + + +/** @} */ + + +/******************************************************************************/ +/** @name Configuration functions + * + * Configuration 'set' functions may only be called while Gazell is disabled. The + * new parameter comes into effect when Gazell is enabled again. + * + * Configuration 'get' functions may be called at any time. + * + * @{ */ +/******************************************************************************/ + + +/** + * @brief Set the mode. + * + * @param mode The mode to be used. + * See nrf_gzll_mode_t for a list of valid modes. + * + * It is allowed to change mode when Gazell is enabled. If the mode is + * being changed while Gazell is enabled, the mode will not change right away. + * In this case the callback function nrf_gzll_mode_changed() will be called + * after the mdoe has changed. + * + * @retval true If the parameter was set. + */ +bool nrf_gzll_set_mode(nrf_gzll_mode_t mode); + + +/** + * @brief Get function counterpart to nrf_gzll_set_mode(). + * + * @return The current mode. + */ +nrf_gzll_mode_t nrf_gzll_get_mode(void); + + +/** + * @brief Set the base address for pipe 0. + * + * The full on-air address for each pipe is composed of a multi-byte base address + * prepended to a prefix byte. + * + * For packets to be received correctly, the most significant byte of + * the base address should not be an alternating sequence of 0s and 1s i.e. + * it should not be 0x55 or 0xAA. + * + * @param base_address The 4 byte base address. All bytes are used. + * + * @retval true If the parameter was set. + * @return false If Gazell was enabled. + */ +bool nrf_gzll_set_base_address_0(uint32_t base_address); + + +/** + * @brief Get function counterpart to nrf_gzll_set_base_address_0(). + * + * @return Base address 0. + */ +uint32_t nrf_gzll_get_base_address_0(void); + + +/** + * @brief Set the base address for pipes 1-7. + * + * Pipes 1 through 7 share base_address_1. @sa nrf_gzll_set_base_address_0. + * + * @param base_address The 4 byte base address. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_base_address_1(uint32_t base_address); + + +/** + * @brief Get function counterpart to nrf_gzll_set_base_address_1(). + * + * @return Base address 1. + */ +uint32_t nrf_gzll_get_base_address_1(void); + + +/** + * @brief Set the address prefix byte for a specific pipe. + * + * Each pipe should have its own unique prefix byte. + * + * @param pipe The pipe that the address should apply to. + * This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @param address_prefix_byte The address prefix byte. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled, or if the pipe was invalid. + */ +bool nrf_gzll_set_address_prefix_byte(uint32_t pipe, uint8_t address_prefix_byte); + + +/** + * @brief Get function counterpart to nrf_gzll_set_address_prefix_byte(). + * + * @param pipe The pipe for which to get the address. + * This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @param out_address_prefix_byte The pointer in which to return the + * address prefix byte. + * + * @retval true If the parameter was returned. + * @retval false If Gazell was enabled, the pipe was invalid or + * out_address was a NULL pointer. + */ +bool nrf_gzll_get_address_prefix_byte(uint32_t pipe, uint8_t* out_address_prefix_byte); + + +/** + * @brief Set which pipes shall listen for packets in Host mode. + * + * This value is a bitmap, and each bit corresponds to a given pipe number. + * Bit 0 set to "1" enables pipes 0, bit 1 set to "1" enables pipe 1 + * and so forth. + * The maximum number of pipes is defined by NRF_GZLL_CONST_PIPE_COUNT. + * + * @param pipes A bitmap specifying which pipes to monitor. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_rx_pipes_enabled(uint32_t pipes); + + +/** + * @brief Get function counterpart to nrf_gzll_set_rx_pipes_enabled(). + * + * @return Bitmap holding the current enabled pipes. + */ +uint32_t nrf_gzll_get_rx_pipes_enabled(void); + + +/** + * @brief Set the timeslot period. + * + * The length in microseconds of a Gazell link layer timeslot. + * + * The minimum value of the timeslot period is dependent of the + * radio data rate (@sa nrf_gzll_set_datarate()). + * + * - For NRF_GZLL_DATARATE_2MBIT the timeslot period must be >= 600 us. + * - For NRF_GZLL_DATARATE_1MBIT the timeslot period must be >= 900 us. + * - For NRF_GZLL_DATARATE_250KBIT the timeslot period must be >= 2700 us. + * + * @param period_us The timeslot period in microseconds. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_timeslot_period(uint32_t period_us); + + +/** + * @brief Get function counterpart to nrf_gzll_get_timeslot_period(). + * + * @return The current timeslot period. + */ +uint32_t nrf_gzll_get_timeslot_period(void); + + +/** + * @brief Set the Device channel selection policy + * + * The policy determines the initial channel when starting a new packet. + * transmission. + * + * @param policy The channel selection policy. + * + * @arg NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_SUCCESSFUL specifies + * that a new packet transmission always shall use the previous + * successful channel from the channel table. If Gazell is "in sync", Gazell + * will wait until this channel is being monitored by the Host before starting + * the transmission. + * + * @arg NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_CURRENT specifies that + * Gazell shall transmit on the channel that is currently being monitored by the + * Host. This parameter is only used when Gazell is "in sync". When "out of" sync, + * Gazell will always start using the "previous successful" channel. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled or the policy was invalid. + */ +bool nrf_gzll_set_device_channel_selection_policy(nrf_gzll_device_channel_selection_policy_t policy); + + +/** + * @brief Get function counterpart to nrf_gzll_set_device_channel_selection_policy(). + * + * @return the Device channel selection policy. + */ +nrf_gzll_device_channel_selection_policy_t nrf_gzll_get_device_channel_selection_policy(void); + + +/** + * @brief Set the number of timeslots that Gazell shall + * reside on a single channel before switching to another channel. + * + * This parameter applies in Host mode and for a Device that is + * in the "in sync" state. + * + * Since the Device and Host can not be in perfect synchronization, a + * transmission should overlap to adjacent timeslots on the Host. + * Therefore this value should be at least 2. + * + * @sa nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync + * + * @param timeslots The number of timeslots to reside on + * each channel before channel switch. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_timeslots_per_channel(uint32_t timeslots); + + +/** + * @brief Get function counterpart to nrf_gzll_set_timeslots_per_channel(). + * + * @return The current number of timeslots. + */ +uint32_t nrf_gzll_get_timeslots_per_channel(void); + + +/** + * @brief Set the number of timeslots that a Gazell shall + * reside on a single channel before switching to another channel when + * in the "out of sync" state. + * + * This value should be set so that the Device transmits on one channel + * while the Host goes through a full channel rotation, i.e., + * channel_table_size*timeslots_per_channel. + * This ensures that the channels on the Device and Host will coincide + * at some point. + * Further increasing the value has been observed to provide better performance + * in the presence of interferers. + * + * @param timeslots The number of timeslots to reside on + * each channel before channel switch. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync(uint32_t timeslots); + + +/** + * @brief Get function counterpart to + * nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync(). + * + * @return The current number of timeslots. + */ +uint32_t nrf_gzll_get_timeslots_per_channel_when_device_out_of_sync(void); + + +/** + * @brief Set the number of timeslots after a successful + * reception of a Device or Host packet that the Gazell Link Layer shall assume + * that the link is synchronized. A value of 0 implies that the + * link is always out of sync. + * + * @param lifetime The sync lifetime in number of timeslots. + * + * @retval true If the sync lifetime was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_sync_lifetime(uint32_t lifetime); + + +/** + * @brief Get function counterpart to nrf_gzll_set_sync_lifetime(). + * + * @return The sync lifetime measured in number of timeslots. + */ +uint32_t nrf_gzll_get_sync_lifetime(void); + + +/** + * @brief Set the maximum number of TX attempts + * that can be used for a single packet. + * + * After the maximum number of attempts have been spent without + * receiving any ACK from the Host, the transmission will be terminated + * and the nrf_gzll_device_tx_failed() callback will be called. + * + * @param max_tx_attempts The maximum number of TX attempts. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_max_tx_attempts(uint16_t max_tx_attempts); + + +/** + * @brief Get function counterpart to nrf_gzll_set_max_tx_attempts(). + * + * @return The current max Device TX attempts. + */ +uint16_t nrf_gzll_get_max_tx_attempts(void); + + +/** + * @brief Set the table of Radio Frequency (RF) channels. + * + * The valid channels are in the range 0 <= channel <= 125, where the + * actual centre frequency is (2400 + channel) MHz. + * The maximum channel table size is defined by + * NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE. + * + * @param channel_table Pointer to the channel table. + * @param size The size of the channel table. + * + * @retval true If the channel table was set. + * @retval false If Gazell was enabled, or the channel_table pointer was NULL, + * or the size was invalid. + */ +bool nrf_gzll_set_channel_table(uint8_t* channel_table, uint32_t size); + + +/** + * @brief Get the table of Radio Frequency (RF) channels. + * + * @param channel_table Pointer to copy the channel table to. + * @param size Pointer to copy the size of the channel table to. + * The value already at size must be at least the size + * of the channel table. + * + * @retval true If the channel table was copied to channel_table. + * @retval false If the channel_table pointer was NULL, + * or the size was not large enough. + */ +bool nrf_gzll_get_channel_table(uint8_t* channel_table, uint32_t* size); + + +/** + * @brief Get the current channel table size. + * + * @return The current channel table size. + */ +uint32_t nrf_gzll_get_channel_table_size(void); + + +/** + * @brief Set the radio TX power. + * + * @param tx_power TX power. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled or the TX power was invalid. +*/ +bool nrf_gzll_set_tx_power(nrf_gzll_tx_power_t tx_power); + + +/** + * @brief Get function counterpart to nrf_gzll_set_tx_power(). + * + * @return The current TX power. + */ +nrf_gzll_tx_power_t nrf_gzll_get_tx_power(void); + + +/** + * @brief Set the radio datarate. + * + * @param data_rate Datarate. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled or the datarate was invalid. + */ +bool nrf_gzll_set_datarate(nrf_gzll_datarate_t data_rate); + + +/** + * @brief Get function counterpart to nrf_gzll_set_datarate(). + * + * @return The current datarate. + */ +nrf_gzll_datarate_t nrf_gzll_get_datarate(void); + + +/** + * @brief Set whether start/stop of external oscillator (XOSC) shall be handled + * automatically inside Gazell or manually by the application. + * + * When controlling the XOSC manually from the application it is + * required that the XOSC is started before Gazell is enabled. + * + * When start/stop of the XOSC is handled automatically by Gazell, + * the XOSC will only be running when needed, that is when the radio + * is being used or when Gazell needs to maintain synchronization. + * + * It is required that the XOSC is started in order for the radio to be + * able to send or receive any packets. + * + * @param xosc_ctl setting for XOSC control. + * + * @retval true if the parameter was set. + * @retval false if Gazell was enabled or the xosc_ctl value was invalid. + */ +bool nrf_gzll_set_xosc_ctl(nrf_gzll_xosc_ctl_t xosc_ctl); + + +/** + * Get function counterpart for nrf_gzll_set_xosc_ctl(); + * + * @return The XOSC control setting. + */ +nrf_gzll_xosc_ctl_t nrf_gzll_get_xosc_ctl(void); + + +/** + * @brief Set Gazell to disable automatically after a certain number of timeslot ticks. + * + * @param num_ticks Number of timeslot ticks. + * + */ +void nrf_gzll_set_auto_disable(uint32_t num_ticks); + + +/** + * @brief Get the number of timeslot ticks that have occurred since + * nrf_gzll_init() was called. + * + * @return Number of timeslot ticks. + * + */ +uint32_t nrf_gzll_get_tick_count(void); + + +/** + * @brief Clear the internal timeslot tick count variable that is read + * by nrf_gzll_get_tick_count(). + * + */ +void nrf_gzll_clear_tick_count(void); + +/** @} */ + + +/******************************************************************************/ +/** @name Error handling functions + * @{ */ +/******************************************************************************/ + + +/** + * @brief Gets the Gazell error code. + * + * @return The current error code. + */ +nrf_gzll_error_code_t nrf_gzll_get_error_code(void); + + +/** + * @brief Reset the Gazell error code. + * + * The error code is reset to NRF_GZLL_ERROR_CODE_NO_ERRROR. + */ +void nrf_gzll_reset_error_code(void); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzll_constants.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzll_constants.h new file mode 100644 index 0000000000000000000000000000000000000000..fa1d2464b93700ba4d1dabd2b3d815f3d9f40dc4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzll_constants.h @@ -0,0 +1,199 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief Gazell Link Layer constants and default values. + * + * NOTE! Changing values here has no effect. They are only provided as a reference. + */ + +#ifndef NRF_GZLL_CONSTANTS_H__ +#define NRF_GZLL_CONSTANTS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @addtogroup gzll_02_api + * @{ + */ + + +/*****************************************************************************/ +/** @name Hardware resources used by Gazell */ +/*****************************************************************************/ +#define NRF_GZLL_HIGH_IRQ_PRIORITY 0 ///< Interrupt priority the Gazell timer and the radio +#define NRF_GZLL_LOW_IRQ_PRIORITY 1 ///< Interrupt priority for Gazell callback functions. + +#ifndef USE_SD_HW_RESOURCES +#define NRF_GZLL_SWI_IRQn SWI0_IRQn ///< Software interrupt # used for callback functions. +#define NRF_GZLL_SWI_IRQ_HANDLER SWI0_IRQHandler ///< Software interrupt handler used for callback functions. + +#define NRF_GZLL_TIMER NRF_TIMER2 ///< Timer to be used as flywheel timer. +#define NRF_GZLL_TIMER_PERPOWER_Msk POWER_PERPOWER_TIMER2_Msk ///< PERPOWER mask for the timer. +#define NRF_GZLL_TIMER_IRQn TIMER2_IRQn ///< Interrupt # for the timer. +#define NRF_GZLL_TIMER_IRQ_HANDLER TIMER2_IRQHandler ///< Interrupt handler for the timer. + +// In addition, Gazell uses the radio peripheral and radio interrupts. + +/* + * PPI configuration + */ +#define NRF_GZLL_PPI_EEP0 (NRF_PPI -> CH0_EEP) ///< Gazell PPI event endpoint 0 +#define NRF_GZLL_PPI_TEP0 (NRF_PPI -> CH0_TEP) ///< Gazell PPI task endpoint 0 +#define NRF_GZLL_PPI_EEP1 (NRF_PPI -> CH1_EEP) ///< Gazell PPI event endpoint 1 +#define NRF_GZLL_PPI_TEP1 (NRF_PPI -> CH1_TEP) ///< Gazell PPI task endpoint 1 +#define NRF_GZLL_PPI_EEP2 (NRF_PPI -> CH2_EEP) ///< Gazell PPI event endpoint 2 +#define NRF_GZLL_PPI_TEP2 (NRF_PPI -> CH2_TEP) ///< Gazell PPI task endpoint 2 + +#define NRF_GZLL_PPI_CHEN_MSK_0_AND_1 (0x03) ///< Channel enable/disable mask for PPI endpoint 0 and 1. +#define NRF_GZLL_PPI_CHEN_MSK_2 (0x04) ///< Channel enable/disable mask for PPI endpoint 2. + +#else + +#define NRF_GZLL_SWI_IRQn SWI1_IRQn ///< Software interrupt # used for callback functions. +#define NRF_GZLL_SWI_IRQ_HANDLER SWI1_IRQHandler ///< Software interrupt handler used for callback functions. + +#define NRF_GZLL_TIMER NRF_TIMER0 ///< Timer to be used as flywheel timer. +#define NRF_GZLL_TIMER_PERPOWER_Msk POWER_PERPOWER_TIMER0_Msk ///< PERPOWER mask for the timer. +#define NRF_GZLL_TIMER_IRQn TIMER0_IRQn ///< Interrupt # for the timer. +#define NRF_GZLL_TIMER_IRQ_HANDLER TIMER0_IRQHandler ///< Interrupt handler for the timer. + +// In addition, Gazell uses the radio peripheral and radio interrupts. + +/* + * PPI configuration + */ +#define NRF_GZLL_PPI_EEP0 (NRF_PPI -> CH8_EEP) ///< Gazell PPI event endpoint 0 +#define NRF_GZLL_PPI_TEP0 (NRF_PPI -> CH8_TEP) ///< Gazell PPI task endpoint 0 +#define NRF_GZLL_PPI_EEP1 (NRF_PPI -> CH9_EEP) ///< Gazell PPI event endpoint 1 +#define NRF_GZLL_PPI_TEP1 (NRF_PPI -> CH9_TEP) ///< Gazell PPI task endpoint 1 +#define NRF_GZLL_PPI_EEP2 (NRF_PPI -> CH10_EEP) ///< Gazell PPI event endpoint 2 +#define NRF_GZLL_PPI_TEP2 (NRF_PPI -> CH10_TEP) ///< Gazell PPI task endpoint 2 + +#define NRF_GZLL_PPI_CHEN_MSK_0_AND_1 (0x300) ///< Channel enable/disable mask for PPI endpoint 0 and 1. +#define NRF_GZLL_PPI_CHEN_MSK_2 (0x400) ///< Channel enable/disable mask for PPI endpoint 2. + +#endif + +#define NRF_GZLL_CONST_PIPE_COUNT 8 ///< Number of TX pipes (at least one for each Device-Host pairs). +#define NRF_GZLL_CONST_FIFO_LENGTH 3 ///< Maximum number of packets allowed in a TX or RX FIFO. +#define NRF_GZLL_CONST_MAX_TOTAL_PACKETS 6 ///< Maximum number of packets available for reservation at any one time. +#define NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH 32 ///< Maximum allowed payload length in bytes. +#define NRF_GZLL_CONST_CALLBACK_QUEUE_LENGTH 10 ///< Maximum number of notifications allowed in the callback queue. +/** @} */ + + + +/*****************************************************************************/ +/** @name Constant pipe and FIFO configuration */ +/*****************************************************************************/ +#define NRF_GZLL_CONST_PIPE_COUNT 8 ///< Number of TX pipes (at least one for each Device-Host pairs). +#define NRF_GZLL_CONST_FIFO_LENGTH 3 ///< Maximum number of packets allowed in a TX or RX FIFO. +#define NRF_GZLL_CONST_MAX_TOTAL_PACKETS 6 ///< Maximum number of packets available for reservation at any one time. +#define NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH 32 ///< Maximum allowed payload length in bytes. +#define NRF_GZLL_CONST_CALLBACK_QUEUE_LENGTH 10 ///< Maximum number of notifications allowed in the callback queue. +/** @} */ + + + +/*****************************************************************************/ +/** @name Default radio configuration */ +/*****************************************************************************/ +#define NRF_GZLL_DEFAULT_TX_POWER NRF_GZLL_TX_POWER_0_DBM ///< Default TX power. +#define NRF_GZLL_DEFAULT_DATARATE NRF_GZLL_DATARATE_2MBIT ///< Default data rate. +#define NRF_GZLL_DEFAULT_CHANNEL_TABLE {4, 25, 42, 63, 77} ///< Default channel table. +#define NRF_GZLL_DEFAULT_CHANNEL_TABLE_SIZE 5 ///< Default channel table size. +#define NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE 16 ///< Maximum channel table size allowed by Gazell. +/** @} */ + + +/*****************************************************************************/ +/** @name Default Address configuration */ +/*****************************************************************************/ +/* +Corresponds to Legacy nRFgo SDK Gazell config: +#define GZLL_DEFAULT_ADDRESS_PIPE0 {0x01, 0x04, 0x07, 0x0A, 0x0D} // {1, 4, 7, 10, 13} +#define GZLL_DEFAULT_ADDRESS_PIPE1 {0x02, 0x05, 0x08, 0x0B, 0x0E} // {2, 5, 8, 11, 14} +#define GZLL_DEFAULT_ADDRESS_PIPE2 3 +#define GZLL_DEFAULT_ADDRESS_PIPE3 4 +#define GZLL_DEFAULT_ADDRESS_PIPE4 5 +#define GZLL_DEFAULT_ADDRESS_PIPE5 6 +*/ +#define NRF_GZLL_DEFAULT_FULL_ADDRESS_PIPE0 {0x01, 0x04, 0x07, 0x0A, 0x0D} ///< Corresponding legacy Gazell pipe 0 address. +#define NRF_GZLL_DEFAULT_BASE_ADDRESS_0 0x0D0A0704 ///< Default base address 0. +#define NRF_GZLL_DEFAULT_BASE_ADDRESS_1 0x0E0B0805 ///< Default base address 1. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_0 1 ///< Default prefix address pipe 0. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_1 2 ///< Default prefix address pipe 1. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_2 3 ///< Default prefix address pipe 2. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_3 4 ///< Default prefix address pipe 3. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_4 5 ///< Default prefix address pipe 4. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_5 6 ///< Default prefix address pipe 5. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_6 7 ///< Default prefix address pipe 6. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_7 8 ///< Default prefix address pipe 7. +#define NRF_GZLL_DEFAULT_BASE_ADDRESS_LENGTH NRF_GZLL_BASE_ADDRESS_LENGTH_4B ///< Default on-air base address length. + +#define NRF_GZLL_DEFAULT_RX_PIPES_ENABLED 0x000000FF ///< Enabled Rx pipes. See nrf_gzll_set_rx_pipes_enabled(). + +/** @} */ + + +/*****************************************************************************/ +/** @name Default timeslot and synchronization configuration */ +/*****************************************************************************/ +#define NRF_GZLL_DEFAULT_TIMESLOT_PERIOD 600 ///< Default timeslot period. +#define NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL 2 ///< Timeslots use by the Host and by the Device when communication is in sync. +#define NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL_WHEN_DEVICE_OUT_OF_SYNC 15 ///< Timeslots use by the Device before communication is in sync. +#define NRF_GZLL_DEFAULT_SYNC_LIFETIME (3 * NRF_GZLL_DEFAULT_CHANNEL_TABLE_SIZE * NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL) ///< Number of timeslots to keep the timer running so that communication remains synchronized. +#define NRF_GZLL_DEFAULT_DEVICE_CHANNEL_SELECTION_POLICY NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_SUCCESSFUL ///< Default channel Gazell Device channel selection policy +#define NRF_GZLL_DEFAULT_MAX_TX_ATTEMPTS 0 ///< Default maximum TX attempts for each packet. A value of zero implies maximum +#define NRF_GZLL_DEFAULT_XOSC_CTL NRF_GZLL_XOSC_CTL_AUTO ///< Deafult setting for controlling the XOSC +/** @} */ + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzll_error.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzll_error.h new file mode 100644 index 0000000000000000000000000000000000000000..c6be5ec7517716b0e642c0aff7fe30c98745964c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzll_error.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief Gazell error API. + */ + +#ifndef NRF_GZLL_ERROR_H__ +#define NRF_GZLL_ERROR_H__ + +#include "sdk_errors.h" +#include "nrf_gzll.h" +#include "app_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GAZELLE_ERROR_CODE_CHECK(GZLL_RESULT) \ + do \ + { \ + if((GZLL_RESULT) == false) \ + { \ + nrf_gzll_error_code_t gzll_error_code = nrf_gzll_get_error_code(); \ + ret_code_t error_code = gzll_error_code + NRF_ERROR_GAZELLE_ERR_BASE; \ + APP_ERROR_HANDLER(error_code); \ + } \ + } while(0) + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzll_resources.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzll_resources.h new file mode 100644 index 0000000000000000000000000000000000000000..84467d133d18eec3871a10626ae33dddda54834a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzll_resources.h @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_GZLL_RESOURCES_H__ +#define NRF_GZLL_RESOURCES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GAZELL_ALTERNATIVE_RESOURCES + #define GZLL_PPI_CHANNELS_USED 0x00000007uL /**< PPI channels utilized by Gazell (not available to th spplication). */ + #define GZLL_TIMERS_USED 0x00000004uL /**< Timers used by Gazell. */ + #define GZLL_SWI_USED 0x00000001uL /**< Software interrupts used by Gazell */ +#else + #define GZLL_PPI_CHANNELS_USED 0x00000700uL /**< PPI channels utilized by Gazell (not available to th spplication). */ + #define GZLL_TIMERS_USED 0x00000001uL /**< Timers used by Gazell. */ + #define GZLL_SWI_USED 0x00000002uL /**< Software interrupts used by Gazell */ +#endif + + + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_GZLL_RESOURCES_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp.c new file mode 100644 index 0000000000000000000000000000000000000000..d8ba3b7d3efcb2f08fd6a63dd34efc0b328134ce --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp.c @@ -0,0 +1,363 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief Implementation of Gazell Pairing Library (gzp), Common functions. + * @defgroup gzp_source_common Gazell Pairing common functions implementation + * @{ + * @ingroup gzp_04_source + */ + + +#include "nrf_gzp.h" +#include "nrf_gzll.h" +#include "nrf_ecb.h" +#include + + +#define SOURCE_FILE NRF_SOURCE_FILE_GZP ///< File identifer for asserts. + + +/******************************************************************************/ +/** @name Global variables + * @{ */ +/******************************************************************************/ + +/** + * Constant holding base address part of the pairing address. + */ +static const uint8_t pairing_base_address[4] = { GZP_ADDRESS }; + +/** + * Constant holding prefix byte of the pairing address. + */ +static const uint8_t pairing_address_prefix_byte = 0; + +/** + * Constant holding pre-defined "validation ID". + */ +static const uint8_t gzp_validation_id[GZP_VALIDATION_ID_LENGTH] = GZP_VALIDATION_ID; + +/** + * Constant holding pre-defined "secret key". + */ +static const uint8_t gzp_secret_key[16] = GZP_SECRET_KEY; + +/** + * Variable used for AES key selection + */ +static gzp_key_select_t gzp_key_select; + + +/** @} */ + + +/******************************************************************************/ +/** @name Misc. external variables. + * @{ */ +/******************************************************************************/ +static uint8_t gzp_session_token[GZP_SESSION_TOKEN_LENGTH]; +static uint8_t gzp_dyn_key[GZP_DYN_KEY_LENGTH]; + +/** @} */ + +/******************************************************************************/ +/** @name Implementation common internal GZP functions + * @{ */ +/******************************************************************************/ +bool gzp_update_radio_params(const uint8_t* system_address) +{ + uint8_t i; + uint8_t channels[NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE]; + uint32_t channel_table_size; + uint32_t pairing_base_address_32, system_address_32; + bool update_ok = true; + bool gzll_enabled_state; + + gzll_enabled_state = nrf_gzll_is_enabled(); + + // Configure "global" pairing address + pairing_base_address_32 = (pairing_base_address[0]) + + ((uint32_t)pairing_base_address[1] << 8) + + ((uint32_t)pairing_base_address[2] << 16) + + ((uint32_t)pairing_base_address[3] << 24) ; + if (system_address != NULL) + { + system_address_32 = (system_address[0]) + + ((uint32_t)system_address[1] << 8) + + ((uint32_t)system_address[2] << 16) + + ((uint32_t)system_address[3] << 24) ; + } + else + { + return false; + } + + nrf_gzp_disable_gzll(); + update_ok = update_ok && nrf_gzll_set_base_address_0(pairing_base_address_32); + update_ok = update_ok && nrf_gzll_set_address_prefix_byte(GZP_PAIRING_PIPE, pairing_address_prefix_byte); + update_ok = update_ok && nrf_gzll_set_base_address_1(system_address_32); + + // Configure address for pipe 1 - 5. Address byte set to equal pipe number. + for (i = 1; i < NRF_GZLL_CONST_PIPE_COUNT; i++) + { + update_ok = update_ok && nrf_gzll_set_address_prefix_byte(i,i); + } + + channel_table_size = nrf_gzll_get_channel_table_size(); + gzp_generate_channels(&channels[0], system_address, channel_table_size); + + // Write generated channel subset to Gazell Link Layer + update_ok = update_ok && nrf_gzll_set_channel_table(&channels[0], channel_table_size); + if (gzll_enabled_state) + { + update_ok = update_ok && nrf_gzll_enable(); + } + return update_ok; +} + +void gzp_generate_channels(uint8_t* ch_dst, const uint8_t* system_address, uint8_t channel_tab_size) +{ + uint8_t binsize, spacing, i; + + binsize = (GZP_CHANNEL_MAX - GZP_CHANNEL_MIN) / channel_tab_size; + + ch_dst[0] = GZP_CHANNEL_LOW; + ch_dst[channel_tab_size - 1] = GZP_CHANNEL_HIGH; + + if (system_address != NULL) + { + for (i = 1; i < (channel_tab_size - 1); i++) + { + ch_dst[i] = (binsize * i) + (system_address[i % 4] % binsize); + } + } + + // If channels are too close, shift them to better positions + for (i = 1; i < channel_tab_size; i++) + { + spacing = (ch_dst[i] - ch_dst[i - 1]); + if (spacing < GZP_CHANNEL_SPACING_MIN) + { + ch_dst[i] += (GZP_CHANNEL_SPACING_MIN - spacing); + } + } +} + +__INLINE void nrf_gzp_disable_gzll(void) +{ + if (nrf_gzll_is_enabled()) + { + nrf_gzll_disable(); + __WFI(); + while (nrf_gzll_is_enabled()) + { + } + } +} + +#ifndef GZP_CRYPT_DISABLE + +void gzp_xor_cipher(uint8_t* dst, const uint8_t* src, const uint8_t* pad, uint8_t length) +{ + uint8_t i; + + for (i = 0; i < length; i++) + { + *dst = *src ^ *pad; + dst++; + src++; + pad++; + } +} + +bool gzp_validate_id(const uint8_t* id) +{ + return (memcmp(id, (void*)gzp_validation_id, GZP_VALIDATION_ID_LENGTH) == 0); +} + +void gzp_add_validation_id(uint8_t* dst) +{ + memcpy(dst, (void const*)gzp_validation_id, GZP_VALIDATION_ID_LENGTH); +} + +void gzp_crypt_set_session_token(const uint8_t * token) +{ + memcpy(gzp_session_token, (void const*)token, GZP_SESSION_TOKEN_LENGTH); +} + +void gzp_crypt_set_dyn_key(const uint8_t* key) +{ + memcpy(gzp_dyn_key, (void const*)key, GZP_DYN_KEY_LENGTH); +} + +void gzp_crypt_get_session_token(uint8_t * dst_token) +{ + memcpy(dst_token, (void const*)gzp_session_token, GZP_SESSION_TOKEN_LENGTH); +} + +void gzp_crypt_get_dyn_key(uint8_t* dst_key) +{ + memcpy(dst_key, (void const*)gzp_dyn_key, GZP_DYN_KEY_LENGTH); +} + +void gzp_crypt_select_key(gzp_key_select_t key_select) +{ + gzp_key_select = key_select; +} + +void gzp_crypt(uint8_t* dst, const uint8_t* src, uint8_t length) +{ + uint8_t i; + uint8_t key[16]; + uint8_t iv[16]; + + // Build AES key based on "gzp_key_select" + + switch (gzp_key_select) + { + case GZP_ID_EXCHANGE: + memcpy(key, (void const*)gzp_secret_key, 16); + break; + case GZP_KEY_EXCHANGE: + memcpy(key, (void const*)gzp_secret_key, 16); + gzp_get_host_id(key); + break; + case GZP_DATA_EXCHANGE: + memcpy(key, (void const*)gzp_secret_key, 16); + memcpy(key, (void const*)gzp_dyn_key, GZP_DYN_KEY_LENGTH); + break; + default: + return; + } + + // Build init vector from "gzp_session_token" + for (i = 0; i < 16; i++) + { + if (i < GZP_SESSION_TOKEN_LENGTH) + { + iv[i] = gzp_session_token[i]; + } + else + { + iv[i] = 0; + } + } + + // Set up hal_aes using new key and init vector + (void)nrf_ecb_init(); + nrf_ecb_set_key(key); + //hal_aes_setup(false, ECB, key, NULL); // Note, here we skip the IV as we use ECB mode + + // Encrypt IV using ECB mode + (void)nrf_ecb_crypt(iv, iv); + + // Encrypt data by XOR'ing with AES output + gzp_xor_cipher(dst, src, iv, length); + +} + +void gzp_random_numbers_generate(uint8_t * dst, uint8_t n) +{ + uint8_t i; + + NRF_RNG->EVENTS_VALRDY=0; + NRF_RNG->TASKS_START = 1; + for (i = 0; i < n; i++) + { + while (NRF_RNG->EVENTS_VALRDY==0) + {} + dst[i] = (uint8_t)NRF_RNG->VALUE; + NRF_RNG->EVENTS_VALRDY=0; + } + NRF_RNG->TASKS_STOP = 1; +} + + +/******************************************************************************/ +/** @name Implementation of nRF51 specific GZP functions + * @{ */ +/******************************************************************************/ + +/** +* @brief Function for setting the Primask variable. Only necessary if ARMCC +* compiler skips __set_PRIMASK at high optimization levels. +* +* @param primask The primask value. 1 to disable interrupts, 0 otherwise. +*/ +static void nrf_gzp_set_primask(uint32_t primask) +{ + #if defined(__CC_ARM) + //lint -save -e10 -e618 -e438 -e550 -e526 -e628 -e526 + volatile register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (primask); + #else + __set_PRIMASK(primask); + #endif + //lint -restore +} + +void nrf_gzp_flush_rx_fifo(uint32_t pipe) +{ + static uint8_t dummy_packet[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH]; + uint32_t length; + + nrf_gzp_set_primask(1); + while (nrf_gzll_get_rx_fifo_packet_count(pipe) >0) + { + length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; + (void)nrf_gzll_fetch_packet_from_rx_fifo(pipe,dummy_packet,&length); + } + nrf_gzp_set_primask(0); +} +/** @} */ + + + +/******************************************************************************/ +/** @name Implementation of debug functions + * @{ */ +/******************************************************************************/ + + +/** @} */ + +/** @} */ +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp.h new file mode 100644 index 0000000000000000000000000000000000000000..10ecc75af310036754dfcea58ebf71a4c91891e9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp.h @@ -0,0 +1,665 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief Gazell Pairing API + */ + +#ifndef __GZP_H +#define __GZP_H + +#include "nrf.h" +#include "nrf_gzp_config.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** +* @defgroup gzp_02_api Gazell Pairing +* @{ +* @ingroup modules_02_gzp +* @brief Gazell Pairing Application Programming Interface (API). +*/ + + +/******************************************************************************/ +/** @name Pairing configuration defines + * @{ */ +/******************************************************************************/ + + +#define GZP_PAIRING_PIPE 0 ///< Pipe reserved for initial pairing communication. +#define GZP_DATA_PIPE 1 ///< Pipe reserved for GZP encrypted data communication (one pipe only). +#define GZP_TX_RX_TRANS_DELAY 10 ///< Time to wait between request and fetch packets in RX_PERIODS (2 timeslot periods) +#define GZP_SYSTEM_ADDRESS_WIDTH 4 ///< Must equal Gazell base address length. + + +#define GZP_VALIDATION_ID {0x32, 0x53, 0x66} ///< Validation ID. Required to be shared by Host and Device. Not a secret. +#define GZP_VALIDATION_ID_LENGTH 3 ///< Validation ID length in bytes. +#define GZP_HOST_ID_LENGTH 5 ///< Host ID length in bytes. +#define GZP_SESSION_TOKEN_LENGTH GZP_HOST_ID_LENGTH ///< Session token length in bytes. +#define GZP_DYN_KEY_LENGTH (16 - GZP_VALIDATION_ID_LENGTH) ///< Dynamic key length in bytes. + +#define GZP_HOST_RX_POWER_THRESHOLD -64 ///< RSSI threshold for when signal strength in RX packet power is high enough. + +/** @} */ + + +/******************************************************************************/ +/** @name Device -> Host packet definitions + * @{ */ +/******************************************************************************/ + +#define GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH 1 ///< "Host address request" packet, payload length + +#define GZP_CMD_HOST_ADDRESS_FETCH_PAYLOAD_LENGTH 1 ///< "Host address fetch" packet, payload length + +#define GZP_CMD_HOST_ID_REQ_SESSION_TOKEN 1 ///< "Host ID request" packet, session token position +#define GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH (GZP_CMD_HOST_ID_REQ_SESSION_TOKEN + GZP_SESSION_TOKEN_LENGTH) ///< "Host ID request" payload length + +#if (GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH > 17) +#error GZP_SESSION_TOKEN_LENGTH too long. +#endif + + +#define GZP_CMD_HOST_ID_FETCH_VALIDATION_ID 1 ///< "Host ID fetch" packet +#define GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH (GZP_CMD_HOST_ID_FETCH_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Host ID fetch" payload length + +#if (GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH > 17) +#error GZP_VALIDATION_ID_LENGTH set too long. +#endif + +#define GZP_CMD_KEY_UPDATE_PREPARE_PAYLOAD_LENGTH 1 ///< "Key update prepare" payload length + +#define GZP_CMD_KEY_UPDATE_VALIDATION_ID 1 ///< "Key update" packet, validation ID position +#define GZP_CMD_KEY_UPDATE_NEW_KEY (GZP_CMD_KEY_UPDATE_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Key update" packet, new key position +#define GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH (GZP_CMD_KEY_UPDATE_NEW_KEY + GZP_DYN_KEY_LENGTH) ///< "Key update" packet, payload length + +#if (GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH > 17) +#error Sum (GZP_VALIDATION_ID_LENGTH + GZP_DYN_KEY_LENGTH) too high. +#endif + + +#define GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID 1 ///< "Encrypted user data" packet, validation ID position +#define GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD ((GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH)) ///< "Encrypted user data" packet, user data position +#define GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD ( GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Encrypted user data" packet, packet overhead length +#define GZP_ENCRYPTED_USER_DATA_MAX_LENGTH (17 - GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD) ///< "Encrypted user data" packet, max payload length + +#if (GZP_MAX_FW_PAYLOAD_LENGTH < 17) + #error GZP_MAX_FW_PAYLOAD_LENGTH must be greater or equal to 17. +#endif + +#define GZP_CMD_FETCH_RESP_PAYLOAD_LENGTH 1 ///< General "fetch response" packet, payload_length + +/** @} */ + + +/******************************************************************************/ +/** @name Host -> Device packet definitions + * @{ */ +/******************************************************************************/ + + +#define GZP_CMD_HOST_ADDRESS_RESP_ADDRESS 1 ///< "Host address fetch" response packet, address position +#define GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH (GZP_CMD_HOST_ADDRESS_RESP_ADDRESS + GZP_SYSTEM_ADDRESS_WIDTH) ///< ///< "Host address fetch" response packet, payload length + +#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH) + #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH. +#endif + + +#define GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID 1 ///< "Host ID fetch" response packet, validation ID position +#define GZP_CMD_HOST_ID_FETCH_RESP_STATUS (GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Host ID fetch" response packet, status position +#define GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID (GZP_CMD_HOST_ID_FETCH_RESP_STATUS + 1) ///< "Host ID fetch" response packet, Host ID position +#define GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH (GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID + GZP_HOST_ID_LENGTH) ///< "Host ID fetch" response packet, payload length + +#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH) + #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH. +#endif + + +#define GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN 1 ///< "Key update prepare" response packet, session token position +#define GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH (GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN + GZP_SESSION_TOKEN_LENGTH) ///< "Key update prepare" response packet, payload length position + +#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH) + #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH. +#endif + + +#define GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN 1 ///< "Encrypted user data" response packet, session token position +#define GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID (GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN + GZP_SESSION_TOKEN_LENGTH) ///< "Encrypted user data" response packet, validation ID position +#define GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH (GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Encrypted user data" response packet, payload length position + +#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH) + #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH. +#endif + +#if (GZP_VALIDATION_ID_LENGTH > GZP_HOST_ID_LENGTH) + #error GZP_HOST_ID_LENGTH should be greater or equal to GZP_VALIDATION_ID_LENGTH. +#endif + +#if (GZP_SESSION_TOKEN_LENGTH != GZP_HOST_ID_LENGTH) + #error GZP_SESSION_TOKEN_LENGTH must equal GZP_HOST_ID_LENGTH. +#endif + +#ifdef GZLL_CRYPT_ENABLE + #error Gazell encryption can not be enabled when using the Gazell pairing library. \ + GZLL_CRYPT_ENABLE must be undefined. +#endif + +/** @} */ + + +/******************************************************************************/ +/** @name Typedefs + * @{ */ +/******************************************************************************/ + + +/** + * @enum gzp_key_select_t + * @brief Enumerator used for selecting the key to be used for encryption. + */ +typedef enum +{ + GZP_ID_EXCHANGE, ///< "Secret key" only + GZP_KEY_EXCHANGE, ///< "Secret key" and "Host ID" + GZP_DATA_EXCHANGE ///< "Dynamic key" and "Host ID" +} gzp_key_select_t; + + +/** + * @enum gzp_cmd_t + * @brief Enumerator used in the first payload byte of each packet to + * indicate the packet type. + */ +typedef enum +{ + GZP_CMD_HOST_ADDRESS_REQ = 0, ///< Host address request + GZP_CMD_HOST_ADDRESS_FETCH, ///< Host address fetch + GZP_CMD_HOST_ID_REQ, ///< Host ID request + GZP_CMD_HOST_ID_FETCH, ///< Host ID fetch request + GZP_CMD_KEY_UPDATE_PREPARE, ///< Key update prepare + GZP_CMD_KEY_UPDATE, ///< Key update + GZP_CMD_ENCRYPTED_USER_DATA, ///< Encrypted user data + GZP_CMD_FETCH_RESP, ///< Fetch response + GZP_CMD_HOST_ADDRESS_RESP, ///< Host address response + GZP_CMD_HOST_ID_FETCH_RESP, ///< Host ID fetch response + GZP_CMD_KEY_UPDATE_PREPARE_RESP, ///< Key update prepare + GZP_CMD_ENCRYPTED_USER_DATA_RESP, ///< Encrypted user data response +} gzp_cmd_t; + + +/** + * @enum gzp_id_req_res_t + * @brief Enumerator used to identify the state of the current + * Host ID request. + */ +typedef enum +{ + GZP_ID_RESP_PENDING, ///< ID response pending + GZP_ID_RESP_GRANTED, ///< ID response granted + GZP_ID_RESP_REJECTED, ///< ID response rejected + GZP_ID_RESP_FAILED, ///< ID response failed + GZP_ID_RESP_NO_REQUEST ///< Default value. No ID request has yet been received. +} gzp_id_req_res_t; + + +/** @} */ + + +/******************************************************************************/ +/** @name Misc. function prototypes + * @{ */ +/******************************************************************************/ + +/** + * Set the session token. + * + * @param token Pointer to the session token to set. + */ +void gzp_crypt_set_session_token(const uint8_t *token); + + +/** + * Get the session token. + * + * @param dst_token Pointer to write the session token. + */ +void gzp_crypt_get_session_token(uint8_t *dst_token); + + +/** + * Set the dynamic key. + * + * @param dyn_key Pointer to the dynamic key to set. + */ +void gzp_crypt_set_dyn_key(const uint8_t* dyn_key); + + +/** + * Get the dynamic key. + * + * @param dst_key Pointer to write the dynamic key too. + */ +void gzp_crypt_get_dyn_key(uint8_t *dst_key); + + +/** + * Set the Host ID. + * + * @param src Pointer to the Host ID to set. + */ +static void gzp_set_host_id(const uint8_t* src); + + +/** + * Get the Host ID. + * + * @param dst Pointer to write the Host ID to. + */ +void gzp_get_host_id(uint8_t *dst); + + +/** + * Selecting what key-set that should be used when encrypting data + * using gzp_crypt(). + * + * @param key_select Key-set to use. + */ +void gzp_crypt_select_key(gzp_key_select_t key_select); + + +/** + * Encypt / decrypt data. + * + * The current "session token" will be used as initialization vector (IV). + * The AES key to be used is selected by gzp_crypt_select_key(). + * AES is a symmetric encryption scheme, this function can be used + * to perform both encryption and decryption. + * + * @param dst Destination to write encrypted data to. Should be 16 bytes long. + * @param src Source data to encrypt. + * @param length Length in bytes of src. + */ +void gzp_crypt(uint8_t* dst, const uint8_t* src, uint8_t length); + + +/** + * Compare the *src_id with a pre-defined validation ID. + * + * @param src_id Pointer to the source validation ID to compare to. + * + * @retval true If *src_id equals the pre-defined ID. + * @retval false If *src_id does not equal the pre-defined ID. + */ +bool gzp_validate_id(const uint8_t *src_id); + + +/** + * Add the pre-defined validation ID to dst_id. + * GZP_VALIDATION_ID_LENGTH bytes will be added. + * + * @param dst_id Pointer to add the GZP validation ID to. + */ +void gzp_add_validation_id(uint8_t *dst_id); + + +/** + * Generate random bytes. + * + * @param dst Destination to write the random bytes to. + * @param n Number of bytes to generate. + */ +void gzp_random_numbers_generate(uint8_t *dst, uint8_t n); + + +/** + * Update the channel table and the system address. + * + * The channel table is updated to pseudo-random set generated using the + * system address. The channel table still includes GZP_CHANNEL_MAX and + * GZP_CHANNEL_MIN. + * The system address is applied to base address 1 and therefore applies + * to pipes 1-7. + * + * @param system_address Pointer to the system_address to set. + * + * @retval true If theradio parameters were updated successfully. + * @retval false If there was an error updated the radio parameters. + */ +bool gzp_update_radio_params(const uint8_t *system_address); + + +/** + * Generate a set of channels from a 4 byte address. + * + * @param ch_dst Destination to write the channel set to. The channel set + * includes GZP_CHANNEL_MAX and GZP_CHANNEL_MIN. + * @param address Four byte address to generate the channel set from. + * @param channel_set_size Size of the channel set to generate. + */ +void gzp_generate_channels(uint8_t *ch_dst, const uint8_t * address, uint8_t channel_set_size); + + +/** + * Perform an XOR on two byte strings. + * + * @param dst Destination to write the result to. Should be of size length. + * @param src + * @param pad + * @param length Number of bytes to perform the XOR operation on. + */ +void gzp_xor_cipher(uint8_t* dst, const uint8_t* src, const uint8_t* pad, uint8_t length); + + +/******************************************************************************/ +/** @name Common Device and Host functions + * @{ */ +/******************************************************************************/ + + +/** + * Initialization function. This function initializes the Gazell Pairing Library. + + * This function must be called before any of the other Gazell Pairing Library functions are + * used and must be called @b after gzll_init() is called. + * + */ +void gzp_init(void); + +/** + * Function for erasing all pairing data. + */ +void gzp_erase_pairing_data(void); + +/** + * Disable Gazell and sleep while waiting for nrf_gzll_disabled callback. + */ +void nrf_gzp_disable_gzll(void); + +/** + Function for cancelling an ongoing (pending) "Host ID request". + + After calling this function the "Host ID request" status will go to + "ID request Idle". +*/ +void gzp_id_req_cancel(void); + +/** + * Flush the GZLL RX FIFO for a specific pipe while GZLL is disabled. + * + * @param pipe Pipe. + */ +void nrf_gzp_flush_rx_fifo(uint32_t pipe); + +/** +@name Device functions +*/ + +/** + * Check whether current GZP packet transaction has completed. + * + * @retval true + * @retval false + */ +bool nrf_gzp_tx_complete(void); + +/** + * Check whether previous GZP packet transaction was successful. + * + * @retval true + * @retval false + */ +bool nrf_gzp_tx_success(void); + +/** + * Reset tx_complete status. + */ +void nrf_gzp_reset_tx_complete(void); + +/** + * Reset tx_success status. + */ +void nrf_gzp_reset_tx_success(void); + +/** +* Function to check whether a Device has existing pairing data, implying that it is +* paired to a Host. +* +* @retval -2 The pairing database is empty. +* @retval -1 The device has a system address but no Host ID. +* @retval >=0 The device has a system address and HostID at this index value in the database. +*/ +int8_t gzp_get_pairing_status(void); + +/** + Function for sending a "system address" request to a Host. + + When calling this function the Device will attempt acquiring the "system address" from + any Host within close proximity. + + If a host is located within close proximity and pairing is enabled in the Host, + a "system address" will be sent in return to the Device. + + The new "system address" will apply immediately in the Device, and the new "system address" + will be stored in non volatile (NV) memory. + + Note. Using OTP devices limits the number of times a new "system address" can + be stored in NV memory. + + @return + + @retval true if new "system address" was received from a Host. + @retval false if no "system address" was received from a Host. +*/ +bool gzp_address_req_send(void); + +/** + Function for sending a "Host ID request" to a Host. + + The "Host ID" is needed to be able to send encrypted data using + gzp_crypt_data_send(). + + The request will be sent using the "system address" previously received using + gzp_address_req_send(). + + It is not required that the Host is within close proximity in order to acquire the + "Host ID". + + The new "Host ID" will apply immediately for the Device, and the new "Host ID" + will be stored in non volatile (NV) memory. + + Note. Using OTP devices limits the number of times a new "Host ID" can + be stored in NV memory. + + @return + + @retval GZP_ID_RESP_PENDING if a "Host ID request" has been sent to the Host, but the Host application has + not yet decided whether to Grant or Reject the "ID request". + @retval GZP_ID_RESP_GRANTED if the "Host ID" has been received from the Host. The received "Host ID" will be stored + in non volatile memory. + @retval GZP_ID_RESP_REJECTED if the Host application has rejected the "Host ID request". + @retval GZP_ID_RESP_FAILED if failing to send a request or receive a response from the Host. +*/ +gzp_id_req_res_t gzp_id_req_send(void); + +/** + Function for sending encrypted user data to the Host. + + Before any data can be sent the Device must acquire both the Host's + "system address" by using gzp_address_req_send() and the "Host ID" by using + gzp_id_req_send(). + + @param *src is a pointer to the data packet to be sent. + @param length is the length of the data packet to be sent. + + + @return + @retval true if the data was successfully transmitted and decrypted by the Host. + @retval false if data transmission failed or Host failed to decryption data correctly. +*/ +bool gzp_crypt_data_send(const uint8_t *src, uint8_t length); + + +/** +@name Host functions +*/ + +/** + Function for enabling/disabling pairing in a host. When pairing is enabled the host will + be monitoring for "system address" and "Host ID" requests from Devices. + + A "system address request" received from a Device will always be granted. + When a "host ID request" has been received, the Host application have to grant, + reject or cancel this by using one of the following functions: + + - gzp_id_req_grant() + - gzp_id_req_reject() + - gzp_id_req_cancel() + + @param enable + @arg true enables pairing. + @arg false disables pairing. +*/ +void gzp_pairing_enable(bool enable); + +/** + * Execute the Gazell Pairing Library Host operation. + * + * This function must be called regularly by the Host application. + */ +void gzp_host_execute(void); + +/** + * Address exchanged check. + * + * @retval true If a "system address" was delivered to a requesting Device during the + * previous call to gzp_host_execute(); + * @retval false Otherwise. +*/ +bool gzp_address_exchanged(void); + +/** + Function for checking if a "Host ID request" has been received from a Device. + + If a request has been received, the Pairing library will enter "ID request pending" + state. + + The application is responsible for responding to this request by calling + one of the following functions: + + - gzp_id_req_grant() + - gzp_id_req_reject() + - gzp_id_req_cancel() + + @retval true if a "Host ID request" has been received (internal state is "ID request pending") + @retval false if no "Host ID request" has been received (internal state is "ID request idle") +*/ +bool gzp_id_req_received(void); + +/** + Function for rejecting the previously received "Host ID request". This function should be called + only when a "Host ID request" has been received (internal state is "ID request pending"). + + The internal state of the Pairing library will remain "ID request pending" until the a "reject" message + has been successfully transmitted to the requesting Device. After this the internal state will + change to "ID request idle". +*/ +void gzp_id_req_reject(void); + +/** + * Function for granting the previously received "Host ID request". This function should be called + only when a "Host ID request" has been received (internal state is "ID request pending"). + + The internal state of the Pairing library will remain "ID request pending" until the "Host ID" has + been successfully transmitted to the requesting Device. After this the internal state will + change to "ID request idle". +*/ +void gzp_id_req_grant(void); + + +/** + * Check if user data has been received. + * + * @retval true If encrypted user data has been received. + * @retval false Otherwise. +*/ +bool gzp_crypt_user_data_received(void); + +/** + Function for reading encrypted user data. + + Note that the read user data will be automatically decrypted. Only data + that was decrypted correctly will be presented. + + @param dst* is a pointer to where the received data will be written. + @param length* is a pointer for returning the number of bytes received. Only 1 byte will + be writtem to length*. + + @return + @retval true if data has been received and is written to dst* + @retval false if no data has been received. +*/ +bool gzp_crypt_user_data_read(uint8_t* dst, uint8_t* length); + + +/** + Function emulating behavior of gzll_rx_start() in legeacy nRF24xx Gaell + linbrary. + + This functions sets Gazell in Host mode and starts reception (enable). +*/ +void gzll_rx_start(void); + + +/** @} */ +/** @} */ +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp_device.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp_device.c new file mode 100644 index 0000000000000000000000000000000000000000..f79a569fb28c064dbfcaef82f5b85d5c778b958e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp_device.c @@ -0,0 +1,1143 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief Implementation of Gazell Pairing Library (gzp), Device functions. + * @defgroup gzp_source_device Gazell Pairing Device implementation. + * @{ + * @ingroup gzp_04_source + */ + + +#include +#include +#include + +#include "nrf_gzll.h" +#include "nrf_gzp.h" +#include "nrf_delay.h" +#include "nrf_nvmc.h" + +#define SOURCE_FILE NRF_SOURCE_FILE_GZP_DEVICE ///< File identifer for asserts. + +/******************************************************************************/ +/** @name Misc. defines + * @{ */ +/******************************************************************************/ + +#define GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS 0 ///< System address position. +#define GZP_PARAMS_DB_ELEMENT_HOST_ID (GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS + GZP_SYSTEM_ADDRESS_WIDTH) ///< Host ID position +#define GZP_PARAMS_DB_ELEMENT_SIZE (GZP_SYSTEM_ADDRESS_WIDTH + GZP_HOST_ID_LENGTH)///< Total size +#define GZP_PARAMS_DB_MAX_ENTRIES 14 ///< Maximum allowed entries in the database. + +/** @} */ + +/******************************************************************************/ +/** @name Derived parameters + * @{ */ +/******************************************************************************/ + +//lint -esym(40, GZP_PARAMS_STORAGE_ADR) "Undeclare identifier" +#define GZP_PARAMS_DB_ADR GZP_PARAMS_STORAGE_ADR ///< +#define GZP_PARAMS_DB_SIZE (GZP_PARAMS_DB_MAX_ENTRIES * GZP_PARAMS_DB_ELEMENT_SIZE) ///< + +#define GZP_INDEX_DB_ADR (GZP_PARAMS_STORAGE_ADR + GZP_PARAMS_DB_SIZE) ///< +#define GZP_INDEX_DB_SIZE (GZP_DEVICE_PARAMS_STORAGE_SIZE - GZP_PARAMS_DB_SIZE) ///< + +#if (GZP_DEVICE_PARAMS_STORAGE_SIZE < GZP_PARAMS_DB_SIZE) + #error GZP_DEVICE_PARAMS_STORAGE_SIZE must be greater or equal to GZP_PAIRING_PARAMS_DB_SIZE +#elif (GZP_DEVICE_PARAMS_STORAGE_SIZE == GZP_PARAMS_DB_SIZE ) + #warning GZP_DEVICE_PARAMS_STORAGE_SIZE to low to be able store any pairing parameters NV memory +#endif +/** @} */ + + +/******************************************************************************/ +/** @name Typedefs + * @{ */ +/******************************************************************************/ + + +/** + * Possible return values for the function gzp_tx_rx_transaction() + */ +typedef enum +{ + GZP_TX_RX_SUCCESS, ///< ACK received. Transaction successful. + GZP_TX_RX_FAILED_TO_SEND, ///< + GZP_TX_RX_NO_RESPONSE ///< +} gzp_tx_rx_trans_result_t; +/** @} */ + + +/******************************************************************************/ +/** @name Internal variables + * @{ */ +/******************************************************************************/ + +static uint8_t gzp_system_address[GZP_SYSTEM_ADDRESS_WIDTH]; ///< +static uint8_t gzp_host_id[GZP_HOST_ID_LENGTH]; ///< +static uint8_t dyn_key[GZP_DYN_KEY_LENGTH]; +static bool gzp_id_req_pending = false; + +/** @} */ + + +/******************************************************************************/ +/** @name Internal (static) function prototypes + * @{ */ +/******************************************************************************/ + +/** + * Function for sending an encrypted packet. + * + * The function waits for the transmission to complete. + * + * @param tx_packet Pointer to the packet to be sent. + * @param length Length of the packet to be sent. + * @param pipe Pipe on which the packet should be sent. + * + * @retval true If the transmission succeeded. + * @retval false If the transmission failed (timed out). + */ +static bool gzp_tx_packet(const uint8_t* tx_packet, uint8_t length, uint8_t pipe); + +/** + * Function sending the packet *tx_packet and a subsequent packet fetching the response + * to *tx_packet. + * + * @param tx_packet is a pointer to the packet to be sent. + * @param tx_length is the length of the packet to be sent. + * @param rx_dst is a pointer to where the received response packet should be stored. + * @param rx_length is a pointer to where the length of the received packet should be stored. + * @param pipe is the pipe on which the packet should be sent. + * + * @return result of the transaction. + */ + static gzp_tx_rx_trans_result_t gzp_tx_rx_transaction(const uint8_t *tx_packet, uint8_t tx_length, uint8_t *rx_dst, uint32_t *rx_length, uint8_t pipe); + +/** + * Function for sending an encrypted packet. The function detects whether the correct + * key was used, and attempts to send a "key update" to the host if the wrong key was being + * used. + + * @param tx_packet is a pointer to the packet to be sent. + * @param length is the length of the packet to be sent. + + * @retval true if transmission succeeded and packet was decrypted correctly by host. + * @retval false if transmission failed or packet was not decrypted correctly by host. + */ +static bool gzp_crypt_tx_transaction(const uint8_t *tx_packet, uint8_t length); + +/** + * Function updateing the "dynamic key" and sending a "key update" to the host. + * + * @retval true if key update succeeded. + * @retval false if if key update failed. + */ +static bool gzp_key_update(void); + +/** + * Function for adding an element to "parameters data base" in non volatile (NV) memory. An element is + * GZP_PARAMS_ELEMENT_SYSTEM_ADDRESS bytes long, holding the "system address" and "host ID". + * + * The "parameters data base" can store up to GZP_DEVICE_PAIRING_PARAMS_DB_MAX_ENTRIES + * elements. + * + * @param src_element is a pointer to the element. + * @param index is a number between 0 and (GZP_PARAMS_DB_MAX_ENTRIES - 1) + * selecting the location in which the element will be stored. + */ +static void gzp_params_db_add(const uint8_t *src_element, uint8_t index); + +/** + * Function for reading an element from "parameters data base" in non volatile (NV) memory. An element is + * GZP_PARAMS_ELEMENT_SYSTEM_ADDRESS bytes long, holding the "system address" and "host ID". + * + * @param dst_element is a pointer where the read element should be stored. + * @param index is a number between 0 and (GZP_PARAMS_DB_MAX_ENTRIES - 1). + * selecting the location that should be read. + */ +static void gzp_params_db_read(uint8_t* dst_element, uint8_t index); + +/** + * Function for writing an index to the "index data base" in non volatile (NV) memory. + * + * @param index is the index to be written to the data base. + */ +static void gzp_index_db_add(uint8_t index); + +/** + * Function for reading the index previously written to the "index data base" in NV memory. + * + * @return + */ +static uint8_t gzp_index_db_read(void); + +/** + * Check "index data base" is full. + * + * @retval true + * @retval false + */ +static bool gzp_index_db_full(void); + +/** + * Function returning @b true if the "index data base" is empty. + * + * @retval true + * @retval false + */ +static bool gzp_index_db_empty(void); + +/** + * Function returning @b true if array contains only 1s (0xff). + * + * @param *src is a pointer to the array to be evaluated. + * @param length is the length of the array to be evaluated. + * + * @retval true + * @retval false + */ +static bool gzp_array_is_set(const uint8_t* src, uint8_t length); + +/** + * Function for storing the current "system address" and "host ID" in NV memory. + * + * @param store_all selects whether only "system address" or both "system address" and + * "host ID" should be stored. + * @arg true selects that both should be stored. + * @arg false selects that only "system address" should be stored. + * + * @retval true + * @retval false + */ +static bool gzp_params_store(bool store_all); + +/** + * Restore the "system address" and "host ID" from NV memory. + * @retval true + * @retval false + */ +static bool gzp_params_restore(void); + +/** + * Delay function. Will add a delay equal to GZLL_RX_PERIOD * rx_periods [us]. + * + * @param rx_periods + */ +void gzp_delay_rx_periods(uint32_t rx_periods); + +/** + * Delay function. Will add a delay equal to GZLL_RX_PERIOD * rx_periods [us] using the + * gazell timer and not a delay loop. + * + * @param rx_periods + */ +void gzp_tick_sleep_rx_periods(uint32_t rx_periods); + +/* + * Print debug string. By default does nothing. + * + * If GZP_DEBUG is defined then the print string function is required to + * be implemented. + */ +void print_string(char* p_expr); + +/** @} */ + +/******************************************************************************/ +/** @name Internal (static) variables + * @{ */ +/******************************************************************************/ + +static nrf_gzll_device_tx_info_t latest_tx_info; ///< Information about the last TX attempt, e.g. RSSI of ACK. + +static volatile bool tx_complete; ///< Flag to indicate whether a GZLL TX attempt has completed. +static bool tx_success; ///< Flag to indicate whether a GZLL TX attempt was successful. + +#if defined(__ICCARM__) + #if GZP_PARAMS_DB_ADR == 0x1000 + static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE/4] @ "gzp_dev_data" + #elif GZP_PARAMS_DB_ADR == 0x15000 + static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE/4] @ "gzp_dev_data_sd" + #else + #error + #endif +#else +static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE / 4] __attribute__((at(GZP_PARAMS_DB_ADR))) +#endif += { +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF +}; ///< Database for storing keys. + + +/** @} */ + + +/******************************************************************************/ +// Implementation: Device-specific API functions +/******************************************************************************/ + + +void gzp_init() +{ + gzp_id_req_pending = false; + +#ifndef GZP_NV_STORAGE_DISABLE + (void)gzp_params_restore(); +#endif + + // Update radio parameters from gzp_system_address + (void)gzp_update_radio_params(gzp_system_address); +} + + +void gzp_erase_pairing_data(void) +{ + // Erase database flash page so that it can be later written to. + nrf_nvmc_page_erase((uint32_t)database); +} + +bool gzp_address_req_send() +{ + //lint -save -e514 Unusual use of a Boolean expression (gzll_update_ok &= ...) + uint8_t i; + bool retval = false; + bool success; + uint8_t address_req[GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH]; + uint8_t rx_payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH]; + uint32_t rx_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; + nrf_gzll_tx_power_t temp_power; + uint32_t temp_max_tx_attempts; + bool gzll_update_ok = true; + + + // Store parameters that are temporarily changed + temp_max_tx_attempts = nrf_gzll_get_max_tx_attempts(); + temp_power = nrf_gzll_get_tx_power(); + + // Modify parameters + nrf_gzp_disable_gzll(); + gzll_update_ok &= nrf_gzll_set_max_tx_attempts(GZP_REQ_TX_TIMEOUT); + gzll_update_ok &= nrf_gzll_set_tx_power(GZP_POWER); + + // Flush RX FIFO + gzll_update_ok &= nrf_gzll_flush_rx_fifo(GZP_PAIRING_PIPE); + gzll_update_ok &= nrf_gzll_enable(); + // Build "request" packet + address_req[0] = (uint8_t)GZP_CMD_HOST_ADDRESS_REQ; + + // Send a number of packets in order to broadcast that devices not within + // close proximity must back off. + for (i = 0; i < GZP_MAX_BACKOFF_PACKETS; i++) + { + success = gzp_tx_packet(address_req, GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, GZP_PAIRING_PIPE); + if (success) + { + nrf_gzp_flush_rx_fifo(GZP_PAIRING_PIPE); + } + else + { + break; + } + } + + gzp_delay_rx_periods(GZP_TX_ACK_WAIT_TIMEOUT); + // Send message for fetching pairing response from host. + address_req[0] = (uint8_t)GZP_CMD_HOST_ADDRESS_FETCH; + + success = gzp_tx_packet(address_req, GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, GZP_PAIRING_PIPE); + if (success && latest_tx_info.payload_received_in_ack) + { + // If pairing response received + if (nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE) > 0) + { + rx_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; //dummy placeholder + if (nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, rx_payload, &rx_payload_length)) + { + if (rx_payload[0] == (uint8_t)GZP_CMD_HOST_ADDRESS_RESP) + { + memcpy(gzp_system_address, &rx_payload[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH); + gzll_update_ok &= gzp_update_radio_params(&rx_payload[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS]); + #ifndef GZP_NV_STORAGE_DISABLE + (void)gzp_params_store(false); // "False" indicates that only "system address" part of DB element will be stored + #endif + retval = true; + } + } + } + } + else + { + gzp_delay_rx_periods(GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT - GZP_TX_ACK_WAIT_TIMEOUT); + } + gzp_delay_rx_periods(GZP_STEP1_RX_TIMEOUT); + + // Clean-up and restore parameters temporarily modified + nrf_gzp_disable_gzll(); + gzll_update_ok &= nrf_gzll_flush_rx_fifo(GZP_PAIRING_PIPE); + gzll_update_ok &= nrf_gzll_flush_tx_fifo(GZP_PAIRING_PIPE); + gzll_update_ok &= nrf_gzll_set_max_tx_attempts(temp_max_tx_attempts); + gzll_update_ok &= nrf_gzll_set_tx_power(temp_power); + gzll_update_ok &= nrf_gzll_enable(); + + if (!gzll_update_ok) + { + /* + The update of the Gazell parameters failed. Use nrf_gzll_get_error_code() + to investigate the cause. + */ + } + + return retval; + //lint -restore +} + +#ifndef GZP_CRYPT_DISABLE + +gzp_id_req_res_t gzp_id_req_send() +{ + uint8_t tx_packet[GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH]; + uint8_t rx_packet[GZP_MAX_ACK_PAYLOAD_LENGTH]; + gzp_tx_rx_trans_result_t trans_result; + + // If no ID request is pending, send new "ID request" + if (!gzp_id_req_pending) + { + // Build "Host ID request packet" + tx_packet[0] = (uint8_t)GZP_CMD_HOST_ID_REQ; + + // Generate new session token + gzp_random_numbers_generate(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_SESSION_TOKEN_LENGTH); + + // Send "Host ID request" + if (gzp_tx_packet(tx_packet, GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH, GZP_DATA_PIPE)) + { + // Update session token if "Host ID request" was successfully transmitted + gzp_crypt_set_session_token(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN]); + gzp_id_req_pending = true; + + return GZP_ID_RESP_PENDING; + } + } + else // If "ID request is pending" send "fetch ID" packet + { + // Build "host ID fetch" packet + tx_packet[0] = (uint8_t)GZP_CMD_HOST_ID_FETCH; + gzp_add_validation_id(&tx_packet[GZP_CMD_HOST_ID_FETCH_VALIDATION_ID]); + + // Encrypt "host ID fetch" packet + gzp_crypt_select_key(GZP_ID_EXCHANGE); + gzp_crypt(&tx_packet[1], &tx_packet[1], GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH - 1); + + trans_result = gzp_tx_rx_transaction(tx_packet, GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE); + // If packet was successfully sent AND a response packet was received + if (trans_result == GZP_TX_RX_SUCCESS) + { + // Validate response packet + if (rx_packet[0] == (uint8_t)GZP_CMD_HOST_ID_FETCH_RESP) + { + gzp_crypt(&rx_packet[1], &rx_packet[1], GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH - 1); + if (gzp_validate_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID])) + { + switch (rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS]) + { + case GZP_ID_RESP_PENDING: + break; + case GZP_ID_RESP_REJECTED: + gzp_id_req_pending = false; + break; + case GZP_ID_RESP_GRANTED: + gzp_set_host_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID]); + gzp_random_numbers_generate(dyn_key, GZP_DYN_KEY_LENGTH); + gzp_crypt_set_dyn_key(dyn_key); + #ifndef GZP_NV_STORAGE_DISABLE + (void)gzp_params_store(true); + #endif + gzp_id_req_pending = false; + break; + default: + break; + } + + return (gzp_id_req_res_t)rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS]; + } + else + { + gzp_id_req_pending = false; + return GZP_ID_RESP_REJECTED; + } + } + } + } + + gzp_id_req_pending = false; + return GZP_ID_RESP_FAILED; +} + +void gzp_id_req_cancel() +{ + gzp_id_req_pending = false; +} + +bool gzp_crypt_data_send(const uint8_t *src, uint8_t length) +{ + if (length <= GZP_ENCRYPTED_USER_DATA_MAX_LENGTH) + { + if (gzp_crypt_tx_transaction(src, length)) + { + return true; + } + else + { + //print_string("GZP_CRYPT_TX failed\r\n"); + // Attempt key update if user data transmission failed + // during normal operation (!gzp_id_req_pending) + if (!gzp_id_req_pending) + { + //print_string("KEY UPDATE\r\n"); + if (gzp_key_update()) + { + return gzp_crypt_tx_transaction(src, length); + } + } + return false; + } + } + else + { + return false; + } +} + +#endif +/** @} */ + + +/******************************************************************************/ +// Implementation: Internal (static) functions +/******************************************************************************/ + +static bool gzp_tx_packet(const uint8_t* tx_packet, uint8_t length, uint8_t pipe) +{ + tx_complete = false; + tx_success = false; + + if (nrf_gzll_add_packet_to_tx_fifo(pipe,(uint8_t *)tx_packet, length)) + { + while (tx_complete == false) + { + __WFI(); + } + return tx_success; + } + else + { + return false; + } +} + +static gzp_tx_rx_trans_result_t gzp_tx_rx_transaction(const uint8_t *tx_packet, uint8_t tx_length, uint8_t *rx_dst, uint32_t *rx_length, uint8_t pipe) +{ + + gzp_tx_rx_trans_result_t retval; + uint8_t fetch_packet[GZP_CMD_FETCH_RESP_PAYLOAD_LENGTH]; + bool tx_packet_success; + bool fetch_success; + uint32_t local_rx_length = GZP_MAX_ACK_PAYLOAD_LENGTH; + uint32_t temp_lifetime; + + nrf_gzp_flush_rx_fifo(pipe); + + retval = GZP_TX_RX_FAILED_TO_SEND; + + (void)nrf_gzll_disable(); + while (nrf_gzll_is_enabled()) + {} + temp_lifetime = nrf_gzll_get_sync_lifetime(); + (void)nrf_gzll_set_sync_lifetime(GZP_TX_RX_TRANS_DELAY * 3); // 3 = RXPERIOD * 2 + margin + (void)nrf_gzll_enable(); + + tx_packet_success = gzp_tx_packet(tx_packet, tx_length, pipe); + + if (tx_packet_success) + { + retval = GZP_TX_RX_NO_RESPONSE; + + nrf_gzp_flush_rx_fifo(pipe); + + fetch_packet[0] = (uint8_t)GZP_CMD_FETCH_RESP; + + gzp_tick_sleep_rx_periods(GZP_TX_RX_TRANS_DELAY); + + tx_packet_success = gzp_tx_packet(fetch_packet, GZP_CMD_FETCH_RESP_PAYLOAD_LENGTH, pipe); + + if (tx_packet_success) + { + if (nrf_gzll_get_rx_fifo_packet_count(pipe)) + { + local_rx_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; + fetch_success = nrf_gzll_fetch_packet_from_rx_fifo(pipe, rx_dst, &local_rx_length); + } + else + { + fetch_success = false; + } + + if (fetch_success) + { + retval = GZP_TX_RX_SUCCESS; + } + else + { + //print_string("GZP_TX_FETCH_FAILED\r\n"); + } + } + else + { + //print_string("GZP_TX_FETCH_NO_ACK\r\n"); + } + } + + (void)nrf_gzll_disable(); + while (nrf_gzll_is_enabled()) + {} + (void)nrf_gzll_set_sync_lifetime(temp_lifetime); + (void)nrf_gzll_enable(); + + return retval; +} + +#ifndef GZP_CRYPT_DISABLE + +static bool gzp_crypt_tx_transaction(const uint8_t *src, uint8_t length) +{ + uint8_t tx_packet[GZP_MAX_FW_PAYLOAD_LENGTH]; + uint8_t rx_packet[GZP_MAX_ACK_PAYLOAD_LENGTH]; + uint8_t tx_packet_length; + + gzp_tx_rx_trans_result_t result; + + tx_packet_length = length + (uint8_t)GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD; + + // Assemble tx packet + tx_packet[0] = (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA; + gzp_add_validation_id(&tx_packet[GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID]); + memcpy(&tx_packet[GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD], (uint8_t*)src, length); + + // Encrypt tx packet + if (gzp_id_req_pending) + { + gzp_crypt_select_key(GZP_ID_EXCHANGE); + } + else + { + gzp_crypt_select_key(GZP_DATA_EXCHANGE); + } + gzp_crypt(&tx_packet[1], &tx_packet[1], tx_packet_length - 1); + + // If packet was successfully sent AND a response packet was received + result = gzp_tx_rx_transaction(tx_packet, tx_packet_length, rx_packet, NULL, GZP_DATA_PIPE); + if (result == GZP_TX_RX_SUCCESS) + { + if (rx_packet[0] == (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA_RESP) + { + gzp_crypt(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], &rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], GZP_VALIDATION_ID_LENGTH); + + // Validate response in order to know whether packet was correctly decrypted by host + if (gzp_validate_id(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID])) + { + // Update session token if normal operation (!gzp_id_req_pending) + if (!gzp_id_req_pending) + { + gzp_crypt_set_session_token(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]); + } + return true; + } + else + { + //print_string("GZP_CRYPT_TX_TRANS: Validation ID bad\r\n"); + return false; + } + } + else + { + //print_string("GZP_CRYPT_TX_TRANS: Bad CMD. \r\n"); + return false; + } + } + else + { + //print_string("GZP_CRYPT_TX_TRANS: gzp_tx_rx_trans not SUCCESS\r\n"); + return false; + } +} + +static bool gzp_key_update(void) +{ + uint8_t tx_packet[GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH], rx_packet[GZP_MAX_ACK_PAYLOAD_LENGTH]; + + // Send "prepare packet" to get session token to be used for key update + tx_packet[0] = (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE; + + // If packet was successfully sent AND a response packet was received + if (gzp_tx_rx_transaction(tx_packet, GZP_CMD_KEY_UPDATE_PREPARE_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE) == GZP_TX_RX_SUCCESS) + { + if (rx_packet[0] == (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE_RESP) + { + gzp_crypt_set_session_token(&rx_packet[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]); + + // Build "key update" packet + tx_packet[0] = (uint8_t)GZP_CMD_KEY_UPDATE; + gzp_add_validation_id(&tx_packet[GZP_CMD_KEY_UPDATE_VALIDATION_ID]); + gzp_random_numbers_generate(&tx_packet[GZP_CMD_KEY_UPDATE_NEW_KEY], GZP_DYN_KEY_LENGTH); + gzp_crypt_set_dyn_key(&tx_packet[GZP_CMD_KEY_UPDATE_NEW_KEY]); + + // Encrypt "key update packet" + gzp_crypt_select_key(GZP_KEY_EXCHANGE); + gzp_crypt(&tx_packet[1], &tx_packet[1], GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH - 1); + + // Send "key update" packet + if (gzp_tx_packet(tx_packet, GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH, GZP_DATA_PIPE)) + { + return true; + } + } + } + + return false; +} + +#endif + +void gzp_set_host_id(const uint8_t * id) +{ + memcpy(gzp_host_id, id, GZP_HOST_ID_LENGTH); +} + +void gzp_get_host_id(uint8_t * dst_id) +{ + memcpy(dst_id, gzp_host_id, GZP_HOST_ID_LENGTH); +} + +static void gzp_params_db_add(const uint8_t* src_element, uint8_t index) +{ + nrf_nvmc_write_bytes((GZP_PARAMS_DB_ADR + (index * GZP_PARAMS_DB_ELEMENT_SIZE)), src_element, (uint32_t)GZP_PARAMS_DB_ELEMENT_SIZE); +} + + +static void gzp_params_db_read(uint8_t* dst_element, uint8_t index) +{ + memcpy(dst_element,(uint8_t*)(GZP_PARAMS_DB_ADR + (index * GZP_PARAMS_DB_ELEMENT_SIZE)), GZP_PARAMS_DB_ELEMENT_SIZE); +} + + +static void gzp_index_db_add(uint8_t val) +{ + int16_t i; + uint8_t temp_val; + uint32_t addr; + + // Search for unwritten loacation in index DB + for (i = 0; i < GZP_INDEX_DB_SIZE; i++) + { + temp_val = *(uint8_t*)(GZP_INDEX_DB_ADR + i); + + // Lower nibble + if (i != (GZP_INDEX_DB_SIZE - 1)) + { + if ((temp_val & 0x0f) == 0x0f) + { + temp_val = (temp_val & 0xf0) | val; + break; + } + // Upper nibble + else if ((temp_val & 0xf0) == 0xf0) + { + temp_val = (temp_val & 0x0f) | (val << 4); + break; + } + } + else + { + temp_val = (GZP_PARAMS_DB_MAX_ENTRIES << 4) | val; + break; + } + } + + // Write index DB + addr = (GZP_INDEX_DB_ADR + i); + nrf_nvmc_write_byte(addr, temp_val); +} + +static uint8_t gzp_index_db_read() +{ + uint8_t retval; + int16_t i; + + // Search for previously written location + for (i = (GZP_INDEX_DB_SIZE - 1); i >= 0; i--) + { + retval = *(uint8_t*)(GZP_INDEX_DB_ADR + i); + + if (retval != 0xff) + { + break; + } + } + + if (retval == 0xff) + { + retval = GZP_PARAMS_DB_MAX_ENTRIES; // index db empty + } + else if ((retval & 0xf0) != 0xf0) + { + retval >>= 4; + } + else + { + retval &= 0x0f; + } + + return retval; +} + +int8_t gzp_get_pairing_status(void) +{ + uint8_t db_byte; + int8_t db_index; + int16_t i; + uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE]; + uint8_t default_host_id[GZP_HOST_ID_LENGTH]; + + db_index = -2; + + // Populate default Host ID with F's. + for (i=0; i< GZP_HOST_ID_LENGTH; i++) + { + default_host_id[i] = 0xFF; + } + + // Search for previously written location + for (i = (GZP_INDEX_DB_SIZE - 1); i >= 0; i--) + { + db_byte = *(uint8_t*)(GZP_INDEX_DB_ADR + i); + + // Check if idx has been written to + if (db_byte != 0xff) + { + // Convert 4-bit nibble to index + if ((db_byte & 0xf0) != 0xf0) + { + db_byte = (db_byte >> 4) & 0x0f; + } + else + { + db_byte = db_byte & 0x0f; + } + + // Retrieve database entry + gzp_params_db_read(temp_element, db_byte); + + // Check if database entry is all F's + if ( memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], default_host_id, GZP_HOST_ID_LENGTH) != 0) + { + + db_index = db_byte; + } + else + { + db_index = -1; + } + break; + } + } + + return db_index; +} + + +static bool gzp_index_db_full() +{ +#if (GZP_INDEX_DB_SIZE != 0) + return ((*(uint8_t*)(GZP_INDEX_DB_ADR + (GZP_INDEX_DB_SIZE - 1)) != 0xff)); +#else + return true; +#endif +} + +//lint -save -e506 Constant value boolean +static bool gzp_index_db_empty() +{ +#if (GZP_INDEX_DB_SIZE != 0) + return ((GZP_INDEX_DB_SIZE == 0) || ((*(uint8_t*)(GZP_INDEX_DB_ADR)) == 0xff)); +#else + return true; +#endif +} +//lint -restore + +static bool gzp_array_is_set(const uint8_t* src, uint8_t length) +{ + uint8_t i; + + for (i = 0; i < length; i++) + { + if (*(src++) != 0xff) + { + return false; + } + } + return true; +} + +static bool gzp_params_store(bool store_all) +{ + uint8_t i; + bool write_index_db = false; + bool write_param_db = false; + uint8_t new_db_index = 0; + uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE]; + + // Search param DB to see if current setup exists + if (store_all) + { + // Search for: Current system address and host ID exists + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + { + gzp_params_db_read(temp_element, i); + + if (((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) && ((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH)) == 0)) + { + write_index_db = true; + new_db_index = i; + break; // System address + host_id allready exists in database + } + } + + // Search for: Current system address and cleared host ID + if (!write_index_db) + { + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + { + gzp_params_db_read(temp_element, i); + + if (((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) && \ + (gzp_array_is_set(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], GZP_HOST_ID_LENGTH))) + { + memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH); + new_db_index = i; + write_index_db = true; + write_param_db = true; + break; + } + } + } + + // Search for: Cleared system address and cleared host ID + if (!write_index_db) + { + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + { + gzp_params_db_read(temp_element, i); + + if (gzp_array_is_set(temp_element, GZP_PARAMS_DB_ELEMENT_SIZE)) + { + memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH); + memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH); + new_db_index = i; + write_index_db = true; + write_param_db = true; + break; + } + } + } + } + else + { + // Search for: System address + any host ID + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + { + gzp_params_db_read(temp_element, i); + + if ((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) + { + //memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH); + write_index_db = true; + new_db_index = i; + break; + } + } + + // Search for: System address cleared + if (!write_index_db) + { + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + { + gzp_params_db_read(temp_element, i); + + if (gzp_array_is_set(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH)) + { + memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH); + write_index_db = true; + write_param_db = true; + new_db_index = i; + break; + } + } + } + } + + if (write_param_db) + { + gzp_params_db_add(temp_element, new_db_index); + } + + if (write_index_db) + { + if (!gzp_index_db_full() && (new_db_index != gzp_index_db_read()) && (new_db_index != GZP_PARAMS_DB_MAX_ENTRIES)) + { + gzp_index_db_add(new_db_index); + return true; + } + } + + return false; +} + +static bool gzp_params_restore(void) +{ + uint8_t i; + uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE]; + + if (!gzp_index_db_full() && !gzp_index_db_empty()) + { + i = gzp_index_db_read(); + + if (i < GZP_PARAMS_DB_MAX_ENTRIES) + { + gzp_params_db_read(temp_element, i); + memcpy(gzp_system_address, &temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH); + gzp_set_host_id(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID]); + return true; + } + } + + return false; +} + +void gzp_delay_rx_periods(uint32_t rx_periods) +{ + nrf_delay_us(rx_periods * 2 * nrf_gzll_get_timeslot_period()); +} + +void gzp_tick_sleep_rx_periods(uint32_t rx_periods) +{ + nrf_gzll_clear_tick_count(); + + while (nrf_gzll_get_tick_count() < 2 * rx_periods) + { + __WFI(); + } +} + + +void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) +{ + latest_tx_info = tx_info; + + tx_complete = true; + tx_success = true; +} + +void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) +{ + latest_tx_info = tx_info; + + tx_complete = true; + tx_success = false; +} + +bool nrf_gzp_tx_complete(void) +{ + return tx_complete; +} + +bool nrf_gzp_tx_success(void) +{ + return tx_success; +} + +void nrf_gzp_reset_tx_complete() +{ + tx_complete = false; +} + +void nrf_gzp_reset_tx_success() +{ + tx_success = false; +} + +void nrf_gzll_disabled(void) +{ +} + +void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info) +{ +} + +/** @} */ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp_host.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp_host.c new file mode 100644 index 0000000000000000000000000000000000000000..9fcbb702c4fb1db8e16621e24628936bda0b31e2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp_host.c @@ -0,0 +1,787 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + * @file + * @brief Implementation of Gazell Pairing Library (gzp), Host functions. + * @defgroup gzp_source_host Gazell Pairing Host implementation + * @{ + * @ingroup gzp_04_source + */ + + +#include "nrf_gzp.h" +#include "nrf_gzll.h" +#include +#include +#include +#include "nrf_assert.h" +#include "nrf_ecb.h" +#include "nrf_nvmc.h" + + +//lint -esym(40, GZP_PARAMS_STORAGE_ADR) "Undeclared identifier" + + +/******************************************************************************/ +/** @name Typedefs + * @{ */ +/******************************************************************************/ + +/** + * Definition of internal states. + */ +typedef enum +{ + GZP_ID_REQ_IDLE, ///< No Host ID request received from Device. + GZP_ID_REQ_PENDING, ///< Host ID request received and waiting on application to grant/reject. + GZP_ID_REQ_PENDING_AND_GRANTED, ///< Host ID request received and granted by application. + GZP_ID_REQ_PENDING_AND_REJECTED, ///< Host ID request received and rejected by application. +} gzp_id_req_stat_t; + +/** @} */ + + +/******************************************************************************/ +/** @name Internal (static) function prototypes + * @{ */ +/******************************************************************************/ + + +/** + * Function for incrementing internal session counter. + */ +static void gzp_session_counter_inc(void); + + +/** + * Function for reading value of internal session counter. + * @param dst Current session counter. + */ +static void gzp_get_session_counter(uint8_t* dst); + + +/** + * Function processing received "system address request" from Device. + * + * @param gzp_req Pointer to RX payload containing system address request. + */ +static void gzp_process_address_req(uint8_t* gzp_req); + + +/** + * Function to process Host ID request from device. + * + * The Host shall retrieve the Host ID from NVM, or shall generate if + * it does not yet exist. + * + * @param rx_payload Pointer to rx_payload contaning Host ID request. + */ +static void gzp_process_id_req(uint8_t* rx_payload); + +/** + * Function to process Host ID fetch request from Device. + * + * The Device fetches the Host ID after the Host has generated/retrieved + * the Host ID. + * + * @param rx_payload Pointer to rx_payload contaning Host ID fetch request. + */ +static void gzp_process_id_fetch(uint8_t* rx_payload); + + +/** + * Function to process Key Update Prepare packet. + * + * Device requests the Session Token to be used for the Key Update request. + */ +static void gzp_process_key_update_prepare(void); + + +/** + * Function to process Key Update packet. + * + * Device requests a Key Update and sends a new Dynamic Key. The Dynamic Key is + * updated on the Host. + * + * @param rx_payload Pointer to rx_payload containing Key Update request. + */ +static void gzp_process_key_update(uint8_t* rx_payload); + + +/** + * Function to process received Encrypted User packet. + * + * @param rx_payload Pointer to rx_payload containing the encrypted user data. + * @param length Length of encrypted user data. + */ +static void gzp_process_encrypted_user_data(uint8_t* rx_payload, uint8_t length); + + +/** + * Function to preload the payload for the next ACK. + * + * @param src Pointer to source payload. + * @param length Length of source payload. + * @param pipe Pipe for the ACK payload. + */ +static void gzp_preload_ack(uint8_t* src, uint8_t length, uint8_t pipe); + + +/** + * Function for reading the Chip ID from non-volatile memory. + * + * The chip ID is used for the system address. + * + * If the Chip ID is not yet created a random Chip ID is created and + * written to non-volatile memory. Note that the term chip ID is used as + * the factory programmed chip sequence number was used for the system + * address in nRF24LU ICs. + * + * @param dst Address to copy Host ID to. + * @param[in] n Number of bytes in the Host ID. + */ +void gzp_host_chip_id_read(uint8_t *dst, uint8_t n); + + +/** + * Function to set the Host ID. + * + * Writes the Host ID to non-volatile memory. + * @param src Address of the Host ID to copy from. + */ +static void gzp_set_host_id(const uint8_t* src); + + +/** + * Function to request disabling of Gazell and wait for it to be disabled. + * + * Emulates legacy gzll_goto_idle(). + */ +static void gzll_goto_idle(void); + + +/** + * Flush all TX FIFOs. + * + * Emulates legacy gzll_tx_fifo_flush(). + */ +static void gzll_tx_fifo_flush(void); + + +/** + * Flush all RX FIFOs. + * + * Emulates legacy gzll_rx_fifo_flush(). + */ +static void gzll_rx_fifo_flush(void); + + +/** + * Set a timeout for the reception of packets on the Gazell Host. + * + * Emulates legacy Gazell function: gzll_set_param(GZLL_PARAM_RX_TIMEOUT, x). + * + * @param timeout Timeout in number of legacy "RX periods" + * (1 RX period = 2 timeslot periods). + */ +static void gzll_set_rx_timeout(uint32_t timeout); + +/** @} */ + + +/******************************************************************************/ +/** @name Internal (static) variabls + * @{ */ +/******************************************************************************/ + +static gzp_id_req_stat_t gzp_id_req_stat; ///< Current state of Host ID request. +static bool gzp_pairing_enabled_f; ///< True if Host is paired with a device. +static bool gzp_address_exchanged_f; ///< True if Host has exchanged a system address with a device and thus pairing has begun. + +static uint8_t gzp_session_counter[GZP_SESSION_TOKEN_LENGTH]; ///< Session counter used for key generation and update. + +static bool gzp_encrypted_user_data[GZP_ENCRYPTED_USER_DATA_MAX_LENGTH]; ///< Placeholder for encrypted data from Device. +static uint8_t gzp_encrypted_user_data_length; ///< Length of gzp_encrypted_user_data. Zero implies no data received. + +static nrf_gzll_host_rx_info_t prev_gzp_rx_info = {0, 0}; ///< RSSI and status of ACK payload transmission of previous Gazell packet. + +/** @} */ + + +/******************************************************************************/ +// Implementation: Host-specific API functions +/******************************************************************************/ + +void gzp_init() +{ + uint8_t system_address[GZP_SYSTEM_ADDRESS_WIDTH]; + + // Read "chip id", of which 4 bytes (GZP_SYSTEM_ADDRESS_WIDTH) + // are used as system address + gzp_host_chip_id_read(system_address, GZP_SYSTEM_ADDRESS_WIDTH); + + // Set up radio parameters (addresses and channel subset) from system_address + (void)gzp_update_radio_params(system_address); + + // Only "data pipe" enabled by default + + (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() | (1 << GZP_DATA_PIPE)); + + gzp_pairing_enabled_f = false; + gzp_address_exchanged_f = false; + gzp_id_req_stat = GZP_ID_REQ_IDLE; + gzp_encrypted_user_data_length = 0; + + // Infinite RX timeout + gzll_set_rx_timeout(0); +} + +void gzp_pairing_enable(bool enable) +{ + if (gzp_pairing_enabled_f != enable) + { + gzll_goto_idle(); + + if (enable) + { + (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() | (1 << GZP_PAIRING_PIPE)); + } + else + { + (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() & ~(1 << GZP_PAIRING_PIPE)); + + gzp_id_req_stat = GZP_ID_REQ_IDLE; + } + + gzp_pairing_enabled_f = enable; + + gzll_rx_start(); + } +} + +void gzp_host_execute() +{ + bool gzp_packet_received = false; + uint32_t payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; + uint8_t rx_payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH]; + + gzp_address_exchanged_f = false; + + if (nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE) > 0) + { + gzp_packet_received = nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, rx_payload, &payload_length); + } + + if (!gzp_packet_received && (gzp_encrypted_user_data_length == 0)) + { + if (nrf_gzll_get_rx_fifo_packet_count(GZP_DATA_PIPE) > 0) + { + gzp_packet_received = nrf_gzll_fetch_packet_from_rx_fifo(GZP_DATA_PIPE, rx_payload, &payload_length); + } + } + + if (gzp_packet_received) + { + //lint -save -esym(644,rx_payload) //may not have been initialized + switch (rx_payload[0]) + { + case GZP_CMD_HOST_ADDRESS_REQ: + gzp_process_address_req(rx_payload); + break; + + #ifndef GZP_CRYPT_DISABLE + + case GZP_CMD_HOST_ID_REQ: + gzp_process_id_req(rx_payload); + break; + case GZP_CMD_HOST_ID_FETCH: + gzp_process_id_fetch(rx_payload); + break; + case GZP_CMD_KEY_UPDATE_PREPARE: + gzp_process_key_update_prepare(); + break; + case GZP_CMD_KEY_UPDATE: + gzp_process_key_update(rx_payload); + break; + case GZP_CMD_ENCRYPTED_USER_DATA: + gzp_process_encrypted_user_data(rx_payload, payload_length); + break; + + #endif + + case GZP_CMD_FETCH_RESP: + default: + break; + } + } + + // Restart reception if "not proximity backoff" period has elapsed + if (!nrf_gzll_is_enabled()) + { + gzll_set_rx_timeout(0); + + if (gzp_pairing_enabled_f) + { + (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() | (1 << GZP_PAIRING_PIPE)); + } + + gzll_rx_start(); + } + + #ifndef GZP_CRYPT_DISABLE + gzp_session_counter_inc(); + #endif +} + +void gzll_rx_start(void) +{ + if (nrf_gzll_get_mode() != NRF_GZLL_MODE_HOST) + { + gzll_goto_idle(); + (void)nrf_gzll_set_mode(NRF_GZLL_MODE_HOST); + } + + if (!nrf_gzll_is_enabled()) + { + (void)nrf_gzll_enable(); + } +} + +bool gzp_id_req_received() +{ + return (gzp_id_req_stat != GZP_ID_REQ_IDLE); +} + +void gzp_id_req_reject() +{ + if (gzp_id_req_received()) + { + gzp_id_req_stat = GZP_ID_REQ_PENDING_AND_REJECTED; + } +} + +void gzp_id_req_grant() +{ + if (gzp_id_req_received()) + { + gzp_id_req_stat = GZP_ID_REQ_PENDING_AND_GRANTED; + } +} + +void gzp_id_req_cancel() +{ + if (gzp_id_req_received()) + { + gzp_id_req_stat = GZP_ID_REQ_IDLE; + } +} + +//----------------------------------------------------------------------------- +// Implementation: Static functions +//----------------------------------------------------------------------------- + +static void gzp_process_address_req(uint8_t* gzp_req) +{ + uint8_t temp_rx_pipes; + uint8_t pairing_resp[GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH]; + uint32_t rx_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; + + gzp_address_exchanged_f = false; + + gzll_goto_idle(); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + + temp_rx_pipes = nrf_gzll_get_rx_pipes_enabled(); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + + // If requesting Device within close proximity + if (prev_gzp_rx_info.rssi >= GZP_HOST_RX_POWER_THRESHOLD) + { + (void)nrf_gzll_set_rx_pipes_enabled(0); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + + gzll_set_rx_timeout(GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + + gzll_rx_fifo_flush(); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + + // Start "proximity" back off period + gzll_rx_start(); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + + while (nrf_gzll_is_enabled()) + {} + + // Build pairing response packet + pairing_resp[0] = (uint8_t)GZP_CMD_HOST_ADDRESS_RESP; + gzp_host_chip_id_read(&pairing_resp[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH); + + (void)nrf_gzll_add_packet_to_tx_fifo(0, &pairing_resp[0], GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + gzll_set_rx_timeout(GZP_STEP1_RX_TIMEOUT); + + // Enable only pairing pipe when waiting for pairing request step 1 + (void)nrf_gzll_set_rx_pipes_enabled((1 << GZP_PAIRING_PIPE)); + + gzll_rx_start(); + + while (nrf_gzll_is_enabled()) + { + if (nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE)) + { + (void)nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, &gzp_req[0], &rx_payload_length); + + // Validate step 1 of pairing request + if (gzp_req[0] == (uint8_t)GZP_CMD_HOST_ADDRESS_FETCH) + { + gzp_address_exchanged_f = true; + } + } + } + + gzll_tx_fifo_flush(); + gzll_rx_fifo_flush(); + + gzll_set_rx_timeout(0); + + (void)nrf_gzll_set_rx_pipes_enabled(temp_rx_pipes); + + // Return to normal operation + gzll_rx_start(); + } + else + { + (void)nrf_gzll_set_rx_pipes_enabled(temp_rx_pipes & ~(1 << GZP_PAIRING_PIPE)); + + gzll_set_rx_timeout(GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT); + + // Start "not proximity" backoff period + gzll_rx_start(); + } +} + +static void gzp_preload_ack(uint8_t* src, uint8_t length, uint8_t pipe) +{ + gzll_goto_idle(); + + gzll_tx_fifo_flush(); + + (void)nrf_gzll_add_packet_to_tx_fifo(pipe, src, length); + + gzll_rx_start(); +} + +static void gzll_set_rx_timeout(uint32_t timeout) +{ + timeout *= 2; // * 2 as gzll_set_rx_timeout() takes RX_PERIODS as input, which equals 2 timeslots. + nrf_gzll_set_auto_disable(timeout); +} + +bool gzp_address_exchanged() +{ + return gzp_address_exchanged_f; +} + +#ifndef GZP_CRYPT_DISABLE + +bool gzp_crypt_user_data_received() +{ + return (gzp_encrypted_user_data_length > 0); +} + +bool gzp_crypt_user_data_read(uint8_t* dst, uint8_t* length) +{ + if (gzp_encrypted_user_data_length > 0) + { + memcpy(dst, (void*)gzp_encrypted_user_data, gzp_encrypted_user_data_length); + + if (length != NULL) + { + *length = gzp_encrypted_user_data_length; + } + gzp_encrypted_user_data_length = 0; + + return true; + } + else + { + return false; + } +} + +static void gzp_session_counter_inc() +{ + uint8_t i; + + for (i = 0; i < GZP_SESSION_TOKEN_LENGTH; i++) + { + gzp_session_counter[i]++; + if (gzp_session_counter[i] != 0) + { + break; + } + } +} + +static void gzp_get_session_counter(uint8_t* dst) +{ + memcpy(dst, (void*)gzp_session_counter, GZP_SESSION_TOKEN_LENGTH); +} + +static void gzp_set_host_id(const uint8_t* src) +{ + if (*((uint8_t*)GZP_PARAMS_STORAGE_ADR) == 0xff) + { + nrf_nvmc_write_bytes(GZP_PARAMS_STORAGE_ADR + 1, src, GZP_HOST_ID_LENGTH); + nrf_nvmc_write_byte(GZP_PARAMS_STORAGE_ADR, 0x00); + } +} + +void gzp_get_host_id(uint8_t *dst) +{ + memcpy(dst, (uint8_t*)GZP_PARAMS_STORAGE_ADR + 1, GZP_HOST_ID_LENGTH); +} + +static void gzp_process_id_req(uint8_t* rx_payload) +{ + int i; + uint8_t temp_host_id[GZP_HOST_ID_LENGTH]; + + if (gzp_pairing_enabled_f) + { + if (!gzp_id_req_received()) + { + gzp_crypt_set_session_token(&rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN]); + gzp_id_req_stat = GZP_ID_REQ_PENDING; + } + + gzp_get_host_id(temp_host_id); + + // Added: + for (i = 0; i < GZP_HOST_ID_LENGTH; i++) + { + if (temp_host_id[i] != 0xFF) + { + break; + } + } + + if (i == GZP_HOST_ID_LENGTH) // If host not generated yet + { + gzp_get_session_counter(temp_host_id); + +#if (GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH) + gzp_xor_cipher(temp_host_id, temp_host_id, &rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_SESSION_TOKEN_LENGTH); +#else //(GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH) + gzp_xor_cipher(temp_host_id, temp_host_id, &rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_HOST_ID_LENGTH); +#endif //(GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH) + + gzp_set_host_id(temp_host_id); + } + } +} + +static void gzp_process_id_fetch(uint8_t* rx_payload) +{ + uint8_t tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH]; + + if (gzp_id_req_received()) + { + gzp_crypt_select_key(GZP_ID_EXCHANGE); + gzp_crypt(&rx_payload[1], &rx_payload[1], GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH - 1); + if (gzp_validate_id(&rx_payload[GZP_CMD_HOST_ID_FETCH_VALIDATION_ID])) + { + switch (gzp_id_req_stat) + { + case GZP_ID_REQ_PENDING_AND_GRANTED: + tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_GRANTED; + gzp_get_host_id(&tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID]); + gzp_id_req_stat = GZP_ID_REQ_IDLE; + break; + case GZP_ID_REQ_PENDING_AND_REJECTED: + tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_REJECTED; + gzp_id_req_stat = GZP_ID_REQ_IDLE; + break; + case GZP_ID_REQ_PENDING: + default: + tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_PENDING; + break; + } + + tx_payload[0] = (uint8_t)GZP_CMD_HOST_ID_FETCH_RESP; + gzp_add_validation_id(&tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID]); + gzp_crypt(&tx_payload[1], &tx_payload[1], GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH - 1); + + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + gzp_preload_ack(tx_payload, GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH, GZP_DATA_PIPE); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + } + } +} + +static void gzp_process_key_update_prepare() +{ + uint8_t tx_payload[GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH]; + + tx_payload[0] = (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE_RESP; + + gzp_get_session_counter(&tx_payload[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]); + + // Update session token if no ID request is pending + if (!gzp_id_req_received()) + { + gzp_crypt_set_session_token(&tx_payload[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]); + } + + gzp_preload_ack(tx_payload, GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH, GZP_DATA_PIPE); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); +} + +static void gzp_process_key_update(uint8_t* rx_payload) +{ + gzp_crypt_select_key(GZP_KEY_EXCHANGE); + gzp_crypt(&rx_payload[1], &rx_payload[1], GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH - 1); + if (gzp_validate_id(&rx_payload[GZP_CMD_KEY_UPDATE_VALIDATION_ID])) + { + gzp_crypt_set_dyn_key(&rx_payload[GZP_CMD_KEY_UPDATE_NEW_KEY]); + } +} + +static void gzp_process_encrypted_user_data(uint8_t* rx_payload, uint8_t length) +{ + uint8_t tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH]; + + if (gzp_id_req_received()) + { + gzp_crypt_select_key(GZP_ID_EXCHANGE); + } + else + { + gzp_crypt_select_key(GZP_DATA_EXCHANGE); + } + + gzp_crypt(&rx_payload[1], &rx_payload[1], length - 1); + if (gzp_validate_id(&rx_payload[GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID])) + { + gzp_encrypted_user_data_length = length - GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD; + memcpy((void*)gzp_encrypted_user_data, &rx_payload[GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD], gzp_encrypted_user_data_length); + } + + // Build response packet + tx_payload[0] = (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA_RESP; + gzp_add_validation_id(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID]); + gzp_crypt(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], &tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], GZP_VALIDATION_ID_LENGTH); + gzp_get_session_counter(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]); + + // Update "session token" only if no ID request is pending + if (!gzp_id_req_received()) + { + gzp_crypt_set_session_token(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]); + } + + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + gzp_preload_ack(tx_payload, GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH, GZP_DATA_PIPE); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); +} + +//----------------------------------------------------------------------------- +// Function added during LE1 -> nRF51 port +//----------------------------------------------------------------------------- + +static void gzll_goto_idle() +{ + nrf_gzll_disable(); + while (nrf_gzll_is_enabled()) + {} +} + +static void gzll_tx_fifo_flush(void) +{ + int i; + + for (i = 0; i < NRF_GZLL_CONST_PIPE_COUNT; i++) + { + (void)nrf_gzll_flush_tx_fifo(i); + } +} + +static void gzll_rx_fifo_flush(void) +{ + int i; + + for (i = 0; i < NRF_GZLL_CONST_PIPE_COUNT; i++) + { + (void)nrf_gzll_flush_rx_fifo(i); + } +} + + +/******************************************************************************/ +// Implementation: Gazell callback functions +/******************************************************************************/ + +void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) +{ +} + + +void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) +{ +} + + +void nrf_gzll_disabled(void) +{ +} + + +void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info) +{ + if (pipe == GZP_PAIRING_PIPE) + { + prev_gzp_rx_info = rx_info; + } +} + +/** @} */ +/** @} */ + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c new file mode 100644 index 0000000000000000000000000000000000000000..0c3947c60cb2f69fda0e7c2ac121eb5e0821fa08 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_gzp.h" +#include "nrf_nvmc.h" + +/** + * @file + * @brief Implementation of Gazell Pairing Library (gzp), nRF5x specific Host functions. + * @defgroup gzp_source_host_nrf5x Gazell Pairing Host nRF5x specific implementation + * @{ + * @ingroup gzp_04_source + */ + + +void gzp_host_chip_id_read(uint8_t *dst, uint8_t n) +{ + uint8_t i; + uint8_t random_number; + + if ( *((uint8_t*)(GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 1)) == 0xff) + { + nrf_nvmc_write_byte((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 1) , 0x00); + + for (i = 0; i < n; i++) + { + gzp_random_numbers_generate(&random_number, 1); + nrf_nvmc_write_byte((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 2 + i) , random_number); + } + } + + for (i = 0; i < n; i++) + { + *(dst++) = *((uint8_t*)(GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 2 + i)); + } +} + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/sdk_validation.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/sdk_validation.h new file mode 100644 index 0000000000000000000000000000000000000000..617f0e732d0ae892839c03eccdc0a8095c42e75f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/sdk_validation.h @@ -0,0 +1,305 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SDK_VALIDATION_H +#define SDK_VALIDATION_H + +#include "nrf_peripherals.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Validate peripheral availibility + +#if ((defined(SAADC_ENABLED)) && (SAADC_ENABLED > 0) && (!defined(SAADC_PRESENT))) +#error "SAADC not present in selected MCU." +#endif + +#if ((defined(ADC_ENABLED)) && (ADC_ENABLED > 0) && (!defined(ADC_PRESENT))) +#error "SAADC not present in selected MCU." +#endif + +#if ((defined(I2S_ENABLED)) && (I2S_ENABLED > 0) && (!defined(I2S_PRESENT))) +#error "I2S not present in selected MCU." +#endif + +#if ((defined(COMP_ENABLED)) && (COMP_ENABLED > 0) && (!defined(COMP_PRESENT))) +#error "COMP not present in selected MCU." +#endif + +#if ((defined(LPCOMP_ENABLED)) && (LPCOMP_ENABLED > 0) && (!defined(LPCOMP_PRESENT))) +#error "LPCOMP not present in selected MCU." +#endif + +#if ((defined(SPIS0_ENABLED)) && (SPIS0_ENABLED > 0) && (!defined(SPIS_PRESENT))) +#error "SPIS0 instance not present in selected MCU." +#endif + +#if ((defined(EGU_ENABLED)) && (EGU_ENABLED > 0) && (!defined(EGU_PRESENT))) +#error "EGU instance not present in selected MCU." +#endif + +#if ((defined(NFC_HAL_ENABLED)) && (NFC_HAL_ENABLED > 0) && (!defined(NFCT_PRESENT))) +#error "NFC TAG not present in selected MCU." +#endif + +// Validate count of instances + +#if ((defined(RTC2_ENABLED)) && (RTC2_ENABLED > 0) && (RTC_COUNT < 2)) +#error "RTC2 not present in selected MCU." +#endif + +#if ((defined(TWIS0_ENABLED) || defined(TWIS1_ENABLED)) &&\ + ((TWIS0_ENABLED + TWIS1_ENABLED) > 0) &&\ + (!defined(TWIS_PRESENT))) +#error "TWIS not present in selected MCU." +#endif + +#if ((defined(SPIS2_ENABLED)) && (SPIS2_ENABLED > 0) && (SPIS_COUNT < 2)) +#error "SPI2/SPIS2 instance not present in selected MCU." +#endif + +#if ((defined(TIMER3_ENABLED) || defined(TIMER4_ENABLED)) &&\ + ((TIMER3_ENABLED + TIMER4_ENABLED ) > 0) &&\ + (TIMER_COUNT < 5)) +#error "TIMER3 and TIMER4 not present in selected MCU." +#endif + +// Validate peripheral sharing feature +#if ((defined(PERIPHERAL_RESOURCE_SHARING_ENABLED)) && (!PERIPHERAL_RESOURCE_SHARING_ENABLED)) + +#if ((defined(TWIM0_ENABLED) && defined(TWIS0_ENABLED)) &&\ + ((TWIM0_ENABLED + TWIS0_ENABLED) > 1)) +#error "Peripherals overlap. TWIM0, TWIS0 - only one of these can be enabled." +#endif + +#if ((defined(TWIM0_ENABLED) && defined(SPIM0_ENABLED)) &&\ + ((TWIM0_ENABLED + SPIM0_ENABLED) > 1)) +#error "Peripherals overlap. TWIM0, SPIM0 - only one of these can be enabled." +#endif + +#if ((defined(TWIM0_ENABLED) && defined(SPIS0_ENABLED)) &&\ + ((TWIM0_ENABLED + SPIS0_ENABLED) > 1)) +#error "Peripherals overlap. TWIM0, SPIS0 - only one of these can be enabled." +#endif + +#if ((defined(TWIM0_ENABLED) && defined(SPI0_ENABLED)) &&\ + ((TWIM0_ENABLED + SPI0_ENABLED) > 1)) +#error "Peripherals overlap. TWIM0, SPI0 - only one of these can be enabled." +#endif + +#if ((defined(TWIM0_ENABLED) && defined(TWI0_ENABLED)) &&\ + ((TWIM0_ENABLED + TWI0_ENABLED) > 1)) +#error "Peripherals overlap. TWIM0, TWI0 - only one of these can be enabled." +#endif + +#if ((defined(TWIS0_ENABLED) && defined(SPIM0_ENABLED)) &&\ + ((TWIS0_ENABLED + SPIM0_ENABLED) > 1)) +#error "Peripherals overlap. TWIS0, SPIM0 - only one of these can be enabled." +#endif + +#if ((defined(TWIS0_ENABLED) && defined(SPIS0_ENABLED)) &&\ + ((TWIS0_ENABLED + SPIS0_ENABLED) > 1)) +#error "Peripherals overlap. TWIS0, SPIS0 - only one of these can be enabled." +#endif + +#if ((defined(TWIS0_ENABLED) && defined(SPI0_ENABLED)) &&\ + ((TWIS0_ENABLED + SPI0_ENABLED) > 1)) +#error "Peripherals overlap. TWIS0, SPI0 - only one of these can be enabled." +#endif + +#if ((defined(TWIS0_ENABLED) && defined(TWI0_ENABLED)) &&\ + ((TWIS0_ENABLED + TWI0_ENABLED) > 1)) +#error "Peripherals overlap. TWIS0, TWI0 - only one of these can be enabled." +#endif + +#if ((defined(SPIM0_ENABLED) && defined(SPIS0_ENABLED)) &&\ + ((SPIM0_ENABLED + SPIS0_ENABLED) > 1)) +#error "Peripherals overlap. SPIM0, SPIS0 - only one of these can be enabled." +#endif + +#if ((defined(SPIM0_ENABLED) && defined(SPI0_ENABLED)) &&\ + ((SPIM0_ENABLED + SPI0_ENABLED) > 1)) +#error "Peripherals overlap. SPIM0, SPI0 - only one of these can be enabled." +#endif + +#if ((defined(SPIM0_ENABLED) && defined(TWI0_ENABLED)) &&\ + ((SPIM0_ENABLED + TWI0_ENABLED) > 1)) +#error "Peripherals overlap. SPIM0, TWI0 - only one of these can be enabled." +#endif + +#if ((defined(SPIS0_ENABLED) && defined(SPI0_ENABLED)) &&\ + ((SPIS0_ENABLED + SPI0_ENABLED) > 1)) +#error "Peripherals overlap. SPIS0, SPI0 - only one of these can be enabled." +#endif + +#if ((defined(SPIS0_ENABLED) && defined(TWI0_ENABLED)) &&\ + ((SPIS0_ENABLED + TWI0_ENABLED) > 1)) +#error "Peripherals overlap. SPIS0, TWI0 - only one of these can be enabled." +#endif + +#if ((defined(SPI0_ENABLED) && defined(TWI0_ENABLED)) &&\ + ((SPI0_ENABLED + TWI0_ENABLED) > 1)) +#error "Peripherals overlap. SPI0, TWI0 - only one of these can be enabled." +#endif + +#if ((defined(TWIM1_ENABLED) && defined(TWIS1_ENABLED)) &&\ + ((TWIM1_ENABLED + TWIS1_ENABLED) > 1)) +#error "Peripherals overlap. TWIM1, TWIS1 - only one of these can be enabled." +#endif + +#if ((defined(TWIM1_ENABLED) && defined(SPIM1_ENABLED)) &&\ + ((TWIM1_ENABLED + SPIM1_ENABLED) > 1)) +#error "Peripherals overlap. TWIM1, SPIM1 - only one of these can be enabled." +#endif + +#if ((defined(TWIM1_ENABLED) && defined(SPIS1_ENABLED)) &&\ + ((TWIM1_ENABLED + SPIS1_ENABLED) > 1)) +#error "Peripherals overlap. TWIM1, SPIS1 - only one of these can be enabled." +#endif + +#if ((defined(TWIM1_ENABLED) && defined(SPI1_ENABLED)) &&\ + ((TWIM1_ENABLED + SPI1_ENABLED) > 1)) +#error "Peripherals overlap. TWIM1, SPI1 - only one of these can be enabled." +#endif + +#if ((defined(TWIM1_ENABLED) && defined(TWI1_ENABLED)) &&\ + ((TWIM1_ENABLED + TWI1_ENABLED) > 1)) +#error "Peripherals overlap. TWIM1, TWI1 - only one of these can be enabled." +#endif + +#if ((defined(TWIS1_ENABLED) && defined(SPIM1_ENABLED)) &&\ + ((TWIS1_ENABLED + SPIM1_ENABLED) > 1)) +#error "Peripherals overlap. TWIS1, SPIM1 - only one of these can be enabled." +#endif + +#if ((defined(TWIS1_ENABLED) && defined(SPIS1_ENABLED)) &&\ + ((TWIS1_ENABLED + SPIS1_ENABLED) > 1)) +#error "Peripherals overlap. TWIS1, SPIS1 - only one of these can be enabled." +#endif + +#if ((defined(TWIS1_ENABLED) && defined(SPI1_ENABLED)) &&\ + ((TWIS1_ENABLED + SPI1_ENABLED) > 1)) +#error "Peripherals overlap. TWIS1, SPI1 - only one of these can be enabled." +#endif + +#if ((defined(TWIS1_ENABLED) && defined(TWI1_ENABLED)) &&\ + ((TWIS1_ENABLED + TWI1_ENABLED) > 1)) +#error "Peripherals overlap. TWIS1, TWI1 - only one of these can be enabled." +#endif + +#if ((defined(SPIM1_ENABLED) && defined(SPIS1_ENABLED)) &&\ + ((SPIM1_ENABLED + SPIS1_ENABLED) > 1)) +#error "Peripherals overlap. SPIM1, SPIS1 - only one of these can be enabled." +#endif + +#if ((defined(SPIM1_ENABLED) && defined(SPI1_ENABLED)) &&\ + ((SPIM1_ENABLED + SPI1_ENABLED) > 1)) +#error "Peripherals overlap. SPIM1, SPI1 - only one of these can be enabled." +#endif + +#if ((defined(SPIM1_ENABLED) && defined(TWI1_ENABLED)) &&\ + ((SPIM1_ENABLED + TWI1_ENABLED) > 1)) +#error "Peripherals overlap. SPIM1, TWI1 - only one of these can be enabled." +#endif + +#if ((defined(SPIS1_ENABLED) && defined(SPI1_ENABLED)) &&\ + ((SPIS1_ENABLED + SPI1_ENABLED) > 1)) +#error "Peripherals overlap. SPIS1, SPI1 - only one of these can be enabled." +#endif + +#if ((defined(SPIS1_ENABLED) && defined(TWI1_ENABLED)) &&\ + ((SPIS1_ENABLED + TWI1_ENABLED) > 1)) +#error "Peripherals overlap. SPIS1, TWI1 - only one of these can be enabled." +#endif + +#if ((defined(SPI1_ENABLED) && defined(TWI1_ENABLED)) &&\ + ((SPI1_ENABLED + TWI1_ENABLED) > 1)) +#error "Peripherals overlap. SPI1, TWI1 - only one of these can be enabled." +#endif + +#if ((defined(SPI2_ENABLED) && defined(SPIS2_ENABLED)) &&\ + ((SPI2_ENABLED + SPIS2_ENABLED) > 1)) +#error "Peripherals overlap. SPI2, SPIS2 - only one of these can be enabled." +#endif + +#if ((defined(SPIM2_ENABLED) && defined(SPIS2_ENABLED)) &&\ + ((SPI2_ENABLED + SPIS2_ENABLED) > 1)) +#error "Peripherals overlap. SPIM2, SPIS2 - only one of these can be enabled." +#endif + +#if ((defined(SPIM2_ENABLED) && defined(SPI2_ENABLED)) &&\ + ((SPI2_ENABLED + SPIS2_ENABLED) > 1)) +#error "Peripherals overlap. SPIM2, SPI2 - only one of these can be enabled." +#endif + +#endif + +#ifdef NFCT_PRESENT + +#if ((defined(NFC_HAL_ENABLED) && defined(CLOCK_ENABLED)) &&\ + ((NFC_HAL_ENABLED) && (!CLOCK_ENABLED))) +#error "NFC_HAL requires CLOCK to work. NFC_HAL can not be enabled without CLOCK." +#endif + +#if ((defined(NFC_HAL_ENABLED) && defined(TIMER4_ENABLED)) &&\ + ((NFC_HAL_ENABLED + TIMER4_ENABLED) > 1)) +#error "TIMER4 is used by NFC_HAL. NFC_HAL, TIMER4 - only one of these can be enabled." +#endif + +#endif +// Complex driver validation +#ifdef LPCOMP_PRESENT + +#if ((defined(COMP_ENABLED) && defined(LPCOMP_ENABLED)) &&\ + (!PERIPHERAL_RESOURCE_SHARING_ENABLED) && \ + ((COMP_ENABLED + LPCOMP_ENABLED) > 1)) +#error "Peripherals overlap. SPIM2, SPI2 - only one of these can be enabled." +#endif + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif // SDK_VALIDATION_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/middleware/app_mw_ant.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/middleware/app_mw_ant.c new file mode 100644 index 0000000000000000000000000000000000000000..8dbfd25586f2232820c3961a8213cbc5ec79d3b7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/middleware/app_mw_ant.c @@ -0,0 +1,1868 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_interface.h" +#include "ble_serialization.h" +#include "ant_app.h" +#include "ser_sd_transport.h" +#include "app_error.h" + +static void * mp_out_params[3]; + +static void tx_buf_alloc(uint8_t * * p_data, uint32_t * p_len) +{ + uint32_t err_code; + uint16_t len16; + + do + { + err_code = ser_sd_transport_tx_alloc(p_data, &len16); + } + while (err_code != NRF_SUCCESS); + + *p_data[0] = SER_PKT_TYPE_ANT_CMD; + *p_len = (uint32_t)len16 - 1; +} + +/**@brief Command response callback function for @ref sd_ant_enable ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t enable_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_enable_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_enable(ANT_ENABLE * const p_ant_enable) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_enable_req_enc(p_ant_enable, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + enable_rsp_dec); + +} + +/**@brief Command response callback function for @ref sd_ant_channel_assign ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_assign_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_assign_rsp_dec(p_buffer, + length, + &result_code); + //@note: Should never fail. + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_assign(uint8_t channel, uint8_t channel_type, uint8_t network, uint8_t ext_assign) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_channel_assign_req_enc(channel, + channel_type, + network, + ext_assign, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_assign_rsp_dec); + +} + +/**@brief Command response callback function for @ref sd_ant_channel_open_with_offset ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_open_with_offset_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_open_with_offset_rsp_dec(p_buffer, + length, + &result_code); + //@note: Should never fail. + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_open_with_offset(uint8_t channel, uint16_t usOffset) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_channel_open_with_offset_req_enc(channel, + usOffset, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_open_with_offset_rsp_dec); + +} + +/**@brief Command response callback function for @ref sd_ant_channel_id_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_id_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_id_set_rsp_dec(p_buffer, + length, + &result_code); + //@note: Should never fail. + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_id_set (uint8_t channel, uint16_t device_number, uint8_t device_type, uint8_t transmit_type) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_channel_id_set_req_enc(channel, + device_number, + device_type, + transmit_type, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_id_set_rsp_dec); + +} + +/**@brief Command response callback function for @ref sd_ant_channel_period_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_period_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_period_set_rsp_dec(p_buffer, + length, + &result_code); + //@note: Should never fail. + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_period_set(uint8_t channel, uint16_t period) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_channel_period_set_req_enc(channel, + period, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_period_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_channel_radio_freq_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_radio_freq_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_radio_freq_set_rsp_dec(p_buffer, + length, + &result_code); + //@note: Should never fail. + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_radio_freq_set (uint8_t channel, uint8_t freq) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_channel_radio_freq_set_req_enc(channel, + freq, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_radio_freq_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_broadcast_message_tx ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t broadcast_message_tx_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_broadcast_message_tx_rsp_dec(p_buffer, + length, + &result_code); + //@note: Should never fail. + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_broadcast_message_tx(uint8_t channel, uint8_t size, uint8_t * p_mesg) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_broadcast_message_tx_req_enc(channel, + size, + p_mesg, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + broadcast_message_tx_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_acknowledge_message_tx ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t acknowledge_message_tx_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_acknowledge_message_tx_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_acknowledge_message_tx(uint8_t channel, uint8_t size, uint8_t * p_mesg) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_acknowledge_message_tx_req_enc(channel, + size, + p_mesg, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + acknowledge_message_tx_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_channel_unassign ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_unassign_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_unassign_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_unassign(uint8_t channel) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_channel_unassign_req_enc(channel, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_unassign_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_channel_close ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_close_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_close_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_close(uint8_t channel) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_channel_close_req_enc(channel, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_close_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_network_address_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t network_address_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_network_address_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_network_address_set(uint8_t network, const uint8_t * p_network_key) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_network_address_set_req_enc(network, + p_network_key, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + network_address_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_channel_radio_tx_power_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_radio_tx_power_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_radio_tx_power_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_radio_tx_power_set(uint8_t channel, uint8_t tx_power, uint8_t custom_tx_power) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_channel_radio_tx_power_set_req_enc(channel, + tx_power, + custom_tx_power, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_radio_tx_power_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_channel_rx_search_timeout_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_rx_search_timeout_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_rx_search_timeout_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_rx_search_timeout_set(uint8_t channel, uint8_t timeout) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_channel_rx_search_timeout_set_req_enc(channel, + timeout, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_rx_search_timeout_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_channel_low_priority_rx_search_timeout_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_low_priority_rx_search_timeout_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_low_priority_rx_search_timeout_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_low_priority_rx_search_timeout_set(uint8_t channel, uint8_t timeout) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_channel_low_priority_rx_search_timeout_set_req_enc(channel, + timeout, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_low_priority_rx_search_timeout_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_prox_search_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t prox_search_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_prox_search_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_prox_search_set(uint8_t channel, uint8_t prox_threshold, uint8_t custom_prox_threshold) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_prox_search_set_req_enc(channel, + prox_threshold, + custom_prox_threshold, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + prox_search_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_search_waveform_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t search_waveform_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_search_waveform_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_search_waveform_set(uint8_t channel, uint16_t waveform) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_search_waveform_set_req_enc(channel, + waveform, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + search_waveform_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_channel_id_get ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_id_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_id_get_rsp_dec(p_buffer, + length, + mp_out_params[0], + mp_out_params[1], + mp_out_params[2], + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_id_get(uint8_t channel, uint16_t * p_device_number, uint8_t * p_device_type, uint8_t * p_transmit_type) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_device_number; + mp_out_params[1] = p_device_type; + mp_out_params[2] = p_transmit_type; + + const uint32_t err_code = ant_channel_id_get_req_enc(channel, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_id_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_channel_radio_freq_get ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_radio_freq_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_radio_freq_get_rsp_dec(p_buffer, + length, + mp_out_params[0], + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_radio_freq_get(uint8_t channel, uint8_t * p_r_freq) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_r_freq; + + const uint32_t err_code = ant_channel_radio_freq_get_req_enc(channel, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_radio_freq_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_channel_period_get ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_period_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_period_get_rsp_dec(p_buffer, + length, + mp_out_params[0], + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_period_get(uint8_t channel, uint16_t * p_period) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_period; + + const uint32_t err_code = ant_channel_period_get_req_enc(channel, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_period_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_search_channel_priority_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t search_channel_priority_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_search_channel_priority_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_search_channel_priority_set(uint8_t channel, uint8_t search_priority) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_search_channel_priority_set_req_enc(channel, + search_priority, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + search_channel_priority_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_active_search_sharing_cycles_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t active_search_sharing_cycles_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_active_search_sharing_cycles_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_active_search_sharing_cycles_set(uint8_t channel, uint8_t cycles) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_active_search_sharing_cycles_set_req_enc(channel, + cycles, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + active_search_sharing_cycles_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_lib_config_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t lib_config_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_lib_config_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_lib_config_set(uint8_t ant_lib_config) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_lib_config_set_req_enc(ant_lib_config, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + lib_config_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_active_search_sharing_channels_get ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t active_search_sharing_cycles_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_active_search_sharing_cycles_get_rsp_dec(p_buffer, + length, + mp_out_params[0], + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_active_search_sharing_cycles_get(uint8_t channel, uint8_t * p_cycles) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_cycles; + + const uint32_t err_code = ant_active_search_sharing_cycles_get_req_enc(channel, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + active_search_sharing_cycles_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_lib_config_get ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t lib_config_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_lib_config_get_rsp_dec(p_buffer, + length, + mp_out_params[0], + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_lib_config_get(uint8_t * p_ant_lib_config) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_ant_lib_config; + + const uint32_t err_code = ant_lib_config_get_req_enc(&(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + lib_config_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_lib_config_clear ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t lib_config_clear_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_lib_config_clear_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_lib_config_clear(uint8_t ant_lib_config) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_lib_config_clear_req_enc(ant_lib_config, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + lib_config_clear_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_stack_reset ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t stack_reset_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_stack_reset_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_stack_reset() +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_stack_reset_req_enc(&(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + stack_reset_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_rx_scan_mode_start ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t rx_scan_mode_start_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_rx_scan_mode_start_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_rx_scan_mode_start(uint8_t sync_channel_packets_only) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_rx_scan_mode_start_req_enc(sync_channel_packets_only, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + rx_scan_mode_start_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_id_list_add ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t id_list_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_id_list_add_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_id_list_add(uint8_t channel, uint8_t * p_dev_id, uint8_t list_index) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_id_list_add_req_enc(channel, + p_dev_id, + list_index, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + id_list_add_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_id_list_config ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t id_list_config_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_id_list_config_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_id_list_config(uint8_t channel, uint8_t id_list_size, uint8_t inc_exc_flag) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_id_list_config_req_enc(channel, + id_list_size, + inc_exc_flag, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + id_list_config_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_channel_status_get ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t channel_status_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_channel_status_get_rsp_dec(p_buffer, + length, + mp_out_params[0], + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_channel_status_get(uint8_t channel, uint8_t * p_status) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_status; + + const uint32_t err_code = ant_channel_status_get_req_enc(channel, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + channel_status_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_cw_test_mode_init ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t cw_test_mode_init_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_cw_test_mode_init_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_cw_test_mode_init() +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_cw_test_mode_init_req_enc(&(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + cw_test_mode_init_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_cw_test_mode ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t cw_test_mode_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_cw_test_mode_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_cw_test_mode(uint8_t radio_freq, uint8_t tx_power, uint8_t custom_tx_power, uint8_t mode) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_cw_test_mode_req_enc(radio_freq, + tx_power, + custom_tx_power, + mode, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + cw_test_mode_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_version_get ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t version_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_version_get_rsp_dec(p_buffer, + length, + &mp_out_params[0], + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_version_get(uint8_t * p_version) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_version; + + const uint32_t err_code = ant_version_get_req_enc(&(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + version_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_capabilities_get ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t capabilities_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_capabilities_get_rsp_dec(p_buffer, + length, + &mp_out_params[0], + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_capabilities_get(uint8_t * p_capabilities) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_capabilities; + + const uint32_t err_code = ant_capabilities_get_req_enc(&(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + capabilities_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_crypto_channel_enable ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t crypto_channel_enable_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_crypto_channel_enable_rsp_dec(p_buffer, + length, + &result_code); + //@note: Should never fail. + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_crypto_channel_enable(uint8_t channel, uint8_t enable, uint8_t key_num, uint8_t decimation_rate) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_crypto_channel_enable_req_enc(channel, + enable, + key_num, + decimation_rate, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + crypto_channel_enable_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_adv_burst_config_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t adv_burst_config_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_adv_burst_config_set_rsp_dec(p_buffer, + length, + &result_code); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_adv_burst_config_set(uint8_t * p_config, uint8_t size) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_adv_burst_config_set_req_enc(p_config, + size, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + adv_burst_config_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_crypto_key_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t crypto_key_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_crypto_key_set_rsp_dec(p_buffer, + length, + &result_code); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_crypto_key_set(uint8_t key_num, uint8_t * p_key) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_crypto_key_set_req_enc(key_num, + p_key, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + crypto_key_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_crypto_info_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t crypto_info_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_crypto_info_set_rsp_dec(p_buffer, + length, + &result_code); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_crypto_info_set(uint8_t type, uint8_t * p_info) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_crypto_info_set_req_enc(type, + p_info, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + crypto_info_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_crypto_info_get ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t crypto_info_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_crypto_info_get_rsp_dec(p_buffer, + length, + mp_out_params[0], + &result_code); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_crypto_info_get(uint8_t type, uint8_t * p_info) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_info; + + const uint32_t err_code = ant_crypto_info_get_req_enc(type, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + crypto_info_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_coex_config_set ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t coex_config_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_coex_config_set_rsp_dec(p_buffer, + length, + &result_code); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_coex_config_set(uint8_t channel, ANT_BUFFER_PTR * p_coex_config, ANT_BUFFER_PTR * p_adv_coex_config) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ant_coex_config_set_req_enc(channel, + p_coex_config, + p_adv_coex_config, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + coex_config_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ant_coex_config_get ANT command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t coex_config_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ant_coex_config_get_rsp_dec(p_buffer, + length, + mp_out_params[0], + mp_out_params[1], + &result_code); + + //@note: Should never fail + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ant_coex_config_get(uint8_t channel, ANT_BUFFER_PTR * p_coex_config, ANT_BUFFER_PTR * p_adv_coex_config) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_coex_config; + mp_out_params[1] = p_adv_coex_config; + + const uint32_t err_code = ant_coex_config_get_req_enc(channel, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + coex_config_get_rsp_dec); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_acknowledge_message_tx.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_acknowledge_message_tx.c new file mode 100644 index 0000000000000000000000000000000000000000..a42850694b583960cef7f9f9078639b592b4f7cb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_acknowledge_message_tx.c @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_acknowledge_message_tx_req_enc(uint8_t channel, + uint8_t size, + uint8_t const * const p_mesg, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint8_t svc_number = SVC_ANT_TX_ACKNOWLEDGED_MESSAGE; + uint32_t err_code = NRF_SUCCESS; + uint32_t buf_len = *p_buf_len; + uint32_t index = 0; + + err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&channel, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&size, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_enc(p_mesg, size, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_acknowledge_message_tx_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_TX_ACKNOWLEDGED_MESSAGE, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c new file mode 100644 index 0000000000000000000000000000000000000000..965e5fb4b2b1408ed94e0f4287ebce772d69e1a9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_active_search_sharing_cycles_get_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_GET; + p_buf[index++] = channel; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_active_search_sharing_cycles_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_cycles, + uint32_t * const p_result_code) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_result_code); + + uint32_t index = 0; + uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, + SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_GET, p_result_code); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (*p_result_code != NRF_SUCCESS) + { + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; + } + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_cycles); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c new file mode 100644 index 0000000000000000000000000000000000000000..855155d86d076bd825e3f84099397336c8536734 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_active_search_sharing_cycles_set_req_enc(uint8_t channel, + uint8_t cycles, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_SET; + p_buf[index++] = channel; + p_buf[index++] = cycles; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_active_search_sharing_cycles_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_adv_burst_config_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_adv_burst_config_set.c new file mode 100644 index 0000000000000000000000000000000000000000..bd72ecf9f96670838231b90f1d5f86ac787a019c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_adv_burst_config_set.c @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_adv_burst_config_set_req_enc(uint8_t const * const p_config, + uint8_t size, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint8_t svc_number = SVC_ANT_ADV_BURST_CONFIG_SET; + uint32_t err_code = NRF_SUCCESS; + uint32_t buf_len = *p_buf_len; + uint32_t index = 0; + + err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&size, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_enc(p_config, size, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_adv_burst_config_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_ADV_BURST_CONFIG_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_app.h new file mode 100644 index 0000000000000000000000000000000000000000..6462e013377e14d7d5fef37d1c12c35613f9c329 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_app.h @@ -0,0 +1,1652 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_APP_H__ +#define ANT_APP_H__ + +/** + * @addtogroup ser_app_s212_codecs Application codecs for S212 + * @ingroup ser_codecs_app + */ + +/**@file + * + * @defgroup ant_app Application command request encoders and command response decoders + * @{ + * @ingroup ser_app_s212_codecs + * + * @brief Application command request encoders and command response decoders. + */ +//#include "ble.h" +#include "ant_interface.h" + +/**@brief Encodes @ref sd_ant_enable command request. + * + * @sa @ref ant_enable_rsp_dec for command response decoder. + * + * @param[in] p_ant_enable_params Pointer to an @ref ANT_ENABLE structure. + * @param[in] p_buf Pointer to buffer where encoded data command will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_enable_req_enc(ANT_ENABLE * p_ant_enable_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_enable command. + * + * @sa @ref ant_enable_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_enable_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_assign command request. + * + * @sa @ref ant_channel_assign_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * to assign. + * @param[in] channel_type Channel Type is an unsigned char (1 octet) denoting the + * channel type. See Assign Channel Parameters/Assign Channel + * Types in ant_parameters.h. + * @param[in] network Network is an unsigned char (1 octet) denoting the network + * key to associate with the channel. + * @param[in] ext_assign Ext Assign is a bit field (1 octet) for an extended + * assign. See Ext. Assign Channel Parameters in + * ant_parameters.h. + * @param[in] p_buf Pointer to buffer where encoded data command will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_assign_req_enc(uint8_t channel, + uint8_t channel_type, + uint8_t network, + uint8_t ext_assign, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_assign command. + * + * @sa @ref ant_channel_assign_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_assign_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_open command request. + * + * @sa @ref ant_channel_open_with_offset_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel to + * open. + * @param[in] usOffset Denote the offset from which to start the channel. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_open_with_offset_req_enc(uint8_t channel, + uint16_t usOffset, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_open command. + * + * @sa @ref ant_channel_open_with_offset_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_open_with_offset_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_id_set command request. + * + * @sa @ref ant_channel_id_set_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number to set. + * @param[in] device_number Device Number is an unsigned short (2 octets) denoting the + * device number. + * @param[in] device_type Device Type is an unsigned char (1 octet) denoting the device + * type. + * @param[in] transmit_type Transmit Type is an unsigned char (1 octet) denoting the + * transmission type. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_id_set_req_enc(uint8_t channel, + uint16_t device_number, + uint8_t device_type, + uint8_t transmit_type, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_id_set command. + * + * @sa @ref ant_channel_id_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_id_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_period_set command request. + * + * @sa @ref ant_channel_period_set_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number to set the period to. + * @param[in] period Period is an unsigned short (2 octets) denoting the period in + * 32 kHz counts (usPeriod/32768 s). + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_period_set_req_enc(uint8_t channel, + uint16_t period, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_period_set command. + * + * @sa @ref ant_channel_period_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_period_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_radio_freq_set command request. + * + * @sa @ref ant_channel_radio_freq_set_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number to set to. + * @param[in] freq Freq is an unsigned char (1 octet) denoting the radio + * frequency offset from 2400 MHz (eg. 2466 MHz, ucFreq = 66). + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_radio_freq_set_req_enc(uint8_t channel, + uint8_t freq, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_radio_freq_set command. + * + * @sa @ref ant_channel_radio_freq_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_radio_freq_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_broadcast_message_tx command request. + * + * @sa @ref ant_broadcast_message_tx_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel to + * send the data on. + * @param[in] size Size is an unsigned char (1 octet) denoting the size of the + * message, ucSize must be 8. + * @param[in] p_mesg Mesg is the buffer where the message is located (array must be + * 8 octets). + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_broadcast_message_tx_req_enc(uint8_t channel, + uint8_t size, + uint8_t const * const p_mesg, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_broadcast_message_tx command. + * + * @sa @ref ant_broadcast_message_tx_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_broadcast_message_tx_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + + +/**@brief Encodes @ref sd_ant_acknowledge_message_tx command request. + * + * @sa @ref ant_acknowledge_message_tx_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel to + * send the data on. + * @param[in] size Size is an unsigned char (1 octet) denoting the size of the + * message, ucSize must be 8. + * @param[in] p_mesg Mesg is the buffer where the message is located (array must be + * 8 octets). + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_acknowledge_message_tx_req_enc(uint8_t channel, + uint8_t size, + uint8_t const * const p_mesg, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_acknowledge_message_tx command. + * + * @sa @ref ant_acknowledge_message_tx_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_acknowledge_message_tx_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_unassign command request. + * + * @sa @ref ant_channel_unassign_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * to unassign. + * @param[in] p_buf Pointer to buffer where encoded data command will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_unassign_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_unassign command. + * + * @sa @ref ant_channel_unassign_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_unassign_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_close command request. + * + * @sa @ref ant_channel_close_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * to close. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_close_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_close command. + * + * @sa @ref ant_channel_close_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_close_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_network_address_set command request. + * + * @sa @ref ant_network_address_set_rsp_dec for command response decoder. + * + * @param[in] network Network is an unsigned char (1 octet) denoting the network + * number to assign the network address to. + * @param[in] p_network_key Network key is the pointer to location of the Network Key (8 + * octets in length). + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_network_address_set_req_enc(uint8_t network, + uint8_t const * const p_network_key, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_network_address_set command. + * + * @sa @ref ant_network_address_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_network_address_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_radio_tx_power_set command request. + * + * @sa @ref ant_channel_radio_tx_power_set_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number to assign the radio TX power. + * @param[in] tx_power TX Power is an unsigned char (1 octet) denoting the ANT + * transmit power index. See Radio TX Power Definitions in + * ant_parameters.h. + * @param[in] custom_tx_power Custom TX Power is an unsigned char (1 octet) denoting the + * custom nRF transmit power as defined in nrf51_bitfields.h. + * Only applicable if tx_power is set to custom TX power + * selection. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_radio_tx_power_set_req_enc(uint8_t channel, + uint8_t tx_power, + uint8_t custom_tx_power, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_radio_tx_power_set command. + * + * @sa @ref ant_channel_radio_tx_power_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_radio_tx_power_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_rx_search_timeout_set command request. + * + * @sa @ref ant_channel_rx_search_timeout_set_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number to set. + * @param[in] timeout Timeout is an unsigned char (1 octet) denoting the time-out + * value. + * When applied to an assigned slave channel, ucTimeout is in 2.5 + * second increments. Default = 10 (25 s) at channel assignment. + * When applied to an assigned master channel, ucTimeout is in + * 250 ms increments. Default = 0 (disabled) at channel assignment + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_rx_search_timeout_set_req_enc(uint8_t channel, + uint8_t timeout, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_rx_search_timeout_set command. + * + * @sa @ref ant_channel_rx_search_timeout_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_rx_search_timeout_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_low_priority_rx_search_timeout_set command request. + * + * @sa @ref ant_channel_low_priority_rx_search_timeout_set_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number to set. + * @param[in] timeout Timeout is an unsigned char (1 octet) denoting the time-out + * value in 2.5 seconds increments. Default = 2 (5s). + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_low_priority_rx_search_timeout_set_req_enc(uint8_t channel, + uint8_t timeout, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_low_priority_rx_search_timeout_set command. + * + * @sa @ref ant_channel_low_priority_rx_search_timeout_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_low_priority_rx_search_timeout_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_prox_search_set command request. + * + * @sa @ref ant_prox_search_set_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number. + * @param[in] prox_threshold Prox threshold is an unsigned char (1 octet) denoting the + * minimum RSSI threshold required for acquisition during a + * search. See Radio Proximity Search Threshold in + * ant_parameters.h. + * @param[in] custom_prox_threshold Custom prox threshold is an unsigned char (1 octet) denoting + * the custom minimum RSSI threshold for acquisition during a + * search. Only applicable if ucProxThreshold is set to custom + * proximity selection. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_prox_search_set_req_enc(uint8_t channel, + uint8_t prox_threshold, + uint8_t custom_prox_threshold, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_prox_search_set command. + * + * @sa @ref ant_prox_search_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_prox_search_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_search_waveform_set command request. + * + * @sa @ref ant_search_waveform_set_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number. + * @param[in] waveform Waveform is an unsigned short (2 octets) denoting the channel + * waveform period (usWaveform/32768 s). Default = 316. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_search_waveform_set_req_enc(uint8_t channel, + uint16_t waveform, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_search_waveform_set command. + * + * @sa @ref ant_search_waveform_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_search_waveform_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_id_get command request. + * + * @sa @ref ant_channel_id_get_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_id_get_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_id_get command. + * + * @sa @ref ant_channel_id_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_device_number Pointer to device number. + * @param[in] p_device_type Pointer to device type. + * @param[in] p_transmit_type Pointer to transmit type. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_id_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_device_number, + void * const p_device_type, + void * const p_transmit_type, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_radio_freq_get command request. + * + * @sa @ref ant_channel_radio_freq_get_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_radio_freq_get_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_radio_freq_get command. + * + * @sa @ref ant_channel_radio_freq_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_r_freq Pointer to radio frequency. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_radio_freq_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_r_freq, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_period_get command request. + * + * @sa @ref ant_channel_period_get_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_period_get_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_period_get command. + * + * @sa @ref ant_channel_period_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_period Pointer to period + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_period_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * p_period, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_search_channel_priority_set command request. + * + * @sa @ref ant_search_channel_priority_set_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number. + * @param[in] search_priority Search Priority is an unsigned char (1 octet) denoting the + * search priority value. 0 to 7 (Default = 0). + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_search_channel_priority_set_req_enc(uint8_t channel, + uint8_t search_priority, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_search_channel_priority_set command. + * + * @sa @ref ant_search_channel_priority_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_search_channel_priority_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + + +/**@brief Encodes @ref sd_ant_active_search_sharing_cycles_set command request. + * + * @sa @ref ant_active_search_sharing_cycles_set_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number. + * @param[in] cycles Cycles is an unsigned char (1 octet) denoting the number of + * cycles to set. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_active_search_sharing_cycles_set_req_enc(uint8_t channel, + uint8_t cycles, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_active_search_sharing_cycles_set command. + * + * @sa @ref ant_active_search_sharing_cycles_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_active_search_sharing_cycles_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_lib_config_set command request. + * + * @sa @ref ant_lib_config_set_rsp_dec for command response decoder. + * + * @param[in] ant_lib_config ANT Lib Config an unsigned char (1 octet) denoting the ANT lib + * config bit flags. See ANT Library Config in ant_parameters.h. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_lib_config_set_req_enc(uint8_t ant_lib_config, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_lib_config_set command. + * + * @sa @ref ant_lib_config_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_lib_config_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_active_search_sharing_cycles_get command request. + * + * @sa @ref ant_active_search_sharing_cycles_get_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_active_search_sharing_cycles_get_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_active_search_sharing_cycles_get command. + * + * @sa @ref ant_active_search_sharing_cycles_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_cycles Pointer to cycles. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_active_search_sharing_cycles_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_cycles, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_lib_config_get command request. + * + * @sa @ref ant_lib_config_get_rsp_dec for command response decoder. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_lib_config_get_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_lib_config_get command. + * + * @sa @ref ant_lib_config_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_ant_lib_config Pointer to the ANT library configuration. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_lib_config_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_ant_lib_config, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_lib_config_clear command request. + * + * @sa @ref ant_lib_config_clear_rsp_dec for command response decoder. + * + * @param[in] ant_lib_config ANT lib config is an unsigned char (1 octet) denoting the + * ANT lib config bit(s) to clear. See ANT Library Config in + * ant_parameters.h. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_lib_config_clear_req_enc(uint8_t ant_lib_config, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_lib_config_clear command. + * + * @sa @ref ant_lib_config_clear_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_lib_config_clear_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_stack_reset command request. + * + * @sa @ref ant_stack_reset_rsp_dec for command response decoder. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_stack_reset_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_stack_reset command. + * + * @sa @ref ant_stack_reset_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_stack_reset_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_rx_scan_mode_start command request. + * + * @sa @ref ant_rx_scan_mode_start_rsp_dec for command response decoder. + * + * @param[in] sync_channel_packets_only Sync channel packets only is an unsigned char (1 octet) + * denoting synchronous channel only scanning mode. + * 0 = disable, 1 = enable. + * @param[in] p_buf Pointer to buffer where encoded data command will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_rx_scan_mode_start_req_enc(uint8_t sync_channel_packets_only, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_rx_scan_mode_start command. + * + * @sa @ref ant_rx_scan_mode_start_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_rx_scan_mode_start_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_id_list_add command request. + * + * @sa @ref ant_id_list_add_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number to add the list entry to. + * @param[in] p_dev_id Dev ID is the pointer to the buffer (4 octets) containing + * device ID information with the following format: + * Byte0 = DeviceNumber_LSB + * Byte1 = DeviceNumber_MSB + * Byte2 = DeviceType + * Byte3 = TransType + * @param[in] list_index List index is an unsigned char (1 octet) denoting the index + * where the specified channel ID is to be placed in the list (0-3). + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_id_list_add_req_enc(uint8_t channel, + uint8_t const * const p_dev_id, + uint8_t list_index, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_id_list_add command. + * + * @sa @ref ant_id_list_add_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_id_list_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_id_list_config command request. + * + * @sa @ref ant_id_list_config_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the + * channel number of the device ID list. + * @param[in] id_list_size ID list size is an unsigned char (1 octet) denoting the size of + * the inclusion or exclusion list (0-4). + * @param[in] inc_exc_flag Inc exc flag is an unsigned char (1 octet) denoting the type of + * list as Include(0) or Exclude(1). + * @param[in] channel + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_id_list_config_req_enc(uint8_t channel, + uint8_t id_list_size, + uint8_t inc_exc_flag, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_id_list_config command. + * + * @sa @ref ant_id_list_config_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_id_list_config_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_channel_status_get command request. + * + * @sa @ref ant_channel_status_get_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel + * number. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_status_get_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_channel_status_get command. + * + * @sa @ref ant_channel_status_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_status Pointer to status + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_channel_status_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_status, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_cw_test_mode_init command request. + * + * @sa @ref ant_cw_test_mode_init_rsp_dec for command response decoder. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_cw_test_mode_init_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_cw_test_mode_init command. + * + * @sa @ref ant_cw_test_mode_init_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_cw_test_mode_init_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_cw_test_mode command request. + * + * @sa @ref ant_cw_test_mode_rsp_dec for command response decoder. + * + * @param[in] radio_freq Radio freq is an unsigned char (1 octet) denoting the radio + * frequency offset from 2400 MHz for continuous wave mode. + * (eg. 2466 MHz, ucRadioFreq = 66). + * @param[in] tx_power TX Power is an unsigned char (1 octet) denoting the ANT transmit + * power index for continuous wave mode. See Radio TX Power + * Definitions in ant_parameters.h + * @param[in] custom_tx_power Custom TX power is an unsigned char (1 octet) denoting the + * custom nRF transmit power as defined in nrf51_bitfields.h. Only + * applicable if ucTxPower is set to custom TX power selection. + * @param[in] mode Mode is an unsigned char (1 octet) denoting test mode type where + * 0 = cw tx carrier transmission, 1 = cw tx modulated transmission. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_cw_test_mode_req_enc(uint8_t radio_freq, + uint8_t tx_power, + uint8_t custom_tx_power, + uint8_t mode, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_cw_test_mode command. + * + * @sa @ref ant_cw_test_mode_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_cw_test_mode_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_version_get command request. + * + * @sa @ref ant_version_get_rsp_dec for command response decoder. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_version_get_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_version_get command. + * + * @sa @ref ant_version_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_version Pointer to version string buffer. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_version_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * * const p_version, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_capabilities_get command request. + * + * @sa @ref ant_capabilities_get_rsp_dec for command response decoder. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_capabilities_get_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_capabilities_get command. + * + * @sa @ref ant_capabilities_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] pp_capabilities Pointer to pointer to capabilities buffer. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_capabilities_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * * const pp_capabilities, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_crypto_channel_enable command request. + * + * @sa @ref ant_crypto_channel_enable_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel in + * which encryption mode is set. + * @param[in] enable Enable is an unsigned char (1 octet) denoting the encryption + * mode. See Encrypted Channel Defines in ant_parameters.h. + * @param[in] key_num Key num is an unsigned char (1 octet) denoting the key index of + * the 128-bit key to be used for encryption. The key index range + * is bound by the number of encrypted channels configured by + * sd_ant_enable(). If sd_ant_enable() is not used then by default + * key num is 0. Range is [0 to (num encrypted channels - 1)], if + * 1 or more encrypted channels are configured. + * @param[in] decimation_rate Decimation rate is an unsigned char (1 octet) denoting the + * decimate rate to apply for encrypted slave channel. Must be > 0. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_crypto_channel_enable_req_enc(uint8_t channel, + uint8_t enable, + uint8_t key_num, + uint8_t decimation_rate, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_crypto_channel_enable command. + * + * @sa @ref ant_crypto_channel_enable_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_crypto_channel_enable_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_adv_burst_config_set command request. + * + * @sa @ref ant_adv_burst_config_set_rsp_dec for command response decoder. + * + * @param[in] p_config Config is a buffer containing the advanced burst + * configuration to be set. + * @param[in] size Size is an unsigned char (1 octet) denoting the size of the + * configuration parameter buffer. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_adv_burst_config_set_req_enc(uint8_t const * const p_config, + uint8_t size, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_adv_burst_config_set command. + * + * @sa @ref ant_adv_burst_config_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_adv_burst_config_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_crypto_key_set command request. + * + * @sa @ref ant_crypto_key_set_rsp_dec for command response decoder. + * + * @param[in] key_num Key num is an unsigned char (1 octet) denoting the key index for + * assignment. + * @param[in] p_key Buffer (16 octets) containing the 128-bit AES key to be + * assigned to the key index. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_crypto_key_set_req_enc(uint8_t key_num, + uint8_t const * const p_key, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_crypto_key_set command. + * + * @sa @ref ant_crypto_key_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_crypto_key_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_crypto_info_set command request. + * + * @sa @ref ant_crypto_info_set_rsp_dec for command response decoder. + * + * @param[in] type Type is an unsigned char (1 octet) denoting the type of + * information being set. + * @param[in] p_info Pointer to a buffer buffer containing the information being set. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_crypto_info_set_req_enc(uint8_t type, + uint8_t const * const p_info, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_crypto_info_set command. + * + * @sa @ref ant_crypto_info_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_crypto_info_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_crypto_info_get command request. + * + * @sa @ref ant_crypto_info_get_rsp_dec for command response decoder. + * + * @param[in] type Type is an unsigned char (1 octet) denoting the type of + * information being set. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_crypto_info_get_req_enc(uint8_t type, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_crypto_info_get command. + * + * @sa @ref ant_crypto_info_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_info Pointer to the info buffer. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_crypto_info_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_info, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_coex_config_set command request. + * + * @sa @ref ant_coex_config_set_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel for + * which the coexistence configuration is to be set + * @param[in] p_config Pointer to a buffer containing the configuration to be set. + * @param[in] p_adv_coex_config Pointer to a buffer containing the advanced coexistence configuration + * to be set. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_coex_config_set_req_enc(uint8_t channel, + ANT_BUFFER_PTR const * const p_config, + ANT_BUFFER_PTR const * const p_adv_coex_config, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_coex_config_set command. + * + * @sa @ref ant_coex_config_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_coex_config_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ant_coex_config_get command request. + * + * @sa @ref ant_coex_config_get_rsp_dec for command response decoder. + * + * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel to + * query. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_coex_config_get_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ant_coex_config_get command. + * + * @sa @ref ant_coex_config_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_coex_config Pointer to the coexistence configuration buffer. + * @param[in] p_adv_coex_config Pointer to the advanced coexistence configuration buffer. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ant_coex_config_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_coex_config, + void * const p_adv_coex_config, + uint32_t * const p_result_code); +/** @} */ +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_broadcast_message_tx.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_broadcast_message_tx.c new file mode 100644 index 0000000000000000000000000000000000000000..71e45397eb9bafa2b6f4087b2c013308fa339eec --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_broadcast_message_tx.c @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_broadcast_message_tx_req_enc(uint8_t channel, + uint8_t size, + uint8_t const * const p_mesg, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint8_t svc_number = SVC_ANT_TX_BROADCAST_MESSAGE; + uint32_t err_code = NRF_SUCCESS; + uint32_t buf_len = *p_buf_len; + uint32_t index = 0; + + err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&channel, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&size, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_enc(p_mesg, size, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_broadcast_message_tx_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_TX_BROADCAST_MESSAGE, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_capabilities_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_capabilities_get.c new file mode 100644 index 0000000000000000000000000000000000000000..9263a3a9efa2612dd41655a1fba086dc12c09dd2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_capabilities_get.c @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_capabilities_get_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CAPABILITIES; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_capabilities_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * * const pp_capabilities, + uint32_t * const p_result_code) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_result_code); + + uint32_t index = 0; + uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, + SVC_ANT_CAPABILITIES, p_result_code); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (*p_result_code != NRF_SUCCESS) + { + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; + } + + err_code = uint8_vector_dec(p_buf, packet_len, &index, (uint8_t *)*pp_capabilities, MESG_CAPABILITIES_SIZE); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_assign.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_assign.c new file mode 100644 index 0000000000000000000000000000000000000000..c53aa462ca5d42be01c920af350ebb5590ec275b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_assign.c @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_assign_req_enc(uint8_t channel, + uint8_t channel_type, + uint8_t network, + uint8_t ext_assign, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_ASSIGN; + p_buf[index++] = channel; + p_buf[index++] = channel_type; + p_buf[index++] = network; + p_buf[index++] = ext_assign; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_channel_assign_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_ASSIGN, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_close.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_close.c new file mode 100644 index 0000000000000000000000000000000000000000..96da1ce2f300a7accf4da16d62f93a55cac6f111 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_close.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_close_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_CLOSE; + p_buf[index++] = channel; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_channel_close_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_CLOSE, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_id_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_id_get.c new file mode 100644 index 0000000000000000000000000000000000000000..d990e72a16d273ca928e664562aaf8c30a7f9130 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_id_get.c @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_id_get_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_ID_GET; + p_buf[index++] = channel; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_channel_id_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_device_number, + void * const p_device_type, + void * const p_transmit_type, + uint32_t * const p_result_code) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_result_code); + + uint32_t index = 0; + uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, + SVC_ANT_CHANNEL_ID_GET, p_result_code); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (*p_result_code != NRF_SUCCESS) + { + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; + } + + err_code = uint16_t_dec(p_buf, packet_len, &index, p_device_number); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_device_type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_transmit_type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_id_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_id_set.c new file mode 100644 index 0000000000000000000000000000000000000000..f2c25b51d42e7cf95b051760cd4760d5a6b02bbe --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_id_set.c @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_id_set_req_enc(uint8_t channel, + uint16_t device_number, + uint8_t device_type, + uint8_t transmit_type, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_ID_SET; + p_buf[index++] = channel; + index += uint16_encode(device_number, &p_buf[index]); + p_buf[index++] = device_type; + p_buf[index++] = transmit_type; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_channel_id_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_ID_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_low_priority_rx_search_timeout_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_low_priority_rx_search_timeout_set.c new file mode 100644 index 0000000000000000000000000000000000000000..a56c2abca5500b5a98cb006c8ba6c790ead0fdfb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_low_priority_rx_search_timeout_set.c @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_low_priority_rx_search_timeout_set_req_enc(uint8_t channel, + uint8_t timeout, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_LOW_PRIO_RX_SEARCH_TIMEOUT_SET; + p_buf[index++] = channel; + p_buf[index++] = timeout; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_channel_low_priority_rx_search_timeout_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_LOW_PRIO_RX_SEARCH_TIMEOUT_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_open_with_offset.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_open_with_offset.c new file mode 100644 index 0000000000000000000000000000000000000000..2084df5a2ff724102cbf620556d54650b01822fb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_open_with_offset.c @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_open_with_offset_req_enc(uint8_t channel, + uint16_t usOffset, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_OPEN; + p_buf[index++] = channel; + index += uint16_encode(usOffset, &p_buf[index]); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_channel_open_with_offset_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_OPEN, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_period_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_period_get.c new file mode 100644 index 0000000000000000000000000000000000000000..893ca651c7440d117b3beeaf08bce403492cd2ad --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_period_get.c @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_period_get_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_PERIOD_GET; + p_buf[index++] = channel; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_channel_period_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * p_period, + uint32_t * const p_result_code) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_result_code); + + uint32_t index = 0; + uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, + SVC_ANT_CHANNEL_PERIOD_GET, p_result_code); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (*p_result_code != NRF_SUCCESS) + { + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; + } + + err_code = uint16_t_dec(p_buf, packet_len, &index, p_period); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_period_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_period_set.c new file mode 100644 index 0000000000000000000000000000000000000000..9df34e7b40bb25a2daec7b28d196ab7873a2e914 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_period_set.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_period_set_req_enc(uint8_t channel, + uint16_t period, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_PERIOD_SET; + p_buf[index++] = channel; + index += uint16_encode(period, &p_buf[index]); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_channel_period_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_PERIOD_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_get.c new file mode 100644 index 0000000000000000000000000000000000000000..79ee2282fd8423e1d9f41b701bd4558abf096f5f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_get.c @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_radio_freq_get_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_RADIO_FREQ_GET; + p_buf[index++] = channel; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_channel_radio_freq_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_r_freq, + uint32_t * const p_result_code) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_result_code); + + uint32_t index = 0; + uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, + SVC_ANT_CHANNEL_RADIO_FREQ_GET, p_result_code); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (*p_result_code != NRF_SUCCESS) + { + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; + } + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_r_freq); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_set.c new file mode 100644 index 0000000000000000000000000000000000000000..4e5a72d2077bf0eff452e4c1a91b59626e708d69 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_set.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_radio_freq_set_req_enc(uint8_t channel, + uint8_t freq, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_RADIO_FREQ_SET; + p_buf[index++] = channel; + p_buf[index++] = freq; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_channel_radio_freq_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_RADIO_FREQ_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_radio_tx_power_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_radio_tx_power_set.c new file mode 100644 index 0000000000000000000000000000000000000000..5637285c9871f3dc5c3b2108ec455c40f51d639f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_radio_tx_power_set.c @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_radio_tx_power_set_req_enc(uint8_t channel, + uint8_t tx_power, + uint8_t custom_tx_power, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_RADIO_TX_POWER_SET; + p_buf[index++] = channel; + p_buf[index++] = tx_power; + p_buf[index++] = custom_tx_power; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_channel_radio_tx_power_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_RADIO_TX_POWER_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c new file mode 100644 index 0000000000000000000000000000000000000000..1e8745bdf0d1d9482328307e161439fbba186a0e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_rx_search_timeout_set_req_enc(uint8_t channel, + uint8_t timeout, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_SEARCH_TIMEOUT_SET; + p_buf[index++] = channel; + p_buf[index++] = timeout; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_channel_rx_search_timeout_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_SEARCH_TIMEOUT_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_status_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_status_get.c new file mode 100644 index 0000000000000000000000000000000000000000..5282dc0f46ae669abad36b74ce18f9c0a733467c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_status_get.c @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_status_get_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_STATUS_GET; + p_buf[index++] = channel; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_channel_status_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_status, + uint32_t * const p_result_code) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_result_code); + + uint32_t index = 0; + uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, + SVC_ANT_CHANNEL_STATUS_GET, p_result_code); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (*p_result_code != NRF_SUCCESS) + { + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; + } + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_status); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_unassign.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_unassign.c new file mode 100644 index 0000000000000000000000000000000000000000..82ea0c298d510f035ccb8a75687490f098f80ccc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_channel_unassign.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_unassign_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CHANNEL_UNASSIGN; + p_buf[index++] = channel; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_channel_unassign_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_UNASSIGN, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_coex_config_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_coex_config_get.c new file mode 100644 index 0000000000000000000000000000000000000000..51ceae615892f95be0f9390cf9c992326fca97da --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_coex_config_get.c @@ -0,0 +1,130 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include "ant_interface.h" + +uint32_t ant_coex_config_get_req_enc(uint8_t channel, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint8_t svc_number = SVC_ANT_COEX_CONFIG_GET; + uint32_t err_code = NRF_SUCCESS; + uint32_t buf_len = *p_buf_len; + uint32_t index = 0; + + err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&channel, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_coex_config_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_coex_config, + void * const p_adv_coex_config, + uint32_t * const p_result_code) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_result_code); + + uint32_t index = 0; + uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, + SVC_ANT_COEX_CONFIG_GET, p_result_code); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (*p_result_code != NRF_SUCCESS) + { + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; + } + + uint8_t coex_config_size; + uint8_t coex_config_buffer[(MESG_BUFFER_SIZE / 2) - 1]; + + uint8_t adv_coex_config_size; + uint8_t adv_coex_config_buffer[(MESG_BUFFER_SIZE / 2) - 1]; + + err_code = uint8_t_dec(p_buf, packet_len, &index, &coex_config_size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_dec(p_buf, packet_len, &index, coex_config_buffer, coex_config_size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, &(adv_coex_config_size)); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_dec(p_buf, packet_len, &index, adv_coex_config_buffer, adv_coex_config_size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + + if (p_coex_config) + { + ((ANT_BUFFER_PTR *)p_coex_config)->ucBufferSize = coex_config_size; + memcpy(((ANT_BUFFER_PTR *)p_coex_config)->pucBuffer, coex_config_buffer,((ANT_BUFFER_PTR *)p_coex_config)->ucBufferSize); + } + + if (p_adv_coex_config) + { + ((ANT_BUFFER_PTR *)p_adv_coex_config)->ucBufferSize = coex_config_size; + memcpy(((ANT_BUFFER_PTR *)p_adv_coex_config)->pucBuffer, coex_config_buffer,((ANT_BUFFER_PTR *)p_adv_coex_config)->ucBufferSize); + } + + SER_ASSERT_LENGTH_LEQ(index, packet_len); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_coex_config_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_coex_config_set.c new file mode 100644 index 0000000000000000000000000000000000000000..34f6daf84bf663313b1b10b72aefc61f1fefc473 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_coex_config_set.c @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_coex_config_set_req_enc(uint8_t channel, + ANT_BUFFER_PTR const * const p_coex_config, + ANT_BUFFER_PTR const * const p_adv_coex_config, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint8_t svc_number = SVC_ANT_COEX_CONFIG_SET; + uint32_t err_code = NRF_SUCCESS; + uint32_t buf_len = *p_buf_len; + uint32_t index = 0; + + err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&channel, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + // Encode coex config buffer size + uint8_t coex_config_buffer_size = p_coex_config -> ucBufferSize; + err_code = uint8_t_enc(&coex_config_buffer_size, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + // Encode coex config buffer + err_code = uint8_vector_enc(p_coex_config -> pucBuffer, + coex_config_buffer_size, + p_buf, + buf_len, + &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + // Encode advanced coex config buffer size + uint8_t adv_coex_config_buffer_size = p_adv_coex_config -> ucBufferSize; + err_code = uint8_t_enc(&adv_coex_config_buffer_size, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + // Encode advanced coex config buffer + err_code = uint8_vector_enc(p_adv_coex_config -> pucBuffer, + adv_coex_config_buffer_size, + p_buf, + buf_len, + &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_coex_config_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_COEX_CONFIG_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_crypto_channel_enable.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_crypto_channel_enable.c new file mode 100644 index 0000000000000000000000000000000000000000..3d116d8a3fbfde9d96c2ff4e29962e44a85fac8b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_crypto_channel_enable.c @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_crypto_channel_enable_req_enc(uint8_t channel, + uint8_t enable, + uint8_t key_num, + uint8_t decimation_rate, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CRYPTO_CHANNEL_ENABLE; + p_buf[index++] = channel; + p_buf[index++] = enable; + p_buf[index++] = key_num; + p_buf[index++] = decimation_rate; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_crypto_channel_enable_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CRYPTO_CHANNEL_ENABLE, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_crypto_info_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_crypto_info_get.c new file mode 100644 index 0000000000000000000000000000000000000000..aadeecae2ea8c35ba3cc0304ef57b3fadb708d4d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_crypto_info_get.c @@ -0,0 +1,123 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_crypto_info_get_req_enc(uint8_t type, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint8_t svc_number = SVC_ANT_CRYPTO_INFO_GET; + uint32_t err_code = NRF_SUCCESS; + uint32_t buf_len = *p_buf_len; + uint32_t index = 0; + + err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&type, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_LEQ(index, buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_crypto_info_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_info, + uint32_t * const p_result_code) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_result_code); + + uint32_t index = 0; + uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, + SVC_ANT_CRYPTO_INFO_GET, p_result_code); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (*p_result_code != NRF_SUCCESS) + { + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; + } + + uint8_t type; + uint8_t crypto_info_size; + + err_code = uint8_t_dec(p_buf, packet_len, &index, &type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + switch (type) + { + case ENCRYPTION_INFO_GET_SUPPORTED_MODE: + crypto_info_size = MESG_CONFIG_ENCRYPT_REQ_CAPABILITIES_SIZE - MESG_CHANNEL_NUM_SIZE; + break; + case ENCRYPTION_INFO_GET_CRYPTO_ID: + crypto_info_size = MESG_CONFIG_ENCRYPT_REQ_CONFIG_ID_SIZE - MESG_CHANNEL_NUM_SIZE; + break; + case ENCRYPTION_INFO_GET_CUSTOM_USER_DATA: + crypto_info_size = (MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE - + MESG_CHANNEL_NUM_SIZE); + break; + default: + crypto_info_size = 0; + break; + } + + err_code = uint8_vector_dec(p_buf, packet_len, &index, (uint8_t *)p_info, crypto_info_size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_LEQ(index, packet_len); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_crypto_info_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_crypto_info_set.c new file mode 100644 index 0000000000000000000000000000000000000000..749cd00e936c29ee32f26772ed2640a4e8d73386 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_crypto_info_set.c @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_crypto_info_set_req_enc(uint8_t type, + uint8_t const * const p_config, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint8_t svc_number = SVC_ANT_CRYPTO_INFO_SET; + uint32_t err_code = NRF_SUCCESS; + uint32_t buf_len = *p_buf_len; + uint32_t index = 0; + + err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&type, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + uint8_t crypto_info_size = (MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE - + MESG_CHANNEL_NUM_SIZE) + + (MESG_CONFIG_ENCRYPT_REQ_CONFIG_ID_SIZE - + MESG_CHANNEL_NUM_SIZE); + + err_code = uint8_vector_enc(p_config, crypto_info_size, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_crypto_info_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CRYPTO_INFO_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_crypto_key_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_crypto_key_set.c new file mode 100644 index 0000000000000000000000000000000000000000..f50a06f7b49bd33baf596602cb1a0aa09fd5a0d6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_crypto_key_set.c @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_crypto_key_set_req_enc(uint8_t key_num, + uint8_t const * const p_key, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint8_t svc_number = SVC_ANT_CRYPTO_KEY_SET; + uint32_t err_code = NRF_SUCCESS; + uint32_t buf_len = *p_buf_len; + uint32_t index = 0; + + err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&key_num, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_enc(p_key, SIZE_OF_ENCRYPTED_KEY, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_crypto_key_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CRYPTO_KEY_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode.c new file mode 100644 index 0000000000000000000000000000000000000000..6058e2232609ea7c6772f7fa42de7627c9f28ea9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode.c @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_cw_test_mode_req_enc(uint8_t radio_freq, + uint8_t tx_power, + uint8_t custom_tx_power, + uint8_t mode, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_CW_TEST_MODE; + p_buf[index++] = radio_freq; + p_buf[index++] = tx_power; + p_buf[index++] = custom_tx_power; + p_buf[index++] = mode; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_cw_test_mode_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CW_TEST_MODE, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode_init.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode_init.c new file mode 100644 index 0000000000000000000000000000000000000000..db887292e4e3731f84a9dcf485855ab45fd607ee --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode_init.c @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_cw_test_mode_init_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_INIT_CW_TEST_MODE; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_cw_test_mode_init_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_INIT_CW_TEST_MODE, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_enable.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_enable.c new file mode 100644 index 0000000000000000000000000000000000000000..7c7065f61e4334d481af49874e7ac28a072e6489 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_enable.c @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_enable_req_enc(ANT_ENABLE * const p_channel_enable, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_ENABLE; + + err_code = cond_field_enc(p_channel_enable, p_buf, *p_buf_len, &index, ANT_ENABLE_enc); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_enable_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_ENABLE, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_event.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_event.c new file mode 100644 index 0000000000000000000000000000000000000000..fa5e696d629c1bba39168e18ab48daa204686599 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_event.c @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +//#include "ble_app.h" +//#include "ble_evt_app.h" +//#include "ble_gap_evt_app.h" +//#include "ble_gattc_evt_app.h" +//#include "ble_gatts_evt_app.h" +//#include "ble_l2cap_evt_app.h" +#include "ble_serialization.h" +#include "app_util.h" +#include "ant_stack_handler_types.h" +#include "ant_struct_serialization.h" +#include "ant_parameters.h" + +uint32_t ant_event_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ant_evt_t * const p_event, + uint32_t * const p_event_len) +{ + uint32_t index = SER_ANT_EVT_ID_POS; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_event_len); + SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE, packet_len); + SER_ASSERT_NOT_NULL(p_event); + + err_code = ant_evt_t_dec(p_buf, packet_len, &index, p_event); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + *p_event_len = index; + + SER_ASSERT_LENGTH_LEQ(p_event->channel, MAX_ANT_CHANNELS); + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_event.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_event.h new file mode 100644 index 0000000000000000000000000000000000000000..490895f7d9c4e78142613e3377add4fbd24ae4a9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_event.h @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef __ANT_EVENT_H__ +#define __ANT_EVENT_H__ + +#include "ble_serialization.h" +#include "app_util.h" +#include "ant_stack_handler_types.h" + +/** + * @addtogroup ser_app_s212_codecs + * @{ + */ + + +/**@brief Event decoding dispatcher. + * + * The event decoding dispatcher will route the event packet to the correct decoder, which in turn + * decodes the contents of the event and updates the \p p_event struct. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of the event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to the \ref ant_evt_t buffer where the decoded event will be + * stored. If NULL, the required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of the decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + * @retval NRF_ERROR_NOT_FOUND Decoding failure. No event decoder is available. + */ +uint32_t ant_event_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ant_evt_t * const p_event, + uint32_t * const p_event_len); +/** @} */ + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_id_list_add.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_id_list_add.c new file mode 100644 index 0000000000000000000000000000000000000000..bbe4fa06220ce571b868b75225eb4a4fe59199cb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_id_list_add.c @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include "ant_parameters.h" + +uint32_t ant_id_list_add_req_enc(uint8_t channel, + uint8_t const * const p_dev_id, + uint8_t list_index, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint8_t svc_number = SVC_ANT_ID_LIST_ADD; + uint32_t err_code = NRF_SUCCESS; + uint32_t buf_len = *p_buf_len; + uint32_t index = 0; + + err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&channel, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_enc(p_dev_id, ANT_ID_SIZE, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&list_index, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_id_list_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_ID_LIST_ADD, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_id_list_config.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_id_list_config.c new file mode 100644 index 0000000000000000000000000000000000000000..e56b417d5d50837423e8b550930648dc45370aa6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_id_list_config.c @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_id_list_config_req_enc(uint8_t channel, + uint8_t id_list_size, + uint8_t inc_exc_flag, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_ID_LIST_CONFIG; + p_buf[index++] = channel; + p_buf[index++] = id_list_size; + p_buf[index++] = inc_exc_flag; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_id_list_config_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_ID_LIST_CONFIG, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_lib_config_clear.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_lib_config_clear.c new file mode 100644 index 0000000000000000000000000000000000000000..81eec58253b347a4f1d34c176ec0e37c3306f5ba --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_lib_config_clear.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_lib_config_clear_req_enc(uint8_t ant_lib_config, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_LIB_CONFIG_CLEAR; + p_buf[index++] = ant_lib_config; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_lib_config_clear_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_LIB_CONFIG_CLEAR, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_lib_config_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_lib_config_get.c new file mode 100644 index 0000000000000000000000000000000000000000..320db148d787b7b6f7940c6068430eaa4e481f0e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_lib_config_get.c @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_lib_config_get_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_LIB_CONFIG_GET; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_lib_config_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * const p_ant_lib_config, + uint32_t * const p_result_code) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_result_code); + + uint32_t index = 0; + uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, + SVC_ANT_LIB_CONFIG_GET, p_result_code); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (*p_result_code != NRF_SUCCESS) + { + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; + } + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_ant_lib_config); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_lib_config_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_lib_config_set.c new file mode 100644 index 0000000000000000000000000000000000000000..5259907e81b2d28c2d907fe94052b471bb2219bd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_lib_config_set.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_lib_config_set_req_enc(uint8_t ant_lib_config, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_LIB_CONFIG_SET; + p_buf[index++] = ant_lib_config; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_lib_config_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_LIB_CONFIG_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_network_address_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_network_address_set.c new file mode 100644 index 0000000000000000000000000000000000000000..ad997e36eb6f2600bfb9c79b0f0a51db2200e187 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_network_address_set.c @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_network_address_set_req_enc(uint8_t network, + uint8_t const * const p_network_key, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint8_t svc_number = SVC_ANT_NETWORK_KEY_SET; + uint32_t err_code = NRF_SUCCESS; + uint32_t buf_len = *p_buf_len; + uint32_t index = 0; + + err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&network, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_enc(p_network_key, MESG_NETWORK_KEY_SIZE - MESG_CHANNEL_NUM_SIZE, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_network_address_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_NETWORK_KEY_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_prox_search_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_prox_search_set.c new file mode 100644 index 0000000000000000000000000000000000000000..fd0598d17bf69af8c1cf012c7dcddba160db6708 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_prox_search_set.c @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_prox_search_set_req_enc(uint8_t channel, + uint8_t prox_threshold, + uint8_t custom_prox_threshold, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_PROX_SEARCH_SET; + p_buf[index++] = channel; + p_buf[index++] = prox_threshold; + p_buf[index++] = custom_prox_threshold; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_prox_search_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_PROX_SEARCH_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_rx_scan_mode_start.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_rx_scan_mode_start.c new file mode 100644 index 0000000000000000000000000000000000000000..7782e75a27291db9fac50cf0d2a2fa9096f35735 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_rx_scan_mode_start.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_rx_scan_mode_start_req_enc(uint8_t sync_scan_channel_packets_only, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_RX_SCAN_MODE_START; + p_buf[index++] = sync_scan_channel_packets_only; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_rx_scan_mode_start_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_RX_SCAN_MODE_START, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_search_channel_priority_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_search_channel_priority_set.c new file mode 100644 index 0000000000000000000000000000000000000000..f9e578aedab52474da6cd114e91f2f82dc44f577 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_search_channel_priority_set.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_search_channel_priority_set_req_enc(uint8_t channel, + uint8_t search_priority, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_SEARCH_CHANNEL_PRIORITY_SET; + p_buf[index++] = channel; + p_buf[index++] = search_priority; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_search_channel_priority_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_SEARCH_CHANNEL_PRIORITY_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_search_waveform_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_search_waveform_set.c new file mode 100644 index 0000000000000000000000000000000000000000..b7ff309b171b5c5859cc14167ce54e2aa18e346b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_search_waveform_set.c @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_search_waveform_set_req_enc(uint8_t channel, + uint16_t waveform, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_SEARCH_WAVEFORM_SET; + p_buf[index++] = channel; + index += uint16_encode(waveform, &p_buf[index]); + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ant_search_waveform_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_SEARCH_WAVEFORM_SET, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_stack_reset.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_stack_reset.c new file mode 100644 index 0000000000000000000000000000000000000000..cf4ace93edf618c2bed6886ddde0e3fb957df650 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_stack_reset.c @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_stack_reset_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_STACK_INIT; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_stack_reset_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + // Use the ble cmd rsp dec function because it is adequte to decode + // the command response as it is the same for both ant and ble. + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_STACK_INIT, p_result_code); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_version_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_version_get.c new file mode 100644 index 0000000000000000000000000000000000000000..50536ad8c34d9584de31ea0068ca1d0df1a31f7a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ant/serializers/ant_version_get.c @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ant_app.h" +#include "ble_serialization.h" +#include "ant_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +uint32_t ant_version_get_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + p_buf[index++] = SVC_ANT_VERSION; + + SER_ASSERT_LENGTH_LEQ(index, *p_buf_len); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ant_version_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + void * * const p_version, + uint32_t * const p_result_code) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_result_code); + + uint32_t index = 0; + uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, + SVC_ANT_VERSION, p_result_code); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (*p_result_code != NRF_SUCCESS) + { + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; + } + + err_code = uint8_vector_dec(p_buf, packet_len, &index, (uint8_t *)*p_version, MESG_BUFFER_SIZE); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble.c new file mode 100644 index 0000000000000000000000000000000000000000..9bc362e8dfa6eeb5e831def3c09b85523044eebf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble.c @@ -0,0 +1,621 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble.h" +#include "ble_serialization.h" +#include +#include "ble_app.h" +#include "ser_sd_transport.h" +#include "app_error.h" +#include "app_ble_user_mem.h" + +extern ser_ble_user_mem_t m_app_user_mem_table[]; + +/**@brief Structure containing @ref sd_ble_uuid_encode output parameters. */ +typedef struct +{ + uint8_t * p_uuid_le_len; /**< @ref sd_ble_uuid_encode appearance p_uuid_le_len output parameter. */ + uint8_t * p_uuid_le; /**< @ref sd_ble_uuid_encode appearance p_uuid_le output parameter. */ +} ble_uuid_encode_out_params_t; + +/**@brief Structure containing @ref sd_ble_user_mem_reply output parameters. */ +typedef struct +{ + uint16_t conn_handle; /**< @ref sd_ble_user_mem_reply conn_handle. */ + uint8_t context_allocated; /**< @ref sd_ble_user_mem_reply user memory context allocated flag. */ +} ble_user_mem_reply_out_params_t; + +/**@brief Union containing BLE command output parameters. */ +typedef union +{ + ble_uuid_encode_out_params_t ble_uuid_encode_out_params; /**< @ref sd_ble_uuid_encode output parameters. */ + ble_user_mem_reply_out_params_t ble_user_mem_reply_out_params; /**< @ref sd_ble_user_mem_reply output parameters. */ +} ble_command_output_params_t; + +static ble_command_output_params_t m_output_params; /**< BLE command output parameters. */ + +static void * mp_out_params[3]; +static uint32_t m_uint32_param; + +static void tx_buf_alloc(uint8_t * * p_data, uint32_t * p_len) +{ + uint32_t err_code; + uint16_t len16; + + do + { + err_code = ser_sd_transport_tx_alloc(p_data, &len16); + } + while (err_code != NRF_SUCCESS); + + *p_data[0] = SER_PKT_TYPE_CMD; + *p_len = (uint32_t)len16 - 1; +} + +/**@brief Command response callback function for @ref sd_ble_uuid_encode BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t uuid_encode_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = + ble_uuid_encode_rsp_dec(p_buffer, + length, + m_output_params.ble_uuid_encode_out_params.p_uuid_le_len, + m_output_params.ble_uuid_encode_out_params.p_uuid_le, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_uuid_encode +#define _sd_ble_uuid_encode sd_ble_uuid_encode +#endif +uint32_t _sd_ble_uuid_encode(ble_uuid_t const * const p_uuid, + uint8_t * const p_uuid_le_len, + uint8_t * const p_uuid_le) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + m_output_params.ble_uuid_encode_out_params.p_uuid_le_len = p_uuid_le_len; + m_output_params.ble_uuid_encode_out_params.p_uuid_le = p_uuid_le; + + uint32_t err_code = ble_uuid_encode_req_enc(p_uuid, + p_uuid_le_len, + p_uuid_le, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + uuid_encode_rsp_dec); + +} + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +/**@brief Command response callback function for @ref sd_ble_tx_packet_count_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t tx_packet_count_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_tx_packet_count_get_rsp_dec(p_buffer, + length, + (uint8_t * *)&mp_out_params[0], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_tx_packet_count_get +#define _sd_ble_tx_packet_count_get sd_ble_tx_packet_count_get +#endif +uint32_t _sd_ble_tx_packet_count_get(uint16_t conn_handle, uint8_t * p_count) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_count; + + const uint32_t err_code = ble_tx_packet_count_get_req_enc(conn_handle, + p_count, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + tx_packet_count_get_rsp_dec); + +} +#endif +/**@brief Command response callback function for @ref sd_ble_uuid_vs_add BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t uuid_vs_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_uuid_vs_add_rsp_dec(p_buffer, + length, + (uint8_t * *)&mp_out_params[0], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_uuid_vs_add +#define _sd_ble_uuid_vs_add sd_ble_uuid_vs_add +#endif +uint32_t _sd_ble_uuid_vs_add(ble_uuid128_t const * const p_vs_uuid, uint8_t * const p_uuid_type) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_uuid_type; + + const uint32_t err_code = ble_uuid_vs_add_req_enc(p_vs_uuid, p_uuid_type, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + uuid_vs_add_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_uuid_decode BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t uuid_decode_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_uuid_decode_rsp_dec(p_buffer, + length, + (ble_uuid_t * *)&mp_out_params[0], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_uuid_decode +#define _sd_ble_uuid_decode sd_ble_uuid_decode +#endif +uint32_t _sd_ble_uuid_decode(uint8_t uuid_le_len, + uint8_t const * const p_uuid_le, + ble_uuid_t * const p_uuid) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_uuid; + + const uint32_t err_code = ble_uuid_decode_req_enc(uuid_le_len, p_uuid_le, p_uuid, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + uuid_decode_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_version_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t version_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_version_get_rsp_dec(p_buffer, + length, + (ble_version_t *)mp_out_params[0], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_version_get +#define _sd_ble_version_get sd_ble_version_get +#endif +uint32_t _sd_ble_version_get(ble_version_t * p_version) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_version; + + const uint32_t err_code = ble_version_get_req_enc(p_version, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + version_get_rsp_dec); + +} + +/**@brief Command response callback function for @ref sd_ble_opt_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t opt_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + uint32_t uint32_param; + uint32_t err_code = ble_opt_get_rsp_dec(p_buffer, + length, + &uint32_param, + (ble_opt_t *)mp_out_params[0], + &result_code); + + APP_ERROR_CHECK(err_code); + if ((result_code == NRF_SUCCESS) && (m_uint32_param != uint32_param)) // decoded id should be the same as encoded one + { + err_code = NRF_ERROR_INVALID_PARAM; + } + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_opt_get +#define _sd_ble_opt_get sd_ble_opt_get +#endif +uint32_t _sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_opt; + m_uint32_param = opt_id; + + const uint32_t err_code = ble_opt_get_req_enc(opt_id, + p_opt, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + opt_get_rsp_dec); + +} + +/**@brief Command response callback function for @ref sd_ble_opt_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t opt_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_opt_set_rsp_dec(p_buffer, + length, + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_opt_set +#define _sd_ble_opt_set sd_ble_opt_set +#endif +uint32_t _sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ble_opt_set_req_enc(opt_id, + p_opt, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + opt_set_rsp_dec); + +} + +/**@brief Command response callback function for @ref sd_ble_enable BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t enable_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_enable_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_enable +#define _sd_ble_enable sd_ble_enable +#endif +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t _sd_ble_enable(ble_enable_params_t * p_params, uint32_t * p_app_ram_base) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + //Ignore ram_base parameter + (void)p_app_ram_base; + + tx_buf_alloc(&p_buffer, &buffer_length); + mp_out_params[0] = p_params; + + const uint32_t err_code = ble_enable_req_enc(p_params, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + enable_rsp_dec); + +} +#else +uint32_t _sd_ble_enable(uint32_t * p_app_ram_base) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + //Ignore ram_base parameter + (void)p_app_ram_base; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ble_enable_req_enc(&(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + enable_rsp_dec); + +} +#endif +/**@brief Command response callback function for @ref sd_ble_user_mem_reply BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t user_mem_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + uint32_t err_code = ble_user_mem_reply_rsp_dec(p_buffer, + length, + &result_code); + APP_ERROR_CHECK(err_code); + + if ((result_code != NRF_SUCCESS) && + (m_output_params.ble_user_mem_reply_out_params.context_allocated)) + { + err_code = app_ble_user_mem_context_destroy( + m_output_params.ble_user_mem_reply_out_params.conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + + return result_code; +} + +#ifndef _sd_ble_user_mem_reply +#define _sd_ble_user_mem_reply sd_ble_user_mem_reply +#endif +uint32_t _sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block) +{ + uint8_t * p_buffer; + uint32_t buffer_length, user_mem_table_index; + uint32_t err_code = NRF_SUCCESS; + + tx_buf_alloc(&p_buffer, &buffer_length); + + // Prepare User Memory Block context for later synchronization when SoftDevice updates + // the data in the memory block + if (p_block != NULL) + { + err_code = app_ble_user_mem_context_create(conn_handle, &user_mem_table_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + m_app_user_mem_table[user_mem_table_index].mem_block.len = p_block->len; + m_app_user_mem_table[user_mem_table_index].mem_block.p_mem = p_block->p_mem; + // Save connection handle and context allocation flag for case if context destroy was needed + m_output_params.ble_user_mem_reply_out_params.conn_handle = conn_handle; + m_output_params.ble_user_mem_reply_out_params.context_allocated = 1; + } + else + { + m_output_params.ble_user_mem_reply_out_params.context_allocated = 0; + } + + err_code = ble_user_mem_reply_req_enc(conn_handle, + p_block, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + user_mem_reply_rsp_dec); +} +#if NRF_SD_BLE_API_VERSION >= 4 +/**@brief Command response callback function for @ref sd_ble_cfg_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t cfg_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_cfg_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_cfg_set +#define _sd_ble_cfg_set sd_ble_cfg_set +#endif +uint32_t _sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t app_ram_base) +{ + uint8_t * p_buffer; + uint32_t buffer_length; + + //Ignore ram_base parameter + (void)app_ram_base; + + tx_buf_alloc(&p_buffer, &buffer_length); + + const uint32_t err_code = ble_cfg_set_req_enc(cfg_id, p_cfg, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + cfg_set_rsp_dec); +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble_gap.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble_gap.c new file mode 100644 index 0000000000000000000000000000000000000000..ee1dafdcd198fed18464d21d49dec99cbbefd4d7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble_gap.c @@ -0,0 +1,1820 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gap.h" +#include +#include +#include "ble_serialization.h" +#include "ser_sd_transport.h" +#include "ble_gap_app.h" +#include "app_error.h" +#include "app_ble_gap_sec_keys.h" + +extern ser_ble_gap_app_keyset_t m_app_keys_table[SER_MAX_CONNECTIONS]; + +/**@brief Structure containing @ref sd_ble_gap_device_name_get output parameters. */ +typedef struct +{ + uint8_t * p_dev_name; /**< @ref sd_ble_gap_device_name_get p_dev_name output parameter. */ + uint16_t * p_len; /**< @ref sd_ble_gap_device_name_get p_len output parameter. */ +} gap_device_name_get_output_params_t; + +/**@brief Structure containing @ref sd_ble_gap_appearance_get output parameters. */ +typedef struct +{ + uint16_t * p_appearance; /**< @ref sd_ble_gap_appearance_get p_appearance output parameter. */ +} gap_appearance_get_output_params_t; + +/**@brief Structure containing @ref sd_ble_gap_ppcp_get output parameters. */ +typedef struct +{ + ble_gap_conn_params_t * p_conn_params; /**< @ref sd_ble_gap_ppcp_get p_conn_params output parameter. */ +} gap_ppcp_get_out_params_t; + +/**@brief Structure containing @ref sd_ble_gap_sec_params_reply output parameters. */ +typedef struct +{ + ble_gap_sec_keyset_t const * p_sec_keyset; /**< @ref sd_ble_gap_sec_params_reply p_sec_keyset output parameter. */ + uint16_t conn_handle; /**< @ref sd_ble_gap_sec_params_reply p_conn_handle output parameter. */ +} gap_sec_params_reply_out_params_t; + +/**@brief Union containing BLE command output parameters. */ +typedef union +{ + gap_device_name_get_output_params_t gap_device_name_get_out_params; /**< @ref sd_ble_gap_device_name_get output parameters. */ + gap_appearance_get_output_params_t gap_appearance_get_out_params; /**< @ref sd_ble_gap_appearance_get output parameters. */ + gap_ppcp_get_out_params_t gap_ppcp_get_out_params; /**< @ref sd_ble_gap_ppcp_get output parameters. */ + gap_sec_params_reply_out_params_t gap_sec_params_reply_out_params;/**< @ref sd_ble_sec_params_reply output parameters. */ +} gap_command_output_params_t; + +static gap_command_output_params_t m_output_params; /**< BLE command output parameters. */ + +static void * mp_out_params[1]; + +static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) +{ + uint32_t err_code; + + do + { + err_code = ser_sd_transport_tx_alloc(p_data, p_len); + } + while (err_code != NRF_SUCCESS); + *p_data[0] = SER_PKT_TYPE_CMD; + *p_len -= 1; +} +/**@brief Command response callback function for @ref sd_ble_gap_adv_start BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_adv_start_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gap_adv_start_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_adv_start +#define _sd_ble_gap_adv_start sd_ble_gap_adv_start +#endif +uint32_t _sd_ble_gap_adv_start(ble_gap_adv_params_t const * const p_adv_params +#if NRF_SD_BLE_API_VERSION >= 4 + ,uint8_t conn_cfg_tag +#endif +) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gap_adv_start_req_enc(p_adv_params, +#if NRF_SD_BLE_API_VERSION >= 4 + conn_cfg_tag, +#endif + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_adv_start_rsp_dec); +} + + +/**@brief Command response callback function for @ref ble_gap_device_name_get_req_enc BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_device_name_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = + ble_gap_device_name_get_rsp_dec(p_buffer, + length, + m_output_params.gap_device_name_get_out_params.p_dev_name, + m_output_params.gap_device_name_get_out_params.p_len, + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_device_name_get +#define _sd_ble_gap_device_name_get sd_ble_gap_device_name_get +#endif +uint32_t _sd_ble_gap_device_name_get(uint8_t * const p_dev_name, uint16_t * const p_len) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + m_output_params.gap_device_name_get_out_params.p_dev_name = p_dev_name; + m_output_params.gap_device_name_get_out_params.p_len = p_len; + + const uint32_t err_code = ble_gap_device_name_get_req_enc(p_dev_name, + p_len, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_device_name_get_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gap_appearance_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_appearance_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = + ble_gap_appearance_get_rsp_dec(p_buffer, + length, + m_output_params.gap_appearance_get_out_params.p_appearance, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_appearance_get +#define _sd_ble_gap_appearance_get sd_ble_gap_appearance_get +#endif +uint32_t _sd_ble_gap_appearance_get(uint16_t * const p_appearance) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + m_output_params.gap_appearance_get_out_params.p_appearance = p_appearance; + + const uint32_t err_code = ble_gap_appearance_get_req_enc(p_appearance, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_appearance_get_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gap_device_name_set BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_device_name_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gap_device_name_set_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_device_name_set +#define _sd_ble_gap_device_name_set sd_ble_gap_device_name_set +#endif +uint32_t _sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const * const p_write_perm, + uint8_t const * const p_dev_name, + uint16_t len) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_device_name_set_req_enc(p_write_perm, + p_dev_name, + len, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_device_name_set_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gap_appearance_set BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_appearance_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gap_appearance_set_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_appearance_set +#define _sd_ble_gap_appearance_set sd_ble_gap_appearance_set +#endif +uint32_t _sd_ble_gap_appearance_set(uint16_t appearance) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_appearance_set_req_enc(appearance, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_appearance_set_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gap_ppcp_set BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_ppcp_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gap_ppcp_set_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + + return result_code; +} + +#ifndef _sd_ble_gap_ppcp_set +#define _sd_ble_gap_ppcp_set sd_ble_gap_ppcp_set +#endif +uint32_t _sd_ble_gap_ppcp_set(ble_gap_conn_params_t const * const p_conn_params) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_ppcp_set_req_enc(p_conn_params, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_ppcp_set_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gap_adv_data_set BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_adv_data_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gap_adv_data_set_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_adv_data_set +#define _sd_ble_gap_adv_data_set sd_ble_gap_adv_data_set +#endif +uint32_t _sd_ble_gap_adv_data_set(uint8_t const * const p_data, + uint8_t dlen, + uint8_t const * const p_sr_data, + uint8_t srdlen) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_adv_data_set_req_enc(p_data, + dlen, + p_sr_data, + srdlen, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_adv_data_set_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gap_conn_param_update BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_conn_param_update_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gap_conn_param_update_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_conn_param_update +#define _sd_ble_gap_conn_param_update sd_ble_gap_conn_param_update +#endif +uint32_t _sd_ble_gap_conn_param_update(uint16_t conn_handle, + ble_gap_conn_params_t const * const p_conn_params) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_conn_param_update_req_enc(conn_handle, + p_conn_params, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_conn_param_update_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gap_disconnect BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_disconnect_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gap_disconnect_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_disconnect +#define _sd_ble_gap_disconnect sd_ble_gap_disconnect +#endif +uint32_t _sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_disconnect_req_enc(conn_handle, + hci_status_code, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_disconnect_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gap_sec_info_reply BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_sec_info_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gap_sec_info_reply_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_sec_info_reply +#define _sd_ble_gap_sec_info_reply sd_ble_gap_sec_info_reply +#endif +uint32_t _sd_ble_gap_sec_info_reply(uint16_t conn_handle, + ble_gap_enc_info_t const * p_enc_info, + ble_gap_irk_t const * p_id_info, + ble_gap_sign_info_t const * p_sign_info) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_sec_info_reply_req_enc(conn_handle, + p_enc_info, + p_id_info, + p_sign_info, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_sec_info_reply_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gap_sec_params_reply BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_sec_params_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + uint32_t err_code = ble_gap_sec_params_reply_rsp_dec(p_buffer, length, + m_output_params.gap_sec_params_reply_out_params.p_sec_keyset, &result_code); + APP_ERROR_CHECK(err_code); + + // If soft device returned error free security context + if (result_code) + { + err_code = app_ble_gap_sec_context_destroy(m_output_params.gap_sec_params_reply_out_params.conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + + return result_code; +} + +#ifndef _sd_ble_gap_sec_params_reply +#define _sd_ble_gap_sec_params_reply sd_ble_gap_sec_params_reply +#endif +uint32_t _sd_ble_gap_sec_params_reply(uint16_t conn_handle, + uint8_t sec_status, + ble_gap_sec_params_t const * p_sec_params, + ble_gap_sec_keyset_t const * p_sec_keyset) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + uint32_t sec_tab_index = 0; + uint32_t err_code = NRF_SUCCESS; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + m_output_params.gap_sec_params_reply_out_params.p_sec_keyset = p_sec_keyset; + m_output_params.gap_sec_params_reply_out_params.conn_handle = conn_handle; + + // First allocate security context for serialization + if (p_sec_keyset) + { + err_code = app_ble_gap_sec_context_create(conn_handle, &sec_tab_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + memcpy(&(m_app_keys_table[sec_tab_index].keyset), p_sec_keyset, sizeof(ble_gap_sec_keyset_t)); + } + + err_code = ble_gap_sec_params_reply_req_enc(conn_handle, + sec_status, + p_sec_params, + p_sec_keyset, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_sec_params_reply_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gap_ppcp_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_ppcp_get_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_ppcp_get_rsp_dec( + p_buffer, + length, + m_output_params.gap_ppcp_get_out_params. + p_conn_params, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_ppcp_get +#define _sd_ble_gap_ppcp_get sd_ble_gap_ppcp_get +#endif +uint32_t _sd_ble_gap_ppcp_get(ble_gap_conn_params_t * const p_conn_params) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + m_output_params.gap_ppcp_get_out_params.p_conn_params = p_conn_params; + + const uint32_t err_code = ble_gap_ppcp_get_req_enc(p_conn_params, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_ppcp_get_reply_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gap_adv_stop BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_adv_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_adv_stop_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_adv_stop +#define _sd_ble_gap_adv_stop sd_ble_gap_adv_stop +#endif +uint32_t _sd_ble_gap_adv_stop(void) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_adv_stop_req_enc(&(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_adv_stop_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_auth_key_reply BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_auth_key_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_auth_key_reply_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + + +#ifndef _sd_ble_gap_auth_key_reply +#define _sd_ble_gap_auth_key_reply sd_ble_gap_auth_key_reply +#endif +uint32_t _sd_ble_gap_auth_key_reply(uint16_t conn_handle, + uint8_t key_type, + uint8_t const * const key) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_auth_key_reply_req_enc(conn_handle, key_type, key, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_auth_key_reply_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_authenticate BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_authenticate_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_authenticate_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gap_authenticate +#define _sd_ble_gap_authenticate sd_ble_gap_authenticate +#endif +uint32_t _sd_ble_gap_authenticate(uint16_t conn_handle, + ble_gap_sec_params_t const * const p_sec_params) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_authenticate_req_enc(conn_handle, p_sec_params, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_authenticate_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_conn_sec_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_conn_sec_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_conn_sec_get_rsp_dec( + p_buffer, + length, + (ble_gap_conn_sec_t * *)&mp_out_params[0 + ], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gap_conn_sec_get +#define _sd_ble_gap_conn_sec_get sd_ble_gap_conn_sec_get +#endif +uint32_t _sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t * const p_conn_sec) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_conn_sec; + + const uint32_t err_code = ble_gap_conn_sec_get_req_enc(conn_handle, p_conn_sec, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_conn_sec_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_rssi_start BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_rssi_start_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_rssi_start_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gap_rssi_start +#define _sd_ble_gap_rssi_start sd_ble_gap_rssi_start +#endif +uint32_t _sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_rssi_start_req_enc(conn_handle, + threshold_dbm, + skip_count, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_rssi_start_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_rssi_stop BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_rssi_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_rssi_stop_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gap_rssi_stop +#define _sd_ble_gap_rssi_stop sd_ble_gap_rssi_stop +#endif +uint32_t _sd_ble_gap_rssi_stop(uint16_t conn_handle) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_rssi_stop_req_enc(conn_handle, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_rssi_stop_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_tx_power_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_tx_power_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_tx_power_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gap_tx_power_set +#define _sd_ble_gap_tx_power_set sd_ble_gap_tx_power_set +#endif +uint32_t _sd_ble_gap_tx_power_set(int8_t tx_power) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_tx_power_set_req_enc(tx_power, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_tx_power_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_scan_stop BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_scan_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_scan_stop_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gap_scan_stop +#define _sd_ble_gap_scan_stop sd_ble_gap_scan_stop +#endif +uint32_t _sd_ble_gap_scan_stop(void) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_scan_stop_req_enc(&(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_scan_stop_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_connect BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_connect_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_connect_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gap_connect +#define _sd_ble_gap_connect sd_ble_gap_connect +#endif +uint32_t _sd_ble_gap_connect(ble_gap_addr_t const * const p_addr, + ble_gap_scan_params_t const * const p_scan_params, + ble_gap_conn_params_t const * const p_conn_params +#if NRF_SD_BLE_API_VERSION >= 4 + ,uint8_t conn_cfg_tag +#endif + ) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_connect_req_enc(p_addr, + p_scan_params, + p_conn_params, +#if NRF_SD_BLE_API_VERSION >= 4 + conn_cfg_tag, +#endif + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_connect_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_connect_cancel BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_connect_cancel_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_connect_cancel_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gap_connect_cancel +#define _sd_ble_gap_connect_cancel sd_ble_gap_connect_cancel +#endif +uint32_t _sd_ble_gap_connect_cancel(void) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_connect_cancel_req_enc(&(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_connect_cancel_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_scan_start BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_scan_start_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_scan_start_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_scan_start +#define _sd_ble_gap_scan_start sd_ble_gap_scan_start +#endif +uint32_t _sd_ble_gap_scan_start(ble_gap_scan_params_t const * const p_scan_params) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_scan_start_req_enc(p_scan_params, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_scan_start_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_encrypt BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_encrypt_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_encrypt_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_encrypt +#define _sd_ble_gap_encrypt sd_ble_gap_encrypt +#endif +uint32_t _sd_ble_gap_encrypt( uint16_t conn_handle, + ble_gap_master_id_t const * p_master_id, + ble_gap_enc_info_t const * p_enc_info) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_encrypt_req_enc( conn_handle, p_master_id, p_enc_info, &(p_buffer[1]), &buffer_length ); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_encrypt_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_rssi_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_rssi_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_rssi_get_rsp_dec(p_buffer, + length, + (int8_t *) mp_out_params[0], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_rssi_get +#define _sd_ble_gap_rssi_get sd_ble_gap_rssi_get +#endif +uint32_t _sd_ble_gap_rssi_get(uint16_t conn_handle, + int8_t * p_rssi) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_rssi; + + const uint32_t err_code = ble_gap_rssi_get_req_enc(conn_handle, p_rssi, &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_rssi_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_keypress_notify BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_keypress_notify_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_keypress_notify_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_keypress_notify +#define _sd_ble_gap_keypress_notify sd_ble_gap_keypress_notify +#endif +uint32_t _sd_ble_gap_keypress_notify( uint16_t conn_handle, uint8_t kp_not) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_keypress_notify_req_enc( conn_handle, kp_not, &p_buffer[1], &buffer_length ); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_keypress_notify_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_lesc_dhkey_reply BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_lesc_dhkey_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_lesc_dhkey_reply_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_lesc_dhkey_reply +#define _sd_ble_gap_lesc_dhkey_reply sd_ble_gap_lesc_dhkey_reply +#endif +uint32_t _sd_ble_gap_lesc_dhkey_reply( uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_lesc_dhkey_reply_req_enc( conn_handle, p_dhkey, &(p_buffer[1]), &buffer_length ); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_lesc_dhkey_reply_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_lesc_oob_data_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_lesc_oob_data_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_lesc_oob_data_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_lesc_oob_data_set +#define _sd_ble_gap_lesc_oob_data_set sd_ble_gap_lesc_oob_data_set +#endif +uint32_t _sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, + ble_gap_lesc_oob_data_t const *p_oobd_own, + ble_gap_lesc_oob_data_t const *p_oobd_peer) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_lesc_oob_data_set_req_enc(conn_handle, p_oobd_own, p_oobd_peer, + &(p_buffer[1]), &buffer_length ); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_lesc_oob_data_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_lesc_oob_data_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_lesc_oob_data_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_lesc_oob_data_get_rsp_dec(p_buffer, + length, + (ble_gap_lesc_oob_data_t **) &mp_out_params[0], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_lesc_oob_data_get +#define _sd_ble_gap_lesc_oob_data_get sd_ble_gap_lesc_oob_data_get +#endif +uint32_t _sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, + ble_gap_lesc_p256_pk_t const *p_pk_own, + ble_gap_lesc_oob_data_t *p_oobd_own) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_oobd_own; + const uint32_t err_code = ble_gap_lesc_oob_data_get_req_enc(conn_handle, p_pk_own, p_oobd_own, + &(p_buffer[1]), &buffer_length ); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_lesc_oob_data_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_addr_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_addr_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_addr_get_rsp_dec(p_buffer, + length, + (ble_gap_addr_t *)mp_out_params[0], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_addr_get +#define _sd_ble_gap_addr_get sd_ble_gap_addr_get +#endif +uint32_t _sd_ble_gap_addr_get(ble_gap_addr_t * const p_addr) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_addr; + + const uint32_t err_code = ble_gap_addr_get_req_enc(p_addr, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_addr_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_addr_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_addr_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_addr_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_addr_set +#define _sd_ble_gap_addr_set sd_ble_gap_addr_set +#endif +uint32_t _sd_ble_gap_addr_set(ble_gap_addr_t const * const p_addr) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_addr_set_req_enc(p_addr, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_addr_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_privacy_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_privacy_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_privacy_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_privacy_set +#define _sd_ble_gap_privacy_set sd_ble_gap_privacy_set +#endif +uint32_t _sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gap_privacy_set_req_enc(p_privacy_params, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_privacy_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_privacy_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_privacy_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_privacy_get_rsp_dec(p_buffer, + length, + (ble_gap_privacy_params_t *)mp_out_params[0], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_privacy_get +#define _sd_ble_gap_privacy_get sd_ble_gap_privacy_get +#endif +uint32_t _sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_privacy_params; + + const uint32_t err_code = ble_gap_privacy_get_req_enc(p_privacy_params, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_privacy_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_whitelist_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_whitelist_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_whitelist_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_whitelist_set +#define _sd_ble_gap_whitelist_set sd_ble_gap_whitelist_set +#endif +uint32_t _sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gap_whitelist_set_req_enc(pp_wl_addrs, len, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_whitelist_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_device_identities_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_device_identities_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_device_identities_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_device_identities_set +#define _sd_ble_gap_device_identities_set sd_ble_gap_device_identities_set +#endif +uint32_t _sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gap_device_identities_set_req_enc(pp_id_keys, + pp_local_irks, + len, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_device_identities_set_rsp_dec); +} + +#if NRF_SD_BLE_API_VERSION >= 4 +/**@brief Command response callback function for @ref sd_ble_gap_data_length_update BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_data_length_update_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_data_length_update_rsp_dec(p_buffer, + length, + (ble_gap_data_length_limitation_t *)mp_out_params[0], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_data_length_update +#define _sd_ble_gap_data_length_update sd_ble_gap_data_length_update +#endif +uint32_t _sd_ble_gap_data_length_update(uint16_t conn_handle, + ble_gap_data_length_params_t const *p_dl_params, + ble_gap_data_length_limitation_t *p_dl_limitation) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_dl_limitation; + + const uint32_t err_code = ble_gap_data_length_update_req_enc(conn_handle, p_dl_params,p_dl_limitation, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_data_length_update_rsp_dec); +} + +#endif + +#if NRF_SD_BLE_API_VERSION >= 5 +/**@brief Command response callback function for @ref sd_ble_gap_phy_request BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_phy_request_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_phy_request_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gap_phy_request +#define _sd_ble_gap_phy_request sd_ble_gap_phy_request +#endif +uint32_t _sd_ble_gap_phy_request(uint16_t conn_handle, + ble_gap_phys_t const * const p_gap_phys) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_phy_request_req_enc(conn_handle, p_gap_phys, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_phy_request_rsp_dec); +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble_gattc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble_gattc.c new file mode 100644 index 0000000000000000000000000000000000000000..948fcd9965973348c05d325d1e21cb5a6efbe43c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble_gattc.c @@ -0,0 +1,566 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "ble_gattc.h" +#include "ble_gattc_app.h" +#include "ble_serialization.h" +#include "ser_sd_transport.h" +#include "app_error.h" + +static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) +{ + uint32_t err_code; + + do + { + err_code = ser_sd_transport_tx_alloc(p_data, p_len); + } + while (err_code != NRF_SUCCESS); + *p_data[0] = SER_PKT_TYPE_CMD; + *p_len -= 1; +} +/**@brief Command response callback function for @ref sd_ble_gattc_primary_services_discover BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_primary_services_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_primary_services_discover_rsp_dec(p_buffer, + length, + &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gattc_primary_services_discover +#define _sd_ble_gattc_primary_services_discover sd_ble_gattc_primary_services_discover +#endif +uint32_t _sd_ble_gattc_primary_services_discover(uint16_t conn_handle, + uint16_t start_handle, + ble_uuid_t const * const p_srvc_uuid) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_primary_services_discover_req_enc(conn_handle, + start_handle, + p_srvc_uuid, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_primary_services_discover_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gattc_relationships_discover BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_relationships_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_relationships_discover_rsp_dec(p_buffer, + length, + &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gattc_relationships_discover +#define _sd_ble_gattc_relationships_discover sd_ble_gattc_relationships_discover +#endif +uint32_t _sd_ble_gattc_relationships_discover(uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_relationships_discover_req_enc(conn_handle, + p_handle_range, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_relationships_discover_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gattc_characteristics_discover BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_characteristics_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_characteristics_discover_rsp_dec(p_buffer, + length, + &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gattc_characteristics_discover +#define _sd_ble_gattc_characteristics_discover sd_ble_gattc_characteristics_discover +#endif +uint32_t _sd_ble_gattc_characteristics_discover( + uint16_t conn_handle, + ble_gattc_handle_range_t const * const + p_handle_range) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_characteristics_discover_req_enc(conn_handle, + p_handle_range, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_characteristics_discover_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gattc_descriptors_discover BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_descriptors_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_descriptors_discover_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gattc_descriptors_discover +#define _sd_ble_gattc_descriptors_discover sd_ble_gattc_descriptors_discover +#endif +uint32_t _sd_ble_gattc_descriptors_discover(uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_descriptors_discover_req_enc(conn_handle, + p_handle_range, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_descriptors_discover_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gattc_char_value_by_uuid_read BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_char_value_by_uuid_read_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_char_value_by_uuid_read_rsp_dec(p_buffer, + length, + &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gattc_char_value_by_uuid_read +#define _sd_ble_gattc_char_value_by_uuid_read sd_ble_gattc_char_value_by_uuid_read +#endif +uint32_t _sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, + ble_uuid_t const * const p_uuid, + ble_gattc_handle_range_t const * const p_handle_range) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_char_value_by_uuid_read_req_enc(conn_handle, + p_uuid, + p_handle_range, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_char_value_by_uuid_read_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gattc_read BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_read_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_read_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gattc_read +#define _sd_ble_gattc_read sd_ble_gattc_read +#endif +uint32_t _sd_ble_gattc_read(uint16_t conn_handle, + uint16_t handle, + uint16_t offset) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_read_req_enc(conn_handle, + handle, + offset, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_read_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gattc_char_values_read BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_char_values_read_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_char_values_read_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gattc_char_values_read +#define _sd_ble_gattc_char_values_read sd_ble_gattc_char_values_read +#endif +uint32_t _sd_ble_gattc_char_values_read(uint16_t conn_handle, + uint16_t const * const p_handles, + uint16_t handle_count) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_char_values_read_req_enc(conn_handle, + p_handles, + handle_count, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_char_values_read_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gattc_write BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_write_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_write_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gattc_write +#define _sd_ble_gattc_write sd_ble_gattc_write +#endif +uint32_t _sd_ble_gattc_write(uint16_t conn_handle, + ble_gattc_write_params_t const * const p_write_params) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_write_req_enc(conn_handle, + p_write_params, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_write_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gattc_hv_confirm BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_hv_confirm_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_hv_confirm_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gattc_hv_confirm +#define _sd_ble_gattc_hv_confirm sd_ble_gattc_hv_confirm +#endif +uint32_t _sd_ble_gattc_hv_confirm(uint16_t conn_handle, + uint16_t handle) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_hv_confirm_req_enc(conn_handle, + handle, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_hv_confirm_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gattc_info_discover BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_attr_info_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_attr_info_discover_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gattc_attr_info_discover +#define _sd_ble_gattc_attr_info_discover sd_ble_gattc_attr_info_discover +#endif +uint32_t _sd_ble_gattc_attr_info_discover(uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_attr_info_discover_req_enc(conn_handle, + p_handle_range, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_attr_info_discover_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gattc_write BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_exchange_mtu_request_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_exchange_mtu_request_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gattc_exchange_mtu_request +#define _sd_ble_gattc_exchange_mtu_request sd_ble_gattc_exchange_mtu_request +#endif +uint32_t _sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, + uint16_t client_rx_mtu) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_exchange_mtu_request_req_enc(conn_handle, + client_rx_mtu, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_exchange_mtu_request_rsp_dec); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble_gatts.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble_gatts.c new file mode 100644 index 0000000000000000000000000000000000000000..9dadb068b1d7ecb726b2c0347266af2c76b8d516 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble_gatts.c @@ -0,0 +1,773 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gatts.h" +#include +#include "ble_serialization.h" +#include "ser_sd_transport.h" +#include "ble_gatts_app.h" +#include "app_error.h" + + +//Pointer for sd calls output params +static void * mp_out_params[3]; + +static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) +{ + uint32_t err_code; + + do + { + err_code = ser_sd_transport_tx_alloc(p_data, p_len); + } + while (err_code != NRF_SUCCESS); + *p_data[0] = SER_PKT_TYPE_CMD; + *p_len -= 1; +} + +/**@brief Command response callback function for @ref sd_ble_gatts_sys_attr_set BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_sys_attr_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gatts_sys_attr_set_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gatts_sys_attr_set +#define _sd_ble_gatts_sys_attr_set sd_ble_gatts_sys_attr_set +#endif +uint32_t _sd_ble_gatts_sys_attr_set(uint16_t conn_handle, + uint8_t const * const p_sys_attr_data, + uint16_t len, + uint32_t flags) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gatts_sys_attr_set_req_enc(conn_handle, + p_sys_attr_data, + len, + flags, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_sys_attr_set_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gatts_hvx BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_hvx_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gatts_hvx_rsp_dec(p_buffer, length, &result_code, + (uint16_t * *)&mp_out_params[0]); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gatts_hvx +#define _sd_ble_gatts_hvx sd_ble_gatts_hvx +#endif +uint32_t _sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const * const p_hvx_params) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = (p_hvx_params) ? p_hvx_params->p_len : NULL; + + const uint32_t err_code = ble_gatts_hvx_req_enc(conn_handle, + p_hvx_params, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_hvx_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gatts_service_add BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_service_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = + ble_gatts_service_add_rsp_dec(p_buffer, + length, + (uint16_t *)mp_out_params[0], + &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gatts_service_add +#define _sd_ble_gatts_service_add sd_ble_gatts_service_add +#endif +uint32_t _sd_ble_gatts_service_add(uint8_t type, + ble_uuid_t const * const p_uuid, + uint16_t * const p_handle) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_handle; + + const uint32_t err_code = ble_gatts_service_add_req_enc(type, + p_uuid, + p_handle, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_service_add_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gatts_service_add BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_service_changed_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = NRF_SUCCESS; + + const uint32_t err_code = ble_gatts_service_changed_rsp_dec(p_buffer, + length, + &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gatts_service_changed +#define _sd_ble_gatts_service_changed sd_ble_gatts_service_changed +#endif +uint32_t _sd_ble_gatts_service_changed(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gatts_service_changed_req_enc(conn_handle, + start_handle, + end_handle, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_service_changed_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gatts_include_add BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_include_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = NRF_SUCCESS; + + const uint32_t err_code = + ble_gatts_include_add_rsp_dec(p_buffer, + length, + (uint16_t *) mp_out_params[0], + &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gatts_include_add +#define _sd_ble_gatts_include_add sd_ble_gatts_include_add +#endif +uint32_t _sd_ble_gatts_include_add(uint16_t service_handle, + uint16_t inc_serv_handle, + uint16_t * const p_include_handle) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_include_handle; + + const uint32_t err_code = ble_gatts_include_add_req_enc(service_handle, + inc_serv_handle, + p_include_handle, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_include_add_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gatts_characteristic_add BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_characteristic_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gatts_characteristic_add_rsp_dec( + p_buffer, + length, + (uint16_t * *)&mp_out_params[0], + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gatts_characteristic_add +#define _sd_ble_gatts_characteristic_add sd_ble_gatts_characteristic_add +#endif +uint32_t _sd_ble_gatts_characteristic_add(uint16_t service_handle, + ble_gatts_char_md_t const * const p_char_md, + ble_gatts_attr_t const * const p_attr_char_value, + ble_gatts_char_handles_t * const p_handles) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_handles; + + const uint32_t err_code = ble_gatts_characteristic_add_req_enc(service_handle, + p_char_md, + p_attr_char_value, + p_handles, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_characteristic_add_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gatts_descriptor_add BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_descriptor_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = NRF_SUCCESS; + + const uint32_t err_code = + ble_gatts_descriptor_add_rsp_dec(p_buffer, + length, + (uint16_t *) mp_out_params[0], + &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gatts_descriptor_add +#define _sd_ble_gatts_descriptor_add sd_ble_gatts_descriptor_add +#endif +uint32_t _sd_ble_gatts_descriptor_add(uint16_t char_handle, + ble_gatts_attr_t const * const p_attr, + uint16_t * const p_handle) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_handle; + + const uint32_t err_code = ble_gatts_descriptor_add_req_enc(char_handle, + p_attr, + p_handle, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_descriptor_add_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gatts_rw_authorize_reply BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_rw_authorize_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = NRF_SUCCESS; + + const uint32_t err_code = ble_gatts_rw_authorize_reply_rsp_dec(p_buffer, + length, + &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gatts_rw_authorize_reply +#define _sd_ble_gatts_rw_authorize_reply sd_ble_gatts_rw_authorize_reply +#endif +uint32_t _sd_ble_gatts_rw_authorize_reply( + uint16_t conn_handle, + ble_gatts_rw_authorize_reply_params_t const * const + p_rw_authorize_reply_params) +{ + + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gatts_rw_authorize_reply_req_enc(conn_handle, + p_rw_authorize_reply_params, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_rw_authorize_reply_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gatts_value_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_value_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gatts_value_get_rsp_dec(p_buffer, + length, + (ble_gatts_value_t *)mp_out_params[0], + &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_gatts_value_get +#define _sd_ble_gatts_value_get sd_ble_gatts_value_get +#endif +uint32_t _sd_ble_gatts_value_get(uint16_t conn_handle, + uint16_t handle, + ble_gatts_value_t * p_value) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_value; + + const uint32_t err_code = ble_gatts_value_get_req_enc(conn_handle, + handle, + p_value, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_value_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gatts_value_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_value_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gatts_value_set_rsp_dec( + p_buffer, + length, + (ble_gatts_value_t *)mp_out_params[0], + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gatts_value_set +#define _sd_ble_gatts_value_set sd_ble_gatts_value_set +#endif +uint32_t _sd_ble_gatts_value_set(uint16_t conn_handle, + uint16_t handle, + ble_gatts_value_t * p_value) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_value; + + const uint32_t err_code = ble_gatts_value_set_req_enc(conn_handle, + handle, + p_value, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_value_set_rsp_dec); +} + + +/**@brief Command response callback function for @ref sd_ble_gatts_sys_attr_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_sys_attr_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gatts_sys_attr_get_rsp_dec( + p_buffer, + length, + (uint8_t * *) &mp_out_params[0], + (uint16_t * *) &mp_out_params[1], + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gatts_sys_attr_get +#define _sd_ble_gatts_sys_attr_get sd_ble_gatts_sys_attr_get +#endif +uint32_t _sd_ble_gatts_sys_attr_get(uint16_t conn_handle, + uint8_t * const p_sys_attr_data, + uint16_t * const p_len, + uint32_t flags) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_sys_attr_data; + mp_out_params[1] = p_len; + + const uint32_t err_code = ble_gatts_sys_attr_get_req_enc(conn_handle, + p_sys_attr_data, + p_len, + flags, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_sys_attr_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gatts_attr_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_attr_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gatts_attr_get_rsp_dec( + p_buffer, + length, + (ble_uuid_t **)&mp_out_params[0], + (ble_gatts_attr_md_t **)&mp_out_params[1], + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gatts_attr_get +#define _sd_ble_gatts_attr_get sd_ble_gatts_attr_get +#endif +uint32_t _sd_ble_gatts_attr_get(uint16_t handle, + ble_uuid_t * p_uuid, + ble_gatts_attr_md_t * p_md) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_uuid; + mp_out_params[1] = p_md; + + const uint32_t err_code = ble_gatts_attr_get_req_enc(handle, + p_uuid, + p_md, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_attr_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gatts_initial_user_handle_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_initial_user_handle_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gatts_initial_user_handle_get_rsp_dec( + p_buffer, + length, + (uint16_t **)&mp_out_params[0], + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gatts_initial_user_handle_get +#define _sd_ble_gatts_initial_user_handle_get sd_ble_gatts_initial_user_handle_get +#endif +uint32_t _sd_ble_gatts_initial_user_handle_get(uint16_t * p_handle) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_handle; + + const uint32_t err_code = ble_gatts_initial_user_handle_get_req_enc(p_handle, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_initial_user_handle_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gatts_exchange_mtu_reply BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_exchange_mtu_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gatts_exchange_mtu_reply_rsp_dec( + p_buffer, + length, + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gatts_exchange_mtu_reply +#define _sd_ble_gatts_exchange_mtu_reply sd_ble_gatts_exchange_mtu_reply +#endif +uint32_t _sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu) +{ + + + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gatts_exchange_mtu_reply_req_enc(conn_handle, + server_rx_mtu, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_exchange_mtu_reply_rsp_dec); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble_l2cap.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble_l2cap.c new file mode 100644 index 0000000000000000000000000000000000000000..183d7ce1f97c31f82ee6fed732cac263a3ad1880 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_ble_l2cap.c @@ -0,0 +1,200 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gap.h" +#include +#include "ble_serialization.h" +#include "ser_sd_transport.h" +#include "ble_l2cap_app.h" +#include "app_error.h" + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) +{ + uint32_t err_code; + + do + { + err_code = ser_sd_transport_tx_alloc(p_data, p_len); + } + while (err_code != NRF_SUCCESS); + *p_data[0] = SER_PKT_TYPE_CMD; + *p_len -= 1; +} +/**@brief Command response callback function for @ref ble_l2cap_cid_register_req_enc BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t l2cap_cid_register_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = + ble_l2cap_cid_register_rsp_dec(p_buffer, + length, + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_l2cap_cid_register +#define _sd_ble_l2cap_cid_register sd_ble_l2cap_cid_register +#endif +uint32_t _sd_ble_l2cap_cid_register(uint16_t cid) +{ + + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_l2cap_cid_register_req_enc(cid, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + l2cap_cid_register_rsp_dec); +} + +/**@brief Command response callback function for @ref ble_l2cap_cid_unregister_req_enc BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t l2cap_cid_unregister_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = + ble_l2cap_cid_unregister_rsp_dec(p_buffer, + length, + &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_l2cap_cid_unregister +#define _sd_ble_l2cap_cid_unregister sd_ble_l2cap_cid_unregister +#endif +uint32_t _sd_ble_l2cap_cid_unregister(uint16_t cid) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_l2cap_cid_unregister_req_enc(cid, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + l2cap_cid_unregister_rsp_dec); +} + +/**@brief Command response callback function for @ref ble_l2cap_tx_req_enc BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t l2cap_tx_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = + ble_l2cap_tx_rsp_dec(p_buffer, + length, + &result_code); + + APP_ERROR_CHECK(err_code); + + + + return result_code; +} + +#ifndef _sd_ble_l2cap_tx +#define _sd_ble_l2cap_tx sd_ble_l2cap_tx +#endif +uint32_t _sd_ble_l2cap_tx(uint16_t conn_handle, + ble_l2cap_header_t const * const p_header, + uint8_t const * const p_data) +{ + + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_l2cap_tx_req_enc(conn_handle, p_header, p_data, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + l2cap_tx_rsp_dec); +} + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_nrf_soc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_nrf_soc.c new file mode 100644 index 0000000000000000000000000000000000000000..3cd550ef9cb0654846bd80f8c2e9916adbb344bf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/middleware/app_mw_nrf_soc.c @@ -0,0 +1,171 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_soc.h" +#include +#include +#include "ser_sd_transport.h" +#include "nrf_soc_app.h" +#include "nrf_error_soc.h" +#include "app_error.h" +#include "ble_serialization.h" + +#include "ser_app_power_system_off.h" + +static void * mp_out_param; + +static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) +{ + uint32_t err_code; + + do + { + err_code = ser_sd_transport_tx_alloc(p_data, p_len); + } + while (err_code != NRF_SUCCESS); + *p_data[0] = SER_PKT_TYPE_CMD; + *p_len -= 1; +} + + +uint32_t sd_power_system_off(void) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = power_system_off_req_enc(&(p_buffer[1]), &buffer_length); + APP_ERROR_CHECK(err_code); + + ser_app_power_system_off_set(); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + NULL); +} + + +/**@brief Command response callback function for @ref sd_temp_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ + +static uint32_t mw_temp_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = temp_get_rsp_dec(p_buffer, + length, + &result_code, + (int32_t * *) &mp_out_param); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_temp_get(int32_t * p_temp) +{ + + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_param = p_temp; + + const uint32_t err_code = temp_get_req_enc(p_temp, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + mw_temp_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ecb_block_encrypt BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ + +static uint32_t mw_ecb_block_encrypt_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ecb_block_encrypt_rsp_dec(p_buffer, + length, + (nrf_ecb_hal_data_t * *)&mp_out_param, + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data) +{ + + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_param = p_ecb_data; + + const uint32_t err_code = ecb_block_encrypt_req_enc(p_ecb_data, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + mw_ecb_block_encrypt_rsp_dec); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/app_ble_gap_sec_keys.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/app_ble_gap_sec_keys.c new file mode 100644 index 0000000000000000000000000000000000000000..e2ad685f66eb2e91c30871840503eb99a50d439f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/app_ble_gap_sec_keys.c @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "app_ble_gap_sec_keys.h" +#include "nrf_error.h" +#include + +ser_ble_gap_app_keyset_t m_app_keys_table[SER_MAX_CONNECTIONS]; + +uint32_t app_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index) +{ + uint32_t err_code = NRF_ERROR_NO_MEM; + uint32_t i; + + for (i=0; i + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SER_MAX_CONNECTIONS +#define SER_MAX_CONNECTIONS 8 +#endif +/**@brief GAP connection - keyset mapping structure. + * + * @note This structure is used to map keysets to connection instances and store them in a static table. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection handle.*/ + uint8_t conn_active; /**< Indication that keys for this connection are used by the SoftDevice. 0: keys used; 1: keys not used. */ + ble_gap_sec_keyset_t keyset; /**< Keyset structure, see @ref ble_gap_sec_keyset_t.*/ +} ser_ble_gap_app_keyset_t; + +/**@brief Allocates the instance in m_app_keys_table[] for storage of encryption keys. + * + * @param[in] conn_handle conn_handle + * @param[out] p_index Pointer to the index of the allocated instance. + * + * @retval NRF_SUCCESS Context allocated. + * @retval NRF_ERROR_NO_MEM No free instance available. + */ +uint32_t app_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index); + +/**@brief Release the instance identified by a connection handle. + * + * @param[in] conn_handle conn_handle + * + * @retval NRF_SUCCESS Context released. + * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found. + */ +uint32_t app_ble_gap_sec_context_destroy(uint16_t conn_handle); + +/**@brief Finds index of instance identified by a connection handle in m_app_keys_table[]. + * + * @param[in] conn_handle conn_handle + * + * @param[out] p_index Pointer to the index of the entry in the context table corresponding to the given conn_handle. + * + * @retval NRF_SUCCESS Context found. + * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found. + */ +uint32_t app_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif //_APP_BLE_GAP_SEC_KEYS_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/app_ble_user_mem.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/app_ble_user_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..027f1c19f30e8236c0fcf7812ff61a892e6ca075 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/app_ble_user_mem.c @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "app_ble_user_mem.h" +#include "ser_config.h" +#include "nrf_error.h" +#include + +ser_ble_user_mem_t m_app_user_mem_table[SER_MAX_CONNECTIONS]; + +uint32_t app_ble_user_mem_context_create(uint16_t conn_handle, uint32_t *p_index) +{ + uint32_t err_code = NRF_ERROR_NO_MEM; + uint32_t i; + + for (i=0; i + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Connection - user memory mapping structure. + * + * @note This structure is used to map user memory to connection instances and store it in a static table. + */ +//lint -esym(452,ser_ble_user_mem_t) +typedef struct +{ + uint16_t conn_handle; /**< Connection handle. */ + uint8_t conn_active; /**< Indication that user memory for this connection is used by the SoftDevice. 0: memory used; 1: memory not used. */ + ble_user_mem_block_t mem_block; /**< User memory block structure, see @ref ble_user_mem_block_t. */ +} ser_ble_user_mem_t; + +/**@brief Allocates instance in m_user_mem_table[] for storage. + * + * @param[in] conn_handle conn_handle + * @param[out] p_index Pointer to the index of the allocated instance. + * + * @retval NRF_SUCCESS Context allocated. + * @retval NRF_ERROR_NO_MEM No free instance available. + */ +uint32_t app_ble_user_mem_context_create(uint16_t conn_handle, uint32_t *p_index); + +/**@brief Release instance identified by a connection handle. + * + * @param[in] conn_handle conn_handle + * + * @retval NRF_SUCCESS Context released. + * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found. + */ +uint32_t app_ble_user_mem_context_destroy(uint16_t conn_handle); + +/**@brief Finds index of the instance identified by a connection handle in m_user_mem_table[]. + * + * @param[in] conn_handle conn_handle + * + * @param[out] p_index Pointer to the index of the entry in the context table corresponding to the given conn_handle. + * + * @retval NRF_SUCCESS Context found. + * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found. + */ +uint32_t app_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif //_APP_BLE_USER_MEM_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_app.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_app.c new file mode 100644 index 0000000000000000000000000000000000000000..5b99902711177e21f64954f07c2f48781efc51f9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_app.c @@ -0,0 +1,495 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "ble_app.h" +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "ble_gatt_struct_serialization.h" +#include "ble_gattc_struct_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_enable_req_enc(ble_enable_params_t * p_ble_enable_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_ENABLE); + SER_PUSH_COND(p_ble_enable_params, ble_enable_params_t_enc); + SER_REQ_ENC_END; +} +#else +uint32_t ble_enable_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_ENABLE); + SER_REQ_ENC_END; +} +#endif + +uint32_t ble_enable_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_ENABLE); +} + +uint32_t ble_opt_get_req_enc(uint32_t opt_id, + ble_opt_t const * const p_opt, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_OPT_GET); + + SER_PUSH_uint32(&opt_id); + SER_PUSH_COND(p_opt, NULL); + + SER_REQ_ENC_END; +} + +uint32_t ble_opt_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_opt_id, + ble_opt_t * const p_opt, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_OPT_GET); + + SER_PULL_uint32(p_opt_id); + + field_decoder_handler_t fp_decoder = NULL; + void * p_struct = NULL; + + switch (*p_opt_id) + { +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_COMMON_OPT_CONN_BW: + fp_decoder = ble_common_opt_conn_bw_t_dec; + p_struct = &(p_opt->common_opt.conn_bw); + break; +#endif + case BLE_COMMON_OPT_PA_LNA: + fp_decoder = ble_common_opt_pa_lna_t_dec; + p_struct = &(p_opt->common_opt.pa_lna); + break; + case BLE_COMMON_OPT_CONN_EVT_EXT: + fp_decoder = ble_common_opt_conn_evt_ext_t_dec; + p_struct = &(p_opt->common_opt.conn_evt_ext); + break; + case BLE_GAP_OPT_CH_MAP: + fp_decoder = ble_gap_opt_ch_map_t_dec; + p_struct =&(p_opt->gap_opt.ch_map); + break; + case BLE_GAP_OPT_LOCAL_CONN_LATENCY: + fp_decoder = ble_gap_opt_local_conn_latency_t_dec; + p_struct = &(p_opt->gap_opt.local_conn_latency); + break; + case BLE_GAP_OPT_PASSKEY: + fp_decoder = ble_gap_opt_passkey_t_dec; + p_struct = &(p_opt->gap_opt.passkey); + break; + case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT: + fp_decoder = ble_gap_opt_auth_payload_timeout_t_dec; + p_struct = &(p_opt->gap_opt.auth_payload_timeout); + break; +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_GAP_OPT_EXT_LEN: + fp_decoder = ble_gap_opt_ext_len_t_dec; + p_struct = &(p_opt->gap_opt.ext_len); + break; +#endif + case BLE_GAP_OPT_SCAN_REQ_REPORT: + fp_decoder = ble_gap_opt_scan_req_report_t_dec; + p_struct = &(p_opt->gap_opt.scan_req_report); + break; +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_GAP_OPT_COMPAT_MODE: + fp_decoder = ble_gap_opt_compat_mode_t_dec; + p_struct = &(p_opt->gap_opt.compat_mode); + break; +#else + case BLE_GAP_OPT_COMPAT_MODE_1: + fp_decoder = ble_gap_opt_compat_mode_1_t_dec; + p_struct = &(p_opt->gap_opt.compat_mode_1); + break; + case BLE_GAP_OPT_COMPAT_MODE_2: + fp_decoder = ble_gap_opt_compat_mode_2_t_dec; + p_struct = &(p_opt->gap_opt.compat_mode_2); + break; + +#endif + default: + SER_ASSERT(NRF_ERROR_INVALID_PARAM, NRF_ERROR_INVALID_PARAM); + break; + } + + SER_PULL_FIELD(p_struct, fp_decoder); + + SER_RSP_DEC_END; +} + + + +uint32_t ble_opt_set_req_enc(uint32_t const opt_id, + ble_opt_t const * const p_opt, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_OPT_SET); + + SER_PUSH_uint32(&opt_id); + + field_encoder_handler_t fp_encoder = NULL; + void const * p_struct = NULL; + + SER_PUSH_COND(p_opt, NULL); + if (p_opt) + { + switch(opt_id) + { +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_COMMON_OPT_CONN_BW: + fp_encoder = ble_common_opt_conn_bw_t_enc; + p_struct = &(p_opt->common_opt.conn_bw); + break; +#endif + case BLE_COMMON_OPT_PA_LNA: + fp_encoder = ble_common_opt_pa_lna_t_enc; + p_struct = &(p_opt->common_opt.pa_lna); + break; + case BLE_COMMON_OPT_CONN_EVT_EXT: + fp_encoder = ble_common_opt_conn_evt_ext_t_enc; + p_struct = &(p_opt->common_opt.conn_evt_ext); + break; + case BLE_GAP_OPT_CH_MAP: + fp_encoder = ble_gap_opt_ch_map_t_enc; + p_struct = &(p_opt->gap_opt.ch_map); + break; + case BLE_GAP_OPT_LOCAL_CONN_LATENCY: + fp_encoder = ble_gap_opt_local_conn_latency_t_enc; + p_struct = &(p_opt->gap_opt.local_conn_latency); + break; + case BLE_GAP_OPT_PASSKEY: + fp_encoder = ble_gap_opt_passkey_t_enc; + p_struct = &(p_opt->gap_opt.passkey); + break; + case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT: + fp_encoder = ble_gap_opt_auth_payload_timeout_t_enc; + p_struct = &(p_opt->gap_opt.auth_payload_timeout); + break; +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_GAP_OPT_EXT_LEN: + fp_encoder = ble_gap_opt_ext_len_t_enc; + p_struct = &(p_opt->gap_opt.ext_len); + break; +#endif + case BLE_GAP_OPT_SCAN_REQ_REPORT: + fp_encoder = ble_gap_opt_scan_req_report_t_enc; + p_struct = &(p_opt->gap_opt.scan_req_report); + break; +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_GAP_OPT_COMPAT_MODE: + fp_encoder = ble_gap_opt_compat_mode_t_enc; + p_struct = &(p_opt->gap_opt.compat_mode); + break; +#else + case BLE_GAP_OPT_COMPAT_MODE_1: + fp_encoder = ble_gap_opt_compat_mode_1_t_enc; + p_struct = &(p_opt->gap_opt.compat_mode_1); + break; + case BLE_GAP_OPT_COMPAT_MODE_2: + fp_encoder = ble_gap_opt_compat_mode_2_t_enc; + p_struct = &(p_opt->gap_opt.compat_mode_2); + break; + case BLE_GAP_OPT_SLAVE_LATENCY_DISABLE: + fp_encoder = ble_gap_opt_slave_latency_disable_t_enc; + p_struct = &(p_opt->gap_opt.slave_latency_disable); + break; +#endif + default: + SER_ASSERT(NRF_ERROR_INVALID_PARAM,NRF_ERROR_INVALID_PARAM); + break; + } + + SER_PUSH_FIELD(p_struct, fp_encoder); + } + + SER_REQ_ENC_END; +} + + +uint32_t ble_opt_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_OPT_SET); +} + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_tx_packet_count_get_req_enc(uint16_t conn_handle, + uint8_t const * const p_count, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_TX_PACKET_COUNT_GET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_count, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_tx_packet_count_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * const pp_count, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_TX_PACKET_COUNT_GET); + SER_PULL_COND(pp_count, uint8_t_dec); + SER_RSP_DEC_END; +} +#endif + +uint32_t ble_user_mem_reply_req_enc(uint16_t conn_handle, + ble_user_mem_block_t const * p_block, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_USER_MEM_REPLY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_block, ble_user_mem_block_t_enc); + + SER_REQ_ENC_END; +} + +uint32_t ble_user_mem_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_USER_MEM_REPLY); +} + + + +uint32_t ble_uuid_decode_req_enc(uint8_t uuid_le_len, + uint8_t const * const p_uuid_le, + ble_uuid_t * const p_uuid, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_UUID_DECODE); + + SER_PUSH_len8data(p_uuid_le, uuid_le_len); + SER_PUSH_COND(p_uuid, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_uuid_decode_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_uuid_t * * const pp_uuid, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_UUID_DECODE); + SER_PULL_COND(pp_uuid, ble_uuid_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid, + uint8_t const * const p_uuid_le_len, + uint8_t const * const p_uuid_le, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_UUID_ENCODE); + + SER_PUSH_COND(p_uuid, ble_uuid_t_enc); + SER_PUSH_COND(p_uuid_le_len, NULL); + SER_PUSH_COND(p_uuid_le, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_uuid_encode_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_uuid_le_len, + uint8_t * const p_uuid_le, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_UUID_ENCODE); + + uint8_t uuid_le_len; + SER_PULL_uint8(&uuid_le_len); + if (p_uuid_le_len) + { + *p_uuid_le_len = uuid_le_len; + if (p_uuid_le) + { + SER_PULL_uint8array(p_uuid_le, uuid_le_len); + } + } + + SER_RSP_DEC_END; +} + +uint32_t ble_uuid_vs_add_req_enc(ble_uuid128_t const * const p_vs_uuid, + uint8_t * const p_uuid_type, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_UUID_VS_ADD); + + SER_PUSH_COND(p_vs_uuid, ble_uuid128_t_enc); + SER_PUSH_COND(p_uuid_type, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_uuid_vs_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * const pp_uuid_type, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_UUID_VS_ADD); + + SER_ASSERT_NOT_NULL(pp_uuid_type); + SER_PULL_COND(pp_uuid_type, uint8_t_dec); + + SER_RSP_DEC_END; +} + +uint32_t ble_version_get_req_enc(ble_version_t const * const p_version, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_VERSION_GET); + SER_PUSH_COND(p_version, NULL); + SER_REQ_ENC_END; +} + +uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_version_t * p_version, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_VERSION_GET); + SER_PULL_FIELD(p_version, ble_version_t_dec); + SER_RSP_DEC_END; +} +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_cfg_set_req_enc(uint32_t cfg_id, + ble_cfg_t const * p_cfg, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_CFG_SET); + SER_PUSH_uint32(&cfg_id); + field_encoder_handler_t fp_encoder = NULL; + void const * p_struct = NULL; + + SER_PUSH_COND(p_cfg, NULL); + if (p_cfg) + { + + switch(cfg_id) + { + case BLE_CONN_CFG_GAP: + fp_encoder = ble_gap_conn_cfg_t_enc; + p_struct = &(p_cfg->conn_cfg.params.gap_conn_cfg); + break; + case BLE_CONN_CFG_GATTC: + fp_encoder = ble_gattc_conn_cfg_t_enc; + p_struct = &(p_cfg->conn_cfg.params.gattc_conn_cfg); + break; + case BLE_CONN_CFG_GATTS: + fp_encoder = ble_gatts_conn_cfg_t_enc; + p_struct = &(p_cfg->conn_cfg.params.gatts_conn_cfg); + break; + case BLE_CONN_CFG_GATT: + fp_encoder = ble_gatt_conn_cfg_t_enc; + p_struct = &(p_cfg->conn_cfg.params.gatt_conn_cfg); + break; + case BLE_COMMON_CFG_VS_UUID: + fp_encoder = ble_common_cfg_vs_uuid_t_enc; + p_struct = &(p_cfg->common_cfg.vs_uuid_cfg); + break; + case BLE_GAP_CFG_ROLE_COUNT: + fp_encoder = ble_gap_cfg_role_count_t_enc; + p_struct = &(p_cfg->gap_cfg.role_count_cfg); + break; + case BLE_GAP_CFG_DEVICE_NAME: + fp_encoder = ble_gap_cfg_device_name_t_enc; + p_struct = &(p_cfg->gap_cfg.device_name_cfg); + break; + case BLE_GATTS_CFG_SERVICE_CHANGED: + fp_encoder = ble_gatts_cfg_service_changed_t_enc; + p_struct = &(p_cfg->gatts_cfg.service_changed); + break; + case BLE_GATTS_CFG_ATTR_TAB_SIZE: + fp_encoder = ble_gatts_cfg_attr_tab_size_t_enc; + p_struct = &(p_cfg->gatts_cfg.attr_tab_size); + break; + } + if (cfg_id >= BLE_CONN_CFG_BASE && cfg_id <= BLE_CONN_CFG_GATT) + { + SER_PUSH_uint8(&p_cfg->conn_cfg.conn_cfg_tag); + } + SER_PUSH_FIELD(p_struct, fp_encoder); + } + SER_REQ_ENC_END; +} + + +uint32_t ble_cfg_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_CFG_SET); +} +#endif //NRF_SD_BLE_API_VERSION >= 4 diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_app.h new file mode 100644 index 0000000000000000000000000000000000000000..0d586095222cdb4d04fd2deb5cea78a6dec3d43e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_app.h @@ -0,0 +1,523 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_APP_H__ +#define BLE_APP_H__ + +/** + * @addtogroup ser_codecs Serialization codecs + * @ingroup ble_sdk_lib_serialization + */ + +/** + * @addtogroup ser_app_s130_codecs Application codecs for S132 and S140 + * @ingroup ser_codecs_app + */ + +/**@file + * + * @defgroup ble_app Application command request encoders and command response decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief Application command request encoders and command response decoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +/** + * @brief Encodes @ref sd_ble_tx_packet_count_get command request. + * + * @sa @ref ble_tx_packet_count_get_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_count Pointer to count value to be filled. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of the encoded command packet. + * + * @note \p p_count will not be updated by the command + * request encoder. Updated values are set by @ref ble_tx_packet_count_get_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_tx_packet_count_get_req_enc(uint16_t conn_handle, + uint8_t const * const p_count, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes a response to @ref sd_ble_tx_packet_count_get command. + * + * @sa @ref ble_tx_packet_count_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] pp_count Pointer to the pointer to count value. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_tx_packet_count_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * const pp_count, + uint32_t * const p_result_code); +#endif +/**@brief Encodes the @ref sd_ble_uuid_encode command request. + * + * @sa @ref ble_uuid_encode_rsp_dec for command response decoder. + * + * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. + * @param[in] p_uuid_le_len Size of \p p_uuid_le, if \p p_uuid_le is not NULL + * @param[in] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes(2 or 16) + * will be stored. Can be NULL to calculate the required size. + * @param[in] p_buf Pointer to a buffer where the encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of the encoded command packet. + * + * @note \p p_uuid_le_len and \p p_uuid_le will not be updated by the command + * request encoder. Updated values are set by @ref ble_uuid_encode_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid, + uint8_t const * const p_uuid_le_len, + uint8_t const * const p_uuid_le, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes a response to the @ref sd_ble_uuid_encode command. + * + * @sa @ref ble_uuid_encode_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of a response packet. + * @param[in,out] p_uuid_le_len \c in: Size (in bytes) of \p p_uuid_le buffer. + * \c out: Length of decoded contents of \p p_uuid_le. + * @param[out] p_uuid_le Pointer to a buffer where the encoded UUID will be stored. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Length of \p p_uuid_le is too small to hold the decoded + * value from response. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match the expected + * operation code. + */ +uint32_t ble_uuid_encode_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_uuid_le_len, + uint8_t * const p_uuid_le, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_uuid_decode command request. + * + * @sa @ref ble_uuid_decode_rsp_dec for command response decoder. + * + * @param[in] uuid_le_len Size of \p p_uuid_le if \p p_uuid_le is not NULL. + * @param[in] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes(2 or 16) + * are stored. + * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure were the raw UUID will be decoded. + * @param[in] p_buf Pointer to the buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of the encoded command packet. + * + * @note \p p_uuid will not be updated by the command request encoder. + * Updated values are set by @ref ble_uuid_decode_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_uuid_decode_req_enc(uint8_t uuid_le_len, + uint8_t const * const p_uuid_le, + ble_uuid_t * const p_uuid, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes a response to the @ref sd_ble_uuid_decode command. + * + * @sa @ref ble_uuid_decode_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to the beginning of command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] p_uuid Pointer to a buffer where the decoded UUID will be stored. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match the expected + * operation code. + */ +uint32_t ble_uuid_decode_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_uuid_t * * const p_uuid, + uint32_t * const p_result_code); + +/**@brief Encodes the @ref sd_ble_uuid_vs_add command request. + * + * @sa @ref ble_uuid_vs_add_rsp_dec for command response decoder. + * + * @param[in] p_vs_uuid Pointer to a @ref ble_uuid128_t structure. + * @param[in] p_uuid_type Pointer to uint8_t where UUID type will be returned. + * @param[in] p_buf Pointer to buffer where the encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @note \p p_uuid_type will not be updated by the command request encoder. + * Updated values are set by @ref ble_uuid_vs_add_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_uuid_vs_add_req_enc(ble_uuid128_t const * const p_vs_uuid, + uint8_t * const p_uuid_type, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to the @ref sd_ble_uuid_vs_add command. + * + * @sa @ref ble_uuid_vs_add_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to the beginning of command response packet. + * @param[in] packet_len Length (in bytes) of a response packet. + * @param[out] pp_uuid_type Pointer to a pointer to uint8_t where the decoded UUID type will be stored. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_uuid_vs_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * const pp_uuid_type, + uint32_t * const p_result_code); + +/**@brief Encodes the @ref sd_ble_version_get command request. + * + * @sa @ref ble_version_get_rsp_dec for command response decoder. + * + * @param[in] p_version Pointer to a @ref ble_version_t structure to be filled by the response. + * @param[in] p_buf Pointer to a buffer where the encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_version_get_req_enc(ble_version_t const * const p_version, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to the @ref sd_ble_version_get command. + * + * @sa @ref ble_version_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] p_version Pointer to a @ref ble_version_t where the decoded version will be stored. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Version information stored successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + */ +uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_version_t * p_version, + uint32_t * const p_result_code); + + +/**@brief Encodes the @ref sd_ble_opt_set command request. + * + * @sa @ref ble_opt_set_rsp_dec for command response decoder. + * + * @param[in] opt_id Identifies type of parameter in ble_opt_t union. + * @param[in] p_opt Pointer to the ble_opt_t union. + * @param[in] p_buf Pointer to a buffer where the encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of the encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. + */ +uint32_t ble_opt_set_req_enc(uint32_t const opt_id, + ble_opt_t const * const p_opt, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to the @ref sd_ble_opt_set command. + * + * @sa @ref ble_opt_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Version information stored successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_opt_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +/**@brief Encodes the @ref sd_ble_enable command request. + * + * @sa @ref ble_enable_rsp_dec for command response decoder. + * + * @param[in] p_ble_enable_params Pointer to the @ref ble_enable_params_t structure. + * @param[in] p_buf Pointer to the buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of the encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_enable_req_enc(ble_enable_params_t * p_ble_enable_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +#else +/**@brief Encodes the @ref sd_ble_enable command request. + * + * @sa @ref ble_enable_rsp_dec for command response decoder. + * + * @param[in] p_buf Pointer to the buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of the encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_enable_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len); + +#endif + +/**@brief Decodes response to the @ref sd_ble_enable command. + * + * @sa @ref ble_enable_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + */ +uint32_t ble_enable_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); +/**@brief Encodes the @ref sd_ble_opt_get command request. + * + * @sa @ref ble_opt_get_rsp_dec for command response decoder. + * + * @param[in] opt_id Identifies the type of parameter in the ble_opt_t union. + * @param[in] p_opt Pointer to the @ref ble_opt_t union to be filled by the response. + * @param[in] p_buf Pointer to the buffer where the encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of the encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. + */ +uint32_t ble_opt_get_req_enc(uint32_t opt_id, + ble_opt_t const * const p_opt, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to the @ref sd_ble_opt_get command. + * + * @sa @ref ble_opt_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] p_opt_id Pointer to the decoded opt_id. + * @param[out] p_opt Pointer to the decoded @ref ble_opt_t union. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Opt stored successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. + */ + +uint32_t ble_opt_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_opt_id, + ble_opt_t * const p_opt, + uint32_t * const p_result_code); + +/**@brief Encodes the @ref sd_ble_user_mem_reply command request. + * + * @sa @ref ble_user_mem_reply_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_block Pointer to the @ref ble_user_mem_block_t structure. + * @param[in] p_buf Pointer to the buffer where the encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of the encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. + */ +uint32_t ble_user_mem_reply_req_enc(uint16_t conn_handle, + ble_user_mem_block_t const * p_block, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to the @ref sd_ble_user_mem_reply command. + * + * @sa @ref ble_user_mem_reply_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Opt stored successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. + */ +uint32_t ble_user_mem_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); +#if NRF_SD_BLE_API_VERSION >= 4 +/**@brief Encodes the @ref sd_ble_cfg_set command request. + * + * @sa @ref ble_cfg_set_rsp_dec for command response decoder. + * + * @param[in] cfg_id Configuratio id. + * @param[in] p_cfg Pointer to the configuration. + * @param[in] p_buf Pointer to the buffer where the encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of the encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. + */ +uint32_t ble_cfg_set_req_enc(uint32_t cfg_id, + ble_cfg_t const * p_cfg, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to the @ref sd_ble_cfg_set command. + * + * @sa @ref ble_cfg_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Opt stored successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. + */ +uint32_t ble_cfg_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); +#endif //NRF_SD_BLE_API_VERSION >= 4 + +/**@brief Event decoding dispatcher. + * + * The event decoding dispatcher will route the event packet to the correct decoder, which in turn + * decodes the contents of the event and updates the \p p_event struct. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of the event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, the required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of the decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + * @retval NRF_ERROR_NOT_FOUND Decoding failure. No event decoder is available. + */ +uint32_t ble_event_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_event.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_event.c new file mode 100644 index 0000000000000000000000000000000000000000..b5858ce26de5b8bebac1e957e6d9c4d98a92268e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_event.c @@ -0,0 +1,276 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_serialization.h" +#include "ble_app.h" +#include "ble_evt_app.h" +#include "ble_gap_evt_app.h" +#include "ble_gattc_evt_app.h" +#include "ble_gatts_evt_app.h" +#include "ble_l2cap_evt_app.h" +#include "app_util.h" + +uint32_t ble_event_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + uint32_t err_code; + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_event_len); + SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE, packet_len); + SER_ASSERT_NOT_NULL(p_event); + SER_ASSERT_LENGTH_LEQ(sizeof (ble_evt_hdr_t), *p_event_len); + *p_event_len -= sizeof (ble_evt_hdr_t); + + const uint16_t event_id = uint16_decode(&p_buf[SER_EVT_ID_POS]); + const uint8_t * p_sub_buffer = &p_buf[SER_EVT_HEADER_SIZE]; + const uint32_t sub_packet_len = packet_len - SER_EVT_HEADER_SIZE; + + uint32_t (*fp_event_decoder)(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) = NULL; + + switch (event_id) + { +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_EVT_TX_COMPLETE: + fp_event_decoder = ble_evt_tx_complete_dec; + break; + case BLE_EVT_DATA_LENGTH_CHANGED: + fp_event_decoder = ble_evt_data_length_changed_dec; + break; +#endif + case BLE_EVT_USER_MEM_REQUEST: + fp_event_decoder = ble_evt_user_mem_request_dec; + break; + + case BLE_EVT_USER_MEM_RELEASE: + fp_event_decoder = ble_evt_user_mem_release_dec; + break; + + + case BLE_GAP_EVT_PASSKEY_DISPLAY: + fp_event_decoder = ble_gap_evt_passkey_display_dec; + break; + + case BLE_GAP_EVT_AUTH_KEY_REQUEST: + fp_event_decoder = ble_gap_evt_auth_key_request_dec; + break; + + case BLE_GAP_EVT_CONN_PARAM_UPDATE: + fp_event_decoder = ble_gap_evt_conn_param_update_dec; + break; + + case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: + fp_event_decoder = ble_gap_evt_conn_param_update_request_dec; + break; + + case BLE_GAP_EVT_CONN_SEC_UPDATE: + fp_event_decoder = ble_gap_evt_conn_sec_update_dec; + break; + + case BLE_GAP_EVT_CONNECTED: + fp_event_decoder = ble_gap_evt_connected_dec; + break; + + case BLE_GAP_EVT_DISCONNECTED: + fp_event_decoder = ble_gap_evt_disconnected_dec; + break; + + case BLE_GAP_EVT_TIMEOUT: + fp_event_decoder = ble_gap_evt_timeout_dec; + break; + + case BLE_GAP_EVT_RSSI_CHANGED: + fp_event_decoder = ble_gap_evt_rssi_changed_dec; + break; + + case BLE_GAP_EVT_SEC_INFO_REQUEST: + fp_event_decoder = ble_gap_evt_sec_info_request_dec; + break; + + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + fp_event_decoder = ble_gap_evt_sec_params_request_dec; + break; + + case BLE_GAP_EVT_AUTH_STATUS: + fp_event_decoder = ble_gap_evt_auth_status_dec; + break; + + case BLE_GAP_EVT_SEC_REQUEST: + fp_event_decoder = ble_gap_evt_sec_request_dec; + break; + + case BLE_GAP_EVT_KEY_PRESSED: + fp_event_decoder = ble_gap_evt_key_pressed_dec; + break; + + case BLE_GAP_EVT_LESC_DHKEY_REQUEST: + fp_event_decoder = ble_gap_evt_lesc_dhkey_request_dec; + break; +#if NRF_SD_BLE_API_VERSION >= 5 + case BLE_GAP_EVT_PHY_UPDATE: + fp_event_decoder = ble_gap_evt_phy_update_dec; + break; +#endif +#if NRF_SD_BLE_API_VERSION >= 4 + case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: + fp_event_decoder = ble_gap_evt_data_length_update_request_dec; + break; + case BLE_GAP_EVT_DATA_LENGTH_UPDATE: + fp_event_decoder = ble_gap_evt_data_length_update_dec; + break; +#endif + case BLE_GATTC_EVT_CHAR_DISC_RSP: + fp_event_decoder = ble_gattc_evt_char_disc_rsp_dec; + break; + + case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP: + fp_event_decoder = ble_gattc_evt_char_val_by_uuid_read_rsp_dec; + break; + + case BLE_GATTC_EVT_DESC_DISC_RSP: + fp_event_decoder = ble_gattc_evt_desc_disc_rsp_dec; + break; + + case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: + fp_event_decoder = ble_gattc_evt_prim_srvc_disc_rsp_dec; + break; + + case BLE_GATTC_EVT_READ_RSP: + fp_event_decoder = ble_gattc_evt_read_rsp_dec; + break; + + case BLE_GATTC_EVT_HVX: + fp_event_decoder = ble_gattc_evt_hvx_dec; + break; + + case BLE_GATTC_EVT_TIMEOUT: + fp_event_decoder = ble_gattc_evt_timeout_dec; + break; + + case BLE_GATTC_EVT_WRITE_RSP: + fp_event_decoder = ble_gattc_evt_write_rsp_dec; + break; + + case BLE_GATTC_EVT_CHAR_VALS_READ_RSP: + fp_event_decoder = ble_gattc_evt_char_vals_read_rsp_dec; + break; + + case BLE_GATTC_EVT_REL_DISC_RSP: + fp_event_decoder = ble_gattc_evt_rel_disc_rsp_dec; + break; + + case BLE_GATTC_EVT_ATTR_INFO_DISC_RSP: + fp_event_decoder = ble_gattc_evt_attr_info_disc_rsp_dec; + break; + + case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: + fp_event_decoder = ble_gattc_evt_exchange_mtu_rsp_dec; + break; +#if NRF_SD_BLE_API_VERSION >= 4 + case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE: + fp_event_decoder = ble_gattc_evt_write_cmd_tx_complete_dec; + break; +#endif + case BLE_GATTS_EVT_WRITE: + fp_event_decoder = ble_gatts_evt_write_dec; + break; + + case BLE_GATTS_EVT_TIMEOUT: + fp_event_decoder = ble_gatts_evt_timeout_dec; + break; + + case BLE_GATTS_EVT_SC_CONFIRM: + fp_event_decoder = ble_gatts_evt_sc_confirm_dec; + break; + + case BLE_GATTS_EVT_HVC: + fp_event_decoder = ble_gatts_evt_hvc_dec; + break; + + case BLE_GATTS_EVT_SYS_ATTR_MISSING: + fp_event_decoder = ble_gatts_evt_sys_attr_missing_dec; + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + fp_event_decoder = ble_gatts_evt_rw_authorize_request_dec; + break; + + case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: + fp_event_decoder = ble_gatts_evt_exchange_mtu_request_dec; + break; +#if NRF_SD_BLE_API_VERSION >= 4 + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + fp_event_decoder = ble_gatts_evt_hvn_tx_complete_dec; + break; +#endif +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_L2CAP_EVT_RX: + fp_event_decoder = ble_l2cap_evt_rx_dec; + break; +#endif + case BLE_GAP_EVT_ADV_REPORT: + fp_event_decoder = ble_gap_evt_adv_report_dec; + break; + + case BLE_GAP_EVT_SCAN_REQ_REPORT: + fp_event_decoder = ble_gap_evt_scan_req_report_dec; + break; + default: + break; + } + + if (fp_event_decoder) + { + err_code = fp_event_decoder(p_sub_buffer, sub_packet_len, p_event, p_event_len); + } + else + { + err_code = NRF_ERROR_NOT_FOUND; + } + + *p_event_len += offsetof(ble_evt_t, evt); + p_event->header.evt_id = (err_code == NRF_SUCCESS) ? event_id : 0; + p_event->header.evt_len = (err_code == NRF_SUCCESS) ? (uint16_t)*p_event_len : 0; + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_evt_app.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_evt_app.c new file mode 100644 index 0000000000000000000000000000000000000000..c72e866a326927948c81aab6b3b2eed40033774c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_evt_app.c @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include "ble_evt_app.h" +#include "app_ble_user_mem.h" + + +// Helper definitions for common event type names to be compliant with +// event serialization macros. +#define ble_common_evt_tx_complete_t ble_evt_tx_complete_t +#define ble_common_evt_user_mem_request_t ble_evt_user_mem_request_t +#define ble_common_evt_user_mem_release_t ble_evt_user_mem_release_t +#define ble_common_evt_data_length_changed_t ble_evt_data_length_changed_t + + +extern ser_ble_user_mem_t m_app_user_mem_table[]; + +uint32_t ble_evt_user_mem_release_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_EVT_USER_MEM_RELEASE, common, user_mem_release); + + SER_PULL_uint16(&p_event->evt.common_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.common_evt.params.user_mem_release.type); + SER_PULL_uint16(&p_event->evt.common_evt.params.user_mem_release.mem_block.len); + + //Set the memory pointer to not-null value. + p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem = (uint8_t *)~0; + SER_PULL_COND(&p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem, NULL); + if (p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem) + { + // Using connection handle find which mem block to release in Application Processor + uint32_t user_mem_table_index; + err_code = app_ble_user_mem_context_find(p_event->evt.common_evt.conn_handle, &user_mem_table_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem = + m_app_user_mem_table[user_mem_table_index].mem_block.p_mem; + } + + // Now user memory context can be released + err_code = app_ble_user_mem_context_destroy(p_event->evt.common_evt.conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_EVT_DEC_END; +} + +uint32_t ble_evt_user_mem_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_EVT_USER_MEM_REQUEST, common, user_mem_request); + + SER_PULL_uint16(&p_event->evt.common_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.common_evt.params.user_mem_request.type); + + SER_EVT_DEC_END; +} + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_EVT_TX_COMPLETE, common, tx_complete); + + SER_PULL_uint16(&p_event->evt.common_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.common_evt.params.tx_complete.count); + + SER_EVT_DEC_END; +} + + +uint32_t ble_evt_data_length_changed_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_EVT_DATA_LENGTH_CHANGED, common, data_length_changed); + + SER_PULL_uint16(&p_event->evt.common_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.common_evt.params.data_length_changed, ble_evt_data_length_changed_t_dec); + + SER_EVT_DEC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_evt_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_evt_app.h new file mode 100644 index 0000000000000000000000000000000000000000..9941481b41f1bca1c2df28034e53e511e4170491 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_evt_app.h @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_EVT_APP_H__ +#define BLE_EVT_APP_H__ + +/**@file + * + * @defgroup ble_evt_app Application event decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief Application event decoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +/** + * @brief Decodes the ble_evt_tx_complete event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of the event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, the required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of the \p p_event buffer. + * \c out: Length of the decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + */ +uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); +#endif +/** + * @brief Decodes the ble_evt_user_mem_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of the event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, the required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of the \p p_event buffer. + * \c out: Length of the decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + */ +uint32_t ble_evt_user_mem_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes the ble_evt_user_mem_release event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of the event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, the required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of the \p p_event buffer. + * \c out: Length of the decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + */ +uint32_t ble_evt_user_mem_release_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +/** + * @brief Decodes the ble_evt_data_length_changed event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of the event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, the required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of the \p p_event buffer. + * \c out: Length of the decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + */ +uint32_t ble_evt_data_length_changed_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gap_app.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gap_app.c new file mode 100644 index 0000000000000000000000000000000000000000..3554837d2bf5b3401ee41830edd7c7b9bce05a60 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gap_app.c @@ -0,0 +1,911 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gap_app.h" +#include +#include +#include "ble_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "ble_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + + +uint32_t ble_gap_adv_data_set_req_enc(uint8_t const * const p_data, + uint8_t dlen, + uint8_t const * const p_sr_data, + uint8_t srdlen, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADV_DATA_SET); + + SER_PUSH_len8data(p_data, dlen); + SER_PUSH_len8data(p_sr_data, srdlen); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_adv_data_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ADV_DATA_SET); +} + + +uint32_t ble_gap_adv_start_req_enc(ble_gap_adv_params_t const * const p_adv_params, +#if NRF_SD_BLE_API_VERSION >= 4 + uint8_t conn_cfg_tag, +#endif + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADV_START); + SER_PUSH_COND(p_adv_params, ble_gap_adv_params_t_enc); +#if NRF_SD_BLE_API_VERSION >= 4 + SER_PUSH_uint8(&conn_cfg_tag); +#endif + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_adv_start_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ADV_START); +} + + +uint32_t ble_gap_adv_stop_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADV_STOP); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_adv_stop_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ADV_STOP); +} + + + +uint32_t ble_gap_appearance_get_req_enc(uint16_t const * const p_appearance, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_APPEARANCE_GET); + SER_PUSH_COND(p_appearance, NULL); + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_appearance_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_appearance, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_APPEARANCE_GET); + SER_PULL_COND(&p_appearance, uint16_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_appearance_set_req_enc(uint16_t appearance, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_APPEARANCE_SET); + SER_PUSH_uint16(&appearance); + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_appearance_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_APPEARANCE_SET); +} + + +uint32_t ble_gap_auth_key_reply_req_enc(uint16_t conn_handle, + uint8_t key_type, + uint8_t const * const p_key, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_AUTH_KEY_REPLY); + + uint8_t key_len; + switch (key_type) + { + case BLE_GAP_AUTH_KEY_TYPE_NONE: + key_len = 0; + break; + + case BLE_GAP_AUTH_KEY_TYPE_PASSKEY: + key_len = 6; + break; + + case BLE_GAP_AUTH_KEY_TYPE_OOB: + key_len = 16; + break; + + default: + return NRF_ERROR_INVALID_PARAM; + } + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint8(&key_type); + SER_PUSH_buf(p_key, key_len); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_auth_key_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_AUTH_KEY_REPLY); +} + + + +uint32_t ble_gap_authenticate_req_enc(uint16_t conn_handle, + ble_gap_sec_params_t const * const p_sec_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_AUTHENTICATE); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_sec_params, ble_gap_sec_params_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_authenticate_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_AUTHENTICATE); +} + + +uint32_t ble_gap_conn_param_update_req_enc(uint16_t conn_handle, + ble_gap_conn_params_t const * const p_conn_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_CONN_PARAM_UPDATE); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_conn_params, ble_gap_conn_params_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_conn_param_update_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_CONN_PARAM_UPDATE); +} + + +uint32_t ble_gap_conn_sec_get_req_enc(uint16_t conn_handle, + ble_gap_conn_sec_t const * const p_conn_sec, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_CONN_SEC_GET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_conn_sec, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_conn_sec_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_conn_sec_t * * const pp_conn_sec, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_CONN_SEC_GET); + SER_PULL_COND(pp_conn_sec, ble_gap_conn_sec_t_dec); + SER_RSP_DEC_END; +} + +uint32_t ble_gap_connect_req_enc(ble_gap_addr_t const * const p_peer_addr, + ble_gap_scan_params_t const * const p_scan_params, + ble_gap_conn_params_t const * const p_conn_params, +#if NRF_SD_BLE_API_VERSION >= 4 + uint8_t conn_cfg_tag, +#endif + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_CONNECT); + + SER_PUSH_COND(p_peer_addr, ble_gap_addr_t_enc); + SER_PUSH_COND(p_scan_params, ble_gap_scan_params_t_enc); + SER_PUSH_COND(p_conn_params, ble_gap_conn_params_t_enc); +#if NRF_SD_BLE_API_VERSION >= 4 + SER_PUSH_uint8(&conn_cfg_tag); +#endif + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_connect_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_CONNECT); +} + + +uint32_t ble_gap_connect_cancel_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_CONNECT_CANCEL); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_connect_cancel_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_CONNECT_CANCEL); +} + + +uint32_t ble_gap_device_name_get_req_enc(uint8_t const * const p_dev_name, + uint16_t const * const p_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_DEVICE_NAME_GET); + + SER_PUSH_COND(p_len, uint16_t_enc); + SER_PUSH_COND(p_dev_name, NULL); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_device_name_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_dev_name, + uint16_t * const p_dev_name_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_DEVICE_NAME_GET); + + SER_PULL_COND(&p_dev_name_len, uint16_t_dec); + if (p_dev_name_len) + { + SER_PULL_uint8array(p_dev_name, *p_dev_name_len); + } + + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_device_name_set_req_enc(ble_gap_conn_sec_mode_t const * const p_write_perm, + uint8_t const * const p_dev_name, + uint16_t len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_DEVICE_NAME_SET); + + SER_ERROR_CHECK(len <= BLE_GAP_DEVNAME_MAX_LEN, NRF_ERROR_INVALID_PARAM); + + SER_PUSH_COND(p_write_perm, ble_gap_conn_sec_mode_t_enc); + SER_PUSH_len16data(p_dev_name, len); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_device_name_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_DEVICE_NAME_SET); +} + + +uint32_t ble_gap_disconnect_req_enc(uint16_t conn_handle, + uint8_t hci_status_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_DISCONNECT); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint8(&hci_status_code); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_disconnect_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_DISCONNECT); +} + + +uint32_t ble_gap_encrypt_req_enc(uint16_t conn_handle, + ble_gap_master_id_t const * const p_master_id, + ble_gap_enc_info_t const * const p_enc_info, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_ENCRYPT); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_master_id, ble_gap_master_id_t_enc); + SER_PUSH_COND(p_enc_info, ble_gap_enc_info_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_encrypt_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ENCRYPT); +} + + +uint32_t ble_gap_keypress_notify_req_enc(uint16_t conn_handle, + uint8_t kp_not, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_KEYPRESS_NOTIFY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint8(&kp_not); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_keypress_notify_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_KEYPRESS_NOTIFY); +} + + +uint32_t ble_gap_lesc_dhkey_reply_req_enc(uint16_t conn_handle, + ble_gap_lesc_dhkey_t const *p_dhkey, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_LESC_DHKEY_REPLY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_dhkey, ble_gap_lesc_dhkey_t_enc); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_lesc_dhkey_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_LESC_DHKEY_REPLY); +} + + +uint32_t ble_gap_lesc_oob_data_get_req_enc(uint16_t conn_handle, + ble_gap_lesc_p256_pk_t const *p_pk_own, + ble_gap_lesc_oob_data_t *p_oobd_own, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_GET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_pk_own, ble_gap_lesc_p256_pk_t_enc); + SER_PUSH_COND(p_oobd_own, NULL); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_lesc_oob_data_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_lesc_oob_data_t * *pp_oobd_own, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_GET); + SER_PULL_COND(pp_oobd_own, ble_gap_lesc_oob_data_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_lesc_oob_data_set_req_enc(uint16_t conn_handle, + ble_gap_lesc_oob_data_t const *p_oobd_own, + ble_gap_lesc_oob_data_t const *p_oobd_peer, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_SET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_oobd_own, ble_gap_lesc_oob_data_t_enc); + SER_PUSH_COND(p_oobd_peer, ble_gap_lesc_oob_data_t_enc); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_lesc_oob_data_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_LESC_OOB_DATA_SET); +} + + +uint32_t ble_gap_ppcp_get_req_enc(ble_gap_conn_params_t const * const p_conn_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_PPCP_GET); + SER_PUSH_COND(p_conn_params, NULL); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_ppcp_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_conn_params_t * const p_conn_params, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_PPCP_GET); + SER_PULL_COND(&p_conn_params, ble_gap_conn_params_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_ppcp_set_req_enc(ble_gap_conn_params_t const * const p_conn_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_PPCP_SET); + SER_PUSH_COND(p_conn_params, ble_gap_conn_params_t_enc); + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_ppcp_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_PPCP_SET); +} + +uint32_t ble_gap_rssi_get_req_enc(uint16_t conn_handle, + int8_t const * const p_rssi, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_RSSI_GET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_rssi, NULL); + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_rssi_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + int8_t * const p_rssi, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_RSSI_GET); + SER_PULL_uint8(p_rssi); + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_rssi_start_req_enc(uint16_t conn_handle, + uint8_t threshold_dbm, + uint8_t skip_count, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_RSSI_START); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint8(&threshold_dbm); + SER_PUSH_uint8(&skip_count); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_rssi_start_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_RSSI_START); +} + + +uint32_t ble_gap_rssi_stop_req_enc(uint16_t conn_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_RSSI_STOP); + SER_PUSH_uint16(&conn_handle); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_rssi_stop_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_RSSI_STOP); +} + + +uint32_t ble_gap_scan_start_req_enc(ble_gap_scan_params_t const * p_scan_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_SCAN_START); + SER_PUSH_COND(p_scan_params, ble_gap_scan_params_t_enc); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_scan_start_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_SCAN_START); +} + + +uint32_t ble_gap_scan_stop_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_SCAN_STOP); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_scan_stop_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_SCAN_STOP); +} + + +uint32_t ble_gap_sec_info_reply_req_enc(uint16_t conn_handle, + ble_gap_enc_info_t const * p_enc_info, + ble_gap_irk_t const * p_id_info, + ble_gap_sign_info_t const * p_sign_info, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_SEC_INFO_REPLY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_enc_info, ble_gap_enc_info_t_enc); + SER_PUSH_COND(p_id_info, ble_gap_irk_t_enc); + SER_PUSH_COND(p_sign_info, ble_gap_sign_info_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_sec_info_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_SEC_INFO_REPLY); +} + + +uint32_t ble_gap_sec_params_reply_req_enc(uint16_t conn_handle, + uint8_t sec_status, + ble_gap_sec_params_t const * const p_sec_params, + ble_gap_sec_keyset_t const * const p_sec_keyset, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_SEC_PARAMS_REPLY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint8(&sec_status); + SER_PUSH_COND(p_sec_params, ble_gap_sec_params_t_enc); + SER_PUSH_COND(p_sec_keyset, ble_gap_sec_keyset_t_enc); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_sec_params_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_sec_keyset_t const * const p_sec_keyset, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_SEC_PARAMS_REPLY); + SER_PULL_COND(&p_sec_keyset, ble_gap_sec_keyset_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_tx_power_set_req_enc(int8_t tx_power, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_TX_POWER_SET); + SER_PUSH_int8(&tx_power); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_tx_power_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_TX_POWER_SET); +} + +uint32_t ble_gap_addr_get_req_enc(ble_gap_addr_t const * const p_address, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADDR_GET); + SER_PUSH_COND(p_address, NULL); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_addr_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * const p_address, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_ADDR_GET); + SER_PULL_FIELD(p_address, ble_gap_addr_t_dec); + SER_RSP_DEC_END; +} + +uint32_t ble_gap_addr_set_req_enc(ble_gap_addr_t const * const p_addr, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADDR_SET); + SER_PUSH_COND(p_addr, ble_gap_addr_t_enc); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_addr_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ADDR_SET); +} + +uint32_t ble_gap_privacy_set_req_enc(ble_gap_privacy_params_t const * p_privacy_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_PRIVACY_SET); + SER_PUSH_COND(p_privacy_params, ble_gap_privacy_params_t_enc); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_privacy_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_PRIVACY_SET); +} + + +uint32_t ble_gap_privacy_get_req_enc(ble_gap_privacy_params_t const * const p_privacy_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_PRIVACY_GET); + SER_PUSH_COND(p_privacy_params, ble_gap_privacy_params_t_enc); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_privacy_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_privacy_params_t const * const p_privacy_params, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_PRIVACY_GET); + SER_PULL_COND((void **)&p_privacy_params, ble_gap_privacy_params_t_dec); + SER_RSP_DEC_END; +} + +uint32_t ble_gap_whitelist_set_req_enc(ble_gap_addr_t const * const * const pp_wl_addrs, + uint8_t const len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_WHITELIST_SET); + + uint8_t presence; + SER_PUSH_uint8(&len); + + if (pp_wl_addrs) + { + presence = SER_FIELD_PRESENT; + SER_PUSH_uint8(&presence); + + for (uint32_t i = 0; i < len; ++i) + { + SER_PUSH_COND(pp_wl_addrs[i], ble_gap_addr_t_enc); + } + } + else + { + presence = SER_FIELD_NOT_PRESENT; + SER_PUSH_uint8(&presence); + } + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_whitelist_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_WHITELIST_SET); +} + +uint32_t ble_gap_device_identities_set_req_enc(ble_gap_id_key_t const * const * const pp_id_keys, + ble_gap_irk_t const * const * const pp_local_irks, + uint8_t const len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_DEVICE_IDENTITIES_SET); + uint8_t presence; + SER_PUSH_uint8(&len); + + if (pp_id_keys) + { + presence = SER_FIELD_PRESENT; + SER_PUSH_uint8(&presence); + + for (uint32_t i = 0; i < len; ++i) + { + SER_PUSH_COND(pp_id_keys[i], ble_gap_id_key_t_enc); + } + } + else + { + presence = SER_FIELD_NOT_PRESENT; + SER_PUSH_uint8(&presence); + } + + if (pp_local_irks) + { + presence = SER_FIELD_PRESENT; + SER_PUSH_uint8(&presence); + + for (uint32_t i = 0; i < len; ++i) + { + SER_PUSH_COND(pp_local_irks[i], ble_gap_irk_t_enc); + } + } + else + { + presence = SER_FIELD_NOT_PRESENT; + SER_PUSH_uint8(&presence); + } + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_device_identities_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_DEVICE_IDENTITIES_SET); +} +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gap_data_length_update_req_enc(uint16_t conn_handle, + ble_gap_data_length_params_t const * p_dl_params, + ble_gap_data_length_limitation_t * p_dl_limitation, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_DATA_LENGTH_UPDATE); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_dl_params, ble_gap_data_length_params_t_enc); + SER_PUSH_COND(p_dl_limitation, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_data_length_update_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_data_length_limitation_t * p_dl_limitation, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_DATA_LENGTH_UPDATE); + SER_PULL_COND((void **)&p_dl_limitation, ble_gap_data_length_limitation_t_dec); + SER_RSP_DEC_END; +} +#endif +#if NRF_SD_BLE_API_VERSION >= 5 +uint32_t ble_gap_phy_request_req_enc(uint16_t conn_handle, + ble_gap_phys_t const * p_gap_phys, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_PHY_REQUEST); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_gap_phys, ble_gap_phys_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_phy_request_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_PHY_REQUEST); +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gap_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gap_app.h new file mode 100644 index 0000000000000000000000000000000000000000..ec7221bd8a0380c3ec807982fa1c4fede6014bdc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gap_app.h @@ -0,0 +1,1528 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GAP_APP_H__ +#define BLE_GAP_APP_H__ + +/**@file + * + * @defgroup ble_gap_app GAP Application command request encoders and command response decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief GAP Application command request encoders and command response decoders. + */ +#include "ble.h" +#include "ble_gap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Encodes @ref sd_ble_gap_adv_data_set command request. + * + * @sa @ref ble_gap_adv_data_set_rsp_dec for command response decoder. + * + * @param[in] p_data Raw data to be placed in advertisement packet. If NULL, no changes + * are made to the current advertisement packet data. + * @param[in] dlen Data length for p_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. + * Should be 0 if p_data is NULL, can be 0 if p_data is not NULL. + * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL, + * no changes are made to the current scan response packet data. + * @param[in] srdlen Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. + * Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_adv_data_set_req_enc(uint8_t const * const p_data, + uint8_t dlen, + uint8_t const * const p_sr_data, + uint8_t srdlen, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_adv_data_set command. + * + * @sa @ref ble_gap_adv_data_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_adv_data_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_adv_start command request. + * + * @sa @ref ble_gap_adv_start_rsp_dec for command response decoder. + * + * @param[in] p_adv_params Pointer to advertising parameters structure. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_adv_start_req_enc(ble_gap_adv_params_t const * const p_adv_params, +#if NRF_SD_BLE_API_VERSION >= 4 + uint8_t conn_cfg_tag, +#endif + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_adv_start command. + * + * @sa @ref ble_gap_adv_start_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_adv_start_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_tx_power_set command request. + * + * @sa @ref ble_gap_tx_power_set_rsp_dec for command response decoder. + * + * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm). + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_tx_power_set_req_enc(int8_t tx_power, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_tx_power_set command. + * + * @sa @ref ble_gap_tx_power_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_tx_power_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_appearance_get command request. + * + * @sa @ref ble_gap_appearance_get_rsp_dec for command response decoder. + * + * @param[in] p_appearance Appearance (16 bit), see @ref BLE_APPEARANCES. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @note \p p_appearance will not be updated by the command + * request encoder. Updated values are set by @ref ble_gap_appearance_get_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_appearance_get_req_enc(uint16_t const * const p_appearance, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_appearance_get command. + * + * @sa @ref ble_gap_appearance_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_appearance Appearance (16 bit), see @ref BLE_APPEARANCES. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_appearance_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_appearance, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_appearance_set command request. + * + * @sa @ref ble_gap_appearance_set_rsp_dec for command response decoder. + * + * @param[in] appearance Appearance (16 bit), see @ref BLE_APPEARANCES. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_appearance_set_req_enc(uint16_t appearance, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_appearance_set command. + * + * @sa @ref ble_gap_appearance_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_appearance_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_device_name_get command request. + * + * @sa @ref ble_gap_device_name_get_rsp_dec for command response decoder. + * + * @param[in] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated + * string will be placed. Set to NULL to obtain the complete device + * name length. + * @param[in] p_dev_name_len Length of the buffer pointed by p_dev_name. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @note \p p_dev_name and \p p_len will not be updated by the command + * request encoder. Updated values are set by @ref ble_gap_device_name_get_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_device_name_get_req_enc(uint8_t const * const p_dev_name, + uint16_t const * const p_dev_name_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_device_name_get command. + * + * @sa @ref ble_gap_device_name_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 + * non NULL-terminated string will be placed. + * @param[in,out] p_dev_name_len Length of the buffer pointed by p_dev_name, complete device name + * length on output. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_device_name_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_dev_name, + uint16_t * const p_dev_name_len, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_device_name_set command request. + * + * @sa @ref ble_gap_device_name_set_rsp_dec for command response decoder. + * + * @param[in] p_write_perm Write permissions for the Device Name characteristic, see + * @ref ble_gap_conn_sec_mode_t. + * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. + * @param[in] len Length of the UTF-8, non NULL-terminated string pointed + * to by p_dev_name in octets (must be smaller or equal + * than @ref BLE_GAP_DEVNAME_MAX_LEN). + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_device_name_set_req_enc(ble_gap_conn_sec_mode_t const * const p_write_perm, + uint8_t const * const p_dev_name, + uint16_t len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_device_name_set command. + * + * @sa @ref ble_gap_device_name_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_device_name_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_ppcp_set command request. + * + * @sa @ref ble_gap_ppcp_set_rsp_dec for command response decoder. + * + * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the + * desired parameters. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_ppcp_set_req_enc(ble_gap_conn_params_t const * const p_conn_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_ppcp_set command. + * + * @sa @ref ble_gap_ppcp_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_ppcp_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_conn_param_update command request. + * + * @sa @ref ble_gap_conn_param_update_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_conn_params Pointer to desired connection parameters. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_conn_param_update_req_enc(uint16_t conn_handle, + ble_gap_conn_params_t const * const p_conn_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_conn_param_update command. + * + * @sa @ref ble_gap_conn_param_update_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_conn_param_update_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_disconnect command request. + * + * @sa @ref ble_gap_disconnect_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_disconnect_req_enc(uint16_t conn_handle, + uint8_t hci_status_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_disconnect command. + * + * @sa @ref ble_gap_disconnect_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_disconnect_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + + +/**@brief Encodes @ref sd_ble_gap_rssi_stop command request. + * + * @sa @ref ble_gap_rssi_stop_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_rssi_stop_req_enc(uint16_t conn_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_rssi_stop command. + * + * @sa @ref ble_gap_rssi_stop_rsp_dec for command response decoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_rssi_stop_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + + + + +/**@brief Encodes @ref sd_ble_gap_ppcp_get command request. + * + * @sa @ref ble_gap_ppcp_get_rsp_dec for command response decoder. + * + * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the + * parameters will be stored. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @note \p p_conn_params will not be updated by the command request encoder. Updated values are + * set by @ref ble_gap_ppcp_get_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_ppcp_get_req_enc(ble_gap_conn_params_t const * const p_conn_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_ppcp_get command. + * + * @sa @ref ble_gap_ppcp_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters + * will be stored. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_ppcp_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_conn_params_t * const p_conn_params, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_auth_key_reply command request. + * + * @sa @ref ble_gap_auth_key_reply_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] key_type Key type which defines length of key data as defined for + * @ref sd_ble_gap_auth_key_reply . + * @param[in] p_key Pointer to a buffer which contains key + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect param provided (key_type). + */ +uint32_t ble_gap_auth_key_reply_req_enc(uint16_t conn_handle, + uint8_t key_type, + uint8_t const * const p_key, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_auth_key_reply command. + * + * @sa @ref ble_gap_auth_key_reply_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_auth_key_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_sec_info_reply command request. + * + * @sa @ref ble_gap_sec_info_reply_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information + * structure. + * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t id information + * structure. + * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information + * structure. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_sec_info_reply_req_enc(uint16_t conn_handle, + ble_gap_enc_info_t const * p_enc_info, + ble_gap_irk_t const * p_id_info, + ble_gap_sign_info_t const * p_sign_info, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_sec_info_reply command. + * + * @sa @ref ble_gap_sec_info_reply_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_sec_info_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_sec_params_reply command request. + * + * @sa @ref ble_gap_sec_params_reply_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. + * @param[in] p_sec_params Pointer to @ref ble_gap_sec_params_t security parameters + * structure. + * @param[in] p_sec_keyset Pointer to @ref ble_gap_sec_keyset_t security keys + * structure. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_sec_params_reply_req_enc(uint16_t conn_handle, + uint8_t sec_status, + ble_gap_sec_params_t const * const p_sec_params, + ble_gap_sec_keyset_t const * const p_sec_keyset, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_sec_params_reply command. + * + * @sa @ref ble_gap_sec_params_reply_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_sec_keyset Pointer to @ref ble_gap_sec_keyset_t security keys + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_sec_params_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_sec_keyset_t const * const p_sec_keyset, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_authenticate command request. + * + * @sa @ref ble_gap_authenticate_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters + * structure. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_authenticate_req_enc(uint16_t conn_handle, + ble_gap_sec_params_t const * const p_sec_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_authenticate command. + * + * @sa @ref ble_gap_authenticate_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_authenticate_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_adv_stop command request. + * + * @sa @ref ble_gap_adv_stop_rsp_dec for command response decoder. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_adv_stop_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_adv_stop command. + * + * @sa @ref ble_gap_adv_stop_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_adv_stop_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_conn_sec_get command request. + * + * @sa @ref ble_gap_conn_sec_get_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_conn_sec Pointer to \ref ble_gap_conn_sec_t which will be filled in + * response. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_conn_sec_get_req_enc(uint16_t conn_handle, + ble_gap_conn_sec_t const * const p_conn_sec, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_conn_sec_get command. + * + * @sa @ref ble_gap_conn_sec_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_conn_sec Pointer to pointer to \ref ble_gap_conn_sec_t which will be filled by + * the decoded data (if present). + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_conn_sec_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_conn_sec_t * * const pp_conn_sec, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_rssi_start command request. + * + * @sa @ref ble_gap_rssi_start_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] threshold_dbm Threshold in dBm. + * @param[in] skip_count Sample skip count. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_rssi_start_req_enc(uint16_t conn_handle, + uint8_t threshold_dbm, + uint8_t skip_count, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_rssi_start command. + * + * @sa @ref ble_gap_rssi_start_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_rssi_start_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_scan_stop command request. + * + * @sa @ref ble_gap_scan_stop_rsp_dec for command response decoder. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_scan_stop_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_scan_stop command. + * + * @sa @ref ble_gap_scan_stop_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_scan_stop_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_scan_start command request. + * + * @sa @ref ble_gap_scan_start_rsp_dec for command response decoder. + * + * @param[in] p_scan_params Pointer to scan params structure. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_scan_start_req_enc(ble_gap_scan_params_t const * p_scan_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_scan_start command. + * + * @sa @ref ble_gap_scan_start_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_scan_start_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_connect command request. + * + * @sa @ref ble_gap_connect_rsp_dec for command response decoder. + * + * @param[in] p_peer_addr Pointer to peer address. + * @param[in] p_scan_params Pointer to scan params structure. + * @param[in] p_conn_params Pointer to desired connection parameters. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_connect_req_enc(ble_gap_addr_t const * const p_peer_addr, + ble_gap_scan_params_t const * const p_scan_params, + ble_gap_conn_params_t const * const p_conn_params, +#if NRF_SD_BLE_API_VERSION >= 4 + uint8_t conn_cfg_tag, +#endif + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_connect command. + * + * @sa @ref ble_gap_connect_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_connect_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_connect_cancel command request. + * + * @sa @ref ble_gap_connect_cancel_rsp_dec for command response decoder. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_connect_cancel_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_connect_cancel command. + * + * @sa @ref ble_gap_connect_cancel_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_connect_cancel_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + + +/**@brief Encodes @ref sd_ble_gap_encrypt command request. + * + * @sa @ref ble_gap_encrypt_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_master_id Pointer to a master identification structure. + * @param[in] p_enc_info Pointer to desired connection parameters. + * @param[in] p_buf Pointer to a ble_gap_enc_info_t encryption information structure. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ + +uint32_t ble_gap_encrypt_req_enc(uint16_t conn_handle, + ble_gap_master_id_t const * const p_master_id, + ble_gap_enc_info_t const * const p_enc_info, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + + +/**@brief Decodes response to @ref sd_ble_gap_encrypt command. + * + * @sa @ref ble_gap_encrypt_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_encrypt_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_rssi_get command request. + * + * @sa @ref ble_gap_rssi_get_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_rssi Pointer to the RSSI value. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_rssi_get_req_enc(uint16_t conn_handle, + int8_t const * const p_rssi, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_rssi_get command. + * + * @sa @ref ble_gap_rssi_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_rssi Pointer to RSSI value. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_rssi_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + int8_t * const p_rssi, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_keypress_notify command request. + * + * @sa @ref ble_gap_keypress_notify_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] kp_not See @ref sd_ble_gap_keypress_notify. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_keypress_notify_req_enc(uint16_t conn_handle, + uint8_t kp_not, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_keypress_notify command. + * + * @sa @ref ble_gap_keypress_notify_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_keypress_notify_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_lesc_dhkey_reply command request. + * + * @sa @ref ble_gap_lesc_dhkey_reply_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dhkey See @ref sd_ble_gap_lesc_dhkey_reply. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_lesc_dhkey_reply_req_enc(uint16_t conn_handle, + ble_gap_lesc_dhkey_t const *p_dhkey, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_lesc_dhkey_reply command. + * + * @sa @ref ble_gap_lesc_dhkey_reply_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_lesc_dhkey_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_lesc_oob_data_set command request. + * + * @sa @ref ble_gap_lesc_oob_data_set_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_oobd_own See @ref sd_ble_gap_lesc_oob_data_set. + * @param[in] p_oobd_peer See @ref sd_ble_gap_lesc_oob_data_set. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_lesc_oob_data_set_req_enc(uint16_t conn_handle, + ble_gap_lesc_oob_data_t const *p_oobd_own, + ble_gap_lesc_oob_data_t const *p_oobd_peer, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_lesc_oob_data_set command. + * + * @sa @ref ble_gap_lesc_oob_data_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_lesc_oob_data_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_lesc_oob_data_get command request. + * + * @sa @ref ble_gap_lesc_oob_data_get_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_pk_own See @ref sd_ble_gap_lesc_oob_data_get. + * @param[in] p_oobd_own See @ref sd_ble_gap_lesc_oob_data_get. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_lesc_oob_data_get_req_enc(uint16_t conn_handle, + ble_gap_lesc_p256_pk_t const *p_pk_own, + ble_gap_lesc_oob_data_t *p_oobd_own, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_lesc_oob_data_get command. + * + * @sa @ref ble_gap_lesc_oob_data_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_oobd_own Pointer to pointer to location where OOB data is decoded. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_lesc_oob_data_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_lesc_oob_data_t * *pp_oobd_own, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_addr_get command request. + * + * @sa @ref ble_gap_addr_get_rsp_dec for command response decoder. + * + * @param[in] p_address Pointer to address. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @note \p p_address will not be updated by the command + * request encoder. Updated values are set by @ref ble_gap_addr_get_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_addr_get_req_enc(ble_gap_addr_t const * const p_address, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_addr_get command. + * + * @sa @ref ble_gap_addr_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_address Pointer to address. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_addr_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * const p_address, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_addr_set command request. + * + * @sa @ref ble_gap_addr_set_rsp_dec for command response decoder. + * + * @param[in] p_addr Pointer to address structure. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_addr_set_req_enc(ble_gap_addr_t const * const p_addr, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_addr_set command. + * + * @sa @ref ble_gap_addr_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_addr_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_privacy_set command request. + * + * @sa @ref ble_gap_privacy_set_rsp_dec for command response decoder. + * + * @param[in] p_privacy_params Pointer to privacy settings structure. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_privacy_set_req_enc(ble_gap_privacy_params_t const * p_privacy_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_privacy_set command. + * + * @sa @ref ble_gap_privacy_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_privacy_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_privacy_get command request. + * + * @sa @ref ble_gap_privacy_get_rsp_dec for command response decoder. + * + * @param[in] p_privacy_params Pointer to privacy settings structure. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_privacy_get_req_enc(ble_gap_privacy_params_t const * const p_privacy_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_privacy_get command. + * + * @sa @ref ble_gap_privacy_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_privacy_params Pointer to privacy settings structure. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_privacy_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_privacy_params_t const * const p_privacy_params, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_whitelist_set command request. + * + * @sa @ref ble_gap_whitelist_set_rsp_dec for command response decoder. + * + * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses. + * @param[out] len Pointer to a length of the whitelist. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_whitelist_set_req_enc(ble_gap_addr_t const * const * const pp_wl_addrs, + uint8_t const len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_whitelist_set command. + * + * @sa @ref ble_gap_whitelist_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_whitelist_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_device_identities_set command request. + * + * @sa @ref ble_gap_device_identities_set_rsp_dec for command response decoder. + * + * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs. + * @param[in] pp_local_irks Pointer to an array of local IRKs. + * @param[out] len Pointer to a length of the device identity list. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_device_identities_set_req_enc(ble_gap_id_key_t const * const * const pp_id_keys, + ble_gap_irk_t const * const * const pp_local_irks, + uint8_t const len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +/** + * @brief Decodes response to @ref sd_ble_gap_device_identities_set command. + * + * @sa @ref ble_gap_device_identities_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_device_identities_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +#if NRF_SD_BLE_API_VERSION >= 4 +/** + * @brief Encodes @ref sd_ble_gap_data_length_update command request. + * + * @sa @ref ble_gap_data_length_update_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dl_params Pointer to a data length params structure. + * @param[out] p_dl_limitation Pointer to a data length limitation structure. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_data_length_update_req_enc(uint16_t conn_handle, + ble_gap_data_length_params_t const * p_dl_params, + ble_gap_data_length_limitation_t * p_dl_limitation, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +/** + * @brief Decodes response to @ref sd_ble_gap_data_length_update command. + * + * @sa @ref ble_gap_data_length_update_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_dl_limitation Pointer to a data length limitation structure. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_data_length_update_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_data_length_limitation_t * p_dl_limitation, + uint32_t * const p_result_code); +#endif + +#if NRF_SD_BLE_API_VERSION >= 5 +/**@brief Encodes @ref sd_ble_gap_phy_request command request. + * + * @sa @ref ble_gap_phy_request_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_gap_phys Pointer to a @ref ble_gap_phys_t + * structure. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_phy_request_req_enc(uint16_t conn_handle, + ble_gap_phys_t const * p_gap_phys, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_phy_request command. + * + * @sa @ref ble_gap_phy_request_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_phy_request_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); +#endif +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.c new file mode 100644 index 0000000000000000000000000000000000000000..b2c5cec380123408f425e60b04fd9c97fed70559 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.c @@ -0,0 +1,354 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gap_evt_app.h" +#include "ble_serialization.h" +#include "app_util.h" +#include "app_ble_gap_sec_keys.h" +#include "ble_gap_struct_serialization.h" +#include "cond_field_serialization.h" +#include + +extern ser_ble_gap_app_keyset_t m_app_keys_table[]; + + +uint32_t ble_gap_evt_adv_report_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_ADV_REPORT, gap, adv_report); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.adv_report, ble_gap_evt_adv_report_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_auth_key_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_AUTH_KEY_REQUEST, gap, auth_key_request); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.gap_evt.params.auth_key_request.key_type); + + SER_EVT_DEC_END; +} + + +extern ser_ble_gap_app_keyset_t m_app_keys_table[]; + +uint32_t ble_gap_evt_auth_status_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_AUTH_STATUS, gap, auth_status); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.auth_status, ble_gap_evt_auth_status_t_dec); + + // keyset is an extension of standard event data - used to synchronize keys at application + uint32_t conn_index; + err_code = app_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); + if (err_code == NRF_SUCCESS) + { + SER_PULL_FIELD(&(m_app_keys_table[conn_index].keyset), ble_gap_sec_keyset_t_dec); + + err_code = app_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + + SER_EVT_DEC_END; +} + + +uint32_t ble_gap_evt_conn_param_update_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE, gap, conn_param_update); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.conn_param_update, ble_gap_evt_conn_param_update_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gap_evt_conn_param_update_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, gap, conn_param_update_request); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.conn_param_update_request, + ble_gap_evt_conn_param_update_request_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gap_evt_conn_sec_update_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, gap, conn_sec_update); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.conn_sec_update, ble_gap_evt_conn_sec_update_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_connected_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_CONNECTED, gap, connected); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.connected, ble_gap_evt_connected_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gap_evt_disconnected_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_DISCONNECTED, gap, disconnected); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.disconnected, ble_gap_evt_disconnected_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_key_pressed_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_KEY_PRESSED, gap, key_pressed); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.gap_evt.params.key_pressed.kp_not); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gap_evt_lesc_dhkey_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_LESC_DHKEY_REQUEST, gap, lesc_dhkey_request); + + uint8_t ser_data; + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + + // keyset is an extension of standard event data - used to synchronize keys at application + uint32_t conn_index; + err_code = app_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + p_event->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer = m_app_keys_table[conn_index].keyset.keys_peer.p_pk; + SER_PULL_COND(&p_event->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer, ble_gap_lesc_p256_pk_t_dec); + + SER_PULL_uint8(&ser_data); + p_event->evt.gap_evt.params.lesc_dhkey_request.oobd_req = ser_data & 0x01; + + SER_EVT_DEC_END; +} + + +#define PASSKEY_LEN sizeof (p_event->evt.gap_evt.params.passkey_display.passkey) + + +uint32_t ble_gap_evt_passkey_display_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_PASSKEY_DISPLAY, gap, passkey_display); + + uint8_t ser_data; + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_uint8array(p_event->evt.gap_evt.params.passkey_display.passkey, BLE_GAP_PASSKEY_LEN); + SER_PULL_uint8(&ser_data); + p_event->evt.gap_evt.params.passkey_display.match_request = (ser_data & 0x01); + + SER_EVT_DEC_END; +} + + + +uint32_t ble_gap_evt_rssi_changed_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_RSSI_CHANGED, gap, rssi_changed); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_int8(&p_event->evt.gap_evt.params.rssi_changed.rssi); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gap_evt_scan_req_report_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_SCAN_REQ_REPORT, gap, scan_req_report); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.scan_req_report.peer_addr, ble_gap_addr_t_dec); + SER_PULL_int8(&p_event->evt.gap_evt.params.scan_req_report.rssi); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_sec_info_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_SEC_INFO_REQUEST, gap, sec_info_request); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.sec_info_request, ble_gap_evt_sec_info_request_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_sec_params_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_SEC_PARAMS_REQUEST, gap, sec_params_request); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.sec_params_request, ble_gap_evt_sec_params_request_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_sec_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_SEC_REQUEST, gap, sec_request); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.sec_request, ble_gap_evt_sec_request_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_timeout_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_TIMEOUT, gap, timeout); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.gap_evt.params.timeout.src); + + SER_EVT_DEC_END; +} + +#if NRF_SD_BLE_API_VERSION >= 5 +uint32_t ble_gap_evt_phy_update_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_PHY_UPDATE, gap, phy_update); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.gap_evt.params.phy_update.status); + SER_PULL_uint8(&p_event->evt.gap_evt.params.phy_update.tx_phy); + SER_PULL_uint8(&p_event->evt.gap_evt.params.phy_update.rx_phy); + + SER_EVT_DEC_END; +} +#endif +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gap_evt_data_length_update_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST, gap, timeout); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.data_length_update_request.peer_params, ble_gap_data_length_params_t_dec); + + SER_EVT_DEC_END; +} +uint32_t ble_gap_evt_data_length_update_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_DATA_LENGTH_UPDATE, gap, timeout); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.data_length_update.effective_params, ble_gap_data_length_params_t_dec); + + SER_EVT_DEC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.h new file mode 100644 index 0000000000000000000000000000000000000000..e958fdcdb33ac5d5586f9c98fbca6c7654aed03e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.h @@ -0,0 +1,523 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GAP_EVT_APP_H__ +#define BLE_GAP_EVT_APP_H__ + +/**@file + * + * @defgroup ble_gap_evt_app GAP Application event decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief GAP Application event decoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Decodes ble_gap_evt_auth_key_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_auth_key_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_auth_status event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_auth_status_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_conn_param_update event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_conn_param_update_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_conn_sec_update event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_conn_sec_update_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_connected event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_connected_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_disconnected event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_disconnected_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_passkey_display event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_passkey_display_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_rssi_changed event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_rssi_changed_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_sec_info_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_sec_info_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_sec_params_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_sec_params_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_timeout event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_timeout_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_sec_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_sec_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_conn_param_update_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_conn_param_update_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); +/** + * @brief Decodes ble_gap_evt_adv_report event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_adv_report_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_scan_req_report event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_scan_req_report_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_key_pressed event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_key_pressed_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); +/** + * @brief Decodes ble_gap_evt_lesc_dhkey_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_lesc_dhkey_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +#if NRF_SD_BLE_API_VERSION >= 5 +/** + * @brief Decodes ble_gap_evt_phy_update event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_phy_update_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); +#endif + +#if NRF_SD_BLE_API_VERSION >= 4 +/** + * @brief Decodes ble_gap_evt_data_length_update_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_data_length_update_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); +/** + * @brief Decodes ble_gap_evt_data_length_update event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_data_length_update_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); +#endif +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gattc_app.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gattc_app.c new file mode 100644 index 0000000000000000000000000000000000000000..96fe8db29bbe8f83bbc3bb3322ef26c1560ef3fe --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gattc_app.c @@ -0,0 +1,286 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gattc_app.h" +#include +#include "ble_serialization.h" +#include "ble_gattc_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include "ble_struct_serialization.h" +#include "ble_types.h" + +uint32_t ble_gattc_attr_info_discover_req_enc(uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_ATTR_INFO_DISCOVER); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_attr_info_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_ATTR_INFO_DISCOVER); +} + +uint32_t ble_gattc_char_value_by_uuid_read_req_enc(uint16_t conn_handle, + ble_uuid_t const * const p_uuid, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_uuid, ble_uuid_t_enc); + SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc); + + SER_REQ_ENC_END; +} + +uint32_t ble_gattc_char_value_by_uuid_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ); +} + +uint32_t ble_gattc_char_values_read_req_enc(uint16_t conn_handle, + uint16_t const * const p_handles, + uint16_t handle_count, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_CHAR_VALUES_READ); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_len16data16(p_handles, handle_count); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_char_values_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_CHAR_VALUES_READ); +} + +uint32_t ble_gattc_characteristics_discover_req_enc( + uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_characteristics_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER); +} + +uint32_t ble_gattc_descriptors_discover_req_enc( + uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_DESCRIPTORS_DISCOVER); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_descriptors_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_DESCRIPTORS_DISCOVER); +} + +uint32_t ble_gattc_hv_confirm_req_enc(uint16_t conn_handle, + uint16_t handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_HV_CONFIRM); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&handle); + + SER_REQ_ENC_END; +} + +uint32_t ble_gattc_hv_confirm_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_HV_CONFIRM); +} + +uint32_t ble_gattc_primary_services_discover_req_enc(uint16_t conn_handle, + uint16_t start_handle, + ble_uuid_t const * const p_srvc_uuid, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&start_handle); + SER_PUSH_COND(p_srvc_uuid, ble_uuid_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_primary_services_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER); +} + +uint32_t ble_gattc_read_req_enc(uint16_t conn_handle, + uint16_t handle, + uint16_t offset, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_READ); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&handle); + SER_PUSH_uint16(&offset); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_READ); +} + +uint32_t ble_gattc_relationships_discover_req_enc( + uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_relationships_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER); +} + +uint32_t ble_gattc_write_req_enc(uint16_t conn_handle, + ble_gattc_write_params_t const * const p_write_params, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_WRITE); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_write_params, ble_gattc_write_params_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_write_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_WRITE); +} + +uint32_t ble_gattc_exchange_mtu_request_req_enc(uint16_t conn_handle, + uint16_t client_rx_mtu, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&client_rx_mtu); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_exchange_mtu_request_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gattc_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gattc_app.h new file mode 100644 index 0000000000000000000000000000000000000000..6d554f792d648018b8f00dd35ec4810378c31aa3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gattc_app.h @@ -0,0 +1,491 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GATTC_APP_H__ +#define BLE_GATTC_APP_H__ + +/**@file + * + * @defgroup ble_gattc_app GATTC Application command request encoders and command response decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief GATTC Application command request encoders and command response decoders. + */ +#include "ble_gattc.h" +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Encodes @ref sd_ble_gattc_primary_services_discover command request. + * + * @sa @ref ble_gattc_primary_services_discover_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] start_handle Handle to start searching from. + * @param[in] p_srvc_uuid Pointer to a @ref ble_uuid_t which indicates the service UUID to + * be found. If it is NULL, all primary services will be returned. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_primary_services_discover_req_enc(uint16_t conn_handle, + uint16_t start_handle, + ble_uuid_t const * const p_srvc_uuid, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gattc_primary_services_discover command. + * + * @sa @ref ble_gattc_primary_services_discover_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_primary_services_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gattc_descriptors_discover command request. + * + * @sa @ref ble_gattc_descriptors_discover_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform + * this procedure on. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_descriptors_discover_req_enc( + uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len); + + +/**@brief Decodes response to @ref sd_ble_gattc_descriptors_discover command. + * + * @sa @ref ble_gattc_primary_services_discover_rsp_dec for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_descriptors_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gattc_relationships_discover command request. + * + * @sa @ref ble_gattc_relationships_discover_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform + * this procedure on. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_relationships_discover_req_enc( + uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gattc_relationships_discover command. + * + * @sa @ref ble_gattc_relationships_discover_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_relationships_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gattc_characteristics_discover command request. + * + * @sa @ref ble_gattc_characteristics_discover_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform + * this procedure on. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_characteristics_discover_req_enc + (uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gattc_characteristics_discover command. + * + * @sa @ref ble_gattc_primary_services_discover_rsp_dec for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_characteristics_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gattc_read command request. + * + * @sa @ref ble_gattc_read_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] handle The handle of the attribute to be read. + * @param[in] offset Offset into the attribute value to be read. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_read_req_enc(uint16_t conn_handle, + uint16_t handle, + uint16_t offset, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gattc_read command. + * + * @sa @ref ble_gattc_read_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gattc_char_values_read command request. + * + * @sa @ref ble_gattc_char_values_read_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. + * @param[in] handle_count The number of handles in p_handles. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_char_values_read_req_enc(uint16_t conn_handle, + uint16_t const * const p_handles, + uint16_t handle_count, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gattc_char_values_read command. + * + * @sa @ref ble_gattc_char_values_read_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_char_values_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gattc_write command request. + * + * @sa @ref ble_gattc_write_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_write_params Pointer to \ref sd_ble_gattc_write params. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_write_req_enc(uint16_t conn_handle, + ble_gattc_write_params_t const * const p_write_params, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gattc_write command. + * + * @sa @ref ble_gattc_write_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_write_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gattc_hv_confirm command request. + * + * @sa @ref ble_gattc_hv_confirm_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] handle Handle of the attribute in the indication. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_hv_confirm_req_enc(uint16_t conn_handle, + uint16_t handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gattc_hv_confirm command. + * + * @sa @ref ble_gattc_hv_confirm_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Pointer to command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_hv_confirm_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gattc_char_value_by_uuid_read command request. + * + * @sa @ref ble_gattc_char_value_by_uuid_read_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_uuid Pointer to a characteristic value UUID to read. + * @param[in] p_handle_range Pointer to the range of handles to perform this procedure on. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_char_value_by_uuid_read_req_enc + (uint16_t conn_handle, + ble_uuid_t const * const p_uuid, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gattc_char_value_by_uuid_read command. + * + * @sa @ref ble_gattc_char_value_by_uuid_read_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Pointer to command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_char_value_by_uuid_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gattc_attr_info_discover command request. + * + * @sa @ref ble_gattc_attr_info_discover_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_handle_range Pointer to the range of handles + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_attr_info_discover_req_enc(uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gattc_attr_info_discover command. + * + * @sa @ref ble_gattc_attr_info_discover_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Pointer to command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_attr_info_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gattc_exchange_mtu_request command request. + * + * @sa @ref ble_gattc_exchange_mtu_request_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] client_rx_mtu Client MTU Size. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_exchange_mtu_request_req_enc(uint16_t conn_handle, + uint16_t client_rx_mtu, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gattc_exchange_mtu_request command. + * + * @sa @ref ble_gattc_exchange_mtu_request_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Pointer to command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_exchange_mtu_request_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.c new file mode 100644 index 0000000000000000000000000000000000000000..d54baf81a7738ed842ead469021983324f90c3b1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.c @@ -0,0 +1,262 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gattc_evt_app.h" +#include +#include "ble_serialization.h" +#include "ble_gattc_struct_serialization.h" +#include "app_util.h" + +uint32_t ble_gattc_evt_attr_info_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, gattc, attr_info_disc_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.attr_info_disc_rsp, + ble_gattc_evt_attr_info_disc_rsp_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gattc_evt_char_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_CHAR_DISC_RSP, gattc, char_disc_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.char_disc_rsp, + ble_gattc_evt_char_disc_rsp_t_dec); + + SER_EVT_DEC_END; +} + + + +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, gattc, char_val_by_uuid_read_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.char_val_by_uuid_read_rsp, + ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gattc_evt_char_vals_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_CHAR_VALS_READ_RSP, gattc, char_vals_read_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.char_vals_read_rsp, + ble_gattc_evt_char_vals_read_rsp_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gattc_evt_desc_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_DESC_DISC_RSP, gattc, desc_disc_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.desc_disc_rsp, + ble_gattc_evt_desc_disc_rsp_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gattc_evt_hvx_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_HVX, gattc, hvx); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.hvx, + ble_gattc_evt_hvx_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP, gattc, prim_srvc_disc_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.prim_srvc_disc_rsp, + ble_gattc_evt_prim_srvc_disc_rsp_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gattc_evt_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_READ_RSP, gattc, read_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.read_rsp, + ble_gattc_evt_read_rsp_t_dec); + + SER_EVT_DEC_END; +} + + +#define BLE_GATTC_EVT_REL_DISC_RSP_COUNT_POSITION 6 + + +uint32_t ble_gattc_evt_rel_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_READ_RSP, gattc, rel_disc_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.rel_disc_rsp, + ble_gattc_evt_rel_disc_rsp_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gattc_evt_timeout_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_TIMEOUT, gattc, timeout); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD(&p_event->evt.gattc_evt.params.timeout, + ble_gattc_evt_timeout_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gattc_evt_write_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_WRITE_RSP, gattc, write_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.write_rsp, + ble_gattc_evt_write_rsp_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gattc_evt_exchange_mtu_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_EXCHANGE_MTU_RSP, gattc, exchange_mtu_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD(&p_event->evt.gattc_evt.params.exchange_mtu_rsp, + ble_gattc_evt_exchange_mtu_rsp_t_dec); + + SER_EVT_DEC_END; +} + +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gattc_evt_write_cmd_tx_complete_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, gattc, write_cmd_tx_complete); + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_uint8(&p_event->evt.gattc_evt.params.write_cmd_tx_complete.count); + + SER_EVT_DEC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.h new file mode 100644 index 0000000000000000000000000000000000000000..65aa0e669ac73087f12cc8ae3121da0c91e6e8af --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.h @@ -0,0 +1,364 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GATTC_EVT_APP_H__ +#define BLE_GATTC_EVT_APP_H__ + +/**@file + * + * @defgroup ble_gattc_evt_app GATTC Application event decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief GATTC Application event decoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Decodes ble_gattc_evt_char_disc_rsp event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_char_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gattc_evt_char_val_by_uuid_read_rsp event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gattc_evt_char_vals_read_rsp event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_char_vals_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gattc_evt_desc_disc_rsp event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_desc_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gattc_evt_hvx event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_hvx_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gattc_evt_prim_srvc_disc_rsp event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gattc_evt_read_rsp event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gattc_evt_rel_disc_rsp_dec event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_rel_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gattc_evt_timeout event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_timeout_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gattc_evt_write_rsp event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_write_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gattc_evt_attr_info_disc_rsp event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_attr_info_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gattc_evt_exchange_mtu_rsp event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_exchange_mtu_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +#if NRF_SD_BLE_API_VERSION >= 4 + +/** + * @brief Decodes ble_gattc_evt_write_cmd_tx_complete event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_write_cmd_tx_complete_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); +#endif +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gatts_app.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gatts_app.c new file mode 100644 index 0000000000000000000000000000000000000000..480d88f9e9e0fba02160f39b6732a7b37d67b1b6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gatts_app.c @@ -0,0 +1,439 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gatts_app.h" +#include +#include +#include "ble_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "ble_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + + +uint32_t ble_gatts_attr_get_req_enc(uint16_t handle, + ble_uuid_t * p_uuid, + ble_gatts_attr_md_t * p_md, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_ATTR_GET); + + SER_PUSH_uint16(&handle); + SER_PUSH_COND(p_uuid, NULL); + SER_PUSH_COND(p_md, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_attr_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_uuid_t ** pp_uuid, + ble_gatts_attr_md_t ** pp_md, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_ATTR_GET); + SER_PULL_COND(pp_uuid, ble_uuid_t_dec); + SER_PULL_COND(pp_md, ble_gatts_attr_md_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_characteristic_add_req_enc( + uint16_t service_handle, + ble_gatts_char_md_t const * const p_char_md, + ble_gatts_attr_t const * const p_attr_char_value, + ble_gatts_char_handles_t const * const p_handles, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_CHARACTERISTIC_ADD); + + SER_PUSH_uint16(&service_handle); + SER_PUSH_COND(p_char_md, ble_gatts_char_md_t_enc); + SER_PUSH_COND(p_attr_char_value, ble_gatts_attr_t_enc); + SER_PUSH_COND(p_handles, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_characteristic_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * * const pp_handles, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_CHARACTERISTIC_ADD); + + SER_PULL_COND(pp_handles, ble_gatts_char_handles_t_dec); + + SER_RSP_DEC_END; +} + + + +uint32_t ble_gatts_descriptor_add_req_enc(uint16_t char_handle, + ble_gatts_attr_t const * const p_attr, + uint16_t * const p_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_DESCRIPTOR_ADD); + + SER_PUSH_uint16(&char_handle); + SER_PUSH_COND(p_attr, ble_gatts_attr_t_enc); + SER_PUSH_COND(p_handle, NULL); + + SER_REQ_ENC_END; +} + +uint32_t ble_gatts_descriptor_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_handle, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_DESCRIPTOR_ADD); + + SER_PULL_COND(&p_handle, uint16_t_dec); + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_hvx_req_enc(uint16_t conn_handle, + ble_gatts_hvx_params_t const * const p_hvx_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_HVX); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_hvx_params, ble_gatts_hvx_params_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_hvx_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code, + uint16_t * * const pp_bytes_written) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_HVX); + + SER_PULL_COND(pp_bytes_written, uint16_t_dec); + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_include_add_req_enc(uint16_t service_handle, + uint16_t inc_srvc_handle, + uint16_t * const p_include_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_INCLUDE_ADD); + + SER_PUSH_uint16(&service_handle); + SER_PUSH_uint16(&inc_srvc_handle); + SER_PUSH_COND(p_include_handle, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_include_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_include_handle, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_INCLUDE_ADD); + + SER_PULL_COND(&p_include_handle, uint16_t_dec); + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_initial_user_handle_get_req_enc(uint16_t * p_handle, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET); + + SER_PUSH_COND(p_handle, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_initial_user_handle_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t ** pp_handle, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET); + + SER_PULL_COND(pp_handle, uint16_t_dec); + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_rw_authorize_reply_req_enc(uint16_t conn_handle, + ble_gatts_rw_authorize_reply_params_t const * const p_reply_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_RW_AUTHORIZE_REPLY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_reply_params, ble_gatts_rw_authorize_reply_params_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_rw_authorize_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTS_RW_AUTHORIZE_REPLY); +} + + +uint32_t ble_gatts_service_add_req_enc(uint8_t type, + ble_uuid_t const * const p_uuid, + uint16_t const * const p_conn_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_SERVICE_ADD); + + SER_PUSH_uint8(&type); + SER_PUSH_COND(p_uuid, ble_uuid_t_enc); + SER_PUSH_COND(p_conn_handle, NULL); + + SER_REQ_ENC_END; +} + +uint32_t ble_gatts_service_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_SERVICE_ADD); + + SER_PULL_COND(&p_conn_handle, uint16_t_dec); + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_service_changed_req_enc(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_SERVICE_CHANGED); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&start_handle); + SER_PUSH_uint16(&end_handle); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_service_changed_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTS_SERVICE_CHANGED); +} + + +uint32_t ble_gatts_sys_attr_get_req_enc(uint16_t conn_handle, + uint8_t const * const p_sys_attr_data, + uint16_t const * const p_sys_attr_data_len, + uint32_t flags, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_SYS_ATTR_GET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_sys_attr_data_len, uint16_t_enc); + SER_PUSH_COND(p_sys_attr_data, NULL); + SER_PUSH_uint32(&flags); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_sys_attr_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * const pp_sys_attr_data, + uint16_t * * const pp_sys_attr_data_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_SYS_ATTR_GET); + + SER_PULL_COND(pp_sys_attr_data_len, uint16_t_dec); + if (*pp_sys_attr_data_len) + { + SER_PULL_buf(pp_sys_attr_data, **pp_sys_attr_data_len, **pp_sys_attr_data_len); + } + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_sys_attr_set_req_enc(uint16_t conn_handle, + uint8_t const * const p_sys_attr_data, + uint16_t sys_attr_data_len, + uint32_t flags, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_SYS_ATTR_SET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_len16data(p_sys_attr_data, sys_attr_data_len); + SER_PUSH_uint32(&flags); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_sys_attr_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTS_SYS_ATTR_SET, p_result_code); +} + + +uint32_t ble_gatts_value_get_req_enc(uint16_t conn_handle, + uint16_t handle, + ble_gatts_value_t const * const p_value, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_VALUE_GET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&handle); + + //Special case: skip the data. + SER_PUSH_COND(p_value, NULL); + if (p_value) + { + SER_PUSH_uint16(&p_value->offset); + SER_PUSH_uint16(&p_value->len); + SER_PUSH_COND(p_value->p_value, NULL); + } + + SER_REQ_ENC_END; +} + +uint32_t ble_gatts_value_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gatts_value_t * const p_value, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_VALUE_GET); + + SER_PULL_COND(&p_value, ble_gatts_value_t_dec); + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_value_set_req_enc(uint16_t conn_handle, + uint16_t handle, + ble_gatts_value_t * p_value, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_VALUE_SET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&handle); + SER_PUSH_COND(p_value, ble_gatts_value_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_value_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gatts_value_t * const p_value, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_VALUE_SET); + + SER_PULL_COND(&p_value, ble_gatts_value_t_dec); + + SER_RSP_DEC_END; +} + +uint32_t ble_gatts_exchange_mtu_reply_req_enc(uint16_t conn_handle, + uint16_t server_rx_mtu, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_EXCHANGE_MTU_REPLY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&server_rx_mtu); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_exchange_mtu_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTS_EXCHANGE_MTU_REPLY); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gatts_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gatts_app.h new file mode 100644 index 0000000000000000000000000000000000000000..567b2fc681a70e933bac411c4f1b0304da37ab7a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gatts_app.h @@ -0,0 +1,677 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GATTS_APP_H__ +#define BLE_GATTS_APP_H__ + +/**@file + * + * @defgroup ble_gatts_app GATTS Application command request encoders and command response decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief GATTS Application command request encoders and command response decoders. + */ +#include "ble_gatts.h" +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Encodes @ref sd_ble_gatts_value_get command request. + * + * @sa @ref ble_gatts_value_get_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] handle Attribute handle. + * @param[in] p_value Pointer to attribute value information. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @note \p p_data_len and \p p_data will not be updated by the command + * request encoder. Updated values are set by @ref ble_gatts_value_get_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_value_get_req_enc(uint16_t conn_handle, + uint16_t handle, + ble_gatts_value_t const * const p_value, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_value_get command. + * + * @sa @ref ble_gatts_value_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_value Pointer to structure where the attribute value will be stored. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Length of \p p_value is too small to hold decoded + * value from response. + */ +uint32_t ble_gatts_value_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gatts_value_t * const p_value, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gatts_hvx command request. + * + * @sa @ref ble_gatts_hvx_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_hvx_params Pointer to an HVx parameters structure to be encoded. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @note \p p_hvx_params will not be updated by the command + * request encoder. Updated values are set by @ref ble_gatts_hvx_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_hvx_req_enc(uint16_t conn_handle, + ble_gatts_hvx_params_t const * const p_hvx_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_hvx command. + * + * @sa @ref ble_gatts_hvx_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * @param[out] pp_bytes_written Pointer to pointer to location where number of bytes is written. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_hvx_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code, + uint16_t * * const pp_bytes_written); + +/**@brief Encodes @ref sd_ble_gatts_characteristic_add command request. + * + * @sa @ref ble_gatts_characteristic_add_rsp_dec for command response decoder. + * + * @param[in] service_handle Handle of the service where the characteristic is to be placed. + * If @ref BLE_GATT_HANDLE_INVALID is used, it will be placed + * sequentially. + * @param[in] p_char_md Pointer to a @ref ble_gatts_char_md_t structure, characteristic + * metadata. + * @param[in] p_attr_char_value Pointer to a @ref ble_gatts_attr_t structure, corresponding to + * the characteristic value. + * @param[in] p_handles Pointer to a @ref ble_gatts_char_handles_t structure, where the + * assigned handles will be stored. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @note \p p_handles will not be updated by the command + * request encoder. Updated values are set by @ref ble_gatts_characteristic_add_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_characteristic_add_req_enc + (uint16_t service_handle, + ble_gatts_char_md_t const * const p_char_md, + ble_gatts_attr_t const * const p_attr_char_value, + ble_gatts_char_handles_t const * const p_handles, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_characteristic_add command. + * + * @sa @ref ble_gatts_characteristic_add_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_handles Pointer to pointer to location where handles should be decoded. + * @param[out] p_result_code Pointer to command result code decode location. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_characteristic_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * * const pp_handles, + uint32_t * const p_result_code); + + +/**@brief Encodes @ref sd_ble_gatts_service_add command request. + * + * @sa @ref ble_gatts_service_add_rsp_dec for command response decoder. + * + * @param[in] type Toggles between primary and secondary services, + * see @ref BLE_GATTS_SRVC_TYPES. + * @param[in] p_uuid Pointer to service UUID. + * @param[in] p_conn_handle Pointer to a 16-bit word where the assigned handle will be stored. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @note \p p_conn_handle will not be updated by the command + * request encoder. Updated values are set by @ref ble_gatts_service_add_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_service_add_req_enc(uint8_t type, + ble_uuid_t const * const p_uuid, + uint16_t const * const p_conn_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_service_add command. + * + * @sa @ref ble_gatts_service_add_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Connection handle. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_service_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gatts_sys_attr_set command request. + * + * @sa @ref ble_gatts_sys_attr_set_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_sys_attr_data Pointer to a buffer (at least \p sys_attr_data_len bytes long) + * containing the attribute value to write. + * @param[in] sys_attr_data_len Length (in bytes) of \p p_sys_attr_data. + * @param[in] flags Optional additional flags. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_sys_attr_set_req_enc(uint16_t conn_handle, + uint8_t const * const p_sys_attr_data, + uint16_t sys_attr_data_len, + uint32_t flags, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_sys_attr_set command. + * + * @sa @ref ble_gatts_sys_attr_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_sys_attr_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gatts_value_set command request. + * + * @sa @ref ble_gatts_value_set_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] handle Attribute handle. + * @param[in] p_value Pointer to attribute value information. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_value_set_req_enc(uint16_t conn_handle, + uint16_t handle, + ble_gatts_value_t * p_value, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_value_set command. + * + * @sa @ref ble_gatts_value_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_value Pointer to attribute value information. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_value_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gatts_value_t * const p_value, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gatts_sys_attr_get command request. + * + * @sa @ref ble_gatts_sys_attr_get_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_sys_attr_data Pointer to buffer where updated information about system + * attributes will be stored. Can be NULL to calculate required + * size. + * @param[in] p_sys_attr_data_len Size of p_sys_attr_data buffer if \p p_sys_attr_data is + * not NULL. + * @param[in] flags Additional optional flags. + * @param[in,out] p_buf Pointer to buffer where encoded data command will + * be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @note \p p_sys_attr_data and \p p_sys_attr_data_len will not be updated by the command + * request encoder. Updated values are set by @ref ble_gatts_sys_attr_get_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_sys_attr_get_req_enc(uint16_t conn_handle, + uint8_t const * const p_sys_attr_data, + uint16_t const * const p_sys_attr_data_len, + uint32_t flags, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_sys_attr_get command. + * + * @sa @ref ble_gatts_sys_attr_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_sys_attr_data Pointer to a buffer where updated information about system + * attributes will be stored. + * @param[in,out] pp_sys_attr_data_len \c in: Size (in bytes) of \p p_sys_attr_data buffer. + * \c out: Length of decoded contents of \p p_sys_attr_data. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Length of \p p_sys_attr_data is too small to hold decoded + * value from response. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_sys_attr_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * const pp_sys_attr_data, + uint16_t * * const pp_sys_attr_data_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gatts_descriptor_add command request. + * + * @sa @ref ble_gatts_descriptor_add_rsp_dec for command response decoder. + * + * @param[in] char_handle Handle of the characteristic where the description is to be placed. + * If @ref BLE_GATT_HANDLE_INVALID is used, it will be placed + * sequentially. + * @param[in] p_attr Pointer to a @ref ble_gatts_attr_t structure, characteristic + * metadata. + * @param[in] p_handle Pointer to a @ref ble_gatts_char_handles_t structure, where the + * assigned handles will be stored. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_descriptor_add_req_enc(uint16_t char_handle, + ble_gatts_attr_t const * const p_attr, + uint16_t * const p_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_descriptor_add command. + * + * @sa @ref ble_gatts_descriptor_add_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_handle Pointer to bufer where descriptor handle will be + returned. + * @param[out] p_result_code Pointer to command result code decode location. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_descriptor_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_handle, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gatts_include_add command request. + * + * @sa @ref ble_gatts_include_add_rsp_dec for command response decoder. + * + * @param[in] service_handle Handle of the service where the included service is to be placed. + * @param[in] inc_srvc_handle Handle of the included service + * @param[in] p_include_handle Pointer to Pointer to a 16-bit word where the assigned handle will be stored. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_include_add_req_enc(uint16_t service_handle, + uint16_t inc_srvc_handle, + uint16_t * const p_include_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_include_add command. + * + * @sa @ref ble_gatts_include_add_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. + * @param[out] p_result_code Pointer to command result code decode location. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_include_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_include_handle, + uint32_t * const p_result_code); + + +/**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command request. + * + * @sa @ref ble_gatts_rw_authorize_reply_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_reply_params Pointer to \ref ble_gatts_rw_authorize_reply_params_t + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Invalid param provided in p_reply_params. + */ +uint32_t ble_gatts_rw_authorize_reply_req_enc( + uint16_t conn_handle, + ble_gatts_rw_authorize_reply_params_t const * const + p_reply_params, + uint8_t * const + p_buf, + uint32_t * const + p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_rw_authorize_reply command. + * + * @sa @ref ble_gatts_rw_authorize_reply_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_rw_authorize_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gatts_service_changed command request. + * + * @sa @ref ble_gatts_service_changed_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] start_handle Start of affected attribute handle range. + * @param[in] end_handle End of affected attribute handle range. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Invalid param provided in p_reply_params. + */ +uint32_t ble_gatts_service_changed_req_enc(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_service_changed command. + * + * @sa @ref ble_gatts_service_changed_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_service_changed_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gatts_attr_get command request. + * + * @sa @ref ble_gatts_attr_get_rsp_dec for command response decoder. + * + * @param[in] handle See @ref sd_ble_gatts_attr_get. + * @param[in] p_uuid See @ref sd_ble_gatts_attr_get. + * @param[out] p_md See @ref sd_ble_gatts_attr_get. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_attr_get_req_enc(uint16_t handle, + ble_uuid_t * p_uuid, + ble_gatts_attr_md_t * p_md, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_attr_get command. + * + * @sa @ref ble_gatts_attr_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_uuid Pointer to address where to put output data. + * @param[out] pp_md Pointer to address where to put output data. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_attr_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_uuid_t ** pp_uuid, + ble_gatts_attr_md_t ** pp_md, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gatts_initial_user_handle_get command request. + * + * @sa @ref ble_gatts_initial_user_handle_get_rsp_dec for command response decoder. + * + * @param[out] p_handle See @ref sd_ble_gatts_initial_user_handle_get. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_initial_user_handle_get_req_enc(uint16_t * p_handle, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_initial_user_handle_get command. + * + * @sa @ref ble_gatts_initial_user_handle_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_handle Pointer to address where to put output data. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_initial_user_handle_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t ** pp_handle, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gatts_exchange_mtu_reply command request. + * + * @sa @ref ble_gatts_exchange_mtu_reply_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] server_rx_mtu Server MTU Size. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Invalid param provided in p_reply_params. + */ +uint32_t ble_gatts_exchange_mtu_reply_req_enc(uint16_t conn_handle, + uint16_t server_rx_mtu, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_exchange_mtu_reply command. + * + * @sa @ref ble_gatts_exchange_mtu_reply_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_exchange_mtu_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif //BLE_GATTS_APP_H__ + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.c new file mode 100644 index 0000000000000000000000000000000000000000..5622b5dd2688849cbfc6e917beb9d4bfb4404e24 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.c @@ -0,0 +1,190 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gatts_evt_app.h" +#include "ble_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "app_ble_user_mem.h" +#include "app_util.h" + +extern ser_ble_user_mem_t m_app_user_mem_table[]; + +uint32_t ble_gatts_evt_hvc_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_HVC, gatts, hvc); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gatts_evt.params.hvc, + ble_gatts_evt_hvc_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gatts_evt_rw_authorize_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_HVC, gatts, rw_authorize_request); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gatts_evt.params.authorize_request, ble_gatts_evt_rw_authorize_request_t_dec); + + //Correct event length / memory sync. + if (p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_READ) + { + evt_struct_len = offsetof(ble_evt_t, evt.gatts_evt.params.authorize_request.request.read) + - offsetof(ble_evt_t, evt) + + sizeof(ble_gatts_evt_read_t); + } + else if ((p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && + ( (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || + (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ))) + { + uint32_t conn_index; + if(app_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) + { + SER_PULL_len16data(&m_app_user_mem_table[conn_index].mem_block.p_mem, &m_app_user_mem_table[conn_index].mem_block.len); + } + } + + SER_EVT_DEC_END; +} + + +uint32_t ble_gatts_evt_sc_confirm_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN_NO_STRUCT(BLE_GATTS_EVT_SC_CONFIRM, gatts); + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_EVT_DEC_END; +} + + +uint32_t ble_gatts_evt_sys_attr_missing_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_SYS_ATTR_MISSING, gatts, sys_attr_missing); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gatts_evt.params.sys_attr_missing, + ble_gatts_evt_sys_attr_missing_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gatts_evt_timeout_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_TIMEOUT, gatts, timeout); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gatts_evt.params.timeout, + ble_gatts_evt_timeout_t_dec); + + SER_EVT_DEC_END; +} + + + + +uint32_t ble_gatts_evt_write_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_WRITE, gatts, write); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gatts_evt.params.write, ble_gatts_evt_write_t_dec); + + if(p_event != NULL) + { + if(p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + { + uint32_t conn_index; + if(app_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) + { + SER_PULL_len16data(&m_app_user_mem_table[conn_index].mem_block.p_mem, &m_app_user_mem_table[conn_index].mem_block.len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + } + } + + SER_EVT_DEC_END; +} + + +uint32_t ble_gatts_evt_exchange_mtu_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, gatts, exchange_mtu_request); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gatts_evt.params.exchange_mtu_request, ble_gatts_evt_exchange_mtu_request_t_dec); + + SER_EVT_DEC_END; +} + +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gatts_evt_hvn_tx_complete_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_HVN_TX_COMPLETE, gatts, hvn_tx_complete); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.gatts_evt.params.hvn_tx_complete.count); + + SER_EVT_DEC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.h new file mode 100644 index 0000000000000000000000000000000000000000..a6d273bb38e50cd986a6357bc265e8c106052891 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.h @@ -0,0 +1,249 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GATTS_EVT_APP_H__ +#define BLE_GATTS_EVT_APP_H__ + +/**@file + * + * @defgroup ble_gatts_evt_app GATTS Application event decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief GATTS Application event decoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Decodes ble_gatts_evt_hvc event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gatts_evt_hvc_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gatts_evt_rw_authorize_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gatts_evt_rw_authorize_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gatts_evt_sc_confirm event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gatts_evt_sc_confirm_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gatts_evt_sys_attr_missing event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gatts_evt_sys_attr_missing_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gatts_evt_timeout event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gatts_evt_timeout_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gatts_evt_write event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gatts_evt_write_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gatts_evt_exchange_mtu_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gatts_evt_exchange_mtu_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +#if NRF_SD_BLE_API_VERSION >= 4 + +/** + * @brief Decodes ble_gatts_evt_hvn_tx_complete event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gatts_evt_hvn_tx_complete_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); +#endif +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.c new file mode 100644 index 0000000000000000000000000000000000000000..9f382d6da804826d6894a567909fc762cfdbf7f7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.c @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "ble_l2cap_app.h" +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_gap.h" +#include "app_util.h" +#include "cond_field_serialization.h" + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_l2cap_cid_register_req_enc(uint16_t cid, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); + + p_buf[index++] = SD_BLE_L2CAP_CID_REGISTER; + err_code = uint16_t_enc(&cid, p_buf, *p_buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ble_l2cap_cid_register_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_CID_REGISTER, p_result_code); +} + +uint32_t ble_l2cap_cid_unregister_req_enc(uint16_t cid, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); + + p_buf[index++] = SD_BLE_L2CAP_CID_UNREGISTER; + err_code = uint16_t_enc(&cid, p_buf, *p_buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ble_l2cap_cid_unregister_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_CID_UNREGISTER, p_result_code); +} + + +uint32_t ble_l2cap_tx_req_enc(uint16_t conn_handle, + ble_l2cap_header_t const * const p_l2cap_header, + uint8_t const * const p_data, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); + p_buf[index++] = SD_BLE_L2CAP_TX; + + err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = cond_field_enc(p_l2cap_header, p_buf, *p_buf_len, &index, ble_l2cap_header_t_enc); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (p_l2cap_header != NULL) + { + err_code = buf_enc(p_data, p_l2cap_header->len, p_buf, *p_buf_len, &index); + } + else + { + err_code = buf_enc(NULL, 0, p_buf, *p_buf_len, &index); + } + + *p_buf_len = index; + + return err_code; +} + +uint32_t ble_l2cap_tx_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_TX, p_result_code); +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.h new file mode 100644 index 0000000000000000000000000000000000000000..d641830d28bc2e422fa38cc0f0297efe1b4fbcc4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.h @@ -0,0 +1,189 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ble_l2cap_app L2CAP Application command request encoders and command response decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief L2CAP Application command request encoders and command response decoders. + */ + +#ifndef BLE_L2CAP_APP_H__ +#define BLE_L2CAP_APP_H__ + +#include "ble.h" +#include "ble_types.h" +#include "ble_ranges.h" +#include "ble_err.h" +#include "ble_l2cap.h" + +#ifdef __cplusplus +extern "C" { +#endif +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +/**@brief Register a CID with L2CAP. + * + * @details This registers a higher protocol layer with the L2CAP multiplexer, and is required prior to all operations on the CID. + * + * @param[in] cid L2CAP CID. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_l2cap_cid_register_req_enc(uint16_t cid, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_l2cap_cid_register command. + * + * @sa @ref ble_l2cap_cid_register_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_l2cap_cid_register_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Unregister a CID with L2CAP. + * + * @details This unregisters a previously registered higher protocol layer with the L2CAP multiplexer. + * + * @param[in] cid L2CAP CID. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_l2cap_cid_unregister_req_enc(uint16_t cid, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_l2cap_cid_unregister command. + * + * @sa @ref ble_l2cap_cid_unregister_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_l2cap_cid_unregister_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Transmit an L2CAP packet. + * + * @note It is important to note that a call to this function will consume an application buffer, and will therefore + * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. + * See the documentation of @ref sd_ble_tx_packet_count_get for more details. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_l2cap_header Pointer to a packet header containing length and CID. + * @param[in] p_data Pointer to the data to be transmitted. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Successfully queued an L2CAP packet for transmission. + * @retval NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CIDs must be registered beforehand with @ref sd_ble_l2cap_cid_register. + * @retval NRF_ERROR_NOT_FOUND CID not found. + * @retval NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, see @ref BLE_L2CAP_MTU_DEF. + */ +uint32_t ble_l2cap_tx_req_enc(uint16_t conn_handle, + ble_l2cap_header_t const * const p_l2cap_header, + uint8_t const * const p_data, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_l2cap_tx command. + * + * @sa @ref ble_l2cap_tx_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_l2cap_tx_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif //BLE_L2CAP_APP_H__ + +/** + @} + */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.c new file mode 100644 index 0000000000000000000000000000000000000000..441eb1ece21ace0943bacc08138b26ad004a6498 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.c @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "app_util.h" +#include "ble_l2cap_evt_app.h" + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_l2cap_evt_rx_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_L2CAP_EVT_RX, l2cap, rx); + + SER_PULL_uint16(&p_event->evt.l2cap_evt.conn_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.l2cap_evt.params.rx, ble_l2cap_evt_rx_t_dec); + + SER_EVT_DEC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.h new file mode 100644 index 0000000000000000000000000000000000000000..63875aff58a7f7de1a79a5c14a05489cc204e979 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_L2CAP_EVT_APP_H__ +#define BLE_L2CAP_EVT_APP_H__ + +/**@file + * + * @defgroup ble_l2cap_evt_app L2CAP Application event decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief L2CAP Application event decoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Decodes ble_l2cap_evt_rx event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_l2cap_evt_rx_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/nrf_soc_app.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/nrf_soc_app.c new file mode 100644 index 0000000000000000000000000000000000000000..bbcede6153e1650470062298713fa17a51ddbadc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/nrf_soc_app.c @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_soc_app.h" +#include "nrf_soc.h" +#include +#include +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "nrf_soc_struct_serialization.h" +#include "app_util.h" + + +uint32_t ecb_block_encrypt_req_enc(nrf_ecb_hal_data_t * p_ecb_data, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_ECB_BLOCK_ENCRYPT); + SER_PUSH_COND(p_ecb_data, nrf_ecb_hal_data_t_in_enc); + SER_REQ_ENC_END; +} + + +uint32_t ecb_block_encrypt_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + nrf_ecb_hal_data_t * * const pp_ecb_data, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_ECB_BLOCK_ENCRYPT); + SER_PULL_COND(pp_ecb_data, nrf_ecb_hal_data_t_out_dec); + SER_RSP_DEC_END; +} + + +uint32_t power_system_off_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_POWER_SYSTEM_OFF); + SER_REQ_ENC_END; +} + + +uint32_t temp_get_req_enc(int32_t const * const p_temp, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_TEMP_GET); + SER_PUSH_COND(p_temp, NULL); + SER_REQ_ENC_END; +} + +uint32_t temp_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code, + int32_t * * const pp_temp) +{ + SER_RSP_DEC_BEGIN(SD_TEMP_GET); + SER_PULL_COND(pp_temp, uint32_t_dec); + SER_RSP_DEC_END; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/nrf_soc_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/nrf_soc_app.h new file mode 100644 index 0000000000000000000000000000000000000000..50c3e35c90f0f674ac9a6f0ffdaac5eb32af48fe --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/ble/serializers/nrf_soc_app.h @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup soc_app SOC Application command request encoders and command response decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief SOC Application command request encoders and command response decoders. + */ + +#ifndef NRF_SOC_APP_H__ +#define NRF_SOC_APP_H__ + +#include +#include "nrf_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif +/**@brief Encodes @ref sd_power_system_off command request. + * + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t power_system_off_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len); + + +/**@brief Encodes @ref sd_temp_get command request. + * + * @sa @ref temp_get_rsp_dec for command response decoder. + * + * @param[in] p_temp Pointer to result of temperature measurement. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t temp_get_req_enc(int32_t const * const p_temp, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_temp_get command. + * + * @sa @ref temp_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * @param[out] pp_temp Pointer to result of temperature measurement. + * + * @retval NRF_SUCCESS Version information stored successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t temp_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code, + int32_t * * const pp_temp); + +/**@brief Encodes @ref sd_ecb_block_encrypt command request. + * + * @sa @ref ecb_block_encrypt_rsp_dec for command response decoder. + * + * @param[in] p_ecb_data Pointer to ECB data. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ecb_block_encrypt_req_enc(nrf_ecb_hal_data_t * p_ecb_data, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ecb_block_encrypt command. + * + * @sa @ref ecb_block_encrypt_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_ecb_data Pointer to ECB data. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Version information stored successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ecb_block_encrypt_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + nrf_ecb_hal_data_t * * const p_ecb_data, + uint32_t * const p_result_code); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SOC_APP_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/ble_dtm_app.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/ble_dtm_app.c new file mode 100644 index 0000000000000000000000000000000000000000..02523a4617542619d70844daf9bf06ddf75406a1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/ble_dtm_app.c @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "app_error.h" +#include "ble_dtm_app.h" +#include "ble_serialization.h" +#include "nrf_error.h" +#include "ser_config.h" +#include "ser_hal_transport.h" +#include "ser_sd_transport.h" + + +static uint32_t dtm_init_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_dtm_init_rsp_dec(p_buffer, length, &result_code); + APP_ERROR_CHECK(err_code); + + return result_code; +} + + +uint32_t ble_dtm_init(app_uart_stream_comm_params_t * p_uart_comm_params) +{ + if (p_uart_comm_params == NULL) + { + return NRF_ERROR_NULL; + } + + uint32_t err_code = NRF_SUCCESS; + uint32_t index = 0; + + uint8_t * p_tx_buf = NULL; + uint32_t tx_buf_len = 0; + + err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + p_tx_buf[index++] = SER_PKT_TYPE_DTM_CMD; + tx_buf_len -= SER_PKT_TYPE_SIZE; + + err_code = ble_dtm_init_req_enc(p_uart_comm_params, &(p_tx_buf[SER_PKT_TYPE_SIZE]), &tx_buf_len); + if (err_code == NRF_SUCCESS) + { + tx_buf_len += SER_PKT_TYPE_SIZE; + + err_code = ser_sd_transport_cmd_write(p_tx_buf, tx_buf_len, dtm_init_rsp_dec); + if (err_code != NRF_SUCCESS) + { + err_code = NRF_ERROR_INTERNAL; + } + } + else + { + err_code = NRF_ERROR_INTERNAL; + } + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/ble_dtm_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/ble_dtm_app.h new file mode 100644 index 0000000000000000000000000000000000000000..c81e9cf633e3f96b830b98d0f0bf33c59b24df70 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/ble_dtm_app.h @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_DTM_APP_H__ +#define BLE_DTM_APP_H__ + +/** + * @addtogroup ser_codecs Serialization codecs + * @ingroup ble_sdk_lib_serialization + * @brief Application and Connectivity codecs. + */ + +/** + * @addtogroup ser_codecs_app Application codecs + * @ingroup ser_codecs + */ + +/** + * @addtogroup ser_app_common_codecs Application common codecs + * @ingroup ser_codecs_app + */ + +/**@file + * + * @defgroup ble_dtm_app DTM Application command request encoders and command response decoders + * @{ + * @ingroup ser_app_common_codecs + * + * @brief DTM Application command request encoders and command response decoders. + */ + +#include "dtm_uart_params.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Encodes the @ref ble_dtm_init command request. + * + * @sa @ref encoding_data for packet format, + * @ref ble_dtm_init_rsp_dec for command response decoder. + * + * @param[in] p_uart_comm_params Pointer to the UART configuration parameters. + * @param[in] p_buf Pointer to the buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of the encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_dtm_init_req_enc(app_uart_stream_comm_params_t const * const p_uart_comm_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + + +/**@brief Decodes the response @ref ble_dtm_init command. + * + * @sa @ref encoding_data for packet format, + * @ref ble_dtm_init_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_dtm_init_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + + +/**@brief Function to initializing the DTM mode. + * + * @param[in] p_uart_comm_params Pointer to the DTM UART configuration parameters. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + */ +uint32_t ble_dtm_init(app_uart_stream_comm_params_t * p_uart_comm_params); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // BLE_DTM_APP_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/ble_dtm_init.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/ble_dtm_init.c new file mode 100644 index 0000000000000000000000000000000000000000..b9581787a3eebdd31406433554624980aa08f871 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/ble_dtm_init.c @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_dtm_app.h" +#include "ble_serialization.h" +#include "nrf_error.h" + +uint32_t ble_dtm_init_req_enc(app_uart_stream_comm_params_t const * const p_uart_comm_params, uint8_t * const p_buf, uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + SER_ASSERT_NOT_NULL(p_uart_comm_params); + + uint32_t index = 0; + uint32_t buf_len = *p_buf_len; + uint32_t err_code; + + err_code = uint8_t_enc(&p_uart_comm_params->tx_pin_no, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&p_uart_comm_params->rx_pin_no, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&p_uart_comm_params->baud_rate, p_buf, buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + *p_buf_len = index; + + return err_code; +} + + +uint32_t ble_dtm_init_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, uint32_t * const p_result_code) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_result_code); + + uint32_t err_code; + uint32_t index = 0; + + err_code = uint32_t_dec(p_buf, packet_len, &index, p_result_code); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT(packet_len == index, NRF_ERROR_INVALID_LENGTH); + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/conn_systemreset.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/conn_systemreset.c new file mode 100644 index 0000000000000000000000000000000000000000..38be7e292ac36ed1c4aa4badd8eea4fc8b72f1c7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/conn_systemreset.c @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "ble_serialization.h" +#include "ser_hal_transport.h" +#include "ser_sd_transport.h" + + +uint32_t conn_systemreset(void) +{ + uint32_t err_code = NRF_SUCCESS; + uint8_t * p_tx_buf = NULL; + uint32_t tx_buf_len = 0; + + err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + SER_ASSERT_LENGTH_LEQ(SER_PKT_TYPE_SIZE, tx_buf_len); + p_tx_buf[SER_PKT_TYPE_POS] = SER_PKT_TYPE_RESET_CMD; + tx_buf_len = SER_PKT_TYPE_SIZE; + + err_code = ser_sd_transport_cmd_write(p_tx_buf, tx_buf_len, NULL); + if (err_code != NRF_SUCCESS) + { + err_code = NRF_ERROR_INTERNAL; + } + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/conn_systemreset.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/conn_systemreset.h new file mode 100644 index 0000000000000000000000000000000000000000..7ec5d42d980857a970b6c48f0dcc040d6607941e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/codecs/common/conn_systemreset.h @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef CONN_SYSTEMRESET_H__ +#define CONN_SYSTEMRESET_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup ser_codecs Serialization codecs + * @ingroup ble_sdk_lib_serialization + */ + +/** + * @addtogroup ser_app_common_codecs Application common codecs + * @ingroup ser_codecs_app + */ + +/**@file + * + * @defgroup conn_systemreset Connectivity chip reset command request encoder + * @{ + * @ingroup ser_app_common_codecs + * + * @brief Connectivity chip reset command request encoder. + */ + +/**@brief Function for performing the connectivity chip reset. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_INTERNAL Encoding failure. Transport error. + */ +uint32_t conn_systemreset(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // CONN_SYSTEMRESET_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/hal/ser_app_hal.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/hal/ser_app_hal.h new file mode 100644 index 0000000000000000000000000000000000000000..0ff3e4fb091fdf9195e5f1cf40a9b94d40035f76 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/hal/ser_app_hal.h @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ser_app_hal Serialization Application Hardware Abstraction Layer (HAL) + * @{ + * @ingroup ble_sdk_lib_serialization + * + * @brief Functions that set up hardware on Application Board and perform the reset of the Connectivity Board. + */ + +#ifndef SER_APP_HAL_H_ +#define SER_APP_HAL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +typedef void (*ser_app_hal_flash_op_done_handler_t)(bool success); +/**@brief Function for initializing hardware modules. + * + * @details Function can initialize hardware modules on the Application Chip. It is optional to + * implement. It is called once the Connectivity Chip is initialized. + * + * @param handler Flash operation event handler. + * + * @return @ref NRF_SUCCESS HAL initialized successfully. + * @return @ref nrf_error "NRF_ERROR_..." HAL initialization failed. + * + */ +uint32_t ser_app_hal_hw_init(ser_app_hal_flash_op_done_handler_t handler); + +/**@brief Function for waiting for a given amount of time. + * + * @param[in] ms Number of milliseconds to wait. + * + */ +void ser_app_hal_delay(uint32_t ms); + +/**@brief Function for clearing the Connectivity Chip reset pin. + * + */ +void ser_app_hal_nrf_reset_pin_clear(void); + +/**@brief Function for setting the Connectivity Chip reset pin. + * + */ +void ser_app_hal_nrf_reset_pin_set(void); + + +/**@brief Function for setting the SoftDevice event interrupt priority that serves the events incoming + * from the Connectivity Chip. + * + * @note Serialization solution on the application side mimics a SoC solution where events are handled in + * the interrupt context in two ways: either directly in the interrupt context or with a message being posted to + * the scheduler. However, it is possible that the Application Chip does not use a dedicated interrupt + * for connectivity events. In that case, this function can be left empty and + * \ref ser_app_hal_nrf_evt_pending will directly call an interrupt handler function. + */ +void ser_app_hal_nrf_evt_irq_priority_set(void); + +/**@brief Function for setting a pending interrupt for serving events incoming from the Connectivity Chip. + * + * @note The interrupt used for event from the Connectivity Chip mimics behavior of SoC and it is not + * intended to be triggered by any hardware event. This function should be the only source of + * interrupt triggering. + */ +void ser_app_hal_nrf_evt_pending(void); + + + +#ifdef __cplusplus +} +#endif + +#endif /* SER_APP_HAL_H_ */ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/hal/ser_app_hal_nrf5x.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/hal/ser_app_hal_nrf5x.c new file mode 100644 index 0000000000000000000000000000000000000000..0352dec042c2a65113c6aad782a0baa4c517e41c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/hal/ser_app_hal_nrf5x.c @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "app_util_platform.h" +#include "ser_app_hal.h" +#include "nrf.h" +#include "nrf_gpio.h" +#include "nrf_soc.h" +#include "nrf_delay.h" +#include "nrf_nvmc.h" +#include "boards.h" +#include "ser_phy.h" +#include "ser_phy_config_app.h" +#include "nrf_drv_clock.h" + +#define SOFTDEVICE_EVT_IRQ SD_EVT_IRQn /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ +#define FLASH_WRITE_MAX_LENGTH ((uint16_t)NRF_FICR->CODEPAGESIZE) +#define BLE_FLASH_PAGE_SIZE ((uint16_t)NRF_FICR->CODEPAGESIZE) /**< Size of one flash page. */ + +static ser_app_hal_flash_op_done_handler_t m_flash_op_handler; +uint32_t ser_app_hal_hw_init(ser_app_hal_flash_op_done_handler_t handler) +{ + + nrf_gpio_cfg_output(CONN_CHIP_RESET_PIN_NO); + + if (NRF_SUCCESS != nrf_drv_clock_init()) + { + return NRF_ERROR_INTERNAL; + } + + nrf_drv_clock_lfclk_request(NULL); + nrf_drv_clock_hfclk_request(NULL); + + while(false == nrf_drv_clock_hfclk_is_running()); + while(false == nrf_drv_clock_lfclk_is_running()); + + return NRF_SUCCESS; +} + +void ser_app_hal_delay(uint32_t ms) +{ + nrf_delay_ms(ms); +} + +void ser_app_hal_nrf_reset_pin_clear() +{ + nrf_gpio_pin_clear(CONN_CHIP_RESET_PIN_NO); +} + +void ser_app_hal_nrf_reset_pin_set() +{ + nrf_gpio_pin_set(CONN_CHIP_RESET_PIN_NO); +} + +void ser_app_hal_nrf_evt_irq_priority_set() +{ + NVIC_SetPriority(SOFTDEVICE_EVT_IRQ, APP_IRQ_PRIORITY_LOWEST); +} + +void ser_app_hal_nrf_evt_pending() +{ + NVIC_SetPendingIRQ(SOFTDEVICE_EVT_IRQ); +} + +uint32_t sd_ppi_channel_enable_get(uint32_t * p_channel_enable) +{ + *p_channel_enable = NRF_PPI->CHEN; + return NRF_SUCCESS; +} + +uint32_t sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk) +{ + NRF_PPI->CHEN = channel_enable_set_msk; + return NRF_SUCCESS; +} + +uint32_t sd_ppi_channel_assign(uint8_t channel_num, + const volatile void * evt_endpoint, + const volatile void * task_endpoint) +{ + NRF_PPI->CH[channel_num].TEP = (uint32_t)task_endpoint; + NRF_PPI->CH[channel_num].EEP = (uint32_t)evt_endpoint; + return NRF_SUCCESS; +} +/** + * @brief Check if given address is in device FLASH range. + * + * @param[in] ptr Address to check. + * @retval true Given address is located in FLASH. + * @retval false Given address is not located in FLASH. + */ +__STATIC_INLINE bool addr_is_in_FLASH(void const * const ptr) +{ + return ((((uintptr_t)ptr) & 0xFF000000u) == 0x00000000u); +} + +uint32_t sd_flash_page_erase(uint32_t page_number) +{ + uint32_t * p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_number); + + if (!addr_is_in_FLASH(p_page)) + { + return NRF_ERROR_INVALID_ADDR; + } + + nrf_nvmc_page_erase((uint32_t) p_page); + m_flash_op_handler(true); + return NRF_SUCCESS; +} + +uint32_t sd_flash_write(uint32_t * const p_dst, uint32_t const * const p_src, uint32_t size) +{ + if (size > FLASH_WRITE_MAX_LENGTH) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (!addr_is_in_FLASH(p_dst)) + { + return NRF_ERROR_INVALID_ADDR; + } + + nrf_nvmc_write_words((uint32_t) p_dst, p_src, size); + m_flash_op_handler(true); + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/hal/ser_app_power_system_off.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/hal/ser_app_power_system_off.c new file mode 100644 index 0000000000000000000000000000000000000000..961d8f48a01ac3923a6414dfb4146f4f2ff528bf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/hal/ser_app_power_system_off.c @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf.h" +#include "ser_app_power_system_off.h" + +static bool m_power_system_off = false; + + +void ser_app_power_system_off_set(void) +{ + m_power_system_off = true; +} + +bool ser_app_power_system_off_get(void) +{ + return m_power_system_off; +} + +void ser_app_power_system_off_enter(void) +{ + NRF_POWER->SYSTEMOFF = POWER_SYSTEMOFF_SYSTEMOFF_Enter; + + /*Only for debugging purpose, will not be reached without connected debugger*/ + while (1); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/hal/ser_app_power_system_off.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/hal/ser_app_power_system_off.h new file mode 100644 index 0000000000000000000000000000000000000000..0f283eb49a7aabe813695b5be099d3d6bd5fcaf4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/hal/ser_app_power_system_off.h @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef APP_POWER_SYSTEM_OFF_H +#define APP_POWER_SYSTEM_OFF_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void ser_app_power_system_off_set(void); + +bool ser_app_power_system_off_get(void); + +void ser_app_power_system_off_enter(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/transport/ser_sd_transport.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/transport/ser_sd_transport.c new file mode 100644 index 0000000000000000000000000000000000000000..d6ea53e03b08189654c2ad7bf87444568f3c3bd4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/transport/ser_sd_transport.c @@ -0,0 +1,324 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include +#include "ser_sd_transport.h" +#include "ser_hal_transport.h" +#include "nrf_error.h" +#include "app_error.h" +#include "ble_serialization.h" +#include "ser_dbg_sd_str.h" +#include "ser_app_power_system_off.h" +#include "app_util.h" +#define NRF_LOG_MODULE_NAME "SER_XFER" +#include "nrf_log.h" + +#ifdef BLE_STACK_SUPPORT_REQD +/** SoftDevice event handler. */ +static ser_sd_transport_evt_handler_t m_ble_evt_handler = NULL; +#endif // BLE_STACK_SUPPORT_REQD + +#ifdef ANT_STACK_SUPPORT_REQD +/** SoftDevice event handler for ANT events. */ +static ser_sd_transport_evt_handler_t m_ant_evt_handler = NULL; +#endif // ANT_STACK_SUPPORT_REQD + +/** 'One time' handler called in task context while waiting for response to scheduled command. */ +static ser_sd_transport_rsp_wait_handler_t m_ot_rsp_wait_handler = NULL; + +/** Handler called in task context while waiting for response to scheduled command. */ +static ser_sd_transport_rsp_wait_handler_t m_os_rsp_wait_handler = NULL; + +/** Handler called in serial peripheral interrupt context when response is received. */ +static ser_sd_transport_rsp_set_handler_t m_os_rsp_set_handler = NULL; + +/** Handler called when hal_transport notifies that packet reception has started. */ +static ser_sd_transport_rx_notification_handler_t m_rx_notify_handler = NULL; + +/** User decoder handler for expected response packet. */ +static ser_sd_transport_rsp_handler_t m_rsp_dec_handler = NULL; + +/** Flag indicated whether module is waiting for response packet. */ +static volatile bool m_rsp_wait = false; + +/** SoftDevice call return value decoded by user decoder handler. */ +static uint32_t m_return_value; + +/**@brief Function for handling the rx packets comming from hal_transport. + * + * @details + * This function is called in serial peripheral interrupt context. Response packets are handled in + * this context. Events are passed to the application and it is up to application in which context + * they are handled. + * + * @param[in] p_data Pointer to received data. + * @param[in] length Size of data. + */ +static void ser_sd_transport_rx_packet_handler(uint8_t * p_data, uint16_t length) +{ + if (p_data && (length >= SER_PKT_TYPE_SIZE)) + { + const uint8_t packet_type = p_data[SER_PKT_TYPE_POS]; + p_data += SER_PKT_TYPE_SIZE; + length -= SER_PKT_TYPE_SIZE; + + switch (packet_type) + { + case SER_PKT_TYPE_RESP: + case SER_PKT_TYPE_DTM_RESP: +#ifdef ANT_STACK_SUPPORT_REQD + case SER_PKT_TYPE_ANT_RESP: +#endif // ANT_STACK_SUPPORT_REQD + if (m_rsp_wait) + { + m_return_value = m_rsp_dec_handler(p_data, length); + (void)ser_sd_transport_rx_free(p_data); + + /* Reset response flag - cmd_write function is pending on it.*/ + m_rsp_wait = false; + + /* If os handler is set, signal os that response has arrived.*/ + if (m_os_rsp_set_handler) + { + m_os_rsp_set_handler(); + } + } + else + { + /* Unexpected packet. */ + (void)ser_sd_transport_rx_free(p_data); + APP_ERROR_HANDLER(packet_type); + } + break; + +#ifdef BLE_STACK_SUPPORT_REQD + case SER_PKT_TYPE_EVT: + /* It is ensured during opening that handler is not NULL. No check needed. */ + NRF_LOG_DEBUG("[EVT]: %s \r\n", (uint32_t)ser_dbg_sd_evt_str_get(uint16_decode(&p_data[SER_EVT_ID_POS]))); // p_data points to EVT_ID + m_ble_evt_handler(p_data, length); + break; +#endif // BLE_STACK_SUPPORT_REQD + +#ifdef ANT_STACK_SUPPORT_REQD + case SER_PKT_TYPE_ANT_EVT: + /* It is ensured during opening that handler is not NULL. No check needed. */ + NRF_LOG_DEBUG("[ANT_EVT_ID]: %s \r\n", (uint32_t)ser_dbg_sd_evt_str_get(uint16_decode(&p_data[SER_EVT_ID_POS]))); // p_data points to EVT_ID + m_ant_evt_handler(p_data, length); + break; +#endif // ANT_STACK_SUPPORT_REQD + + default: + (void)ser_sd_transport_rx_free(p_data); + APP_ERROR_HANDLER(packet_type); + break; + } + } +} + +/**@brief Function for handling the event from hal_transport. + * + * @param[in] event Event from hal_transport. + */ +static void ser_sd_transport_hal_handler(ser_hal_transport_evt_t event) +{ + switch (event.evt_type) + { + case SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED: + ser_sd_transport_rx_packet_handler(event.evt_params.rx_pkt_received.p_buffer, + event.evt_params.rx_pkt_received.num_of_bytes); + break; + case SER_HAL_TRANSP_EVT_RX_PKT_RECEIVING: + if (m_rx_notify_handler) + { + m_rx_notify_handler(); + } + break; + case SER_HAL_TRANSP_EVT_TX_PKT_SENT: + if (ser_app_power_system_off_get() == true) + { + ser_app_power_system_off_enter(); + } + break; + case SER_HAL_TRANSP_EVT_PHY_ERROR: + + if (m_rsp_wait) + { + m_return_value = NRF_ERROR_INTERNAL; + + /* Reset response flag - cmd_write function is pending on it.*/ + m_rsp_wait = false; + + /* If os handler is set, signal os that response has arrived.*/ + if (m_os_rsp_set_handler) + { + m_os_rsp_set_handler(); + } + } + break; + default: + break; + } +} + +uint32_t ser_sd_transport_open(ser_sd_transport_evt_handler_t ble_evt_handler, + ser_sd_transport_evt_handler_t ant_evt_handler, + ser_sd_transport_rsp_wait_handler_t os_rsp_wait_handler, + ser_sd_transport_rsp_set_handler_t os_rsp_set_handler, + ser_sd_transport_rx_notification_handler_t rx_not_handler) +{ + m_os_rsp_wait_handler = os_rsp_wait_handler; + m_os_rsp_set_handler = os_rsp_set_handler; + m_rx_notify_handler = rx_not_handler; + m_ot_rsp_wait_handler = NULL; + +#ifdef ANT_STACK_SUPPORT_REQD + m_ant_evt_handler = ant_evt_handler; + + if (m_ant_evt_handler == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } +#else + UNUSED_PARAMETER(ant_evt_handler); +#endif // ANT_STACK_SUPPORT_REQD + +#ifdef BLE_STACK_SUPPORT_REQD + m_ble_evt_handler = ble_evt_handler; + + if (m_ble_evt_handler == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } +#else + UNUSED_PARAMETER(ble_evt_handler); +#endif // BLE_STACK_SUPPORT_REQD + + return ser_hal_transport_open(ser_sd_transport_hal_handler); +} + +uint32_t ser_sd_transport_close(void) +{ +#ifdef ANT_STACK_SUPPORT_REQD + m_ant_evt_handler = NULL; +#endif // ANT_STACK_SUPPORT_REQD + +#ifdef BLE_STACK_SUPPORT_REQD + m_ble_evt_handler = NULL; +#endif // BLE_STACK_SUPPORT_REQD + + m_os_rsp_wait_handler = NULL; + m_os_rsp_set_handler = NULL; + m_ot_rsp_wait_handler = NULL; + + ser_hal_transport_close(); + + return NRF_SUCCESS; +} + +uint32_t ser_sd_transport_ot_rsp_wait_handler_set(ser_sd_transport_rsp_wait_handler_t handler) +{ + m_ot_rsp_wait_handler = handler; + + return NRF_SUCCESS; +} + +bool ser_sd_transport_is_busy(void) +{ + return m_rsp_wait; +} + +uint32_t ser_sd_transport_tx_alloc(uint8_t * * pp_data, uint16_t * p_len) +{ + uint32_t err_code; + + if (m_rsp_wait) + { + err_code = NRF_ERROR_BUSY; + } + else + { + err_code = ser_hal_transport_tx_pkt_alloc(pp_data, p_len); + } + return err_code; +} + +uint32_t ser_sd_transport_tx_free(uint8_t * p_data) +{ + return ser_hal_transport_tx_pkt_free(p_data); +} + +uint32_t ser_sd_transport_rx_free(uint8_t * p_data) +{ + p_data -= SER_PKT_TYPE_SIZE; + return ser_hal_transport_rx_pkt_free(p_data); +} + +uint32_t ser_sd_transport_cmd_write(const uint8_t * p_buffer, + uint16_t length, + ser_sd_transport_rsp_handler_t cmd_rsp_decode_callback) +{ + uint32_t err_code = NRF_SUCCESS; + + m_rsp_wait = true; + m_rsp_dec_handler = cmd_rsp_decode_callback; + err_code = ser_hal_transport_tx_pkt_send(p_buffer, length); + APP_ERROR_CHECK(err_code); + + /* Execute callback for response decoding only if one was provided.*/ + if ((err_code == NRF_SUCCESS) && cmd_rsp_decode_callback) + { + if (m_ot_rsp_wait_handler) + { + m_ot_rsp_wait_handler(); + m_ot_rsp_wait_handler = NULL; + } + + m_os_rsp_wait_handler(); + err_code = m_return_value; + } + else + { + m_rsp_wait = false; + } + + NRF_LOG_DEBUG("[SD_CALL]:%s, err_code= 0x%X\r\n", (uint32_t)ser_dbg_sd_call_str_get(p_buffer[1]), err_code); + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/transport/ser_sd_transport.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/transport/ser_sd_transport.h new file mode 100644 index 0000000000000000000000000000000000000000..c64b788028a0d645c81ad6a07d123d6a29283a5d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/transport/ser_sd_transport.h @@ -0,0 +1,193 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ser_app Application side code + * @ingroup ble_sdk_lib_serialization + * @brief SoftDevice handler and transport on the application side. + */ + +/** @file + * + * @defgroup ser_sd_transport Serialization SoftDevice Transport + * @{ + * @ingroup ser_app + * + * @brief Serialization SoftDevice Transport on application side. + * + * @details This file contains declarations of functions and definitions of data structures and + * identifiers (typedef enum) used as API of the serialization of SoftDevice. This layer + * ensures atomic nature of SoftDevice calls (command and waiting for response). Packet + * type field of incoming packets is handled in this layer - responses are handled by + * ser_sd_transport (using response decoder handler provided for each SoftDevice call), but + * events are forwarded to the user so it is up to the user to free the RX buffer. + * + */ +#ifndef SER_SD_TRANSPORT_H_ +#define SER_SD_TRANSPORT_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*ser_sd_transport_evt_handler_t)(uint8_t * p_buffer, uint16_t length); +typedef void (*ser_sd_transport_rsp_wait_handler_t)(void); +typedef void (*ser_sd_transport_rsp_set_handler_t)(void); +typedef void (*ser_sd_transport_rx_notification_handler_t)(void); + +typedef uint32_t (*ser_sd_transport_rsp_handler_t)(const uint8_t * p_buffer, uint16_t length); + +/**@brief Function for opening the module. + * + * @note 'Wait for response' and 'Response set' callbacks can be set in RTOS environment. + * It enables rescheduling while waiting for the Connectivity Chip response. In a nonOS environment, + * usually 'Wait for response' will only be used for handling incoming events or forcing the + * application to low power mode. + * + * @param[in] ble_evt_handler Handler to be called when ble event packet is received. + * @param[in] ant_evt_handler Handler to be called when ant event packet is received. + * @param[in] os_rsp_wait_handler Handler to be called after the request is send. It should + * implement a 'Wait for signal' functionality in an OS environment. + * @param[in] os_rsp_set_handler Handler to be called after response reception. It should + * implement a 'Signal Set' functionality in an OS environment. + * @param[in] rx_not_handler Handler to be called after the transport layer notifies that + * an incoming RX packet is detected. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_PARAM Operation failure. Parameter propagated from ser_hal_transport + * opening or timer creation. + * @retval NRF_ERROR_INVALID_STATE Operation failure. Parameter propagated from ser_hal_transport + * opening or timer creation. + * @retval NRF_ERROR_INTERNAL Operation failure. Parameter propagated from ser_hal_transport + * opening or timer creation. + * @retval NRF_ERROR_NO_MEM Operation failure. Parameter propagated from timer creation. + */ +uint32_t ser_sd_transport_open(ser_sd_transport_evt_handler_t ble_evt_handler, + ser_sd_transport_evt_handler_t ant_evt_handler, + ser_sd_transport_rsp_wait_handler_t os_rsp_wait_handler, + ser_sd_transport_rsp_set_handler_t os_rsp_set_handler, + ser_sd_transport_rx_notification_handler_t rx_not_handler); + + +/**@brief Function setting a 'One Time' handler to be called between sending the next request packet and + * receiving the response packet. + * @note It is intended to be used in a nonOS environment to implement concurrency. + * @note It is a 'One Time' handler meaning that it is valid only for the next SoftDevice call processing. + * + * + * @param[in] wait_handler Handler to be called after the request packet is sent. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t ser_sd_transport_ot_rsp_wait_handler_set(ser_sd_transport_rsp_wait_handler_t wait_handler); + + +/**@brief Function for closing the module. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t ser_sd_transport_close(void); + +/**@brief Function for allocating a TX packet to be used for request command. + * + * @param[out] pp_data Pointer to the data pointer to be set to point to allocated buffer. + * @param[out] p_len Pointer to allocated buffer length. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t ser_sd_transport_tx_alloc(uint8_t * * pp_data, uint16_t * p_len); + + +/**@brief Function for freeing a TX packet. + * + * @note Function should be called once the command is processed. + * + * @param[out] p_data Pointer to the allocated TX buffer. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t ser_sd_transport_tx_free(uint8_t * p_data); + + +/**@brief Function for freeing an RX event packet. + * + * @note Function should be called once the SoftDevice event buffer is processed. + * + * @param[out] p_data Pointer to the allocated RX buffer. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t ser_sd_transport_rx_free(uint8_t * p_data); + + +/**@brief Function for checking if module is busy waiting for response from connectivity side. + * + * @retval true Module busy. Cannot accept the next command. + * @retval false Module not busy. Can accept next the command. + */ +bool ser_sd_transport_is_busy(void); + +/**@brief Function for handling a SoftDevice command. + * + * @note Function blocks task context until response is received and processed. + * @note Non-blocking functionality can be achieved using OS handlers or a 'One Time' handler + * @warning Function should not be called from interrupt context, which would block switching to + * serial port interrupt. + * + * @param[in] p_buffer Pointer to command. + * @param[in] length Pointer to allocated buffer length. + * @param[in] cmd_resp_decode_callback Pointer to a function for decoding the response packet. + * + * @retval NRF_SUCCESS Operation success. + */ +uint32_t ser_sd_transport_cmd_write(const uint8_t * p_buffer, + uint16_t length, + ser_sd_transport_rsp_handler_t cmd_resp_decode_callback); + + +#ifdef __cplusplus +} +#endif + +#endif /* SER_SD_TRANSPORT_H_ */ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/transport/ser_softdevice_handler.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/transport/ser_softdevice_handler.c new file mode 100644 index 0000000000000000000000000000000000000000..60229fee18c8b31e988dbc331ee9f8c0d93677b3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/transport/ser_softdevice_handler.c @@ -0,0 +1,307 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "nrf_queue.h" +#include "app_scheduler.h" +#include "softdevice_handler.h" +#include "ser_sd_transport.h" +#include "ser_app_hal.h" +#include "ser_config.h" +#include "nrf_soc.h" +#include "ble_serialization.h" +#if defined(BLE_STACK_SUPPORT_REQD) +#include "ble_app.h" +#endif +#if defined(ANT_STACK_SUPPORT_REQD) +#include "ant_event.h" +#endif + +#define SD_BLE_EVT_MAILBOX_QUEUE_SIZE 5 /**< Size of mailbox queue. */ + +/** @brief Structure used to pass packet details through mailbox. + */ +#if defined(BLE_STACK_SUPPORT_REQD) +typedef struct +{ + uint32_t evt_data[CEIL_DIV(BLE_STACK_EVT_MSG_BUF_SIZE, sizeof (uint32_t))]; /**< Buffer for decoded event */ +} ser_sd_handler_evt_data_t; +#endif + +#if defined(ANT_STACK_SUPPORT_REQD) +typedef struct +{ + uint32_t evt_data[CEIL_DIV(sizeof(ant_evt_t), sizeof (uint32_t))]; /**< Buffer for decoded event */ +} ser_ant_sd_handler_evt_data_t; +#endif + +/** @brief + * Mailbox used for communication between event handler (called from serial stream + * interrupt context) and event processing function (called from scheduler or interrupt context). + */ +#if defined(BLE_STACK_SUPPORT_REQD) +NRF_QUEUE_DEF(ser_sd_handler_evt_data_t, + m_sd_ble_evt_mailbox, + SD_BLE_EVT_MAILBOX_QUEUE_SIZE, + NRF_QUEUE_MODE_NO_OVERFLOW); +#endif + +#if defined(ANT_STACK_SUPPORT_REQD) +NRF_QUEUE_DEF(ser_ant_sd_handler_evt_data_t, + m_sd_ant_evt_mailbox, + SD_BLE_EVT_MAILBOX_QUEUE_SIZE, + NRF_QUEUE_MODE_NO_OVERFLOW); +#endif + +NRF_QUEUE_DEF(uint32_t, + m_sd_soc_evt_mailbox, + SD_BLE_EVT_MAILBOX_QUEUE_SIZE, + NRF_QUEUE_MODE_NO_OVERFLOW); + +/** + * @brief Function to be replaced by user implementation if needed. + * + * Weak function - user can add different implementation of this function if application needs it. + */ +__WEAK void os_rsp_set_handler(void) +{ + +} + +static void connectivity_reset_low(void) +{ + //Signal a reset to the connectivity chip by setting the reset pin low. + ser_app_hal_nrf_reset_pin_clear(); + ser_app_hal_delay(CONN_CHIP_RESET_TIME); + +} + +static void connectivity_reset_high(void) +{ + + //Set the reset level to high again. + ser_app_hal_nrf_reset_pin_set(); + + //Wait for connectivity chip to be ready. + ser_app_hal_delay(CONN_CHIP_WAKEUP_TIME); +} + +#if defined(BLE_STACK_SUPPORT_REQD) +static void ser_softdevice_ble_evt_handler(uint8_t * p_data, uint16_t length) +{ + ser_sd_handler_evt_data_t item; + uint32_t err_code; + uint32_t len32 = sizeof (item.evt_data); + + err_code = ble_event_dec(p_data, length, (ble_evt_t *)item.evt_data, &len32); + APP_ERROR_CHECK(err_code); + + err_code = ser_sd_transport_rx_free(p_data); + APP_ERROR_CHECK(err_code); + + err_code = nrf_queue_push(&m_sd_ble_evt_mailbox, &item); + APP_ERROR_CHECK(err_code); + + ser_app_hal_nrf_evt_pending(); +} +#endif + +#if defined(ANT_STACK_SUPPORT_REQD) +static void ser_softdevice_ant_evt_handler(uint8_t * p_data, uint16_t length) +{ + ser_ant_sd_handler_evt_data_t item; + uint32_t err_code; + uint32_t len32 = sizeof (item.evt_data); + + err_code = ant_event_dec(p_data, length, (ant_evt_t *)item.evt_data, &len32); + APP_ERROR_CHECK(err_code); + + err_code = ser_sd_transport_rx_free(p_data); + APP_ERROR_CHECK(err_code); + + err_code = nrf_queue_push(&m_sd_ant_evt_mailbox, &item); + APP_ERROR_CHECK(err_code); + + ser_app_hal_nrf_evt_pending(); +} +#endif + +void ser_softdevice_flash_operation_success_evt(bool success) +{ + uint32_t evt_type = success ? NRF_EVT_FLASH_OPERATION_SUCCESS : + NRF_EVT_FLASH_OPERATION_ERROR; + + uint32_t err_code = nrf_queue_push(&m_sd_soc_evt_mailbox, &evt_type); + APP_ERROR_CHECK(err_code); + + ser_app_hal_nrf_evt_pending(); +} + +/** + * @brief Function called while waiting for connectivity chip response. It handles incoming events. + */ +static void ser_sd_rsp_wait(void) +{ + do + { + (void)sd_app_evt_wait(); + + //intern_softdevice_events_execute(); + } + while (ser_sd_transport_is_busy()); +} + +uint32_t sd_evt_get(uint32_t * p_evt_id) +{ + return nrf_queue_pop(&m_sd_soc_evt_mailbox, p_evt_id); +} + +#if defined(BLE_STACK_SUPPORT_REQD) +uint32_t sd_ble_evt_get(uint8_t * p_data, uint16_t * p_len) +{ + uint32_t err_code = nrf_queue_pop(&m_sd_ble_evt_mailbox, p_data); + + if (err_code == NRF_SUCCESS) //if anything in the mailbox + { + if (((ble_evt_t *)p_data)->header.evt_len > *p_len) + { + err_code = NRF_ERROR_DATA_SIZE; + } + else + { + *p_len = ((ble_evt_t *)p_data)->header.evt_len; + } + } + else + { + err_code = NRF_ERROR_NOT_FOUND; + } + + return err_code; +} +#endif + +#if defined(ANT_STACK_SUPPORT_REQD) +uint32_t sd_ant_event_get(uint8_t* p_channel, uint8_t* p_event, uint8_t* p_ant_mesg) +{ + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_event); + SER_ASSERT_NOT_NULL(p_ant_mesg); + + uint32_t err_code; + + ser_ant_sd_handler_evt_data_t item; + + err_code = nrf_queue_pop(&m_sd_ant_evt_mailbox, &item); + + if (err_code == NRF_SUCCESS) + { + *p_event = ((ant_evt_t *)item.evt_data) -> event; + *p_channel = ((ant_evt_t *)item.evt_data) -> channel; + memcpy(p_ant_mesg, ((ant_evt_t *)item.evt_data) -> msg.evt_buffer, ANT_STACK_EVT_MSG_BUF_SIZE); + } else { + err_code = NRF_ERROR_NOT_FOUND; + } + + return err_code; +} +#endif + +#if defined(BLE_STACK_SUPPORT_REQD) +uint32_t sd_ble_evt_mailbox_length_get(uint32_t * p_mailbox_length) +{ + *p_mailbox_length = nrf_queue_utilization_get(&m_sd_ble_evt_mailbox); + return NRF_SUCCESS; +} +#endif + +#if (defined(S332) || defined(S212)) +uint32_t sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, + nrf_fault_handler_t fault_handler, + const char* p_license_key) +#else +uint32_t sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, + nrf_fault_handler_t assertion_handler) +#endif +{ + uint32_t err_code; + + err_code = ser_app_hal_hw_init(ser_softdevice_flash_operation_success_evt); + + if (err_code == NRF_SUCCESS) + { + connectivity_reset_low(); + + nrf_queue_reset(&m_sd_soc_evt_mailbox); + ser_sd_transport_evt_handler_t ble_evt_handler = NULL; + ser_sd_transport_evt_handler_t ant_evt_handler = NULL; + +#ifdef BLE_STACK_SUPPORT_REQD + ble_evt_handler = ser_softdevice_ble_evt_handler; + nrf_queue_reset(&m_sd_ble_evt_mailbox); +#endif // BLE_STACK_SUPPORT_REQD + +#ifdef ANT_STACK_SUPPORT_REQD + ant_evt_handler = ser_softdevice_ant_evt_handler; + nrf_queue_reset(&m_sd_ant_evt_mailbox); +#endif // ANT_STACK_SUPPORT_REQD + err_code = ser_sd_transport_open(ble_evt_handler, + ant_evt_handler, + ser_sd_rsp_wait, + os_rsp_set_handler, + NULL); + + if (err_code == NRF_SUCCESS) + { + connectivity_reset_high(); + } + + ser_app_hal_nrf_evt_irq_priority_set(); + } + + return err_code; +} + + +uint32_t sd_softdevice_disable(void) +{ + return ser_sd_transport_close(); +} + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/transport/ser_softdevice_handler.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/transport/ser_softdevice_handler.h new file mode 100644 index 0000000000000000000000000000000000000000..bc28eca9d01192b4b7fd13eafc7763f611ee4a43 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/application/transport/ser_softdevice_handler.h @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ser_app Application side code + * @ingroup ble_sdk_lib_serialization + */ + +/** @file + * + * @defgroup ser_softdevice_handler Serialization SoftDevice Handler + * @{ + * @ingroup ser_app + * + * @brief Serialization SoftDevice Handler on application side. + * + */ +#ifndef SER_SOFTDEVICE_HANDLER_H_ +#define SER_SOFTDEVICE_HANDLER_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Function for checking if there are any more events in the internal mailbox. + * + * @param[in] p_mailbox_length Pointer to mailbox length. + * + * @retval ::NRF_SUCCESS Length succesfully obtained. + * @retval ::NRF_ERROR_NULL Null pointer provided. + */ +uint32_t sd_ble_evt_mailbox_length_get(uint32_t * p_mailbox_length); + + +#ifdef __cplusplus +} +#endif + +#endif /* SER_SOFTDEVICE_HANDLER_H_ */ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ble_serialization.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ble_serialization.c new file mode 100644 index 0000000000000000000000000000000000000000..1305304bc3a5833b88212036f45d2fd865ebc45e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ble_serialization.c @@ -0,0 +1,549 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_serialization.h" +#include "nrf_error.h" +#include "app_util.h" +#include +#include + +uint32_t ser_ble_cmd_rsp_status_code_enc(uint8_t op_code, + uint32_t command_status, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + uint32_t index = 0; + + SER_ASSERT_LENGTH_LEQ(SER_CMD_RSP_HEADER_SIZE, *p_buf_len); + + //Encode Op Code. + p_buf[index++] = op_code; + + //Encode Status. + index += uint32_encode(command_status, &(p_buf[index])); + *p_buf_len = index; + + return NRF_SUCCESS; +} + + +uint32_t ser_ble_cmd_rsp_result_code_dec(uint8_t const * const p_buf, + uint32_t * const p_pos, + uint32_t packet_len, + uint8_t op_code, + uint32_t * const p_result_code) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_pos); + SER_ASSERT_NOT_NULL(p_result_code); + + if (packet_len < SER_CMD_RSP_HEADER_SIZE) + { + return NRF_ERROR_DATA_SIZE; + } + + if (p_buf[(*p_pos)] != op_code) + { + return NRF_ERROR_INVALID_DATA; + } + + *p_result_code = uint32_decode(&(p_buf[(*p_pos) + SER_CMD_RSP_STATUS_CODE_POS])); + *p_pos += SER_CMD_RSP_HEADER_SIZE; + + return NRF_SUCCESS; +} + + +uint32_t ser_ble_cmd_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t op_code, + uint32_t * const p_result_code) +{ + uint32_t index = 0; + uint32_t result_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, op_code, + p_result_code); + + if (result_code != NRF_SUCCESS) + { + return result_code; + } + + if (index != packet_len) + { + return NRF_ERROR_DATA_SIZE; + } + + return NRF_SUCCESS; +} + +uint32_t uint32_t_enc(void const * const p_field, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_field); + SER_ASSERT_NOT_NULL(p_index); + + uint32_t * p_uint32 = (uint32_t *)p_field; + + SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index); + + *p_index += uint32_encode(*p_uint32, &p_buf[*p_index]); + + return NRF_SUCCESS; +} + +uint32_t uint32_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * p_field) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_index); + SER_ASSERT_NOT_NULL(p_field); + + uint32_t * p_uint32 = (uint32_t *)p_field; + + SER_ASSERT_LENGTH_LEQ(4, ((int32_t)buf_len - *p_index)); + + *p_uint32 = uint32_decode(&p_buf[*p_index]); + *p_index += 4; + + return NRF_SUCCESS; +} + +uint32_t uint16_t_enc(const void * const p_field, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + uint16_t * p_u16 = (uint16_t *)p_field; + + SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); + + *p_index += uint16_encode(*p_u16, &p_buf[*p_index]); + + return NRF_SUCCESS; +} + +uint32_t uint16_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * p_field) +{ + uint16_t * p_u16 = (uint16_t *)p_field; + + SER_ASSERT_LENGTH_LEQ(2, ((int32_t)buf_len - *p_index)); + + *p_u16 = uint16_decode(&p_buf[*p_index]); + *p_index += 2; + + return NRF_SUCCESS; +} + +void uint16_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const index, + uint16_t * const value) +{ + SER_ASSERT_VOID_RETURN(*index + 2 <= buf_len); + *value = uint16_decode(&p_buf[*index]); + *index += 2; +} + +uint32_t uint8_t_enc(const void * const p_field, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); + + uint8_t * p_u8 = (uint8_t *)p_field; + p_buf[*p_index] = *p_u8; + *p_index += 1; + + return NRF_SUCCESS; +} + +uint32_t uint8_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * p_field) +{ + uint8_t * p_u8 = (uint8_t *)p_field; + + SER_ASSERT_LENGTH_LEQ(1, ((int32_t)buf_len - *p_index)); + *p_u8 = p_buf[*p_index]; + *p_index += 1; + + return NRF_SUCCESS; +} + +void uint8_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const index, + uint8_t * const value) +{ + SER_ASSERT_VOID_RETURN(*index + 1 <= buf_len); + *value = p_buf[*index]; + *index += 1; +} + + +void int8_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const index, + int8_t * const value) +{ + SER_ASSERT_VOID_RETURN(*index + 1 <= buf_len); + *value = p_buf[*index]; + *index += 1; +} + +uint32_t len8data_enc(uint8_t const * const p_data, + uint8_t const dlen, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + uint32_t err_code = NRF_SUCCESS; + + err_code = uint8_t_enc(&dlen, p_buf, buf_len, p_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = buf_enc(p_data, dlen, p_buf, buf_len, p_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t len8data_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint8_t * * const pp_data, + uint8_t * const p_len) +{ + uint32_t err_code = NRF_SUCCESS; + uint16_t out_buf_len = *p_len; + + err_code = uint8_t_dec(p_buf, buf_len, p_index, p_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = buf_dec(p_buf, buf_len, p_index, pp_data, out_buf_len, *p_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t len16data_enc(uint8_t const * const p_data, + uint16_t const dlen, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + uint32_t err_code = NRF_SUCCESS; + + err_code = uint16_t_enc(&dlen, p_buf, buf_len, p_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = buf_enc(p_data, dlen, p_buf, buf_len, p_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t len16data_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint8_t * * const pp_data, + uint16_t * const p_dlen) +{ + uint32_t err_code = NRF_SUCCESS; + uint16_t out_buf_len = *p_dlen; + + err_code = uint16_t_dec(p_buf, buf_len, p_index, p_dlen); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = buf_dec(p_buf, buf_len, p_index, pp_data, out_buf_len, *p_dlen); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t count16_cond_data16_enc(uint16_t const * const p_data, + uint16_t const count, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + uint32_t i = 0; + + SER_ASSERT_LENGTH_LEQ(3, ((int32_t)buf_len - *p_index)); + *p_index += uint16_encode(count, &p_buf[*p_index]); + + if (p_data) + { + SER_ASSERT_LENGTH_LEQ((int32_t)(2 * count + 1), ((int32_t)buf_len - (int32_t) * p_index)); + p_buf[*p_index] = SER_FIELD_PRESENT; + *p_index += 1; + + //memcpy may fail in case of Endianness difference between application and connectivity processor + for (i = 0; i < count; i++) + { + *p_index += uint16_encode(p_data[i], &p_buf[*p_index]); + } + } + else + { + SER_ASSERT_LENGTH_LEQ((1), ((int32_t)buf_len - *p_index)); + p_buf[*p_index] = SER_FIELD_NOT_PRESENT; + *p_index += 1; + } + + return NRF_SUCCESS; +} + +uint32_t count16_cond_data16_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint16_t * * const pp_data, + uint16_t * const p_count) + +{ + uint16_t count = 0; + uint8_t is_present = 0; + uint16_t i; + + SER_ASSERT_NOT_NULL(p_count); + SER_ASSERT_NOT_NULL(pp_data); + SER_ASSERT_NOT_NULL(*pp_data); + + SER_ASSERT_LENGTH_LEQ(3, ((int32_t)buf_len - (*p_index))); + + uint16_dec(p_buf, buf_len, p_index, &count); + + if (count > *p_count) + { + return NRF_ERROR_DATA_SIZE; + } + + SER_ASSERT_LENGTH_LEQ(count, *p_count); + + uint8_dec(p_buf, buf_len, p_index, &is_present); + + if (!is_present) + { + *p_count = count; + *pp_data = NULL; + return NRF_SUCCESS; + } + else + { + for (i = 0; i < count; i++ ) + { + uint16_dec(p_buf, buf_len, p_index, &((&(**pp_data))[i]) ); + } + *p_count = i; + } + return NRF_SUCCESS; +} + + + +uint32_t cond_len16_cond_data_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint8_t * * const pp_data, + uint16_t * * const pp_len) +{ + SER_ASSERT_NOT_NULL(pp_len); + SER_ASSERT_NOT_NULL(*pp_len); + SER_ASSERT_NOT_NULL(pp_data); + SER_ASSERT_NOT_NULL(*pp_data); + + SER_ASSERT_LENGTH_LEQ(2, ((int32_t)buf_len - (*p_index))); + uint8_t is_present = 0; + + uint8_dec(p_buf, buf_len, p_index, &is_present); + + if (!is_present) + { + *pp_len = NULL; //if length field is not present + (*p_index)++; //then data can not be present + *pp_data = NULL; + return NRF_SUCCESS; + } + else + { + return len16data_dec(p_buf, buf_len, p_index, pp_data, *pp_len); + } +} + +uint32_t op_status_enc(uint8_t op_code, + uint32_t return_code, + uint8_t * const p_buff, + uint32_t * const p_buff_len, + uint32_t * const p_index) +{ + SER_ASSERT_NOT_NULL(p_buff); + SER_ASSERT_NOT_NULL(p_buff_len); + SER_ASSERT_NOT_NULL(p_index); + SER_ASSERT_LENGTH_LEQ(SER_CMD_RSP_HEADER_SIZE, *p_buff_len - *p_index); + + //Encode Op Code. + p_buff[(*p_index)++] = op_code; + //Encode Status. + *p_index += uint32_encode(return_code, &(p_buff[*p_index])); + //update size of used buffer + *p_buff_len = *p_index; + + return NRF_SUCCESS; +} + +uint32_t op_status_cond_uint16_enc(uint8_t op_code, + uint32_t return_code, + uint16_t value, + uint8_t * const p_buff, + uint32_t * const p_buff_len, + uint32_t * const p_index) +{ + uint32_t status_code; + uint32_t init_buff_len = *p_buff_len; + + status_code = op_status_enc(op_code, return_code, p_buff, p_buff_len, p_index); + SER_ASSERT(status_code == NRF_SUCCESS, status_code); + + if (return_code == NRF_SUCCESS) //Add 16bit value when return_code is a success + { + *p_buff_len = init_buff_len; //restore original value - it has been modified by op_status_enc + status_code = uint16_t_enc(&value, p_buff, *p_buff_len, p_index); + *p_buff_len = *p_index; + SER_ASSERT(status_code == NRF_SUCCESS, status_code); + } + + return status_code; +} + +uint32_t buf_enc(uint8_t const * const p_data, + uint16_t const dlen, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + uint32_t err_code = NRF_SUCCESS; + uint8_t is_present = (p_data == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; + + err_code = uint8_t_enc(&is_present, p_buf, buf_len, p_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (p_data) + { + SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index)); + memcpy(&p_buf[*p_index], p_data, dlen); + *p_index += dlen; + } + + return err_code; +} + +uint32_t buf_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint8_t * * const pp_data, + uint16_t data_len, + uint16_t dlen) +{ + uint8_t is_present = 0; + + SER_ASSERT_LENGTH_LEQ(1, ((int32_t)buf_len - *p_index)); + uint8_dec(p_buf, buf_len, p_index, &is_present); + + if (is_present == SER_FIELD_PRESENT) + { + SER_ASSERT_NOT_NULL(pp_data); + SER_ASSERT_NOT_NULL(*pp_data); + SER_ASSERT_LENGTH_LEQ(dlen, data_len); + SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index)); + memcpy(*pp_data, &p_buf[*p_index], dlen); + *p_index += dlen; + } + else + { + if (pp_data) + { + *pp_data = NULL; + } + } + return NRF_SUCCESS; +} + +uint32_t uint8_vector_enc(uint8_t const * const p_data, + uint16_t const dlen, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + + SER_ASSERT_NOT_NULL(p_data); + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_index); + SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index)); + memcpy(&p_buf[*p_index], p_data, dlen); + *p_index += dlen; + + return NRF_SUCCESS; +} + +uint32_t uint8_vector_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint8_t * const p_data, + uint16_t dlen) +{ + SER_ASSERT_NOT_NULL(p_data); + SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index)); + memcpy(p_data, &p_buf[*p_index], dlen); + *p_index += dlen; + + return NRF_SUCCESS; +} + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ble_serialization.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ble_serialization.h new file mode 100644 index 0000000000000000000000000000000000000000..92b20892e6de220e1b047a7158d295b5db939707 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ble_serialization.h @@ -0,0 +1,1100 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_SERIALIZATION_H__ +#define BLE_SERIALIZATION_H__ + +#include "nordic_common.h" +#include "nrf_error.h" +#include +#include +#include "cond_field_serialization.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Types of serialization packets. */ +typedef enum +{ + SER_PKT_TYPE_CMD = 0, /**< Command packet type. */ + SER_PKT_TYPE_RESP, /**< Command Response packet type. */ + SER_PKT_TYPE_EVT, /**< Event packet type. */ + SER_PKT_TYPE_DTM_CMD, /**< DTM Command packet type. */ + SER_PKT_TYPE_DTM_RESP, /**< DTM Response packet type. */ + SER_PKT_TYPE_RESET_CMD, /**< System Reset Command packet type. */ +#if defined(ANT_STACK_SUPPORT_REQD) + SER_PKT_TYPE_ANT_CMD, /**< ANT Command packet type. */ + SER_PKT_TYPE_ANT_RESP, /**< ANT Response packet type. */ + SER_PKT_TYPE_ANT_EVT, /**< ANT Event packet type. */ +#endif + SER_PKT_TYPE_MAX /**< Upper bound. */ +} ser_pkt_type_t; + +#define LOW16(a) ((uint16_t)((a & 0x0000FFFF) >> 0)) +#define HIGH16(a) ((uint16_t)((a & 0xFFFF0000) >> 16)) + +//lint -esym(516,__INTADDR__) Symbol '__INTADDR__()' has arg. type conflict +//lint -esym(628,__INTADDR__) no argument information provided for function '__INTADDR__()' + +/** Size in bytes of the Error Code field in a Command Response packet. */ +#define SER_ERR_CODE_SIZE 4 +/** Size in bytes of the Packet Type field (@ref ser_pkt_type_t). */ +#define SER_PKT_TYPE_SIZE 1 +/** Size in bytes of the Operation Code field. */ +#define SER_OP_CODE_SIZE 1 + +/** Position of the Packet Type field in a serialized packet buffer. */ +#define SER_PKT_TYPE_POS 0 +/** Position of the Operation Code field in a serialized packet buffer. */ +#define SER_PKT_OP_CODE_POS (SER_PKT_TYPE_SIZE) +/** Position of the Data in a serialized packet buffer. */ +#define SER_PKT_DATA_POS (SER_PKT_TYPE_SIZE + SER_OP_CODE_SIZE) + +/** Position of the Operation Code field in a command buffer. */ +#define SER_CMD_OP_CODE_POS 0 +/** Position of the Data in a command buffer.*/ +#define SER_CMD_DATA_POS (SER_OP_CODE_SIZE) +/** Size of the Command header. */ +#define SER_CMD_HEADER_SIZE (SER_OP_CODE_SIZE) +/** Size of the Command Response header. */ +#define SER_CMD_RSP_HEADER_SIZE (SER_OP_CODE_SIZE + SER_ERR_CODE_SIZE) +/** Position of the Command Response code. */ +#define SER_CMD_RSP_STATUS_CODE_POS (SER_OP_CODE_SIZE) + +/** Size of event ID field. */ +#define SER_EVT_ID_SIZE 2 +/** Position of event ID field. */ +#define SER_EVT_ID_POS 0 +/** Size of event header. */ +#define SER_EVT_HEADER_SIZE (SER_EVT_ID_SIZE) +/** Size of event connection handler. */ +#define SER_EVT_CONN_HANDLE_SIZE 2 + +#if defined(ANT_STACK_SUPPORT_REQD) +/** Size of event ID field. */ +#define SER_ANT_EVT_ID_SIZE 2 +/** Position of event ID field. */ +#define SER_ANT_EVT_ID_POS 0 +/** Size of event header. */ +#define SER_ANT_EVT_HEADER_SIZE (SER_ANT_EVT_ID_SIZE) +#endif + +/** Position of the Op Code in the DTM command buffer.*/ +#define SER_DTM_CMD_OP_CODE_POS 0 +/** Position of the data in the DTM command buffer.*/ +#define SER_DTM_CMD_DATA_POS 1 + +/** Position of the Op Code in the DTM command response buffer.*/ +#define SER_DTM_RESP_OP_CODE_POS 1 +/** Position of the status field in the DTM command response buffer.*/ +#define SER_DTM_RESP_STATUS_POS 2 + +/** Value to indicate that an optional field is encoded in the serialized packet, e.g. white list.*/ +#define SER_FIELD_PRESENT 0x01 +/** Value to indicate that an optional field is not encoded in the serialized packet. */ +#define SER_FIELD_NOT_PRESENT 0x00 + + +/** Enable SER_ASSERT<*> asserts */ +#define SER_ASSERTS_ENABLED 1 + +/** Returns with error code if expr is not true. It is used for checking error which should be + * checked even when SER_ASSERTS_ENABLED is not set. */ +#define SER_ERROR_CHECK(expr, error_code) do { if (!(expr)) return (error_code); } while (0) + + +#ifdef SER_ASSERTS_ENABLED +/** Returns with error code if expr is not true. */ +#define SER_ASSERT(expr, error_code) SER_ERROR_CHECK(expr, error_code) +/** Returns if expression is not true. */ +#define SER_ASSERT_VOID_RETURN(expr) do { if (!(expr)) return; } while (0) +/** Returns with \ref NRF_ERROR_INVALID_LENGTH if len is not less or equal to maxlen. */ +#define SER_ASSERT_LENGTH_LEQ(len, maxlen) \ + SER_ASSERT((len) <= (maxlen), NRF_ERROR_INVALID_LENGTH) +/** Returns with \ref NRF_ERROR_INVALID_LENGTH if actual_len is not equal to expected_len. */ +#define SER_ASSERT_LENGTH_EQ(actual_len, expected_len) \ + SER_ASSERT((actual_len) == (expected_len), NRF_ERROR_INVALID_LENGTH) +/** Returns with \ref NRF_ERROR_NULL if pointer is null. */ +#define SER_ASSERT_NOT_NULL(ptr) SER_ASSERT((ptr) != NULL, NRF_ERROR_NULL) +#else +#define SER_ASSERT(expr, error_code) +#define SER_ASSERT_VOID_RETURN(expr) +#define SER_ASSERT_LENGTH_LEQ(len, maxlen) UNUSED_VARIABLE(maxlen) +#define SER_ASSERT_LENGTH_EQ(actual_len, expected_len) +#define SER_ASSERT_NOT_NULL(ptr) +#endif + +#if defined(BLE_GATT_MTU_SIZE_DEFAULT) && !defined(GATT_MTU_SIZE_DEFAULT) +#define GATT_MTU_SIZE_DEFAULT BLE_GATT_MTU_SIZE_DEFAULT +#endif +/** Maximum length of p_value in \ref ble_gattc_write_params_t. See Bluetooth 4.0 spec: 3.4.5.1 and + * 3.4.5.3. */ +#define BLE_GATTC_WRITE_P_VALUE_LEN_MAX (GATT_MTU_SIZE_DEFAULT - 3) + +/** See Bluetooth 4.0 spec: 3.4.4.7. */ +#define BLE_GATTC_HANDLE_COUNT_LEN_MAX ((GATT_MTU_SIZE_DEFAULT - 1) / 2) + +/** Subtract 1 from X if X is greater than 0. */ +#define SUB1(X) (((X)>0) ? ((X)-1) : (X)) + +static inline void static_force_impl_castable_p_void(void const * const p) {} +/** Force the argument to be a double pointer. */ +#define STATIC_FORCE_PP(PP) static_force_impl_castable_p_void(*(PP)) + +/** Field decoder for special structures containing variable length data. */ +typedef uint32_t (*field_ext_decoder_handler_t)(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_length, + void * p_field); + + +/** Push uint8_t field into the output packet. */ +#define SER_PUSH_uint8(P_VAR) do { \ + err_code = uint8_t_enc((P_VAR), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push uint16_t field into the output packet. */ +#define SER_PUSH_uint16(P_VAR) do { \ + err_code = uint16_t_enc((P_VAR), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push uint32_t field into the output packet. */ +#define SER_PUSH_uint32(P_VAR) do { \ + err_code = uint32_t_enc((P_VAR), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push int8_t field into the output packet. */ +#define SER_PUSH_int8(P_VAR) SER_PUSH_uint8(P_VAR) + +/** Push uint16_t field into the output packet. */ +#define SER_PUSH_int16(P_VAR) SER_PUSH_uint16(P_VAR) + +/** Push uint32_t field into the output packet. */ +#define SER_PUSH_int32(P_VAR) SER_PUSH_uint32(P_VAR) + +/** Push a constant length array of bytes into the output packet. */ +#define SER_PUSH_uint8array(P_DATA, LEN) do { \ + err_code = uint8_vector_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push a variable length (8-bit) array of bytes into the output packet. */ +#define SER_PUSH_len8data(P_DATA, LEN) do { \ + err_code = len8data_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push a variable length (16-bit) array of bytes into the output packet. */ +#define SER_PUSH_len16data(P_DATA, LEN) do { \ + err_code = len16data_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push a variable length (16-bit) array of 16-bit words into the output packet. */ +#define SER_PUSH_len16data16(P_DATA, LEN) do { \ + err_code = count16_cond_data16_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push a buffer into the output packet. */ +#define SER_PUSH_buf(P_DATA, LEN) do { \ + err_code = buf_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push a structure into the output packet. */ +#define SER_PUSH_FIELD(P_VAR, P_ENCODER) do { \ + err_code = field_enc((P_VAR), p_buf, buf_len, p_index, (P_ENCODER)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push an array of structures into the output packet. */ +#define SER_PUSH_FIELD_ARRAY(P_ARRAY, P_ENCODER, COUNT) do { \ + for (uint32_t _idx = 0; _idx < (COUNT); ++_idx) \ + { \ + SER_PUSH_FIELD(&((P_ARRAY)[_idx]),P_ENCODER);\ + } \ + } while (0) + +/** Conditionally push a field if the specified pointer is not null. */ +#define SER_PUSH_COND(P_VAR, P_ENCODER) do { \ + err_code = cond_field_enc((P_VAR), p_buf, buf_len, p_index, (P_ENCODER)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + + +/** Pull a uint8_t field from the input packet. */ +#define SER_PULL_uint8(P_VAR) do { \ + err_code = uint8_t_dec(p_buf, packet_len, p_index, (P_VAR)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a uint16_t field from the input packet. */ +#define SER_PULL_uint16(P_VAR) do { \ + err_code = uint16_t_dec(p_buf, packet_len, p_index, (P_VAR)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a uint32_t field from the input packet. */ +#define SER_PULL_uint32(P_VAR) do { \ + err_code = uint32_t_dec(p_buf, packet_len, p_index, (P_VAR)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull an int8_t field from the input packet. */ +#define SER_PULL_int8(P_VAR) SER_PULL_uint8(P_VAR) + +/** Pull an int16_t field from the input packet. */ +#define SER_PULL_int16(P_VAR) SER_PULL_uint16(P_VAR) + +/** Pull an int32_t field from the input packet. */ +#define SER_PULL_int32(P_VAR) SER_PULL_uint32(P_VAR) + +/** Pull a constant length byte array from the input packet. */ +#define SER_PULL_uint8array(P_DATA, LEN) do { \ + err_code = uint8_vector_dec(p_buf, packet_len, p_index, (P_DATA), (LEN)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a variable length (8-bit) byte array from the input packet. */ +#define SER_PULL_len8data(PP_DATA, LEN) do { \ + STATIC_FORCE_PP(PP_DATA); \ + err_code = len8data_dec(p_buf, packet_len, p_index, (PP_DATA), (LEN)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a variable length (16-bit) byte array from the input packet. */ +#define SER_PULL_len16data(PP_DATA, P_LEN) do { \ + STATIC_FORCE_PP(PP_DATA); \ + err_code = len16data_dec(p_buf, packet_len, p_index, (PP_DATA), (P_LEN)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a variable length (16-bit) word (16-bit) array from the input packet. */ +#define SER_PULL_len16data16(PP_DATA, P_LEN) do { \ + STATIC_FORCE_PP(PP_DATA); \ + err_code = count16_cond_data16_dec(p_buf, packet_len, p_index, (PP_DATA), (P_LEN)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a buffer from the input packet. */ +#define SER_PULL_buf(PP_DATA, OUT_BUF_LEN, LEN) do { \ + STATIC_FORCE_PP(PP_DATA); \ + err_code = buf_dec(p_buf, packet_len, p_index, (PP_DATA), (OUT_BUF_LEN), (LEN)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a structure from the input packet. */ +#define SER_PULL_FIELD(P_VAR, P_DECODER) do { \ + err_code = field_dec(p_buf, packet_len, p_index, (P_VAR), (P_DECODER)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull an array of structures from the input packet. */ +#define SER_PULL_FIELD_ARRAY(P_ARRAY, P_DECODER, COUNT) do { \ + for (uint32_t _idx = 0; _idx < (COUNT); ++_idx) \ + { \ + SER_PULL_FIELD(&((P_ARRAY)[_idx]),P_DECODER); \ + } \ + } while (0) + +/** Conditionally pull a structure from the input packet. */ +#define SER_PULL_COND(PP_VAR, P_DECODER) do { \ + STATIC_FORCE_PP(PP_VAR); \ + err_code = cond_field_dec(p_buf, packet_len, p_index, (void * *)(PP_VAR), (P_DECODER)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + + +/** Start the encoding of a structure and prepare local variables for the usage of SER_PUSH_ macros. */ +#define SER_STRUCT_ENC_BEGIN(STRUCT_TYPE) \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_index); \ + SER_ASSERT_NOT_NULL(p_void_struct); \ + STRUCT_TYPE * p_struct = (STRUCT_TYPE *) p_void_struct; \ + uint32_t err_code = NRF_SUCCESS + +/** End the encoding of a structure. */ +#define SER_STRUCT_ENC_END return err_code + +/** Start the decoding of a structure and prepare local variables for the usage of SER_PULL_ macros. */ +#define SER_STRUCT_DEC_BEGIN(STRUCT_TYPE) \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_index); \ + SER_ASSERT_NOT_NULL(p_void_struct); \ + STRUCT_TYPE * p_struct = (STRUCT_TYPE *) p_void_struct; \ + uint32_t err_code = NRF_SUCCESS; \ + uint32_t packet_len = buf_len + +/** End the encoding of a structure. */ +#define SER_STRUCT_DEC_END return err_code + + +/** Start the encoding of command request and prepare local variables for the usage of SER_PUSH_ macros. */ +#define SER_REQ_ENC_BEGIN(OPCODE) \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_buf_len); \ + \ + uint32_t index = 0; \ + uint32_t * const p_index = &index; \ + uint32_t err_code = NRF_SUCCESS; \ + uint32_t buf_len = *p_buf_len; \ + \ + uint8_t opcode = (OPCODE); \ + SER_PUSH_uint8(&opcode) + +/** End the encoding of command request. */ +#define SER_REQ_ENC_END \ + *p_buf_len = index; \ + return NRF_SUCCESS \ + +/** Start the decoding of command response that does not contain any data except the result code. */ +#define SER_RSP_DEC_RESULT_ONLY(OPCODE) \ + return ser_ble_cmd_rsp_dec(p_buf, packet_len, (OPCODE), p_result_code) + +/** Start the decoding of command response and prepare local variables for the usage of SER_PULL_ macros. */ +#define SER_RSP_DEC_BEGIN(OPCODE) \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_result_code); \ + uint32_t err_code = NRF_SUCCESS; \ + uint32_t index = 0; \ + uint32_t * const p_index = &index; \ + /* Decode the result code and exit if decoding has failed or \ + the decoded result is not NRF_SUCCESS. */ \ + err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, (OPCODE), p_result_code); \ + \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + if (*p_result_code != NRF_SUCCESS) \ + { \ + SER_ASSERT_LENGTH_EQ(index, packet_len); \ + return NRF_SUCCESS; \ + } + +/** End the decoding of command response. */ +#define SER_RSP_DEC_END \ + /* Require all data to be pulled. */ \ + SER_ASSERT_LENGTH_EQ(index, packet_len); \ + return err_code + + +/** Start the decoding of command request and prepare local variables for the usage of SER_PULL_ macros. */ +#define SER_REQ_DEC_BEGIN(OPCODE) \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT(packet_len>0, NRF_ERROR_INVALID_PARAM); \ + uint32_t index = 0; \ + uint32_t * const p_index = &index; \ + uint32_t err_code = NRF_SUCCESS; \ + SER_ASSERT(p_buf[index] == (OPCODE), NRF_ERROR_INVALID_PARAM); \ + (void)err_code; \ + (void)p_index; \ + ++index + +/** End the decoding of command request. */ +#define SER_REQ_DEC_END \ + SER_ASSERT_LENGTH_EQ(index, packet_len); \ + return NRF_SUCCESS + +/** Start the encoding of command response and prepare local variables for the usage of SER_PUSH_ macros. */ +#define SER_RSP_ENC_BEGIN(OPCODE) \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_buf_len); \ + uint32_t index = 0; \ + uint32_t * const p_index = &index; \ + uint32_t err_code = NRF_SUCCESS; \ + uint32_t buf_len = *p_buf_len; \ + /* Push the opcode + result and exit if result \ + is not NRF_SUCCESS. */ \ + uint8_t opcode = (OPCODE); \ + SER_PUSH_uint8(&opcode); \ + SER_PUSH_uint32(&return_code); \ + \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + if (return_code != NRF_SUCCESS) \ + { \ + SER_RSP_ENC_END; \ + } + +/** Start the encoding of command response that contains the result code only. */ +#define SER_RSP_ENC_RESULT_ONLY(OPCODE) \ + return ser_ble_cmd_rsp_status_code_enc((OPCODE), return_code, p_buf, p_buf_len) + +/** End the encoding of command response. */ +#define SER_RSP_ENC_END \ + *p_buf_len = index; \ + return NRF_SUCCESS + + +/** Start the encoding of an event and prepare local variables for the usage of SER_PUSH_ macros. */ +#define SER_EVT_ENC_BEGIN(EVT_HEADER) \ + SER_ASSERT_NOT_NULL(p_event); \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_buf_len); \ + SER_ASSERT(p_event->header.evt_id == (EVT_HEADER), NRF_ERROR_INVALID_PARAM); \ + uint32_t index = 0; \ + uint32_t * p_index = &index; \ + uint32_t buf_len = *p_buf_len; \ + uint32_t err_code = NRF_SUCCESS; \ + uint16_t evt_header = (EVT_HEADER); \ + /* Push event header. */ \ + SER_PUSH_uint16(&evt_header) + +/** End the encoding of an event. */ +#define SER_EVT_ENC_END \ + *p_buf_len = index; \ + return err_code + + +/** Start the decoding of an event that has an event-specific data structure + and prepare local variables for the usage of SER_PULL_ macros. */ +#define SER_EVT_DEC_BEGIN(EVT_CODE, EVT_GROUP, EVT_NAME) \ + uint32_t err_code = NRF_SUCCESS; \ + uint32_t index = 0; \ + uint32_t * p_index = &index; \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_event_len); \ + /* Calculate the base event structure length */ \ + /* and make sure that there is enough free space */ \ + /* in the output buffer. */ \ + uint32_t evt_struct_len = \ + offsetof(ble_evt_t, evt.EVT_GROUP##_evt.params) \ + - offsetof(ble_evt_t, evt) \ + + sizeof(ble_##EVT_GROUP##_evt_##EVT_NAME##_t); \ + SER_ASSERT_LENGTH_LEQ(evt_struct_len, *p_event_len); \ + *p_event_len -= evt_struct_len; \ + /* Some structures contains variable length arrays */ \ + /* and the overall size may be greater. */ \ + uint32_t evt_extended_len = 0; \ + (void) evt_extended_len; \ + p_event->header.evt_id = EVT_CODE + +/** Start the decoding of an event that has no event-specific data structure. + and prepare local variables for the usage of SER_PULL_ macros. */ +#define SER_EVT_DEC_BEGIN_NO_STRUCT(EVT_CODE, EVT_GROUP) \ + uint32_t err_code = NRF_SUCCESS; \ + uint32_t index = 0; \ + uint32_t * p_index = &index; \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_event_len); \ + /* Calculate the base event structure length */ \ + /* and make sure that there is enough free space */ \ + /* in the output buffer. */ \ + uint32_t evt_struct_len = \ + offsetof(ble_evt_t, evt.EVT_GROUP##_evt.params) \ + - offsetof(ble_evt_t, evt) ; \ + SER_ASSERT_LENGTH_LEQ(evt_struct_len, *p_event_len); \ + *p_event_len -= evt_struct_len; \ + /* Some structures contain variable length arrays */ \ + /* and the overall size may be greater. */ \ + uint32_t evt_extended_len = 0; \ + (void) evt_extended_len; \ + p_event->header.evt_id = EVT_CODE + +/** End the decoding of an event. */ +#define SER_EVT_DEC_END \ + SER_ASSERT_LENGTH_EQ(index, packet_len); \ + /*p_event_len = index; */ \ + /*p_event->header.evt_len = index; */ \ + *p_event_len = evt_struct_len + evt_extended_len; \ + return NRF_SUCCESS + +/** Push an event-specific special field that contains variable length fields and get the extended data size. */ +#define SER_PULL_FIELD_EXTENDED(P_VAR, P_DECODER) \ + do \ + { \ + uint32_t field_ext_len = *p_event_len; \ + err_code = field_ext_dec(p_buf, packet_len, p_index, &field_ext_len, (P_VAR), (P_DECODER)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + *p_event_len -= field_ext_len; \ + evt_extended_len += field_ext_len; \ + } while(0) \ + + +/** Generic command response status code encoder. */ +uint32_t ser_ble_cmd_rsp_status_code_enc(uint8_t op_code, + uint32_t command_status, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** Generic command response result code decoder. */ +uint32_t ser_ble_cmd_rsp_result_code_dec(uint8_t const * const p_buf, + uint32_t * const p_pos, + uint32_t packet_len, + uint8_t op_code, + uint32_t * const p_result_code); + +/** Generic command response decoder. */ +uint32_t ser_ble_cmd_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t op_code, + uint32_t * const p_result_code); + + + +/**@brief Function for safe field encoding field. + * + * @param[in] p_field Pointer to the input struct. Must not be a null. + * @param[in] p_buf Pointer to the beginning of the output buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. + * \c out: Index in the buffer to the first byte after the encoded data. + * @param[in] fp_field_encoder Pointer to the function that implements fields encoding. + * + * @return NRF_SUCCESS Field encoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_NULL p_field or fp_field_encoder is NULL. + */ +static inline uint32_t field_enc(void const * const p_field, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + field_encoder_handler_t fp_field_encoder) +{ + SER_ASSERT_NOT_NULL(fp_field_encoder); + SER_ASSERT_NOT_NULL(p_field); + + return fp_field_encoder(p_field, p_buf, buf_len, p_index); +} + +/**@brief Function for safe field decoding. + * + * Function checks if conditional field is present in the input buffer and if it is set, it calls + * the provided parser function that attempts to parse the buffer content to the known field. + * + * @param[in] p_buf Pointer to the beginning of the input buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of uint8 value in buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[in] p_field Pointer to the output location. + * @param[in] fp_field_decoder Pointer to the function that implements field decoding. + * + * @return NRF_SUCCESS Field decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_NULL p_field or fp_field_decoder is NULL. + */ +static inline uint32_t field_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_field, + field_decoder_handler_t fp_field_decoder) +{ + SER_ASSERT_NOT_NULL(fp_field_decoder); + SER_ASSERT_NOT_NULL(p_field); + + return fp_field_decoder(p_buf, buf_len, p_index, p_field); +} + +/**@brief Function for safe decoding of an event-specific field that contains extended data. + * + * Some event structures contain a variable length array (extended data), + * that may be written next to the event structure. + * + * @param[in] p_buf Pointer to the beginning of the input buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[in,out] p_ext_length \c in: Maximum size of extended data. + * \c out: Extended data length in bytes. + * @param[in] p_field Pointer to output location. + * @param[in] fp_field_decoder Pointer to the function that implements field decoding. + * + * @return NRF_SUCCESS Field decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_NULL p_field or fp_field_decoder is NULL. + */ +static inline uint32_t field_ext_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_length, + void * const p_field, + field_ext_decoder_handler_t fp_field_decoder) +{ + SER_ASSERT_NOT_NULL(fp_field_decoder); + SER_ASSERT_NOT_NULL(p_field); + + return fp_field_decoder(p_buf, buf_len, p_index, p_ext_length, p_field); +} + +/**@brief Function for safe encoding an uint16 value. + * + * Safe decoding of a uint16 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_field A uint16 value to be encoded. + * @param[out] p_buf Buffer containing the value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint16 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t uint16_t_enc(const void * const p_field, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +/**@brief Function for safe decoding of a uint16 value. + * + * Safe decoding of a uint16 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_buf Buffer containing the value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint16 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * @param[out] p_field Pointer to the location where the uint16 value will be decoded. + */ +uint32_t uint16_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * p_field); + +/**@brief Function for safe decoding of a uint16 value. + * + * Safe decoding of a uint16 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_buf Buffer containing the value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] index \c in: Index to the start of the uint16 value in buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * @param[out] value Decoded uint16 value. + */ +void uint16_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const index, + uint16_t * const value); + +/**@brief Function for safe encoding of a uint18 value. + * + * Safe decoding of a uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_buf Buffer containing the value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * @param[out] p_field Pointer to uint8 value to be encoded. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t uint8_t_enc(const void * const p_field, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +/**@brief Function for safe decoding of a uint8 value. + * + * Safe decoding of a uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_buf Buffer containing the value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * @param[out] p_field Pointer to the location for decoded uint8 value. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t uint8_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * p_field); + +/**@brief Function for safe decoding of a uint8 value. + * + * Safe decoding of a uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_buf Buffer containing the value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * @param[out] value Decoded uint8 value. + */ +void uint8_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const index, + uint8_t * const value); + +/**@brief Function for safe decoding of a uint18 value. + * + * Safe decoding of a uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_buf Buffer containing the value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * @param[out] value Decoded uint8 value. + */ +void int8_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const index, + int8_t * const value); + +/**@brief Function for safe encoding of a variable length field encoded as length(8bit) + data. + * + * Safe encoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[out] p_data Pointer to data to encode. + * @param[in] dlen Length of data to encode (0-255). + * @param[out] p_buf Buffer containing the value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t len8data_enc(uint8_t const * const p_data, + uint8_t const dlen, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +/**@brief Function for safe decoding of a variable length field encoded as length(8bit) + data. + * + * Safe decoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_buf Buffer containing the value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * @param[out] pp_data Pointer to decoded data (p_data is set to NULL in + * case data is not present in the buffer). + * @param[out] p_len Decoded length (0-255). + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t len8data_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint8_t * * const pp_data, + uint8_t * const p_len); + +/**@brief Function for safe encoding of a variable length field encoded as length(16 bit) + data. + * + * Safe encoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * It is possible that provided p_data is NULL. In that case, length is encoded and it is followed by + * SER_FIELD_NOT_PRESENT flag. Otherwise, the SER_FIELD_PRESENT flag precedes the data. + * + * @param[in] p_data Data to encode. + * @param[in] dlen Input data length (16 bit). + * @param[in] p_buf Pointer to the beginning of the output buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the encoded data. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t len16data_enc(uint8_t const * const p_data, + uint16_t const dlen, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +/**@brief Function for safe decoding of a variable length field encoded as length(16 bit) + data. + * + * Safe decoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Encoded data consists of a length field, a presence flag, and conditional data (present only if the presence flag + * is set). The p_data pointer cannot be NULL if the presence flag is set. + * + * @param[in] p_buf Pointer to the beginning of the input buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[in] pp_data Pointer to decoded data. + * @param[in] p_dlen Data length (16 bit). + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t len16data_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint8_t * * const pp_data, + uint16_t * const p_dlen); + + +/**@brief Function for safe encoding of a uint16 table with a given element count. + * + * Safe encoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * It is possible that the provided p_data is NULL. In that case, length is encoded and it is followed by a + * SER_FIELD_NOT_PRESENT flag. Otherwise, the SER_FIELD_PRESENT flag precedes the data. + * + * @param[in] p_data Data table to encode. + * @param[in] count Table element count. + * @param[in] p_buf Pointer to the beginning of the output buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the encoded data. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ + +uint32_t count16_cond_data16_enc(uint16_t const * const p_data, + uint16_t const count, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +/**@brief Function for safe decoding of a uint16 table with a given element count. + * + * Safe encoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * It is possible that the provided p_data is NULL. In that case, length is encoded and it is followed by a + * SER_FIELD_NOT_PRESENT flag. Otherwise, the SER_FIELD_PRESENT flag precedes the data. + * + * @param[in] p_buf Pointer to the beginning of the output buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the encoded data. + * @param[in] pp_data Pointer to the table to encode. + * @param[in,out] p_count Pointer to table element count - initialised with max count. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Initial count is smaller than actual. + */ + +uint32_t count16_cond_data16_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint16_t * * const pp_data, + uint16_t * const p_count); + + +/**@brief Function for safe decoding of a variable length field encoded as length(16 bit) + data. + * + * Safe decoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Encoded data consists of a presence flag, an optional length field, a second presence flag, and optional data. + * + * + * @param[in] p_buf Pointer to the beginning of the input buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[out] pp_data Pointer to decoded data. + * @param[out] pp_len Data length (16 bit). + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ + +uint32_t cond_len16_cond_data_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint8_t * * const pp_data, + uint16_t * * const pp_len); + +/**@brief Command response encoder - replacement of ser_ble_cmd_rsp_status_code_enc + * with layout aligned to the rest of encoder functions. + * + * @param[in] op_code Operation code - see BLE_GAP_SVCS. + * @param[in] return_code nRF error code. + * @param[in] p_buff Pointer to the start of pointer to decoded data. + * @param[in,out] p_buff_len \c in: Size of the buffer. + * \c out: Used bytes in the buffer. + * @param[in,out] p_buff_len \c in: Initial offset in the buffer. + * \c out: Final offset in the buffer. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_NULL Invalid pointer. + */ +uint32_t op_status_enc(uint8_t op_code, + uint32_t return_code, + uint8_t * const p_buff, + uint32_t * const p_buff_len, + uint32_t * const p_index); + +/**@brief Command response encoder with a conditional 16-bit field. + * + * @param[in] op_code Operation code - see BLE_GAP_SVCS. + * @param[in] return_code nRF error code. + * @param[in] value Optional 16-bit field encoded for return code == NRF_SUCCESS. + * @param[in] p_buff Pointer to the start of pointer to decoded data. + * @param[in,out] p_buff_len \c in: Size of the buffer. + * \c out: Used bytes in the buffer. + * @param[in,out] p_buff_len \c in: Initial offset in the buffer. + * \c out: Final offset in the buffer. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_NULL Invalid pointer. + */ + +uint32_t op_status_cond_uint16_enc(uint8_t op_code, + uint32_t return_code, + uint16_t value, + uint8_t * const p_buff, + uint32_t * const p_buff_len, + uint32_t * const p_index); + +/**@brief Function for safe encoding of a buffer of known size. + * + * Safe encoding of a buffer. Encoder assumes that the size is known to the decoder and it is not + * encoded here. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_data Data to encode. + * @param[in] dlen Input data length (16 bit). + * @param[in] p_buf Pointer to the beginning of the output buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the encoded data. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t buf_enc(uint8_t const * const p_data, + uint16_t const dlen, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +/**@brief Function for safe decoding of a buffer of known size. + * + * Safe decoding of a buffer of known size. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Encoded data consists of a presence flag and conditional data (present only if the presence flag + * is set). The p_data pointer cannot be NULL only if the presence flag is set. Length is provided + * as input to the function. + * + * @param[in] p_buf Pointer to the beginning of the input buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[in] pp_data Pointer to decoded data. + * @param[in] data_len Length of the buffer for decoded data (16 bit). + * @param[in] dlen Length of the data to decode (16 bit). + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t buf_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint8_t * * const pp_data, + uint16_t data_len, + uint16_t dlen); + +/**@brief Function for safe encoding of a uint32 value. + * + * Safe decoding of a uint32 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_field A uint32 value to be encoded. + * @param[out] p_buf Buffer containing the value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint32 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t uint32_t_enc(void const * const p_field, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +/**@brief Function for safe decoding of a uint32 value. + * + * Safe decoding of a uint32 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_buf Buffer containing the value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint32 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * @param[out] value Decoded uint32 value. + */ +uint32_t uint32_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * p_field); + +/**@brief Function for safe encoding of a uint8 vector. + * + * Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * * + * @param[in] p_data Data to encode. + * @param[in] dlen Input data length (16 bit). + * @param[in] p_buf Pointer to the beginning of the output buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the encoded data. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t uint8_vector_enc(uint8_t const * const p_data, + uint16_t const dlen, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +/**@brief Function for safe decoding a uint8 vector. + * + * Safe decoding of a buffer of known size. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Vector length is provided as input to the function. + * + * @param[in] p_buf Pointer to the beginning of the input buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[in] p_data Pointer to decoded data. + * @param[in] dlen Length of data to decode (16 bit). + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t uint8_vector_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint8_t * const p_data, + uint16_t dlen); + + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/cond_field_serialization.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/cond_field_serialization.c new file mode 100644 index 0000000000000000000000000000000000000000..ca51f62dcaa3b2bcbdabef825d407aa64e6c9db4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/cond_field_serialization.c @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_error.h" +#include "cond_field_serialization.h" +#include "ble_serialization.h" +#include + +uint32_t cond_field_enc(void const * const p_field, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + field_encoder_handler_t fp_field_encoder) +{ + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_LENGTH_LEQ(*p_index + 1, buf_len); + p_buf[*p_index] = (p_field == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; + *p_index += 1; + + if (p_field && (fp_field_encoder != NULL)) + { + err_code = fp_field_encoder(p_field, p_buf, buf_len, p_index); + } + + return err_code; +} + + +uint32_t cond_field_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * * const pp_field, + field_decoder_handler_t fp_field_decoder) +{ + uint32_t err_code = NRF_SUCCESS; + uint8_t is_present; + + SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); + uint8_dec(p_buf, buf_len, p_index, &is_present); + + if (is_present == SER_FIELD_PRESENT) + { + SER_ASSERT_NOT_NULL(pp_field); + SER_ASSERT_NOT_NULL(*pp_field); + + if (fp_field_decoder != NULL) + { + err_code = fp_field_decoder(p_buf, buf_len, p_index, *pp_field); + } + } + else if (is_present == SER_FIELD_NOT_PRESENT) + { + if (pp_field != NULL) + { + *pp_field = NULL; + } + } + else + { + err_code = NRF_ERROR_INVALID_DATA; + } + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/cond_field_serialization.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/cond_field_serialization.h new file mode 100644 index 0000000000000000000000000000000000000000..9ebad154559dc9bbf0ecd68ef11f0d75d746b8dc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/cond_field_serialization.h @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef COND_FIELD_SERIALIZATION_H__ +#define COND_FIELD_SERIALIZATION_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint32_t (*field_encoder_handler_t)(void const * const p_field, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +typedef uint32_t (*field_decoder_handler_t)(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * p_field); + +/**@brief Function for safe encoding of a conditional field. + * + * Function sets a presence flag and checks if conditional field is provided. If the field is not NULL, + * it calls the provided parser function which attempts to encode the field content to the buffer stream. + * + * @param[in] p_field Pointer to the input struct. + * @param[in] p_buf Pointer to the beginning of the output buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the encoded data. + * @param[in] fp_field_encoder Pointer to the function which implements fields encoding. + * + * @return NRF_SUCCESS Fields encoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t cond_field_enc(void const * const p_field, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + field_encoder_handler_t fp_field_encoder); + +/**@brief Function for safe decoding of a conditional field. + * + * Function checks if conditional field is present in the input buffer. If it is set, it calls + * the provided parser function which attempts to parse the buffer content to the known field. + * + * @param[in] p_buf Pointer to the beginning of the input buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[in] pp_field Pointer to output location. + * @param[in] fp_field_decoder Pointer to the function which implements field decoding. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t cond_field_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * * const pp_field, + field_decoder_handler_t fp_field_decoder); + +#ifdef __cplusplus +} +#endif + +#endif // COND_FIELD_SERIALIZATION_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ser_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ser_config.h new file mode 100644 index 0000000000000000000000000000000000000000..a4dfe2407efd525869f5d9ce50d130480ab18161 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ser_config.h @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SER_CONFIG_H__ +#define SER_CONFIG_H__ + +#include + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***********************************************************************************************//** + * General parameters configuration. + **************************************************************************************************/ + +/** Value used as error code on SoftDevice stack dump. Can be used to identify stack location on + * stack unwind.*/ +#define SER_SD_ERROR_CODE (0xDEADBEEFUL) + +/** Value used as error code indicating warning - unusual situation but not critical so system + * should NOT be reset. */ +#define SER_WARNING_CODE (0xBADDCAFEUL) + +/***********************************************************************************************//** + * HAL Transport layer configuration. + **************************************************************************************************/ + +/** Max packets size in serialization HAL Transport layer (packets before adding PHY header i.e. + * packet length). */ +#define SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE (384UL) +#define SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE (384UL) + +#define SER_HAL_TRANSPORT_MAX_PKT_SIZE ((SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE) >= \ + (SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE) \ + ? \ + (SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE) : \ + (SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE)) +#ifdef SER_CONNECTIVITY + #define SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE + #define SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE + +#else /* APPLICATION SIDE */ + #define SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE + #define SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE +#endif /* SER_CONNECTIVITY */ + + +/***********************************************************************************************//** + * SER_PHY layer configuration. + **************************************************************************************************/ + +#define SER_PHY_HEADER_SIZE 2 + +#define SER_PHY_HCI_SLIP_TX_BUF_SIZE 30 + +#define SER_PHY_SPI_FREQUENCY NRF_DRV_SPI_FREQ_1M + +/** Max transfer unit for SPI MASTER and SPI SLAVE. */ +#define SER_PHY_SPI_MTU_SIZE 255 + +/** UART transmission parameters */ +#define SER_PHY_UART_FLOW_CTRL NRF_UART_HWFC_ENABLED +#define SER_PHY_UART_PARITY NRF_UART_PARITY_INCLUDED +#define SER_PHY_UART_BAUDRATE UART_BAUDRATE_BAUDRATE_Baud1M + +/** Find UART baud rate value based on the chosen register setting. */ +#if (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud1200) + #define SER_PHY_UART_BAUDRATE_VAL 1200uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud2400) + #define SER_PHY_UART_BAUDRATE_VAL 2400uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud4800) + #define SER_PHY_UART_BAUDRATE_VAL 4800uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud9600) + #define SER_PHY_UART_BAUDRATE_VAL 9600uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud14400) + #define SER_PHY_UART_BAUDRATE_VAL 14400uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud19200) + #define SER_PHY_UART_BAUDRATE_VAL 19200uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud28800) + #define SER_PHY_UART_BAUDRATE_VAL 28800uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud38400) + #define SER_PHY_UART_BAUDRATE_VAL 38400uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud57600) + #define SER_PHY_UART_BAUDRATE_VAL 57600uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud76800) + #define SER_PHY_UART_BAUDRATE_VAL 76800uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud115200) + #define SER_PHY_UART_BAUDRATE_VAL 115200uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud230400) + #define SER_PHY_UART_BAUDRATE_VAL 230400uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud250000) + #define SER_PHY_UART_BAUDRATE_VAL 250000uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud460800) + #define SER_PHY_UART_BAUDRATE_VAL 460800uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud921600) + #define SER_PHY_UART_BAUDRATE_VAL 921600uL +#elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud1M) + #define SER_PHY_UART_BAUDRATE_VAL 1000000uL +#else + #error "Unsupported baudrate" +#endif /* SER_PHY_UART_BAUDRATE */ + +/** Configuration timeouts of connectivity MCU. */ +#define CONN_CHIP_RESET_TIME 50 /**< Time to keep the reset line to the connectivity chip low (in milliseconds). */ +#define CONN_CHIP_WAKEUP_TIME 500 /**< Time for the connectivity chip to reset and become ready to receive serialized commands (in milliseconds). */ + +#define SER_MAX_CONNECTIONS 8 + + +#ifdef __cplusplus +} +#endif + +#endif /* SER_CONFIG_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ser_dbg_sd_str.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ser_dbg_sd_str.c new file mode 100644 index 0000000000000000000000000000000000000000..adc76c460c5e9726ad88a92bc7f8f31959eba6e1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ser_dbg_sd_str.c @@ -0,0 +1,312 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ser_dbg_sd_str.h" +#include "nrf_soc.h" +#include "nrf_log.h" +#include +#include "sdk_common.h" + +#ifdef BLE_STACK_SUPPORT_REQD +#include "ble_ranges.h" +#endif + +#ifdef ANT_STACK_SUPPORT_REQD +#include "ant_interface.h" +#include "ant_parameters.h" +#endif + +#if NRF_MODULE_ENABLED(NRF_LOG) +static const char * sd_events[] = { + "BLE_EVT_TX_COMPLETE", /*0x01*/ + "BLE_EVT_USER_MEM_REQUEST", /*0x02*/ + "BLE_EVT_USER_MEM_RELEASE", /*0x03*/ + "BLE_EVT_DATA_LENGTH_CHANGED", /*0x04*/ + "SD_EVT_UNKNOWN", /*0x05*/ + "SD_EVT_UNKNOWN", /*0x06*/ + "SD_EVT_UNKNOWN", /*0x07*/ + "SD_EVT_UNKNOWN", /*0x08*/ + "SD_EVT_UNKNOWN", /*0x09*/ + "SD_EVT_UNKNOWN", /*0x0a*/ + "SD_EVT_UNKNOWN", /*0x0b*/ + "SD_EVT_UNKNOWN", /*0x0c*/ + "SD_EVT_UNKNOWN", /*0x0d*/ + "SD_EVT_UNKNOWN", /*0x0e*/ + "SD_EVT_UNKNOWN", /*0x0f*/ + "BLE_GAP_EVT_CONNECTED", /*0x10*/ + "BLE_GAP_EVT_DISCONNECTED", /*0x11*/ + "BLE_GAP_EVT_CONN_PARAM_UPDATE", /*0x12*/ + "BLE_GAP_EVT_SEC_PARAMS_REQUEST", /*0x13*/ + "BLE_GAP_EVT_SEC_INFO_REQUEST", /*0x14*/ + "BLE_GAP_EVT_PASSKEY_DISPLAY", /*0x15*/ + "BLE_GAP_EVT_KEY_PRESxSED", /*0x16*/ + "BLE_GAP_EVT_AUTH_KEY_REQUEST", /*0x17*/ + "BLE_GAP_EVT_LESC_DHKEY_REQUEST", /*0x18*/ + "BLE_GAP_EVT_AUTH_STATUS", /*0x19*/ + "BLE_GAP_EVT_CONN_SEC_UPDATE", /*0x1a*/ + "BLE_GAP_EVT_TIMEOUT", /*0x1b*/ + "BLE_GAP_EVT_RSSI_CHANGED", /*0x1c*/ + "BLE_GAP_EVT_ADV_REPORT", /*0x1d*/ + "BLE_GAP_EVT_SEC_REQUEST", /*0x1e*/ + "BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST", /*0x1f*/ + "BLE_GAP_EVT_SCAN_REQ_REPORT", /*0x20*/ + "SD_EVT_UNKNOWN", /*0x21*/ + "SD_EVT_UNKNOWN", /*0x22*/ + "SD_EVT_UNKNOWN", /*0x23*/ + "SD_EVT_UNKNOWN", /*0x24*/ + "SD_EVT_UNKNOWN", /*0x25*/ + "SD_EVT_UNKNOWN", /*0x26*/ + "SD_EVT_UNKNOWN", /*0x27*/ + "SD_EVT_UNKNOWN", /*0x28*/ + "SD_EVT_UNKNOWN", /*0x29*/ + "SD_EVT_UNKNOWN", /*0x2a*/ + "SD_EVT_UNKNOWN", /*0x2b*/ + "SD_EVT_UNKNOWN", /*0x2c*/ + "SD_EVT_UNKNOWN", /*0x2d*/ + "SD_EVT_UNKNOWN", /*0x2e*/ + "SD_EVT_UNKNOWN", /*0x2f*/ + "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP", /*0x30*/ + "BLE_GATTC_EVT_REL_DISC_RSP", /*0x31*/ + "BLE_GATTC_EVT_CHAR_DISC_RSP", /*0x32*/ + "BLE_GATTC_EVT_DESC_DISC_RSP", /*0x33*/ + "BLE_GATTC_EVT_ATTR_INFO_DISC_RSP", /*0x34*/ + "BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP", /*0x35*/ + "BLE_GATTC_EVT_READ_RSP", /*0x36*/ + "BLE_GATTC_EVT_CHAR_VALS_READ_RSP", /*0x37*/ + "BLE_GATTC_EVT_WRITE_RSP", /*0x38*/ + "BLE_GATTC_EVT_HVX", /*0x39*/ + "BLE_GATTC_EVT_EXCHANGE_MTU_RSP", /*0x3a*/ + "BLE_GATTC_EVT_TIMEOUT", /*0x3b*/ + "SD_EVT_UNKNOWN", /*0x3c*/ + "SD_EVT_UNKNOWN", /*0x3d*/ + "SD_EVT_UNKNOWN", /*0x3e*/ + "SD_EVT_UNKNOWN", /*0x3f*/ + "SD_EVT_UNKNOWN", /*0x40*/ + "SD_EVT_UNKNOWN", /*0x41*/ + "SD_EVT_UNKNOWN", /*0x42*/ + "SD_EVT_UNKNOWN", /*0x43*/ + "SD_EVT_UNKNOWN", /*0x44*/ + "SD_EVT_UNKNOWN", /*0x45*/ + "SD_EVT_UNKNOWN", /*0x46*/ + "SD_EVT_UNKNOWN", /*0x47*/ + "SD_EVT_UNKNOWN", /*0x48*/ + "SD_EVT_UNKNOWN", /*0x49*/ + "SD_EVT_UNKNOWN", /*0x4a*/ + "SD_EVT_UNKNOWN", /*0x4b*/ + "SD_EVT_UNKNOWN", /*0x4c*/ + "SD_EVT_UNKNOWN", /*0x4d*/ + "SD_EVT_UNKNOWN", /*0x4e*/ + "SD_EVT_UNKNOWN", /*0x4f*/ + "BLE_GATTS_EVT_WRITE", /*0x50*/ + "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST", /*0x51*/ + "BLE_GATTS_EVT_SYS_ATTR_MISSING", /*0x52*/ + "BLE_GATTS_EVT_HVC", /*0x53*/ + "BLE_GATTS_EVT_SC_CONFIRM", /*0x54*/ + "BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST", /*0x55*/ + "BLE_GATTS_EVT_TIMEOUT", /*0x56*/ +}; + +static const char * sd_functions[] = { + /* 0x60 offset */ + "SD_BLE_ENABLE", /*0x60*/ + "SD_BLE_EVT_GET", /*0x61*/ + "SD_BLE_TX_PACKET_COUNT_GET", /*0x62*/ + "SD_BLE_UUID_VS_ADD", /*0x63*/ + "SD_BLE_UUID_DECODE", /*0x64*/ + "SD_BLE_UUID_ENCODE", /*0x65*/ + "SD_BLE_VERSION_GET", /*0x66*/ + "SD_BLE_USER_MEM_REPLY", /*0x67*/ + "SD_BLE_OPT_SET", /*0x68*/ + "SD_BLE_OPT_GET", /*0x69*/ + "SD_UNKNOWN", /*0x6A*/ + "SD_UNKNOWN", /*0x6B*/ + "SD_BLE_GAP_ADDRESS_SET", /*0x6C*/ + "SD_BLE_GAP_ADDRESS_GET", /*0x6D*/ + "SD_BLE_GAP_WHITELIST_SET", /*0x6E*/ + "SD_BLE_GAP_DEVICE_IDENTITIES_SET", /*0x6F*/ + "SD_BLE_GAP_PRIVACY_SET", /*0x70*/ + "SD_BLE_GAP_PRIVACY_GET", /*0x71*/ + "SD_BLE_GAP_ADV_DATA_SET", /*0x72*/ + "SD_BLE_GAP_ADV_START", /*0x73*/ + "SD_BLE_GAP_ADV_STOP", /*0x74*/ + "SD_BLE_GAP_CONN_PARAM_UPDATE", /*0x75*/ + "SD_BLE_GAP_DISCONNECT", /*0x76*/ + "SD_BLE_GAP_TX_POWER_SET", /*0x77*/ + "SD_BLE_GAP_APPEARANCE_SET", /*0x78*/ + "SD_BLE_GAP_APPEARANCE_GET", /*0x79*/ + "SD_BLE_GAP_PPCP_SET", /*0x7a*/ + "SD_BLE_GAP_PPCP_GET", /*0x7b*/ + "SD_BLE_GAP_DEVICE_NAME_SET", /*0x7c*/ + "SD_BLE_GAP_DEVICE_NAME_GET", /*0x7d*/ + "SD_BLE_GAP_AUTHENTICATE", /*0x7e*/ + "SD_BLE_GAP_SEC_PARAMS_REPLY", /*0x7f*/ + "SD_BLE_GAP_AUTH_KEY_REPLY", /*0x80*/ + "SD_BLE_GAP_LESC_DHKEY_REPLY", /*0x81*/ + "SD_BLE_GAP_KEYPRESS_NOTIFY", /*0x82*/ + "SD_BLE_GAP_LESC_OOB_DATA_GET", /*0x83*/ + "SD_BLE_GAP_LESC_OOB_DATA_SET", /*0x84*/ + "SD_BLE_GAP_ENCRYPT", /*0x85*/ + "SD_BLE_GAP_SEC_INFO_REPLY", /*0x86*/ + "SD_BLE_GAP_CONN_SEC_GET", /*0x87*/ + "SD_BLE_GAP_RSSI_START", /*0x88*/ + "SD_BLE_GAP_RSSI_STOP", /*0x89*/ + "SD_BLE_GAP_SCAN_START", /*0x8a*/ + "SD_BLE_GAP_SCAN_STOP", /*0x8b*/ + "SD_BLE_GAP_CONNECT", /*0x8c*/ + "SD_BLE_GAP_CONNECT_CANCEL", /*0x8d*/ + "SD_BLE_GAP_RSSI_GET", /*0x8e*/ + "SD_UNKNOWN", /*0x8f*/ + "SD_UNKNOWN", /*0x90*/ + "SD_UNKNOWN", /*0x91*/ + "SD_UNKNOWN", /*0x92*/ + "SD_UNKNOWN", /*0x93*/ + "SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER", /*0x94*/ + "SD_BLE_GATTC_RELATIONSHIPS_DISCOVER", /*0x95*/ + "SD_BLE_GATTC_CHARACTERISTICS_DISCOVER", /*0x96*/ + "SD_BLE_GATTC_DESCRIPTORS_DISCOVER", /*0x97*/ + "SD_BLE_GATTC_ATTR_INFO_DISCOVER", /*0x98*/ + "SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ", /*0x99*/ + "SD_BLE_GATTC_READ", /*0x9A*/ + "SD_BLE_GATTC_CHAR_VALUES_READ", /*0x9b*/ + "SD_BLE_GATTC_WRITE", /*0x9c*/ + "SD_BLE_GATTC_HV_CONFIRM", /*0x9d*/ + "SD_BLE_GATTC_EXCHANGE_MTU_REQUEST", /*0x9e*/ + "SD_UNKNOWN", /*0x9F*/ + "SD_BLE_GATTS_SERVICE_ADD", /*0xA0*/ + "SD_BLE_GATTS_INCLUDE_ADD", /*0xA1*/ + "SD_BLE_GATTS_CHARACTERISTIC_ADD", /*0xA2*/ + "SD_BLE_GATTS_DESCRIPTOR_ADD", /*0xA3*/ + "SD_BLE_GATTS_VALUE_SET", /*0xA4*/ + "SD_BLE_GATTS_VALUE_GET", /*0xA5*/ + "SD_BLE_GATTS_HVX", /*0xA6*/ + "SD_BLE_GATTS_SERVICE_CHANGED", /*0xA7*/ + "SD_BLE_GATTS_RW_AUTHORIZE_REPLY", /*0xA8*/ + "SD_BLE_GATTS_SYS_ATTR_SET", /*0xA9*/ + "SD_BLE_GATTS_SYS_ATTR_GET", /*0xAa*/ + "SD_BLE_GATTS_INITIAL_USER_HANDLE_GET", /*0xAb*/ + "SD_BLE_GATTS_ATTR_GET", /*0xAc*/ + "SD_BLE_GATTS_EXCHANGE_MTU_REPLY", /*0xAd*/ +}; +#endif // NRF_MODULE_ENABLED(NRF_LOG) + +#ifdef ANT_STACK_SUPPORT_REQD +const char * string[] = +{ + "ANT SVC", + "ANT_EVT", +}; +#endif // ANT_STACK_SUPPORT_REQD + +const char * ser_dbg_sd_call_str_get(uint8_t opcode) +{ +#if NRF_MODULE_ENABLED(NRF_LOG) + const char * p_str = "SD_CALL_UNKNOWN"; +#ifdef BLE_STACK_SUPPORT_REQD + if (opcode >= BLE_SVC_BASE && opcode <= BLE_GATTS_SVC_LAST) + { + uint32_t idx = opcode-BLE_SVC_BASE; + if (idx < ARRAY_SIZE(sd_functions) ) + { + p_str = sd_functions[idx]; + } + } +#endif // BLE_STACK_SUPPORT_REQD + +#ifdef ANT_STACK_SUPPORT_REQD + // Check if opcode is within the range of the ANT Stack API SVC numbers +#ifdef BLE_STACK_SUPPORT_REQD + else if (opcode >= STK_SVC_BASE_2 && opcode <= SVC_ANT_EXTENDED2) +#else + if (opcode >= STK_SVC_BASE_2 && opcode <= SVC_ANT_EXTENDED2) +#endif // BLE_STACK_SUPPORT_REQD + { + p_str = string[0]; + } +#endif // ANT_STACK_SUPPORT_REQD + else + { + switch (opcode) + { + case SD_ECB_BLOCK_ENCRYPT: + p_str = "SD_ECB_BLOCK_ENCRYPT"; + break; + case SD_TEMP_GET: + p_str = "SD_TEMP_GET"; + break; + default: + break; + } + } + return p_str; +#else + return NULL; +#endif +} + +const char * ser_dbg_sd_evt_str_get(uint16_t opcode) +{ +#if NRF_MODULE_ENABLED(NRF_LOG) + const char * p_str = "SD_EVT_UNKNOWN"; +#ifdef BLE_STACK_SUPPORT_REQD + if (opcode >= BLE_EVT_BASE && opcode <= BLE_GATTS_EVT_LAST) + { + uint32_t idx = opcode - BLE_EVT_BASE; + if (idx < ARRAY_SIZE(sd_events)) + { + p_str = sd_events[idx]; + } + } +#endif // BLE_STACK_SUPPORT_REQD + +#ifdef ANT_STACK_SUPPORT_REQD + // Check if opcode is within the range of the ANT Stack API SVC numbers +#ifdef BLE_STACK_SUPPORT_REQD + else if (opcode >= NO_EVENT && opcode <= EVENT_BLOCKED) +#else + if (opcode >= NO_EVENT && opcode <= EVENT_BLOCKED) +#endif // BLE_STACK_SUPPORT_REQD + { + p_str = string[1]; + } +#endif + return p_str; +#else + return NULL; +#endif // NRF_MODULE_ENABLED(NRF_LOG) +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ser_dbg_sd_str.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ser_dbg_sd_str.h new file mode 100644 index 0000000000000000000000000000000000000000..8b9bd2f46f4201752ced54a4e74e3194d0e0c386 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/ser_dbg_sd_str.h @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SER_DBG_SD_STR_H +#define SER_DBG_SD_STR_H +#include +const char * ser_dbg_sd_call_str_get(uint8_t opcode); +const char * ser_dbg_sd_evt_str_get(uint16_t opcode); +#endif //SER_DBG_SD_STR_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ant/ant_struct_serialization.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ant/ant_struct_serialization.c new file mode 100644 index 0000000000000000000000000000000000000000..1369971a5a372401c74f5b171d5e1565b6369203 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ant/ant_struct_serialization.c @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ant_interface.h" +#include "ant_struct_serialization.h" +#include "ant_stack_handler_types.h" +#include "ble_serialization.h" +#include "app_util.h" +#include "cond_field_serialization.h" +#include + + +uint32_t ANT_ENABLE_enc(void const * const p_void_enable_params, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_index); + SER_ASSERT_NOT_NULL(p_void_enable_params); + + ANT_ENABLE * p_enable_params = (ANT_ENABLE *)p_void_enable_params; + uint32_t err_code = NRF_SUCCESS; + + err_code = uint8_t_enc(&p_enable_params->ucTotalNumberOfChannels, p_buf, buf_len, p_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&p_enable_params->ucNumberOfEncryptedChannels, p_buf, buf_len, p_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint16_t_enc(&p_enable_params->usNumberOfEvents, p_buf, buf_len, p_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint32_t_enc(&p_enable_params->pucMemoryBlockStartLocation, p_buf, buf_len, p_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint16_t_enc(&p_enable_params->usMemoryBlockByteSize, p_buf, buf_len, p_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + + +uint32_t ANT_ENABLE_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_enable_params) + +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_index); + SER_ASSERT_NOT_NULL(p_void_enable_params); + + ANT_ENABLE * p_enable_params = (ANT_ENABLE *)p_void_enable_params; + uint32_t err_code = NRF_SUCCESS; + + err_code = uint8_t_dec(p_buf, buf_len, p_index, &p_enable_params->ucTotalNumberOfChannels); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, buf_len, p_index, &p_enable_params->ucNumberOfEncryptedChannels); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint16_t_dec(p_buf, buf_len, p_index, &p_enable_params->usNumberOfEvents); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint32_t_dec(p_buf, buf_len, p_index, &p_enable_params->pucMemoryBlockStartLocation); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint16_t_dec(p_buf, buf_len, p_index, &p_enable_params->usMemoryBlockByteSize); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t ant_evt_t_enc(void const * const p_void_ant_evt, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_index); + SER_ASSERT_NOT_NULL(p_void_ant_evt); + + ant_evt_t * p_ant_evt = (ant_evt_t *)p_void_ant_evt; + uint32_t err_code = NRF_SUCCESS; + + memcpy(&p_buf[*p_index], p_ant_evt->msg.evt_buffer, ANT_STACK_EVT_MSG_BUF_SIZE); // Size + sizeof(size) & sizeof(msg id) + *p_index += ANT_STACK_EVT_MSG_BUF_SIZE; + + err_code = uint8_t_enc(&p_ant_evt->event, p_buf, buf_len, p_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&p_ant_evt->channel, p_buf, buf_len, p_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return(err_code); +} + +uint32_t ant_evt_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_ant_evt) + +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_index); + SER_ASSERT_NOT_NULL(p_void_ant_evt); + + ant_evt_t * p_ant_evt = (ant_evt_t *)p_void_ant_evt; + uint32_t err_code = NRF_SUCCESS; + + memcpy(p_ant_evt->msg.evt_buffer, &p_buf[*p_index], ANT_STACK_EVT_MSG_BUF_SIZE); // Size + sizeof(size) & sizeof(msg id) + *p_index += ANT_STACK_EVT_MSG_BUF_SIZE; + + err_code = uint8_t_dec(p_buf, buf_len, p_index, &p_ant_evt->event); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, buf_len, p_index, &p_ant_evt->channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ant/ant_struct_serialization.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ant/ant_struct_serialization.h new file mode 100644 index 0000000000000000000000000000000000000000..bec753c9c3e7c9cc78ac2f19aadf45f8fbc99cda --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ant/ant_struct_serialization.h @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#ifndef _ANT_STRUCT_SERIALIZATION_ +#define _ANT_STRUCT_SERIALIZATION_ + +/**@brief Function for safe encoding of an ANT_ENABLE struct. + * + * Safe decoding of an ANT_ENABLE struct. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_void_enable_params An ANT_ENABLE struct to be encoded. + * @param[out] p_buf Buffer containing the struct. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the ANT_ENABLE struct in the buffer. + * \c out: Index in the buffer to the first byte after the decoded struct. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ANT_ENABLE_enc( void const * const p_void_enable_params, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +/**@brief Function for safe decoding of an ANT_ENABLE struct. + * + * Safe decoding of a ANT_ENABLE struct. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_buf Buffer containing the struct. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the ANT_ENABLE struct in the buffer. + * \c out: Index in the buffer to the first byte after the decoded struct. + * @param[out] p_void_enable_params Decoded ANT_ENABLE struct. + */ +uint32_t ANT_ENABLE_dec( uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_enable_params); + +/**@brief Function for safe encoding of an ant_evt_t struct. + * + * Safe decoding of an ant_evt_t struct. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_void_ant_evt An ant_evt_t struct to be encoded. + * @param[out] p_buf Buffer containing the struct. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the ant_evt_t struct in the buffer. + * \c out: Index in the buffer to the first byte after the decoded struct. + * + * @return NRF_SUCCESS Fields decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_evt_t_enc( void const * const p_void_ant_evt, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +/**@brief Function for safe decoding of an ant_evt_t struct. + * + * Safe decoding of a ant_evt_t struct. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * + * @param[in] p_buf Buffer containing the struct. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the ant_evt_t struct in the buffer. + * \c out: Index in the buffer to the first byte after the decoded struct. + * @param[out] p_void_ant_evt Decoded ant_evt_t struct. + */ +uint32_t ant_evt_t_dec( uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_ant_evt); + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.c new file mode 100644 index 0000000000000000000000000000000000000000..9579be459fbcce20c3ae71b8357fb289c4903acb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.c @@ -0,0 +1,1454 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gap_struct_serialization.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include "string.h" +#include "ble_gatts.h" + +uint32_t ble_gap_evt_adv_report_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_adv_report_t); + + uint8_t ser_data = (p_struct->scan_rsp & 0x01) + | ((p_struct->type & 0x03) << 1); + uint8_t data_len = (p_struct->dlen & 0x1F); + SER_PUSH_FIELD(&p_struct->peer_addr, ble_gap_addr_t_enc); + SER_PUSH_FIELD(&p_struct->direct_addr, ble_gap_addr_t_enc); + SER_PUSH_int8(&p_struct->rssi); + SER_PUSH_uint8(&ser_data); + SER_PUSH_len8data(p_struct->data, data_len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_adv_report_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_adv_report_t); + + uint8_t ser_data; + uint8_t data_len = BLE_GAP_ADV_MAX_SIZE; + uint8_t * p_field_data = p_struct->data; + SER_PULL_FIELD(&p_struct->peer_addr, ble_gap_addr_t_dec); + SER_PULL_FIELD(&p_struct->direct_addr, ble_gap_addr_t_dec); + SER_PULL_int8(&p_struct->rssi); + SER_PULL_uint8(&ser_data); + SER_PULL_len8data(&p_field_data, &data_len); + + p_struct->scan_rsp = ser_data & 0x01; + p_struct->type = (ser_data >> 1) & 0x03; + p_struct->dlen = data_len; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_irk_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_irk_t); + SER_PUSH_uint8array(p_struct->irk, BLE_GAP_SEC_KEY_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_irk_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_irk_t); + SER_PULL_uint8array(p_struct->irk, BLE_GAP_SEC_KEY_LEN); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_addr_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_addr_t); + + uint8_t ser_data = (p_struct->addr_id_peer & 0x01) + | ((p_struct->addr_type & 0x7F) << 1); + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint8array(p_struct->addr, BLE_GAP_ADDR_LEN); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_addr_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_addr_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + SER_PULL_uint8array(p_struct->addr, BLE_GAP_ADDR_LEN); + + p_struct->addr_id_peer = ser_data & 0x01; + p_struct->addr_type = (ser_data >> 1) & 0x7F; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_sec_levels_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_sec_levels_t); + + uint8_t sec_levels_serialized = (p_struct->lv1 << 0) | (p_struct->lv2 << 1) + | (p_struct->lv3 << 2) | (p_struct->lv4 << 3); + SER_PUSH_uint8(&sec_levels_serialized); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_sec_levels_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_sec_levels_t); + + uint32_t sec_levels_serialized; + SER_PULL_uint8(&sec_levels_serialized); + + p_struct->lv1 = sec_levels_serialized & 0x01; + p_struct->lv2 = (sec_levels_serialized >> 1) & 0x01; + p_struct->lv3 = (sec_levels_serialized >> 2) & 0x01; + p_struct->lv4 = (sec_levels_serialized >> 3) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_sec_keys_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_sec_keys_t); + + SER_PUSH_COND(p_struct->p_enc_key, ble_gap_enc_key_t_enc); + SER_PUSH_COND(p_struct->p_id_key, ble_gap_id_key_t_enc); + SER_PUSH_COND(p_struct->p_sign_key, ble_gap_sign_info_t_enc); + SER_PUSH_COND(p_struct->p_pk, ble_gap_lesc_p256_pk_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_sec_keys_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_sec_keys_t); + + SER_PULL_COND(&(p_struct->p_enc_key), ble_gap_enc_key_t_dec); + SER_PULL_COND(&(p_struct->p_id_key), ble_gap_id_key_t_dec); + SER_PULL_COND(&(p_struct->p_sign_key), ble_gap_sign_info_t_dec); + SER_PULL_COND(&(p_struct->p_pk), ble_gap_lesc_p256_pk_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_enc_info_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_enc_info_t); + + SER_PUSH_uint8array(p_struct->ltk, BLE_GAP_SEC_KEY_LEN); + uint8_t ser_data = (p_struct->lesc & 0x01) + | ((p_struct->auth & 0x01) << 1) + | ((p_struct->ltk_len & 0x3F) << 2); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_enc_info_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_enc_info_t); + + uint8_t ser_data; + SER_PULL_uint8array(p_struct->ltk, BLE_GAP_SEC_KEY_LEN); + SER_PULL_uint8(&ser_data); + p_struct->lesc = ser_data & 0x01; + p_struct->auth = (ser_data >> 1) & 0x01; + p_struct->ltk_len = (ser_data >> 2) & 0x3F; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_sign_info_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_sign_info_t); + SER_PUSH_uint8array(p_struct->csrk, BLE_GAP_SEC_KEY_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_sign_info_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_sign_info_t); + SER_PULL_uint8array(p_struct->csrk, BLE_GAP_SEC_KEY_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_auth_status_t); + + uint8_t ser_data = (p_struct->error_src) | ((p_struct->bonded) << 2); + SER_PUSH_uint8(&(p_struct->auth_status)); + SER_PUSH_uint8(&ser_data); + + SER_PUSH_FIELD(&(p_struct->sm1_levels), ble_gap_sec_levels_t_enc); + SER_PUSH_FIELD(&(p_struct->sm2_levels), ble_gap_sec_levels_t_enc); + SER_PUSH_FIELD(&(p_struct->kdist_own), ble_gap_sec_kdist_t_enc); + SER_PUSH_FIELD(&(p_struct->kdist_peer), ble_gap_sec_kdist_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_auth_status_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_auth_status_t); + + uint8_t ser_data; + SER_PULL_uint8(&(p_struct->auth_status)); + SER_PULL_uint8(&ser_data); + p_struct->error_src = ser_data & 0x03; + p_struct->bonded = (ser_data >> 2) & 0x01; + + SER_PULL_FIELD(&(p_struct->sm1_levels), ble_gap_sec_levels_t_dec); + SER_PULL_FIELD(&(p_struct->sm2_levels), ble_gap_sec_levels_t_dec); + SER_PULL_FIELD(&(p_struct->kdist_own), ble_gap_sec_kdist_t_dec); + SER_PULL_FIELD(&(p_struct->kdist_peer), ble_gap_sec_kdist_t_dec); + + SER_STRUCT_DEC_END; +} + + +uint32_t ble_gap_conn_sec_mode_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_conn_sec_mode_t); + + uint8_t ser_data = (p_struct->sm & 0x0F) + | ((p_struct->lv & 0x0F) << 4); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_conn_sec_mode_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_conn_sec_mode_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->sm = ser_data & 0x0F; + p_struct->lv = (ser_data >> 4) & 0x0F; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_conn_sec_update_t); + SER_PUSH_FIELD(&(p_struct->conn_sec), ble_gap_conn_sec_t_enc); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_conn_sec_update_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_conn_sec_update_t); + SER_PULL_FIELD(&(p_struct->conn_sec), ble_gap_conn_sec_t_dec); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_conn_sec_t); + + SER_PUSH_FIELD(&p_struct->sec_mode, ble_gap_conn_sec_mode_t_enc); + SER_PUSH_uint8(&p_struct->encr_key_size); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_conn_sec_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_conn_sec_t); + + SER_PULL_FIELD(&p_struct->sec_mode, ble_gap_conn_sec_mode_t_dec); + SER_PULL_uint8(&p_struct->encr_key_size); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_sec_info_request_t); + + uint8_t ser_data = (p_struct->enc_info & 0x01) + | ((p_struct->id_info & 0x01) << 1) + | ((p_struct->sign_info& 0x01) << 2); + SER_PUSH_FIELD(&p_struct->peer_addr, ble_gap_addr_t_enc); + SER_PUSH_FIELD(&p_struct->master_id, ble_gap_master_id_t_enc); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_sec_info_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_sec_info_request_t); + + uint8_t ser_data; + SER_PULL_FIELD(&p_struct->peer_addr, ble_gap_addr_t_dec); + SER_PULL_FIELD(&p_struct->master_id, ble_gap_master_id_t_dec); + SER_PULL_uint8(&ser_data); + p_struct->enc_info = ser_data & 0x01; + p_struct->id_info = (ser_data >> 1) & 0x01; + p_struct->sign_info = (ser_data >> 2) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_connected_t); + + SER_PUSH_FIELD(&p_struct->peer_addr, ble_gap_addr_t_enc); + SER_PUSH_uint8(&p_struct->role); + SER_PUSH_FIELD(&p_struct->conn_params, ble_gap_conn_params_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_connected_t); + + SER_PULL_FIELD(&p_struct->peer_addr, ble_gap_addr_t_dec); + SER_PULL_uint8(&p_struct->role); + SER_PULL_FIELD(&p_struct->conn_params, ble_gap_conn_params_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_sec_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_sec_params_t); + + uint8_t ser_data = (p_struct->bond & 0x01) + | ((p_struct->mitm & 0x01) << 1) + | ((p_struct->lesc & 0x01) << 2) + | ((p_struct->keypress & 0x01) << 3) + | ((p_struct->io_caps & 0x07) << 4) + | ((p_struct->oob & 0x01) << 7); + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint8(&p_struct->min_key_size); + SER_PUSH_uint8(&p_struct->max_key_size); + SER_PUSH_FIELD(&p_struct->kdist_own, ble_gap_sec_kdist_t_enc); + SER_PUSH_FIELD(&p_struct->kdist_peer, ble_gap_sec_kdist_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_sec_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_sec_params_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + SER_PULL_uint8(&p_struct->min_key_size); + SER_PULL_uint8(&p_struct->max_key_size); + SER_PULL_FIELD(&p_struct->kdist_own, ble_gap_sec_kdist_t_dec); + SER_PULL_FIELD(&p_struct->kdist_peer, ble_gap_sec_kdist_t_dec); + p_struct->bond = ser_data & 0x01; + p_struct->mitm = (ser_data >> 1) & 0x01; + p_struct->lesc = (ser_data >> 2) & 0x01; + p_struct->keypress = (ser_data >> 3) & 0x01; + p_struct->io_caps = (ser_data >> 4) & 0x07; + p_struct->oob = (ser_data >> 7) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_sec_params_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_sec_params_request_t); + SER_PUSH_FIELD(&(p_struct->peer_params), ble_gap_sec_params_t_enc); + SER_STRUCT_ENC_END; +} + + uint32_t ble_gap_evt_sec_params_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_sec_params_request_t); + SER_PULL_FIELD(&(p_struct->peer_params), ble_gap_sec_params_t_dec); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_conn_param_update_t); + SER_PUSH_FIELD(&(p_struct->conn_params), ble_gap_conn_params_t_enc); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_conn_param_update_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_conn_param_update_t); + SER_PULL_FIELD(&(p_struct->conn_params), ble_gap_conn_params_t_dec); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_conn_param_update_request_t); + SER_PUSH_FIELD(&(p_struct->conn_params), ble_gap_conn_params_t_enc); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_conn_param_update_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_conn_param_update_request_t); + SER_PULL_FIELD(&(p_struct->conn_params), ble_gap_conn_params_t_dec); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_conn_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_conn_params_t); + + SER_PUSH_uint16(&p_struct->min_conn_interval); + SER_PUSH_uint16(&p_struct->max_conn_interval); + SER_PUSH_uint16(&p_struct->slave_latency); + SER_PUSH_uint16(&p_struct->conn_sup_timeout); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_conn_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_conn_params_t); + + SER_PULL_uint16(&p_struct->min_conn_interval); + SER_PULL_uint16(&p_struct->max_conn_interval); + SER_PULL_uint16(&p_struct->slave_latency); + SER_PULL_uint16(&p_struct->conn_sup_timeout); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_disconnected_t); + SER_PUSH_uint8(&p_struct->reason); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_disconnected_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_disconnected_t); + SER_PULL_uint8(&p_struct->reason); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_master_id_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_master_id_t); + SER_PUSH_uint16(&p_struct->ediv); + SER_PUSH_uint8array(p_struct->rand, BLE_GAP_SEC_RAND_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_master_id_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_master_id_t); + SER_PULL_uint16(&p_struct->ediv); + SER_PULL_uint8array(p_struct->rand, BLE_GAP_SEC_RAND_LEN); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_scan_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_scan_params_t); + + uint8_t ser_data = (p_struct->active & 0x01) + | ((p_struct->use_whitelist & 0x01) << 1) + | ((p_struct->adv_dir_report & 0x01) << 2); + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint16(&p_struct->interval); + SER_PUSH_uint16(&p_struct->window); + SER_PUSH_uint16(&p_struct->timeout); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_scan_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_scan_params_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + SER_PULL_uint16(&p_struct->interval); + SER_PULL_uint16(&p_struct->window); + SER_PULL_uint16(&p_struct->timeout); + + p_struct->active = ser_data & 0x01; + p_struct->use_whitelist = (ser_data >> 1) & 0x01; + p_struct->adv_dir_report = (ser_data >> 2) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_enc_key_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_enc_key_t); + + SER_PUSH_FIELD(&p_struct->enc_info, ble_gap_enc_info_t_enc); + SER_PUSH_FIELD(&p_struct->master_id, ble_gap_master_id_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_enc_key_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_enc_key_t); + + SER_PULL_FIELD(&p_struct->enc_info, ble_gap_enc_info_t_dec); + SER_PULL_FIELD(&p_struct->master_id, ble_gap_master_id_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_id_key_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_id_key_t); + + SER_PUSH_FIELD(&p_struct->id_info, ble_gap_irk_t_enc); + SER_PUSH_FIELD(&p_struct->id_addr_info, ble_gap_addr_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_id_key_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_id_key_t); + + SER_PULL_FIELD(&p_struct->id_info, ble_gap_irk_t_dec); + SER_PULL_FIELD(&p_struct->id_addr_info, ble_gap_addr_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_sec_keyset_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_sec_keyset_t); + + SER_PUSH_FIELD(&p_struct->keys_own, ble_gap_sec_keys_t_enc); + SER_PUSH_FIELD(&p_struct->keys_peer, ble_gap_sec_keys_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_sec_keyset_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_sec_keyset_t); + + SER_PULL_FIELD(&p_struct->keys_own, ble_gap_sec_keys_t_dec); + SER_PULL_FIELD(&p_struct->keys_peer, ble_gap_sec_keys_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_sec_request_t); + + uint8_t ser_data = (p_struct->bond & 0x01) + | ((p_struct->mitm & 0x01) << 1) + | ((p_struct->lesc & 0x01) << 2) + | ((p_struct->keypress & 0x01) << 3); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_sec_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_sec_request_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->bond = ser_data & 0x01; + p_struct->mitm = (ser_data >> 1) & 0x01; + p_struct->lesc = (ser_data >> 2) & 0x01; + p_struct->keypress = (ser_data >> 3) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_sec_kdist_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_sec_kdist_t); + + uint8_t ser_data = (p_struct->enc & 0x01) + | (p_struct->id & 0x01) << 1 + | (p_struct->sign & 0x01) << 2 + | (p_struct->link & 0x01) << 3; + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_sec_kdist_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_sec_kdist_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->enc = ser_data & 0x01; + p_struct->id = (ser_data >> 1) & 0x01; + p_struct->sign = (ser_data >> 2) & 0x01; + p_struct->link = (ser_data >> 3) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_ch_map_t); + + SER_PUSH_uint16(&p_struct->conn_handle); + SER_PUSH_uint8array(p_struct->ch_map, 5); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_ch_map_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_ch_map_t); + + SER_PULL_uint16(&p_struct->conn_handle); + SER_PULL_uint8array(p_struct->ch_map, 5); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_local_conn_latency_t); + + SER_PUSH_uint16(&p_struct->conn_handle); + SER_PUSH_uint16(&p_struct->requested_latency); + SER_PUSH_COND(p_struct->p_actual_latency, uint16_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_local_conn_latency_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_local_conn_latency_t); + + SER_PULL_uint16(&p_struct->conn_handle); + SER_PULL_uint16(&p_struct->requested_latency); + SER_PULL_COND(&p_struct->p_actual_latency, uint16_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_passkey_t); + SER_PUSH_buf(p_struct->p_passkey, BLE_GAP_PASSKEY_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_passkey_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_passkey_t); + SER_PULL_buf((uint8_t**)&p_struct->p_passkey, BLE_GAP_PASSKEY_LEN, BLE_GAP_PASSKEY_LEN); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_scan_req_report_t); + + uint8_t ser_data = p_struct->enable & 0x01; + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_scan_req_report_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_scan_req_report_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->enable = ser_data & 0x01; + + SER_STRUCT_DEC_END; +} + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_compat_mode_t); + + uint8_t ser_data = p_struct->mode_1_enable & 0x01; + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_compat_mode_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_compat_mode_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->mode_1_enable = ser_data & 0x01; + + SER_STRUCT_DEC_END; +} +#endif + +uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_adv_ch_mask_t); + + uint8_t ser_data = (p_struct->ch_37_off & 0x01) + | ((p_struct->ch_38_off & 0x01) << 1) + | ((p_struct->ch_39_off & 0x01) << 2); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_adv_ch_mask_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_adv_ch_mask_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->ch_37_off = ser_data & 0x01; + p_struct->ch_38_off = (ser_data >> 1) & 0x01; + p_struct->ch_39_off = (ser_data >> 2) & 0x01; + + SER_STRUCT_DEC_END; +} + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_gap_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_enable_params_t); + + SER_PUSH_uint8(&p_struct->periph_conn_count); + SER_PUSH_uint8(&p_struct->central_conn_count); + SER_PUSH_uint8(&p_struct->central_sec_count); + SER_PUSH_COND(p_struct->p_device_name, ble_gap_device_name_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_enable_params_t); + + SER_PULL_uint8(&p_struct->periph_conn_count); + SER_PULL_uint8(&p_struct->central_conn_count); + SER_PULL_uint8(&p_struct->central_sec_count); + SER_PULL_COND(&p_struct->p_device_name, ble_gap_device_name_t_dec); + + SER_STRUCT_DEC_END; +} +#endif + +uint32_t ble_gap_lesc_p256_pk_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_lesc_p256_pk_t); + SER_PUSH_uint8array(p_struct->pk, BLE_GAP_LESC_P256_PK_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_lesc_p256_pk_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_lesc_p256_pk_t); + SER_PULL_uint8array(p_struct->pk, BLE_GAP_LESC_P256_PK_LEN); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_lesc_dhkey_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_lesc_dhkey_t); + SER_PUSH_uint8array(p_struct->key, BLE_GAP_LESC_DHKEY_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_lesc_dhkey_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_lesc_dhkey_t); + SER_PULL_uint8array(p_struct->key, BLE_GAP_LESC_DHKEY_LEN); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_lesc_oob_data_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_lesc_oob_data_t); + + SER_PUSH_FIELD(&p_struct->addr, ble_gap_addr_t_enc); + SER_PUSH_uint8array(p_struct->r, BLE_GAP_SEC_KEY_LEN); + SER_PUSH_uint8array(p_struct->c, BLE_GAP_SEC_KEY_LEN); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_lesc_oob_data_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_lesc_oob_data_t); + + SER_PULL_FIELD(&p_struct->addr, ble_gap_addr_t_dec); + SER_PULL_uint8array(p_struct->r, BLE_GAP_SEC_KEY_LEN); + SER_PULL_uint8array(p_struct->c, BLE_GAP_SEC_KEY_LEN); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_adv_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_adv_params_t); + + SER_PUSH_uint8(&p_struct->type); + SER_PUSH_COND(p_struct->p_peer_addr, ble_gap_addr_t_enc); + SER_PUSH_uint8(&p_struct->fp); + SER_PUSH_uint16(&p_struct->interval); + SER_PUSH_uint16(&p_struct->timeout); + SER_PUSH_FIELD(&p_struct->channel_mask, ble_gap_adv_ch_mask_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_adv_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_adv_params_t); + + SER_PULL_uint8(&p_struct->type); + SER_PULL_COND(&p_struct->p_peer_addr, ble_gap_addr_t_dec); + SER_PULL_uint8(&p_struct->fp); + SER_PULL_uint16(&p_struct->interval); + SER_PULL_uint16(&p_struct->timeout); + SER_PULL_FIELD(&p_struct->channel_mask, ble_gap_adv_ch_mask_t_dec); + + SER_STRUCT_DEC_END; +} +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_gap_opt_ext_len_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_ext_len_t); + SER_PUSH_uint8(&p_struct->rxtx_max_pdu_payload_size); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_ext_len_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_ext_len_t); + SER_PULL_uint8(&p_struct->rxtx_max_pdu_payload_size); + SER_STRUCT_DEC_END; +} +#endif +uint32_t ble_gap_opt_auth_payload_timeout_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_auth_payload_timeout_t); + + SER_PUSH_uint16(&p_struct->conn_handle); + SER_PUSH_uint16(&p_struct->auth_payload_timeout); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_auth_payload_timeout_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_auth_payload_timeout_t); + + SER_PULL_uint16(&p_struct->conn_handle); + SER_PULL_uint16(&p_struct->auth_payload_timeout); + + SER_STRUCT_DEC_END; +} + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_gap_device_name_t_enc +#else +uint32_t ble_gap_cfg_device_name_t_enc +#endif + (void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) + +{ +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + SER_STRUCT_ENC_BEGIN(ble_gap_device_name_t); +#else + SER_STRUCT_ENC_BEGIN(ble_gap_cfg_device_name_t); +#endif + /* serializer does not support attributes on stack */ + if (p_struct->vloc != BLE_GATTS_VLOC_STACK) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + + SER_PUSH_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_enc); + + uint8_t ser_data = p_struct->vloc & 0x03; + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint16(&p_struct->current_len); + SER_PUSH_uint16(&p_struct->max_len); + SER_PUSH_buf(p_struct->p_value, p_struct->current_len); + + SER_STRUCT_ENC_END; +} + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_gap_device_name_t_dec +#else +uint32_t ble_gap_cfg_device_name_t_dec +#endif + (uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + SER_STRUCT_DEC_BEGIN(ble_gap_device_name_t); +#else + SER_STRUCT_DEC_BEGIN(ble_gap_cfg_device_name_t); +#endif + + uint16_t value_max_len = p_struct->max_len; + uint8_t ser_data; + SER_PULL_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_dec); + SER_PULL_uint8(&ser_data); + p_struct->vloc = ser_data & 0x03; + SER_PULL_uint16(&p_struct->current_len); + SER_PULL_uint16(&p_struct->max_len); + SER_PULL_buf(&p_struct->p_value,value_max_len, p_struct->current_len); + + SER_STRUCT_DEC_END; +} + + + +uint32_t ble_gap_privacy_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_privacy_params_t); + + SER_PUSH_uint8(&p_struct->privacy_mode); + SER_PUSH_uint8(&p_struct->private_addr_type); + SER_PUSH_uint16(&p_struct->private_addr_cycle_s); + SER_PUSH_COND(p_struct->p_device_irk, ble_gap_irk_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_privacy_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_privacy_params_t); + + SER_PULL_uint8(&p_struct->privacy_mode); + SER_PULL_uint8(&p_struct->private_addr_type); + SER_PULL_uint16(&p_struct->private_addr_cycle_s); + SER_PULL_COND(&p_struct->p_device_irk, ble_gap_irk_t_dec); + + SER_STRUCT_DEC_END; +} + + + + +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gap_opt_compat_mode_1_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_compat_mode_1_t); + + uint8_t enable = p_struct->enable; + SER_PUSH_uint8(&enable); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_compat_mode_1_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_compat_mode_1_t); + + uint8_t enable; + SER_PULL_uint8(&enable); + p_struct->enable = enable; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_compat_mode_2_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_compat_mode_2_t); + + uint8_t enable = p_struct->enable; + SER_PUSH_uint8(&enable); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_compat_mode_2_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_compat_mode_2_t); + + uint8_t enable; + SER_PULL_uint8(&enable); + p_struct->enable = enable; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_slave_latency_disable_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_slave_latency_disable_t); + + SER_PUSH_uint16(&p_struct->conn_handle); + uint8_t disable = p_struct->disable; + SER_PUSH_uint8(&disable); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_slave_latency_disable_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_slave_latency_disable_t); + + SER_PULL_uint16(&p_struct->conn_handle); + uint8_t disable; + SER_PULL_uint8(&disable); + p_struct->disable = disable; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_conn_cfg_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_conn_cfg_t); + + SER_PUSH_uint8(&p_struct->conn_count); + SER_PUSH_uint16(&p_struct->event_length); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_conn_cfg_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_conn_cfg_t); + + SER_PULL_uint8(&p_struct->conn_count); + SER_PULL_uint16(&p_struct->event_length); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_cfg_role_count_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_cfg_role_count_t); + + SER_PUSH_uint8(&p_struct->periph_role_count); + SER_PUSH_uint8(&p_struct->central_role_count); + SER_PUSH_uint8(&p_struct->central_sec_count); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_cfg_role_count_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_cfg_role_count_t); + + SER_PULL_uint8(&p_struct->periph_role_count); + SER_PULL_uint8(&p_struct->central_role_count); + SER_PULL_uint8(&p_struct->central_sec_count); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_data_length_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_data_length_params_t); + + SER_PUSH_uint8(&p_struct->max_tx_octets); + SER_PUSH_uint8(&p_struct->max_rx_octets); + SER_PUSH_uint16(&p_struct->max_tx_time_us); + SER_PUSH_uint16(&p_struct->max_rx_time_us); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_data_length_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_data_length_params_t); + + SER_PULL_uint8(&p_struct->max_tx_octets); + SER_PULL_uint8(&p_struct->max_rx_octets); + SER_PULL_uint16(&p_struct->max_tx_time_us); + SER_PULL_uint16(&p_struct->max_rx_time_us); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_data_length_limitation_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_data_length_limitation_t); + + SER_PUSH_uint8(&p_struct->tx_payload_limited_octets); + SER_PUSH_uint8(&p_struct->rx_payload_limited_octets); + SER_PUSH_uint16(&p_struct->tx_rx_time_limited_us); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_data_length_limitation_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_data_length_limitation_t); + + SER_PULL_uint8(&p_struct->tx_payload_limited_octets); + SER_PULL_uint8(&p_struct->rx_payload_limited_octets); + SER_PULL_uint16(&p_struct->tx_rx_time_limited_us); + + SER_STRUCT_DEC_END; +} +#endif + +#if NRF_SD_BLE_API_VERSION >= 5 +uint32_t ble_gap_phys_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_phys_t); + + SER_PUSH_uint8(&p_struct->tx_phys); + SER_PUSH_uint8(&p_struct->rx_phys); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_phys_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_phys_t); + + SER_PULL_uint8(&p_struct->tx_phys); + SER_PULL_uint8(&p_struct->rx_phys); + + SER_STRUCT_DEC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.h new file mode 100644 index 0000000000000000000000000000000000000000..1fa57a013fb6459a83e2c2c777993595707e7d66 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.h @@ -0,0 +1,560 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GAP_STRUCT_SERIALIZATION_H__ +#define BLE_GAP_STRUCT_SERIALIZATION_H__ + +#include "ble_gap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t ble_gap_evt_adv_report_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_evt_adv_report_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_irk_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_irk_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_addr_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_addr_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_sec_levels_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_sec_levels_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_sec_keys_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_sec_keys_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_enc_info_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_enc_info_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_sign_info_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_sign_info_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_evt_auth_status_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_conn_sec_mode_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_conn_sec_mode_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_conn_sec_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_evt_conn_sec_update_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_evt_sec_info_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_sec_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_sec_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_evt_sec_params_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_evt_sec_params_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_conn_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_conn_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_evt_conn_param_update_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_evt_conn_param_update_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_evt_disconnected_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_scan_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_scan_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_data); + +uint32_t ble_gap_master_id_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_master_id_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_enc_key_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_enc_key_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_id_key_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_id_key_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_sec_keyset_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_sec_keyset_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_evt_sec_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_sec_kdist_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_sec_kdist_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_opt_ch_map_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_opt_local_conn_latency_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_opt_passkey_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_opt_scan_req_report_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_opt_compat_mode_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#endif +uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_adv_ch_mask_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_lesc_p256_pk_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_lesc_p256_pk_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_lesc_dhkey_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_lesc_dhkey_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_lesc_oob_data_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_lesc_oob_data_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_adv_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_adv_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_gap_opt_ext_len_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_opt_ext_len_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#endif + +uint32_t ble_gap_opt_auth_payload_timeout_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_opt_auth_payload_timeout_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_gap_device_name_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_device_name_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#else +uint32_t ble_gap_cfg_device_name_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_cfg_device_name_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#endif + +uint32_t ble_gap_privacy_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_privacy_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gap_opt_compat_mode_1_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_opt_compat_mode_1_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_opt_compat_mode_2_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_opt_compat_mode_2_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +uint32_t ble_gap_opt_slave_latency_disable_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_opt_slave_latency_disable_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_conn_cfg_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_conn_cfg_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_cfg_role_count_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_cfg_role_count_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_data_length_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_data_length_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_data_length_limitation_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_data_length_limitation_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#endif + +#if NRF_SD_BLE_API_VERSION >= 5 +uint32_t ble_gap_phys_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_phys_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // BLE_GAP_STRUCT_SERIALIZATION_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.c new file mode 100644 index 0000000000000000000000000000000000000000..f681c956a5154ea063ac93e40bc6bd53ac068d49 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.c @@ -0,0 +1,158 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_gatt_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include "ble_gatt.h" +#include + +uint32_t ble_gatt_char_props_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatt_char_props_t); + + uint8_t ser_data = (p_struct->broadcast & 0x01) + | ((p_struct->read & 0x01) << 1) + | ((p_struct->write_wo_resp & 0x01) << 2) + | ((p_struct->write & 0x01) << 3) + | ((p_struct->notify & 0x01) << 4) + | ((p_struct->indicate & 0x01) << 5) + | ((p_struct->auth_signed_wr & 0x01) << 6); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatt_char_props_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatt_char_props_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->broadcast = ser_data & 0x01; + p_struct->read = (ser_data >> 1) & 0x01; + p_struct->write_wo_resp = (ser_data >> 2) & 0x01; + p_struct->write = (ser_data >> 3) & 0x01; + p_struct->notify = (ser_data >> 4) & 0x01; + p_struct->indicate = (ser_data >> 5) & 0x01; + p_struct->auth_signed_wr = (ser_data >> 6) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatt_char_ext_props_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatt_char_ext_props_t); + + uint8_t ser_data = (p_struct->reliable_wr & 0x01) + | ((p_struct->wr_aux & 0x01) << 1); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatt_char_ext_props_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatt_char_ext_props_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->reliable_wr = ser_data & 0x01; + p_struct->wr_aux = (ser_data >> 1) & 0x01; + + SER_STRUCT_DEC_END; +} + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_gatt_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatt_enable_params_t); + SER_PUSH_uint16(&p_struct->att_mtu); + SER_STRUCT_ENC_END; +} + + +uint32_t ble_gatt_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatt_enable_params_t); + SER_PULL_uint16(&p_struct->att_mtu); + SER_STRUCT_DEC_END; +} +#else +uint32_t ble_gatt_conn_cfg_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatt_conn_cfg_t); + SER_PUSH_uint16(&p_struct->att_mtu); + SER_STRUCT_ENC_END; +} + + +uint32_t ble_gatt_conn_cfg_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatt_conn_cfg_t); + SER_PULL_uint16(&p_struct->att_mtu); + SER_STRUCT_DEC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.h new file mode 100644 index 0000000000000000000000000000000000000000..d14fa104af49ab7eba9068ed763f9518f500ba0d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.h @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GATT_STRUCT_SERIALIZATION_H +#define BLE_GATT_STRUCT_SERIALIZATION_H + +#include "ble_gatt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t ble_gatt_char_props_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatt_char_props_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatt_char_ext_props_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatt_char_ext_props_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_gatt_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatt_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#else +uint32_t ble_gatt_conn_cfg_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatt_conn_cfg_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#endif +#ifdef __cplusplus +} +#endif + +#endif /*BLE_GATT_STRUCT_SERIALIZATION_H*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.c new file mode 100644 index 0000000000000000000000000000000000000000..eb1103bcf5f1ce480fb5b3b7c25b6abe25edbef8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.c @@ -0,0 +1,715 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gatt_struct_serialization.h" +#include "ble_gattc_struct_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_serialization.h" +#include "app_util.h" +#include "ble_gattc.h" +#include "cond_field_serialization.h" +#include + +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_char_val_by_uuid_read_rsp_t); + + SER_PUSH_uint16(&p_struct->count); + SER_PUSH_uint16(&p_struct->value_len); + + // Copy the whole packed list. + uint16_t list_length = (p_struct->value_len + sizeof(uint16_t)) * p_struct->count; + SER_PUSH_uint8array(p_struct->handle_value, list_length); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_char_val_by_uuid_read_rsp_t); + + SER_PULL_uint16(&p_struct->count); + SER_PULL_uint16(&p_struct->value_len); + + uint16_t list_length = (p_struct->value_len + sizeof(uint16_t)) * p_struct->count; + SER_ASSERT_LENGTH_LEQ(list_length, *p_ext_len); + SER_PULL_uint8array(p_struct->handle_value, list_length); + *p_ext_len = list_length; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_char_vals_read_rsp_t); + + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_uint8array(p_struct->values, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_char_vals_read_rsp_t); + + SER_PULL_uint16(&p_struct->len); + + SER_ASSERT_LENGTH_LEQ(p_struct->len, *p_ext_len); + SER_PULL_uint8array(p_struct->values, p_struct->len); + *p_ext_len = p_struct->len; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_handle_range_t); + + SER_PUSH_uint16(&p_struct->start_handle); + SER_PUSH_uint16(&p_struct->end_handle); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_handle_range_t); + + SER_PULL_uint16(&p_struct->start_handle); + SER_PULL_uint16(&p_struct->end_handle); + + SER_STRUCT_DEC_END; +} + + +uint32_t ble_gattc_service_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_service_t); + + SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc); + SER_PUSH_FIELD(&p_struct->handle_range, ble_gattc_handle_range_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_service_t); + + SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec); + SER_PULL_FIELD(&p_struct->handle_range, ble_gattc_handle_range_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_include_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_include_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_FIELD(&p_struct->included_srvc, ble_gattc_service_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_include_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_FIELD(&p_struct->included_srvc, ble_gattc_service_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_rel_disc_rsp_t); + + SER_PUSH_uint16(&p_struct->count); + + ble_gattc_include_t * p_include = &(p_struct->includes[0]); + uint32_t i; + + for (i = 0; i < p_struct->count; i++) + { + SER_PUSH_FIELD(p_include, ble_gattc_include_t_enc); + ++p_include; + } + + SER_STRUCT_ENC_END; +} + + + +uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_rel_disc_rsp_t); + + SER_PULL_uint16(&p_struct->count); + + uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_include_t)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + ble_gattc_include_t * p_include = &(p_struct->includes[0]); + uint32_t i; + + for (i = 0; i < p_struct->count; i++) + { + SER_PULL_FIELD(p_include, ble_gattc_include_t_dec); + ++p_include; + } + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_write_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_write_params_t); + + SER_PUSH_uint8(&p_struct->write_op); + SER_PUSH_uint8(&p_struct->flags); + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_len16data(p_struct->p_value, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_write_params_t); + + SER_PULL_uint8(&p_struct->write_op); + SER_PULL_uint8(&p_struct->flags); + SER_PULL_uint16(&p_struct->handle); + SER_PULL_uint16(&p_struct->offset); + SER_PULL_len16data((uint8_t **) &p_struct->p_value, &p_struct->len); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_attr_info16_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_attr_info16_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_FIELD(&(p_struct->uuid), ble_uuid_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_attr_info16_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_attr_info16_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_FIELD(&(p_struct->uuid), ble_uuid_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_attr_info128_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_attr_info128_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_FIELD(&(p_struct->uuid), ble_uuid128_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_attr_info128_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_attr_info128_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_FIELD(&(p_struct->uuid), ble_uuid128_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_attr_info_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_attr_info_disc_rsp_t); + + SER_PUSH_uint16(&p_struct->count); + SER_PUSH_uint8(&p_struct->format); + + field_encoder_handler_t fp_encoder = (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) ? + ble_gattc_attr_info16_t_enc : ble_gattc_attr_info128_t_enc; + + uint32_t i; + for (i = 0; i < p_struct->count; ++i) + { + void * uuid_struct; + uuid_struct = (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) ? + (void *)&(p_struct->info.attr_info16[i]) : (void *)&(p_struct->info.attr_info128[i]); + SER_PUSH_FIELD(uuid_struct, fp_encoder); + } + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_attr_info_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_attr_info_disc_rsp_t); + + SER_PULL_uint16(&p_struct->count); + SER_PULL_uint8(&p_struct->format); + + uint32_t i; + uint32_t data_len; + field_decoder_handler_t fp_decoder; + if (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) + { + fp_decoder = ble_gattc_attr_info16_t_dec; + data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_attr_info16_t)); + } + else + { + fp_decoder = ble_gattc_attr_info128_t_dec; + data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_attr_info128_t)); + } + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + for (i = 0; i < p_struct->count; i++) + { + void * uuid_struct; + uuid_struct = (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) ? + (void *)&(p_struct->info.attr_info16[i]) : (void *)&(p_struct->info.attr_info128[i]); + SER_PULL_FIELD(uuid_struct, fp_decoder); + } + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_char_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_char_t); + + uint8_t ser_data; + SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc); + SER_PUSH_FIELD(&p_struct->char_props, ble_gatt_char_props_t_enc); + ser_data = p_struct->char_ext_props & 0x01; + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint16(&p_struct->handle_decl); + SER_PUSH_uint16(&p_struct->handle_value); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_char_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_char_t); + + uint8_t ser_data; + SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec); + SER_PULL_FIELD(&p_struct->char_props, ble_gatt_char_props_t_dec); + SER_PULL_uint8(&ser_data); + p_struct->char_ext_props = ser_data & 0x01; + SER_PULL_uint16(&p_struct->handle_decl); + SER_PULL_uint16(&p_struct->handle_value); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_char_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_char_disc_rsp_t); + + SER_PUSH_uint16(&p_struct->count); + SER_PUSH_FIELD_ARRAY(p_struct->chars, ble_gattc_char_t_enc, p_struct->count); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_char_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_char_disc_rsp_t); + + SER_PULL_uint16(&p_struct->count); + uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_char_t)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_FIELD_ARRAY(p_struct->chars, ble_gattc_char_t_dec, p_struct->count); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_desc_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_desc_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_desc_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_desc_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_desc_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_desc_disc_rsp_t); + + SER_PUSH_uint16(&p_struct->count); + SER_PUSH_FIELD_ARRAY(p_struct->descs, ble_gattc_desc_t_enc, p_struct->count); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_desc_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_desc_disc_rsp_t); + + SER_PULL_uint16(&p_struct->count); + uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_desc_t)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_FIELD_ARRAY(p_struct->descs, ble_gattc_desc_t_dec, p_struct->count); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_hvx_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_hvx_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_uint8(&p_struct->type); + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_uint8array(p_struct->data, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_hvx_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_hvx_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_uint8(&p_struct->type); + SER_PULL_uint16(&p_struct->len); + + uint32_t data_len = (SUB1(p_struct->len)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_uint8array(p_struct->data, p_struct->len); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_prim_srvc_disc_rsp_t); + + SER_PUSH_uint16(&p_struct->count); + SER_PUSH_FIELD_ARRAY(p_struct->services, ble_gattc_service_t_enc, p_struct->count); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_prim_srvc_disc_rsp_t); + + SER_PULL_uint16(&p_struct->count); + uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_service_t)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_FIELD_ARRAY(p_struct->services, ble_gattc_service_t_dec, p_struct->count); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_read_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_read_rsp_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_uint8array(p_struct->data, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_read_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_read_rsp_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_uint16(&p_struct->offset); + SER_PULL_uint16(&p_struct->len); + + uint32_t data_len = (SUB1(p_struct->len)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_uint8array(p_struct->data, p_struct->len); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_timeout_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_timeout_t); + SER_PUSH_uint8(&p_struct->src); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_timeout_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_timeout_t); + SER_PULL_uint8(&p_struct->src); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_write_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_write_rsp_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_uint8(&p_struct->write_op); + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_uint8array(p_struct->data, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_write_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_write_rsp_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_uint8(&p_struct->write_op); + SER_PULL_uint16(&p_struct->offset); + SER_PULL_uint16(&p_struct->len); + + uint32_t data_len = (SUB1(p_struct->len)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_uint8array(p_struct->data, p_struct->len); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_exchange_mtu_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_exchange_mtu_rsp_t); + SER_PUSH_uint16(&p_struct->server_rx_mtu); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_exchange_mtu_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_exchange_mtu_rsp_t); + SER_PULL_uint16(&p_struct->server_rx_mtu); + SER_STRUCT_DEC_END; +} + +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gattc_conn_cfg_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_conn_cfg_t); + SER_PUSH_uint8(&p_struct->write_cmd_tx_queue_size); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_conn_cfg_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_conn_cfg_t); + SER_PULL_uint8(&p_struct->write_cmd_tx_queue_size); + SER_STRUCT_DEC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.h new file mode 100644 index 0000000000000000000000000000000000000000..c447f37f16a9db4eac6cf6f9d562eb4641acf20f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.h @@ -0,0 +1,293 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GATTC_STRUCT_SERIALIZATION_H +#define BLE_GATTC_STRUCT_SERIALIZATION_H + +#include "ble_gattc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_service_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_include_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_write_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_attr_info16_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_attr_info16_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_attr_info128_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_attr_info128_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_evt_attr_info_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_attr_info_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gatt_char_props_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatt_char_props_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatt_char_ext_props_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatt_char_ext_props_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_char_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_char_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_evt_char_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_char_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_desc_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_desc_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_evt_desc_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_desc_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_evt_hvx_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_hvx_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_evt_read_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_read_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_evt_timeout_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_timeout_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_evt_write_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_write_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_evt_exchange_mtu_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_exchange_mtu_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gattc_conn_cfg_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_conn_cfg_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#endif +#ifdef __cplusplus +} +#endif + +#endif /*BLE_GATTC_STRUCT_SERIALIZATION_H*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.c new file mode 100644 index 0000000000000000000000000000000000000000..8e7b7a0338d93abbaa900e567433b5d460ee2470 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.c @@ -0,0 +1,689 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gatt_struct_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_serialization.h" +#include "app_util.h" +#include "ble_gatts.h" +#include "cond_field_serialization.h" +#include + +uint32_t ble_gatts_char_pf_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_char_pf_t); + + SER_PUSH_uint8(&p_struct->format); + SER_PUSH_int8(&p_struct->exponent); + SER_PUSH_uint16(&p_struct->unit); + SER_PUSH_uint8(&p_struct->name_space); + SER_PUSH_uint16(&p_struct->desc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_char_pf_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_char_pf_t); + + SER_PULL_uint8(&p_struct->format); + SER_PULL_int8(&p_struct->exponent); + SER_PULL_uint16(&p_struct->unit); + SER_PULL_uint8(&p_struct->name_space); + SER_PULL_uint16(&p_struct->desc); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_attr_md_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_attr_md_t); + + SER_PUSH_FIELD(&p_struct->read_perm, ble_gap_conn_sec_mode_t_enc); + SER_PUSH_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_enc); + uint8_t ser_data = (p_struct->vlen & 0x01) + | ((p_struct->vloc & 0x03) << 1) + | ((p_struct->rd_auth & 0x01) << 3) + | ((p_struct->wr_auth & 0x01) << 4); + SER_PUSH_uint8(&ser_data); + + // Serializer does not support attributes on stack. + if (p_struct->vloc != BLE_GATTS_VLOC_STACK) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_attr_md_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_attr_md_t); + + uint8_t ser_data; + SER_PULL_FIELD(&p_struct->read_perm, ble_gap_conn_sec_mode_t_dec); + SER_PULL_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_dec); + SER_PULL_uint8(&ser_data); + + p_struct->vlen = ser_data & 0x01; + p_struct->vloc = (ser_data >> 1) & 0x03; + p_struct->rd_auth = (ser_data >> 3) & 0x01; + p_struct->wr_auth = (ser_data >> 4) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_char_md_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_char_md_t); + + SER_PUSH_FIELD(&p_struct->char_props, ble_gatt_char_props_t_enc); + SER_PUSH_FIELD(&p_struct->char_ext_props, ble_gatt_char_ext_props_t_enc); + SER_PUSH_uint16(&p_struct->char_user_desc_max_size); + SER_ERROR_CHECK(p_struct->char_user_desc_size <= BLE_GATTS_VAR_ATTR_LEN_MAX, + NRF_ERROR_INVALID_PARAM); + SER_PUSH_len16data(p_struct->p_char_user_desc, p_struct->char_user_desc_size); + SER_PUSH_COND(p_struct->p_char_pf, ble_gatts_char_pf_t_enc); + SER_PUSH_COND(p_struct->p_user_desc_md, ble_gatts_attr_md_t_enc); + SER_PUSH_COND(p_struct->p_cccd_md, ble_gatts_attr_md_t_enc); + SER_PUSH_COND(p_struct->p_sccd_md, ble_gatts_attr_md_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_char_md_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_char_md_t); + + SER_PULL_FIELD(&p_struct->char_props, ble_gatt_char_props_t_dec); + SER_PULL_FIELD(&p_struct->char_ext_props, ble_gatt_char_ext_props_t_dec); + SER_PULL_uint16(&p_struct->char_user_desc_max_size); +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + SER_PULL_len16data(&p_struct->p_char_user_desc, &p_struct->char_user_desc_size); +#else + SER_PULL_len16data((uint8_t * * )&p_struct->p_char_user_desc, &p_struct->char_user_desc_size); +#endif + SER_PULL_COND(&p_struct->p_char_pf, ble_gatts_char_pf_t_dec); + SER_PULL_COND(&p_struct->p_user_desc_md, ble_gatts_attr_md_t_dec); + SER_PULL_COND(&p_struct->p_cccd_md, ble_gatts_attr_md_t_dec); + SER_PULL_COND(&p_struct->p_sccd_md, ble_gatts_attr_md_t_dec); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_attr_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_attr_t); + + SER_PUSH_COND(p_struct->p_uuid, ble_uuid_t_enc); + SER_PUSH_COND(p_struct->p_attr_md, ble_gatts_attr_md_t_enc); + SER_PUSH_uint16(&p_struct->init_offs); + SER_PUSH_uint16(&p_struct->max_len); + SER_ERROR_CHECK(p_struct->init_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM); + SER_PUSH_len16data(p_struct->p_value, p_struct->init_len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_attr_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_attr_t); + + SER_PULL_COND(&p_struct->p_uuid, ble_uuid_t_dec); + SER_PULL_COND(&p_struct->p_attr_md, ble_gatts_attr_md_t_dec); + SER_PULL_uint16(&p_struct->init_offs); + SER_PULL_uint16(&p_struct->max_len); + SER_PULL_len16data(&p_struct->p_value, &p_struct->init_len); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_char_handles_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_char_handles_t); + + SER_PUSH_uint16(&p_struct->value_handle); + SER_PUSH_uint16(&p_struct->user_desc_handle); + SER_PUSH_uint16(&p_struct->cccd_handle); + SER_PUSH_uint16(&p_struct->sccd_handle); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_char_handles_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_char_handles_t); + + SER_PULL_uint16(&p_struct->value_handle); + SER_PULL_uint16(&p_struct->user_desc_handle); + SER_PULL_uint16(&p_struct->cccd_handle); + SER_PULL_uint16(&p_struct->sccd_handle); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_hvx_params_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_uint8(&p_struct->type); + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_COND(p_struct->p_len, uint16_t_enc); + if (p_struct->p_len) + { + SER_PUSH_buf(p_struct->p_data, *p_struct->p_len); + } + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_hvx_params_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_uint8(&p_struct->type); + SER_PULL_uint16(&p_struct->offset); + SER_PULL_COND(&p_struct->p_len, uint16_t_dec); + if (p_struct->p_len) + { +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + SER_PULL_buf(&p_struct->p_data, *p_struct->p_len, *p_struct->p_len); +#else + SER_PULL_buf((uint8_t**)&p_struct->p_data, *p_struct->p_len, *p_struct->p_len); +#endif + } + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_write_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc); + SER_PUSH_uint8(&p_struct->op); + SER_PUSH_uint8(&p_struct->auth_required); + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_uint8array(p_struct->data, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_write_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec); + SER_PULL_uint8(&p_struct->op); + SER_PULL_uint8(&p_struct->auth_required); + SER_PULL_uint16(&p_struct->offset); + SER_PULL_uint16(&p_struct->len); + + // Data field is defined as 1-element array, so the first element + // is always allocated in the structure. + SER_ASSERT_LENGTH_LEQ(p_struct->len, *p_ext_len + 1); + SER_PULL_uint8array(p_struct->data, p_struct->len); + *p_ext_len = (p_struct->len > 1) ? p_struct->len - 1 : 0; + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_read_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc); + SER_PUSH_uint16(&p_struct->offset); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_read_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec); + SER_PULL_uint16(&p_struct->offset); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_rw_authorize_request_t); + + SER_PUSH_uint8(&p_struct->type); + + switch (p_struct->type) + { + case BLE_GATTS_AUTHORIZE_TYPE_READ: + SER_PUSH_FIELD(&p_struct->request.read, ble_gatts_evt_read_t_enc); + break; + + case BLE_GATTS_AUTHORIZE_TYPE_WRITE: + SER_PUSH_FIELD(&p_struct->request.write, ble_gatts_evt_write_t_enc); + break; + + default: + case BLE_GATTS_AUTHORIZE_TYPE_INVALID: + err_code = NRF_ERROR_INVALID_PARAM; + break; + } + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_rw_authorize_request_t); + + SER_PULL_uint8(&p_struct->type); + + switch (p_struct->type) + { + case BLE_GATTS_AUTHORIZE_TYPE_READ: + SER_PULL_FIELD(&p_struct->request.read, ble_gatts_evt_read_t_dec); + break; + + case BLE_GATTS_AUTHORIZE_TYPE_WRITE: + err_code = ble_gatts_evt_write_t_dec(p_buf, + buf_len, + p_index, + p_ext_len, + &p_struct->request.write); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + break; + + default: + case BLE_GATTS_AUTHORIZE_TYPE_INVALID: + return NRF_ERROR_INVALID_DATA; + } + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_authorize_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_authorize_params_t); + + uint8_t ser_data = p_struct->update & 0x01; + SER_PUSH_uint16(&p_struct->gatt_status); + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_len16data(p_struct->p_data, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_authorize_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_authorize_params_t); + + uint8_t ser_data; + SER_PULL_uint16(&p_struct->gatt_status); + SER_PULL_uint8(&ser_data); + SER_PULL_uint16(&p_struct->offset); + SER_PULL_len16data((uint8_t **) &p_struct->p_data, &p_struct->len); + + p_struct->update = ser_data & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_rw_authorize_reply_params_t); + + SER_PUSH_uint8(&p_struct->type); + if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_READ) + { + SER_PUSH_FIELD(&p_struct->params.read, ble_gatts_authorize_params_t_enc); + } + else if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + SER_PUSH_FIELD(&p_struct->params.write, ble_gatts_authorize_params_t_enc); + } + else + { + return NRF_ERROR_INVALID_PARAM; + } + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_rw_authorize_reply_params_t); + + SER_PULL_uint8(&p_struct->type); + if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_READ) + { + SER_PULL_FIELD(&p_struct->params.read, ble_gatts_authorize_params_t_dec); + } + else if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + SER_PULL_FIELD(&p_struct->params.write, ble_gatts_authorize_params_t_dec); + } + else + { + return NRF_ERROR_INVALID_PARAM; + } + + SER_STRUCT_DEC_END; +} +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_gatts_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_enable_params_t); + + uint8_t ser_data = p_struct->service_changed & 0x01; + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint32(&p_struct->attr_tab_size); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_enable_params_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + SER_PULL_uint32(&p_struct->attr_tab_size); + + p_struct->service_changed = ser_data & 0x01; + + SER_STRUCT_DEC_END; +} +#endif + +uint32_t ble_gatts_value_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_value_t); + + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_len16data(p_struct->p_value, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_value_t); + + SER_PULL_uint16(&p_struct->offset); + SER_PULL_len16data(&p_struct->p_value, &p_struct->len); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_evt_exchange_mtu_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_exchange_mtu_request_t); + SER_PUSH_uint16(&p_struct->client_rx_mtu); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_exchange_mtu_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_exchange_mtu_request_t); + SER_PULL_uint16(&p_struct->client_rx_mtu); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_evt_hvc_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_hvc_t); + SER_PUSH_uint16(&p_struct->handle); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_hvc_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_hvc_t); + SER_PULL_uint16(&p_struct->handle); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_evt_sys_attr_missing_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_sys_attr_missing_t); + SER_PUSH_uint8(&p_struct->hint); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_sys_attr_missing_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_sys_attr_missing_t); + SER_PULL_uint8(&p_struct->hint); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_evt_timeout_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_timeout_t); + SER_PUSH_uint8(&p_struct->src); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_timeout_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_timeout_t); + SER_PULL_uint8(&p_struct->src); + SER_STRUCT_DEC_END; +} + +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gatts_conn_cfg_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_conn_cfg_t); + SER_PUSH_uint8(&p_struct->hvn_tx_queue_size); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_conn_cfg_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_conn_cfg_t); + SER_PULL_uint8(&p_struct->hvn_tx_queue_size); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_cfg_service_changed_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_cfg_service_changed_t); + uint8_t service_changed = p_struct->service_changed; + SER_PUSH_uint8(&service_changed); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_cfg_service_changed_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_cfg_service_changed_t); + uint8_t service_changed; + SER_PULL_uint8(&service_changed); + p_struct->service_changed = service_changed; + SER_STRUCT_DEC_END; +} +uint32_t ble_gatts_cfg_attr_tab_size_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_cfg_attr_tab_size_t); + SER_PUSH_uint32(&p_struct->attr_tab_size); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_cfg_attr_tab_size_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_cfg_attr_tab_size_t); + SER_PULL_uint32(&p_struct->attr_tab_size); + SER_STRUCT_DEC_END; +} + + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.h new file mode 100644 index 0000000000000000000000000000000000000000..9ea86d6db8abe853860e238aa312193714246104 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.h @@ -0,0 +1,259 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GATTS_STRUCT_SERIALIZATION_H +#define BLE_GATTS_STRUCT_SERIALIZATION_H + +#include "ble_gatts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t ble_gatts_char_pf_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_char_pf_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_attr_md_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_attr_md_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_char_md_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_char_md_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_attr_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_attr_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_char_handles_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_char_handles_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gatts_authorize_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_authorize_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_gatts_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#endif + +uint32_t ble_gatts_value_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_exchange_mtu_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_exchange_mtu_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_hvc_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_hvc_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_sys_attr_missing_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_sys_attr_missing_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_timeout_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_timeout_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gatts_conn_cfg_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_conn_cfg_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_cfg_service_changed_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_cfg_service_changed_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_cfg_attr_tab_size_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_cfg_attr_tab_size_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#endif +#ifdef __cplusplus +} +#endif + +#endif /* BLE_GATTS_STRUCT_SERIALIZATION_H */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_struct_serialization.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_struct_serialization.c new file mode 100644 index 0000000000000000000000000000000000000000..e2eb2c3acf628ebc959eaa042bdec54d617a3fe3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_struct_serialization.c @@ -0,0 +1,520 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_struct_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "ble_gatt_struct_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "ble_serialization.h" +#include "app_util.h" +#include "ble_types.h" +#include "ble_l2cap.h" +#include "ble.h" +#include "cond_field_serialization.h" +#include + + +uint32_t ble_uuid_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_uuid_t); + + SER_PUSH_uint16(&p_struct->uuid); + SER_PUSH_uint8(&p_struct->type); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_uuid_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_uuid_t); + + SER_PULL_uint16(&p_struct->uuid); + SER_PULL_uint8(&p_struct->type); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_uuid128_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_uuid128_t); + SER_PUSH_uint8array(p_struct->uuid128, sizeof (p_struct->uuid128)); + SER_STRUCT_ENC_END; +} + +uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_uuid128_t); + SER_PULL_uint8array(p_struct->uuid128, sizeof (p_struct->uuid128)); + SER_STRUCT_DEC_END; +} + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_l2cap_header_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_l2cap_header_t); + + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_uint16(&p_struct->cid); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_l2cap_header_t); + + SER_PULL_uint16(&p_struct->len); + SER_PULL_uint16(&p_struct->cid); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_l2cap_evt_rx_t); + + SER_PUSH_FIELD(&p_struct->header, ble_l2cap_header_t_enc); + SER_PUSH_uint8array(p_struct->data, p_struct->header.len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_l2cap_evt_rx_t); + + SER_PULL_FIELD(&p_struct->header, ble_l2cap_header_t_dec); + + uint32_t data_len = (SUB1(p_struct->header.len)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_uint8array(p_struct->data, p_struct->header.len); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_enable_params_t); + + SER_PUSH_FIELD(&p_struct->common_enable_params, ble_common_enable_params_t_enc); + SER_PUSH_FIELD(&p_struct->gap_enable_params, ble_gap_enable_params_t_enc); + SER_PUSH_FIELD(&p_struct->gatt_enable_params, ble_gatt_enable_params_t_enc); + SER_PUSH_FIELD(&p_struct->gatts_enable_params, ble_gatts_enable_params_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_enable_params_t); + + SER_PULL_FIELD(&p_struct->common_enable_params, ble_common_enable_params_t_dec); + SER_PULL_FIELD(&p_struct->gap_enable_params, ble_gap_enable_params_t_dec); + SER_PULL_FIELD(&p_struct->gatt_enable_params, ble_gatt_enable_params_t_dec); + SER_PULL_FIELD(&p_struct->gatts_enable_params, ble_gatts_enable_params_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_conn_bw_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_conn_bw_t); + + SER_PUSH_uint8(&p_struct->conn_bw_rx); + SER_PUSH_uint8(&p_struct->conn_bw_tx); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_conn_bw_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_conn_bw_t); + + SER_PULL_uint8(&p_struct->conn_bw_rx); + SER_PULL_uint8(&p_struct->conn_bw_tx); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_common_opt_conn_bw_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_common_opt_conn_bw_t); + + SER_PUSH_uint8(&p_struct->role); + SER_PUSH_FIELD(&p_struct->conn_bw, ble_conn_bw_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_common_opt_conn_bw_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_common_opt_conn_bw_t); + + SER_PULL_uint8(&p_struct->role); + SER_PULL_FIELD(&p_struct->conn_bw, ble_conn_bw_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_conn_bw_count_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_conn_bw_count_t); + + SER_PUSH_uint8(&p_struct->high_count); + SER_PUSH_uint8(&p_struct->mid_count); + SER_PUSH_uint8(&p_struct->low_count); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_conn_bw_count_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_conn_bw_count_t); + + SER_PULL_uint8(&p_struct->high_count); + SER_PULL_uint8(&p_struct->mid_count); + SER_PULL_uint8(&p_struct->low_count); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_conn_bw_counts_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_conn_bw_counts_t); + + SER_PUSH_FIELD(&p_struct->tx_counts, ble_conn_bw_count_t_enc); + SER_PUSH_FIELD(&p_struct->rx_counts, ble_conn_bw_count_t_enc); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_conn_bw_counts_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_conn_bw_counts_t); + + SER_PULL_FIELD(&p_struct->tx_counts, ble_conn_bw_count_t_dec); + SER_PULL_FIELD(&p_struct->rx_counts, ble_conn_bw_count_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_common_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_common_enable_params_t); + + SER_PUSH_uint16(&p_struct->vs_uuid_count); + SER_PUSH_COND(p_struct->p_conn_bw_counts, ble_conn_bw_counts_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_common_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_common_enable_params_t); + + SER_PULL_uint16(&p_struct->vs_uuid_count); + SER_PULL_COND(&p_struct->p_conn_bw_counts, ble_conn_bw_counts_t_dec); + + SER_STRUCT_DEC_END; +} +#endif +uint32_t ble_common_opt_pa_lna_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_common_opt_pa_lna_t); + + SER_PUSH_FIELD(&p_struct->pa_cfg, ble_pa_lna_cfg_t_enc); + SER_PUSH_FIELD(&p_struct->lna_cfg, ble_pa_lna_cfg_t_enc); + SER_PUSH_uint8(&p_struct->ppi_ch_id_set); + SER_PUSH_uint8(&p_struct->ppi_ch_id_clr); + SER_PUSH_uint8(&p_struct->gpiote_ch_id); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_common_opt_pa_lna_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_common_opt_pa_lna_t); + + SER_PULL_FIELD(&p_struct->pa_cfg, ble_pa_lna_cfg_t_dec); + SER_PULL_FIELD(&p_struct->lna_cfg, ble_pa_lna_cfg_t_dec); + SER_PULL_uint8(&p_struct->ppi_ch_id_set); + SER_PULL_uint8(&p_struct->ppi_ch_id_clr); + SER_PULL_uint8(&p_struct->gpiote_ch_id); + + SER_STRUCT_DEC_END; +} + + +uint32_t ble_pa_lna_cfg_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_pa_lna_cfg_t); + + uint8_t ser_data = (p_struct->enable & 0x01) + | ((p_struct->active_high & 0x01) << 1) + | ((p_struct->gpio_pin & 0x3F) << 2); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_pa_lna_cfg_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_pa_lna_cfg_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->enable = ser_data & 0x01; + p_struct->active_high = (ser_data >> 1) & 0x01; + p_struct->gpio_pin = (ser_data >> 2) & 0x3F; + + SER_STRUCT_DEC_END; +} + + +uint32_t ble_user_mem_block_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_user_mem_block_t); + + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_COND(p_struct->p_mem, NULL); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_user_mem_block_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_user_mem_block_t); + + SER_PULL_uint16(&p_struct->len); + SER_PULL_COND(&p_struct->p_mem, NULL); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_version_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_version_t); + + SER_PUSH_uint8(&p_struct->version_number); + SER_PUSH_uint16(&p_struct->company_id); + SER_PUSH_uint16(&p_struct->subversion_number); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_version_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_version_t); + + SER_PULL_uint8(&p_struct->version_number); + SER_PULL_uint16(&p_struct->company_id); + SER_PULL_uint16(&p_struct->subversion_number); + + SER_STRUCT_DEC_END; +} +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_evt_data_length_changed_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_evt_data_length_changed_t); + + SER_PUSH_uint16(&p_struct->max_tx_octets); + SER_PUSH_uint16(&p_struct->max_tx_time); + SER_PUSH_uint16(&p_struct->max_rx_octets); + SER_PUSH_uint16(&p_struct->max_rx_time); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_evt_data_length_changed_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_evt_data_length_changed_t); + + SER_PULL_uint16(&p_struct->max_tx_octets); + SER_PULL_uint16(&p_struct->max_tx_time); + SER_PULL_uint16(&p_struct->max_rx_octets); + SER_PULL_uint16(&p_struct->max_rx_time); + + SER_STRUCT_DEC_END; +} +#endif +uint32_t ble_common_opt_conn_evt_ext_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_common_opt_conn_evt_ext_t); + + uint8_t ser_data = p_struct->enable & 0x01; + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_common_opt_conn_evt_ext_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_common_opt_conn_evt_ext_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->enable = ser_data & 0x01; + + SER_STRUCT_DEC_END; +} +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_common_cfg_vs_uuid_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_common_cfg_vs_uuid_t); + + SER_PUSH_uint8(&p_struct->vs_uuid_count); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_common_cfg_vs_uuid_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_common_cfg_vs_uuid_t); + + SER_PULL_uint8(&p_struct->vs_uuid_count); + + SER_STRUCT_DEC_END; +} + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_struct_serialization.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_struct_serialization.h new file mode 100644 index 0000000000000000000000000000000000000000..76bf7570fd11fd47217536545d93be28110da602 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/ble_struct_serialization.h @@ -0,0 +1,226 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_STRUCT_SERIALIZATION_H__ +#define BLE_STRUCT_SERIALIZATION_H__ + +#include "ble_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +uint32_t ble_uuid_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_uuid_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_uuid128_t_enc(const void * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_l2cap_header_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_conn_bw_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_conn_bw_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_common_opt_conn_bw_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_common_opt_conn_bw_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_conn_bw_count_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_conn_bw_count_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_conn_bw_counts_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_conn_bw_counts_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_common_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_common_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_common_opt_pa_lna_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_common_opt_pa_lna_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_pa_lna_cfg_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_pa_lna_cfg_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_user_mem_block_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_user_mem_block_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_version_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_version_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_evt_data_length_changed_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_evt_data_length_changed_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_common_opt_conn_evt_ext_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_common_opt_conn_evt_ext_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_common_cfg_vs_uuid_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_common_cfg_vs_uuid_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#endif +#ifdef __cplusplus +} +#endif + +#endif // BLE_STRUCT_SERIALIZATION_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.c new file mode 100644 index 0000000000000000000000000000000000000000..210f2cf10da18a46db65bc1c43e79fa859474a66 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.c @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_soc_struct_serialization.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include "string.h" + +uint32_t nrf_ecb_hal_data_t_in_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(nrf_ecb_hal_data_t); + + SER_PUSH_uint8array(p_struct->key, SOC_ECB_KEY_LENGTH); + SER_PUSH_uint8array(p_struct->cleartext, SOC_ECB_CLEARTEXT_LENGTH); + + SER_STRUCT_DEC_END; +} + +uint32_t nrf_ecb_hal_data_t_in_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(nrf_ecb_hal_data_t); + + SER_PULL_uint8array(p_struct->key, SOC_ECB_KEY_LENGTH); + SER_PULL_uint8array(p_struct->cleartext, SOC_ECB_CLEARTEXT_LENGTH); + + SER_STRUCT_DEC_END; +} + +uint32_t nrf_ecb_hal_data_t_out_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(nrf_ecb_hal_data_t); + SER_PUSH_uint8array(p_struct->ciphertext, SOC_ECB_CIPHERTEXT_LENGTH); + SER_STRUCT_DEC_END; +} + +uint32_t nrf_ecb_hal_data_t_out_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(nrf_ecb_hal_data_t); + SER_PULL_uint8array(p_struct->ciphertext, SOC_ECB_CIPHERTEXT_LENGTH); + SER_STRUCT_DEC_END; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.h new file mode 100644 index 0000000000000000000000000000000000000000..55a6415854a5336c4e908c1fd03a16c8f91673c3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.h @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SOC_STRUCT_SERIALIZATION_H__ +#define NRF_SOC_STRUCT_SERIALIZATION_H__ + +#include "nrf_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t nrf_ecb_hal_data_t_in_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t nrf_ecb_hal_data_t_in_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t nrf_ecb_hal_data_t_out_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t nrf_ecb_hal_data_t_out_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SOC_STRUCT_SERIALIZATION_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/dtm_uart_params.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/dtm_uart_params.h new file mode 100644 index 0000000000000000000000000000000000000000..f91faa1ec6751338066e297c911261d8c655d470 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/dtm_uart_params.h @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef DTM_UART_PARAMS_H__ +#define DTM_UART_PARAMS_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @ingroup ble_dtm_app + */ + + +/**@brief Enumeration of supported baud rates. */ +typedef enum +{ + UART_BAUD_RATE_1200, /**< Baud rate 1200. */ + UART_BAUD_RATE_2400, /**< Baud rate 2400. */ + UART_BAUD_RATE_4800, /**< Baud rate 4800. */ + UART_BAUD_RATE_9600, /**< Baud rate 9600. */ + UART_BAUD_RATE_14400, /**< Baud rate 14400. */ + UART_BAUD_RATE_19200, /**< Baud rate 19200. */ + UART_BAUD_RATE_28800, /**< Baud rate 28800. */ + UART_BAUD_RATE_38400, /**< Baud rate 38400. */ + UART_BAUD_RATE_57600, /**< Baud rate 57600. */ + UART_BAUD_RATE_76800, /**< Baud rate 76800. */ + UART_BAUD_RATE_115200, /**< Baud rate 115200. */ + UART_BAUD_RATE_230400, /**< Baud rate 230400. */ + UART_BAUD_RATE_250000, /**< Baud rate 250000. */ + UART_BAUD_RATE_460800, /**< Baud rate 460800. */ + UART_BAUD_RATE_921600, /**< Baud rate 921600. */ + UART_BAUD_RATE_1000000, /**< Baud rate 1000000. */ + UART_BAUD_RATE_MAX /**< Enumeration upper bound. */ +} app_uart_stream_baud_rate_t; + +/**@brief UART communication structure holding configuration settings for the peripheral. + */ +typedef struct +{ + uint8_t rx_pin_no; /**< RX pin number. */ + uint8_t tx_pin_no; /**< TX pin number. */ + uint8_t rts_pin_no; /**< RTS pin number, only used if flow control is enabled. */ + uint8_t cts_pin_no; /**< CTS pin number, only used if flow control is enabled. */ + bool use_parity; /**< Even parity if TRUE, no parity if FALSE. */ + app_uart_stream_baud_rate_t baud_rate; /**< Baud rate configuration. */ +} app_uart_stream_comm_params_t; + + +#ifdef __cplusplus +} +#endif + +#endif // DTM_UART_PARAMS_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_hal_transport.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_hal_transport.c new file mode 100644 index 0000000000000000000000000000000000000000..86837bb8caa981504ae2af40bd896456090db8c6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_hal_transport.c @@ -0,0 +1,487 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "app_error.h" +#include "ser_config.h" +#include "ser_phy.h" +#include "ser_hal_transport.h" + +/** + * @brief States of the RX state machine. + */ +typedef enum +{ + HAL_TRANSP_RX_STATE_CLOSED = 0, + HAL_TRANSP_RX_STATE_IDLE, + HAL_TRANSP_RX_STATE_RECEIVING, + HAL_TRANSP_RX_STATE_DROPPING, + HAL_TRANSP_RX_STATE_RECEIVED, + HAL_TRANSP_RX_STATE_RECEIVED_PENDING_BUF_REQ, + HAL_TRANSP_RX_STATE_RECEIVED_DROPPING, + HAL_TRANSP_RX_STATE_MAX +}ser_hal_transp_rx_states_t; + +/** + * @brief States of the TX state machine. + */ +typedef enum +{ + HAL_TRANSP_TX_STATE_CLOSED = 0, + HAL_TRANSP_TX_STATE_IDLE, + HAL_TRANSP_TX_STATE_TX_ALLOCATED, + HAL_TRANSP_TX_STATE_TRANSMITTING, + HAL_TRANSP_TX_STATE_TRANSMITTED, + HAL_TRANSP_TX_STATE_MAX +}ser_hal_transp_tx_states_t; + +/** + * @brief RX state. + */ +static ser_hal_transp_rx_states_t m_rx_state = HAL_TRANSP_RX_STATE_CLOSED; +/** + * @brief TX state. + */ +static ser_hal_transp_tx_states_t m_tx_state = HAL_TRANSP_TX_STATE_CLOSED; + +/** + * @brief Transmission buffer. + */ +static uint8_t m_tx_buffer[SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE]; +/** + * @brief Reception buffer. + */ +static uint8_t m_rx_buffer[SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE]; + +/** + * @brief Callback function handler for Serialization HAL Transport layer events. + */ +static ser_hal_transport_events_handler_t m_events_handler = NULL; + + +/** + * @brief A callback function to be used to handle a PHY module events. This function is called in + * an interrupt context. + */ +static void phy_events_handler(ser_phy_evt_t phy_event) +{ + uint32_t err_code = 0; + ser_hal_transport_evt_t hal_transp_event; + + memset(&hal_transp_event, 0, sizeof (ser_hal_transport_evt_t)); + hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_TYPE_MAX; + + switch (phy_event.evt_type) + { + case SER_PHY_EVT_TX_PKT_SENT: + { + if (HAL_TRANSP_TX_STATE_TRANSMITTING == m_tx_state) + { + m_tx_state = HAL_TRANSP_TX_STATE_TRANSMITTED; + err_code = ser_hal_transport_tx_pkt_free(m_tx_buffer); + APP_ERROR_CHECK(err_code); + /* An event to an upper layer that a packet has been transmitted. */ + hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_TX_PKT_SENT; + m_events_handler(hal_transp_event); + } + else + { + /* Lower layer should not generate this event in current state. */ + APP_ERROR_CHECK_BOOL(false); + } + break; + } + + case SER_PHY_EVT_RX_BUF_REQUEST: + { + /* An event to an upper layer that a packet is being scheduled to receive or to drop. */ + hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_RX_PKT_RECEIVING; + + /* Receive or drop a packet. */ + if (phy_event.evt_params.rx_buf_request.num_of_bytes <= sizeof (m_rx_buffer)) + { + if (HAL_TRANSP_RX_STATE_IDLE == m_rx_state) + { + m_events_handler(hal_transp_event); + err_code = ser_phy_rx_buf_set(m_rx_buffer); + APP_ERROR_CHECK(err_code); + m_rx_state = HAL_TRANSP_RX_STATE_RECEIVING; + } + else if (HAL_TRANSP_RX_STATE_RECEIVED == m_rx_state) + { + /* It is OK to get know higher layer at this point that we are going to receive + * a new packet even though we will start receiving when rx buffer is freed. */ + m_events_handler(hal_transp_event); + m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED_PENDING_BUF_REQ; + } + else + { + /* Lower layer should not generate this event in current state. */ + APP_ERROR_CHECK_BOOL(false); + } + } + else + { + /* There is not enough memory but packet has to be received to dummy location. */ + if (HAL_TRANSP_RX_STATE_IDLE == m_rx_state) + { + m_events_handler(hal_transp_event); + err_code = ser_phy_rx_buf_set(NULL); + APP_ERROR_CHECK(err_code); + m_rx_state = HAL_TRANSP_RX_STATE_DROPPING; + } + else if (HAL_TRANSP_RX_STATE_RECEIVED == m_rx_state) + { + m_events_handler(hal_transp_event); + err_code = ser_phy_rx_buf_set(NULL); + APP_ERROR_CHECK(err_code); + m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED_DROPPING; + } + else + { + /* Lower layer should not generate this event in current state. */ + APP_ERROR_CHECK_BOOL(false); + } + } + break; + } + + case SER_PHY_EVT_RX_PKT_RECEIVED: + { + if (HAL_TRANSP_RX_STATE_RECEIVING == m_rx_state) + { + m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED; + /* Generate the event to an upper layer. */ + hal_transp_event.evt_type = + SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED; + hal_transp_event.evt_params.rx_pkt_received.p_buffer = + phy_event.evt_params.rx_pkt_received.p_buffer; + hal_transp_event.evt_params.rx_pkt_received.num_of_bytes = + phy_event.evt_params.rx_pkt_received.num_of_bytes; + m_events_handler(hal_transp_event); + } + else + { + /* Lower layer should not generate this event in current state. */ + APP_ERROR_CHECK_BOOL(false); + } + break; + } + + case SER_PHY_EVT_RX_PKT_DROPPED: + { + if (HAL_TRANSP_RX_STATE_DROPPING == m_rx_state) + { + /* Generate the event to an upper layer. */ + hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_RX_PKT_DROPPED; + m_events_handler(hal_transp_event); + m_rx_state = HAL_TRANSP_RX_STATE_IDLE; + } + else if (HAL_TRANSP_RX_STATE_RECEIVED_DROPPING == m_rx_state) + { + /* Generate the event to an upper layer. */ + hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_RX_PKT_DROPPED; + m_events_handler(hal_transp_event); + m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED; + } + else + { + /* Lower layer should not generate this event in current state. */ + APP_ERROR_CHECK_BOOL(false); + } + break; + } + + case SER_PHY_EVT_RX_OVERFLOW_ERROR: + { + /* Generate the event to an upper layer. */ + hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_PHY_ERROR; + hal_transp_event.evt_params.phy_error.error_type = + SER_HAL_TRANSP_PHY_ERROR_RX_OVERFLOW; + m_events_handler(hal_transp_event); + break; + } + + case SER_PHY_EVT_TX_OVERREAD_ERROR: + { + /* Generate the event to an upper layer. */ + hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_PHY_ERROR; + hal_transp_event.evt_params.phy_error.error_type = + SER_HAL_TRANSP_PHY_ERROR_TX_OVERREAD; + m_events_handler(hal_transp_event); + break; + } + + case SER_PHY_EVT_HW_ERROR: + { + /* Generate the event to an upper layer. */ + hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_PHY_ERROR; + hal_transp_event.evt_params.phy_error.error_type = + SER_HAL_TRANSP_PHY_ERROR_HW_ERROR; + hal_transp_event.evt_params.phy_error.hw_error_code = + phy_event.evt_params.hw_error.error_code; + if (HAL_TRANSP_TX_STATE_TRANSMITTING == m_tx_state) + { + m_tx_state = HAL_TRANSP_TX_STATE_TRANSMITTED; + err_code = ser_hal_transport_tx_pkt_free(phy_event.evt_params.hw_error.p_buffer); + APP_ERROR_CHECK(err_code); + /* An event to an upper layer that a packet has been transmitted. */ + } + else if (HAL_TRANSP_RX_STATE_RECEIVING == m_rx_state) + { + m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED; + err_code = ser_hal_transport_rx_pkt_free(phy_event.evt_params.hw_error.p_buffer); + APP_ERROR_CHECK(err_code); + } + m_events_handler(hal_transp_event); + + break; + } + + default: + { + APP_ERROR_CHECK_BOOL(false); + break; + } + } +} + +uint32_t ser_hal_transport_open(ser_hal_transport_events_handler_t events_handler) +{ + uint32_t err_code = NRF_SUCCESS; + + if ((HAL_TRANSP_RX_STATE_CLOSED != m_rx_state) || (HAL_TRANSP_TX_STATE_CLOSED != m_tx_state)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else if (NULL == events_handler) + { + err_code = NRF_ERROR_NULL; + } + else + { + /* We have to change states before calling lower layer because ser_phy_open() function is + * going to enable interrupts. On success an event from PHY layer can be emitted immediately + * after return from ser_phy_open(). */ + m_rx_state = HAL_TRANSP_RX_STATE_IDLE; + m_tx_state = HAL_TRANSP_TX_STATE_IDLE; + + m_events_handler = events_handler; + + /* Initialize a PHY module. */ + err_code = ser_phy_open(phy_events_handler); + + if (NRF_SUCCESS != err_code) + { + m_rx_state = HAL_TRANSP_RX_STATE_CLOSED; + m_tx_state = HAL_TRANSP_TX_STATE_CLOSED; + m_events_handler = NULL; + + if (NRF_ERROR_INVALID_PARAM != err_code) + { + err_code = NRF_ERROR_INTERNAL; + } + } + } + + return err_code; +} + + +void ser_hal_transport_close(void) +{ + /* Reset generic handler for all events, reset internal states and close PHY module. */ + ser_phy_interrupts_disable(); + m_rx_state = HAL_TRANSP_RX_STATE_CLOSED; + m_tx_state = HAL_TRANSP_TX_STATE_CLOSED; + + m_events_handler = NULL; + + ser_phy_close(); +} + + +uint32_t ser_hal_transport_rx_pkt_free(uint8_t * p_buffer) +{ + uint32_t err_code = NRF_SUCCESS; + + ser_phy_interrupts_disable(); + + if (NULL == p_buffer) + { + err_code = NRF_ERROR_NULL; + } + else if (p_buffer != m_rx_buffer) + { + err_code = NRF_ERROR_INVALID_ADDR; + } + else if (HAL_TRANSP_RX_STATE_RECEIVED == m_rx_state) + { + m_rx_state = HAL_TRANSP_RX_STATE_IDLE; + } + else if (HAL_TRANSP_RX_STATE_RECEIVED_DROPPING == m_rx_state) + { + m_rx_state = HAL_TRANSP_RX_STATE_DROPPING; + } + else if (HAL_TRANSP_RX_STATE_RECEIVED_PENDING_BUF_REQ == m_rx_state) + { + err_code = ser_phy_rx_buf_set(m_rx_buffer); + + if (NRF_SUCCESS == err_code) + { + m_rx_state = HAL_TRANSP_RX_STATE_RECEIVING; + } + else + { + err_code = NRF_ERROR_INTERNAL; + } + } + else + { + /* Upper layer should not call this function in current state. */ + err_code = NRF_ERROR_INVALID_STATE; + } + ser_phy_interrupts_enable(); + + return err_code; +} + + +uint32_t ser_hal_transport_tx_pkt_alloc(uint8_t * * pp_memory, uint16_t * p_num_of_bytes) +{ + uint32_t err_code = NRF_SUCCESS; + + if ((NULL == pp_memory) || (NULL == p_num_of_bytes)) + { + err_code = NRF_ERROR_NULL; + } + else if (HAL_TRANSP_TX_STATE_CLOSED == m_tx_state) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else if (HAL_TRANSP_TX_STATE_IDLE == m_tx_state) + { + m_tx_state = HAL_TRANSP_TX_STATE_TX_ALLOCATED; + *pp_memory = &m_tx_buffer[0]; + *p_num_of_bytes = (uint16_t)sizeof (m_tx_buffer); + } + else + { + err_code = NRF_ERROR_NO_MEM; + } + + return err_code; +} + + +uint32_t ser_hal_transport_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) +{ + uint32_t err_code = NRF_SUCCESS; + + /* The buffer provided to this function must be allocated through ser_hal_transport_tx_alloc() + * function - this assures correct state and that correct memory buffer is used. */ + if (NULL == p_buffer) + { + err_code = NRF_ERROR_NULL; + } + else if (0 == num_of_bytes) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else if (p_buffer != m_tx_buffer) + { + err_code = NRF_ERROR_INVALID_ADDR; + } + else if (num_of_bytes > sizeof (m_tx_buffer)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + else if (HAL_TRANSP_TX_STATE_TX_ALLOCATED == m_tx_state) + { + ser_phy_interrupts_disable(); + err_code = ser_phy_tx_pkt_send(p_buffer, num_of_bytes); + + if (NRF_SUCCESS == err_code) + { + m_tx_state = HAL_TRANSP_TX_STATE_TRANSMITTING; + } + else + { + if (NRF_ERROR_BUSY != err_code) + { + err_code = NRF_ERROR_INTERNAL; + } + } + ser_phy_interrupts_enable(); + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + + return err_code; +} + + +uint32_t ser_hal_transport_tx_pkt_free(uint8_t * p_buffer) +{ + uint32_t err_code = NRF_SUCCESS; + + if (NULL == p_buffer) + { + err_code = NRF_ERROR_NULL; + } + else if (p_buffer != m_tx_buffer) + { + err_code = NRF_ERROR_INVALID_ADDR; + } + else if ((HAL_TRANSP_TX_STATE_TX_ALLOCATED == m_tx_state) || + (HAL_TRANSP_TX_STATE_TRANSMITTED == m_tx_state)) + { + /* Release TX buffer for use. */ + m_tx_state = HAL_TRANSP_TX_STATE_IDLE; + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_hal_transport.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_hal_transport.h new file mode 100644 index 0000000000000000000000000000000000000000..c281970e074607c48a654e0e12577a0cf125eaa4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_hal_transport.h @@ -0,0 +1,266 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ser_hal_transport Serialization HAL Transport + * @{ + * @ingroup ble_sdk_lib_serialization + * + * @brief HAL Transport layer for serialization. + * + * @details The @ref ser_hal_transport declares functions and typedefs used as API of the HAL + * transport layer for serialization. This layer is fully hardware-independent. + * Currently, the HAL transport layer is responsible for controlling the PHY layer and + * memory management. In the future, more features might be added to it, such as CRC + * or retransmission. + * + * \n \n + * \image html ser_hal_transport_rx_state_machine.svg "RX state machine" + * \n \n + * \image html ser_hal_transport_tx_state_machine.svg "TX state machine" + * \n + */ + +#ifndef SER_HAL_TRANSPORT_H__ +#define SER_HAL_TRANSPORT_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Serialization HAL Transport layer event types. */ +typedef enum +{ + SER_HAL_TRANSP_EVT_TX_PKT_SENT = 0, /**< An event indicating that TX packet has been + transmitted. */ + SER_HAL_TRANSP_EVT_RX_PKT_RECEIVING, /**< An event indicating that RX packet is being + scheduled to receive or to drop. */ + SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED, /**< An event indicating that RX packet is ready for + read. */ + SER_HAL_TRANSP_EVT_RX_PKT_DROPPED, /**< An event indicating that RX packet was dropped + because it was longer than available buffer. */ + SER_HAL_TRANSP_EVT_PHY_ERROR, /**< An event indicating error on PHY layer. */ + SER_HAL_TRANSP_EVT_TYPE_MAX /**< Enumeration upper bound. */ +} ser_hal_transport_evt_type_t; + + +/**@brief Serialization PHY layer error types. */ +typedef enum +{ + SER_HAL_TRANSP_PHY_ERROR_RX_OVERFLOW = 0, /**< An error indicating that more information has + been transmitted than the PHY module could handle. */ + SER_HAL_TRANSP_PHY_ERROR_TX_OVERREAD, /**< An error indicating that the PHY module was forced to + transmit more information than possessed. */ + SER_HAL_TRANSP_PHY_ERROR_HW_ERROR, /**< An error indicating a hardware error in the PHY + module. */ + SER_HAL_TRANSP_PHY_ERROR_TYPE_MAX /**< Enumeration upper bound. */ +} ser_hal_transport_phy_error_type_t; + + +/**@brief Struct containing parameters of event of type + * @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED. + */ +typedef struct +{ + uint8_t * p_buffer; /**< Pointer to a buffer containing a packet to read. */ + uint16_t num_of_bytes; /**< Length of a received packet in octets. */ +} ser_hal_transport_evt_rx_pkt_received_params_t; + + +/**@brief Struct containing parameters of event of type @ref SER_HAL_TRANSP_EVT_PHY_ERROR. */ +typedef struct +{ + ser_hal_transport_phy_error_type_t error_type; /**< Type of the PHY error. */ + uint32_t hw_error_code; /**< Hardware error code - specific for a microcontroller. Parameter + is valid only for the PHY error of type + @ref SER_HAL_TRANSP_PHY_ERROR_HW_ERROR. */ +} ser_hal_transport_evt_phy_error_params_t; + + +/**@brief Struct containing events from the Serialization HAL Transport layer. + * + * @note Some events do not have parameters, then the whole information is contained in the evt_type. + */ +typedef struct +{ + ser_hal_transport_evt_type_t evt_type; /**< Type of event. */ + union /**< Union alternative identified by evt_type in the enclosing struct. */ + { + ser_hal_transport_evt_rx_pkt_received_params_t rx_pkt_received; /**< Parameters of event of type @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED. */ + ser_hal_transport_evt_phy_error_params_t phy_error; /**< Parameters of event of type @ref SER_HAL_TRANSP_EVT_PHY_ERROR. */ + } evt_params; +} ser_hal_transport_evt_t; + + +/**@brief Generic callback function type to be used by all Serialization HAL Transport layer + * events. + * + * @param[in] event Serialization HAL Transport layer event. + */ +typedef void (*ser_hal_transport_events_handler_t)(ser_hal_transport_evt_t event); + + +/**@brief Function for opening and initializing the Serialization HAL Transport layer. + * + * @note The function opens the transport channel, initializes a PHY layer, and registers the callback + * function to be used by all Serialization HAL Transport layer events. + * + * @warning If the function has been already called, the function @ref ser_hal_transport_close has + * to be called before ser_hal_transport_open can be called again. + * + * @param[in] events_handler Generic callback function to be used by all Serialization HAL + * Transport layer events. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_PARAM Operation failure. Hardware initialization parameters taken from + * the configuration file are wrong. + * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called. To call + * it again the function @ref ser_hal_transport_close has to be + * called first. + * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred. + */ +uint32_t ser_hal_transport_open(ser_hal_transport_events_handler_t events_handler); + + +/**@brief Function for closing a transport channel. + * + * @note The function disables the hardware, resets internal module states, and unregisters the events + * callback function. Can be called multiple times, also for a channel that is not opened. + */ +void ser_hal_transport_close(void); + + +/**@brief Function for freeing memory allocated for an RX packet. + * + * @note The function should be called as a response to an event of type + * @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED when the received data has beed processed. The function + * frees the RX memory pointed by p_buffer. The memory, immediately or at a later time, is + * reused by the underlying transport layer. + * + * @param[in] p_buffer A pointer to the beginning of the buffer that has been processed (has to be + * the same address as provided in the event of type + * @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED). + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer (provided address is not + * the starting address of a buffer managed by HAL Transport layer). + * @retval NRF_ERROR_INVALID_STATE Operation failure. The function should be called as a response + * to an event of type @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED. + * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred. + */ +uint32_t ser_hal_transport_rx_pkt_free(uint8_t * p_buffer); + + +/**@brief Function for allocating memory for a TX packet. + * + * @param[out] pp_memory A pointer to pointer to which an address of the beginning of the + * allocated buffer is written. + * @param[out] p_num_of_bytes A pointer to a variable to which size in octets of the allocated + * buffer is written. + * + * @retval NRF_SUCCESS Operation success. Memory was allocated. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_NO_MEM Operation failure. No memory available. + * @retval NRF_ERROR_INVALID_STATE Operation failure. The function was called before calling + * @ref ser_hal_transport_open function. + */ +uint32_t ser_hal_transport_tx_pkt_alloc(uint8_t ** pp_memory, uint16_t * p_num_of_bytes); + +/**@brief Function for transmitting a packet. + * + * @note The function adds a packet pointed by the p_buffer parameter to a transmission queue. A buffer + * provided to this function must be allocated by the @ref ser_hal_transport_tx_pkt_alloc function. + * + * @warning Completion of this method does not guarantee that actual peripheral transmission will be completed. + * + * @param[in] p_buffer Pointer to the buffer to transmit. + * @param[in] num_of_bytes Number of octets to transmit. Must be more than 0. + * + * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_PARAM Operation failure. num_of_bytes is equal to 0. + * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer (provided address is not + * the starting address of a buffer managed by HAL Transport layer). + * @retval NRF_ERROR_DATA_SIZE Operation failure. Packet size exceeds limit. + * @retval NRF_ERROR_BUSY Operation failure. Transmission queue is full so packet was not + * added to the transmission queue. + * @retval NRF_ERROR_INVALID_STATE Operation failure. Transmittion channel was not opened by + * @ref ser_hal_transport_open function or provided buffer was not + * allocated by @ref ser_hal_transport_tx_pkt_alloc function. + * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred. + */ +uint32_t ser_hal_transport_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes); + + +/**@brief Function for freeing memory allocated for a TX packet. + * + * @note The function frees the TX memory pointed by p_buffer. Freeing a TX buffer is possible only if + * the buffer was allocated by @ref ser_hal_transport_tx_pkt_alloc function and transmittion + * is not in progress. When transmittion has finished, this function is automatically called by + * the Serialization HAL Transport layer, so the only case when this function should be used + * from outside is when a TX buffer was allocated but a transmittion has not been started + * (@ref ser_hal_transport_tx_pkt_send function has not been called). + * + * @param[in] p_buffer Pointer to the beginning of a buffer that has been allocated by + * @ref ser_hal_transport_tx_pkt_alloc function. + * + * @retval NRF_SUCCESS Operation success. Memory was freed. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer (provided address is not + * the starting address of a buffer managed by HAL Transport layer). + * @retval NRF_ERROR_INVALID_STATE Operation failure. Freeing a TX buffer is possible only if the + * buffer was allocated by @ref ser_hal_transport_tx_pkt_alloc + * function and transmittion is not in progress. + */ +uint32_t ser_hal_transport_tx_pkt_free(uint8_t * p_buffer); + + + +#ifdef __cplusplus +} +#endif + +#endif /* SER_HAL_TRANSPORT_H__ */ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_config_5W_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_config_5W_app.h new file mode 100644 index 0000000000000000000000000000000000000000..051caa19ba366a687098f24182526d952ca4ff1c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_config_5W_app.h @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SER_CONFIG_5W_APP_H__ +#define SER_CONFIG_5W_APP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif // SER_CONFIG_5W_APP_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_phy_config_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_phy_config_app.h new file mode 100644 index 0000000000000000000000000000000000000000..30c6303c543fc34fadfca2702e635464c82eb0d8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_phy_config_app.h @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SER_PHY_CONFIG_APP_H__ +#define SER_PHY_CONFIG_APP_H__ + +#include "boards.h" +#include "ser_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(SPI_MASTER_0_ENABLE) +#define SER_PHY_SPI_MASTER SPI_MASTER_0 +#endif +#if defined(SPI_MASTER_1_ENABLE) +#define SER_PHY_SPI_MASTER SPI_MASTER_1 +#endif +#if defined(SPI_MASTER_2_ENABLE) +#define SER_PHY_SPI_MASTER SPI_MASTER_2 +#endif + +#if (defined(SPI0_ENABLED) && (SPI0_ENABLED == 1)) || defined(SPI_MASTER_0_ENABLE) + +#define SER_PHY_SPI_MASTER_INSTANCE NRF_DRV_SPI_INSTANCE(0) +#define SER_PHY_SPI_MASTER_PIN_SCK SER_APP_SPIM0_SCK_PIN +#define SER_PHY_SPI_MASTER_PIN_MISO SER_APP_SPIM0_MISO_PIN +#define SER_PHY_SPI_MASTER_PIN_MOSI SER_APP_SPIM0_MOSI_PIN +#define SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT SER_APP_SPIM0_SS_PIN +#define SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST SER_APP_SPIM0_REQ_PIN +#define SER_PHY_SPI_MASTER_PIN_SLAVE_READY SER_APP_SPIM0_RDY_PIN + +#elif (defined(SPI1_ENABLED) && (SPI1_ENABLED == 1)) || defined(SPI_MASTER_1_ENABLE) + +#define SER_PHY_SPI_MASTER_INSTANCE NRF_DRV_SPI_INSTANCE(1) +#define SER_PHY_SPI_MASTER_PIN_SCK SER_APP_SPIM1_SCK_PIN +#define SER_PHY_SPI_MASTER_PIN_MISO SER_APP_SPIM1_MISO_PIN +#define SER_PHY_SPI_MASTER_PIN_MOSI SER_APP_SPIM1_MOSI_PIN +#define SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT SER_APP_SPIM1_SS_PIN +#define SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST SER_APP_SPIM1_REQ_PIN +#define SER_PHY_SPI_MASTER_PIN_SLAVE_READY SER_APP_SPIM1_RDY_PIN + +#elif (defined(SPI2_ENABLED) && (SPI2_ENABLED == 1)) || defined(SPI_MASTER_2_ENABLE) + +#define SER_PHY_SPI_MASTER_INSTANCE NRF_DRV_SPI_INSTANCE(2) +#define SER_PHY_SPI_MASTER_PIN_SCK SER_APP_SPIM2_SCK_PIN +#define SER_PHY_SPI_MASTER_PIN_MISO SER_APP_SPIM2_MISO_PIN +#define SER_PHY_SPI_MASTER_PIN_MOSI SER_APP_SPIM2_MOSI_PIN +#define SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT SER_APP_SPIM2_SS_PIN +#define SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST SER_APP_SPIM2_REQ_PIN +#define SER_PHY_SPI_MASTER_PIN_SLAVE_READY SER_APP_SPIM2_RDY_PIN + +#endif + +#define CONN_CHIP_RESET_PIN_NO SER_CONN_CHIP_RESET_PIN /**< Pin used for reseting the connectivity. */ + +/* UART configuration */ +#define UART_IRQ_PRIORITY APP_IRQ_PRIORITY_MID +#define SER_PHY_UART_RX SER_APP_RX_PIN +#define SER_PHY_UART_TX SER_APP_TX_PIN +#define SER_PHY_UART_CTS SER_APP_CTS_PIN +#define SER_PHY_UART_RTS SER_APP_RTS_PIN + + +#ifdef __cplusplus +} +#endif + +#endif // SER_PHY_CONFIG_APP_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..9eaf33a68a41af00ea541a32edbebe38e325f016 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SER_PHY_CONFIG_CONN_H__ +#define SER_PHY_CONFIG_CONN_H__ + +#include "boards.h" +#include "ser_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***********************************************************************************************//** + * SER_PHY layer configuration. + **************************************************************************************************/ +#define SER_PHY_SPI_PPI_RDY_CH 0 +#define SER_PHY_SPI_GPIOTE_RDY_CH 0 + +#define SER_PHY_SPI_SLAVE_INSTANCE 1 + +#define SER_PHY_SPI_SLAVE_REQ_PIN SER_CON_SPIS_REQ_PIN +#define SER_PHY_SPI_SLAVE_RDY_PIN SER_CON_SPIS_RDY_PIN +#define SER_PHY_SPI_SLAVE_SCK_PIN SER_CON_SPIS_SCK_PIN +#define SER_PHY_SPI_SLAVE_MISO_PIN SER_CON_SPIS_MISO_PIN +#define SER_PHY_SPI_SLAVE_MOSI_PIN SER_CON_SPIS_MOSI_PIN +#define SER_PHY_SPI_SLAVE_SS_PIN SER_CON_SPIS_CSN_PIN + +/* UART configuration */ +#define UART_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST + +#define SER_PHY_UART_RX SER_CON_RX_PIN +#define SER_PHY_UART_TX SER_CON_TX_PIN +#define SER_PHY_UART_CTS SER_CON_CTS_PIN +#define SER_PHY_UART_RTS SER_CON_RTS_PIN + + +#ifdef __cplusplus +} +#endif + +#endif // SER_PHY_CONFIG_CONN_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_phy_debug_app.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_phy_debug_app.h new file mode 100644 index 0000000000000000000000000000000000000000..2597966f75c759bc37c72072c0f9d37b1e07b1e3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_phy_debug_app.h @@ -0,0 +1,198 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SER_PHY_DEBUG_APP_H__ +#define SER_PHY_DEBUG_APP_H__ + +#ifndef SER_PHY_DEBUG_APP_ENABLE + +#define DEBUG_EVT_SPI_MASTER_RAW_REQUEST(data) +#define DEBUG_EVT_SPI_MASTER_RAW_READY(data) +#define DEBUG_EVT_SPI_MASTER_RAW_XFER_DONE(data) +#define DEBUG_EVT_SPI_MASTER_RAW_API_CALL(data) +#define DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE(data) +#define DEBUG_EVT_SPI_MASTER_RAW_REQUEST_EDGE(data) +#define DEBUG_EVT_SPI_MASTER_PHY_TX_PKT_SENT(data) +#define DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_DROPPED(data) +#define DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_RECEIVED(data) +#define DEBUG_EVT_SPI_MASTER_PHY_BUF_REQUEST(data) + +#define DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(data) +#define DEBUG_EVT_SPI_MASTER_RAW_XFER_PASSED(data) +#define DEBUG_EVT_SPI_MASTER_RAW_XFER_ABORTED(data) +#define DEBUG_EVT_SPI_MASTER_RAW_XFER_RESTARTED(data) + +#else +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//Low level hardware events +typedef enum +{ + SPI_MASTER_RAW_READY, + SPI_MASTER_RAW_REQUEST, + SPI_MASTER_RAW_XFER_DONE, + SPI_MASTER_RAW_API_CALL, + SPI_MASTER_RAW_READY_EDGE, + SPI_MASTER_RAW_REQUEST_EDGE, + SPI_MASTER_RAW_XFER_STARTED, + SPI_MASTER_RAW_XFER_GUARDED, + SPI_MASTER_RAW_XFER_PASSED, + SPI_MASTER_RAW_XFER_ABORTED, + SPI_MASTER_RAW_XFER_RESTARTED, + SPI_MASTER_PHY_TX_PKT_SENT, + SPI_MASTER_PHY_BUF_REQUEST, + SPI_MASTER_PHY_RX_PKT_RECEIVED, + SPI_MASTER_PHY_RX_PKT_DROPPED, + SPI_MASTER_EVT_MAX +} spi_master_raw_evt_type_t; + + +//Low level hardware event definition +typedef struct +{ + spi_master_raw_evt_type_t evt; + uint32_t data; +} spi_master_raw_evt_t; + +typedef void (*spi_master_raw_callback_t)(spi_master_raw_evt_t event); + +void debug_init(spi_master_raw_callback_t spi_master_raw_evt_callback); + +void debug_evt(spi_master_raw_evt_type_t evt, uint32_t data); + + +#define DEBUG_EVT(evt, data) \ +do { \ + debug_evt(evt, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_MASTER_RAW_REQUEST(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_RAW_REQUEST, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_MASTER_RAW_READY(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_RAW_READY, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_MASTER_RAW_XFER_DONE(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_RAW_XFER_DONE, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_MASTER_RAW_API_CALL(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_RAW_API_CALL, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_RAW_READY_EDGE, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_MASTER_RAW_REQUEST_EDGE(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_RAW_REQUEST_EDGE, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_MASTER_PHY_TX_PKT_SENT(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_PHY_TX_PKT_SENT, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_DROPPED(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_PHY_RX_PKT_DROPPED, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_RECEIVED(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_PHY_RX_PKT_RECEIVED, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_MASTER_PHY_BUF_REQUEST(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_PHY_BUF_REQUEST, data); \ +} while (0); + +#define DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_RAW_XFER_GUARDED, data); \ +} while (0); + +#define DEBUG_EVT_SPI_MASTER_RAW_XFER_PASSED(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_RAW_XFER_PASSED, data); \ +} while (0); + +#define DEBUG_EVT_SPI_MASTER_RAW_XFER_ABORTED(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_RAW_XFER_ABORTED, data); \ +} while (0); + +#define DEBUG_EVT_SPI_MASTER_RAW_XFER_RESTARTED(data) \ +do { \ + DEBUG_EVT(SPI_MASTER_RAW_XFER_RESTARTED, data); \ +} while (0); + + + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif //SER_PHY_DEBUG_APP_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_phy_debug_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_phy_debug_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..af4b717347e5eb02b4878b86d04f47fe065d2a04 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/config/ser_phy_debug_conn.h @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SER_PHY_DEBUG_CONN_H__ +#define SER_PHY_DEBUG_CONN_H__ + +#ifndef SER_PHY_DEBUG_CONN_ENABLE + +#define DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(data); + +#define DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(data); + +#define DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(data); + +#define DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(data); + +#define DEBUG_EVT_SPI_SLAVE_RAW_REQ_CLEARED(data); + +#define DEBUG_EVT_SPI_SLAVE_PHY_BUF_REQUEST(data); + +#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_RECEIVED(data); + +#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_DROPPED(data); + +#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_SENT(data); + +#else + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// low level hardware event types +typedef enum +{ + SPI_SLAVE_RAW_BUFFERS_SET, + SPI_SLAVE_RAW_RX_XFER_DONE, + SPI_SLAVE_RAW_TX_XFER_DONE, + SPI_SLAVE_RAW_REQ_SET, + SPI_SLAVE_RAW_REQ_CLEARED, + SPI_SLAVE_PHY_BUF_REQUEST, + SPI_SLAVE_PHY_PKT_SENT, + SPI_SLAVE_PHY_PKT_RECEIVED, + SPI_SLAVE_PHY_PKT_DROPPED, + SPI_SLAVE_RAW_EVT_TYPE_MAX +} spi_slave_raw_evt_type_t; + +// low level hardware event definition +typedef struct +{ + spi_slave_raw_evt_type_t evt_type; + uint32_t data; +} spi_slave_raw_evt_t; + +typedef void (*spi_slave_raw_callback_t)(spi_slave_raw_evt_t event); + +void debug_init(spi_slave_raw_callback_t spi_slave_raw_evt_callback); + +void debug_evt(spi_slave_raw_evt_type_t evt_type, uint32_t data); + +#define DEBUG_EVT(evt, data) \ +do { \ + debug_evt(evt, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(data) \ +do { \ + DEBUG_EVT(SPI_SLAVE_RAW_RX_XFER_DONE, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(data) \ +do { \ + DEBUG_EVT(SPI_SLAVE_RAW_TX_XFER_DONE, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(data) \ +do { \ + DEBUG_EVT(SPI_SLAVE_RAW_BUFFERS_SET, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(data) \ +do { \ + DEBUG_EVT(SPI_SLAVE_RAW_REQ_SET, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_SLAVE_RAW_REQ_CLEARED(data) \ +do { \ + DEBUG_EVT(SPI_SLAVE_RAW_REQ_CLEARED, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_SLAVE_PHY_BUF_REQUEST(data) \ +do { \ + DEBUG_EVT(SPI_SLAVE_PHY_BUF_REQUEST, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_RECEIVED(data) \ +do { \ + DEBUG_EVT(SPI_SLAVE_PHY_PKT_RECEIVED, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_DROPPED(data) \ +do { \ + DEBUG_EVT(SPI_SLAVE_PHY_PKT_DROPPED, data); \ +} while (0); + + +#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_SENT(data) \ +do { \ + DEBUG_EVT(SPI_SLAVE_PHY_PKT_SENT, data); \ +} while (0); + + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif //SER_PHY_DEBUG_CONN_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy.c new file mode 100644 index 0000000000000000000000000000000000000000..c2d1ba62c63b8319c3efb0fa92e6d7a0f5f772c1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy.c @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ser_phy.h" +#include "app_error.h" + + +__weak uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) +{ + /* A function stub. Function should be implemented according to ser_phy.h API. */ + APP_ERROR_CHECK_BOOL(false); + + return NRF_SUCCESS; +} + +__weak uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) +{ + /* A function stub. Function should be implemented according to ser_phy.h API. */ + APP_ERROR_CHECK_BOOL(false); + + return NRF_SUCCESS; +} + +__weak uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) +{ + /* A function stub. Function should be implemented according to ser_phy.h API. */ + APP_ERROR_CHECK_BOOL(false); + + return NRF_SUCCESS; +} + +__weak void ser_phy_close(void) +{ + /* A function stub. Function should be implemented according to ser_phy.h API. */ + APP_ERROR_CHECK_BOOL(false); +} + + +__weak void ser_phy_interrupts_enable(void) +{ + /* A function stub. Function should be implemented according to ser_phy.h API. */ + APP_ERROR_CHECK_BOOL(false); +} + + +__weak void ser_phy_interrupts_disable(void) +{ + /* A function stub. Function should be implemented according to ser_phy.h API. */ + APP_ERROR_CHECK_BOOL(false); +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy.h new file mode 100644 index 0000000000000000000000000000000000000000..1a3c7bcbc3f6cf9cead480eec7788aa7457f9cbe --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy.h @@ -0,0 +1,308 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ser_phy Serialization PHY + * @{ + * @ingroup ble_sdk_lib_serialization + * + * @brief PHY layer for serialization. + * + * @details The @ref ser_phy library declares functions and definitions of data structures and + * identifiers (typedef enum) that are used as API of the serialization PHY layer. + * + * \par Rationale + * Each specific PHY layer (SPI, I2C, UART, low power UART etc.) should provide the same API. This + * allows the layer above (the HAL Transport layer), which is responsible for controlling the PHY + * layer, memory management, CRC, retransmission etc., to be hardware independent. + * + * + * \par Interlayer communication and control + * The PHY layer is controlled by the HAL transport layer by calling functions declared in + * the @ref ser_phy library. + * + * @par + * The PHY layer communicates events to the HAL transport layer by calling a callback function. + * A handler to this function is passed in the @ref ser_phy_open function. This callback function + * should be called with a parameter of type @ref ser_phy_evt_t, filled accordingly to an event to be + * passed. Types of supported events are defined in @ref ser_phy_evt_type_t. + * + * @par + * For example, to pass an event indicating that an RX packet has been successfully received, first a + * struct of type @ref ser_phy_evt_t must be filled: + * @code + * ser_phy_evt_t phy_evt; + * phy_evt.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; + * phy_evt.evt_params.rx_pkt_received.p_buffer = (pointer to the RX buffer); + * phy_evt.evt_params.rx_pkt_received.num_of_bytes = (number of received bytes); + * @endcode + * Then, the callback function must be called: + * @code + * events_handler(phy_evt); + * @endcode + * All functions declared in the @ref ser_phy file (ser_phy.h) must be implemented. Some events specified in + * @ref ser_phy_evt_type_t are optional to implement. + * + * \par Transmitting a packet + * Each PHY layer is responsible for adding the PHY header to a packet to be sent. This header + * consists of a 16-bit field that carries the packet length (the uint16_encode function defined in + * app_util.h should be used to ensure endianness independence). A pointer to a packet to be sent + * and length of the packet are parameters of the @ref ser_phy_tx_pkt_send function. When a packet + * has been transmitted, an event of type @ref SER_PHY_EVT_TX_PKT_SENT should be emitted. + * + * \image html ser_phy_transport_tx.svg "TX - interlayer communication" + * + * \par Receiving a packet + * The PHY layer should be able to store only the PHY header (16-bit field carrying the packet + * length). After the PHY header has been received, the transmission is stopped and the PHY + * layer must send a request to the HAL transport layer for memory to store the packet - an event + * of type @ref SER_PHY_EVT_RX_BUF_REQUEST with event parameters defined in + * @ref ser_phy_evt_rx_buf_request_params_t (the uint16_decode function defined in app_util.h should + * be used for header decoding to ensure endianness independence). The transmission should be + * resumed when the @ref ser_phy_rx_buf_set function has been called. + * + * @par + * When the @ref ser_phy_rx_buf_set function parameter equals NULL, there is not + * enough memory to store the packet. However, the packet will be received to a dummy location to + * ensure continuous communication. After receiving has finished, an event of type + * @ref SER_PHY_EVT_RX_PKT_DROPPED is generated. + * + * \image html ser_phy_transport_rx_dropped.svg "RX dropping - interlayer communication" + * + * @par + * When the @ref ser_phy_rx_buf_set function parameter is different than NULL, the packet is + * received to a buffer pointed to by it. After receiving has finished, an event of type + * @ref SER_PHY_EVT_RX_PKT_RECEIVED is generated with event parameters defined in + * @ref ser_phy_evt_rx_pkt_received_params_t. + * + * \image html ser_phy_transport_rx_received.svg "RX - interlayer communication" + * + * \par PHY layer errors + * PHY layer errors can be signaled by an event of type @ref SER_PHY_EVT_RX_OVERFLOW_ERROR or + * @ref SER_PHY_EVT_TX_OVERREAD_ERROR or @ref SER_PHY_EVT_HW_ERROR with event parameters defined in + * @ref ser_phy_evt_hw_error_params_t. + * + * @par Available PHY layers + * The following PHY layers are available: + * - @ref ser_phy_spi_page + * - @ref ser_phy_spi_5W_page + * - @ref ser_phy_uart_page + * - @ref ser_phy_uart_hci_page + * + * + */ + +#ifndef SER_PHY_H__ +#define SER_PHY_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Serialization PHY module event types. */ +typedef enum +{ + SER_PHY_EVT_TX_PKT_SENT = 0, /**< Obligatory to implement. An event indicating that a TX packet + * has been transmitted. */ + SER_PHY_EVT_RX_BUF_REQUEST, /**< Obligatory to implement. An event indicating that the PHY layer + * needs a buffer for an RX packet. The PHY flow should be blocked + * until the @ref ser_phy_rx_buf_set function is called. */ + SER_PHY_EVT_RX_PKT_RECEIVED, /**< Obligatory to implement. An event indicating that an RX packet + * has been successfully received. */ + SER_PHY_EVT_RX_PKT_DROPPED, /**< Obligatory to implement. An event indicating that the RX packet + * receiving has been finished but the packet was discarded because + * it was longer than available the buffer. */ + + SER_PHY_EVT_RX_OVERFLOW_ERROR, /**< Optional to implement. An event indicating that more + * information has been transmitted than the PHY module could + * handle. */ + SER_PHY_EVT_TX_OVERREAD_ERROR, /**< Optional to implement. An event indicating that the PHY module + * was forced to transmit more information than possessed. */ + SER_PHY_EVT_HW_ERROR, /**< Optional to implement. An event indicating a hardware error + * in the PHY module. */ + SER_PHY_EVT_TYPE_MAX /**< Enumeration upper bound. */ +} ser_phy_evt_type_t; + + +/**@brief A struct containing parameters of event of type @ref SER_PHY_EVT_RX_BUF_REQUEST. */ +typedef struct +{ + uint16_t num_of_bytes; /**< Length of a buffer in octets that the layer above the PHY module should + * deliver, so that the PHY module can receive a packet. */ +} ser_phy_evt_rx_buf_request_params_t; + + +/**@brief A struct containing parameters of event of type @ref SER_PHY_EVT_RX_PKT_RECEIVED. */ +typedef struct +{ + uint8_t * p_buffer; /**< Pointer to a buffer containing the received packet. */ + uint16_t num_of_bytes; /**< Length of the received packet in octets. */ +} ser_phy_evt_rx_pkt_received_params_t; + + +/**@brief A struct containing parameters of event of type @ref SER_PHY_EVT_HW_ERROR. */ +typedef struct +{ + uint32_t error_code; /**< Hardware error code - specific for a microcontroller. */ + uint8_t * p_buffer; /**< Pointer to the buffer that was processed when error occured. */ +} ser_phy_evt_hw_error_params_t; + + +/**@brief A struct containing events from a Serialization PHY module. + * + * @note Some events do not have parameters, then whole information is contained in the evt_type. + */ +typedef struct +{ + ser_phy_evt_type_t evt_type; /**< Type of event. */ + + union /**< Union alternative identified by evt_type in enclosing struct. */ + { + /** Parameters of event of type @ref SER_PHY_EVT_RX_BUF_REQUEST. */ + ser_phy_evt_rx_buf_request_params_t rx_buf_request; + /** Parameters of event of type @ref SER_PHY_EVT_RX_PKT_RECEIVED. */ + ser_phy_evt_rx_pkt_received_params_t rx_pkt_received; + /** Parameters of the event of type @ref SER_PHY_EVT_HW_ERROR. */ + ser_phy_evt_hw_error_params_t hw_error; + } evt_params; +} ser_phy_evt_t; + + +/**@brief A type of generic callback function handler to be used by all PHY module events. + * + * @param[in] event Serialization PHY module event. + */ +typedef void (*ser_phy_events_handler_t)(ser_phy_evt_t event); + + +/**@brief Function for opening and initializing the PHY module. + * + * @note The function initializes hardware and internal module states, and registers callback + * function to be used by all PHY module events. + * + * @warning If the function has been already called, the function @ref ser_phy_close has to be + * called before ser_phy_open can be called again. + * + * @param[in] events_handler Generic callback function handler to be used by all PHY module + * events. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called. + * To call it again, the function @ref ser_phy_close has to be + * called first. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_PARAM Operation failure. Hardware initialization parameters are not + * supported. + */ +uint32_t ser_phy_open(ser_phy_events_handler_t events_handler); + + +/**@brief Function for transmitting a packet. + * + * @note The function adds a packet pointed by p_buffer parameter to a transmission queue and + * schedules generation of an event of type @ref SER_PHY_EVT_TX_PKT_SENT upon transmission + * completion. + * + * @param[in] p_buffer Pointer to a buffer to transmit. + * @param[in] num_of_bytes Number of octets to transmit. Must be more than 0. + * + * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue + * and event will be send upon transmission completion. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_PARAM Operation failure. The num_of_bytes parameter equal to 0. + * @retval NRF_ERROR_BUSY Operation failure. Transmitting of a packet in progress. + */ +uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes); + + +/**@brief Function for setting an RX buffer and enabling reception of data (the PHY flow). + * + * @note The function has to be called as a response to an event of type + * @ref SER_PHY_EVT_RX_BUF_REQUEST. The function sets an RX buffer and enables reception of + * data (enables the PHY flow). + * Size of a buffer pointed by the p_buffer parameter should be at least equal to the + * num_of_bytes parameter passed within the event (@ref ser_phy_evt_rx_buf_request_params_t), + * or p_buffer should be equal to NULL if there is not enough memory. + * When p_buffer is different from NULL and num_of_bytes octets have been received, an event of + * type @ref SER_PHY_EVT_RX_PKT_RECEIVED is generated + * (@ref ser_phy_evt_rx_pkt_received_params_t). + * When p_buffer is equal to NULL, data is received to dummy location to ensure continuous + * communication. Then, if num_of_bytes octets have been received, an event of type + * @ref SER_PHY_EVT_RX_PKT_DROPPED is generated. + * + * @param[in] p_buffer Pointer to an RX buffer in which to receive. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_INVALID_STATE Operation failure. A buffer was set without request. + */ +uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer); + + +/**@brief Function for closing the PHY module. + * + * @note The function disables hardware, resets internal module states, and unregisters the events + * callback function. + */ +void ser_phy_close(void); + + +/**@brief Function for enabling the PHY module interrupts. + * + * @note The function enables all interrupts that are used by the PHY module (and only those). + */ +void ser_phy_interrupts_enable(void); + + +/**@brief Function for disabling the PHY module interrupts. + * + * @note The function disables all interrupts that are used by the PHY module (and only those). + */ +void ser_phy_interrupts_disable(void); + + + +#ifdef __cplusplus +} +#endif + +#endif /* SER_PHY_H__ */ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_hci.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_hci.c new file mode 100644 index 0000000000000000000000000000000000000000..d03c8e1beaeadc7a28fb8c63d9e3d83313dd64b4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_hci.c @@ -0,0 +1,1698 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include + +#include "app_error.h" +#include "app_util.h" +#include "app_util_platform.h" +#include "app_timer.h" +#include "nrf_queue.h" +#include "ser_phy.h" +#include "ser_phy_hci.h" +#include "crc16.h" +#include "nrf_soc.h" +#include "ser_config.h" +#include "ser_phy_debug_comm.h" +#define NRF_LOG_MODULE_NAME "SPHY_HCI" +#include "nrf_log.h" +// hide globals for release version, expose for debug version +#if defined(SER_PHY_HCI_DEBUG_ENABLE) +#define _static +#else +#define _static static +#endif + +#define PKT_HDR_SIZE 4 /**< Packet header size in number of bytes. */ +#define PKT_CRC_SIZE 2 /**< Packet CRC size in number of bytes. */ +#define MAX_PACKET_SIZE_IN_BITS (11uL * \ + (SER_HAL_TRANSPORT_MAX_PKT_SIZE + PKT_HDR_SIZE + PKT_CRC_SIZE)) +#define BAUD_TIME_us (1000000uL / SER_PHY_UART_BAUDRATE_VAL) + +#define TX_EVT_QUEUE_SIZE 16 +#define RX_EVT_QUEUE_SIZE 16 +#define PKT_TYPE_VENDOR_SPECIFIC 14 /**< Packet type vendor specific. */ +#define PKT_TYPE_ACK 0 /**< Packet type acknowledgement. */ +#define PKT_TYPE_LINK_CONTROL 15 /**< Packet type link control. */ +#define DATA_INTEGRITY_MASK (1 << 6) /**< Mask for data integrity bit in the packet header. */ +#define RELIABLE_PKT_MASK (1 << 7) /**< Mask for reliable packet bit in the packet header. */ +#define INITIAL_ACK_NUMBER_EXPECTED 0 /**< Initial acknowledge number expected. */ +#define INITIAL_SEQ_NUMBER INITIAL_ACK_NUMBER_EXPECTED /**< Initial acknowledge number transmitted. */ +#define INVALID_PKT_TYPE 0xFFFFFFFFu /**< Internal invalid packet type value. */ +#define MAX_TRANSMISSION_TIME_ms (MAX_PACKET_SIZE_IN_BITS * BAUD_TIME_us / 1000uL) /**< Max transmission time of a single application packet over UART in units of mseconds. */ +#define RETRANSMISSION_TIMEOUT_IN_ms (10uL * MAX_TRANSMISSION_TIME_ms) /**< Retransmission timeout for application packet in units of mseconds. */ + +#ifdef HCI_LINK_CONTROL +#define HCI_PKT_SYNC 0x7E01u /**< Link Control Packet: type SYNC */ +#define HCI_PKT_SYNC_RSP 0x7D02u /**< Link Control Packet: type SYNC RESPONSE */ +#define HCI_PKT_CONFIG 0xFC03u /**< Link Control Packet: type CONFIG */ +#define HCI_PKT_CONFIG_RSP 0x7B04u /**< Link Control Packet: type CONFIG RESPONSE */ +#define HCI_CONFIG_FIELD 0x11u /**< Configuration field of CONFIG and CONFIG_RSP packet */ +#define HCI_PKT_SYNC_SIZE 6u /**< Size of SYNC and SYNC_RSP packet */ +#define HCI_PKT_CONFIG_SIZE 7u /**< Size of CONFIG and CONFIG_RSP packet */ +#define HCI_LINK_CONTROL_PKT_INVALID 0xFFFFu /**< Size of CONFIG and CONFIG_RSP packet */ +#define HCI_LINK_CONTROL_TIMEOUT 1u /**< Default link control timeout. */ +#endif /* HCI_LINK_CONTROL */ + + +#define RETRANSMISSION_TIMEOUT_IN_TICKS (APP_TIMER_TICKS(RETRANSMISSION_TIMEOUT_IN_ms)) /**< Retransmission timeout for application packet in units of timer ticks. */ +#define MAX_RETRY_COUNT 5 /**< Max retransmission retry count for application packets. */ + +#if (defined(HCI_TIMER0)) +#define HCI_TIMER NRF_TIMER0 +#define HCI_TIMER_IRQn TIMER0_IRQn +#define HCI_TIMER_IRQHandler TIMER0_IRQHandler +#elif (defined(HCI_TIMER1)) +#define HCI_TIMER NRF_TIMER1 +#define HCI_TIMER_IRQn TIMER1_IRQn +#define HCI_TIMER_IRQHandler TIMER1_IRQHandler +#elif (defined(HCI_TIMER2)) +#define HCI_TIMER NRF_TIMER2 +#define HCI_TIMER_IRQn TIMER2_IRQn +#define HCI_TIMER_IRQHandler TIMER2_IRQHandler +#else +#define HCI_APP_TIMER +#endif + + +/**@brief States of the hci event driven state machine. */ +typedef enum +{ + HCI_TX_STATE_DISABLE, + HCI_TX_STATE_SEND, + HCI_TX_STATE_WAIT_FOR_FIRST_TX_END, + HCI_TX_STATE_WAIT_FOR_ACK_OR_TX_END, + HCI_TX_STATE_WAIT_FOR_ACK, + HCI_TX_STATE_WAIT_FOR_TX_END +} hci_tx_fsm_state_t; + +typedef enum +{ + HCI_RX_STATE_DISABLE, + HCI_RX_STATE_RECEIVE, + HCI_RX_STATE_WAIT_FOR_MEM, + HCI_RX_STATE_WAIT_FOR_SLIP_ACK_END, + HCI_RX_STATE_WAIT_FOR_SLIP_NACK_END, +} hci_rx_fsm_state_t; + +typedef enum +{ + HCI_EVT_TIMEOUT, +} hci_timer_evt_type_t; + +typedef enum +{ + HCI_SER_PHY_TX_REQUEST, + HCI_SER_PHY_RX_BUF_GRANTED, + HCI_SER_PHY_EVT_GEN_ENABLE, + HCI_SER_PHY_EVT_GEN_DISABLE +} ser_phy_int_evt_type_t; + +typedef enum +{ + HCI_SER_PHY_EVT, + HCI_SLIP_EVT, + HCI_TIMER_EVT, +} hci_evt_source_t; + +#ifdef HCI_LINK_CONTROL +typedef enum +{ + HCI_MODE_DISABLE, + HCI_MODE_UNINITIALIZED, + HCI_MODE_INITIALIZED, + HCI_MODE_ACTIVE, +} hci_mode_t; +#endif /*HCI_LINK_CONTROL */ + +typedef struct +{ + hci_timer_evt_type_t evt_type; /**< Type of an event. */ +} hci_timer_evt_t; + +typedef struct +{ + ser_phy_int_evt_type_t evt_type; /**< Type of an event. */ +} ser_phy_int_evt_t; + +typedef struct +{ + hci_evt_source_t evt_source; /**< source of an event. */ + union + { + ser_phy_int_evt_t ser_phy_evt; /**< ser_phy event. */ + ser_phy_hci_slip_evt_t ser_phy_slip_evt; /**< ser_phy_hci event. */ + hci_timer_evt_t timer_evt; /**< timer event. */ + } evt; +} hci_evt_t; + +_static uint8_t m_tx_packet_header[PKT_HDR_SIZE]; +_static uint8_t m_tx_packet_crc[PKT_CRC_SIZE]; +_static uint8_t m_tx_ack_packet[PKT_HDR_SIZE]; +#ifdef HCI_LINK_CONTROL +_static uint8_t m_tx_link_control_header[PKT_HDR_SIZE]; +_static uint8_t m_tx_link_control_payload[HCI_PKT_CONFIG_SIZE - PKT_HDR_SIZE]; +#endif /* HCI_LINK_CONTROL */ + +_static uint32_t m_packet_ack_number; // Sequence number counter of the packet expected to be received +_static uint32_t m_packet_seq_number; // Sequence number counter of the transmitted packet for which acknowledgement packet is waited for + + +_static uint32_t m_tx_retry_count; + + +// _static uint32_t m_tx_retx_counter = 0; +// _static uint32_t m_rx_drop_counter = 0; + +NRF_QUEUE_DEF(hci_evt_t, + m_tx_evt_queue, + TX_EVT_QUEUE_SIZE, + NRF_QUEUE_MODE_NO_OVERFLOW); + +NRF_QUEUE_DEF(hci_evt_t, + m_rx_evt_queue, + RX_EVT_QUEUE_SIZE, + NRF_QUEUE_MODE_NO_OVERFLOW); + +_static hci_tx_fsm_state_t m_hci_tx_fsm_state = HCI_TX_STATE_DISABLE; +_static hci_rx_fsm_state_t m_hci_rx_fsm_state = HCI_RX_STATE_DISABLE; + +#ifdef HCI_LINK_CONTROL +_static hci_mode_t m_hci_mode = HCI_MODE_DISABLE; +_static uint16_t m_hci_link_control_next_pkt = HCI_PKT_SYNC; +_static bool m_hci_other_side_active = false; +#endif /* HCI_LINK_CONTROL */ + +#ifdef HCI_APP_TIMER +APP_TIMER_DEF(m_app_timer_id); +#endif + +_static bool m_tx_fsm_idle_flag = true; +_static bool m_rx_fsm_idle_flag = true; + +_static bool m_buffer_reqested_flag = false; + +_static uint8_t * m_p_rx_buffer = NULL; +_static uint16_t m_rx_packet_length; +_static uint8_t * m_p_rx_packet; +_static uint8_t * m_p_tx_payload = NULL; +_static uint16_t m_tx_payload_length; + +_static ser_phy_events_handler_t m_ser_phy_callback = NULL; + +static void hci_tx_event_handler(hci_evt_t * p_event); +static void hci_rx_event_handler(hci_evt_t * p_event); +#ifdef HCI_LINK_CONTROL +static void hci_link_control_event_handler(hci_evt_t * p_event); +#endif /* HCI_LINK_CONTROL */ + +_static bool m_hci_timer_enabled_flag = true; +_static bool m_hci_timout_pending_flag = false; +_static bool m_hci_global_enable_flag = true; + +#define ser_phy_hci_assert(cond) APP_ERROR_CHECK_BOOL(cond) + +static void hci_signal_timeout_event(void) +{ + hci_evt_t event; + + event.evt_source = HCI_TIMER_EVT; + event.evt.timer_evt.evt_type = HCI_EVT_TIMEOUT; + DEBUG_EVT_TIMEOUT(0); + +#ifndef HCI_LINK_CONTROL + hci_tx_event_handler(&event); +#else + hci_link_control_event_handler(&event); + if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active) + { + hci_tx_event_handler(&event); + } +#endif /* HCI_LINK_CONTROL */ +} + + +#ifndef HCI_APP_TIMER + +void HCI_TIMER_IRQHandler(void) +{ + + if ((HCI_TIMER->EVENTS_COMPARE[1] == 1) && (HCI_TIMER->INTENSET & TIMER_INTENSET_COMPARE1_Msk)) + { + HCI_TIMER->EVENTS_COMPARE[1] = 0; + HCI_TIMER->TASKS_CLEAR = 1; + + if (m_hci_timer_enabled_flag) + { + hci_signal_timeout_event(); + } + else + { + m_hci_timout_pending_flag = true; + } + } +} + + +static void hci_timeout_setup(uint32_t count) +{ + + uint32_t time_msec; + + if (count) + { + HCI_TIMER->INTENCLR = TIMER_INTENCLR_COMPARE1_Msk; + time_msec = count * RETRANSMISSION_TIMEOUT_IN_ms; + HCI_TIMER->CC[1] = time_msec * 31; + HCI_TIMER->CC[1] += time_msec / 4; + HCI_TIMER->TASKS_CLEAR = 1; // < Clear TIMER + HCI_TIMER->EVENTS_COMPARE[1] = 0; + HCI_TIMER->TASKS_START = 1; // < Start TIMER + HCI_TIMER->INTENSET = TIMER_INTENSET_COMPARE1_Msk; + } + else + { + HCI_TIMER->INTENCLR = TIMER_INTENCLR_COMPARE1_Msk; + HCI_TIMER->TASKS_STOP = 1; // < Start TIMER + } +} + + +#else + +_static bool m_hci_timer_setup_flag = false; +_static uint32_t m_hci_timer_counter = 0; +_static uint32_t m_hci_timer_setup; + +static void hci_timeout_setup(uint32_t count) +{ + m_hci_timer_setup = count; + m_hci_timer_setup_flag = true; +} + + +static void hci_timeout_handler(void * p_context) +{ + + if (m_hci_timer_setup_flag) + { + m_hci_timer_setup_flag = false; + m_hci_timer_counter = m_hci_timer_setup; /* for 1 it will be always more than 1 tick - jitter is up to 1 tick */ + } + else if ( m_hci_timer_counter ) + { + m_hci_timer_counter--; + + if (m_hci_timer_counter == 0) + { + if (m_hci_timer_enabled_flag) + { + hci_signal_timeout_event(); + } + else + { + m_hci_timout_pending_flag = true; + } + } + } + return; +} + + +#endif + + +/**@brief Function for validating a received packet. + * + * @param[in] p_buffer Pointer to the packet data. + * @param[in] length Length of packet data in bytes. + * + * @return true if received packet is valid, false in other case. + */ +static bool is_rx_pkt_valid(const uint8_t * p_buffer, uint32_t length) +{ + // Executed packet filtering algorithm order: + // - verify packet overall length + // - verify data integrity bit set + // - verify reliable packet bit set + // - verify supported packet type + // - verify header checksum + // - verify payload length field + // - verify CRC + if (length <= PKT_HDR_SIZE) + { + return false; + } + + if (!(p_buffer[0] & DATA_INTEGRITY_MASK)) + { + return false; + } + + if (!(p_buffer[0] & RELIABLE_PKT_MASK)) + { + return false; + } + + if ((p_buffer[1] & 0x0Fu) != PKT_TYPE_VENDOR_SPECIFIC) + { + return false; + } + + const uint32_t expected_checksum = + ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu; + + if (expected_checksum != 0) + { + return false; + } + + const uint16_t crc_calculated = crc16_compute(p_buffer, (length - PKT_CRC_SIZE), NULL); + const uint16_t crc_received = uint16_decode(&p_buffer[length - PKT_CRC_SIZE]); + + if (crc_calculated != crc_received) + { + return false; + } + + return true; +} + + +/**@brief Function for getting the sequence number of the next reliable packet expected. + * + * @return sequence number of the next reliable packet expected. + */ +static __INLINE uint8_t packet_ack_get(void) +{ + return (uint8_t) m_packet_ack_number; +} + + +/**@brief Function for getting the sequence number of a reliable TX packet for which peer protocol + * entity acknowledgment is pending. + * + * @return sequence number of a reliable TX packet for which peer protocol entity acknowledgement + * is pending. + */ +static __INLINE uint8_t packet_seq_get(void) +{ + return m_packet_seq_number; +} + + +static __INLINE uint8_t packet_seq_nmbr_extract(const uint8_t * p_buffer) +{ + return (p_buffer[0] & 0x07u); +} + + +/**@brief Function for constructing 1st byte of the packet header of the packet to be transmitted. + * + * @return 1st byte of the packet header of the packet to be transmitted + */ +static __INLINE uint8_t tx_packet_byte_zero_construct(void) +{ + const uint32_t value = DATA_INTEGRITY_MASK | RELIABLE_PKT_MASK | + (packet_ack_get() << 3u) | packet_seq_get(); + + return (uint8_t) value; +} + + +/**@brief Function for calculating a packet header checksum. + * + * @param[in] p_hdr Pointer to the packet header. + * + * @return Calculated checksum. + */ +static __INLINE uint8_t header_checksum_calculate(const uint8_t * p_hdr) +{ + // @note: no pointer validation check needed as already checked by calling function. + uint32_t checksum; + + checksum = p_hdr[0]; + checksum += p_hdr[1]; + checksum += p_hdr[2]; + checksum &= 0xFFu; + checksum = (~checksum + 1u); + + return (uint8_t)checksum; +} + + +/**@brief Function for getting the expected ACK number. + * + * @return expected ACK number. + */ +static __INLINE uint8_t expected_ack_number_get(void) +{ + uint8_t seq_nmbr = packet_seq_get(); + + ++seq_nmbr; + seq_nmbr &= 0x07u; + + return seq_nmbr; +} + + +/**@brief Function for getting the expected ACK number. + * + * @return next expected ACK number. + */ + +static __INLINE uint8_t next_expected_ack_number_get(void) +{ + uint8_t seq_nmbr = expected_ack_number_get(); + + ++seq_nmbr; + seq_nmbr &= 0x07u; + + return seq_nmbr; +} + + +/**@brief Function for processing a received acknowledgement packet. + * + * Verifies does the received acknowledgement packet has the expected acknowledgement number and + * that the header checksum is correct. + * + * @param[in] p_buffer Pointer to the packet data. + * + * @return true if valid acknowledgement packet received. + */ + +static bool rx_ack_pkt_valid(const uint8_t * p_buffer) +{ + // @note: no pointer validation check needed as allready checked by calling function. + + // Verify header checksum. + const uint32_t expected_checksum = + ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu; + + if (expected_checksum != 0) + { + return false; + } + + const uint8_t ack_number = (p_buffer[0] >> 3u) & 0x07u; + + // Verify expected acknowledgment number. + return ( (ack_number == expected_ack_number_get()) || + (ack_number == next_expected_ack_number_get()) ); +} + + +/**@brief Function for decoding a packet type field. + * + * @param[in] p_buffer Pointer to the packet data. + * @param[in] length Length of packet data in bytes. + * + * @return Packet type field or INVALID_PKT_TYPE in case of decode error. + */ + +static uint32_t packet_type_decode(const uint8_t * p_buffer, uint32_t length) +{ + // @note: no pointer validation check needed as allready checked by calling function. + uint32_t return_value; + + if (length >= PKT_HDR_SIZE) + { + return_value = (p_buffer[1] & 0x0Fu); + } + else + { + return_value = INVALID_PKT_TYPE; + } + + return return_value; +} + +#ifdef HCI_LINK_CONTROL +/**@brief Function for decoding a link control packet. + * + * @param[in] p_buffer Pointer to the packet data. + * @param[in] length Length of packet data in bytes. + * + * @return Link Control Packet Type if decoding successful, HCI_LINK_CONTROL_PKT_INVALID otherwise. + */ +static uint16_t link_control_packet_decode(const uint8_t * p_buffer, uint32_t length) +{ + // @note: no pointer validation check needed as allready checked by calling function. + uint16_t packet_type = HCI_LINK_CONTROL_PKT_INVALID; + + // Executed link control packet filtering algorithm order: + // - verify packet overall length + // - verify data integrity bit cleared + // - verify reliable packet bit cleared + // - verify header checksum + // - verify payload: length and value + + if (length < HCI_PKT_SYNC_SIZE) + { + packet_type = HCI_LINK_CONTROL_PKT_INVALID; + } + + packet_type = p_buffer[PKT_HDR_SIZE] | (p_buffer[PKT_HDR_SIZE + 1] << 8u); + + if ((p_buffer[0] & DATA_INTEGRITY_MASK) || (p_buffer[0] & RELIABLE_PKT_MASK)) + { + packet_type = HCI_LINK_CONTROL_PKT_INVALID; + } + + const uint32_t expected_checksum = + ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu; + + if (expected_checksum != 0) + { + packet_type = HCI_LINK_CONTROL_PKT_INVALID; + } + + // This is a CONFIG or CONFIG_RSP packet + if ((packet_type == HCI_PKT_CONFIG) || (packet_type == HCI_PKT_CONFIG_RSP)) + { + if (length != HCI_PKT_CONFIG_SIZE) + { + packet_type = HCI_LINK_CONTROL_PKT_INVALID; + } + // Verify configuration field (0x11): + // - Sliding Window Size == 1, + // - OOF Flow Control == 0, + // - Data Integrity Check Type == 1, + // - Version Number == 0 + if (p_buffer[HCI_PKT_CONFIG_SIZE - 1] != HCI_CONFIG_FIELD) + { + packet_type = HCI_LINK_CONTROL_PKT_INVALID; + } + } + // This is a SYNC or SYNC_RSP packet + else if ((packet_type == HCI_PKT_SYNC) || (packet_type == HCI_PKT_SYNC_RSP)) + { + if (length != HCI_PKT_SYNC_SIZE) + { + packet_type = HCI_LINK_CONTROL_PKT_INVALID; + } + } + else + { + packet_type = HCI_LINK_CONTROL_PKT_INVALID; + } + + return packet_type; +} +#endif /* HCI_LINK_CONTROL */ + +/**@brief Function for writing an acknowledgment packet for transmission. + */ + +static void ack_transmit(void) +{ + uint32_t err_code; + // TX ACK packet format: + // - Unreliable Packet type + // - Payload Length set to 0 + // - Sequence Number set to 0 + // - Header checksum calculated + // - Acknowledge Number set correctly + m_tx_ack_packet[0] = (packet_ack_get() << 3u); + m_tx_ack_packet[1] = 0; + m_tx_ack_packet[2] = 0; + m_tx_ack_packet[3] = header_checksum_calculate(m_tx_ack_packet); + + ser_phy_hci_pkt_params_t pkt_header; + + pkt_header.p_buffer = m_tx_ack_packet; + pkt_header.num_of_bytes = PKT_HDR_SIZE; + DEBUG_EVT_SLIP_ACK_TX(0); + err_code = ser_phy_hci_slip_tx_pkt_send(&pkt_header, NULL, NULL); + ser_phy_hci_assert(err_code == NRF_SUCCESS); + + return; +} + + +static void ser_phy_event_callback(ser_phy_evt_t event) +{ + if (m_ser_phy_callback) + { + m_ser_phy_callback(event); + } + + return; +} + + +static void memory_request_callback(uint16_t size) +{ + ser_phy_evt_t event; + + DEBUG_EVT_HCI_PHY_EVT_BUF_REQUEST(0); + + event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; + event.evt_params.rx_buf_request.num_of_bytes = size; + ser_phy_event_callback(event); +} + + +static void packet_received_callback(uint8_t * pBuffer, uint16_t size) +{ + ser_phy_evt_t event; + + DEBUG_EVT_HCI_PHY_EVT_RX_PKT_RECEIVED(0); + + event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; + event.evt_params.rx_pkt_received.num_of_bytes = size; + event.evt_params.rx_pkt_received.p_buffer = pBuffer; + ser_phy_event_callback(event); +} + + +static void packet_dropped_callback(void) +{ + ser_phy_evt_t event; + + DEBUG_EVT_HCI_PHY_EVT_RX_PKT_DROPPED(0); + + event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED; + ser_phy_event_callback(event); +} + + +static void packet_transmitted_callback(void) +{ + ser_phy_evt_t event; + + DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(0); + + event.evt_type = SER_PHY_EVT_TX_PKT_SENT; + ser_phy_event_callback(event); +} + + +static void error_callback(void) +{ + ser_phy_evt_t event; + + DEBUG_EVT_HCI_PHY_EVT_TX_ERROR(0); + + event.evt_type = SER_PHY_EVT_HW_ERROR; + event.evt_params.hw_error.p_buffer = m_p_tx_payload; + ser_phy_event_callback(event); +} + + +static void hci_slip_event_handler(ser_phy_hci_slip_evt_t * p_event) +{ + hci_evt_t event; + uint32_t packet_type; + uint32_t err_code; + + if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT ) + { + NRF_LOG_DEBUG("EVT_PKT_SENT\r\n"); + + DEBUG_EVT_SLIP_PACKET_TXED(0); + event.evt_source = HCI_SLIP_EVT; + event.evt.ser_phy_slip_evt.evt_type = p_event->evt_type; +#ifndef HCI_LINK_CONTROL + hci_tx_event_handler(&event); +#else + if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active) + { + hci_tx_event_handler(&event); + } +#endif /*HCI_LINK_CONTROL*/ + } + else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_ACK_SENT ) + { + NRF_LOG_DEBUG("EVT_ACK_SENT\r\n"); + + DEBUG_EVT_SLIP_ACK_TXED(0); + event.evt_source = HCI_SLIP_EVT; + event.evt.ser_phy_slip_evt.evt_type = p_event->evt_type; +#ifndef HCI_LINK_CONTROL + hci_rx_event_handler(&event); +#else + if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active) + { + hci_rx_event_handler(&event); + } +#endif /* HCI_LINK_CONTROL */ + } + + else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED ) + { + event.evt_source = HCI_SLIP_EVT; + event.evt.ser_phy_slip_evt.evt_type = p_event->evt_type; + event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer = + p_event->evt_params.received_pkt.p_buffer; + event.evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes = + p_event->evt_params.received_pkt.num_of_bytes; + ser_phy_hci_assert(event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer != NULL); + ser_phy_hci_assert(event.evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes != 0); + packet_type = packet_type_decode( + event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer, + event.evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes); + + NRF_LOG_DEBUG("EVT_PKT_RECEIVED 0x%X/%u\r\n", packet_type, + p_event->evt_params.received_pkt.num_of_bytes); + + if (packet_type == PKT_TYPE_ACK ) + { + DEBUG_EVT_SLIP_ACK_RXED(0); +#ifndef HCI_LINK_CONTROL + hci_tx_event_handler(&event); +#else + if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active) + { + hci_tx_event_handler(&event); + } + else + { + err_code = ser_phy_hci_slip_rx_buf_free( + event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer); + } +#endif /* HCI_LINK_CONTROL */ + } + else if ( packet_type == PKT_TYPE_VENDOR_SPECIFIC ) + { + if (is_rx_pkt_valid(event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer, + event.evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes)) + { + DEBUG_EVT_SLIP_PACKET_RXED(0); +#ifndef HCI_LINK_CONTROL + hci_rx_event_handler(&event); +#else + if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active) + { + hci_rx_event_handler(&event); + } + else + { + err_code = ser_phy_hci_slip_rx_buf_free( + event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer); + } +#endif /* HCI_LINK_CONTROL */ + } + else + { + err_code = ser_phy_hci_slip_rx_buf_free( + event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer); + ser_phy_hci_assert(err_code == NRF_SUCCESS); + /* throw assert when in debug mode*/ + DEBUG_EVT_SLIP_ERR_RXED(0); + } + } +#ifdef HCI_LINK_CONTROL + else if (packet_type == PKT_TYPE_LINK_CONTROL) + { + hci_link_control_event_handler(&event); + } +#endif /* HCI_LINK_CONTROL */ + else + { + err_code = ser_phy_hci_slip_rx_buf_free( + event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer); + ser_phy_hci_assert(err_code == NRF_SUCCESS); + /* throw assert when in debug mode*/ + DEBUG_EVT_SLIP_ERR_RXED(0); + } + } + else + { + NRF_LOG_DEBUG("EVT_HW_ERROR\r\n"); + } +} + + +static void hci_pkt_send(void) +{ + uint32_t err_code; + + m_tx_packet_header[0] = tx_packet_byte_zero_construct(); + uint16_t type_and_length_fields = ((m_tx_payload_length << 4u) | PKT_TYPE_VENDOR_SPECIFIC); + (void)uint16_encode(type_and_length_fields, &(m_tx_packet_header[1])); + m_tx_packet_header[3] = header_checksum_calculate(m_tx_packet_header); + uint16_t crc = crc16_compute(m_tx_packet_header, PKT_HDR_SIZE, NULL); + crc = crc16_compute(m_p_tx_payload, m_tx_payload_length, &crc); + (void)uint16_encode(crc, m_tx_packet_crc); + + ser_phy_hci_pkt_params_t pkt_header; + ser_phy_hci_pkt_params_t pkt_payload; + ser_phy_hci_pkt_params_t pkt_crc; + + pkt_header.p_buffer = m_tx_packet_header; + pkt_header.num_of_bytes = PKT_HDR_SIZE; + pkt_payload.p_buffer = m_p_tx_payload; + pkt_payload.num_of_bytes = m_tx_payload_length; + pkt_crc.p_buffer = m_tx_packet_crc; + pkt_crc.num_of_bytes = PKT_CRC_SIZE; + DEBUG_EVT_SLIP_PACKET_TX(0); + err_code = ser_phy_hci_slip_tx_pkt_send(&pkt_header, &pkt_payload, &pkt_crc); + ser_phy_hci_assert(err_code == NRF_SUCCESS); + + return; +} + +#ifdef HCI_LINK_CONTROL +static void hci_link_control_pkt_send(void) +{ + uint32_t err_code; + uint16_t link_control_payload_len = 0; + + m_tx_link_control_header[0] = 0x00u; // SEQ, ACK, DI and RP are set to 0 for link control + if (m_hci_link_control_next_pkt == HCI_PKT_SYNC) + { + link_control_payload_len = HCI_PKT_SYNC_SIZE - PKT_HDR_SIZE; + (void)uint16_encode(HCI_PKT_SYNC, m_tx_link_control_payload); + } + else if (m_hci_link_control_next_pkt == HCI_PKT_SYNC_RSP) + { + link_control_payload_len = HCI_PKT_SYNC_SIZE - PKT_HDR_SIZE; + (void)uint16_encode(HCI_PKT_SYNC_RSP, m_tx_link_control_payload); + } + else if (m_hci_link_control_next_pkt == HCI_PKT_CONFIG) + { + link_control_payload_len = HCI_PKT_CONFIG_SIZE - PKT_HDR_SIZE; + (void)uint16_encode(HCI_PKT_CONFIG, m_tx_link_control_payload); + m_tx_link_control_payload[2] = HCI_CONFIG_FIELD; + } + else if (m_hci_link_control_next_pkt == HCI_PKT_CONFIG_RSP) + { + link_control_payload_len = HCI_PKT_CONFIG_SIZE - PKT_HDR_SIZE; + (void)uint16_encode(HCI_PKT_CONFIG_RSP, m_tx_link_control_payload); + m_tx_link_control_payload[2] = HCI_CONFIG_FIELD; + } + uint16_t type_and_length_fields = ((link_control_payload_len << 4u) | PKT_TYPE_LINK_CONTROL); + (void)uint16_encode(type_and_length_fields, &(m_tx_link_control_header[1])); + m_tx_link_control_header[3] = header_checksum_calculate(m_tx_link_control_header); + + ser_phy_hci_pkt_params_t pkt_header; + ser_phy_hci_pkt_params_t pkt_payload; + ser_phy_hci_pkt_params_t pkt_crc; + + pkt_header.p_buffer = m_tx_link_control_header; + pkt_header.num_of_bytes = PKT_HDR_SIZE; + pkt_payload.p_buffer = m_tx_link_control_payload; + pkt_payload.num_of_bytes = link_control_payload_len; + pkt_crc.p_buffer = NULL; + pkt_crc.num_of_bytes = 0; + DEBUG_EVT_SLIP_PACKET_TX(0); + err_code = ser_phy_hci_slip_tx_pkt_send(&pkt_header, &pkt_payload, &pkt_crc); + ser_phy_hci_assert(err_code == NRF_SUCCESS); + + return; +} +#endif /* HCI_LINK_CONTROL */ + +static void hci_pkt_sent_upcall(void) +{ + m_packet_seq_number++; // incoming ACK is valid, increment SEQ + m_packet_seq_number &= 0x07u; + m_p_tx_payload = NULL; + packet_transmitted_callback(); + + return; +} + + +static void hci_release_ack_buffer(hci_evt_t * p_event) +{ + uint32_t err_code; + + err_code = ser_phy_hci_slip_rx_buf_free( + p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer); + ser_phy_hci_assert(err_code == NRF_SUCCESS); + + return; +} + + +static void hci_process_orphaned_ack(hci_evt_t * p_event) +{ + hci_release_ack_buffer(p_event); + return; +} + +/* main tx fsm */ +static void hci_tx_fsm_event_process(hci_evt_t * p_event) +{ + + switch (m_hci_tx_fsm_state) + { + case HCI_TX_STATE_SEND: + + if ((p_event->evt_source == HCI_SER_PHY_EVT) && + (p_event->evt.ser_phy_evt.evt_type == HCI_SER_PHY_TX_REQUEST)) + { + hci_pkt_send(); + hci_timeout_setup(0); + m_tx_retry_count = MAX_RETRY_COUNT; + m_hci_tx_fsm_state = HCI_TX_STATE_WAIT_FOR_FIRST_TX_END; + } + else if ((p_event->evt_source == HCI_SLIP_EVT) && + (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED)) + { + hci_process_orphaned_ack(p_event); + } + + break; + + case HCI_TX_STATE_WAIT_FOR_FIRST_TX_END: + + if ((p_event->evt_source == HCI_SLIP_EVT) && + (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT)) + { + hci_timeout_setup(1); + m_hci_tx_fsm_state = HCI_TX_STATE_WAIT_FOR_ACK; + } + else if ((p_event->evt_source == HCI_SLIP_EVT) && + (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED)) + { + hci_process_orphaned_ack(p_event); + } + break; + + case HCI_TX_STATE_WAIT_FOR_ACK_OR_TX_END: + + if ((p_event->evt_source == HCI_SLIP_EVT) && + (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT)) + { + hci_timeout_setup(1); + m_hci_tx_fsm_state = HCI_TX_STATE_WAIT_FOR_ACK; + } + else if ((p_event->evt_source == HCI_SLIP_EVT) && + (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED)) + { + if (rx_ack_pkt_valid(p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer)) + { + hci_timeout_setup(0); + m_hci_tx_fsm_state = HCI_TX_STATE_WAIT_FOR_TX_END; + } + hci_release_ack_buffer(p_event); + } + break; + + case HCI_TX_STATE_WAIT_FOR_ACK: + + if ((p_event->evt_source == HCI_SLIP_EVT) && + (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED)) + { + if (rx_ack_pkt_valid(p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer)) + { + hci_timeout_setup(0); + hci_pkt_sent_upcall(); + m_hci_tx_fsm_state = HCI_TX_STATE_SEND; + } + hci_release_ack_buffer(p_event); + } + else if (p_event->evt_source == HCI_TIMER_EVT) + { + m_tx_retry_count--; + // m_tx_retx_counter++; // global retransmissions counter + if (m_tx_retry_count) + { + hci_pkt_send(); + DEBUG_HCI_RETX(0); + m_hci_tx_fsm_state = HCI_TX_STATE_WAIT_FOR_ACK_OR_TX_END; + } + else + { + error_callback(); + m_hci_tx_fsm_state = HCI_TX_STATE_SEND; + } + } + break; + + case HCI_TX_STATE_WAIT_FOR_TX_END: + + if ((p_event->evt_source == HCI_SLIP_EVT) && + (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT)) + { + hci_pkt_sent_upcall(); + m_hci_tx_fsm_state = HCI_TX_STATE_SEND; + } + else if ((p_event->evt_source == HCI_SLIP_EVT) && + (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED)) + { + hci_process_orphaned_ack(p_event); + } + + break; + +#ifdef HCI_LINK_CONTROL + case HCI_TX_STATE_DISABLE: + /* This case should not happen if HCI is in ACTIVE mode */ + if (m_hci_mode == HCI_MODE_ACTIVE) + { + ser_phy_hci_assert(false); + } + break; +#endif /* HCI_LINK_CONTROL */ + + default: + ser_phy_hci_assert(false); + break; + } +} + + +static void hci_mem_request(hci_evt_t * p_event) +{ + m_buffer_reqested_flag = true; + m_p_rx_packet = p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer; + m_rx_packet_length = p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes; + ser_phy_hci_assert(m_rx_packet_length > PKT_HDR_SIZE + PKT_CRC_SIZE); + memory_request_callback(m_rx_packet_length - PKT_HDR_SIZE - PKT_CRC_SIZE); + return; +} + + +static void hci_inc_ack() +{ + m_packet_ack_number++; + m_packet_ack_number &= 0x07u; +} + + +static void hci_rx_fsm_event_process(hci_evt_t * p_event) +{ + switch (m_hci_rx_fsm_state) + { + case HCI_RX_STATE_RECEIVE: + + if ((p_event->evt_source == HCI_SLIP_EVT) && + (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED)) + { + /* type and crc and check sum are validated by slip handler */ + uint8_t rx_seq_number = packet_seq_nmbr_extract( + p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer); + + if (packet_ack_get() == rx_seq_number) + { + hci_mem_request(p_event); + m_hci_rx_fsm_state = HCI_RX_STATE_WAIT_FOR_MEM; + } + else + { + // m_rx_drop_counter++; + m_hci_rx_fsm_state = HCI_RX_STATE_WAIT_FOR_SLIP_NACK_END; + (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_packet); // and drop a packet + ack_transmit(); // send NACK with valid ACK + } + } + break; + + case HCI_RX_STATE_WAIT_FOR_MEM: + + if ((p_event->evt_source == HCI_SER_PHY_EVT) && + (p_event->evt.ser_phy_evt.evt_type == HCI_SER_PHY_RX_BUF_GRANTED)) + { + if (m_p_rx_buffer) + { + memcpy(m_p_rx_buffer, + m_p_rx_packet + PKT_HDR_SIZE, + m_rx_packet_length - PKT_HDR_SIZE - PKT_CRC_SIZE); + (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_packet); + } + m_hci_rx_fsm_state = HCI_RX_STATE_WAIT_FOR_SLIP_ACK_END; + hci_inc_ack(); // SEQ was valid for good packet, we will send incremented SEQ as ACK + ack_transmit(); + } + + break; + + case HCI_RX_STATE_WAIT_FOR_SLIP_ACK_END: + + if ((p_event->evt_source == HCI_SLIP_EVT) && + (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_ACK_SENT)) + { + + if (m_p_rx_buffer) + { + packet_received_callback(m_p_rx_buffer, + m_rx_packet_length - PKT_HDR_SIZE - PKT_CRC_SIZE); + } + else + { + packet_dropped_callback(); + } + m_hci_rx_fsm_state = HCI_RX_STATE_RECEIVE; + } + else if ((p_event->evt_source == HCI_SLIP_EVT) && + (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED)) + { + (void) ser_phy_hci_slip_rx_buf_free(p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer); + } + break; + + case HCI_RX_STATE_WAIT_FOR_SLIP_NACK_END: + if ((p_event->evt_source == HCI_SLIP_EVT) && + (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_ACK_SENT)) + { + m_hci_rx_fsm_state = HCI_RX_STATE_RECEIVE; + } + else + { + (void) ser_phy_hci_slip_rx_buf_free(p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer); + } + break; + + +#ifdef HCI_LINK_CONTROL + case HCI_RX_STATE_DISABLE: + if (m_hci_mode == HCI_MODE_ACTIVE) + { + ser_phy_hci_assert(false); + } + break; +#endif /* HCI_LINK_CONTROL */ + + default: + ser_phy_hci_assert(false); + break; + } +} + + +/* this function might be entered only via hci_tx_event_handler */ +static void hci_tx_fsm(void) +{ + hci_evt_t event; + uint32_t err_code = NRF_SUCCESS; + + while (err_code == NRF_SUCCESS) + { + + CRITICAL_REGION_ENTER(); + err_code = nrf_queue_pop(&m_tx_evt_queue, &event); + + if (err_code != NRF_SUCCESS) + { + m_tx_fsm_idle_flag = true; + } + CRITICAL_REGION_EXIT(); + + if (err_code == NRF_SUCCESS) + { + hci_tx_fsm_event_process(&event); /* this is the only entry to the TX_FSM */ + } + } + return; +} + + +/* this function might be entered only via hci_rx_event_handler */ +static void hci_rx_fsm(void) +{ + hci_evt_t event; + uint32_t err_code = NRF_SUCCESS; + + while (err_code == NRF_SUCCESS) + { + CRITICAL_REGION_ENTER(); + err_code = nrf_queue_pop(&m_rx_evt_queue, &event); + + if (err_code != NRF_SUCCESS) + { + m_rx_fsm_idle_flag = true; + } + CRITICAL_REGION_EXIT(); + + if (err_code == NRF_SUCCESS) + { + hci_rx_fsm_event_process(&event); /* this is the only entry to the RX_FSM */ + } + } + return; +} + + +/* something might have been queued by API with disabled 'PHY-interrupts' */ +static void hci_tx_reschedule() +{ + bool tx_exec_flag = false; + uint32_t tx_queue_length; + + CRITICAL_REGION_ENTER(); + tx_queue_length = nrf_queue_utilization_get(&m_tx_evt_queue); + +#ifndef HCI_LINK_CONTROL + if (m_tx_fsm_idle_flag && m_hci_global_enable_flag && tx_queue_length) +#else + if (m_tx_fsm_idle_flag && m_hci_global_enable_flag && tx_queue_length && (m_hci_mode == HCI_MODE_ACTIVE)) +#endif /* HCI_LINK_CONTROL */ + { + tx_exec_flag = true; // FSM should be activated + m_tx_fsm_idle_flag = false; // FSM will be busy from now on till the queue is exhausted + } + CRITICAL_REGION_EXIT(); + + if (tx_exec_flag) + { + hci_tx_fsm(); + } + return; +} + + +/* entry to TX state machine, might be called asynchronously from different contexts */ +/* Puts event into the TX event queue and execute if FSM was idle */ +static void hci_tx_event_handler(hci_evt_t * p_event) +{ + bool tx_exec_flag = false; + uint32_t err_code; + + CRITICAL_REGION_ENTER(); + err_code = nrf_queue_push(&m_tx_evt_queue, p_event); + ser_phy_hci_assert(err_code == NRF_SUCCESS); + + // CRITICAL_REGION_ENTER(); + /* only one process can acquire tx_exec_flag */ + if (m_tx_fsm_idle_flag && m_hci_global_enable_flag) + { + tx_exec_flag = true; // FSM should be activated + m_tx_fsm_idle_flag = false; // FSM will be busy from now on till the queue is exhausted + } + CRITICAL_REGION_EXIT(); + + if (tx_exec_flag) + { + hci_tx_fsm(); + } + return; +} + + +/* Something might have been queued by API with disabled 'PHY-interrupts' */ +static void hci_rx_reschedule() +{ + bool rx_exec_flag = false; + uint32_t rx_queue_length; + + CRITICAL_REGION_ENTER(); + rx_queue_length = nrf_queue_utilization_get(&m_rx_evt_queue); + +#ifndef HCI_LINK_CONTROL + if (m_rx_fsm_idle_flag && m_hci_global_enable_flag && rx_queue_length) +#else + if (m_rx_fsm_idle_flag && m_hci_global_enable_flag && rx_queue_length && (m_hci_mode == HCI_MODE_ACTIVE)) +#endif /* HCI_LINK_CONTROL */ + { + rx_exec_flag = true; // FSM should be activated + m_rx_fsm_idle_flag = false; // FSM will be busy from now on till the queue is exhausted + } + CRITICAL_REGION_EXIT(); + + if (rx_exec_flag) + { + hci_rx_fsm(); + } + +} + + +/* Entry to RX state machine, might be called asynchronously from different contexts */ +/* Puts event into the RX event queue and execute if FSM was idle */ +static void hci_rx_event_handler(hci_evt_t * p_event) +{ + bool rx_exec_flag = false; + uint32_t err_code; + + CRITICAL_REGION_ENTER(); + err_code = nrf_queue_push(&m_rx_evt_queue, p_event); + ser_phy_hci_assert(err_code == NRF_SUCCESS); + + /* only one process can acquire rx_exec_flag */ + // CRITICAL_REGION_ENTER(); + if (m_rx_fsm_idle_flag && m_hci_global_enable_flag) + { + rx_exec_flag = true; // FSM should be activated + m_rx_fsm_idle_flag = false; // FSM will be busy from now on till the queue is exhausted + } + CRITICAL_REGION_EXIT(); + + if (rx_exec_flag) + { + hci_rx_fsm(); + } + + return; +} + +#ifdef HCI_LINK_CONTROL +/* Link control event handler - used only for Link Control packets */ +/* This handler will be called only in 2 cases: + - when SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED event is received + - when HCI_TIMER_EVT event is reveived */ +static void hci_link_control_event_handler(hci_evt_t * p_event) +{ + uint16_t pkt_type = HCI_LINK_CONTROL_PKT_INVALID; + + switch (p_event->evt_source) + { + case HCI_SLIP_EVT: + pkt_type = link_control_packet_decode( + p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer, + p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes); + /* Perform HCI mode transition if needed */ + CRITICAL_REGION_ENTER(); + switch (pkt_type) + { + case HCI_PKT_SYNC: + m_hci_link_control_next_pkt = HCI_PKT_SYNC_RSP; + /* Restart HCI communication if it was in ACTIVE mode */ + if (m_hci_mode == HCI_MODE_ACTIVE) + { + m_hci_mode = HCI_MODE_UNINITIALIZED; + m_packet_ack_number = INITIAL_ACK_NUMBER_EXPECTED; + m_packet_seq_number = INITIAL_SEQ_NUMBER; + m_hci_tx_fsm_state = HCI_TX_STATE_DISABLE; + m_hci_rx_fsm_state = HCI_RX_STATE_DISABLE; + m_hci_other_side_active = false; + } + hci_link_control_pkt_send(); + hci_timeout_setup(HCI_LINK_CONTROL_TIMEOUT); // Need to trigger transmitting SYNC messages + break; + case HCI_PKT_SYNC_RSP: + if (m_hci_mode == HCI_MODE_UNINITIALIZED) + { + m_hci_mode = HCI_MODE_INITIALIZED; + m_hci_link_control_next_pkt = HCI_PKT_CONFIG; + } + break; + case HCI_PKT_CONFIG: + if (m_hci_mode != HCI_MODE_UNINITIALIZED) + { + m_hci_link_control_next_pkt = HCI_PKT_CONFIG_RSP; + hci_link_control_pkt_send(); + m_hci_other_side_active = true; + } + break; + case HCI_PKT_CONFIG_RSP: + if (m_hci_mode == HCI_MODE_INITIALIZED) + { + m_hci_mode = HCI_MODE_ACTIVE; + m_hci_tx_fsm_state = HCI_TX_STATE_SEND; + m_hci_rx_fsm_state = HCI_RX_STATE_RECEIVE; + } + break; + } + CRITICAL_REGION_EXIT(); + (void) ser_phy_hci_slip_rx_buf_free( + p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer); + /* Kick the state machine so it can start process BLE packets */ + if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active) + { + hci_tx_reschedule(); + hci_rx_reschedule(); + } + break; + + case HCI_TIMER_EVT: + /* Send one of the Link Control packets if in Unintialized or Initialized state */ + CRITICAL_REGION_ENTER(); + switch (m_hci_mode) + { + case HCI_MODE_UNINITIALIZED: + //send packet + m_hci_link_control_next_pkt = HCI_PKT_SYNC; + hci_link_control_pkt_send(); + hci_timeout_setup(HCI_LINK_CONTROL_TIMEOUT); + break; + case HCI_MODE_INITIALIZED: + m_hci_link_control_next_pkt = HCI_PKT_CONFIG; + hci_link_control_pkt_send(); + hci_timeout_setup(HCI_LINK_CONTROL_TIMEOUT); + break; + case HCI_MODE_ACTIVE: + case HCI_MODE_DISABLE: + default: + // No implementation needed + break; + } + CRITICAL_REGION_EXIT(); + break; + case HCI_SER_PHY_EVT: + default: + // No implementation needed + break; + } +} +#endif /* HCI_LINK_CONTROL */ + +/* ser_phy API function */ +void ser_phy_interrupts_enable(void) +{ + bool pending_timer_callback_flag = false; + + CRITICAL_REGION_ENTER(); + m_hci_timer_enabled_flag = true; + + if (m_hci_timout_pending_flag) + { + m_hci_timout_pending_flag = false; + pending_timer_callback_flag = true; + } + CRITICAL_REGION_EXIT(); + // this is a workaround - scheduled SER_PHY EVENTS + m_hci_global_enable_flag = true; + hci_tx_reschedule(); + hci_rx_reschedule(); + + if (pending_timer_callback_flag) + { + hci_signal_timeout_event(); + } + + return; +} + + +/* ser_phy API function */ +void ser_phy_interrupts_disable(void) +{ + CRITICAL_REGION_ENTER(); + m_hci_timer_enabled_flag = false; + // transport calls PHY API with ser_phy_interrupts_disabled + m_hci_global_enable_flag = false; + CRITICAL_REGION_EXIT(); +} + + +/* ser_phy API function */ +uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) +{ + uint32_t status = NRF_SUCCESS; + hci_evt_t event; + + if (m_buffer_reqested_flag) + { + m_buffer_reqested_flag = false; + m_p_rx_buffer = p_buffer; + event.evt_source = HCI_SER_PHY_EVT; + event.evt.ser_phy_evt.evt_type = HCI_SER_PHY_RX_BUF_GRANTED; + hci_rx_event_handler(&event); + } + else + { + status = NRF_ERROR_BUSY; + } + return status; +} + + +/* ser_phy API function */ +uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) +{ + uint32_t status = NRF_SUCCESS; + hci_evt_t event; + + if ( p_buffer == NULL || num_of_bytes == 0) + { + return NRF_ERROR_NULL; + } + + if ( m_p_tx_payload == NULL) + { + m_tx_payload_length = num_of_bytes; + m_p_tx_payload = (uint8_t *)p_buffer; + DEBUG_EVT_TX_REQ(0); + event.evt_source = HCI_SER_PHY_EVT; + event.evt.ser_phy_evt.evt_type = HCI_SER_PHY_TX_REQUEST; + hci_tx_event_handler(&event); + } + else + { + status = NRF_ERROR_BUSY; + } + + return status; +} + + +static uint32_t hci_timer_init(void) +{ + uint32_t err_code = NRF_SUCCESS; + +#ifdef HCI_APP_TIMER + + err_code = app_timer_create(&m_app_timer_id, APP_TIMER_MODE_REPEATED, hci_timeout_handler); + + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + err_code = app_timer_start(m_app_timer_id, RETRANSMISSION_TIMEOUT_IN_TICKS, NULL); + + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + +#else + + // Configure TIMER for compare[1] event + HCI_TIMER->PRESCALER = 9; + HCI_TIMER->MODE = TIMER_MODE_MODE_Timer; + HCI_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit; + + // Clear TIMER + HCI_TIMER->TASKS_CLEAR = 1; + + // Enable interrupt + HCI_TIMER->INTENCLR = 0xFFFFFFFF; + HCI_TIMER->INTENSET = TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos; + + NVIC_ClearPendingIRQ(HCI_TIMER_IRQn); + NVIC_SetPriority(HCI_TIMER_IRQn, APP_IRQ_PRIORITY_HIGH); + NVIC_EnableIRQ(HCI_TIMER_IRQn); + +#endif + + return err_code; + +} + + +/* ser_phy API function */ +uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) +{ + uint32_t err_code; + + if ((m_hci_tx_fsm_state != HCI_TX_STATE_DISABLE) || (m_hci_rx_fsm_state != HCI_RX_STATE_DISABLE)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (events_handler == NULL) + { + return NRF_ERROR_NULL; + } + + err_code = hci_timer_init(); + + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + nrf_queue_reset(&m_tx_evt_queue); + nrf_queue_reset(&m_rx_evt_queue); + + err_code = ser_phy_hci_slip_open(hci_slip_event_handler); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (err_code == NRF_SUCCESS) + { + m_packet_ack_number = INITIAL_ACK_NUMBER_EXPECTED; + m_packet_seq_number = INITIAL_SEQ_NUMBER; + m_ser_phy_callback = events_handler; + +#ifndef HCI_LINK_CONTROL + m_hci_tx_fsm_state = HCI_TX_STATE_SEND; + m_hci_rx_fsm_state = HCI_RX_STATE_RECEIVE; +#else + hci_timeout_setup(HCI_LINK_CONTROL_TIMEOUT);// Trigger sending SYNC messages + m_hci_mode = HCI_MODE_UNINITIALIZED; + m_hci_other_side_active = false; +#endif /*HCI_LINK_CONTROL*/ + } + return err_code; +} + +static uint32_t hci_timer_close(void) +{ + uint32_t err_code = NRF_SUCCESS; + +#ifdef HCI_APP_TIMER + err_code = app_timer_stop(m_app_timer_id); + + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } +#endif + + return err_code; +} + +/* ser_phy API function */ +void ser_phy_close(void) +{ + m_ser_phy_callback = NULL; + ser_phy_hci_slip_close(); + m_hci_tx_fsm_state = HCI_TX_STATE_DISABLE; + m_hci_rx_fsm_state = HCI_RX_STATE_DISABLE; + +#ifdef HCI_LINK_CONTROL + m_hci_mode = HCI_MODE_DISABLE; +#endif /* HCI_LINK_CONTROL */ + + uint32_t err_code = hci_timer_close(); + ser_phy_hci_assert(err_code == NRF_SUCCESS); +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_hci.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_hci.h new file mode 100644 index 0000000000000000000000000000000000000000..4b7b345c96f9c1ee92f98eebc0037aa9986c5090 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_hci.h @@ -0,0 +1,183 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup ser_phy_hci HCI Serialization PHY + * @{ + * @ingroup ble_sdk_lib_serialization + * + * @brief HCI PHY layer for serialization. + * + * @details This file contains declarations of functions and definitions of data structures and + * identifiers (typedef enum) used as API of the serialization HCI PHY layer. + * + * + */ + +#ifndef SER_PHY_HCI_H__ +#define SER_PHY_HCI_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Serialization PHY HCI module events types. */ +typedef enum +{ + SER_PHY_HCI_SLIP_EVT_PKT_SENT = 0, /**< An event indicating that packet has been transmitted. */ + SER_PHY_HCI_SLIP_EVT_ACK_SENT, /**< An event indicating that ack packet has been transmitted. */ + SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED, /**< An event indicating that packet has been received. */ + SER_PHY_HCI_SLIP_EVT_HW_ERROR, /**< An event indicating a hardware error in PHY HCI module. */ + SER_PHY_HCI_SLIP_EVT_TYPE_MAX /**< Enumeration upper bound. */ +} ser_phy_hci_slip_evt_type_t; + +/**@brief Struct representing a PHY HCI packet. */ +typedef struct +{ + uint8_t * p_buffer; /**< Pointer to a buffer containing a packet. */ + uint16_t num_of_bytes; /**< Length of a packet in octets. */ +} ser_phy_hci_pkt_params_t; + + +/**@brief Struct containing parameters of event of type @ref SER_PHY_HCI_SLIP_EVT_HW_ERROR. */ +typedef struct +{ + uint32_t error_code; /**< Hardware error code - specific for a microcontroller. */ +} ser_phy_hci_evt_hw_error_params_t; + + +/**@brief Struct containing events from the Serialization PHY module. + * + * @note Some events do not have parameters, then the whole information is contained in the evt_type. + */ +typedef struct +{ + ser_phy_hci_slip_evt_type_t evt_type; /**< Type of an event. */ + union /**< Union alternative identified by evt_type in the enclosing struct. */ + { + /** Parameters of event of type @ref SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED. */ + ser_phy_hci_pkt_params_t received_pkt; + /** Parameters of event of type @ref SER_PHY_HCI_SLIP_EVT_HW_ERROR. */ + ser_phy_hci_evt_hw_error_params_t hw_error; + } evt_params; +} ser_phy_hci_slip_evt_t; + + +/**@brief Type of generic callback function handler to be used by all PHY HCI events. + * + * @param[in] event Serialization PHY HCI module event. + */ +typedef void (*ser_phy_hci_slip_event_handler_t)(ser_phy_hci_slip_evt_t *p_event); + +/**@brief Function for opening and initializing a HCI SLIP PHY module. + * + * @note The function initializes hardware and internal module states and registers callback + * function to be used by all PHY HCI module events. + * + * @warning If the function has been already called, the function @ref ser_phy_hci_slip_close has to be + * called before ser_phy_hci_slip_open can be called again. + * + * @param[in] events_handler Generic callback function handler to be used by all PHY HCI module + * events. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called. + * To call it again, the function @ref ser_phy_hci_slip_close has to + * be called first. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_PARAM Operation failure. Hardware initialization parameters are not + * supported. + */ +uint32_t ser_phy_hci_slip_open(ser_phy_hci_slip_event_handler_t events_handler); + + +/**@brief A function for transmitting a HCI SLIP packet. + * + * @note The function adds a packet pointed by p_buffer parameter to a transmission queue and + * schedules generation of an event of type @ref SER_PHY_HCI_SLIP_EVT_PKT_SENT upon transmission + * completion. + * + * @param[in] p_header Pointer to ser_phy_hci_pkt_params_t structure representing packet header. + * @param[in] p_payload Pointer to ser_phy_hci_pkt_params_t structure representing packet payload. + * @param[in] p_crc Pointer to ser_phy_hci_pkt_params_t structure representing packet crc. + * + * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue + * and event will be sent upon transmission completion. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied in p_header parameter. + * NULL pointer is allowed for p_payload and p_crc parameters. + * @retval NRF_ERROR_INVALID_PARAM Operation failure. Number of bytes to be sent equals 0. + * @retval NRF_ERROR_BUSY Operation failure. Transmitting of a packet in progress. + */ +uint32_t ser_phy_hci_slip_tx_pkt_send(const ser_phy_hci_pkt_params_t * p_header, + const ser_phy_hci_pkt_params_t * p_payload, + const ser_phy_hci_pkt_params_t * p_crc); + + +/**@brief A function for freeing an RX buffer. + * + * @note The function has to be called as a response to event @ref SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED + * when an RX packet has been processed. The function frees the RX buffer and therefore enables + * reception of next incoming data. + + * @param[in] p_buffer Pointer to an RX buffer which must be freed. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_STATE Operation failure. A buffer was already free. + */ +uint32_t ser_phy_hci_slip_rx_buf_free(uint8_t * p_buffer); + + +/**@brief A function for closing a PHY HCI module. + * + * @note The function disables hardware, resets internal module states, and unregisters the events + * callback function. + */ +void ser_phy_hci_slip_close(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* SER_PHY_HCI_H__ */ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_hci_slip.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_hci_slip.c new file mode 100644 index 0000000000000000000000000000000000000000..75eaaef9dee6dfd193c93ff7fbcbc024001909cd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_hci_slip.c @@ -0,0 +1,689 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ser_phy_hci.h" +#include "ser_config.h" +#ifdef SER_CONNECTIVITY +#include "ser_phy_config_conn.h" +#else +#include "ser_phy_config_app.h" +#endif +#include "nrf_drv_uart.h" +#include "app_error.h" +#include "app_util_platform.h" + +#define APP_SLIP_END 0xC0 /**< SLIP code for identifying the beginning and end of a packet frame.. */ +#define APP_SLIP_ESC 0xDB /**< SLIP escape code. This code is used to specify that the following character is specially encoded. */ +#define APP_SLIP_ESC_END 0xDC /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xC0.. */ +#define APP_SLIP_ESC_ESC 0xDD /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xDB. */ + +#define HDR_SIZE 4 +#define CRC_SIZE 2 +#define PKT_SIZE (SER_HAL_TRANSPORT_MAX_PKT_SIZE + HDR_SIZE + CRC_SIZE) + +static const nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0); +static const nrf_drv_uart_config_t m_uart_config = { + .pseltxd = SER_PHY_UART_TX, + .pselrxd = SER_PHY_UART_RX, + .pselrts = SER_PHY_UART_RTS, + .pselcts = SER_PHY_UART_CTS, + .p_context = NULL, + .interrupt_priority = UART_IRQ_PRIORITY, +#ifdef UARTE_PRESENT + .use_easy_dma = true, +#endif + // These values are common for application and connectivity, they are + // defined in "ser_config.h". + .hwfc = SER_PHY_UART_FLOW_CTRL, + .parity = SER_PHY_UART_PARITY, + .baudrate = (nrf_uart_baudrate_t)SER_PHY_UART_BAUDRATE +}; + +typedef struct { + ser_phy_hci_pkt_params_t header; + ser_phy_hci_pkt_params_t payload; + ser_phy_hci_pkt_params_t crc; +} ser_phy_hci_slip_pkt_t; +static ser_phy_hci_slip_pkt_t m_tx_curr_packet; +static ser_phy_hci_slip_pkt_t m_tx_next_packet; + +static ser_phy_hci_slip_evt_t m_ser_phy_hci_slip_event; +static ser_phy_hci_slip_event_handler_t m_ser_phy_hci_slip_event_handler; /**< Event handler for upper layer */ + +static uint8_t m_tx_buf0[SER_PHY_HCI_SLIP_TX_BUF_SIZE]; +static uint8_t m_tx_buf1[SER_PHY_HCI_SLIP_TX_BUF_SIZE]; +static uint8_t * mp_tx_buf; +static uint8_t m_tx_bytes; +static enum { + PHASE_BEGIN, + PHASE_HEADER, + PHASE_PAYLOAD, + PHASE_CRC, + PHASE_ACK_END, + // The following three elements have to have consecutive values, + // 'tx_buf_fill()' relies on this. + PHASE_PACKET_END, + PHASE_PRE_IDLE = PHASE_PACKET_END + 1, + PHASE_IDLE = PHASE_PRE_IDLE + 1 +} volatile m_tx_phase; +static bool volatile m_tx_in_progress; +static bool volatile m_tx_pending; + +#define NO_EVENT SER_PHY_HCI_SLIP_EVT_TYPE_MAX +static ser_phy_hci_slip_evt_type_t m_tx_evt_type; +static ser_phy_hci_slip_evt_type_t m_tx_pending_evt_type; + +static uint8_t m_small_buffer[HDR_SIZE]; +static uint8_t m_big_buffer[PKT_SIZE]; + +static uint8_t * mp_small_buffer = NULL; +static uint8_t * mp_big_buffer = NULL; +static uint8_t * mp_buffer = NULL; + +static uint8_t m_rx_buf[1]; +static bool m_rx_escape; + + +// The function returns false to signal that no more bytes can be passed to be +// sent (put into the TX buffer) until UART transmission is done. +static bool tx_buf_put(uint8_t data_byte) +{ + ASSERT(m_tx_bytes < SER_PHY_HCI_SLIP_TX_BUF_SIZE); + + mp_tx_buf[m_tx_bytes] = data_byte; + ++m_tx_bytes; + + bool flush = false; + ser_phy_hci_slip_evt_type_t slip_evt_type = NO_EVENT; + if (m_tx_phase == PHASE_ACK_END) + { + // Send buffer, then signal that an acknowledge packet has been sent. + flush = true; + slip_evt_type = SER_PHY_HCI_SLIP_EVT_ACK_SENT; + } + else if (m_tx_phase == PHASE_PACKET_END) + { + // Send buffer, then signal that a packet with payload has been sent. + flush = true; + slip_evt_type = SER_PHY_HCI_SLIP_EVT_PKT_SENT; + } + else if (m_tx_bytes >= SER_PHY_HCI_SLIP_TX_BUF_SIZE) + { + // Send buffer (because it is filled up), but don't signal anything, + // since the packet sending is not complete yet. + flush = true; + } + + if (flush) + { + // If some TX transfer is being done at the moment, a new one cannot be + // started, it must be scheduled to be performed later. + if (m_tx_in_progress) + { + m_tx_pending_evt_type = slip_evt_type; + m_tx_pending = true; + // No more buffers available, can't continue filling. + return false; + } + + m_tx_in_progress = true; + m_tx_evt_type = slip_evt_type; + APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, mp_tx_buf, m_tx_bytes)); + + // Switch to the second buffer. + mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0; + m_tx_bytes = 0; + } + + return true; +} + +static void tx_buf_fill(void) +{ + static ser_phy_hci_pkt_params_t * mp_tx_data = NULL; + static uint32_t m_tx_index; + bool can_continue = true; + + do { + static uint8_t tx_escaped_data = 0; + + if (tx_escaped_data != 0) + { + can_continue = tx_buf_put(tx_escaped_data); + tx_escaped_data = 0; + } + else switch (m_tx_phase) + { + case PHASE_BEGIN: + can_continue = tx_buf_put(APP_SLIP_END); + mp_tx_data = &m_tx_curr_packet.header; + m_tx_index = 0; + m_tx_phase = PHASE_HEADER; + tx_escaped_data = 0; + break; + + case PHASE_ACK_END: + case PHASE_PACKET_END: + can_continue = tx_buf_put(APP_SLIP_END); + + // [this is needed for the '++m_tx_phase;' below] + m_tx_phase = PHASE_PACKET_END; + // no break, intentional fall-through + + case PHASE_PRE_IDLE: + // In PHASE_PRE_IDLE the sending process is almost finished, only + // the NRF_DRV_UART_EVT_TX_DONE event is needed before it can switch + // to PHASE_IDLE. But during this waiting a new packet may appear + // (i.e. 'ser_phy_hci_slip_tx_pkt_send()' may be called), hence + // the following pointer must be checked before switching the phase, + // just like right after writing whole packet to buffer (i.e. in + // PHASE_PACKET_END). Therefore, the following code is common for + // these two cases. + if (m_tx_next_packet.header.p_buffer != NULL) + { + m_tx_curr_packet = m_tx_next_packet; + m_tx_next_packet.header.p_buffer = NULL; + + m_tx_phase = PHASE_BEGIN; + break; + } + // Go to the next phase: + // PHASE_PACKET_END -> PHASE_PRE_IDLE + // PHASE_PRE_IDLE -> PHASE_IDLE + ++m_tx_phase; + return; + + default: + ASSERT(mp_tx_data->p_buffer != NULL); + uint8_t data = mp_tx_data->p_buffer[m_tx_index]; + ++m_tx_index; + + if (data == APP_SLIP_END) + { + data = APP_SLIP_ESC; + tx_escaped_data = APP_SLIP_ESC_END; + } + else if (data == APP_SLIP_ESC) + { + tx_escaped_data = APP_SLIP_ESC_ESC; + } + can_continue = tx_buf_put(data); + + if (m_tx_index >= mp_tx_data->num_of_bytes) + { + mp_tx_data->p_buffer = NULL; + + if (m_tx_phase == PHASE_HEADER) + { + if (m_tx_curr_packet.payload.p_buffer == NULL) + { + // No payload -> ACK packet. + m_tx_phase = PHASE_ACK_END; + } + else + { + mp_tx_data = &m_tx_curr_packet.payload; + m_tx_index = 0; + m_tx_phase = PHASE_PAYLOAD; + } + } + else if (m_tx_phase == PHASE_PAYLOAD) + { + if (m_tx_curr_packet.crc.p_buffer == NULL) + { + // Packet without CRC. + m_tx_phase = PHASE_PACKET_END; + } + else + { + mp_tx_data = &m_tx_curr_packet.crc; + m_tx_index = 0; + m_tx_phase = PHASE_CRC; + } + } + else + { + ASSERT(m_tx_phase == PHASE_CRC); + m_tx_phase = PHASE_PACKET_END; + } + } + break; + } + } while (can_continue); +} + +uint32_t ser_phy_hci_slip_tx_pkt_send(const ser_phy_hci_pkt_params_t * p_header, + const ser_phy_hci_pkt_params_t * p_payload, + const ser_phy_hci_pkt_params_t * p_crc) +{ + if (p_header == NULL) + { + return NRF_ERROR_NULL; + } + + CRITICAL_REGION_ENTER(); + + // If some packet is already transmitted, schedule this new one to be sent + // as next. A critical region is needed here to ensure that the transmission + // won't finish before the following assignments are done. + if (m_tx_phase != PHASE_IDLE) + { + m_tx_next_packet.header = *p_header; + + if (p_payload == NULL) + { + m_tx_next_packet.payload.p_buffer = NULL; + } + else + { + m_tx_next_packet.payload = *p_payload; + } + + if (p_crc == NULL) + { + m_tx_next_packet.crc.p_buffer = NULL; + } + else + { + m_tx_next_packet.crc = *p_crc; + } + } + else + { + m_tx_curr_packet.header = *p_header; + + if (p_payload == NULL) + { + m_tx_curr_packet.payload.p_buffer = NULL; + } + else + { + m_tx_curr_packet.payload = *p_payload; + } + + if (p_crc == NULL) + { + m_tx_curr_packet.crc.p_buffer = NULL; + } + else + { + m_tx_curr_packet.crc = *p_crc; + } + + m_tx_phase = PHASE_BEGIN; + tx_buf_fill(); + } + + CRITICAL_REGION_EXIT(); + + return NRF_SUCCESS; +} + +/* Function returns false when last byte in packet is detected.*/ +static bool slip_decode(uint8_t * p_received_byte) +{ + switch (*p_received_byte) + { + case APP_SLIP_END: + return false; + + case APP_SLIP_ESC: + m_rx_escape = true; + break; + + case APP_SLIP_ESC_END: + + if (m_rx_escape == true) + { + m_rx_escape = false; + *p_received_byte = APP_SLIP_END; + } + break; + + case APP_SLIP_ESC_ESC: + + if (m_rx_escape == true) + { + m_rx_escape = false; + *p_received_byte = APP_SLIP_ESC; + } + break; + + /* Normal character - decoding not needed*/ + default: + break; + } + + return true; +} + + +static void ser_phi_hci_rx_byte(uint8_t rx_byte) +{ + static bool rx_sync = false; + uint8_t received_byte = rx_byte; + static bool big_buff_in_use = false; + static uint32_t m_rx_index; + /* Test received byte for SLIP packet start: 0xC0*/ + if (!rx_sync) + { + if (received_byte == APP_SLIP_END) + { + m_rx_index = 0; + rx_sync = true; + } + return; + } + + /* Additional check needed in case rx_sync flag was set by end of previous packet*/ + if ((m_rx_index) == 0 && (received_byte == APP_SLIP_END)) + { + return; + } + + /* Check if small (ACK) buffer is available*/ + if ((mp_small_buffer != NULL) && (big_buff_in_use == false)) + { + if (m_rx_index == 0) + { + mp_buffer = mp_small_buffer; + } + + /* Check if switch between small and big buffer is needed*/ + if (m_rx_index == sizeof (m_small_buffer) && received_byte != APP_SLIP_END) + { + /* Check if big (PKT) buffer is available*/ + if (mp_big_buffer != NULL) + { + /* Switch to big buffer*/ + memcpy(m_big_buffer, m_small_buffer, sizeof (m_small_buffer)); + mp_buffer = m_big_buffer; + } + else + { + /* Small buffer is too small and big buffer not available - cannot continue reception*/ + rx_sync = false; + return; + } + } + + /* Check if big buffer is full */ + if ((m_rx_index >= PKT_SIZE) && (received_byte != APP_SLIP_END)) + { + /* Do not notify upper layer - the packet is too big and cannot be handled by slip */ + rx_sync = false; + return; + } + + /* Decode byte. Will return false when it is 0xC0 - end of packet*/ + if (slip_decode(&received_byte)) + { + /* Write Rx byte only if it is not escape char */ + if (!m_rx_escape) + { + mp_buffer[m_rx_index++] = received_byte; + } + } + else + { + /* Reset pointers to signalise buffers are locked waiting for upper layer */ + if (mp_buffer == mp_small_buffer) + { + mp_small_buffer = NULL; + } + else + { + mp_big_buffer = NULL; + } + /* Report packet reception end*/ + m_ser_phy_hci_slip_event.evt_type = + SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED; + m_ser_phy_hci_slip_event.evt_params.received_pkt.p_buffer = mp_buffer; + m_ser_phy_hci_slip_event.evt_params.received_pkt.num_of_bytes = m_rx_index; + m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event); + + rx_sync = false; + } + } + else if (mp_big_buffer != NULL) + { + big_buff_in_use = true; + mp_buffer = mp_big_buffer; + + /* Check if big buffer is full */ + if ((m_rx_index >= PKT_SIZE) && (received_byte != APP_SLIP_END)) + { + /* Do not notify upper layer - the packet is too big and cannot be handled by slip */ + rx_sync = false; + return; + } + + /* Decode byte*/ + if (slip_decode(&received_byte)) + { + /* Write Rx byte only if it is not escape char */ + if (!m_rx_escape) + { + mp_buffer[m_rx_index++] = received_byte; + } + } + else + { + // Mark the big buffer as locked (it should be freed by the upper + // layer). + mp_big_buffer = NULL; + big_buff_in_use = false; + + /* Report packet reception end*/ + m_ser_phy_hci_slip_event.evt_type = + SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED; + m_ser_phy_hci_slip_event.evt_params.received_pkt.p_buffer = mp_buffer; + m_ser_phy_hci_slip_event.evt_params.received_pkt.num_of_bytes = m_rx_index; + m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event); + + rx_sync = false; + } + } + else + { + /* Both buffers are not available - cannot continue reception*/ + rx_sync = false; + return; + } +} + + +uint32_t ser_phy_hci_slip_rx_buf_free(uint8_t * p_buffer) +{ + uint32_t err_code = NRF_SUCCESS; + + if (p_buffer == NULL) + { + return NRF_ERROR_NULL; + } + else if (p_buffer == m_small_buffer) + { + /* Free small buffer*/ + if (mp_small_buffer == NULL) + { + mp_small_buffer = m_small_buffer; + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + } + else if (p_buffer == m_big_buffer) + { + /* Free big buffer*/ + if (mp_big_buffer == NULL) + { + mp_big_buffer = m_big_buffer; + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + } + + return err_code; +} + + +static void uart_event_handler(nrf_drv_uart_event_t * p_event, + void * p_context) +{ + (void)p_context; + + switch (p_event->type) + { + case NRF_DRV_UART_EVT_ERROR: + // Process the error only if this is a parity or overrun error. + // Break and framing errors will always occur before the other + // side becomes active. + if (p_event->data.error.error_mask & + (NRF_UART_ERROR_PARITY_MASK | NRF_UART_ERROR_OVERRUN_MASK)) + { + // Pass error source to upper layer + m_ser_phy_hci_slip_event.evt_type = + SER_PHY_HCI_SLIP_EVT_HW_ERROR; + m_ser_phy_hci_slip_event.evt_params.hw_error.error_code = + p_event->data.error.error_mask; + m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event); + } + APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_buf, 1)); + break; + + case NRF_DRV_UART_EVT_TX_DONE: + // If there is a pending transfer (the second buffer is ready to + // be sent), start it immediately. + if (m_tx_pending) + { + APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, mp_tx_buf, m_tx_bytes)); + + // Switch to the buffer that has just been sent completely + // and now can be filled again. + mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0; + m_tx_bytes = 0; + + m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type; + m_tx_evt_type = m_tx_pending_evt_type; + + m_tx_pending = false; + } + else + { + m_tx_in_progress = false; + m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type; + } + // If needed, notify the upper layer that the packet transfer is + // complete (note that this notification may result in another + // packet send request, so everything must be cleaned up above). + if (m_ser_phy_hci_slip_event.evt_type != NO_EVENT) + { + m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event); + } + // And if the sending process is not yet finished, look what is + // to be done next. + if (m_tx_phase != PHASE_IDLE) + { + tx_buf_fill(); + } + break; + + case NRF_DRV_UART_EVT_RX_DONE: + { + uint8_t rx_byte = m_rx_buf[0]; + APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_buf, 1)); + ser_phi_hci_rx_byte(rx_byte); + } + break; + + default: + APP_ERROR_CHECK(NRF_ERROR_INTERNAL); + } +} + + +uint32_t ser_phy_hci_slip_open(ser_phy_hci_slip_event_handler_t events_handler) +{ + uint32_t err_code; + + if (events_handler == NULL) + { + return NRF_ERROR_NULL; + } + + // Check if function was not called before. + if (m_ser_phy_hci_slip_event_handler != NULL) + { + return NRF_ERROR_INVALID_STATE; + } + + m_ser_phy_hci_slip_event_handler = events_handler; + + err_code = nrf_drv_uart_init(&m_uart, &m_uart_config, uart_event_handler); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INVALID_PARAM; + } + + mp_tx_buf = m_tx_buf0; + m_tx_bytes = 0; + m_tx_phase = PHASE_IDLE; + m_tx_in_progress = false; + m_tx_pending = false; + + m_rx_escape = false; + mp_small_buffer = m_small_buffer; + mp_big_buffer = m_big_buffer; + + APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_buf, 1)); + + return NRF_SUCCESS; +} + + +void ser_phy_hci_slip_close(void) +{ + nrf_drv_uart_uninit(&m_uart); + m_ser_phy_hci_slip_event_handler = NULL; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_hci_slip_cdc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_hci_slip_cdc.c new file mode 100644 index 0000000000000000000000000000000000000000..58942dd85b0f8eb7faddb3e0ec5c5ffd9133fef5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_hci_slip_cdc.c @@ -0,0 +1,770 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ser_phy_hci.h" +#include "ser_config.h" +#ifdef SER_CONNECTIVITY +#include "ser_phy_config_conn.h" +#else +#include "ser_phy_config_app.h" +#endif +#include "app_usbd_cdc_acm.h" +#include "nrf_drv_clock.h" +#include "app_error.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "CONN" +#include "nrf_log.h" + +#define APP_SLIP_END 0xC0 /**< SLIP code for identifying the beginning and end of a packet frame.. */ +#define APP_SLIP_ESC 0xDB /**< SLIP escape code. This code is used to specify that the following character is specially encoded. */ +#define APP_SLIP_ESC_END 0xDC /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xC0.. */ +#define APP_SLIP_ESC_ESC 0xDD /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xDB. */ + +#define HDR_SIZE 4 +#define CRC_SIZE 2 +#define PKT_SIZE (SER_HAL_TRANSPORT_MAX_PKT_SIZE + HDR_SIZE + CRC_SIZE) + +static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_cdc_acm_user_event_t event); + +#define CDC_ACM_COMM_INTERFACE 0 +#define CDC_ACM_COMM_EPIN NRF_DRV_USBD_EPIN2 + +#define CDC_ACM_DATA_INTERFACE 1 +#define CDC_ACM_DATA_EPIN NRF_DRV_USBD_EPIN1 +#define CDC_ACM_DATA_EPOUT NRF_DRV_USBD_EPOUT1 + +#define CDC_ACM_INTERFACES_CONFIG() \ + APP_USBD_CDC_ACM_CONFIG(CDC_ACM_COMM_INTERFACE, \ + CDC_ACM_COMM_EPIN, \ + CDC_ACM_DATA_INTERFACE, \ + CDC_ACM_DATA_EPIN, \ + CDC_ACM_DATA_EPOUT) + +static const uint8_t m_cdc_acm_class_descriptors[] = { + APP_USBD_CDC_ACM_DEFAULT_DESC(CDC_ACM_COMM_INTERFACE, + CDC_ACM_COMM_EPIN, + CDC_ACM_DATA_INTERFACE, + CDC_ACM_DATA_EPIN, + CDC_ACM_DATA_EPOUT) +}; + +/*lint -save -e40 -e26 -e64 -e123 -e505 -e651*/ +APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm, + CDC_ACM_INTERFACES_CONFIG(), + cdc_acm_user_ev_handler, + m_cdc_acm_class_descriptors +); +/*lint -restore*/ + +static bool volatile m_port_open; + +typedef struct { + ser_phy_hci_pkt_params_t header; + ser_phy_hci_pkt_params_t payload; + ser_phy_hci_pkt_params_t crc; +} ser_phy_hci_slip_pkt_t; +static ser_phy_hci_slip_pkt_t m_tx_curr_packet; +static ser_phy_hci_slip_pkt_t m_tx_next_packet; + +static ser_phy_hci_slip_evt_t m_ser_phy_hci_slip_event; +static ser_phy_hci_slip_event_handler_t m_ser_phy_hci_slip_event_handler; /**< Event handler for upper layer */ + +static uint8_t m_tx_buf0[NRF_DRV_USBD_EPSIZE]; +static uint8_t m_tx_buf1[NRF_DRV_USBD_EPSIZE]; +static uint8_t * mp_tx_buf; +static uint8_t m_tx_bytes; +static enum { + PHASE_BEGIN, + PHASE_HEADER, + PHASE_PAYLOAD, + PHASE_CRC, + PHASE_ACK_END, + // The following three elements have to have consecutive values, + // 'tx_buf_fill()' relies on this. + PHASE_PACKET_END, + PHASE_PRE_IDLE = PHASE_PACKET_END + 1, + PHASE_IDLE = PHASE_PRE_IDLE + 1 +} volatile m_tx_phase; +static bool volatile m_tx_in_progress; +static bool volatile m_tx_pending; + +#define NO_EVENT SER_PHY_HCI_SLIP_EVT_TYPE_MAX +static ser_phy_hci_slip_evt_type_t m_tx_evt_type; +static ser_phy_hci_slip_evt_type_t m_tx_pending_evt_type; + +static ser_phy_hci_pkt_params_t * mp_tx_data = NULL; +static uint32_t m_tx_index; + +static uint8_t m_small_buffer[HDR_SIZE]; +static uint8_t m_big_buffer[PKT_SIZE]; + +static uint8_t * mp_small_buffer = NULL; +static uint8_t * mp_big_buffer = NULL; +static uint8_t * mp_buffer = NULL; +static uint32_t m_rx_index; + +static uint8_t m_rx_buf[NRF_DRV_USBD_EPSIZE]; +static bool m_rx_escape; + +#define SERIAL_NUMBER_STRING_SIZE (16) +uint16_t g_extern_serial_number[SERIAL_NUMBER_STRING_SIZE + 1]; + +static void serial_number_string_create(void) +{ + g_extern_serial_number[0] = (uint16_t)APP_USBD_DESCRIPTOR_STRING << 8 | + sizeof(g_extern_serial_number); + + uint32_t dev_id_hi = NRF_FICR->DEVICEID[1]; + uint32_t dev_id_lo = NRF_FICR->DEVICEID[0]; + uint64_t device_id = (((uint64_t)dev_id_hi) << 32) | dev_id_lo; + + for (size_t i = SERIAL_NUMBER_STRING_SIZE; i > 0; --i) + { + uint8_t nibble = (uint8_t)(device_id & 0xF); + device_id >>= 4; + + uint8_t hex_digit; + if (nibble >= 10) + { + hex_digit = 'A' + (nibble - 10); + } + else + { + hex_digit = '0' + nibble; + } + g_extern_serial_number[i] = hex_digit; + } +} + +// The function returns false to signal that no more bytes can be passed to be +// sent (put into the TX buffer) until UART transmission is done. +static bool tx_buf_put(uint8_t data_byte) +{ + ASSERT(m_tx_bytes < SER_PHY_HCI_SLIP_TX_BUF_SIZE); + mp_tx_buf[m_tx_bytes] = data_byte; + ++m_tx_bytes; + + bool flush = false; + ser_phy_hci_slip_evt_type_t slip_evt_type = NO_EVENT; + if (m_tx_phase == PHASE_ACK_END) + { + // Send buffer, then signal that an acknowledge packet has been sent. + flush = true; + slip_evt_type = SER_PHY_HCI_SLIP_EVT_ACK_SENT; + } + else if (m_tx_phase == PHASE_PACKET_END) + { + // Send buffer, then signal that a packet with payload has been sent. + flush = true; + slip_evt_type = SER_PHY_HCI_SLIP_EVT_PKT_SENT; + } + else if (m_tx_bytes >= SER_PHY_HCI_SLIP_TX_BUF_SIZE) + { + // Send buffer (because it is filled up), but don't signal anything, + // since the packet sending is not complete yet. + flush = true; + } + + if (flush) + { + // If some TX transfer is being done at the moment, a new one cannot be + // started, it must be scheduled to be performed later. + if (m_tx_in_progress) + { + m_tx_pending_evt_type = slip_evt_type; + m_tx_pending = true; + // No more buffers available, can't continue filling. + return false; + } + + if (m_port_open) + { + m_tx_in_progress = true; + m_tx_evt_type = slip_evt_type; + APP_ERROR_CHECK(app_usbd_cdc_acm_write(&m_app_cdc_acm, + mp_tx_buf, m_tx_bytes)); + } + + // Switch to the second buffer. + mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0; + m_tx_bytes = 0; + } + + return true; +} + +static void tx_buf_fill(void) +{ + bool can_continue = true; + do { + static uint8_t tx_escaped_data = 0; + + if (tx_escaped_data != 0) + { + can_continue = tx_buf_put(tx_escaped_data); + tx_escaped_data = 0; + } + else switch (m_tx_phase) + { + case PHASE_BEGIN: + can_continue = tx_buf_put(APP_SLIP_END); + mp_tx_data = &m_tx_curr_packet.header; + m_tx_index = 0; + m_tx_phase = PHASE_HEADER; + tx_escaped_data = 0; + break; + + case PHASE_ACK_END: + case PHASE_PACKET_END: + can_continue = tx_buf_put(APP_SLIP_END); + + // [this is needed for the '++m_tx_phase;' below] + m_tx_phase = PHASE_PACKET_END; + // no break, intentional fall-through + + case PHASE_PRE_IDLE: + // In PHASE_PRE_IDLE the sending process is almost finished, only + // the NRF_DRV_UART_EVT_TX_DONE event is needed before it can switch + // to PHASE_IDLE. But during this waiting a new packet may appear + // (i.e. 'ser_phy_hci_slip_tx_pkt_send()' may be called), hence + // the following pointer must be checked before switching the phase, + // just like right after writing whole packet to buffer (i.e. in + // PHASE_PACKET_END). Therefore, the following code is common for + // these two cases. + if (m_tx_next_packet.header.p_buffer != NULL) + { + m_tx_curr_packet = m_tx_next_packet; + m_tx_next_packet.header.p_buffer = NULL; + + m_tx_phase = PHASE_BEGIN; + break; + } + // Go to the next phase: + // PHASE_PACKET_END -> PHASE_PRE_IDLE + // PHASE_PRE_IDLE -> PHASE_IDLE + ++m_tx_phase; + return; + + default: + ASSERT(mp_tx_data->p_buffer != NULL); + uint8_t data = mp_tx_data->p_buffer[m_tx_index]; + ++m_tx_index; + + if (data == APP_SLIP_END) + { + data = APP_SLIP_ESC; + tx_escaped_data = APP_SLIP_ESC_END; + } + else if (data == APP_SLIP_ESC) + { + tx_escaped_data = APP_SLIP_ESC_ESC; + } + can_continue = tx_buf_put(data); + + if (m_tx_index >= mp_tx_data->num_of_bytes) + { + mp_tx_data->p_buffer = NULL; + + if (m_tx_phase == PHASE_HEADER) + { + if (m_tx_curr_packet.payload.p_buffer == NULL) + { + // No payload -> ACK packet. + m_tx_phase = PHASE_ACK_END; + } + else + { + mp_tx_data = &m_tx_curr_packet.payload; + m_tx_index = 0; + m_tx_phase = PHASE_PAYLOAD; + } + } + else if (m_tx_phase == PHASE_PAYLOAD) + { + if (m_tx_curr_packet.crc.p_buffer == NULL) + { + // Packet without CRC. + m_tx_phase = PHASE_PACKET_END; + } + else + { + mp_tx_data = &m_tx_curr_packet.crc; + m_tx_index = 0; + m_tx_phase = PHASE_CRC; + } + } + else + { + ASSERT(m_tx_phase == PHASE_CRC); + m_tx_phase = PHASE_PACKET_END; + } + } + break; + } + } while (can_continue); +} + +uint32_t ser_phy_hci_slip_tx_pkt_send(const ser_phy_hci_pkt_params_t * p_header, + const ser_phy_hci_pkt_params_t * p_payload, + const ser_phy_hci_pkt_params_t * p_crc) +{ + if (p_header == NULL) + { + return NRF_ERROR_NULL; + } + + if (!m_port_open) + { + return NRF_SUCCESS; + } + + CRITICAL_REGION_ENTER(); + + // If some packet is already transmitted, schedule this new one to be sent + // as next. A critical region is needed here to ensure that the transmission + // won't finish before the following assignments are done. + if (m_tx_phase != PHASE_IDLE) + { + m_tx_next_packet.header = *p_header; + + if (p_payload == NULL) + { + m_tx_next_packet.payload.p_buffer = NULL; + } + else + { + m_tx_next_packet.payload = *p_payload; + } + + if (p_crc == NULL) + { + m_tx_next_packet.crc.p_buffer = NULL; + } + else + { + m_tx_next_packet.crc = *p_crc; + } + } + else + { + m_tx_curr_packet.header = *p_header; + + if (p_payload == NULL) + { + m_tx_curr_packet.payload.p_buffer = NULL; + } + else + { + m_tx_curr_packet.payload = *p_payload; + } + + if (p_crc == NULL) + { + m_tx_curr_packet.crc.p_buffer = NULL; + } + else + { + m_tx_curr_packet.crc = *p_crc; + } + + m_tx_phase = PHASE_BEGIN; + tx_buf_fill(); + } + + CRITICAL_REGION_EXIT(); + + return NRF_SUCCESS; +} + +/* Function returns false when last byte in packet is detected.*/ +static bool slip_decode(uint8_t * p_received_byte) +{ + switch (*p_received_byte) + { + case APP_SLIP_END: + return false; + + case APP_SLIP_ESC: + m_rx_escape = true; + break; + + case APP_SLIP_ESC_END: + + if (m_rx_escape == true) + { + m_rx_escape = false; + *p_received_byte = APP_SLIP_END; + } + break; + + case APP_SLIP_ESC_ESC: + + if (m_rx_escape == true) + { + m_rx_escape = false; + *p_received_byte = APP_SLIP_ESC; + } + break; + + /* Normal character - decoding not needed*/ + default: + break; + } + + return true; +} + + +static void ser_phi_hci_rx_byte(uint8_t rx_byte) +{ + static bool rx_sync = false; + uint8_t received_byte = rx_byte; + static bool big_buff_in_use = false; + + /* Test received byte for SLIP packet start: 0xC0*/ + if (!rx_sync) + { + if (received_byte == APP_SLIP_END) + { + m_rx_index = 0; + rx_sync = true; + } + return; + } + + /* Additional check needed in case rx_sync flag was set by end of previous packet*/ + if ((m_rx_index) == 0 && (received_byte == APP_SLIP_END)) + { + return; + } + + /* Check if small (ACK) buffer is available*/ + if ((mp_small_buffer != NULL) && (big_buff_in_use == false)) + { + if (m_rx_index == 0) + { + mp_buffer = mp_small_buffer; + } + + /* Check if switch between small and big buffer is needed*/ + if (m_rx_index == sizeof (m_small_buffer) /*NEW!!!*/ && received_byte != APP_SLIP_END) + { + /* Check if big (PKT) buffer is available*/ + if (mp_big_buffer != NULL) + { + /* Switch to big buffer*/ + memcpy(m_big_buffer, m_small_buffer, sizeof (m_small_buffer)); + mp_buffer = m_big_buffer; + } + else + { + /* Small buffer is too small and big buffer not available - cannot continue reception*/ + rx_sync = false; + return; + } + } + + /* Check if big buffer is full */ + if ((m_rx_index >= PKT_SIZE) && (received_byte != APP_SLIP_END)) + { + /* Do not notify upper layer - the packet is too big and cannot be handled by slip */ + rx_sync = false; + return; + } + + /* Decode byte. Will return false when it is 0xC0 - end of packet*/ + if (slip_decode(&received_byte)) + { + /* Write Rx byte only if it is not escape char */ + if (!m_rx_escape) + { + mp_buffer[m_rx_index++] = received_byte; + } + } + else + { + /* Reset pointers to signalise buffers are locked waiting for upper layer */ + if (mp_buffer == mp_small_buffer) + { + mp_small_buffer = NULL; + } + else + { + mp_big_buffer = NULL; + } + /* Report packet reception end*/ + m_ser_phy_hci_slip_event.evt_type = + SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED; + m_ser_phy_hci_slip_event.evt_params.received_pkt.p_buffer = mp_buffer; + m_ser_phy_hci_slip_event.evt_params.received_pkt.num_of_bytes = m_rx_index; + m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event); + + rx_sync = false; + } + } + else if (mp_big_buffer != NULL) + { + big_buff_in_use = true; + mp_buffer = mp_big_buffer; + + /* Check if big buffer is full */ + if ((m_rx_index >= PKT_SIZE) && (received_byte != APP_SLIP_END)) + { + /* Do not notify upper layer - the packet is too big and cannot be handled by slip */ + rx_sync = false; + return; + } + + /* Decode byte*/ + if (slip_decode(&received_byte)) + { + /* Write Rx byte only if it is not escape char */ + if (!m_rx_escape) + { + mp_buffer[m_rx_index++] = received_byte; + } + } + else + { + // Mark the big buffer as locked (it should be freed by the upper + // layer). + mp_big_buffer = NULL; + big_buff_in_use = false; + + /* Report packet reception end*/ + m_ser_phy_hci_slip_event.evt_type = + SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED; + m_ser_phy_hci_slip_event.evt_params.received_pkt.p_buffer = mp_buffer; + m_ser_phy_hci_slip_event.evt_params.received_pkt.num_of_bytes = m_rx_index; + m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event); + + rx_sync = false; + } + } + else + { + /* Both buffers are not available - cannot continue reception*/ + rx_sync = false; + return; + } +} + + +uint32_t ser_phy_hci_slip_rx_buf_free(uint8_t * p_buffer) +{ + uint32_t err_code = NRF_SUCCESS; + + if (p_buffer == NULL) + { + return NRF_ERROR_NULL; + } + else if (p_buffer == m_small_buffer) + { + /* Free small buffer*/ + if (mp_small_buffer == NULL) + { + mp_small_buffer = m_small_buffer; + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + } + else if (p_buffer == m_big_buffer) + { + /* Free big buffer*/ + if (mp_big_buffer == NULL) + { + mp_big_buffer = m_big_buffer; + } + else + { + err_code = NRF_ERROR_INVALID_STATE; + } + } + + return err_code; +} + + +static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_cdc_acm_user_event_t event) +{ + app_usbd_cdc_acm_t const * p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst); + + switch (event) + { + case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN: + NRF_LOG_DEBUG("EVT_PORT_OPEN\r\n"); + if (!m_port_open) + { + m_port_open = true; + APP_ERROR_CHECK(app_usbd_cdc_acm_read(p_cdc_acm, + m_rx_buf, sizeof(m_rx_buf))); + } + break; + + case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE: + NRF_LOG_DEBUG("EVT_PORT_CLOSE\r\n"); + m_port_open = false; + break; + + case APP_USBD_CDC_ACM_USER_EVT_TX_DONE: + // If there is a pending transfer (the second buffer is ready to + // be sent), start it immediately. + if (m_tx_pending) + { + APP_ERROR_CHECK(app_usbd_cdc_acm_write(p_cdc_acm, + mp_tx_buf, m_tx_bytes)); + + // Switch to the buffer that has just been sent completely + // and now can be filled again. + mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0; + m_tx_bytes = 0; + + m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type; + m_tx_evt_type = m_tx_pending_evt_type; + + m_tx_pending = false; + } + else + { + m_tx_in_progress = false; + m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type; + } + // If needed, notify the upper layer that the packet transfer is + // complete (note that this notification may result in another + // packet send request, so everything must be cleaned up above). + if (m_ser_phy_hci_slip_event.evt_type != NO_EVENT) + { + m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event); + } + // And if the sending process is not yet finished, look what is + // to be done next. + if (m_tx_phase != PHASE_IDLE) + { + tx_buf_fill(); + } + break; + + case APP_USBD_CDC_ACM_USER_EVT_RX_DONE: + { + size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm); + for (size_t i = 0; i < size; ++i) + { + ser_phi_hci_rx_byte(m_rx_buf[i]); + } + APP_ERROR_CHECK(app_usbd_cdc_acm_read(p_cdc_acm, + m_rx_buf, sizeof(m_rx_buf))); + } + break; + + default: + break; + } +} + +static void clock_event_handler(nrf_drv_clock_evt_type_t event) +{ + ASSERT(event == NRF_DRV_CLOCK_EVT_HFCLK_STARTED); + (void)event; + + NRF_LOG_DEBUG("Clock started\r\n"); + + APP_ERROR_CHECK(app_usbd_init(NULL)); + APP_ERROR_CHECK(app_usbd_class_append( + app_usbd_cdc_acm_class_inst_get(&m_app_cdc_acm))); + + app_usbd_enable(); + app_usbd_start(); + + NRF_LOG_DEBUG("USB started\r\n"); +} +static nrf_drv_clock_handler_item_t m_clock_handler_item = { + NULL, + clock_event_handler +}; + +uint32_t ser_phy_hci_slip_open(ser_phy_hci_slip_event_handler_t events_handler) +{ + if (events_handler == NULL) + { + return NRF_ERROR_NULL; + } + + // Check if function was not called before. + if (m_ser_phy_hci_slip_event_handler != NULL) + { + return NRF_ERROR_INVALID_STATE; + } + + serial_number_string_create(); + + (void)nrf_drv_clock_init(); + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + + m_ser_phy_hci_slip_event_handler = events_handler; + + mp_tx_buf = m_tx_buf0; + m_tx_bytes = 0; + m_tx_phase = PHASE_IDLE; + m_tx_in_progress = false; + m_tx_pending = false; + + m_rx_escape = false; + mp_small_buffer = m_small_buffer; + mp_big_buffer = m_big_buffer; + + return NRF_SUCCESS; +} + + +void ser_phy_hci_slip_close(void) +{ + app_usbd_stop(); + app_usbd_disable(); + (void)app_usbd_uninit(); + nrf_drv_clock_hfclk_release(); + + m_ser_phy_hci_slip_event_handler = NULL; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_nohci.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_nohci.c new file mode 100644 index 0000000000000000000000000000000000000000..4708858bb735e2671e02c02ff7f67a1b1b661ab5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_nohci.c @@ -0,0 +1,382 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ser_phy_spi_phy_driver_slave ser_phy_nrf51_spi_slave.c + * @{ + * @ingroup ser_phy_spi_phy_driver_slave + * + * @brief SPI_RAW PHY slave driver. + */ + +#include +#include + +#include "app_error.h" +#include "app_util.h" +#include "app_util_platform.h" +#include "app_timer.h" +#include "ser_phy.h" +#include "ser_phy_hci.h" +#include "crc16.h" +#include "nrf_soc.h" + +#include "ser_phy_debug_comm.h" + +static bool m_flag_nohci_init = false; +static bool m_flag_expect_ack; +static bool m_flag_buffer_reqested = false; + +static uint16_t m_rx_packet_length; +static uint8_t * m_p_rx_packet; + +static uint16_t m_rx_pending_packet_length; +static uint8_t * m_p_rx_pending_packet; + +static uint16_t m_rx_allocated_packet_length; +static uint8_t * m_p_rx_allocated_packet; + +static uint8_t * m_p_tx_packet = NULL; +static uint16_t m_tx_packet_length; + +static ser_phy_events_handler_t m_ser_phy_callback = NULL; + +#define PKT_HDR_SIZE 4 /**< Packet header size in number of bytes. */ +#define PKT_CRC_SIZE 2 /**< Packet CRC size in number of bytes. */ + +static void ser_phy_nohci_assert(bool cond) +{ + APP_ERROR_CHECK_BOOL(cond); +} + + +static void ser_phy_event_callback(ser_phy_evt_t event) +{ + if (m_ser_phy_callback) + { + m_ser_phy_callback(event); + } +} + + +static void memory_request_callback(uint16_t size) +{ + ser_phy_evt_t event; + + DEBUG_EVT_HCI_PHY_EVT_BUF_REQUEST(0); + + event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; + event.evt_params.rx_buf_request.num_of_bytes = size; + ser_phy_event_callback(event); +} + + +static void packet_received_callback(uint8_t * pBuffer, uint16_t size) +{ + ser_phy_evt_t event; + + DEBUG_EVT_HCI_PHY_EVT_RX_PKT_RECEIVED(0); + + event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; + event.evt_params.rx_pkt_received.num_of_bytes = size; + event.evt_params.rx_pkt_received.p_buffer = pBuffer; + ser_phy_event_callback(event); +} + + +static void packet_dropped_callback(void) +{ + ser_phy_evt_t event; + + DEBUG_EVT_HCI_PHY_EVT_RX_PKT_DROPPED(0); + + event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED; + ser_phy_event_callback(event); +} + + +static void packet_transmitted_callback(void) +{ + ser_phy_evt_t event; + + DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(0); + + event.evt_type = SER_PHY_EVT_TX_PKT_SENT; + ser_phy_event_callback(event); +} + + +static void hci_slip_event_handler(ser_phy_hci_slip_evt_t * p_event) +{ + if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT ) + { + DEBUG_EVT_SLIP_PACKET_TXED(0); + + if (!m_flag_expect_ack) + { + m_p_tx_packet = NULL; + packet_transmitted_callback(); + } + else + { + ser_phy_nohci_assert(false); // packet was send as a ACK packet, callback should be with ACK_SENT + } + + } + else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_ACK_SENT ) + { + DEBUG_EVT_SLIP_ACK_TXED(0); + + if (m_flag_expect_ack) + { + m_p_tx_packet = NULL; + packet_transmitted_callback(); + } + else + { + ser_phy_nohci_assert(false); // packet was send as a normal packet, callback should be with PKT_SENT + } + + } + else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED ) + { + CRITICAL_REGION_ENTER(); + + if (m_p_rx_packet == NULL) + { + m_p_rx_packet = p_event->evt_params.received_pkt.p_buffer; + m_rx_packet_length = p_event->evt_params.received_pkt.num_of_bytes; + m_p_rx_allocated_packet = m_p_rx_packet; + m_rx_allocated_packet_length = m_rx_packet_length; + m_flag_buffer_reqested = true; + memory_request_callback(m_rx_allocated_packet_length); + } + else if (m_p_rx_pending_packet == NULL) + { + m_p_rx_pending_packet = p_event->evt_params.received_pkt.p_buffer; + m_rx_pending_packet_length = p_event->evt_params.received_pkt.num_of_bytes; + } + else + { + // both buffers are not released; this is fault + ser_phy_nohci_assert(false); + } + CRITICAL_REGION_EXIT(); + } + else + { + // no other callbacks are expected + ser_phy_nohci_assert(false); + } +} + + +/* ser_phy API function */ +void ser_phy_interrupts_enable(void) +{ + + NVIC_EnableIRQ(UART0_IRQn); + return; +} + + +/* ser_phy API function */ +void ser_phy_interrupts_disable(void) +{ + NVIC_DisableIRQ(UART0_IRQn); + return; +} + + +/* ser_phy API function */ +uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) +{ + uint32_t status = NRF_SUCCESS; + + if (m_flag_buffer_reqested) + { + m_flag_buffer_reqested = false; + + if (p_buffer) + { + memcpy(p_buffer, m_p_rx_allocated_packet, m_rx_allocated_packet_length); + packet_received_callback(p_buffer, m_rx_allocated_packet_length); + } + else + { + packet_dropped_callback(); + } + + CRITICAL_REGION_ENTER(); + + if (m_p_rx_allocated_packet == m_p_rx_packet && (m_p_rx_pending_packet == NULL)) + { + // packet is copied and there is no pending packet + (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_packet); + m_p_rx_packet = NULL; + m_p_rx_allocated_packet = NULL; + } + else if (m_p_rx_allocated_packet == m_p_rx_packet && (m_p_rx_pending_packet != NULL)) + { + // there is a pending packet - request memory for it + m_p_rx_allocated_packet = m_p_rx_pending_packet; + m_rx_allocated_packet_length = m_rx_pending_packet_length; + m_flag_buffer_reqested = true; + } + else if (m_p_rx_allocated_packet == m_p_rx_pending_packet ) + { + // the pending packet was serviced - release both + m_p_rx_allocated_packet = NULL; + (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_packet); + m_p_rx_packet = NULL; + (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_pending_packet); + m_p_rx_pending_packet = NULL; + } + else + { + // no other calls are expected + ser_phy_nohci_assert(false); + } + CRITICAL_REGION_EXIT(); + + // request memory for a pending + if (m_p_rx_allocated_packet) + { + memory_request_callback(m_rx_allocated_packet_length); + } + } + else + { + status = NRF_ERROR_BUSY; + } + return status; +} + + +/* ser_phy API function */ +uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) +{ + uint32_t status = NRF_SUCCESS; + uint32_t err_code; + + if ( p_buffer == NULL || num_of_bytes == 0) + { + return NRF_ERROR_NULL; + } + + if ( m_p_tx_packet == NULL) + { + m_tx_packet_length = num_of_bytes; + m_p_tx_packet = (uint8_t *)p_buffer; + + if (m_tx_packet_length <= PKT_HDR_SIZE + PKT_CRC_SIZE) + { + ser_phy_hci_pkt_params_t pkt; // all packets smaller than 6 goes as ACK + + m_flag_expect_ack = true; + pkt.p_buffer = (uint8_t *)m_p_tx_packet; + pkt.num_of_bytes = m_tx_packet_length; + DEBUG_EVT_SLIP_ACK_TX(0); + err_code = ser_phy_hci_slip_tx_pkt_send(&pkt, NULL, NULL); // this will look like ACK for slip + ser_phy_nohci_assert(err_code == NRF_SUCCESS); + } + else + { + ser_phy_hci_pkt_params_t header; // this is fake header - just first 4 bytes + ser_phy_hci_pkt_params_t crc; // this is fake header - just last 2 bytes + ser_phy_hci_pkt_params_t payload; // this is fake payload - all except for header and crc + + m_flag_expect_ack = false; + header.p_buffer = (uint8_t *)m_p_tx_packet; + header.num_of_bytes = PKT_HDR_SIZE; + crc.p_buffer = (uint8_t *)m_p_tx_packet + m_tx_packet_length - PKT_CRC_SIZE; + crc.num_of_bytes = PKT_CRC_SIZE; + payload.p_buffer = (uint8_t *)m_p_tx_packet + PKT_HDR_SIZE; + payload.num_of_bytes = m_tx_packet_length - PKT_HDR_SIZE - PKT_CRC_SIZE; + DEBUG_EVT_SLIP_PACKET_TX(0); + err_code = ser_phy_hci_slip_tx_pkt_send(&header, &payload, &crc); // this will look like normal packet for slip + ser_phy_nohci_assert(err_code == NRF_SUCCESS); + } + } + else + { + status = NRF_ERROR_BUSY; + } + + return status; +} + + +/* ser_phy API function */ +uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) +{ + uint32_t err_code; + + if (m_flag_nohci_init) + { + return NRF_ERROR_INVALID_STATE; + } + + if (events_handler == NULL) + { + return NRF_ERROR_NULL; + } + err_code = ser_phy_hci_slip_open(hci_slip_event_handler); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + m_ser_phy_callback = events_handler; + m_flag_nohci_init = true; + return NRF_SUCCESS; +} + + +/* ser_phy API function */ +void ser_phy_close(void) +{ + m_ser_phy_callback = NULL; + ser_phy_hci_slip_close(); + m_flag_nohci_init = false; +} + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_master.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_master.c new file mode 100644 index 0000000000000000000000000000000000000000..f005e753aeb2d88eee05456bbf31d339e03b1631 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_master.c @@ -0,0 +1,823 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ser_phy_spi_5W_phy_driver_master ser_phy_nrf51_spi_5W_master.c + * @{ + * @ingroup ser_phy_spi_5W_phy_driver_master + * + * @brief SPI_5W_RAW PHY master driver. + */ + +#include +#include "app_util.h" +#include "app_util_platform.h" +#include "boards.h" +#include "nrf_error.h" +#include "nrf_gpio.h" +#include "nrf_drv_gpiote.h" +#include "ser_config.h" +#include "ser_config_5W_app.h" +#include "ser_phy.h" +#include "ser_phy_config_app.h" +#include "spi_5W_master.h" +#include "ser_phy_debug_app.h" +#include "app_error.h" +#define notUSE_PendSV + +#ifdef USE_PendSV +#define SW_IRQn PendSV_IRQn +#define SW_IRQ_Handler() PendSV_Handler() +#define SET_Pend_SW_IRQ() SCB->ICSR = SCB->ICSR | SCB_ICSR_PENDSVSET_Msk //NVIC_SetPendingIRQ(PendSV_IRQn) - PendSV_IRQn is a negative - does not work with CMSIS +#else +#define SW_IRQn SWI3_IRQn +#define SW_IRQ_Handler() SWI3_IRQHandler() +#define SET_Pend_SW_IRQ() NVIC_SetPendingIRQ(SWI3_IRQn) +#endif + +#define SER_PHY_SPI_5W_MTU_SIZE SER_PHY_SPI_MTU_SIZE + +typedef enum +{ + SER_PHY_STATE_IDLE = 0, + SER_PHY_STATE_TX_HEADER, + SER_PHY_STATE_TX_WAIT_FOR_RDY, + SER_PHY_STATE_TX_PAYLOAD, + SER_PHY_STATE_RX_WAIT_FOR_RDY, + SER_PHY_STATE_TX_ZERO_HEADER, + SER_PHY_STATE_RX_HEADER, + SER_PHY_STATE_MEMORY_REQUEST, + SER_PHY_STATE_RX_PAYLOAD, + SER_PHY_STATE_DISABLED +} ser_phy_spi_master_state_t; + +typedef enum +{ + SER_PHY_EVT_GPIO_RDY = 0, + SER_PHY_EVT_GPIO_REQ, + SER_PHY_EVT_SPI_TRANSFER_DONE, + SER_PHY_EVT_TX_API_CALL, + SER_PHY_EVT_RX_API_CALL +} ser_phy_event_source_t; + +#define _static static + +_static uint8_t * mp_tx_buffer = NULL; +_static uint16_t m_tx_buf_len = 0; + +_static uint8_t * mp_rx_buffer = NULL; +_static uint16_t m_rx_buf_len = 0; +_static uint8_t m_recv_buffer[SER_PHY_SPI_5W_MTU_SIZE]; +_static uint8_t m_len_buffer[SER_PHY_HEADER_SIZE + 1] = { 0 }; //len is asymmetric for 5W, there is a 1 byte guard when receiving + +_static uint16_t m_tx_packet_length = 0; +_static uint16_t m_accumulated_tx_packet_length = 0; +_static uint16_t m_current_tx_packet_length = 0; + +_static uint16_t m_rx_packet_length = 0; +_static uint16_t m_accumulated_rx_packet_length = 0; +_static uint16_t m_current_rx_packet_length = 0; + +_static volatile bool m_pend_req_flag = 0; +_static volatile bool m_pend_rdy_flag = 0; +_static volatile bool m_pend_xfer_flag = 0; +_static volatile bool m_pend_rx_api_flag = 0; +_static volatile bool m_pend_tx_api_flag = 0; + +_static volatile bool m_slave_ready_flag = false; +_static volatile bool m_slave_request_flag = false; + + +_static ser_phy_events_handler_t m_callback_events_handler = NULL; +_static ser_phy_spi_master_state_t m_spi_master_state = SER_PHY_STATE_DISABLED; + +static void ser_phy_switch_state(ser_phy_event_source_t evt_src); + +static void spi_master_raw_assert(bool cond) +{ + APP_ERROR_CHECK_BOOL(cond); +} + +void SW_IRQ_Handler() +{ + if (m_pend_req_flag) + { + m_pend_req_flag = false; + DEBUG_EVT_SPI_MASTER_RAW_REQUEST(0); + ser_phy_switch_state(SER_PHY_EVT_GPIO_REQ); + } + + if (m_pend_rdy_flag) + { + m_pend_rdy_flag = false; + DEBUG_EVT_SPI_MASTER_RAW_READY(0); + ser_phy_switch_state(SER_PHY_EVT_GPIO_RDY); + } + + if (m_pend_xfer_flag) + { + m_pend_xfer_flag = false; + DEBUG_EVT_SPI_MASTER_RAW_XFER_DONE(0); + ser_phy_switch_state(SER_PHY_EVT_SPI_TRANSFER_DONE); + } + + if (m_pend_rx_api_flag) + { + m_pend_rx_api_flag = false; + DEBUG_EVT_SPI_MASTER_RAW_API_CALL(0); + ser_phy_switch_state(SER_PHY_EVT_RX_API_CALL); + } + + if (m_pend_tx_api_flag) + { + m_pend_tx_api_flag = false; + DEBUG_EVT_SPI_MASTER_RAW_API_CALL(0); + ser_phy_switch_state(SER_PHY_EVT_TX_API_CALL); + } + +} + +#ifndef _SPI_5W_ +static void ser_phy_spi_master_ready(nrf_drv_gpiote_pin_t pin, + nrf_gpiote_polarity_t action) +{ + if (nrf_gpio_pin_read(pin) == 0) + { + m_slave_ready_flag = true; + m_pend_rdy_flag = true; + } + else + { + m_slave_ready_flag = false; + } + + DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE((uint32_t) !m_slave_ready_flag); + SET_Pend_SW_IRQ(); +} +#endif + +static void ser_phy_spi_master_request(nrf_drv_gpiote_pin_t pin, + nrf_gpiote_polarity_t action) +{ + if (nrf_gpio_pin_read(pin) == 0) + { + m_slave_request_flag = true; + m_pend_req_flag = true; + } + else + { + m_slave_request_flag = false; + } + + DEBUG_EVT_SPI_MASTER_RAW_REQUEST_EDGE((uint32_t) !m_slave_request_flag); + SET_Pend_SW_IRQ(); +} + +/* Send event SER_PHY_EVT_TX_PKT_SENT */ +static __INLINE void callback_packet_sent() +{ + ser_phy_evt_t event; + + event.evt_type = SER_PHY_EVT_TX_PKT_SENT; + m_callback_events_handler(event); +} + +/* Send event SER_PHY_EVT_RX_PKT_DROPPED */ +static __INLINE void callback_packet_dropped() +{ + ser_phy_evt_t event; + + event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED; + m_callback_events_handler(event); +} + +/* Send event SER_PHY_EVT_RX_PKT_RECEIVED */ +static __INLINE void callback_packet_received() +{ + ser_phy_evt_t event; + + event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; + event.evt_params.rx_pkt_received.p_buffer = mp_rx_buffer; + event.evt_params.rx_pkt_received.num_of_bytes = m_rx_buf_len; + m_callback_events_handler(event); +} + +/* Send event SER_PHY_EVT_RX_BUF_REQUEST */ +static __INLINE void callback_mem_request() +{ + ser_phy_evt_t event; + + event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; + event.evt_params.rx_buf_request.num_of_bytes = m_rx_buf_len; + m_callback_events_handler(event); +} + +static __INLINE void copy_buff(uint8_t * const p_dest, uint8_t const * const p_src, uint16_t len) +{ + uint16_t index; + + for (index = 0; index < len; index++) + { + p_dest[index] = p_src[index]; + } + return; +} + +static __INLINE void buffer_release(uint8_t * * const pp_buffer, uint16_t * const p_buf_len) +{ + *pp_buffer = NULL; + *p_buf_len = 0; +} + +static uint16_t compute_current_packet_length(const uint16_t packet_length, + const uint16_t accumulated_packet_length) +{ + uint16_t current_packet_length = packet_length - accumulated_packet_length; + + if (current_packet_length > SER_PHY_SPI_5W_MTU_SIZE) + { + current_packet_length = SER_PHY_SPI_5W_MTU_SIZE; + } + + return current_packet_length; +} + +static __INLINE uint32_t header_send(const uint16_t length) +{ + uint16_t buf_len_size = uint16_encode(length, m_len_buffer); + + return spi_master_send_recv(SER_PHY_SPI_MASTER, m_len_buffer, buf_len_size, NULL, 0); +} + +static __INLINE uint32_t frame_send() +{ + uint32_t err_code; + + m_current_tx_packet_length = compute_current_packet_length(m_tx_packet_length, + m_accumulated_tx_packet_length); + err_code = + spi_master_send_recv(SER_PHY_SPI_MASTER, + &mp_tx_buffer[m_accumulated_tx_packet_length], + m_current_tx_packet_length, + NULL, + 0); + m_accumulated_tx_packet_length += m_current_tx_packet_length; + return err_code; +} + +static __INLINE uint32_t header_get() +{ + return spi_master_send_recv(SER_PHY_SPI_MASTER, NULL, 0, m_len_buffer, SER_PHY_HEADER_SIZE + 1); //add 0 byte guard when receiving +} + +static __INLINE uint32_t frame_get() +{ + uint32_t err_code; + + m_current_rx_packet_length = compute_current_packet_length(m_rx_packet_length, + m_accumulated_rx_packet_length); + + if (m_current_rx_packet_length < SER_PHY_SPI_5W_MTU_SIZE) + { + m_current_rx_packet_length++; //take into account guard byte when receiving + } + err_code = spi_master_send_recv(SER_PHY_SPI_MASTER, + NULL, + 0, + m_recv_buffer, + m_current_rx_packet_length); + return err_code; +} + +/** + * \brief Master driver main state machine + * Executed only in the context of PendSV_Handler() + * For UML graph, please refer to SDK documentation +*/ + +static void ser_phy_switch_state(ser_phy_event_source_t evt_src) +{ + uint32_t err_code = NRF_SUCCESS; + static bool m_waitForReadyFlag = false; //local scheduling flag to defer RDY events + + switch (m_spi_master_state) + { + + case SER_PHY_STATE_IDLE: + + if (evt_src == SER_PHY_EVT_GPIO_REQ) + { + m_waitForReadyFlag = false; + + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER; + err_code = header_send(0); + } + else + { + m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY; + } + } + else if (evt_src == SER_PHY_EVT_TX_API_CALL) + { + spi_master_raw_assert(mp_tx_buffer != NULL); //api event with tx_buffer == NULL has no sense + m_waitForReadyFlag = false; + + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_TX_HEADER; + err_code = header_send(m_tx_buf_len); + } + else + { + m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY; + } + } + break; + + case SER_PHY_STATE_TX_WAIT_FOR_RDY: + + if (evt_src == SER_PHY_EVT_GPIO_RDY) + { + m_spi_master_state = SER_PHY_STATE_TX_HEADER; + err_code = header_send(m_tx_buf_len); + } + break; + + case SER_PHY_STATE_RX_WAIT_FOR_RDY: + + if (evt_src == SER_PHY_EVT_GPIO_RDY) + { + m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER; + err_code = header_send(0); + + } + break; + + case SER_PHY_STATE_TX_HEADER: + + if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) + { + m_tx_packet_length = m_tx_buf_len; + m_accumulated_tx_packet_length = 0; + + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD; + err_code = frame_send(); + + } + else + { + m_waitForReadyFlag = true; + } + } + else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag) + { + m_waitForReadyFlag = false; + m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD; + err_code = frame_send(); + } + + break; + + case SER_PHY_STATE_TX_PAYLOAD: + + if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) + { + if (m_accumulated_tx_packet_length < m_tx_packet_length) + { + if (m_slave_ready_flag) + { + err_code = frame_send(); + } + else + { + m_waitForReadyFlag = true; + } + } + else + { + spi_master_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length); + //Release TX buffer + buffer_release(&mp_tx_buffer, &m_tx_buf_len); + callback_packet_sent(); + + if ( m_slave_request_flag) + { + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER; + err_code = header_send(0); + } + else + { + m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY; + } + } + else + { + m_spi_master_state = SER_PHY_STATE_IDLE; //m_Tx_buffer is NULL - have to wait for API event + } + } + } + else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag ) + { + m_waitForReadyFlag = false; + err_code = frame_send(); + } + + break; + + case SER_PHY_STATE_TX_ZERO_HEADER: + + if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) + { + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_RX_HEADER; + err_code = header_get(); + } + else + { + m_waitForReadyFlag = true; + } + } + else if ( (evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag) + { + m_waitForReadyFlag = false; + m_spi_master_state = SER_PHY_STATE_RX_HEADER; + err_code = header_get(); + } + break; + + case SER_PHY_STATE_RX_HEADER: + + if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) + { + m_spi_master_state = SER_PHY_STATE_MEMORY_REQUEST; + m_rx_buf_len = uint16_decode(&(m_len_buffer[1])); //skip guard when receiving + m_rx_packet_length = m_rx_buf_len; + callback_mem_request(); + } + break; + + case SER_PHY_STATE_MEMORY_REQUEST: + + if (evt_src == SER_PHY_EVT_RX_API_CALL) + { + m_accumulated_rx_packet_length = 0; + + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD; + err_code = frame_get(); + } + else + { + m_waitForReadyFlag = true; + } + } + else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag) + { + m_waitForReadyFlag = false; + m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD; + err_code = frame_get(); + } + break; + + case SER_PHY_STATE_RX_PAYLOAD: + + if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) + { + if (mp_rx_buffer) + { + copy_buff(&(mp_rx_buffer[m_accumulated_rx_packet_length]), + &(m_recv_buffer[1]), + m_current_rx_packet_length - 1); //skip guard byte when receiving + } + m_accumulated_rx_packet_length += (m_current_rx_packet_length - 1); + + if (m_accumulated_rx_packet_length < m_rx_packet_length) + { + if (m_slave_ready_flag) + { + err_code = frame_get(); + } + else + { + m_waitForReadyFlag = true; + } + } + else + { + spi_master_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length); + + if (mp_rx_buffer == NULL) + { + callback_packet_dropped(); + } + else + { + callback_packet_received(); + } + //Release RX buffer + buffer_release(&mp_rx_buffer, &m_rx_buf_len); + + if ((mp_tx_buffer != NULL)) //mp_tx_buffer !=NULL, this means that API_EVT was scheduled + { + if (m_slave_ready_flag ) + { + err_code = header_send(m_tx_buf_len); + m_spi_master_state = SER_PHY_STATE_TX_HEADER; + } + else + { + m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY; + } + } + else if (m_slave_request_flag) + { + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER; + err_code = header_send(0); + } + else + { + m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY; + } + } + else + { + m_spi_master_state = SER_PHY_STATE_IDLE; + } + } + } + else if ( evt_src == SER_PHY_EVT_GPIO_RDY && m_waitForReadyFlag) + { + m_waitForReadyFlag = false; + err_code = frame_get(); + } + + + break; + + default: + break; + } + + + if (err_code != NRF_SUCCESS) + { + (void)err_code; + } +} + +/* SPI master event handler */ +static void ser_phy_spi_master_event_handler(spi_master_evt_t spi_master_evt) +{ + switch (spi_master_evt.type) + { + case SPI_MASTER_EVT_TRANSFER_COMPLETED: + + /* Switch state */ + m_pend_xfer_flag = true; + SET_Pend_SW_IRQ(); + + break; + + default: + break; + } +} + +static void ser_phy_init_pendSV(void) +{ + NVIC_SetPriority(SW_IRQn, APP_IRQ_PRIORITY_MID); + NVIC_EnableIRQ(SW_IRQn); +} + +static void ser_phy_init_gpiote(void) +{ + if (!nrf_drv_gpiote_is_init()) + { + (void)nrf_drv_gpiote_init(); + } + NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH); + + nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true); + /* Enable pullup to ensure high state while connectivity device is reset */ + config.pull = NRF_GPIO_PIN_PULLUP; + (void)nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST, &config, + ser_phy_spi_master_request); + nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST,true); + m_slave_request_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST)); + +#ifdef _SPI_5W_ + m_slave_ready_flag = true; +#else + (void)nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_READY, &config, + ser_phy_spi_master_ready); + nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_READY,true); + m_slave_ready_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_READY)); +#endif + + NVIC_ClearPendingIRQ(SW_IRQn); +} + +static void ser_phy_deinit_gpiote(void) +{ + nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST); +#ifndef _SPI_5W_ + nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_READY); +#endif +} + +/* ser_phy API function */ +uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) +{ + if (p_buffer == NULL) + { + return NRF_ERROR_NULL; + } + + if (num_of_bytes == 0) + { + return NRF_ERROR_INVALID_PARAM; + } + + if (mp_tx_buffer != NULL) + { + return NRF_ERROR_BUSY; + } + + //ser_phy_interrupts_disable(); + CRITICAL_REGION_ENTER(); + mp_tx_buffer = (uint8_t *)p_buffer; + m_tx_buf_len = num_of_bytes; + m_pend_tx_api_flag = true; + SET_Pend_SW_IRQ(); + //ser_phy_interrupts_enable(); + CRITICAL_REGION_EXIT(); + + return NRF_SUCCESS; +} + +/* ser_phy API function */ +uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) +{ + if (m_spi_master_state != SER_PHY_STATE_MEMORY_REQUEST) + { + return NRF_ERROR_INVALID_STATE; + } + + //ser_phy_interrupts_disable(); + CRITICAL_REGION_ENTER(); + mp_rx_buffer = p_buffer; + m_pend_rx_api_flag = true; + SET_Pend_SW_IRQ(); + //ser_phy_interrupts_enable(); + CRITICAL_REGION_EXIT(); + + return NRF_SUCCESS; +} + +/* ser_phy API function */ +uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) +{ + + if (m_spi_master_state != SER_PHY_STATE_DISABLED) + { + return NRF_ERROR_INVALID_STATE; + } + + if (events_handler == NULL) + { + return NRF_ERROR_NULL; + } + + uint32_t err_code = NRF_SUCCESS; + m_spi_master_state = SER_PHY_STATE_IDLE; + m_callback_events_handler = events_handler; + ser_phy_init_gpiote(); + + /* Configure SPI Master driver */ + spi_master_config_t spi_master_config; + spi_master_config.SPI_Freq = SPI_FREQUENCY_FREQUENCY_M1; + spi_master_config.SPI_Pin_SCK = SER_PHY_SPI_MASTER_PIN_SCK; + spi_master_config.SPI_Pin_MISO = SER_PHY_SPI_MASTER_PIN_MISO; + spi_master_config.SPI_Pin_MOSI = SER_PHY_SPI_MASTER_PIN_MOSI; + spi_master_config.SPI_Pin_SS = SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT; + spi_master_config.SPI_ORDER = SPI_CONFIG_ORDER_LsbFirst; + spi_master_config.SPI_CPOL = SPI_CONFIG_CPOL_ActiveHigh; + spi_master_config.SPI_CPHA = SPI_CONFIG_CPHA_Leading; + + err_code = spi_master_open(SER_PHY_SPI_MASTER, &spi_master_config); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } +#ifdef _SPI_5W_ + spi_5W_master_evt_handler_reg(SER_PHY_SPI_MASTER, ser_phy_spi_master_event_handler); +#else + spi_master_evt_handler_reg(SER_PHY_SPI_MASTER, ser_phy_spi_master_event_handler); +#endif + ser_phy_init_pendSV(); + + return err_code; +} + +/* ser_phy API function */ +void ser_phy_close(void) +{ + m_spi_master_state = SER_PHY_STATE_DISABLED; + + m_callback_events_handler = NULL; + + buffer_release(&mp_tx_buffer, &m_tx_buf_len); + buffer_release(&mp_rx_buffer, &m_rx_buf_len); + m_tx_packet_length = 0; + m_accumulated_tx_packet_length = 0; + m_current_tx_packet_length = 0; + m_rx_packet_length = 0; + m_accumulated_rx_packet_length = 0; + m_current_rx_packet_length = 0; + ser_phy_deinit_gpiote(); + spi_master_close(SER_PHY_SPI_MASTER); +} + +/* ser_phy API function */ +void ser_phy_interrupts_enable(void) +{ + NVIC_EnableIRQ(SW_IRQn); +} + +/* ser_phy API function */ +void ser_phy_interrupts_disable(void) +{ + NVIC_DisableIRQ(SW_IRQn); +} + + +#ifdef SER_PHY_DEBUG_APP_ENABLE + +static spi_master_raw_callback_t m_spi_master_raw_evt_callback; + +void debug_evt(spi_master_raw_evt_type_t evt, uint32_t data) +{ + if (m_spi_master_raw_evt_callback) + { + spi_master_raw_evt_t e; + e.evt = evt; + e.data = data; + m_spi_master_raw_evt_callback(e); + } +} + +void debug_init(spi_master_raw_callback_t spi_master_raw_evt_callback) +{ + m_spi_master_raw_evt_callback = spi_master_raw_evt_callback; +} + +#endif +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_slave.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_slave.c new file mode 100644 index 0000000000000000000000000000000000000000..c0049c1ee5cee8da8a777755499f29f447179311 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_slave.c @@ -0,0 +1,645 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ser_phy_spi_5W_phy_driver_slave ser_phy_nrf51_spi_5W_slave.c + * @{ + * @ingroup ser_phy_spi_5W_phy_driver_slave + * + * @brief SPI_5W_RAW PHY slave driver. + */ + + +#include +#include + + +#include "boards.h" +#include "nrf_drv_spis.h" +#include "ser_phy.h" +#include "ser_config.h" +#include "nrf_gpio.h" +#include "nrf_delay.h" +#include "nrf_gpiote.h" +#include "nrf_soc.h" +#include "app_error.h" +#include "app_util.h" +#include "ser_phy_config_conn.h" +#include "ser_phy_debug_conn.h" +#include "app_error.h" + +#define _static static + +#define SER_PHY_SPI_5W_MTU_SIZE SER_PHY_SPI_MTU_SIZE + +#define SER_PHY_SPI_DEF_CHARACTER 0xFF //SPI default character. Character clocked out in case of an ignored transaction +#define SER_PHY_SPI_ORC_CHARACTER 0xFF //SPI over-read character. Character clocked out after an over-read of the transmit buffer + +static nrf_drv_spis_t m_spis = NRF_DRV_SPIS_INSTANCE(SER_PHY_SPI_SLAVE_INSTANCE); + +#define _SPI_5W_ + +//SPI raw peripheral device configuration data +typedef struct +{ + int32_t pin_req; //SPI /REQ pin. -1 for not using + int32_t pin_rdy; //SPI /RDY pin. -1 for not using + int32_t ppi_rdy_ch; //SPI /RDY ppi ready channel + int32_t gpiote_rdy_ch; //SPI /RDY pin ready channel +} spi_slave_raw_trasp_cfg_t; + +/**@brief States of the SPI transaction state machine. */ +typedef enum +{ + SPI_RAW_STATE_UNKNOWN, + SPI_RAW_STATE_SETUP_HEADER, + SPI_RAW_STATE_RX_HEADER, + SPI_RAW_STATE_MEM_REQUESTED, + SPI_RAW_STATE_RX_PAYLOAD, + SPI_RAW_STATE_TX_HEADER, + SPI_RAW_STATE_TX_PAYLOAD, +} trans_state_t; + +_static spi_slave_raw_trasp_cfg_t m_spi_slave_raw_config; + +_static uint16_t m_accumulated_rx_packet_length; +_static uint16_t m_rx_packet_length; +_static uint16_t m_current_rx_frame_length; + +_static uint16_t m_accumulated_tx_packet_length; +_static uint16_t m_tx_packet_length; +_static uint16_t m_current_tx_frame_length; + +_static uint8_t m_header_rx_buffer[SER_PHY_HEADER_SIZE + 1]; // + 1 for '0' guard in SPI_5W +_static uint8_t m_header_tx_buffer[SER_PHY_HEADER_SIZE + 1]; // + 1 for '0' guard in SPI_5W + +_static uint8_t m_tx_frame_buffer[SER_PHY_SPI_5W_MTU_SIZE]; +_static uint8_t m_rx_frame_buffer[SER_PHY_SPI_5W_MTU_SIZE]; +_static uint8_t m_zero_buff[SER_PHY_SPI_5W_MTU_SIZE] = { 0 }; //ROM'able declaration - all guard bytes + +_static uint8_t * volatile m_p_rx_buffer = NULL; +_static const uint8_t * volatile m_p_tx_buffer = NULL; + +_static bool m_trash_payload_flag; +_static bool m_buffer_reqested_flag; + +_static trans_state_t m_trans_state = SPI_RAW_STATE_UNKNOWN; +_static ser_phy_events_handler_t m_ser_phy_callback = NULL; + +static void spi_slave_raw_assert(bool cond) +{ + APP_ERROR_CHECK_BOOL(cond); +} + +static void callback_ser_phy_event(ser_phy_evt_t event) +{ + if (m_ser_phy_callback) + { + m_ser_phy_callback(event); + } + return; +} + +static void callback_memory_request(uint16_t size) +{ + ser_phy_evt_t event; + + event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; + event.evt_params.rx_buf_request.num_of_bytes = size; + callback_ser_phy_event(event); + return; + +} + +static void callback_packet_received(uint8_t * pBuffer, uint16_t size) +{ + ser_phy_evt_t event; + + event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; + event.evt_params.rx_pkt_received.num_of_bytes = size; + event.evt_params.rx_pkt_received.p_buffer = pBuffer; + callback_ser_phy_event(event); + return; +} + +static void callback_packet_dropped() +{ + ser_phy_evt_t event; + + event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED; + callback_ser_phy_event(event); + return; +} + +static void callback_packet_transmitted(void) +{ + ser_phy_evt_t event; + + event.evt_type = SER_PHY_EVT_TX_PKT_SENT; + callback_ser_phy_event(event); + return; +} + +static void copy_buff(uint8_t * const p_dest, uint8_t const * const p_src, uint16_t len) +{ + uint16_t index; + + for (index = 0; index < len; index++) + { + p_dest[index] = p_src[index]; + } + return; +} + +/* Function computes current packet length */ +static uint16_t compute_current_frame_length(const uint16_t packet_length, + const uint16_t accumulated_packet_length) +{ + uint16_t current_packet_length = packet_length - accumulated_packet_length; + + if (current_packet_length > SER_PHY_SPI_5W_MTU_SIZE) + { + current_packet_length = SER_PHY_SPI_5W_MTU_SIZE; + } + + return current_packet_length; +} + +static uint32_t header_get() +{ + uint32_t err_code; + + err_code = nrf_drv_spis_buffers_set(&m_spis, + (uint8_t *) m_zero_buff, + SER_PHY_HEADER_SIZE, + m_header_rx_buffer, + SER_PHY_HEADER_SIZE); + return err_code; +} + +static uint32_t frame_get() +{ + uint32_t err_code; + + m_current_rx_frame_length = compute_current_frame_length(m_rx_packet_length, + m_accumulated_rx_packet_length); + + if (!m_trash_payload_flag) + { + err_code = + nrf_drv_spis_buffers_set(&m_spis, + (uint8_t *) m_zero_buff, + m_current_rx_frame_length, + &(m_p_rx_buffer[m_accumulated_rx_packet_length]), + m_current_rx_frame_length); + } + else + { + err_code = nrf_drv_spis_buffers_set(&m_spis, + (uint8_t *) m_zero_buff, + m_current_rx_frame_length, + m_rx_frame_buffer, + m_current_rx_frame_length); + } + return err_code; +} + +static uint32_t header_send(uint16_t len) +{ + uint32_t err_code; + + m_header_tx_buffer[0] = (uint8_t) 0; //this is guard byte + (void)uint16_encode(len, &(m_header_tx_buffer[1])); + err_code = nrf_drv_spis_buffers_set(&m_spis, + m_header_tx_buffer, + SER_PHY_HEADER_SIZE + 1, + m_header_rx_buffer, + SER_PHY_HEADER_SIZE + 1); + return err_code; +} + +static uint32_t frame_send() +{ + uint32_t err_code; + + m_current_tx_frame_length = compute_current_frame_length(m_tx_packet_length, + m_accumulated_tx_packet_length); + + if (m_current_tx_frame_length == SER_PHY_SPI_5W_MTU_SIZE) + { + m_current_tx_frame_length -= 1; //extra space for guard byte must be taken into account for MTU + } + m_tx_frame_buffer[0] = 0; //guard byte + copy_buff(&(m_tx_frame_buffer[1]), + &(m_p_tx_buffer[m_accumulated_tx_packet_length]), + m_current_tx_frame_length); + err_code = nrf_drv_spis_buffers_set(&m_spis, + m_tx_frame_buffer, + m_current_tx_frame_length + 1, + m_rx_frame_buffer, + m_current_tx_frame_length + 1); + + return err_code; +} + +static void set_ready_line(void) +{ +#ifndef _SPI_5W_ + //toggle - this should go high - but toggle is unsafe + uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.gpiote_rdy_ch); + *(uint32_t *)rdy_task = 1; +#endif + return; +} + +static void set_request_line(void) +{ + //active low logic - set is 0 + nrf_gpio_pin_clear(m_spi_slave_raw_config.pin_req); + DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(0); + return; +} + +static void clear_request_line(void) +{ + //active low logic - clear is 1 + nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req); + DEBUG_EVT_SPI_SLAVE_RAW_REQ_CLEARED(0); + return; +} + +/** + * \brief Slave driver main state machine + * For UML graph, please refer to SDK documentation +*/ +static void spi_slave_event_handle(nrf_drv_spis_event_t event) +{ + static uint32_t err_code = NRF_SUCCESS; + static uint16_t packetLength; + + switch (m_trans_state) + { + case SPI_RAW_STATE_SETUP_HEADER: + m_trans_state = SPI_RAW_STATE_RX_HEADER; + err_code = header_get(); + break; + + case SPI_RAW_STATE_RX_HEADER: + + if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); + set_ready_line(); + } + + if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount); + spi_slave_raw_assert(event.rx_amount == SER_PHY_HEADER_SIZE); + packetLength = uint16_decode(m_header_rx_buffer); + + if (packetLength != 0 ) + { + m_trans_state = SPI_RAW_STATE_MEM_REQUESTED; + m_buffer_reqested_flag = true; + m_rx_packet_length = packetLength; + callback_memory_request(packetLength); + } + else + { + if (m_p_tx_buffer) + { + clear_request_line(); + m_trans_state = SPI_RAW_STATE_TX_HEADER; + err_code = header_send(m_tx_packet_length); + } + else + { + //there is nothing to send - zero response facilitates pooling - but perhaps, it should be assert + err_code = header_send(0); + } + } + } + + break; + + case SPI_RAW_STATE_MEM_REQUESTED: + + if (event.evt_type == NRF_DRV_SPIS_EVT_TYPE_MAX) //This is API dummy event + { + m_buffer_reqested_flag = false; + m_trans_state = SPI_RAW_STATE_RX_PAYLOAD; + m_accumulated_rx_packet_length = 0; + err_code = frame_get(); + } + break; + + + case SPI_RAW_STATE_RX_PAYLOAD: + + if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); + set_ready_line(); + } + + if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount); + spi_slave_raw_assert(event.rx_amount == m_current_rx_frame_length); + m_accumulated_rx_packet_length += m_current_rx_frame_length; + + if (m_accumulated_rx_packet_length < m_rx_packet_length ) + { + err_code = frame_get(); + } + else + { + spi_slave_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length); + m_trans_state = SPI_RAW_STATE_RX_HEADER; + err_code = header_get(); + + if (!m_trash_payload_flag) + { + callback_packet_received(m_p_rx_buffer, m_accumulated_rx_packet_length); + } + else + { + callback_packet_dropped(); + } + } + } + break; + + case SPI_RAW_STATE_TX_HEADER: + + if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); + set_ready_line(); + } + + if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount); + spi_slave_raw_assert(event.tx_amount == SER_PHY_HEADER_SIZE + 1); + m_trans_state = SPI_RAW_STATE_TX_PAYLOAD; + m_accumulated_tx_packet_length = 0; + err_code = frame_send(); + } + + break; + + case SPI_RAW_STATE_TX_PAYLOAD: + + if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); + set_ready_line(); + } + + if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount); + spi_slave_raw_assert(event.tx_amount == m_current_tx_frame_length + 1); + m_accumulated_tx_packet_length += m_current_tx_frame_length; + + if ( m_accumulated_tx_packet_length < m_tx_packet_length ) + { + err_code = frame_send(); + } + else + { + spi_slave_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length); + //clear pointer before callback + m_p_tx_buffer = NULL; + callback_packet_transmitted(); + //spi slave TX transfer is possible only when RX is ready, so return to waiting for a header + m_trans_state = SPI_RAW_STATE_RX_HEADER; + err_code = header_get(); + } + } + break; + + default: + err_code = NRF_ERROR_INVALID_STATE; + break; + } + APP_ERROR_CHECK(err_code); +} + +#ifndef _SPI_5W_ +static void spi_slave_gpiote_init(void) +{ + if (!nrf_drv_gpiote_is_init()) + { + (void)nrf_drv_gpiote_init(); + } + nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true); + (void)nrf_drv_gpiote_out_init(m_spi_slave_raw_config.gpiote_rdy_ch, &config); + return; +} + +static void spi_slave_ppi_init(void) +{ + uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.gpiote_rdy_ch); + //Configure PPI channel to clear /RDY line + NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].EEP = (uint32_t)(&NRF_SPIS1->EVENTS_END); + NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].TEP = rdy_task; + + //this works only for channels 0..15 - but soft device is using 8-15 anyway + NRF_PPI->CHEN |= (1 << m_spi_slave_raw_config.ppi_rdy_ch); + return; +} +#endif + +static void spi_slave_gpio_init(void) +{ + nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req); + nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_req); +#ifndef _SPI_5W_ + nrf_gpio_pin_set(m_spi_slave_raw_config.pin_rdy); + nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_rdy); +#endif + return; +} + +/* ser_phy API function */ +void ser_phy_interrupts_enable(void) +{ + NVIC_EnableIRQ(m_spis.irq); +} + +/* ser_phy API function */ +void ser_phy_interrupts_disable(void) +{ + NVIC_DisableIRQ(m_spis.irq); +} + +/* ser_phy API function */ +uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) +{ + uint32_t status = NRF_SUCCESS; + nrf_drv_spis_event_t event; + + ser_phy_interrupts_disable(); + + if (m_buffer_reqested_flag && (m_trans_state == SPI_RAW_STATE_MEM_REQUESTED)) + { + m_p_rx_buffer = p_buffer; + + if (m_p_rx_buffer) + { + m_trash_payload_flag = false; + } + else + { + m_trash_payload_flag = true; + } + + event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition with dummy event + event.rx_amount = 0; + event.tx_amount = 0; + spi_slave_event_handle(event); + } + else + { + status = NRF_ERROR_BUSY; + } + ser_phy_interrupts_enable(); + + return status; +} + +/* ser_phy API function */ +uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) +{ + uint32_t status = NRF_SUCCESS; + + if ( p_buffer == NULL || num_of_bytes == 0) + { + return NRF_ERROR_NULL; + } + + ser_phy_interrupts_disable(); + + if ( m_p_tx_buffer == NULL) + { + m_tx_packet_length = num_of_bytes; + m_p_tx_buffer = p_buffer; + set_request_line(); + } + else + { + status = NRF_ERROR_BUSY; + } + ser_phy_interrupts_enable(); + + return status; +} + +/* ser_phy API function */ +uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) +{ + uint32_t err_code; + nrf_drv_spis_config_t spi_slave_config; + nrf_drv_spis_event_t event; + + if (m_trans_state != SPI_RAW_STATE_UNKNOWN) + { + return NRF_ERROR_INVALID_STATE; + } + + if (events_handler == NULL) + { + return NRF_ERROR_NULL; + } + + //one ppi channel and one gpiote channel are used to drive RDY line + m_spi_slave_raw_config.pin_req = SER_PHY_SPI_SLAVE_REQ_PIN; + m_spi_slave_raw_config.pin_rdy = SER_PHY_SPI_SLAVE_RDY_PIN; + m_spi_slave_raw_config.ppi_rdy_ch = SER_PHY_SPI_PPI_RDY_CH; + m_spi_slave_raw_config.gpiote_rdy_ch = SER_PHY_SPI_GPIOTE_RDY_CH; + + spi_slave_gpio_init(); +#ifndef _SPI_5W_ + spi_slave_gpiote_init(); + spi_slave_ppi_init(); +#endif + + spi_slave_config.miso_pin = SER_CON_SPIS_MISO_PIN; + spi_slave_config.mosi_pin = SER_CON_SPIS_MOSI_PIN; + spi_slave_config.sck_pin = SER_CON_SPIS_SCK_PIN; + spi_slave_config.csn_pin = SER_CON_SPIS_CSN_PIN; + spi_slave_config.mode = NRF_DRV_SPIS_MODE_0; + spi_slave_config.bit_order = NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST; + spi_slave_config.def = SER_PHY_SPI_DEF_CHARACTER; + spi_slave_config.orc = SER_PHY_SPI_ORC_CHARACTER; + spi_slave_config.csn_pullup = NRF_GPIO_PIN_PULLUP; + spi_slave_config.irq_priority = APP_IRQ_PRIORITY_LOWEST; + + //keep /CS high when init + nrf_gpio_cfg_input(spi_slave_config.csn_pin, NRF_GPIO_PIN_PULLUP); + + err_code = nrf_drv_spis_init(&m_spis, &spi_slave_config, spi_slave_event_handle); + APP_ERROR_CHECK(err_code); + + if (err_code == NRF_SUCCESS) + { + m_ser_phy_callback = events_handler; + + m_trans_state = SPI_RAW_STATE_SETUP_HEADER; + event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition for dummy event + event.rx_amount = 0; + event.tx_amount = 0; + spi_slave_event_handle(event); + + } + + return err_code; +} + +/* ser_phy API function */ +void ser_phy_close(void) +{ + nrf_drv_spis_uninit(&m_spis); + m_ser_phy_callback = NULL; + m_trans_state = SPI_RAW_STATE_UNKNOWN; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_spi_master.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_spi_master.c new file mode 100644 index 0000000000000000000000000000000000000000..df70ddb19948b709dcfd80259d030a33afd01ba9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_spi_master.c @@ -0,0 +1,804 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ser_phy_spi_phy_driver_master ser_phy_nrf51_spi_master.c + * @{ + * @ingroup ser_phy_spi_phy_driver_master + * + * @brief SPI_RAW PHY master driver. + */ + +#include +#include "nrf_drv_gpiote.h" +#include "nrf_drv_spi.h" +#include "ser_phy.h" +#include "ser_config.h" +#include "app_util.h" +#include "app_util_platform.h" +#include "app_error.h" +#include "nrf_error.h" +#include "nrf_gpio.h" +#include "nrf_gpiote.h" +#include "boards.h" +#include "app_error.h" +#include "ser_phy_config_app.h" +#include "ser_phy_debug_app.h" + +#define notUSE_PendSV + +#ifdef USE_PendSV + +#define SW_IRQn PendSV_IRQn +#define SW_IRQ_Handler() PendSV_Handler() +#define SET_Pend_SW_IRQ() SCB->ICSR = SCB->ICSR | SCB_ICSR_PENDSVSET_Msk //NVIC_SetPendingIRQ(PendSV_IRQn) - PendSV_IRQn is a negative - does not work with CMSIS + +#else + +#define SW_IRQn SWI3_IRQn +#define SW_IRQ_Handler() SWI3_IRQHandler() +#define SET_Pend_SW_IRQ() NVIC_SetPendingIRQ(SWI3_IRQn) +#endif /* USE_PendSV */ + +typedef enum +{ + SER_PHY_STATE_IDLE = 0, + SER_PHY_STATE_TX_HEADER, + SER_PHY_STATE_TX_WAIT_FOR_RDY, + SER_PHY_STATE_TX_PAYLOAD, + SER_PHY_STATE_RX_WAIT_FOR_RDY, + SER_PHY_STATE_TX_ZERO_HEADER, + SER_PHY_STATE_RX_HEADER, + SER_PHY_STATE_MEMORY_REQUEST, + SER_PHY_STATE_RX_PAYLOAD, + SER_PHY_STATE_DISABLED +} ser_phy_spi_master_state_t; + +typedef enum +{ + SER_PHY_EVT_GPIO_RDY = 0, + SER_PHY_EVT_GPIO_REQ, + SER_PHY_EVT_SPI_TRANSFER_DONE, + SER_PHY_EVT_TX_API_CALL, + SER_PHY_EVT_RX_API_CALL +} ser_phy_event_source_t; + +#define _static static + +_static uint8_t * mp_tx_buffer = NULL; +_static uint16_t m_tx_buf_len = 0; + +_static uint8_t * mp_rx_buffer = NULL; +_static uint16_t m_rx_buf_len = 0; +_static uint8_t m_frame_buffer[SER_PHY_SPI_MTU_SIZE]; +_static uint8_t m_header_buffer[SER_PHY_HEADER_SIZE] = { 0 }; + +_static uint16_t m_tx_packet_length = 0; +_static uint16_t m_accumulated_tx_packet_length = 0; +_static uint16_t m_current_tx_packet_length = 0; + +_static uint16_t m_rx_packet_length = 0; +_static uint16_t m_accumulated_rx_packet_length = 0; +_static uint16_t m_current_rx_packet_length = 0; + +_static volatile bool m_pend_req_flag = 0; +_static volatile bool m_pend_rdy_flag = 0; +_static volatile bool m_pend_xfer_flag = 0; +_static volatile bool m_pend_rx_api_flag = 0; +_static volatile bool m_pend_tx_api_flag = 0; + +_static volatile bool m_slave_ready_flag = false; +_static volatile bool m_slave_request_flag = false; + +_static ser_phy_events_handler_t m_callback_events_handler = NULL; +_static ser_phy_spi_master_state_t m_spi_master_state = SER_PHY_STATE_DISABLED; + +_static const nrf_drv_spi_t m_spi_master = SER_PHY_SPI_MASTER_INSTANCE; + +static void ser_phy_switch_state(ser_phy_event_source_t evt_src); + +static void spi_master_raw_assert(bool cond) +{ + APP_ERROR_CHECK_BOOL(cond); +} + +void SW_IRQ_Handler() +{ + if (m_pend_req_flag) + { + m_pend_req_flag = false; + DEBUG_EVT_SPI_MASTER_RAW_REQUEST(0); + ser_phy_switch_state(SER_PHY_EVT_GPIO_REQ); + } + + if (m_pend_rdy_flag) + { + m_pend_rdy_flag = false; + DEBUG_EVT_SPI_MASTER_RAW_READY(0); + ser_phy_switch_state(SER_PHY_EVT_GPIO_RDY); + } + + if (m_pend_xfer_flag) + { + m_pend_xfer_flag = false; + DEBUG_EVT_SPI_MASTER_RAW_XFER_DONE(0); + ser_phy_switch_state(SER_PHY_EVT_SPI_TRANSFER_DONE); + } + + if (m_pend_rx_api_flag) + { + m_pend_rx_api_flag = false; + DEBUG_EVT_SPI_MASTER_RAW_API_CALL(0); + ser_phy_switch_state(SER_PHY_EVT_RX_API_CALL); + } + + if (m_pend_tx_api_flag) + { + m_pend_tx_api_flag = false; + DEBUG_EVT_SPI_MASTER_RAW_API_CALL(0); + ser_phy_switch_state(SER_PHY_EVT_TX_API_CALL); + } +} + +static void ser_phy_spi_master_ready(nrf_drv_gpiote_pin_t pin, + nrf_gpiote_polarity_t action) +{ + if (nrf_gpio_pin_read(pin) == 0) + { + m_slave_ready_flag = true; + m_pend_rdy_flag = true; + } + else + { + m_slave_ready_flag = false; + } + + DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE((uint32_t) !m_slave_ready_flag); + SET_Pend_SW_IRQ(); +} + +static void ser_phy_spi_master_request(nrf_drv_gpiote_pin_t pin, + nrf_gpiote_polarity_t action) +{ + if (nrf_gpio_pin_read(pin) == 0) + { + m_slave_request_flag = true; + m_pend_req_flag = true; + } + else + { + m_slave_request_flag = false; + } + + DEBUG_EVT_SPI_MASTER_RAW_REQUEST_EDGE((uint32_t) !m_slave_request_flag); + SET_Pend_SW_IRQ(); +} + +/* Send event SER_PHY_EVT_TX_PKT_SENT */ +static __INLINE void callback_packet_sent() +{ + ser_phy_evt_t event; + + DEBUG_EVT_SPI_MASTER_PHY_TX_PKT_SENT(0); + + event.evt_type = SER_PHY_EVT_TX_PKT_SENT; + m_callback_events_handler(event); +} + +/* Send event SER_PHY_EVT_RX_PKT_DROPPED */ +static __INLINE void callback_packet_dropped() +{ + ser_phy_evt_t event; + + DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_DROPPED(0); + + event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED; + m_callback_events_handler(event); +} + +/* Send event SER_PHY_EVT_RX_PKT_RECEIVED */ +static __INLINE void callback_packet_received() +{ + ser_phy_evt_t event; + + DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_RECEIVED(0); + + event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; + event.evt_params.rx_pkt_received.p_buffer = mp_rx_buffer; + event.evt_params.rx_pkt_received.num_of_bytes = m_rx_buf_len; + m_callback_events_handler(event); +} + +/* Send event SER_PHY_EVT_RX_BUF_REQUEST */ +static __INLINE void callback_mem_request() +{ + ser_phy_evt_t event; + + DEBUG_EVT_SPI_MASTER_PHY_BUF_REQUEST(0); + + event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; + event.evt_params.rx_buf_request.num_of_bytes = m_rx_buf_len; + m_callback_events_handler(event); +} + +/* Release buffer */ +static __INLINE void buffer_release(uint8_t * * const pp_buffer, + uint16_t * const p_buf_len) +{ + *pp_buffer = NULL; + *p_buf_len = 0; +} + +/* Function computes current packet length */ +static uint16_t compute_current_packet_length(const uint16_t packet_length, + const uint16_t accumulated_packet_length) +{ + uint16_t current_packet_length = packet_length - accumulated_packet_length; + + if (current_packet_length > SER_PHY_SPI_MTU_SIZE) + { + current_packet_length = SER_PHY_SPI_MTU_SIZE; + } + + return current_packet_length; +} + +static __INLINE uint32_t header_send(const uint16_t length) +{ + uint8_t buf_len_size = uint16_encode(length, m_header_buffer); + + return nrf_drv_spi_transfer(&m_spi_master, m_header_buffer, buf_len_size, NULL, 0); +} + + +static __INLINE uint32_t frame_send() +{ + uint32_t err_code; + + m_current_tx_packet_length = compute_current_packet_length(m_tx_packet_length, + m_accumulated_tx_packet_length); + err_code = + nrf_drv_spi_transfer(&m_spi_master, + &mp_tx_buffer[m_accumulated_tx_packet_length], + m_current_tx_packet_length, + NULL, + 0); + m_accumulated_tx_packet_length += m_current_tx_packet_length; + return err_code; +} + +static __INLINE uint32_t header_get() +{ + return nrf_drv_spi_transfer(&m_spi_master, NULL, 0, m_header_buffer, SER_PHY_HEADER_SIZE); +} + +static __INLINE uint32_t frame_get() +{ + uint32_t err_code; + + m_current_rx_packet_length = compute_current_packet_length(m_rx_packet_length, + m_accumulated_rx_packet_length); + + if (mp_rx_buffer) + { + err_code = nrf_drv_spi_transfer(&m_spi_master, + NULL, + 0, + &(mp_rx_buffer[m_accumulated_rx_packet_length]), + m_current_rx_packet_length); + } + else + { + err_code = nrf_drv_spi_transfer(&m_spi_master, + NULL, + 0, + m_frame_buffer, + m_current_rx_packet_length); + } + return err_code; +} + + +/** + * \brief Master driver main state machine + * Executed only in the context of PendSV_Handler() + * For UML graph, please refer to SDK documentation +*/ +static void ser_phy_switch_state(ser_phy_event_source_t evt_src) +{ + uint32_t err_code = NRF_SUCCESS; + static bool m_wait_for_ready_flag = false; //local scheduling flag to defer RDY events + + switch (m_spi_master_state) + { + + case SER_PHY_STATE_IDLE: + + if (evt_src == SER_PHY_EVT_GPIO_REQ) + { + m_wait_for_ready_flag = false; + + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER; + err_code = header_send(0); + } + else + { + m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY; + } + } + else if (evt_src == SER_PHY_EVT_TX_API_CALL) + { + spi_master_raw_assert(mp_tx_buffer != NULL); //api event with tx_buffer == NULL has no sense + m_wait_for_ready_flag = false; + + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_TX_HEADER; + err_code = header_send(m_tx_buf_len); + } + else + { + m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY; + } + } + break; + + case SER_PHY_STATE_TX_WAIT_FOR_RDY: + + if (evt_src == SER_PHY_EVT_GPIO_RDY) + { + m_spi_master_state = SER_PHY_STATE_TX_HEADER; + err_code = header_send(m_tx_buf_len); + } + break; + + case SER_PHY_STATE_RX_WAIT_FOR_RDY: + + if (evt_src == SER_PHY_EVT_GPIO_RDY) + { + m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER; + err_code = header_send(0); + + } + break; + + case SER_PHY_STATE_TX_HEADER: + + if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) + { + m_tx_packet_length = m_tx_buf_len; + m_accumulated_tx_packet_length = 0; + + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD; + err_code = frame_send(); + + } + else + { + m_wait_for_ready_flag = true; + } + } + else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_wait_for_ready_flag) + { + m_wait_for_ready_flag = false; + m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD; + err_code = frame_send(); + } + + break; + + case SER_PHY_STATE_TX_PAYLOAD: + + if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) + { + if (m_accumulated_tx_packet_length < m_tx_packet_length) + { + if (m_slave_ready_flag) + { + err_code = frame_send(); + } + else + { + m_wait_for_ready_flag = true; + } + } + else + { + spi_master_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length); + buffer_release(&mp_tx_buffer, &m_tx_buf_len); + callback_packet_sent(); + if ( m_slave_request_flag) + { + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER; + err_code = header_send(0); + } + else + { + m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY; + } + } + else + { + m_spi_master_state = SER_PHY_STATE_IDLE; //m_Tx_buffer is NULL - have to wait for API event + } + } + } + else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_wait_for_ready_flag ) + { + m_wait_for_ready_flag = false; + err_code = frame_send(); + } + + break; + + case SER_PHY_STATE_TX_ZERO_HEADER: + + if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) + { + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_RX_HEADER; + err_code = header_get(); + } + else + { + m_wait_for_ready_flag = true; + } + } + else if ( (evt_src == SER_PHY_EVT_GPIO_RDY) && m_wait_for_ready_flag) + { + m_wait_for_ready_flag = false; + m_spi_master_state = SER_PHY_STATE_RX_HEADER; + err_code = header_get(); + } + break; + + case SER_PHY_STATE_RX_HEADER: + + if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) + { + m_spi_master_state = SER_PHY_STATE_MEMORY_REQUEST; + m_rx_buf_len = uint16_decode(m_header_buffer); + m_rx_packet_length = m_rx_buf_len; + callback_mem_request(); + + } + break; + + case SER_PHY_STATE_MEMORY_REQUEST: + + if (evt_src == SER_PHY_EVT_RX_API_CALL) + { + m_accumulated_rx_packet_length = 0; + + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD; + err_code = frame_get(); + } + else + { + m_wait_for_ready_flag = true; + } + } + else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_wait_for_ready_flag) + { + m_wait_for_ready_flag = false; + m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD; + err_code = frame_get(); + } + break; + + case SER_PHY_STATE_RX_PAYLOAD: + + if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE) + { + m_accumulated_rx_packet_length += m_current_rx_packet_length; + + if (m_accumulated_rx_packet_length < m_rx_packet_length) + { + if (m_slave_ready_flag) + { + err_code = frame_get(); + } + else + { + m_wait_for_ready_flag = true; + } + } + else + { + spi_master_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length); + + if (mp_rx_buffer == NULL) + { + callback_packet_dropped(); + } + else + { + callback_packet_received(); + } + buffer_release(&mp_rx_buffer, &m_rx_buf_len); + if (mp_tx_buffer != NULL) //mp_tx_buffer !=NULL, this means that API_EVT was scheduled + { + if (m_slave_ready_flag ) + { + err_code = header_send(m_tx_buf_len); + m_spi_master_state = SER_PHY_STATE_TX_HEADER; + } + else + { + m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY; + } + } + else if (m_slave_request_flag) + { + if (m_slave_ready_flag) + { + m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER; + err_code = header_send(0); + } + else + { + m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY; + } + } + else + { + m_spi_master_state = SER_PHY_STATE_IDLE; + + } + } + + } + else if ( evt_src == SER_PHY_EVT_GPIO_RDY && m_wait_for_ready_flag) + { + m_wait_for_ready_flag = false; + err_code = frame_get(); + } + break; + + default: + break; + } + + if (err_code != NRF_SUCCESS) + { + (void)err_code; + } +} + +static void ser_phy_spi_master_event_handler(nrf_drv_spi_evt_t const * p_event, + void * p_context) +{ + switch (p_event->type) + { + case NRF_DRV_SPI_EVENT_DONE: + + /* Switch state */ + m_pend_xfer_flag = true; + SET_Pend_SW_IRQ(); + + break; + + default: + break; + } +} + +static void ser_phy_init_PendSV(void) +{ + NVIC_SetPriority(SW_IRQn, APP_IRQ_PRIORITY_MID); + NVIC_EnableIRQ(SW_IRQn); +} + +static ret_code_t ser_phy_init_gpiote(void) +{ + if (!nrf_drv_gpiote_is_init()) + { + (void)nrf_drv_gpiote_init(); + } + NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH); + + nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true); + /* Enable pullup to ensure high state while connectivity device is reset */ + config.pull = NRF_GPIO_PIN_PULLUP; + ret_code_t err_code = nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST, + &config, ser_phy_spi_master_request); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST,true); + + err_code = nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_READY, + &config, ser_phy_spi_master_ready); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_READY,true); + + m_slave_request_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST)); + m_slave_ready_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_READY)); + + NVIC_ClearPendingIRQ(SW_IRQn); + + return NRF_SUCCESS; +} + +static void ser_phy_deinit_gpiote(void) +{ + nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST); + nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_READY); +} + +/* ser_phy API function */ +uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) +{ + if (p_buffer == NULL) + { + return NRF_ERROR_NULL; + } + + if (num_of_bytes == 0) + { + return NRF_ERROR_INVALID_PARAM; + } + + if (mp_tx_buffer != NULL) + { + return NRF_ERROR_BUSY; + } + + //ser_phy_interrupts_disable(); + CRITICAL_REGION_ENTER(); + mp_tx_buffer = (uint8_t *)p_buffer; + m_tx_buf_len = num_of_bytes; + m_pend_tx_api_flag = true; + SET_Pend_SW_IRQ(); + //ser_phy_interrupts_enable(); + CRITICAL_REGION_EXIT(); + + return NRF_SUCCESS; +} +/* ser_phy API function */ +uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) +{ + if (m_spi_master_state != SER_PHY_STATE_MEMORY_REQUEST) + { + return NRF_ERROR_INVALID_STATE; + } + + //ser_phy_interrupts_disable(); + CRITICAL_REGION_ENTER(); + mp_rx_buffer = p_buffer; + m_pend_rx_api_flag = true; + SET_Pend_SW_IRQ(); + //ser_phy_interrupts_enable(); + CRITICAL_REGION_EXIT(); + + return NRF_SUCCESS; +} + +/* ser_phy API function */ +uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) +{ + if (m_spi_master_state != SER_PHY_STATE_DISABLED) + { + return NRF_ERROR_INVALID_STATE; + } + + if (events_handler == NULL) + { + return NRF_ERROR_NULL; + } + + uint32_t err_code = NRF_SUCCESS; + + m_spi_master_state = SER_PHY_STATE_IDLE; + m_callback_events_handler = events_handler; + nrf_drv_spi_config_t spi_master_config = { + .sck_pin = SER_PHY_SPI_MASTER_PIN_SCK, + .mosi_pin = SER_PHY_SPI_MASTER_PIN_MOSI, + .miso_pin = SER_PHY_SPI_MASTER_PIN_MISO, + .ss_pin = SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT, + .irq_priority = APP_IRQ_PRIORITY_MID, + .orc = 0, + .frequency = SER_PHY_SPI_FREQUENCY, + .mode = NRF_DRV_SPI_MODE_0, + .bit_order = NRF_DRV_SPI_BIT_ORDER_LSB_FIRST, + }; + err_code = nrf_drv_spi_init(&m_spi_master, + &spi_master_config, + ser_phy_spi_master_event_handler, + NULL); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = ser_phy_init_gpiote(); + ser_phy_init_PendSV(); + return err_code; +} + +/* ser_phy API function */ +void ser_phy_close(void) +{ + m_spi_master_state = SER_PHY_STATE_DISABLED; + + m_callback_events_handler = NULL; + + buffer_release(&mp_tx_buffer, &m_tx_buf_len); + buffer_release(&mp_rx_buffer, &m_rx_buf_len); + + m_tx_packet_length = 0; + m_accumulated_tx_packet_length = 0; + m_current_tx_packet_length = 0; + + m_rx_packet_length = 0; + m_accumulated_rx_packet_length = 0; + m_current_rx_packet_length = 0; + + ser_phy_deinit_gpiote(); + nrf_drv_spi_uninit(&m_spi_master); +} + +/* ser_phy API function */ +/* only PendSV may interact with ser_phy layer, other interrupts are internal */ +void ser_phy_interrupts_enable(void) +{ + NVIC_EnableIRQ(SW_IRQn); +} + +/* ser_phy API function */ +void ser_phy_interrupts_disable(void) +{ + NVIC_DisableIRQ(SW_IRQn); +} + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_spi_slave.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_spi_slave.c new file mode 100644 index 0000000000000000000000000000000000000000..989b9d5ecfa33b6951ca138f1c9703c42eec8a9d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_spi_slave.c @@ -0,0 +1,607 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ser_phy_spi_phy_driver_slave ser_phy_nrf51_spi_slave.c + * @{ + * @ingroup ser_phy_spi_phy_driver_slave + * + * @brief SPI_RAW PHY slave driver. + */ + +#include +#include + +#include "app_error.h" +#include "app_util.h" +#include "boards.h" +#include "nrf_gpio.h" +#include "nrf_drv_gpiote.h" +#include "nrf_soc.h" +#include "nrf_drv_spis.h" +#include "ser_config.h" +#include "ser_phy.h" +#include "ser_phy_config_conn.h" +#include "ser_phy_debug_conn.h" + +#define SER_PHY_SPI_DEF_CHARACTER 0xFF //SPI default character. Character clocked out in case of an ignored transaction +#define SER_PHY_SPI_ORC_CHARACTER 0xFF //SPI over-read character. Character clocked out after an over-read of the transmit buffer + +static nrf_drv_spis_t m_spis = NRF_DRV_SPIS_INSTANCE(SER_PHY_SPI_SLAVE_INSTANCE); + +//SPI raw peripheral device configuration data +typedef struct +{ + int32_t pin_req; //SPI /REQ pin. -1 for not using + int32_t pin_rdy; //SPI /RDY pin. -1 for not using + int32_t ppi_rdy_ch; //SPI /RDY ppi ready channel + int32_t gpiote_rdy_ch; //SPI /RDY pin ready channel +} spi_slave_raw_trasp_cfg_t; + +/**@brief States of the SPI transaction state machine. */ +typedef enum +{ + SPI_RAW_STATE_UNKNOWN, + SPI_RAW_STATE_SETUP_HEADER, + SPI_RAW_STATE_RX_HEADER, + SPI_RAW_STATE_MEM_REQUESTED, + SPI_RAW_STATE_RX_PAYLOAD, + SPI_RAW_STATE_TX_HEADER, + SPI_RAW_STATE_TX_PAYLOAD, +} trans_state_t; + +#define _static static + +static spi_slave_raw_trasp_cfg_t m_spi_slave_raw_config; + +_static uint16_t m_accumulated_rx_packet_length; +_static uint16_t m_rx_packet_length; +_static uint16_t m_current_rx_frame_length; + +_static uint16_t m_accumulated_tx_packet_length; +_static uint16_t m_tx_packet_length; +_static uint16_t m_current_tx_frame_length; + +_static uint8_t m_header_rx_buffer[SER_PHY_HEADER_SIZE]; +_static uint8_t m_header_tx_buffer[SER_PHY_HEADER_SIZE]; + +_static uint8_t m_frame_buffer[SER_PHY_SPI_MTU_SIZE]; //trash storage +_static uint8_t m_zero_buffer[SER_PHY_SPI_MTU_SIZE] = { 0 }; //ROM'able declaration + +_static uint8_t * volatile m_p_rx_buffer = NULL; +_static const uint8_t * volatile m_p_tx_buffer = NULL; + +_static bool m_trash_payload_flag; +_static bool m_buffer_reqested_flag; + +_static trans_state_t m_trans_state = SPI_RAW_STATE_UNKNOWN; +_static ser_phy_events_handler_t m_ser_phy_callback = NULL; + +static void spi_slave_raw_assert(bool cond) +{ + APP_ERROR_CHECK_BOOL(cond); +} + +static void callback_ser_phy_event(ser_phy_evt_t event) +{ + if (m_ser_phy_callback) + { + m_ser_phy_callback(event); + } +} + +static void callback_memory_request(uint16_t size) +{ + ser_phy_evt_t event; + + DEBUG_EVT_SPI_SLAVE_PHY_BUF_REQUEST(0); + + event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; + event.evt_params.rx_buf_request.num_of_bytes = size; + callback_ser_phy_event(event); +} + +static void callback_packet_received(uint8_t * pBuffer, uint16_t size) +{ + ser_phy_evt_t event; + + DEBUG_EVT_SPI_SLAVE_PHY_PKT_RECEIVED(0); + + event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; + event.evt_params.rx_pkt_received.num_of_bytes = size; + event.evt_params.rx_pkt_received.p_buffer = pBuffer; + callback_ser_phy_event(event); +} + +static void callback_packet_dropped() +{ + ser_phy_evt_t event; + + DEBUG_EVT_SPI_SLAVE_PHY_PKT_DROPPED(0); + + event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED; + callback_ser_phy_event(event); +} + +static void callback_packet_transmitted(void) +{ + ser_phy_evt_t event; + + DEBUG_EVT_SPI_SLAVE_PHY_PKT_SENT(0); + + event.evt_type = SER_PHY_EVT_TX_PKT_SENT; + callback_ser_phy_event(event); +} + +/* Function computes current packet length */ +static uint16_t compute_current_frame_length(const uint16_t packet_length, + const uint16_t accumulated_packet_length) +{ + uint16_t current_packet_length = packet_length - accumulated_packet_length; + + if (current_packet_length > SER_PHY_SPI_MTU_SIZE) + { + current_packet_length = SER_PHY_SPI_MTU_SIZE; + } + + return current_packet_length; +} + +static uint32_t header_get() +{ + uint32_t err_code; + + err_code = nrf_drv_spis_buffers_set(&m_spis, + (uint8_t *) m_zero_buffer, + SER_PHY_HEADER_SIZE, + m_header_rx_buffer, + SER_PHY_HEADER_SIZE); + return err_code; +} + +static uint32_t frame_get() +{ + uint32_t err_code; + + m_current_rx_frame_length = compute_current_frame_length(m_rx_packet_length, + m_accumulated_rx_packet_length); + + if (!m_trash_payload_flag) + { + err_code = + nrf_drv_spis_buffers_set(&m_spis, + (uint8_t *) m_zero_buffer, + m_current_rx_frame_length, + &(m_p_rx_buffer[m_accumulated_rx_packet_length]), + m_current_rx_frame_length); + } + else + { + err_code = nrf_drv_spis_buffers_set(&m_spis, + (uint8_t *) m_zero_buffer, + m_current_rx_frame_length, + m_frame_buffer, + m_current_rx_frame_length); + } + return err_code; +} + +static uint32_t header_send(uint16_t len) +{ + uint32_t err_code; + + (void) uint16_encode(len, m_header_tx_buffer); + err_code = + nrf_drv_spis_buffers_set(&m_spis, + m_header_tx_buffer, + sizeof (m_header_tx_buffer), + m_header_rx_buffer, + sizeof (m_header_tx_buffer)); + return err_code; +} + +static uint32_t frame_send() +{ + uint32_t err_code; + + m_current_tx_frame_length = compute_current_frame_length(m_tx_packet_length, + m_accumulated_tx_packet_length); + err_code = + nrf_drv_spis_buffers_set(&m_spis, + (uint8_t *) &(m_p_tx_buffer[m_accumulated_tx_packet_length]), + m_current_tx_frame_length, + m_frame_buffer, + m_current_tx_frame_length); + return err_code; +} + +static void set_ready_line(void) +{ + //toggle - this should go high - but toggle is unsafe + uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.pin_rdy); + *(uint32_t *)rdy_task = 1; + return; +} + +static void set_request_line(void) +{ + //active low logic - set is 0 + nrf_gpio_pin_clear(m_spi_slave_raw_config.pin_req); + DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(0); +} + +static void clear_request_line(void) +{ + //active low logic - clear is 1 + nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req); + DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(0); +} + +/** + * \brief Slave driver main state machine + * For UML graph, please refer to SDK documentation +*/ +static void spi_slave_event_handle(nrf_drv_spis_event_t event) +{ + uint32_t err_code = NRF_SUCCESS; + static uint16_t packetLength; + + switch (m_trans_state) + { + case SPI_RAW_STATE_SETUP_HEADER: + m_trans_state = SPI_RAW_STATE_RX_HEADER; + err_code = header_get(); + break; + + case SPI_RAW_STATE_RX_HEADER: + + if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); + set_ready_line(); + } + + if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount); + spi_slave_raw_assert(event.rx_amount == SER_PHY_HEADER_SIZE); + packetLength = uint16_decode(m_header_rx_buffer); + + if (packetLength != 0 ) + { + m_trans_state = SPI_RAW_STATE_MEM_REQUESTED; + m_buffer_reqested_flag = true; + m_rx_packet_length = packetLength; + callback_memory_request(packetLength); + } + else + { + if (m_p_tx_buffer) + { + clear_request_line(); + m_trans_state = SPI_RAW_STATE_TX_HEADER; + err_code = header_send(m_tx_packet_length); + } + else + { + //there is nothing to send - zero response facilitates pooling - but perhaps, it should be assert + err_code = header_send(0); + } + } + } + + break; + + case SPI_RAW_STATE_MEM_REQUESTED: + + if (event.evt_type == NRF_DRV_SPIS_EVT_TYPE_MAX) //This is API dummy event + { + m_buffer_reqested_flag = false; + m_trans_state = SPI_RAW_STATE_RX_PAYLOAD; + m_accumulated_rx_packet_length = 0; + err_code = frame_get(); + } + break; + + case SPI_RAW_STATE_RX_PAYLOAD: + + if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); + set_ready_line(); + } + + if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount); + spi_slave_raw_assert(event.rx_amount == m_current_rx_frame_length); + m_accumulated_rx_packet_length += m_current_rx_frame_length; + + if (m_accumulated_rx_packet_length < m_rx_packet_length ) + { + err_code = frame_get(); + } + else + { + spi_slave_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length); + m_trans_state = SPI_RAW_STATE_RX_HEADER; + err_code = header_get(); + + if (!m_trash_payload_flag) + { + callback_packet_received(m_p_rx_buffer, m_accumulated_rx_packet_length); + } + else + { + callback_packet_dropped(); + } + } + } + break; + + case SPI_RAW_STATE_TX_HEADER: + + if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); + set_ready_line(); + } + + if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount); + spi_slave_raw_assert(event.tx_amount == SER_PHY_HEADER_SIZE); + m_trans_state = SPI_RAW_STATE_TX_PAYLOAD; + m_accumulated_tx_packet_length = 0; + err_code = frame_send(); + } + + break; + + case SPI_RAW_STATE_TX_PAYLOAD: + + if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0); + set_ready_line(); + } + + if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) + { + DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount); + spi_slave_raw_assert(event.tx_amount == m_current_tx_frame_length); + m_accumulated_tx_packet_length += m_current_tx_frame_length; + + if ( m_accumulated_tx_packet_length < m_tx_packet_length ) + { + err_code = frame_send(); + } + else + { + spi_slave_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length); + //clear pointer before callback + m_p_tx_buffer = NULL; + callback_packet_transmitted(); + //spi slave TX transfer is possible only when RX is ready, so return to waiting for a header + m_trans_state = SPI_RAW_STATE_RX_HEADER; + err_code = header_get(); + } + } + break; + + default: + err_code = NRF_ERROR_INVALID_STATE; + break; + } + APP_ERROR_CHECK(err_code); +} + +static void spi_slave_gpiote_init(void) +{ + if (!nrf_drv_gpiote_is_init()) + { + (void)nrf_drv_gpiote_init(); + } + nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true); + (void) nrf_drv_gpiote_out_init(m_spi_slave_raw_config.pin_rdy, &config); + (void) nrf_drv_gpiote_out_task_enable(m_spi_slave_raw_config.pin_rdy); + return; +} + +static void spi_slave_ppi_init(void) +{ + uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.pin_rdy); + //Configure PPI channel to clear /RDY line + NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].EEP = (uint32_t)(&NRF_SPIS1->EVENTS_END); + NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].TEP = rdy_task; + + //this works only for channels 0..15 - but soft device is using 8-15 anyway + NRF_PPI->CHEN |= (1 << m_spi_slave_raw_config.ppi_rdy_ch); + return; +} + +static void spi_slave_gpio_init(void) +{ + nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req); + nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_req); + nrf_gpio_pin_set(m_spi_slave_raw_config.pin_rdy); + nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_rdy); +} + +/* ser_phy API function */ +void ser_phy_interrupts_enable(void) +{ + (void)sd_nvic_EnableIRQ(m_spis.irq); +} + +/* ser_phy API function */ +void ser_phy_interrupts_disable(void) +{ + (void)sd_nvic_DisableIRQ(m_spis.irq); +} + +/* ser_phy API function */ +uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) +{ + uint32_t status = NRF_SUCCESS; + nrf_drv_spis_event_t event; + + ser_phy_interrupts_disable(); + + if (m_buffer_reqested_flag && (m_trans_state == SPI_RAW_STATE_MEM_REQUESTED)) + { + m_p_rx_buffer = p_buffer; + + if (m_p_rx_buffer) + { + m_trash_payload_flag = false; + } + else + { + m_trash_payload_flag = true; + } + event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition with dummy event + event.rx_amount = 0; + event.tx_amount = 0; + spi_slave_event_handle(event); + } + else + { + status = NRF_ERROR_BUSY; + } + ser_phy_interrupts_enable(); + + return status; +} + +/* ser_phy API function */ +uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) +{ + uint32_t status = NRF_SUCCESS; + + if ( p_buffer == NULL || num_of_bytes == 0) + { + return NRF_ERROR_NULL; + } + + ser_phy_interrupts_disable(); + + if ( m_p_tx_buffer == NULL) + { + m_tx_packet_length = num_of_bytes; + m_p_tx_buffer = p_buffer; + set_request_line(); + } + else + { + status = NRF_ERROR_BUSY; + } + ser_phy_interrupts_enable(); + + return status; +} + +/* ser_phy API function */ +uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) +{ + uint32_t err_code; + nrf_drv_spis_config_t spi_slave_config; + nrf_drv_spis_event_t event; + + if (m_trans_state != SPI_RAW_STATE_UNKNOWN) + { + return NRF_ERROR_INVALID_STATE; + } + + if (events_handler == NULL) + { + return NRF_ERROR_NULL; + } + + //one ppi channel and one gpiote channel are used to drive RDY line + m_spi_slave_raw_config.pin_req = SER_PHY_SPI_SLAVE_REQ_PIN; + m_spi_slave_raw_config.pin_rdy = SER_PHY_SPI_SLAVE_RDY_PIN; + m_spi_slave_raw_config.ppi_rdy_ch = SER_PHY_SPI_PPI_RDY_CH; + m_spi_slave_raw_config.gpiote_rdy_ch = SER_PHY_SPI_GPIOTE_RDY_CH; + + spi_slave_gpio_init(); + spi_slave_gpiote_init(); + spi_slave_ppi_init(); + + spi_slave_config.miso_pin = SER_PHY_SPI_SLAVE_MISO_PIN; + spi_slave_config.mosi_pin = SER_PHY_SPI_SLAVE_MOSI_PIN; + spi_slave_config.sck_pin = SER_PHY_SPI_SLAVE_SCK_PIN; + spi_slave_config.csn_pin = SER_PHY_SPI_SLAVE_SS_PIN; + spi_slave_config.mode = NRF_DRV_SPIS_MODE_0; + spi_slave_config.bit_order = NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST; + spi_slave_config.def = SER_PHY_SPI_DEF_CHARACTER; + spi_slave_config.orc = SER_PHY_SPI_ORC_CHARACTER; + spi_slave_config.irq_priority = APP_IRQ_PRIORITY_LOWEST; + spi_slave_config.miso_drive = NRF_DRV_SPIS_DEFAULT_MISO_DRIVE; + //use /CS pullup because state of the line might be undefined when master redefines PIO lines + spi_slave_config.csn_pullup = NRF_GPIO_PIN_PULLUP; + + //keep /CS high when init + nrf_gpio_cfg_input(spi_slave_config.csn_pin, NRF_GPIO_PIN_PULLUP); + + err_code = nrf_drv_spis_init(&m_spis, &spi_slave_config, spi_slave_event_handle); + APP_ERROR_CHECK(err_code); + + if (err_code == NRF_SUCCESS) + { + m_ser_phy_callback = events_handler; + + m_trans_state = SPI_RAW_STATE_SETUP_HEADER; + event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition for dummy event + event.rx_amount = 0; + event.tx_amount = 0; + spi_slave_event_handle(event); + + } + return err_code; +} + +/* ser_phy API function */ +void ser_phy_close(void) +{ + nrf_drv_spis_uninit(&m_spis); + m_ser_phy_callback = NULL; + m_trans_state = SPI_RAW_STATE_UNKNOWN; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_uart.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..1b47a892ea0e195b0856051ab960d4f88e77e579 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy/ser_phy_uart.c @@ -0,0 +1,352 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ser_phy.h" +#include "ser_config.h" +#ifdef SER_CONNECTIVITY + #include "ser_phy_config_conn.h" +#else + #include "ser_phy_config_app.h" +#endif +#include "nrf_drv_uart.h" +#include "app_error.h" +#include "app_util.h" +#include "app_util_platform.h" + +#define UART_TRANSFER_MAX 255 + +#define SER_UART_IRQ UART0_IRQn +static const nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0); +static const nrf_drv_uart_config_t m_uart_config = { + .pseltxd = SER_PHY_UART_TX, + .pselrxd = SER_PHY_UART_RX, + .pselrts = SER_PHY_UART_RTS, + .pselcts = SER_PHY_UART_CTS, + .p_context = NULL, + .interrupt_priority = UART_IRQ_PRIORITY, +#ifdef UARTE_PRESENT + .use_easy_dma = true, +#endif + // These values are common for application and connectivity, they are + // defined in "ser_config.h". + .hwfc = SER_PHY_UART_FLOW_CTRL, + .parity = SER_PHY_UART_PARITY, + .baudrate = (nrf_uart_baudrate_t)SER_PHY_UART_BAUDRATE +}; + +static bool volatile m_tx_in_progress; +static uint8_t m_tx_header_buf[SER_PHY_HEADER_SIZE]; +static uint16_t m_bytes_to_transmit; +static uint8_t const * mp_tx_buffer; + +static uint8_t m_rx_header_buf[SER_PHY_HEADER_SIZE]; +static uint16_t m_bytes_to_receive; +static uint8_t m_rx_drop_buf[1]; + +static ser_phy_events_handler_t m_ser_phy_event_handler; +static ser_phy_evt_t m_ser_phy_rx_event; + + +static void packet_sent_callback(void) +{ + static ser_phy_evt_t const event = { + .evt_type = SER_PHY_EVT_TX_PKT_SENT, + }; + m_ser_phy_event_handler(event); +} + +static void buffer_request_callback(uint16_t num_of_bytes) +{ + m_ser_phy_rx_event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; + m_ser_phy_rx_event.evt_params.rx_buf_request.num_of_bytes = num_of_bytes; + m_ser_phy_event_handler(m_ser_phy_rx_event); +} + +static void packet_received_callback(void) +{ + m_ser_phy_event_handler(m_ser_phy_rx_event); +} + +static void packet_dropped_callback(void) +{ + static ser_phy_evt_t const event = { + .evt_type = SER_PHY_EVT_RX_PKT_DROPPED, + }; + m_ser_phy_event_handler(event); +} + +static void hardware_error_callback(uint32_t hw_error) +{ + ser_phy_evt_t event = { + .evt_type = SER_PHY_EVT_HW_ERROR, + .evt_params.hw_error.error_code = hw_error, + }; + m_ser_phy_event_handler(event); +} + +static void packet_rx_start(void) +{ + APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_header_buf, + SER_PHY_HEADER_SIZE)); +} + +static void packet_byte_drop(void) +{ + APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_drop_buf, 1)); +} + +static void uart_event_handler(nrf_drv_uart_event_t * p_event, + void * p_context) +{ + (void)p_context; + + switch (p_event->type) + { + case NRF_DRV_UART_EVT_ERROR: + // Process the error only if this is a parity or overrun error. + // Break and framing errors will always occur before the other + // side becomes active. + if (p_event->data.error.error_mask & + (NRF_UART_ERROR_PARITY_MASK | NRF_UART_ERROR_OVERRUN_MASK)) + { + // Pass error source to upper layer. + hardware_error_callback(p_event->data.error.error_mask); + } + + packet_rx_start(); + break; + + case NRF_DRV_UART_EVT_TX_DONE: + if (p_event->data.rxtx.p_data == m_tx_header_buf) + { +#if (SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE > UART_TRANSFER_MAX) + if (m_bytes_to_transmit > UART_TRANSFER_MAX) + { + APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, mp_tx_buffer, + UART_TRANSFER_MAX)); + } + else +#endif // (SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE > UART_TRANSFER_MAX) + { + APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, mp_tx_buffer, + m_bytes_to_transmit)); + } + } + else + { +#if (SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE > UART_TRANSFER_MAX) + ASSERT(p_event->data.rxtx.bytes <= m_bytes_to_transmit); + m_bytes_to_transmit -= p_event->data.rxtx.bytes; + if (m_bytes_to_transmit != 0) + { + APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, + p_event->data.rxtx.p_data + p_event->data.rxtx.bytes, + m_bytes_to_transmit < UART_TRANSFER_MAX ? + m_bytes_to_transmit : UART_TRANSFER_MAX)); + } + else +#endif // (SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE > UART_TRANSFER_MAX) + { + m_tx_in_progress = false; + packet_sent_callback(); + } + } + break; + + case NRF_DRV_UART_EVT_RX_DONE: + if (p_event->data.rxtx.p_data == m_rx_header_buf) + { + m_bytes_to_receive = uint16_decode(m_rx_header_buf); + buffer_request_callback(m_bytes_to_receive); + } + else if (p_event->data.rxtx.p_data == m_rx_drop_buf) + { + --m_bytes_to_receive; + if (m_bytes_to_receive != 0) + { + packet_byte_drop(); + } + else + { + packet_dropped_callback(); + + packet_rx_start(); + } + } + else + { +#if (SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE > UART_TRANSFER_MAX) + ASSERT(p_event->data.rxtx.bytes <= m_bytes_to_receive); + m_bytes_to_receive -= p_event->data.rxtx.bytes; + if (m_bytes_to_receive != 0) + { + APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, + p_event->data.rxtx.p_data + p_event->data.rxtx.bytes, + m_bytes_to_receive < UART_TRANSFER_MAX ? + m_bytes_to_receive : UART_TRANSFER_MAX)); + } + else +#endif // (SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE > UART_TRANSFER_MAX) + { + packet_received_callback(); + + packet_rx_start(); + } + } + break; + + default: + APP_ERROR_CHECK(NRF_ERROR_INTERNAL); + } +} + +/** API FUNCTIONS */ + +uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) +{ + uint32_t err_code; + + if (events_handler == NULL) + { + return NRF_ERROR_NULL; + } + + // Check if function was not called before. + if (m_ser_phy_event_handler != NULL) + { + return NRF_ERROR_INVALID_STATE; + } + + err_code = nrf_drv_uart_init(&m_uart, &m_uart_config, uart_event_handler); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INVALID_PARAM; + } + + m_ser_phy_event_handler = events_handler; + + packet_rx_start(); + + return err_code; +} + +uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) +{ + if (p_buffer == NULL) + { + return NRF_ERROR_NULL; + } + else if (num_of_bytes == 0) + { + return NRF_ERROR_INVALID_PARAM; + } + + bool busy; + + CRITICAL_REGION_ENTER(); + busy = m_tx_in_progress; + m_tx_in_progress = true; + CRITICAL_REGION_EXIT(); + + if (busy) + { + return NRF_ERROR_BUSY; + } + + (void)uint16_encode(num_of_bytes, m_tx_header_buf); + mp_tx_buffer = p_buffer; + m_bytes_to_transmit = num_of_bytes; + APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, m_tx_header_buf, + SER_PHY_HEADER_SIZE)); + + return NRF_SUCCESS; +} + + +uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) +{ + + if (m_ser_phy_rx_event.evt_type != SER_PHY_EVT_RX_BUF_REQUEST) + { + return NRF_ERROR_INVALID_STATE; + } + + m_ser_phy_rx_event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; + m_ser_phy_rx_event.evt_params.rx_pkt_received.p_buffer = p_buffer; + m_ser_phy_rx_event.evt_params.rx_pkt_received.num_of_bytes = + m_bytes_to_receive; + + // If there is not enough memory to receive the packet (no buffer was + // provided), drop its data byte by byte (using an internal 1-byte buffer). + if (p_buffer == NULL) + { + packet_byte_drop(); + } +#if (SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE > UART_TRANSFER_MAX) + else if (m_bytes_to_receive > UART_TRANSFER_MAX) + { + APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, p_buffer, UART_TRANSFER_MAX)); + } +#endif // (SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE > UART_TRANSFER_MAX) + else + { + APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, p_buffer, m_bytes_to_receive)); + } + + return NRF_SUCCESS; +} + + +void ser_phy_close(void) +{ + nrf_drv_uart_uninit(&m_uart); + m_ser_phy_event_handler = NULL; +} + + +void ser_phy_interrupts_enable(void) +{ + NVIC_EnableIRQ(SER_UART_IRQ); +} + + +void ser_phy_interrupts_disable(void) +{ + NVIC_DisableIRQ(SER_UART_IRQ); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy_debug_comm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy_debug_comm.h new file mode 100644 index 0000000000000000000000000000000000000000..c2bacd7b4b5f26b3b714046a06f5574b8d367ac2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/common/transport/ser_phy_debug_comm.h @@ -0,0 +1,203 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SER_PHY_DEBUG_COMM_H__ +#define SER_PHY_DEBUG_COMM_H__ + +#ifndef SER_PHY_HCI_DEBUG_ENABLE + +// empty definitions here +#define DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(data) +#define DEBUG_EVT_HCI_PHY_EVT_BUF_REQUEST(data) +#define DEBUG_EVT_HCI_PHY_EVT_RX_PKT_RECEIVED(data) +#define DEBUG_EVT_HCI_PHY_EVT_RX_PKT_DROPPED(data) +#define DEBUG_EVT_HCI_PHY_EVT_TX_ERROR(data) +#define DEBUG_EVT_SLIP_PACKET_TX(data) +#define DEBUG_EVT_SLIP_ACK_TX(data) +#define DEBUG_EVT_SLIP_PACKET_TXED(data) +#define DEBUG_EVT_SLIP_ACK_TXED(data) +#define DEBUG_EVT_SLIP_PACKET_RXED(data) +#define DEBUG_EVT_SLIP_ACK_RXED(data) +#define DEBUG_EVT_SLIP_ERR_RXED(data) +#define DEBUG_EVT_TIMEOUT(data) +#define DEBUG_HCI_RETX(data) +#define DEBUG_EVT_MAIN_BUSY(data) +#define DEBUG_EVT_TX_REQ(data) + +#else +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//Low level hardware events +typedef enum +{ + HCI_PHY_EVT_TX_PKT_SENT, + HCI_PHY_EVT_BUF_REQUEST, + HCI_PHY_EVT_RX_PKT_RECEIVED, + HCI_PHY_EVT_RX_PKT_DROPPED, + HCI_PHY_EVT_TX_ERROR, + HCI_SLIP_EVT_PACKET_TX, + HCI_SLIP_EVT_ACK_TX, + HCI_SLIP_EVT_PACKET_TXED, + HCI_SLIP_EVT_ACK_TXED, + HCI_SLIP_EVT_PACKET_RXED, + HCI_SLIP_EVT_ACK_RXED, + HCI_SLIP_EVT_ERR_RXED, + HCI_TIMER_EVT_TIMEOUT, + HCI_RETX, + HCI_MAIN_BUSY, + HCI_TX_REQ, + HCI_PHY_EVT_MAX +} hci_dbg_evt_type_t; + + +//Low level hardware event definition +typedef struct +{ + hci_dbg_evt_type_t evt; + uint32_t data; +} hci_dbg_evt_t; + +typedef void (*hci_dbg_event_handler_t)(hci_dbg_evt_t event); + +void debug_init(hci_dbg_event_handler_t evt_callback); + +void debug_evt(hci_dbg_evt_type_t evt, uint32_t data); + + +#define DEBUG_EVT(event_type, data) \ +do { \ + debug_evt(event_type, data); \ +} while (0); + + +#define DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(data) \ +do { \ + DEBUG_EVT(HCI_PHY_EVT_TX_PKT_SENT, data); \ +} while (0); + + +#define DEBUG_EVT_HCI_PHY_EVT_BUF_REQUEST(data) \ +do { \ + DEBUG_EVT(HCI_PHY_EVT_BUF_REQUEST, data); \ +} while (0); + + +#define DEBUG_EVT_HCI_PHY_EVT_RX_PKT_RECEIVED(data) \ +do { \ + DEBUG_EVT(HCI_PHY_EVT_RX_PKT_RECEIVED, data); \ +} while (0); + + +#define DEBUG_EVT_HCI_PHY_EVT_RX_PKT_DROPPED(data) \ +do { \ + DEBUG_EVT(HCI_PHY_EVT_RX_PKT_DROPPED, data); \ +} while (0); + +#define DEBUG_EVT_HCI_PHY_EVT_TX_ERROR(data) \ +do { \ + DEBUG_EVT(HCI_PHY_EVT_TX_ERROR, data); \ +} while (0); + +#define DEBUG_EVT_SLIP_PACKET_TX(data) \ +do { \ + DEBUG_EVT(HCI_SLIP_EVT_PACKET_TX, data); \ +} while (0); + +#define DEBUG_EVT_SLIP_ACK_TX(data) \ +do { \ + DEBUG_EVT(HCI_SLIP_EVT_ACK_TX, data); \ +} while (0); + +#define DEBUG_EVT_SLIP_PACKET_TXED(data) \ +do { \ + DEBUG_EVT(HCI_SLIP_EVT_PACKET_TXED, data); \ +} while (0); + +#define DEBUG_EVT_SLIP_ACK_TXED(data) \ +do { \ + DEBUG_EVT(HCI_SLIP_EVT_ACK_TXED, data); \ +} while (0); + +#define DEBUG_EVT_SLIP_PACKET_RXED(data) \ +do { \ + DEBUG_EVT(HCI_SLIP_EVT_PACKET_RXED, data); \ +} while (0); + +#define DEBUG_EVT_SLIP_ACK_RXED(data) \ +do { \ + DEBUG_EVT(HCI_SLIP_EVT_ACK_RXED, data); \ +} while (0); + +#define DEBUG_EVT_SLIP_ERR_RXED(data) \ +do { \ + DEBUG_EVT(HCI_SLIP_EVT_ERR_RXED, data); \ +} while (0); + +#define DEBUG_EVT_TIMEOUT(data) \ +do { \ + DEBUG_EVT(HCI_TIMER_EVT_TIMEOUT, data); \ +} while (0); + +#define DEBUG_HCI_RETX(data) \ +do { \ + DEBUG_EVT(HCI_RETX, data); \ +} while (0); + +#define DEBUG_EVT_MAIN_BUSY(data) \ +do { \ + DEBUG_EVT(HCI_MAIN_BUSY, data); \ +} while (0); + +#define DEBUG_EVT_TX_REQ(data) \ +do { \ + DEBUG_EVT(HCI_TX_REQ, data); \ +} while (0); + +#endif // SER_PHY_HCI_DEBUG_ENABLE + + +#ifdef __cplusplus +} +#endif + +#endif // SER_PHY_DEBUG_COMM_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.c new file mode 100644 index 0000000000000000000000000000000000000000..f8669643800a3c75bfdcf9750e71e42a04fb1e17 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.c @@ -0,0 +1,1196 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "ant_conn.h" +#include "conn_mw_ant.h" +#include "ble_serialization.h" +#include "nrf_log_ctrl.h" +#include "sdk_config.h" + +#define ANT_BUFFER_SIZE_FOR_SD ANT_ENABLE_GET_REQUIRED_SPACE(ANT_SER_CONFIG_TOTAL_CHANNELS_ALLOCATED, \ + ANT_SER_CONFIG_ENCRYPTED_CHANNELS, \ + ANT_SER_CONFIG_BURST_QUEUE_SIZE, \ + ANT_SER_CONFIG_EVENT_QUEUE_SIZE) +#define ANT_ADV_BURST_CFG_SIZE_MAX (11u) +#define ANT_CRYPTO_INFO_SIZE (((MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE) - \ + (MESG_CHANNEL_NUM_SIZE)) + \ + ((MESG_CONFIG_ENCRYPT_REQ_CONFIG_ID_SIZE) - \ + (MESG_CHANNEL_NUM_SIZE))) +#define ANT_CRYPTO_INFO_MAX_SIZE (MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE - \ + MESG_CHANNEL_NUM_SIZE) + +#ifdef ANT_STACK_SUPPORT_REQD +static union +{ + uint8_t u8[ANT_BUFFER_SIZE_FOR_SD]; + uint32_t u32[1]; // force allign to uint32_t +}ant_stack_buffer; /*!< Memory buffer provided in order to support channel configuration */ +#endif + +uint32_t conn_mw_ant_enable(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + + ANT_ENABLE params; + ANT_ENABLE * p_params = ¶ms; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_enable_req_dec(p_rx_buf, rx_buf_len, &p_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT(p_params -> ucTotalNumberOfChannels == ANT_SER_CONFIG_TOTAL_CHANNELS_ALLOCATED, err_code); + SER_ASSERT(p_params -> ucNumberOfEncryptedChannels == ANT_SER_CONFIG_ENCRYPTED_CHANNELS, err_code); + SER_ASSERT(p_params -> usNumberOfEvents == ANT_SER_CONFIG_EVENT_QUEUE_SIZE, err_code); + SER_ASSERT(p_params -> usMemoryBlockByteSize == ANT_BUFFER_SIZE_FOR_SD, err_code); + + ANT_ENABLE m_ant_enable_cfg = + { + .ucTotalNumberOfChannels = p_params -> ucTotalNumberOfChannels, + .ucNumberOfEncryptedChannels = p_params -> ucNumberOfEncryptedChannels, + .usNumberOfEvents = p_params -> usNumberOfEvents, + .pucMemoryBlockStartLocation = ant_stack_buffer.u8, + .usMemoryBlockByteSize = p_params -> usMemoryBlockByteSize + }; + + sd_err_code = sd_ant_enable(&m_ant_enable_cfg); + + err_code = ant_enable_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_channel_assign(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t type; + uint8_t network; + uint8_t ext_assign; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code =ant_channel_assign_req_dec(p_rx_buf, rx_buf_len, &channel, &type, &network, &ext_assign); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + //disabled till codec is adopted. + sd_err_code = sd_ant_channel_assign(channel, type, network, ext_assign); + + + err_code = ant_channel_assign_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; + +} + +uint32_t conn_ant_channel_open_with_offset(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint16_t usOffset; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_channel_open_with_offset_req_dec(p_rx_buf, rx_buf_len, &channel, &usOffset); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_channel_open_with_offset(channel, usOffset); + + err_code = ant_channel_open_with_offset_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + + +uint32_t conn_ant_channel_id_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint16_t device_number; + uint8_t device_type; + uint8_t transmission_type; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code =ant_channel_id_set_req_dec(p_rx_buf, rx_buf_len, &channel, &device_number, &device_type, &transmission_type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + //disabled till codec is adopted. + sd_err_code = sd_ant_channel_id_set(channel, device_number, device_type, transmission_type); + + err_code = ant_channel_id_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_channel_period_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint16_t period; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_channel_period_set_req_dec(p_rx_buf, rx_buf_len, &channel, &period); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_channel_period_set(channel, period); + + err_code = ant_channel_period_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_channel_radio_freq_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t freq; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_channel_radio_freq_set_req_dec(p_rx_buf, rx_buf_len, &channel, &freq); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_channel_radio_freq_set(channel, freq); + + err_code = ant_channel_radio_freq_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_broadcast_message_tx(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t size; + uint8_t mesg[ANT_STANDARD_DATA_PAYLOAD_SIZE]; + uint8_t * p_mesg = mesg; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_broadcast_message_tx_req_dec(p_rx_buf, rx_buf_len, &channel, &size, &p_mesg); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_broadcast_message_tx(channel, size, p_mesg); + + err_code = ant_broadcast_message_tx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_acknowledge_message_tx(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t size; + uint8_t mesg[ANT_STANDARD_DATA_PAYLOAD_SIZE]; + uint8_t * p_mesg = mesg; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_acknowledge_message_tx_req_dec(p_rx_buf, rx_buf_len, &channel, &size, &p_mesg); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_acknowledge_message_tx(channel, size, p_mesg); + + err_code = ant_acknowledge_message_tx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_channel_unassign(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_channel_unassign_req_dec(p_rx_buf, rx_buf_len, &channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_channel_unassign(channel); + + err_code = ant_channel_unassign_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_channel_close(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_channel_close_req_dec(p_rx_buf, rx_buf_len, &channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_channel_close(channel); + + err_code = ant_channel_close_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_network_address_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t network; + uint8_t network_address[MESG_NETWORK_KEY_SIZE - MESG_CHANNEL_NUM_SIZE]; + uint8_t * p_network_address = network_address; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_network_address_set_req_dec(p_rx_buf, rx_buf_len, &network, &p_network_address); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_network_address_set(network, p_network_address); + + err_code = ant_network_address_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_channel_radio_tx_power_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t tx_power; + uint8_t custom_tx_power; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_channel_radio_tx_power_set_req_dec(p_rx_buf, rx_buf_len, &channel, &tx_power, &custom_tx_power); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_channel_radio_tx_power_set(channel, tx_power, custom_tx_power); + + err_code = ant_channel_radio_tx_power_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_channel_rx_search_timeout_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t timeout; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_channel_rx_search_timeout_set_req_dec(p_rx_buf, rx_buf_len, &channel, &timeout); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_channel_rx_search_timeout_set(channel, timeout); + + err_code = ant_channel_rx_search_timeout_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_channel_low_priority_rx_search_timeout_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t timeout; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_channel_low_priority_rx_search_timeout_set_req_dec(p_rx_buf, rx_buf_len, &channel, &timeout); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_channel_low_priority_rx_search_timeout_set(channel, timeout); + + err_code = ant_channel_low_priority_rx_search_timeout_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_prox_search_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t prox_threshold; + uint8_t custom_prox_threshold; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_prox_search_set_req_dec(p_rx_buf, rx_buf_len, &channel, &prox_threshold, &custom_prox_threshold); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_prox_search_set(channel, prox_threshold, custom_prox_threshold); + + err_code = ant_prox_search_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_search_waveform_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint16_t waveform; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_search_waveform_set_req_dec(p_rx_buf, rx_buf_len, &channel, &waveform); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_search_waveform_set(channel, waveform); + + err_code = ant_search_waveform_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_channel_id_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t device_number; + uint8_t device_type; + uint8_t transmit_type; + uint8_t channel; + uint16_t * p_device_number = &device_number; + uint8_t * p_device_type = &device_type; + uint8_t * p_transmit_type = &transmit_type; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_channel_id_get_req_dec(p_rx_buf, rx_buf_len, &channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_channel_id_get(channel, p_device_number, p_device_type, p_transmit_type); + + err_code = ant_channel_id_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_device_number, p_device_type, p_transmit_type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_channel_radio_freq_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t r_freq; + uint8_t channel; + uint8_t * p_r_freq = &r_freq; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_channel_radio_freq_get_req_dec(p_rx_buf, rx_buf_len, &channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_channel_radio_freq_get(channel, p_r_freq); + + err_code = ant_channel_radio_freq_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_r_freq); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_channel_period_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t period; + uint8_t channel; + uint16_t * p_period = . + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_channel_period_get_req_dec(p_rx_buf, rx_buf_len, &channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_channel_period_get(channel, p_period); + + err_code = ant_channel_period_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_period); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_search_channel_priority_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t search_priority; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_search_channel_priority_set_req_dec(p_rx_buf, rx_buf_len, &channel, &search_priority); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_search_channel_priority_set(channel, search_priority); + + err_code = ant_search_channel_priority_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_active_search_sharing_cycles_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t cycles; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_active_search_sharing_cycles_set_req_dec(p_rx_buf, rx_buf_len, &channel, &cycles); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_active_search_sharing_cycles_set(channel, cycles); + + err_code = ant_active_search_sharing_cycles_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_lib_config_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t ant_lib_config; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_lib_config_set_req_dec(p_rx_buf, rx_buf_len, &ant_lib_config); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_lib_config_set(ant_lib_config); + + err_code = ant_lib_config_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_active_search_sharing_cycles_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t cycles; + uint8_t channel; + uint8_t * p_cycles = &cycles; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_active_search_sharing_cycles_get_req_dec(p_rx_buf, rx_buf_len, &channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_active_search_sharing_cycles_get(channel, p_cycles); + + err_code = ant_active_search_sharing_cycles_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_cycles); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_lib_config_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t ant_lib_config; + uint8_t * p_ant_lib_config = &ant_lib_config; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + sd_err_code = sd_ant_lib_config_get(p_ant_lib_config); + + err_code = ant_lib_config_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_ant_lib_config); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_lib_config_clear(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t ant_lib_config; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_lib_config_clear_req_dec(p_rx_buf, rx_buf_len, &ant_lib_config); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_lib_config_clear(ant_lib_config); + + err_code = ant_lib_config_clear_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_stack_reset(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + sd_err_code = sd_ant_stack_reset(); + + err_code = ant_stack_reset_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_rx_scan_mode_start(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t sync_channel_packets_only; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_rx_scan_mode_start_req_dec(p_rx_buf, rx_buf_len, &sync_channel_packets_only); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_rx_scan_mode_start(sync_channel_packets_only); + + err_code = ant_rx_scan_mode_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_id_list_add(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t dev_id[ANT_ID_SIZE]; + uint8_t * p_dev_id = dev_id; + uint8_t list_index; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_id_list_add_req_dec(p_rx_buf, rx_buf_len, &channel, &p_dev_id, &list_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_id_list_add(channel, p_dev_id, list_index); + + err_code = ant_id_list_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_id_list_config(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t id_list_size; + uint8_t inc_exc_flag; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_id_list_config_req_dec(p_rx_buf, rx_buf_len, &channel, &id_list_size, &inc_exc_flag); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_id_list_config(channel, id_list_size, inc_exc_flag); + + err_code = ant_id_list_config_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_channel_status_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t status; + uint8_t channel; + uint8_t * p_status = &status; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_channel_status_get_req_dec(p_rx_buf, rx_buf_len, &channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_channel_status_get(channel, p_status); + + err_code = ant_channel_status_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_status); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_cw_test_mode_init(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + sd_err_code = sd_ant_cw_test_mode_init(); + + err_code = ant_cw_test_mode_init_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_cw_test_mode(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t radio_freq; + uint8_t tx_power; + uint8_t custom_tx_power; + uint8_t mode; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_cw_test_mode_req_dec(p_rx_buf, rx_buf_len, &radio_freq, &tx_power, &custom_tx_power, &mode); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_cw_test_mode(radio_freq, tx_power, custom_tx_power, mode); + + err_code = ant_cw_test_mode_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_version_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t version[MESG_BUFFER_SIZE]; + memset(version, 0, sizeof(version)); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + sd_err_code = sd_ant_version_get(version); + + err_code = ant_version_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, version); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_capabilities_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t capabilities[MESG_CAPABILITIES_SIZE]; + memset(capabilities, 0, sizeof(capabilities)); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + sd_err_code = sd_ant_capabilities_get(capabilities); + + err_code = ant_capabilities_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, capabilities); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_crypto_channel_enable(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t enable; + uint8_t key_num; + uint8_t decimation_rate; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_crypto_channel_enable_req_dec(p_rx_buf, rx_buf_len, &channel, &enable, &key_num, &decimation_rate); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_crypto_channel_enable(channel, enable, key_num, decimation_rate); + + err_code = ant_crypto_channel_enable_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_adv_burst_config_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t size; + uint8_t config[ANT_ADV_BURST_CFG_SIZE_MAX]; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_adv_burst_config_set_req_dec(p_rx_buf, rx_buf_len, config, &size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_adv_burst_config_set(config, size); + + err_code = ant_adv_burst_config_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_crypto_key_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t key_num; + uint8_t key[SIZE_OF_ENCRYPTED_KEY]; + uint8_t * p_key = key; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_crypto_key_set_req_dec(p_rx_buf, rx_buf_len, &key_num, &p_key); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_crypto_key_set(key_num, p_key); + + err_code = ant_crypto_key_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_crypto_info_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t type; + uint8_t info[ANT_CRYPTO_INFO_SIZE]; + uint8_t * p_info = info; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_crypto_info_set_req_dec(p_rx_buf, rx_buf_len, &type, &p_info); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_crypto_info_set(type, p_info); + + err_code = ant_crypto_info_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_crypto_info_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t type; + uint8_t info[ANT_CRYPTO_INFO_MAX_SIZE]; + memset(info, 0, sizeof(info)); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_crypto_info_get_req_dec(p_rx_buf, rx_buf_len, &type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_crypto_info_get(type, info); + + err_code = ant_crypto_info_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, type, info); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_coex_config_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t coex_config_buffer[(MESG_BUFFER_SIZE / 2) - 1]; + uint8_t adv_coex_config_buffer[(MESG_BUFFER_SIZE / 2) - 1]; + + ANT_BUFFER_PTR coex_config = + { + .ucBufferSize = 0, + .pucBuffer = coex_config_buffer + }; + + ANT_BUFFER_PTR adv_coex_config = + { + .ucBufferSize = 0, + .pucBuffer = adv_coex_config_buffer + }; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_coex_config_set_req_dec(p_rx_buf, rx_buf_len, &channel, &coex_config, &adv_coex_config); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (coex_config.ucBufferSize == 0 && adv_coex_config.ucBufferSize == 0) + { + sd_err_code = sd_ant_coex_config_set(channel, NULL, NULL); + } + else if (coex_config.ucBufferSize == 0) + { + sd_err_code = sd_ant_coex_config_set(channel, NULL, &adv_coex_config); + } + else if (adv_coex_config.ucBufferSize == 0) + { + sd_err_code = sd_ant_coex_config_set(channel, &coex_config, NULL); + } + else + { + sd_err_code = sd_ant_coex_config_set(channel, &coex_config, &adv_coex_config); + } + + err_code = ant_coex_config_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_ant_coex_config_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t channel; + uint8_t coex_config_buffer[(MESG_BUFFER_SIZE / 2) - 1]; + uint8_t adv_coex_config_buffer[(MESG_BUFFER_SIZE / 2) - 1]; + + ANT_BUFFER_PTR coex_config = + { + .ucBufferSize = sizeof(coex_config_buffer), + .pucBuffer = coex_config_buffer + }; + + ANT_BUFFER_PTR adv_coex_config = + { + .ucBufferSize = sizeof(adv_coex_config_buffer), + .pucBuffer = adv_coex_config_buffer + }; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code = 0; + + err_code = ant_coex_config_get_req_dec(p_rx_buf, rx_buf_len, &channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ant_coex_config_get(channel, &coex_config, &adv_coex_config); + + err_code = ant_coex_config_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, &coex_config, &adv_coex_config); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.h new file mode 100644 index 0000000000000000000000000000000000000000..5e4b9734204245beea32919933e183631eac5da5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.h @@ -0,0 +1,793 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef _CONN_MW_ANT_H +#define _CONN_MW_ANT_H + +#include + +/** + * @addtogroup sercon_mw_ant Connectivity middleware codecs for S212 (connectivity side) + * @{ + * @ingroup ser_codecs_mw + */ + + +/**@brief Handles @ref sd_ant_enable command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ant_enable(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_assign command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_assign(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_open command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_open_with_offset(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_id_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_id_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_period_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_period_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_radio_freq_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_radio_freq_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_broadcast_message_tx command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_broadcast_message_tx(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_acknowledge_message_tx command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_acknowledge_message_tx(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_unassign command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_unassign(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_close command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_close(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_network_address_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_network_address_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_radio_tx_power_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_radio_tx_power_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_rx_search_timeout_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_rx_search_timeout_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_low_priority_rx_search_timeout_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_low_priority_rx_search_timeout_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_prox_search_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_prox_search_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_search_waveform_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_search_waveform_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_id_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_id_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_radio_freq_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_radio_freq_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_period_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_period_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_search_channel_priority_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_search_channel_priority_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_active_search_sharing_cycles_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_active_search_sharing_cycles_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_lib_config_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_lib_config_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_active_search_sharing_cycles_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_active_search_sharing_cycles_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_lib_config_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_lib_config_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_lib_config_clear command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_lib_config_clear(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_stack_reset command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_stack_reset(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_rx_scan_mode_start command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_rx_scan_mode_start(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_id_list_add command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_id_list_add(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_id_list_config command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_id_list_config(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_channel_status_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_channel_status_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_cw_test_mode_init command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_cw_test_mode_init(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_cw_test_mode command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_cw_test_mode(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_version_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_version_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_capabilities_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_capabilities_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_crypto_channel_enable command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_crypto_channel_enable(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_adv_burst_config_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_adv_burst_config_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_crypto_key_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_crypto_key_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_crypto_info_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_crypto_info_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_crypto_info_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_crypto_info_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_coex_config_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_coex_config_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ant_coex_config_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_ant_coex_config_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + + +/** @} */ + +#endif //_CONN_MW_ANT_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_acknowledge_message_tx.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_acknowledge_message_tx.c new file mode 100644 index 0000000000000000000000000000000000000000..96d5e5ca4afa450312514665bb2a1fee223614a1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_acknowledge_message_tx.c @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_acknowledge_message_tx_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_size, + uint8_t * * const pp_mesg) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_size); + SER_ASSERT_NOT_NULL(*pp_mesg); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_dec(p_buf, packet_len, &index, *pp_mesg, *p_size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + + +uint32_t ant_acknowledge_message_tx_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_TX_ACKNOWLEDGED_MESSAGE, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c new file mode 100644 index 0000000000000000000000000000000000000000..8c12b326eb0be7fca2cd5db153b75c6042c68330 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_active_search_sharing_cycles_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_channel) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_active_search_sharing_cycles_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_cycles) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint32_t total_len = *p_buf_len; + + uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_GET, return_code, + p_buf, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (return_code != NRF_SUCCESS) + { + return NRF_SUCCESS; + } + + err_code = uint8_t_enc(p_cycles, p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c new file mode 100644 index 0000000000000000000000000000000000000000..41d2e3e164b538708bca454be927f85d2949aae1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_active_search_sharing_cycles_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_cycles) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_cycles); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_cycles); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_active_search_sharing_cycles_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_adv_burst_config_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_adv_burst_config_set.c new file mode 100644 index 0000000000000000000000000000000000000000..55c7654067877c38cf231dc654b4ede759367da6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_adv_burst_config_set.c @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_adv_burst_config_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_config, + uint8_t * const p_size) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_size); + SER_ASSERT_NOT_NULL(p_config); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_dec(p_buf, packet_len, &index, p_config, *p_size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + + +uint32_t ant_adv_burst_config_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_ADV_BURST_CONFIG_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_broadcast_message_tx.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_broadcast_message_tx.c new file mode 100644 index 0000000000000000000000000000000000000000..1da9f57c31ed0a051b6872b1698372382b76fd2d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_broadcast_message_tx.c @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_broadcast_message_tx_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_size, + uint8_t * * const pp_mesg) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_size); + SER_ASSERT_NOT_NULL(*pp_mesg); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_dec(p_buf, packet_len, &index, *pp_mesg, *p_size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + + +uint32_t ant_broadcast_message_tx_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_TX_BROADCAST_MESSAGE, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_capabilities_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_capabilities_get.c new file mode 100644 index 0000000000000000000000000000000000000000..dc93842671e247ef1caee2a7728abbef583eb7e1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_capabilities_get.c @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_capabilities_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_capabilities) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint32_t total_len = *p_buf_len; + + uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_CAPABILITIES, return_code, + p_buf, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (return_code != NRF_SUCCESS) + { + return NRF_SUCCESS; + } + + err_code = uint8_vector_enc(p_capabilities, MESG_CAPABILITIES_SIZE, p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_assign.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_assign.c new file mode 100644 index 0000000000000000000000000000000000000000..204db58d9db7971671f3cb2e93210016d358d918 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_assign.c @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_assign_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_type, + uint8_t * const p_network, + uint8_t * const p_ext_assign) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_type); + SER_ASSERT_NOT_NULL(p_network); + SER_ASSERT_NOT_NULL(p_ext_assign); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_network); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_ext_assign); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + + +uint32_t ant_channel_assign_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CHANNEL_ASSIGN, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_close.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_close.c new file mode 100644 index 0000000000000000000000000000000000000000..62dddfdbff6b05dca11ed6cc8fd2e44957b99413 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_close.c @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_close_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_channel_close_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CHANNEL_CLOSE, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_get.c new file mode 100644 index 0000000000000000000000000000000000000000..a13fe01a7fdfd8844fe4299a163434a951f4dd9c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_get.c @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_id_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_channel) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_channel_id_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_device_number, + uint8_t const * const p_device_type, + uint8_t const * const p_transmit_type) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint32_t total_len = *p_buf_len; + + uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_CHANNEL_ID_GET, return_code, + p_buf, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (return_code != NRF_SUCCESS) + { + return NRF_SUCCESS; + } + + err_code = uint16_t_enc(p_device_number, p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(p_device_type, p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(p_transmit_type, p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_set.c new file mode 100644 index 0000000000000000000000000000000000000000..17df86c5d2a52167390023a5fe5dda9bcf416f3f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_set.c @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_id_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint16_t * const p_device_number, + uint8_t * const p_device_type, + uint8_t * const p_transmission_type) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_device_number); + SER_ASSERT_NOT_NULL(p_device_type); + SER_ASSERT_NOT_NULL(p_transmission_type); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint16_t_dec(p_buf, packet_len, &index, p_device_number); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_device_type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_transmission_type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + + +uint32_t ant_channel_id_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CHANNEL_ID_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_low_priority_rx_search_timout_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_low_priority_rx_search_timout_set.c new file mode 100644 index 0000000000000000000000000000000000000000..cd060f9407f9a21d6016326376b928e05d28ff4a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_low_priority_rx_search_timout_set.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_low_priority_rx_search_timeout_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_timeout) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_timeout); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_timeout); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_channel_low_priority_rx_search_timeout_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CHANNEL_LOW_PRIO_RX_SEARCH_TIMEOUT_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_open_with_offset.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_open_with_offset.c new file mode 100644 index 0000000000000000000000000000000000000000..3eb3744e96b1dab925a6153dc4bc4ed79a62c3f4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_open_with_offset.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_open_with_offset_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint16_t * const p_usOffset) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint16_t_dec(p_buf, packet_len, &index, p_usOffset); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + + +uint32_t ant_channel_open_with_offset_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CHANNEL_OPEN, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_get.c new file mode 100644 index 0000000000000000000000000000000000000000..9495878cc878715cf3ef9f40e54eef490e8e4e19 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_get.c @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_period_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_channel) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_channel_period_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_period) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint32_t total_len = *p_buf_len; + + uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_CHANNEL_PERIOD_GET, return_code, + p_buf, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (return_code != NRF_SUCCESS) + { + return NRF_SUCCESS; + } + + err_code = uint16_t_enc(p_period, p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_set.c new file mode 100644 index 0000000000000000000000000000000000000000..5ee3e9206bf19441f96b868b95461f52f8ac86f5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_set.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_period_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint16_t * const p_period) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_period); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint16_t_dec(p_buf, packet_len, &index, p_period); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_channel_period_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CHANNEL_PERIOD_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_get.c new file mode 100644 index 0000000000000000000000000000000000000000..19d687aaec629a1fcdb31e3b8bcbcdde39a4bd1f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_get.c @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_radio_freq_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_channel) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_channel_radio_freq_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_r_freq) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint32_t total_len = *p_buf_len; + + uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_CHANNEL_RADIO_FREQ_GET, return_code, + p_buf, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (return_code != NRF_SUCCESS) + { + return NRF_SUCCESS; + } + + err_code = uint8_t_enc(p_r_freq, p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_set.c new file mode 100644 index 0000000000000000000000000000000000000000..71c10f3af02709559860d05f4c83c1f7c7aa4f12 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_set.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_radio_freq_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_freq) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_freq); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_freq); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_channel_radio_freq_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CHANNEL_RADIO_FREQ_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_tx_power_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_tx_power_set.c new file mode 100644 index 0000000000000000000000000000000000000000..5cf86311aa30c10f6f8544c5e5114f2c265c9e9e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_tx_power_set.c @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_radio_tx_power_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_tx_power, + uint8_t * const p_custom_tx_power) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_tx_power); + SER_ASSERT_NOT_NULL(p_custom_tx_power); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_tx_power); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_custom_tx_power); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_channel_radio_tx_power_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CHANNEL_RADIO_TX_POWER_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c new file mode 100644 index 0000000000000000000000000000000000000000..7ea5579a0af2758bef5c05f17df9ee4b988fb780 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_rx_search_timeout_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_timeout) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_timeout); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_timeout); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_channel_rx_search_timeout_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CHANNEL_SEARCH_TIMEOUT_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_status_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_status_get.c new file mode 100644 index 0000000000000000000000000000000000000000..7d42cf11edf75df86f99b686002c6c3739b9adc3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_status_get.c @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_status_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_channel) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_channel_status_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_status) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint32_t total_len = *p_buf_len; + + uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_CHANNEL_STATUS_GET, return_code, + p_buf, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (return_code != NRF_SUCCESS) + { + return NRF_SUCCESS; + } + + err_code = uint8_t_enc(p_status, p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_unassign.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_unassign.c new file mode 100644 index 0000000000000000000000000000000000000000..6b59fa6c7fe1a2cbc45f21a2924b358f672118e8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_channel_unassign.c @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_channel_unassign_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_channel_unassign_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CHANNEL_UNASSIGN, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_get.c new file mode 100644 index 0000000000000000000000000000000000000000..e608b70c6b41424a31863ae5562194ffabbeeebc --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_get.c @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_coex_config_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_channel) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_coex_config_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ANT_BUFFER_PTR * const p_coex_config, + ANT_BUFFER_PTR * const p_adv_coex_config) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint32_t total_len = *p_buf_len; + + uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_COEX_CONFIG_GET, return_code, + p_buf, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (return_code != NRF_SUCCESS) + { + return NRF_SUCCESS; + } + + err_code = uint8_t_enc(&(p_coex_config->ucBufferSize), p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_enc(p_coex_config->pucBuffer, + p_coex_config->ucBufferSize, + p_buf, + total_len, + p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_enc(&(p_adv_coex_config->ucBufferSize), p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_enc(p_adv_coex_config->pucBuffer, + p_adv_coex_config->ucBufferSize, + p_buf, + total_len, + p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_set.c new file mode 100644 index 0000000000000000000000000000000000000000..8f37cb57a3f50f8243cde6101842b7a49d73f2be --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_set.c @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_coex_config_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + ANT_BUFFER_PTR * const p_coex_config, + ANT_BUFFER_PTR * const p_adv_coex_config) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_coex_config); + SER_ASSERT_NOT_NULL(p_adv_coex_config); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + // Decode coex config buffer size + err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_coex_config->ucBufferSize)); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + // Decode coex config buffer + err_code = uint8_vector_dec(p_buf, + packet_len, + &index, + p_coex_config->pucBuffer, + p_coex_config->ucBufferSize); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + // Decode advanced coex config buffer size + err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_adv_coex_config->ucBufferSize)); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + // Decode advanced coex config buffer + err_code = uint8_vector_dec(p_buf, + packet_len, + &index, + p_adv_coex_config->pucBuffer, + p_adv_coex_config->ucBufferSize); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_coex_config_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_COEX_CONFIG_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..1dfbfade849d0f884c90c4a7175c1860186ff64d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_conn.h @@ -0,0 +1,1591 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef ANT_CONN_H__ +#define ANT_CONN_H__ + + +/** + * @addtogroup ser_conn_s212_codecs Connectivity codecs for S212 + * @ingroup ser_codecs_conn + */ + +/**@file + * + * @defgroup ant_conn Connectivity command request decoders and command response encoders + * @{ + * @ingroup ser_conn_s212_codecs + * + * @brief Connectivity command request decoders and command response encoders. + */ +#include "ant_interface.h" + +/**@brief Decodes @ref sd_ant_enable command request. + * + * @sa @ref ant_enable_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_ant_enable_params Pointer to pointer to @ref ANT_ENABLE. + * \c It will be set to NULL if p_ant_enable_params is not + * present in the packet. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_enable_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ANT_ENABLE * * const pp_ant_enable_params); + +/**@brief Encodes @ref sd_ant_enable command response. + * + * @sa @ref ant_enable_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_enable_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_channel_assign command request. + * + * @sa @ref ant_channel_assign_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel to be + * assigned will be set. + * @param[out] p_type Pointer to an unsigned char (1 octet) where the channel type + * to be assigned will be set. + * @param[out] p_network Pointer to an unsigned char (1 octet) where the network key to + * associate with the channel will be set. + * @param[out] p_ext_assign Pointer to a bit field (1 octet) where an extended assign will + * be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_assign_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_type, + uint8_t * const p_network, + uint8_t * const p_ext_assign); + +/**@brief Encodes @ref sd_ant_channel_assign command response. + * + * @sa @ref ant_channel_assign_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_assign_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_channel_open command request. + * + * @sa @ref ant_channel_open_with_offset_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel to be + * opened will be set. + * @param[out] p_usOffset Pointer to a channel start time offset value. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_open_with_offset_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint16_t * const p_usOffset); + +/**@brief Encodes @ref sd_ant_channel_open command response. + * + * @sa @ref ant_channel_open_with_offset_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_open_with_offset_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_channel_id_set command request. + * + * @sa @ref ant_channel_id_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number + * will be set. + * @param[out] p_device_number Pointer to an unsigned short (2 octets) where the device + * number will be set. + * @param[out] p_device_type Pointer to an an unsigned char (1 octet) where the device type + * will be set. + * @param[out] p_transmission_type Pointer to an unsigned char (1 octet) where the transmission + * type will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_id_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint16_t * const p_device_number, + uint8_t * const p_device_type, + uint8_t * const p_transmission_type); + +/**@brief Encodes @ref sd_ant_channel_id_set command response. + * + * @sa @ref ant_channel_id_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_id_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_channel_period_set command request. + * + * @sa @ref ant_channel_period_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number + * associated with the period will be set. + * @param[out] p_period Pointer to an unsigned short (2 octets) where the period will + * be set. Value is in 32 kHz counts (usPeriod/32768 s). + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_period_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint16_t * const p_period); + +/**@brief Encodes @ref sd_ant_channel_period_set command response. + * + * @sa @ref ant_channel_period_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_period_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_channel_radio_freq_set command request. + * + * @sa @ref ant_channel_radio_freq_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number + * associated with the radio frequency will be set. + * @param[out] p_freq Pointer to an unsigned char (1 octet) where the radio + * frequency will be set. Value is offset from 2400 MHz + * (eg. 2466 MHz, ucFreq = 66). + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_radio_freq_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_freq); + +/**@brief Encodes @ref sd_ant_channel_radio_freq_set command response. + * + * @sa @ref ant_channel_radio_freq_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_radio_freq_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_broadcast_message_tx command request. + * + * @sa @ref ant_broadcast_message_tx_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel to + * send the data on will be set. + * @param[out] p_size Pointer to an unsigned char (1 octet) where the size of the + * message will be set. + * @param[out] pp_mesg Pointer to pointer to the buffer where the broadcast message + * will be set (array must be 8 octets). + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_broadcast_message_tx_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_size, + uint8_t * * const pp_mesg); + +/**@brief Encodes @ref sd_ant_broadcast_message_tx command response. + * + * @sa @ref ant_broadcast_message_tx_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_broadcast_message_tx_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_acknowledge_message_tx command request. + * + * @sa @ref ant_acknowledge_message_tx_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel to + * send the data on will be set. + * @param[out] p_size Pointer to an unsigned char (1 octet) where the size of the + * message will be set. + * @param[out] pp_mesg Pointer to pointer to the buffer where the acknowledge message + * will be set (array must be 8 octets). + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_acknowledge_message_tx_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_size, + uint8_t * * const pp_mesg); + +/**@brief Encodes @ref sd_ant_acknowledge_message_tx command response. + * + * @sa @ref ant_acknowledge_message_tx_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_acknowledge_message_tx_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_channel_unassign command request. + * + * @sa @ref ant_channel_unassign_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel to be + * unassigned will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_unassign_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel); + +/**@brief Encodes @ref sd_ant_channel_unassign command response. + * + * @sa @ref ant_channel_unassign_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_unassign_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_channel_close command request. + * + * @sa @ref ant_channel_close_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel to be + * closed will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_close_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel); + +/**@brief Encodes @ref sd_ant_channel_close command response. + * + * @sa @ref ant_channel_close_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_close_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_network_address_set command request. + * + * @sa @ref ant_network_address_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_network Pointer to an unsigned char (1 octet) where the network number + * to assign the network address to will be set. + * @param[out] pp_network_key Pointer to a pointer to where the network key (8 octets in + * length) will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_network_address_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_network, + uint8_t * * const pp_network_key); + +/**@brief Encodes @ref sd_ant_network_address_set command response. + * + * @sa @ref ant_network_address_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_network_address_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_channel_radio_tx_power_set command request. + * + * @sa @ref ant_channel_radio_tx_power_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number + * to assign the radio TX power will be set. + * @param[out] p_tx_power Pointer to an unsigned char (1 octet) where the ANT transmit + * power index will be set. See Radio TX Power Definitions in + * ant_parameters.h. + * @param[out] p_custom_tx_power Pointer to an unsigned char (1 octet) where the custom nRF + * transmit power as defined in nrf51_bitfields.h will be set. + * Only applicable if tx_power is set to custom TX power + * selection. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_radio_tx_power_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_tx_power, + uint8_t * const p_custom_tx_power); + +/**@brief Encodes @ref sd_ant_channel_radio_tx_power_set command response. + * + * @sa @ref ant_channel_radio_tx_power_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_radio_tx_power_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_channel_rx_search_timeout_set command request. + * + * @sa @ref ant_channel_rx_search_timeout_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number + * will be set. + * @param[out] p_timeout Pointer to an unsigned char (1 octet) where the time-out value + * will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_rx_search_timeout_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_timeout); + +/**@brief Encodes @ref sd_ant_channel_rx_search_timeout_set command response. + * + * @sa @ref ant_channel_rx_search_timeout_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_rx_search_timeout_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_channel_low_priority_rx_search_timeout_set command request. + * + * @sa @ref ant_channel_low_priority_rx_search_timeout_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number + * will be set. + * @param[out] p_timeout Pointer to an unsigned char (1 octet) where the time-out value + * will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_low_priority_rx_search_timeout_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_timeout); + +/**@brief Encodes @ref sd_ant_channel_low_priority_rx_search_timeout_set command response. + * + * @sa @ref ant_channel_low_priority_rx_search_timeout_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_low_priority_rx_search_timeout_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_prox_search_set command request. + * + * @sa @ref ant_prox_search_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel + * number will be set. + * @param[out] p_prox_threshold Pointer to an unsigned char (1 octet) where the minimum + * RSSI threshold required for acquisition during a search + * will be set. See Radio Proximity Search Threshold in + * ant_parameters.h. + * @param[out] p_custom_prox_threshold Pointer to an unsigned char (1 octet) where the custom + * minimum RSSI threshold for acquisition during a search + * will be set. Only applicable if prox_threshold is set to + * custom proximity selection. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_prox_search_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_prox_threshold, + uint8_t * const p_custom_prox_threshold); + +/**@brief Encodes @ref sd_ant_prox_search_set command response. + * + * @sa @ref ant_prox_search_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_prox_search_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_search_waveform_set command request. + * + * @sa @ref ant_search_waveform_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel + * number will be set. + * @param[out] p_waveform Pointer to an unsigned short (2 octets) where the channel + * waveform period (usWaveform/32768 s) will be set. + * Default = 316. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_search_waveform_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint16_t * const p_waveform); + +/**@brief Encodes @ref sd_ant_search_waveform_set command response. + * + * @sa @ref ant_search_waveform_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_search_waveform_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_channel_id_get command request. + * + * @sa @ref ant_channel_id_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel + * number will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_id_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_channel); + +/**@brief Encodes @ref sd_ant_channel_id_get command response. + * + * @sa @ref ant_channel_id_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_device_number Pointer to device number + * @param[in] p_device_type Pointer to device type + * @param[in] p_transmit_type Pointer to transmit type + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_id_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_device_number, + uint8_t const * const p_device_type, + uint8_t const * const p_transmit_type); + +/**@brief Decodes @ref sd_ant_channel_radio_freq_get command request. + * + * @sa @ref ant_channel_radio_freq_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number + * will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_radio_freq_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_channel); + +/**@brief Encodes @ref sd_ant_channel_radio_freq_get command response. + * + * @sa @ref ant_channel_radio_freq_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_r_freq Pointer to radio frequency + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_radio_freq_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_r_freq); + +/**@brief Decodes @ref sd_ant_channel_period_get command request. + * + * @sa @ref ant_channel_period_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number + * will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_period_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_channel); + +/**@brief Encodes @ref sd_ant_channel_period_get command response. + * + * @sa @ref ant_channel_period_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_period Pointer to period + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_period_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_period); + +/**@brief Decodes @ref sd_ant_search_channel_priority_set command request. + * + * @sa @ref ant_search_channel_priority_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number + * will be set. + * @param[out] p_search_priority Pointer to an unsigned char (1 octet) where the search + * priority value will be set. 0 to 7 (Default = 0). + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_search_channel_priority_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_search_priority); + +/**@brief Encodes @ref sd_ant_search_channel_priority_set command response. + * + * @sa @ref ant_search_channel_priority_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_search_channel_priority_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_active_search_sharing_cycles_set command request. + * + * @sa @ref ant_active_search_sharing_cycles_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number + * will be set. + * @param[out] p_cycles Pointer to an unsigned char (1 octet) where the numbe of + * cycles will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_active_search_sharing_cycles_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_cycles); + +/**@brief Encodes @ref sd_ant_active_search_sharing_cycles_set command response. + * + * @sa @ref ant_active_search_sharing_cycles_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_active_search_sharing_cycles_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_lib_config_set command request. + * + * @sa @ref ant_lib_config_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_ant_lib_config Pointer to an unsigned char (1 octet) where the ANT lib + * config bit flags will be set. See ANT Library Config in + * ant_parameters.h. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_lib_config_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_ant_lib_config); + +/**@brief Encodes @ref sd_ant_lib_config_set command response. + * + * @sa @ref ant_lib_config_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_lib_config_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_active_search_sharing_cycles_get command request. + * + * @sa @ref ant_active_search_sharing_cycles_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number + * will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_active_search_sharing_cycles_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_channel); + +/**@brief Encodes @ref sd_ant_active_search_sharing_cycles_get command response. + * + * @sa @ref ant_active_search_sharing_cycles_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_cycles Pointer to cycles. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_active_search_sharing_cycles_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_cycles); + +/**@brief Encodes @ref sd_ant_lib_config_get command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_ant_lib_config Pointer to ANT library configuration. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_lib_config_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_ant_lib_config); + +/**@brief Decodes @ref sd_ant_lib_config_clear command request. + * + * @sa @ref ant_lib_config_clear_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_ant_lib_config Pointer to an unsigned char (1 octet) where the ANT lib config + * bit(s) to clear will be set. See ANT Library Config in + * ant_parameters.h. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_lib_config_clear_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_ant_lib_config); + +/**@brief Encodes @ref sd_ant_lib_config_clear command response. + * + * @sa @ref ant_lib_config_clear_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_lib_config_clear_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Encodes @ref sd_ant_stack_reset command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_stack_reset_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_rx_scan_mode_start command request. + * + * @sa @ref ant_rx_scan_mode_start_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_sync_channel_packets_only Pointer to an unsigned char (1 octet) where the + * synchronous channel only scanning mode will be set. + * 0 = disable, 1 = enable. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_rx_scan_mode_start_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_sync_channel_packets_only); + +/**@brief Encodes @ref sd_ant_rx_scan_mode_start command response. + * + * @sa @ref ant_rx_scan_mode_start_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_rx_scan_mode_start_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_id_list_add command request. + * + * @sa @ref ant_id_list_add_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel + * number to add the list entry to will be set. + * @param[out] pp_dev_id Pointer to pointer to where the Dev ID will be stored. + * @param[out] p_list_index Pointer to an unsigned char (1 octet) where the list + * index (0-3), will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_id_list_add_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * * const pp_dev_id, + uint8_t * const p_list_index); + +/**@brief Encodes @ref sd_ant_id_list_add command response. + * + * @sa @ref ant_id_list_add_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_id_list_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_id_list_config command request. + * + * @sa @ref ant_id_list_config_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) wher the channel number + * of the device ID list will be stored. + * @param[out] p_id_list_size Pointer to an unsigned char (1 octet) where the size of the + * inclusion or exclusion list (0-4) will be stored. + * @param[out] p_inc_exc_flag Pointer to an unsigned char (1 octet) where the type of list + * will be stored. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_id_list_config_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_id_list_size, + uint8_t * const p_inc_exc_flag); + +/**@brief Encodes @ref sd_ant_id_list_add command response. + * + * @sa @ref ant_id_list_config_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_id_list_config_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_channel_status_get command request. + * + * @sa @ref ant_channel_status_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number + * will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_status_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_channel); + +/**@brief Encodes @ref sd_ant_channel_status_get command response. + * + * @sa @ref ant_channel_status_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_status Pointer to status + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_channel_status_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_status); + +/**@brief Encodes @ref sd_ant_cw_test_mode_init command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_cw_test_mode_init_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_cw_test_mode command request. + * + * @sa @ref ant_cw_test_mode_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_radio_freq Pointer to an unsigned char (1 octet) where the radio + * frequency offset from 2400 MHz for continuous wave mode will be + * set. (eg. 2466 MHz, ucRadioFreq = 66). + * @param[out] p_tx_power Pointer to an unsigned char (1 octet) where the ANT transmit + * power index for continuous wave mode will be set. See Radio + * TX Power Definitions in ant_parameters.h + * @param[out] p_custom_tx_power Pointer to an unsigned char (1 octet) where the custom nRF + * transmit power as defined in nrf51_bitfields.h will be set. Only + * applicable if ucTxPower is set to custom TX power selection. + * @param[out] p_mode Pointer to an unsigned char (1 octet) where the test mode type + * will be set. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_cw_test_mode_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_radio_freq, + uint8_t * const p_tx_power, + uint8_t * const p_custom_tx_power, + uint8_t * const p_mode); + +/**@brief Encodes @ref sd_ant_cw_test_mode command response. + * + * @sa @ref ant_cw_test_mode_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_cw_test_mode_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Encodes @ref sd_ant_version_get command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_version Pointer to version. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_version_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_version); + +/**@brief Encodes @ref sd_ant_capabilities_get command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_capabilities Pointer to ant capabilities buffer. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_capabilities_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_capabilities); + +/**@brief Decodes @ref sd_ant_crypto_channel_enable command request. + * + * @sa @ref ant_crypto_channel_enable_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel in which + * encryption mode is set will be copied to. + * @param[out] p_enable Pointer to an unsigned char (1 octet) where the encryption + * mode will be set. + * @param[out] p_key_num Pointer to an unsigned char (1 octet) where the key index of the + * 128-bit key to be used for encryption will be set. + * @param[out] p_decimation_rate Pointer to an unsigned char (1 octet) where the decimate rate to + * apply for encrypted slave channel will be set. Must be > 0. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_crypto_channel_enable_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_enable, + uint8_t * const p_key_num, + uint8_t * const p_decimation_rate); + +/**@brief Encodes @ref sd_ant_crypto_channel_enable command response. + * + * @sa @ref ant_crypto_channel_enable_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_crypto_channel_enable_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_adv_burst_config_set command request. + * + * @sa @ref ant_adv_burst_config_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_config Pointer to the buffer where advanced burst + * configuration will be set. + * @param[out] p_size Pointer to an unsigned char (1 octet) where the size of the + * configuration parameter buffer will be set. + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_adv_burst_config_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_config, + uint8_t * const p_size); + +/**@brief Encodes @ref sd_ant_adv_burst_config_set command response. + * + * @sa @ref ant_adv_burst_config_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_adv_burst_config_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_crypto_key_set command request. + * + * @sa @ref ant_crypto_key_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_key_num Pointer to an unsigned char (1 octet) where the key index for + * assignment will be set. + * @param[out] pp_key Pointer to pointer to buffer (16 octets) where the 128-bit + * AES key to be assigned to the key index will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_crypto_key_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_key_num, + uint8_t * * const pp_key); + +/**@brief Encodes @ref sd_ant_crypto_key_set command response. + * + * @sa @ref ant_crypto_key_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_crypto_key_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_crypto_info_set command request. + * + * @sa @ref ant_crypto_info_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_type Pointer to an unsigned char (1 octet) where the type of + * information being set will be copied. + * @param[out] pp_info Pointer to pointer to buffer where information being set will be + * copied. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_crypto_info_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_type, + uint8_t * * const pp_info); + +/**@brief Encodes @ref sd_ant_crypto_info_set command response. + * + * @sa @ref ant_crypto_info_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_crypto_info_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_crypto_info_get command request. + * + * @sa @ref ant_crypto_info_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_type Pointer to an unsigned char (1 octet) where the type of + * information being set will be copied. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_crypto_info_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_type); + +/**@brief Encodes @ref sd_ant_crypto_info_get command response. + * + * @sa @ref ant_crypto_info_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] type The type of information being set. + * @param[in] p_info Pointer to info buffer. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_crypto_info_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t type, + uint8_t const * const p_info); + +/**@brief Decodes @ref sd_ant_coex_config_set command request. + * + * @sa @ref ant_coex_config_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[in] p_channel Pointer to an unsigned char (1 octet) where the channel for + * which the coexistence configuration is to be set will be copied. + * @param[in] p_coex_config Pointer to a buffer where the coexistence configuration to be set will + * be copied. + * @param[in] p_adv_coex_config Pointer to a buffer where the advanced coexistence configuration to be set will + * be copied. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_coex_config_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + ANT_BUFFER_PTR * const p_coex_config, + ANT_BUFFER_PTR * const p_adv_coex_config); + +/**@brief Encodes @ref sd_ant_coex_config_set command response. + * + * @sa @ref ant_coex_config_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_coex_config_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ant_coex_config_get command request. + * + * @sa @ref ant_channel_id_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel + * number will be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ant_coex_config_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_channel); + +/**@brief Encodes @ref sd_ant_coex_config_get command response. + * + * @sa @ref ant_channel_id_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_coex_config Pointer to the coexistence configuration. + * @param[in] p_adv_coex_config Pointer to the advanced coexistence configuration. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_coex_config_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ANT_BUFFER_PTR * const p_coex_config, + ANT_BUFFER_PTR * const p_adv_coex_config); +/** @} */ + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_channel_enable.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_channel_enable.c new file mode 100644 index 0000000000000000000000000000000000000000..6f616c0e07870e86e3a6a5ba9314e6c58c197a48 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_channel_enable.c @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_crypto_channel_enable_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_enable, + uint8_t * const p_key_num, + uint8_t * const p_decimation_rate) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_enable); + SER_ASSERT_NOT_NULL(p_key_num); + SER_ASSERT_NOT_NULL(p_decimation_rate); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_enable); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_key_num); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_decimation_rate); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_crypto_channel_enable_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CRYPTO_CHANNEL_ENABLE, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_get.c new file mode 100644 index 0000000000000000000000000000000000000000..349c0a9c77c698db8b5f776528b5ce706d4fe46c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_get.c @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_crypto_info_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint8_t * const p_type) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_type); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_crypto_info_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t type, + uint8_t const * const p_info) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint32_t total_len = *p_buf_len; + + uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_CRYPTO_INFO_GET, return_code, + p_buf, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (return_code != NRF_SUCCESS) + { + return NRF_SUCCESS; + } + + err_code = uint8_t_enc(&type, p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + uint8_t crypto_info_size = (MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE - + MESG_CHANNEL_NUM_SIZE); + + err_code = uint8_vector_enc(p_info, crypto_info_size, p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_set.c new file mode 100644 index 0000000000000000000000000000000000000000..8d37dc4bc803f80f36de0df64b15d6f6a741069a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_set.c @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_crypto_info_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_type, + uint8_t * * const pp_info) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_type); + SER_ASSERT_NOT_NULL(*pp_info); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + uint8_t crypto_info_size = (MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE - + MESG_CHANNEL_NUM_SIZE) + + (MESG_CONFIG_ENCRYPT_REQ_CONFIG_ID_SIZE - + MESG_CHANNEL_NUM_SIZE); + + err_code = uint8_vector_dec(p_buf, packet_len, &index, *pp_info, crypto_info_size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + + +uint32_t ant_crypto_info_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CRYPTO_INFO_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_key_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_key_set.c new file mode 100644 index 0000000000000000000000000000000000000000..590b8741ff02d42a93b29dd5548ec583704afe34 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_key_set.c @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_crypto_key_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_key_num, + uint8_t * * const pp_key) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_key_num); + SER_ASSERT_NOT_NULL(*pp_key); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_key_num); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_dec(p_buf, packet_len, &index, *pp_key, SIZE_OF_ENCRYPTED_KEY); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + + +uint32_t ant_crypto_key_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CRYPTO_KEY_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode.c new file mode 100644 index 0000000000000000000000000000000000000000..48cec039ceda337587818837da3275fd95811d1e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode.c @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_cw_test_mode_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_radio_freq, + uint8_t * const p_tx_power, + uint8_t * const p_custom_tx_power, + uint8_t * const p_mode) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_radio_freq); + SER_ASSERT_NOT_NULL(p_tx_power); + SER_ASSERT_NOT_NULL(p_custom_tx_power); + SER_ASSERT_NOT_NULL(p_mode); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_radio_freq); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_tx_power); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_custom_tx_power); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_mode); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_cw_test_mode_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_CW_TEST_MODE, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode_init.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode_init.c new file mode 100644 index 0000000000000000000000000000000000000000..542da8f42f1497c8d1672ce8c78bbfe85095f02a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode_init.c @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_cw_test_mode_init_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_INIT_CW_TEST_MODE, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_enable.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_enable.c new file mode 100644 index 0000000000000000000000000000000000000000..32c3d828379ef3760283dbe8fc8255b78dee12e7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_enable.c @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_enable_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ANT_ENABLE * * const pp_ant_enable_params) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(pp_ant_enable_params); + SER_ASSERT_NOT_NULL(*pp_ant_enable_params); + + err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_ant_enable_params, ANT_ENABLE_dec); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + + +uint32_t ant_enable_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_ENABLE, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_event.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_event.c new file mode 100644 index 0000000000000000000000000000000000000000..7bc19e9684a973e0308600f29496cce7072d5444 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_event.c @@ -0,0 +1,114 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ant_parameters.h" +#include "ant_stack_handler_types.h" +#include "ant_struct_serialization.h" +#include "ble_serialization.h" +#include "ant_event_rx.h" +#include "app_util.h" +#include "cond_field_serialization.h" + + +uint32_t ant_event_enc(ant_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t ret_val = NRF_SUCCESS; + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + SER_ASSERT_NOT_NULL(p_event); + + switch (p_event->event) + { + case NO_EVENT: + case EVENT_RX_SEARCH_TIMEOUT: + case EVENT_RX_FAIL: + case EVENT_TRANSFER_RX_FAILED: + case EVENT_TRANSFER_TX_COMPLETED: + case EVENT_TRANSFER_TX_FAILED: + case EVENT_CHANNEL_CLOSED: + case EVENT_RX_FAIL_GO_TO_SEARCH: + case EVENT_CHANNEL_COLLISION: + case EVENT_TRANSFER_TX_START: + case EVENT_TRANSFER_NEXT_DATA_BLOCK: + case CHANNEL_IN_WRONG_STATE: + case CHANNEL_NOT_OPENED: + case CHANNEL_ID_NOT_SET: + case CLOSE_ALL_CHANNELS: + case TRANSFER_IN_PROGRESS: + case TRANSFER_SEQUENCE_NUMBER_ERROR: + case TRANSFER_IN_ERROR: + case TRANSFER_BUSY: + case MESSAGE_SIZE_EXCEEDS_LIMIT: + case INVALID_MESSAGE: + case INVALID_NETWORK_NUMBER: + case INVALID_LIST_ID: + case INVALID_SCAN_TX_CHANNEL: + case INVALID_PARAMETER_PROVIDED: + case EVENT_QUE_OVERFLOW: + case EVENT_ENCRYPT_NEGOTIATION_SUCCESS: + case EVENT_ENCRYPT_NEGOTIATION_FAIL: + case EVENT_RFACTIVE_NOTIFICATION: + case EVENT_CONNECTION_START: + case EVENT_CONNECTION_SUCCESS: + case EVENT_CONNECTION_FAIL: + case EVENT_CONNECTION_TIMEOUT: + case EVENT_CONNECTION_UPDATE: + case NO_RESPONSE_MESSAGE: + case EVENT_RX: + case EVENT_BLOCKED: + case EVENT_TX: + { + uint32_t index = 0; + // TO DO - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); + uint32_t err_code = ant_evt_t_enc(p_event, p_buf, *p_buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + *p_buf_len = index; + break; + } + default: + ret_val = NRF_ERROR_NOT_SUPPORTED; + break; + } + + return ret_val; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_event.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_event.h new file mode 100644 index 0000000000000000000000000000000000000000..4dc2c006616323252716872d2d31fbb92f54f7d6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_event.h @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef __ANT_EVENT_H__ +#define __ANT_EVENT_H__ +#include "ant_parameters.h" +#include "app_util.h" +#include "ant_stack_handler_types.h" + +/** + * @addtogroup ser_conn_s212_codecs + * @{ + * @ingroup ser_codecs_conn + */ + +/**@brief Event encoding dispatcher. + * + * The event encoding dispatcher will route the event packet to the correct encoder which in turn + * encodes the contents of the event and updates the \p p_buf buffer. + * + * @param[in] p_event Pointer to the \ref ant_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + * @retval NRF_ERROR_NOT_SUPPORTED Event encoder is not implemented. + */ +uint32_t ant_event_enc(ant_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @} */ +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.c new file mode 100644 index 0000000000000000000000000000000000000000..28b9a2be2b57d132605e544ac7890ecda13c1b73 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.c @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_event_rx.h" +#include "ble_serialization.h" +#include "app_util.h" + +uint32_t ant_event_rx_enc(ant_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + ANT_MESSAGE * p_message; + uint32_t index = 0; + + + SER_ASSERT_NOT_NULL(p_event); + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); + p_message = (ANT_MESSAGE *)p_event->msg.evt_buffer; + + index += uint16_encode(EVENT_RX, &(p_buf[index])); // Mesg ID + p_buf[index++] = p_message->ANT_MESSAGE_ucSize; // Mesg Size + memcpy(&(p_buf[index]), p_message->ANT_MESSAGE_aucPayload,p_message->ANT_MESSAGE_ucSize); // Payload + index += p_message->ANT_MESSAGE_ucSize; + + *p_buf_len = index; + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.h new file mode 100644 index 0000000000000000000000000000000000000000..4e566108dacb79063ec980376498ad95299e179e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef __ANT_EVENT_RX_H__ +#define __ANT_EVENT_RX_H__ + +#include +#include "ant_parameters.h" +#include "ant_stack_handler_types.h" + +/** + * @addtogroup ser_conn_s212_codecs + * @{ + * @ingroup ser_codecs_conn + */ + +/** + * @brief Encodes ant_event_rx event. + * + * @param[in] p_event Pointer to the \ref ant_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ant_event_rx_enc(ant_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @} */ +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_add.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_add.c new file mode 100644 index 0000000000000000000000000000000000000000..6da2ebd220a12230769579c8d1905b8e71b2b414 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_add.c @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_id_list_add_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * * const pp_dev_id, + uint8_t * const p_list_index) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(*pp_dev_id); + SER_ASSERT_NOT_NULL(p_list_index); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_dec(p_buf, packet_len, &index, *pp_dev_id, ANT_ID_SIZE); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_list_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + + +uint32_t ant_id_list_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_ID_LIST_ADD, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_config.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_config.c new file mode 100644 index 0000000000000000000000000000000000000000..b93fed5d61dc070a60fa9ab52c62739bc81d79a4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_config.c @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_id_list_config_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_id_list_size, + uint8_t * const p_inc_exc_flag) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_id_list_size); + SER_ASSERT_NOT_NULL(p_inc_exc_flag); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_id_list_size); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_inc_exc_flag); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + + +uint32_t ant_id_list_config_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_ID_LIST_CONFIG, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_clear.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_clear.c new file mode 100644 index 0000000000000000000000000000000000000000..a530ec71ad7a42f782ec9b4f0b4476e64f717fb8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_clear.c @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_lib_config_clear_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_ant_lib_config) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_ant_lib_config); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_ant_lib_config); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_lib_config_clear_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_LIB_CONFIG_CLEAR, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_get.c new file mode 100644 index 0000000000000000000000000000000000000000..e4a2fbe5c9fe3bc2966b1968a22acdacd58d689a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_get.c @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_lib_config_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_ant_lib_config) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint32_t total_len = *p_buf_len; + + uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_LIB_CONFIG_GET, return_code, + p_buf, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (return_code != NRF_SUCCESS) + { + return NRF_SUCCESS; + } + + err_code = uint8_t_enc(p_ant_lib_config, p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_set.c new file mode 100644 index 0000000000000000000000000000000000000000..98820efa69700f2c221cb2ec299b40acbbd6b56d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_set.c @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_lib_config_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_ant_lib_config) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_ant_lib_config); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_ant_lib_config); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_lib_config_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_LIB_CONFIG_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_network_address_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_network_address_set.c new file mode 100644 index 0000000000000000000000000000000000000000..a207a1580c5daf47adaefe133cc660cc302c1a85 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_network_address_set.c @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_network_address_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_network, + uint8_t * * const pp_network_key) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_network); + SER_ASSERT_NOT_NULL(*pp_network_key); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_network); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_vector_dec(p_buf, packet_len, &index, *pp_network_key, MESG_NETWORK_KEY_SIZE - MESG_CHANNEL_NUM_SIZE); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + + +uint32_t ant_network_address_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_NETWORK_KEY_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_prox_search_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_prox_search_set.c new file mode 100644 index 0000000000000000000000000000000000000000..6416a9d77b3e89eaff2a5d88d505ebc1ca038751 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_prox_search_set.c @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_prox_search_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_prox_threshold, + uint8_t * const p_custom_prox_threshold) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_prox_threshold); + SER_ASSERT_NOT_NULL(p_custom_prox_threshold); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_prox_threshold); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_custom_prox_threshold); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_prox_search_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_PROX_SEARCH_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_rx_scan_mode_start.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_rx_scan_mode_start.c new file mode 100644 index 0000000000000000000000000000000000000000..7706edbc9899c83a911f5a67efdc1db808b2988e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_rx_scan_mode_start.c @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_rx_scan_mode_start_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_sync_channel_packets_only) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_sync_channel_packets_only); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_sync_channel_packets_only); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_rx_scan_mode_start_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_RX_SCAN_MODE_START, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_search_channel_priority_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_search_channel_priority_set.c new file mode 100644 index 0000000000000000000000000000000000000000..47af40b8637e29314182663f2c0246efac917cd2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_search_channel_priority_set.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_search_channel_priority_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint8_t * const p_search_priority) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_search_priority); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_search_priority); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_search_channel_priority_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_SEARCH_CHANNEL_PRIORITY_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_search_waveform_set.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_search_waveform_set.c new file mode 100644 index 0000000000000000000000000000000000000000..aba67841c2c924f64819850aee85e607cb7d458c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_search_waveform_set.c @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_search_waveform_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_channel, + uint16_t * const p_waveform) +{ + uint32_t index = SER_CMD_DATA_POS; + uint32_t err_code; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_channel); + SER_ASSERT_NOT_NULL(p_waveform); + + err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint16_t_dec(p_buf, packet_len, &index, p_waveform); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, packet_len); + + return err_code; +} + +uint32_t ant_search_waveform_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_SEARCH_WAVEFORM_SET, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_stack_reset.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_stack_reset.c new file mode 100644 index 0000000000000000000000000000000000000000..dbda4bb58c6135e0bddea5708cb3cb2dc7a07033 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_stack_reset.c @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_stack_reset_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + + return op_status_enc(SVC_ANT_STACK_INIT, return_code, p_buf, p_buf_len, &index); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_version_get.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_version_get.c new file mode 100644 index 0000000000000000000000000000000000000000..64f5be41b2092fce173fc60bd4fe4139d53553e6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ant/serializers/ant_version_get.c @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ant_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ant_struct_serialization.h" +#include "app_util.h" + +uint32_t ant_version_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_version) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint32_t total_len = *p_buf_len; + + uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_VERSION, return_code, + p_buf, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (return_code != NRF_SUCCESS) + { + return NRF_SUCCESS; + } + + err_code = uint8_vector_enc(p_version, MESG_BUFFER_SIZE, p_buf, total_len, p_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return NRF_SUCCESS; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw.h new file mode 100644 index 0000000000000000000000000000000000000000..8b7031be9a94556c8f277f25e78a892c50907be6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw.h @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef _CONN_MW_H +#define _CONN_MW_H + +/** + * @addtogroup sercon_mw_s132 Connectivity middleware codecs for S132 and S140 (connectivity side) + * @{ + * @ingroup ser_codecs_mw + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Connectivity Middleware dispatcher function + * + * @details It handles decoding of the opcode from the RX buffer and based on the opcode, it searches + * for registered handler. Handler is called once it is found. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. + */ +uint32_t conn_mw_handler (uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif //_CONN_MW_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.c new file mode 100644 index 0000000000000000000000000000000000000000..b92a4e782e3b9f2de4173ea8255bc98da0cd4a03 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.c @@ -0,0 +1,407 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_conn.h" +#include "conn_mw_ble.h" +#include "ble_serialization.h" +#include "conn_ble_user_mem.h" +#include +extern sercon_ble_user_mem_t m_conn_user_mem_table[]; + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t conn_mw_ble_tx_packet_count_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t count; + uint16_t conn_handle; + uint8_t * p_count = &count; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_tx_packet_count_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_count); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_tx_packet_count_get(conn_handle, p_count); + + err_code = ble_tx_packet_count_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_count); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} +#endif +uint32_t conn_mw_ble_uuid_vs_add(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + ble_uuid128_t uuid; + ble_uuid128_t * p_uuid = &uuid; + uint8_t uuid_type; + uint8_t * p_uuid_type = &uuid_type; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_uuid_vs_add_req_dec(p_rx_buf, rx_buf_len, &p_uuid, &p_uuid_type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_uuid_vs_add(p_uuid, p_uuid_type); + + err_code = ble_uuid_vs_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_uuid_type); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + return err_code; +} + +uint32_t conn_mw_ble_uuid_decode(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t raw_uuid[16]; + uint8_t uuid_len = sizeof (raw_uuid); + uint8_t * p_raw_uuid = raw_uuid; + ble_uuid_t uuid; + ble_uuid_t * p_uuid = &uuid; + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_uuid_decode_req_dec(p_rx_buf, rx_buf_len, &uuid_len, &p_raw_uuid, &p_uuid); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_uuid_decode(uuid_len, p_raw_uuid, p_uuid); + + err_code = ble_uuid_decode_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_uuid); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_uuid_encode(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t raw_uuid[16]; + uint8_t uuid_len = sizeof (raw_uuid); + uint8_t * p_uuid_len = &uuid_len; + uint8_t * p_raw_uuid = raw_uuid; + ble_uuid_t uuid; + ble_uuid_t * p_uuid = &uuid; + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + memset(&uuid, 0, sizeof(uuid)); + err_code = ble_uuid_encode_req_dec(p_rx_buf, rx_buf_len, &p_uuid, &p_uuid_len, &p_raw_uuid); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_uuid_encode(p_uuid, p_uuid_len, p_raw_uuid); + + err_code = ble_uuid_encode_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, uuid_len, p_raw_uuid); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_version_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + ble_version_t version; + ble_version_t * p_version = &version; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_version_get_req_dec(p_rx_buf, rx_buf_len, &p_version); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_version_get(p_version); + + err_code = ble_version_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_version); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} +uint32_t conn_mw_ble_opt_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t opt_id; + ble_opt_t opt; + ble_opt_t *p_opt = &opt; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_opt_get_req_dec(p_rx_buf, rx_buf_len, &opt_id, &p_opt); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + uint16_t act_latency; + uint8_t passkey[BLE_GAP_PASSKEY_LEN]; + /* Initialaize appropriate pointers inside opt union based on opt_id */ + switch (opt_id) + { + case BLE_GAP_OPT_LOCAL_CONN_LATENCY: + opt.gap_opt.local_conn_latency.p_actual_latency = &act_latency; + break; + case BLE_GAP_OPT_PASSKEY: + opt.gap_opt.passkey.p_passkey = passkey; + break; + } + sd_err_code = sd_ble_opt_get(opt_id, p_opt); + + err_code = ble_opt_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, opt_id, p_opt); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t opt_id = 0xFFFFFFFF; + uint16_t act_latency; + uint8_t passkey[BLE_GAP_PASSKEY_LEN]; + uint32_t err_code = NRF_SUCCESS; + + /* Pre-decode type of ble_opt_t union */ + err_code = ble_opt_id_pre_dec(p_rx_buf, rx_buf_len, &opt_id); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + ble_opt_t opt; + ble_opt_t *p_opt = &opt; + /* Initialaize appropriate pointers inside opt union based on opt_id */ + switch (opt_id) + { + case BLE_GAP_OPT_LOCAL_CONN_LATENCY: + opt.gap_opt.local_conn_latency.p_actual_latency = &act_latency; + break; + case BLE_GAP_OPT_PASSKEY: + opt.gap_opt.passkey.p_passkey = passkey; + break; + } + + uint32_t sd_err_code; + + err_code = ble_opt_set_req_dec(p_rx_buf, rx_buf_len, &opt_id, &p_opt); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_opt_set(opt_id, p_opt); + + err_code = ble_opt_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_enable(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t app_ram_base; + +/*lint --e{10} --e{19} --e{27} --e{40} --e{529} -save suppress Error 27: Illegal character */ +#if defined(_WIN32) || defined(__unix) || defined(__APPLE__) + uint32_t ram_start = 0; +#elif defined ( __CC_ARM ) + extern uint32_t Image$$RW_IRAM1$$Base; + volatile uint32_t ram_start = (uint32_t) &Image$$RW_IRAM1$$Base; +#elif defined ( __ICCARM__ ) + extern uint32_t __ICFEDIT_region_RAM_start__; + volatile uint32_t ram_start = (uint32_t) &__ICFEDIT_region_RAM_start__; +#elif defined ( __GNUC__ ) + extern uint32_t __data_start__; + volatile uint32_t ram_start = (uint32_t) &__data_start__; +#endif + app_ram_base = ram_start; + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + ble_enable_params_t params; + ble_enable_params_t * p_params = ¶ms; + ble_conn_bw_counts_t conn_bw_counts; + params.common_enable_params.p_conn_bw_counts = &conn_bw_counts; + + uint8_t gap_device_name_value[BLE_GAP_DEVNAME_MAX_LEN]; + ble_gap_device_name_t device_name; + device_name.max_len = BLE_GAP_DEVNAME_MAX_LEN; + device_name.p_value = gap_device_name_value; + params.gap_enable_params.p_device_name = &device_name; + + err_code = ble_enable_req_dec(p_rx_buf, rx_buf_len, &p_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_enable(p_params, &app_ram_base); +#else + err_code = ble_enable_req_dec(p_rx_buf, rx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_enable(&app_ram_base); +#endif + + err_code = ble_enable_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_user_mem_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + ble_user_mem_block_t mem_block; + ble_user_mem_block_t * p_mem_block = &mem_block; + uint32_t err_code = NRF_SUCCESS; + uint32_t user_mem_tab_index; + uint16_t conn_handle; + /* Allocate user memory context for SoftDevice */ + + uint32_t sd_err_code; + + err_code = ble_user_mem_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_mem_block); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (p_mem_block != NULL) + { + //Use the context if p_mem_block was not null + err_code = conn_ble_user_mem_context_create(&user_mem_tab_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + m_conn_user_mem_table[user_mem_tab_index].conn_handle = conn_handle; + m_conn_user_mem_table[user_mem_tab_index].mem_block.len = p_mem_block->len; + p_mem_block = &(m_conn_user_mem_table[user_mem_tab_index].mem_block); + } + + sd_err_code = sd_ble_user_mem_reply(conn_handle, p_mem_block); + + err_code = ble_user_mem_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t conn_mw_ble_cfg_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t app_ram_base; + +/*lint --e{10} --e{19} --e{27} --e{40} --e{529} -save suppress Error 27: Illegal character */ +#if defined(_WIN32) || defined(__unix) || defined(__APPLE__) + uint32_t ram_start = 0; +#elif defined ( __CC_ARM ) + extern uint32_t Image$$RW_IRAM1$$Base; + volatile uint32_t ram_start = (uint32_t) &Image$$RW_IRAM1$$Base; +#elif defined ( __ICCARM__ ) + extern uint32_t __ICFEDIT_region_RAM_start__; + volatile uint32_t ram_start = (uint32_t) &__ICFEDIT_region_RAM_start__; +#elif defined ( __GNUC__ ) + extern uint32_t __data_start__; + volatile uint32_t ram_start = (uint32_t) &__data_start__; +#endif + app_ram_base = ram_start; + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + uint32_t cfg_id; + ble_cfg_t cfg; + uint8_t gap_device_name_value[BLE_GAP_DEVNAME_MAX_LEN]; + cfg.gap_cfg.device_name_cfg.p_value = gap_device_name_value; + cfg.gap_cfg.device_name_cfg.max_len = BLE_GAP_DEVNAME_MAX_LEN; + ble_cfg_t * p_cfg = &cfg; + + err_code = ble_cfg_set_req_dec(p_rx_buf, rx_buf_len, &cfg_id, &p_cfg); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_cfg_set(cfg_id,p_cfg, app_ram_base); + + err_code = ble_cfg_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.h new file mode 100644 index 0000000000000000000000000000000000000000..7c89ae2c04c6bf556fba5a81e4c0f590f34d4a71 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.h @@ -0,0 +1,242 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef _CONN_MW_BLE_H +#define _CONN_MW_BLE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup sercon_mw_s132_ble Middleware command handlers + * @{ + * @ingroup sercon_mw_s132 + */ + +/**@brief Handles sd_ble_tx_packet_count_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_tx_packet_count_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_uuid_vs_add command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_uuid_vs_add(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_uuid_decode command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_uuid_decode(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_uuid_encode command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_uuid_encode(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_version_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_version_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_opt_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_opt_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_opt_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_enable command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_enable(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_user_mem_reply command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_user_mem_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); +#if NRF_SD_BLE_API_VERSION >= 4 +/**@brief Handles @ref sd_ble_cfg_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_cfg_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); +#endif + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif //_CONN_MW_BLE_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.c new file mode 100644 index 0000000000000000000000000000000000000000..1864afba140021d2ef9813dce1806bbbab71b48e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.c @@ -0,0 +1,1142 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gap_conn.h" +#include "conn_mw_ble_gap.h" +#include "ble_serialization.h" +#include "conn_ble_gap_sec_keys.h" +#include + +extern ser_ble_gap_conn_keyset_t m_conn_keys_table[SER_MAX_CONNECTIONS]; + +uint32_t conn_mw_ble_gap_connect(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + ble_gap_addr_t addr; + ble_gap_addr_t * p_addr = &addr; + + ble_gap_scan_params_t scan_params; + ble_gap_scan_params_t * p_scan_params = &scan_params; + + ble_gap_conn_params_t conn_params; + ble_gap_conn_params_t * p_conn_params = &conn_params; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + +#if NRF_SD_BLE_API_VERSION >= 4 + uint8_t conn_cfg_tag; + err_code = ble_gap_connect_req_dec(p_rx_buf, rx_buf_len, &p_addr, + &p_scan_params, &p_conn_params, &conn_cfg_tag); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_connect(p_addr, p_scan_params, p_conn_params, conn_cfg_tag); +#else + err_code = ble_gap_connect_req_dec(p_rx_buf, rx_buf_len, &p_addr, + &p_scan_params, &p_conn_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_connect(p_addr, p_scan_params, p_conn_params); +#endif + + err_code = ble_gap_connect_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_connect_cancel(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + sd_err_code = sd_ble_gap_connect_cancel(); + + err_code = ble_gap_connect_cancel_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_scan_start(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + ble_gap_scan_params_t scan_params; + ble_gap_scan_params_t * p_scan_params = &scan_params; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_scan_start_req_dec(p_rx_buf, rx_buf_len, &p_scan_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_scan_start(p_scan_params); + + err_code = ble_gap_scan_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_adv_data_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t data[BLE_GAP_ADV_MAX_SIZE]; + uint8_t * p_data = data; + uint8_t dlen = sizeof (data); + + uint8_t sr_data[BLE_GAP_ADV_MAX_SIZE]; + uint8_t * p_sr_data = sr_data; + uint8_t srdlen = sizeof (sr_data); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_adv_data_set_req_dec(p_rx_buf, + rx_buf_len, + &p_data, + &dlen, + &p_sr_data, + &srdlen); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_adv_data_set(p_data, dlen, p_sr_data, srdlen); + + err_code = ble_gap_adv_data_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_adv_start(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + ble_gap_addr_t peer_addr; + ble_gap_adv_params_t adv_params; + ble_gap_adv_params_t * p_adv_params; + + adv_params.p_peer_addr = &peer_addr; + p_adv_params = &adv_params; + +#if NRF_SD_BLE_API_VERSION >= 4 + uint8_t conn_cfg_tag; + err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &p_adv_params, &conn_cfg_tag); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_adv_start(p_adv_params, conn_cfg_tag); +#else + err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &p_adv_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_adv_start(p_adv_params); +#endif + err_code = ble_gap_adv_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_adv_stop(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + sd_err_code = sd_ble_gap_adv_stop(); + + err_code = ble_gap_adv_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_conn_param_update(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + ble_gap_conn_params_t conn_params; + ble_gap_conn_params_t * p_conn_params = &conn_params; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_conn_param_update_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_conn_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_conn_param_update(conn_handle, p_conn_params); + + err_code = ble_gap_conn_param_update_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_disconnect(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint8_t hci_status_code; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_disconnect_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &hci_status_code); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_disconnect(conn_handle, hci_status_code); + + err_code = ble_gap_disconnect_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_tx_power_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + int8_t tx_power; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_tx_power_set_req_dec(p_rx_buf, rx_buf_len, &tx_power); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_tx_power_set(tx_power); + + err_code = ble_gap_tx_power_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_appearance_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t appearance; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_appearance_set_req_dec(p_rx_buf, rx_buf_len, &appearance); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_appearance_set(appearance); + + err_code = ble_gap_appearance_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_appearance_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t appearance; + uint16_t * p_appearance = &appearance; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_appearance_get_req_dec(p_rx_buf, rx_buf_len, &p_appearance); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_appearance_get(p_appearance); + + err_code = ble_gap_appearance_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_appearance); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + + +uint32_t conn_mw_ble_gap_ppcp_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + ble_gap_conn_params_t conn_params; + ble_gap_conn_params_t * p_conn_params = &conn_params; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_ppcp_set_req_dec(p_rx_buf, rx_buf_len, &p_conn_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_ppcp_set(p_conn_params); + + err_code = ble_gap_ppcp_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_ppcp_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + ble_gap_conn_params_t conn_params; + ble_gap_conn_params_t * p_conn_params = &conn_params; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_ppcp_get_req_dec(p_rx_buf, rx_buf_len, &p_conn_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_ppcp_get(p_conn_params); + + err_code = ble_gap_ppcp_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_conn_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_device_name_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint8_t dev_name[BLE_GAP_DEVNAME_MAX_LEN]; + uint8_t * p_dev_name = dev_name; + + uint16_t len; + uint16_t * p_len = &len; + + err_code = ble_gap_device_name_get_req_dec(p_rx_buf, rx_buf_len, &p_dev_name, &p_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_device_name_get(p_dev_name, p_len); + + err_code = ble_gap_device_name_get_rsp_enc(sd_err_code, p_dev_name, p_len, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_device_name_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + ble_gap_conn_sec_mode_t write_perm; + ble_gap_conn_sec_mode_t * p_write_perm = &write_perm; + + uint8_t dev_name[BLE_GAP_DEVNAME_MAX_LEN]; + uint8_t * p_dev_name = dev_name; + + uint16_t len = BLE_GAP_DEVNAME_MAX_LEN; + + err_code = ble_gap_device_name_set_req_dec(p_rx_buf, + rx_buf_len, + &p_write_perm, + &p_dev_name, + &len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_device_name_set(p_write_perm, p_dev_name, len); + + err_code = ble_gap_device_name_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_authenticate(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + + ble_gap_sec_params_t sec_params; + ble_gap_sec_params_t * p_sec_params = &sec_params; + + err_code = ble_gap_authenticate_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sec_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params); + + err_code = ble_gap_authenticate_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_sec_params_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + uint32_t sec_tab_index = 0; + + uint16_t * p_conn_handle; + uint8_t sec_status; + + ble_gap_sec_params_t sec_params; + ble_gap_sec_params_t * p_sec_params = &sec_params; + + // Allocate global security context for soft device + err_code = conn_ble_gap_sec_context_create(&sec_tab_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + p_conn_handle = &(m_conn_keys_table[sec_tab_index].conn_handle); + + // Set up global structure for command decoder + ble_gap_sec_keyset_t * p_sec_keyset = &(m_conn_keys_table[sec_tab_index].keyset); + + p_sec_keyset->keys_own.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_own); + p_sec_keyset->keys_own.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_own); + p_sec_keyset->keys_own.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_own); + p_sec_keyset->keys_own.p_pk = &(m_conn_keys_table[sec_tab_index].pk_own); + p_sec_keyset->keys_peer.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_peer); + p_sec_keyset->keys_peer.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_peer); + p_sec_keyset->keys_peer.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_peer); + p_sec_keyset->keys_peer.p_pk = &(m_conn_keys_table[sec_tab_index].pk_peer); + + err_code = ble_gap_sec_params_reply_req_dec(p_rx_buf, + rx_buf_len, + p_conn_handle, + &sec_status, + &p_sec_params, + &p_sec_keyset); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (p_sec_keyset == NULL) + { + //If no keyset was sent destroy the context. + err_code = conn_ble_gap_sec_context_destroy(*p_conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + sd_err_code = sd_ble_gap_sec_params_reply(*p_conn_handle, sec_status, p_sec_params, p_sec_keyset); + + err_code = ble_gap_sec_params_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_sec_keyset); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_auth_key_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + uint8_t key_type; + + uint8_t key[BLE_GAP_SEC_KEY_LEN]; + uint8_t * p_key = key; + + err_code = ble_gap_auth_key_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &key_type, &p_key); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_auth_key_reply(conn_handle, key_type, p_key); + + err_code = ble_gap_auth_key_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_sec_info_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + + ble_gap_enc_info_t enc_info; + ble_gap_enc_info_t * p_enc_info = &enc_info; + + ble_gap_irk_t id_info; + ble_gap_irk_t * p_id_info = &id_info; + + ble_gap_sign_info_t sign_info; + ble_gap_sign_info_t * p_sign_info = &sign_info; + + err_code = ble_gap_sec_info_reply_req_dec(p_rx_buf, + rx_buf_len, + &conn_handle, + &p_enc_info, + &p_id_info, + &p_sign_info); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_sec_info_reply(conn_handle, p_enc_info, p_id_info, p_sign_info); + + err_code = ble_gap_sec_info_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_conn_sec_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + + ble_gap_conn_sec_t conn_sec; + ble_gap_conn_sec_t * p_conn_sec = &conn_sec; + + err_code = ble_gap_conn_sec_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_conn_sec); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_conn_sec_get(conn_handle, p_conn_sec); + + err_code = ble_gap_conn_sec_get_rsp_enc(sd_err_code, p_conn_sec, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_rssi_start(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + uint8_t threshold_dbm; + uint8_t skip_count; + + err_code = ble_gap_rssi_start_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &threshold_dbm, &skip_count); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_rssi_start(conn_handle, threshold_dbm, skip_count); + + err_code = ble_gap_rssi_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_rssi_stop(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + + err_code = ble_gap_rssi_stop_req_dec(p_rx_buf, rx_buf_len, &conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_rssi_stop(conn_handle); + + err_code = ble_gap_rssi_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_scan_stop(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + sd_err_code = sd_ble_gap_scan_stop(); + + err_code = ble_gap_scan_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_encrypt(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + + ble_gap_master_id_t master_id; + ble_gap_master_id_t *p_master_id = &master_id; + + ble_gap_enc_info_t enc_info; + ble_gap_enc_info_t *p_enc_info = &enc_info; + + err_code = ble_gap_encrypt_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_master_id, &p_enc_info); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_encrypt(conn_handle, p_master_id, p_enc_info); + + err_code = ble_gap_encrypt_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_rssi_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + int8_t rssi; + int8_t * p_rssi = &rssi; + + err_code = ble_gap_rssi_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_rssi); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_rssi_get(conn_handle, p_rssi); + + err_code = ble_gap_rssi_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, rssi); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_keypress_notify(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + uint8_t kp_not; + + err_code = ble_gap_keypress_notify_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &kp_not); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_keypress_notify(conn_handle, kp_not); + + err_code = ble_gap_keypress_notify_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_lesc_dhkey_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + ble_gap_lesc_dhkey_t dhkey; + ble_gap_lesc_dhkey_t * p_dhkey = &dhkey; + + err_code = ble_gap_lesc_dhkey_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_dhkey); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_lesc_dhkey_reply(conn_handle, p_dhkey); + + err_code = ble_gap_lesc_dhkey_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_lesc_oob_data_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + ble_gap_lesc_oob_data_t own; + ble_gap_lesc_oob_data_t peer; + ble_gap_lesc_oob_data_t * p_own = &own; + ble_gap_lesc_oob_data_t * p_peer = &peer; + + err_code = ble_gap_lesc_oob_data_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_own, &p_peer); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_lesc_oob_data_set(conn_handle, p_own, p_peer); + + err_code = ble_gap_lesc_oob_data_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_lesc_oob_data_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + ble_gap_lesc_oob_data_t own; + ble_gap_lesc_oob_data_t * p_own = &own; + ble_gap_lesc_p256_pk_t pk; + ble_gap_lesc_p256_pk_t * p_pk = &pk; + + err_code = ble_gap_lesc_oob_data_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_pk, &p_own); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + sd_err_code = sd_ble_gap_lesc_oob_data_get(conn_handle, p_pk, p_own); + + err_code = ble_gap_lesc_oob_data_get_rsp_enc(sd_err_code, p_own, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_addr_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + ble_gap_addr_t addr; + ble_gap_addr_t * p_addr = &addr; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_addr_set_req_dec(p_rx_buf, rx_buf_len, &p_addr); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_addr_set(p_addr); + + err_code = ble_gap_addr_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} +uint32_t conn_mw_ble_gap_addr_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + ble_gap_addr_t addr; + ble_gap_addr_t * p_addr = &addr; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_addr_get_req_dec(p_rx_buf, rx_buf_len, &p_addr); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_addr_get(p_addr); + + err_code = ble_gap_addr_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_addr); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_privacy_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + ble_gap_privacy_params_t privacy_params; + ble_gap_privacy_params_t * p_privacy_params = &privacy_params; + + ble_gap_irk_t irk; + privacy_params.p_device_irk = &irk; + + err_code = ble_gap_privacy_set_req_dec(p_rx_buf, rx_buf_len, &p_privacy_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_privacy_set(p_privacy_params); + + err_code = ble_gap_privacy_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + + +uint32_t conn_mw_ble_gap_privacy_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + ble_gap_privacy_params_t privacy_params; + ble_gap_privacy_params_t * p_privacy_params = &privacy_params; + + ble_gap_irk_t irk; + privacy_params.p_device_irk = &irk; + + err_code = ble_gap_privacy_get_req_dec(p_rx_buf, rx_buf_len, &p_privacy_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_privacy_get(p_privacy_params); + + err_code = ble_gap_privacy_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_privacy_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_whitelist_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint8_t length; + ble_gap_addr_t wl_addr_array[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + ble_gap_addr_t * p_wl_addrs_array[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + + for (uint8_t i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; ++i) + { + p_wl_addrs_array[i] = &wl_addr_array[i]; + } + + ble_gap_addr_t * * pp_wl_addrs = p_wl_addrs_array; + + err_code = ble_gap_whitelist_set_req_dec(p_rx_buf, rx_buf_len, &pp_wl_addrs, &length); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + sd_err_code = sd_ble_gap_whitelist_set((ble_gap_addr_t const * *)pp_wl_addrs, length); + + err_code = ble_gap_whitelist_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_device_identities_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint8_t length; + ble_gap_id_key_t id_key_array[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + ble_gap_id_key_t * p_id_key_array[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + ble_gap_irk_t irk_array[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + ble_gap_irk_t * p_irk_array[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + + for (uint8_t i = 0; i < BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT; ++i) + { + p_id_key_array[i] = &id_key_array[i]; + p_irk_array[i] = &irk_array[i]; + } + + ble_gap_id_key_t * * pp_id_keys = p_id_key_array; + ble_gap_irk_t * * pp_local_irks = p_irk_array; + + err_code = ble_gap_device_identities_set_req_dec(p_rx_buf, rx_buf_len, + &pp_id_keys, + &pp_local_irks, + &length); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_device_identities_set((ble_gap_id_key_t const * *) pp_id_keys, + (ble_gap_irk_t const * *) pp_local_irks, + length); + + err_code = ble_gap_device_identities_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +#if NRF_SD_BLE_API_VERSION >= 5 +uint32_t conn_mw_ble_gap_phy_request(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + + ble_gap_phys_t gap_phys; + ble_gap_phys_t * p_gap_phys = &gap_phys; + + err_code = ble_gap_phy_request_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_gap_phys); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_phy_request(conn_handle, p_gap_phys); + + err_code = ble_gap_phy_request_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} +#endif + +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t conn_mw_ble_gap_data_length_update(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + ble_gap_data_length_params_t dl_params; + ble_gap_data_length_params_t * p_dl_params = &dl_params; + ble_gap_data_length_limitation_t dl_limitation; + ble_gap_data_length_limitation_t * p_dl_limitation = &dl_limitation; + + err_code = ble_gap_data_length_update_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_dl_params, &p_dl_limitation); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_data_length_update(conn_handle, p_dl_params,p_dl_limitation ); + + err_code = ble_gap_data_length_update_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_dl_limitation); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.h new file mode 100644 index 0000000000000000000000000000000000000000..102428951e62a75744c00de8cb17263e236903d0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.h @@ -0,0 +1,766 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef _CONN_MW_BLE_GAP_H +#define _CONN_MW_BLE_GAP_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup sercon_mw_s132_ble_gap GAP Middleware command handlers + * @{ + * @ingroup sercon_mw_s132 + */ + +/**@brief Handles @ref sd_ble_gap_adv_data_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_adv_data_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_adv_start command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_adv_start(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_adv_stop command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_adv_stop(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_conn_param_update command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_conn_param_update(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_disconnect command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_disconnect(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_tx_power_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_tx_power_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_appearance_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_appearance_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_appearance_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_appearance_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_ppcp_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_ppcp_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_ppcp_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_ppcp_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_device_name_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_device_name_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_device_name_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_device_name_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_authenticate command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_authenticate(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_sec_params_reply command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_sec_params_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_auth_key_reply command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_auth_key_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_sec_info_reply command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_sec_info_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_conn_sec_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_conn_sec_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_rssi_start command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_rssi_start(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_rssi_stop command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_rssi_stop(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_rssi_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_rssi_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_connect command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_connect(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_connect_cancel command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_connect_cancel(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_scan_start command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_scan_start(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_scan_stop command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_scan_stop(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_encrypt command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ + +uint32_t conn_mw_ble_gap_encrypt(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_keypress_notify command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ + +uint32_t conn_mw_ble_gap_keypress_notify(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_lesc_dhkey_reply command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ + +uint32_t conn_mw_ble_gap_lesc_dhkey_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_lesc_oob_data_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ + +uint32_t conn_mw_ble_gap_lesc_oob_data_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_lesc_oob_data_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ + +uint32_t conn_mw_ble_gap_lesc_oob_data_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Allocates instance in m_conn_keys_table[] for storage of encryption keys. + * + * @param[in] conn_handle Connection handle. + * @param[out] p_index Pointer to the index of allocated instance. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_NO_MEM No free instance available. + */ +uint32_t conn_mw_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index); + +/**@brief Releases the instance identified by a connection handle. + * + * @param[in] conn_handle Connection handle. + + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_NOT_FOUND Instance with the @p conn_handle not found. + */ +uint32_t conn_mw_ble_gap_sec_context_destroy(uint16_t conn_handle); + +/**@brief Finds index of instance identified by a connection handle in m_conn_keys_table[]. + * + * @param[in] conn_handle Connection handle. + * @param[out] p_index Pointer to the index of the context instance. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_NOT_FOUND Instance with the @p conn_handle not found. + */ +uint32_t conn_mw_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); + +/**@brief Handles @ref sd_ble_gap_addr_set command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_addr_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_addr_get command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_addr_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_privacy_set command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_privacy_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_privacy_get command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_privacy_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_whitelist_set command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_whitelist_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_device_identities_set command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_device_identities_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_phy_request command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ + +#if NRF_SD_BLE_API_VERSION >= 5 +uint32_t conn_mw_ble_gap_phy_request(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); +#endif +#ifdef __cplusplus +} +#endif + +#if NRF_SD_BLE_API_VERSION >= 4 +/**@brief Handles @ref sd_ble_data_length_update command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_data_length_update(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + + +#endif +#endif //_CONN_MW_BLE_GAP_H + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.c new file mode 100644 index 0000000000000000000000000000000000000000..21f804a945e01d84780768d44e2257f3b07b2ff1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.c @@ -0,0 +1,390 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gattc_conn.h" +#include "conn_mw_ble_gattc.h" +#include "ble_serialization.h" + +#if defined(BLE_GATT_MTU_SIZE_DEFAULT) && !defined(GATT_MTU_SIZE_DEFAULT) +#define GATT_MTU_SIZE_DEFAULT BLE_GATT_MTU_SIZE_DEFAULT +#endif + +#if defined(BLE_GATT_ATT_MTU_DEFAULT) && !defined(GATT_MTU_SIZE_DEFAULT) +#define GATT_MTU_SIZE_DEFAULT BLE_GATT_ATT_MTU_DEFAULT +#endif +/** Maximum length of p_value in \ref ble_gattc_write_params_t. See Bluetooth 4.0 spec: 3.4.5.1 and + * 3.4.5.3. */ +#define BLE_GATTC_WRITE_P_VALUE_LEN_MAX (GATT_MTU_SIZE_DEFAULT - 3) + +/** See Bluetooth 4.0 spec: 3.4.4.7. */ +#define BLE_GATTC_HANDLE_COUNT_LEN_MAX ((GATT_MTU_SIZE_DEFAULT - 1) / 2) + +uint32_t conn_mw_ble_gattc_primary_services_discover(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t start_handle; + ble_uuid_t srvc_uuid; + ble_uuid_t * p_srvc_uuid = &srvc_uuid; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gattc_primary_services_discover_req_dec(p_rx_buf, + rx_buf_len, + &conn_handle, + &start_handle, + &p_srvc_uuid); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_primary_services_discover(conn_handle, start_handle, p_srvc_uuid); + + err_code = ble_gattc_primary_services_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gattc_relationships_discover(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + ble_gattc_handle_range_t handle_range; + ble_gattc_handle_range_t * p_handle_range = &handle_range; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gattc_relationships_discover_req_dec(p_rx_buf, rx_buf_len, + &conn_handle, &p_handle_range); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_relationships_discover(conn_handle, p_handle_range); + + err_code = ble_gattc_relationships_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gattc_characteristics_discover(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + ble_gattc_handle_range_t handle_range; + ble_gattc_handle_range_t * p_handle_range = &handle_range; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gattc_characteristics_discover_req_dec(p_rx_buf, rx_buf_len, + &conn_handle, &p_handle_range); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_characteristics_discover(conn_handle, p_handle_range); + + err_code = ble_gattc_characteristics_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gattc_descriptors_discover(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + ble_gattc_handle_range_t handle_range; + ble_gattc_handle_range_t * p_handle_range = &handle_range; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gattc_descriptors_discover_req_dec(p_rx_buf, rx_buf_len, + &conn_handle, &p_handle_range); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_descriptors_discover(conn_handle, p_handle_range); + + err_code = ble_gattc_descriptors_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gattc_char_value_by_uuid_read(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + + ble_uuid_t uuid = {0}; + ble_uuid_t * p_uuid = &uuid; + + ble_gattc_handle_range_t handle_range; + ble_gattc_handle_range_t * p_handle_range = &handle_range; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gattc_char_value_by_uuid_read_req_dec(p_rx_buf, rx_buf_len, + &conn_handle, &p_uuid, &p_handle_range); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_char_value_by_uuid_read(conn_handle, p_uuid, p_handle_range); + + err_code = ble_gattc_char_value_by_uuid_read_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gattc_read(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t * p_conn_handle = &conn_handle; + + uint16_t handle; + uint16_t * p_handle = &handle; + + uint16_t offset; + uint16_t * p_offset = &offset; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gattc_read_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, p_handle, p_offset); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_read(conn_handle, handle, offset); + + err_code = ble_gattc_read_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gattc_char_values_read(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t * p_conn_handle = &conn_handle; + + uint16_t handles[BLE_GATTC_HANDLE_COUNT_LEN_MAX]; + uint16_t * p_handles = handles; + + uint16_t handle_count = BLE_GATTC_HANDLE_COUNT_LEN_MAX; + uint16_t * p_handle_count = &handle_count; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gattc_char_values_read_req_dec(p_rx_buf, + rx_buf_len, + p_conn_handle, + &p_handles, + p_handle_count); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_char_values_read(conn_handle, p_handles, handle_count); + + err_code = ble_gattc_char_values_read_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gattc_write(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t * p_conn_handle = &conn_handle; + + uint8_t value[BLE_GATTC_WRITE_P_VALUE_LEN_MAX]; + + ble_gattc_write_params_t write_params = {0}; + ble_gattc_write_params_t * p_write_params = &write_params; + + p_write_params->len = BLE_GATTC_WRITE_P_VALUE_LEN_MAX; + p_write_params->p_value = value; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gattc_write_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, &p_write_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_write(conn_handle, p_write_params); + + err_code = ble_gattc_write_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gattc_hv_confirm(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + uint16_t * p_conn_handle = &conn_handle; + + uint16_t handle; + uint16_t * p_handle = &handle; + + err_code = ble_gattc_hv_confirm_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, p_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_hv_confirm(conn_handle, handle); + + err_code = ble_gattc_hv_confirm_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gattc_attr_info_discover(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t * p_conn_handle = &conn_handle; + + ble_gattc_handle_range_t range = {0}; + ble_gattc_handle_range_t * p_range = ⦥ + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gattc_attr_info_discover_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, &p_range); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_attr_info_discover(conn_handle, p_range); + + err_code = ble_gattc_attr_info_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gattc_exchange_mtu_request(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t client_rx_mtu; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gattc_exchange_mtu_request_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &client_rx_mtu); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_exchange_mtu_request(conn_handle, client_rx_mtu); + + err_code = ble_gattc_exchange_mtu_request_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.h new file mode 100644 index 0000000000000000000000000000000000000000..89aae5976a1c3d5f70ecd37eb1a09fdaf636c7e6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.h @@ -0,0 +1,259 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef _CONN_MW_BLE_GATTC_H + #define _CONN_MW_BLE_GATTC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup sercon_mw_s132_ble_gattc GATTC Middleware command handlers + * @{ + * @ingroup sercon_mw_s132 + */ + +/**@brief Handles @ref sd_ble_gattc_primary_services_discover command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_primary_services_discover (uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gattc_relationships_discover command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_relationships_discover(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gattc_characteristics_discover command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_characteristics_discover(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gattc_descriptors_discover command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_descriptors_discover(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gattc_char_value_by_uuid_read command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_char_value_by_uuid_read(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gattc_read command and prepares response. + * + * @param[in] rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_read (uint8_t const *const rx_buf, + uint32_t rx_buf_len, + uint8_t *const tx_buf, + uint32_t *const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gattc_char_values_read command and prepares response. + * + * @param[in] rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_char_values_read (uint8_t const *const rx_buf, + uint32_t rx_buf_len, + uint8_t *const tx_buf, + uint32_t *const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gattc_write command and prepares response. + * + * @param[in] rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_write (uint8_t const *const rx_buf, + uint32_t rx_buf_len, + uint8_t *const tx_buf, + uint32_t *const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gattc_hv_confirm command and prepares response. + * + * @param[in] rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_hv_confirm (uint8_t const *const rx_buf, + uint32_t rx_buf_len, + uint8_t *const tx_buf, + uint32_t *const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gattc_attr_info_discover command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_attr_info_discover(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gattc_exchange_mtu_request command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_exchange_mtu_request(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif //_CONN_MW_BLE_GATTC_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.c new file mode 100644 index 0000000000000000000000000000000000000000..508137eb9d0c71fef6a0adc566124b30b1a2eba7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.c @@ -0,0 +1,517 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gatts_conn.h" +#include "conn_mw_ble_gatts.h" +#include "ble_serialization.h" + +uint32_t conn_mw_ble_gatts_service_add(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint8_t type; + ble_uuid_t uuid = {0}; + ble_uuid_t * p_uuid = &uuid; + uint16_t handle; + uint16_t * p_handle = &handle; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_service_add_req_dec(p_rx_buf, rx_buf_len, &type, &p_uuid, &p_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_service_add(type, p_uuid, p_handle); + + err_code = ble_gatts_service_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_characteristic_add(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t service_handle; + + //Preparing char_md + ble_gatts_char_md_t char_md; + + uint8_t char_user_desc[BLE_GATTS_VAR_ATTR_LEN_MAX]; + ble_gatts_char_pf_t char_pf; + ble_gatts_attr_md_t user_desc_md; + ble_gatts_attr_md_t cccd_md; + ble_gatts_attr_md_t sccd_md; + + char_md.char_user_desc_size = sizeof (char_user_desc); + char_md.p_char_user_desc = char_user_desc; + char_md.p_char_pf = &char_pf; + char_md.p_user_desc_md = &user_desc_md; + char_md.p_cccd_md = &cccd_md; + char_md.p_sccd_md = &sccd_md; + + ble_gatts_char_md_t * p_char_md = &char_md; + + //Preparing attr_char_value + ble_gatts_attr_t attr_char_value; + ble_uuid_t uuid; + ble_gatts_attr_md_t attr_md; + uint8_t value[BLE_GATTS_VAR_ATTR_LEN_MAX]; + + attr_char_value.p_uuid = &uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = sizeof (value); + attr_char_value.p_value = value; + + ble_gatts_attr_t * p_attr_char_value = &attr_char_value; + + //Preparing handles + ble_gatts_char_handles_t handles; + ble_gatts_char_handles_t * p_handles = &handles; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_characteristic_add_req_dec(p_rx_buf, rx_buf_len, &service_handle, + &p_char_md, &p_attr_char_value, &p_handles); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_characteristic_add(service_handle, p_char_md, + p_attr_char_value, p_handles); + + err_code = ble_gatts_characteristic_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, + p_handles); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; + +} + +uint32_t conn_mw_ble_gatts_include_add(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t service_handle; + uint16_t inc_srvc_handle; + uint16_t handle; + uint16_t * p_handle = &handle; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_include_add_req_dec(p_rx_buf, rx_buf_len, &service_handle, + &inc_srvc_handle, &p_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_include_add(service_handle, inc_srvc_handle, p_handle); + + err_code = ble_gatts_include_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_descriptor_add(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t char_handle; + uint8_t attr_value[BLE_GATTS_VAR_ATTR_LEN_MAX]; + ble_uuid_t char_uuid; + ble_gatts_attr_md_t metadata; + ble_gatts_attr_t attr; + ble_gatts_attr_t * p_attr = &attr; + + attr.p_uuid = &char_uuid; + attr.p_attr_md = &metadata; + attr.p_value = attr_value; + attr.init_len = sizeof (attr_value); + + uint16_t handle; + uint16_t * p_handle = &handle; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_descriptor_add_req_dec(p_rx_buf, rx_buf_len, &char_handle, &p_attr, + &p_handle); + + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_descriptor_add(char_handle, p_attr, p_handle); + + err_code = ble_gatts_descriptor_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_value_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t handle; + uint8_t attr_val_table[BLE_GATTS_VAR_ATTR_LEN_MAX]; + ble_gatts_value_t attr_val = + { + .len = sizeof (attr_val_table), + .offset = 0, + .p_value = attr_val_table + }; + ble_gatts_value_t * p_attr_val = &attr_val; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_value_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &handle, &p_attr_val); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_value_set(conn_handle, handle, p_attr_val); + + err_code = ble_gatts_value_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_attr_val); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_value_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t handle; + uint8_t val[BLE_GATTS_VAR_ATTR_LEN_MAX]; + ble_gatts_value_t attr_value; + ble_gatts_value_t * p_attr_value = &attr_value; + + attr_value.p_value = val; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_value_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &handle, &p_attr_value); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + sd_err_code = sd_ble_gatts_value_get(conn_handle, handle, p_attr_value); + + err_code = ble_gatts_value_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_attr_value); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_hvx(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint8_t data[BLE_GATTS_VAR_ATTR_LEN_MAX]; + uint8_t * p_data = data; + uint16_t len = sizeof data; + uint16_t * p_len = &len; + + ble_gatts_hvx_params_t hvx_params; + ble_gatts_hvx_params_t * p_hvx_params = &hvx_params; + + hvx_params.p_len = p_len; + hvx_params.p_data = p_data; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_hvx_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_hvx_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + sd_err_code = sd_ble_gatts_hvx(conn_handle, p_hvx_params); + + p_len = (p_hvx_params) ? p_hvx_params->p_len : NULL; + err_code = ble_gatts_hvx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_service_changed(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_service_changed_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &start_handle, + &end_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_service_changed(conn_handle, start_handle, end_handle); + + err_code = ble_gatts_service_changed_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_rw_authorize_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + + uint8_t data[BLE_GATTS_VAR_ATTR_LEN_MAX]; + ble_gatts_rw_authorize_reply_params_t auth_params; + ble_gatts_rw_authorize_reply_params_t * p_auth_params = &auth_params; + + auth_params.params.read.p_data = data; + auth_params.params.read.len = sizeof (data); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_rw_authorize_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, + &p_auth_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_rw_authorize_reply(conn_handle, p_auth_params); + + err_code = ble_gatts_rw_authorize_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_sys_attr_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + + uint8_t sys_attr[BLE_GATTS_VAR_ATTR_LEN_MAX]; + + uint8_t * p_sys_attr = sys_attr; + uint16_t sys_attr_len = sizeof (sys_attr); + + uint32_t flags; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_sys_attr_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sys_attr, + &sys_attr_len, &flags); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_sys_attr_set(conn_handle, p_sys_attr, sys_attr_len, flags); + + err_code = ble_gatts_sys_attr_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_sys_attr_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + + uint8_t sys_attr[BLE_GATTS_VAR_ATTR_LEN_MAX]; + + uint8_t * p_sys_attr = sys_attr; + uint16_t sys_attr_len = sizeof (sys_attr); + uint16_t * p_sys_attr_len = &sys_attr_len; + + uint32_t flags; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_sys_attr_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sys_attr, + &p_sys_attr_len, &flags); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_sys_attr_get(conn_handle, p_sys_attr, p_sys_attr_len, flags); + + err_code = ble_gatts_sys_attr_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_sys_attr, + p_sys_attr_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_attr_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t handle; + + ble_gatts_attr_md_t md; + ble_gatts_attr_md_t * p_md = &md; + ble_uuid_t uuid; + ble_uuid_t * p_uuid = &uuid; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_attr_get_req_dec(p_rx_buf, rx_buf_len, &handle, &p_uuid, &p_md); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_attr_get(handle, p_uuid, p_md); + + err_code = ble_gatts_attr_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_uuid, p_md); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_initial_user_handle_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t handle; + uint16_t * p_handle = &handle; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_initial_user_handle_get_req_dec(p_rx_buf, rx_buf_len, &p_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_initial_user_handle_get(p_handle); + + err_code = ble_gatts_initial_user_handle_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_exchange_mtu_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t * p_conn_handle = &conn_handle; + uint16_t server_rx_mtu; + uint16_t * p_server_rx_mtu = &server_rx_mtu; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_exchange_mtu_reply_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, p_server_rx_mtu); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_exchange_mtu_reply(conn_handle, server_rx_mtu); + + err_code = ble_gatts_exchange_mtu_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.h new file mode 100644 index 0000000000000000000000000000000000000000..2fc8df96cc4f10e08c44b24d584a43b621e147e2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.h @@ -0,0 +1,314 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef _CONN_MW_BLE_GATTS_H +#define _CONN_MW_BLE_GATTS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup sercon_mw_s132_ble_gatts GATTS Middleware command handlers + * @{ + * @ingroup sercon_mw_s132 + */ + +/**@brief Handles @ref sd_ble_gatts_service_add command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_service_add (uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gatts_characteristic_add command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_characteristic_add(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_include_add command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_include_add (uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_descriptor_add command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_descriptor_add(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_value_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_value_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_value_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_value_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_hvx command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_hvx(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_service_changed command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_service_changed(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_rw_authorize_reply command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_rw_authorize_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_sys_attr_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_sys_attr_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_sys_attr_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_sys_attr_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_attr_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_attr_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_initial_user_handle_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_initial_user_handle_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_exchange_mtu_reply command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_exchange_mtu_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif //_CONN_MW_BLE_GATTS_H + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.c new file mode 100644 index 0000000000000000000000000000000000000000..a99d815e50216a36aae762a0fdf38752da8801f5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.c @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_l2cap_conn.h" +#include "conn_mw_ble_l2cap.h" +#include "ble_serialization.h" + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t conn_mw_ble_l2cap_cid_register(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t cid; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_l2cap_cid_register_req_dec(p_rx_buf, rx_buf_len, &cid); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_l2cap_cid_register(cid); + + err_code = ble_l2cap_cid_register_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_l2cap_cid_unregister(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t cid; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_l2cap_cid_unregister_req_dec(p_rx_buf, rx_buf_len, &cid); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_l2cap_cid_unregister(cid); + + err_code = ble_l2cap_cid_unregister_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_l2cap_tx(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + ble_l2cap_header_t l2cap_header; + ble_l2cap_header_t * p_l2cap_header = &l2cap_header; + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + uint8_t const * p_data = NULL; + + err_code = ble_l2cap_tx_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_l2cap_header, &p_data); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_l2cap_tx(conn_handle, p_l2cap_header, p_data); + + err_code = ble_l2cap_tx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.h new file mode 100644 index 0000000000000000000000000000000000000000..6dffb1d5d22f3a251d32a59295af0905feba125b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.h @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef _CONN_MW_BLE_L2CAP_H_ +#define _CONN_MW_BLE_L2CAP_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup sercon_mw_s132_ble_l2cap L2CAP Middleware command handlers + * @{ + * @ingroup sercon_mw_s132 + */ + +/**@brief Handles sd_ble_l2cap_cid_register command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_l2cap_cid_register(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles sd_ble_l2cap_cid_unregister command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_l2cap_cid_unregister(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles sd_ble_l2cap_tx command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_l2cap_tx(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_conn.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_conn.c new file mode 100644 index 0000000000000000000000000000000000000000..f306101c3c3df8fdda8e4872d87727604ff15ea9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_conn.c @@ -0,0 +1,539 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "ble_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "ble_gatt_struct_serialization.h" +#include "ble_gattc_struct_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "app_util.h" + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_enable_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_enable_params_t * * const pp_ble_enable_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_ENABLE); + SER_PULL_COND(pp_ble_enable_params, ble_enable_params_t_dec); + SER_REQ_DEC_END; +} +#else +uint32_t ble_enable_req_dec(uint8_t const * const p_buf, + uint32_t packet_len) +{ + SER_REQ_DEC_BEGIN(SD_BLE_ENABLE); + SER_REQ_DEC_END; +} +#endif + +uint32_t ble_enable_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_ENABLE); +} + + +uint32_t ble_opt_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint32_t * const p_opt_id, + ble_opt_t **const pp_opt ) +{ + SER_REQ_DEC_BEGIN(SD_BLE_OPT_GET); + + SER_ASSERT_NOT_NULL(p_opt_id); + SER_ASSERT_NOT_NULL(pp_opt); + SER_ASSERT_NOT_NULL(*pp_opt); + + SER_PULL_uint32(p_opt_id); + + SER_PULL_COND(pp_opt, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_opt_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint32_t opt_id, + ble_opt_t const * const p_opt) +{ + SER_RSP_ENC_BEGIN(SD_BLE_OPT_GET); + + SER_ASSERT_NOT_NULL(p_opt); + + SER_PUSH_uint32(&opt_id); + + field_encoder_handler_t fp_encoder = NULL; + void const * p_struct = NULL; + + switch (opt_id) + { +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_COMMON_OPT_CONN_BW: + fp_encoder = ble_common_opt_conn_bw_t_enc; + p_struct = &p_opt->common_opt.conn_bw; + break; +#endif + case BLE_COMMON_OPT_PA_LNA: + fp_encoder = ble_common_opt_pa_lna_t_enc; + p_struct = &p_opt->common_opt.pa_lna; + break; + case BLE_COMMON_OPT_CONN_EVT_EXT: + fp_encoder = ble_common_opt_conn_evt_ext_t_enc; + p_struct = &p_opt->common_opt.conn_evt_ext; + break; + case BLE_GAP_OPT_CH_MAP: + fp_encoder = ble_gap_opt_ch_map_t_enc; + p_struct = &p_opt->gap_opt.ch_map; + break; + case BLE_GAP_OPT_LOCAL_CONN_LATENCY: + fp_encoder = ble_gap_opt_local_conn_latency_t_enc; + p_struct = &p_opt->gap_opt.local_conn_latency; + break; + case BLE_GAP_OPT_PASSKEY: + fp_encoder = ble_gap_opt_passkey_t_enc; + p_struct = &p_opt->gap_opt.passkey; + break; + case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT: + fp_encoder = ble_gap_opt_auth_payload_timeout_t_enc; + p_struct = &p_opt->gap_opt.auth_payload_timeout; + break; +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_GAP_OPT_EXT_LEN: + fp_encoder = ble_gap_opt_ext_len_t_enc; + p_struct = &p_opt->gap_opt.ext_len; + break; +#endif + case BLE_GAP_OPT_SCAN_REQ_REPORT: + fp_encoder = ble_gap_opt_scan_req_report_t_enc; + p_struct = &p_opt->gap_opt.scan_req_report; + break; +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_GAP_OPT_COMPAT_MODE: + fp_encoder = ble_gap_opt_compat_mode_t_enc; + p_struct = &p_opt->gap_opt.compat_mode; + break; +#else + case BLE_GAP_OPT_COMPAT_MODE_1: + fp_encoder = ble_gap_opt_compat_mode_1_t_enc; + p_struct = &p_opt->gap_opt.compat_mode_1; + break; + case BLE_GAP_OPT_COMPAT_MODE_2: + fp_encoder = ble_gap_opt_compat_mode_2_t_enc; + p_struct = &p_opt->gap_opt.compat_mode_2; + break; +#endif + default: + SER_ASSERT(NRF_ERROR_INVALID_PARAM, NRF_ERROR_INVALID_PARAM); + break; + } + + SER_PUSH_FIELD(p_struct, fp_encoder); + + SER_RSP_ENC_END; +} + + +uint32_t ble_opt_set_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint32_t * const p_opt_id, + ble_opt_t **const pp_opt ) +{ + SER_REQ_DEC_BEGIN(SD_BLE_OPT_SET); + + SER_ASSERT_NOT_NULL(p_opt_id); + SER_ASSERT_NOT_NULL(pp_opt); + SER_ASSERT_NOT_NULL(*pp_opt); + + SER_PULL_uint32(p_opt_id); + + SER_PULL_COND(pp_opt, NULL); + if (*pp_opt) + { + field_decoder_handler_t fp_decoder = NULL; + void * p_struct = NULL; + + switch(*p_opt_id) + { +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_COMMON_OPT_CONN_BW: + fp_decoder = ble_common_opt_conn_bw_t_dec; + p_struct = &((*pp_opt)->common_opt.conn_bw); + break; +#endif + case BLE_COMMON_OPT_PA_LNA: + fp_decoder = ble_common_opt_pa_lna_t_dec; + p_struct = &((*pp_opt)->common_opt.pa_lna); + break; + case BLE_COMMON_OPT_CONN_EVT_EXT: + fp_decoder = ble_common_opt_conn_evt_ext_t_dec; + p_struct = &((*pp_opt)->common_opt.conn_evt_ext); + break; + case BLE_GAP_OPT_CH_MAP: + fp_decoder = ble_gap_opt_ch_map_t_dec; + p_struct = &((*pp_opt)->gap_opt.ch_map); + break; + case BLE_GAP_OPT_LOCAL_CONN_LATENCY: + fp_decoder = ble_gap_opt_local_conn_latency_t_dec; + p_struct = &((*pp_opt)->gap_opt.local_conn_latency); + break; + case BLE_GAP_OPT_PASSKEY: + fp_decoder = ble_gap_opt_passkey_t_dec; + p_struct = &((*pp_opt)->gap_opt.passkey); + break; + case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT: + fp_decoder = ble_gap_opt_auth_payload_timeout_t_dec; + p_struct = &((*pp_opt)->gap_opt.auth_payload_timeout); + break; +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_GAP_OPT_EXT_LEN: + fp_decoder = ble_gap_opt_ext_len_t_dec; + p_struct = &((*pp_opt)->gap_opt.ext_len); + break; +#endif + case BLE_GAP_OPT_SCAN_REQ_REPORT: + fp_decoder = ble_gap_opt_scan_req_report_t_dec; + p_struct = &((*pp_opt)->gap_opt.scan_req_report); + break; +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_GAP_OPT_COMPAT_MODE: + fp_decoder = ble_gap_opt_compat_mode_t_dec; + p_struct = &((*pp_opt)->gap_opt.compat_mode); + break; +#else + case BLE_GAP_OPT_COMPAT_MODE_1: + fp_decoder = ble_gap_opt_compat_mode_1_t_dec; + p_struct = &((*pp_opt)->gap_opt.compat_mode_1); + break; + case BLE_GAP_OPT_COMPAT_MODE_2: + fp_decoder = ble_gap_opt_compat_mode_2_t_dec; + p_struct = &((*pp_opt)->gap_opt.compat_mode_2); + break; + case BLE_GAP_OPT_SLAVE_LATENCY_DISABLE: + fp_decoder = ble_gap_opt_slave_latency_disable_t_dec; + p_struct = &((*pp_opt)->gap_opt.slave_latency_disable); + break; +#endif + default: + SER_ASSERT(NRF_ERROR_INVALID_PARAM,NRF_ERROR_INVALID_PARAM); + break; + } + + SER_PULL_FIELD(p_struct, fp_decoder); + } + + SER_REQ_DEC_END; +} + + +uint32_t ble_opt_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_OPT_SET); +} + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_tx_packet_count_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint8_t * * const pp_count) +{ + SER_REQ_DEC_BEGIN(SD_BLE_TX_PACKET_COUNT_GET); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_count, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_tx_packet_count_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_count) +{ + SER_RSP_ENC_BEGIN(SD_BLE_TX_PACKET_COUNT_GET); + SER_PUSH_COND(p_count, uint8_t_enc); + SER_RSP_ENC_END; +} +#endif + +uint32_t ble_user_mem_reply_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + ble_user_mem_block_t * * const pp_mem_block) +{ + SER_REQ_DEC_BEGIN(SD_BLE_USER_MEM_REPLY); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_mem_block); + SER_ASSERT_NOT_NULL(*pp_mem_block); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_mem_block, ble_user_mem_block_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_user_mem_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_USER_MEM_REPLY); +} + +uint32_t ble_uuid_decode_req_dec(uint8_t const * const p_buf, + uint32_t const packet_len, + uint8_t * p_uuid_le_len, + uint8_t * * const pp_uuid_le, + ble_uuid_t * * const pp_uuid) +{ + SER_REQ_DEC_BEGIN(SD_BLE_UUID_DECODE); + + SER_PULL_len8data(pp_uuid_le, p_uuid_le_len); + SER_PULL_COND(pp_uuid, NULL); + + SER_REQ_DEC_END; +} + +uint32_t ble_uuid_decode_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_uuid_t const * const p_uuid) +{ + SER_RSP_ENC_BEGIN(SD_BLE_UUID_DECODE); + SER_PUSH_COND(p_uuid, ble_uuid_t_enc); + SER_RSP_ENC_END; +} + +uint32_t ble_uuid_encode_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_uuid_t * * const pp_uuid, + uint8_t * * const pp_uuid_le_len, + uint8_t * * const pp_uuid_le) +{ + SER_REQ_DEC_BEGIN(SD_BLE_UUID_ENCODE); + + SER_ASSERT_NOT_NULL(pp_uuid); + SER_ASSERT_NOT_NULL(pp_uuid_le_len); + SER_ASSERT_NOT_NULL(pp_uuid_le); + SER_ASSERT_NOT_NULL(*pp_uuid); + SER_ASSERT_NOT_NULL(*pp_uuid_le_len); + SER_ASSERT_NOT_NULL(*pp_uuid_le); + + SER_PULL_COND(pp_uuid, ble_uuid_t_dec); + SER_PULL_COND(pp_uuid_le_len, NULL); + SER_PULL_COND(pp_uuid_le, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_uuid_encode_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t uuid_le_len, + uint8_t const * const p_uuid_le) +{ + SER_RSP_ENC_BEGIN(SD_BLE_UUID_ENCODE); + + SER_PUSH_uint8(&uuid_le_len); + if (p_uuid_le != NULL) + { + SER_PUSH_uint8array(p_uuid_le, uuid_le_len); + } + + SER_RSP_ENC_END; +} + +uint32_t ble_uuid_vs_add_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_uuid128_t * * const pp_uuid, + uint8_t * * const pp_uuid_type) +{ + SER_REQ_DEC_BEGIN(SD_BLE_UUID_VS_ADD); + + SER_ASSERT_NOT_NULL(pp_uuid); + SER_ASSERT_NOT_NULL(pp_uuid_type); + SER_ASSERT_NOT_NULL(*pp_uuid); + SER_ASSERT_NOT_NULL(*pp_uuid_type); + + SER_PULL_COND(pp_uuid, ble_uuid128_t_dec); + SER_PULL_COND(pp_uuid_type, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_uuid_vs_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_uuid_type) +{ + SER_RSP_ENC_BEGIN(SD_BLE_UUID_VS_ADD); + SER_PUSH_COND(p_uuid_type, uint8_t_enc); + SER_RSP_ENC_END; +} + +uint32_t ble_version_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_version_t * * const pp_version) +{ + SER_REQ_DEC_BEGIN(SD_BLE_VERSION_GET); + + SER_ASSERT_NOT_NULL(pp_version); + SER_ASSERT_NOT_NULL(*pp_version); + + SER_PULL_COND(pp_version, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_version_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_version_t const * const p_version) +{ + SER_RSP_ENC_BEGIN(SD_BLE_VERSION_GET); + SER_PUSH_FIELD(p_version, ble_version_t_enc); + SER_RSP_ENC_END; +} + + + +uint32_t ble_opt_id_pre_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint32_t * const p_opt_id) +{ + SER_REQ_DEC_BEGIN(SD_BLE_OPT_SET); + + SER_ASSERT_NOT_NULL(p_opt_id); + SER_PULL_uint32(p_opt_id); + + // Pre-decoding; do not check if the whole packet was processed. + return NRF_SUCCESS; +} +#if NRF_SD_BLE_API_VERSION >= 4 + +uint32_t ble_cfg_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * p_cfg_id, + ble_cfg_t * * const pp_cfg) +{ + SER_REQ_DEC_BEGIN(SD_BLE_CFG_SET); + SER_PULL_uint32(p_cfg_id); + SER_PULL_COND(pp_cfg, NULL); + + if (*pp_cfg) + { + + field_decoder_handler_t fp_decoder = NULL; + void * p_struct = NULL; + + switch(*p_cfg_id) + { + case BLE_CONN_CFG_GAP: + fp_decoder = ble_gap_conn_cfg_t_dec; + p_struct = &((*pp_cfg)->conn_cfg.params.gap_conn_cfg); + break; + case BLE_CONN_CFG_GATTC: + fp_decoder = ble_gattc_conn_cfg_t_dec; + p_struct = &((*pp_cfg)->conn_cfg.params.gattc_conn_cfg); + break; + case BLE_CONN_CFG_GATTS: + fp_decoder = ble_gatts_conn_cfg_t_dec; + p_struct = &((*pp_cfg)->conn_cfg.params.gatts_conn_cfg); + break; + case BLE_CONN_CFG_GATT: + fp_decoder = ble_gatt_conn_cfg_t_dec; + p_struct = &((*pp_cfg)->conn_cfg.params.gatt_conn_cfg); + break; + case BLE_COMMON_CFG_VS_UUID: + fp_decoder = ble_common_cfg_vs_uuid_t_dec; + p_struct = &((*pp_cfg)->common_cfg.vs_uuid_cfg); + break; + case BLE_GAP_CFG_ROLE_COUNT: + fp_decoder = ble_gap_cfg_role_count_t_dec; + p_struct = &((*pp_cfg)->gap_cfg.role_count_cfg); + break; + case BLE_GAP_CFG_DEVICE_NAME: + fp_decoder = ble_gap_cfg_device_name_t_dec; + p_struct = &((*pp_cfg)->gap_cfg.device_name_cfg); + break; + case BLE_GATTS_CFG_SERVICE_CHANGED: + fp_decoder = ble_gatts_cfg_service_changed_t_dec; + p_struct = &((*pp_cfg)->gatts_cfg.service_changed); + break; + case BLE_GATTS_CFG_ATTR_TAB_SIZE: + fp_decoder = ble_gatts_cfg_attr_tab_size_t_dec; + p_struct = &((*pp_cfg)->gatts_cfg.attr_tab_size); + break; + default: + SER_ASSERT(NRF_ERROR_INVALID_PARAM,NRF_ERROR_INVALID_PARAM); + break; + } + + if (*p_cfg_id >= BLE_CONN_CFG_BASE && *p_cfg_id <= BLE_CONN_CFG_GATT) + { + SER_PULL_uint8(&(*pp_cfg)->conn_cfg.conn_cfg_tag); + } + SER_PULL_FIELD(p_struct, fp_decoder); + } + SER_REQ_DEC_END; +} + + + +uint32_t ble_cfg_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_CFG_SET); +} + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..10f8978a67ba94cfd1011cfd2e2bd2e9b8f1186e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_conn.h @@ -0,0 +1,521 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_CONN_H__ +#define BLE_CONN_H__ + +/** + * @addtogroup ser_conn_s130_codecs Connectivity codecs for S132 and S140 + * @ingroup ser_codecs_conn + */ + +/**@file + * + * @defgroup ble_conn Connectivity command request decoders and command response encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief Connectivity command request decoders and command response encoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +/**@brief Decodes @ref sd_ble_tx_packet_count_get command request. + * + * @sa @ref ble_tx_packet_count_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] pp_count Pointer to pointer to location for count. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_tx_packet_count_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint8_t * * const pp_count); + +/**@brief Encodes @ref sd_ble_tx_packet_count_get command response. + * + * @sa @ref ble_tx_packet_count_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_count Pointer to count value. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_tx_packet_count_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_count); +#endif + +/**@brief Event encoding dispatcher. + * + * The event encoding dispatcher will route the event packet to the correct encoder which in turn + * encodes the contents of the event and updates the \p p_buf buffer. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + * @retval NRF_ERROR_NOT_SUPPORTED Event encoder is not implemented. + */ +uint32_t ble_event_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_version_get command request. + * + * @sa @ref ble_version_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_version Pointer to pointer to @ref ble_version_t address. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_version_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_version_t * * const pp_version); + +/**@brief Encodes @ref sd_ble_version_get command response. + * + * @sa @ref ble_version_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_version Pointer to @ref ble_version_t address. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_version_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_version_t const * const p_version); + + +/**@brief Decodes @ref sd_ble_opt_get command request. + * + * @sa @ref ble_opt_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_opt_id Pointer to pointer to @ref ble_version_t address. + * @param[out] pp_opt Pointer to pointer to @ref ble_opt_t address. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_opt_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint32_t * const p_opt_id, + ble_opt_t **const pp_opt ); + + +/**@brief Encodes @ref sd_ble_opt_get command response. + * + * @sa @ref ble_opt_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] opt_id identifies type of ble_opt_t union + * @param[in] p_opt Pointer to @ref ble_opt_t union. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ + +uint32_t ble_opt_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint32_t opt_id, + ble_opt_t const * const p_opt); + + +/**@brief Decodes @ref sd_ble_opt_set command request. + * + * @sa @ref ble_opt_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_opt_id Pointer to @ref ble_opt_t union type identifier. + * @param[out] pp_opt Pointer to pointer to @ref ble_opt_t union. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_opt_set_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint32_t * const p_opt_id, + ble_opt_t **const pp_opt ); + + +/**@brief Encodes @ref sd_ble_opt_set command response. + * + * @sa @ref ble_opt_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ + +uint32_t ble_opt_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + + +/**@brief Decodes @ref sd_ble_uuid_encode command request. + * + * @sa @ref ble_uuid_encode_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_uuid Pointer to pointer to @ref ble_uuid_t structure. + * @param[out] pp_uuid_le_len Pointer to pointer to the length of encoded UUID. + * @param[out] pp_uuid_le Pointer to pointer to buffer where encoded UUID will be stored. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_uuid_encode_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_uuid_t * * const pp_uuid, + uint8_t * * const pp_uuid_le_len, + uint8_t * * const pp_uuid_le); + +/**@brief Encodes @ref sd_ble_uuid_encode command response. + * + * @sa @ref ble_uuid_encode_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] uuid_le_len Length of the encoded UUID. + * @param[in] p_uuid_le Pointer to the buffer with encoded UUID. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_uuid_encode_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t uuid_le_len, + uint8_t const * const p_uuid_le); + +/**@brief Decodes @ref sd_ble_uuid_decode command request. + * + * @sa @ref ble_uuid_decode_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_uuid_le_len Pointer to the length of encoded UUID. + * @param[out] pp_uuid_le Pointer to pointer to buffer where encoded UUID will be stored. + * @param[out] pp_uuid Pointer to pointer to @ref ble_uuid_t structure. + * \c It will be set to NULL if p_uuid is not present in the packet. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_uuid_decode_req_dec(uint8_t const * const p_buf, + uint32_t const packet_len, + uint8_t * p_uuid_le_len, + uint8_t * * const pp_uuid_le, + ble_uuid_t * * const pp_uuid); + +/**@brief Encodes @ref sd_ble_uuid_decode command response. + * + * @sa @ref ble_uuid_decode_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_uuid Pointer to the buffer with encoded UUID. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_uuid_decode_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_uuid_t const * const p_uuid); + +/**@brief Decodes @ref sd_ble_uuid_vs_add command request. + * + * @sa @ref ble_uuid_vs_add_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_uuid Pointer to pointer to UUID. + * \c It will be set to NULL if p_uuid is not present in the packet. + * @param[out] pp_uuid_type Pointer to pointer to UUID type. + * \c It will be set to NULL if p_uuid_type is not present in the packet. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_uuid_vs_add_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_uuid128_t * * const pp_uuid, + uint8_t * * const pp_uuid_type); + +/**@brief Encodes @ref sd_ble_uuid_vs_add command response. + * + * @sa @ref ble_uuid_vs_add_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_uuid_type Pointer to the UUID type. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_uuid_vs_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_uuid_type); + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +/**@brief Decodes @ref sd_ble_enable command request. + * + * @sa @ref ble_enable_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_ble_enable_params Pointer to pointer to ble_enable_params_t. + * \c It will be set to NULL if p_ble_enable_params is not present in the packet. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_enable_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_enable_params_t * * const pp_ble_enable_params); +#else +/**@brief Decodes @ref sd_ble_enable command request. + * + * @sa @ref ble_enable_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_enable_req_dec(uint8_t const * const p_buf, + uint32_t packet_len); + +#endif +/**@brief Encodes @ref sd_ble_enable command response. + * + * @sa @ref ble_enable_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_enable_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Pre-decodes opt_id of @ref ble_opt_t for middleware. + * + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] packet_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in,out] p_opt_id Pointer to opt_id which identifies type of @ref ble_opt_t union. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_opt_id_pre_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint32_t * const p_opt_id); + +/**@brief Decodes @ref sd_ble_user_mem_reply command request. + * + * @sa @ref ble_user_mem_reply_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_conn_handle Pointer to Connection Handle. + * @param[in,out] pp_block Pointer to pointer to ble_user_mem_block_t. + * \c It will be set to NULL if p_block is not present in the packet. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_user_mem_reply_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + ble_user_mem_block_t * * const pp_block); + +/**@brief Encodes @ref sd_ble_user_mem_reply command response. + * + * @sa @ref ble_user_mem_reply_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_user_mem_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +#if NRF_SD_BLE_API_VERSION >= 4 +/**@brief Decodes @ref sd_ble_cfg_set command request. + * + * @sa @ref ble_cfg_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_cfg_id Pointer to ConfigurationId. + * @param[in,out] pp_cfg Pointer to pointer to configuration struct. + * \c It will be set to NULL if p_block is not present in the packet. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_cfg_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * p_cfg_id, + ble_cfg_t * * const pp_cfg); + +/**@brief Encodes @ref sd_ble_cfg_set command response. + * + * @sa @ref ble_cfg_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_cfg_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +#endif + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_event_enc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_event_enc.c new file mode 100644 index 0000000000000000000000000000000000000000..36d25add1200372687191241b4514508ca634af1 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_event_enc.c @@ -0,0 +1,259 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_conn.h" +#include "ble_evt_conn.h" +#include "ble_gap_evt_conn.h" +#include "ble_gattc_evt_conn.h" +#include "ble_gatts_evt_conn.h" +#include "ble_l2cap_evt_conn.h" +#include "ble_serialization.h" +#include "app_util.h" +#include "nrf_log.h" + +uint32_t ble_event_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t ret_val = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + SER_ASSERT_NOT_NULL(p_event); + + switch (p_event->header.evt_id) + { +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_EVT_TX_COMPLETE: + ret_val = ble_evt_tx_complete_enc(p_event, event_len, p_buf, p_buf_len); + break; +#endif + case BLE_EVT_USER_MEM_RELEASE: + ret_val = ble_evt_user_mem_release_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_EVT_USER_MEM_REQUEST: + ret_val = ble_evt_user_mem_request_enc(p_event, event_len, p_buf, p_buf_len); + break; +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_EVT_DATA_LENGTH_CHANGED: + ret_val = ble_evt_data_length_changed_enc(p_event, event_len, p_buf, p_buf_len); + break; +#endif + + case BLE_GAP_EVT_CONN_PARAM_UPDATE: + ret_val = ble_gap_evt_conn_param_update_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: + ret_val = ble_gap_evt_conn_param_update_request_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + ret_val = ble_gap_evt_sec_params_request_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_SEC_INFO_REQUEST: + ret_val = ble_gap_evt_sec_info_request_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_AUTH_STATUS: + ret_val = ble_gap_evt_auth_status_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_PASSKEY_DISPLAY: + ret_val = ble_gap_evt_passkey_display_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_AUTH_KEY_REQUEST: + ret_val = ble_gap_evt_auth_key_request_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_CONN_SEC_UPDATE: + ret_val = ble_gap_evt_conn_sec_update_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_RSSI_CHANGED: + ret_val = ble_gap_evt_rssi_changed_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_TIMEOUT: + ret_val = ble_gap_evt_timeout_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_DISCONNECTED: + ret_val = ble_gap_evt_disconnected_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_CONNECTED: + ret_val = ble_gap_evt_connected_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_SEC_REQUEST: + ret_val = ble_gap_evt_sec_request_enc(p_event, event_len, p_buf, p_buf_len); + break; + case BLE_GAP_EVT_KEY_PRESSED: + ret_val = ble_gap_evt_key_pressed_enc(p_event, event_len, p_buf, p_buf_len); + break; + case BLE_GAP_EVT_LESC_DHKEY_REQUEST: + ret_val = ble_gap_evt_lesc_dhkey_request_enc(p_event, event_len, p_buf, p_buf_len); + break; +#if NRF_SD_BLE_API_VERSION >= 5 + case BLE_GAP_EVT_PHY_UPDATE: + ret_val = ble_gap_evt_phy_update_enc(p_event, event_len, p_buf, p_buf_len); + break; +#endif +#if NRF_SD_BLE_API_VERSION >= 4 + case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: + ret_val = ble_gap_evt_data_length_update_request_enc(p_event, event_len, p_buf, p_buf_len); + break; + case BLE_GAP_EVT_DATA_LENGTH_UPDATE: + ret_val = ble_gap_evt_data_length_update_enc(p_event, event_len, p_buf, p_buf_len); + break; +#endif + case BLE_GATTC_EVT_CHAR_DISC_RSP: + ret_val = ble_gattc_evt_char_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTC_EVT_DESC_DISC_RSP: + ret_val = ble_gattc_evt_desc_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP: + ret_val = ble_gattc_evt_char_val_by_uuid_read_rsp_enc(p_event, + event_len, + p_buf, + p_buf_len); + break; + + case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: + ret_val = ble_gattc_evt_prim_srvc_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTC_EVT_HVX: + ret_val = ble_gattc_evt_hvx_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTC_EVT_READ_RSP: + ret_val = ble_gattc_evt_read_rsp_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTC_EVT_TIMEOUT: + ret_val = ble_gattc_evt_timeout_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + ret_val = ble_gattc_evt_write_rsp_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTC_EVT_REL_DISC_RSP: + ret_val = ble_gattc_evt_rel_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTC_EVT_CHAR_VALS_READ_RSP: + ret_val = ble_gattc_evt_char_vals_read_rsp_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTC_EVT_ATTR_INFO_DISC_RSP: + ret_val = ble_gattc_evt_attr_info_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: + ret_val = ble_gattc_evt_exchange_mtu_rsp_enc(p_event, event_len, p_buf, p_buf_len); + break; +#if NRF_SD_BLE_API_VERSION >= 4 + case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE: + ret_val = ble_gattc_evt_write_cmd_tx_complete_enc(p_event, event_len, p_buf, p_buf_len); + break; +#endif + + case BLE_GATTS_EVT_HVC: + ret_val = ble_gatts_evt_hvc_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTS_EVT_TIMEOUT: + ret_val = ble_gatts_evt_timeout_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTS_EVT_SC_CONFIRM: + ret_val = ble_gatts_evt_sc_confirm_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTS_EVT_WRITE: + ret_val = ble_gatts_evt_write_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + ret_val = ble_gatts_evt_rw_authorize_request_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTS_EVT_SYS_ATTR_MISSING: + ret_val = ble_gatts_evt_sys_attr_missing_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: + ret_val = ble_gatts_evt_exchange_mtu_request_enc(p_event, event_len, p_buf, p_buf_len); + break; +#if NRF_SD_BLE_API_VERSION >= 4 + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + ret_val = ble_gatts_evt_hvn_tx_complete_enc(p_event, event_len, p_buf, p_buf_len); + break; +#endif +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + case BLE_L2CAP_EVT_RX: + ret_val = ble_l2cap_evt_rx_enc(p_event, event_len, p_buf, p_buf_len); + break; +#endif + case BLE_GAP_EVT_ADV_REPORT: + ret_val = ble_gap_evt_adv_report_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GAP_EVT_SCAN_REQ_REPORT: + ret_val = ble_gap_evt_scan_req_report_enc(p_event, event_len, p_buf, p_buf_len); + break; + + default: + ret_val = NRF_ERROR_NOT_SUPPORTED; + *p_buf_len = 0; + break; + } + + return ret_val; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.c new file mode 100644 index 0000000000000000000000000000000000000000..e9b47bc9400eb905a2e4476bf0d10bd861038120 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.c @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_evt_conn.h" +#include +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "app_util.h" +#include "conn_ble_user_mem.h" + +uint32_t ble_evt_user_mem_release_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_EVT_USER_MEM_RELEASE); + + SER_PUSH_uint16(&p_event->evt.common_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.common_evt.params.user_mem_release.type); + SER_PUSH_uint16(&p_event->evt.common_evt.params.user_mem_release.mem_block.len); + SER_PUSH_COND(p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem, NULL); + + // Now user memory context can be released + err_code = conn_ble_user_mem_context_destroy(p_event->evt.common_evt.conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_EVT_ENC_END; +} + + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_evt_tx_complete_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_EVT_TX_COMPLETE); + + SER_PUSH_uint16(&p_event->evt.common_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.common_evt.params.tx_complete.count); + + SER_EVT_ENC_END; +} +#endif + +uint32_t ble_evt_user_mem_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_EVT_USER_MEM_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.common_evt.params.user_mem_request.type); + + SER_EVT_ENC_END; +} + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_evt_data_length_changed_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_EVT_DATA_LENGTH_CHANGED); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.common_evt.params.data_length_changed, ble_evt_data_length_changed_t_enc); + + SER_EVT_ENC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..03fcbdec6a1659c29710717ff7c0ebcfed0fb3a7 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.h @@ -0,0 +1,138 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_EVT_CONN_H__ +#define BLE_EVT_CONN_H__ + + +/**@file + * + * @defgroup ble_evt_conn Connectivity event encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief Connectivity event encoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +/** + * @brief Encodes ble_evt_tx_complete event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that will be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_evt_tx_complete_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +#endif +/** + * @brief Encodes ble_evt_user_mem_release event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_evt_user_mem_release_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_evt_user_mem_request event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that will be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_evt_user_mem_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +/** + * @brief Encodes ble_evt_data_length_changed event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that will be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_evt_data_length_changed_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +#endif +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.c new file mode 100644 index 0000000000000000000000000000000000000000..a86f86cd3b2bcd594be0dd5b86df1f0068159ae4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.c @@ -0,0 +1,981 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gap_conn.h" +#include +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "app_util.h" + +uint32_t ble_gap_adv_data_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * const pp_data, + uint8_t * p_dlen, + uint8_t * * const pp_sr_data, + uint8_t * p_srdlen) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADV_DATA_SET); + + SER_ASSERT_NOT_NULL(p_dlen); + SER_ASSERT_NOT_NULL(p_srdlen); + SER_PULL_len8data(pp_data, p_dlen); + SER_PULL_len8data(pp_sr_data, p_srdlen); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_adv_data_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ADV_DATA_SET); +} + +uint32_t ble_gap_adv_start_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_adv_params_t * * const pp_adv_params +#if NRF_SD_BLE_API_VERSION >= 4 + ,uint8_t * p_conn_cfg_tag +#endif + ) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADV_START); + + SER_ASSERT_NOT_NULL(pp_adv_params); + SER_ASSERT_NOT_NULL(*pp_adv_params); + SER_ASSERT_NOT_NULL((*pp_adv_params)->p_peer_addr); + + SER_PULL_COND(pp_adv_params, ble_gap_adv_params_t_dec); +#if NRF_SD_BLE_API_VERSION >= 4 + SER_PULL_uint8(p_conn_cfg_tag); +#endif + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_adv_start_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ADV_START); +} + + +uint32_t ble_gap_adv_stop_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ADV_STOP); +} + + +uint32_t ble_gap_appearance_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * * const pp_appearance) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_APPEARANCE_GET); + + SER_ASSERT_NOT_NULL(pp_appearance); + SER_ASSERT_NOT_NULL(*pp_appearance); + SER_PULL_COND(pp_appearance, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_appearance_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_appearance) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_APPEARANCE_GET); + + SER_PUSH_COND(p_appearance, uint16_t_enc); + SER_RSP_ENC_END; +} + +uint32_t ble_gap_appearance_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_appearance) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_APPEARANCE_SET); + + SER_ASSERT_NOT_NULL(p_appearance); + SER_PULL_uint16(p_appearance); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_appearance_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_APPEARANCE_SET); +} + +uint32_t ble_gap_auth_key_reply_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_key_type, + uint8_t * * const pp_key) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_AUTH_KEY_REPLY); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(p_key_type); + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint8(p_key_type); + + uint8_t key_len; + switch (*p_key_type) + { + case BLE_GAP_AUTH_KEY_TYPE_NONE: + key_len = 0; + break; + + case BLE_GAP_AUTH_KEY_TYPE_PASSKEY: + key_len = 6; + break; + + case BLE_GAP_AUTH_KEY_TYPE_OOB: + key_len = 16; + break; + + default: + return NRF_ERROR_INVALID_PARAM; + } + + SER_PULL_buf(pp_key, key_len, key_len); + SER_REQ_DEC_END; +} + +uint32_t ble_gap_auth_key_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_AUTH_KEY_REPLY); +} + + +uint32_t ble_gap_authenticate_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + ble_gap_sec_params_t * * const pp_sec_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_AUTHENTICATE); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_sec_params); + SER_ASSERT_NOT_NULL(*pp_sec_params); + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_sec_params, ble_gap_sec_params_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_authenticate_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_AUTHENTICATE); +} + +uint32_t ble_gap_conn_param_update_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_conn_params_t * * const pp_conn_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_CONN_PARAM_UPDATE); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_conn_params); + SER_ASSERT_NOT_NULL(*pp_conn_params); + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_conn_params, ble_gap_conn_params_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_conn_param_update_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_CONN_PARAM_UPDATE); +} + +uint32_t ble_gap_conn_sec_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_conn_sec_t * * const pp_conn_sec) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_CONN_SEC_GET); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_conn_sec, NULL); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_conn_sec_get_rsp_enc(uint32_t return_code, + ble_gap_conn_sec_t * const p_conn_sec, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_CONN_SEC_GET); + + SER_PUSH_COND(p_conn_sec, ble_gap_conn_sec_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gap_connect_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * * const pp_addr, + ble_gap_scan_params_t * * const pp_scan_params, + ble_gap_conn_params_t * * const pp_conn_params +#if NRF_SD_BLE_API_VERSION >= 4 + ,uint8_t * p_conn_cfg_tag +#endif + ) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_CONNECT); + + SER_ASSERT_NOT_NULL(pp_addr); + SER_ASSERT_NOT_NULL(*pp_addr); + SER_ASSERT_NOT_NULL(pp_scan_params); + SER_ASSERT_NOT_NULL(*pp_scan_params); + SER_ASSERT_NOT_NULL(pp_conn_params); + SER_ASSERT_NOT_NULL(*pp_conn_params); + + SER_PULL_COND(pp_addr, ble_gap_addr_t_dec); + SER_PULL_COND(pp_scan_params, ble_gap_scan_params_t_dec); + SER_PULL_COND(pp_conn_params, ble_gap_conn_params_t_dec); +#if NRF_SD_BLE_API_VERSION >= 4 + SER_PULL_uint8(p_conn_cfg_tag); +#endif + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_connect_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_CONNECT); +} +uint32_t ble_gap_connect_cancel_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_CONNECT_CANCEL); +} + +uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * pp_name, + uint16_t * * pp_name_len) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_DEVICE_NAME_GET); + + SER_ASSERT_NOT_NULL(pp_name_len); + + SER_PULL_COND(pp_name_len, uint16_t_dec); + SER_PULL_COND(pp_name, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_device_name_get_rsp_enc(uint32_t return_code, + uint8_t const * const p_dev_name, + uint16_t * p_dev_name_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_DEVICE_NAME_GET); + + SER_PUSH_COND(p_dev_name_len, uint16_t_enc); + + if (p_dev_name_len) + { + SER_PUSH_uint8array(p_dev_name, *p_dev_name_len); + } + + SER_RSP_ENC_END; +} + +uint32_t ble_gap_device_name_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_conn_sec_mode_t * * const pp_write_perm, + uint8_t * * const pp_dev_name, + uint16_t * const p_dev_name_len) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_DEVICE_NAME_SET); + + SER_ASSERT_NOT_NULL(pp_write_perm); + SER_ASSERT_NOT_NULL(pp_dev_name); + SER_ASSERT_NOT_NULL(p_dev_name_len); + + SER_PULL_COND(pp_write_perm, ble_gap_conn_sec_mode_t_dec); + SER_PULL_len16data(pp_dev_name, p_dev_name_len); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_device_name_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_DEVICE_NAME_SET); +} + +uint32_t ble_gap_disconnect_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint8_t * const p_hci_status) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_DISCONNECT); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(p_hci_status); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint8(p_hci_status); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_disconnect_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_DISCONNECT); +} + +uint32_t ble_gap_encrypt_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gap_master_id_t ** const pp_master_id, + ble_gap_enc_info_t ** const pp_enc_info) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_ENCRYPT); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_enc_info); + SER_ASSERT_NOT_NULL(pp_master_id); + SER_ASSERT_NOT_NULL(*pp_enc_info); + SER_ASSERT_NOT_NULL(*pp_master_id); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_master_id, ble_gap_master_id_t_dec); + SER_PULL_COND(pp_enc_info, ble_gap_enc_info_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_encrypt_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ENCRYPT); +} + +uint32_t ble_gap_keypress_notify_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_kp_not) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_KEYPRESS_NOTIFY); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(p_kp_not); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint8(p_kp_not); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_keypress_notify_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_KEYPRESS_NOTIFY); +} + +uint32_t ble_gap_lesc_dhkey_reply_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_lesc_dhkey_t * * pp_dhkey) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_LESC_DHKEY_REPLY); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_dhkey); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_dhkey, ble_gap_lesc_dhkey_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_lesc_dhkey_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_LESC_DHKEY_REPLY); +} + +uint32_t ble_gap_lesc_oob_data_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_lesc_p256_pk_t * * pp_pk_own, + ble_gap_lesc_oob_data_t * * pp_oobd_own) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_GET); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_oobd_own); + SER_ASSERT_NOT_NULL(pp_pk_own); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_pk_own, ble_gap_lesc_p256_pk_t_dec); + SER_PULL_COND(pp_oobd_own, NULL); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_lesc_oob_data_get_rsp_enc(uint32_t return_code, + ble_gap_lesc_oob_data_t * p_oobd_own, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_GET); + + SER_PUSH_COND(p_oobd_own, ble_gap_lesc_oob_data_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gap_lesc_oob_data_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_lesc_oob_data_t * * pp_oobd_own, + ble_gap_lesc_oob_data_t * * pp_oobd_peer) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_SET); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_oobd_own); + SER_ASSERT_NOT_NULL(pp_oobd_peer); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_oobd_own, ble_gap_lesc_oob_data_t_dec); + SER_PULL_COND(pp_oobd_peer, ble_gap_lesc_oob_data_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_lesc_oob_data_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_LESC_OOB_DATA_SET); +} + +uint32_t ble_gap_ppcp_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_gap_conn_params_t * * const pp_conn_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_PPCP_GET); + + SER_ASSERT_NOT_NULL(pp_conn_params); + SER_ASSERT_NOT_NULL(*pp_conn_params); + SER_ASSERT_LENGTH_LEQ(2, packet_len); + + SER_PULL_COND(pp_conn_params, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_ppcp_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_conn_params_t const * const p_conn_params) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_PPCP_GET); + + SER_PUSH_COND(p_conn_params, ble_gap_conn_params_t_enc); + + SER_RSP_ENC_END; +} + + +uint32_t ble_gap_ppcp_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_conn_params_t * * const pp_conn_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_PPCP_SET); + + SER_ASSERT_NOT_NULL(pp_conn_params); + SER_PULL_COND(pp_conn_params, ble_gap_conn_params_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_ppcp_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_PPCP_SET); +} + +uint32_t ble_gap_rssi_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + int8_t * * const pp_rssi) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_RSSI_GET); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_rssi); + SER_ASSERT_NOT_NULL(*pp_rssi); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_rssi, NULL); + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_rssi_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + int8_t rssi) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_RSSI_GET); + + SER_PUSH_int8(&rssi); + + SER_RSP_ENC_END; +} + +uint32_t ble_gap_rssi_start_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_threshold_dbm, + uint8_t * p_skip_count) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_RSSI_START); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(p_threshold_dbm); + SER_ASSERT_NOT_NULL(p_skip_count); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint8(p_threshold_dbm); + SER_PULL_uint8(p_skip_count); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_rssi_start_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_RSSI_START); +} + +uint32_t ble_gap_rssi_stop_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_RSSI_STOP); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_PULL_uint16(p_conn_handle); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_rssi_stop_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_RSSI_STOP); +} + +uint32_t ble_gap_scan_start_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_scan_params_t * * const pp_scan_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_SCAN_START); + + SER_ASSERT_NOT_NULL(pp_scan_params); + SER_ASSERT_NOT_NULL(*pp_scan_params); + + SER_PULL_COND(pp_scan_params, ble_gap_scan_params_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_scan_start_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_SCAN_START); +} + +uint32_t ble_gap_scan_stop_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_SCAN_STOP); +} + +uint32_t ble_gap_sec_info_reply_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + ble_gap_enc_info_t * * const pp_enc_info, + ble_gap_irk_t * * const pp_id_info, + ble_gap_sign_info_t * * const pp_sign_info) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_SEC_INFO_REPLY); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_enc_info); + SER_ASSERT_NOT_NULL(pp_id_info); + SER_ASSERT_NOT_NULL(pp_sign_info); + SER_ASSERT_NOT_NULL(*pp_enc_info); + SER_ASSERT_NOT_NULL(*pp_id_info); + SER_ASSERT_NOT_NULL(*pp_sign_info); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_enc_info, ble_gap_enc_info_t_dec); + SER_PULL_COND(pp_id_info, ble_gap_irk_t_dec); + SER_PULL_COND(pp_sign_info, ble_gap_sign_info_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_sec_info_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_SEC_INFO_REPLY); +} + +uint32_t ble_gap_sec_params_reply_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_sec_status, + ble_gap_sec_params_t * * const pp_sec_params, + ble_gap_sec_keyset_t * * const pp_sec_keyset) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_SEC_PARAMS_REPLY); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(p_sec_status); + SER_ASSERT_NOT_NULL(pp_sec_params); + SER_ASSERT_NOT_NULL(*pp_sec_params); + SER_ASSERT_NOT_NULL(pp_sec_keyset); + SER_ASSERT_NOT_NULL(*pp_sec_keyset); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint8(p_sec_status); + SER_PULL_COND(pp_sec_params, ble_gap_sec_params_t_dec); + SER_PULL_COND(pp_sec_keyset, ble_gap_sec_keyset_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_sec_params_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_sec_keyset_t * const p_sec_keyset) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_SEC_PARAMS_REPLY); + SER_PUSH_COND(p_sec_keyset, ble_gap_sec_keyset_t_enc); + SER_RSP_ENC_END; +} + +uint32_t ble_gap_tx_power_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + int8_t * p_tx_power) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_TX_POWER_SET); + + SER_ASSERT_NOT_NULL(p_tx_power); + SER_PULL_int8(p_tx_power); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_tx_power_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_TX_POWER_SET); +} + + +uint32_t ble_gap_addr_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_gap_addr_t * * const pp_address) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADDR_GET); + SER_PULL_COND(pp_address, NULL); + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_addr_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_addr_t const * const p_address) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_ADDR_GET); + SER_PUSH_FIELD(p_address, ble_gap_addr_t_enc); + SER_RSP_ENC_END; +} + + +uint32_t ble_gap_addr_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * * const pp_addr) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADDR_SET); + SER_PULL_COND(pp_addr, ble_gap_addr_t_dec); + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_addr_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ADDR_SET); +} + +uint32_t ble_gap_privacy_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_privacy_params_t * * const pp_privacy_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_PRIVACY_SET); + SER_PULL_COND(pp_privacy_params, ble_gap_privacy_params_t_dec); + SER_REQ_DEC_END; +} + +uint32_t ble_gap_privacy_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_PRIVACY_SET); +} + +uint32_t ble_gap_privacy_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_gap_privacy_params_t * * const pp_privacy_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_PRIVACY_GET); + SER_PULL_COND(pp_privacy_params, ble_gap_privacy_params_t_dec); + SER_REQ_DEC_END; +} + +uint32_t ble_gap_privacy_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_privacy_params_t const * const p_privacy_params) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_PRIVACY_GET); + SER_PUSH_COND(p_privacy_params, ble_gap_privacy_params_t_enc); + SER_RSP_ENC_END; +} + +uint32_t ble_gap_whitelist_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * * * const ppp_wl_addrs, + uint8_t * const p_len) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_WHITELIST_SET); + + SER_ASSERT_NOT_NULL(ppp_wl_addrs); + SER_ASSERT_NOT_NULL(*ppp_wl_addrs); + SER_ASSERT_NOT_NULL(**ppp_wl_addrs); + + uint8_t presence; + SER_PULL_uint8(p_len); + + SER_PULL_uint8(&presence); + if (presence == SER_FIELD_PRESENT) + { + ble_gap_addr_t * * const pp_wl_addrs = *ppp_wl_addrs; + for (uint32_t i = 0; i < *p_len; ++i) + { + SER_PULL_COND(&(pp_wl_addrs[i]), ble_gap_addr_t_dec); + } + } + else + { + *ppp_wl_addrs = NULL; + } + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_whitelist_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_WHITELIST_SET); +} + +uint32_t ble_gap_device_identities_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_id_key_t * * * const ppp_id_keys, + ble_gap_irk_t * * * const ppp_local_irks, + uint8_t * const p_len) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_DEVICE_IDENTITIES_SET); + + SER_ASSERT_NOT_NULL(ppp_id_keys); + SER_ASSERT_NOT_NULL(*ppp_id_keys); + SER_ASSERT_NOT_NULL(**ppp_id_keys); + SER_ASSERT_NOT_NULL(ppp_local_irks); + SER_ASSERT_NOT_NULL(*ppp_local_irks); + SER_ASSERT_NOT_NULL(**ppp_local_irks); + + uint8_t presence; + SER_PULL_uint8(p_len); + + SER_PULL_uint8(&presence); + if (presence == SER_FIELD_PRESENT) + { + ble_gap_id_key_t * * const pp_id_keys = *ppp_id_keys; + for (uint32_t i = 0; i < *p_len; ++i) + { + SER_PULL_COND(&(pp_id_keys[i]), ble_gap_id_key_t_dec); + } + } + else + { + *ppp_id_keys = NULL; + } + SER_PULL_uint8(&presence); + if (presence == SER_FIELD_PRESENT) + { + ble_gap_irk_t * * const pp_local_irks = *ppp_local_irks; + for (uint32_t i = 0; i < *p_len; ++i) + { + SER_PULL_COND(&(pp_local_irks[i]), ble_gap_irk_t_dec); + } + } + else + { + *ppp_local_irks = NULL; + } + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_device_identities_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_DEVICE_IDENTITIES_SET); +} + +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gap_data_length_update_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + ble_gap_data_length_params_t * * const pp_dl_params, + ble_gap_data_length_limitation_t * * const pp_dl_limitation) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_DATA_LENGTH_UPDATE); + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_dl_params, ble_gap_data_length_params_t_dec); + SER_PULL_COND(pp_dl_limitation, NULL); + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_data_length_update_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_data_length_limitation_t const * const p_dl_limitation) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_DATA_LENGTH_UPDATE); + SER_PUSH_COND(p_dl_limitation, ble_gap_data_length_limitation_t_enc); + SER_RSP_ENC_END; +} +#endif +#if NRF_SD_BLE_API_VERSION >= 5 +uint32_t ble_gap_phy_request_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + ble_gap_phys_t * * const pp_gap_phys) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_PHY_REQUEST); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_gap_phys); + SER_ASSERT_NOT_NULL(*pp_gap_phys); + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_gap_phys, ble_gap_phys_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_phy_request_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_PHY_REQUEST); +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..592417efae4033293d60655dc67786100993eeb5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.h @@ -0,0 +1,1383 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GAP_CONN_H__ +#define BLE_GAP_CONN_H__ + +/**@file + * + * @defgroup ble_gap_conn GAP Connectivity command request decoders and command response encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief GAP Connectivity command request decoders and command response encoders + */ +#include "ble_gap.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Decodes @ref sd_ble_gap_authenticate command request. + * + * @sa @ref ble_gap_authenticate_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle + * @param[out] pp_sec_params Pointer to pointer to security parameters. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_authenticate_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + ble_gap_sec_params_t * * const pp_sec_params); + +/**@brief Encodes @ref sd_ble_gap_authenticate command response. + * + * @sa @ref ble_gap_authenticate_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_authenticate_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_adv_data_set command request. + * + * @sa @ref ble_gap_adv_data_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] pp_data Pointer to the buffer raw data to be placed in advertisement packet. + * @param[out] p_dlen Pointer to data length for p_data. + * @param[out] pp_sr_data Pointer to the buffer raw data to be placed in scan response packet. + * @param[out] p_srdlen Pointer to data length for p_sr_data. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_adv_data_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * const pp_data, + uint8_t * p_dlen, + uint8_t * * const pp_sr_data, + uint8_t * p_srdlen); + +/**@brief Encodes @ref sd_ble_gap_adv_data_set command response. + * + * @sa @ref ble_gap_adv_data_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_adv_data_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_adv_start command request. + * + * @sa @ref ble_gap_adv_start_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_adv_params Pointer to pointer to advertising parameters. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_adv_start_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_adv_params_t * * const pp_adv_params +#if NRF_SD_BLE_API_VERSION >= 4 + ,uint8_t * p_conn_cfg_tag +#endif + ); + +/**@brief Encodes @ref sd_ble_gap_adv_start command response. + * + * @sa @ref ble_gap_adv_start_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_adv_start_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_device_name_get command request. + * + * @sa @ref ble_gap_device_name_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_dev_name Pointer to pointer to device name buffer. + * @param[out] pp_dev_name_len Pointer to pointer to device name length location. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * pp_dev_name, + uint16_t * * pp_dev_name_len); + +/**@brief Encodes @ref sd_ble_gap_device_name_get command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_dev_name Pointer to device name buffer. + * @param[in] p_dev_name_len Length of device name buffer. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_device_name_get_rsp_enc(uint32_t return_code, + uint8_t const * const p_dev_name, + uint16_t * p_dev_name_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_conn_param_update command request. + * + * @sa @ref ble_gap_conn_param_update_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] pp_conn_params Pointer to pointer to connection parameters. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for connection + * parameters field present. + */ +uint32_t ble_gap_conn_param_update_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_conn_params_t * * const pp_conn_params); + +/**@brief Encodes @ref sd_ble_gap_conn_param_update command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_conn_param_update_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + + +/**@brief Decodes @ref sd_ble_gap_disconnect command request. + * + * @sa @ref ble_gap_disconnect_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_conn_handle Pointer to Connection Handle. + * @param[in] p_hci_status Pointer to HCI Status Code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_disconnect_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint8_t * const p_hci_status); + +/**@brief Encodes @ref sd_ble_gap_disconnect command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_disconnect_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_tx_power_set command request. + * + * @sa @ref ble_gap_tx_power_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] tx_power Pointer to TX power value. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_tx_power_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + int8_t * tx_power); + +/**@brief Encodes @ref sd_ble_gap_tx_power_set command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_tx_power_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_ppcp_set command request. + * + * @sa @ref ble_gap_ppcp_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_conn_params Pointer to pointer to connection parameters to be set. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for connection + * parameters field present. + */ +uint32_t ble_gap_ppcp_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_conn_params_t * * const pp_conn_params); + +/**@brief Encodes @ref sd_ble_gap_ppcp_set command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_ppcp_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + + +/**@brief Decodes @ref sd_ble_gap_ppcp_get command request. + * + * @sa @ref ble_gap_ppcp_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_conn_params Pointer to pointer to ble_gap_conn_params_t. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_ppcp_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_gap_conn_params_t * * const pp_conn_params); + +/**@brief Encodes @ref sd_ble_gap_ppcp_get command response. + * + * @sa @ref ble_gap_ppcp_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_conn_params Pointer to ble_gap_conn_params_t. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_ppcp_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_conn_params_t const * const p_conn_params); + +/**@brief Encodes @ref sd_ble_gap_adv_stop command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_adv_stop_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_auth_key_reply command request. + * + * @sa @ref ble_gap_auth_key_reply_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] p_key_type Pointer to key type. + * @param[out] pp_key Pointer to pointer to buffer for incoming key. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_auth_key_reply_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_key_type, + uint8_t * * const pp_key); + +/**@brief Encodes @ref sd_ble_gap_auth_key_reply command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_auth_key_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_sec_params_reply command request. + * + * @sa @ref ble_gap_sec_params_reply_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] p_sec_status Pointer to security status. + * @param[out] pp_sec_params Pointer to pointer to security parameters structure. + * @param[out] pp_sec_keyset Pointer to pointer to security keyset structure. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for connection + * parameters field present. + */ +uint32_t ble_gap_sec_params_reply_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_sec_status, + ble_gap_sec_params_t * * const pp_sec_params, + ble_gap_sec_keyset_t * * const pp_sec_keyset); + +/**@brief Encodes @ref sd_ble_gap_sec_params_reply command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in] p_sec_keyset Pointer to security keyset structure. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_sec_params_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_sec_keyset_t * const p_sec_keyset); + +/**@brief Decodes @ref sd_ble_gap_rssi_start command request. + * + * @sa @ref ble_gap_rssi_start_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] p_threshold_dbm Pointer to threshold in dBm. + * @param[out] p_skip_count Pointer to sample skip count. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_rssi_start_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_threshold_dbm, + uint8_t * p_skip_count); + +/**@brief Encodes @ref sd_ble_gap_rssi_start command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ + +uint32_t ble_gap_rssi_start_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_rssi_stop command request. + * + * @sa @ref ble_gap_rssi_stop_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] conn_handle Pointer to connection handle. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ + +uint32_t ble_gap_rssi_stop_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * conn_handle); + +/**@brief Encodes @ref sd_ble_gap_rssi_stop command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ + +uint32_t ble_gap_rssi_stop_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_appearance_get command request. + * + * @sa @ref ble_gap_appearance_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_appearance Pointer to pointer to uint16_t appearance. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_appearance_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * * const pp_appearance); + +/**@brief Encodes @ref sd_ble_gap_appearance_get command response. + * + * @sa @ref ble_gap_appearance_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_appearance Pointer to uint16_t appearance. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_appearance_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_appearance); + + +/**@brief Decodes @ref sd_ble_gap_appearance_set command request. + * + * @sa @ref ble_gap_tx_power_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] buf_len Length (in bytes) of the packet. + * @param[out] p_appearance Pointer to the appearance. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_appearance_set_req_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint16_t * const p_appearance); + +/**@brief Encodes @ref sd_ble_gap_appearance_set command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_appearance_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + + +/**@brief Decodes @ref sd_ble_gap_sec_info_reply command request. + * + * @sa @ref ble_gap_sec_info_reply_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of the packet. + * @param[out] p_conn_handle Pointer to the Connection Handle. + * @param[out] pp_enc_info Pointer to pointer to Encryption Information. + * @param[out] pp_id_info Pointer to pointer to ID Information. + * @param[out] pp_sign_info Pointer to pointer to Signing Information. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_sec_info_reply_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + ble_gap_enc_info_t * * const pp_enc_info, + ble_gap_irk_t * * const pp_id_info, + ble_gap_sign_info_t * * const pp_sign_info); + +/**@brief Encodes @ref sd_ble_gap_sec_info_reply command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_sec_info_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_device_name_set command request. + * + * @sa @ref ble_gap_device_name_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of the packet. + * @param[out] pp_write_perm Pointer to pointer to write permissions filed. + * @param[out] pp_dev_name Pointer to pointer to device name string. + * @param[out] p_dev_name_len Pointer to device name string length. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_device_name_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_conn_sec_mode_t * * const pp_write_perm, + uint8_t * * const pp_dev_name, + uint16_t * const p_dev_name_len); + + +/**@brief Encodes @ref sd_ble_gap_device_name_set command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_device_name_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_conn_sec_get command request. + * + * @sa @ref ble_gap_conn_sec_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to Connection Handle. + * @param[out] pp_conn_sec Pointer to pointer to @ref ble_gap_conn_sec_t to be filled by + * the SoftDevice. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_conn_sec_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_conn_sec_t * * const pp_conn_sec); + +/**@brief Encodes @ref sd_ble_gap_conn_sec_get command response. + * + * @sa @ref ble_gap_conn_sec_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_conn_sec Pointer to @ref ble_gap_conn_sec_t to be encoded. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_conn_sec_get_rsp_enc(uint32_t return_code, + ble_gap_conn_sec_t * const p_conn_sec, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Encodes @ref sd_ble_gap_scan_stop command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_scan_stop_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_connect command request. + * + * @sa @ref ble_gap_connect_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_addr Pointer to pointer to peer address @ref ble_gap_addr_t. + * @param[out] pp_scan_params Pointer to pointer to @ref ble_gap_scan_params_t. + * @param[out] pp_conn_params Pointer to pointer to @ref ble_gap_conn_params_t. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_connect_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * * const pp_addr, + ble_gap_scan_params_t * * const pp_scan_params, + ble_gap_conn_params_t * * const pp_conn_params +#if NRF_SD_BLE_API_VERSION >= 4 + ,uint8_t * p_conn_cfg_tag +#endif + ); + +/**@brief Encodes @ref sd_ble_gap_connect command response. + * + * @sa @ref ble_gap_connect_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_connect_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_scan_start command request. + * + * @sa @ref ble_gap_scan_start_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_scan_params Pointer to pointer to @ref ble_gap_scan_params_t. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_scan_start_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_scan_params_t * * const pp_scan_params); + +/**@brief Encodes @ref sd_ble_gap_scan_start command response. + * + * @sa @ref ble_gap_scan_start_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_scan_start_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Encodes @ref sd_ble_gap_connect_cancel command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_connect_cancel_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_encrypt command request. + * + * @sa @ref ble_gap_encrypt_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer connection_handle. + * @param[out] pp_master_id Pointer to pointer to @ref ble_gap_master_id_t. + * @param[out] pp_enc_info Pointer to pointer to @ref ble_gap_enc_info_t. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ + +uint32_t ble_gap_encrypt_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gap_master_id_t ** const pp_master_id, + ble_gap_enc_info_t ** const pp_enc_info); + +/**@brief Encodes @ref sd_ble_gap_encrypt command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_encrypt_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_rssi_get command request. + * + * @sa @ref ble_gap_rssi_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_conn_handle Connection handle. + * @param[out] pp_rssi Pointer to pointer to RSSI value. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_rssi_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + int8_t * * const pp_rssi); + +/**@brief Encodes @ref sd_ble_gap_rssi_get command response. + * + * @sa @ref ble_gap_rssi_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] rssi RSSI value. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_rssi_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + int8_t rssi); + +/**@brief Decodes @ref sd_ble_gap_keypress_notify command request. + * + * @sa @ref ble_gap_keypress_notify_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Connection handle. + * @param[out] p_kp_not Pointer kp_not value. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_keypress_notify_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_kp_not); + +/**@brief Encodes @ref sd_ble_gap_keypress_notify command response. + * + * @sa @ref ble_gap_keypress_notify_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_keypress_notify_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_lesc_dhkey_reply command request. + * + * @sa @ref ble_gap_lesc_dhkey_reply_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Connection handle. + * @param[out] pp_dhkey Pointer to pointer to dhkey struct. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_lesc_dhkey_reply_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_lesc_dhkey_t * * pp_dhkey); + +/**@brief Encodes @ref sd_ble_gap_lesc_dhkey_reply command response. + * + * @sa @ref ble_gap_lesc_dhkey_reply_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_lesc_dhkey_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_lesc_oob_data_set command request. + * + * @sa @ref ble_gap_lesc_oob_data_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Connection handle. + * @param[out] pp_oobd_own Pointer to pointer to own OOB data struct. + * @param[out] pp_oobd_peer Pointer to pointer to peer OOB data struct. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_lesc_oob_data_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_lesc_oob_data_t * * pp_oobd_own, + ble_gap_lesc_oob_data_t * * pp_oobd_peer); + +/**@brief Encodes @ref sd_ble_gap_lesc_oob_data_set command response. + * + * @sa @ref ble_gap_lesc_oob_data_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_lesc_oob_data_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_lesc_oob_data_get command request. + * + * @sa @ref ble_gap_lesc_oob_data_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Connection handle. + * @param[out] pp_pk_own Pointer to pointer to PK. + * @param[out] pp_oobd_own Pointer to pointer to own OOB data struct. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_lesc_oob_data_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_lesc_p256_pk_t * * pp_pk_own, + ble_gap_lesc_oob_data_t * * pp_oobd_own); + +/**@brief Encodes @ref sd_ble_gap_lesc_oob_data_get command response. + * + * @sa @ref ble_gap_lesc_oob_data_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_oobd_own Pointer to OOB data. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_lesc_oob_data_get_rsp_enc(uint32_t return_code, + ble_gap_lesc_oob_data_t * p_oobd_own, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_addr_get command request. + * + * @sa @ref ble_gap_addr_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_address Pointer to pointer to address. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_addr_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_gap_addr_t * * const pp_address); + +/**@brief Encodes @ref sd_ble_gap_addr_get command response. + * + * @sa @ref ble_gap_addr_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_address Pointer to @ref ble_gap_addr_t address + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_addr_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_addr_t const * const p_address); + +/** @brief Decodes @ref sd_ble_gap_addr_set command request. + * + * @sa @ref ble_gap_addr_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] pp_addr Pointer to pointer to the address structure. + + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_addr_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * * const pp_addr); + +/**@brief Encodes @ref sd_ble_gap_addr_set command response. + * + * @sa @ref ble_gap_addr_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_addr_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @brief Decodes @ref sd_ble_gap_privacy_set command request. + * + * @sa @ref ble_gap_privacy_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] pp_privacy_params Pointer to pointer to the privacy settings structure. + + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_privacy_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_privacy_params_t * * const pp_privacy_params); + +/**@brief Encodes @ref sd_ble_gap_privacy_set command response. + * + * @sa @ref ble_gap_privacy_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_privacy_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @brief Decodes @ref sd_ble_gap_privacy_get command request. + * + * @sa @ref ble_gap_privacy_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] pp_privacy_params Pointer to pointer to the privacy settings structure. + + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_privacy_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_gap_privacy_params_t * * const pp_privacy_params); + +/**@brief Encodes @ref sd_ble_gap_privacy_set command response. + * + * @sa @ref ble_gap_privacy_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[out] p_privacy_params Pointer to privacy settings structure. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_privacy_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_privacy_params_t const * const p_privacy_params); + +/** @brief Decodes @ref sd_ble_gap_whitelist_set command request. + * + * @sa @ref ble_gap_whitelist_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] ppp_wl_addrs Pointer to a whitelist of peer addresses. + * @param[out] p_len Pointer to a length of the whitelist. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_whitelist_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * * * const ppp_wl_addrs, + uint8_t * const p_len); + +/**@brief Encodes @ref sd_ble_gap_whitelist_set command response. + * + * @sa @ref ble_gap_whitelist_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_whitelist_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @brief Decodes @ref sd_ble_gap_device_identities_set command request. + * + * @sa @ref ble_gap_device_identities_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] ppp_id_keys Pointer to an array of peer identity addresses and peer IRKs. + * @param[out] ppp_local_irks Pointer to an array of local IRKs. + * @param[out] p_len Pointer to a length of the device identity list. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_device_identities_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_id_key_t * * * const ppp_id_keys, + ble_gap_irk_t * * * const ppp_local_irks, + uint8_t * const p_len); + +/**@brief Encodes @ref sd_ble_gap_device_identities_set command response. + * + * @sa @ref ble_gap_device_identities_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_device_identities_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +#if NRF_SD_BLE_API_VERSION >= 4 +/** @brief Decodes @ref sd_bble_gap_data_length_update command request. + * + * @sa @ref ble_gap_data_length_update_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] p_conn_handle Pointer to a connection handle. + * @param[out] pp_dl_params Pointer to pointer to a data length params structure. + * @param[out] pp_dl_limitation Pointer to pointer to a data length limitation structure. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_data_length_update_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + ble_gap_data_length_params_t * * const pp_dl_params, + ble_gap_data_length_limitation_t * * const pp_dl_limitation); + +/**@brief Encodes @ref sd_ble_gap_data_length_update command response. + * + * @sa @ref ble_gap_data_length_update_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_data_length_update_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_data_length_limitation_t const * const p_dl_limitation); +#endif +#if NRF_SD_BLE_API_VERSION >= 5 +/**@brief Decodes @ref sd_ble_gap_phy_request command request. + * + * @sa @ref ble_gap_phy_request_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle + * @param[out] pp_gap_phys Pointer to pointer to the struct. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_phy_request_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + ble_gap_phys_t * * const pp_gap_phys); + +/**@brief Encodes @ref sd_ble_gap_phy_request command response. + * + * @sa @ref ble_gap_phy_request_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_phy_request_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +#endif +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.c new file mode 100644 index 0000000000000000000000000000000000000000..be64d8639542aa0d6d2f45acc4d39ac0162e6a03 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.c @@ -0,0 +1,348 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble.h" +#include "ble_gap_evt_conn.h" +#include +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "conn_ble_gap_sec_keys.h" +#include "app_util.h" + +extern ser_ble_gap_conn_keyset_t m_conn_keys_table[]; + +uint32_t ble_gap_evt_adv_report_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_ADV_REPORT); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.adv_report, ble_gap_evt_adv_report_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_auth_key_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_AUTH_KEY_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.gap_evt.params.auth_key_request.key_type); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_auth_status_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_AUTH_STATUS); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.auth_status, ble_gap_evt_auth_status_t_enc); + + // keyset is an extension of standard event data - used to synchronize keys at application + uint32_t conn_index; + err_code = conn_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); + if (err_code == NRF_SUCCESS) + { + SER_PUSH_FIELD(&(m_conn_keys_table[conn_index].keyset), ble_gap_sec_keyset_t_enc); + + err_code = conn_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + else + { + err_code = NRF_SUCCESS; + } + + SER_EVT_ENC_END; +} + + +uint32_t ble_gap_evt_conn_param_update_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.conn_param_update, ble_gap_evt_conn_param_update_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_conn_param_update_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.conn_param_update_request, + ble_gap_evt_conn_param_update_request_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_conn_sec_update_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_CONN_SEC_UPDATE); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.conn_sec_update, ble_gap_evt_conn_sec_update_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_connected_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_CONNECTED); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.connected, ble_gap_evt_connected_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_disconnected_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_DISCONNECTED); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.disconnected, ble_gap_evt_disconnected_t_enc); + + // If disconnected and context is not yet destroyed, destroy it now + uint32_t conn_index; + err_code = conn_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); + if (err_code == NRF_SUCCESS) + { + err_code = conn_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + err_code = NRF_SUCCESS; + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_key_pressed_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_KEY_PRESSED); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.gap_evt.params.key_pressed.kp_not); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_lesc_dhkey_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_LESC_DHKEY_REQUEST); + + uint8_t ser_data = p_event->evt.gap_evt.params.lesc_dhkey_request.oobd_req & 0x01; + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_COND(p_event->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer, ble_gap_lesc_p256_pk_t_enc); + SER_PUSH_uint8(&ser_data); + + SER_EVT_ENC_END; +} + +#define PASSKEY_LEN sizeof (p_event->evt.gap_evt.params.passkey_display.passkey) + + +uint32_t ble_gap_evt_passkey_display_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_PASSKEY_DISPLAY); + + uint8_t ser_data = p_event->evt.gap_evt.params.passkey_display.match_request & 0x01; + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_uint8array(p_event->evt.gap_evt.params.passkey_display.passkey, BLE_GAP_PASSKEY_LEN); + SER_PUSH_uint8(&ser_data); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_rssi_changed_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_RSSI_CHANGED); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_int8(&p_event->evt.gap_evt.params.rssi_changed.rssi); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_scan_req_report_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_SCAN_REQ_REPORT); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.scan_req_report.peer_addr, ble_gap_addr_t_enc); + SER_PUSH_int8(&p_event->evt.gap_evt.params.scan_req_report.rssi); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_sec_info_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_SEC_INFO_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.sec_info_request, ble_gap_evt_sec_info_request_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_sec_params_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_SEC_PARAMS_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.sec_params_request, ble_gap_evt_sec_params_request_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_sec_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_SEC_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.sec_request, ble_gap_evt_sec_request_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_timeout_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_TIMEOUT); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.gap_evt.params.timeout.src); + + SER_EVT_ENC_END; +} + +#if NRF_SD_BLE_API_VERSION >= 5 +uint32_t ble_gap_evt_phy_update_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_PHY_UPDATE); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.gap_evt.params.phy_update.status); + SER_PUSH_uint8(&p_event->evt.gap_evt.params.phy_update.tx_phy); + SER_PUSH_uint8(&p_event->evt.gap_evt.params.phy_update.rx_phy); + + SER_EVT_ENC_END; +} +#endif +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gap_evt_data_length_update_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.data_length_update_request.peer_params, ble_gap_data_length_params_t_enc); + + SER_EVT_ENC_END; +} +uint32_t ble_gap_evt_data_length_update_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_DATA_LENGTH_UPDATE); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.data_length_update.effective_params, ble_gap_data_length_params_t_enc); + + SER_EVT_ENC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..8619597750422a1c4646de1a0b45e6887401b689 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.h @@ -0,0 +1,425 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GAP_EVT_CONN_H__ +#define BLE_GAP_EVT_CONN_H__ + +/**@file + * + * @defgroup ble_gap_evt_conn GAP Connectivity event encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief GAP Connectivity event encoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Encodes ble_gap_evt_auth_key_request event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_auth_key_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_auth_status event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_auth_status_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_conn_param_update event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_conn_param_update_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_conn_sec_update event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_conn_sec_update_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_connected event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_connected_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_disconnected event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_disconnected_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_passkey_display event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_passkey_display_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_rssi_changed event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_rssi_changed_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_sec_info_request event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_sec_info_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_sec_params_request event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_sec_params_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_timeout event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_timeout_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_sec_request event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_sec_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_conn_param_update_request event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_conn_param_update_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_adv_report event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_adv_report_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_scan_req_report event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_scan_req_report_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + + uint32_t * const p_buf_len); +/** + * @brief Encodes ble_gap_evt_key_pressed event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_key_pressed_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_lesc_dhkey_request event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_lesc_dhkey_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +#if NRF_SD_BLE_API_VERSION >= 5 +/** + * @brief Encodes ble_gap_evt_phy_update event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_phy_update_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +#endif + +#if NRF_SD_BLE_API_VERSION >= 4 +/** + * @brief Encodes ble_gap_evt_data_length_update_request event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_data_length_update_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +/** + * @brief Encodes ble_gap_evt_data_length_update event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_data_length_update_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +#endif +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.c new file mode 100644 index 0000000000000000000000000000000000000000..098d7d4ad315e77256105c33221eb86927881243 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.c @@ -0,0 +1,299 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gattc_conn.h" +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_gattc_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include + + +uint32_t ble_gattc_attr_info_discover_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_ATTR_INFO_DISCOVER); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_handle_range); + SER_ASSERT_NOT_NULL(*pp_handle_range); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gattc_attr_info_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_ATTR_INFO_DISCOVER); +} + +uint32_t ble_gattc_char_value_by_uuid_read_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_uuid_t * * const pp_uuid, + ble_gattc_handle_range_t * * const + pp_handle_range) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_uuid); + SER_ASSERT_NOT_NULL(*pp_uuid); + SER_ASSERT_NOT_NULL(pp_handle_range); + SER_ASSERT_NOT_NULL(*pp_handle_range); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_uuid, ble_uuid_t_dec); + SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gattc_char_value_by_uuid_read_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ); +} + + +uint32_t ble_gattc_char_values_read_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * * const pp_handles, + uint16_t * const p_handle_count) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_CHAR_VALUES_READ); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_handles); + SER_ASSERT_NOT_NULL(*pp_handles); + SER_ASSERT_NOT_NULL(p_handle_count); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_len16data16(pp_handles, p_handle_count); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gattc_char_values_read_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_CHAR_VALUES_READ); +} + +uint32_t ble_gattc_characteristics_discover_req_dec( + uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gattc_characteristics_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER); +} + + +uint32_t ble_gattc_descriptors_discover_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_DESCRIPTORS_DISCOVER); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gattc_descriptors_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_DESCRIPTORS_DISCOVER); +} + +uint32_t ble_gattc_hv_confirm_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_HV_CONFIRM); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_handle); + + SER_REQ_DEC_END; +} + +uint32_t ble_gattc_hv_confirm_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_HV_CONFIRM); +} + +uint32_t ble_gattc_primary_services_discover_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_start_handle, + ble_uuid_t * * const pp_srvc_uuid) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_start_handle); + SER_PULL_COND(pp_srvc_uuid, ble_uuid_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gattc_primary_services_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER); +} + +uint32_t ble_gattc_read_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_handle, + uint16_t * const p_offset) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_READ); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_handle); + SER_PULL_uint16(p_offset); + + SER_REQ_DEC_END; +} + +uint32_t ble_gattc_read_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_READ); +} + +uint32_t ble_gattc_relationships_discover_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gattc_relationships_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER); +} + +uint32_t ble_gattc_write_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_write_params_t * * const pp_write_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_WRITE); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_write_params, ble_gattc_write_params_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gattc_write_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_WRITE); +} + +uint32_t ble_gattc_exchange_mtu_request_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_client_rx_mtu) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_client_rx_mtu); + + SER_REQ_DEC_END; +} + +uint32_t ble_gattc_exchange_mtu_request_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..2e871487a44c20a289f6e01cd112a2d5960977e2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.h @@ -0,0 +1,481 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GATTC_CONN_H__ +#define BLE_GATTC_CONN_H__ + +/**@file + * + * @defgroup ble_gatc_conn GATTC connectivity command request decoders and command response encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief GATTC Connectivity command request decoders and command response encoders + */ +#include "ble_gattc.h" +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Decodes @ref sd_ble_gattc_characteristics_discover command request. + * + * @sa @ref ble_gattc_characteristics_discover_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] pp_handle_range Pointer to pointer to handle range. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for handle range field present. + */ +uint32_t ble_gattc_characteristics_discover_req_dec + (uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range); + +/**@brief Encodes @ref sd_ble_gattc_characteristics_discover command response. + * + * @sa @ref ble_gattc_characteristics_discover_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_characteristics_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gattc_descriptors_discover command request. + * + * @sa @ref ble_gattc_descriptors_discover_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] pp_handle_range Pointer to pointer to handle range. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for handle range field present. + */ +uint32_t ble_gattc_descriptors_discover_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range); + +/**@brief Encodes @ref sd_ble_gattc_descriptors_discover command response. + * + * @sa @ref ble_gattc_descriptors_discover_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_descriptors_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gattc_relationships_discover command request. + * + * @sa @ref ble_gattc_relationships_discover_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] pp_handle_range Pointer to pointer to handle range. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for handle range field present. + */ +uint32_t ble_gattc_relationships_discover_req_dec + (uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range); + +/**@brief Encodes @ref sd_ble_gattc_relationships_discover command response. + * + * @sa @ref ble_gattc_relationships_discover_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_relationships_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gattc_primary_services_discover command request. + * + * @sa @ref ble_gattc_primary_services_discover_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] p_start_handle Pointer to start handle. + * @param[out] pp_srvc_uuid Pointer to pointer to service uuid. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for uuid field present. + */ +uint32_t ble_gattc_primary_services_discover_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_start_handle, + ble_uuid_t * * const pp_srvc_uuid); + +/**@brief Encodes @ref sd_ble_gattc_primary_services_discover command response. + * + * @sa @ref ble_gattc_primary_services_discover_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_primary_services_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gattc_read command request. + * + * @sa @ref ble_gattc_read_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] p_handle Pointer to handle. + * @param[out] p_offset Pointer to offset. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_read_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_handle, + uint16_t * const p_offset); + +/**@brief Encodes @ref sd_ble_gattc_read command response. + * + * @sa @ref ble_gattc_read_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_read_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gattc_char_values_read command request. + * + * @sa @ref ble_gattc_char_values_read_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] pp_handles Pointer to pointer to handle table. + * @param[out] p_handle_count Pointer to handle handle table count. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ + +uint32_t ble_gattc_char_values_read_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * * const pp_handles, + uint16_t * const p_handle_count); + +/**@brief Encodes @ref sd_ble_gattc_char_values_read command response. + * + * @sa @ref ble_gattc_char_values_read_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_char_values_read_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gattc_write command request. + * + * @sa @ref ble_gattc_write_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] pp_write_params Pointer to pointer to write parameters. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_write_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_write_params_t * * const pp_write_params); + +/**@brief Encodes @ref sd_ble_gattc_write command response. + * + * @sa @ref ble_gattc_write_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_write_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gattc_hv_confirm command request. + * + * @sa @ref ble_gattc_hv_confirm_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] p_handle Pointer to handle of the attribute in the indication. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_hv_confirm_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_handle); + +/**@brief Encodes @ref sd_ble_gattc_hv_confirm command response. + * + * @sa @ref ble_gattc_hv_confirm_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_hv_confirm_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gattc_char_value_by_uuid_read command request. + * + * @sa @ref ble_gattc_char_value_by_uuid_read_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] p_conn_handle Pointer to connection handle of the connection. + * @param[out] pp_uuid Pointer to pointer to a characteristic value UUID to read. + * @param[out] pp_handle_range Pointer to pointer to the range of handles to perform this + * procedure on. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid operation type. + */ +uint32_t ble_gattc_char_value_by_uuid_read_req_dec + (uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_uuid_t * * const pp_uuid, + ble_gattc_handle_range_t * * const pp_handle_range); + +/**@brief Encodes @ref sd_ble_gattc_char_value_by_uuid_read command response. + * + * @sa @ref ble_gattc_char_value_by_uuid_read_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_char_value_by_uuid_read_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gattc_attr_info_discover command request. + * + * @sa @ref ble_gattc_attr_info_discover_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] buf_len Length (in bytes) of request packet. + * @param[out] p_conn_handle Pointer to connection handle of the connection. + * @param[out] pp_handle_range Pointer to pointer to the range of handles. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid operation type. + */ +uint32_t ble_gattc_attr_info_discover_req_dec(uint8_t const * const p_buf, + uint16_t buf_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range); + +/**@brief Encodes @ref sd_ble_gattc_attr_info_discover command response. + * + * @sa @ref ble_gattc_attr_info_discover_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_attr_info_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gattc_exchange_mtu_request command request. + * + * @sa @ref ble_gattc_exchange_mtu_request_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] p_conn_handle Pointer to connection handle of the connection. + * @param[out] p_client_rx_mtu Pointer to Client RX MTU size. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid operation type. + */ +uint32_t ble_gattc_exchange_mtu_request_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_client_rx_mtu); + +/**@brief Encodes @ref sd_ble_gattc_exchange_mtu_request command response. + * + * @sa @ref ble_gattc_exchange_mtu_request_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_exchange_mtu_request_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.c new file mode 100644 index 0000000000000000000000000000000000000000..fdf313659acf7e53207ef1d74a3644d41e4ca683 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.c @@ -0,0 +1,253 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gattc_evt_conn.h" +#include "ble_serialization.h" +#include "ble_gattc_struct_serialization.h" +#include "app_util.h" +#include + +uint32_t ble_gattc_evt_attr_info_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_ATTR_INFO_DISC_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.attr_info_disc_rsp, + ble_gattc_evt_attr_info_disc_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_char_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_CHAR_DISC_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.char_disc_rsp, + ble_gattc_evt_char_disc_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.char_val_by_uuid_read_rsp, + ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_char_vals_read_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_CHAR_VALS_READ_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.char_vals_read_rsp, + ble_gattc_evt_char_vals_read_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_desc_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_DESC_DISC_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.desc_disc_rsp, + ble_gattc_evt_desc_disc_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_hvx_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_HVX); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.hvx, ble_gattc_evt_hvx_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.prim_srvc_disc_rsp, + ble_gattc_evt_prim_srvc_disc_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_read_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_READ_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.read_rsp, + ble_gattc_evt_read_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_rel_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_REL_DISC_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.rel_disc_rsp, + ble_gattc_evt_rel_disc_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_timeout_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_TIMEOUT); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.timeout, + ble_gattc_evt_timeout_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_write_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_WRITE_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.write_rsp, + ble_gattc_evt_write_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_exchange_mtu_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_EXCHANGE_MTU_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.exchange_mtu_rsp, + ble_gattc_evt_exchange_mtu_rsp_t_enc); + + SER_EVT_ENC_END; +} + +#if NRF_SD_BLE_API_VERSION >= 4 + +uint32_t ble_gattc_evt_write_cmd_tx_complete_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_uint8(&p_event->evt.gattc_evt.params.write_cmd_tx_complete.count); + + SER_EVT_ENC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..986713f77e993c74300ff8da4c5c80acd45c05e4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.h @@ -0,0 +1,300 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GATTC_EVT_CONN_H__ +#define BLE_GATTC_EVT_CONN_H__ + +/**@file + * + * @defgroup ble_gattc_evt_conn GATTC Connectivity event encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief GATTC Connectivity event encoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Encodes ble_gattc_evt_char_disc_rsp event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_char_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gattc_evt_char_val_by_uuid_read_rsp event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gattc_evt_char_vals_read_rsp event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_char_vals_read_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gattc_evt_desc_disc_rsp event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_desc_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gattc_evt_hvx event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_hvx_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gattc_evt_prim_srvc_disc_rsp event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gattc_evt_read_rsp event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_read_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gattc_evt_rel_disc_rsp event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_rel_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gattc_evt_timeout event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_timeout_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gattc_evt_write_rsp event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_write_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gattc_evt_attr_info_disc_rsp event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_attr_info_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gattc_evt_exchange_mtu_rsp event. + * + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ + +uint32_t ble_gattc_evt_exchange_mtu_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +#if NRF_SD_BLE_API_VERSION >= 4 +/** + * @brief Encodes @ref BLE_gattc_EVT_WRITE_CMD_TX_COMPLETE event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_write_cmd_tx_complete_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +#endif +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.c new file mode 100644 index 0000000000000000000000000000000000000000..ecb2abe97776cd31a17858674a8d56ee3de89822 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.c @@ -0,0 +1,421 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gatts_conn.h" +#include +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "app_util.h" +#include "cond_field_serialization.h" + +uint32_t ble_gatts_attr_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_handle, + ble_uuid_t * * pp_uuid, + ble_gatts_attr_md_t * * pp_md) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_ATTR_GET); + + SER_PULL_uint16(p_handle); + SER_PULL_COND(pp_uuid, NULL); + SER_PULL_COND(pp_md, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gatts_attr_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_uuid_t * p_uuid, + ble_gatts_attr_md_t * p_md) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_ATTR_GET); + + SER_PUSH_COND(p_uuid, ble_uuid_t_enc); + SER_PUSH_COND(p_md, ble_gatts_attr_md_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_characteristic_add_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_service_handle, + ble_gatts_char_md_t * * const pp_char_md, + ble_gatts_attr_t * * const pp_attr_char_value, + ble_gatts_char_handles_t * * const pp_handles) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_CHARACTERISTIC_ADD); + + SER_PULL_uint16(p_service_handle); + SER_PULL_COND(pp_char_md, ble_gatts_char_md_t_dec); + SER_PULL_COND(pp_attr_char_value, ble_gatts_attr_t_dec); + SER_PULL_COND(pp_handles, NULL); + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_characteristic_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gatts_char_handles_t const * const p_handles) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_CHARACTERISTIC_ADD); + + SER_PUSH_COND(p_handles, ble_gatts_char_handles_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_descriptor_add_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_char_handle, + ble_gatts_attr_t * * const pp_attr, + uint16_t * * const pp_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_DESCRIPTOR_ADD); + + SER_PULL_uint16(p_char_handle); + SER_PULL_COND(pp_attr, ble_gatts_attr_t_dec); + SER_PULL_COND(pp_handle, NULL); + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_descriptor_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t * p_handle) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_DESCRIPTOR_ADD); + + SER_PUSH_COND(p_handle,uint16_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_hvx_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + ble_gatts_hvx_params_t * * const pp_hvx_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_HVX); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_hvx_params, ble_gatts_hvx_params_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_hvx_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_bytes_written) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_HVX); + + SER_PUSH_COND(p_bytes_written, uint16_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_include_add_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_service_handle, + uint16_t * const p_inc_srvc_handle, + uint16_t * * const pp_include_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_INCLUDE_ADD); + + SER_PULL_uint16(p_service_handle); + SER_PULL_uint16(p_inc_srvc_handle); + SER_PULL_COND(pp_include_handle, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gatts_include_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_include_handle) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_INCLUDE_ADD); + + SER_PUSH_COND(p_include_handle, uint16_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_initial_user_handle_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * * pp_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET); + + SER_PULL_COND(pp_handle, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gatts_initial_user_handle_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t * p_handle) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET); + + SER_PUSH_COND(p_handle, uint16_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_rw_authorize_reply_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gatts_rw_authorize_reply_params_t * * const pp_reply_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_RW_AUTHORIZE_REPLY); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_reply_params, ble_gatts_rw_authorize_reply_params_t_dec); + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_rw_authorize_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTS_RW_AUTHORIZE_REPLY); +} + +uint32_t ble_gatts_service_add_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_type, + ble_uuid_t * * const pp_uuid, + uint16_t * * const pp_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_SERVICE_ADD); + + SER_PULL_uint8(p_type); + SER_PULL_COND(pp_uuid, ble_uuid_t_dec); + SER_PULL_COND(pp_handle, NULL); + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_service_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_handle) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_SERVICE_ADD); + + SER_PUSH_COND(p_handle, uint16_t_enc); + //SER_PUSH_uint16(p_handle); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_service_changed_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint16_t * p_start_handle, + uint16_t * p_end_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_SERVICE_CHANGED); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_start_handle); + SER_PULL_uint16(p_end_handle); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gatts_service_changed_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTS_SERVICE_CHANGED); +} + +uint32_t ble_gatts_sys_attr_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint8_t * * const pp_sys_attr_data, + uint16_t * * const pp_sys_attr_data_len, + uint32_t * const p_flags) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_SYS_ATTR_GET); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_sys_attr_data_len, uint16_t_dec); + SER_PULL_COND(pp_sys_attr_data, NULL); + SER_PULL_uint32(p_flags); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gatts_sys_attr_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_sys_attr_data, + uint16_t const * const p_sys_attr_data_len) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_SYS_ATTR_GET); + + SER_PUSH_COND(p_sys_attr_data_len, uint16_t_enc); + if (p_sys_attr_data_len) + { + SER_PUSH_buf(p_sys_attr_data, *p_sys_attr_data_len); + } + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_sys_attr_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint8_t * * const pp_sys_attr_data, + uint16_t * const p_sys_attr_data_len, + uint32_t * const p_flags) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_SYS_ATTR_SET); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_len16data(pp_sys_attr_data, p_sys_attr_data_len); + SER_PULL_uint32(p_flags); + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_sys_attr_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTS_SYS_ATTR_SET); +} + +uint32_t ble_gatts_value_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_handle, + ble_gatts_value_t * * const pp_value) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_VALUE_GET); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_handle); + + //Special case: skip the data. + SER_PULL_COND(pp_value, NULL); + if (*pp_value) + { + SER_PULL_uint16(&(*pp_value)->offset); + SER_PULL_uint16(&(*pp_value)->len); + SER_PULL_COND(&(*pp_value)->p_value, NULL); + } + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_value_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gatts_value_t * const p_value) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_VALUE_GET); + + SER_PUSH_COND(p_value, ble_gatts_value_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_value_set_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + uint16_t * p_handle, + ble_gatts_value_t * * const pp_value) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_VALUE_SET); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_handle); + SER_PULL_COND(pp_value, ble_gatts_value_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gatts_value_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gatts_value_t * p_value) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_VALUE_SET); + + SER_PUSH_COND(p_value, ble_gatts_value_t_enc); + + SER_RSP_ENC_END; +} + + +uint32_t ble_gatts_exchange_mtu_reply_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_server_rx_mtu) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_EXCHANGE_MTU_REPLY); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_server_rx_mtu); + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_exchange_mtu_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTS_EXCHANGE_MTU_REPLY); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..811418a2007145817d4217ac8ee0c50887c42880 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.h @@ -0,0 +1,634 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GATTS_CONN_H__ +#define BLE_GATTS_CONN_H__ + +/**@file + * + * @defgroup ble_gatts_conn GATTS Connectivity command request decoders and command response encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief GATTS Connectivity command request decoders and command response encoders. + */ + +#include "ble_gatts.h" +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Decodes @ref sd_ble_gatts_value_get command request. + * + * @sa @ref ble_gatts_value_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] p_conn_handle Pointer to the connection_handle. + * @param[out] p_handle Pointer to the attribute_handle. + * @param[out] pp_value Pointer to pointer to the Attribute Value structure. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_value_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_handle, + ble_gatts_value_t * * const pp_value); + +/**@brief Encodes @ref sd_ble_gatts_value_get command response. + * + * @sa @ref ble_gatts_value_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_value Pointer to Attribute Value structure. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_value_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gatts_value_t * const p_value); + +/**@brief Decodes @ref sd_ble_gatts_characteristic_add command request. + * + * @sa @ref ble_gatts_characteristic_add_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] p_service_handle Pointer to the service_handle. + * @param[out] constpp_char_md Pointer to pointer to the location where Characteristic metadata + * will be decoded. + * @param[out] pp_attr_char_value Pointer to pointer to the location where GATT Attribute will be + * decoded. + * @param[out] pp_handles Pointer to pointer to the location where Characteristic definition + * handles will be decoded. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_characteristic_add_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_service_handle, + ble_gatts_char_md_t * * constpp_char_md, + ble_gatts_attr_t * * const pp_attr_char_value, + ble_gatts_char_handles_t * * const pp_handles); + +/**@brief Encodes @ref ble_gatts_sys_attr_get_rsp_enc command response. + * + * @sa @ref ble_gatts_sys_attr_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_handles Pointer to handle struct to be encoded. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_characteristic_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gatts_char_handles_t const * const p_handles); + +/**@brief Decodes @ref sd_ble_gatts_include_add command request. + * + * @sa @ref ble_gatts_include_add_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] p_service_handle Pointer to the service_handle. + * @param[out] p_inc_srvc_handle Pointer to the handle of the included service. + * @param[out] pp_include_handle Pointer to Pointer to 16-bit word where the assigned handle will be stored. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ + +uint32_t ble_gatts_include_add_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_service_handle, + uint16_t * const p_inc_srvc_handle, + uint16_t * * const pp_include_handle); + +/**@brief Encodes @ref ble_gatts_include_add_rsp_enc command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_include_handle Pointer to a 16-bit word where the assigned handle was stored. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ + +uint32_t ble_gatts_include_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_include_handle); + +/**@brief Decodes @ref sd_ble_gatts_service_add command request. + * + * @sa @ref ble_gatts_service_add_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] p_type Pointer to the service type. + * @param[out] pp_uuid Pointer to pointer to service UUID. + * @param[out] pp_handle Pointer to pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ + +uint32_t ble_gatts_service_add_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_type, + ble_uuid_t * * const pp_uuid, + uint16_t * * const pp_handle); + +/**@brief Encodes @ref ble_gatts_service_add_rsp_enc command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_handle Pointer to a 16-bit word where the assigned handle was stored. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ + +uint32_t ble_gatts_service_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_handle); + +/**@brief Decodes @ref ble_gatts_sys_attr_get_req_dec command request. + * + * @sa @ref ble_gatts_sys_attr_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connectiton handle. + * @param[out] pp_sys_attr_data Pointer to pointer to buffer where system attributes data will be filled in. + * @param[out] pp_sys_attr_data_len Pointer to pointer to variable which contains size of buffer for system attributes. + * @param[out] p_flags Pointer to additional optional flags. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gatts_sys_attr_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint8_t * * const pp_sys_attr_data, + uint16_t * * const pp_sys_attr_data_len, + uint32_t * const p_flags); + +/**@brief Encodes @ref ble_gatts_sys_attr_get_rsp_enc command response. + * + * @sa @ref ble_gatts_sys_attr_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_sys_attr_data Pointer to buffer where system attributes data are stored. + * @param[in] p_sys_attr_data_len Pointer to variable which contains size of buffer for system attributes. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_sys_attr_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_sys_attr_data, + uint16_t const * const p_sys_attr_data_len); + +/**@brief Decodes @ref sd_ble_gatts_value_set command request. + * + * @sa @ref ble_gatts_value_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] p_handle Pointer to attribute handle. + * @param[out] pp_value Pointer to pointer to attribute value structure. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ + +uint32_t ble_gatts_value_set_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + uint16_t * p_handle, + ble_gatts_value_t * * const pp_value); + +/**@brief Encodes @ref sd_ble_gatts_value_set command response. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_value \c in: size of value returned when value was written with success + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_value_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gatts_value_t * p_value); + +/**@brief Decodes @ref sd_ble_gatts_sys_attr_set command request. + * + * @sa @ref ble_gatts_sys_attr_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] p_conn_handle Pointer to the buffer raw data to be placed in advertisement packet. + * @param[out] pp_sys_attr_data Pointer to pointer to system attribute data. + * @param[out] p_sys_attr_data_len Pointer to data length for system attribute data. + * @param[out] p_flags Pointer to additional optional flags. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_sys_attr_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint8_t * * const pp_sys_attr_data, + uint16_t * const p_sys_attr_data_len, + uint32_t * const p_flags); + +/**@brief Encodes @ref sd_ble_gatts_sys_attr_set command response. + * + * @sa @ref ble_gatts_sys_attr_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_sys_attr_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref ble_gatts_hvx_req_dec command request. + * + * @sa @ref ble_gatts_hvx_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] p_conn_handle Pointer to the buffer raw data to be placed in advertisement packet. + * @param[out] pp_hvx_params Pointer to an HVx parameters structure. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_hvx_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + ble_gatts_hvx_params_t * * const pp_hvx_params); + +/**@brief Encodes @ref ble_gatts_hvx_rsp_enc command response. + * + * @sa @ref ble_gatts_hvx_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_bytes_written Pointer to number of bytes written. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_hvx_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_bytes_written); + +/**@brief Decodes @ref sd_ble_gatts_descriptor_add command request. + * + * @sa @ref ble_gatts_descriptor_add_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] p_char_handle Pointer to buffer where characteristic handle will be. + returned. + * @param[out] pp_attr Pointer to pointer to an attribute structure. + * @param[out] pp_handle Pointer to pointer to descriptor handle. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_descriptor_add_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_char_handle, + ble_gatts_attr_t * * const pp_attr, + uint16_t * * const pp_handle); + +/**@brief Encodes @ref sd_ble_gatts_descriptor_add command response. + * + * @sa @ref ble_gatts_descriptor_add_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_handle Pointer to descriptor handle value. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_descriptor_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t * p_handle); + +/**@brief Decodes @ref sd_ble_gatts_rw_authorize_reply command request. + * + * @sa @ref ble_gatts_rw_authorize_reply_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] pp_reply_params Pointer to pointer to \ref ble_gatts_rw_authorize_reply_params_t . + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ + +uint32_t ble_gatts_rw_authorize_reply_req_dec( + uint8_t const * const p_buf, + uint32_t + packet_len, + uint16_t * + p_conn_handle, + ble_gatts_rw_authorize_reply_params_t * * const + pp_reply_params); + +/**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command response. + * + * @sa @ref ble_gatts_rw_authorize_reply_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_rw_authorize_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gatts_service_changed command request. + * + * @sa @ref ble_gatts_service_changed_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] p_start_handle Pointer to start handle. + * @param[out] p_end_handle Pointer to end handle. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gatts_service_changed_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint16_t * p_start_handle, + uint16_t * p_end_handle); + +/**@brief Encodes @ref sd_ble_gatts_service_changed command response. + * + * @sa @ref ble_gatts_service_changed_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_service_changed_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref ble_gatts_attr_get_req_dec command request. + * + * @sa @ref ble_gatts_attr_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_handle Pointer to handle. + * @param[out] pp_uuid Pointer to pointer to location for decoded uuid structure. + * @param[out] pp_md Pointer to pointer to location for md structure. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gatts_attr_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_handle, + ble_uuid_t * * pp_uuid, + ble_gatts_attr_md_t * * pp_md); + +/**@brief Encodes @ref ble_gatts_attr_get_rsp_enc command response. + * + * @sa @ref ble_gatts_attr_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_uuid Pointer to structure to be encoded. + * @param[in] p_md Pointer to structure to be encoded. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_attr_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_uuid_t * p_uuid, + ble_gatts_attr_md_t * p_md); + +/**@brief Decodes @ref ble_gatts_initial_user_handle_get_req_dec command request. + * + * @sa @ref ble_gatts_initial_user_handle_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_handle Pointer to pointer to handle. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gatts_initial_user_handle_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * * pp_handle); + +/**@brief Encodes @ref ble_gatts_initial_user_handle_get_rsp_enc command response. + * + * @sa @ref ble_gatts_initial_user_handle_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_handle Pointer to handle to be encoded. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_initial_user_handle_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t * p_handle); + +/**@brief Decodes @ref sd_ble_gatts_rw_authorize_reply command request. + * + * @ref ble_gatts_exchange_mtu_reply_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] p_server_rx_mtu Pointer to Server RX MTU size. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ + +uint32_t ble_gatts_exchange_mtu_reply_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_server_rx_mtu); + +/**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command response. + * + * @ref ble_gatts_exchange_mtu_reply_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_exchange_mtu_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif //BLE_GATTS_CONN_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.c new file mode 100644 index 0000000000000000000000000000000000000000..81a262896a8c397804bb60e268bf8c455bb09369 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.c @@ -0,0 +1,178 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_gatts_evt_conn.h" +#include "ble_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "conn_ble_user_mem.h" +#include "app_util.h" + +extern sercon_ble_user_mem_t m_conn_user_mem_table[]; + + +uint32_t ble_gatts_evt_rw_authorize_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.authorize_request, ble_gatts_evt_rw_authorize_request_t_enc); + + if((p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && + ((p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || + (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ))) + { + uint32_t conn_index; + + if(conn_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) + { + err_code = len16data_enc(m_conn_user_mem_table[conn_index].mem_block.p_mem, m_conn_user_mem_table[conn_index].mem_block.len, p_buf, *p_buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + } + + SER_EVT_ENC_END; +} + + +uint32_t ble_gatts_evt_hvc_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_HVC); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.hvc, ble_gatts_evt_hvc_t_enc); + + SER_EVT_ENC_END; +} + + +uint32_t ble_gatts_evt_sc_confirm_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_HVC); + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_EVT_ENC_END; +} + + +uint32_t ble_gatts_evt_sys_attr_missing_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_SYS_ATTR_MISSING); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.sys_attr_missing, ble_gatts_evt_sys_attr_missing_t_enc); + + SER_EVT_ENC_END; +} + + +uint32_t ble_gatts_evt_timeout_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_TIMEOUT); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.timeout, ble_gatts_evt_timeout_t_enc); + + SER_EVT_ENC_END; +} + + +uint32_t ble_gatts_evt_write_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_WRITE); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.write, ble_gatts_evt_write_t_enc); + + if((p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_WRITE_REQ) || (p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)) + { + uint32_t conn_index; + if(conn_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) + { + SER_PUSH_len16data(m_conn_user_mem_table[conn_index].mem_block.p_mem, m_conn_user_mem_table[conn_index].mem_block.len); + } + } + + SER_EVT_ENC_END; +} + + +uint32_t ble_gatts_evt_exchange_mtu_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.exchange_mtu_request, ble_gatts_evt_exchange_mtu_request_t_enc); + + SER_EVT_ENC_END; +} + +#if NRF_SD_BLE_API_VERSION >= 4 +uint32_t ble_gatts_evt_hvn_tx_complete_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_HVN_TX_COMPLETE); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.gatts_evt.params.hvn_tx_complete.count); + + SER_EVT_ENC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..0123d3dd87660deea1e3cf59588d3e14c63c0f09 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.h @@ -0,0 +1,208 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_GATTS_EVT_CONN_H__ +#define BLE_GATTS_EVT_CONN_H__ + +/**@file + * + * @defgroup ble_gatts_evt_conn GATTS Connectivity event encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief GATTS Connectivity event encoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Encodes @ref BLE_GATTS_EVT_HVC event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_evt_hvc_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_evt_rw_authorize_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes @ref BLE_GATTS_EVT_SC_CONFIRM event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_evt_sc_confirm_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes @ref BLE_GATTS_EVT_SYS_ATTR_MISSING event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_evt_sys_attr_missing_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes @ref BLE_GATTS_EVT_TIMEOUT event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_evt_timeout_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes @ref BLE_GATTS_EVT_WRITE event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_evt_write_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_evt_exchange_mtu_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +#if NRF_SD_BLE_API_VERSION >= 4 + +/** + * @brief Encodes @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_evt_hvn_tx_complete_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +#endif +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.c new file mode 100644 index 0000000000000000000000000000000000000000..deaaf4b3350f55a3835ea6ded66b00340195cefa --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.c @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "ble_l2cap_conn.h" +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_l2cap_cid_register_req_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint16_t * p_cid) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_cid); + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_LENGTH_EQ(3, buf_len); + SER_ASSERT(p_buf[index] == SD_BLE_L2CAP_CID_REGISTER, NRF_ERROR_INVALID_PARAM); + + index++; + err_code = uint16_t_dec(p_buf, buf_len, &index, p_cid); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, buf_len); + + return err_code; +} + + +uint32_t ble_l2cap_cid_register_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_CID_REGISTER, return_code, + p_buf, p_buf_len); +} + +uint32_t ble_l2cap_cid_unregister_req_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint16_t * p_cid) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_cid); + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_LENGTH_EQ(3, buf_len); + SER_ASSERT(p_buf[index] == SD_BLE_L2CAP_CID_UNREGISTER, NRF_ERROR_INVALID_PARAM); + + index++; + err_code = uint16_t_dec(p_buf, buf_len, &index, p_cid); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, buf_len); + + return err_code; +} + + +uint32_t ble_l2cap_cid_unregister_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_CID_UNREGISTER, return_code, + p_buf, p_buf_len); +} + + +uint32_t ble_l2cap_tx_req_dec(uint8_t const * const p_buf, + uint32_t const buf_len, + uint16_t * p_conn_handle, + ble_l2cap_header_t * * const pp_l2cap_header, + uint8_t const * * pp_data) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_l2cap_header); + SER_ASSERT_NOT_NULL(*pp_l2cap_header); + SER_ASSERT_NOT_NULL(pp_data); + //SER_ASSERT_NOT_NULL(*pp_data); + + uint32_t err_code = NRF_SUCCESS; + uint32_t index = SER_CMD_DATA_POS; + + err_code = uint16_t_dec(p_buf, buf_len, &index, p_conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_l2cap_header, + ble_l2cap_header_t_dec); + + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (*pp_l2cap_header != NULL) + { + *pp_data = p_buf + index + 1; + index += 1 + (*pp_l2cap_header)->len; + } + else + { + *pp_data = NULL; + index++; + } + + SER_ASSERT_LENGTH_EQ(index, buf_len); + + return err_code; +} + +uint32_t ble_l2cap_tx_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_TX, return_code, + p_buf, p_buf_len); +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..03565eb1c8b1e7cedabf02232776d3a9be9c9bad --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.h @@ -0,0 +1,180 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ble_l2cap_conn L2CAP Connectivity command request decoders and command response encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief L2CAP Connectivity command request decoders and command response encoders. + */ + +#ifndef BLE_L2CAP_CONN_H__ +#define BLE_L2CAP_CON__H__ + +#include "ble.h" +#include "ble_types.h" +#include "ble_ranges.h" +#include "ble_err.h" +#include "ble_l2cap.h" + +#ifdef __cplusplus +extern "C" { +#endif +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +/**@brief Decodes @ref sd_ble_l2cap_cid_register command request. + * + * @sa @ref ble_l2cap_cid_register_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] buf_len Length (in bytes) of response packet. + * @param[in] p_cid Pointer to L2CAP CID. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_l2cap_cid_register_req_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint16_t * p_cid); + +/**@brief Encodes @ref sd_ble_l2cap_cid_register command response. + * + * @sa @ref ble_l2cap_cid_register_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_l2cap_cid_register_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_l2cap_cid_unregister command request. + * + * @sa @ref ble_l2cap_cid_unregister_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] buf_len Length (in bytes) of response packet. + * @param[in] p_cid Pointer to L2CAP CID. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_l2cap_cid_unregister_req_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint16_t * p_cid); + +/**@brief Encodes @ref sd_ble_l2cap_cid_unregister command response. + * + * @sa @ref ble_l2cap_cid_unregister_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_l2cap_cid_unregister_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_l2cap_tx command request. + * + * @sa @ref ble_l2cap_tx_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] buf_len Length (in bytes) of response packet. + * @param[in] p_conn_handle Pointer to connection handle. + * @param[in] pp_l2cap_header Pointer to pointer to L2CAP header. + * @param[in] pp_data Pointer to pointer L2CAP data. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_l2cap_tx_req_dec(uint8_t const * const p_buf, + uint32_t const buf_len, + uint16_t * p_conn_handle, + ble_l2cap_header_t * * const pp_l2cap_header, + uint8_t const * * pp_data); + +/**@brief Encodes @ref sd_ble_l2cap_tx command response. + * + * @sa @ref ble_l2cap_tx_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_l2cap_tx_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +#endif +#ifdef __cplusplus +} +#endif + +#endif //BLE_L2CAP_CONN_H__ + +/** + @} + */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.c new file mode 100644 index 0000000000000000000000000000000000000000..efa18d70ac43a2bced96e1ab132b4255f75f9355 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.c @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_l2cap_evt_conn.h" +#include +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "app_util.h" + +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 +uint32_t ble_l2cap_evt_rx_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_L2CAP_EVT_RX); + + SER_PUSH_uint16(&p_event->evt.l2cap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.l2cap_evt.params.rx, ble_l2cap_evt_rx_t_enc); + + SER_EVT_ENC_END; +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..73d4665baa81c003c94666621109385380dfc5f9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.h @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_L2CAP_EVT_CONN_H__ +#define BLE_L2CAP_EVT_CONN_H__ + +/**@file + * + * @defgroup ble_l2cap_evt_conn L2CAP Connectivity event encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief L2CAP Connectivity event encoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Encodes ble_l2cap_evt_rx event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_l2cap_evt_rx_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/conn_ble_gap_sec_keys.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/conn_ble_gap_sec_keys.c new file mode 100644 index 0000000000000000000000000000000000000000..b46c3ff93dafa31008b432f187a4d4483da632ed --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/conn_ble_gap_sec_keys.c @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "conn_ble_gap_sec_keys.h" +#include "nrf_error.h" +#include + +ser_ble_gap_conn_keyset_t m_conn_keys_table[SER_MAX_CONNECTIONS]; + +uint32_t conn_ble_gap_sec_context_create(uint32_t *p_index) +{ + uint32_t err_code = NRF_ERROR_NO_MEM; + uint32_t i; + + for (i=0; i + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SER_MAX_CONNECTIONS +#define SER_MAX_CONNECTIONS 8 +#endif + +/**@brief GAP connection - keyset mapping structure. + * + * @note This structure is used to map keysets to connection instances, and will be stored in a static table. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection handle. */ + uint8_t conn_active; /**< Indication that keys for this connection are used by the SoftDevice. 0: keys used; 1: keys not used. */ + ble_gap_sec_keyset_t keyset; /**< Keyset structure, see @ref ble_gap_sec_keyset_t. */ + ble_gap_enc_key_t enc_key_own; /**< Own Encryption Key, see @ref ble_gap_enc_key_t. */ + ble_gap_id_key_t id_key_own; /**< Own Identity Key, see @ref ble_gap_id_key_t. */ + ble_gap_sign_info_t sign_key_own; /**< Own Signing Information, see @ref ble_gap_sign_info_t. */ + ble_gap_lesc_p256_pk_t pk_own; /**< Own Public key, see @ref ble_gap_lesc_p256_pk_t. */ + ble_gap_enc_key_t enc_key_peer; /**< Peer Encryption Key, see @ref ble_gap_enc_key_t. */ + ble_gap_id_key_t id_key_peer; /**< Peer Identity Key, see @ref ble_gap_id_key_t. */ + ble_gap_sign_info_t sign_key_peer; /**< Peer Signing Information, see @ref ble_gap_sign_info_t. */ + ble_gap_lesc_p256_pk_t pk_peer; /**< Peer Public key, see @ref ble_gap_lesc_p256_pk_t. */ +} ser_ble_gap_conn_keyset_t; + +/**@brief Allocates instance in m_conn_keys_table[] for storage of encryption keys. + * + * @param[out] p_index Pointer to the index of allocated instance. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_NO_MEM No free instance available. + */ +uint32_t conn_ble_gap_sec_context_create(uint32_t *p_index); + +/**@brief Releases the instance identified by a connection handle. + * + * @param[in] conn_handle conn_handle + * + * @retval NRF_SUCCESS Context released. + * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found. + */ +uint32_t conn_ble_gap_sec_context_destroy(uint16_t conn_handle); + +/**@brief Finds index of the instance identified by a connection handle in m_conn_keys_table[]. + * + * @param[in] conn_handle conn_handle + * + * @param[out] p_index Pointer to the index of entry in the context table corresponding to the given conn_handle. + * + * @retval NRF_SUCCESS Context table entry found. + * @retval NRF_ERROR_NOT_FOUND Instance with the conn_handle not found. + */ +uint32_t conn_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif //_CONN_BLE_GAP_SEC_KEYS_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/conn_ble_user_mem.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/conn_ble_user_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..3aedf484ea6be2d4bb920b17ee0dcdfdd642f471 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/conn_ble_user_mem.c @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "conn_ble_user_mem.h" +#include "ser_config.h" +#include "nrf_error.h" +#include + + + +sercon_ble_user_mem_t m_conn_user_mem_table[SER_MAX_CONNECTIONS]; + +uint32_t conn_ble_user_mem_context_create(uint32_t *p_index) +{ + uint32_t err_code = NRF_ERROR_NO_MEM; + uint32_t i; + + for (i=0; i + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Connection - user memory mapping structure. + * + * @note This structure is used to map keysets to connection instances, and will be stored in a static table. + */ +//lint -esym(452,ser_ble_user_mem_t) +typedef struct +{ + uint16_t conn_handle; /**< Connection handle.*/ + uint8_t conn_active; /**< Indication that user memory for this connection is used by the SoftDevice. 0: memory used; 1: memory not used. */ + ble_user_mem_block_t mem_block; /**< User memory block structure, see @ref ble_user_mem_block_t. */ + uint8_t mem_table[64]; /**< Memory table. */ +} sercon_ble_user_mem_t; + +/**@brief Allocates instance in m_user_mem_table[] for storage. + * + * @param[out] p_index Pointer to the index of allocated instance. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_NO_MEM No free instance available. + */ +uint32_t conn_ble_user_mem_context_create(uint32_t *p_index); + +/**@brief Releases the instance identified by a connection handle. + * + * @param[in] conn_handle conn_handle + * + * @retval NRF_SUCCESS Context released. + * @retval NRF_ERROR_NOT_FOUND Instance with the conn_handle not found. + */ +uint32_t conn_ble_user_mem_context_destroy(uint16_t conn_handle); + +/**@brief Finds index of the instance identified by a connection handle in m_user_mem_table[]. + * + * @param[in] conn_handle conn_handle + * + * @param[out] p_index Pointer to the index of entry in the context table corresponding to the given conn_handle. + * + * @retval NRF_SUCCESS Context table entry found. + * @retval NRF_ERROR_NOT_FOUND Instance with the conn_handle not found. + */ +uint32_t conn_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif //_CONN_BLE_USER_MEM_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.c new file mode 100644 index 0000000000000000000000000000000000000000..3d13dff902925c80d99ea441e58567807a1dc3e0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.c @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_soc.h" +#include "nrf_soc_conn.h" +#include "nrf_error.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "nrf_soc_struct_serialization.h" + +uint32_t ecb_block_encrypt_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + nrf_ecb_hal_data_t * * const pp_ecb_data) +{ + SER_REQ_DEC_BEGIN(SD_ECB_BLOCK_ENCRYPT); + SER_PULL_COND(pp_ecb_data, nrf_ecb_hal_data_t_in_dec); + SER_REQ_DEC_END; +} + +uint32_t ecb_block_encrypt_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + nrf_ecb_hal_data_t * const p_ecb_data) +{ + SER_RSP_ENC_BEGIN(SD_ECB_BLOCK_ENCRYPT); + SER_PUSH_COND(p_ecb_data, nrf_ecb_hal_data_t_out_enc); + SER_RSP_ENC_END; +} +uint32_t power_system_off_req_dec(uint8_t const * const p_buf, + uint16_t packet_len) +{ + SER_REQ_DEC_BEGIN(SD_POWER_SYSTEM_OFF); + SER_REQ_DEC_END; +} + +uint32_t temp_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + int32_t * * const pp_temp) +{ + SER_REQ_DEC_BEGIN(SD_TEMP_GET); + SER_PULL_COND(pp_temp, NULL); + SER_REQ_DEC_END; +} + +uint32_t temp_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + int32_t * const p_temp) +{ + SER_RSP_ENC_BEGIN(SD_TEMP_GET); + SER_PUSH_COND(p_temp, uint32_t_enc); + SER_RSP_ENC_END; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..5c405d8ff5b29390fa59b4a114674c106df2775b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.h @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SOC_CONN_H__ +#define NRF_SOC_CONN_H__ + +/**@file + * + * @defgroup soc_conn SOC Connectivity command request decoders and command response encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief SOC Connectivity command request decoders and command response encoders. + */ +#include "nrf_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Decodes @ref sd_power_system_off command request. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in] packet_len Length (in bytes) of request packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter. + */ +uint32_t power_system_off_req_dec(uint8_t const * const p_buf, uint16_t packet_len); + + +/**@brief Decodes @ref sd_temp_get command request. + * + * @sa @ref temp_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] pp_temp Pointer to pointer to result of temperature measurement. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter. + */ +uint32_t temp_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + int32_t * * const pp_temp); + +/**@brief Encodes @ref sd_temp_get command response. + * + * @sa @ref temp_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_temp Pointer to result of temperature measurement. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t temp_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + int32_t * const p_temp); + +/**@brief Decodes @ref sd_ecb_block_encrypt command request. + * + * @sa @ref ecb_block_encrypt_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] pp_ecb_data Pointer to pointer to ECB data. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied + * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter. + */ +uint32_t ecb_block_encrypt_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + nrf_ecb_hal_data_t * * const pp_ecb_data); + +/**@brief Encodes @ref sd_ecb_block_encrypt command response. + * + * @sa @ref ecb_block_encrypt_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_ecb_data Pointer to ECB data. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ecb_block_encrypt_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + nrf_ecb_hal_data_t * const p_ecb_data); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/ble_dtm_conn.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/ble_dtm_conn.h new file mode 100644 index 0000000000000000000000000000000000000000..0ac61cf925b45ec795a829fec67a5b52cc74192c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/ble_dtm_conn.h @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef BLE_DTM_CONN_H__ +#define BLE_DTM_CONN_H__ + +/** + * @addtogroup ser_codecs_conn Connectivity codecs + * @ingroup ser_codecs + */ + +/** + * @addtogroup ser_conn_common_codecs Connectivity common codecs + * @ingroup ser_codecs_conn + */ + +/**@file + * + * @defgroup ble_dtm_conn DTM Connectivity command request decoder and command response encoder + * @{ + * @ingroup ser_conn_common_codecs + * + * @brief DTM Connectivity command request decoder and command response encoder. + */ + +#include "dtm_uart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Decodes @ref ble_dtm_init command request. + * + * @sa @ref encoding_data for packet format, + * @ref ble_dtm_init_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[in] p_comm_params Pointer to the structure with DTM UART configuration. + + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_dtm_init_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + app_uart_stream_comm_params_t * p_comm_params); + + +/**@brief Encodes @ref ble_dtm_init command response. + * + * @sa @ref encoding_data for packet format. + * @ref ble_dtm_init_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_dtm_init_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // BLE_DTM_CONN_H__ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/ble_dtm_init.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/ble_dtm_init.c new file mode 100644 index 0000000000000000000000000000000000000000..afd2f4e337312a3403fe00f845e35a7e74528c10 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/ble_dtm_init.c @@ -0,0 +1,83 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ble_dtm_conn.h" +#include "dtm_uart.h" +#include "nrf_error.h" +#include "ble_serialization.h" + +uint32_t ble_dtm_init_req_dec(uint8_t const * const p_buf, uint16_t packet_len, + app_uart_stream_comm_params_t * p_comm_params) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_comm_params); + + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + err_code = uint8_t_dec(p_buf, packet_len, &index, &p_comm_params->tx_pin_no); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, &p_comm_params->rx_pin_no); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = uint8_t_dec(p_buf, packet_len, &index, &p_comm_params->baud_rate); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT(index == packet_len, NRF_ERROR_INVALID_LENGTH); + + return err_code; +} + +uint32_t ble_dtm_init_rsp_enc(uint32_t return_code, uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + err_code = uint32_t_enc(&return_code, p_buf, *p_buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + *p_buf_len = index; + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw.c new file mode 100644 index 0000000000000000000000000000000000000000..c989e62abb4474322e942314c721248eca1a55db --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw.c @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include + +#include "ble_serialization.h" +#include "nrf_soc.h" + +#ifdef BLE_STACK_SUPPORT_REQD +#include "ble.h" +#include "ble_l2cap.h" +#include "ble_gap.h" +#include "ble_gattc.h" +#include "ble_gatts.h" +#endif // BLE_STAK_SUPPORT_REQD + +/**@brief Connectivity middleware handler type. */ +typedef uint32_t (*conn_mw_handler_t)(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Connectivity middleware item. */ +typedef struct +{ + uint8_t opcode; /**< Opcode by which specific codec is identified */ + conn_mw_handler_t fp_handler; /**< Function pointer to handler associated with given opcode */ +} conn_mw_item_t; + +/* Include handlers for given softdevice */ +#include "conn_mw_items.c" + +/**@brief Number of registered connectivity middleware handlers. */ +static const uint32_t conn_mw_item_len = sizeof (conn_mw_item) / sizeof (conn_mw_item[0]); + +/**@brief Local function for finding connectivity middleware handler in the table.. */ +static conn_mw_handler_t conn_mw_handler_get(uint8_t opcode) +{ + conn_mw_handler_t fp_handler = NULL; + uint32_t i; + + for (i = 0; i < conn_mw_item_len; i++) + { + if (opcode == conn_mw_item[i].opcode) + { + fp_handler = conn_mw_item[i].fp_handler; + break; + } + } + + return fp_handler; +} + +uint32_t conn_mw_handler(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + conn_mw_handler_t fp_handler; + uint32_t err_code = NRF_SUCCESS; + uint8_t opcode = p_rx_buf[SER_CMD_OP_CODE_POS]; + + fp_handler = conn_mw_handler_get(opcode); + + if (fp_handler) + { + err_code = fp_handler(p_rx_buf, rx_buf_len, p_tx_buf, p_tx_buf_len); + } + else + { + err_code = NRF_ERROR_NOT_SUPPORTED; + } + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw.h new file mode 100644 index 0000000000000000000000000000000000000000..08765660e30c184038ad76ecbc51ca7166880f81 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw.h @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef _CONN_MW_H +#define _CONN_MW_H + +/** + * @addtogroup ser_codecs_mw Connectivity middleware codecs + * @ingroup ser_codecs + */ + +/** + * @addtogroup ser_mw_common_codecs Connectivity middleware common codecs + * @{ + * @ingroup ser_codecs_mw + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Connectivity Middleware dispatcher function + * + * @details It will handle decode the opcode from the RX buffer and based on the opcode it will search + * for registered handler. Handler is called once it is found. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. + */ +uint32_t conn_mw_handler (uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif //_CONN_MW_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw_items.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw_items.c new file mode 100644 index 0000000000000000000000000000000000000000..16ee362f7d3420cb48478c3eb7ca0e4e4d3c81ae --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw_items.c @@ -0,0 +1,196 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "conn_mw_nrf_soc.h" +#if defined(BLE_STACK_SUPPORT_REQD) +#include "conn_mw_ble.h" +#include "conn_mw_ble_l2cap.h" +#include "conn_mw_ble_gap.h" +#include "conn_mw_ble_gatts.h" +#include "conn_mw_ble_gattc.h" +#endif // defined(BLE_STACK_SUPPORT_REQD) +#if defined(ANT_STACK_SUPPORT_REQD) +#include "conn_mw_ant.h" +#include "ant_interface.h" +#endif // defined(ANT_STACK_SUPPORT_REQD) + +/**@brief Connectivity middleware handlers table. */ +static const conn_mw_item_t conn_mw_item[] = { + //Functions from nrf_soc.h + {SD_POWER_SYSTEM_OFF, conn_mw_power_system_off}, + {SD_TEMP_GET, conn_mw_temp_get}, + {SD_ECB_BLOCK_ENCRYPT, conn_mw_ecb_block_encrypt}, +#if defined(BLE_STACK_SUPPORT_REQD) + //Functions from ble.h +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + {SD_BLE_TX_PACKET_COUNT_GET, conn_mw_ble_tx_packet_count_get}, +#endif + {SD_BLE_UUID_VS_ADD, conn_mw_ble_uuid_vs_add}, + {SD_BLE_UUID_DECODE, conn_mw_ble_uuid_decode}, + {SD_BLE_UUID_ENCODE, conn_mw_ble_uuid_encode}, + {SD_BLE_VERSION_GET, conn_mw_ble_version_get}, + {SD_BLE_OPT_GET, conn_mw_ble_opt_get}, + {SD_BLE_OPT_SET, conn_mw_ble_opt_set}, + {SD_BLE_ENABLE, conn_mw_ble_enable}, + {SD_BLE_USER_MEM_REPLY, conn_mw_ble_user_mem_reply}, +#if NRF_SD_BLE_API_VERSION >= 4 + {SD_BLE_CFG_SET, conn_mw_ble_cfg_set}, +#endif + //Functions from ble_l2cap.h +#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4 + {SD_BLE_L2CAP_CID_REGISTER, conn_mw_ble_l2cap_cid_register}, + {SD_BLE_L2CAP_CID_UNREGISTER, conn_mw_ble_l2cap_cid_unregister}, + {SD_BLE_L2CAP_TX, conn_mw_ble_l2cap_tx}, +#endif + //Functions from ble_gap.h + {SD_BLE_GAP_SCAN_STOP, conn_mw_ble_gap_scan_stop}, + {SD_BLE_GAP_ADDR_SET, conn_mw_ble_gap_addr_set}, + {SD_BLE_GAP_ADDR_GET, conn_mw_ble_gap_addr_get}, + {SD_BLE_GAP_PRIVACY_SET, conn_mw_ble_gap_privacy_set}, + {SD_BLE_GAP_PRIVACY_GET, conn_mw_ble_gap_privacy_get}, + {SD_BLE_GAP_WHITELIST_SET, conn_mw_ble_gap_whitelist_set}, + {SD_BLE_GAP_DEVICE_IDENTITIES_SET, conn_mw_ble_gap_device_identities_set}, + {SD_BLE_GAP_CONNECT, conn_mw_ble_gap_connect}, + {SD_BLE_GAP_CONNECT_CANCEL, conn_mw_ble_gap_connect_cancel}, + {SD_BLE_GAP_SCAN_START, conn_mw_ble_gap_scan_start}, + {SD_BLE_GAP_SEC_INFO_REPLY, conn_mw_ble_gap_sec_info_reply}, + {SD_BLE_GAP_ENCRYPT, conn_mw_ble_gap_encrypt}, + {SD_BLE_GAP_ADV_DATA_SET, conn_mw_ble_gap_adv_data_set}, + {SD_BLE_GAP_ADV_START, conn_mw_ble_gap_adv_start}, + {SD_BLE_GAP_ADV_STOP, conn_mw_ble_gap_adv_stop}, + {SD_BLE_GAP_CONN_PARAM_UPDATE, conn_mw_ble_gap_conn_param_update}, + {SD_BLE_GAP_DISCONNECT, conn_mw_ble_gap_disconnect}, + {SD_BLE_GAP_TX_POWER_SET, conn_mw_ble_gap_tx_power_set}, + {SD_BLE_GAP_APPEARANCE_SET, conn_mw_ble_gap_appearance_set}, + {SD_BLE_GAP_APPEARANCE_GET, conn_mw_ble_gap_appearance_get}, + {SD_BLE_GAP_PPCP_SET, conn_mw_ble_gap_ppcp_set}, + {SD_BLE_GAP_PPCP_GET, conn_mw_ble_gap_ppcp_get}, + {SD_BLE_GAP_DEVICE_NAME_SET, conn_mw_ble_gap_device_name_set}, + {SD_BLE_GAP_DEVICE_NAME_GET, conn_mw_ble_gap_device_name_get}, + {SD_BLE_GAP_AUTHENTICATE, conn_mw_ble_gap_authenticate}, + {SD_BLE_GAP_SEC_PARAMS_REPLY, conn_mw_ble_gap_sec_params_reply}, + {SD_BLE_GAP_AUTH_KEY_REPLY, conn_mw_ble_gap_auth_key_reply}, + {SD_BLE_GAP_SEC_INFO_REPLY, conn_mw_ble_gap_sec_info_reply}, + {SD_BLE_GAP_CONN_SEC_GET, conn_mw_ble_gap_conn_sec_get}, + {SD_BLE_GAP_RSSI_START, conn_mw_ble_gap_rssi_start}, + {SD_BLE_GAP_RSSI_STOP, conn_mw_ble_gap_rssi_stop}, + {SD_BLE_GAP_KEYPRESS_NOTIFY, conn_mw_ble_gap_keypress_notify}, + {SD_BLE_GAP_LESC_DHKEY_REPLY, conn_mw_ble_gap_lesc_dhkey_reply}, + {SD_BLE_GAP_LESC_OOB_DATA_SET, conn_mw_ble_gap_lesc_oob_data_set}, + {SD_BLE_GAP_LESC_OOB_DATA_GET, conn_mw_ble_gap_lesc_oob_data_get}, + {SD_BLE_GAP_RSSI_GET, conn_mw_ble_gap_rssi_get}, +#if NRF_SD_BLE_API_VERSION >= 5 + {SD_BLE_GAP_PHY_REQUEST, conn_mw_ble_gap_phy_request}, +#endif +#if NRF_SD_BLE_API_VERSION >= 4 + {SD_BLE_GAP_DATA_LENGTH_UPDATE, conn_mw_ble_gap_data_length_update}, +#endif + //Functions from ble_gattc.h + {SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, conn_mw_ble_gattc_primary_services_discover}, + {SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, conn_mw_ble_gattc_relationships_discover}, + {SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, conn_mw_ble_gattc_characteristics_discover}, + {SD_BLE_GATTC_DESCRIPTORS_DISCOVER, conn_mw_ble_gattc_descriptors_discover}, + {SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, conn_mw_ble_gattc_char_value_by_uuid_read}, + {SD_BLE_GATTC_READ, conn_mw_ble_gattc_read}, + {SD_BLE_GATTC_CHAR_VALUES_READ, conn_mw_ble_gattc_char_values_read}, + {SD_BLE_GATTC_WRITE, conn_mw_ble_gattc_write}, + {SD_BLE_GATTC_HV_CONFIRM, conn_mw_ble_gattc_hv_confirm}, + {SD_BLE_GATTC_ATTR_INFO_DISCOVER, conn_mw_ble_gattc_attr_info_discover}, + {SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, conn_mw_ble_gattc_exchange_mtu_request}, + //Functions from ble_gatts.h + {SD_BLE_GATTS_SERVICE_ADD, conn_mw_ble_gatts_service_add}, + {SD_BLE_GATTS_INCLUDE_ADD, conn_mw_ble_gatts_include_add}, + {SD_BLE_GATTS_CHARACTERISTIC_ADD, conn_mw_ble_gatts_characteristic_add}, + {SD_BLE_GATTS_DESCRIPTOR_ADD, conn_mw_ble_gatts_descriptor_add}, + {SD_BLE_GATTS_VALUE_SET, conn_mw_ble_gatts_value_set}, + {SD_BLE_GATTS_VALUE_GET, conn_mw_ble_gatts_value_get}, + {SD_BLE_GATTS_HVX, conn_mw_ble_gatts_hvx}, + {SD_BLE_GATTS_SERVICE_CHANGED, conn_mw_ble_gatts_service_changed}, + {SD_BLE_GATTS_RW_AUTHORIZE_REPLY, conn_mw_ble_gatts_rw_authorize_reply}, + {SD_BLE_GATTS_SYS_ATTR_SET, conn_mw_ble_gatts_sys_attr_set}, + {SD_BLE_GATTS_SYS_ATTR_GET, conn_mw_ble_gatts_sys_attr_get}, + {SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, conn_mw_ble_gatts_initial_user_handle_get}, + {SD_BLE_GATTS_ATTR_GET, conn_mw_ble_gatts_attr_get}, + {SD_BLE_GATTS_EXCHANGE_MTU_REPLY, conn_mw_ble_gatts_exchange_mtu_reply}, +#endif // // defined(BLE_STACK_SUPPORT_REQD) +#if defined(ANT_STACK_SUPPORT_REQD) + //Functions from ant_interface.h + {SVC_ANT_ENABLE, conn_mw_ant_enable}, + {SVC_ANT_CHANNEL_ASSIGN, conn_ant_channel_assign}, + {SVC_ANT_CHANNEL_OPEN, conn_ant_channel_open_with_offset}, + {SVC_ANT_CHANNEL_ID_SET, conn_ant_channel_id_set}, + {SVC_ANT_CHANNEL_PERIOD_SET, conn_ant_channel_period_set}, + {SVC_ANT_CHANNEL_RADIO_FREQ_SET, conn_ant_channel_radio_freq_set}, + {SVC_ANT_TX_BROADCAST_MESSAGE, conn_ant_broadcast_message_tx}, + {SVC_ANT_TX_ACKNOWLEDGED_MESSAGE, conn_ant_acknowledge_message_tx}, + {SVC_ANT_CHANNEL_UNASSIGN, conn_ant_channel_unassign}, + {SVC_ANT_CHANNEL_CLOSE, conn_ant_channel_close}, + {SVC_ANT_NETWORK_KEY_SET, conn_ant_network_address_set}, + {SVC_ANT_CHANNEL_RADIO_TX_POWER_SET, conn_ant_channel_radio_tx_power_set}, + {SVC_ANT_CHANNEL_SEARCH_TIMEOUT_SET, conn_ant_channel_rx_search_timeout_set}, + {SVC_ANT_CHANNEL_LOW_PRIO_RX_SEARCH_TIMEOUT_SET, conn_ant_channel_low_priority_rx_search_timeout_set}, + {SVC_ANT_PROX_SEARCH_SET, conn_ant_prox_search_set}, + {SVC_ANT_SEARCH_WAVEFORM_SET, conn_ant_search_waveform_set}, + {SVC_ANT_CHANNEL_ID_GET, conn_ant_channel_id_get}, + {SVC_ANT_CHANNEL_RADIO_FREQ_GET, conn_ant_channel_radio_freq_get}, + {SVC_ANT_CHANNEL_PERIOD_GET, conn_ant_channel_period_get}, + {SVC_ANT_SEARCH_CHANNEL_PRIORITY_SET, conn_ant_search_channel_priority_set}, + {SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_SET, conn_ant_active_search_sharing_cycles_set}, + {SVC_ANT_LIB_CONFIG_SET, conn_ant_lib_config_set}, + {SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_GET, conn_ant_active_search_sharing_cycles_get}, + {SVC_ANT_LIB_CONFIG_GET, conn_ant_lib_config_get}, + {SVC_ANT_LIB_CONFIG_CLEAR, conn_ant_lib_config_clear}, + {SVC_ANT_STACK_INIT, conn_ant_stack_reset}, + {SVC_ANT_RX_SCAN_MODE_START, conn_ant_rx_scan_mode_start}, + {SVC_ANT_ID_LIST_ADD, conn_ant_id_list_add}, + {SVC_ANT_ID_LIST_CONFIG, conn_ant_id_list_config}, + {SVC_ANT_CHANNEL_STATUS_GET, conn_ant_channel_status_get}, + {SVC_ANT_INIT_CW_TEST_MODE, conn_ant_cw_test_mode_init}, + {SVC_ANT_CW_TEST_MODE, conn_ant_cw_test_mode}, + {SVC_ANT_VERSION, conn_ant_version_get}, + {SVC_ANT_CAPABILITIES, conn_ant_capabilities_get}, + {SVC_ANT_CRYPTO_CHANNEL_ENABLE, conn_ant_crypto_channel_enable}, + {SVC_ANT_ADV_BURST_CONFIG_SET, conn_ant_adv_burst_config_set}, + {SVC_ANT_CRYPTO_KEY_SET, conn_ant_crypto_key_set}, + {SVC_ANT_CRYPTO_INFO_SET, conn_ant_crypto_info_set}, + {SVC_ANT_CRYPTO_INFO_GET, conn_ant_crypto_info_get}, + {SVC_ANT_COEX_CONFIG_SET, conn_ant_coex_config_set}, + {SVC_ANT_COEX_CONFIG_GET, conn_ant_coex_config_get}, +#endif // // defined(ANT_STACK_SUPPORT_REQD) +}; diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.c new file mode 100644 index 0000000000000000000000000000000000000000..5743e6b51cd9cbdc14bed4e98d721878b50f7436 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.c @@ -0,0 +1,114 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_soc_conn.h" +#include "conn_mw_nrf_soc.h" +#include "ble_serialization.h" + +uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + + err_code = power_system_off_req_dec(p_rx_buf, rx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = sd_power_system_off(); + /* There should be no return from sd_power_system_off() */ + + return err_code; +} + +uint32_t conn_mw_temp_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + int32_t temperature; + int32_t * p_temperature = &temperature; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = temp_get_req_dec(p_rx_buf, rx_buf_len, &p_temperature); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_temp_get(p_temperature); + + err_code = temp_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_temperature); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ecb_block_encrypt(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + nrf_ecb_hal_data_t ecb_data; + nrf_ecb_hal_data_t * p_ecb_data = &ecb_data; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ecb_block_encrypt_req_dec(p_rx_buf, rx_buf_len, &p_ecb_data); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ecb_block_encrypt(p_ecb_data); + + err_code = ecb_block_encrypt_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_ecb_data); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.h new file mode 100644 index 0000000000000000000000000000000000000000..625f7254fe985f509dcc84823e3e07ae835df23f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.h @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef CONN_MW_NRF_SOC_H__ +#define CONN_MW_NRF_SOC_H__ + +/** + * @addtogroup ser_mw_common_codecs + * @{ + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Handles @ref sd_power_system_off command request. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. + */ +uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_temp_get command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. + */ +uint32_t conn_mw_temp_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ecb_block_encrypt command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of @p p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. + */ +uint32_t conn_mw_ecb_block_encrypt(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/hal/dtm_uart.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/hal/dtm_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..a14778186730e4015a21150bf6321281cc0ab7f6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/hal/dtm_uart.c @@ -0,0 +1,262 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** + @defgroup dtm_standalone main.c + @{ + @ingroup ble_sdk_app_dtm_serial + @brief Stand-alone DTM application for UART interface. + + */ + +#include +#include +#include "nrf.h" +#include "ble_dtm.h" +#include "nrf_gpio.h" +#include "dtm_uart.h" +#include "nrf_error.h" +#include "app_util.h" +#include "nrf_drv_uart.h" +#include "app_util_platform.h" + +//Configuration parameters. +#define BITRATE UART_BAUDRATE_BAUDRATE_Baud57600 /**< Serial bitrate on the UART */ + +//@note: The BLE DTM 2-wire UART standard specifies 8 data bits, 1 stop bit, no flow control. +//These parameters are not configurable in the BLE standard. + +/**@details Maximum iterations needed in the main loop between stop bit 1st byte and start bit 2nd + * byte. DTM standard allows 5000us delay between stop bit 1st byte and start bit 2nd byte. + * As the time is only known when a byte is received, then the time between between stop bit 1st + * byte and stop bit 2nd byte becomes: + * 5000us + transmission time of 2nd byte. + * + * Byte transmission time is (Baud rate of 19200): + * 10bits * 1/19200 = approx. 520 us/byte (8 data bits + start & stop bit). + * + * Loop time on polling UART register for received byte is defined in ble_dtm.c as: + * UART_POLL_CYCLE = 260 us + * + * The max time between two bytes thus becomes (loop time: 260us / iteration): + * (5000us + 520us) / 260us / iteration = 21.2 iterations. + * + * This is rounded down to 21. + * + * @note If UART bit rate is changed, this value should be recalculated as well. + */ + +static uint32_t m_baud_rates[] = {[UART_BAUD_RATE_1200] = UART_BAUDRATE_BAUDRATE_Baud1200, + [UART_BAUD_RATE_2400] = UART_BAUDRATE_BAUDRATE_Baud2400, + [UART_BAUD_RATE_4800] = UART_BAUDRATE_BAUDRATE_Baud4800, + [UART_BAUD_RATE_9600] = UART_BAUDRATE_BAUDRATE_Baud9600, + [UART_BAUD_RATE_14400] = UART_BAUDRATE_BAUDRATE_Baud14400, + [UART_BAUD_RATE_19200] = UART_BAUDRATE_BAUDRATE_Baud19200, + [UART_BAUD_RATE_28800] = UART_BAUDRATE_BAUDRATE_Baud28800, + [UART_BAUD_RATE_38400] = UART_BAUDRATE_BAUDRATE_Baud38400, + [UART_BAUD_RATE_57600] = UART_BAUDRATE_BAUDRATE_Baud57600, + [UART_BAUD_RATE_76800] = UART_BAUDRATE_BAUDRATE_Baud76800, + [UART_BAUD_RATE_115200] = UART_BAUDRATE_BAUDRATE_Baud115200, }; + +static uint32_t m_iteration[] = {[UART_BAUD_RATE_1200] = 51, + [UART_BAUD_RATE_2400] = 35, + [UART_BAUD_RATE_4800] = 27, + [UART_BAUD_RATE_9600] = 23, + [UART_BAUD_RATE_14400] = 21, + [UART_BAUD_RATE_19200] = 21, + [UART_BAUD_RATE_28800] = 20, + [UART_BAUD_RATE_38400] = 20, + [UART_BAUD_RATE_57600] = 19, + [UART_BAUD_RATE_76800] = 19, + [UART_BAUD_RATE_115200] = 19, }; + +static uint32_t m_iterations_next_byte_max = 51; + +static nrf_drv_uart_t m_dtm_uart_driver = NRF_DRV_UART_INSTANCE(0); + +/**@brief Function for UART initialization. + */ +static uint32_t uart_init(app_uart_stream_comm_params_t * p_comm_params) +{ + if (p_comm_params->baud_rate > UART_BAUD_RATE_115200) + { + return NRF_ERROR_INVALID_PARAM; + } + + nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG; + + config.pselrxd = p_comm_params->rx_pin_no; + config.pseltxd = p_comm_params->tx_pin_no; + config.baudrate = (nrf_uart_baudrate_t) m_baud_rates[p_comm_params->baud_rate]; + config.hwfc = NRF_UART_HWFC_DISABLED; + config.parity = NRF_UART_PARITY_EXCLUDED; + + nrf_drv_uart_uninit(&m_dtm_uart_driver); + uint32_t err_code = nrf_drv_uart_init(&m_dtm_uart_driver, &config, NULL); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + nrf_drv_uart_rx_enable(&m_dtm_uart_driver); + + m_iterations_next_byte_max = m_iteration[p_comm_params->baud_rate]; + + return NRF_SUCCESS; +} + + +/**@brief Function for splitting UART command bit fields into separate command parameters for the DTM library. + * + * @param[in] command The packed UART command. + * @return result status from dtmlib. + */ +static uint32_t dtm_cmd_put(uint16_t command) +{ + dtm_cmd_t command_code = (command >> 14) & 0x03; + dtm_freq_t freq = (command >> 8) & 0x3F; + uint32_t length = (command >> 2) & 0x3F; + dtm_pkt_type_t payload = command & 0x03; + + //Check for Vendor Specific payload. + if (payload == 0x03) + { + /* Note that in a HCI adaption layer, as well as in the DTM PDU format, + the value 0x03 is a distinct bit pattern (PRBS15). Even though BLE does not + support PRBS15, this implementation re-maps 0x03 to DTM_PKT_VENDORSPECIFIC, + to avoid the risk of confusion, should the code be extended to greater coverage. + */ + payload = DTM_PKT_VENDORSPECIFIC; + } + return dtm_cmd(command_code, freq, length, payload); +} + + +/**@brief Function for application main entry. + * + * @details This function serves as an adaptation layer between a 2-wire UART interface and the + * dtmlib. After initialization, DTM commands submitted through the UART are forwarded to + * dtmlib and events (i.e. results from the command) is reported back through the UART. + */ +uint32_t dtm_start(app_uart_stream_comm_params_t uart_comm_params) +{ + uint32_t current_time; + uint32_t dtm_error_code; + uint32_t msb_time = 0; //Time when MSB of the DTM command was read. Used to catch stray bytes from "misbehaving" testers. + bool is_msb_read = false; //True when MSB of the DTM command has been read and the application is waiting for LSB. + uint16_t dtm_cmd_from_uart = 0; //Packed command containing command_code:freqency:length:payload in 2:6:6:2 bits. + uint8_t rx_byte; //Last byte read from UART. + dtm_event_t result; //Result of a DTM operation. + uint32_t err_code; + + err_code = uart_init(&uart_comm_params); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + dtm_error_code = dtm_init(); + + if (dtm_error_code != DTM_SUCCESS) + { + //If DTM cannot be correctly initialized, then we just return. + return NRF_ERROR_INTERNAL; + } + + for (;; ) + { + //Will return every timeout, 625 us. + current_time = dtm_wait(); + + if (NRF_SUCCESS != nrf_drv_uart_rx(&m_dtm_uart_driver, &rx_byte,1)) + { + return NRF_ERROR_INTERNAL; + } + + if (!is_msb_read) + { + //This is first byte of two-byte command. + is_msb_read = true; + dtm_cmd_from_uart = ((dtm_cmd_t)rx_byte) << 8; + msb_time = current_time; + + //Go back and wait for 2nd byte of command word. + continue; + } + + //This is the second byte read; combine it with the first and process command + if (current_time > (msb_time + m_iterations_next_byte_max)) + { + //More than ~5mS after msb: Drop old byte, take the new byte as MSB. + //The variable is_msb_read will remains true. + //Go back and wait for 2nd byte of the command word. + dtm_cmd_from_uart = ((dtm_cmd_t)rx_byte) << 8; + msb_time = current_time; + continue; + } + + //2-byte UART command received. + is_msb_read = false; + dtm_cmd_from_uart |= (dtm_cmd_t)rx_byte; + + if (dtm_cmd_put(dtm_cmd_from_uart) != DTM_SUCCESS) + { + //Extended error handling may be put here. + //Default behavior is to return the event on the UART (see below); + //the event report will reflect any lack of success. + } + + //Retrieve result of the operation. This implementation will busy-loop + //for the duration of the byte transmissions on the UART. + if (dtm_event_get(&result)) + { + //Report command status on the UART. + uint8_t tx_byte = (result >> 8) & 0xFF; + + //Transmit MSB of the result. + (void)nrf_drv_uart_tx(&m_dtm_uart_driver, &tx_byte, 1); + + //Transmit LSB of the result. + tx_byte = result & 0xFF; + (void)nrf_drv_uart_tx(&m_dtm_uart_driver, &tx_byte, 1); + } + } +} + +/// @} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/hal/dtm_uart.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/hal/dtm_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..780bdf331ce29ae4e15ee5aaf2b958e0dd223e6c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/hal/dtm_uart.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef DTM_UART_H__ +#define DTM_UART_H__ + +#include +#include "dtm_uart_params.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UART_PIN_DISCONNECTED 0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */ + +uint32_t dtm_start(app_uart_stream_comm_params_t uart_comm_params); + + +#ifdef __cplusplus +} +#endif + +#endif // DTM_UART_H__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/pstorage_platform.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/pstorage_platform.h new file mode 100644 index 0000000000000000000000000000000000000000..0034ce73c1dd1c656367ec30b506e950710e194d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/pstorage_platform.h @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @cond To make doxygen skip this file */ + +/** @file + * This header contains defines regarding persistent storage that are specific to + * persistent storage implementation and application use case. + */ +#ifndef PSTORAGE_PL_H__ +#define PSTORAGE_PL_H__ + +#include +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static __INLINE uint16_t pstorage_flash_page_size() +{ + return (uint16_t)NRF_FICR->CODEPAGESIZE; +} + +#define PSTORAGE_FLASH_PAGE_SIZE pstorage_flash_page_size() /**< Size of one flash page. */ +#define PSTORAGE_FLASH_EMPTY_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */ + +static __INLINE uint32_t pstorage_flash_page_end() +{ + uint32_t bootloader_addr = NRF_UICR->NRFFW[0]; + + return ((bootloader_addr != PSTORAGE_FLASH_EMPTY_MASK) ? + (bootloader_addr/ PSTORAGE_FLASH_PAGE_SIZE) : NRF_FICR->CODESIZE); +} + +#define PSTORAGE_FLASH_PAGE_END pstorage_flash_page_end() + +#define PSTORAGE_NUM_OF_PAGES 2 /**< Number of flash pages allocated for the pstorage module excluding the swap page, configurable based on system requirements. */ +#define PSTORAGE_MIN_BLOCK_SIZE 0x0010 /**< Minimum size of block that can be registered with the module. Should be configured based on system requirements, recommendation for this value is to have at least the size of a word. */ + +#define PSTORAGE_DATA_START_ADDR ((PSTORAGE_FLASH_PAGE_END - PSTORAGE_NUM_OF_PAGES) \ + * PSTORAGE_FLASH_PAGE_SIZE) /**< Start address for persistent data, configurable according to system requirements. */ +#define PSTORAGE_DATA_END_ADDR (PSTORAGE_FLASH_PAGE_END * PSTORAGE_FLASH_PAGE_SIZE) /**< End address for persistent data, configurable according to system requirements. */ +#define PSTORAGE_MAX_BLOCK_SIZE PSTORAGE_FLASH_PAGE_SIZE /**< Maximum size of block that can be registered with the module. Should be configured based on system requirements. Also, should be greater than or equal to the minimum size. */ +#define PSTORAGE_CMD_QUEUE_SIZE 30 /**< Maximum number of flash access commands that can be maintained by the module for all applications. Configurable. */ + + +/** Abstracts persistently memory block identifier. */ +typedef uint32_t pstorage_block_t; + +typedef struct +{ + uint32_t module_id; /**< Module ID.*/ + pstorage_block_t block_id; /**< Block ID.*/ +} pstorage_handle_t; + +typedef uint16_t pstorage_size_t; /** Size of length and offset fields. */ + +/**@brief Handles Flash Access Result Events. To be called in the system event dispatcher of the application. */ +void pstorage_sys_event_handler (uint32_t sys_evt); + + +#ifdef __cplusplus +} +#endif + +#endif // PSTORAGE_PL_H__ + +/** @} */ +/** @endcond */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_cmd_decoder.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_cmd_decoder.c new file mode 100644 index 0000000000000000000000000000000000000000..39afb1df126754b7ce564e3215e14098a759ff7a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_cmd_decoder.c @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "nordic_common.h" +#include "app_error.h" +#include "ble_serialization.h" +#include "ser_config.h" +#include "conn_mw.h" +#include "ser_hal_transport.h" +#include "ser_conn_cmd_decoder.h" + + +uint32_t ser_conn_command_process(uint8_t * p_command, uint16_t command_len) +{ + SER_ASSERT_NOT_NULL(p_command); + SER_ASSERT_LENGTH_LEQ(SER_OP_CODE_SIZE, command_len); + + uint32_t err_code = NRF_SUCCESS; + uint8_t * p_tx_buf = NULL; + uint32_t tx_buf_len = 0; + uint8_t opcode = p_command[SER_CMD_OP_CODE_POS]; + uint32_t index = 0; + + /* Allocate a memory buffer from HAL Transport layer for transmitting the Command Response. + * Loop until a buffer is available. */ + do + { + err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len); + } + while (NRF_ERROR_NO_MEM == err_code); + + if (NRF_SUCCESS == err_code) + { + /* Create a new response packet. */ + p_tx_buf[SER_PKT_TYPE_POS] = SER_PKT_TYPE_RESP; + tx_buf_len -= SER_PKT_TYPE_SIZE; + + /* Decode a request, pass a memory for a response command (opcode + data) and encode it. */ + err_code = conn_mw_handler + (p_command, command_len, &p_tx_buf[SER_PKT_OP_CODE_POS], &tx_buf_len); + + /* Command decoder not found. */ + if (NRF_ERROR_NOT_SUPPORTED == err_code) + { + APP_ERROR_CHECK(SER_WARNING_CODE); + err_code = op_status_enc + (opcode, NRF_ERROR_NOT_SUPPORTED, + &p_tx_buf[SER_PKT_OP_CODE_POS], &tx_buf_len, &index); + if (NRF_SUCCESS == err_code) + { + tx_buf_len += SER_PKT_TYPE_SIZE; + err_code = ser_hal_transport_tx_pkt_send(p_tx_buf, (uint16_t)tx_buf_len); + /* TX buffer is going to be freed automatically in the HAL Transport layer. */ + if (NRF_SUCCESS != err_code) + { + err_code = NRF_ERROR_INTERNAL; + } + } + else + { + err_code = NRF_ERROR_INTERNAL; + } + } + else if (NRF_SUCCESS == err_code) /* Send a response. */ + { + tx_buf_len += SER_PKT_TYPE_SIZE; + err_code = ser_hal_transport_tx_pkt_send(p_tx_buf, (uint16_t)tx_buf_len); + + /* TX buffer is going to be freed automatically in the HAL Transport layer. */ + if (NRF_SUCCESS != err_code) + { + err_code = NRF_ERROR_INTERNAL; + } + } + else + { + err_code = NRF_ERROR_INTERNAL; + } + } + else + { + err_code = NRF_ERROR_INTERNAL; + } + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_cmd_decoder.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_cmd_decoder.h new file mode 100644 index 0000000000000000000000000000000000000000..e14b7cd7f3e1b216ee85667f582d9c2cc55af3ff --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_cmd_decoder.h @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ser_conn Connectivity application code + * @ingroup ble_sdk_lib_serialization + */ + +/** @file + * + * @defgroup ser_cmd_decoder Command decoder in the Connectivity Chip + * @{ + * @ingroup ser_conn + * + * @brief Decoder for serialized commands from the Application Chip. + * + * @details This file contains declaration of common function used for commands decoding and sending + * responses back to the Application Chip after a command is processed. + */ + +#ifndef SER_CONN_CMD_DECODER_H__ +#define SER_CONN_CMD_DECODER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief A function decodes an encoded command and sends a response to the Application Chip. + * + * @details The function decodes an encoded command and calls a SoftDevice API function when a + * command decoder is found or forms a common response with error code + * NRF_ERROR_NOT_SUPPORTED otherwise. Then the function sends a SoftDevice response or + * the response with NRF_ERROR_NOT_SUPPORTED error code to the Application Chip. + * + * @param[in] p_command The encoded command. + * @param[in] command_len Length of the encoded command including opcode. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred. . + */ +uint32_t ser_conn_command_process(uint8_t * p_command, uint16_t command_len); + + +#ifdef __cplusplus +} +#endif + +#endif /* SER_CONN_CMD_DECODER_H__ */ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.c new file mode 100644 index 0000000000000000000000000000000000000000..42e6d704293018eaecf863b9e0277c61d13b389c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.c @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "app_util.h" +#include "ble_dtm_conn.h" +#include "ble_serialization.h" +#include "nrf_error.h" +#include "softdevice_handler.h" +#include "ser_conn_dtm_cmd_decoder.h" +#include "ser_hal_transport.h" + +static bool m_is_ready_to_enter_dtm = false; +static app_uart_stream_comm_params_t m_comm_params = { 0 }; + +uint32_t ser_conn_dtm_command_process(uint8_t * p_command, uint16_t command_len) +{ + SER_ASSERT_NOT_NULL(p_command); + + uint32_t err_code = NRF_SUCCESS; + uint8_t * p_tx_buf = NULL; + uint32_t tx_buf_len = 0; + + /* Allocate a memory buffer from HAL Transport layer for transmitting the Command Response. + * Loop until a buffer is available. */ + do + { + err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len); + } + while (NRF_ERROR_NO_MEM == err_code); + + if (err_code == NRF_SUCCESS) + { + p_tx_buf[SER_PKT_TYPE_POS] = SER_PKT_TYPE_DTM_RESP; + tx_buf_len -= SER_PKT_TYPE_SIZE; + + err_code = ble_dtm_init_req_dec(p_command, command_len, &m_comm_params); + + if (NRF_SUCCESS == err_code) + { + err_code = ble_dtm_init_rsp_enc(NRF_SUCCESS, + &p_tx_buf[SER_PKT_TYPE_SIZE], + &tx_buf_len); + + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + tx_buf_len += SER_PKT_TYPE_SIZE; + + /* Set a flag that device is ready to enter DTM mode. */ + m_is_ready_to_enter_dtm = true; + + err_code = ser_hal_transport_tx_pkt_send(p_tx_buf, (uint16_t)tx_buf_len); + if (err_code != NRF_SUCCESS) + { + err_code = NRF_ERROR_INTERNAL; + } + + /* TX buffer is going to be freed automatically in the HAL Transport layer. */ + } + else + { + err_code = NRF_ERROR_INTERNAL; + } + } + + return err_code; +} + + +void ser_conn_is_ready_to_enter_dtm(void) +{ + if (m_is_ready_to_enter_dtm) + { + /* Disable SoftDevice. */ + (void)sd_softdevice_disable(); + + /* Close HAL Transport Layer. */ + ser_hal_transport_close(); + + /* Start DTM mode. */ + (void)dtm_start(m_comm_params); + } +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.h new file mode 100644 index 0000000000000000000000000000000000000000..9b646026dff26a50072e678f5f6d9ab778dec156 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ser_conn Connectivity application code + * @ingroup ble_sdk_lib_serialization + */ + +/** @file + * + * @defgroup ser_dtm_decoder DTM Command Decoder in the Connectivity Chip + * @{ + * @ingroup ser_conn + * + * @brief Decoder for serialized DTM commands from the Application Chip. + * + * @details This file contains declaration of common function used for DTM commands decoding and + * sending responses back to the Application Chip after a DTM command is processed. + */ + +#ifndef SER_CONN_DTM_CMD_DECODER_H__ +#define SER_CONN_DTM_CMD_DECODER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief A function for processing the encoded DTM commands from the Application Chip. + * + * @details The function decodes encoded DTM commands and calls the appropriate DTM API. + * Then creates a DTM Command Response packet with the return value from the + * DTM API encoded in it and sends it to the Application Chip. + * + * @param[in] p_command The encoded command. + * @param[in] command_len Length of the encoded command. + * + * @retval NRF_SUCCESS If the decoding of the command was successful, the DTM API + * was called, and the command response was sent to peer, otherwise an + * error code. + */ +uint32_t ser_conn_dtm_command_process(uint8_t * p_command, uint16_t command_len); + + +/**@brief A function for checking if the Connectivity Chip is ready to enter the DTM mode. + * + * @details The function checks if the Connectivity Chip is ready to enter into DTM mode. + * If it is ready, then it disables the SoftDevice, closes HAL Transport Layer, + * and starts DTM mode. + */ +void ser_conn_is_ready_to_enter_dtm(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* SER_CONN_DTM_CMD_DECODER_H__ */ + +/** @} */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_error_handling.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_error_handling.c new file mode 100644 index 0000000000000000000000000000000000000000..5252a19150b6f8e166becdc8898c12774d31622b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_error_handling.c @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_assert.h" +#include "app_error.h" +#include "ser_config.h" + +#include "boards.h" + +/** @file + * + * @defgroup ser_conn_error_handling Errors handling for the Connectivity Chip. + * @{ + * @ingroup sdk_lib_serialization + * + * @brief A module to handle the Connectivity Chip errors and warnings. + * + * @details This file contains definitions of functions used for handling the Connectivity Chip + * errors and warnings. + */ + +/**@brief Function for handling the Connectivity Chip errors and warnings. + * + * @details This function will be called if the ASSERT macro in the connectivity application fails. + * Function declaration can be found in the app_error.h file. + * + * @param[in] error_code Error code supplied to the handler. + * @param[in] line_num Line number where the handler is called. + * @param[in] p_file_name Pointer to the file name. + */ + +#include "app_util_platform.h" +#include "nrf_soc.h" + +// uint32_t m_error_code; +// uint32_t m_error_line_num; +// const uint8_t *m_p_error_file_name; + +void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) +{ + // disable INTs + CRITICAL_REGION_ENTER(); + + #if LEDS_NUMBER > 0 + + /* Light a LED on error or warning. */ + // nrf_gpio_cfg_output(SER_CONN_ASSERT_LED_PIN); + // nrf_gpio_pin_set(SER_CONN_ASSERT_LED_PIN); + + #endif + + // m_p_error_file_name = p_file_name; + // m_error_code = error_code; + // m_error_line_num = line_num; + + /* Do not reset when warning. */ + if (SER_WARNING_CODE != id) + { + /* This call can be used for debug purposes during application development. + * @note CAUTION: Activating code below will write the stack to flash on an error. + * This function should NOT be used in a final product. + * It is intended STRICTLY for development/debugging purposes. + * The flash write will happen EVEN if the radio is active, thus interrupting any communication. + * Use with care. Un-comment the line below to use. */ + + /* ble_debug_assert_handler(error_code, line_num, p_file_name); */ + +#if 0 + /* Reset the chip. Should be used in the release version. */ + NVIC_SystemReset(); +#else /* Debug version. */ + /* To be able to see function parameters in a debugger. */ + uint32_t temp = 1; + while (temp); +#endif + + } + + CRITICAL_REGION_EXIT(); +} + + +/**@brief Callback function for asserts in the SoftDevice. + * + * @details This function will be called if the ASSERT macro in the SoftDevice fails. Function + * declaration can be found in the nrf_assert.h file. + * + * @param[in] line_num Line number of the failing ASSERT call. + * @param[in] p_file_name File name of the failing ASSERT call. + */ +void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name) +{ + app_error_handler(SER_SD_ERROR_CODE, line_num, p_file_name); +} +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_event_encoder.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_event_encoder.c new file mode 100644 index 0000000000000000000000000000000000000000..c4797121788605b36186d7cc641e3c1470d01b67 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_event_encoder.c @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "app_error.h" +#include "app_scheduler.h" +#include "ble_serialization.h" +#include "ser_config.h" +#include "ser_hal_transport.h" +#include "ser_conn_event_encoder.h" + +#ifdef BLE_STACK_SUPPORT_REQD +#include "ble_conn.h" +#endif // BLE_STACK_SUPPORT_REQD + +#ifdef ANT_STACK_SUPPORT_REQD +#include "ant_event.h" +#endif // ANT_STACK_SUPPORT_REQD + +#ifdef BLE_STACK_SUPPORT_REQD +void ser_conn_ble_event_encoder(void * p_event_data, uint16_t event_size) +{ + if (NULL == p_event_data) + { + APP_ERROR_CHECK(NRF_ERROR_NULL); + } + UNUSED_PARAMETER(event_size); + + uint32_t err_code = NRF_SUCCESS; + uint8_t * p_tx_buf = NULL; + uint32_t tx_buf_len = 0; + ble_evt_t * p_ble_evt = (ble_evt_t *)p_event_data; + + /* Allocate a memory buffer from HAL Transport layer for transmitting an event. + * Loop until a buffer is available. */ + do + { + err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len); + } + while (err_code == NRF_ERROR_NO_MEM); + APP_ERROR_CHECK(err_code); + + /* Create a new packet. */ + p_tx_buf[SER_PKT_TYPE_POS] = SER_PKT_TYPE_EVT; + tx_buf_len -= SER_PKT_TYPE_SIZE; + + /* Pass a memory for an event (opcode + data) and encode it. */ + err_code = ble_event_enc(p_ble_evt, 0, &p_tx_buf[SER_PKT_OP_CODE_POS], &tx_buf_len); + + if (NRF_ERROR_NOT_SUPPORTED != err_code) + { + APP_ERROR_CHECK(err_code); + tx_buf_len += SER_PKT_TYPE_SIZE; + err_code = ser_hal_transport_tx_pkt_send(p_tx_buf, (uint16_t)tx_buf_len); + APP_ERROR_CHECK(err_code); + /* TX buffer is going to be freed automatically in the HAL Transport layer. + * Scheduler must be paused because this function returns before a packet is physically sent + * by transport layer. This can cause start processing of a next event from the application + * scheduler queue. In result the next event reserves the TX buffer before the current + * packet is sent. If in meantime a command arrives a command response cannot be sent in + * result. Pausing the scheduler temporary prevents processing a next event. */ + app_sched_pause(); + } + else + { + /* Event was NOT encoded, therefore the buffer is freed immediately. */ + err_code = ser_hal_transport_tx_pkt_free(p_tx_buf); + APP_ERROR_CHECK(err_code); + APP_ERROR_CHECK(SER_WARNING_CODE); + } +} +#endif // BLE_STACK_SUPPORT_REQD + +#ifdef ANT_STACK_SUPPORT_REQD +void ser_conn_ant_event_encoder(void * p_event_data, uint16_t event_size) +{ + + if (NULL == p_event_data) + { + APP_ERROR_CHECK(NRF_ERROR_NULL); + } + UNUSED_PARAMETER(event_size); + + uint32_t err_code = NRF_SUCCESS; + uint8_t * p_tx_buf = NULL; + uint32_t tx_buf_len = 0; + ant_evt_t * p_ant_evt = (ant_evt_t *)p_event_data; + + /* Allocate a memory buffer from HAL Transport layer for transmitting an event. + * Loop until a buffer is available. */ + do + { + err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len); + } + while (err_code == NRF_ERROR_NO_MEM); + APP_ERROR_CHECK(err_code); + + /* Create a new packet. */ + p_tx_buf[SER_PKT_TYPE_POS] = SER_PKT_TYPE_ANT_EVT; + tx_buf_len -= SER_PKT_TYPE_SIZE; + + /* Pass a memory for an event (opcode + data) and encode it. */ + err_code = ant_event_enc(p_ant_evt, 0, &p_tx_buf[SER_PKT_OP_CODE_POS], &tx_buf_len); + + if (NRF_ERROR_NOT_SUPPORTED != err_code) + { + APP_ERROR_CHECK(err_code); + tx_buf_len += SER_PKT_TYPE_SIZE; + err_code = ser_hal_transport_tx_pkt_send(p_tx_buf, (uint16_t)tx_buf_len); + APP_ERROR_CHECK(err_code); + /* TX buffer is going to be freed automatically in the HAL Transport layer. + * Scheduler must be paused because this function returns before a packet is physically sent + * by transport layer. This can cause start processing of a next event from the application + * scheduler queue. In result the next event reserves the TX buffer before the current + * packet is sent. If in meantime a command arrives a command response cannot be sent in + * result. Pausing the scheduler temporary prevents processing a next event. */ + app_sched_pause(); + } + else + { + /* Event was NOT encoded, therefore the buffer is freed immediately. */ + err_code = ser_hal_transport_tx_pkt_free(p_tx_buf); + APP_ERROR_CHECK(err_code); + APP_ERROR_CHECK(SER_WARNING_CODE); + } + +} +#endif diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_event_encoder.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_event_encoder.h new file mode 100644 index 0000000000000000000000000000000000000000..e78f4c30f1cfcb3dfb22def6c01b91de5d7b9f09 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_event_encoder.h @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ser_conn Connectivity application code + * @ingroup ble_sdk_lib_serialization + * @brief Encoders, decoders, and event handlers related to the Connectivity Chip. + */ + +/** @file + * + * @defgroup ser_event_encoder Events encoder in the Connectivity Chip + * @{ + * @ingroup ser_conn + * + * @brief Events encoder for BLE SoftDevice. + * + * @details This file contains declaration of common function used for serializing BLE SoftDevice + * events. + * + */ +#ifndef SER_CONN_EVENT_ENCODER_H__ +#define SER_CONN_EVENT_ENCODER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief A function for encoding a @ref ble_evt_t. The function passes the serialized byte stream + * to the transport layer after encoding. + * + * @details The function is called by the application scheduler to process an event previously + * pulled from BLE SoftDevice. + * The function creates a new packet, calls an appropriate event encoder and sends the + * packet to the Application Chip. + * + * @param[in] p_event_data Pointer to event data of type @ref ble_evt_t. + * @param[in] event_size Event data size. + */ +void ser_conn_ble_event_encoder(void * p_event_data, uint16_t event_size); + +/**@brief A function for encoding a @ref ant_evt_t. The function passes the serialized byte stream + * to the transport layer after encoding. + * + * @details The function is called by the application scheduler to process an event previously + * pulled from ANT SoftDevice. + * The function creates a new packet, calls an appropriate event encoder and sends the + * packet to the Application Chip. + * + * @param[in] p_event_data Pointer to event data of type @ref ant_evt_t. + * @param[in] event_size Event data size. + */ +void ser_conn_ant_event_encoder(void * p_event_data, uint16_t event_size); + +#ifdef __cplusplus +} +#endif + +#endif /* SER_CONN_EVENT_ENCODER_H__ */ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_handlers.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_handlers.c new file mode 100644 index 0000000000000000000000000000000000000000..b838aca81be42c4cced7b5eb0bd162c10734c28d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_handlers.c @@ -0,0 +1,185 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include "app_error.h" +#include "app_scheduler.h" +#include "ser_config.h" +#include "ser_conn_handlers.h" +#include "ser_conn_event_encoder.h" +#include "ser_conn_pkt_decoder.h" +#include "ser_conn_dtm_cmd_decoder.h" + + +/** @file + * + * @defgroup ser_conn_handlers Events handlers for the Connectivity Chip. + * @{ + * @ingroup sdk_lib_serialization + * + * @brief A module to handle the Connectivity application events. + * + * @details There are two types of events in the Connectivity application: BLE events generated by + * the SoftDevice and events generated by the HAL Transport layer. + */ + +/** Parameters of a received packet. */ +static ser_hal_transport_evt_rx_pkt_received_params_t m_rx_pkt_received_params; + +/** Indicator of received packet that should be process. */ +static bool m_rx_pkt_to_process = false; + + +void ser_conn_hal_transport_event_handle(ser_hal_transport_evt_t event) +{ + switch (event.evt_type) + { + case SER_HAL_TRANSP_EVT_TX_PKT_SENT: + { + /* SoftDevice event or response to received packet was sent, so unblock the application + * scheduler to process a next event. */ + app_sched_resume(); + + /* Check if chip is ready to enter DTM mode. */ + ser_conn_is_ready_to_enter_dtm(); + + break; + } + + case SER_HAL_TRANSP_EVT_RX_PKT_RECEIVING: + { + /* The connectivity side has started receiving a packet. Temporary block processing + * SoftDevice events. It is going to be unblocked when a response for the packet will + * be sent. This prevents communication block. */ + app_sched_pause(); + break; + } + + case SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED: + { + /* We can NOT add received packets as events to the application scheduler queue because + * received packets have to be processed before SoftDevice events but the scheduler + * queue do not have priorities. */ + memcpy(&m_rx_pkt_received_params, &event.evt_params.rx_pkt_received, + sizeof (ser_hal_transport_evt_rx_pkt_received_params_t)); + m_rx_pkt_to_process = true; + break; + } + + case SER_HAL_TRANSP_EVT_RX_PKT_DROPPED: + { + APP_ERROR_CHECK(SER_WARNING_CODE); + break; + } + + case SER_HAL_TRANSP_EVT_PHY_ERROR: + { + APP_ERROR_CHECK(NRF_ERROR_FORBIDDEN); + break; + } + + default: + { + /* do nothing */ + break; + } + } +} + + +uint32_t ser_conn_rx_process(void) +{ + uint32_t err_code = NRF_SUCCESS; + + if (m_rx_pkt_to_process) + { + /* No critical section needed on m_rx_pkt_to_process parameter because it is not possible + * to get next packet before sending a response. */ + m_rx_pkt_to_process = false; + err_code = ser_conn_received_pkt_process(&m_rx_pkt_received_params); + } + + return err_code; +} + +#ifdef BLE_STACK_SUPPORT_REQD +void ser_conn_ble_event_handle(ble_evt_t * p_ble_evt) +{ + uint32_t err_code = NRF_SUCCESS; + + /* We can NOT encode and send BLE events here. SoftDevice handler implemented in + * softdevice_handler.c pull all available BLE events at once but we need to reschedule between + * encoding and sending every BLE event because sending a response on received packet has higher + * priority than sending a BLE event. Solution for that is to put BLE events into application + * scheduler queue to be processed at a later time. */ + err_code = app_sched_event_put(p_ble_evt, sizeof (ble_evt_hdr_t) + p_ble_evt->header.evt_len, + ser_conn_ble_event_encoder); + APP_ERROR_CHECK(err_code); + uint16_t free_space = app_sched_queue_space_get(); + if (!free_space) + { + // Queue is full. Do not pull new events. + softdevice_handler_suspend(); + } +} +#endif // BLE_STACK_SUPPORT_REQD + +#ifdef ANT_STACK_SUPPORT_REQD +void ser_conn_ant_event_handle(ant_evt_t * p_ant_evt) +{ + uint32_t err_code = NRF_SUCCESS; + + /* We can NOT encode and send ANT events here. SoftDevice handler implemented in + * softdevice_handler.c pull all available ANT events at once but we need to reschedule between + * encoding and sending every ANT event because sending a response on received packet has higher + * priority than sending an ANT event. Solution for that is to put ANT events into application + * scheduler queue to be processed at a later time. */ + err_code = app_sched_event_put(p_ant_evt, sizeof (ant_evt_t), + ser_conn_ant_event_encoder); + APP_ERROR_CHECK(err_code); + uint16_t free_space = app_sched_queue_space_get(); + if (!free_space) + { + // Queue is full. Do not pull new events. + softdevice_handler_suspend(); + } +} +#endif // ANT_STACK_SUPPORT_REQD + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_handlers.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_handlers.h new file mode 100644 index 0000000000000000000000000000000000000000..ee22f7dd0e81774299bdc08bb42d798c60347719 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_handlers.h @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ser_conn Connectivity application code + * @ingroup ble_sdk_lib_serialization + */ + + +/** @file + * + * @defgroup ser_conn_handlers Events handlers in the Connectivity Chip + * @{ + * @ingroup ser_conn + * + * @brief Events handlers used to process high level events in the connectivity application. + * + * @details This file contains functions: processing the HAL Transport layer events, processing BLE + * SoftDevice events, starting processing received packets. + */ + +#ifndef SER_CONN_HANDLERS_H__ +#define SER_CONN_HANDLERS_H__ + +#include +#include "nordic_common.h" +#include "app_util.h" +#include "ble_stack_handler_types.h" +#include "ant_stack_handler_types.h" +#include "softdevice_handler.h" +#include "ser_hal_transport.h" + +#ifdef BLE_STACK_SUPPORT_REQD +#include "ble.h" +#endif // BLE_STACK_SUPPORT_REQD + +#ifdef __cplusplus +extern "C" { +#endif + +/** Maximum number of events in the application scheduler queue. */ +#define SER_CONN_SCHED_QUEUE_SIZE 16u + +/** Maximum size of events data in the application scheduler queue aligned to 32 bits - this is + * size of the buffer created in the SOFTDEVICE_HANDLER_INIT macro, which stores events pulled + * from the SoftDevice. */ +#define SER_CONN_SCHED_MAX_EVENT_DATA_SIZE ((CEIL_DIV(MAX( \ + MAX(BLE_STACK_EVT_MSG_BUF_SIZE, \ + ANT_STACK_EVT_STRUCT_SIZE), \ + SYS_EVT_MSG_BUF_SIZE \ + ), \ + sizeof(uint32_t))) * \ + sizeof(uint32_t)) + + +/**@brief A function for processing the HAL Transport layer events. + * + * @param[in] event HAL Transport layer event. + */ +void ser_conn_hal_transport_event_handle(ser_hal_transport_evt_t event); + + +/**@brief A function to call the function to process a packet when it is fully received. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred. + */ +uint32_t ser_conn_rx_process(void); + +#ifdef BLE_STACK_SUPPORT_REQD +/**@brief A function for processing BLE SoftDevice events. + * + * @details BLE events are put into application scheduler queue to be processed at a later time. + * + * @param[in] p_ble_evt A pointer to a BLE event. + */ +void ser_conn_ble_event_handle(ble_evt_t * p_ble_evt); +#endif // BLE_STACK_SUPPORT_REQD + +#ifdef ANT_STACK_SUPPORT_REQD +/**@brief A function for processing ANT SoftDevice events. + * + * @details ANT events are put into application scheduler queue to be processed at a later time. + * + * @param[in] p_ant_evt A pointer to a BLE event. + */ +void ser_conn_ant_event_handle(ant_evt_t * p_ant_evt); +#endif // ANT_STACK_SUPPORT_REQD + +#ifdef __cplusplus +} +#endif + +#endif /* SER_CONN_HANDLERS_H__ */ +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_pkt_decoder.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_pkt_decoder.c new file mode 100644 index 0000000000000000000000000000000000000000..25040640b07dcd42a5fba44fc489c259f0327082 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_pkt_decoder.c @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include +#include +#include "nordic_common.h" +#include "app_error.h" +#include "softdevice_handler.h" +#include "ble_serialization.h" +#include "ser_config.h" +#include "ser_hal_transport.h" +#include "ser_conn_pkt_decoder.h" +#include "ser_conn_cmd_decoder.h" +#include "ser_conn_dtm_cmd_decoder.h" +#include "ser_conn_reset_cmd_decoder.h" +#include "ser_dbg_sd_str.h" + +#define NRF_LOG_MODULE_NAME "SER_CONN" +#include "nrf_log.h" + + +uint32_t ser_conn_received_pkt_process( + ser_hal_transport_evt_rx_pkt_received_params_t * p_rx_pkt_params) +{ + uint32_t err_code = NRF_SUCCESS; + + if (NULL != p_rx_pkt_params) + { + /* For further processing pass only command (opcode + data). */ + uint8_t * p_command = &p_rx_pkt_params->p_buffer[SER_PKT_OP_CODE_POS]; + uint16_t command_len = p_rx_pkt_params->num_of_bytes - SER_PKT_TYPE_SIZE; + + NRF_LOG_DEBUG("[SD_CALL]:%s\r\n", + (uint32_t)ser_dbg_sd_call_str_get(*p_command)); + + switch (p_rx_pkt_params->p_buffer[SER_PKT_TYPE_POS]) + { + #if defined(ANT_STACK_SUPPORT_REQD) + case SER_PKT_TYPE_ANT_CMD: + //!! INTENTIONAL FALLTHROUGH + #endif + case SER_PKT_TYPE_CMD: + { + err_code = ser_conn_command_process(p_command, command_len); + break; + } + + case SER_PKT_TYPE_DTM_CMD: + { + err_code = ser_conn_dtm_command_process(p_command, command_len); + break; + } + + case SER_PKT_TYPE_RESET_CMD: + { + ser_conn_reset_command_process(); + break; + } + + default: + { + APP_ERROR_CHECK(SER_WARNING_CODE); + break; + } + } + + if (NRF_SUCCESS == err_code) + { + /* Free a received packet. */ + err_code = ser_hal_transport_rx_pkt_free(p_rx_pkt_params->p_buffer); + + if (NRF_SUCCESS != err_code) + { + err_code = NRF_ERROR_INTERNAL; + } + } + else + { + err_code = NRF_ERROR_INTERNAL; + } + } + else + { + err_code = NRF_ERROR_NULL; + } + + return err_code; +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_pkt_decoder.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_pkt_decoder.h new file mode 100644 index 0000000000000000000000000000000000000000..439ed235ff00e28419862f5e5ddf2544f4b053ee --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_pkt_decoder.h @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ser_conn Connectivity application code + * @ingroup ble_sdk_lib_serialization + */ + +/** @file + * + * @defgroup ser_pkt_decoder Packets decoder in the Connectivity Chip + * @{ + * @ingroup ser_conn + * + * @brief Decoder for serialized packets from the Application Chip. + * + * @details This file contains declaration of common function used for processing packets (packets + * dispatcher) received by the transport layer. + */ + +#ifndef SER_CONN_PKT_DECODER_H__ +#define SER_CONN_PKT_DECODER_H__ + +#include +#include "ser_hal_transport.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief A function for dispatching packets from the Application Chip to an appropriate decoder. + * + * @details The function is called to process received packets from a transport layer. + * The function analyzes packet type and calls appropriate command decoder which among + * other things processes command and sends a response. Then a received packet is freed. + * + * @param[in] p_rx_pkt_params A pointer to a transport layer event of type + * @ref ser_hal_transport_evt_rx_pkt_received_params_t. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred. + */ +uint32_t ser_conn_received_pkt_process( + ser_hal_transport_evt_rx_pkt_received_params_t * p_rx_pkt_params); + + +#ifdef __cplusplus +} +#endif + +#endif /* SER_CONN_PKT_DECODER_H__ */ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_reset_cmd_decoder.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_reset_cmd_decoder.c new file mode 100644 index 0000000000000000000000000000000000000000..c0dfc238753c1231ec5f38d39ae3de0fe47f391f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_reset_cmd_decoder.c @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "nrf_nvic.h" +#include "ser_conn_reset_cmd_decoder.h" + +void ser_conn_reset_command_process() +{ + (void)sd_nvic_SystemReset(); + while (1); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_reset_cmd_decoder.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_reset_cmd_decoder.h new file mode 100644 index 0000000000000000000000000000000000000000..da34ef03a15cf61e9134615facc89d5f88935c5a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/serialization/connectivity/ser_conn_reset_cmd_decoder.h @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ser_conn Connectivity application code + * @ingroup ble_sdk_lib_serialization + */ + +/** @file + * + * @defgroup ser_reset_cmd_decoder Reset Command Decoder in the connectivity chip + * @{ + * @ingroup ser_conn + * + * @brief Decoder for serialized reset command from the Application Chip. + * + * @details This file contains declaration of common function used for reset command decoding and + * sending responses back to the Application Chip after a command is processed. + */ + +#ifndef SER_CONN_RESET_CMD_DECODER_H__ +#define SER_CONN_RESET_CMD_DECODER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief A function for processing the encoded reset commands from the Application Chip. + * + * @details The function decodes encoded system reset command and performs software reset. + * This command does not send back the Command Response packet to the Application Chip. + */ +void ser_conn_reset_command_process(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* SER_CONN_RESET_CMD_DECODER_H__ */ + +/** @} */ + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/ant_stack_handler_types.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/ant_stack_handler_types.h new file mode 100644 index 0000000000000000000000000000000000000000..0bae6b19ef426749395327266753b91e498fed0b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/ant_stack_handler_types.h @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ant_stack_handler_types Types definitions for ANT support in SoftDevice handler. + * @{ + * @ingroup softdevice_handler + * @brief This file contains the declarations of types required for ANT stack support. These + * types will be defined when the preprocessor define ANT_STACK_SUPPORT_REQD is defined. + */ + +#ifndef ANT_STACK_HANDLER_TYPES_H__ +#define ANT_STACK_HANDLER_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef ANT_STACK_SUPPORT_REQD + +#include +#include + +#define ANT_STACK_EVT_MSG_BUF_SIZE 32 /**< Size of ANT event message buffer. This will be provided to the SoftDevice while fetching an event. */ +#define ANT_STACK_EVT_STRUCT_SIZE (sizeof(ant_evt_t)) /**< Size of the @ref ant_evt_t structure. This will be used by the @ref softdevice_handler to internal event buffer size needed. */ + +/**@brief ANT stack event type. */ +typedef struct +{ + union + { + uint32_t ulForceAlign; ///< force the evt_buffer to be 4-byte aligned, required for some casting to ANT_MESSAGE. + uint8_t evt_buffer[ANT_STACK_EVT_MSG_BUF_SIZE]; ///< Event message buffer. + } msg; + uint8_t channel; ///< Channel number. + uint8_t event; ///< Event code. +} ant_evt_t; + +/**@brief Application ANT stack event handler type. */ +typedef void (*ant_evt_handler_t) (ant_evt_t * p_ant_evt); + +/**@brief Function for registering for ANT events. + * + * @details The application should use this function to register for receiving ANT events from + * the SoftDevice. If the application does not call this function, then any ANT event + * that may be generated by the SoftDevice will NOT be fetched. Once the application has + * registered for the events, it is not possible to possible to cancel the registration. + * However, it is possible to register a different function for handling the events at + * any point of time. + * + * @param[in] ant_evt_handler Function to be called for each received ANT event. + * + * @retval NRF_SUCCESS Successful registration. + * @retval NRF_ERROR_NULL Null pointer provided as input. + */ +uint32_t softdevice_ant_evt_handler_set(ant_evt_handler_t ant_evt_handler); + +#else + +// The ANT Stack support is not required. + +#define ANT_STACK_EVT_STRUCT_SIZE 0 /**< Since the ANT stack support is not required, this is equated to 0, so that the @ref softdevice_handler.h can compute the internal event buffer size without having to care for ANT events.*/ + +#endif // ANT_STACK_SUPPORT_REQD + + +#ifdef __cplusplus +} +#endif + +#endif // ANT_STACK_HANDLER_TYPES_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/ble_stack_handler_types.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/ble_stack_handler_types.h new file mode 100644 index 0000000000000000000000000000000000000000..3d21144da79bc7743cd415672c63ecd0329e2037 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/ble_stack_handler_types.h @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/**@file + * + * @defgroup ble_stack_handler_types Types definitions for BLE support in SoftDevice handler. + * @{ + * @ingroup softdevice_handler + * @brief This file contains the declarations of types required for BLE stack support. These + * types will be defined when the preprocessor define BLE_STACK_SUPPORT_REQD is defined. + */ + +#ifndef BLE_STACK_HANDLER_TYPES_H__ +#define BLE_STACK_HANDLER_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef BLE_STACK_SUPPORT_REQD + +#include +#include "ble.h" +#include "nrf_sdm.h" +#include "app_error.h" +#include "app_util.h" +#include "sdk_config.h" + +/** @brief Default Maximum ATT MTU size. + * + * This define should be defined in the sdk_config.h file to override the default. + */ +#ifndef NRF_BLE_GATT_MAX_MTU_SIZE + #if (NRF_SD_BLE_API_VERSION >= 3) + #define NRF_BLE_GATT_MAX_MTU_SIZE BLE_GATT_ATT_MTU_DEFAULT + #else + #define NRF_BLE_GATT_MAX_MTU_SIZE GATT_MTU_SIZE_DEFAULT + #endif +#endif + +#define BLE_STACK_EVT_MSG_BUF_SIZE (sizeof(ble_evt_t) + (NRF_BLE_GATT_MAX_MTU_SIZE)) /**< Size of BLE event message buffer. This will be provided to the SoftDevice while fetching an event. */ +#define BLE_STACK_HANDLER_SCHED_EVT_SIZE 0 /**< The size of the scheduler event used by SoftDevice handler when passing BLE events using the @ref app_scheduler. */ + +/**@brief Application stack event handler type. */ +typedef void (*ble_evt_handler_t) (ble_evt_t * p_ble_evt); + +/**@brief Function for registering for BLE events. + * + * @details The application should use this function to register for receiving BLE events from + * the SoftDevice. If the application does not call this function, then any BLE event + * that may be generated by the SoftDevice will NOT be fetched. Once the application has + * registered for the events, it is not possible to cancel the registration. + * However, it is possible to register a different function for handling the events at + * any point of time. + * + * @param[in] ble_evt_handler Function to be called for each received BLE event. + * + * @retval NRF_SUCCESS Successful registration. + * @retval NRF_ERROR_NULL Null pointer provided as input. + */ +uint32_t softdevice_ble_evt_handler_set(ble_evt_handler_t ble_evt_handler); + +#else + +#define BLE_STACK_EVT_MSG_BUF_SIZE 0 /**< Since the BLE stack support is not required, this is equated to 0, so that the @ref softdevice_handler.h can compute the internal event buffer size without having to care for BLE events.*/ +#define BLE_STACK_HANDLER_SCHED_EVT_SIZE 0 + +#endif // BLE_STACK_SUPPORT_REQD + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_STACK_HANDLER_TYPES_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/softdevice_handler.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/softdevice_handler.c new file mode 100644 index 0000000000000000000000000000000000000000..6eb157afabf6ce687fdf12fcc952b5caea9b6284 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/softdevice_handler.c @@ -0,0 +1,597 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "softdevice_handler.h" +#include +#include +#include +#include +#include "nrf.h" +#include "nrf_assert.h" +#include "nrf_soc.h" +#include "nrf_nvic.h" +#include "sdk_common.h" + +#if NRF_MODULE_ENABLED(CLOCK) +#include "nrf_drv_clock.h" +#endif // NRF_MODULE_ENABLED(CLOCK) +#if NRF_MODULE_ENABLED(POWER) +#include "nrf_drv_power.h" +#endif // NRF_MODULE_ENABLED(POWER) +#include "app_error.h" + +#if NRF_MODULE_ENABLED(RNG) +#include "nrf_drv_rng.h" +#endif // NRF_MODULE_ENABLED(RNG) + +#define NRF_LOG_MODULE_NAME "SDH" +#include "nrf_log.h" +#if defined(ANT_STACK_SUPPORT_REQD) && defined(BLE_STACK_SUPPORT_REQD) + #include "ant_interface.h" +#elif defined(ANT_STACK_SUPPORT_REQD) + #include "ant_interface.h" +#elif defined(BLE_STACK_SUPPORT_REQD) + #include "ble.h" +#endif + + +#define RAM_START_ADDRESS 0x20000000 +#define SOFTDEVICE_EVT_IRQ SD_EVT_IRQn /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ +#define SOFTDEVICE_EVT_IRQHandler SD_EVT_IRQHandler +#define RAM_TOTAL_SIZE ((NRF_FICR->INFO.RAM) * 1024) +#define RAM_END_ADDRESS (RAM_START_ADDRESS + RAM_TOTAL_SIZE) + + +static softdevice_evt_schedule_func_t m_evt_schedule_func; /**< Pointer to function for propagating SoftDevice events to the scheduler. */ +static sys_evt_handler_t m_sys_evt_handler; /**< Application event handler for handling System (SOC) events. */ + +static volatile bool m_softdevice_enabled = false; /**< Variable to indicate whether the SoftDevice is enabled. */ +static volatile bool m_suspended; /**< Current state of the event handler. */ + +// The following three definitions is needed only if BLE events are needed to be pulled from the stack. +#ifdef BLE_STACK_SUPPORT_REQD +static uint8_t * mp_ble_evt_buffer; /**< Buffer for receiving BLE events from the SoftDevice. */ +static uint16_t m_ble_evt_buffer_size; /**< Size of BLE event buffer. */ +static ble_evt_handler_t m_ble_evt_handler; /**< Application event handler for handling BLE events. */ +#endif + +#ifdef ANT_STACK_SUPPORT_REQD +// The following two definitions are needed only if ANT events are needed to be pulled from the stack. +static ant_evt_t m_ant_evt_buffer; /**< Buffer for receiving ANT events from the SoftDevice. */ +static ant_evt_handler_t m_ant_evt_handler; /**< Application event handler for handling ANT events. */ +#endif + + +#if defined(S1XX) +/**@brief Callback function for asserts in the SoftDevice. + * + * @details A pointer to this function will be passed to the SoftDevice. This function will be + * called if an ASSERT statement in the SoftDevice fails. + * + * @param[in] pc The value of the program counter when the ASSERT call failed. + * @param[in] line_num Line number of the failing ASSERT call. + * @param[in] file_name File name of the failing ASSERT call. + */ +void softdevice_assertion_handler(uint32_t pc, uint16_t line_num, const uint8_t * file_name) +{ + UNUSED_PARAMETER(pc); + assert_nrf_callback(line_num, file_name); +} +#else +/**@brief Callback function for asserts in the SoftDevice. + * + * @details A pointer to this function will be passed to the SoftDevice. This function will be + * called by the SoftDevice if certain unrecoverable errors occur within the + * application or SoftDevice. + * + * See @ref nrf_fault_handler_t for more details. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault. + * @param[in] info Optional additional information regarding the fault. Refer to each fault + * identifier for details. + */ +void softdevice_fault_handler(uint32_t id, uint32_t pc, uint32_t info) +{ + app_error_fault_handler(id, pc, info); +} +#endif + + +void intern_softdevice_events_execute(void) +{ + if (!m_softdevice_enabled) + { + // SoftDevice not enabled. This can be possible if the SoftDevice was enabled by the + // application without using this module's API (i.e softdevice_handler_init) + + return; + } +#if NRF_MODULE_ENABLED(CLOCK) + bool no_more_soc_evts = false; +#else + bool no_more_soc_evts = (m_sys_evt_handler == NULL); +#endif +#ifdef BLE_STACK_SUPPORT_REQD + bool no_more_ble_evts = (m_ble_evt_handler == NULL); +#endif +#ifdef ANT_STACK_SUPPORT_REQD + bool no_more_ant_evts = (m_ant_evt_handler == NULL); +#endif + + for (;;) + { + uint32_t err_code; + + if (!no_more_soc_evts) + { + if (m_suspended) + { + // Cancel pulling next event if event handler was suspended by user. + return; + } + + uint32_t evt_id; + + // Pull event from SOC. + err_code = sd_evt_get(&evt_id); + + if (err_code == NRF_ERROR_NOT_FOUND) + { + no_more_soc_evts = true; + } + else if (err_code != NRF_SUCCESS) + { + APP_ERROR_HANDLER(err_code); + } + else + { +#ifdef SOFTDEVICE_PRESENT + // Call application's SOC event handler. +#if NRF_MODULE_ENABLED(POWER) + nrf_drv_power_on_soc_event(evt_id); +#endif +#if NRF_MODULE_ENABLED(CLOCK) + nrf_drv_clock_on_soc_event(evt_id); +#endif +#endif /* SOFTDEVICE_PRESENT */ + if (m_sys_evt_handler) + { + m_sys_evt_handler(evt_id); + } + } + } + +#ifdef BLE_STACK_SUPPORT_REQD + // Fetch BLE Events. + if (!no_more_ble_evts) + { + if (m_suspended) + { + // Cancel pulling next event if event handler was suspended by user. + return; + } + + // Pull event from stack + uint16_t evt_len = m_ble_evt_buffer_size; + + err_code = sd_ble_evt_get(mp_ble_evt_buffer, &evt_len); + if (err_code == NRF_ERROR_NOT_FOUND) + { + no_more_ble_evts = true; + } + else if (err_code != NRF_SUCCESS) + { + APP_ERROR_HANDLER(err_code); + } + else + { + // Call application's BLE stack event handler. + m_ble_evt_handler((ble_evt_t *)mp_ble_evt_buffer); + } + } +#endif + +#ifdef ANT_STACK_SUPPORT_REQD + // Fetch ANT Events. + if (!no_more_ant_evts) + { + if (m_suspended) + { + // Cancel pulling next event if event handler was suspended by user. + return; + } + + // Pull event from stack + err_code = sd_ant_event_get(&m_ant_evt_buffer.channel, + &m_ant_evt_buffer.event, + m_ant_evt_buffer.msg.evt_buffer); + if (err_code == NRF_ERROR_NOT_FOUND) + { + no_more_ant_evts = true; + } + else if (err_code != NRF_SUCCESS) + { + APP_ERROR_HANDLER(err_code); + } + else + { + // Call application's ANT stack event handler. + m_ant_evt_handler(&m_ant_evt_buffer); + } + } +#endif + + if (no_more_soc_evts) + { + // There are no remaining System (SOC) events to be fetched from the SoftDevice. +#if defined(ANT_STACK_SUPPORT_REQD) && defined(BLE_STACK_SUPPORT_REQD) + // Check if there are any remaining BLE and ANT events. + if (no_more_ble_evts && no_more_ant_evts) + { + break; + } +#elif defined(BLE_STACK_SUPPORT_REQD) + // Check if there are any remaining BLE events. + if (no_more_ble_evts) + { + break; + } +#elif defined(ANT_STACK_SUPPORT_REQD) + // Check if there are any remaining ANT events. + if (no_more_ant_evts) + { + break; + } +#else + // No need to check for BLE or ANT events since there is no support for BLE and ANT + // required. + break; +#endif + } + } +} + + +bool softdevice_handler_is_enabled(void) +{ + return m_softdevice_enabled; +} + +#if defined(S1XX) +uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t clock_source, + void * p_ble_evt_buffer, + uint16_t ble_evt_buffer_size, + softdevice_evt_schedule_func_t evt_schedule_func) +#else +uint32_t softdevice_handler_init(nrf_clock_lf_cfg_t * p_clock_lf_cfg, + void * p_ble_evt_buffer, + uint16_t ble_evt_buffer_size, + softdevice_evt_schedule_func_t evt_schedule_func) +#endif +{ + uint32_t err_code; + + // Save configuration. +#if defined (BLE_STACK_SUPPORT_REQD) + // Check that buffer is not NULL. + if (p_ble_evt_buffer == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Check that buffer is correctly aligned. + if (!is_word_aligned(p_ble_evt_buffer)) + { + return NRF_ERROR_INVALID_PARAM; + } + + mp_ble_evt_buffer = (uint8_t *)p_ble_evt_buffer; + m_ble_evt_buffer_size = ble_evt_buffer_size; +#else + // The variables p_ble_evt_buffer and ble_evt_buffer_size is not needed if BLE Stack support + // is not required. + UNUSED_PARAMETER(p_ble_evt_buffer); + UNUSED_PARAMETER(ble_evt_buffer_size); +#endif + + m_evt_schedule_func = evt_schedule_func; + + // Initialize SoftDevice. +#if ((NRF_MODULE_ENABLED(CLOCK) || NRF_MODULE_ENABLED(POWER)) && defined(SOFTDEVICE_PRESENT)) + bool power_clock_isr_enabled = nrf_drv_common_irq_enable_check(POWER_CLOCK_IRQn); + if (power_clock_isr_enabled) + { + NVIC_DisableIRQ(POWER_CLOCK_IRQn); + } +#endif + +#if (NRF_MODULE_ENABLED(RNG) && defined(SOFTDEVICE_PRESENT)) + bool rng_isr_enabled = nrf_drv_common_irq_enable_check(RNG_IRQn); + if (rng_isr_enabled) + { + NVIC_DisableIRQ(RNG_IRQn); + } +#endif +#if defined(S212) || defined(S332) + err_code = sd_softdevice_enable(p_clock_lf_cfg, softdevice_fault_handler, ANT_LICENSE_KEY); +#elif defined(S1XX) + err_code = sd_softdevice_enable(clock_source, softdevice_assertion_handler); +#else + err_code = sd_softdevice_enable(p_clock_lf_cfg, softdevice_fault_handler); +#endif + + if (err_code != NRF_SUCCESS) + { +#if (NRF_MODULE_ENABLED(RNG) && defined(SOFTDEVICE_PRESENT)) + if (rng_isr_enabled) + { + NVIC_EnableIRQ(RNG_IRQn); + } +#endif +#if ((NRF_MODULE_ENABLED(CLOCK) || NRF_MODULE_ENABLED(POWER)) && defined(SOFTDEVICE_PRESENT)) + if (power_clock_isr_enabled) + { + NVIC_EnableIRQ(POWER_CLOCK_IRQn); + } +#endif + return err_code; + } + + m_softdevice_enabled = true; +#ifdef SOFTDEVICE_PRESENT +#if NRF_MODULE_ENABLED(POWER) + nrf_drv_power_on_sd_enable(); +#endif +#if NRF_MODULE_ENABLED(CLOCK) + nrf_drv_clock_on_sd_enable(); +#endif +#endif /* SOFTDEVICE_PRESENT */ + + // Enable BLE event interrupt (interrupt priority has already been set by the stack). +#ifdef SOFTDEVICE_PRESENT + err_code = sd_nvic_EnableIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ); + return err_code; + +#else + //In case of Serialization NVIC must be accessed directly. + NVIC_EnableIRQ(SOFTDEVICE_EVT_IRQ); + return NRF_SUCCESS; +#endif +} + + +uint32_t softdevice_handler_sd_disable(void) +{ + uint32_t err_code = sd_softdevice_disable(); + if (err_code == NRF_SUCCESS) + { + m_softdevice_enabled = false; +#ifdef SOFTDEVICE_PRESENT +#if NRF_MODULE_ENABLED(POWER) + nrf_drv_power_on_sd_disable(); +#endif +#if NRF_MODULE_ENABLED(CLOCK) + nrf_drv_clock_on_sd_disable(); +#endif +#if NRF_MODULE_ENABLED(RNG) + nrf_drv_rng_on_sd_disable(); +#endif +#endif /* SOFTDEVICE_PRESENT */ + } + return err_code; +} + + +#ifdef BLE_STACK_SUPPORT_REQD +uint32_t softdevice_ble_evt_handler_set(ble_evt_handler_t ble_evt_handler) +{ + VERIFY_PARAM_NOT_NULL(ble_evt_handler); + + m_ble_evt_handler = ble_evt_handler; + + return NRF_SUCCESS; +} +#endif + + +#ifdef ANT_STACK_SUPPORT_REQD +uint32_t softdevice_ant_evt_handler_set(ant_evt_handler_t ant_evt_handler) +{ + VERIFY_PARAM_NOT_NULL(ant_evt_handler); + + m_ant_evt_handler = ant_evt_handler; + + return NRF_SUCCESS; +} +#endif + + +uint32_t softdevice_sys_evt_handler_set(sys_evt_handler_t sys_evt_handler) +{ + VERIFY_PARAM_NOT_NULL(sys_evt_handler); + + m_sys_evt_handler = sys_evt_handler; + + return NRF_SUCCESS; +} + + +/**@brief Function for handling the Application's BLE Stack events interrupt. + * + * @details This function is called whenever an event is ready to be pulled. + */ +void SOFTDEVICE_EVT_IRQHandler(void) +{ + if (m_evt_schedule_func != NULL) + { + uint32_t err_code = m_evt_schedule_func(); + APP_ERROR_CHECK(err_code); + } + else + { + intern_softdevice_events_execute(); + } +} + + +void softdevice_handler_suspend() +{ +#ifdef SOFTDEVICE_PRESENT + ret_code_t err_code = sd_nvic_DisableIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ); + APP_ERROR_CHECK(err_code); +#else + NVIC_DisableIRQ(SOFTDEVICE_EVT_IRQ); +#endif + m_suspended = true; + return; +} + + +void softdevice_handler_resume() +{ + if (!m_suspended) + { + return; + } + m_suspended = false; + +#ifdef SOFTDEVICE_PRESENT + ret_code_t err_code; + + // Force calling ISR again to make sure that events not pulled previously + // has been processed. + err_code = sd_nvic_SetPendingIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ); + APP_ERROR_CHECK(err_code); + err_code = sd_nvic_EnableIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ); + APP_ERROR_CHECK(err_code); +#else + NVIC_SetPendingIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ); + NVIC_EnableIRQ(SOFTDEVICE_EVT_IRQ); +#endif + + return; +} + + +bool softdevice_handler_is_suspended() +{ + return m_suspended; +} + +#if defined(BLE_STACK_SUPPORT_REQD) && !defined(S1XX) + +static inline uint32_t ram_total_size_get(void) +{ +#ifdef NRF51 + uint32_t size_ram_blocks = (uint32_t)NRF_FICR->SIZERAMBLOCKS; + uint32_t total_ram_size = size_ram_blocks; + total_ram_size = total_ram_size * (NRF_FICR->NUMRAMBLOCK); + return total_ram_size; +#elif (defined (NRF52) || defined(NRF52840_XXAA)) + return RAM_TOTAL_SIZE; +#endif /* NRF51 */ +} + + +/*lint --e{528} -save suppress 528: symbol not referenced */ +/**@brief Function for finding the end address of the RAM. + * + * @retval ram_end_address Address of the end of the RAM. + */ +static inline uint32_t ram_end_address_get(void) +{ + uint32_t ram_end_address = (uint32_t)RAM_START_ADDRESS; + ram_end_address += ram_total_size_get(); + return ram_end_address; +} +/*lint -restore*/ + + +/*lint --e{10} --e{27} --e{40} --e{529} -save */ +ret_code_t softdevice_app_ram_start_get(uint32_t * app_ram_base) +{ + ret_code_t ret = NRF_SUCCESS; +#if defined ( __CC_ARM ) + extern uint32_t Image$$RW_IRAM1$$Base; + const volatile uint32_t ram_start = (uint32_t) &Image$$RW_IRAM1$$Base; +#elif defined ( __ICCARM__ ) + extern uint32_t __ICFEDIT_region_RAM_start__; + volatile uint32_t ram_start = (uint32_t) &__ICFEDIT_region_RAM_start__; +#elif defined ( __GNUC__ ) + extern uint32_t __data_start__; + volatile uint32_t ram_start = (uint32_t) &__data_start__; +#else + ret = NRF_ERROR_NOT_FOUND; + return ret; +#endif + *app_ram_base = ram_start; + return ret; +} +/*lint -restore*/ + + +/*lint --e{10} --e{27} --e{40} --e{529} -save */ +uint32_t softdevice_enable(uint32_t * ram_start) +{ +#if (defined(S130) || defined(S132) || defined(S332) || defined(S140)) + uint32_t err_code; + uint32_t app_ram_base = *ram_start; + + NRF_LOG_DEBUG("RAM start at 0x%x.\r\n", app_ram_base); + err_code = sd_ble_enable(&app_ram_base); + + if (app_ram_base != *ram_start) + { + NRF_LOG_WARNING("RAM start should be adjusted to 0x%x.\r\n", app_ram_base); + NRF_LOG_WARNING("RAM size should be adjusted to 0x%x.\r\n", + ram_end_address_get() - app_ram_base); + } + else if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("sd_ble_enable() returned unexpected value: 0x%x.\r\n", err_code); + } + return err_code; +#else + return NRF_SUCCESS; +#endif //defined(S130) || defined(S132) || defined(S332) || defined(S140) +} +/*lint -restore*/ + +#endif //BLE_STACK_SUPPORT_REQD diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/softdevice_handler.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/softdevice_handler.h new file mode 100644 index 0000000000000000000000000000000000000000..8db0be7b83b951a3373b600e27337bbe374e13d6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/softdevice_handler.h @@ -0,0 +1,290 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +/** @file + * + * @defgroup softdevice_handler SoftDevice Event Handler + * @{ + * @ingroup app_common + * @brief API for initializing and disabling the SoftDevice + * + * @details This API contains the functions and defines exposed by the @ref lib_softdevice_handler. + * For more information on the library and how the application should use it, please refer + * @ref lib_softdevice_handler. + * + * @note Use the USE_SCHEDULER parameter of the SOFTDEVICE_HANDLER_INIT() macro to select if + * the @ref app_scheduler is to be used or not. + * + * @note Even if the scheduler is not used, softdevice_handler.h will include app_scheduler.h. + * So when compiling, app_scheduler.h must be available in one of the compiler include + * paths. + */ + +#ifndef SOFTDEVICE_HANDLER_H__ +#define SOFTDEVICE_HANDLER_H__ + +#include +#include "nordic_common.h" +#include "nrf_sdm.h" +#include "app_error.h" +#include "app_util.h" +#include "ble_stack_handler_types.h" +#include "ant_stack_handler_types.h" +#if defined(BLE_STACK_SUPPORT_REQD) + #include "ble.h" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#define SOFTDEVICE_SCHED_EVT_SIZE 0 /**< Size of button events being passed through the scheduler (is to be used for computing the maximum size of scheduler events). For SoftDevice events, this size is 0, since the events are being pulled in the event handler. */ +#define SYS_EVT_MSG_BUF_SIZE sizeof(uint32_t) /**< Size of System (SOC) event message buffer. */ + + +/**@brief Function for checking the RAM requirement of the SoftDevice. + * + * @details Call this function to check if the project settings have the correct RAM start address in respect to what the SoftDevice requires. + * + * @note This function is called using the CHECK_RAM_START_ADDR_INTERN macro and should not be called directly. + */ +uint32_t sd_check_ram_start(uint32_t sd_req_ram_start); + + +/**@brief Type of function for passing events from the stack handler module to the scheduler. */ +typedef uint32_t (*softdevice_evt_schedule_func_t) (void); + + +/**@brief Application System (SOC) event handler type. */ +typedef void (*sys_evt_handler_t) (uint32_t evt_id); + + +/**@brief Macro for initializing the stack event handler. + * + * @details It will handle dimensioning and allocation of the memory buffer required for reading + * events from the stack, making sure the buffer is correctly aligned. It will also + * connect the stack event handler to the scheduler/RTOS (if specified). + * + * @param[in] CLOCK_SOURCE Low frequency clock source and accuracy (type nrf_clock_lf_cfg_t_t, + * see sd_softdevice_enable() for details). + * @param[in] EVT_HANDLER scheduler/RTOS event handler function. + * + * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it + * several times as long as it is from the same location, that is to do a + * reinitialization). + */ +/*lint -emacro(506, SOFTDEVICE_HANDLER_INIT) */ /* Suppress "Constant value Boolean */ +#define SOFTDEVICE_HANDLER_INIT(CLOCK_SOURCE, \ + EVT_HANDLER) \ + do \ + { \ + static uint32_t BLE_EVT_BUFFER[CEIL_DIV(BLE_STACK_EVT_MSG_BUF_SIZE, sizeof(uint32_t))]; \ + uint32_t ERR_CODE; \ + ERR_CODE = softdevice_handler_init((CLOCK_SOURCE), \ + BLE_EVT_BUFFER, \ + sizeof(BLE_EVT_BUFFER), \ + EVT_HANDLER); \ + APP_ERROR_CHECK(ERR_CODE); \ + } while (0) + + +/** + * @brief Function for retrieving the information about SD state + * + * The information about current state of softdevice. + * @retval false SD is not initialized and SD commands should not be called. + * @retval true SD is already initialized + */ +bool softdevice_handler_is_enabled(void); + +#ifndef S1XX +/**@brief Function for initializing the stack handler module. + * + * @details Enables the SoftDevice and the stack event interrupt handler. + * + * @note This function must be called before calling any function in the SoftDevice API. + * + * @note Normally initialization should be done using the SOFTDEVICE_HANDLER_INIT() macro, + * as that will both allocate the event buffer, and also align the buffer correctly. + * + * @param[in] p_clock_lf_cfg Low frequency clock source to be used by the SoftDevice. + * @param[in] p_ble_evt_buffer Buffer for holding one BLE stack event. Since heap is not being + * used, this buffer must be provided by the application. The + * buffer must be large enough to hold the biggest stack event the + * application is supposed to handle. The buffer must be aligned to + * a 4 byte boundary. This parameter is unused if BLE stack support + * is not required. + * @param[in] ble_evt_buffer_size Size of SoftDevice BLE event buffer. This parameter is unused if + * BLE stack support is not required. + * @param[in] evt_schedule_func Function for passing events to the scheduler. Point to + * ble_ant_stack_evt_schedule() to connect to the scheduler. + * Set to NULL to make the stack handler module call the event + * handler directly from the stack event interrupt handler. + * + * @retval NRF_SUCCESS Successful initialization. + * @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte + * boundary) or NULL. + */ +uint32_t softdevice_handler_init(nrf_clock_lf_cfg_t * p_clock_lf_cfg, + void * p_ble_evt_buffer, + uint16_t ble_evt_buffer_size, + softdevice_evt_schedule_func_t evt_schedule_func); +#else +/**@brief Function for initializing the stack handler module. + * + * @details Enables the SoftDevice and the stack event interrupt handler. + * + * @note This function must be called before calling any function in the SoftDevice API. + * + * @note Normally initialization should be done using the SOFTDEVICE_HANDLER_INIT() macro, + * as that will both allocate the event buffer, and also align the buffer correctly. + * + * @param[in] clock_source Low frequency clock source to be used by the SoftDevice. + * @param[in] p_ble_evt_buffer Buffer for holding one BLE stack event. Since heap is not being + * used, this buffer must be provided by the application. The + * buffer must be large enough to hold the biggest stack event the + * application is supposed to handle. The buffer must be aligned to + * a 4 byte boundary. This parameter is unused if BLE stack support + * is not required. + * @param[in] ble_evt_buffer_size Size of SoftDevice BLE event buffer. This parameter is unused if + * BLE stack support is not required. + * @param[in] evt_schedule_func Function for passing events to the scheduler. Point to + * ble_ant_stack_evt_schedule() to connect to the scheduler. + * Set to NULL to make the stack handler module call the event + * handler directly from the stack event interrupt handler. + * + * @retval NRF_SUCCESS Successful initialization. + * @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte + * boundary) or NULL. + */ +uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t clock_source, + void * p_ble_evt_buffer, + uint16_t ble_evt_buffer_size, + softdevice_evt_schedule_func_t evt_schedule_func); +#endif + +/**@brief Function for disabling the SoftDevice. + * + * @details This function will disable the SoftDevice. It will also update the internal state + * of this module. + */ +uint32_t softdevice_handler_sd_disable(void); + + +/**@brief Function for suspending the event handler. + * + * @details When event handler is disabled, no new events are pulled from SoftDevice. + * Application can suspend pulling incoming events when its event queue is full. + */ +void softdevice_handler_suspend(void); + + +/**@brief Function for re-enabling the event handler after suspending. + */ +void softdevice_handler_resume(void); + + +/**@brief Function for retrieving the information about the event handler state + * + * @retval false Event handler is active. + * @retval true Event handler is suspended and events from SD will not be pulled. + */ +bool softdevice_handler_is_suspended(void); + + +/**@brief Function for registering for System (SOC) events. + * + * @details The application should use this function to register for receiving System (SOC) + * events from the SoftDevice. If the application does not call this function, then any + * System (SOC) events that may be generated by the SoftDevice will NOT be fetched. Once + * the application has registered for the events, it is not possible to possible to + * cancel the registration. However, it is possible to register a different function for + * handling the events at any point of time. + * + * @param[in] sys_evt_handler Function to be called for each received System (SOC) event. + * + * @retval NRF_SUCCESS Successful registration. + * @retval NRF_ERROR_NULL Null pointer provided as input. + */ +uint32_t softdevice_sys_evt_handler_set(sys_evt_handler_t sys_evt_handler); + + +#if defined(BLE_STACK_SUPPORT_REQD) +/**@brief Function for fetching the start address of the application RAM. + * + * @details This function must be called before @ref softdevice_enable and @ref sd_ble_cfg_set. + * It reads the RAM start address as a region symbol, depending on the compiler. + * + * @param[in] app_ram_base Variable to store the start address for the application RAM. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NOT_FOUND If the compiler is not supported. + */ +ret_code_t softdevice_app_ram_start_get(uint32_t * app_ram_base); + +/**@brief Function for enabling the SoftDevice. + * + * @details This function calls the @ref sd_ble_enable SVC call. It has been abstracted to give + * feedback on the app_ram_base. If the app_ram_base is too low, this function will + * return an error. Using a app_ram_base that is too high will not fail, but will + * result in RAM that is never used. If the DEBUG macro is enabled, this + * function will provide the correct app_ram_base as mandated by the SoftDevice. + * This is useful to tweak the RAM use of your application. + * + * @param[in] ram_start Parameters for configuring links and bandwidths. + * + * @retval NRF_SUCCESS If the operation was successful. + */ +uint32_t softdevice_enable(uint32_t * ram_start); +#endif //BLE_STACK_SUPPORT_REQD + +// Functions for connecting the Stack Event Handler to the scheduler: +/**@cond NO_DOXYGEN */ +void intern_softdevice_events_execute(void); +/**@endcond */ + + +#ifdef __cplusplus +} +#endif + +#endif // SOFTDEVICE_HANDLER_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.c new file mode 100644 index 0000000000000000000000000000000000000000..6b05f83c44ef5a48b9efa88e1c66ac62f5faccbb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.c @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "softdevice_handler_appsh.h" +#include "app_scheduler.h" +#include + +void softdevice_evt_get(void * p_event_data, uint16_t event_size) +{ + APP_ERROR_CHECK_BOOL(event_size == 0); + intern_softdevice_events_execute(); +} + +uint32_t softdevice_evt_schedule(void) +{ + return app_sched_event_put(NULL, 0, softdevice_evt_get); +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.h new file mode 100644 index 0000000000000000000000000000000000000000..c1f3259a5178aea852e5143a6618ba0e26a0440d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef SOFTDEVICE_HANDLER_APPSH_H +#define SOFTDEVICE_HANDLER_APPSH_H + +#include "softdevice_handler.h" +#include + +#define SOFTDEVICE_HANDLER_APPSH_INIT(CLOCK_SOURCE,USE_SCHEDULER) \ + SOFTDEVICE_HANDLER_INIT(CLOCK_SOURCE,(USE_SCHEDULER) ? softdevice_evt_schedule : NULL) + +uint32_t softdevice_evt_schedule(void); + +#endif //SOFTDEVICE_HANDLER_APPSH_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_licence-agreement.pdf b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_licence-agreement.pdf new file mode 100644 index 0000000000000000000000000000000000000000..68424a831e694bab02025a4332a1f0873094fc29 Binary files /dev/null and b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_licence-agreement.pdf differ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_licence-agreement.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_licence-agreement.txt new file mode 100644 index 0000000000000000000000000000000000000000..09a78bbc69f5f858448e42bb6c16feced2332620 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_licence-agreement.txt @@ -0,0 +1,96 @@ +S110/S120/S130/S132 license agreement + + +NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT + +License Agreement for the Nordic Semiconductor ASA ("Nordic") S110, S120, S130 and S132 Bluetooth SoftDevice software packages +("SoftDevice"). + +You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before +downloading, installing and/or using any software or content in the SoftDevice provided herewith. + +YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS +OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF +THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. + +IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE +INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE. + +1. Grant of License +Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license +("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated +in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this +agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit. + +2. Title +Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and +other intellectual property rights in and to the SoftDevice. + +3. No Modifications or Reverse Engineering +Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code +parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code. + +4. Distribution Restrictions +Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party. +Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein. +Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee +necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making +such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice. + +5. No Other Rights +Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be +contrary to this Agreement. + +6. Fees +Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to +comply with the Agreement. + +7. DISCLAIMER OF WARRANTY +THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS +LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR +THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE +IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE +REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE. +LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S +INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. + + +8. No Support +Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, +bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice. + +9. Limitation of Liability +In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of +procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any +special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, +tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers, +licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or +limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to +USD 50. + +10. Breach of Contract +Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably +attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both +direct and indirect costs for Nordic and its licensors. + +11. Indemnity +Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and +agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which +is not due to causes for which Nordic is responsible. + +12. Governing Law +This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. + +13. Assignment +Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. + +14. Termination +Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this +Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any +other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. + +15. Third party beneficiaries +Nordic’s licensors are intended third party beneficiaries under this Agreement. + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_migration-document.pdf b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_migration-document.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d0968d5f29646c7ecc31a0bcfdea1951eaca1e8f Binary files /dev/null and b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_migration-document.pdf differ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_readme.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..89c6962c9580da5f04ee3ce12141365ffe7b454f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_readme.txt @@ -0,0 +1,13 @@ +s132_nrf52_4.0.2 + +This release consists of the following: +- This readme file +- The s132_nrf52_4.0.2 API (SoftDevice header files) +- The s132_nrf52_4.0.2 license agreement +- The s132_nrf52_4.0.2 release notes +- The s132_nrf52_4.0.2 SoftDevice (binary hex file) +- The s132_nrf52_4.0.2 migration document +- The s132_nrf52_4.0.2 API diff + + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_release-notes.pdf b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_release-notes.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0df54baee800399063741d674d30035feb8c5946 Binary files /dev/null and b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/doc/s132_nrf52_4.0.2_release-notes.pdf differ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble.h new file mode 100644 index 0000000000000000000000000000000000000000..e0b15b2ecd23df482e39eeaee12901e697807119 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble.h @@ -0,0 +1,615 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_COMMON BLE SoftDevice Common + @{ + @defgroup ble_api Events, type definitions and API calls + @{ + + @brief Module independent events, type definitions and API calls for the BLE SoftDevice. + + */ + +#ifndef BLE_H__ +#define BLE_H__ + +#include "ble_ranges.h" +#include "ble_types.h" +#include "ble_gap.h" +#include "ble_l2cap.h" +#include "ble_gatt.h" +#include "ble_gattc.h" +#include "ble_gatts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations + * @{ */ + +/** + * @brief Common API SVC numbers. + */ +enum BLE_COMMON_SVCS +{ + SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */ + SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */ + SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific UUID. */ + SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */ + SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */ + SD_BLE_VERSION_GET, /**< Get the local version information (company ID, Link Layer Version, Link Layer Subversion). */ + SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */ + SD_BLE_OPT_SET, /**< Set a BLE option. */ + SD_BLE_OPT_GET, /**< Get a BLE option. */ + SD_BLE_CFG_SET, /**< Add a configuration to the BLE stack. */ +}; + +/** + * @brief BLE Module Independent Event IDs. + */ +enum BLE_COMMON_EVTS +{ + BLE_EVT_USER_MEM_REQUEST = BLE_EVT_BASE, /**< User Memory request. @ref ble_evt_user_mem_request_t */ + BLE_EVT_USER_MEM_RELEASE, /**< User Memory release. @ref ble_evt_user_mem_release_t */ +}; + +/**@brief BLE Connection Configuration IDs. + * + * IDs that uniquely identify a connection configuration. + */ +enum BLE_CONN_CFGS +{ + BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE, /**< BLE GAP specific connection configuration. */ + BLE_CONN_CFG_GATTC, /**< BLE GATTC specific connection configuration. */ + BLE_CONN_CFG_GATTS, /**< BLE GATTS specific connection configuration. */ + BLE_CONN_CFG_GATT, /**< BLE GATT specific connection configuration. */ +}; + +/**@brief BLE Common Configuration IDs. + * + * IDs that uniquely identify a common configuration. + */ +enum BLE_COMMON_CFGS +{ + BLE_COMMON_CFG_VS_UUID = BLE_CFG_BASE, /**< Vendor specific UUID configuration */ +}; + +/**@brief Common Option IDs. + * IDs that uniquely identify a common option. + */ +enum BLE_COMMON_OPTS +{ + BLE_COMMON_OPT_PA_LNA = BLE_OPT_BASE, /**< PA and LNA options */ + BLE_COMMON_OPT_CONN_EVT_EXT, /**< Extended connection events option */ +}; + +/** @} */ + +/** @addtogroup BLE_COMMON_DEFINES Defines + * @{ */ + +/** @brief Required pointer alignment for BLE Events. +*/ +#define BLE_EVT_PTR_ALIGNMENT 4 + +/** @brief Leaves the maximum of the two arguments. +*/ +#define BLE_MAX(a, b) ((a) < (b) ? (b) : (a)) + +/** @brief Maximum possible length for BLE Events. + * @note The highest value used for @ref ble_gatt_conn_cfg_t::att_mtu in any connection configuration shall be used as a parameter. + * If that value has not been configured for any connections then @ref BLE_GATT_ATT_MTU_DEFAULT must be used instead. +*/ +#define BLE_EVT_LEN_MAX(ATT_MTU) (BLE_MAX( \ + sizeof(ble_evt_t), \ + BLE_MAX( \ + offsetof(ble_evt_t, evt.gattc_evt.params.rel_disc_rsp.includes) + ((ATT_MTU) - 2) / 6 * sizeof(ble_gattc_include_t), \ + offsetof(ble_evt_t, evt.gattc_evt.params.attr_info_disc_rsp.info.attr_info16) + ((ATT_MTU) - 2) / 4 * sizeof(ble_gattc_attr_info16_t) \ + ) \ +)) + +/** @defgroup BLE_USER_MEM_TYPES User Memory Types + * @{ */ +#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */ +#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */ +/** @} */ + +/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific UUID counts + * @{ + */ +#define BLE_UUID_VS_COUNT_DEFAULT 10 /**< Default VS UUID count. */ +#define BLE_UUID_VS_COUNT_MAX 254 /**< Maximum VS UUID count. */ +/** @} */ + +/** @defgroup BLE_COMMON_CFG_DEFAULTS Configuration defaults. + * @{ + */ +#define BLE_CONN_CFG_TAG_DEFAULT 0 /**< Default configuration tag, SoftDevice default connection configuration. */ + +/** @} */ + +/** @} */ + +/** @addtogroup BLE_COMMON_STRUCTURES Structures + * @{ */ + +/**@brief User Memory Block. */ +typedef struct +{ + uint8_t *p_mem; /**< Pointer to the start of the user memory block. */ + uint16_t len; /**< Length in bytes of the user memory block. */ +} ble_user_mem_block_t; + +/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */ +typedef struct +{ + uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ +} ble_evt_user_mem_request_t; + +/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */ +typedef struct +{ + uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ + ble_user_mem_block_t mem_block; /**< User memory block */ +} ble_evt_user_mem_release_t; + +/**@brief Event structure for events not associated with a specific function module. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which this event occurred. */ + union + { + ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */ + ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */ + } params; /**< Event parameter union. */ +} ble_common_evt_t; + +/**@brief BLE Event header. */ +typedef struct +{ + uint16_t evt_id; /**< Value from a BLE__EVT series. */ + uint16_t evt_len; /**< Length in octets including this header. */ +} ble_evt_hdr_t; + +/**@brief Common BLE Event type, wrapping the module specific event reports. */ +typedef struct +{ + ble_evt_hdr_t header; /**< Event header. */ + union + { + ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ + ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ + ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ + ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ + } evt; /**< Event union. */ +} ble_evt_t; + + +/** + * @brief Version Information. + */ +typedef struct +{ + uint8_t version_number; /**< Link Layer Version number. See https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer for assigned values. */ + uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ + uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ +} ble_version_t; + +/** + * @brief Configuration parameters for the PA and LNA. + */ +typedef struct +{ + uint8_t enable :1; /**< Enable toggling for this amplifier */ + uint8_t active_high :1; /**< Set the pin to be active high */ + uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */ +} ble_pa_lna_cfg_t; + +/** + * @brief PA & LNA GPIO toggle configuration + * + * This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or + * a low noise amplifier. + * + * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided + * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * @note This feature is only supported for nRF52, on nRF51 @ref NRF_ERROR_NOT_SUPPORTED will always be returned. + * @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences + * and must be avoided by the application. + */ +typedef struct +{ + ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */ + ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */ + + uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */ + uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */ + uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */ +} ble_common_opt_pa_lna_t; + +/** + * @brief Configuration of extended BLE connection events. + * + * When enabled the SoftDevice will dynamically extend the connection event when possible. + * + * The connection event length is controlled by the connection configuration as set by @ref ble_gap_conn_cfg_t::event_length. + * The connection event can be extended if there is time to send another packet pair before the start of the next connection interval, + * and if there are no conflicts with other BLE roles requesting radio time. + * + * @note @ref sd_ble_opt_get is not supported for this option. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */ +} ble_common_opt_conn_evt_ext_t; + +/**@brief Option structure for common options. */ +typedef union +{ + ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */ + ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */ +} ble_common_opt_t; + +/**@brief Common BLE Option type, wrapping the module specific options. */ +typedef union +{ + ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */ + ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */ +} ble_opt_t; + +/**@brief BLE connection configuration type, wrapping the module specific configurations, set with + * @ref sd_ble_cfg_set. + * + * @note Connection configurations don't have to be set. + * In the case that no configurations has been set, or fewer connection configurations has been set than enabled connections, + * the default connection configuration will be automatically added for the remaining connections. + * When creating connections with the default configuration, @ref BLE_CONN_CFG_TAG_DEFAULT should be used in + * place of @ref ble_conn_cfg_t::conn_cfg_tag. See @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect()" + * + * @mscs + * @mmsc{@ref BLE_CONN_CFG} + * @endmscs + + */ +typedef struct +{ + uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect() + calls to select this configuration when creating a connection. + Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */ + union { + ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */ + ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */ + ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS this connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */ + ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT this connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */ + } params; /**< Connection configuration union. */ +} ble_conn_cfg_t; + +/** + * @brief Configuration of Vendor Specific UUIDs, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_PARAM Too many UUIDs configured. + */ +typedef struct +{ + uint8_t vs_uuid_count; /**< Number of 128-bit Vendor Specific UUID bases to allocate memory for. + Default value is @ref BLE_UUID_VS_COUNT_DEFAULT. Maximum value is + @ref BLE_UUID_VS_COUNT_MAX. */ +} ble_common_cfg_vs_uuid_t; + +/**@brief Common BLE Configuration type, wrapping the common configurations. */ +typedef union +{ + ble_common_cfg_vs_uuid_t vs_uuid_cfg; /**< Vendor specific UUID configuration, cfg_id is @ref BLE_COMMON_CFG_VS_UUID. */ +} ble_common_cfg_t; + +/**@brief BLE Configuration type, wrapping the module specific configurations. */ +typedef union +{ + ble_conn_cfg_t conn_cfg; /**< Connection specific configurations, cfg_id in @ref BLE_CONN_CFGS series. */ + ble_common_cfg_t common_cfg; /**< Global common configurations, cfg_id in @ref BLE_COMMON_CFGS series. */ + ble_gap_cfg_t gap_cfg; /**< Global GAP configurations, cfg_id in @ref BLE_GAP_CFGS series. */ + ble_gatts_cfg_t gatts_cfg; /**< Global GATTS configuration, cfg_id in @ref BLE_GATTS_CFGS series. */ +} ble_cfg_t; + +/** @} */ + +/** @addtogroup BLE_COMMON_FUNCTIONS Functions + * @{ */ + +/**@brief Enable the BLE stack + * + * @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the + * application RAM region (APP_RAM_BASE). On return, this will + * contain the minimum start address of the application RAM region + * required by the SoftDevice for this configuration. + * + * @note The memory requirement for a specific configuration will not increase between SoftDevices + * with the same major version number. + * + * @note The value of *p_app_ram_base when the app has done no custom configuration of the + * SoftDevice, i.e. the app has not called @ref sd_ble_cfg_set before @ref sd_ble_enable, can + * be found in the release notes. + * + * @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located + * between 0x20000000 and APP_RAM_BASE-1 and the application's RAM region is located between + * APP_RAM_BASE and the start of the call stack. + * + * @details This call initializes the BLE stack, no BLE related function other than @ref + * sd_ble_cfg_set can be called before this one. + * + * @mscs + * @mmsc{@ref BLE_COMMON_ENABLE} + * @endmscs + * + * @retval ::NRF_SUCCESS The BLE stack has been initialized successfully. + * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by *p_app_ram_base is not + * large enough to fit this configuration's memory requirement. Check *p_app_ram_base + * and set the start address of the application RAM region accordingly. + */ +SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(uint32_t * p_app_ram_base)); + +/**@brief Add configurations for the BLE stack + * + * @param[in] cfg_id Config ID, see @ref BLE_CONN_CFGS, @ref BLE_COMMON_CFGS, @ref + * BLE_GAP_CFGS or @ref BLE_GATTS_CFGS. + * @param[in] p_cfg Pointer to a ble_cfg_t structure containing the configuration value. + * @param[in] app_ram_base The start address of the application RAM region (APP_RAM_BASE). + * See @ref sd_ble_enable for details about APP_RAM_BASE. + * + * @note The memory requirement for a specific configuration will not increase between SoftDevices + * with the same major version number. + * + * @note If a configuration is set more than once, the last one set is the one that takes effect on + * @ref sd_ble_enable. + * + * @note Any part of the BLE stack that is NOT configured with @ref sd_ble_cfg_set will have default + * configuration. + * + * @note @ref sd_ble_cfg_set may be called at any time when the SoftDevice is enabled (see @ref + * sd_softdevice_enable) while the BLE part of the SoftDevice is not enabled (see @ref + * sd_ble_enable). + * + * @note Error codes for the configurations are described in the configuration structs. + * + * @mscs + * @mmsc{@ref BLE_COMMON_ENABLE} + * @endmscs + * + * @retval ::NRF_SUCCESS The configuration has been added successfully. + * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid cfg_id supplied. + * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by app_ram_base is not + * large enough to fit this configuration's memory requirement. + */ +SVCALL(SD_BLE_CFG_SET, uint32_t, sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t app_ram_base)); + +/**@brief Get an event from the pending events queue. + * + * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. + * This buffer must be aligned to the extend defined by @ref BLE_EVT_PTR_ALIGNMENT. + * The buffer should be interpreted as a @ref ble_evt_t struct. + * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length. + * + * @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that + * an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt. + * The application is free to choose whether to call this function from thread mode (main context) or directly from the + * Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher + * priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) + * every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so + * could potentially leave events in the internal queue without the application being aware of this fact. + * + * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to + * be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event, + * @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size. + * The maximum possible event length is defined by @ref BLE_EVT_LEN_MAX. The application may also "peek" the event length + * by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return: + * + * \code + * uint16_t len; + * errcode = sd_ble_evt_get(NULL, &len); + * \endcode + * + * @mscs + * @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC} + * @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled. + * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer. + */ +SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len)); + + +/**@brief Add a Vendor Specific base UUID. + * + * @details This call enables the application to add a vendor specific base UUID to the BLE stack's table, for later + * use with all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t + * format when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code + * paths. This is accomplished by extending the grouping mechanism that the Bluetooth SIG standard base UUID uses + * for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to + * @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the UUID field + * in the same structure contains the 2 bytes at indexes 12 and 13. The number of possible 128-bit UUIDs available to + * the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, + * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. + * + * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by + * the 16-bit uuid field in @ref ble_uuid_t. + * + * @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in + * p_uuid_type along with an NRF_SUCCESS error code. + * + * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding + * bytes 12 and 13. + * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored. + * + * @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID. + * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid. + * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs. + */ +SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type)); + + +/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure. + * + * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared + * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add + * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index + * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. + * + * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE. + * + * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). + * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. + * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length. + * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs. + */ +SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid)); + + +/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit). + * + * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed. + * + * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. + * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). + * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. + * + * @retval ::NRF_SUCCESS Successfully encoded into the buffer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type. + */ +SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le)); + + +/**@brief Get Version Information. + * + * @details This call allows the application to get the BLE stack version information. + * + * @param[out] p_version Pointer to a ble_version_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Version information stored successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure). + */ +SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version)); + + +/**@brief Provide a user memory block. + * + * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_block Pointer to a user memory block structure or NULL if memory is managed by the application. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully queued a response to the peer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending. + */ +SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)); + +/**@brief Set a BLE option. + * + * @details This call allows the application to set the value of an option. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @endmscs + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. + * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value. + * + * @retval ::NRF_SUCCESS Option set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. + */ +SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt)); + + +/**@brief Get a BLE option. + * + * @details This call allows the application to retrieve the value of an option. + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. + * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Option retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. + * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported. + * + */ +SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)); + +/** @} */ +#ifdef __cplusplus +} +#endif +#endif /* BLE_H__ */ + +/** + @} + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_err.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_err.h new file mode 100644 index 0000000000000000000000000000000000000000..f3377856bd1e975172db3a6cc71359fa5525e009 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_err.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_COMMON + @{ + @addtogroup nrf_error + @{ + @ingroup BLE_COMMON + @} + + @defgroup ble_err General error codes + @{ + + @brief General error code definitions for the BLE API. + + @ingroup BLE_COMMON +*/ +#ifndef NRF_BLE_ERR_H__ +#define NRF_BLE_ERR_H__ + +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* @defgroup BLE_ERRORS Error Codes + * @{ */ +#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */ +#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */ +#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */ +#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x004) /**< Invalid role. */ +/** @} */ + + +/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges + * @brief Assignment of subranges for module specific error codes. + * @note For specific error codes, see ble_.h or ble_error_.h. + * @{ */ +#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */ +#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */ +#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */ +#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */ +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif + + +/** + @} + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_gap.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_gap.h new file mode 100644 index 0000000000000000000000000000000000000000..3395cc2c5748a9dd219a9357302fc8616ec0f6b8 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_gap.h @@ -0,0 +1,2109 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_GAP Generic Access Profile (GAP) + @{ + @brief Definitions and prototypes for the GAP interface. + */ + +#ifndef BLE_GAP_H__ +#define BLE_GAP_H__ + + +#include "ble_types.h" +#include "ble_ranges.h" +#include "nrf_svc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations + * @{ */ + +/**@brief GAP API SVC numbers. + */ +enum BLE_GAP_SVCS +{ + SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */ + SD_BLE_GAP_ADDR_GET, /**< Get own Bluetooth Address. */ + SD_BLE_GAP_WHITELIST_SET, /**< Set active whitelist. */ + SD_BLE_GAP_DEVICE_IDENTITIES_SET, /**< Set device identity list. */ + SD_BLE_GAP_PRIVACY_SET, /**< Set Privacy settings*/ + SD_BLE_GAP_PRIVACY_GET, /**< Get Privacy settings*/ + SD_BLE_GAP_ADV_DATA_SET, /**< Set Advertising Data. */ + SD_BLE_GAP_ADV_START, /**< Start Advertising. */ + SD_BLE_GAP_ADV_STOP, /**< Stop Advertising. */ + SD_BLE_GAP_CONN_PARAM_UPDATE, /**< Connection Parameter Update. */ + SD_BLE_GAP_DISCONNECT, /**< Disconnect. */ + SD_BLE_GAP_TX_POWER_SET, /**< Set TX Power. */ + SD_BLE_GAP_APPEARANCE_SET, /**< Set Appearance. */ + SD_BLE_GAP_APPEARANCE_GET, /**< Get Appearance. */ + SD_BLE_GAP_PPCP_SET, /**< Set PPCP. */ + SD_BLE_GAP_PPCP_GET, /**< Get PPCP. */ + SD_BLE_GAP_DEVICE_NAME_SET, /**< Set Device Name. */ + SD_BLE_GAP_DEVICE_NAME_GET, /**< Get Device Name. */ + SD_BLE_GAP_AUTHENTICATE, /**< Initiate Pairing/Bonding. */ + SD_BLE_GAP_SEC_PARAMS_REPLY, /**< Reply with Security Parameters. */ + SD_BLE_GAP_AUTH_KEY_REPLY, /**< Reply with an authentication key. */ + SD_BLE_GAP_LESC_DHKEY_REPLY, /**< Reply with an LE Secure Connections DHKey. */ + SD_BLE_GAP_KEYPRESS_NOTIFY, /**< Notify of a keypress during an authentication procedure. */ + SD_BLE_GAP_LESC_OOB_DATA_GET, /**< Get the local LE Secure Connections OOB data. */ + SD_BLE_GAP_LESC_OOB_DATA_SET, /**< Set the remote LE Secure Connections OOB data. */ + SD_BLE_GAP_ENCRYPT, /**< Initiate encryption procedure. */ + SD_BLE_GAP_SEC_INFO_REPLY, /**< Reply with Security Information. */ + SD_BLE_GAP_CONN_SEC_GET, /**< Obtain connection security level. */ + SD_BLE_GAP_RSSI_START, /**< Start reporting of changes in RSSI. */ + SD_BLE_GAP_RSSI_STOP, /**< Stop reporting of changes in RSSI. */ + SD_BLE_GAP_SCAN_START, /**< Start Scanning. */ + SD_BLE_GAP_SCAN_STOP, /**< Stop Scanning. */ + SD_BLE_GAP_CONNECT, /**< Connect. */ + SD_BLE_GAP_CONNECT_CANCEL, /**< Cancel ongoing connection procedure. */ + SD_BLE_GAP_RSSI_GET, /**< Get the last RSSI sample. */ + SD_BLE_GAP_DATA_LENGTH_UPDATE, /**< Initiate or respond to a Data Length Update Procedure. */ +}; + +/**@brief GAP Event IDs. + * IDs that uniquely identify an event coming from the stack to the application. + */ +enum BLE_GAP_EVTS +{ + BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connection established. \n See @ref ble_gap_evt_connected_t. */ + BLE_GAP_EVT_DISCONNECTED, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */ + BLE_GAP_EVT_SEC_PARAMS_REQUEST, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. \n See @ref ble_gap_evt_sec_params_request_t. */ + BLE_GAP_EVT_SEC_INFO_REQUEST, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. \n See @ref ble_gap_evt_sec_info_request_t. */ + BLE_GAP_EVT_PASSKEY_DISPLAY, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */ + BLE_GAP_EVT_KEY_PRESSED, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */ + BLE_GAP_EVT_AUTH_KEY_REQUEST, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_auth_key_request_t. */ + BLE_GAP_EVT_LESC_DHKEY_REQUEST, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */ + BLE_GAP_EVT_AUTH_STATUS, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */ + BLE_GAP_EVT_CONN_SEC_UPDATE, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */ + BLE_GAP_EVT_TIMEOUT, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */ + BLE_GAP_EVT_RSSI_CHANGED, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */ + BLE_GAP_EVT_ADV_REPORT, /**< Advertising report. \n See @ref ble_gap_evt_adv_report_t. */ + BLE_GAP_EVT_SEC_REQUEST, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, /**< Connection Parameter Update Request. \n Reply with @ref sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */ + BLE_GAP_EVT_SCAN_REQ_REPORT, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */ + BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST, /**< Data Length Update request. \n Reply with @ref sd_ble_gap_data_length_update.\n See @ref ble_gap_evt_data_length_update_request_t. */ + BLE_GAP_EVT_DATA_LENGTH_UPDATE, /**< LL Data Channel PDU payload length updated. \n See @ref ble_gap_evt_data_length_update_t. */ +}; + +/**@brief GAP Option IDs. + * IDs that uniquely identify a GAP option. + */ +enum BLE_GAP_OPTS +{ + BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */ + BLE_GAP_OPT_LOCAL_CONN_LATENCY, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */ + BLE_GAP_OPT_PASSKEY, /**< Set passkey. @ref ble_gap_opt_passkey_t */ + BLE_GAP_OPT_SCAN_REQ_REPORT, /**< Scan request report. @ref ble_gap_opt_scan_req_report_t */ + BLE_GAP_OPT_COMPAT_MODE_1, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_1_t */ + BLE_GAP_OPT_COMPAT_MODE_2, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_2_t */ + BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */ + BLE_GAP_OPT_SLAVE_LATENCY_DISABLE, /**< Disable slave latency. @ref ble_gap_opt_slave_latency_disable_t */ +}; + +/**@brief GAP Configuration IDs. + * + * IDs that uniquely identify a GAP configuration. + */ +enum BLE_GAP_CFGS +{ + BLE_GAP_CFG_ROLE_COUNT = BLE_GAP_CFG_BASE, /**< Role count configuration. */ + BLE_GAP_CFG_DEVICE_NAME, /**< Device name configuration. */ +}; + +/** @} */ + +/**@addtogroup BLE_GAP_DEFINES Defines + * @{ */ + +/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP + * @{ */ +#define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */ +#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */ +#define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */ +#define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to modify the whitelist while already in use by another operation. */ +#define BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE (NRF_GAP_ERR_BASE + 0x004) /**< Attempt to modify the device identity list while already in use by another operation. */ +#define BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE (NRF_GAP_ERR_BASE + 0x005) /**< The device identity list contains entries with duplicate identity addresses. */ +/**@} */ + + +/**@defgroup BLE_GAP_ROLES GAP Roles + * @note Not explicitly used in peripheral API, but will be relevant for central API. + * @{ */ +#define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */ +#define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */ +#define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */ +/**@} */ + + +/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources + * @{ */ +#define BLE_GAP_TIMEOUT_SRC_ADVERTISING 0x00 /**< Advertising timeout. */ +#define BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST 0x01 /**< Security request timeout. */ +#define BLE_GAP_TIMEOUT_SRC_SCAN 0x02 /**< Scanning timeout. */ +#define BLE_GAP_TIMEOUT_SRC_CONN 0x03 /**< Connection timeout. */ +#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x04 /**< Authenticated payload timeout. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types + * @{ */ +#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Random private resolvable address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Random private non-resolvable address. */ +/**@} */ + + +/**@brief The default interval in seconds at which a private address is refreshed. */ +#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (900) /* 15 minutes. */ +/**@brief The maximum interval in seconds at which a private address can be refreshed. */ +#define BLE_GAP_MAX_PRIVATE_ADDR_CYCLE_INTERVAL_S (41400) /* 11 hours 30 minutes. */ + + +/** @brief BLE address length. */ +#define BLE_GAP_ADDR_LEN (6) + + +/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes + * @{ */ +#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */ +#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */ +/**@} */ + + +/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format + * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm + * @{ */ +#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */ +#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */ +#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */ +#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */ +#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */ +#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */ +#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */ +#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */ +#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */ +#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */ +#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */ +#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */ +#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */ +#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */ +#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */ +#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */ +#define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE 0x22 /**< LE Secure Connections Confirmation Value */ +#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 /**< LE Secure Connections Random Value */ +#define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */ +#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */ +#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags + * @{ */ +#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */ +#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */ +#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */ +#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */ +#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */ +#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */ +#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min + * @{ */ +#define BLE_GAP_ADV_INTERVAL_MIN 0x0020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */ +#define BLE_GAP_ADV_NONCON_INTERVAL_MIN 0x00A0 /**< Minimum Advertising interval in 625 us units for non connectable mode, i.e. 100 ms. */ +#define BLE_GAP_ADV_INTERVAL_MAX 0x4000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s. */ + /**@} */ + + +/**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min + * @{ */ +#define BLE_GAP_SCAN_INTERVAL_MIN 0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */ +#define BLE_GAP_SCAN_INTERVAL_MAX 0x4000 /**< Maximum Scan interval in 625 us units, i.e. 10.24 s. */ + /** @} */ + + +/**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min + * @{ */ +#define BLE_GAP_SCAN_WINDOW_MIN 0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */ +#define BLE_GAP_SCAN_WINDOW_MAX 0x4000 /**< Maximum Scan window in 625 us units, i.e. 10.24 s. */ + /** @} */ + + +/**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min + * @{ */ +#define BLE_GAP_SCAN_TIMEOUT_MIN 0x0001 /**< Minimum Scan timeout in seconds. */ +#define BLE_GAP_SCAN_TIMEOUT_MAX 0xFFFF /**< Maximum Scan timeout in seconds. */ + /** @} */ + + +/**@brief Maximum size of advertising data in octets. */ +#define BLE_GAP_ADV_MAX_SIZE (31) + + +/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types + * @{ */ +#define BLE_GAP_ADV_TYPE_ADV_IND 0x00 /**< Connectable undirected. */ +#define BLE_GAP_ADV_TYPE_ADV_DIRECT_IND 0x01 /**< Connectable directed. */ +#define BLE_GAP_ADV_TYPE_ADV_SCAN_IND 0x02 /**< Scannable undirected. */ +#define BLE_GAP_ADV_TYPE_ADV_NONCONN_IND 0x03 /**< Non connectable undirected. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies + * @{ */ +#define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */ +#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */ +#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */ +#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values + * @{ */ +#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX (180) /**< Maximum advertising time in limited discoverable mode (TGAP(lim_adv_timeout) = 180 s). */ +#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED (0) /**< Unlimited advertising in general discoverable mode. */ +/**@} */ + + +/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes + * @{ */ +#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */ +#define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */ +#define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */ +/**@} */ + + +/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities + * @{ */ +#define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */ +#define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */ +#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */ +#define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */ +#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */ +/**@} */ + + +/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types + * @{ */ +#define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */ +#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */ +#define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */ +/**@} */ + + +/**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types + * @{ */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */ +/**@} */ + + +/**@defgroup BLE_GAP_SEC_STATUS GAP Security status + * @{ */ +#define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */ +#define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */ +#define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN 0x03 /**< Reserved for Future Use range #1 begin. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE1_END 0x80 /**< Reserved for Future Use range #1 end. */ +#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user canceled or other). */ +#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */ +#define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */ +#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */ +#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */ +#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */ +#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */ +#define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */ +#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */ +#define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */ +#define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */ +#define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */ +#define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */ +#define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */ +/**@} */ + + +/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources + * @{ */ +#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */ +#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */ +/**@} */ + + +/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits + * @{ */ +#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ +#define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */ +/**@} */ + + +/**@defgroup BLE_GAP_DEVNAME GAP device name defines. + * @{ */ +#define BLE_GAP_DEVNAME_DEFAULT "nRF5x" /**< Default device name value. */ +#define BLE_GAP_DEVNAME_DEFAULT_LEN 31 /**< Default number of octets in device name. */ +#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximum number of octets in device name. */ +/**@} */ + + +/**@brief Disable RSSI events for connections */ +#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF + + +/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters + * + * See @ref ble_gap_conn_sec_mode_t. + * @{ */ +/**@brief Set sec_mode pointed to by ptr to have no access rights.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0) +/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0) +/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0) +/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0) +/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0) +/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0) +/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0) +/**@} */ + + +/**@brief GAP Security Random Number Length. */ +#define BLE_GAP_SEC_RAND_LEN 8 + + +/**@brief GAP Security Key Length. */ +#define BLE_GAP_SEC_KEY_LEN 16 + + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */ +#define BLE_GAP_LESC_P256_PK_LEN 64 + + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */ +#define BLE_GAP_LESC_DHKEY_LEN 32 + + +/**@brief GAP Passkey Length. */ +#define BLE_GAP_PASSKEY_LEN 6 + + +/**@brief Maximum amount of addresses in the whitelist. */ +#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8) + + +/**@brief Maximum amount of identities in the device identities list. */ +#define BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT (8) + + +/**@brief Default connection count for a configuration. */ +#define BLE_GAP_CONN_COUNT_DEFAULT (1) + + +/**@defgroup BLE_GAP_EVENT_LENGTH GAP event length defines. + * @{ */ +#define BLE_GAP_EVENT_LENGTH_MIN (2) /**< Minimum event length, in 1.25 ms units. */ +#define BLE_GAP_EVENT_LENGTH_DEFAULT (3) /**< Default event length, in 1.25 ms units. */ +/**@} */ + + +/**@defgroup BLE_GAP_ROLE_COUNT GAP concurrent connection count defines. + * @{ */ +#define BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT (1) /**< Default maximum number of connections concurrently acting as peripherals. */ +#define BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT (3) /**< Default maximum number of connections concurrently acting as centrals. */ +#define BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT (1) /**< Default number of SMP instances shared between all connections acting as centrals. */ +#define BLE_GAP_ROLE_COUNT_COMBINED_MAX (20) /**< Maximum supported number of concurrent connections in the peripheral and central roles combined. */ +/**@} */ + + + + +/**@brief Automatic data length parameter. */ +#define BLE_GAP_DATA_LENGTH_AUTO 0 + + +/**@defgroup GAP_SEC_MODES GAP Security Modes + * @{ */ +#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */ +/**@} */ +/** @} */ + + +/**@addtogroup BLE_GAP_STRUCTURES Structures + * @{ */ + +/**@brief Bluetooth Low Energy address. */ +typedef struct +{ + uint8_t addr_id_peer : 1; /**< Only valid for peer addresses. + Reference to peer in device identities list (as set with @ref sd_ble_gap_device_identities_set) when peer is using privacy. */ + uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */ + uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. */ +} ble_gap_addr_t; + + +/**@brief GAP connection parameters. + * + * @note When ble_conn_params_t is received in an event, both min_conn_interval and + * max_conn_interval will be equal to the connection interval set by the central. + * + * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies: + * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval + * that corresponds to the following Bluetooth Spec requirement: + * The Supervision_Timeout in milliseconds shall be larger than + * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds. + */ +typedef struct +{ + uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ +} ble_gap_conn_params_t; + + +/**@brief GAP connection security modes. + * + * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n + * Security Mode 1 Level 1: No security is needed (aka open link).\n + * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n + * Security Mode 1 Level 3: MITM protected encrypted link required.\n + * Security Mode 1 Level 4: LESC MITM protected encrypted link required.\n + * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n + * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n + */ +typedef struct +{ + uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */ + uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */ + +} ble_gap_conn_sec_mode_t; + + +/**@brief GAP connection security status.*/ +typedef struct +{ + ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/ + uint8_t encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */ +} ble_gap_conn_sec_t; + +/**@brief Identity Resolving Key. */ +typedef struct +{ + uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */ +} ble_gap_irk_t; + + +/**@brief Channel mask for RF channels used in advertising. */ +typedef struct +{ + uint8_t ch_37_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 37 */ + uint8_t ch_38_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 38 */ + uint8_t ch_39_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 39 */ +} ble_gap_adv_ch_mask_t; + + +/**@brief GAP advertising parameters. */ +typedef struct +{ + uint8_t type; /**< See @ref BLE_GAP_ADV_TYPES. */ + ble_gap_addr_t const *p_peer_addr; /**< Address of a known peer. + - When privacy is enabled and the local device use @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE addresses, the device identity list is searched for a matching + entry. If the local IRK for that device identity is set, the local IRK for that device will be used to generate the advertiser address field in the advertise packet. + - If type is @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this must be set to the targeted initiator. If the initiator is in the device identity list, + the peer IRK for that device will be used to generate the initiator address field in the ADV_DIRECT_IND packet. */ + uint8_t fp; /**< Filter Policy, see @ref BLE_GAP_ADV_FILTER_POLICIES. */ + uint16_t interval; /**< Advertising interval between 0x0020 and 0x4000 in 0.625 ms units (20 ms to 10.24 s), see @ref BLE_GAP_ADV_INTERVALS. + - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for high duty cycle directed advertising. + - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, set @ref BLE_GAP_ADV_INTERVAL_MIN <= interval <= @ref BLE_GAP_ADV_INTERVAL_MAX for low duty cycle advertising.*/ + uint16_t timeout; /**< Advertising timeout between 0x0001 and 0x3FFF in seconds, 0x0000 disables timeout. See also @ref BLE_GAP_ADV_TIMEOUT_VALUES. If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for High duty cycle directed advertising. */ + ble_gap_adv_ch_mask_t channel_mask; /**< Advertising channel mask. See @ref ble_gap_adv_ch_mask_t. */ +} ble_gap_adv_params_t; + + +/**@brief GAP scanning parameters. */ +typedef struct +{ + uint8_t active : 1; /**< If 1, perform active scanning (scan requests). */ + uint8_t use_whitelist : 1; /**< If 1, filter advertisers using current active whitelist. */ + uint8_t adv_dir_report : 1; /**< If 1, also report directed advertisements where the initiator field is set to a private resolvable address, + even if the address did not resolve to an entry in the device identity list. A report will be generated + even if the peer is not in the whitelist. */ + uint16_t interval; /**< Scan interval between 0x0004 and 0x4000 in 0.625 ms units (2.5 ms to 10.24 s). */ + uint16_t window; /**< Scan window between 0x0004 and 0x4000 in 0.625 ms units (2.5 ms to 10.24 s). */ + uint16_t timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ +} ble_gap_scan_params_t; + + +/**@brief Device Privacy. + * + * The privacy feature provides a way for the device to avoid being tracked over a period of time. + * The privacy feature, when enabled, hides the local device identity and replaces it with a private address + * that is automatically refreshed at a specified interval. + * + * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK). + * With this key, a device can generate a random private address that can only be recognized by peers in possession of that key, + * and devices can establish connections without revealing their real identities. + * + * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all + * bonding procedures performed after @ref sd_ble_gap_privacy_set returns. + * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is called. + */ +typedef struct +{ + uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */ + uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */ + uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */ + ble_gap_irk_t *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used. + When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored. + By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */ +} ble_gap_privacy_params_t; + + +/** @brief Keys that can be exchanged during a bonding procedure. */ +typedef struct +{ + uint8_t enc : 1; /**< Long Term Key and Master Identification. */ + uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */ + uint8_t sign : 1; /**< Connection Signature Resolving Key. */ + uint8_t link : 1; /**< Derive the Link Key from the LTK. */ +} ble_gap_sec_kdist_t; + + +/**@brief GAP security parameters. */ +typedef struct +{ + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Enable Man In The Middle protection. */ + uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */ + uint8_t keypress : 1; /**< Enable generation of keypress notifications. */ + uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ + uint8_t oob : 1; /**< The OOB data flag. + - In LE legacy pairing, this flag is set if a device has out of band authentication data. + The OOB method is used if both of the devices have out of band authentication data. + - In LE Secure Connections pairing, this flag is set if a device has the peer device's out of band authentication data. + The OOB method is used if at least one device has the peer device's OOB data available. */ + uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */ + uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */ + ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */ + ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */ +} ble_gap_sec_params_t; + + +/**@brief GAP Encryption Information. */ +typedef struct +{ + uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */ + uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */ + uint8_t auth : 1; /**< Authenticated Key. */ + uint8_t ltk_len : 6; /**< LTK length in octets. */ +} ble_gap_enc_info_t; + + +/**@brief GAP Master Identification. */ +typedef struct +{ + uint16_t ediv; /**< Encrypted Diversifier. */ + uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */ +} ble_gap_master_id_t; + + +/**@brief GAP Signing Information. */ +typedef struct +{ + uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */ +} ble_gap_sign_info_t; + + +/**@brief GAP LE Secure Connections P-256 Public Key. */ +typedef struct +{ + uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the standard SMP protocol format: {X,Y} both in little-endian. */ +} ble_gap_lesc_p256_pk_t; + + +/**@brief GAP LE Secure Connections DHKey. */ +typedef struct +{ + uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */ +} ble_gap_lesc_dhkey_t; + + +/**@brief GAP LE Secure Connections OOB data. */ +typedef struct +{ + ble_gap_addr_t addr; /**< Bluetooth address of the device. */ + uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */ + uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */ +} ble_gap_lesc_oob_data_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */ +typedef struct +{ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ + uint8_t role; /**< BLE role for this connection, see @ref BLE_GAP_ROLES */ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ +} ble_gap_evt_connected_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */ +typedef struct +{ + uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */ +} ble_gap_evt_disconnected_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */ +typedef struct +{ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ +} ble_gap_evt_conn_param_update_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */ +typedef struct +{ + ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */ +} ble_gap_evt_sec_params_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */ +typedef struct +{ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ + ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */ + uint8_t enc_info : 1; /**< If 1, Encryption Information required. */ + uint8_t id_info : 1; /**< If 1, Identity Information required. */ + uint8_t sign_info : 1; /**< If 1, Signing Information required. */ +} ble_gap_evt_sec_info_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */ +typedef struct +{ + uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ + uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply + with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or + @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */ +} ble_gap_evt_passkey_display_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */ +typedef struct +{ + uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */ +} ble_gap_evt_key_pressed_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */ +typedef struct +{ + uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */ +} ble_gap_evt_auth_key_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */ +typedef struct +{ + ble_gap_lesc_p256_pk_t *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory + inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */ + uint8_t oobd_req :1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the procedure. */ +} ble_gap_evt_lesc_dhkey_request_t; + + +/**@brief Security levels supported. + * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1. +*/ +typedef struct +{ + uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */ + uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */ + uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */ + uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */ +} ble_gap_sec_levels_t; + + +/**@brief Encryption Key. */ +typedef struct +{ + ble_gap_enc_info_t enc_info; /**< Encryption Information. */ + ble_gap_master_id_t master_id; /**< Master Identification. */ +} ble_gap_enc_key_t; + + +/**@brief Identity Key. */ +typedef struct +{ + ble_gap_irk_t id_info; /**< Identity Resolving Key. */ + ble_gap_addr_t id_addr_info; /**< Identity Address. */ +} ble_gap_id_key_t; + + +/**@brief Security Keys. */ +typedef struct +{ + ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ + ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ + ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ + ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the value defined + in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */ +} ble_gap_sec_keys_t; + + +/**@brief Security key set for both local and peer keys. */ +typedef struct +{ + ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be generated locally and will always be stored if bonding. */ + ble_gap_sec_keys_t keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */ +} ble_gap_sec_keyset_t; + + +/**@brief Data Length Update Procedure parameters. */ +typedef struct +{ + uint16_t max_tx_octets; /**< Maximum number of payload octets that a Controller supports for transmission of a single Link Layer Data Channel PDU. */ + uint16_t max_rx_octets; /**< Maximum number of payload octets that a Controller supports for reception of a single Link Layer Data Channel PDU. */ + uint16_t max_tx_time_us; /**< Maximum time, in microseconds, that a Controller supports for transmission of a single Link Layer Data Channel PDU. */ + uint16_t max_rx_time_us; /**< Maximum time, in microseconds, that a Controller supports for reception of a single Link Layer Data Channel PDU. */ +} ble_gap_data_length_params_t; + + +/**@brief Data Length Update Procedure local limitation. */ +typedef struct +{ + uint16_t tx_payload_limited_octets; /**< If > 0, the requested TX packet length is too long by this many octets. */ + uint16_t rx_payload_limited_octets; /**< If > 0, the requested RX packet length is too long by this many octets. */ + uint16_t tx_rx_time_limited_us; /**< If > 0, the requested combination of TX and RX packet lengths is too long by this many microseconds. */ +} ble_gap_data_length_limitation_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */ +typedef struct +{ + uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */ + uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ + uint8_t bonded : 1; /**< Procedure resulted in a bond. */ + ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */ + ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */ + ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */ + ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */ +} ble_gap_evt_auth_status_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */ +typedef struct +{ + ble_gap_conn_sec_t conn_sec; /**< Connection security level. */ +} ble_gap_evt_conn_sec_update_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */ +typedef struct +{ + uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */ +} ble_gap_evt_timeout_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */ +typedef struct +{ + int8_t rssi; /**< Received Signal Strength Indication in dBm. */ +} ble_gap_evt_rssi_changed_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT. */ +typedef struct +{ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ + ble_gap_addr_t direct_addr; /**< Set when the scanner is unable to resolve the private resolvable address of the initiator + field of a directed advertisement packet and the scanner has been enabled to report this in @ref ble_gap_scan_params_t::adv_dir_report. */ + int8_t rssi; /**< Received Signal Strength Indication in dBm. */ + uint8_t scan_rsp : 1; /**< If 1, the report corresponds to a scan response and the type field may be ignored. */ + uint8_t type : 2; /**< See @ref BLE_GAP_ADV_TYPES. Only valid if the scan_rsp field is 0. */ + uint8_t dlen : 5; /**< Advertising or scan response data length. */ + uint8_t data[BLE_GAP_ADV_MAX_SIZE]; /**< Advertising or scan response data. */ +} ble_gap_evt_adv_report_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */ +typedef struct +{ + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Man In The Middle protection requested. */ + uint8_t lesc : 1; /**< LE Secure Connections requested. */ + uint8_t keypress : 1; /**< Generation of keypress notifications requested. */ +} ble_gap_evt_sec_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST. */ +typedef struct +{ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ +} ble_gap_evt_conn_param_update_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */ +typedef struct +{ + int8_t rssi; /**< Received Signal Strength Indication in dBm. */ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ +} ble_gap_evt_scan_req_report_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST. */ +typedef struct +{ + ble_gap_data_length_params_t peer_params; /**< Peer data length parameters. */ +} ble_gap_evt_data_length_update_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE. */ +typedef struct +{ + ble_gap_data_length_params_t effective_params; /**< The effective data length parameters. */ +} ble_gap_evt_data_length_update_t; + + +/**@brief GAP event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which event occurred. */ + union /**< union alternative identified by evt_id in enclosing struct. */ + { + ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */ + ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */ + ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */ + ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */ + ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */ + ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */ + ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */ + ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */ + ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */ + ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */ + ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */ + ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */ + ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event parameters. */ + ble_gap_evt_adv_report_t adv_report; /**< Advertising Report Event Parameters. */ + ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */ + ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */ + ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report parameters. */ + ble_gap_evt_data_length_update_request_t data_length_update_request; /**< Data Length Update Request Event Parameters. */ + ble_gap_evt_data_length_update_t data_length_update; /**< Data Length Update Event Parameters. */ + } params; /**< Event Parameters. */ +} ble_gap_evt_t; + + +/** + * @brief BLE GAP connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_CONN_COUNT The connection count for the connection configurations is zero. + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - The sum of conn_count for all connection configurations combined exceeds UINT8_MAX. + * - The event length is smaller than @ref BLE_GAP_EVENT_LENGTH_MIN. + */ +typedef struct +{ + uint8_t conn_count; /**< The number of concurrent connections the application can create with this configuration. + The default and minimum value is @ref BLE_GAP_CONN_COUNT_DEFAULT. */ + uint16_t event_length; /**< The time set aside for this connection on every connection interval in 1.25 ms units. + The default value is @ref BLE_GAP_EVENT_LENGTH_DEFAULT, the minimum value is @ref BLE_GAP_EVENT_LENGTH_MIN. + The event length and the connection interval are the primary parameters + for setting the throughput of a connection. + See the SoftDevice Specification for details on throughput. */ +} ble_gap_conn_cfg_t; + + +/** + * @brief Configuration of maximum concurrent connections in the different connected roles, set with + * @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_CONN_COUNT The sum of periph_role_count and central_role_count is too + * large. The maximum supported sum of concurrent connections is + * @ref BLE_GAP_ROLE_COUNT_COMBINED_MAX. + * @retval ::NRF_ERROR_INVALID_PARAM central_sec_count is larger than central_role_count. + */ +typedef struct +{ + uint8_t periph_role_count; /**< Maximum number of connections concurrently acting as a peripheral. Default value is @ref BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT. */ + uint8_t central_role_count; /**< Maximum number of connections concurrently acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT. */ + uint8_t central_sec_count; /**< Number of SMP instances shared between all connections acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT. */ +} ble_gap_cfg_role_count_t; + + +/** + * @brief Device name and its properties, set with @ref sd_ble_cfg_set. + * + * @note If the device name is not configured, the default device name will be @ref + * BLE_GAP_DEVNAME_DEFAULT, the maximum device name length will be @ref + * BLE_GAP_DEVNAME_DEFAULT_LEN, vloc will be set to @ref BLE_GATTS_VLOC_STACK and the device name + * will have no write access. + * + * @note If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK, + * the attribute table size must be increased to have room for the longer device name (see + * @ref sd_ble_cfg_set and @ref ble_gatts_cfg_attr_tab_size_t). + * + * @note If vloc is @ref BLE_GATTS_VLOC_STACK : + * - p_value must point to non-volatile memory (flash) or be NULL. + * - If p_value is NULL, the device name will initially be empty. + * + * @note If vloc is @ref BLE_GATTS_VLOC_USER : + * - p_value cannot be NULL. + * - If the device name is writable, p_value must point to volatile memory (RAM). + * + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - Invalid device name location (vloc). + * - Invalid device name security mode. + * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: + * - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN). + * - The device name length is too long for the given Attribute Table. + * @retval ::NRF_ERROR_NOT_SUPPORTED Device name security mode is not supported. + */ +typedef struct +{ + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ + uint8_t vloc:2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ + uint8_t *p_value; /**< Pointer to where the value (device name) is stored or will be stored. */ + uint16_t current_len; /**< Current length in bytes of the memory pointed to by p_value.*/ + uint16_t max_len; /**< Maximum length in bytes of the memory pointed to by p_value.*/ +} ble_gap_cfg_device_name_t; + + +/**@brief Configuration structure for GAP configurations. */ +typedef union +{ + ble_gap_cfg_role_count_t role_count_cfg; /**< Role count configuration, cfg_id is @ref BLE_GAP_CFG_ROLE_COUNT. */ + ble_gap_cfg_device_name_t device_name_cfg; /**< Device name configuration, cfg_id is @ref BLE_GAP_CFG_DEVICE_NAME. */ +} ble_gap_cfg_t; + + +/**@brief Channel Map option. + * Used with @ref sd_ble_opt_get to get the current channel map + * or @ref sd_ble_opt_set to set a new channel map. When setting the + * channel map, it applies to all current and future connections. When getting the + * current channel map, it applies to a single connection and the connection handle + * must be supplied. + * + * @note Setting the channel map may take some time, depending on connection parameters. + * The time taken may be different for each connection and the get operation will + * return the previous channel map until the new one has taken effect. + * + * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed. + * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46. + * + * @retval ::NRF_SUCCESS Get or set successful. + * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get. + * @retval ::NRF_ERROR_NOT_SUPPORTED Returned by sd_ble_opt_set in peripheral-only SoftDevices. + * + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle (only applicable for get) */ + uint8_t ch_map[5]; /**< Channel Map (37-bit). */ +} ble_gap_opt_ch_map_t; + + +/**@brief Local connection latency option. + * + * Local connection latency is a feature which enables the slave to improve + * current consumption by ignoring the slave latency set by the peer. The + * local connection latency can only be set to a multiple of the slave latency, + * and cannot be longer than half of the supervision timeout. + * + * Used with @ref sd_ble_opt_set to set the local connection latency. The + * @ref sd_ble_opt_get is not supported for this option, but the actual + * local connection latency (unless set to NULL) is set as a return parameter + * when setting the option. + * + * @note The latency set will be truncated down to the closest slave latency event + * multiple, or the nearest multiple before half of the supervision timeout. + * + * @note The local connection latency is disabled by default, and needs to be enabled for new + * connections and whenever the connection is updated. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint16_t requested_latency; /**< Requested local connection latency. */ + uint16_t * p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */ +} ble_gap_opt_local_conn_latency_t; + +/**@brief Disable slave latency + * + * Used with @ref sd_ble_opt_set to temporarily disable slave latency of a peripheral connection (see @ref ble_gap_conn_params_t::slave_latency). And to re-enable it again. + * When disabled, the peripheral will ignore the slave_latency set by the central. + * + * @note Shall only be called on peripheral links. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint8_t disable : 1; /**< Set to 1 to disable slave latency. Set to 0 enable it again.*/ +} ble_gap_opt_slave_latency_disable_t; + +/**@brief Passkey Option. + * + * Structure containing the passkey to be used during pairing. This can be used with @ref + * sd_ble_opt_set to make the SoftDevice use a preprogrammed passkey for authentication + * instead of generating a random one. + * + * @note Repeated pairing attempts using the same preprogrammed passkey makes pairing vulnerable to MITM attacks. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * + */ +typedef struct +{ + uint8_t const * p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/ +} ble_gap_opt_passkey_t; + + +/**@brief Scan request report option. + * + * This can be used with @ref sd_ble_opt_set to make the SoftDevice send + * @ref BLE_GAP_EVT_SCAN_REQ_REPORT events. + * + * @note Due to the limited space reserved for scan request report events, + * not all received scan requests will be reported. + * + * @note If whitelisting is used, only whitelisted requests are reported. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_STATE When advertising is ongoing while the option is set. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable scan request reports. */ +} ble_gap_opt_scan_req_report_t; + +/**@brief Compatibility mode 1 option. + * + * This can be used with @ref sd_ble_opt_set to enable and disable + * compatibility mode 1. Compatibility mode 1 is disabled by default. + * + * @note Compatibility mode 1 enables interoperability with devices that do not support + * a value of 0 for the WinOffset parameter in the Link Layer CONNECT_REQ packet. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable compatibility mode 1.*/ +} ble_gap_opt_compat_mode_1_t; + +/**@brief Compatibility mode 2 option. + * + * This can be used with @ref sd_ble_opt_set to enable compatibility mode 2. + * Compatibility mode 2 is disabled by default. + * + * @note Compatibility mode 2 enables interoperability with devices that initiate Feature exchange + * and version exchange procedure in parallel. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM if enable bit is not set to 1. Currently only enabling is supported. + * @retval ::NRF_ERROR_INVALID_STATE When any role is running while mode 2 is set. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable compatibility mode 2.*/ +} ble_gap_opt_compat_mode_2_t; + + +/**@brief Authenticated payload timeout option. + * + * This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other than the default of 8 minutes. + * + * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated + * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted + * link. + * + * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance + * to reset the timer. In addition the stack will try to prioritize running of LE ping over other + * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects + * on other activities, it is recommended to use high timeout values. + * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)). + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit. Maximum is 48 000 (=480 000 ms =8 min). Minimum is 1 (=10 ms). */ +} ble_gap_opt_auth_payload_timeout_t; + + +/**@brief Option structure for GAP options. */ +typedef union +{ + ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */ + ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */ + ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/ + ble_gap_opt_scan_req_report_t scan_req_report; /**< Parameters for the scan request report option.*/ + ble_gap_opt_compat_mode_1_t compat_mode_1; /**< Parameters for the compatibility mode 1 option.*/ + ble_gap_opt_compat_mode_2_t compat_mode_2; /**< Parameters for the compatibility mode 2 option.*/ + ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/ + ble_gap_opt_slave_latency_disable_t slave_latency_disable; /**< Parameters for the Disable slave latency option */ +} ble_gap_opt_t; +/**@} */ + + +/**@addtogroup BLE_GAP_FUNCTIONS Functions + * @{ */ + +/**@brief Set the local Bluetooth identity address. + * + * The local Bluetooth identity address is the address that identifies this device to other peers. + * The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * + * @note The identity address cannot be changed while advertising, scanning or creating a connection. + * + * @note This address will be distributed to the peer during bonding. + * If the address changes, the address stored in the peer device will not be valid and the ability to + * reconnect using the old address will be lost. + * + * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being + * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged + * for the lifetime of each IC. + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @endmscs + * + * @param[in] p_addr Pointer to address structure. + * + * @retval ::NRF_SUCCESS Address successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_STATE The identity address cannot be changed while advertising, + * scanning or creating a connection. + */ +SVCALL(SD_BLE_GAP_ADDR_SET, uint32_t, sd_ble_gap_addr_set(ble_gap_addr_t const *p_addr)); + + +/**@brief Get local Bluetooth identity address. + * + * @note This will always return the identity address irrespective of the privacy settings, + * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * + * @param[out] p_addr Pointer to address structure to be filled in. + * + * @retval ::NRF_SUCCESS Address successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + */ +SVCALL(SD_BLE_GAP_ADDR_GET, uint32_t, sd_ble_gap_addr_get(ble_gap_addr_t *p_addr)); + + +/**@brief Set the active whitelist in the SoftDevice. + * + * @note Only one whitelist can be used at a time and the whitelist is shared between the BLE roles. + * The whitelist cannot be set if a BLE role is using the whitelist. + * + * @note If an address is resolved using the information in the device identity list, then the whitelist + * filter policy applies to the peer identity address and not the resolvable address sent on air. + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} + * @endmscs + * + * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses, if NULL the whitelist will be cleared. + * @param[in] len Length of the whitelist, maximum @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. + * + * @retval ::NRF_SUCCESS The whitelist is successfully set/cleared. + * @retval ::NRF_ERROR_INVALID_ADDR The whitelist (or one of its entries) provided is invalid. + * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE The whitelist is in use by a BLE role and cannot be set or cleared. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_DATA_SIZE The given whitelist size is invalid (zero or too large); this can only return when + * pp_wl_addrs is not NULL. + */ +SVCALL(SD_BLE_GAP_WHITELIST_SET, uint32_t, sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len)); + + +/**@brief Set device identity list. + * + * @note Only one device identity list can be used at a time and the list is shared between the BLE roles. + * The device identity list cannot be set if a BLE role is using the list. + * + * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs, if NULL the device identity list will be cleared. + * @param[in] pp_local_irks Pointer to an array of local IRKs. Each entry in the array maps to the entry in pp_id_keys at the same index. + * To fill in the list with the currently set device IRK for all peers, set to NULL. + * @param[in] len Length of the device identity list, maximum @ref BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT. + * + * @mscs + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS The device identity list successfully set/cleared. + * @retval ::NRF_ERROR_INVALID_ADDR The device identity list (or one of its entries) provided is invalid. + * This code may be returned if the local IRK list also has an invalid entry. + * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE The device identity list is in use and cannot be set or cleared. + * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE The device identity list contains multiple entries with the same identity address. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_DATA_SIZE The given device identity list size invalid (zero or too large); this can + * only return when pp_id_keys is not NULL. + */ +SVCALL(SD_BLE_GAP_DEVICE_IDENTITIES_SET, uint32_t, sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len)); + + +/**@brief Set privacy settings. + * + * @note Privacy settings cannot be changed while advertising, scanning or creating a connection. + * + * @param[in] p_privacy_params Privacy settings. + * + * @mscs + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_INVALID_ADDR The pointer to privacy settings is NULL or invalid. + * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. + * @retval ::NRF_ERROR_INVALID_PARAM Out of range parameters are provided. + * @retval ::NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while advertising, scanning + * or creating a connection. + */ +SVCALL(SD_BLE_GAP_PRIVACY_SET, uint32_t, sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params)); + + +/**@brief Get privacy settings. + * + * @note The privacy settings returned include the current device irk as well. + * + * @param[in] p_privacy_params Privacy settings. + * + * @retval ::NRF_SUCCESS Privacy settings read. + * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid. + * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. + */ +SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params)); + + +/**@brief Set, clear or update advertising and scan response data. + * + * @note The format of the advertising data will be checked by this call to ensure interoperability. + * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and + * duplicating the local name in the advertising data and scan response data. + * + * @note To clear the advertising data and set it to a 0-length packet, simply provide a valid pointer (p_data/p_sr_data) with its corresponding + * length (dlen/srdlen) set to 0. + * + * @note The call will fail if p_data and p_sr_data are both NULL since this would have no effect. + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] p_data Raw data to be placed in advertising packet. If NULL, no changes are made to the current advertising packet data. + * @param[in] dlen Data length for p_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_data is NULL, can be 0 if p_data is not NULL. + * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL, no changes are made to the current scan response packet data. + * @param[in] srdlen Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL. + * + * @retval ::NRF_SUCCESS Advertising data successfully updated or cleared. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, both p_data and p_sr_data cannot be NULL. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied. + * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied, check the advertising data format specification. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data type. + * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied. + */ +SVCALL(SD_BLE_GAP_ADV_DATA_SET, uint32_t, sd_ble_gap_adv_data_set(uint8_t const *p_data, uint8_t dlen, uint8_t const *p_sr_data, uint8_t srdlen)); + + +/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). + * + * @note Only one advertiser may be active at any time. + * + * @events + * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Advertisement has timed out.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] p_adv_params Pointer to advertising parameters structure. + * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or @ref + * BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. + * + * @retval ::NRF_SUCCESS The BLE stack has started advertising. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check the accepted ranges and limits. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Bluetooth address supplied. + * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Observer) and try again + */ +SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(ble_gap_adv_params_t const *p_adv_params, uint8_t conn_cfg_tag)); + + +/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS The BLE stack has stopped advertising. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in advertising state). + */ +SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(void)); + + + +/**@brief Update connection parameters. + * + * @details In the central role this will initiate a Link Layer connection parameter update procedure, + * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for + * the central to perform the procedure. In both cases, and regardless of success or failure, the application + * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event. + * + * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested. + * + * @events + * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CPU_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CPU_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CPU_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role, + * the parameters in the PPCP characteristic of the GAP service will be used instead. + * If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected + * + * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, process pending events and wait for pending procedures to complete and retry. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params)); + + +/**@brief Disconnect (GAP Link Termination). + * + * @details This call initiates the disconnection procedure, and its completion will be communicated to the application + * with a @ref BLE_GAP_EVT_DISCONNECTED event. + * + * @events + * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CONN_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE). + * + * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (disconnection is already in progress). + */ +SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code)); + + +/**@brief Set the radio's transmit power. + * + * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, 3, and 4 dBm). + * + * @note The +3dBm setting is only available on nRF52 series ICs. + * @note The -30dBm setting is only available on nRF51 series ICs. + * @note The -40dBm setting is only available on nRF52 series ICs. + * + * @retval ::NRF_SUCCESS Successfully changed the transmit power. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + */ +SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(int8_t tx_power)); + + +/**@brief Set GAP Appearance value. + * + * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES. + * + * @retval ::NRF_SUCCESS Appearance value set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + */ +SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance)); + + +/**@brief Get GAP Appearance value. + * + * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES. + * + * @retval ::NRF_SUCCESS Appearance value retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance)); + + +/**@brief Set GAP Peripheral Preferred Connection Parameters. + * + * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters. + * + * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + */ +SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params)); + + +/**@brief Get GAP Peripheral Preferred Connection Parameters. + * + * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored. + * + * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params)); + + +/**@brief Set GAP device name. + * + * @note If the device name is located in application flash memory (see @ref ble_gap_cfg_device_name_t), + * it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned. + * + * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t. + * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. + * @param[in] len Length of the UTF-8, non NULL-terminated string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN). + * + * @retval ::NRF_SUCCESS GAP device name and permissions set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_FORBIDDEN Device name is not writable. + */ +SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len)); + + +/**@brief Get GAP device name. + * + * @note If the device name is longer than the size of the supplied buffer, + * p_len will return the complete device name length, + * and not the number of bytes actually returned in p_dev_name. + * The application may use this information to allocate a suitable buffer size. + * + * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to NULL to obtain the complete device name length. + * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. + * + * @retval ::NRF_SUCCESS GAP device name retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + */ +SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len)); + + +/**@brief Initiate the GAP Authentication procedure. + * + * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), + * otherwise in the peripheral role, an SMP Security Request will be sent. + * + * @events + * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be generated:} + * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST} + * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST} + * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY} + * @event{@ref BLE_GAP_EVT_KEY_PRESSED} + * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST} + * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST} + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE} + * @event{@ref BLE_GAP_EVT_AUTH_STATUS} + * @event{@ref BLE_GAP_EVT_TIMEOUT} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure. + * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used. + * In the central role, this pointer may be NULL to reject a Security Request. + * + * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. + * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited. + */ +SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params)); + + +/**@brief Reply with GAP security parameters. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. + * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have + * already been provided during a previous call to @ref sd_ble_gap_authenticate. + * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure + * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application + * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event. + * Note that the SoftDevice expects the application to provide memory for storing the + * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key + * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the + * @ref BLE_GAP_EVT_AUTH_STATUS event. + * + * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. + */ +SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset)); + + +/**@brief Reply with an authentication key. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES. + * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination) + * or NULL when confirming LE Secure Connections Numeric Comparison. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in little-endian format. + * + * @retval ::NRF_SUCCESS Authentication key successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key)); + +/**@brief Reply with an LE Secure connections DHKey. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dhkey LE Secure Connections DHKey. + * + * @retval ::NRF_SUCCESS DHKey successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey)); + +/**@brief Notify the peer of a local keypress. + * + * @details This function can only be used when an authentication procedure using LE Secure Connection is in progress. Calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES. + * + * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either not entering a passkey or keypresses have not been enabled by both peers. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time. + */ +SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not)); + +/**@brief Generate a set of OOB data to send to a peer out of band. + * + * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has already been established, + * the one used during connection setup). The application may manually overwrite it with an updated value. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. Can be BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet. + * @param[in] p_pk_own LE Secure Connections local P-256 Public Key. + * @param[out] p_oobd_own The OOB data to be sent out of band to a peer. + * + * @retval ::NRF_SUCCESS OOB data successfully generated. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, ble_gap_lesc_oob_data_t *p_oobd_own)); + +/**@brief Provide the OOB data sent/received out of band. + * + * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function. + * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this function. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if the peer has not received OOB data. + * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. + * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received. + * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref sd_ble_gap_authenticate in the central role + * or @ref sd_ble_gap_sec_params_reply in the peripheral role. + * + * @retval ::NRF_SUCCESS OOB data accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, ble_gap_lesc_oob_data_t const *p_oobd_peer)); + +/**@brief Initiate GAP Encryption procedure. + * + * @details In the central role, this function will initiate the encryption procedure using the encryption information provided. + * + * @events + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE, The connection security has been updated.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. + * + * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. + * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and retry. + */ +SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info)); + + +/**@brief Reply with GAP security information. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * @note Data signing is not yet supported, and p_sign_info must therefore be NULL. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available. + * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available. + * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available. + * + * @retval ::NRF_SUCCESS Successfully accepted security information. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info)); + + +/**@brief Get the current connection security. + * + * @param[in] conn_handle Connection handle. + * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Current connection security successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec)); + + +/**@brief Start reporting the received signal strength to the application. + * + * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called. + * + * @events + * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is + * dependent on the settings of the threshold_dbm + * and skip_count input parameters.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID. + * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event. + * + * @retval ::NRF_SUCCESS Successfully activated RSSI reporting. + * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress. Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count)); + + +/**@brief Stop reporting the received signal strength. + * + * @note An RSSI change detected before the call but not yet received by the application + * may be reported after @ref sd_ble_gap_rssi_stop has been called. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * + * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle)); + + +/**@brief Get the received signal strength for the last connection event. + * + * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND + * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. + * + * @retval ::NRF_SUCCESS Successfully read the RSSI. + * @retval ::NRF_ERROR_NOT_FOUND No sample is available. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing, or disconnection in progress. + */ +SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi)); + + +/**@brief Start scanning (GAP Discovery procedure, Observer Procedure). + * + * @events + * @event{@ref BLE_GAP_EVT_ADV_REPORT, An advertising or scan response packet has been received.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Scanner has timed out.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] p_scan_params Pointer to scan parameters structure. + * + * @retval ::NRF_SUCCESS Successfully initiated scanning procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again + */ +SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params)); + + +/**@brief Stop scanning (GAP Discovery procedure, Observer Procedure). + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully stopped scanning procedure. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in scanning state). + */ +SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void)); + + +/**@brief Create a connection (GAP Link Establishment). + * + * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function. + * The scanning procedure will be stopped even if the function returns an error. + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs + * + * @param[in] p_peer_addr Pointer to peer address. If the use_whitelist bit is set in @ref ble_gap_scan_params_t, then this is ignored. + * If @ref ble_gap_addr_t::addr_id_peer is set then p_peer_addr must be present in the device identity list + * see @ref sd_ble_gap_device_identities_set. + * @param[in] p_scan_params Pointer to scan parameters structure. + * @param[in] p_conn_params Pointer to desired connection parameters. + * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or @ref + * BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. + * + * @retval ::NRF_SUCCESS Successfully initiated connection procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * - Invalid parameter(s) in p_scan_params or p_conn_params. + * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set. + * - Peer address was not present in the device identity list, see @ref sd_ble_gap_device_identities_set. + * @retval ::NRF_ERROR_INVALID_STATE The SoftDevice is in an invalid state to perform this operation. This may be due to an + * existing locally initiated connect procedure, which must complete before initiating again. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. If another connection is being established + * wait for the corresponding @ref BLE_GAP_EVT_CONNECTED event before calling again. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again + */ +SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag)); + + +/**@brief Cancel a connection establishment. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully canceled an ongoing connection procedure. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + */ +SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void)); + + +/**@brief Initiate or respond to a Data Length Update Procedure. + * + * @note Only symmetric input parameters for the Data Length Update is supported. Only @ref + * BLE_GAP_DATA_LENGTH_AUTO for max_tx_time_us and max_rx_time_us is supported. + * + * @note If the application uses @ref BLE_GAP_DATA_LENGTH_AUTO for one or more members of + * p_dl_params, the SoftDevice will choose the highest value supported in current + * configuration and connection parameters. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dl_params Pointer to local parameters to be used in Data Length Update + * Procedure. Set any member to @ref BLE_GAP_DATA_LENGTH_AUTO to let + * the SoftDevice automatically decide the value for that member. + * Set to NULL to use automatic values for all members. + * @param[out] p_dl_limitation Pointer to limitation to be written when local device does not + * have enough resources to accommodate the requested Data Length + * Update parameters. Ignored if NULL. + * + * @mscs + * @mmsc{@ref BLE_GAP_DATA_LENGTH_UPDATE_PROCEDURE_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully set Data Length Extension initiation/response parameters. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED The requested parameters are not supported by the SoftDevice. + * @retval ::NRF_ERROR_RESOURCES The requested parameters can not be accommodated. Inspect + * p_dl_limitation so see where the limitation is. + * @retval ::NRF_ERROR_BUSY Peer has already initiated a Data Length Update Procedure. Process the + * pending @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event to respond. + */ +SVCALL(SD_BLE_GAP_DATA_LENGTH_UPDATE, uint32_t, sd_ble_gap_data_length_update(uint16_t conn_handle, ble_gap_data_length_params_t const *p_dl_params, ble_gap_data_length_limitation_t *p_dl_limitation)); + + + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GAP_H__ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_gatt.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_gatt.h new file mode 100644 index 0000000000000000000000000000000000000000..f6e7ee856373e950db962ae89a5aa1f9d48ce6ac --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_gatt.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_GATT Generic Attribute Profile (GATT) Common + @{ + @brief Common definitions and prototypes for the GATT interfaces. + */ + +#ifndef BLE_GATT_H__ +#define BLE_GATT_H__ + +#include "ble_types.h" +#include "ble_ranges.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATT_DEFINES Defines + * @{ */ + +/** @brief Default ATT MTU, in bytes. */ +#define BLE_GATT_ATT_MTU_DEFAULT 23 + +/**@brief Invalid Attribute Handle. */ +#define BLE_GATT_HANDLE_INVALID 0x0000 + +/**@brief First Attribute Handle. */ +#define BLE_GATT_HANDLE_START 0x0001 + +/**@brief Last Attribute Handle. */ +#define BLE_GATT_HANDLE_END 0xFFFF + +/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources + * @{ */ +#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */ +/** @} */ + +/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations + * @{ */ +#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */ +#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */ +#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ +#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ +#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */ +/** @} */ + +/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags + * @{ */ +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */ +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */ +/** @} */ + +/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations + * @{ */ +#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */ +#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */ +/** @} */ + +/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes + * @{ */ +#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */ +#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */ +#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */ +#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */ +#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */ +#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorization. */ +#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */ +#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */ +#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */ +#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */ +#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */ +#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */ +#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */ +#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */ +#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */ +#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */ +/** @} */ + + +/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats + * @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml + * @{ */ +#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */ +#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */ +#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */ +#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */ +#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */ +#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */ +#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */ +#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */ +#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */ +#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */ +#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */ +#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */ +/** @} */ + +/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces + * @{ + */ +#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */ +#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATT_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATT connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval NRF_ERROR_INVALID_PARAM att_mtu is smaller than @ref BLE_GATT_ATT_MTU_DEFAULT. + */ +typedef struct +{ + uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive. + The default and minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + @mscs + @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} + @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} + @endmscs + */ +} ble_gatt_conn_cfg_t; + +/**@brief GATT Characteristic Properties. */ +typedef struct +{ + /* Standard properties */ + uint8_t broadcast :1; /**< Broadcasting of the value permitted. */ + uint8_t read :1; /**< Reading the value permitted. */ + uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */ + uint8_t write :1; /**< Writing the value with Write Request permitted. */ + uint8_t notify :1; /**< Notification of the value permitted. */ + uint8_t indicate :1; /**< Indications of the value permitted. */ + uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */ +} ble_gatt_char_props_t; + +/**@brief GATT Characteristic Extended Properties. */ +typedef struct +{ + /* Extended properties */ + uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */ + uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */ +} ble_gatt_char_ext_props_t; + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GATT_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_gattc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_gattc.h new file mode 100644 index 0000000000000000000000000000000000000000..b6a75ece770363fae5b3ac85c36bc971dd97a88a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_gattc.h @@ -0,0 +1,700 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_GATTC Generic Attribute Profile (GATT) Client + @{ + @brief Definitions and prototypes for the GATT Client interface. + */ + +#ifndef BLE_GATTC_H__ +#define BLE_GATTC_H__ + +#include "ble_gatt.h" +#include "ble_types.h" +#include "ble_ranges.h" +#include "nrf_svc.h" +#include "nrf_error.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations + * @{ */ + +/**@brief GATTC API SVC numbers. */ +enum BLE_GATTC_SVCS +{ + SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */ + SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */ + SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */ + SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */ + SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */ + SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */ + SD_BLE_GATTC_READ, /**< Generic read. */ + SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */ + SD_BLE_GATTC_WRITE, /**< Generic write. */ + SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */ + SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */ +}; + +/** + * @brief GATT Client Event IDs. + */ +enum BLE_GATTC_EVTS +{ + BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */ + BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */ + BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */ + BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */ + BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */ + BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */ + BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */ + BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */ + BLE_GATTC_EVT_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref ble_gattc_evt_exchange_mtu_rsp_t. */ + BLE_GATTC_EVT_TIMEOUT, /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */ + BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE /**< Write without Response transmission complete. \n See @ref ble_gattc_evt_write_cmd_tx_complete_t. */ +}; + +/** @} */ + +/** @addtogroup BLE_GATTC_DEFINES Defines + * @{ */ + +/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC + * @{ */ +#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */ +/** @} */ + +/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats + * @{ */ +#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */ +#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */ +/** @} */ + +/** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults + * @{ */ +#define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Write without Response that can be queued for transmission. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATTC_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATTC connection configuration parameters, set with @ref sd_ble_cfg_set. + */ +typedef struct +{ + uint8_t write_cmd_tx_queue_size; /**< The guaranteed minimum number of Write without Response that can be queued for transmission. + The default value is @ref BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT */ +} ble_gattc_conn_cfg_t; + +/**@brief Operation Handle Range. */ +typedef struct +{ + uint16_t start_handle; /**< Start Handle. */ + uint16_t end_handle; /**< End Handle. */ +} ble_gattc_handle_range_t; + + +/**@brief GATT service. */ +typedef struct +{ + ble_uuid_t uuid; /**< Service UUID. */ + ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */ +} ble_gattc_service_t; + + +/**@brief GATT include. */ +typedef struct +{ + uint16_t handle; /**< Include Handle. */ + ble_gattc_service_t included_srvc; /**< Handle of the included service. */ +} ble_gattc_include_t; + + +/**@brief GATT characteristic. */ +typedef struct +{ + ble_uuid_t uuid; /**< Characteristic UUID. */ + ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ + uint8_t char_ext_props : 1; /**< Extended properties present. */ + uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */ + uint16_t handle_value; /**< Handle of the Characteristic Value. */ +} ble_gattc_char_t; + + +/**@brief GATT descriptor. */ +typedef struct +{ + uint16_t handle; /**< Descriptor Handle. */ + ble_uuid_t uuid; /**< Descriptor UUID. */ +} ble_gattc_desc_t; + + +/**@brief Write Parameters. */ +typedef struct +{ + uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */ + uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */ + uint16_t handle; /**< Handle to the attribute to be written. */ + uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */ + uint16_t len; /**< Length of data in bytes. */ + uint8_t const *p_value; /**< Pointer to the value data. */ +} ble_gattc_write_params_t; + +/**@brief Attribute Information for 16-bit Attribute UUID. */ +typedef struct +{ + uint16_t handle; /**< Attribute handle. */ + ble_uuid_t uuid; /**< 16-bit Attribute UUID. */ +} ble_gattc_attr_info16_t; + +/**@brief Attribute Information for 128-bit Attribute UUID. */ +typedef struct +{ + uint16_t handle; /**< Attribute handle. */ + ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */ +} ble_gattc_attr_info128_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Service count. */ + ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_prim_srvc_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Include count. */ + ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_rel_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Characteristic count. */ + ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_char_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Descriptor count. */ + ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_desc_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Attribute count. */ + uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */ + union { + ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ + ble_gattc_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ + } info; /**< Attribute information union. */ +} ble_gattc_evt_attr_info_disc_rsp_t; + +/**@brief GATT read by UUID handle value pair. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + uint8_t *p_value; /**< Pointer to the Attribute Value, length is available in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */ +} ble_gattc_handle_value_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */ +typedef struct +{ + uint16_t count; /**< Handle-Value Pair Count. */ + uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */ + uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_char_val_by_uuid_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + uint16_t offset; /**< Offset of the attribute data. */ + uint16_t len; /**< Attribute data length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */ +typedef struct +{ + uint16_t len; /**< Concatenated Attribute values length. */ + uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_char_vals_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */ + uint16_t offset; /**< Data offset. */ + uint16_t len; /**< Data length. */ + uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_write_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */ +typedef struct +{ + uint16_t handle; /**< Handle to which the HVx operation applies. */ + uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ + uint16_t len; /**< Attribute data length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_hvx_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. */ +typedef struct +{ + uint16_t server_rx_mtu; /**< Server RX MTU size. */ +} ble_gattc_evt_exchange_mtu_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */ +typedef struct +{ + uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ +} ble_gattc_evt_timeout_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE. */ +typedef struct +{ + uint8_t count; /**< Number of write without response transmissions completed. */ +} ble_gattc_evt_write_cmd_tx_complete_t; + +/**@brief GATTC event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which event occurred. */ + uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ + uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */ + union + { + ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */ + ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */ + ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */ + ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */ + ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */ + ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */ + ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */ + ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */ + ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */ + ble_gattc_evt_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response Event Parameters. */ + ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */ + ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */ + ble_gattc_evt_write_cmd_tx_complete_t write_cmd_tx_complete; /**< Write without Response transmission complete Event Parameters. */ + } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */ +} ble_gattc_evt_t; +/** @} */ + +/** @addtogroup BLE_GATTC_FUNCTIONS Functions + * @{ */ + +/**@brief Initiate or continue a GATT Primary Service Discovery procedure. + * + * @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle. + * If the last service has not been reached, this function must be called again with an updated start handle value to continue the search. + * + * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with + * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. + * + * @events + * @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] start_handle Handle to start searching from. + * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid)); + + +/**@brief Initiate or continue a GATT Relationship Discovery procedure. + * + * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached, + * this must be called again with an updated handle range to continue the search. + * + * @events + * @event{@ref BLE_GATTC_EVT_REL_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_REL_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Characteristic Discovery procedure. + * + * @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached, + * this must be called again with an updated handle range to continue the discovery. + * + * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with + * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure. + * + * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached, + * this must be called again with an updated handle range to continue the discovery. + * + * @events + * @event{@ref BLE_GATTC_EVT_DESC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_DESC_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure. + * + * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached, + * this must be called again with an updated handle range to continue the discovery. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_UUID_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_uuid Pointer to a Characteristic value UUID to read. + * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure. + * + * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor + * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the + * complete value. + * + * @events + * @event{@ref BLE_GATTC_EVT_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_READ_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] handle The handle of the attribute to be read. + * @param[in] offset Offset into the attribute value to be read. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset)); + + +/**@brief Initiate a GATT Read Multiple Characteristic Values procedure. + * + * @details This function initiates a GATT Read Multiple Characteristic Values procedure. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_MULT_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. + * @param[in] handle_count The number of handles in p_handles. + * + * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count)); + + +/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure. + * + * @details This function can perform all write procedures described in GATT. + * + * @note Only one write with response procedure can be ongoing per connection at a time. + * If the application tries to write with response while another write with response procedure is ongoing, + * the function call will return @ref NRF_ERROR_BUSY. + * A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer. + * + * @note The number of Write without Response that can be queued is configured by @ref ble_gattc_conn_cfg_t::write_cmd_tx_queue_size + * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. + * A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete. + * + * @note The application can keep track of the available queue element count for writes without responses by following the procedure below: + * - Store initial queue element count in a variable. + * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS. + * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event. + * + * @events + * @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.} + * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_write_params A pointer to a write parameters structure. + * + * @retval ::NRF_SUCCESS Successfully started the Write procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_BUSY For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry. + * @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued. + * Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry. + */ +SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params)); + + +/**@brief Send a Handle Value Confirmation to the GATT Server. + * + * @mscs + * @mmsc{@ref BLE_GATTC_HVI_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] handle The handle of the attribute in the indication. + * + * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle. + */ +SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle)); + +/**@brief Discovers information about a range of attributes on a GATT server. + * + * @events + * @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.} + * @endevents + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range The range of handles to request information about. + * + * @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range)); + +/**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server. + * + * @details The SoftDevice sets ATT_MTU to the minimum of: + * - The Client RX MTU value, and + * - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. + * + * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. + * + * @events + * @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] client_rx_mtu Client RX MTU size. + * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration + used for this connection. + * - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply + * if an ATT_MTU exchange has already been performed in the other direction. + * + * @retval ::NRF_SUCCESS Successfully sent request to the server. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu)); + +/**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. + * + * @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. + * @note If the buffer contains different event, behavior is undefined. + * @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with + * the next Handle-Value pair in each iteration. If the function returns other than + * @ref NRF_SUCCESS, it will not be changed. + * - To start iteration, initialize the structure to zero. + * - To continue, pass the value from previous iteration. + * + * \code + * ble_gattc_handle_value_t iter; + * memset(&iter, 0, sizeof(ble_gattc_handle_value_t)); + * while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS) + * { + * app_handle = iter.handle; + * memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len); + * } + * \endcode + * + * @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair. + * @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list. + */ +__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter); + +/** @} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter) +{ + uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len; + uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value; + uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first; + + if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count) + { + p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0]; + p_iter->p_value = p_next + sizeof(uint16_t); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_NOT_FOUND; + } +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +#ifdef __cplusplus +} +#endif +#endif /* BLE_GATTC_H__ */ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_gatts.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_gatts.h new file mode 100644 index 0000000000000000000000000000000000000000..6bb24831d870b80df2835f7d2043d7501b9119ae --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_gatts.h @@ -0,0 +1,832 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_GATTS Generic Attribute Profile (GATT) Server + @{ + @brief Definitions and prototypes for the GATTS interface. + */ + +#ifndef BLE_GATTS_H__ +#define BLE_GATTS_H__ + +#include "ble_types.h" +#include "ble_ranges.h" +#include "ble_l2cap.h" +#include "ble_gap.h" +#include "ble_gatt.h" +#include "nrf_svc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations + * @{ */ + +/** + * @brief GATTS API SVC numbers. + */ +enum BLE_GATTS_SVCS +{ + SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */ + SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */ + SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */ + SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */ + SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */ + SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */ + SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */ + SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */ + SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */ + SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */ + SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */ + SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */ + SD_BLE_GATTS_ATTR_GET, /**< Retrieve the UUID and/or metadata of an attribute. */ + SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */ +}; + +/** + * @brief GATT Server Event IDs. + */ +enum BLE_GATTS_EVTS +{ + BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */ + BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */ + BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */ + BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */ + BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. \n No additional event structure applies. */ + BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. */ + BLE_GATTS_EVT_TIMEOUT, /**< Peer failed to respond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */ + BLE_GATTS_EVT_HVN_TX_COMPLETE /**< Handle Value Notification transmission complete. \n See @ref ble_gatts_evt_hvn_tx_complete_t. */ +}; + +/**@brief GATTS Configuration IDs. + * + * IDs that uniquely identify a GATTS configuration. + */ +enum BLE_GATTS_CFGS +{ + BLE_GATTS_CFG_SERVICE_CHANGED = BLE_GATTS_CFG_BASE, /**< Service changed configuration. */ + BLE_GATTS_CFG_ATTR_TAB_SIZE, /**< Attribute table size configuration. */ +}; + +/** @} */ + +/** @addtogroup BLE_GATTS_DEFINES Defines + * @{ */ + +/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS + * @{ */ +#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */ +#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */ +/** @} */ + +/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths + * @{ */ +#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */ +#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */ +/** @} */ + +/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types + * @{ */ +#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */ +#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */ +#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */ +/** @} */ + + +/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types + * @{ */ +#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */ +#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */ +#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */ +#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */ +#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */ +#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */ +#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */ +#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */ +/** @} */ + + +/** @defgroup BLE_GATTS_OPS GATT Server Operations + * @{ */ +#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */ +#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */ +#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ +#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ +#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */ +#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */ +/** @} */ + +/** @defgroup BLE_GATTS_VLOCS GATT Value Locations + * @{ */ +#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */ +#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */ +#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack + will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */ +/** @} */ + +/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types + * @{ */ +#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */ +#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */ +#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */ +/** @} */ + +/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags + * @{ */ +#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */ +#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */ +/** @} */ + +/** @defgroup BLE_GATTS_SERVICE_CHANGED Service Changed Inclusion Values + * @{ + */ +#define BLE_GATTS_SERVICE_CHANGED_DEFAULT (1) /**< Default is to include the Service Changed characteristic in the Attribute Table. */ +/** @} */ + +/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size + * @{ + */ +#define BLE_GATTS_ATTR_TAB_SIZE_MIN (248) /**< Minimum Attribute Table size */ +#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) /**< Default Attribute Table size. */ +/** @} */ + +/** @defgroup BLE_GATTS_DEFAULTS GATT Server defaults + * @{ + */ +#define BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Handle Value Notifications that can be queued for transmission. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATTS_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATTS connection configuration parameters, set with @ref sd_ble_cfg_set. + */ +typedef struct +{ + uint8_t hvn_tx_queue_size; /**< Minimum guaranteed number of Handle Value Notifications that can be queued for transmission. + The default value is @ref BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT */ +} ble_gatts_conn_cfg_t; + +/**@brief Attribute metadata. */ +typedef struct +{ + ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */ + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ + uint8_t vlen :1; /**< Variable length attribute. */ + uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ + uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */ + uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */ +} ble_gatts_attr_md_t; + + +/**@brief GATT Attribute. */ +typedef struct +{ + ble_uuid_t const *p_uuid; /**< Pointer to the attribute UUID. */ + ble_gatts_attr_md_t const *p_attr_md; /**< Pointer to the attribute metadata structure. */ + uint16_t init_len; /**< Initial attribute value length in bytes. */ + uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */ + uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */ + uint8_t *p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer + that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location. + The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/ +} ble_gatts_attr_t; + +/**@brief GATT Attribute Value. */ +typedef struct +{ + uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/ + uint16_t offset; /**< Attribute value offset. */ + uint8_t *p_value; /**< Pointer to where value is stored or will be stored. + If value is stored in user memory, only the attribute length is updated when p_value == NULL. + Set to NULL when reading to obtain the complete length of the attribute value */ +} ble_gatts_value_t; + + +/**@brief GATT Characteristic Presentation Format. */ +typedef struct +{ + uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */ + int8_t exponent; /**< Exponent for integer data types. */ + uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */ + uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ + uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ +} ble_gatts_char_pf_t; + + +/**@brief GATT Characteristic metadata. */ +typedef struct +{ + ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ + ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */ + uint8_t const *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */ + uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */ + uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */ + ble_gatts_char_pf_t const *p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */ + ble_gatts_attr_md_t const *p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */ + ble_gatts_attr_md_t const *p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */ + ble_gatts_attr_md_t const *p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */ +} ble_gatts_char_md_t; + + +/**@brief GATT Characteristic Definition Handles. */ +typedef struct +{ + uint16_t value_handle; /**< Handle to the characteristic value. */ + uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ + uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ + uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ +} ble_gatts_char_handles_t; + + +/**@brief GATT HVx parameters. */ +typedef struct +{ + uint16_t handle; /**< Characteristic Value Handle. */ + uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ + uint16_t offset; /**< Offset within the attribute value. */ + uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after successful return. */ + uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */ +} ble_gatts_hvx_params_t; + +/**@brief GATT Authorization parameters. */ +typedef struct +{ + uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ + uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value. + Please note that for @ref BLE_GATTS_AUTHORIZE_TYPE_WRITE operations this bit must always be set, + as the data to be written needs to be stored and later provided by the application. */ + uint16_t offset; /**< Offset of the attribute value being updated. */ + uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */ + uint8_t const *p_data; /**< Pointer to new value used to update the attribute value. */ +} ble_gatts_authorize_params_t; + +/**@brief GATT Read or Write Authorize Reply parameters. */ +typedef struct +{ + uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ + union { + ble_gatts_authorize_params_t read; /**< Read authorization parameters. */ + ble_gatts_authorize_params_t write; /**< Write authorization parameters. */ + } params; /**< Reply Parameters. */ +} ble_gatts_rw_authorize_reply_params_t; + +/**@brief Service Changed Inclusion configuration parameters, set with @ref sd_ble_cfg_set. */ +typedef struct +{ + uint8_t service_changed : 1; /**< If 1, include the Service Changed characteristic in the Attribute Table. Default is @ref BLE_GATTS_SERVICE_CHANGED_DEFAULT. */ +} ble_gatts_cfg_service_changed_t; + +/**@brief Attribute table size configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: + * - The specified Attribute Table size is too small. + * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. + * - The specified Attribute Table size is not a multiple of 4. + */ +typedef struct +{ + uint32_t attr_tab_size; /**< Attribute table size. Default is @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, minimum is @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. */ +} ble_gatts_cfg_attr_tab_size_t; + +/**@brief Config structure for GATTS configurations. */ +typedef union +{ + ble_gatts_cfg_service_changed_t service_changed; /**< Include service changed characteristic, cfg_id is @ref BLE_GATTS_CFG_SERVICE_CHANGED. */ + ble_gatts_cfg_attr_tab_size_t attr_tab_size; /**< Attribute table size, cfg_id is @ref BLE_GATTS_CFG_ATTR_TAB_SIZE. */ +} ble_gatts_cfg_t; + + +/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + ble_uuid_t uuid; /**< Attribute UUID. */ + uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */ + uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalize the writing operation. */ + uint16_t offset; /**< Offset for the write operation. */ + uint16_t len; /**< Length of the received data. */ + uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gatts_evt_write_t; + +/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + ble_uuid_t uuid; /**< Attribute UUID. */ + uint16_t offset; /**< Offset for the read operation. */ +} ble_gatts_evt_read_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */ +typedef struct +{ + uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ + union { + ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */ + ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */ + } request; /**< Request Parameters. */ +} ble_gatts_evt_rw_authorize_request_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */ +typedef struct +{ + uint8_t hint; /**< Hint (currently unused). */ +} ble_gatts_evt_sys_attr_missing_t; + + +/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ +} ble_gatts_evt_hvc_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST. */ +typedef struct +{ + uint16_t client_rx_mtu; /**< Client RX MTU size. */ +} ble_gatts_evt_exchange_mtu_request_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */ +typedef struct +{ + uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ +} ble_gatts_evt_timeout_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_HVN_TX_COMPLETE. */ +typedef struct +{ + uint8_t count; /**< Number of notification transmissions completed. */ +} ble_gatts_evt_hvn_tx_complete_t; + +/**@brief GATTS event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which the event occurred. */ + union + { + ble_gatts_evt_write_t write; /**< Write Event Parameters. */ + ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */ + ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */ + ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */ + ble_gatts_evt_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */ + ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */ + ble_gatts_evt_hvn_tx_complete_t hvn_tx_complete; /**< Handle Value Notification transmission complete Event Parameters. */ + } params; /**< Event Parameters. */ +} ble_gatts_evt_t; + +/** @} */ + +/** @addtogroup BLE_GATTS_FUNCTIONS Functions + * @{ */ + +/**@brief Add a service declaration to the Attribute Table. + * + * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to + * add a secondary service declaration that is not referenced by another service later in the Attribute Table. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES. + * @param[in] p_uuid Pointer to service UUID. + * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a service declaration. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle)); + + +/**@brief Add an include declaration to the Attribute Table. + * + * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time). + * + * @note The included service must already be present in the Attribute Table prior to this call. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] inc_srvc_handle Handle of the included service. + * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added an include declaration. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + */ +SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle)); + + +/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table. + * + * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time). + * + * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writable auxiliaries bits, + * readable (no security) and writable (selectable) CCCDs and SCCDs and valid presentation format values. + * + * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] p_char_md Characteristic metadata. + * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value. + * @param[out] p_handles Pointer to the structure where the assigned handles will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a characteristic. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + */ +SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles)); + + +/**@brief Add a descriptor to the Attribute Table. + * + * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time). + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] p_attr Pointer to the attribute structure. + * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a descriptor. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + */ +SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle)); + +/**@brief Set the value of a given attribute. + * + * @note Values other than system attributes can be set at any time, regardless of whether any active connections exist. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. + * @param[in] handle Attribute handle. + * @param[in,out] p_value Attribute value information. + * + * @retval ::NRF_SUCCESS Successfully set the value of the attribute. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. + */ +SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); + +/**@brief Get the value of a given attribute. + * + * @note If the attribute value is longer than the size of the supplied buffer, + * p_len will return the total attribute value length (excluding offset), + * and not the number of bytes actually returned in p_data. + * The application may use this information to allocate a suitable buffer size. + * + * @note When retrieving system attribute values with this function, the connection handle + * may refer to an already disconnected connection. Refer to the documentation of + * @ref sd_ble_gatts_sys_attr_get for further information. + * + * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. + * @param[in] handle Attribute handle. + * @param[in,out] p_value Attribute value information. + * + * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. + */ +SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); + +/**@brief Notify or Indicate an attribute value. + * + * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation + * (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that + * the application can atomically perform a value update and a server initiated transaction with a single API call. + * + * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution. + * The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, + * @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES. + * The caller can check whether the value has been updated by looking at the contents of *(p_hvx_params->p_len). + * + * @note Only one indication procedure can be ongoing per connection at a time. + * If the application tries to indicate an attribute value while another indication procedure is ongoing, + * the function call will return @ref NRF_ERROR_BUSY. + * A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer. + * + * @note The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size + * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. + * A @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete. + * + * @note The application can keep track of the available queue element count for notifications by following the procedure below: + * - Store initial queue element count in a variable. + * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS. + * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event. + * + * @events + * @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.} + * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_HVN_MSC} + * @mmsc{@ref BLE_GATTS_HVI_MSC} + * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_hvx_params Pointer to an HVx parameters structure. If the p_data member contains a non-NULL pointer the attribute value will be updated with + * the contents pointed by it before sending the notification or indication. + * + * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: + * - Invalid Connection State + * - Notifications and/or indications not enabled in the CCCD + * - An ATT_MTU exchange is ongoing + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate. + * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. + * @retval ::NRF_ERROR_RESOURCES Too many notifications queued. + * Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry. + */ +SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params)); + +/**@brief Indicate the Service Changed attribute value. + * + * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute + * Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will + * be issued. + * + * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here. + * + * @events + * @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_SC_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] start_handle Start of affected attribute handle range. + * @param[in] end_handle End of affected attribute handle range. + * + * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref + * sd_ble_cfg_set and @ref ble_gatts_cfg_service_changed_t. + * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: + * - Invalid Connection State + * - Notifications and/or indications not enabled in the CCCD + * - An ATT_MTU exchange is ongoing + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application. + * @retval ::NRF_ERROR_BUSY Procedure already in progress. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. + */ +SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle)); + +/**@brief Respond to a Read/Write authorization request. + * + * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application. + * + * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond + * to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update + * is set to 0. + * + * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending. + * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid, + * handle supplied does not match requested handle, + * or invalid data to be written provided by the application. + */ +SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params)); + + +/**@brief Update persistent system attribute information. + * + * @details Supply information about persistent system attributes to the stack, + * previously obtained using @ref sd_ble_gatts_sys_attr_get. + * This call is only allowed for active connections, and is usually + * made immediately after a connection is established with an known bonded device, + * often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. + * + * p_sysattrs may point directly to the application's stored copy of the system attributes + * obtained using @ref sd_ble_gatts_sys_attr_get. + * If the pointer is NULL, the system attribute info is initialized, assuming that + * the application does not have any previously saved system attribute data for this device. + * + * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration. + * + * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially. + * This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or + * reset the SoftDevice to return to a known state. + * + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified. + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified. + * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL. + * @param[in] len Size of data pointed by p_sys_attr_data, in octets. + * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS + * + * @retval ::NRF_SUCCESS Successfully set the system attribute information. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. + * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags)); + + +/**@brief Retrieve persistent system attribute information from the stack. + * + * @details This call is used to retrieve information about values to be stored persistently by the application + * during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device, + * the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set. + * If retrieved after disconnection, the data should be read before a new connection established. The connection handle for + * the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it. + * Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes + * may be written to at any time by the peer during a connection's lifetime. + * + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned. + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned. + * + * @mscs + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle of the recently terminated connection. + * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described + * in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data. + * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditionally updated to actual length of system attribute data. + * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS + * + * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. + * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer. + * @retval ::NRF_ERROR_NOT_FOUND No system attributes found. + */ +SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); + + +/**@brief Retrieve the first valid user attribute handle. + * + * @param[out] p_handle Pointer to an integer where the handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully retrieved the handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle)); + +/**@brief Retrieve the attribute UUID and/or metadata. + * + * @param[in] handle Attribute handle + * @param[out] p_uuid UUID of the attribute. Use NULL to omit this field. + * @param[out] p_md Metadata of the attribute. Use NULL to omit this field. + * + * @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata, + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL. + * @retval ::NRF_ERROR_NOT_FOUND Attribute was not found. + */ +SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md)); + +/**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client. + * + * @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. + * + * @details The SoftDevice sets ATT_MTU to the minimum of: + * - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and + * - The Server RX MTU value. + * + * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. + * + * @mscs + * @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] server_rx_mtu Server RX MTU size. + * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration + used for this connection. + * - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request + * if an ATT_MTU exchange has already been performed in the other direction. + * + * @retval ::NRF_SUCCESS Successfully sent response to the client. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied. + */ +SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu)); +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GATTS_H__ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_hci.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_hci.h new file mode 100644 index 0000000000000000000000000000000000000000..1ce527c6538f26995bf0e75cc399455898ba54da --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_hci.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_COMMON + @{ +*/ + + +#ifndef BLE_HCI_H__ +#define BLE_HCI_H__ +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes + * @{ */ + +#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */ +#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */ +#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */ +/*0x03 Hardware Failure +0x04 Page Timeout +*/ +#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */ +#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */ +#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */ +#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */ +/*0x09 Connection Limit Exceeded +0x0A Synchronous Connection Limit To A Device Exceeded +0x0B ACL Connection Already Exists*/ +#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */ +/*0x0D Connection Rejected due to Limited Resources +0x0E Connection Rejected Due To Security Reasons +0x0F Connection Rejected due to Unacceptable BD_ADDR +0x10 Connection Accept Timeout Exceeded +0x11 Unsupported Feature or Parameter Value*/ +#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */ +#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */ +#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/ +#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */ +#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */ +/* +0x17 Repeated Attempts +0x18 Pairing Not Allowed +0x19 Unknown LMP PDU +*/ +#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */ +/* +0x1B SCO Offset Rejected +0x1C SCO Interval Rejected +0x1D SCO Air Mode Rejected*/ +#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */ +#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */ +/*0x20 Unsupported LMP Parameter Value +0x21 Role Change Not Allowed +*/ +#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */ +/*0x23 LMP Error Transaction Collision*/ +#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */ +/*0x25 Encryption Mode Not Acceptable +0x26 Link Key Can Not be Changed +0x27 Requested QoS Not Supported +*/ +#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */ +#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */ +#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */ +/* +0x2B Reserved +0x2C QoS Unacceptable Parameter +0x2D QoS Rejected +0x2E Channel Classification Not Supported +0x2F Insufficient Security +0x30 Parameter Out Of Mandatory Range +0x31 Reserved +0x32 Role Switch Pending +0x33 Reserved +0x34 Reserved Slot Violation +0x35 Role Switch Failed +0x36 Extended Inquiry Response Too Large +0x37 Secure Simple Pairing Not Supported By Host. +0x38 Host Busy - Pairing +0x39 Connection Rejected due to No Suitable Channel Found*/ +#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */ +#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */ +#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Advertisement Timeout. */ +#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */ +#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */ + +/** @} */ + + +#ifdef __cplusplus +} +#endif +#endif // BLE_HCI_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_l2cap.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_l2cap.h new file mode 100644 index 0000000000000000000000000000000000000000..90cce565d8e037dbb21d82336266d635af524b6d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_l2cap.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP) + @{ + @brief Definitions and prototypes for the L2CAP interface. + */ + +#ifndef BLE_L2CAP_H__ +#define BLE_L2CAP_H__ + +#include "ble_types.h" +#include "ble_ranges.h" +#include "ble_err.h" +#include "nrf_svc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup BLE_L2CAP_DEFINES Defines + * @{ */ + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_L2CAP_H__ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_ranges.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_ranges.h new file mode 100644 index 0000000000000000000000000000000000000000..f9c6af76b803a8899e42e47888df41005b8b5243 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_ranges.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_COMMON + @{ + @defgroup ble_ranges Module specific SVC, event and option number subranges + @{ + + @brief Definition of SVC, event and option number subranges for each API module. + + @note + SVCs, event and option numbers are split into subranges for each API module. + Each module receives its entire allocated range of SVC calls, whether implemented or not, + but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range. + + Note that the symbols BLE__SVC_LAST is the end of the allocated SVC range, + rather than the last SVC function call actually defined and implemented. + + Specific SVC, event and option values are defined in each module's ble_.h file, + which defines names of each individual SVC code based on the range start value. +*/ + +#ifndef BLE_RANGES_H__ +#define BLE_RANGES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */ +#define BLE_SVC_LAST 0x6B /**< Common BLE SVC last. */ + +#define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */ +#define BLE_GAP_SVC_LAST 0x93 /**< GAP BLE SVC last. */ + +#define BLE_GATTC_SVC_BASE 0x94 /**< GATTC BLE SVC base. */ +#define BLE_GATTC_SVC_LAST 0x9F /**< GATTC BLE SVC last. */ + +#define BLE_GATTS_SVC_BASE 0xA0 /**< GATTS BLE SVC base. */ +#define BLE_GATTS_SVC_LAST 0xAF /**< GATTS BLE SVC last. */ + +#define BLE_L2CAP_SVC_BASE 0xB0 /**< L2CAP BLE SVC base. */ +#define BLE_L2CAP_SVC_LAST 0xBF /**< L2CAP BLE SVC last. */ + + +#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */ + +#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */ +#define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */ + +#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */ +#define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */ + +#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */ +#define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */ + +#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */ +#define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */ + +#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */ +#define BLE_L2CAP_EVT_LAST 0x8F /**< L2CAP BLE Event last. */ + + +#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */ + +#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */ +#define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */ + +#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */ +#define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */ + +#define BLE_GATT_OPT_BASE 0x40 /**< GATT BLE Option base. */ +#define BLE_GATT_OPT_LAST 0x5F /**< GATT BLE Option last. */ + +#define BLE_GATTC_OPT_BASE 0x60 /**< GATTC BLE Option base. */ +#define BLE_GATTC_OPT_LAST 0x7F /**< GATTC BLE Option last. */ + +#define BLE_GATTS_OPT_BASE 0x80 /**< GATTS BLE Option base. */ +#define BLE_GATTS_OPT_LAST 0x9F /**< GATTS BLE Option last. */ + +#define BLE_L2CAP_OPT_BASE 0xA0 /**< L2CAP BLE Option base. */ +#define BLE_L2CAP_OPT_LAST 0xBF /**< L2CAP BLE Option last. */ + + +#define BLE_CFG_INVALID 0x00 /**< Invalid BLE configuration. */ + +#define BLE_CFG_BASE 0x01 /**< Common BLE configuration base. */ +#define BLE_CFG_LAST 0x1F /**< Common BLE configuration last. */ + +#define BLE_CONN_CFG_BASE 0x20 /**< BLE connection configuration base. */ +#define BLE_CONN_CFG_LAST 0x3F /**< BLE connection configuration last. */ + +#define BLE_GAP_CFG_BASE 0x40 /**< GAP BLE configuration base. */ +#define BLE_GAP_CFG_LAST 0x5F /**< GAP BLE configuration last. */ + +#define BLE_GATT_CFG_BASE 0x60 /**< GATT BLE configuration base. */ +#define BLE_GATT_CFG_LAST 0x7F /**< GATT BLE configuration last. */ + +#define BLE_GATTC_CFG_BASE 0x80 /**< GATTC BLE configuration base. */ +#define BLE_GATTC_CFG_LAST 0x9F /**< GATTC BLE configuration last. */ + +#define BLE_GATTS_CFG_BASE 0xA0 /**< GATTS BLE configuration base. */ +#define BLE_GATTS_CFG_LAST 0xBF /**< GATTS BLE configuration last. */ + +#define BLE_L2CAP_CFG_BASE 0xC0 /**< L2CAP BLE configuration base. */ +#define BLE_L2CAP_CFG_LAST 0xDF /**< L2CAP BLE configuration last. */ + + + + + +#ifdef __cplusplus +} +#endif +#endif /* BLE_RANGES_H__ */ + +/** + @} + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_types.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_types.h new file mode 100644 index 0000000000000000000000000000000000000000..e24be0b57496ea7d058794dc20a84868a31b0f3b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/ble_types.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_COMMON + @{ + @defgroup ble_types Common types and macro definitions + @{ + + @brief Common types and macro definitions for the BLE SoftDevice. + */ + +#ifndef BLE_TYPES_H__ +#define BLE_TYPES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_TYPES_DEFINES Defines + * @{ */ + +/** @defgroup BLE_CONN_HANDLES BLE Connection Handles + * @{ */ +#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */ +#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */ +/** @} */ + + +/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs + * @{ */ +/* Generic UUIDs, applicable to all services */ +#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */ +#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */ +#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */ +#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */ +#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */ +#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */ +#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */ +/* GATT specific UUIDs */ +#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */ +#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */ +/* GAP specific UUIDs */ +#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */ +#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution Characteristic. */ +/** @} */ + + +/** @defgroup BLE_UUID_TYPES Types of UUID + * @{ */ +#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */ +#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */ +#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */ +/** @} */ + + +/** @defgroup BLE_APPEARANCES Bluetooth Appearance values + * @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml + * @{ */ +#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */ +#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */ +#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */ +#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */ +#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */ +#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */ +#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */ +#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */ +#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */ +#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */ +#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */ +#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */ +#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */ +#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */ +#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */ +#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */ +#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */ +#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */ +#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */ +#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */ +#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */ +#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */ +#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */ +#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystick (HID Subtype). */ +#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */ +#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */ +#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */ +#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */ +#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */ +#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */ +#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */ +#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */ +#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */ +#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */ +#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */ +#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */ +#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */ +#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */ +#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */ +#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */ +#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */ +#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */ +/** @} */ + +/** @brief Set .type and .uuid fields of ble_uuid_struct to specified UUID value. */ +#define BLE_UUID_BLE_ASSIGN(instance, value) do {\ + instance.type = BLE_UUID_TYPE_BLE; \ + instance.uuid = value;} while(0) + +/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */ +#define BLE_UUID_COPY_PTR(dst, src) do {\ + (dst)->type = (src)->type; \ + (dst)->uuid = (src)->uuid;} while(0) + +/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */ +#define BLE_UUID_COPY_INST(dst, src) do {\ + (dst).type = (src).type; \ + (dst).uuid = (src).uuid;} while(0) + +/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ +#define BLE_UUID_EQ(p_uuid1, p_uuid2) \ + (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid)) + +/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ +#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \ + (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid)) + +/** @} */ + +/** @addtogroup BLE_TYPES_STRUCTURES Structures + * @{ */ + +/** @brief 128 bit UUID values. */ +typedef struct +{ + uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */ +} ble_uuid128_t; + +/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */ +typedef struct +{ + uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ + uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ +} ble_uuid_t; + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* BLE_TYPES_H__ */ + +/** + @} + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf52/nrf_mbr.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf52/nrf_mbr.h new file mode 100644 index 0000000000000000000000000000000000000000..ccbe96bd59e01b83139b37b588c57e132239dca6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf52/nrf_mbr.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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. + * + */ +/** + @defgroup nrf_mbr_api Master Boot Record API + @{ + + @brief APIs for updating SoftDevice and BootLoader + +*/ + +#ifndef NRF_MBR_H__ +#define NRF_MBR_H__ + +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup NRF_MBR_DEFINES Defines + * @{ */ + +/**@brief MBR SVC Base number. */ +#define MBR_SVC_BASE (0x18) + +/**@brief Page size in words. */ +#define MBR_PAGE_SIZE_IN_WORDS (1024) + +/** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash. +This is the offset where the first byte of the SoftDevice hex file is written.*/ +#define MBR_SIZE (0x1000) + +/** @} */ + +/** @addtogroup NRF_MBR_ENUMS Enumerations + * @{ */ + +/**@brief nRF Master Boot Record API SVC numbers. */ +enum NRF_MBR_SVCS +{ + SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */ +}; + +/**@brief Possible values for ::sd_mbr_command_t.command */ +enum NRF_MBR_COMMANDS +{ + SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see sd_mbr_command_copy_bl_t*/ + SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/ + SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD*/ + SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/ + SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Start forwarding all exception to this address @see ::sd_mbr_command_vector_table_base_set_t*/ +}; + +/** @} */ + +/** @addtogroup NRF_MBR_TYPES Types + * @{ */ + +/**@brief This command copies part of a new SoftDevice + * The destination area is erased before copying. + * If dst is in the middle of a flash page, that whole flash page will be erased. + * If (dst+len) is in the middle of a flash page, that whole flash page will be erased. + * + * The user of this function is responsible for setting the BPROT registers. + * + * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. + * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + */ +typedef struct +{ + uint32_t *src; /**< Pointer to the source of data to be copied.*/ + uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/ + uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/ +} sd_mbr_command_copy_sd_t; + + +/**@brief This command works like memcmp, but takes the length in words. + * + * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal. + * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal. + */ +typedef struct +{ + uint32_t *ptr1; /**< Pointer to block of memory. */ + uint32_t *ptr2; /**< Pointer to block of memory. */ + uint32_t len; /**< Number of 32 bit words to compare.*/ +} sd_mbr_command_compare_t; + + +/**@brief This command copies a new BootLoader. + * With this command, destination of BootLoader is always the address written in NRF_UICR->BOOTADDR. + * + * Destination is erased by this function. + * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased. + * + * This function will use PROTENSET to protect the flash that is not intended to be written. + * + * On success, this function will not return. It will start the new BootLoader from reset-vector as normal. + * + * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. + * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set. + * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area. + * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info) + */ +typedef struct +{ + uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/ + uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */ +} sd_mbr_command_copy_bl_t; + +/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR + * + * Once this function has been called, this address is where the MBR will start to forward interrupts to after a reset. + * + * To restore default forwarding this function should be called with @param address set to 0. + * The MBR will then start forwarding to interrupts to the address in NFR_UICR->BOOTADDR or to the SoftDevice if the BOOTADDR is not set. + * + * On success, this function will not return. It will reset the device. + * + * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. + * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size. + * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info) + */ +typedef struct +{ + uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ +} sd_mbr_command_vector_table_base_set_t; + + +typedef struct +{ + uint32_t command; /**< type of command to be issued see @ref NRF_MBR_COMMANDS. */ + union + { + sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/ + sd_mbr_command_compare_t compare; /**< Parameters for verify.*/ + sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */ + sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/ + } params; +} sd_mbr_command_t; + +/** @} */ + +/** @addtogroup NRF_MBR_FUNCTIONS Functions + * @{ */ + +/**@brief Issue Master Boot Record commands + * + * Commands used when updating a SoftDevice and bootloader. + * + * The SD_MBR_COMMAND_COPY_BL and SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires parameters to be + * retained by the MBR when resetting the IC. This is done in a separate flash page + * provided by the application. The UICR register UICR.NRFFW[1] must be set + * to an address corresponding to a page in the application flash space. This page will be cleared + * by the MBR and used to store the command before reset. When the UICR.NRFFW[1] field is set + * the page it refers to must not be used by the application. If the UICR.NRFFW[1] is set to + * 0xFFFFFFFF (the default) MBR commands which use flash will be unavailable and return + * NRF_ERROR_NO_MEM. + * + * @param[in] param Pointer to a struct describing the command. + * + * @note For return values, see ::sd_mbr_command_copy_sd_t ::sd_mbr_command_copy_bl_t ::sd_mbr_command_compare_t ::sd_mbr_command_vector_table_base_set_t + * + * @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. +*/ +SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_MBR_H__ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_error.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_error.h new file mode 100644 index 0000000000000000000000000000000000000000..43c091630bdcd0a3922170d0c32371a643580d9a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_error.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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. + * + */ + /** + @defgroup nrf_error SoftDevice Global Error Codes + @{ + + @brief Global Error definitions +*/ + +/* Header guard */ +#ifndef NRF_ERROR_H__ +#define NRF_ERROR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions + * @{ */ +#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base +#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base +#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base +#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base +/** @} */ + +#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command +#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing +#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled +#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error +#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation +#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found +#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported +#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter +#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state +#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length +#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags +#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data +#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size +#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out +#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer +#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation +#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address +#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy +#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded. +#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_H__ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_error_sdm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_error_sdm.h new file mode 100644 index 0000000000000000000000000000000000000000..103659a913899d0ab0b59a7e6042e6a8d3b612a2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_error_sdm.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 nrf_sdm_api + @{ + @defgroup nrf_sdm_error SoftDevice Manager Error Codes + @{ + + @brief Error definitions for the SDM API +*/ + +/* Header guard */ +#ifndef NRF_ERROR_SDM_H__ +#define NRF_ERROR_SDM_H__ + +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown LFCLK source. +#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). +#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing). + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_SDM_H__ + +/** + @} + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_error_soc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_error_soc.h new file mode 100644 index 0000000000000000000000000000000000000000..e31d8c9c97831f67e895855e4ce433b45beacf1e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_error_soc.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 nrf_soc_api + @{ + @defgroup nrf_soc_error SoC Library Error Codes + @{ + + @brief Error definitions for the SoC library + +*/ + +/* Header guard */ +#ifndef NRF_ERROR_SOC_H__ +#define NRF_ERROR_SOC_H__ + +#include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* Mutex Errors */ +#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken + +/* NVIC errors */ +#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available +#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed +#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return + +/* Power errors */ +#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown +#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown +#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return + +/* Rand errors */ +#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values + +/* PPI errors */ +#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel +#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_SOC_H__ +/** + @} + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_nvic.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_nvic.h new file mode 100644 index 0000000000000000000000000000000000000000..73d3ee9910805af6a4fb39bad344fe26374a32bf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_nvic.h @@ -0,0 +1,517 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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. + * + */ +/** + * @defgroup nrf_nvic_api SoftDevice NVIC API + * @{ + * + * @note In order to use this module, the following code has to be added to a .c file: + * \code + * nrf_nvic_state_t nrf_nvic_state = {0}; + * \endcode + * + * @note Definitions and declarations starting with __ (double underscore) in this header file are + * not intended for direct use by the application. + * + * @brief APIs for the accessing NVIC when using a SoftDevice. + * + */ + +#ifndef NRF_NVIC_H__ +#define NRF_NVIC_H__ + +#include +#include "nrf.h" + +#include "nrf_error_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup NRF_NVIC_DEFINES Defines + * @{ */ + +/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions + * @{ */ + +#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */ + +#ifdef NRF51 + #define __NRF_NVIC_ISER_COUNT (1) /**< The number of ISER/ICER registers in the NVIC that are used. */ + + /**@brief Interrupts used by the SoftDevice. */ + #define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ + (1U << POWER_CLOCK_IRQn) \ + | (1U << RADIO_IRQn) \ + | (1U << RTC0_IRQn) \ + | (1U << TIMER0_IRQn) \ + | (1U << RNG_IRQn) \ + | (1U << ECB_IRQn) \ + | (1U << CCM_AAR_IRQn) \ + | (1U << TEMP_IRQn) \ + | (1U << __NRF_NVIC_NVMC_IRQn) \ + | (1U << (uint32_t)SWI5_IRQn) \ + )) + + /**@brief Interrupts available for to application. */ + #define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) +#endif + +#ifdef NRF52 + #define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */ + + /**@brief Interrupts used by the SoftDevice. */ + #define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ + (1U << POWER_CLOCK_IRQn) \ + | (1U << RADIO_IRQn) \ + | (1U << RTC0_IRQn) \ + | (1U << TIMER0_IRQn) \ + | (1U << RNG_IRQn) \ + | (1U << ECB_IRQn) \ + | (1U << CCM_AAR_IRQn) \ + | (1U << TEMP_IRQn) \ + | (1U << __NRF_NVIC_NVMC_IRQn) \ + | (1U << (uint32_t)SWI5_EGU5_IRQn) \ + )) + #define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0) + + /**@brief Interrupts available for to application. */ + #define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) + #define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1) +#endif +/**@} */ + +/**@} */ + +/**@addtogroup NRF_NVIC_VARIABLES Variables + * @{ */ + +/**@brief Type representing the state struct for the SoftDevice NVIC module. */ +typedef struct +{ + uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */ + uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */ +} nrf_nvic_state_t; + +/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an + * application source file. */ +extern nrf_nvic_state_t nrf_nvic_state; + +/**@} */ + +/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions + * @{ */ + +/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts. + * + * @retval The value of PRIMASK prior to disabling the interrupts. + */ +__STATIC_INLINE int __sd_nvic_irq_disable(void); + +/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts. + */ +__STATIC_INLINE void __sd_nvic_irq_enable(void); + +/**@brief Checks if IRQn is available to application + * @param[in] IRQn IRQ to check + * + * @retval 1 (true) if the IRQ to check is available to the application + */ +__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn); + +/**@brief Checks if priority is available to application + * @param[in] priority priority to check + * + * @retval 1 (true) if the priority to check is available to the application + */ +__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority); + +/**@} */ + +/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions + * @{ */ + +/**@brief Enable External Interrupt. + * @note Corresponds to NVIC_EnableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was enabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn); + +/**@brief Disable External Interrupt. + * @note Corresponds to NVIC_DisableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was disabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn); + +/**@brief Get Pending Interrupt. + * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. + * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. + * + * @retval ::NRF_SUCCESS The interrupt is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq); + +/**@brief Set Pending Interrupt. + * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt is set pending. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn); + +/**@brief Clear Pending Interrupt. + * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn); + +/**@brief Set Interrupt Priority. + * @note Corresponds to NVIC_SetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * @pre Priority is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. + * @param[in] priority A valid IRQ priority for use by the application. + * + * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority); + +/**@brief Get Interrupt Priority. + * @note Corresponds to NVIC_GetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. + * @param[out] p_priority Return value from NVIC_GetPriority. + * + * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority); + +/**@brief System Reset. + * @note Corresponds to NVIC_SystemReset in CMSIS. + * + * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN + */ +__STATIC_INLINE uint32_t sd_nvic_SystemReset(void); + +/**@brief Enter critical region. + * + * @post Application interrupts will be disabled. + * @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each + * execution context + * @sa sd_nvic_critical_region_exit + * + * @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region. + * + * @retval ::NRF_SUCCESS + */ +__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region); + +/**@brief Exit critical region. + * + * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. + * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. + * + * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. + * + * @retval ::NRF_SUCCESS + */ +__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region); + +/**@} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE int __sd_nvic_irq_disable(void) +{ + int pm = __get_PRIMASK(); + __disable_irq(); + return pm; +} + +__STATIC_INLINE void __sd_nvic_irq_enable(void) +{ + __enable_irq(); +} + +__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn) +{ + if (IRQn < 32) + { + return ((1UL<= (1 << __NVIC_PRIO_BITS)) + { + return 0; + } +#ifdef NRF51 + if( priority == 0 + || priority == 2 + ) + { + return 0; + } +#endif +#ifdef NRF52 + if( priority == 0 + || priority == 1 + || priority == 4 + || priority == 5 + ) + { + return 0; + } +#endif + return 1; +} + + +__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn))) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + if (nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); + } + else + { + NVIC_EnableIRQ(IRQn); + } + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F)); + } + else + { + NVIC_DisableIRQ(IRQn); + } + + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + *p_pending_irq = NVIC_GetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + NVIC_SetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + NVIC_ClearPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (!__sd_nvic_is_app_accessible_priority(priority)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + NVIC_SetPriority(IRQn, (uint32_t)priority); + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + *p_priority = (NVIC_GetPriority(IRQn) & 0xFF); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SystemReset(void) +{ + NVIC_SystemReset(); + return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN; +} + +__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region) +{ + int was_masked = __sd_nvic_irq_disable(); + if (!nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__cr_flag = 1; + nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 ); + NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0; + #ifdef NRF52 + nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 ); + NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1; + #endif + *p_is_nested_critical_region = 0; + } + else + { + *p_is_nested_critical_region = 1; + } + if (!was_masked) + { + __sd_nvic_irq_enable(); + } + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) +{ + if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0)) + { + int was_masked = __sd_nvic_irq_disable(); + NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0]; + #ifdef NRF52 + NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1]; + #endif + nrf_nvic_state.__cr_flag = 0; + if (!was_masked) + { + __sd_nvic_irq_enable(); + } + } + + return NRF_SUCCESS; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_NVIC_H__ + +/**@} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_sd_def.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_sd_def.h new file mode 100644 index 0000000000000000000000000000000000000000..0b4d221d6a47d2a9b7e25b6deb90f293c480ce77 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_sd_def.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SD_DEF_H__ +#define NRF_SD_DEF_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SD_PPI_CHANNELS_USED 0xFFFE0000uL /**< PPI channels utilized by SotfDevice (not available to the application). */ +#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */ +#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */ +#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SD_DEF_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_sdm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_sdm.h new file mode 100644 index 0000000000000000000000000000000000000000..d20a65242ca7ec179b89e6936d131c8d3857c009 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_sdm.h @@ -0,0 +1,338 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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. + * + */ +/** + @defgroup nrf_sdm_api SoftDevice Manager API + @{ + + @brief APIs for SoftDevice management. + +*/ + +#ifndef NRF_SDM_H__ +#define NRF_SDM_H__ + +#include "nrf_svc.h" +#include "nrf.h" +#include "nrf_soc.h" +#include "nrf_error_sdm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ +#ifdef NRFSOC_DOXYGEN +/// Declared in nrf_mbr.h +#define MBR_SIZE 0 +#warning test +#endif + +/** @brief The major version for the SoftDevice binary distributed with this header file. */ +#define SD_MAJOR_VERSION (4) + +/** @brief The minor version for the SoftDevice binary distributed with this header file. */ +#define SD_MINOR_VERSION (0) + +/** @brief The bugfix version for the SoftDevice binary distributed with this header file. */ +#define SD_BUGFIX_VERSION (2) + +/** @brief The full version number for the SoftDevice binary this header file was distributed + * with, as a decimal number in the form Mmmmbbb, where: + * - M is major version (one or more digits) + * - mmm is minor version (three digits) + * - bbb is bugfix version (three digits). */ +#define SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION) + +/** @brief SoftDevice Manager SVC Base number. */ +#define SDM_SVC_BASE 0x10 + +/** @brief Invalid info field. Returned when an info field does not exist. */ +#define SDM_INFO_FIELD_INVALID (0) + +/** @brief Defines the SoftDevice Information Structure location (address) as an offset from +the start of the SoftDevice (without MBR)*/ +#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) + +/** @brief Defines the absolute SoftDevice Information Structure location (address) when the + * SoftDevice is installed just above the MBR (the usual case). */ +#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) + +/** @brief Defines the offset for the SoftDevice Information Structure size value relative to the + * SoftDevice base address. The size value is of type uint8_t. */ +#define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET) + +/** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address. + * The size value is of type uint32_t. */ +#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) + +/** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value + * is of type uint16_t. */ +#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) + +/** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID + * is of type uint32_t. */ +#define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10) + +/** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in + * the same format as @ref SD_VERSION, stored as an uint32_t. */ +#define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14) + +/** @brief Defines a macro for retrieving the actual SoftDevice Information Structure size value + * from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is + * installed just above the MBR (the usual case). */ +#define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *) ((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET))) + +/** @brief Defines a macro for retrieving the actual SoftDevice size value from a given base + * address. Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above + * the MBR (the usual case). */ +#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET))) + +/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use @ref + * MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual + * case). */ +#define SD_FWID_GET(baseaddr) (*((uint16_t *) ((baseaddr) + SD_FWID_OFFSET))) + +/** @brief Defines a macro for retrieving the actual SoftDevice ID from a given base address. Use + * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the + * usual case). */ +#define SD_ID_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (*((uint32_t *) ((baseaddr) + SD_ID_OFFSET))) : SDM_INFO_FIELD_INVALID) + +/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use @ref + * MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual + * case). */ +#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID) + +/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges + * @{ */ +#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */ +#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */ +/**@} */ + +/**@defgroup NRF_FAULT_IDS Fault ID types + * @{ */ +#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter is reserved for future used. */ +#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access (nRF52 only). The info parameter will contain 0x00000000, in case of SoftDevice RAM + access violation. In case of SoftDevice peripheral register violation the info parameter will contain the sub-region number of PREGION[0], on whose address range the disallowed + write access caused the memory access fault. */ +/**@} */ + +/** @} */ + +/** @addtogroup NRF_SDM_ENUMS Enumerations + * @{ */ + +/**@brief nRF SoftDevice Manager API SVC numbers. */ +enum NRF_SD_SVCS +{ + SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */ + SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */ + SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */ + SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */ + SVC_SDM_LAST /**< Placeholder for last SDM SVC */ +}; + +/** @} */ + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ + +/**@defgroup NRF_CLOCK_LF_XTAL_ACCURACY Clock accuracy + * @{ */ + +#define NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM (0) /**< Default: 250 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_500_PPM (1) /**< 500 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_150_PPM (2) /**< 150 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_100_PPM (3) /**< 100 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_75_PPM (4) /**< 75 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_50_PPM (5) /**< 50 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_30_PPM (6) /**< 30 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM (7) /**< 20 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_10_PPM (8) /**< 10 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_5_PPM (9) /**< 5 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_2_PPM (10) /**< 2 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_1_PPM (11) /**< 1 ppm */ + +/** @} */ + +/**@defgroup NRF_CLOCK_LF_SRC Possible LFCLK oscillator sources + * @{ */ + +#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */ +#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */ +#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */ + +/** @} */ + +/** @} */ + +/** @addtogroup NRF_SDM_TYPES Types + * @{ */ + +/**@brief Type representing LFCLK oscillator source. */ +typedef struct +{ + uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */ + uint8_t rc_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second + units (nRF51: 1-64, nRF52: 1-32). + @note To avoid excessive clock drift, 0.5 degrees Celsius is the + maximum temperature change allowed in one calibration timer + interval. The interval should be selected to ensure this. + + @note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. */ + uint8_t rc_temp_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: How often (in number of calibration + intervals) the RC oscillator shall be calibrated if the temperature + hasn't changed. + 0: Always calibrate even if the temperature hasn't changed. + 1: Only calibrate if the temperature has changed (nRF51 only). + 2-33: Check the temperature and only calibrate if it has changed, + however calibration will take place every rc_temp_ctiv + intervals in any case. + + @note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. + + @note For nRF52, the application must ensure calibration at least once + every 8 seconds to ensure +/-250 ppm clock stability. The + recommended configuration for NRF_CLOCK_LF_SRC_RC on nRF52 is + rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at + least once every 8 seconds and for temperature changes of 0.5 + degrees Celsius every 4 seconds. See the Product Specification + for the nRF52 device being used for more information.*/ + uint8_t xtal_accuracy; /**< External crystal clock accuracy used in the LL to compute timing + windows, see @ref NRF_CLOCK_LF_XTAL_ACCURACY. + + @note For the NRF_CLOCK_LF_SRC_RC clock source this parameter is ignored. */ +} nrf_clock_lf_cfg_t; + +/**@brief Fault Handler type. + * + * When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back. + * The protocol stack will be in an undefined state when this happens and the only way to recover will be to + * perform a reset, using e.g. CMSIS NVIC_SystemReset(). + * If the application returns from the fault handler the SoftDevice will call NVIC_SystemReset(). + * + * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault. + * @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details. + * + * @note When id is set to NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time when + * the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the one that triggered the fault. + */ +typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info); + +/** @} */ + +/** @addtogroup NRF_SDM_FUNCTIONS Functions + * @{ */ + +/**@brief Enables the SoftDevice and by extension the protocol stack. + * + * @note Some care must be taken if a low frequency clock source is already running when calling this function: + * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new + * clock source will be started. + * + * @note This function has no effect when returning with an error. + * + * @post If return code is ::NRF_SUCCESS + * - SoC library and protocol stack APIs are made available. + * - A portion of RAM will be unavailable (see relevant SDS documentation). + * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). + * - Interrupts will not arrive from protected peripherals or interrupts. + * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice. + * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). + * - Chosen low frequency clock source will be running. + * + * @param p_clock_lf_cfg Low frequency clock source and accuracy. + If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2 + In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock. + * @param fault_handler Callback to be invoked in case of fault, cannot be NULL. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated. + * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level. + * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. + */ +SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler)); + + +/**@brief Disables the SoftDevice and by extension the protocol stack. + * + * Idempotent function to disable the SoftDevice. + * + * @post SoC library and protocol stack APIs are made unavailable. + * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest). + * @post All peripherals used by the SoftDevice will be reset to default values. + * @post All of RAM become available. + * @post All interrupts are forwarded to the application. + * @post LFCLK source chosen in ::sd_softdevice_enable will be left running. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); + +/**@brief Check if the SoftDevice is enabled. + * + * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled)); + +/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice + * + * This function is only intended to be called when a bootloader is enabled. + * + * @param[in] address The base address of the interrupt vector table for forwarded interrupts. + + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_SDM_H__ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_soc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_soc.h new file mode 100644 index 0000000000000000000000000000000000000000..e85f178275fbe623369abdec90b9385a9ad3dfb6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_soc.h @@ -0,0 +1,929 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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. + * + */ +/** + * @defgroup nrf_soc_api SoC Library API + * @{ + * + * @brief APIs for the SoC library. + * + */ + +#ifndef NRF_SOC_H__ +#define NRF_SOC_H__ + +#include +#include +#include "nrf_svc.h" +#include "nrf.h" + +#include "nrf_error_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup NRF_SOC_DEFINES Defines + * @{ */ + +/**@brief The number of the lowest SVC number reserved for the SoC library. */ +#define SOC_SVC_BASE (0x20) /**< Base value for SVCs that are available when the SoftDevice is disabled. */ +#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */ + +/**@brief Guaranteed time for application to process radio inactive notification. */ +#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62) + +/**@brief The minimum allowed timeslot extension time. */ +#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200) + +#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */ +#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */ +#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */ + +#ifdef NRF51 +#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ +#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */ +#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */ +#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. */ +#endif +#ifdef NRF52 +#define SD_EVT_IRQn (SWI2_EGU2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ +#define SD_EVT_IRQHandler (SWI2_EGU2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. + The default interrupt priority for this handler is set to 4 */ +#define RADIO_NOTIFICATION_IRQn (SWI1_EGU1_IRQn) /**< The radio notification IRQ number. */ +#define RADIO_NOTIFICATION_IRQHandler (SWI1_EGU1_IRQHandler) /**< The radio notification IRQ handler. + The default interrupt priority for this handler is set to 4 */ +#endif + +#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */ +#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */ + +#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */ + +#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */ + +#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */ + +/**@} */ + +/**@addtogroup NRF_SOC_ENUMS Enumerations + * @{ */ + +/**@brief The SVC numbers used by the SVC functions in the SoC library. */ +enum NRF_SOC_SVCS +{ + SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE, + SD_PPI_CHANNEL_ENABLE_SET, + SD_PPI_CHANNEL_ENABLE_CLR, + SD_PPI_CHANNEL_ASSIGN, + SD_PPI_GROUP_TASK_ENABLE, + SD_PPI_GROUP_TASK_DISABLE, + SD_PPI_GROUP_ASSIGN, + SD_PPI_GROUP_GET, + SD_FLASH_PAGE_ERASE, + SD_FLASH_WRITE, + SD_FLASH_PROTECT, + SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE, + SD_MUTEX_ACQUIRE, + SD_MUTEX_RELEASE, + SD_RAND_APPLICATION_POOL_CAPACITY_GET, + SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, + SD_RAND_APPLICATION_VECTOR_GET, + SD_POWER_MODE_SET, + SD_POWER_SYSTEM_OFF, + SD_POWER_RESET_REASON_GET, + SD_POWER_RESET_REASON_CLR, + SD_POWER_POF_ENABLE, + SD_POWER_POF_THRESHOLD_SET, + SD_POWER_RAM_POWER_SET, + SD_POWER_RAM_POWER_CLR, + SD_POWER_RAM_POWER_GET, + SD_POWER_GPREGRET_SET, + SD_POWER_GPREGRET_CLR, + SD_POWER_GPREGRET_GET, + SD_POWER_DCDC_MODE_SET, + SD_APP_EVT_WAIT, + SD_CLOCK_HFCLK_REQUEST, + SD_CLOCK_HFCLK_RELEASE, + SD_CLOCK_HFCLK_IS_RUNNING, + SD_RADIO_NOTIFICATION_CFG_SET, + SD_ECB_BLOCK_ENCRYPT, + SD_ECB_BLOCKS_ENCRYPT, + SD_RADIO_SESSION_OPEN, + SD_RADIO_SESSION_CLOSE, + SD_RADIO_REQUEST, + SD_EVT_GET, + SD_TEMP_GET, + SVC_SOC_LAST +}; + +/**@brief Possible values of a ::nrf_mutex_t. */ +enum NRF_MUTEX_VALUES +{ + NRF_MUTEX_FREE, + NRF_MUTEX_TAKEN +}; + +/**@brief Power modes. */ +enum NRF_POWER_MODES +{ + NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ + NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */ +}; + + +/**@brief Power failure thresholds */ +enum NRF_POWER_THRESHOLDS +{ + NRF_POWER_THRESHOLD_V17 = 4UL, /**< 1.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V18, /**< 1.8 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V19, /**< 1.9 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V20, /**< 2.0 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V22, /**< 2.2 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V24, /**< 2.4 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V26, /**< 2.6 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V27, /**< 2.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V28 /**< 2.8 Volts power failure threshold. */ +}; + + +/**@brief DC/DC converter modes. */ +enum NRF_POWER_DCDC_MODES +{ + NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ + NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ +}; + +/**@brief Radio notification distances. */ +enum NRF_RADIO_NOTIFICATION_DISTANCES +{ + NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */ + NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */ +}; + + +/**@brief Radio notification types. */ +enum NRF_RADIO_NOTIFICATION_TYPES +{ + NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */ +}; + +/**@brief The Radio signal callback types. */ +enum NRF_RADIO_CALLBACK_SIGNAL_TYPE +{ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */ +}; + +/**@brief The actions requested by the signal callback. + * + * This code gives the SOC instructions about what action to take when the signal callback has + * returned. + */ +enum NRF_RADIO_SIGNAL_CALLBACK_ACTION +{ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current timeslot (maximum execution time for this action is when the extension succeeded). */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */ +}; + +/**@brief Radio timeslot high frequency clock source configuration. */ +enum NRF_RADIO_HFCLK_CFG +{ + NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the + external crystal for the whole duration of the timeslot. This should be the + preferred option for events that use the radio or require high timing accuracy. + @note The SoftDevice will automatically turn on and off the external crystal, + at the beginning and end of the timeslot, respectively. The crystal may also + intentionally be left running after the timeslot, in cases where it is needed + by the SoftDevice shortly after the end of the timeslot. */ + NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots. + The RC oscillator may be the clock source in part or for the whole duration of the timeslot. + The RC oscillator's accuracy must therefore be taken into consideration. + @note If the application will use the radio peripheral in timeslots with this configuration, + it must make sure that the crystal is running and stable before starting the radio. */ +}; + +/**@brief Radio timeslot priorities. */ +enum NRF_RADIO_PRIORITY +{ + NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */ + NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activities of the SoftDevice stack(s)). */ +}; + +/**@brief Radio timeslot request type. */ +enum NRF_RADIO_REQUEST_TYPE +{ + NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */ + NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */ +}; + +/**@brief SoC Events. */ +enum NRF_SOC_EVTS +{ + NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ + NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ + NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ + NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ + NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ + NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ + NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */ + NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */ + NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */ + NRF_EVT_NUMBER_OF_EVTS +}; + +/**@} */ + + +/**@addtogroup NRF_SOC_STRUCTURES Structures + * @{ */ + +/**@brief Represents a mutex for use with the nrf_mutex functions. + * @note Accessing the value directly is not safe, use the mutex functions! + */ +typedef volatile uint8_t nrf_mutex_t; + +/**@brief Parameters for a request for a timeslot as early as possible. */ +typedef struct +{ + uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ + uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ + uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */ + uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */ +} nrf_radio_request_earliest_t; + +/**@brief Parameters for a normal radio timeslot request. */ +typedef struct +{ + uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ + uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ + uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */ + uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */ +} nrf_radio_request_normal_t; + +/**@brief Radio timeslot request parameters. */ +typedef struct +{ + uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */ + union + { + nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */ + nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */ + } params; /**< Parameter union. */ +} nrf_radio_request_t; + +/**@brief Return parameters of the radio timeslot signal callback. */ +typedef struct +{ + uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */ + union + { + struct + { + nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */ + } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */ + struct + { + uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ + } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */ + } params; /**< Parameter union. */ +} nrf_radio_signal_callback_return_param_t; + +/**@brief The radio timeslot signal callback type. + * + * @note In case of invalid return parameters, the radio timeslot will automatically end + * immediately after returning from the signal callback and the + * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent. + * @note The returned struct pointer must remain valid after the signal callback + * function returns. For instance, this means that it must not point to a stack variable. + * + * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE. + * + * @return Pointer to structure containing action requested by the application. + */ +typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type); + +/**@brief AES ECB parameter typedefs */ +typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH]; /**< Encryption key type. */ +typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */ +typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */ + +/**@brief AES ECB data structure */ +typedef struct +{ + soc_ecb_key_t key; /**< Encryption key. */ + soc_ecb_cleartext_t cleartext; /**< Cleartext data. */ + soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */ +} nrf_ecb_hal_data_t; + +/**@brief AES ECB block. Used to provide multiple blocks in a single call + to @ref sd_ecb_blocks_encrypt.*/ +typedef struct +{ + soc_ecb_key_t const * p_key; /**< Pointer to the Encryption key. */ + soc_ecb_cleartext_t const * p_cleartext; /**< Pointer to the Cleartext data. */ + soc_ecb_ciphertext_t * p_ciphertext; /**< Pointer to the Ciphertext data. */ +} nrf_ecb_hal_data_block_t; + +/**@} */ + +/**@addtogroup NRF_SOC_FUNCTIONS Functions + * @{ */ + +/**@brief Initialize a mutex. + * + * @param[in] p_mutex Pointer to the mutex to initialize. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex)); + +/**@brief Attempt to acquire a mutex. + * + * @param[in] p_mutex Pointer to the mutex to acquire. + * + * @retval ::NRF_SUCCESS The mutex was successfully acquired. + * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired. + */ +SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex)); + +/**@brief Release a mutex. + * + * @param[in] p_mutex Pointer to the mutex to release. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex)); + +/**@brief Query the capacity of the application random pool. + * + * @param[out] p_pool_capacity The capacity of the pool. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); + +/**@brief Get number of random bytes available to the application. + * + * @param[out] p_bytes_available The number of bytes currently available in the pool. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); + +/**@brief Get random bytes from the application pool. + * + * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes. + * @param[in] length Number of bytes to take from pool and place in p_buff. + * + * @retval ::NRF_SUCCESS The requested bytes were written to p_buff. + * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available. +*/ +SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); + +/**@brief Gets the reset reason register. + * + * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason)); + +/**@brief Clears the bits of the reset reason register. + * + * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk)); + +/**@brief Sets the power mode when in CPU sleep. + * + * @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait + * + * @retval ::NRF_SUCCESS The power mode was set. + * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown. + */ +SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode)); + +/**@brief Puts the chip in System OFF mode. + * + * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN + */ +SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void)); + +/**@brief Enables or disables the power-fail comparator. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable)); + +/**@brief Sets the power-fail threshold value. + * + * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS. + * + * @retval ::NRF_SUCCESS The power failure threshold was set. + * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. + */ +SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold)); + +/**@brief Writes the NRF_POWER->RAM[index].POWERSET register. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERSET register to write to. + * @param[in] ram_powerset Contains the word to write to the NRF_POWER->RAM[index].POWERSET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_SET, uint32_t, sd_power_ram_power_set(uint8_t index, uint32_t ram_powerset)); + +/**@brief Writes the NRF_POWER->RAM[index].POWERCLR register. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERCLR register to write to. + * @param[in] ram_powerclr Contains the word to write to the NRF_POWER->RAM[index].POWERCLR register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_CLR, uint32_t, sd_power_ram_power_clr(uint8_t index, uint32_t ram_powerclr)); + +/**@brief Get contents of NRF_POWER->RAM[index].POWER register, indicates power status of RAM[index] blocks. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWER register to read from. + * @param[out] p_ram_power Content of NRF_POWER->RAM[index].POWER register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_GET, uint32_t, sd_power_ram_power_get(uint8_t index, uint32_t * p_ram_power)); + +/**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[in] gpregret_msk Bits to be set in the GPREGRET register. + * + * @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk)); + +/**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[in] gpregret_msk Bits to be clear in the GPREGRET register. + * + * @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk)); + +/**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[out] p_gpregret Contents of the GPREGRET register. + * + * @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, uint32_t *p_gpregret)); + +/**@brief Sets the DCDC mode. + * + * Enable or disable the DCDC peripheral. + * + * @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid. + */ +SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode)); + +/**@brief Request the high frequency crystal oscillator. + * + * Will start the high frequency crystal oscillator, the startup time of the crystal varies + * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started. + * + * @see sd_clock_hfclk_is_running + * @see sd_clock_hfclk_release + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void)); + +/**@brief Releases the high frequency crystal oscillator. + * + * Will stop the high frequency crystal oscillator, this happens immediately. + * + * @see sd_clock_hfclk_is_running + * @see sd_clock_hfclk_request + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void)); + +/**@brief Checks if the high frequency crystal oscillator is running. + * + * @see sd_clock_hfclk_request + * @see sd_clock_hfclk_release + * + * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running)); + +/**@brief Waits for an application event. + * + * An application event is either an application interrupt or a pended interrupt when the interrupt + * is disabled. + * + * When the application waits for an application event by calling this function, an interrupt that + * is enabled will be taken immediately on pending since this function will wait in thread mode, + * then the execution will return in the application's main thread. + * + * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M + * MCU's System Control Register (SCR), CMSIS_SCB. In that case, when a disabled interrupt gets + * pended, this function will return to the application's main thread. + * + * @note The application must ensure that the pended flag is cleared using ::sd_nvic_ClearPendingIRQ + * in order to sleep using this function. This is only necessary for disabled interrupts, as + * the interrupt handler will clear the pending flag automatically for enabled interrupts. + * + * @note If an application interrupt has happened since the last time sd_app_evt_wait was + * called this function will return immediately and not go to sleep. This is to avoid race + * conditions that can occur when a flag is updated in the interrupt handler and processed + * in the main loop. + * + * @post An application interrupt has happened or a interrupt pending flag is set. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void)); + +/**@brief Get PPI channel enable register contents. + * + * @param[out] p_channel_enable The contents of the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable)); + +/**@brief Set PPI channel enable register. + * + * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk)); + +/**@brief Clear PPI channel enable register. + * + * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk)); + +/**@brief Assign endpoints to a PPI channel. + * + * @param[in] channel_num Number of the PPI channel to assign. + * @param[in] evt_endpoint Event endpoint of the PPI channel. + * @param[in] task_endpoint Task endpoint of the PPI channel. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint)); + +/**@brief Task to enable a channel group. + * + * @param[in] group_num Number of the channel group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num)); + +/**@brief Task to disable a channel group. + * + * @param[in] group_num Number of the PPI group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num)); + +/**@brief Assign PPI channels to a channel group. + * + * @param[in] group_num Number of the channel group. + * @param[in] channel_msk Mask of the channels to assign to the group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk)); + +/**@brief Gets the PPI channels of a channel group. + * + * @param[in] group_num Number of the channel group. + * @param[out] p_channel_msk Mask of the channels assigned to the group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk)); + +/**@brief Configures the Radio Notification signal. + * + * @note + * - The notification signal latency depends on the interrupt priority settings of SWI used + * for notification signal. + * - To ensure that the radio notification signal behaves in a consistent way, the radio + * notifications must be configured when there is no protocol stack or other SoftDevice + * activity in progress. It is recommended that the radio notification signal is + * configured directly after the SoftDevice has been enabled. + * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice + * will interrupt the application to do Radio Event preparation. + * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have + * to shorten the connection events to have time for the Radio Notification signals. + * + * @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES. + * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio + * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is + * recommended (but not required) to be used with + * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE. + * + * @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES. + * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or + * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. + * + * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid. + * @retval ::NRF_ERROR_INVALID_STATE A protocol stack or other SoftDevice is running. Stop all + * running activities and retry. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance)); + +/**@brief Encrypts a block according to the specified parameters. + * + * 128-bit AES encryption. + * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * + * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input + * parameters and one output parameter). + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data)); + +/**@brief Encrypts multiple data blocks provided as an array of data block structures. + * + * @details: Performs 128-bit AES encryption on multiple data blocks + * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * + * @param[in] block_count Count of blocks in the p_data_blocks array. + * @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of + * @ref nrf_ecb_hal_data_block_t structures. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks)); + +/**@brief Gets any pending events generated by the SoC API. + * + * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned. + * + * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending. + * + * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter. + * @retval ::NRF_ERROR_NOT_FOUND No pending events. + */ +SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id)); + +/**@brief Get the temperature measured on the chip + * + * This function will block until the temperature measurement is done. + * It takes around 50 us from call to return. + * + * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees Celsius. + * + * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp + */ +SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp)); + +/**@brief Flash Write +* +* Commands to write a buffer to flash +* +* If the SoftDevice is enabled: +* This call initiates the flash access command, and its completion will be communicated to the +* application with exactly one of the following events: +* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. +* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. +* +* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the + * write has been completed +* +* @note +* - This call takes control over the radio and the CPU during flash erase and write to make sure that +* they will not interfere with the flash access. This means that all interrupts will be blocked +* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual +* and the command parameters). +* - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS +* or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled. +* +* +* @param[in] p_dst Pointer to start of flash location to be written. +* @param[in] p_src Pointer to buffer with data to be written. +* @param[in] size Number of 32-bit words to write. Maximum size is 256 32-bit words for nRF51 and 1024 for nRF52. +* +* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. +* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. +* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size. +* @retval ::NRF_ERROR_FORBIDDEN Tried to write to or read from protected location. +* @retval ::NRF_SUCCESS The command was accepted. +*/ +SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * p_dst, uint32_t const * p_src, uint32_t size)); + + +/**@brief Flash Erase page +* +* Commands to erase a flash page +* If the SoftDevice is enabled: +* This call initiates the flash access command, and its completion will be communicated to the +* application with exactly one of the following events: +* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. +* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. +* +* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the +* erase has been completed +* +* @note +* - This call takes control over the radio and the CPU during flash erase and write to make sure that +* they will not interfere with the flash access. This means that all interrupts will be blocked +* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual +* and the command parameters). +* +* +* @param[in] page_number Page number of the page to erase +* +* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. +* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page. +* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. +* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a protected page. +* @retval ::NRF_SUCCESS The command was accepted. +*/ +SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)); + + +/**@brief Flash Protection set + * + * Commands to set the flash protection configuration registers. + On nRF51 this sets the PROTENSETx registers of the MPU peripheral. + On nRF52 this sets the CONFIGx registers of the BPROT peripheral. + * + * @note To read the values read them directly. They are only write-protected. + * + * @param[in] block_cfg0 Value to be written to the configuration register. + * @param[in] block_cfg1 Value to be written to the configuration register. + * @param[in] block_cfg2 Value to be written to the configuration register (ignored on nRF51). + * @param[in] block_cfg3 Value to be written to the configuration register (ignored on nRF51). + * + * @retval ::NRF_ERROR_FORBIDDEN Tried to protect the SoftDevice. + * @retval ::NRF_SUCCESS Values successfully written to configuration registers. + */ +SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t block_cfg0, uint32_t block_cfg1, uint32_t block_cfg2, uint32_t block_cfg3)); + +/**@brief Opens a session for radio timeslot requests. + * + * @note Only one session can be open at a time. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot + * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed + * by the application. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0 + * interrupt occurs. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO + * interrupt occurs. + * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This + * implies that none of the sd_* API calls can be used from p_radio_signal_callback(). + * + * @param[in] p_radio_signal_callback The signal callback. + * + * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer. + * @retval ::NRF_ERROR_BUSY If session cannot be opened. + * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. + * @retval ::NRF_SUCCESS Otherwise. + */ + SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback)); + +/**@brief Closes a session for radio timeslot requests. + * + * @note Any current radio timeslot will be finished before the session is closed. + * @note If a radio timeslot is scheduled when the session is closed, it will be canceled. + * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED + * event is received. + * + * @retval ::NRF_ERROR_FORBIDDEN If session not opened. + * @retval ::NRF_ERROR_BUSY If session is currently being closed. + * @retval ::NRF_SUCCESS Otherwise. + */ + SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void)); + +/**@brief Requests a radio timeslot. + * + * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST + * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST. + * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by + * p_request->distance_us and is given relative to the start of the previous timeslot. + * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event. + * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event. + * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths. + * @note If an opportunity for the first radio timeslot is not found before 100 ms after the call to this + * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent. + * The application may then try to schedule the first radio timeslot again. + * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START). + * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS. + * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us. + * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the + * specified radio timeslot start, but this does not affect the actual start time of the timeslot. + * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency + * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is + * guaranteed to be clocked from the external crystal. + * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral + * during the radio timeslot. + * + * @param[in] p_request Pointer to the request parameters. + * + * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE. + * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid. + * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid. + * @retval ::NRF_SUCCESS Otherwise. + */ + SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t const * p_request)); + +/**@} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_SOC_H__ + +/**@} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_svc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_svc.h new file mode 100644 index 0000000000000000000000000000000000000000..31ea671529ff857e5f47ac5002c97cb20e9d822f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/headers/nrf_svc.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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. + * + */ + +#ifndef NRF_SVC__ +#define NRF_SVC__ + +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SVCALL_AS_NORMAL_FUNCTION +#define SVCALL(number, return_type, signature) return_type signature +#else + +#ifndef SVCALL +#if defined (__CC_ARM) +#define SVCALL(number, return_type, signature) return_type __svc(number) signature +#elif defined (__GNUC__) +#ifdef __cplusplus +#define GCC_CAST_CPP (uint16_t) +#else +#define GCC_CAST_CPP +#endif +#define SVCALL(number, return_type, signature) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ + __attribute__((naked)) \ + __attribute__((unused)) \ + static return_type signature \ + { \ + __asm( \ + "svc %0\n" \ + "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \ + ); \ + } \ + _Pragma("GCC diagnostic pop") + +#elif defined (__ICCARM__) +#define PRAGMA(x) _Pragma(#x) +#define SVCALL(number, return_type, signature) \ +PRAGMA(swi_number = (number)) \ + __swi return_type signature; +#else +#define SVCALL(number, return_type, signature) return_type signature +#endif +#endif // SVCALL + +#endif // SVCALL_AS_NORMAL_FUNCTION + +#ifdef __cplusplus +} +#endif +#endif // NRF_SVC__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/hex/s132_nrf52_4.0.2_licence-agreement.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/hex/s132_nrf52_4.0.2_licence-agreement.txt new file mode 100644 index 0000000000000000000000000000000000000000..09a78bbc69f5f858448e42bb6c16feced2332620 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/hex/s132_nrf52_4.0.2_licence-agreement.txt @@ -0,0 +1,96 @@ +S110/S120/S130/S132 license agreement + + +NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT + +License Agreement for the Nordic Semiconductor ASA ("Nordic") S110, S120, S130 and S132 Bluetooth SoftDevice software packages +("SoftDevice"). + +You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before +downloading, installing and/or using any software or content in the SoftDevice provided herewith. + +YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS +OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF +THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. + +IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE +INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE. + +1. Grant of License +Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license +("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated +in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this +agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit. + +2. Title +Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and +other intellectual property rights in and to the SoftDevice. + +3. No Modifications or Reverse Engineering +Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code +parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code. + +4. Distribution Restrictions +Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party. +Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein. +Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee +necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making +such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice. + +5. No Other Rights +Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be +contrary to this Agreement. + +6. Fees +Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to +comply with the Agreement. + +7. DISCLAIMER OF WARRANTY +THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS +LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR +THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE +IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE +REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE. +LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S +INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. + + +8. No Support +Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, +bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice. + +9. Limitation of Liability +In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of +procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any +special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, +tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers, +licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or +limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to +USD 50. + +10. Breach of Contract +Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably +attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both +direct and indirect costs for Nordic and its licensors. + +11. Indemnity +Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and +agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which +is not due to causes for which Nordic is responsible. + +12. Governing Law +This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. + +13. Assignment +Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. + +14. Termination +Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this +Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any +other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. + +15. Third party beneficiaries +Nordic’s licensors are intended third party beneficiaries under this Agreement. + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/toolchain/armgcc/armgcc_s132_nrf52832_xxaa.ld b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/toolchain/armgcc/armgcc_s132_nrf52832_xxaa.ld new file mode 100644 index 0000000000000000000000000000000000000000..20f024b4d0803c88276ec620d51db99c24510e3e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/toolchain/armgcc/armgcc_s132_nrf52832_xxaa.ld @@ -0,0 +1,32 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000 + RAM (rwx) : ORIGIN = 0x200013c0, LENGTH = 0xec40 +} + +SECTIONS +{ + .fs_data : + { + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM +} INSERT AFTER .data; + +SECTIONS +{ + .pwr_mgmt_data : + { + PROVIDE(__start_pwr_mgmt_data = .); + KEEP(*(SORT(.pwr_mgmt_data*))) + PROVIDE(__stop_pwr_mgmt_data = .); + } > FLASH +} INSERT AFTER .text + +INCLUDE "nrf5x_common.ld" diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/toolchain/iar/iar_s132_nrf52832_xxaa.icf b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/toolchain/iar/iar_s132_nrf52832_xxaa.icf new file mode 100644 index 0000000000000000000000000000000000000000..12982471b2182478505c4f2d6391ef81ebcef281 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s132/toolchain/iar/iar_s132_nrf52832_xxaa.icf @@ -0,0 +1,34 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x1f000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x1f000; +define symbol __ICFEDIT_region_ROM_end__ = 0x7ffff; +define symbol __ICFEDIT_region_RAM_start__ = 0x200013c0; +define symbol __ICFEDIT_region_RAM_end__ = 0x2000ffff; +export symbol __ICFEDIT_region_RAM_start__; +export symbol __ICFEDIT_region_RAM_end__; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x800; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +keep { section .intvec }; +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, + block HEAP }; + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_licence-agreement.pdf b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_licence-agreement.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1a1a731d3ade66c29e06ca096207060cb04bead6 Binary files /dev/null and b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_licence-agreement.pdf differ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_licence-agreement.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_licence-agreement.txt new file mode 100644 index 0000000000000000000000000000000000000000..b8d26c9a84f2be533482bc230dc83d5a812009aa --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_licence-agreement.txt @@ -0,0 +1,96 @@ +S110/S120/S130/S132/S140 license agreement + + +NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT + +License Agreement for the Nordic Semiconductor ASA ("Nordic") S110, S120, S130, S132, and S140 Bluetooth SoftDevice software packages +("SoftDevice"). + +You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before +downloading, installing and/or using any software or content in the SoftDevice provided herewith. + +YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS +OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF +THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. + +IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE +INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE. + +1. Grant of License +Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license +("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated +in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this +agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit. + +2. Title +Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and +other intellectual property rights in and to the SoftDevice. + +3. No Modifications or Reverse Engineering +Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code +parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code. + +4. Distribution Restrictions +Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party. +Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein. +Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee +necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making +such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice. + +5. No Other Rights +Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be +contrary to this Agreement. + +6. Fees +Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to +comply with the Agreement. + +7. DISCLAIMER OF WARRANTY +THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS +LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR +THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE +IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE +REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE. +LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S +INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. + + +8. No Support +Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, +bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice. + +9. Limitation of Liability +In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of +procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any +special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, +tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers, +licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or +limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to +USD 50. + +10. Breach of Contract +Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably +attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both +direct and indirect costs for Nordic and its licensors. + +11. Indemnity +Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and +agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which +is not due to causes for which Nordic is responsible. + +12. Governing Law +This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. + +13. Assignment +Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. + +14. Termination +Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this +Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any +other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. + +15. Third party beneficiaries +Nordic’s licensors are intended third party beneficiaries under this Agreement. + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_migration-document.pdf b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_migration-document.pdf new file mode 100644 index 0000000000000000000000000000000000000000..802676219692617f575001412e6726f7af6f3342 Binary files /dev/null and b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_migration-document.pdf differ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_readme.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..2cce458228fd252b493d2da7450965411f5d8a58 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_readme.txt @@ -0,0 +1,10 @@ +s140_nrf52840_5.0.0-2.alpha + +This release consists of the following: + +- This readme file +- The s140_nrf52840_5.0.0-2.alpha API (SoftDevice header files) +- The s140_nrf52840_5.0.0-2.alpha license agreement +- The s140_nrf52840_5.0.0-2.alpha release notes +- The s140_nrf52840_5.0.0-2.alpha SoftDevice (binary hex file) +- The s140_nrf52840_5.0.0-2.alpha Migration Document diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_release-notes-update-1.pdf b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_release-notes-update-1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9ffceb9b56e62e50fbc8160acb532dda1e75ba68 Binary files /dev/null and b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/doc/s140_nrf52840_5.0.0-2.alpha_release-notes-update-1.pdf differ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble.h new file mode 100644 index 0000000000000000000000000000000000000000..c4835fa6ef73879185bc8a039ba42939d993cd6f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble.h @@ -0,0 +1,615 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_COMMON BLE SoftDevice Common + @{ + @defgroup ble_api Events, type definitions and API calls + @{ + + @brief Module independent events, type definitions and API calls for the BLE SoftDevice. + + */ + +#ifndef BLE_H__ +#define BLE_H__ + +#include "ble_ranges.h" +#include "ble_types.h" +#include "ble_gap.h" +#include "ble_l2cap.h" +#include "ble_gatt.h" +#include "ble_gattc.h" +#include "ble_gatts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations + * @{ */ + +/** + * @brief Common API SVC numbers. + */ +enum BLE_COMMON_SVCS +{ + SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */ + SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */ + SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific UUID. */ + SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */ + SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */ + SD_BLE_VERSION_GET, /**< Get the local version information (company ID, Link Layer Version, Link Layer Subversion). */ + SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */ + SD_BLE_OPT_SET, /**< Set a BLE option. */ + SD_BLE_OPT_GET, /**< Get a BLE option. */ + SD_BLE_CFG_SET, /**< Add a configuration to the BLE stack. */ +}; + +/** + * @brief BLE Module Independent Event IDs. + */ +enum BLE_COMMON_EVTS +{ + BLE_EVT_USER_MEM_REQUEST = BLE_EVT_BASE, /**< User Memory request. @ref ble_evt_user_mem_request_t */ + BLE_EVT_USER_MEM_RELEASE, /**< User Memory release. @ref ble_evt_user_mem_release_t */ +}; + +/**@brief BLE Connection Configuration IDs. + * + * IDs that uniquely identify a connection configuration. + */ +enum BLE_CONN_CFGS +{ + BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE, /**< BLE GAP specific connection configuration. */ + BLE_CONN_CFG_GATTC, /**< BLE GATTC specific connection configuration. */ + BLE_CONN_CFG_GATTS, /**< BLE GATTS specific connection configuration. */ + BLE_CONN_CFG_GATT, /**< BLE GATT specific connection configuration. */ +}; + +/**@brief BLE Common Configuration IDs. + * + * IDs that uniquely identify a common configuration. + */ +enum BLE_COMMON_CFGS +{ + BLE_COMMON_CFG_VS_UUID = BLE_CFG_BASE, /**< Vendor specific UUID configuration */ +}; + +/**@brief Common Option IDs. + * IDs that uniquely identify a common option. + */ +enum BLE_COMMON_OPTS +{ + BLE_COMMON_OPT_PA_LNA = BLE_OPT_BASE, /**< PA and LNA options */ + BLE_COMMON_OPT_CONN_EVT_EXT, /**< Extended connection events option */ +}; + +/** @} */ + +/** @addtogroup BLE_COMMON_DEFINES Defines + * @{ */ + +/** @brief Required pointer alignment for BLE Events. +*/ +#define BLE_EVT_PTR_ALIGNMENT 4 + +/** @brief Leaves the maximum of the two arguments. +*/ +#define BLE_MAX(a, b) ((a) < (b) ? (b) : (a)) + +/** @brief Maximum possible length for BLE Events. + * @note The highest value used for @ref ble_gatt_conn_cfg_t::att_mtu in any connection configuration shall be used as a parameter. + * If that value has not been configured for any connections then @ref BLE_GATT_ATT_MTU_DEFAULT must be used instead. +*/ +#define BLE_EVT_LEN_MAX(ATT_MTU) (BLE_MAX( \ + sizeof(ble_evt_t), \ + BLE_MAX( \ + offsetof(ble_evt_t, evt.gattc_evt.params.rel_disc_rsp.includes) + ((ATT_MTU) - 2) / 6 * sizeof(ble_gattc_include_t), \ + offsetof(ble_evt_t, evt.gattc_evt.params.attr_info_disc_rsp.info.attr_info16) + ((ATT_MTU) - 2) / 4 * sizeof(ble_gattc_attr_info16_t) \ + ) \ +)) + +/** @defgroup BLE_USER_MEM_TYPES User Memory Types + * @{ */ +#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */ +#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */ +/** @} */ + +/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific UUID counts + * @{ + */ +#define BLE_UUID_VS_COUNT_DEFAULT 10 /**< Default VS UUID count. */ +#define BLE_UUID_VS_COUNT_MAX 254 /**< Maximum VS UUID count. */ +/** @} */ + +/** @defgroup BLE_COMMON_CFG_DEFAULTS Configuration defaults. + * @{ + */ +#define BLE_CONN_CFG_TAG_DEFAULT 0 /**< Default configuration tag, SoftDevice default connection configuration. */ + +/** @} */ + +/** @} */ + +/** @addtogroup BLE_COMMON_STRUCTURES Structures + * @{ */ + +/**@brief User Memory Block. */ +typedef struct +{ + uint8_t *p_mem; /**< Pointer to the start of the user memory block. */ + uint16_t len; /**< Length in bytes of the user memory block. */ +} ble_user_mem_block_t; + +/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */ +typedef struct +{ + uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ +} ble_evt_user_mem_request_t; + +/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */ +typedef struct +{ + uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ + ble_user_mem_block_t mem_block; /**< User memory block */ +} ble_evt_user_mem_release_t; + +/**@brief Event structure for events not associated with a specific function module. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which this event occurred. */ + union + { + ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */ + ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */ + } params; /**< Event parameter union. */ +} ble_common_evt_t; + +/**@brief BLE Event header. */ +typedef struct +{ + uint16_t evt_id; /**< Value from a BLE__EVT series. */ + uint16_t evt_len; /**< Length in octets including this header. */ +} ble_evt_hdr_t; + +/**@brief Common BLE Event type, wrapping the module specific event reports. */ +typedef struct +{ + ble_evt_hdr_t header; /**< Event header. */ + union + { + ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ + ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ + ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ + ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ + } evt; /**< Event union. */ +} ble_evt_t; + + +/** + * @brief Version Information. + */ +typedef struct +{ + uint8_t version_number; /**< Link Layer Version number for BT 4.1 spec is 7 (https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer). */ + uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ + uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ +} ble_version_t; + +/** + * @brief Configuration parameters for the PA and LNA. + */ +typedef struct +{ + uint8_t enable :1; /**< Enable toggling for this amplifier */ + uint8_t active_high :1; /**< Set the pin to be active high */ + uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */ +} ble_pa_lna_cfg_t; + +/** + * @brief PA & LNA GPIO toggle configuration + * + * This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or + * a low noise amplifier. + * + * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided + * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * @note This feature is only supported for nRF52, on nRF51 @ref NRF_ERROR_NOT_SUPPORTED will always be returned. + * @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences + * and must be avoided by the application. + */ +typedef struct +{ + ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */ + ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */ + + uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */ + uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */ + uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */ +} ble_common_opt_pa_lna_t; + +/** + * @brief Configuration of extended BLE connection events. + * + * When enabled the SoftDevice will dynamically extend the connection event when possible. + * + * The connection event length is controlled by the connection configuration as set by @ref ble_gap_conn_cfg_t::event_length. + * The connection event can be extended if there is time to send another packet pair before the start of the next connection interval, + * and if there are no conflicts with other BLE roles requesting radio time. + * + * @note @ref sd_ble_opt_get is not supported for this option. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */ +} ble_common_opt_conn_evt_ext_t; + +/**@brief Option structure for common options. */ +typedef union +{ + ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */ + ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */ +} ble_common_opt_t; + +/**@brief Common BLE Option type, wrapping the module specific options. */ +typedef union +{ + ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */ + ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */ +} ble_opt_t; + +/**@brief BLE connection configuration type, wrapping the module specific configurations, set with + * @ref sd_ble_cfg_set. + * + * @note Connection configurations don't have to be set. + * In the case that no configurations has been set, or fewer connection configurations has been set than enabled connections, + * the default connection configuration will be automatically added for the remaining connections. + * When creating connections with the default configuration, @ref BLE_CONN_CFG_TAG_DEFAULT should be used in + * place of @ref ble_conn_cfg_t::conn_cfg_tag. See @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect()" + * + * @mscs + * @mmsc{@ref BLE_CONN_CFG} + * @endmscs + + */ +typedef struct +{ + uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect() + calls to select this configuration when creating a connection. + Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */ + union { + ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */ + ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */ + ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS this connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */ + ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT this connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */ + } params; /**< Connection configuration union. */ +} ble_conn_cfg_t; + +/** + * @brief Configuration of Vendor Specific UUIDs, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_PARAM Too many UUIDs configured. + */ +typedef struct +{ + uint8_t vs_uuid_count; /**< Number of 128-bit Vendor Specific UUID bases to allocate memory for. + Default value is @ref BLE_UUID_VS_COUNT_DEFAULT. Maximum value is + @ref BLE_UUID_VS_COUNT_MAX. */ +} ble_common_cfg_vs_uuid_t; + +/**@brief Common BLE Configuration type, wrapping the common configurations. */ +typedef union +{ + ble_common_cfg_vs_uuid_t vs_uuid_cfg; /**< Vendor specific UUID configuration, cfg_id is @ref BLE_COMMON_CFG_VS_UUID. */ +} ble_common_cfg_t; + +/**@brief BLE Configuration type, wrapping the module specific configurations. */ +typedef union +{ + ble_conn_cfg_t conn_cfg; /**< Connection specific configurations, cfg_id in @ref BLE_CONN_CFGS series. */ + ble_common_cfg_t common_cfg; /**< Global common configurations, cfg_id in @ref BLE_COMMON_CFGS series. */ + ble_gap_cfg_t gap_cfg; /**< Global GAP configurations, cfg_id in @ref BLE_GAP_CFGS series. */ + ble_gatts_cfg_t gatts_cfg; /**< Global GATTS configuration, cfg_id in @ref BLE_GATTS_CFGS series. */ +} ble_cfg_t; + +/** @} */ + +/** @addtogroup BLE_COMMON_FUNCTIONS Functions + * @{ */ + +/**@brief Enable the BLE stack + * + * @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the + * application RAM region (APP_RAM_BASE). On return, this will + * contain the minimum start address of the application RAM region + * required by the SoftDevice for this configuration. + * + * @note The memory requirement for a specific configuration will not increase between SoftDevices + * with the same major version number. + * + * @note The value of *p_app_ram_base when the app has done no custom configuration of the + * SoftDevice, i.e. the app has not called @ref sd_ble_cfg_set before @ref sd_ble_enable, can + * be found in the release notes. + * + * @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located + * between 0x20000000 and APP_RAM_BASE-1 and the application's RAM region is located between + * APP_RAM_BASE and the start of the call stack. + * + * @details This call initializes the BLE stack, no BLE related function other than @ref + * sd_ble_cfg_set can be called before this one. + * + * @mscs + * @mmsc{@ref BLE_COMMON_ENABLE} + * @endmscs + * + * @retval ::NRF_SUCCESS The BLE stack has been initialized successfully. + * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by *p_app_ram_base is not + * large enough to fit this configuration's memory requirement. Check *p_app_ram_base + * and set the start address of the application RAM region accordingly. + */ +SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(uint32_t * p_app_ram_base)); + +/**@brief Add configurations for the BLE stack + * + * @param[in] cfg_id Config ID, see @ref BLE_CONN_CFGS, @ref BLE_COMMON_CFGS, @ref + * BLE_GAP_CFGS or @ref BLE_GATTS_CFGS. + * @param[in] p_cfg Pointer to a ble_cfg_t structure containing the configuration value. + * @param[in] app_ram_base The start address of the application RAM region (APP_RAM_BASE). + * See @ref sd_ble_enable for details about APP_RAM_BASE. + * + * @note The memory requirement for a specific configuration will not increase between SoftDevices + * with the same major version number. + * + * @note If a configuration is set more than once, the last one set is the one that takes effect on + * @ref sd_ble_enable. + * + * @note Any part of the BLE stack that is NOT configured with @ref sd_ble_cfg_set will have default + * configuration. + * + * @note @ref sd_ble_cfg_set may be called at any time when the SoftDevice is enabled (see @ref + * sd_softdevice_enable) while the BLE part of the SoftDevice is not enabled (see @ref + * sd_ble_enable). + * + * @note Error codes for the configurations are described in the configuration structs. + * + * @mscs + * @mmsc{@ref BLE_COMMON_ENABLE} + * @endmscs + * + * @retval ::NRF_SUCCESS The configuration has been added successfully. + * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid cfg_id supplied. + * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by app_ram_base is not + * large enough to fit this configuration's memory requirement. + */ +SVCALL(SD_BLE_CFG_SET, uint32_t, sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t app_ram_base)); + +/**@brief Get an event from the pending events queue. + * + * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. + * This buffer must be aligned to the extend defined by @ref BLE_EVT_PTR_ALIGNMENT. + * The buffer should be interpreted as a @ref ble_evt_t struct. + * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length. + * + * @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that + * an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt. + * The application is free to choose whether to call this function from thread mode (main context) or directly from the + * Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher + * priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) + * every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so + * could potentially leave events in the internal queue without the application being aware of this fact. + * + * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to + * be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event, + * @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size. + * The maximum possible event length is defined by @ref BLE_EVT_LEN_MAX. The application may also "peek" the event length + * by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return: + * + * \code + * uint16_t len; + * errcode = sd_ble_evt_get(NULL, &len); + * \endcode + * + * @mscs + * @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC} + * @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled. + * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer. + */ +SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len)); + + +/**@brief Add a Vendor Specific base UUID. + * + * @details This call enables the application to add a vendor specific base UUID to the BLE stack's table, for later + * use with all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t + * format when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code + * paths. This is accomplished by extending the grouping mechanism that the Bluetooth SIG standard base UUID uses + * for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to + * @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the UUID field + * in the same structure contains the 2 bytes at indexes 12 and 13. The number of possible 128-bit UUIDs available to + * the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, + * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. + * + * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by + * the 16-bit uuid field in @ref ble_uuid_t. + * + * @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in + * p_uuid_type along with an NRF_SUCCESS error code. + * + * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding + * bytes 12 and 13. + * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored. + * + * @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID. + * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid. + * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs. + */ +SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type)); + + +/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure. + * + * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared + * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add + * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index + * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. + * + * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE. + * + * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). + * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. + * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length. + * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs. + */ +SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid)); + + +/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit). + * + * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed. + * + * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. + * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). + * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. + * + * @retval ::NRF_SUCCESS Successfully encoded into the buffer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type. + */ +SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le)); + + +/**@brief Get Version Information. + * + * @details This call allows the application to get the BLE stack version information. + * + * @param[out] p_version Pointer to a ble_version_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Version information stored successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure). + */ +SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version)); + + +/**@brief Provide a user memory block. + * + * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_block Pointer to a user memory block structure or NULL if memory is managed by the application. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully queued a response to the peer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending. + */ +SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)); + +/**@brief Set a BLE option. + * + * @details This call allows the application to set the value of an option. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @endmscs + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. + * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value. + * + * @retval ::NRF_SUCCESS Option set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. + */ +SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt)); + + +/**@brief Get a BLE option. + * + * @details This call allows the application to retrieve the value of an option. + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. + * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Option retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. + * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported. + * + */ +SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)); + +/** @} */ +#ifdef __cplusplus +} +#endif +#endif /* BLE_H__ */ + +/** + @} + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_err.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_err.h new file mode 100644 index 0000000000000000000000000000000000000000..36d54a0dc0bc96026da1040ea2c59eff36cc2cd0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_err.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_COMMON + @{ + @addtogroup nrf_error + @{ + @ingroup BLE_COMMON + @} + + @defgroup ble_err General error codes + @{ + + @brief General error code definitions for the BLE API. + + @ingroup BLE_COMMON +*/ +#ifndef NRF_BLE_ERR_H__ +#define NRF_BLE_ERR_H__ + +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* @defgroup BLE_ERRORS Error Codes + * @{ */ +#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */ +#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */ +#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */ +#define BLE_ERROR_NO_TX_PACKETS (NRF_ERROR_STK_BASE_NUM+0x004) /**< Not enough application packets available on this connection. */ +#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */ +#define BLE_ERROR_BLOCKED_BY_OTHER_LINKS (NRF_ERROR_STK_BASE_NUM+0x006) /**< The attempt to change link settings failed due to the scheduling of other links. */ +/** @} */ + + +/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges + * @brief Assignment of subranges for module specific error codes. + * @note For specific error codes, see ble_.h or ble_error_.h. + * @{ */ +#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */ +#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */ +#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */ +#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */ +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif + + +/** + @} + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_gap.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_gap.h new file mode 100644 index 0000000000000000000000000000000000000000..339db01fd18709c215e511f8fad8eee033222a40 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_gap.h @@ -0,0 +1,2211 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_GAP Generic Access Profile (GAP) + @{ + @brief Definitions and prototypes for the GAP interface. + */ + +#ifndef BLE_GAP_H__ +#define BLE_GAP_H__ + + +#include "ble_types.h" +#include "ble_ranges.h" +#include "nrf_svc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations + * @{ */ + +/**@brief GAP API SVC numbers. + */ +enum BLE_GAP_SVCS +{ + SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */ + SD_BLE_GAP_ADDR_GET, /**< Get own Bluetooth Address. */ + SD_BLE_GAP_WHITELIST_SET, /**< Set active whitelist. */ + SD_BLE_GAP_DEVICE_IDENTITIES_SET, /**< Set device identity list. */ + SD_BLE_GAP_PRIVACY_SET, /**< Set Privacy settings*/ + SD_BLE_GAP_PRIVACY_GET, /**< Get Privacy settings*/ + SD_BLE_GAP_ADV_DATA_SET, /**< Set Advertising Data. */ + SD_BLE_GAP_ADV_START, /**< Start Advertising. */ + SD_BLE_GAP_ADV_STOP, /**< Stop Advertising. */ + SD_BLE_GAP_CONN_PARAM_UPDATE, /**< Connection Parameter Update. */ + SD_BLE_GAP_DISCONNECT, /**< Disconnect. */ + SD_BLE_GAP_TX_POWER_SET, /**< Set TX Power. */ + SD_BLE_GAP_APPEARANCE_SET, /**< Set Appearance. */ + SD_BLE_GAP_APPEARANCE_GET, /**< Get Appearance. */ + SD_BLE_GAP_PPCP_SET, /**< Set PPCP. */ + SD_BLE_GAP_PPCP_GET, /**< Get PPCP. */ + SD_BLE_GAP_DEVICE_NAME_SET, /**< Set Device Name. */ + SD_BLE_GAP_DEVICE_NAME_GET, /**< Get Device Name. */ + SD_BLE_GAP_AUTHENTICATE, /**< Initiate Pairing/Bonding. */ + SD_BLE_GAP_SEC_PARAMS_REPLY, /**< Reply with Security Parameters. */ + SD_BLE_GAP_AUTH_KEY_REPLY, /**< Reply with an authentication key. */ + SD_BLE_GAP_LESC_DHKEY_REPLY, /**< Reply with an LE Secure Connections DHKey. */ + SD_BLE_GAP_KEYPRESS_NOTIFY, /**< Notify of a keypress during an authentication procedure. */ + SD_BLE_GAP_LESC_OOB_DATA_GET, /**< Get the local LE Secure Connections OOB data. */ + SD_BLE_GAP_LESC_OOB_DATA_SET, /**< Set the remote LE Secure Connections OOB data. */ + SD_BLE_GAP_ENCRYPT, /**< Initiate encryption procedure. */ + SD_BLE_GAP_SEC_INFO_REPLY, /**< Reply with Security Information. */ + SD_BLE_GAP_CONN_SEC_GET, /**< Obtain connection security level. */ + SD_BLE_GAP_RSSI_START, /**< Start reporting of changes in RSSI. */ + SD_BLE_GAP_RSSI_STOP, /**< Stop reporting of changes in RSSI. */ + SD_BLE_GAP_SCAN_START, /**< Start Scanning. */ + SD_BLE_GAP_SCAN_STOP, /**< Stop Scanning. */ + SD_BLE_GAP_CONNECT, /**< Connect. */ + SD_BLE_GAP_CONNECT_CANCEL, /**< Cancel ongoing connection procedure. */ + SD_BLE_GAP_RSSI_GET, /**< Get the last RSSI sample. */ + SD_BLE_GAP_PHY_REQUEST, /**< Initiate PHY Update procedure. */ + SD_BLE_GAP_DATA_LENGTH_UPDATE, /**< Initiate or respond to a Data Length Update Procedure. */ +}; + +/**@brief GAP Event IDs. + * IDs that uniquely identify an event coming from the stack to the application. + */ +enum BLE_GAP_EVTS +{ + BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connection established. \n See @ref ble_gap_evt_connected_t. */ + BLE_GAP_EVT_DISCONNECTED, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */ + BLE_GAP_EVT_SEC_PARAMS_REQUEST, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. \n See @ref ble_gap_evt_sec_params_request_t. */ + BLE_GAP_EVT_SEC_INFO_REQUEST, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. \n See @ref ble_gap_evt_sec_info_request_t. */ + BLE_GAP_EVT_PASSKEY_DISPLAY, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */ + BLE_GAP_EVT_KEY_PRESSED, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */ + BLE_GAP_EVT_AUTH_KEY_REQUEST, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_auth_key_request_t. */ + BLE_GAP_EVT_LESC_DHKEY_REQUEST, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */ + BLE_GAP_EVT_AUTH_STATUS, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */ + BLE_GAP_EVT_CONN_SEC_UPDATE, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */ + BLE_GAP_EVT_TIMEOUT, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */ + BLE_GAP_EVT_RSSI_CHANGED, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */ + BLE_GAP_EVT_ADV_REPORT, /**< Advertising report. \n See @ref ble_gap_evt_adv_report_t. */ + BLE_GAP_EVT_SEC_REQUEST, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, /**< Connection Parameter Update Request. \n Reply with @ref sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */ + BLE_GAP_EVT_SCAN_REQ_REPORT, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */ + BLE_GAP_EVT_PHY_UPDATE, /**< PHY have been updated \n See @ref ble_gap_evt_phy_update_t. */ + BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST, /**< Data Length Update request. \n Reply with @ref sd_ble_gap_data_length_update.\n See @ref ble_gap_evt_data_length_update_request_t. */ + BLE_GAP_EVT_DATA_LENGTH_UPDATE, /**< LL Data Channel PDU payload length updated. \n See @ref ble_gap_evt_data_length_update_t. */ +}; + +/**@brief GAP Option IDs. + * IDs that uniquely identify a GAP option. + */ +enum BLE_GAP_OPTS +{ + BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */ + BLE_GAP_OPT_LOCAL_CONN_LATENCY, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */ + BLE_GAP_OPT_PASSKEY, /**< Set passkey. @ref ble_gap_opt_passkey_t */ + BLE_GAP_OPT_SCAN_REQ_REPORT, /**< Scan request report. @ref ble_gap_opt_scan_req_report_t */ + BLE_GAP_OPT_COMPAT_MODE_1, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_1_t */ + BLE_GAP_OPT_COMPAT_MODE_2, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_2_t */ + BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */ + BLE_GAP_OPT_PREFERRED_PHYS_SET, /**< Set the preferred PHYs for all new connections. @ref ble_gap_opt_preferred_phys_t */ + BLE_GAP_OPT_SLAVE_LATENCY_DISABLE, /**< Disable slave latency. @ref ble_gap_opt_slave_latency_disable_t */ +}; + +/**@brief GAP Configuration IDs. + * + * IDs that uniquely identify a GAP configuration. + */ +enum BLE_GAP_CFGS +{ + BLE_GAP_CFG_ROLE_COUNT = BLE_GAP_CFG_BASE, /**< Role count configuration. */ + BLE_GAP_CFG_DEVICE_NAME, /**< Device name configuration. */ +}; + +/** @} */ + +/**@addtogroup BLE_GAP_DEFINES Defines + * @{ */ + +/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP + * @{ */ +#define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */ +#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */ +#define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */ +#define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to modify the whitelist while already in use by another operation. */ +#define BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE (NRF_GAP_ERR_BASE + 0x004) /**< Attempt to modify the device identity list while already in use by another operation. */ +#define BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE (NRF_GAP_ERR_BASE + 0x005) /**< The device identity list contains entries with duplicate identity addresses. */ +/**@} */ + + +/**@defgroup BLE_GAP_ROLES GAP Roles + * @note Not explicitly used in peripheral API, but will be relevant for central API. + * @{ */ +#define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */ +#define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */ +#define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */ +/**@} */ + + +/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources + * @{ */ +#define BLE_GAP_TIMEOUT_SRC_ADVERTISING 0x00 /**< Advertising timeout. */ +#define BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST 0x01 /**< Security request timeout. */ +#define BLE_GAP_TIMEOUT_SRC_SCAN 0x02 /**< Scanning timeout. */ +#define BLE_GAP_TIMEOUT_SRC_CONN 0x03 /**< Connection timeout. */ +#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x04 /**< Authenticated payload timeout. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types + * @{ */ +#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Random private resolvable address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Random private non-resolvable address. */ +/**@} */ + + +/**@brief The default interval in seconds at which a private address is refreshed. */ +#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (900) /* 15 minutes. */ +/**@brief The maximum interval in seconds at which a private address can be refreshed. */ +#define BLE_GAP_MAX_PRIVATE_ADDR_CYCLE_INTERVAL_S (41400) /* 11 hours 30 minutes. */ + + +/** @brief BLE address length. */ +#define BLE_GAP_ADDR_LEN (6) + + +/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes + * @{ */ +#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */ +#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */ +/**@} */ + + +/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format + * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm + * @{ */ +#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */ +#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */ +#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */ +#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */ +#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */ +#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */ +#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */ +#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */ +#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */ +#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */ +#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */ +#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */ +#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */ +#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */ +#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */ +#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */ +#define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE 0x22 /**< LE Secure Connections Confirmation Value */ +#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 /**< LE Secure Connections Random Value */ +#define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */ +#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */ +#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags + * @{ */ +#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */ +#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */ +#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */ +#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */ +#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */ +#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */ +#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min + * @{ */ +#define BLE_GAP_ADV_INTERVAL_MIN 0x0020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */ +#define BLE_GAP_ADV_NONCON_INTERVAL_MIN 0x00A0 /**< Minimum Advertising interval in 625 us units for non connectable mode, i.e. 100 ms. */ +#define BLE_GAP_ADV_INTERVAL_MAX 0x4000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s. */ + /**@} */ + + +/**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min + * @{ */ +#define BLE_GAP_SCAN_INTERVAL_MIN 0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */ +#define BLE_GAP_SCAN_INTERVAL_MAX 0x4000 /**< Maximum Scan interval in 625 us units, i.e. 10.24 s. */ + /** @} */ + + +/**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min + * @{ */ +#define BLE_GAP_SCAN_WINDOW_MIN 0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */ +#define BLE_GAP_SCAN_WINDOW_MAX 0x4000 /**< Maximum Scan window in 625 us units, i.e. 10.24 s. */ + /** @} */ + + +/**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min + * @{ */ +#define BLE_GAP_SCAN_TIMEOUT_MIN 0x0001 /**< Minimum Scan timeout in seconds. */ +#define BLE_GAP_SCAN_TIMEOUT_MAX 0xFFFF /**< Maximum Scan timeout in seconds. */ + /** @} */ + + +/**@brief Maximum size of advertising data in octets. */ +#define BLE_GAP_ADV_MAX_SIZE (31) + + +/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types + * @{ */ +#define BLE_GAP_ADV_TYPE_ADV_IND 0x00 /**< Connectable undirected. */ +#define BLE_GAP_ADV_TYPE_ADV_DIRECT_IND 0x01 /**< Connectable directed. */ +#define BLE_GAP_ADV_TYPE_ADV_SCAN_IND 0x02 /**< Scannable undirected. */ +#define BLE_GAP_ADV_TYPE_ADV_NONCONN_IND 0x03 /**< Non connectable undirected. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies + * @{ */ +#define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */ +#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */ +#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */ +#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */ +/**@} */ + + +/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values + * @{ */ +#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX (180) /**< Maximum advertising time in limited discoverable mode (TGAP(lim_adv_timeout) = 180 s). */ +#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED (0) /**< Unlimited advertising in general discoverable mode. */ +/**@} */ + + +/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes + * @{ */ +#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */ +#define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */ +#define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */ +/**@} */ + + +/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities + * @{ */ +#define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */ +#define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */ +#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */ +#define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */ +#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */ +/**@} */ + + +/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types + * @{ */ +#define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */ +#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */ +#define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */ +/**@} */ + + +/**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types + * @{ */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */ +/**@} */ + + +/**@defgroup BLE_GAP_SEC_STATUS GAP Security status + * @{ */ +#define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */ +#define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */ +#define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN 0x03 /**< Reserved for Future Use range #1 begin. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE1_END 0x80 /**< Reserved for Future Use range #1 end. */ +#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user canceled or other). */ +#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */ +#define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */ +#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */ +#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */ +#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */ +#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */ +#define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */ +#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */ +#define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */ +#define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */ +#define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */ +#define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */ +#define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */ +/**@} */ + + +/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources + * @{ */ +#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */ +#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */ +/**@} */ + + +/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits + * @{ */ +#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ +#define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */ +/**@} */ + + +/**@defgroup BLE_GAP_DEVNAME GAP device name defines. + * @{ */ +#define BLE_GAP_DEVNAME_DEFAULT "nRF5x" /**< Default device name value. */ +#define BLE_GAP_DEVNAME_DEFAULT_LEN 31 /**< Default number of octets in device name. */ +#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximum number of octets in device name. */ +/**@} */ + + +/**@brief Disable RSSI events for connections */ +#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF + +/**@defgroup BLE_GAP_PHYS GAP PHYs + * @{ */ +#define BLE_GAP_PHY_1MBPS 0x01 /**< 1 Mbps PHY. */ +#define BLE_GAP_PHY_2MBPS 0x02 /**< 2 Mbps PHY. */ +#define BLE_GAP_PHY_CODED 0x04 /**< Coded PHY. */ +/**@} */ + +/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters + * + * See @ref ble_gap_conn_sec_mode_t. + * @{ */ +/**@brief Set sec_mode pointed to by ptr to have no access rights.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0) +/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0) +/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0) +/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0) +/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0) +/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0) +/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0) +/**@} */ + + +/**@brief GAP Security Random Number Length. */ +#define BLE_GAP_SEC_RAND_LEN 8 + + +/**@brief GAP Security Key Length. */ +#define BLE_GAP_SEC_KEY_LEN 16 + + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */ +#define BLE_GAP_LESC_P256_PK_LEN 64 + + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */ +#define BLE_GAP_LESC_DHKEY_LEN 32 + + +/**@brief GAP Passkey Length. */ +#define BLE_GAP_PASSKEY_LEN 6 + + +/**@brief Maximum amount of addresses in the whitelist. */ +#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8) + + +/**@brief Maximum amount of identities in the device identities list. */ +#define BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT (8) + + +/**@brief Default connection count for a configuration. */ +#define BLE_GAP_CONN_COUNT_DEFAULT (1) + + +/**@defgroup BLE_GAP_EVENT_LENGTH GAP event length defines. + * @{ */ +#define BLE_GAP_EVENT_LENGTH_MIN (2) /**< Minimum event length, in 1.25 ms units. */ +#define BLE_GAP_EVENT_LENGTH_DEFAULT (3) /**< Default event length, in 1.25 ms units. */ +/**@} */ + + +/**@defgroup BLE_GAP_ROLE_COUNT GAP concurrent connection count defines. + * @{ */ +#define BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT (1) /**< Default maximum number of connections concurrently acting as peripherals. */ +#define BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT (3) /**< Default maximum number of connections concurrently acting as centrals. */ +#define BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT (1) /**< Default number of SMP instances shared between all connections acting as centrals. */ +#define BLE_GAP_ROLE_COUNT_COMBINED_MAX (20) /**< Maximum supported number of concurrent connections in the peripheral and central roles combined. */ +/**@} */ + + + + +/**@brief Automatic data length parameter. */ +#define BLE_GAP_DATA_LENGTH_AUTO 0 + + +/**@defgroup GAP_SEC_MODES GAP Security Modes + * @{ */ +#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */ +/**@} */ +/** @} */ + + +/**@addtogroup BLE_GAP_STRUCTURES Structures + * @{ */ + +/**@brief Bluetooth Low Energy address. */ +typedef struct +{ + uint8_t addr_id_peer : 1; /**< Only valid for peer addresses. + Reference to peer in device identities list (as set with @ref sd_ble_gap_device_identities_set) when peer is using privacy. */ + uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */ + uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. */ +} ble_gap_addr_t; + + +/**@brief GAP connection parameters. + * + * @note When ble_conn_params_t is received in an event, both min_conn_interval and + * max_conn_interval will be equal to the connection interval set by the central. + * + * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies: + * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval + * that corresponds to the following Bluetooth Spec requirement: + * The Supervision_Timeout in milliseconds shall be larger than + * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds. + */ +typedef struct +{ + uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ +} ble_gap_conn_params_t; + + +/**@brief GAP connection security modes. + * + * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n + * Security Mode 1 Level 1: No security is needed (aka open link).\n + * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n + * Security Mode 1 Level 3: MITM protected encrypted link required.\n + * Security Mode 1 Level 4: LESC MITM protected encrypted link required.\n + * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n + * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n + */ +typedef struct +{ + uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */ + uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */ + +} ble_gap_conn_sec_mode_t; + + +/**@brief GAP connection security status.*/ +typedef struct +{ + ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/ + uint8_t encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */ +} ble_gap_conn_sec_t; + +/**@brief Identity Resolving Key. */ +typedef struct +{ + uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */ +} ble_gap_irk_t; + + +/**@brief Channel mask for RF channels used in advertising. */ +typedef struct +{ + uint8_t ch_37_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 37 */ + uint8_t ch_38_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 38 */ + uint8_t ch_39_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 39 */ +} ble_gap_adv_ch_mask_t; + + +/**@brief GAP advertising parameters. */ +typedef struct +{ + uint8_t type; /**< See @ref BLE_GAP_ADV_TYPES. */ + ble_gap_addr_t const *p_peer_addr; /**< Address of a known peer. + - When privacy is enabled and the local device use @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE addresses, the device identity list is searched for a matching + entry. If the local IRK for that device identity is set, the local IRK for that device will be used to generate the advertiser address field in the advertise packet. + - If type is @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this must be set to the targeted initiator. If the initiator is in the device identity list, + the peer IRK for that device will be used to generate the initiator address field in the ADV_DIRECT_IND packet. */ + uint8_t fp; /**< Filter Policy, see @ref BLE_GAP_ADV_FILTER_POLICIES. */ + uint16_t interval; /**< Advertising interval between 0x0020 and 0x4000 in 0.625 ms units (20 ms to 10.24 s), see @ref BLE_GAP_ADV_INTERVALS. + - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for high duty cycle directed advertising. + - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, set @ref BLE_GAP_ADV_INTERVAL_MIN <= interval <= @ref BLE_GAP_ADV_INTERVAL_MAX for low duty cycle advertising.*/ + uint16_t timeout; /**< Advertising timeout between 0x0001 and 0x3FFF in seconds, 0x0000 disables timeout. See also @ref BLE_GAP_ADV_TIMEOUT_VALUES. If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for High duty cycle directed advertising. */ + ble_gap_adv_ch_mask_t channel_mask; /**< Advertising channel mask. See @ref ble_gap_adv_ch_mask_t. */ +} ble_gap_adv_params_t; + + +/**@brief GAP scanning parameters. */ +typedef struct +{ + uint8_t active : 1; /**< If 1, perform active scanning (scan requests). */ + uint8_t use_whitelist : 1; /**< If 1, filter advertisers using current active whitelist. */ + uint8_t adv_dir_report : 1; /**< If 1, also report directed advertisements where the initiator field is set to a private resolvable address, + even if the address did not resolve to an entry in the device identity list. A report will be generated + even if the peer is not in the whitelist. */ + uint16_t interval; /**< Scan interval between 0x0004 and 0x4000 in 0.625 ms units (2.5 ms to 10.24 s). */ + uint16_t window; /**< Scan window between 0x0004 and 0x4000 in 0.625 ms units (2.5 ms to 10.24 s). */ + uint16_t timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ +} ble_gap_scan_params_t; + + +/**@brief Device Privacy. + * + * The privacy feature provides a way for the device to avoid being tracked over a period of time. + * The privacy feature, when enabled, hides the local device identity and replaces it with a private address + * that is automatically refreshed at a specified interval. + * + * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK). + * With this key, a device can generate a random private address that can only be recognized by peers in possession of that key, + * and devices can establish connections without revealing their real identities. + * + * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all + * bonding procedures performed after @ref sd_ble_gap_privacy_set returns. + * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is called. + */ +typedef struct +{ + uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */ + uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */ + uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */ + ble_gap_irk_t *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used. + When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored. + By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */ +} ble_gap_privacy_params_t; + + +/**@brief Physical Layer configuration + * @note tx_phys and rx_phys are bitfields, to indicate multiple preferred PHYs for each direction they can be ORed together. + * @code + * p_gap_phys->tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; + * p_gap_phys->rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; + * @endcode + * + */ +typedef struct +{ + uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */ + uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */ +} ble_gap_phys_t; + +/** @brief Keys that can be exchanged during a bonding procedure. */ +typedef struct +{ + uint8_t enc : 1; /**< Long Term Key and Master Identification. */ + uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */ + uint8_t sign : 1; /**< Connection Signature Resolving Key. */ + uint8_t link : 1; /**< Derive the Link Key from the LTK. */ +} ble_gap_sec_kdist_t; + + +/**@brief GAP security parameters. */ +typedef struct +{ + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Enable Man In The Middle protection. */ + uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */ + uint8_t keypress : 1; /**< Enable generation of keypress notifications. */ + uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ + uint8_t oob : 1; /**< The OOB data flag. + - In LE legacy pairing, this flag is set if a device has out of band authentication data. + The OOB method is used if both of the devices have out of band authentication data. + - In LE Secure Connections pairing, this flag is set if a device has the peer device's out of band authentication data. + The OOB method is used if at least one device has the peer device's OOB data available. */ + uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */ + uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */ + ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */ + ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */ +} ble_gap_sec_params_t; + + +/**@brief GAP Encryption Information. */ +typedef struct +{ + uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */ + uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */ + uint8_t auth : 1; /**< Authenticated Key. */ + uint8_t ltk_len : 6; /**< LTK length in octets. */ +} ble_gap_enc_info_t; + + +/**@brief GAP Master Identification. */ +typedef struct +{ + uint16_t ediv; /**< Encrypted Diversifier. */ + uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */ +} ble_gap_master_id_t; + + +/**@brief GAP Signing Information. */ +typedef struct +{ + uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */ +} ble_gap_sign_info_t; + + +/**@brief GAP LE Secure Connections P-256 Public Key. */ +typedef struct +{ + uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the standard SMP protocol format: {X,Y} both in little-endian. */ +} ble_gap_lesc_p256_pk_t; + + +/**@brief GAP LE Secure Connections DHKey. */ +typedef struct +{ + uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */ +} ble_gap_lesc_dhkey_t; + + +/**@brief GAP LE Secure Connections OOB data. */ +typedef struct +{ + ble_gap_addr_t addr; /**< Bluetooth address of the device. */ + uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */ + uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */ +} ble_gap_lesc_oob_data_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */ +typedef struct +{ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ + uint8_t role; /**< BLE role for this connection, see @ref BLE_GAP_ROLES */ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ +} ble_gap_evt_connected_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */ +typedef struct +{ + uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */ +} ble_gap_evt_disconnected_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */ +typedef struct +{ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ +} ble_gap_evt_conn_param_update_t; + +/**@brief Event Structure for @ref BLE_GAP_EVT_PHY_UPDATE. */ +typedef struct +{ + uint8_t status; /**< Status of the procedure, see @ref BLE_HCI_STATUS_CODES */ + uint8_t tx_phy; /**< TX PHY for this connection, see @ref BLE_GAP_PHYS. */ + uint8_t rx_phy; /**< RX PHY for this connection, see @ref BLE_GAP_PHYS. */ +} ble_gap_evt_phy_update_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */ +typedef struct +{ + ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */ +} ble_gap_evt_sec_params_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */ +typedef struct +{ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ + ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */ + uint8_t enc_info : 1; /**< If 1, Encryption Information required. */ + uint8_t id_info : 1; /**< If 1, Identity Information required. */ + uint8_t sign_info : 1; /**< If 1, Signing Information required. */ +} ble_gap_evt_sec_info_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */ +typedef struct +{ + uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ + uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply + with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or + @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */ +} ble_gap_evt_passkey_display_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */ +typedef struct +{ + uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */ +} ble_gap_evt_key_pressed_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */ +typedef struct +{ + uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */ +} ble_gap_evt_auth_key_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */ +typedef struct +{ + ble_gap_lesc_p256_pk_t *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory + inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */ + uint8_t oobd_req :1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the procedure. */ +} ble_gap_evt_lesc_dhkey_request_t; + + +/**@brief Security levels supported. + * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1. +*/ +typedef struct +{ + uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */ + uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */ + uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */ + uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */ +} ble_gap_sec_levels_t; + + +/**@brief Encryption Key. */ +typedef struct +{ + ble_gap_enc_info_t enc_info; /**< Encryption Information. */ + ble_gap_master_id_t master_id; /**< Master Identification. */ +} ble_gap_enc_key_t; + + +/**@brief Identity Key. */ +typedef struct +{ + ble_gap_irk_t id_info; /**< Identity Resolving Key. */ + ble_gap_addr_t id_addr_info; /**< Identity Address. */ +} ble_gap_id_key_t; + + +/**@brief Security Keys. */ +typedef struct +{ + ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ + ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ + ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ + ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the value defined + in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */ +} ble_gap_sec_keys_t; + + +/**@brief Security key set for both local and peer keys. */ +typedef struct +{ + ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be generated locally and will always be stored if bonding. */ + ble_gap_sec_keys_t keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */ +} ble_gap_sec_keyset_t; + + +/**@brief Data Length Update Procedure parameters. */ +typedef struct +{ + uint16_t max_tx_octets; /**< Maximum number of payload octets that a Controller supports for transmission of a single Link Layer Data Channel PDU. */ + uint16_t max_rx_octets; /**< Maximum number of payload octets that a Controller supports for reception of a single Link Layer Data Channel PDU. */ + uint16_t max_tx_time_us; /**< Maximum time, in microseconds, that a Controller supports for transmission of a single Link Layer Data Channel PDU. */ + uint16_t max_rx_time_us; /**< Maximum time, in microseconds, that a Controller supports for reception of a single Link Layer Data Channel PDU. */ +} ble_gap_data_length_params_t; + + +/**@brief Data Length Update Procedure local limitation. */ +typedef struct +{ + uint16_t tx_payload_limited_octets; /**< If > 0, the requested TX packet length is too long by this many octets. */ + uint16_t rx_payload_limited_octets; /**< If > 0, the requested RX packet length is too long by this many octets. */ + uint16_t tx_rx_time_limited_us; /**< If > 0, the requested combination of TX and RX packet lengths is too long by this many microseconds. */ +} ble_gap_data_length_limitation_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */ +typedef struct +{ + uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */ + uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ + uint8_t bonded : 1; /**< Procedure resulted in a bond. */ + ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */ + ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */ + ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */ + ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */ +} ble_gap_evt_auth_status_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */ +typedef struct +{ + ble_gap_conn_sec_t conn_sec; /**< Connection security level. */ +} ble_gap_evt_conn_sec_update_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */ +typedef struct +{ + uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */ +} ble_gap_evt_timeout_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */ +typedef struct +{ + int8_t rssi; /**< Received Signal Strength Indication in dBm. */ +} ble_gap_evt_rssi_changed_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT. */ +typedef struct +{ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ + ble_gap_addr_t direct_addr; /**< Set when the scanner is unable to resolve the private resolvable address of the initiator + field of a directed advertisement packet and the scanner has been enabled to report this in @ref ble_gap_scan_params_t::adv_dir_report. */ + int8_t rssi; /**< Received Signal Strength Indication in dBm. */ + uint8_t scan_rsp : 1; /**< If 1, the report corresponds to a scan response and the type field may be ignored. */ + uint8_t type : 2; /**< See @ref BLE_GAP_ADV_TYPES. Only valid if the scan_rsp field is 0. */ + uint8_t dlen : 5; /**< Advertising or scan response data length. */ + uint8_t data[BLE_GAP_ADV_MAX_SIZE]; /**< Advertising or scan response data. */ +} ble_gap_evt_adv_report_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */ +typedef struct +{ + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Man In The Middle protection requested. */ + uint8_t lesc : 1; /**< LE Secure Connections requested. */ + uint8_t keypress : 1; /**< Generation of keypress notifications requested. */ +} ble_gap_evt_sec_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST. */ +typedef struct +{ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ +} ble_gap_evt_conn_param_update_request_t; + + +/**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */ +typedef struct +{ + int8_t rssi; /**< Received Signal Strength Indication in dBm. */ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ +} ble_gap_evt_scan_req_report_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST. */ +typedef struct +{ + ble_gap_data_length_params_t peer_params; /**< Peer data length parameters. */ +} ble_gap_evt_data_length_update_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE. */ +typedef struct +{ + ble_gap_data_length_params_t effective_params; /**< The effective data length parameters. */ +} ble_gap_evt_data_length_update_t; + + +/**@brief GAP event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which event occurred. */ + union /**< union alternative identified by evt_id in enclosing struct. */ + { + ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */ + ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */ + ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */ + ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */ + ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */ + ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */ + ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */ + ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */ + ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */ + ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */ + ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */ + ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */ + ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event Parameters. */ + ble_gap_evt_adv_report_t adv_report; /**< Advertising Report Event Parameters. */ + ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */ + ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */ + ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report Parameters. */ + ble_gap_evt_phy_update_t phy_update; /**< PHY Update Parameters. */ + ble_gap_evt_data_length_update_request_t data_length_update_request; /**< Data Length Update Request Event Parameters. */ + ble_gap_evt_data_length_update_t data_length_update; /**< Data Length Update Event Parameters. */ + } params; /**< Event Parameters. */ +} ble_gap_evt_t; + + +/** + * @brief BLE GAP connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_CONN_COUNT The connection count for the connection configurations is zero. + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - The sum of conn_count for all connection configurations combined exceeds UINT8_MAX. + * - The event length is smaller than @ref BLE_GAP_EVENT_LENGTH_MIN. + */ +typedef struct +{ + uint8_t conn_count; /**< The number of concurrent connections the application can create with this configuration. + The default and minimum value is @ref BLE_GAP_CONN_COUNT_DEFAULT. */ + uint16_t event_length; /**< The time set aside for this connection on every connection interval in 1.25 ms units. + The default value is @ref BLE_GAP_EVENT_LENGTH_DEFAULT, the minimum value is @ref BLE_GAP_EVENT_LENGTH_MIN. + The event length and the connection interval are the primary parameters + for setting the throughput of a connection. + See the SoftDevice Specification for details on throughput. */ +} ble_gap_conn_cfg_t; + + +/** + * @brief Configuration of maximum concurrent connections in the different connected roles, set with + * @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_CONN_COUNT The sum of periph_role_count and central_role_count is too + * large. The maximum supported sum of concurrent connections is + * @ref BLE_GAP_ROLE_COUNT_COMBINED_MAX. + * @retval ::NRF_ERROR_INVALID_PARAM central_sec_count is larger than central_role_count. + */ +typedef struct +{ + uint8_t periph_role_count; /**< Maximum number of connections concurrently acting as a peripheral. Default value is @ref BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT. */ + uint8_t central_role_count; /**< Maximum number of connections concurrently acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT. */ + uint8_t central_sec_count; /**< Number of SMP instances shared between all connections acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT. */ +} ble_gap_cfg_role_count_t; + + +/** + * @brief Device name and its properties, set with @ref sd_ble_cfg_set. + * + * @note If the device name is not configured, the default device name will be @ref + * BLE_GAP_DEVNAME_DEFAULT, the maximum device name length will be @ref + * BLE_GAP_DEVNAME_DEFAULT_LEN, vloc will be set to @ref BLE_GATTS_VLOC_STACK and the device name + * will have no write access. + * + * @note If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK, + * the attribute table size must be increased to have room for the longer device name (see + * @ref sd_ble_cfg_set and @ref ble_gatts_cfg_attr_tab_size_t). + * + * @note If vloc is @ref BLE_GATTS_VLOC_STACK : + * - p_value must point to non-volatile memory (flash) or be NULL. + * - If p_value is NULL, the device name will initially be empty. + * + * @note If vloc is @ref BLE_GATTS_VLOC_USER : + * - p_value cannot be NULL. + * - If the device name is writable, p_value must point to volatile memory (RAM). + * + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - Invalid device name location (vloc). + * - Invalid device name security mode. + * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: + * - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN). + * - The device name length is too long for the given Attribute Table. + * @retval ::NRF_ERROR_NOT_SUPPORTED Device name security mode is not supported. + */ +typedef struct +{ + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ + uint8_t vloc:2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ + uint8_t *p_value; /**< Pointer to where the value (device name) is stored or will be stored. */ + uint16_t current_len; /**< Current length in bytes of the memory pointed to by p_value.*/ + uint16_t max_len; /**< Maximum length in bytes of the memory pointed to by p_value.*/ +} ble_gap_cfg_device_name_t; + + +/**@brief Configuration structure for GAP configurations. */ +typedef union +{ + ble_gap_cfg_role_count_t role_count_cfg; /**< Role count configuration, cfg_id is @ref BLE_GAP_CFG_ROLE_COUNT. */ + ble_gap_cfg_device_name_t device_name_cfg; /**< Device name configuration, cfg_id is @ref BLE_GAP_CFG_DEVICE_NAME. */ +} ble_gap_cfg_t; + + +/**@brief Channel Map option. + * Used with @ref sd_ble_opt_get to get the current channel map + * or @ref sd_ble_opt_set to set a new channel map. When setting the + * channel map, it applies to all current and future connections. When getting the + * current channel map, it applies to a single connection and the connection handle + * must be supplied. + * + * @note Setting the channel map may take some time, depending on connection parameters. + * The time taken may be different for each connection and the get operation will + * return the previous channel map until the new one has taken effect. + * + * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed. + * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46. + * + * @retval ::NRF_SUCCESS Get or set successful. + * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get. + * @retval ::NRF_ERROR_NOT_SUPPORTED Returned by sd_ble_opt_set in peripheral-only SoftDevices. + * + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle (only applicable for get) */ + uint8_t ch_map[5]; /**< Channel Map (37-bit). */ +} ble_gap_opt_ch_map_t; + + +/**@brief Local connection latency option. + * + * Local connection latency is a feature which enables the slave to improve + * current consumption by ignoring the slave latency set by the peer. The + * local connection latency can only be set to a multiple of the slave latency, + * and cannot be longer than half of the supervision timeout. + * + * Used with @ref sd_ble_opt_set to set the local connection latency. The + * @ref sd_ble_opt_get is not supported for this option, but the actual + * local connection latency (unless set to NULL) is set as a return parameter + * when setting the option. + * + * @note The latency set will be truncated down to the closest slave latency event + * multiple, or the nearest multiple before half of the supervision timeout. + * + * @note The local connection latency is disabled by default, and needs to be enabled for new + * connections and whenever the connection is updated. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint16_t requested_latency; /**< Requested local connection latency. */ + uint16_t * p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */ +} ble_gap_opt_local_conn_latency_t; + +/**@brief Disable slave latency + * + * Used with @ref sd_ble_opt_set to temporarily disable slave latency of a peripheral connection (see @ref ble_gap_conn_params_t::slave_latency). And to re-enable it again. + * When disabled, the peripheral will ignore the slave_latency set by the central. + * + * @note Shall only be called on peripheral links. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint8_t disable : 1; /**< Set to 1 to disable slave latency. Set to 0 enable it again.*/ +} ble_gap_opt_slave_latency_disable_t; + +/**@brief Passkey Option. + * + * Structure containing the passkey to be used during pairing. This can be used with @ref + * sd_ble_opt_set to make the SoftDevice use a preprogrammed passkey for authentication + * instead of generating a random one. + * + * @note Repeated pairing attempts using the same preprogrammed passkey makes pairing vulnerable to MITM attacks. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * + */ +typedef struct +{ + uint8_t const * p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/ +} ble_gap_opt_passkey_t; + + +/**@brief Scan request report option. + * + * This can be used with @ref sd_ble_opt_set to make the SoftDevice send + * @ref BLE_GAP_EVT_SCAN_REQ_REPORT events. + * + * @note Due to the limited space reserved for scan request report events, + * not all received scan requests will be reported. + * + * @note If whitelisting is used, only whitelisted requests are reported. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_STATE When advertising is ongoing while the option is set. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable scan request reports. */ +} ble_gap_opt_scan_req_report_t; + +/**@brief Compatibility mode 1 option. + * + * This can be used with @ref sd_ble_opt_set to enable and disable + * compatibility mode 1. Compatibility mode 1 is disabled by default. + * + * @note Compatibility mode 1 enables interoperability with devices that do not support + * a value of 0 for the WinOffset parameter in the Link Layer CONNECT_REQ packet. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable compatibility mode 1.*/ +} ble_gap_opt_compat_mode_1_t; + +/**@brief Compatibility mode 2 option. + * + * This can be used with @ref sd_ble_opt_set to enable compatibility mode 2. + * Compatibility mode 2 is disabled by default. + * + * @note Compatibility mode 2 enables interoperability with devices that initiate Feature exchange + * and version exchange procedure in parallel. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM if enable bit is not set to 1. Currently only enabling is supported. + * @retval ::NRF_ERROR_INVALID_STATE When any role is running while mode 2 is set. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable compatibility mode 2.*/ +} ble_gap_opt_compat_mode_2_t; + + +/**@brief Authenticated payload timeout option. + * + * This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other than the default of 8 minutes. + * + * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated + * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted + * link. + * + * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance + * to reset the timer. In addition the stack will try to prioritize running of LE ping over other + * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects + * on other activities, it is recommended to use high timeout values. + * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)). + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit. Maximum is 48 000 (=480 000 ms =8 min). Minimum is 1 (=10 ms). */ +} ble_gap_opt_auth_payload_timeout_t; + +/**@brief Preferred PHY option + * + * @details This can be used with @ref sd_ble_opt_set to change the preferred PHYs. Before this function is called the PHYs + * for peer initiated PHY Update procedure is @ref BLE_GAP_PHY_1MBPS. If @ref ble_gap_opt_preferred_phys_t::tx_phys or + * @ref ble_gap_opt_preferred_phys_t::rx_phys is 0, then the stack will select PHYs based on the peer requirements on that specific direction. + * + * @note The preferred PHYs are only valid for newly created connections after this option is called. If the PHYs should be + * changed for an existing link the @ref sd_ble_gap_phy_request would have to be called, and that would try to update the + * PHYs for the given link. + * + * @note tx_phys and rx_phys are bitfields, to indicate multiple preferred PHYs for each direction they can be ORed together. + * @code + * tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; + * rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; + * @endcode + * + * @events + * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update if initiated by peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_PHY_REQUEST} + * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_REQUEST} + * @endmscs + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + */ +typedef struct +{ + uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */ + uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */ +} ble_gap_opt_preferred_phys_t; + +/**@brief Option structure for GAP options. */ +typedef union +{ + ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */ + ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */ + ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/ + ble_gap_opt_scan_req_report_t scan_req_report; /**< Parameters for the scan request report option.*/ + ble_gap_opt_compat_mode_1_t compat_mode_1; /**< Parameters for the compatibility mode 1 option.*/ + ble_gap_opt_compat_mode_2_t compat_mode_2; /**< Parameters for the compatibility mode 2 option.*/ + ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/ + ble_gap_opt_preferred_phys_t preferred_phys; /**< Parameters for the preferred PHYs option. */ + ble_gap_opt_slave_latency_disable_t slave_latency_disable; /**< Parameters for the Disable slave latency option */ +} ble_gap_opt_t; +/**@} */ + + +/**@addtogroup BLE_GAP_FUNCTIONS Functions + * @{ */ + +/**@brief Set the local Bluetooth identity address. + * + * The local Bluetooth identity address is the address that identifies this device to other peers. + * The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * The identity address cannot be changed while roles are running. + * + * @note This address will be distributed to the peer during bonding. + * If the address changes, the address stored in the peer device will not be valid and the ability to + * reconnect using the old address will be lost. + * + * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being + * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged + * for the lifetime of each IC. + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @endmscs + * + * @param[in] p_addr Pointer to address structure. + * + * @retval ::NRF_SUCCESS Address successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_STATE The identity address cannot be changed while the roles are running. + */ +SVCALL(SD_BLE_GAP_ADDR_SET, uint32_t, sd_ble_gap_addr_set(ble_gap_addr_t const *p_addr)); + + +/**@brief Get local Bluetooth identity address. + * + * @note This will always return the identity address irrespective of the privacy settings, + * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * + * @param[out] p_addr Pointer to address structure to be filled in. + * + * @retval ::NRF_SUCCESS Address successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + */ +SVCALL(SD_BLE_GAP_ADDR_GET, uint32_t, sd_ble_gap_addr_get(ble_gap_addr_t *p_addr)); + + +/**@brief Set the active whitelist in the SoftDevice. + * + * @note Only one whitelist can be used at a time and the whitelist is shared between the BLE roles. + * The whitelist cannot be set if a BLE role is using the whitelist. + * + * @note If an address is resolved using the information in the device identity list, then the whitelist + * filter policy applies to the peer identity address and not the resolvable address sent on air. + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} + * @endmscs + * + * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses, if NULL the whitelist will be cleared. + * @param[in] len Length of the whitelist, maximum @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. + * + * @retval ::NRF_SUCCESS The whitelist is successfully set/cleared. + * @retval ::NRF_ERROR_INVALID_ADDR The whitelist (or one of its entries) provided is invalid. + * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE The whitelist is in use by a BLE role and cannot be set or cleared. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_DATA_SIZE The given whitelist size is invalid (zero or too large); this can only return when + * pp_wl_addrs is not NULL. + */ +SVCALL(SD_BLE_GAP_WHITELIST_SET, uint32_t, sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len)); + + +/**@brief Set device identity list. + * + * @note Only one device identity list can be used at a time and the list is shared between the BLE roles. + * The device identity list cannot be set if a BLE role is using the list. + * + * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs, if NULL the device identity list will be cleared. + * @param[in] pp_local_irks Pointer to an array of local IRKs. Each entry in the array maps to the entry in pp_id_keys at the same index. + * To fill in the list with the currently set device IRK for all peers, set to NULL. + * @param[in] len Length of the device identity list, maximum @ref BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT. + * + * @mscs + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS The device identity list successfully set/cleared. + * @retval ::NRF_ERROR_INVALID_ADDR The device identity list (or one of its entries) provided is invalid. + * This code may be returned if the local IRK list also has an invalid entry. + * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE The device identity list is in use and cannot be set or cleared. + * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE The device identity list contains multiple entries with the same identity address. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_DATA_SIZE The given device identity list size invalid (zero or too large); this can + * only return when pp_id_keys is not NULL. + */ +SVCALL(SD_BLE_GAP_DEVICE_IDENTITIES_SET, uint32_t, sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len)); + + +/**@brief Set privacy settings. + * + * @note Privacy settings cannot be set while BLE roles are running. + * + * @param[in] p_privacy_params Privacy settings. + * + * @mscs + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_INVALID_ADDR The pointer to privacy settings is NULL or invalid. + * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. + * @retval ::NRF_ERROR_INVALID_PARAM Out of range parameters are provided. + * @retval ::NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while BLE roles using privacy are enabled. + */ +SVCALL(SD_BLE_GAP_PRIVACY_SET, uint32_t, sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params)); + + +/**@brief Get privacy settings. + * + * @note The privacy settings returned include the current device irk as well. + * + * @param[in] p_privacy_params Privacy settings. + * + * @retval ::NRF_SUCCESS Privacy settings read. + * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid. + * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. + */ +SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params)); + + +/**@brief Set, clear or update advertising and scan response data. + * + * @note The format of the advertising data will be checked by this call to ensure interoperability. + * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and + * duplicating the local name in the advertising data and scan response data. + * + * @note To clear the advertising data and set it to a 0-length packet, simply provide a valid pointer (p_data/p_sr_data) with its corresponding + * length (dlen/srdlen) set to 0. + * + * @note The call will fail if p_data and p_sr_data are both NULL since this would have no effect. + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] p_data Raw data to be placed in advertising packet. If NULL, no changes are made to the current advertising packet data. + * @param[in] dlen Data length for p_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_data is NULL, can be 0 if p_data is not NULL. + * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL, no changes are made to the current scan response packet data. + * @param[in] srdlen Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL. + * + * @retval ::NRF_SUCCESS Advertising data successfully updated or cleared. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, both p_data and p_sr_data cannot be NULL. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied. + * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied, check the advertising data format specification. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data type. + * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied. + */ +SVCALL(SD_BLE_GAP_ADV_DATA_SET, uint32_t, sd_ble_gap_adv_data_set(uint8_t const *p_data, uint8_t dlen, uint8_t const *p_sr_data, uint8_t srdlen)); + + +/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). + * + * @note An application can start an advertising procedure for broadcasting purposes while a connection + * is active. After a @ref BLE_GAP_EVT_CONNECTED event is received, this function may therefore + * be called to start a broadcast advertising procedure. The advertising procedure + * cannot however be connectable (it must be of type @ref BLE_GAP_ADV_TYPE_ADV_SCAN_IND or + * @ref BLE_GAP_ADV_TYPE_ADV_NONCONN_IND). @note Only one advertiser may be active at any time. + * + * @events + * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Advertisement has timed out.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] p_adv_params Pointer to advertising parameters structure. + * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or @ref + * BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. + * + * @retval ::NRF_SUCCESS The BLE stack has started advertising. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check the accepted ranges and limits. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Bluetooth address supplied. + * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Observer) and try again + */ +SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(ble_gap_adv_params_t const *p_adv_params, uint8_t conn_cfg_tag)); + + +/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS The BLE stack has stopped advertising. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in advertising state). + */ +SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(void)); + + + +/**@brief Update connection parameters. + * + * @details In the central role this will initiate a Link Layer connection parameter update procedure, + * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for + * the central to perform the procedure. In both cases, and regardless of success or failure, the application + * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event. + * + * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested. + * + * @events + * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CPU_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CPU_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CPU_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role, + * the parameters in the PPCP characteristic of the GAP service will be used instead. + * If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected + * + * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, process pending events and wait for pending procedures to complete and retry. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params)); + + +/**@brief Disconnect (GAP Link Termination). + * + * @details This call initiates the disconnection procedure, and its completion will be communicated to the application + * with a @ref BLE_GAP_EVT_DISCONNECTED event. + * + * @events + * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CONN_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE). + * + * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (disconnection is already in progress). + */ +SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code)); + + +/**@brief Set the radio's transmit power. + * + * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -20, -16, -12, -8, -4, 0, 2, 3, 4, 5, 6, 7, 8 and 9 dBm). + * + * @note The -40dBm, -20dBm, -16dBm, -12dBm, -8dBm, -4dBm, 0dBm, +2dBm, +3dBm, +4dBm, +5dBm, +6dBm, +7dBm, +8dBm and +9dBm settings are available on nRF52840 series ICs. + * @note The -40dBm, -20dBm, -16dBm, -12dBm, -8dBm, -4dBm, 0dBm, +3dBm and +4dBm settings are available on nRF52 series ICs. + * + * @retval ::NRF_SUCCESS Successfully changed the transmit power. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + */ +SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(int8_t tx_power)); + + +/**@brief Set GAP Appearance value. + * + * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES. + * + * @retval ::NRF_SUCCESS Appearance value set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + */ +SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance)); + + +/**@brief Get GAP Appearance value. + * + * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES. + * + * @retval ::NRF_SUCCESS Appearance value retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance)); + + +/**@brief Set GAP Peripheral Preferred Connection Parameters. + * + * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters. + * + * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + */ +SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params)); + + +/**@brief Get GAP Peripheral Preferred Connection Parameters. + * + * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored. + * + * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params)); + + +/**@brief Set GAP device name. + * + * @note If the device name is located in application flash memory (see @ref ble_gap_cfg_device_name_t), + * it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned. + * + * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t. + * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. + * @param[in] len Length of the UTF-8, non NULL-terminated string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN). + * + * @retval ::NRF_SUCCESS GAP device name and permissions set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_FORBIDDEN Device name is not writable. + */ +SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len)); + + +/**@brief Get GAP device name. + * + * @note If the device name is longer than the size of the supplied buffer, + * p_len will return the complete device name length, + * and not the number of bytes actually returned in p_dev_name. + * The application may use this information to allocate a suitable buffer size. + * + * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to NULL to obtain the complete device name length. + * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. + * + * @retval ::NRF_SUCCESS GAP device name retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + */ +SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len)); + + +/**@brief Initiate the GAP Authentication procedure. + * + * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), + * otherwise in the peripheral role, an SMP Security Request will be sent. + * + * @events + * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be generated:} + * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST} + * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST} + * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY} + * @event{@ref BLE_GAP_EVT_KEY_PRESSED} + * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST} + * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST} + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE} + * @event{@ref BLE_GAP_EVT_AUTH_STATUS} + * @event{@ref BLE_GAP_EVT_TIMEOUT} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure. + * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used. + * In the central role, this pointer may be NULL to reject a Security Request. + * + * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. + * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited. + */ +SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params)); + + +/**@brief Reply with GAP security parameters. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. + * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have + * already been provided during a previous call to @ref sd_ble_gap_authenticate. + * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure + * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application + * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event. + * Note that the SoftDevice expects the application to provide memory for storing the + * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key + * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the + * @ref BLE_GAP_EVT_AUTH_STATUS event. + * + * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. + */ +SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset)); + + +/**@brief Reply with an authentication key. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES. + * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination) + * or NULL when confirming LE Secure Connections Numeric Comparison. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in little-endian format. + * + * @retval ::NRF_SUCCESS Authentication key successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key)); + +/**@brief Reply with an LE Secure connections DHKey. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dhkey LE Secure Connections DHKey. + * + * @retval ::NRF_SUCCESS DHKey successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey)); + +/**@brief Notify the peer of a local keypress. + * + * @details This function can only be used when an authentication procedure using LE Secure Connection is in progress. Calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES. + * + * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either not entering a passkey or keypresses have not been enabled by both peers. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time. + */ +SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not)); + +/**@brief Generate a set of OOB data to send to a peer out of band. + * + * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has already been established, + * the one used during connection setup). The application may manually overwrite it with an updated value. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. Can be BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet. + * @param[in] p_pk_own LE Secure Connections local P-256 Public Key. + * @param[out] p_oobd_own The OOB data to be sent out of band to a peer. + * + * @retval ::NRF_SUCCESS OOB data successfully generated. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, ble_gap_lesc_oob_data_t *p_oobd_own)); + +/**@brief Provide the OOB data sent/received out of band. + * + * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function. + * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this function. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if the peer has not received OOB data. + * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. + * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received. + * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref sd_ble_gap_authenticate in the central role + * or @ref sd_ble_gap_sec_params_reply in the peripheral role. + * + * @retval ::NRF_SUCCESS OOB data accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, ble_gap_lesc_oob_data_t const *p_oobd_peer)); + +/**@brief Initiate GAP Encryption procedure. + * + * @details In the central role, this function will initiate the encryption procedure using the encryption information provided. + * + * @events + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE, The connection security has been updated.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. + * + * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. + * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and retry. + */ +SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info)); + + +/**@brief Reply with GAP security information. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * @note Data signing is not yet supported, and p_sign_info must therefore be NULL. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available. + * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available. + * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available. + * + * @retval ::NRF_SUCCESS Successfully accepted security information. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info)); + + +/**@brief Get the current connection security. + * + * @param[in] conn_handle Connection handle. + * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Current connection security successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec)); + + +/**@brief Start reporting the received signal strength to the application. + * + * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called. + * + * @events + * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is + * dependent on the settings of the threshold_dbm + * and skip_count input parameters.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID. + * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event. + * + * @retval ::NRF_SUCCESS Successfully activated RSSI reporting. + * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress. Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count)); + + +/**@brief Stop reporting the received signal strength. + * + * @note An RSSI change detected before the call but not yet received by the application + * may be reported after @ref sd_ble_gap_rssi_stop has been called. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * + * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle)); + + +/**@brief Get the received signal strength for the last connection event. + * + * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND + * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. + * + * @retval ::NRF_SUCCESS Successfully read the RSSI. + * @retval ::NRF_ERROR_NOT_FOUND No sample is available. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing, or disconnection in progress. + */ +SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi)); + + +/**@brief Start scanning (GAP Discovery procedure, Observer Procedure). + * + * @events + * @event{@ref BLE_GAP_EVT_ADV_REPORT, An advertising or scan response packet has been received.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Scanner has timed out.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] p_scan_params Pointer to scan parameters structure. + * + * @retval ::NRF_SUCCESS Successfully initiated scanning procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again + */ +SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params)); + + +/**@brief Stop scanning (GAP Discovery procedure, Observer Procedure). + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully stopped scanning procedure. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in scanning state). + */ +SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void)); + + +/**@brief Create a connection (GAP Link Establishment). + * + * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function. + * The scanning procedure will be stopped even if the function returns an error. + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs + * + * @param[in] p_peer_addr Pointer to peer address. If the use_whitelist bit is set in @ref ble_gap_scan_params_t, then this is ignored. + * If @ref ble_gap_addr_t::addr_id_peer is set then p_peer_addr must be present in the device identity list + * see @ref sd_ble_gap_device_identities_set. + * @param[in] p_scan_params Pointer to scan parameters structure. + * @param[in] p_conn_params Pointer to desired connection parameters. + * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or @ref + * BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. + * + * @retval ::NRF_SUCCESS Successfully initiated connection procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * - Invalid parameter(s) in p_scan_params or p_conn_params. + * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set. + * - Peer address was not present in the device identity list, see @ref sd_ble_gap_device_identities_set. + * @retval ::NRF_ERROR_INVALID_STATE The SoftDevice is in an invalid state to perform this operation. This may be due to an + * existing locally initiated connect procedure, which must complete before initiating again. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. If another connection is being established + * wait for the corresponding @ref BLE_GAP_EVT_CONNECTED event before calling again. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again + */ +SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag)); + + +/**@brief Cancel a connection establishment. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully canceled an ongoing connection procedure. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + */ +SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void)); + + +/**@brief PHY Update Request + * + * @details This function is used to request a new PHY configuration for a central or a peripheral connection. It will always generate a + * @ref BLE_GAP_EVT_PHY_UPDATE event if successfully executed. If @ref ble_gap_phys_t::tx_phys or @ref ble_gap_phys_t::rx_phys + * is 0, then the stack will select PHYs based on the peer requirements on that specific direction. If the peer does not support + * the PHY Update procedure, then the resulting @ref BLE_GAP_EVT_PHY_UPDATE event will have a status different from + * @ref BLE_HCI_STATUS_CODE_SUCCESS. + * + * @note The requested PHYs does not have to be within the set of the preferred PHYs. + * + * @note If the @ref ble_gap_opt_preferred_phys_t have not been configured with @ref BLE_GAP_PHY_CODED, then this call might return + * @ref BLE_ERROR_BLOCKED_BY_OTHER_LINKS if there are multiple devices connected. + * + * + * @events + * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update procedure procedure.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_PHY_REQUEST} + * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_REQUEST} + * @endmscs + * + * @param[in] conn_handle Connection handle to indicate the connection for which the PHY Update is requested. + * @param[in] p_gap_phys Pointer to PHY structure. + * + * @retval ::NRF_SUCCESS Successfully requested a PHY Update. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Unsupported PHYs supplied to the call. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_BLOCKED_BY_OTHER_LINKS Other connections may block the scheduling of the current link. + * @retval ::NRF_ERROR_BUSY Procedure is already in progress or not allowed at this time. Process pending events and wait for the pending procedure to complete and retry. + * + */ +SVCALL(SD_BLE_GAP_PHY_REQUEST, uint32_t, sd_ble_gap_phy_request(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys)); + +/**@brief Initiate or respond to a Data Length Update Procedure. + * + * @note Only symmetric input parameters for the Data Length Update is supported. Only @ref + * BLE_GAP_DATA_LENGTH_AUTO for max_tx_time_us and max_rx_time_us is supported. + * + * @note If the application uses @ref BLE_GAP_DATA_LENGTH_AUTO for one or more members of + * p_dl_params, the SoftDevice will choose the highest value supported in current + * configuration and connection parameters. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dl_params Pointer to local parameters to be used in Data Length Update + * Procedure. Set any member to @ref BLE_GAP_DATA_LENGTH_AUTO to let + * the SoftDevice automatically decide the value for that member. + * Set to NULL to use automatic values for all members. + * @param[out] p_dl_limitation Pointer to limitation to be written when local device does not + * have enough resources to accommodate the requested Data Length + * Update parameters. Ignored if NULL. + * + * @mscs + * @mmsc{@ref BLE_GAP_DATA_LENGTH_UPDATE_PROCEDURE_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully set Data Length Extension initiation/response parameters. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED The requested parameters are not supported by the SoftDevice. + * @retval ::NRF_ERROR_RESOURCES The requested parameters can not be accommodated. Inspect + * p_dl_limitation so see where the limitation is. + * @retval ::NRF_ERROR_BUSY Peer has already initiated a Data Length Update Procedure. Process the + * pending @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event to respond. + */ +SVCALL(SD_BLE_GAP_DATA_LENGTH_UPDATE, uint32_t, sd_ble_gap_data_length_update(uint16_t conn_handle, ble_gap_data_length_params_t const *p_dl_params, ble_gap_data_length_limitation_t *p_dl_limitation)); + + + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GAP_H__ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_gatt.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_gatt.h new file mode 100644 index 0000000000000000000000000000000000000000..f6e7ee856373e950db962ae89a5aa1f9d48ce6ac --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_gatt.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_GATT Generic Attribute Profile (GATT) Common + @{ + @brief Common definitions and prototypes for the GATT interfaces. + */ + +#ifndef BLE_GATT_H__ +#define BLE_GATT_H__ + +#include "ble_types.h" +#include "ble_ranges.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATT_DEFINES Defines + * @{ */ + +/** @brief Default ATT MTU, in bytes. */ +#define BLE_GATT_ATT_MTU_DEFAULT 23 + +/**@brief Invalid Attribute Handle. */ +#define BLE_GATT_HANDLE_INVALID 0x0000 + +/**@brief First Attribute Handle. */ +#define BLE_GATT_HANDLE_START 0x0001 + +/**@brief Last Attribute Handle. */ +#define BLE_GATT_HANDLE_END 0xFFFF + +/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources + * @{ */ +#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */ +/** @} */ + +/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations + * @{ */ +#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */ +#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */ +#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ +#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ +#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */ +/** @} */ + +/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags + * @{ */ +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */ +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */ +/** @} */ + +/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations + * @{ */ +#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */ +#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */ +/** @} */ + +/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes + * @{ */ +#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */ +#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */ +#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */ +#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */ +#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */ +#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorization. */ +#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */ +#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */ +#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */ +#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */ +#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */ +#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */ +#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */ +#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */ +#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */ +#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */ +/** @} */ + + +/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats + * @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml + * @{ */ +#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */ +#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */ +#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */ +#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */ +#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */ +#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */ +#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */ +#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */ +#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */ +#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */ +#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */ +#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */ +/** @} */ + +/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces + * @{ + */ +#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */ +#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATT_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATT connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval NRF_ERROR_INVALID_PARAM att_mtu is smaller than @ref BLE_GATT_ATT_MTU_DEFAULT. + */ +typedef struct +{ + uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive. + The default and minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + @mscs + @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} + @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} + @endmscs + */ +} ble_gatt_conn_cfg_t; + +/**@brief GATT Characteristic Properties. */ +typedef struct +{ + /* Standard properties */ + uint8_t broadcast :1; /**< Broadcasting of the value permitted. */ + uint8_t read :1; /**< Reading the value permitted. */ + uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */ + uint8_t write :1; /**< Writing the value with Write Request permitted. */ + uint8_t notify :1; /**< Notification of the value permitted. */ + uint8_t indicate :1; /**< Indications of the value permitted. */ + uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */ +} ble_gatt_char_props_t; + +/**@brief GATT Characteristic Extended Properties. */ +typedef struct +{ + /* Extended properties */ + uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */ + uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */ +} ble_gatt_char_ext_props_t; + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GATT_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_gattc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_gattc.h new file mode 100644 index 0000000000000000000000000000000000000000..b6a75ece770363fae5b3ac85c36bc971dd97a88a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_gattc.h @@ -0,0 +1,700 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_GATTC Generic Attribute Profile (GATT) Client + @{ + @brief Definitions and prototypes for the GATT Client interface. + */ + +#ifndef BLE_GATTC_H__ +#define BLE_GATTC_H__ + +#include "ble_gatt.h" +#include "ble_types.h" +#include "ble_ranges.h" +#include "nrf_svc.h" +#include "nrf_error.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations + * @{ */ + +/**@brief GATTC API SVC numbers. */ +enum BLE_GATTC_SVCS +{ + SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */ + SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */ + SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */ + SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */ + SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */ + SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */ + SD_BLE_GATTC_READ, /**< Generic read. */ + SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */ + SD_BLE_GATTC_WRITE, /**< Generic write. */ + SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */ + SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */ +}; + +/** + * @brief GATT Client Event IDs. + */ +enum BLE_GATTC_EVTS +{ + BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */ + BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */ + BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */ + BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */ + BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */ + BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */ + BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */ + BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */ + BLE_GATTC_EVT_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref ble_gattc_evt_exchange_mtu_rsp_t. */ + BLE_GATTC_EVT_TIMEOUT, /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */ + BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE /**< Write without Response transmission complete. \n See @ref ble_gattc_evt_write_cmd_tx_complete_t. */ +}; + +/** @} */ + +/** @addtogroup BLE_GATTC_DEFINES Defines + * @{ */ + +/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC + * @{ */ +#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */ +/** @} */ + +/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats + * @{ */ +#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */ +#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */ +/** @} */ + +/** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults + * @{ */ +#define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Write without Response that can be queued for transmission. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATTC_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATTC connection configuration parameters, set with @ref sd_ble_cfg_set. + */ +typedef struct +{ + uint8_t write_cmd_tx_queue_size; /**< The guaranteed minimum number of Write without Response that can be queued for transmission. + The default value is @ref BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT */ +} ble_gattc_conn_cfg_t; + +/**@brief Operation Handle Range. */ +typedef struct +{ + uint16_t start_handle; /**< Start Handle. */ + uint16_t end_handle; /**< End Handle. */ +} ble_gattc_handle_range_t; + + +/**@brief GATT service. */ +typedef struct +{ + ble_uuid_t uuid; /**< Service UUID. */ + ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */ +} ble_gattc_service_t; + + +/**@brief GATT include. */ +typedef struct +{ + uint16_t handle; /**< Include Handle. */ + ble_gattc_service_t included_srvc; /**< Handle of the included service. */ +} ble_gattc_include_t; + + +/**@brief GATT characteristic. */ +typedef struct +{ + ble_uuid_t uuid; /**< Characteristic UUID. */ + ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ + uint8_t char_ext_props : 1; /**< Extended properties present. */ + uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */ + uint16_t handle_value; /**< Handle of the Characteristic Value. */ +} ble_gattc_char_t; + + +/**@brief GATT descriptor. */ +typedef struct +{ + uint16_t handle; /**< Descriptor Handle. */ + ble_uuid_t uuid; /**< Descriptor UUID. */ +} ble_gattc_desc_t; + + +/**@brief Write Parameters. */ +typedef struct +{ + uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */ + uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */ + uint16_t handle; /**< Handle to the attribute to be written. */ + uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */ + uint16_t len; /**< Length of data in bytes. */ + uint8_t const *p_value; /**< Pointer to the value data. */ +} ble_gattc_write_params_t; + +/**@brief Attribute Information for 16-bit Attribute UUID. */ +typedef struct +{ + uint16_t handle; /**< Attribute handle. */ + ble_uuid_t uuid; /**< 16-bit Attribute UUID. */ +} ble_gattc_attr_info16_t; + +/**@brief Attribute Information for 128-bit Attribute UUID. */ +typedef struct +{ + uint16_t handle; /**< Attribute handle. */ + ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */ +} ble_gattc_attr_info128_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Service count. */ + ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_prim_srvc_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Include count. */ + ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_rel_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Characteristic count. */ + ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_char_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Descriptor count. */ + ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_desc_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Attribute count. */ + uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */ + union { + ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ + ble_gattc_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ + } info; /**< Attribute information union. */ +} ble_gattc_evt_attr_info_disc_rsp_t; + +/**@brief GATT read by UUID handle value pair. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + uint8_t *p_value; /**< Pointer to the Attribute Value, length is available in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */ +} ble_gattc_handle_value_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */ +typedef struct +{ + uint16_t count; /**< Handle-Value Pair Count. */ + uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */ + uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_char_val_by_uuid_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + uint16_t offset; /**< Offset of the attribute data. */ + uint16_t len; /**< Attribute data length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */ +typedef struct +{ + uint16_t len; /**< Concatenated Attribute values length. */ + uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_char_vals_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */ + uint16_t offset; /**< Data offset. */ + uint16_t len; /**< Data length. */ + uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_write_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */ +typedef struct +{ + uint16_t handle; /**< Handle to which the HVx operation applies. */ + uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ + uint16_t len; /**< Attribute data length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_hvx_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. */ +typedef struct +{ + uint16_t server_rx_mtu; /**< Server RX MTU size. */ +} ble_gattc_evt_exchange_mtu_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */ +typedef struct +{ + uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ +} ble_gattc_evt_timeout_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE. */ +typedef struct +{ + uint8_t count; /**< Number of write without response transmissions completed. */ +} ble_gattc_evt_write_cmd_tx_complete_t; + +/**@brief GATTC event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which event occurred. */ + uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ + uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */ + union + { + ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */ + ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */ + ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */ + ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */ + ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */ + ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */ + ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */ + ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */ + ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */ + ble_gattc_evt_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response Event Parameters. */ + ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */ + ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */ + ble_gattc_evt_write_cmd_tx_complete_t write_cmd_tx_complete; /**< Write without Response transmission complete Event Parameters. */ + } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */ +} ble_gattc_evt_t; +/** @} */ + +/** @addtogroup BLE_GATTC_FUNCTIONS Functions + * @{ */ + +/**@brief Initiate or continue a GATT Primary Service Discovery procedure. + * + * @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle. + * If the last service has not been reached, this function must be called again with an updated start handle value to continue the search. + * + * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with + * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. + * + * @events + * @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] start_handle Handle to start searching from. + * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid)); + + +/**@brief Initiate or continue a GATT Relationship Discovery procedure. + * + * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached, + * this must be called again with an updated handle range to continue the search. + * + * @events + * @event{@ref BLE_GATTC_EVT_REL_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_REL_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Characteristic Discovery procedure. + * + * @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached, + * this must be called again with an updated handle range to continue the discovery. + * + * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with + * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure. + * + * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached, + * this must be called again with an updated handle range to continue the discovery. + * + * @events + * @event{@ref BLE_GATTC_EVT_DESC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_DESC_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure. + * + * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached, + * this must be called again with an updated handle range to continue the discovery. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_UUID_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_uuid Pointer to a Characteristic value UUID to read. + * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range)); + + +/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure. + * + * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor + * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the + * complete value. + * + * @events + * @event{@ref BLE_GATTC_EVT_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_READ_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] handle The handle of the attribute to be read. + * @param[in] offset Offset into the attribute value to be read. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset)); + + +/**@brief Initiate a GATT Read Multiple Characteristic Values procedure. + * + * @details This function initiates a GATT Read Multiple Characteristic Values procedure. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_MULT_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. + * @param[in] handle_count The number of handles in p_handles. + * + * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count)); + + +/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure. + * + * @details This function can perform all write procedures described in GATT. + * + * @note Only one write with response procedure can be ongoing per connection at a time. + * If the application tries to write with response while another write with response procedure is ongoing, + * the function call will return @ref NRF_ERROR_BUSY. + * A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer. + * + * @note The number of Write without Response that can be queued is configured by @ref ble_gattc_conn_cfg_t::write_cmd_tx_queue_size + * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. + * A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete. + * + * @note The application can keep track of the available queue element count for writes without responses by following the procedure below: + * - Store initial queue element count in a variable. + * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS. + * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event. + * + * @events + * @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.} + * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_write_params A pointer to a write parameters structure. + * + * @retval ::NRF_SUCCESS Successfully started the Write procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_BUSY For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry. + * @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued. + * Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry. + */ +SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params)); + + +/**@brief Send a Handle Value Confirmation to the GATT Server. + * + * @mscs + * @mmsc{@ref BLE_GATTC_HVI_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] handle The handle of the attribute in the indication. + * + * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle. + */ +SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle)); + +/**@brief Discovers information about a range of attributes on a GATT server. + * + * @events + * @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.} + * @endevents + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range The range of handles to request information about. + * + * @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range)); + +/**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server. + * + * @details The SoftDevice sets ATT_MTU to the minimum of: + * - The Client RX MTU value, and + * - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. + * + * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. + * + * @events + * @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] client_rx_mtu Client RX MTU size. + * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration + used for this connection. + * - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply + * if an ATT_MTU exchange has already been performed in the other direction. + * + * @retval ::NRF_SUCCESS Successfully sent request to the server. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu)); + +/**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. + * + * @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. + * @note If the buffer contains different event, behavior is undefined. + * @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with + * the next Handle-Value pair in each iteration. If the function returns other than + * @ref NRF_SUCCESS, it will not be changed. + * - To start iteration, initialize the structure to zero. + * - To continue, pass the value from previous iteration. + * + * \code + * ble_gattc_handle_value_t iter; + * memset(&iter, 0, sizeof(ble_gattc_handle_value_t)); + * while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS) + * { + * app_handle = iter.handle; + * memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len); + * } + * \endcode + * + * @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair. + * @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list. + */ +__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter); + +/** @} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter) +{ + uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len; + uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value; + uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first; + + if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count) + { + p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0]; + p_iter->p_value = p_next + sizeof(uint16_t); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_NOT_FOUND; + } +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +#ifdef __cplusplus +} +#endif +#endif /* BLE_GATTC_H__ */ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_gatts.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_gatts.h new file mode 100644 index 0000000000000000000000000000000000000000..6bb24831d870b80df2835f7d2043d7501b9119ae --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_gatts.h @@ -0,0 +1,832 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_GATTS Generic Attribute Profile (GATT) Server + @{ + @brief Definitions and prototypes for the GATTS interface. + */ + +#ifndef BLE_GATTS_H__ +#define BLE_GATTS_H__ + +#include "ble_types.h" +#include "ble_ranges.h" +#include "ble_l2cap.h" +#include "ble_gap.h" +#include "ble_gatt.h" +#include "nrf_svc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations + * @{ */ + +/** + * @brief GATTS API SVC numbers. + */ +enum BLE_GATTS_SVCS +{ + SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */ + SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */ + SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */ + SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */ + SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */ + SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */ + SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */ + SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */ + SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */ + SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */ + SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */ + SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */ + SD_BLE_GATTS_ATTR_GET, /**< Retrieve the UUID and/or metadata of an attribute. */ + SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */ +}; + +/** + * @brief GATT Server Event IDs. + */ +enum BLE_GATTS_EVTS +{ + BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */ + BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */ + BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */ + BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */ + BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. \n No additional event structure applies. */ + BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. */ + BLE_GATTS_EVT_TIMEOUT, /**< Peer failed to respond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */ + BLE_GATTS_EVT_HVN_TX_COMPLETE /**< Handle Value Notification transmission complete. \n See @ref ble_gatts_evt_hvn_tx_complete_t. */ +}; + +/**@brief GATTS Configuration IDs. + * + * IDs that uniquely identify a GATTS configuration. + */ +enum BLE_GATTS_CFGS +{ + BLE_GATTS_CFG_SERVICE_CHANGED = BLE_GATTS_CFG_BASE, /**< Service changed configuration. */ + BLE_GATTS_CFG_ATTR_TAB_SIZE, /**< Attribute table size configuration. */ +}; + +/** @} */ + +/** @addtogroup BLE_GATTS_DEFINES Defines + * @{ */ + +/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS + * @{ */ +#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */ +#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */ +/** @} */ + +/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths + * @{ */ +#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */ +#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */ +/** @} */ + +/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types + * @{ */ +#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */ +#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */ +#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */ +/** @} */ + + +/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types + * @{ */ +#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */ +#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */ +#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */ +#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */ +#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */ +#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */ +#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */ +#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */ +/** @} */ + + +/** @defgroup BLE_GATTS_OPS GATT Server Operations + * @{ */ +#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */ +#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */ +#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ +#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ +#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */ +#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */ +/** @} */ + +/** @defgroup BLE_GATTS_VLOCS GATT Value Locations + * @{ */ +#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */ +#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */ +#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack + will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */ +/** @} */ + +/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types + * @{ */ +#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */ +#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */ +#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */ +/** @} */ + +/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags + * @{ */ +#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */ +#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */ +/** @} */ + +/** @defgroup BLE_GATTS_SERVICE_CHANGED Service Changed Inclusion Values + * @{ + */ +#define BLE_GATTS_SERVICE_CHANGED_DEFAULT (1) /**< Default is to include the Service Changed characteristic in the Attribute Table. */ +/** @} */ + +/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size + * @{ + */ +#define BLE_GATTS_ATTR_TAB_SIZE_MIN (248) /**< Minimum Attribute Table size */ +#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) /**< Default Attribute Table size. */ +/** @} */ + +/** @defgroup BLE_GATTS_DEFAULTS GATT Server defaults + * @{ + */ +#define BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Handle Value Notifications that can be queued for transmission. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATTS_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATTS connection configuration parameters, set with @ref sd_ble_cfg_set. + */ +typedef struct +{ + uint8_t hvn_tx_queue_size; /**< Minimum guaranteed number of Handle Value Notifications that can be queued for transmission. + The default value is @ref BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT */ +} ble_gatts_conn_cfg_t; + +/**@brief Attribute metadata. */ +typedef struct +{ + ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */ + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ + uint8_t vlen :1; /**< Variable length attribute. */ + uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ + uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */ + uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */ +} ble_gatts_attr_md_t; + + +/**@brief GATT Attribute. */ +typedef struct +{ + ble_uuid_t const *p_uuid; /**< Pointer to the attribute UUID. */ + ble_gatts_attr_md_t const *p_attr_md; /**< Pointer to the attribute metadata structure. */ + uint16_t init_len; /**< Initial attribute value length in bytes. */ + uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */ + uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */ + uint8_t *p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer + that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location. + The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/ +} ble_gatts_attr_t; + +/**@brief GATT Attribute Value. */ +typedef struct +{ + uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/ + uint16_t offset; /**< Attribute value offset. */ + uint8_t *p_value; /**< Pointer to where value is stored or will be stored. + If value is stored in user memory, only the attribute length is updated when p_value == NULL. + Set to NULL when reading to obtain the complete length of the attribute value */ +} ble_gatts_value_t; + + +/**@brief GATT Characteristic Presentation Format. */ +typedef struct +{ + uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */ + int8_t exponent; /**< Exponent for integer data types. */ + uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */ + uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ + uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ +} ble_gatts_char_pf_t; + + +/**@brief GATT Characteristic metadata. */ +typedef struct +{ + ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ + ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */ + uint8_t const *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */ + uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */ + uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */ + ble_gatts_char_pf_t const *p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */ + ble_gatts_attr_md_t const *p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */ + ble_gatts_attr_md_t const *p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */ + ble_gatts_attr_md_t const *p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */ +} ble_gatts_char_md_t; + + +/**@brief GATT Characteristic Definition Handles. */ +typedef struct +{ + uint16_t value_handle; /**< Handle to the characteristic value. */ + uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ + uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ + uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ +} ble_gatts_char_handles_t; + + +/**@brief GATT HVx parameters. */ +typedef struct +{ + uint16_t handle; /**< Characteristic Value Handle. */ + uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ + uint16_t offset; /**< Offset within the attribute value. */ + uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after successful return. */ + uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */ +} ble_gatts_hvx_params_t; + +/**@brief GATT Authorization parameters. */ +typedef struct +{ + uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ + uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value. + Please note that for @ref BLE_GATTS_AUTHORIZE_TYPE_WRITE operations this bit must always be set, + as the data to be written needs to be stored and later provided by the application. */ + uint16_t offset; /**< Offset of the attribute value being updated. */ + uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */ + uint8_t const *p_data; /**< Pointer to new value used to update the attribute value. */ +} ble_gatts_authorize_params_t; + +/**@brief GATT Read or Write Authorize Reply parameters. */ +typedef struct +{ + uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ + union { + ble_gatts_authorize_params_t read; /**< Read authorization parameters. */ + ble_gatts_authorize_params_t write; /**< Write authorization parameters. */ + } params; /**< Reply Parameters. */ +} ble_gatts_rw_authorize_reply_params_t; + +/**@brief Service Changed Inclusion configuration parameters, set with @ref sd_ble_cfg_set. */ +typedef struct +{ + uint8_t service_changed : 1; /**< If 1, include the Service Changed characteristic in the Attribute Table. Default is @ref BLE_GATTS_SERVICE_CHANGED_DEFAULT. */ +} ble_gatts_cfg_service_changed_t; + +/**@brief Attribute table size configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: + * - The specified Attribute Table size is too small. + * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. + * - The specified Attribute Table size is not a multiple of 4. + */ +typedef struct +{ + uint32_t attr_tab_size; /**< Attribute table size. Default is @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, minimum is @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. */ +} ble_gatts_cfg_attr_tab_size_t; + +/**@brief Config structure for GATTS configurations. */ +typedef union +{ + ble_gatts_cfg_service_changed_t service_changed; /**< Include service changed characteristic, cfg_id is @ref BLE_GATTS_CFG_SERVICE_CHANGED. */ + ble_gatts_cfg_attr_tab_size_t attr_tab_size; /**< Attribute table size, cfg_id is @ref BLE_GATTS_CFG_ATTR_TAB_SIZE. */ +} ble_gatts_cfg_t; + + +/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + ble_uuid_t uuid; /**< Attribute UUID. */ + uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */ + uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalize the writing operation. */ + uint16_t offset; /**< Offset for the write operation. */ + uint16_t len; /**< Length of the received data. */ + uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gatts_evt_write_t; + +/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ + ble_uuid_t uuid; /**< Attribute UUID. */ + uint16_t offset; /**< Offset for the read operation. */ +} ble_gatts_evt_read_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */ +typedef struct +{ + uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ + union { + ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */ + ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */ + } request; /**< Request Parameters. */ +} ble_gatts_evt_rw_authorize_request_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */ +typedef struct +{ + uint8_t hint; /**< Hint (currently unused). */ +} ble_gatts_evt_sys_attr_missing_t; + + +/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */ +typedef struct +{ + uint16_t handle; /**< Attribute Handle. */ +} ble_gatts_evt_hvc_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST. */ +typedef struct +{ + uint16_t client_rx_mtu; /**< Client RX MTU size. */ +} ble_gatts_evt_exchange_mtu_request_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */ +typedef struct +{ + uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ +} ble_gatts_evt_timeout_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_HVN_TX_COMPLETE. */ +typedef struct +{ + uint8_t count; /**< Number of notification transmissions completed. */ +} ble_gatts_evt_hvn_tx_complete_t; + +/**@brief GATTS event structure. */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle on which the event occurred. */ + union + { + ble_gatts_evt_write_t write; /**< Write Event Parameters. */ + ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */ + ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */ + ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */ + ble_gatts_evt_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */ + ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */ + ble_gatts_evt_hvn_tx_complete_t hvn_tx_complete; /**< Handle Value Notification transmission complete Event Parameters. */ + } params; /**< Event Parameters. */ +} ble_gatts_evt_t; + +/** @} */ + +/** @addtogroup BLE_GATTS_FUNCTIONS Functions + * @{ */ + +/**@brief Add a service declaration to the Attribute Table. + * + * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to + * add a secondary service declaration that is not referenced by another service later in the Attribute Table. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES. + * @param[in] p_uuid Pointer to service UUID. + * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a service declaration. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle)); + + +/**@brief Add an include declaration to the Attribute Table. + * + * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time). + * + * @note The included service must already be present in the Attribute Table prior to this call. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] inc_srvc_handle Handle of the included service. + * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added an include declaration. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + */ +SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle)); + + +/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table. + * + * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time). + * + * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writable auxiliaries bits, + * readable (no security) and writable (selectable) CCCDs and SCCDs and valid presentation format values. + * + * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] p_char_md Characteristic metadata. + * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value. + * @param[out] p_handles Pointer to the structure where the assigned handles will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a characteristic. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + */ +SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles)); + + +/**@brief Add a descriptor to the Attribute Table. + * + * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time). + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. + * @param[in] p_attr Pointer to the attribute structure. + * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a descriptor. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + */ +SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle)); + +/**@brief Set the value of a given attribute. + * + * @note Values other than system attributes can be set at any time, regardless of whether any active connections exist. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. + * @param[in] handle Attribute handle. + * @param[in,out] p_value Attribute value information. + * + * @retval ::NRF_SUCCESS Successfully set the value of the attribute. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. + */ +SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); + +/**@brief Get the value of a given attribute. + * + * @note If the attribute value is longer than the size of the supplied buffer, + * p_len will return the total attribute value length (excluding offset), + * and not the number of bytes actually returned in p_data. + * The application may use this information to allocate a suitable buffer size. + * + * @note When retrieving system attribute values with this function, the connection handle + * may refer to an already disconnected connection. Refer to the documentation of + * @ref sd_ble_gatts_sys_attr_get for further information. + * + * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. + * @param[in] handle Attribute handle. + * @param[in,out] p_value Attribute value information. + * + * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. + */ +SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); + +/**@brief Notify or Indicate an attribute value. + * + * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation + * (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that + * the application can atomically perform a value update and a server initiated transaction with a single API call. + * + * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution. + * The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, + * @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES. + * The caller can check whether the value has been updated by looking at the contents of *(p_hvx_params->p_len). + * + * @note Only one indication procedure can be ongoing per connection at a time. + * If the application tries to indicate an attribute value while another indication procedure is ongoing, + * the function call will return @ref NRF_ERROR_BUSY. + * A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer. + * + * @note The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size + * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. + * A @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete. + * + * @note The application can keep track of the available queue element count for notifications by following the procedure below: + * - Store initial queue element count in a variable. + * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS. + * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event. + * + * @events + * @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.} + * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_HVN_MSC} + * @mmsc{@ref BLE_GATTS_HVI_MSC} + * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_hvx_params Pointer to an HVx parameters structure. If the p_data member contains a non-NULL pointer the attribute value will be updated with + * the contents pointed by it before sending the notification or indication. + * + * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: + * - Invalid Connection State + * - Notifications and/or indications not enabled in the CCCD + * - An ATT_MTU exchange is ongoing + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate. + * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. + * @retval ::NRF_ERROR_RESOURCES Too many notifications queued. + * Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry. + */ +SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params)); + +/**@brief Indicate the Service Changed attribute value. + * + * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute + * Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will + * be issued. + * + * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here. + * + * @events + * @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_SC_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] start_handle Start of affected attribute handle range. + * @param[in] end_handle End of affected attribute handle range. + * + * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref + * sd_ble_cfg_set and @ref ble_gatts_cfg_service_changed_t. + * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: + * - Invalid Connection State + * - Notifications and/or indications not enabled in the CCCD + * - An ATT_MTU exchange is ongoing + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application. + * @retval ::NRF_ERROR_BUSY Procedure already in progress. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. + */ +SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle)); + +/**@brief Respond to a Read/Write authorization request. + * + * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application. + * + * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond + * to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update + * is set to 0. + * + * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending. + * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid, + * handle supplied does not match requested handle, + * or invalid data to be written provided by the application. + */ +SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params)); + + +/**@brief Update persistent system attribute information. + * + * @details Supply information about persistent system attributes to the stack, + * previously obtained using @ref sd_ble_gatts_sys_attr_get. + * This call is only allowed for active connections, and is usually + * made immediately after a connection is established with an known bonded device, + * often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. + * + * p_sysattrs may point directly to the application's stored copy of the system attributes + * obtained using @ref sd_ble_gatts_sys_attr_get. + * If the pointer is NULL, the system attribute info is initialized, assuming that + * the application does not have any previously saved system attribute data for this device. + * + * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration. + * + * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially. + * This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or + * reset the SoftDevice to return to a known state. + * + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified. + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified. + * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL. + * @param[in] len Size of data pointed by p_sys_attr_data, in octets. + * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS + * + * @retval ::NRF_SUCCESS Successfully set the system attribute information. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. + * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags)); + + +/**@brief Retrieve persistent system attribute information from the stack. + * + * @details This call is used to retrieve information about values to be stored persistently by the application + * during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device, + * the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set. + * If retrieved after disconnection, the data should be read before a new connection established. The connection handle for + * the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it. + * Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes + * may be written to at any time by the peer during a connection's lifetime. + * + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned. + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned. + * + * @mscs + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle of the recently terminated connection. + * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described + * in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data. + * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditionally updated to actual length of system attribute data. + * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS + * + * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. + * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer. + * @retval ::NRF_ERROR_NOT_FOUND No system attributes found. + */ +SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); + + +/**@brief Retrieve the first valid user attribute handle. + * + * @param[out] p_handle Pointer to an integer where the handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully retrieved the handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle)); + +/**@brief Retrieve the attribute UUID and/or metadata. + * + * @param[in] handle Attribute handle + * @param[out] p_uuid UUID of the attribute. Use NULL to omit this field. + * @param[out] p_md Metadata of the attribute. Use NULL to omit this field. + * + * @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata, + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL. + * @retval ::NRF_ERROR_NOT_FOUND Attribute was not found. + */ +SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md)); + +/**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client. + * + * @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. + * + * @details The SoftDevice sets ATT_MTU to the minimum of: + * - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and + * - The Server RX MTU value. + * + * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. + * + * @mscs + * @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] server_rx_mtu Server RX MTU size. + * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration + used for this connection. + * - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request + * if an ATT_MTU exchange has already been performed in the other direction. + * + * @retval ::NRF_SUCCESS Successfully sent response to the client. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied. + */ +SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu)); +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GATTS_H__ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_hci.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_hci.h new file mode 100644 index 0000000000000000000000000000000000000000..21293e8efcc2d38693127cc8557d90a7bd1f8560 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_hci.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_COMMON + @{ +*/ + + +#ifndef BLE_HCI_H__ +#define BLE_HCI_H__ +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes + * @{ */ + +#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */ +#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */ +#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */ +/*0x03 Hardware Failure +0x04 Page Timeout +*/ +#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */ +#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */ +#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */ +#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */ +/*0x09 Connection Limit Exceeded +0x0A Synchronous Connection Limit To A Device Exceeded +0x0B ACL Connection Already Exists*/ +#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */ +/*0x0D Connection Rejected due to Limited Resources +0x0E Connection Rejected Due To Security Reasons +0x0F Connection Rejected due to Unacceptable BD_ADDR +0x10 Connection Accept Timeout Exceeded +0x11 Unsupported Feature or Parameter Value*/ +#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */ +#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */ +#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/ +#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */ +#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */ +/* +0x17 Repeated Attempts +0x18 Pairing Not Allowed +0x19 Unknown LMP PDU +*/ +#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */ +/* +0x1B SCO Offset Rejected +0x1C SCO Interval Rejected +0x1D SCO Air Mode Rejected*/ +#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */ +#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */ +/*0x20 Unsupported LMP Parameter Value +0x21 Role Change Not Allowed +*/ +#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */ +#define BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23 /**< LMP Error Transaction Collision/LL Procedure Collision. */ +#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */ +/*0x25 Encryption Mode Not Acceptable +0x26 Link Key Can Not be Changed +0x27 Requested QoS Not Supported +*/ +#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */ +#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */ +#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */ +/* +0x2B Reserved +0x2C QoS Unacceptable Parameter +0x2D QoS Rejected +0x2E Channel Classification Not Supported +0x2F Insufficient Security +0x30 Parameter Out Of Mandatory Range +0x31 Reserved +0x32 Role Switch Pending +0x33 Reserved +0x34 Reserved Slot Violation +0x35 Role Switch Failed +0x36 Extended Inquiry Response Too Large +0x37 Secure Simple Pairing Not Supported By Host. +0x38 Host Busy - Pairing +0x39 Connection Rejected due to No Suitable Channel Found*/ +#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */ +#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */ +#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Advertisement Timeout. */ +#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */ +#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */ + +/** @} */ + + +#ifdef __cplusplus +} +#endif +#endif // BLE_HCI_H__ + +/** @} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_l2cap.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_l2cap.h new file mode 100644 index 0000000000000000000000000000000000000000..90cce565d8e037dbb21d82336266d635af524b6d --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_l2cap.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP) + @{ + @brief Definitions and prototypes for the L2CAP interface. + */ + +#ifndef BLE_L2CAP_H__ +#define BLE_L2CAP_H__ + +#include "ble_types.h" +#include "ble_ranges.h" +#include "ble_err.h" +#include "nrf_svc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup BLE_L2CAP_DEFINES Defines + * @{ */ + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_L2CAP_H__ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_ranges.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_ranges.h new file mode 100644 index 0000000000000000000000000000000000000000..f9c6af76b803a8899e42e47888df41005b8b5243 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_ranges.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_COMMON + @{ + @defgroup ble_ranges Module specific SVC, event and option number subranges + @{ + + @brief Definition of SVC, event and option number subranges for each API module. + + @note + SVCs, event and option numbers are split into subranges for each API module. + Each module receives its entire allocated range of SVC calls, whether implemented or not, + but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range. + + Note that the symbols BLE__SVC_LAST is the end of the allocated SVC range, + rather than the last SVC function call actually defined and implemented. + + Specific SVC, event and option values are defined in each module's ble_.h file, + which defines names of each individual SVC code based on the range start value. +*/ + +#ifndef BLE_RANGES_H__ +#define BLE_RANGES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */ +#define BLE_SVC_LAST 0x6B /**< Common BLE SVC last. */ + +#define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */ +#define BLE_GAP_SVC_LAST 0x93 /**< GAP BLE SVC last. */ + +#define BLE_GATTC_SVC_BASE 0x94 /**< GATTC BLE SVC base. */ +#define BLE_GATTC_SVC_LAST 0x9F /**< GATTC BLE SVC last. */ + +#define BLE_GATTS_SVC_BASE 0xA0 /**< GATTS BLE SVC base. */ +#define BLE_GATTS_SVC_LAST 0xAF /**< GATTS BLE SVC last. */ + +#define BLE_L2CAP_SVC_BASE 0xB0 /**< L2CAP BLE SVC base. */ +#define BLE_L2CAP_SVC_LAST 0xBF /**< L2CAP BLE SVC last. */ + + +#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */ + +#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */ +#define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */ + +#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */ +#define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */ + +#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */ +#define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */ + +#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */ +#define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */ + +#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */ +#define BLE_L2CAP_EVT_LAST 0x8F /**< L2CAP BLE Event last. */ + + +#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */ + +#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */ +#define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */ + +#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */ +#define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */ + +#define BLE_GATT_OPT_BASE 0x40 /**< GATT BLE Option base. */ +#define BLE_GATT_OPT_LAST 0x5F /**< GATT BLE Option last. */ + +#define BLE_GATTC_OPT_BASE 0x60 /**< GATTC BLE Option base. */ +#define BLE_GATTC_OPT_LAST 0x7F /**< GATTC BLE Option last. */ + +#define BLE_GATTS_OPT_BASE 0x80 /**< GATTS BLE Option base. */ +#define BLE_GATTS_OPT_LAST 0x9F /**< GATTS BLE Option last. */ + +#define BLE_L2CAP_OPT_BASE 0xA0 /**< L2CAP BLE Option base. */ +#define BLE_L2CAP_OPT_LAST 0xBF /**< L2CAP BLE Option last. */ + + +#define BLE_CFG_INVALID 0x00 /**< Invalid BLE configuration. */ + +#define BLE_CFG_BASE 0x01 /**< Common BLE configuration base. */ +#define BLE_CFG_LAST 0x1F /**< Common BLE configuration last. */ + +#define BLE_CONN_CFG_BASE 0x20 /**< BLE connection configuration base. */ +#define BLE_CONN_CFG_LAST 0x3F /**< BLE connection configuration last. */ + +#define BLE_GAP_CFG_BASE 0x40 /**< GAP BLE configuration base. */ +#define BLE_GAP_CFG_LAST 0x5F /**< GAP BLE configuration last. */ + +#define BLE_GATT_CFG_BASE 0x60 /**< GATT BLE configuration base. */ +#define BLE_GATT_CFG_LAST 0x7F /**< GATT BLE configuration last. */ + +#define BLE_GATTC_CFG_BASE 0x80 /**< GATTC BLE configuration base. */ +#define BLE_GATTC_CFG_LAST 0x9F /**< GATTC BLE configuration last. */ + +#define BLE_GATTS_CFG_BASE 0xA0 /**< GATTS BLE configuration base. */ +#define BLE_GATTS_CFG_LAST 0xBF /**< GATTS BLE configuration last. */ + +#define BLE_L2CAP_CFG_BASE 0xC0 /**< L2CAP BLE configuration base. */ +#define BLE_L2CAP_CFG_LAST 0xDF /**< L2CAP BLE configuration last. */ + + + + + +#ifdef __cplusplus +} +#endif +#endif /* BLE_RANGES_H__ */ + +/** + @} + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_types.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_types.h new file mode 100644 index 0000000000000000000000000000000000000000..e24be0b57496ea7d058794dc20a84868a31b0f3b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/ble_types.h @@ -0,0 +1,205 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 BLE_COMMON + @{ + @defgroup ble_types Common types and macro definitions + @{ + + @brief Common types and macro definitions for the BLE SoftDevice. + */ + +#ifndef BLE_TYPES_H__ +#define BLE_TYPES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_TYPES_DEFINES Defines + * @{ */ + +/** @defgroup BLE_CONN_HANDLES BLE Connection Handles + * @{ */ +#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */ +#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */ +/** @} */ + + +/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs + * @{ */ +/* Generic UUIDs, applicable to all services */ +#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */ +#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */ +#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */ +#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */ +#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */ +#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */ +#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */ +/* GATT specific UUIDs */ +#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */ +#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */ +/* GAP specific UUIDs */ +#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */ +#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution Characteristic. */ +/** @} */ + + +/** @defgroup BLE_UUID_TYPES Types of UUID + * @{ */ +#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */ +#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */ +#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */ +/** @} */ + + +/** @defgroup BLE_APPEARANCES Bluetooth Appearance values + * @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml + * @{ */ +#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */ +#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */ +#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */ +#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */ +#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */ +#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */ +#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */ +#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */ +#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */ +#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */ +#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */ +#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */ +#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */ +#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */ +#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */ +#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */ +#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */ +#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */ +#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */ +#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */ +#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */ +#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */ +#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */ +#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystick (HID Subtype). */ +#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */ +#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */ +#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */ +#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */ +#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */ +#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */ +#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */ +#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */ +#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */ +#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */ +#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */ +#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */ +#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */ +#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */ +#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */ +#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */ +#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */ +#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */ +/** @} */ + +/** @brief Set .type and .uuid fields of ble_uuid_struct to specified UUID value. */ +#define BLE_UUID_BLE_ASSIGN(instance, value) do {\ + instance.type = BLE_UUID_TYPE_BLE; \ + instance.uuid = value;} while(0) + +/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */ +#define BLE_UUID_COPY_PTR(dst, src) do {\ + (dst)->type = (src)->type; \ + (dst)->uuid = (src)->uuid;} while(0) + +/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */ +#define BLE_UUID_COPY_INST(dst, src) do {\ + (dst).type = (src).type; \ + (dst).uuid = (src).uuid;} while(0) + +/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ +#define BLE_UUID_EQ(p_uuid1, p_uuid2) \ + (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid)) + +/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ +#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \ + (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid)) + +/** @} */ + +/** @addtogroup BLE_TYPES_STRUCTURES Structures + * @{ */ + +/** @brief 128 bit UUID values. */ +typedef struct +{ + uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */ +} ble_uuid128_t; + +/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */ +typedef struct +{ + uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ + uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ +} ble_uuid_t; + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* BLE_TYPES_H__ */ + +/** + @} + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf52/nrf_mbr.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf52/nrf_mbr.h new file mode 100644 index 0000000000000000000000000000000000000000..ccbe96bd59e01b83139b37b588c57e132239dca6 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf52/nrf_mbr.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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. + * + */ +/** + @defgroup nrf_mbr_api Master Boot Record API + @{ + + @brief APIs for updating SoftDevice and BootLoader + +*/ + +#ifndef NRF_MBR_H__ +#define NRF_MBR_H__ + +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup NRF_MBR_DEFINES Defines + * @{ */ + +/**@brief MBR SVC Base number. */ +#define MBR_SVC_BASE (0x18) + +/**@brief Page size in words. */ +#define MBR_PAGE_SIZE_IN_WORDS (1024) + +/** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash. +This is the offset where the first byte of the SoftDevice hex file is written.*/ +#define MBR_SIZE (0x1000) + +/** @} */ + +/** @addtogroup NRF_MBR_ENUMS Enumerations + * @{ */ + +/**@brief nRF Master Boot Record API SVC numbers. */ +enum NRF_MBR_SVCS +{ + SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */ +}; + +/**@brief Possible values for ::sd_mbr_command_t.command */ +enum NRF_MBR_COMMANDS +{ + SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see sd_mbr_command_copy_bl_t*/ + SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/ + SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD*/ + SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/ + SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Start forwarding all exception to this address @see ::sd_mbr_command_vector_table_base_set_t*/ +}; + +/** @} */ + +/** @addtogroup NRF_MBR_TYPES Types + * @{ */ + +/**@brief This command copies part of a new SoftDevice + * The destination area is erased before copying. + * If dst is in the middle of a flash page, that whole flash page will be erased. + * If (dst+len) is in the middle of a flash page, that whole flash page will be erased. + * + * The user of this function is responsible for setting the BPROT registers. + * + * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. + * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + */ +typedef struct +{ + uint32_t *src; /**< Pointer to the source of data to be copied.*/ + uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/ + uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/ +} sd_mbr_command_copy_sd_t; + + +/**@brief This command works like memcmp, but takes the length in words. + * + * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal. + * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal. + */ +typedef struct +{ + uint32_t *ptr1; /**< Pointer to block of memory. */ + uint32_t *ptr2; /**< Pointer to block of memory. */ + uint32_t len; /**< Number of 32 bit words to compare.*/ +} sd_mbr_command_compare_t; + + +/**@brief This command copies a new BootLoader. + * With this command, destination of BootLoader is always the address written in NRF_UICR->BOOTADDR. + * + * Destination is erased by this function. + * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased. + * + * This function will use PROTENSET to protect the flash that is not intended to be written. + * + * On success, this function will not return. It will start the new BootLoader from reset-vector as normal. + * + * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. + * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set. + * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area. + * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info) + */ +typedef struct +{ + uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/ + uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */ +} sd_mbr_command_copy_bl_t; + +/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR + * + * Once this function has been called, this address is where the MBR will start to forward interrupts to after a reset. + * + * To restore default forwarding this function should be called with @param address set to 0. + * The MBR will then start forwarding to interrupts to the address in NFR_UICR->BOOTADDR or to the SoftDevice if the BOOTADDR is not set. + * + * On success, this function will not return. It will reset the device. + * + * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. + * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size. + * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info) + */ +typedef struct +{ + uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ +} sd_mbr_command_vector_table_base_set_t; + + +typedef struct +{ + uint32_t command; /**< type of command to be issued see @ref NRF_MBR_COMMANDS. */ + union + { + sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/ + sd_mbr_command_compare_t compare; /**< Parameters for verify.*/ + sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */ + sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/ + } params; +} sd_mbr_command_t; + +/** @} */ + +/** @addtogroup NRF_MBR_FUNCTIONS Functions + * @{ */ + +/**@brief Issue Master Boot Record commands + * + * Commands used when updating a SoftDevice and bootloader. + * + * The SD_MBR_COMMAND_COPY_BL and SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires parameters to be + * retained by the MBR when resetting the IC. This is done in a separate flash page + * provided by the application. The UICR register UICR.NRFFW[1] must be set + * to an address corresponding to a page in the application flash space. This page will be cleared + * by the MBR and used to store the command before reset. When the UICR.NRFFW[1] field is set + * the page it refers to must not be used by the application. If the UICR.NRFFW[1] is set to + * 0xFFFFFFFF (the default) MBR commands which use flash will be unavailable and return + * NRF_ERROR_NO_MEM. + * + * @param[in] param Pointer to a struct describing the command. + * + * @note For return values, see ::sd_mbr_command_copy_sd_t ::sd_mbr_command_copy_bl_t ::sd_mbr_command_compare_t ::sd_mbr_command_vector_table_base_set_t + * + * @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. +*/ +SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_MBR_H__ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_error.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_error.h new file mode 100644 index 0000000000000000000000000000000000000000..43c091630bdcd0a3922170d0c32371a643580d9a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_error.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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. + * + */ + /** + @defgroup nrf_error SoftDevice Global Error Codes + @{ + + @brief Global Error definitions +*/ + +/* Header guard */ +#ifndef NRF_ERROR_H__ +#define NRF_ERROR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions + * @{ */ +#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base +#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base +#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base +#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base +/** @} */ + +#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command +#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing +#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled +#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error +#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation +#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found +#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported +#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter +#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state +#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length +#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags +#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data +#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size +#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out +#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer +#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation +#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address +#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy +#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded. +#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_H__ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_error_sdm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_error_sdm.h new file mode 100644 index 0000000000000000000000000000000000000000..103659a913899d0ab0b59a7e6042e6a8d3b612a2 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_error_sdm.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 nrf_sdm_api + @{ + @defgroup nrf_sdm_error SoftDevice Manager Error Codes + @{ + + @brief Error definitions for the SDM API +*/ + +/* Header guard */ +#ifndef NRF_ERROR_SDM_H__ +#define NRF_ERROR_SDM_H__ + +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown LFCLK source. +#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). +#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing). + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_SDM_H__ + +/** + @} + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_error_soc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_error_soc.h new file mode 100644 index 0000000000000000000000000000000000000000..e31d8c9c97831f67e895855e4ce433b45beacf1e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_error_soc.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 nrf_soc_api + @{ + @defgroup nrf_soc_error SoC Library Error Codes + @{ + + @brief Error definitions for the SoC library + +*/ + +/* Header guard */ +#ifndef NRF_ERROR_SOC_H__ +#define NRF_ERROR_SOC_H__ + +#include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* Mutex Errors */ +#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken + +/* NVIC errors */ +#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available +#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed +#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return + +/* Power errors */ +#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown +#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown +#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return + +/* Rand errors */ +#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values + +/* PPI errors */ +#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel +#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_SOC_H__ +/** + @} + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_nvic.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_nvic.h new file mode 100644 index 0000000000000000000000000000000000000000..f4e3808071fa4dc883579971eb6c1d62fbcbdc14 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_nvic.h @@ -0,0 +1,517 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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. + * + */ +/** + * @defgroup nrf_nvic_api SoftDevice NVIC API + * @{ + * + * @note In order to use this module, the following code has to be added to a .c file: + * \code + * nrf_nvic_state_t nrf_nvic_state = {0}; + * \endcode + * + * @note Definitions and declarations starting with __ (double underscore) in this header file are + * not intended for direct use by the application. + * + * @brief APIs for the accessing NVIC when using a SoftDevice. + * + */ + +#ifndef NRF_NVIC_H__ +#define NRF_NVIC_H__ + +#include +#include "nrf.h" + +#include "nrf_error_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup NRF_NVIC_DEFINES Defines + * @{ */ + +/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions + * @{ */ + +#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */ + +#ifdef NRF51 + #define __NRF_NVIC_ISER_COUNT (1) /**< The number of ISER/ICER registers in the NVIC that are used. */ + + /**@brief Interrupts used by the SoftDevice. */ + #define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ + (1U << POWER_CLOCK_IRQn) \ + | (1U << RADIO_IRQn) \ + | (1U << RTC0_IRQn) \ + | (1U << TIMER0_IRQn) \ + | (1U << RNG_IRQn) \ + | (1U << ECB_IRQn) \ + | (1U << CCM_AAR_IRQn) \ + | (1U << TEMP_IRQn) \ + | (1U << __NRF_NVIC_NVMC_IRQn) \ + | (1U << (uint32_t)SWI5_IRQn) \ + )) + + /**@brief Interrupts available for to application. */ + #define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) +#endif + +#if defined(NRF52) || defined(NRF52840_XXAA) + #define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */ + + /**@brief Interrupts used by the SoftDevice. */ + #define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ + (1U << POWER_CLOCK_IRQn) \ + | (1U << RADIO_IRQn) \ + | (1U << RTC0_IRQn) \ + | (1U << TIMER0_IRQn) \ + | (1U << RNG_IRQn) \ + | (1U << ECB_IRQn) \ + | (1U << CCM_AAR_IRQn) \ + | (1U << TEMP_IRQn) \ + | (1U << __NRF_NVIC_NVMC_IRQn) \ + | (1U << (uint32_t)SWI5_EGU5_IRQn) \ + )) + #define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0) + + /**@brief Interrupts available for to application. */ + #define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) + #define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1) +#endif +/**@} */ + +/**@} */ + +/**@addtogroup NRF_NVIC_VARIABLES Variables + * @{ */ + +/**@brief Type representing the state struct for the SoftDevice NVIC module. */ +typedef struct +{ + uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */ + uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */ +} nrf_nvic_state_t; + +/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an + * application source file. */ +extern nrf_nvic_state_t nrf_nvic_state; + +/**@} */ + +/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions + * @{ */ + +/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts. + * + * @retval The value of PRIMASK prior to disabling the interrupts. + */ +__STATIC_INLINE int __sd_nvic_irq_disable(void); + +/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts. + */ +__STATIC_INLINE void __sd_nvic_irq_enable(void); + +/**@brief Checks if IRQn is available to application + * @param[in] IRQn IRQ to check + * + * @retval 1 (true) if the IRQ to check is available to the application + */ +__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn); + +/**@brief Checks if priority is available to application + * @param[in] priority priority to check + * + * @retval 1 (true) if the priority to check is available to the application + */ +__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority); + +/**@} */ + +/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions + * @{ */ + +/**@brief Enable External Interrupt. + * @note Corresponds to NVIC_EnableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was enabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn); + +/**@brief Disable External Interrupt. + * @note Corresponds to NVIC_DisableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was disabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn); + +/**@brief Get Pending Interrupt. + * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. + * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. + * + * @retval ::NRF_SUCCESS The interrupt is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq); + +/**@brief Set Pending Interrupt. + * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt is set pending. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn); + +/**@brief Clear Pending Interrupt. + * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn); + +/**@brief Set Interrupt Priority. + * @note Corresponds to NVIC_SetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * @pre Priority is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. + * @param[in] priority A valid IRQ priority for use by the application. + * + * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority); + +/**@brief Get Interrupt Priority. + * @note Corresponds to NVIC_GetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. + * @param[out] p_priority Return value from NVIC_GetPriority. + * + * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority); + +/**@brief System Reset. + * @note Corresponds to NVIC_SystemReset in CMSIS. + * + * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN + */ +__STATIC_INLINE uint32_t sd_nvic_SystemReset(void); + +/**@brief Enter critical region. + * + * @post Application interrupts will be disabled. + * @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each + * execution context + * @sa sd_nvic_critical_region_exit + * + * @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region. + * + * @retval ::NRF_SUCCESS + */ +__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region); + +/**@brief Exit critical region. + * + * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. + * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. + * + * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. + * + * @retval ::NRF_SUCCESS + */ +__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region); + +/**@} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE int __sd_nvic_irq_disable(void) +{ + int pm = __get_PRIMASK(); + __disable_irq(); + return pm; +} + +__STATIC_INLINE void __sd_nvic_irq_enable(void) +{ + __enable_irq(); +} + +__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn) +{ + if (IRQn < 32) + { + return ((1UL<= (1 << __NVIC_PRIO_BITS)) + { + return 0; + } +#ifdef NRF51 + if( priority == 0 + || priority == 2 + ) + { + return 0; + } +#endif +#if defined(NRF52) || defined(NRF52840_XXAA) + if( priority == 0 + || priority == 1 + || priority == 4 + || priority == 5 + ) + { + return 0; + } +#endif + return 1; +} + + +__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn))) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + if (nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); + } + else + { + NVIC_EnableIRQ(IRQn); + } + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F)); + } + else + { + NVIC_DisableIRQ(IRQn); + } + + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + *p_pending_irq = NVIC_GetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + NVIC_SetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + NVIC_ClearPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (!__sd_nvic_is_app_accessible_priority(priority)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + NVIC_SetPriority(IRQn, (uint32_t)priority); + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + *p_priority = (NVIC_GetPriority(IRQn) & 0xFF); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SystemReset(void) +{ + NVIC_SystemReset(); + return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN; +} + +__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region) +{ + int was_masked = __sd_nvic_irq_disable(); + if (!nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__cr_flag = 1; + nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 ); + NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0; + #if defined(NRF52) || defined(NRF52840_XXAA) + nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 ); + NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1; + #endif + *p_is_nested_critical_region = 0; + } + else + { + *p_is_nested_critical_region = 1; + } + if (!was_masked) + { + __sd_nvic_irq_enable(); + } + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) +{ + if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0)) + { + int was_masked = __sd_nvic_irq_disable(); + NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0]; + #if defined(NRF52) || defined(NRF52840_XXAA) + NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1]; + #endif + nrf_nvic_state.__cr_flag = 0; + if (!was_masked) + { + __sd_nvic_irq_enable(); + } + } + + return NRF_SUCCESS; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_NVIC_H__ + +/**@} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_sd_def.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_sd_def.h new file mode 100644 index 0000000000000000000000000000000000000000..0b4d221d6a47d2a9b7e25b6deb90f293c480ce77 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_sd_def.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SD_DEF_H__ +#define NRF_SD_DEF_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SD_PPI_CHANNELS_USED 0xFFFE0000uL /**< PPI channels utilized by SotfDevice (not available to the application). */ +#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */ +#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */ +#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SD_DEF_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_sdm.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_sdm.h new file mode 100644 index 0000000000000000000000000000000000000000..57ffe13358df8066fcfab45c7a31d1bc1de65961 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_sdm.h @@ -0,0 +1,338 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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. + * + */ +/** + @defgroup nrf_sdm_api SoftDevice Manager API + @{ + + @brief APIs for SoftDevice management. + +*/ + +#ifndef NRF_SDM_H__ +#define NRF_SDM_H__ + +#include "nrf_svc.h" +#include "nrf.h" +#include "nrf_soc.h" +#include "nrf_error_sdm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ +#ifdef NRFSOC_DOXYGEN +/// Declared in nrf_mbr.h +#define MBR_SIZE 0 +#warning test +#endif + +/** @brief The major version for the SoftDevice binary distributed with this header file. */ +#define SD_MAJOR_VERSION (0) + +/** @brief The minor version for the SoftDevice binary distributed with this header file. */ +#define SD_MINOR_VERSION (0) + +/** @brief The bugfix version for the SoftDevice binary distributed with this header file. */ +#define SD_BUGFIX_VERSION (0) + +/** @brief The full version number for the SoftDevice binary this header file was distributed + * with, as a decimal number in the form Mmmmbbb, where: + * - M is major version (one or more digits) + * - mmm is minor version (three digits) + * - bbb is bugfix version (three digits). */ +#define SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION) + +/** @brief SoftDevice Manager SVC Base number. */ +#define SDM_SVC_BASE 0x10 + +/** @brief Invalid info field. Returned when an info field does not exist. */ +#define SDM_INFO_FIELD_INVALID (0) + +/** @brief Defines the SoftDevice Information Structure location (address) as an offset from +the start of the SoftDevice (without MBR)*/ +#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) + +/** @brief Defines the absolute SoftDevice Information Structure location (address) when the + * SoftDevice is installed just above the MBR (the usual case). */ +#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) + +/** @brief Defines the offset for the SoftDevice Information Structure size value relative to the + * SoftDevice base address. The size value is of type uint8_t. */ +#define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET) + +/** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address. + * The size value is of type uint32_t. */ +#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) + +/** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value + * is of type uint16_t. */ +#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) + +/** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID + * is of type uint32_t. */ +#define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10) + +/** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in + * the same format as @ref SD_VERSION, stored as an uint32_t. */ +#define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14) + +/** @brief Defines a macro for retrieving the actual SoftDevice Information Structure size value + * from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is + * installed just above the MBR (the usual case). */ +#define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *) ((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET))) + +/** @brief Defines a macro for retrieving the actual SoftDevice size value from a given base + * address. Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above + * the MBR (the usual case). */ +#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET))) + +/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use @ref + * MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual + * case). */ +#define SD_FWID_GET(baseaddr) (*((uint16_t *) ((baseaddr) + SD_FWID_OFFSET))) + +/** @brief Defines a macro for retrieving the actual SoftDevice ID from a given base address. Use + * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the + * usual case). */ +#define SD_ID_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (*((uint32_t *) ((baseaddr) + SD_ID_OFFSET))) : SDM_INFO_FIELD_INVALID) + +/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use @ref + * MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual + * case). */ +#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID) + +/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges + * @{ */ +#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */ +#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */ +/**@} */ + +/**@defgroup NRF_FAULT_IDS Fault ID types + * @{ */ +#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter is reserved for future used. */ +#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access (nRF52 only). The info parameter will contain 0x00000000, in case of SoftDevice RAM + access violation. In case of SoftDevice peripheral register violation the info parameter will contain the sub-region number of PREGION[0], on whose address range the disallowed + write access caused the memory access fault. */ +/**@} */ + +/** @} */ + +/** @addtogroup NRF_SDM_ENUMS Enumerations + * @{ */ + +/**@brief nRF SoftDevice Manager API SVC numbers. */ +enum NRF_SD_SVCS +{ + SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */ + SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */ + SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */ + SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */ + SVC_SDM_LAST /**< Placeholder for last SDM SVC */ +}; + +/** @} */ + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ + +/**@defgroup NRF_CLOCK_LF_XTAL_ACCURACY Clock accuracy + * @{ */ + +#define NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM (0) /**< Default: 250 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_500_PPM (1) /**< 500 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_150_PPM (2) /**< 150 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_100_PPM (3) /**< 100 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_75_PPM (4) /**< 75 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_50_PPM (5) /**< 50 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_30_PPM (6) /**< 30 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM (7) /**< 20 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_10_PPM (8) /**< 10 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_5_PPM (9) /**< 5 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_2_PPM (10) /**< 2 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_1_PPM (11) /**< 1 ppm */ + +/** @} */ + +/**@defgroup NRF_CLOCK_LF_SRC Possible LFCLK oscillator sources + * @{ */ + +#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */ +#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */ +#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */ + +/** @} */ + +/** @} */ + +/** @addtogroup NRF_SDM_TYPES Types + * @{ */ + +/**@brief Type representing LFCLK oscillator source. */ +typedef struct +{ + uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */ + uint8_t rc_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second + units (nRF51: 1-64, nRF52: 1-32). + @note To avoid excessive clock drift, 0.5 degrees Celsius is the + maximum temperature change allowed in one calibration timer + interval. The interval should be selected to ensure this. + + @note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. */ + uint8_t rc_temp_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: How often (in number of calibration + intervals) the RC oscillator shall be calibrated if the temperature + hasn't changed. + 0: Always calibrate even if the temperature hasn't changed. + 1: Only calibrate if the temperature has changed (nRF51 only). + 2-33: Check the temperature and only calibrate if it has changed, + however calibration will take place every rc_temp_ctiv + intervals in any case. + + @note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. + + @note For nRF52, the application must ensure calibration at least once + every 8 seconds to ensure +/-250 ppm clock stability. The + recommended configuration for NRF_CLOCK_LF_SRC_RC on nRF52 is + rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at + least once every 8 seconds and for temperature changes of 0.5 + degrees Celsius every 4 seconds. See the Product Specification + for the nRF52 device being used for more information.*/ + uint8_t xtal_accuracy; /**< External crystal clock accuracy used in the LL to compute timing + windows, see @ref NRF_CLOCK_LF_XTAL_ACCURACY. + + @note For the NRF_CLOCK_LF_SRC_RC clock source this parameter is ignored. */ +} nrf_clock_lf_cfg_t; + +/**@brief Fault Handler type. + * + * When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back. + * The protocol stack will be in an undefined state when this happens and the only way to recover will be to + * perform a reset, using e.g. CMSIS NVIC_SystemReset(). + * If the application returns from the fault handler the SoftDevice will call NVIC_SystemReset(). + * + * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault. + * @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details. + * + * @note When id is set to NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time when + * the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the one that triggered the fault. + */ +typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info); + +/** @} */ + +/** @addtogroup NRF_SDM_FUNCTIONS Functions + * @{ */ + +/**@brief Enables the SoftDevice and by extension the protocol stack. + * + * @note Some care must be taken if a low frequency clock source is already running when calling this function: + * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new + * clock source will be started. + * + * @note This function has no effect when returning with an error. + * + * @post If return code is ::NRF_SUCCESS + * - SoC library and protocol stack APIs are made available. + * - A portion of RAM will be unavailable (see relevant SDS documentation). + * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). + * - Interrupts will not arrive from protected peripherals or interrupts. + * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice. + * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). + * - Chosen low frequency clock source will be running. + * + * @param p_clock_lf_cfg Low frequency clock source and accuracy. + If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2 + In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock. + * @param fault_handler Callback to be invoked in case of fault, cannot be NULL. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated. + * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level. + * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. + */ +SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler)); + + +/**@brief Disables the SoftDevice and by extension the protocol stack. + * + * Idempotent function to disable the SoftDevice. + * + * @post SoC library and protocol stack APIs are made unavailable. + * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest). + * @post All peripherals used by the SoftDevice will be reset to default values. + * @post All of RAM become available. + * @post All interrupts are forwarded to the application. + * @post LFCLK source chosen in ::sd_softdevice_enable will be left running. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); + +/**@brief Check if the SoftDevice is enabled. + * + * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled)); + +/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice + * + * This function is only intended to be called when a bootloader is enabled. + * + * @param[in] address The base address of the interrupt vector table for forwarded interrupts. + + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_SDM_H__ + +/** + @} +*/ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_soc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_soc.h new file mode 100644 index 0000000000000000000000000000000000000000..875f9bb63fc1a8ba92259e3774a9a2355994ade3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_soc.h @@ -0,0 +1,926 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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. + * + */ +/** + * @defgroup nrf_soc_api SoC Library API + * @{ + * + * @brief APIs for the SoC library. + * + */ + +#ifndef NRF_SOC_H__ +#define NRF_SOC_H__ + +#include +#include +#include "nrf_svc.h" +#include "nrf.h" + +#include "nrf_error_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup NRF_SOC_DEFINES Defines + * @{ */ + +/**@brief The number of the lowest SVC number reserved for the SoC library. */ +#define SOC_SVC_BASE (0x20) /**< Base value for SVCs that are available when the SoftDevice is disabled. */ +#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */ + +/**@brief Guaranteed time for application to process radio inactive notification. */ +#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62) + +/**@brief The minimum allowed timeslot extension time. */ +#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200) + +#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */ +#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */ +#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */ + +#ifdef NRF51 +#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ +#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */ +#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */ +#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. */ +#endif +#if defined(NRF52) || defined(NRF52840_XXAA) +#define SD_EVT_IRQn (SWI2_EGU2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ +#define SD_EVT_IRQHandler (SWI2_EGU2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. + The default interrupt priority for this handler is set to 4 */ +#define RADIO_NOTIFICATION_IRQn (SWI1_EGU1_IRQn) /**< The radio notification IRQ number. */ +#define RADIO_NOTIFICATION_IRQHandler (SWI1_EGU1_IRQHandler) /**< The radio notification IRQ handler. + The default interrupt priority for this handler is set to 4 */ +#endif + +#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */ +#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */ + +#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */ + +#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */ + +#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */ + +/**@} */ + +/**@addtogroup NRF_SOC_ENUMS Enumerations + * @{ */ + +/**@brief The SVC numbers used by the SVC functions in the SoC library. */ +enum NRF_SOC_SVCS +{ + SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE, + SD_PPI_CHANNEL_ENABLE_SET, + SD_PPI_CHANNEL_ENABLE_CLR, + SD_PPI_CHANNEL_ASSIGN, + SD_PPI_GROUP_TASK_ENABLE, + SD_PPI_GROUP_TASK_DISABLE, + SD_PPI_GROUP_ASSIGN, + SD_PPI_GROUP_GET, + SD_FLASH_PAGE_ERASE, + SD_FLASH_WRITE, + SD_FLASH_PROTECT, + SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE, + SD_MUTEX_ACQUIRE, + SD_MUTEX_RELEASE, + SD_RAND_APPLICATION_POOL_CAPACITY_GET, + SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, + SD_RAND_APPLICATION_VECTOR_GET, + SD_POWER_MODE_SET, + SD_POWER_SYSTEM_OFF, + SD_POWER_RESET_REASON_GET, + SD_POWER_RESET_REASON_CLR, + SD_POWER_POF_ENABLE, + SD_POWER_POF_THRESHOLD_SET, + SD_POWER_RAM_POWER_SET, + SD_POWER_RAM_POWER_CLR, + SD_POWER_RAM_POWER_GET, + SD_POWER_GPREGRET_SET, + SD_POWER_GPREGRET_CLR, + SD_POWER_GPREGRET_GET, + SD_POWER_DCDC_MODE_SET, + SD_APP_EVT_WAIT, + SD_CLOCK_HFCLK_REQUEST, + SD_CLOCK_HFCLK_RELEASE, + SD_CLOCK_HFCLK_IS_RUNNING, + SD_RADIO_NOTIFICATION_CFG_SET, + SD_ECB_BLOCK_ENCRYPT, + SD_ECB_BLOCKS_ENCRYPT, + SD_RADIO_SESSION_OPEN, + SD_RADIO_SESSION_CLOSE, + SD_RADIO_REQUEST, + SD_EVT_GET, + SD_TEMP_GET, + SVC_SOC_LAST +}; + +/**@brief Possible values of a ::nrf_mutex_t. */ +enum NRF_MUTEX_VALUES +{ + NRF_MUTEX_FREE, + NRF_MUTEX_TAKEN +}; + +/**@brief Power modes. */ +enum NRF_POWER_MODES +{ + NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ + NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */ +}; + + +/**@brief Power failure thresholds */ +enum NRF_POWER_THRESHOLDS +{ + NRF_POWER_THRESHOLD_V17 = 4UL, /**< 1.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V18, /**< 1.8 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V19, /**< 1.9 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V20, /**< 2.0 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V22, /**< 2.2 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V24, /**< 2.4 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V26, /**< 2.6 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V27, /**< 2.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V28 /**< 2.8 Volts power failure threshold. */ +}; + + +/**@brief DC/DC converter modes. */ +enum NRF_POWER_DCDC_MODES +{ + NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ + NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ +}; + +/**@brief Radio notification distances. */ +enum NRF_RADIO_NOTIFICATION_DISTANCES +{ + NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */ + NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */ +}; + + +/**@brief Radio notification types. */ +enum NRF_RADIO_NOTIFICATION_TYPES +{ + NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */ +}; + +/**@brief The Radio signal callback types. */ +enum NRF_RADIO_CALLBACK_SIGNAL_TYPE +{ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */ +}; + +/**@brief The actions requested by the signal callback. + * + * This code gives the SOC instructions about what action to take when the signal callback has + * returned. + */ +enum NRF_RADIO_SIGNAL_CALLBACK_ACTION +{ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current timeslot (maximum execution time for this action is when the extension succeeded). */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */ +}; + +/**@brief Radio timeslot high frequency clock source configuration. */ +enum NRF_RADIO_HFCLK_CFG +{ + NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the + external crystal for the whole duration of the timeslot. This should be the + preferred option for events that use the radio or require high timing accuracy. + @note The SoftDevice will automatically turn on and off the external crystal, + at the beginning and end of the timeslot, respectively. The crystal may also + intentionally be left running after the timeslot, in cases where it is needed + by the SoftDevice shortly after the end of the timeslot. */ + NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots. + The RC oscillator may be the clock source in part or for the whole duration of the timeslot. + The RC oscillator's accuracy must therefore be taken into consideration. + @note If the application will use the radio peripheral in timeslots with this configuration, + it must make sure that the crystal is running and stable before starting the radio. */ +}; + +/**@brief Radio timeslot priorities. */ +enum NRF_RADIO_PRIORITY +{ + NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */ + NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activities of the SoftDevice stack(s)). */ +}; + +/**@brief Radio timeslot request type. */ +enum NRF_RADIO_REQUEST_TYPE +{ + NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */ + NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */ +}; + +/**@brief SoC Events. */ +enum NRF_SOC_EVTS +{ + NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ + NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ + NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ + NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ + NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ + NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ + NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */ + NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */ + NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */ + NRF_EVT_NUMBER_OF_EVTS +}; + +/**@} */ + + +/**@addtogroup NRF_SOC_STRUCTURES Structures + * @{ */ + +/**@brief Represents a mutex for use with the nrf_mutex functions. + * @note Accessing the value directly is not safe, use the mutex functions! + */ +typedef volatile uint8_t nrf_mutex_t; + +/**@brief Parameters for a request for a timeslot as early as possible. */ +typedef struct +{ + uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ + uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ + uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */ + uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */ +} nrf_radio_request_earliest_t; + +/**@brief Parameters for a normal radio timeslot request. */ +typedef struct +{ + uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ + uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ + uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */ + uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */ +} nrf_radio_request_normal_t; + +/**@brief Radio timeslot request parameters. */ +typedef struct +{ + uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */ + union + { + nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */ + nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */ + } params; /**< Parameter union. */ +} nrf_radio_request_t; + +/**@brief Return parameters of the radio timeslot signal callback. */ +typedef struct +{ + uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */ + union + { + struct + { + nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */ + } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */ + struct + { + uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ + } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */ + } params; /**< Parameter union. */ +} nrf_radio_signal_callback_return_param_t; + +/**@brief The radio timeslot signal callback type. + * + * @note In case of invalid return parameters, the radio timeslot will automatically end + * immediately after returning from the signal callback and the + * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent. + * @note The returned struct pointer must remain valid after the signal callback + * function returns. For instance, this means that it must not point to a stack variable. + * + * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE. + * + * @return Pointer to structure containing action requested by the application. + */ +typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type); + +/**@brief AES ECB parameter typedefs */ +typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH]; /**< Encryption key type. */ +typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */ +typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */ + +/**@brief AES ECB data structure */ +typedef struct +{ + soc_ecb_key_t key; /**< Encryption key. */ + soc_ecb_cleartext_t cleartext; /**< Cleartext data. */ + soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */ +} nrf_ecb_hal_data_t; + +/**@brief AES ECB block. Used to provide multiple blocks in a single call + to @ref sd_ecb_blocks_encrypt.*/ +typedef struct +{ + soc_ecb_key_t const * p_key; /**< Pointer to the Encryption key. */ + soc_ecb_cleartext_t const * p_cleartext; /**< Pointer to the Cleartext data. */ + soc_ecb_ciphertext_t * p_ciphertext; /**< Pointer to the Ciphertext data. */ +} nrf_ecb_hal_data_block_t; + +/**@} */ + +/**@addtogroup NRF_SOC_FUNCTIONS Functions + * @{ */ + +/**@brief Initialize a mutex. + * + * @param[in] p_mutex Pointer to the mutex to initialize. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex)); + +/**@brief Attempt to acquire a mutex. + * + * @param[in] p_mutex Pointer to the mutex to acquire. + * + * @retval ::NRF_SUCCESS The mutex was successfully acquired. + * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired. + */ +SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex)); + +/**@brief Release a mutex. + * + * @param[in] p_mutex Pointer to the mutex to release. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex)); + +/**@brief Query the capacity of the application random pool. + * + * @param[out] p_pool_capacity The capacity of the pool. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); + +/**@brief Get number of random bytes available to the application. + * + * @param[out] p_bytes_available The number of bytes currently available in the pool. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); + +/**@brief Get random bytes from the application pool. + * + * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes. + * @param[in] length Number of bytes to take from pool and place in p_buff. + * + * @retval ::NRF_SUCCESS The requested bytes were written to p_buff. + * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available. +*/ +SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); + +/**@brief Gets the reset reason register. + * + * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason)); + +/**@brief Clears the bits of the reset reason register. + * + * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk)); + +/**@brief Sets the power mode when in CPU sleep. + * + * @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait + * + * @retval ::NRF_SUCCESS The power mode was set. + * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown. + */ +SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode)); + +/**@brief Puts the chip in System OFF mode. + * + * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN + */ +SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void)); + +/**@brief Enables or disables the power-fail comparator. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable)); + +/**@brief Sets the power-fail threshold value. + * + * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS. + * + * @retval ::NRF_SUCCESS The power failure threshold was set. + * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. + */ +SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold)); + +/**@brief Writes the NRF_POWER->RAM[index].POWERSET register. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERSET register to write to. + * @param[in] ram_powerset Contains the word to write to the NRF_POWER->RAM[index].POWERSET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_SET, uint32_t, sd_power_ram_power_set(uint8_t index, uint32_t ram_powerset)); + +/**@brief Writes the NRF_POWER->RAM[index].POWERCLR register. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERCLR register to write to. + * @param[in] ram_powerclr Contains the word to write to the NRF_POWER->RAM[index].POWERCLR register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_CLR, uint32_t, sd_power_ram_power_clr(uint8_t index, uint32_t ram_powerclr)); + +/**@brief Get contents of NRF_POWER->RAM[index].POWER register, indicates power status of RAM[index] blocks. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWER register to read from. + * @param[out] p_ram_power Content of NRF_POWER->RAM[index].POWER register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_GET, uint32_t, sd_power_ram_power_get(uint8_t index, uint32_t * p_ram_power)); + +/**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[in] gpregret_msk Bits to be set in the GPREGRET register. + * + * @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk)); + +/**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[in] gpregret_msk Bits to be clear in the GPREGRET register. + * + * @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk)); + +/**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[out] p_gpregret Contents of the GPREGRET register. + * + * @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, uint32_t *p_gpregret)); + +/**@brief Sets the DCDC mode. + * + * Enable or disable the DCDC peripheral. + * + * @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid. + */ +SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode)); + +/**@brief Request the high frequency crystal oscillator. + * + * Will start the high frequency crystal oscillator, the startup time of the crystal varies + * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started. + * + * @see sd_clock_hfclk_is_running + * @see sd_clock_hfclk_release + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void)); + +/**@brief Releases the high frequency crystal oscillator. + * + * Will stop the high frequency crystal oscillator, this happens immediately. + * + * @see sd_clock_hfclk_is_running + * @see sd_clock_hfclk_request + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void)); + +/**@brief Checks if the high frequency crystal oscillator is running. + * + * @see sd_clock_hfclk_request + * @see sd_clock_hfclk_release + * + * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running)); + +/**@brief Waits for an application event. + * + * An application event is either an application interrupt or a pended interrupt when the + * interrupt is disabled. When the interrupt is enabled it will be taken immediately since + * this function will wait in thread mode, then the execution will return in the application's + * main thread. When an interrupt is disabled and gets pended it will return to the application's + * main thread. The application must ensure that the pended flag is cleared using + * ::sd_nvic_ClearPendingIRQ in order to sleep using this function. This is only necessary for + * disabled interrupts, as the interrupt handler will clear the pending flag automatically for + * enabled interrupts. + * + * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M0 + * System Control Register (SCR). @sa CMSIS_SCB + * + * @note If an application interrupt has happened since the last time sd_app_evt_wait was + * called this function will return immediately and not go to sleep. This is to avoid race + * conditions that can occur when a flag is updated in the interrupt handler and processed + * in the main loop. + * + * @post An application interrupt has happened or a interrupt pending flag is set. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void)); + +/**@brief Get PPI channel enable register contents. + * + * @param[out] p_channel_enable The contents of the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable)); + +/**@brief Set PPI channel enable register. + * + * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk)); + +/**@brief Clear PPI channel enable register. + * + * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk)); + +/**@brief Assign endpoints to a PPI channel. + * + * @param[in] channel_num Number of the PPI channel to assign. + * @param[in] evt_endpoint Event endpoint of the PPI channel. + * @param[in] task_endpoint Task endpoint of the PPI channel. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint)); + +/**@brief Task to enable a channel group. + * + * @param[in] group_num Number of the channel group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num)); + +/**@brief Task to disable a channel group. + * + * @param[in] group_num Number of the PPI group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num)); + +/**@brief Assign PPI channels to a channel group. + * + * @param[in] group_num Number of the channel group. + * @param[in] channel_msk Mask of the channels to assign to the group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk)); + +/**@brief Gets the PPI channels of a channel group. + * + * @param[in] group_num Number of the channel group. + * @param[out] p_channel_msk Mask of the channels assigned to the group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk)); + +/**@brief Configures the Radio Notification signal. + * + * @note + * - The notification signal latency depends on the interrupt priority settings of SWI used + * for notification signal. + * - To ensure that the radio notification signal behaves in a consistent way, the radio + * notifications must be configured when there is no protocol stack or other SoftDevice + * activity in progress. It is recommended that the radio notification signal is + * configured directly after the SoftDevice has been enabled. + * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice + * will interrupt the application to do Radio Event preparation. + * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have + * to shorten the connection events to have time for the Radio Notification signals. + * + * @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES. + * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio + * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is + * recommended (but not required) to be used with + * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE. + * + * @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES. + * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or + * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. + * + * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid. + * @retval ::NRF_ERROR_INVALID_STATE A protocol stack or other SoftDevice is running. Stop all + * running activities and retry. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance)); + +/**@brief Encrypts a block according to the specified parameters. + * + * 128-bit AES encryption. + * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * + * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input + * parameters and one output parameter). + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data)); + +/**@brief Encrypts multiple data blocks provided as an array of data block structures. + * + * @details: Performs 128-bit AES encryption on multiple data blocks + * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * + * @param[in] block_count Count of blocks in the p_data_blocks array. + * @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of + * @ref nrf_ecb_hal_data_block_t structures. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks)); + +/**@brief Gets any pending events generated by the SoC API. + * + * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned. + * + * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending. + * + * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter. + * @retval ::NRF_ERROR_NOT_FOUND No pending events. + */ +SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id)); + +/**@brief Get the temperature measured on the chip + * + * This function will block until the temperature measurement is done. + * It takes around 50 us from call to return. + * + * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees Celsius. + * + * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp + */ +SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp)); + +/**@brief Flash Write +* +* Commands to write a buffer to flash +* +* If the SoftDevice is enabled: +* This call initiates the flash access command, and its completion will be communicated to the +* application with exactly one of the following events: +* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. +* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. +* +* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the + * write has been completed +* +* @note +* - This call takes control over the radio and the CPU during flash erase and write to make sure that +* they will not interfere with the flash access. This means that all interrupts will be blocked +* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual +* and the command parameters). +* - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS +* or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled. +* +* +* @param[in] p_dst Pointer to start of flash location to be written. +* @param[in] p_src Pointer to buffer with data to be written. +* @param[in] size Number of 32-bit words to write. Maximum size is 256 32-bit words for nRF51 and 1024 for nRF52. +* +* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. +* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. +* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size. +* @retval ::NRF_ERROR_FORBIDDEN Tried to write to or read from protected location. +* @retval ::NRF_SUCCESS The command was accepted. +*/ +SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * p_dst, uint32_t const * p_src, uint32_t size)); + + +/**@brief Flash Erase page +* +* Commands to erase a flash page +* If the SoftDevice is enabled: +* This call initiates the flash access command, and its completion will be communicated to the +* application with exactly one of the following events: +* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. +* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. +* +* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the +* erase has been completed +* +* @note +* - This call takes control over the radio and the CPU during flash erase and write to make sure that +* they will not interfere with the flash access. This means that all interrupts will be blocked +* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual +* and the command parameters). +* +* +* @param[in] page_number Page number of the page to erase +* +* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. +* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page. +* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. +* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a protected page. +* @retval ::NRF_SUCCESS The command was accepted. +*/ +SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)); + + +/**@brief Flash Protection set + * + * Commands to set the flash protection configuration registers. + On nRF51 this sets the PROTENSETx registers of the MPU peripheral. + On nRF52 this sets the CONFIGx registers of the BPROT peripheral. + * + * @note To read the values read them directly. They are only write-protected. + * + * @param[in] block_cfg0 Value to be written to the configuration register. + * @param[in] block_cfg1 Value to be written to the configuration register. + * @param[in] block_cfg2 Value to be written to the configuration register (ignored on nRF51). + * @param[in] block_cfg3 Value to be written to the configuration register (ignored on nRF51). + * + * @retval ::NRF_ERROR_FORBIDDEN Tried to protect the SoftDevice. + * @retval ::NRF_SUCCESS Values successfully written to configuration registers. + */ +SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t block_cfg0, uint32_t block_cfg1, uint32_t block_cfg2, uint32_t block_cfg3)); + +/**@brief Opens a session for radio timeslot requests. + * + * @note Only one session can be open at a time. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot + * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed + * by the application. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0 + * interrupt occurs. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO + * interrupt occurs. + * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This + * implies that none of the sd_* API calls can be used from p_radio_signal_callback(). + * + * @param[in] p_radio_signal_callback The signal callback. + * + * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer. + * @retval ::NRF_ERROR_BUSY If session cannot be opened. + * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. + * @retval ::NRF_SUCCESS Otherwise. + */ + SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback)); + +/**@brief Closes a session for radio timeslot requests. + * + * @note Any current radio timeslot will be finished before the session is closed. + * @note If a radio timeslot is scheduled when the session is closed, it will be canceled. + * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED + * event is received. + * + * @retval ::NRF_ERROR_FORBIDDEN If session not opened. + * @retval ::NRF_ERROR_BUSY If session is currently being closed. + * @retval ::NRF_SUCCESS Otherwise. + */ + SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void)); + +/**@brief Requests a radio timeslot. + * + * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST + * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST. + * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by + * p_request->distance_us and is given relative to the start of the previous timeslot. + * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event. + * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event. + * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths. + * @note If an opportunity for the first radio timeslot is not found before 100 ms after the call to this + * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent. + * The application may then try to schedule the first radio timeslot again. + * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START). + * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS. + * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us. + * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the + * specified radio timeslot start, but this does not affect the actual start time of the timeslot. + * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency + * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is + * guaranteed to be clocked from the external crystal. + * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral + * during the radio timeslot. + * + * @param[in] p_request Pointer to the request parameters. + * + * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE. + * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid. + * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid. + * @retval ::NRF_SUCCESS Otherwise. + */ + SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t const * p_request)); + +/**@} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_SOC_H__ + +/**@} */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_svc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_svc.h new file mode 100644 index 0000000000000000000000000000000000000000..31ea671529ff857e5f47ac5002c97cb20e9d822f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/headers/nrf_svc.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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. + * + */ + +#ifndef NRF_SVC__ +#define NRF_SVC__ + +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef SVCALL_AS_NORMAL_FUNCTION +#define SVCALL(number, return_type, signature) return_type signature +#else + +#ifndef SVCALL +#if defined (__CC_ARM) +#define SVCALL(number, return_type, signature) return_type __svc(number) signature +#elif defined (__GNUC__) +#ifdef __cplusplus +#define GCC_CAST_CPP (uint16_t) +#else +#define GCC_CAST_CPP +#endif +#define SVCALL(number, return_type, signature) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ + __attribute__((naked)) \ + __attribute__((unused)) \ + static return_type signature \ + { \ + __asm( \ + "svc %0\n" \ + "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \ + ); \ + } \ + _Pragma("GCC diagnostic pop") + +#elif defined (__ICCARM__) +#define PRAGMA(x) _Pragma(#x) +#define SVCALL(number, return_type, signature) \ +PRAGMA(swi_number = (number)) \ + __swi return_type signature; +#else +#define SVCALL(number, return_type, signature) return_type signature +#endif +#endif // SVCALL + +#endif // SVCALL_AS_NORMAL_FUNCTION + +#ifdef __cplusplus +} +#endif +#endif // NRF_SVC__ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/hex/s140_nrf52840_5.0.0-2.alpha_licence-agreement.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/hex/s140_nrf52840_5.0.0-2.alpha_licence-agreement.txt new file mode 100644 index 0000000000000000000000000000000000000000..b8d26c9a84f2be533482bc230dc83d5a812009aa --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s140/hex/s140_nrf52840_5.0.0-2.alpha_licence-agreement.txt @@ -0,0 +1,96 @@ +S110/S120/S130/S132/S140 license agreement + + +NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT + +License Agreement for the Nordic Semiconductor ASA ("Nordic") S110, S120, S130, S132, and S140 Bluetooth SoftDevice software packages +("SoftDevice"). + +You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before +downloading, installing and/or using any software or content in the SoftDevice provided herewith. + +YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS +OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF +THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. + +IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE +INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE. + +1. Grant of License +Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license +("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated +in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this +agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit. + +2. Title +Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and +other intellectual property rights in and to the SoftDevice. + +3. No Modifications or Reverse Engineering +Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code +parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code. + +4. Distribution Restrictions +Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party. +Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein. +Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee +necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making +such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice. + +5. No Other Rights +Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be +contrary to this Agreement. + +6. Fees +Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to +comply with the Agreement. + +7. DISCLAIMER OF WARRANTY +THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS +LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR +THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE +IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE +REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE. +LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S +INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. + + +8. No Support +Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, +bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice. + +9. Limitation of Liability +In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of +procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any +special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, +tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers, +licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or +limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to +USD 50. + +10. Breach of Contract +Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably +attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both +direct and indirect costs for Nordic and its licensors. + +11. Indemnity +Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and +agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which +is not due to causes for which Nordic is responsible. + +12. Governing Law +This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. + +13. Assignment +Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. + +14. Termination +Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this +Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any +other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. + +15. Third party beneficiaries +Nordic’s licensors are intended third party beneficiaries under this Agreement. + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s212/headers/nrf_sd_def.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s212/headers/nrf_sd_def.h new file mode 100644 index 0000000000000000000000000000000000000000..365af9c5bdee47793dad8df02693ef7e952f93b9 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s212/headers/nrf_sd_def.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#ifndef NRF_SD_DEF_H__ +#define NRF_SD_DEF_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SD_PPI_CHANNELS_USED 0xFFF0FF00uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */ +#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */ +#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */ +#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SD_DEF_H__ */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s212/toolchain/armgcc/armgcc_s212_nrf52832_xxaa.ld b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s212/toolchain/armgcc/armgcc_s212_nrf52832_xxaa.ld new file mode 100644 index 0000000000000000000000000000000000000000..30c1eda41129af8718cca14f53ae8fb0f277730f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s212/toolchain/armgcc/armgcc_s212_nrf52832_xxaa.ld @@ -0,0 +1,32 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x12000, LENGTH = 0x6e000 + RAM (rwx) : ORIGIN = 0x20000a80, LENGTH = 0xf580 +} + +SECTIONS +{ + .fs_data : + { + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM +} INSERT AFTER .data; + +SECTIONS +{ + .pwr_mgmt_data : + { + PROVIDE(__start_pwr_mgmt_data = .); + KEEP(*(SORT(.pwr_mgmt_data*))) + PROVIDE(__stop_pwr_mgmt_data = .); + } > FLASH +} INSERT AFTER .text + +INCLUDE "nrf5x_common.ld" diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s212/toolchain/iar/iar_s212_nrf52832_xxaa.icf b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s212/toolchain/iar/iar_s212_nrf52832_xxaa.icf new file mode 100644 index 0000000000000000000000000000000000000000..709cc6b7374d66403e677b06e41b78f66c4876c3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/softdevice/s212/toolchain/iar/iar_s212_nrf52832_xxaa.icf @@ -0,0 +1,34 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x12000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x12000; +define symbol __ICFEDIT_region_ROM_end__ = 0x7ffff; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000a80; +define symbol __ICFEDIT_region_RAM_end__ = 0x2000ffff; +export symbol __ICFEDIT_region_RAM_start__; +export symbol __ICFEDIT_region_RAM_end__; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x800; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +keep { section .intvec }; +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, + block HEAP }; + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/arm/arm_startup_nrf51.s b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/arm/arm_startup_nrf51.s new file mode 100644 index 0000000000000000000000000000000000000000..668f3cd8c147ab48dd690edc31ca0aa95699e4dd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/arm/arm_startup_nrf51.s @@ -0,0 +1,259 @@ +; Copyright (c) 2009-2017 ARM Limited. All rights reserved. +; +; SPDX-License-Identifier: Apache-2.0 +; +; Licensed 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 +; +; 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. +; +; NOTICE: This file has been modified by Nordic Semiconductor ASA. + + IF :DEF: __STARTUP_CONFIG +#include "startup_config.h" +#ifndef __STARTUP_CONFIG_STACK_ALIGNEMENT +#define __STARTUP_CONFIG_STACK_ALIGNEMENT 3 +#endif + ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Size EQU __STARTUP_CONFIG_STACK_SIZE + ELIF :DEF: __STACK_SIZE +Stack_Size EQU __STACK_SIZE + ELSE +Stack_Size EQU 2048 + ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Align EQU __STARTUP_CONFIG_STACK_ALIGNEMENT + ELSE +Stack_Align EQU 3 + ENDIF + + AREA STACK, NOINIT, READWRITE, ALIGN=Stack_Align +Stack_Mem SPACE Stack_Size +__initial_sp + + IF :DEF: __STARTUP_CONFIG +Heap_Size EQU __STARTUP_CONFIG_HEAP_SIZE + ELIF :DEF: __HEAP_SIZE +Heap_Size EQU __HEAP_SIZE + ELSE +Heap_Size EQU 2048 + ENDIF + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler + DCD NMI_Handler + DCD HardFault_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD POWER_CLOCK_IRQHandler + DCD RADIO_IRQHandler + DCD UART0_IRQHandler + DCD SPI0_TWI0_IRQHandler + DCD SPI1_TWI1_IRQHandler + DCD 0 ; Reserved + DCD GPIOTE_IRQHandler + DCD ADC_IRQHandler + DCD TIMER0_IRQHandler + DCD TIMER1_IRQHandler + DCD TIMER2_IRQHandler + DCD RTC0_IRQHandler + DCD TEMP_IRQHandler + DCD RNG_IRQHandler + DCD ECB_IRQHandler + DCD CCM_AAR_IRQHandler + DCD WDT_IRQHandler + DCD RTC1_IRQHandler + DCD QDEC_IRQHandler + DCD LPCOMP_IRQHandler + DCD SWI0_IRQHandler + DCD SWI1_IRQHandler + DCD SWI2_IRQHandler + DCD SWI3_IRQHandler + DCD SWI4_IRQHandler + DCD SWI5_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset Handler + +NRF_POWER_RAMON_ADDRESS EQU 0x40000524 ; NRF_POWER->RAMON address +NRF_POWER_RAMONB_ADDRESS EQU 0x40000554 ; NRF_POWER->RAMONB address +NRF_POWER_RAMONx_RAMxON_ONMODE_Msk EQU 0x3 ; All RAM blocks on in onmode bit mask + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + MOVS R1, #NRF_POWER_RAMONx_RAMxON_ONMODE_Msk + + LDR R0, =NRF_POWER_RAMON_ADDRESS + LDR R2, [R0] + ORRS R2, R2, R1 + STR R2, [R0] + + LDR R0, =NRF_POWER_RAMONB_ADDRESS + LDR R2, [R0] + ORRS R2, R2, R1 + STR R2, [R0] + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT POWER_CLOCK_IRQHandler [WEAK] + EXPORT RADIO_IRQHandler [WEAK] + EXPORT UART0_IRQHandler [WEAK] + EXPORT SPI0_TWI0_IRQHandler [WEAK] + EXPORT SPI1_TWI1_IRQHandler [WEAK] + EXPORT GPIOTE_IRQHandler [WEAK] + EXPORT ADC_IRQHandler [WEAK] + EXPORT TIMER0_IRQHandler [WEAK] + EXPORT TIMER1_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT RTC0_IRQHandler [WEAK] + EXPORT TEMP_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT ECB_IRQHandler [WEAK] + EXPORT CCM_AAR_IRQHandler [WEAK] + EXPORT WDT_IRQHandler [WEAK] + EXPORT RTC1_IRQHandler [WEAK] + EXPORT QDEC_IRQHandler [WEAK] + EXPORT LPCOMP_IRQHandler [WEAK] + EXPORT SWI0_IRQHandler [WEAK] + EXPORT SWI1_IRQHandler [WEAK] + EXPORT SWI2_IRQHandler [WEAK] + EXPORT SWI3_IRQHandler [WEAK] + EXPORT SWI4_IRQHandler [WEAK] + EXPORT SWI5_IRQHandler [WEAK] +POWER_CLOCK_IRQHandler +RADIO_IRQHandler +UART0_IRQHandler +SPI0_TWI0_IRQHandler +SPI1_TWI1_IRQHandler +GPIOTE_IRQHandler +ADC_IRQHandler +TIMER0_IRQHandler +TIMER1_IRQHandler +TIMER2_IRQHandler +RTC0_IRQHandler +TEMP_IRQHandler +RNG_IRQHandler +ECB_IRQHandler +CCM_AAR_IRQHandler +WDT_IRQHandler +RTC1_IRQHandler +QDEC_IRQHandler +LPCOMP_IRQHandler +SWI0_IRQHandler +SWI1_IRQHandler +SWI2_IRQHandler +SWI3_IRQHandler +SWI4_IRQHandler +SWI5_IRQHandler + B . + ENDP + ALIGN + +; User Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + + LDR R0, = Heap_Mem + LDR R1, = (Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/bsp/nrf52832/Libraries/nrf52832/Source/templates/arm/arm_startup_nrf52.s b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/arm/arm_startup_nrf52.s similarity index 55% rename from bsp/nrf52832/Libraries/nrf52832/Source/templates/arm/arm_startup_nrf52.s rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/arm/arm_startup_nrf52.s index 5c763b549db2e508a052cc97e0e0df621a87e14e..ac0493b69c3086b2df250eb507d66040f5edd8b5 100644 --- a/bsp/nrf52832/Libraries/nrf52832/Source/templates/arm/arm_startup_nrf52.s +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/arm/arm_startup_nrf52.s @@ -1,48 +1,50 @@ -; Copyright (c) 2015, Nordic Semiconductor ASA -; All rights reserved. +; Copyright (c) 2009-2017 ARM Limited. All rights reserved. ; -; Redistribution and use in source and binary forms, with or without -; modification, are permitted provided that the following conditions are met: +; SPDX-License-Identifier: Apache-2.0 ; -; * Redistributions of source code must retain the above copyright notice, this -; list of conditions and the following disclaimer. +; Licensed 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 ; -; * 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. +; www.apache.org/licenses/LICENSE-2.0 ; -; * Neither the name of Nordic Semiconductor ASA nor the names of its -; contributors may be used to endorse or promote products derived from -; this software without specific prior written permission. +; 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. ; -; 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. - -; NOTE: Template files (including this one) are application specific and therefore -; expected to be copied into the application project folder prior to its use! - -; Description message - - IF :DEF: __STACK_SIZE -Stack_Size EQU __STACK_SIZE +; NOTICE: This file has been modified by Nordic Semiconductor ASA. + + IF :DEF: __STARTUP_CONFIG +#include "startup_config.h" +#ifndef __STARTUP_CONFIG_STACK_ALIGNEMENT +#define __STARTUP_CONFIG_STACK_ALIGNEMENT 3 +#endif + ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Size EQU __STARTUP_CONFIG_STACK_SIZE + ELIF :DEF: __STACK_SIZE +Stack_Size EQU __STACK_SIZE ELSE Stack_Size EQU 8192 ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Align EQU __STARTUP_CONFIG_STACK_ALIGNEMENT + ELSE +Stack_Align EQU 3 + ENDIF - AREA STACK, NOINIT, READWRITE, ALIGN=3 + AREA STACK, NOINIT, READWRITE, ALIGN=Stack_Align Stack_Mem SPACE Stack_Size __initial_sp - IF :DEF: __HEAP_SIZE -Heap_Size EQU __HEAP_SIZE + IF :DEF: __STARTUP_CONFIG +Heap_Size EQU __STARTUP_CONFIG_HEAP_SIZE + ELIF :DEF: __HEAP_SIZE +Heap_Size EQU __HEAP_SIZE ELSE Heap_Size EQU 8192 ENDIF @@ -74,7 +76,7 @@ __Vectors DCD __initial_sp ; Top of Stack DCD 0 ; Reserved DCD 0 ; Reserved DCD SVC_Handler - DCD 0 ; Reserved + DCD DebugMon_Handler DCD 0 ; Reserved DCD PendSV_Handler DCD SysTick_Handler @@ -118,135 +120,7 @@ __Vectors DCD __initial_sp ; Top of Stack DCD SPIM2_SPIS2_SPI2_IRQHandler DCD RTC2_IRQHandler DCD I2S_IRQHandler - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved + DCD FPU_IRQHandler DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved @@ -334,7 +208,8 @@ Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main - + + LDR R0, =SystemInit BLX R0 LDR R0, =__main @@ -371,6 +246,11 @@ SVC_Handler PROC EXPORT SVC_Handler [WEAK] B . ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP PendSV_Handler PROC EXPORT PendSV_Handler [WEAK] B . @@ -418,6 +298,7 @@ Default_Handler PROC EXPORT SPIM2_SPIS2_SPI2_IRQHandler [WEAK] EXPORT RTC2_IRQHandler [WEAK] EXPORT I2S_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] POWER_CLOCK_IRQHandler RADIO_IRQHandler UARTE0_UART0_IRQHandler @@ -454,6 +335,7 @@ PWM2_IRQHandler SPIM2_SPIS2_SPI2_IRQHandler RTC2_IRQHandler I2S_IRQHandler +FPU_IRQHandler B . ENDP ALIGN @@ -461,7 +343,7 @@ I2S_IRQHandler ; User Initial Stack & Heap IF :DEF:__MICROLIB - + EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit @@ -470,13 +352,15 @@ I2S_IRQHandler IMPORT __use_two_region_memory EXPORT __user_initial_stackheap -__user_initial_stackheap + +__user_initial_stackheap PROC LDR R0, = Heap_Mem LDR R1, = (Stack_Mem + Stack_Size) LDR R2, = (Heap_Mem + Heap_Size) LDR R3, = Stack_Mem BX LR + ENDP ALIGN diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/arm/arm_startup_nrf52840.s b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/arm/arm_startup_nrf52840.s new file mode 100644 index 0000000000000000000000000000000000000000..96e6d3c156b6a80d21afcd7d262b2883c3e34f31 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/arm/arm_startup_nrf52840.s @@ -0,0 +1,381 @@ +; Copyright (c) 2009-2017 ARM Limited. All rights reserved. +; +; SPDX-License-Identifier: Apache-2.0 +; +; Licensed 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 +; +; 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. +; +; NOTICE: This file has been modified by Nordic Semiconductor ASA. + + IF :DEF: __STARTUP_CONFIG +#include "startup_config.h" +#ifndef __STARTUP_CONFIG_STACK_ALIGNEMENT +#define __STARTUP_CONFIG_STACK_ALIGNEMENT 3 +#endif + ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Size EQU __STARTUP_CONFIG_STACK_SIZE + ELIF :DEF: __STACK_SIZE +Stack_Size EQU __STACK_SIZE + ELSE +Stack_Size EQU 8192 + ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Align EQU __STARTUP_CONFIG_STACK_ALIGNEMENT + ELSE +Stack_Align EQU 3 + ENDIF + + AREA STACK, NOINIT, READWRITE, ALIGN=Stack_Align +Stack_Mem SPACE Stack_Size +__initial_sp + + IF :DEF: __STARTUP_CONFIG +Heap_Size EQU __STARTUP_CONFIG_HEAP_SIZE + ELIF :DEF: __HEAP_SIZE +Heap_Size EQU __HEAP_SIZE + ELSE +Heap_Size EQU 8192 + ENDIF + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler + DCD NMI_Handler + DCD HardFault_Handler + DCD MemoryManagement_Handler + DCD BusFault_Handler + DCD UsageFault_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler + DCD DebugMon_Handler + DCD 0 ; Reserved + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD POWER_CLOCK_IRQHandler + DCD RADIO_IRQHandler + DCD UARTE0_UART0_IRQHandler + DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + DCD NFCT_IRQHandler + DCD GPIOTE_IRQHandler + DCD SAADC_IRQHandler + DCD TIMER0_IRQHandler + DCD TIMER1_IRQHandler + DCD TIMER2_IRQHandler + DCD RTC0_IRQHandler + DCD TEMP_IRQHandler + DCD RNG_IRQHandler + DCD ECB_IRQHandler + DCD CCM_AAR_IRQHandler + DCD WDT_IRQHandler + DCD RTC1_IRQHandler + DCD QDEC_IRQHandler + DCD COMP_LPCOMP_IRQHandler + DCD SWI0_EGU0_IRQHandler + DCD SWI1_EGU1_IRQHandler + DCD SWI2_EGU2_IRQHandler + DCD SWI3_EGU3_IRQHandler + DCD SWI4_EGU4_IRQHandler + DCD SWI5_EGU5_IRQHandler + DCD TIMER3_IRQHandler + DCD TIMER4_IRQHandler + DCD PWM0_IRQHandler + DCD PDM_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD MWU_IRQHandler + DCD PWM1_IRQHandler + DCD PWM2_IRQHandler + DCD SPIM2_SPIS2_SPI2_IRQHandler + DCD RTC2_IRQHandler + DCD I2S_IRQHandler + DCD FPU_IRQHandler + DCD USBD_IRQHandler + DCD UARTE1_IRQHandler + DCD QSPI_IRQHandler + DCD CRYPTOCELL_IRQHandler + DCD SPIM3_IRQHandler + DCD 0 ; Reserved + DCD PWM3_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset Handler + + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemoryManagement_Handler\ + PROC + EXPORT MemoryManagement_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT POWER_CLOCK_IRQHandler [WEAK] + EXPORT RADIO_IRQHandler [WEAK] + EXPORT UARTE0_UART0_IRQHandler [WEAK] + EXPORT SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler [WEAK] + EXPORT SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler [WEAK] + EXPORT NFCT_IRQHandler [WEAK] + EXPORT GPIOTE_IRQHandler [WEAK] + EXPORT SAADC_IRQHandler [WEAK] + EXPORT TIMER0_IRQHandler [WEAK] + EXPORT TIMER1_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT RTC0_IRQHandler [WEAK] + EXPORT TEMP_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT ECB_IRQHandler [WEAK] + EXPORT CCM_AAR_IRQHandler [WEAK] + EXPORT WDT_IRQHandler [WEAK] + EXPORT RTC1_IRQHandler [WEAK] + EXPORT QDEC_IRQHandler [WEAK] + EXPORT COMP_LPCOMP_IRQHandler [WEAK] + EXPORT SWI0_EGU0_IRQHandler [WEAK] + EXPORT SWI1_EGU1_IRQHandler [WEAK] + EXPORT SWI2_EGU2_IRQHandler [WEAK] + EXPORT SWI3_EGU3_IRQHandler [WEAK] + EXPORT SWI4_EGU4_IRQHandler [WEAK] + EXPORT SWI5_EGU5_IRQHandler [WEAK] + EXPORT TIMER3_IRQHandler [WEAK] + EXPORT TIMER4_IRQHandler [WEAK] + EXPORT PWM0_IRQHandler [WEAK] + EXPORT PDM_IRQHandler [WEAK] + EXPORT MWU_IRQHandler [WEAK] + EXPORT PWM1_IRQHandler [WEAK] + EXPORT PWM2_IRQHandler [WEAK] + EXPORT SPIM2_SPIS2_SPI2_IRQHandler [WEAK] + EXPORT RTC2_IRQHandler [WEAK] + EXPORT I2S_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT USBD_IRQHandler [WEAK] + EXPORT UARTE1_IRQHandler [WEAK] + EXPORT QSPI_IRQHandler [WEAK] + EXPORT CRYPTOCELL_IRQHandler [WEAK] + EXPORT SPIM3_IRQHandler [WEAK] + EXPORT PWM3_IRQHandler [WEAK] +POWER_CLOCK_IRQHandler +RADIO_IRQHandler +UARTE0_UART0_IRQHandler +SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler +SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler +NFCT_IRQHandler +GPIOTE_IRQHandler +SAADC_IRQHandler +TIMER0_IRQHandler +TIMER1_IRQHandler +TIMER2_IRQHandler +RTC0_IRQHandler +TEMP_IRQHandler +RNG_IRQHandler +ECB_IRQHandler +CCM_AAR_IRQHandler +WDT_IRQHandler +RTC1_IRQHandler +QDEC_IRQHandler +COMP_LPCOMP_IRQHandler +SWI0_EGU0_IRQHandler +SWI1_EGU1_IRQHandler +SWI2_EGU2_IRQHandler +SWI3_EGU3_IRQHandler +SWI4_EGU4_IRQHandler +SWI5_EGU5_IRQHandler +TIMER3_IRQHandler +TIMER4_IRQHandler +PWM0_IRQHandler +PDM_IRQHandler +MWU_IRQHandler +PWM1_IRQHandler +PWM2_IRQHandler +SPIM2_SPIS2_SPI2_IRQHandler +RTC2_IRQHandler +I2S_IRQHandler +FPU_IRQHandler +USBD_IRQHandler +UARTE1_IRQHandler +QSPI_IRQHandler +CRYPTOCELL_IRQHandler +SPIM3_IRQHandler +PWM3_IRQHandler + B . + ENDP + ALIGN + +; User Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + + LDR R0, = Heap_Mem + LDR R1, = (Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/arm/uicr_config.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/arm/uicr_config.h new file mode 100644 index 0000000000000000000000000000000000000000..be5a40c5c2b5fa6ff9164dd496be82c1575180ec --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/arm/uicr_config.h @@ -0,0 +1,114 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * 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, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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 Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/* Template files (including this one) are application specific and therefore expected to + be copied into the application project folder prior to its use! */ + +#ifndef _UICR_CONFIG_H +#define _UICR_CONFIG_H + +/*lint ++flb "Enter library region" */ + +#include + +/* + * Include this file in your project if you want to include in your compiled code files data + * for the User Information Configuration Registers (UICR) area; see nRF51 Series Reference + * Manual chapter User Information Configuration Registers. This file declares one variable + * per register of the UICR area and informs the linker where to place them. To include + * the desired value in the desired address, uncomment the variable with the proper address + * at the target area and update the assignment value. + * + * Please note that UICR values are stored in a reserved area of the flash and should only be + * stored into when downloading a hex file. Do not use these defined variables to store data + * at run time. + * + * Note as well that this file uses one non-standard attribute ("at"). It will only function + * with the ARMCC compiler toolset. + * + * Note that the hex file generated when this file is included will fail to download when using + * the standard download algorithm provided by Nordic. See example project "uicr_config_example" + * in any of the board example folders for an example of the recommended download method as well + * as the documentation that follows with the SDK. nrfjprog can be used as normal. + * + * Please note as well that if you are using a SoftDevice the UICR_CLENR0 address will + * already be in use. Do not uncomment that line. + */ + +// const uint32_t UICR_CLENR0 __attribute__((at(0x10001000))) __attribute__((used)) = 0xFFFFFFFF; // WARNING: This address might be used by the SoftDevice. Use with care. +// const uint32_t UICR_RBPCONF __attribute__((at(0x10001004))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_XTALFREQ __attribute__((at(0x10001008))) __attribute__((used)) = 0xFFFFFFFF; + +// const uint32_t UICR_ADDR_0x80 __attribute__((at(0x10001080))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0x84 __attribute__((at(0x10001084))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0x88 __attribute__((at(0x10001088))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0x8C __attribute__((at(0x1000108C))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0x90 __attribute__((at(0x10001090))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0x94 __attribute__((at(0x10001094))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0x98 __attribute__((at(0x10001098))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0x9C __attribute__((at(0x1000109C))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xA0 __attribute__((at(0x100010A0))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xA4 __attribute__((at(0x100010A4))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xA8 __attribute__((at(0x100010A8))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xAC __attribute__((at(0x100010AC))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xB0 __attribute__((at(0x100010B0))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xB4 __attribute__((at(0x100010B4))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xB8 __attribute__((at(0x100010B8))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xBC __attribute__((at(0x100010BC))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xC0 __attribute__((at(0x100010C0))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xC4 __attribute__((at(0x100010C4))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xC8 __attribute__((at(0x100010C8))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xCC __attribute__((at(0x100010CC))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xD0 __attribute__((at(0x100010D0))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xD4 __attribute__((at(0x100010D4))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xD8 __attribute__((at(0x100010D8))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xDC __attribute__((at(0x100010DC))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xE0 __attribute__((at(0x100010E0))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xE4 __attribute__((at(0x100010E4))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xE8 __attribute__((at(0x100010E8))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xEC __attribute__((at(0x100010EC))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xF0 __attribute__((at(0x100010F0))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xF4 __attribute__((at(0x100010F4))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xF8 __attribute__((at(0x100010F8))) __attribute__((used)) = 0xFFFFFFFF; +// const uint32_t UICR_ADDR_0xFC __attribute__((at(0x100010FC))) __attribute__((used)) = 0xFFFFFFFF; + +/*lint --flb "Leave library region" */ + +#endif //_UICR_CONFIG_H diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/dsp/license.txt b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/dsp/license.txt new file mode 100644 index 0000000000000000000000000000000000000000..139c1ff8d4db3a3f48bc43e3126fc44dc020c6de --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/dsp/license.txt @@ -0,0 +1,28 @@ +All pre-build libraries contained in the folders "ARM" and "GCC" +are guided by the following license: + +Copyright (C) 2009-2014 ARM Limited. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - 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. + - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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. diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/arm_common_tables.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/arm_common_tables.h similarity index 100% rename from bsp/nrf52832/Libraries/CMSIS/Include/arm_common_tables.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/arm_common_tables.h diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/arm_const_structs.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/arm_const_structs.h similarity index 100% rename from bsp/nrf52832/Libraries/CMSIS/Include/arm_const_structs.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/arm_const_structs.h diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/arm_math.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/arm_math.h similarity index 96% rename from bsp/nrf52832/Libraries/CMSIS/Include/arm_math.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/arm_math.h index d33f8a9b3b57f9b146dc5da036b06281d17a4594..e21a3cc3718e355c4a73ef4348a070556005c1d0 100644 --- a/bsp/nrf52832/Libraries/CMSIS/Include/arm_math.h +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/arm_math.h @@ -38,130 +38,6 @@ * POSSIBILITY OF SUCH DAMAGE. * -------------------------------------------------------------------- */ -/** - \mainpage CMSIS DSP Software Library - * - * Introduction - * ------------ - * - * This user manual describes the CMSIS DSP software library, - * a suite of common signal processing functions for use on Cortex-M processor based devices. - * - * The library is divided into a number of functions each covering a specific category: - * - Basic math functions - * - Fast math functions - * - Complex math functions - * - Filters - * - Matrix functions - * - Transforms - * - Motor control functions - * - Statistical functions - * - Support functions - * - Interpolation functions - * - * The library has separate functions for operating on 8-bit integers, 16-bit integers, - * 32-bit integer and 32-bit floating-point values. - * - * Using the Library - * ------------ - * - * The library installer contains prebuilt versions of the libraries in the Lib folder. - * - arm_cortexM7lfdp_math.lib (Little endian and Double Precision Floating Point Unit on Cortex-M7) - * - arm_cortexM7bfdp_math.lib (Big endian and Double Precision Floating Point Unit on Cortex-M7) - * - arm_cortexM7lfsp_math.lib (Little endian and Single Precision Floating Point Unit on Cortex-M7) - * - arm_cortexM7bfsp_math.lib (Big endian and Single Precision Floating Point Unit on Cortex-M7) - * - arm_cortexM7l_math.lib (Little endian on Cortex-M7) - * - arm_cortexM7b_math.lib (Big endian on Cortex-M7) - * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4) - * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4) - * - arm_cortexM4l_math.lib (Little endian on Cortex-M4) - * - arm_cortexM4b_math.lib (Big endian on Cortex-M4) - * - arm_cortexM3l_math.lib (Little endian on Cortex-M3) - * - arm_cortexM3b_math.lib (Big endian on Cortex-M3) - * - arm_cortexM0l_math.lib (Little endian on Cortex-M0 / CortexM0+) - * - arm_cortexM0b_math.lib (Big endian on Cortex-M0 / CortexM0+) - * - * The library functions are declared in the public file arm_math.h which is placed in the Include folder. - * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single - * public header file arm_math.h for Cortex-M7/M4/M3/M0/M0+ with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. - * Define the appropriate pre processor MACRO ARM_MATH_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or - * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. - * - * Examples - * -------- - * - * The library ships with a number of examples which demonstrate how to use the library functions. - * - * Toolchain Support - * ------------ - * - * The library has been developed and tested with MDK-ARM version 5.14.0.0 - * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. - * - * Building the Library - * ------------ - * - * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. - * - arm_cortexM_math.uvprojx - * - * - * The libraries can be built by opening the arm_cortexM_math.uvprojx project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above. - * - * Pre-processor Macros - * ------------ - * - * Each library project have differant pre-processor macros. - * - * - UNALIGNED_SUPPORT_DISABLE: - * - * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access - * - * - ARM_MATH_BIG_ENDIAN: - * - * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. - * - * - ARM_MATH_MATRIX_CHECK: - * - * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices - * - * - ARM_MATH_ROUNDING: - * - * Define macro ARM_MATH_ROUNDING for rounding on support functions - * - * - ARM_MATH_CMx: - * - * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target - * and ARM_MATH_CM0 for building library on Cortex-M0 target, ARM_MATH_CM0PLUS for building library on Cortex-M0+ target, and - * ARM_MATH_CM7 for building the library on cortex-M7. - * - * - __FPU_PRESENT: - * - * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries - * - *
- * CMSIS-DSP in ARM::CMSIS Pack - * ----------------------------- - * - * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: - * |File/Folder |Content | - * |------------------------------|------------------------------------------------------------------------| - * |\b CMSIS\\Documentation\\DSP | This documentation | - * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | - * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | - * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | - * - *
- * Revision History of CMSIS-DSP - * ------------ - * Please refer to \ref ChangeLog_pg. - * - * Copyright Notice - * ------------ - * - * Copyright (C) 2010-2015 ARM Limited. All rights reserved. - */ - - /** * @defgroup groupMath Basic Math Functions */ @@ -546,7 +422,7 @@ extern "C" uint32_t count = 0; uint32_t mask = 0x80000000; - while((data & mask) == 0) + while ((data & mask) == 0) { count += 1u; mask = mask >> 1u; @@ -570,7 +446,7 @@ extern "C" uint32_t index, i; uint32_t signBits; - if(in > 0) + if (in > 0) { signBits = ((uint32_t) (__CLZ( in) - 1)); } @@ -621,7 +497,7 @@ extern "C" uint32_t index = 0, i = 0; uint32_t signBits = 0; - if(in > 0) + if (in > 0) { signBits = ((uint32_t)(__CLZ( in) - 17)); } @@ -676,11 +552,11 @@ extern "C" posMax = posMax * 2; } - if(x > 0) + if (x > 0) { posMax = (posMax - 1); - if(x > posMax) + if (x > posMax) { x = posMax; } @@ -689,7 +565,7 @@ extern "C" { negMin = -posMax; - if(x < negMin) + if (x < negMin) { x = negMin; } @@ -1029,7 +905,7 @@ extern "C" typedef struct { uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ } arm_fir_instance_q7; @@ -1039,7 +915,7 @@ extern "C" typedef struct { uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ } arm_fir_instance_q15; @@ -1049,7 +925,7 @@ extern "C" typedef struct { uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ } arm_fir_instance_q31; @@ -1059,7 +935,7 @@ extern "C" typedef struct { uint16_t numTaps; /**< number of filter coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ } arm_fir_instance_f32; @@ -2912,7 +2788,7 @@ void arm_rfft_fast_f32( * @param[in] srcALen length of the first input sequence. * @param[in] pSrcB points to the second input sequence. * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + * @param[out] pDst points to the location where the output result is written. Length srcALen + srcBLen-1. */ void arm_conv_f32( float32_t * pSrcA, @@ -2928,7 +2804,7 @@ void arm_rfft_fast_f32( * @param[in] srcALen length of the first input sequence. * @param[in] pSrcB points to the second input sequence. * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1. * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). */ @@ -2948,7 +2824,7 @@ void arm_rfft_fast_f32( * @param[in] srcALen length of the first input sequence. * @param[in] pSrcB points to the second input sequence. * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + * @param[out] pDst points to the location where the output result is written. Length srcALen + srcBLen-1. */ void arm_conv_q15( q15_t * pSrcA, @@ -2964,7 +2840,7 @@ void arm_rfft_fast_f32( * @param[in] srcALen length of the first input sequence. * @param[in] pSrcB points to the second input sequence. * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1. */ void arm_conv_fast_q15( q15_t * pSrcA, @@ -2980,7 +2856,7 @@ void arm_rfft_fast_f32( * @param[in] srcALen length of the first input sequence. * @param[in] pSrcB points to the second input sequence. * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1. * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). */ @@ -3000,7 +2876,7 @@ void arm_rfft_fast_f32( * @param[in] srcALen length of the first input sequence. * @param[in] pSrcB points to the second input sequence. * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1. */ void arm_conv_q31( q31_t * pSrcA, @@ -3016,7 +2892,7 @@ void arm_rfft_fast_f32( * @param[in] srcALen length of the first input sequence. * @param[in] pSrcB points to the second input sequence. * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1. */ void arm_conv_fast_q31( q31_t * pSrcA, @@ -3032,7 +2908,7 @@ void arm_rfft_fast_f32( * @param[in] srcALen length of the first input sequence. * @param[in] pSrcB points to the second input sequence. * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1. * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). */ @@ -3052,7 +2928,7 @@ void arm_rfft_fast_f32( * @param[in] srcALen length of the first input sequence. * @param[in] pSrcB points to the second input sequence. * @param[in] srcBLen length of the second input sequence. - * @param[out] pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1. */ void arm_conv_q7( q7_t * pSrcA, @@ -3071,7 +2947,7 @@ void arm_rfft_fast_f32( * @param[out] pDst points to the block of output data * @param[in] firstIndex is the first output sample to start with. * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2]. */ arm_status arm_conv_partial_f32( float32_t * pSrcA, @@ -3094,7 +2970,7 @@ void arm_rfft_fast_f32( * @param[in] numPoints is the number of output points to be computed. * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2]. */ arm_status arm_conv_partial_opt_q15( q15_t * pSrcA, @@ -3117,7 +2993,7 @@ void arm_rfft_fast_f32( * @param[out] pDst points to the block of output data * @param[in] firstIndex is the first output sample to start with. * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2]. */ arm_status arm_conv_partial_q15( q15_t * pSrcA, @@ -3138,7 +3014,7 @@ void arm_rfft_fast_f32( * @param[out] pDst points to the block of output data * @param[in] firstIndex is the first output sample to start with. * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2]. */ arm_status arm_conv_partial_fast_q15( q15_t * pSrcA, @@ -3161,7 +3037,7 @@ void arm_rfft_fast_f32( * @param[in] numPoints is the number of output points to be computed. * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2]. */ arm_status arm_conv_partial_fast_opt_q15( q15_t * pSrcA, @@ -3184,7 +3060,7 @@ void arm_rfft_fast_f32( * @param[out] pDst points to the block of output data * @param[in] firstIndex is the first output sample to start with. * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2]. */ arm_status arm_conv_partial_q31( q31_t * pSrcA, @@ -3205,7 +3081,7 @@ void arm_rfft_fast_f32( * @param[out] pDst points to the block of output data * @param[in] firstIndex is the first output sample to start with. * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2]. */ arm_status arm_conv_partial_fast_q31( q31_t * pSrcA, @@ -3228,7 +3104,7 @@ void arm_rfft_fast_f32( * @param[in] numPoints is the number of output points to be computed. * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2]. */ arm_status arm_conv_partial_opt_q7( q7_t * pSrcA, @@ -3251,7 +3127,7 @@ void arm_rfft_fast_f32( * @param[out] pDst points to the block of output data * @param[in] firstIndex is the first output sample to start with. * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2]. */ arm_status arm_conv_partial_q7( q7_t * pSrcA, @@ -3271,7 +3147,7 @@ void arm_rfft_fast_f32( uint8_t M; /**< decimation factor. */ uint16_t numTaps; /**< number of coefficients in the filter. */ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ } arm_fir_decimate_instance_q15; /** @@ -3282,7 +3158,7 @@ void arm_rfft_fast_f32( uint8_t M; /**< decimation factor. */ uint16_t numTaps; /**< number of coefficients in the filter. */ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ } arm_fir_decimate_instance_q31; /** @@ -3293,7 +3169,7 @@ void arm_rfft_fast_f32( uint8_t M; /**< decimation factor. */ uint16_t numTaps; /**< number of coefficients in the filter. */ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ } arm_fir_decimate_instance_f32; @@ -3434,7 +3310,7 @@ void arm_rfft_fast_f32( uint8_t L; /**< upsample factor. */ uint16_t phaseLength; /**< length of each polyphase filter component. */ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize + phaseLength-1. */ } arm_fir_interpolate_instance_q15; /** @@ -3445,7 +3321,7 @@ void arm_rfft_fast_f32( uint8_t L; /**< upsample factor. */ uint16_t phaseLength; /**< length of each polyphase filter component. */ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize + phaseLength-1. */ } arm_fir_interpolate_instance_q31; /** @@ -3456,7 +3332,7 @@ void arm_rfft_fast_f32( uint8_t L; /**< upsample factor. */ uint16_t phaseLength; /**< length of each polyphase filter component. */ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength + numTaps-1. */ } arm_fir_interpolate_instance_f32; @@ -3838,9 +3714,9 @@ void arm_rfft_fast_f32( typedef struct { uint16_t numStages; /**< number of stages in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages + blockSize. */ q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages + 1. */ } arm_iir_lattice_instance_q15; /** @@ -3849,9 +3725,9 @@ void arm_rfft_fast_f32( typedef struct { uint16_t numStages; /**< number of stages in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages + blockSize. */ q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages + 1. */ } arm_iir_lattice_instance_q31; /** @@ -3860,9 +3736,9 @@ void arm_rfft_fast_f32( typedef struct { uint16_t numStages; /**< number of stages in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages + blockSize. */ float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages + 1. */ } arm_iir_lattice_instance_f32; @@ -3885,8 +3761,8 @@ void arm_rfft_fast_f32( * @param[in] S points to an instance of the floating-point IIR lattice structure. * @param[in] numStages number of stages in the filter. * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. - * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. - * @param[in] pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages + 1. + * @param[in] pState points to the state buffer. The array is of length numStages + blockSize-1. * @param[in] blockSize number of samples to process. */ void arm_iir_lattice_init_f32( @@ -3917,8 +3793,8 @@ void arm_rfft_fast_f32( * @param[in] S points to an instance of the Q31 IIR lattice structure. * @param[in] numStages number of stages in the filter. * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. - * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. - * @param[in] pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages + 1. + * @param[in] pState points to the state buffer. The array is of length numStages + blockSize. * @param[in] blockSize number of samples to process. */ void arm_iir_lattice_init_q31( @@ -3949,8 +3825,8 @@ void arm_rfft_fast_f32( * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure. * @param[in] numStages number of stages in the filter. * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages. - * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. - * @param[in] pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages + 1. + * @param[in] pState points to state buffer. The array is of length numStages + blockSize. * @param[in] blockSize number of samples to process per call. */ void arm_iir_lattice_init_q15( @@ -3968,7 +3844,7 @@ void arm_rfft_fast_f32( typedef struct { uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ float32_t mu; /**< step size that controls filter coefficient updates. */ } arm_lms_instance_f32; @@ -4016,7 +3892,7 @@ void arm_rfft_fast_f32( typedef struct { uint16_t numTaps; /**< number of coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ q15_t mu; /**< step size that controls filter coefficient updates. */ uint32_t postShift; /**< bit shift applied to coefficients. */ @@ -4067,7 +3943,7 @@ void arm_rfft_fast_f32( typedef struct { uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ q31_t mu; /**< step size that controls filter coefficient updates. */ uint32_t postShift; /**< bit shift applied to coefficients. */ @@ -4118,7 +3994,7 @@ void arm_rfft_fast_f32( typedef struct { uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ float32_t mu; /**< step size that control filter coefficient updates. */ float32_t energy; /**< saves previous frame energy. */ @@ -4168,7 +4044,7 @@ void arm_rfft_fast_f32( typedef struct { uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ q31_t mu; /**< step size that controls filter coefficient updates. */ uint8_t postShift; /**< bit shift applied to coefficients. */ @@ -4222,7 +4098,7 @@ void arm_rfft_fast_f32( typedef struct { uint16_t numTaps; /**< Number of coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ q15_t mu; /**< step size that controls filter coefficient updates. */ uint8_t postShift; /**< bit shift applied to coefficients. */ @@ -4431,7 +4307,7 @@ void arm_rfft_fast_f32( { uint16_t numTaps; /**< number of coefficients in the filter. */ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay + blockSize-1. */ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ @@ -4444,7 +4320,7 @@ void arm_rfft_fast_f32( { uint16_t numTaps; /**< number of coefficients in the filter. */ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay + blockSize-1. */ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ @@ -4457,7 +4333,7 @@ void arm_rfft_fast_f32( { uint16_t numTaps; /**< number of coefficients in the filter. */ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay + blockSize-1. */ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ @@ -4470,7 +4346,7 @@ void arm_rfft_fast_f32( { uint16_t numTaps; /**< number of coefficients in the filter. */ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay + blockSize-1. */ q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ @@ -5444,12 +5320,12 @@ void arm_rfft_fast_f32( /* Calculation of index */ i = (int32_t) ((x - S->x1) / xSpacing); - if(i < 0) + if (i < 0) { /* Iniatilize output for below specified range as least output value of table */ y = pYData[0]; } - else if((uint32_t)i >= S->nValues) + else if ((uint32_t)i >= S->nValues) { /* Iniatilize output for above specified range as last output value of table */ y = pYData[S->nValues - 1]; @@ -5502,11 +5378,11 @@ void arm_rfft_fast_f32( /* Index value calculation */ index = ((x & (q31_t)0xFFF00000) >> 20); - if(index >= (int32_t)(nValues - 1)) + if (index >= (int32_t)(nValues - 1)) { return (pYData[nValues - 1]); } - else if(index < 0) + else if (index < 0) { return (pYData[0]); } @@ -5560,11 +5436,11 @@ void arm_rfft_fast_f32( /* Index value calculation */ index = ((x & (int32_t)0xFFF00000) >> 20); - if(index >= (int32_t)(nValues - 1)) + if (index >= (int32_t)(nValues - 1)) { return (pYData[nValues - 1]); } - else if(index < 0) + else if (index < 0) { return (pYData[0]); } @@ -5621,7 +5497,7 @@ void arm_rfft_fast_f32( } index = (x >> 20) & 0xfff; - if(index >= (nValues - 1)) + if (index >= (nValues - 1)) { return (pYData[nValues - 1]); } @@ -5746,7 +5622,7 @@ void arm_rfft_fast_f32( float32_t in, float32_t * pOut) { - if(in >= 0.0f) + if (in >= 0.0f) { #if (__FPU_USED == 1) && defined ( __CC_ARM ) @@ -5821,7 +5697,7 @@ void arm_rfft_fast_f32( /* Loop over the blockSize */ i = blockSize; - while(i > 0u) + while (i > 0u) { /* copy the input sample to the circular buffer */ circBuffer[wOffset] = *src; @@ -5831,7 +5707,7 @@ void arm_rfft_fast_f32( /* Circularly update wOffset. Watch out for positive and negative value */ wOffset += bufferInc; - if(wOffset >= L) + if (wOffset >= L) wOffset -= L; /* Decrement the loop counter */ @@ -5869,7 +5745,7 @@ void arm_rfft_fast_f32( /* Loop over the blockSize */ i = blockSize; - while(i > 0u) + while (i > 0u) { /* copy the sample from the circular buffer to the destination buffer */ *dst = circBuffer[rOffset]; @@ -5877,7 +5753,7 @@ void arm_rfft_fast_f32( /* Update the input pointer */ dst += dstInc; - if(dst == (int32_t *) dst_end) + if (dst == (int32_t *) dst_end) { dst = dst_base; } @@ -5885,7 +5761,7 @@ void arm_rfft_fast_f32( /* Circularly update rOffset. Watch out for positive and negative value */ rOffset += bufferInc; - if(rOffset >= L) + if (rOffset >= L) { rOffset -= L; } @@ -5921,7 +5797,7 @@ void arm_rfft_fast_f32( /* Loop over the blockSize */ i = blockSize; - while(i > 0u) + while (i > 0u) { /* copy the input sample to the circular buffer */ circBuffer[wOffset] = *src; @@ -5931,7 +5807,7 @@ void arm_rfft_fast_f32( /* Circularly update wOffset. Watch out for positive and negative value */ wOffset += bufferInc; - if(wOffset >= L) + if (wOffset >= L) wOffset -= L; /* Decrement the loop counter */ @@ -5969,7 +5845,7 @@ void arm_rfft_fast_f32( /* Loop over the blockSize */ i = blockSize; - while(i > 0u) + while (i > 0u) { /* copy the sample from the circular buffer to the destination buffer */ *dst = circBuffer[rOffset]; @@ -5977,7 +5853,7 @@ void arm_rfft_fast_f32( /* Update the input pointer */ dst += dstInc; - if(dst == (q15_t *) dst_end) + if (dst == (q15_t *) dst_end) { dst = dst_base; } @@ -5985,7 +5861,7 @@ void arm_rfft_fast_f32( /* Circularly update wOffset. Watch out for positive and negative value */ rOffset += bufferInc; - if(rOffset >= L) + if (rOffset >= L) { rOffset -= L; } @@ -6021,7 +5897,7 @@ void arm_rfft_fast_f32( /* Loop over the blockSize */ i = blockSize; - while(i > 0u) + while (i > 0u) { /* copy the input sample to the circular buffer */ circBuffer[wOffset] = *src; @@ -6031,7 +5907,7 @@ void arm_rfft_fast_f32( /* Circularly update wOffset. Watch out for positive and negative value */ wOffset += bufferInc; - if(wOffset >= L) + if (wOffset >= L) wOffset -= L; /* Decrement the loop counter */ @@ -6069,7 +5945,7 @@ void arm_rfft_fast_f32( /* Loop over the blockSize */ i = blockSize; - while(i > 0u) + while (i > 0u) { /* copy the sample from the circular buffer to the destination buffer */ *dst = circBuffer[rOffset]; @@ -6077,7 +5953,7 @@ void arm_rfft_fast_f32( /* Update the input pointer */ dst += dstInc; - if(dst == (q7_t *) dst_end) + if (dst == (q7_t *) dst_end) { dst = dst_base; } @@ -6085,7 +5961,7 @@ void arm_rfft_fast_f32( /* Circularly update rOffset. Watch out for positive and negative value */ rOffset += bufferInc; - if(rOffset >= L) + if (rOffset >= L) { rOffset -= L; } @@ -6723,9 +6599,9 @@ void arm_rfft_fast_f32( * The interpolated output point is computed as: *
    *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
-   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
-   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
-   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   *           + f(XF + 1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF + 1) * (1-(x-XF))*(y-YF)
+   *           + f(XF + 1, YF + 1) * (x-XF)*(y-YF)
    * 
* Note that the coordinates (x, y) contain integer and fractional components. * The integer components specify which portion of the table to use while the @@ -6766,7 +6642,7 @@ void arm_rfft_fast_f32( /* Care taken for table outside boundary */ /* Returns zero output when values are outside table boundary */ - if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) + if (xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1)) { return (0); } @@ -6840,7 +6716,7 @@ void arm_rfft_fast_f32( /* Care taken for table outside boundary */ /* Returns zero output when values are outside table boundary */ - if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) { return (0); } @@ -6914,7 +6790,7 @@ void arm_rfft_fast_f32( /* Care taken for table outside boundary */ /* Returns zero output when values are outside table boundary */ - if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) { return (0); } @@ -6992,7 +6868,7 @@ void arm_rfft_fast_f32( /* Care taken for table outside boundary */ /* Returns zero output when values are outside table boundary */ - if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) { return (0); } diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/cmsis_armcc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/cmsis_armcc.h similarity index 100% rename from bsp/nrf52832/Libraries/CMSIS/Include/cmsis_armcc.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/cmsis_armcc.h diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/cmsis_armcc_V6.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/cmsis_armcc_V6.h similarity index 100% rename from bsp/nrf52832/Libraries/CMSIS/Include/cmsis_armcc_V6.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/cmsis_armcc_V6.h diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/cmsis_gcc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/cmsis_gcc.h similarity index 100% rename from bsp/nrf52832/Libraries/CMSIS/Include/cmsis_gcc.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/cmsis_gcc.h diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/core_cm0.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm0.h similarity index 99% rename from bsp/nrf52832/Libraries/CMSIS/Include/core_cm0.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm0.h index 711dad551702720712e7933bb693699e5ea745fa..b43ce5539f96d258bba334c4c0cc8b75c38b316f 100644 --- a/bsp/nrf52832/Libraries/CMSIS/Include/core_cm0.h +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm0.h @@ -735,7 +735,7 @@ __STATIC_INLINE void NVIC_SystemReset(void) SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); /* Ensure completion of memory access */ - for(;;) /* wait until reset */ + for (;;) /* wait until reset */ { __NOP(); } diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/core_cm0plus.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm0plus.h similarity index 99% rename from bsp/nrf52832/Libraries/CMSIS/Include/core_cm0plus.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm0plus.h index b04aa3905323c5a0376c26989c1a3c9b8f3afe6a..89e2285ed72a125bbd83c746a7370937979fe126 100644 --- a/bsp/nrf52832/Libraries/CMSIS/Include/core_cm0plus.h +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm0plus.h @@ -851,7 +851,7 @@ __STATIC_INLINE void NVIC_SystemReset(void) SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); /* Ensure completion of memory access */ - for(;;) /* wait until reset */ + for (;;) /* wait until reset */ { __NOP(); } diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/core_cm3.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm3.h similarity index 99% rename from bsp/nrf52832/Libraries/CMSIS/Include/core_cm3.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm3.h index b4ac4c7b05a799590575c0b5c8e24c51748ee20b..88f5e65fcf98fb7acc522c3f2a73f1f0a7c27d3b 100644 --- a/bsp/nrf52832/Libraries/CMSIS/Include/core_cm3.h +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm3.h @@ -1622,7 +1622,7 @@ __STATIC_INLINE void NVIC_SystemReset(void) SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ - for(;;) /* wait until reset */ + for (;;) /* wait until reset */ { __NOP(); } diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/core_cm4.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm4.h similarity index 99% rename from bsp/nrf52832/Libraries/CMSIS/Include/core_cm4.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm4.h index dc840ebf2221382b8ca8e9ed8ce72b99e4027ad1..d02b11136dded8a922af1129a15c126077e011a1 100644 --- a/bsp/nrf52832/Libraries/CMSIS/Include/core_cm4.h +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm4.h @@ -1796,7 +1796,7 @@ __STATIC_INLINE void NVIC_SystemReset(void) SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ - for(;;) /* wait until reset */ + for (;;) /* wait until reset */ { __NOP(); } diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/core_cm7.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm7.h similarity index 99% rename from bsp/nrf52832/Libraries/CMSIS/Include/core_cm7.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm7.h index 3b7530ad505b57d283cc6f07e7f51b9a54be9a0b..b1de1be499132e21affb3bbb41641a324ad666f5 100644 --- a/bsp/nrf52832/Libraries/CMSIS/Include/core_cm7.h +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cm7.h @@ -2004,7 +2004,7 @@ __STATIC_INLINE void NVIC_SystemReset(void) SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ - for(;;) /* wait until reset */ + for (;;) /* wait until reset */ { __NOP(); } @@ -2143,7 +2143,7 @@ __STATIC_INLINE void SCB_EnableDCache (void) __schedule_barrier(); #endif } while (ways--); - } while(sets--); + } while (sets--); __DSB(); SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ @@ -2183,7 +2183,7 @@ __STATIC_INLINE void SCB_DisableDCache (void) __schedule_barrier(); #endif } while (ways--); - } while(sets--); + } while (sets--); __DSB(); __ISB(); @@ -2218,7 +2218,7 @@ __STATIC_INLINE void SCB_InvalidateDCache (void) __schedule_barrier(); #endif } while (ways--); - } while(sets--); + } while (sets--); __DSB(); __ISB(); @@ -2253,7 +2253,7 @@ __STATIC_INLINE void SCB_CleanDCache (void) __schedule_barrier(); #endif } while (ways--); - } while(sets--); + } while (sets--); __DSB(); __ISB(); @@ -2288,7 +2288,7 @@ __STATIC_INLINE void SCB_CleanInvalidateDCache (void) __schedule_barrier(); #endif } while (ways--); - } while(sets--); + } while (sets--); __DSB(); __ISB(); diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/core_cmFunc.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cmFunc.h similarity index 99% rename from bsp/nrf52832/Libraries/CMSIS/Include/core_cmFunc.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cmFunc.h index 652a48af07a93d9a48ea9bfa818eebd6429045da..979696f50a36e361c0da3858b696c276e849de8b 100644 --- a/bsp/nrf52832/Libraries/CMSIS/Include/core_cmFunc.h +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cmFunc.h @@ -31,7 +31,6 @@ POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - #if defined ( __ICCARM__ ) #pragma system_include /* treat file as system include file for MISRA check */ #elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/core_cmInstr.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cmInstr.h similarity index 100% rename from bsp/nrf52832/Libraries/CMSIS/Include/core_cmInstr.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cmInstr.h diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/core_cmSimd.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cmSimd.h similarity index 100% rename from bsp/nrf52832/Libraries/CMSIS/Include/core_cmSimd.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_cmSimd.h diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/core_sc000.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_sc000.h similarity index 99% rename from bsp/nrf52832/Libraries/CMSIS/Include/core_sc000.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_sc000.h index 514dbd81b9f776af5e0f29e65d075866c05a4b5a..44db659f84a2484e0300c458d54b59b47ddb2152 100644 --- a/bsp/nrf52832/Libraries/CMSIS/Include/core_sc000.h +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_sc000.h @@ -863,7 +863,7 @@ __STATIC_INLINE void NVIC_SystemReset(void) SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); /* Ensure completion of memory access */ - for(;;) /* wait until reset */ + for (;;) /* wait until reset */ { __NOP(); } diff --git a/bsp/nrf52832/Libraries/CMSIS/Include/core_sc300.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_sc300.h similarity index 99% rename from bsp/nrf52832/Libraries/CMSIS/Include/core_sc300.h rename to bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_sc300.h index 8bd18aa318a982b66863b4e413672eed272d2657..5b58f49ea5f7ef77895e844bc6b2c0b22cb6c603 100644 --- a/bsp/nrf52832/Libraries/CMSIS/Include/core_sc300.h +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/cmsis/include/core_sc300.h @@ -1604,7 +1604,7 @@ __STATIC_INLINE void NVIC_SystemReset(void) SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ - for(;;) /* wait until reset */ + for (;;) /* wait until reset */ { __NOP(); } diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/Makefile.common b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/Makefile.common new file mode 100644 index 0000000000000000000000000000000000000000..acb6505e10708797162b03b272bf13553060d946 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/Makefile.common @@ -0,0 +1,169 @@ +# Copyright (c) 2016 Nordic Semiconductor. All Rights Reserved. +# +# The information contained herein is property of Nordic Semiconductor ASA. +# Terms and conditions of usage are described in detail in NORDIC +# SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. +# +# Licensees are granted free, non-transferable use of the information. NO +# WARRANTY of ANY KIND is provided. This heading must NOT be removed from +# the file. + +PLATFORM_SUFFIX := $(if $(filter Windows%,$(OS)),windows,posix) +TOOLCHAIN_CONFIG_FILE := $(TEMPLATE_PATH)/Makefile.$(PLATFORM_SUFFIX) +include $(TOOLCHAIN_CONFIG_FILE) + +# Toolchain commands +CC := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc" +CXX := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-c++" +AS := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as" +AR := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar" -r +LD := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld" +NM := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm" +OBJDUMP := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump" +OBJCOPY := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy" +SIZE := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-size" +$(if $(shell $(CC) --version),,$(info Cannot find: $(CC).) \ + $(info Please set values in: "$(abspath $(TOOLCHAIN_CONFIG_FILE))") \ + $(info according to the actual configuration of your system.) \ + $(error Cannot continue)) + +# Use ccache on linux if available +CCACHE := $(if $(filter Windows%,$(OS)),, \ + $(if $(wildcard /usr/bin/ccache),ccache)) +CC := $(CCACHE) $(CC) + +MK := mkdir +RM := rm -rf + +# echo suspend +ifeq ($(VERBOSE),1) + NO_ECHO := +else + NO_ECHO := @ +endif + +# $1 type of item +# $2 path to check +define ensure_exists +$(if $(wildcard $(2)),, $(warning Cannot find $(1): $(2))) +endef + +# $1 object file +# $2 source file +define bind_obj_with_src +$(eval $(1) := $(2)) +endef + +# $1 object file +# $2 target name +define bind_obj_with_target +$(eval $(1)T := $(2)) +endef + +# $1 target name +# $2 source file name +# Note: this additional .o for .s-files is a workaround for issues with make 4.1 +# from MinGW (it does nothing to remake .s.o files when a rule for .S.o +# files is defined as well). +define get_object_file_name +$(OUTPUT_DIRECTORY)/$(strip $(1))_$(patsubst %.s,%.s.o,$(notdir $(2))).o +endef + +# $1 target name +# $2 list of source files +define get_object_files +$(foreach src_file, $(2), \ + $(call ensure_exists,source file, $(src_file)) \ + $(eval obj_file := $(call get_object_file_name, $(1), $(src_file))) \ + $(eval DEPENDENCIES += $(obj_file:.o=.d)) \ + $(call bind_obj_with_src, $(obj_file), $(src_file)) \ + $(call bind_obj_with_target, $(obj_file), $(1)) \ + $(eval $(obj_file): Makefile) \ + $(obj_file)) +endef + +# $1 variable name +# $2 target name +define target_specific +$($(addsuffix _$(strip $(2)), $(1))) +endef + +# $1 target name +# $2 link target name +define prepare_build +$(eval DEPENDENCIES :=) \ +$(eval $(2): \ + $(call get_object_files, $(1), $(SRC_FILES) \ + $(call target_specific, SRC_FILES, $(1)))) \ +$(eval -include $(DEPENDENCIES)) \ +$(eval INC_PATHS_$(strip $(1)) := \ + $(foreach folder, $(INC_FOLDERS) $(call target_specific, INC_FOLDERS, $(1)), \ + $(call ensure_exists,include folder, $(folder)) \ + -I"$(folder)")) +endef + +INC_PATHS = $(call target_specific, INC_PATHS, $($@T)) + +# $1 target name +define define_target +$(eval OUTPUT_FILE := $(OUTPUT_DIRECTORY)/$(strip $(1))) \ +$(eval $(1): $(OUTPUT_FILE).out $(OUTPUT_FILE).hex $(OUTPUT_FILE).bin) \ +$(call prepare_build, $(1), $(OUTPUT_FILE).out) +endef + +# $1 target name +# $2 library file name +define define_library +$(eval $(1) := $(2)) \ +$(call prepare_build, $(1), $(1)) +endef + +.PHONY: $(TARGETS) default all clean help flash + +all: $(TARGETS) + +clean: + $(RM) $(OUTPUT_DIRECTORY) + +# Create build directories +$(OUTPUT_DIRECTORY): + $(MK) $@ + +# Create objects from C source files +$(OUTPUT_DIRECTORY)/%.c.o: | $(OUTPUT_DIRECTORY) + @echo Compiling file: $(notdir $($@)) + $(NO_ECHO)$(CC) -MP -MD -std=c99 $(CFLAGS) $(INC_PATHS) -c -o $@ "$($@)" + +# Create objects from C++ source files +$(OUTPUT_DIRECTORY)/%.cpp.o: | $(OUTPUT_DIRECTORY) + @echo Compiling file: $(notdir $($@)) + $(NO_ECHO)$(CXX) -MP -MD $(CFLAGS) $(CXXFLAGS) $(INC_PATHS) -c -o $@ "$($@)" + +# Create objects from assembly files +$(OUTPUT_DIRECTORY)/%.S.o \ +$(OUTPUT_DIRECTORY)/%.s.o.o: | $(OUTPUT_DIRECTORY) + @echo Assembling file: $(notdir $($@)) + $(NO_ECHO)$(CC) -MP -MD -std=c99 $(ASMFLAGS) $(INC_PATHS) -c -o $@ "$($@)" + +export FILE_LIST +DUMP_FILE_LIST := \ + "$(MAKE)" -s --no-print-directory -f $(TEMPLATE_PATH)/file_list.mk +# Link object files +%.out: + $(eval FILE_LIST := $^ $(LIB_FILES)) + $(NO_ECHO)$(DUMP_FILE_LIST) > $(@:.out=.in) + @echo Linking target: $@ + $(NO_ECHO)$(CC) -Wl,-Map=$(@:.out=.map) $(LDFLAGS) @$(@:.out=.in) -lm -o $@ + -@echo '' + $(NO_ECHO)$(SIZE) $@ + -@echo '' + +# Create binary .bin file from the .out file +%.bin: %.out + @echo Preparing: $@ + $(NO_ECHO)$(OBJCOPY) -O binary $< $@ + +# Create binary .hex file from the .out file +%.hex: %.out + @echo Preparing: $@ + $(NO_ECHO)$(OBJCOPY) -O ihex $< $@ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/Makefile.posix b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/Makefile.posix new file mode 100644 index 0000000000000000000000000000000000000000..b37277db539830d88994554acc08d6059f00c86b --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/Makefile.posix @@ -0,0 +1,3 @@ +GNU_INSTALL_ROOT := /usr/local/gcc-arm-none-eabi-4_9-2015q3 +GNU_VERSION := 4.9.3 +GNU_PREFIX := arm-none-eabi diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/Makefile.windows b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/Makefile.windows new file mode 100644 index 0000000000000000000000000000000000000000..87109c431a67b2c72504afdf29f8e98da435853a --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/Makefile.windows @@ -0,0 +1,3 @@ +GNU_INSTALL_ROOT := C:/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q3 +GNU_VERSION := 4.9.3 +GNU_PREFIX := arm-none-eabi diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/file_list.mk b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/file_list.mk new file mode 100644 index 0000000000000000000000000000000000000000..bd5cd686936f8a6bf75ea68841c88af0f3803c4e --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/file_list.mk @@ -0,0 +1,2 @@ +$(info $(FILE_LIST)) +all: ; diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/gcc_nrf51_common.ld b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/gcc_nrf51_common.ld new file mode 100644 index 0000000000000000000000000000000000000000..a4b8b289d6a668bdf2ffc81bed761c5a6b47d506 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/gcc_nrf51_common.ld @@ -0,0 +1,164 @@ +/* Linker script for Nordic Semiconductor nRF5 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.Vectors)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + *(.eh_frame*) + . = ALIGN(4); + } > FLASH + + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + . = ALIGN(4); + } > FLASH + __exidx_end = .; + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + *(.preinit_array) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + *(SORT(.init_array.*)) + *(.init_array) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + end = __end__; + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/gcc_startup_nrf51.S b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/gcc_startup_nrf51.S new file mode 100644 index 0000000000000000000000000000000000000000..b0dfe6c65ab2e57aeb7c98a20c426d657c196123 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/gcc_startup_nrf51.S @@ -0,0 +1,298 @@ +/* + +Copyright (c) 2009-2017 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed 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 + + 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. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + + .syntax unified + .arch armv6-m + +#ifdef __STARTUP_CONFIG +#include "startup_config.h" +#ifndef __STARTUP_CONFIG_STACK_ALIGNEMENT +#define __STARTUP_CONFIG_STACK_ALIGNEMENT 3 +#endif +#endif + + .section .stack +#if defined(__STARTUP_CONFIG) + .align __STARTUP_CONFIG_STACK_ALIGNEMENT + .equ Stack_Size, __STARTUP_CONFIG_STACK_SIZE +#elif defined(__STACK_SIZE) + .align 3 + .equ Stack_Size, __STACK_SIZE +#else + .align 3 + .equ Stack_Size, 2048 +#endif + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#if defined(__STARTUP_CONFIG) + .equ Heap_Size, __STARTUP_CONFIG_HEAP_SIZE +#elif defined(__HEAP_SIZE) + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 2048 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + .section .isr_vector + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler + .long NMI_Handler + .long HardFault_Handler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SVC_Handler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long PendSV_Handler + .long SysTick_Handler + + /* External Interrupts */ + .long POWER_CLOCK_IRQHandler + .long RADIO_IRQHandler + .long UART0_IRQHandler + .long SPI0_TWI0_IRQHandler + .long SPI1_TWI1_IRQHandler + .long 0 /*Reserved */ + .long GPIOTE_IRQHandler + .long ADC_IRQHandler + .long TIMER0_IRQHandler + .long TIMER1_IRQHandler + .long TIMER2_IRQHandler + .long RTC0_IRQHandler + .long TEMP_IRQHandler + .long RNG_IRQHandler + .long ECB_IRQHandler + .long CCM_AAR_IRQHandler + .long WDT_IRQHandler + .long RTC1_IRQHandler + .long QDEC_IRQHandler + .long LPCOMP_IRQHandler + .long SWI0_IRQHandler + .long SWI1_IRQHandler + .long SWI2_IRQHandler + .long SWI3_IRQHandler + .long SWI4_IRQHandler + .long SWI5_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + + .size __isr_vector, . - __isr_vector + +/* Reset Handler */ + + .equ NRF_POWER_RAMON_ADDRESS, 0x40000524 + .equ NRF_POWER_RAMONB_ADDRESS, 0x40000554 + .equ NRF_POWER_RAMONx_RAMxON_ONMODE_Msk, 0x3 + + .text + .thumb + .thumb_func + .align 1 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + + MOVS R1, #NRF_POWER_RAMONx_RAMxON_ONMODE_Msk + + LDR R0, =NRF_POWER_RAMON_ADDRESS + LDR R2, [R0] + ORRS R2, R1 + STR R2, [R0] + + LDR R0, =NRF_POWER_RAMONB_ADDRESS + LDR R2, [R0] + ORRS R2, R1 + STR R2, [R0] + +/* Loop to copy data from read only memory to RAM. + * The ranges of copy from/to are specified by following symbols: + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to. + * __bss_start__: VMA of end of the section to copy to. Normally __data_end__ is used, but by using __bss_start__ + * the user can add their own initialized data section before BSS section with the INTERT AFTER command. + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__bss_start__ + + subs r3, r2 + ble .L_loop1_done + +.L_loop1: + subs r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .L_loop1 + +.L_loop1_done: + +/* This part of work usually is done in C library startup code. Otherwise, + * define __STARTUP_CLEAR_BSS to enable it in this startup. This section + * clears the RAM where BSS data is located. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * All addresses must be aligned to 4 bytes boundary. + */ +#ifdef __STARTUP_CLEAR_BSS + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 + + subs r2, r1 + ble .L_loop3_done + +.L_loop3: + subs r2, #4 + str r0, [r1, r2] + bgt .L_loop3 + +.L_loop3_done: +#endif /* __STARTUP_CLEAR_BSS */ + +/* Execute SystemInit function. */ + bl SystemInit + +/* Call _start function provided by libraries. + * If those libraries are not accessible, define __START as your entry point. + */ +#ifndef __START +#define __START _start +#endif + bl __START + + .pool + .size Reset_Handler,.-Reset_Handler + + .section ".text" + + +/* Dummy Exception Handlers (infinite loops which can be modified) */ + + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + b . + .size NMI_Handler, . - NMI_Handler + + + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + b . + .size HardFault_Handler, . - HardFault_Handler + + + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + b . + .size SVC_Handler, . - SVC_Handler + + + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + b . + .size PendSV_Handler, . - PendSV_Handler + + + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + b . + .size SysTick_Handler, . - SysTick_Handler + + +/* IRQ Handlers */ + + .globl Default_Handler + .type Default_Handler, %function +Default_Handler: + b . + .size Default_Handler, . - Default_Handler + + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + IRQ POWER_CLOCK_IRQHandler + IRQ RADIO_IRQHandler + IRQ UART0_IRQHandler + IRQ SPI0_TWI0_IRQHandler + IRQ SPI1_TWI1_IRQHandler + IRQ GPIOTE_IRQHandler + IRQ ADC_IRQHandler + IRQ TIMER0_IRQHandler + IRQ TIMER1_IRQHandler + IRQ TIMER2_IRQHandler + IRQ RTC0_IRQHandler + IRQ TEMP_IRQHandler + IRQ RNG_IRQHandler + IRQ ECB_IRQHandler + IRQ CCM_AAR_IRQHandler + IRQ WDT_IRQHandler + IRQ RTC1_IRQHandler + IRQ QDEC_IRQHandler + IRQ LPCOMP_IRQHandler + IRQ SWI0_IRQHandler + IRQ SWI1_IRQHandler + IRQ SWI2_IRQHandler + IRQ SWI3_IRQHandler + IRQ SWI4_IRQHandler + IRQ SWI5_IRQHandler + + .end diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/gcc_startup_nrf52.S b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/gcc_startup_nrf52.S new file mode 100644 index 0000000000000000000000000000000000000000..cb33d980d94507046a04aa18a2121878767c3221 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/gcc_startup_nrf52.S @@ -0,0 +1,404 @@ +/* + +Copyright (c) 2009-2017 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed 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 + + 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. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + + .syntax unified + .arch armv7e-m + +#ifdef __STARTUP_CONFIG +#include "startup_config.h" +#ifndef __STARTUP_CONFIG_STACK_ALIGNEMENT +#define __STARTUP_CONFIG_STACK_ALIGNEMENT 3 +#endif +#endif + + .section .stack +#if defined(__STARTUP_CONFIG) + .align __STARTUP_CONFIG_STACK_ALIGNEMENT + .equ Stack_Size, __STARTUP_CONFIG_STACK_SIZE +#elif defined(__STACK_SIZE) + .align 3 + .equ Stack_Size, __STACK_SIZE +#else + .align 3 + .equ Stack_Size, 8192 +#endif + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#if defined(__STARTUP_CONFIG) + .equ Heap_Size, __STARTUP_CONFIG_HEAP_SIZE +#elif defined(__HEAP_SIZE) + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 8192 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + .section .isr_vector + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler + .long NMI_Handler + .long HardFault_Handler + .long MemoryManagement_Handler + .long BusFault_Handler + .long UsageFault_Handler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SVC_Handler + .long DebugMon_Handler + .long 0 /*Reserved */ + .long PendSV_Handler + .long SysTick_Handler + + /* External Interrupts */ + .long POWER_CLOCK_IRQHandler + .long RADIO_IRQHandler + .long UARTE0_UART0_IRQHandler + .long SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + .long SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + .long NFCT_IRQHandler + .long GPIOTE_IRQHandler + .long SAADC_IRQHandler + .long TIMER0_IRQHandler + .long TIMER1_IRQHandler + .long TIMER2_IRQHandler + .long RTC0_IRQHandler + .long TEMP_IRQHandler + .long RNG_IRQHandler + .long ECB_IRQHandler + .long CCM_AAR_IRQHandler + .long WDT_IRQHandler + .long RTC1_IRQHandler + .long QDEC_IRQHandler + .long COMP_LPCOMP_IRQHandler + .long SWI0_EGU0_IRQHandler + .long SWI1_EGU1_IRQHandler + .long SWI2_EGU2_IRQHandler + .long SWI3_EGU3_IRQHandler + .long SWI4_EGU4_IRQHandler + .long SWI5_EGU5_IRQHandler + .long TIMER3_IRQHandler + .long TIMER4_IRQHandler + .long PWM0_IRQHandler + .long PDM_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long MWU_IRQHandler + .long PWM1_IRQHandler + .long PWM2_IRQHandler + .long SPIM2_SPIS2_SPI2_IRQHandler + .long RTC2_IRQHandler + .long I2S_IRQHandler + .long FPU_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + + .size __isr_vector, . - __isr_vector + +/* Reset Handler */ + + + .text + .thumb + .thumb_func + .align 1 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + + +/* Loop to copy data from read only memory to RAM. + * The ranges of copy from/to are specified by following symbols: + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to. + * __bss_start__: VMA of end of the section to copy to. Normally __data_end__ is used, but by using __bss_start__ + * the user can add their own initialized data section before BSS section with the INTERT AFTER command. + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__bss_start__ + + subs r3, r2 + ble .L_loop1_done + +.L_loop1: + subs r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .L_loop1 + +.L_loop1_done: + +/* This part of work usually is done in C library startup code. Otherwise, + * define __STARTUP_CLEAR_BSS to enable it in this startup. This section + * clears the RAM where BSS data is located. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * All addresses must be aligned to 4 bytes boundary. + */ +#ifdef __STARTUP_CLEAR_BSS + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 + + subs r2, r1 + ble .L_loop3_done + +.L_loop3: + subs r2, #4 + str r0, [r1, r2] + bgt .L_loop3 + +.L_loop3_done: +#endif /* __STARTUP_CLEAR_BSS */ + +/* Execute SystemInit function. */ + bl SystemInit + +/* Call _start function provided by libraries. + * If those libraries are not accessible, define __START as your entry point. + */ +#ifndef __START +#define __START _start +#endif + bl __START + + .pool + .size Reset_Handler,.-Reset_Handler + + .section ".text" + + +/* Dummy Exception Handlers (infinite loops which can be modified) */ + + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + b . + .size NMI_Handler, . - NMI_Handler + + + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + b . + .size HardFault_Handler, . - HardFault_Handler + + + .weak MemoryManagement_Handler + .type MemoryManagement_Handler, %function +MemoryManagement_Handler: + b . + .size MemoryManagement_Handler, . - MemoryManagement_Handler + + + .weak BusFault_Handler + .type BusFault_Handler, %function +BusFault_Handler: + b . + .size BusFault_Handler, . - BusFault_Handler + + + .weak UsageFault_Handler + .type UsageFault_Handler, %function +UsageFault_Handler: + b . + .size UsageFault_Handler, . - UsageFault_Handler + + + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + b . + .size SVC_Handler, . - SVC_Handler + + + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + b . + .size DebugMon_Handler, . - DebugMon_Handler + + + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + b . + .size PendSV_Handler, . - PendSV_Handler + + + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + b . + .size SysTick_Handler, . - SysTick_Handler + + +/* IRQ Handlers */ + + .globl Default_Handler + .type Default_Handler, %function +Default_Handler: + b . + .size Default_Handler, . - Default_Handler + + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + IRQ POWER_CLOCK_IRQHandler + IRQ RADIO_IRQHandler + IRQ UARTE0_UART0_IRQHandler + IRQ SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + IRQ SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + IRQ NFCT_IRQHandler + IRQ GPIOTE_IRQHandler + IRQ SAADC_IRQHandler + IRQ TIMER0_IRQHandler + IRQ TIMER1_IRQHandler + IRQ TIMER2_IRQHandler + IRQ RTC0_IRQHandler + IRQ TEMP_IRQHandler + IRQ RNG_IRQHandler + IRQ ECB_IRQHandler + IRQ CCM_AAR_IRQHandler + IRQ WDT_IRQHandler + IRQ RTC1_IRQHandler + IRQ QDEC_IRQHandler + IRQ COMP_LPCOMP_IRQHandler + IRQ SWI0_EGU0_IRQHandler + IRQ SWI1_EGU1_IRQHandler + IRQ SWI2_EGU2_IRQHandler + IRQ SWI3_EGU3_IRQHandler + IRQ SWI4_EGU4_IRQHandler + IRQ SWI5_EGU5_IRQHandler + IRQ TIMER3_IRQHandler + IRQ TIMER4_IRQHandler + IRQ PWM0_IRQHandler + IRQ PDM_IRQHandler + IRQ MWU_IRQHandler + IRQ PWM1_IRQHandler + IRQ PWM2_IRQHandler + IRQ SPIM2_SPIS2_SPI2_IRQHandler + IRQ RTC2_IRQHandler + IRQ I2S_IRQHandler + IRQ FPU_IRQHandler + + .end diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/gcc_startup_nrf52840.S b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/gcc_startup_nrf52840.S new file mode 100644 index 0000000000000000000000000000000000000000..6fd94fcf691a34ccbded64c277514fabe64c406c --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/gcc_startup_nrf52840.S @@ -0,0 +1,410 @@ +/* + +Copyright (c) 2009-2017 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed 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 + + 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. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + + .syntax unified + .arch armv7e-m + +#ifdef __STARTUP_CONFIG +#include "startup_config.h" +#ifndef __STARTUP_CONFIG_STACK_ALIGNEMENT +#define __STARTUP_CONFIG_STACK_ALIGNEMENT 3 +#endif +#endif + + .section .stack +#if defined(__STARTUP_CONFIG) + .align __STARTUP_CONFIG_STACK_ALIGNEMENT + .equ Stack_Size, __STARTUP_CONFIG_STACK_SIZE +#elif defined(__STACK_SIZE) + .align 3 + .equ Stack_Size, __STACK_SIZE +#else + .align 3 + .equ Stack_Size, 8192 +#endif + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#if defined(__STARTUP_CONFIG) + .equ Heap_Size, __STARTUP_CONFIG_HEAP_SIZE +#elif defined(__HEAP_SIZE) + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 8192 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + .section .isr_vector + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler + .long NMI_Handler + .long HardFault_Handler + .long MemoryManagement_Handler + .long BusFault_Handler + .long UsageFault_Handler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SVC_Handler + .long DebugMon_Handler + .long 0 /*Reserved */ + .long PendSV_Handler + .long SysTick_Handler + + /* External Interrupts */ + .long POWER_CLOCK_IRQHandler + .long RADIO_IRQHandler + .long UARTE0_UART0_IRQHandler + .long SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + .long SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + .long NFCT_IRQHandler + .long GPIOTE_IRQHandler + .long SAADC_IRQHandler + .long TIMER0_IRQHandler + .long TIMER1_IRQHandler + .long TIMER2_IRQHandler + .long RTC0_IRQHandler + .long TEMP_IRQHandler + .long RNG_IRQHandler + .long ECB_IRQHandler + .long CCM_AAR_IRQHandler + .long WDT_IRQHandler + .long RTC1_IRQHandler + .long QDEC_IRQHandler + .long COMP_LPCOMP_IRQHandler + .long SWI0_EGU0_IRQHandler + .long SWI1_EGU1_IRQHandler + .long SWI2_EGU2_IRQHandler + .long SWI3_EGU3_IRQHandler + .long SWI4_EGU4_IRQHandler + .long SWI5_EGU5_IRQHandler + .long TIMER3_IRQHandler + .long TIMER4_IRQHandler + .long PWM0_IRQHandler + .long PDM_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long MWU_IRQHandler + .long PWM1_IRQHandler + .long PWM2_IRQHandler + .long SPIM2_SPIS2_SPI2_IRQHandler + .long RTC2_IRQHandler + .long I2S_IRQHandler + .long FPU_IRQHandler + .long USBD_IRQHandler + .long UARTE1_IRQHandler + .long QSPI_IRQHandler + .long CRYPTOCELL_IRQHandler + .long SPIM3_IRQHandler + .long 0 /*Reserved */ + .long PWM3_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + + .size __isr_vector, . - __isr_vector + +/* Reset Handler */ + + + .text + .thumb + .thumb_func + .align 1 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + + +/* Loop to copy data from read only memory to RAM. + * The ranges of copy from/to are specified by following symbols: + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to. + * __bss_start__: VMA of end of the section to copy to. Normally __data_end__ is used, but by using __bss_start__ + * the user can add their own initialized data section before BSS section with the INTERT AFTER command. + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__bss_start__ + + subs r3, r2 + ble .L_loop1_done + +.L_loop1: + subs r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .L_loop1 + +.L_loop1_done: + +/* This part of work usually is done in C library startup code. Otherwise, + * define __STARTUP_CLEAR_BSS to enable it in this startup. This section + * clears the RAM where BSS data is located. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * All addresses must be aligned to 4 bytes boundary. + */ +#ifdef __STARTUP_CLEAR_BSS + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 + + subs r2, r1 + ble .L_loop3_done + +.L_loop3: + subs r2, #4 + str r0, [r1, r2] + bgt .L_loop3 + +.L_loop3_done: +#endif /* __STARTUP_CLEAR_BSS */ + +/* Execute SystemInit function. */ + bl SystemInit + +/* Call _start function provided by libraries. + * If those libraries are not accessible, define __START as your entry point. + */ +#ifndef __START +#define __START _start +#endif + bl __START + + .pool + .size Reset_Handler,.-Reset_Handler + + .section ".text" + + +/* Dummy Exception Handlers (infinite loops which can be modified) */ + + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + b . + .size NMI_Handler, . - NMI_Handler + + + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + b . + .size HardFault_Handler, . - HardFault_Handler + + + .weak MemoryManagement_Handler + .type MemoryManagement_Handler, %function +MemoryManagement_Handler: + b . + .size MemoryManagement_Handler, . - MemoryManagement_Handler + + + .weak BusFault_Handler + .type BusFault_Handler, %function +BusFault_Handler: + b . + .size BusFault_Handler, . - BusFault_Handler + + + .weak UsageFault_Handler + .type UsageFault_Handler, %function +UsageFault_Handler: + b . + .size UsageFault_Handler, . - UsageFault_Handler + + + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + b . + .size SVC_Handler, . - SVC_Handler + + + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + b . + .size DebugMon_Handler, . - DebugMon_Handler + + + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + b . + .size PendSV_Handler, . - PendSV_Handler + + + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + b . + .size SysTick_Handler, . - SysTick_Handler + + +/* IRQ Handlers */ + + .globl Default_Handler + .type Default_Handler, %function +Default_Handler: + b . + .size Default_Handler, . - Default_Handler + + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + IRQ POWER_CLOCK_IRQHandler + IRQ RADIO_IRQHandler + IRQ UARTE0_UART0_IRQHandler + IRQ SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + IRQ SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + IRQ NFCT_IRQHandler + IRQ GPIOTE_IRQHandler + IRQ SAADC_IRQHandler + IRQ TIMER0_IRQHandler + IRQ TIMER1_IRQHandler + IRQ TIMER2_IRQHandler + IRQ RTC0_IRQHandler + IRQ TEMP_IRQHandler + IRQ RNG_IRQHandler + IRQ ECB_IRQHandler + IRQ CCM_AAR_IRQHandler + IRQ WDT_IRQHandler + IRQ RTC1_IRQHandler + IRQ QDEC_IRQHandler + IRQ COMP_LPCOMP_IRQHandler + IRQ SWI0_EGU0_IRQHandler + IRQ SWI1_EGU1_IRQHandler + IRQ SWI2_EGU2_IRQHandler + IRQ SWI3_EGU3_IRQHandler + IRQ SWI4_EGU4_IRQHandler + IRQ SWI5_EGU5_IRQHandler + IRQ TIMER3_IRQHandler + IRQ TIMER4_IRQHandler + IRQ PWM0_IRQHandler + IRQ PDM_IRQHandler + IRQ MWU_IRQHandler + IRQ PWM1_IRQHandler + IRQ PWM2_IRQHandler + IRQ SPIM2_SPIS2_SPI2_IRQHandler + IRQ RTC2_IRQHandler + IRQ I2S_IRQHandler + IRQ FPU_IRQHandler + IRQ USBD_IRQHandler + IRQ UARTE1_IRQHandler + IRQ QSPI_IRQHandler + IRQ CRYPTOCELL_IRQHandler + IRQ SPIM3_IRQHandler + IRQ PWM3_IRQHandler + + .end diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf51_common.ld b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf51_common.ld new file mode 100644 index 0000000000000000000000000000000000000000..e49ee3013ad5f76a6e552da81c0219a4f7d93ea5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf51_common.ld @@ -0,0 +1,161 @@ +/* Linker script for Nordic Semiconductor nRF51 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __HeapBase = .; + __end__ = .; + PROVIDE(end = .); + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf51_xxaa.ld b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf51_xxaa.ld new file mode 100644 index 0000000000000000000000000000000000000000..ab9a5d241c66bf7be6a9aafe45cb38cd8e0cc4e3 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf51_xxaa.ld @@ -0,0 +1,13 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x40000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x4000 +} + + +INCLUDE "nrf51_common.ld" diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf51_xxab.ld b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf51_xxab.ld new file mode 100644 index 0000000000000000000000000000000000000000..95804ae8a36259d87b8410be7126677bf4e50fb0 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf51_xxab.ld @@ -0,0 +1,13 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x20000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x4000 +} + + +INCLUDE "nrf51_common.ld" diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf51_xxac.ld b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf51_xxac.ld new file mode 100644 index 0000000000000000000000000000000000000000..d74fa441e89907dbb90618114cbd24e9d7579416 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf51_xxac.ld @@ -0,0 +1,13 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x40000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x8000 +} + + +INCLUDE "nrf51_common.ld" diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf52840_xxaa.ld b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf52840_xxaa.ld new file mode 100644 index 0000000000000000000000000000000000000000..24c4e131b6689ba5c813a57ee531937963f54395 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf52840_xxaa.ld @@ -0,0 +1,13 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 +} + + +INCLUDE "nrf52_common.ld" diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf52_common.ld b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf52_common.ld new file mode 100644 index 0000000000000000000000000000000000000000..013e0b47aa77c25ae9a8e3633dadd8193d635817 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf52_common.ld @@ -0,0 +1,161 @@ +/* Linker script for Nordic Semiconductor nRF52 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __HeapBase = .; + __end__ = .; + PROVIDE(end = .); + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf52_xxaa.ld b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf52_xxaa.ld new file mode 100644 index 0000000000000000000000000000000000000000..2ddbc8409aa49996f17fff6f5397a1b55d566cc4 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf52_xxaa.ld @@ -0,0 +1,13 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000 +} + + +INCLUDE "nrf52_common.ld" diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf5x_common.ld b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf5x_common.ld new file mode 100644 index 0000000000000000000000000000000000000000..e49ee3013ad5f76a6e552da81c0219a4f7d93ea5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/gcc/nrf5x_common.ld @@ -0,0 +1,161 @@ +/* Linker script for Nordic Semiconductor nRF51 devices + * + * Version: Sourcery G++ 4.5-1 + * Support: https://support.codesourcery.com/GNUToolchain/ + * + * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + */ +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __HeapBase = .; + __end__ = .; + PROVIDE(end = .); + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_nrf51_blank_xxaa.icf b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_nrf51_blank_xxaa.icf new file mode 100644 index 0000000000000000000000000000000000000000..a05fa11d01680fe6e6bff3ecef834df8b3cfa2de --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_nrf51_blank_xxaa.icf @@ -0,0 +1,31 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x800; +define symbol __ICFEDIT_size_heap__ = 0x800; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +keep { section .intvec }; +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, + block HEAP }; diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_nrf51_blank_xxac.icf b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_nrf51_blank_xxac.icf new file mode 100644 index 0000000000000000000000000000000000000000..ee54a3ce47fe070f140b23bea45aae9c06424b8f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_nrf51_blank_xxac.icf @@ -0,0 +1,31 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x800; +define symbol __ICFEDIT_size_heap__ = 0x800; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +keep { section .intvec }; +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, + block HEAP }; diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_startup_nrf51.s b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_startup_nrf51.s new file mode 100644 index 0000000000000000000000000000000000000000..95801311b449bbc5e8e76fe182f3eea8ebab17fd --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_startup_nrf51.s @@ -0,0 +1,311 @@ +; Copyright (c) 2009-2017 ARM Limited. All rights reserved. +; +; SPDX-License-Identifier: Apache-2.0 +; +; Licensed 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 +; +; 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. +; +; NOTICE: This file has been modified by Nordic Semiconductor ASA. + +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. + + MODULE ?cstartup + +#if defined(__STARTUP_CONFIG) + + #include "startup_config.h" + + #ifndef __STARTUP_CONFIG_STACK_ALIGNEMENT + #define __STARTUP_CONFIG_STACK_ALIGNEMENT 3 + #endif + + SECTION CSTACK:DATA:NOROOT(__STARTUP_CONFIG_STACK_ALIGNEMENT) + DS8 __STARTUP_CONFIG_STACK_SIZE + + SECTION HEAP:DATA:NOROOT(3) + DS8 __STARTUP_CONFIG_HEAP_SIZE + +#else + + ;; Stack size default : Defined in *.icf (linker file). Can be modified inside EW. + ;; Heap size default : Defined in *.icf (linker file). Can be modified inside EW. + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + +#endif + + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + DCD NMI_Handler + DCD HardFault_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD POWER_CLOCK_IRQHandler + DCD RADIO_IRQHandler + DCD UART0_IRQHandler + DCD SPI0_TWI0_IRQHandler + DCD SPI1_TWI1_IRQHandler + DCD 0 ; Reserved + DCD GPIOTE_IRQHandler + DCD ADC_IRQHandler + DCD TIMER0_IRQHandler + DCD TIMER1_IRQHandler + DCD TIMER2_IRQHandler + DCD RTC0_IRQHandler + DCD TEMP_IRQHandler + DCD RNG_IRQHandler + DCD ECB_IRQHandler + DCD CCM_AAR_IRQHandler + DCD WDT_IRQHandler + DCD RTC1_IRQHandler + DCD QDEC_IRQHandler + DCD LPCOMP_IRQHandler + DCD SWI0_IRQHandler + DCD SWI1_IRQHandler + DCD SWI2_IRQHandler + DCD SWI3_IRQHandler + DCD SWI4_IRQHandler + DCD SWI5_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + +__Vectors_End +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + +NRF_POWER_RAMON_ADDRESS EQU 0x40000524 ; NRF_POWER->RAMON address +NRF_POWER_RAMONB_ADDRESS EQU 0x40000554 ; NRF_POWER->RAMONB address +NRF_POWER_RAMONx_RAMxON_ONMODE_Msk EQU 0x3 ; All RAM blocks on in onmode bit mask + +; Default handlers. + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + MOVS R1, #NRF_POWER_RAMONx_RAMxON_ONMODE_Msk + + LDR R0, =NRF_POWER_RAMON_ADDRESS + LDR R2, [R0] + ORRS R2, R2, R1 + STR R2, [R0] + + LDR R0, =NRF_POWER_RAMONB_ADDRESS + LDR R2, [R0] + ORRS R2, R2, R1 + STR R2, [R0] + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + ; Dummy exception handlers + + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + + ; Dummy interrupt handlers + + PUBWEAK POWER_CLOCK_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +POWER_CLOCK_IRQHandler + B . + + PUBWEAK RADIO_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RADIO_IRQHandler + B . + + PUBWEAK UART0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +UART0_IRQHandler + B . + + PUBWEAK SPI0_TWI0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPI0_TWI0_IRQHandler + B . + + PUBWEAK SPI1_TWI1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPI1_TWI1_IRQHandler + B . + + PUBWEAK GPIOTE_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIOTE_IRQHandler + B . + + PUBWEAK ADC_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ADC_IRQHandler + B . + + PUBWEAK TIMER0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER0_IRQHandler + B . + + PUBWEAK TIMER1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER1_IRQHandler + B . + + PUBWEAK TIMER2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER2_IRQHandler + B . + + PUBWEAK RTC0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC0_IRQHandler + B . + + PUBWEAK TEMP_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TEMP_IRQHandler + B . + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RNG_IRQHandler + B . + + PUBWEAK ECB_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ECB_IRQHandler + B . + + PUBWEAK CCM_AAR_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +CCM_AAR_IRQHandler + B . + + PUBWEAK WDT_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +WDT_IRQHandler + B . + + PUBWEAK RTC1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC1_IRQHandler + B . + + PUBWEAK QDEC_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +QDEC_IRQHandler + B . + + PUBWEAK LPCOMP_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +LPCOMP_IRQHandler + B . + + PUBWEAK SWI0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI0_IRQHandler + B . + + PUBWEAK SWI1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI1_IRQHandler + B . + + PUBWEAK SWI2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI2_IRQHandler + B . + + PUBWEAK SWI3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI3_IRQHandler + B . + + PUBWEAK SWI4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI4_IRQHandler + B . + + PUBWEAK SWI5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI5_IRQHandler + B . + + + END + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_startup_nrf52.s b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_startup_nrf52.s new file mode 100644 index 0000000000000000000000000000000000000000..75d2ac57907698997f749702c73c143dc260a289 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_startup_nrf52.s @@ -0,0 +1,457 @@ +; Copyright (c) 2009-2017 ARM Limited. All rights reserved. +; +; SPDX-License-Identifier: Apache-2.0 +; +; Licensed 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 +; +; 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. +; +; NOTICE: This file has been modified by Nordic Semiconductor ASA. + +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. + + MODULE ?cstartup + +#if defined(__STARTUP_CONFIG) + + #include "startup_config.h" + + #ifndef __STARTUP_CONFIG_STACK_ALIGNEMENT + #define __STARTUP_CONFIG_STACK_ALIGNEMENT 3 + #endif + + SECTION CSTACK:DATA:NOROOT(__STARTUP_CONFIG_STACK_ALIGNEMENT) + DS8 __STARTUP_CONFIG_STACK_SIZE + + SECTION HEAP:DATA:NOROOT(3) + DS8 __STARTUP_CONFIG_HEAP_SIZE + +#else + + ;; Stack size default : Defined in *.icf (linker file). Can be modified inside EW. + ;; Heap size default : Defined in *.icf (linker file). Can be modified inside EW. + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + +#endif + + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + DCD NMI_Handler + DCD HardFault_Handler + DCD MemoryManagement_Handler + DCD BusFault_Handler + DCD UsageFault_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler + DCD DebugMon_Handler + DCD 0 ; Reserved + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD POWER_CLOCK_IRQHandler + DCD RADIO_IRQHandler + DCD UARTE0_UART0_IRQHandler + DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + DCD NFCT_IRQHandler + DCD GPIOTE_IRQHandler + DCD SAADC_IRQHandler + DCD TIMER0_IRQHandler + DCD TIMER1_IRQHandler + DCD TIMER2_IRQHandler + DCD RTC0_IRQHandler + DCD TEMP_IRQHandler + DCD RNG_IRQHandler + DCD ECB_IRQHandler + DCD CCM_AAR_IRQHandler + DCD WDT_IRQHandler + DCD RTC1_IRQHandler + DCD QDEC_IRQHandler + DCD COMP_LPCOMP_IRQHandler + DCD SWI0_EGU0_IRQHandler + DCD SWI1_EGU1_IRQHandler + DCD SWI2_EGU2_IRQHandler + DCD SWI3_EGU3_IRQHandler + DCD SWI4_EGU4_IRQHandler + DCD SWI5_EGU5_IRQHandler + DCD TIMER3_IRQHandler + DCD TIMER4_IRQHandler + DCD PWM0_IRQHandler + DCD PDM_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD MWU_IRQHandler + DCD PWM1_IRQHandler + DCD PWM2_IRQHandler + DCD SPIM2_SPIS2_SPI2_IRQHandler + DCD RTC2_IRQHandler + DCD I2S_IRQHandler + DCD FPU_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + +__Vectors_End +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +; Default handlers. + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + ; Dummy exception handlers + + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + PUBWEAK MemoryManagement_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +MemoryManagement_Handler + B . + + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +BusFault_Handler + B . + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +UsageFault_Handler + B . + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +DebugMon_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + + ; Dummy interrupt handlers + + PUBWEAK POWER_CLOCK_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +POWER_CLOCK_IRQHandler + B . + + PUBWEAK RADIO_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RADIO_IRQHandler + B . + + PUBWEAK UARTE0_UART0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +UARTE0_UART0_IRQHandler + B . + + PUBWEAK SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + B . + + PUBWEAK SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + B . + + PUBWEAK NFCT_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +NFCT_IRQHandler + B . + + PUBWEAK GPIOTE_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIOTE_IRQHandler + B . + + PUBWEAK SAADC_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SAADC_IRQHandler + B . + + PUBWEAK TIMER0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER0_IRQHandler + B . + + PUBWEAK TIMER1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER1_IRQHandler + B . + + PUBWEAK TIMER2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER2_IRQHandler + B . + + PUBWEAK RTC0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC0_IRQHandler + B . + + PUBWEAK TEMP_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TEMP_IRQHandler + B . + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RNG_IRQHandler + B . + + PUBWEAK ECB_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ECB_IRQHandler + B . + + PUBWEAK CCM_AAR_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +CCM_AAR_IRQHandler + B . + + PUBWEAK WDT_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +WDT_IRQHandler + B . + + PUBWEAK RTC1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC1_IRQHandler + B . + + PUBWEAK QDEC_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +QDEC_IRQHandler + B . + + PUBWEAK COMP_LPCOMP_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +COMP_LPCOMP_IRQHandler + B . + + PUBWEAK SWI0_EGU0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI0_EGU0_IRQHandler + B . + + PUBWEAK SWI1_EGU1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI1_EGU1_IRQHandler + B . + + PUBWEAK SWI2_EGU2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI2_EGU2_IRQHandler + B . + + PUBWEAK SWI3_EGU3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI3_EGU3_IRQHandler + B . + + PUBWEAK SWI4_EGU4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI4_EGU4_IRQHandler + B . + + PUBWEAK SWI5_EGU5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI5_EGU5_IRQHandler + B . + + PUBWEAK TIMER3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER3_IRQHandler + B . + + PUBWEAK TIMER4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER4_IRQHandler + B . + + PUBWEAK PWM0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PWM0_IRQHandler + B . + + PUBWEAK PDM_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PDM_IRQHandler + B . + + PUBWEAK MWU_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +MWU_IRQHandler + B . + + PUBWEAK PWM1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PWM1_IRQHandler + B . + + PUBWEAK PWM2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PWM2_IRQHandler + B . + + PUBWEAK SPIM2_SPIS2_SPI2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM2_SPIS2_SPI2_IRQHandler + B . + + PUBWEAK RTC2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC2_IRQHandler + B . + + PUBWEAK I2S_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +I2S_IRQHandler + B . + + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +FPU_IRQHandler + B . + + + END + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_startup_nrf52840.s b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_startup_nrf52840.s new file mode 100644 index 0000000000000000000000000000000000000000..2dbbd22387145835608458d3de180dec853a1ecb --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/iar/iar_startup_nrf52840.s @@ -0,0 +1,487 @@ +; Copyright (c) 2009-2017 ARM Limited. All rights reserved. +; +; SPDX-License-Identifier: Apache-2.0 +; +; Licensed 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 +; +; 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. +; +; NOTICE: This file has been modified by Nordic Semiconductor ASA. + +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. + + MODULE ?cstartup + +#if defined(__STARTUP_CONFIG) + + #include "startup_config.h" + + #ifndef __STARTUP_CONFIG_STACK_ALIGNEMENT + #define __STARTUP_CONFIG_STACK_ALIGNEMENT 3 + #endif + + SECTION CSTACK:DATA:NOROOT(__STARTUP_CONFIG_STACK_ALIGNEMENT) + DS8 __STARTUP_CONFIG_STACK_SIZE + + SECTION HEAP:DATA:NOROOT(3) + DS8 __STARTUP_CONFIG_HEAP_SIZE + +#else + + ;; Stack size default : Defined in *.icf (linker file). Can be modified inside EW. + ;; Heap size default : Defined in *.icf (linker file). Can be modified inside EW. + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + +#endif + + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + DCD NMI_Handler + DCD HardFault_Handler + DCD MemoryManagement_Handler + DCD BusFault_Handler + DCD UsageFault_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler + DCD DebugMon_Handler + DCD 0 ; Reserved + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD POWER_CLOCK_IRQHandler + DCD RADIO_IRQHandler + DCD UARTE0_UART0_IRQHandler + DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + DCD NFCT_IRQHandler + DCD GPIOTE_IRQHandler + DCD SAADC_IRQHandler + DCD TIMER0_IRQHandler + DCD TIMER1_IRQHandler + DCD TIMER2_IRQHandler + DCD RTC0_IRQHandler + DCD TEMP_IRQHandler + DCD RNG_IRQHandler + DCD ECB_IRQHandler + DCD CCM_AAR_IRQHandler + DCD WDT_IRQHandler + DCD RTC1_IRQHandler + DCD QDEC_IRQHandler + DCD COMP_LPCOMP_IRQHandler + DCD SWI0_EGU0_IRQHandler + DCD SWI1_EGU1_IRQHandler + DCD SWI2_EGU2_IRQHandler + DCD SWI3_EGU3_IRQHandler + DCD SWI4_EGU4_IRQHandler + DCD SWI5_EGU5_IRQHandler + DCD TIMER3_IRQHandler + DCD TIMER4_IRQHandler + DCD PWM0_IRQHandler + DCD PDM_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD MWU_IRQHandler + DCD PWM1_IRQHandler + DCD PWM2_IRQHandler + DCD SPIM2_SPIS2_SPI2_IRQHandler + DCD RTC2_IRQHandler + DCD I2S_IRQHandler + DCD FPU_IRQHandler + DCD USBD_IRQHandler + DCD UARTE1_IRQHandler + DCD QSPI_IRQHandler + DCD CRYPTOCELL_IRQHandler + DCD SPIM3_IRQHandler + DCD 0 ; Reserved + DCD PWM3_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + +__Vectors_End +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +; Default handlers. + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + ; Dummy exception handlers + + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + PUBWEAK MemoryManagement_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +MemoryManagement_Handler + B . + + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +BusFault_Handler + B . + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +UsageFault_Handler + B . + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +DebugMon_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + + ; Dummy interrupt handlers + + PUBWEAK POWER_CLOCK_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +POWER_CLOCK_IRQHandler + B . + + PUBWEAK RADIO_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RADIO_IRQHandler + B . + + PUBWEAK UARTE0_UART0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +UARTE0_UART0_IRQHandler + B . + + PUBWEAK SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + B . + + PUBWEAK SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + B . + + PUBWEAK NFCT_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +NFCT_IRQHandler + B . + + PUBWEAK GPIOTE_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIOTE_IRQHandler + B . + + PUBWEAK SAADC_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SAADC_IRQHandler + B . + + PUBWEAK TIMER0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER0_IRQHandler + B . + + PUBWEAK TIMER1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER1_IRQHandler + B . + + PUBWEAK TIMER2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER2_IRQHandler + B . + + PUBWEAK RTC0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC0_IRQHandler + B . + + PUBWEAK TEMP_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TEMP_IRQHandler + B . + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RNG_IRQHandler + B . + + PUBWEAK ECB_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ECB_IRQHandler + B . + + PUBWEAK CCM_AAR_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +CCM_AAR_IRQHandler + B . + + PUBWEAK WDT_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +WDT_IRQHandler + B . + + PUBWEAK RTC1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC1_IRQHandler + B . + + PUBWEAK QDEC_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +QDEC_IRQHandler + B . + + PUBWEAK COMP_LPCOMP_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +COMP_LPCOMP_IRQHandler + B . + + PUBWEAK SWI0_EGU0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI0_EGU0_IRQHandler + B . + + PUBWEAK SWI1_EGU1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI1_EGU1_IRQHandler + B . + + PUBWEAK SWI2_EGU2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI2_EGU2_IRQHandler + B . + + PUBWEAK SWI3_EGU3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI3_EGU3_IRQHandler + B . + + PUBWEAK SWI4_EGU4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI4_EGU4_IRQHandler + B . + + PUBWEAK SWI5_EGU5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI5_EGU5_IRQHandler + B . + + PUBWEAK TIMER3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER3_IRQHandler + B . + + PUBWEAK TIMER4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER4_IRQHandler + B . + + PUBWEAK PWM0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PWM0_IRQHandler + B . + + PUBWEAK PDM_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PDM_IRQHandler + B . + + PUBWEAK MWU_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +MWU_IRQHandler + B . + + PUBWEAK PWM1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PWM1_IRQHandler + B . + + PUBWEAK PWM2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PWM2_IRQHandler + B . + + PUBWEAK SPIM2_SPIS2_SPI2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM2_SPIS2_SPI2_IRQHandler + B . + + PUBWEAK RTC2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC2_IRQHandler + B . + + PUBWEAK I2S_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +I2S_IRQHandler + B . + + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +FPU_IRQHandler + B . + + PUBWEAK USBD_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +USBD_IRQHandler + B . + + PUBWEAK UARTE1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +UARTE1_IRQHandler + B . + + PUBWEAK QSPI_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +QSPI_IRQHandler + B . + + PUBWEAK CRYPTOCELL_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +CRYPTOCELL_IRQHandler + B . + + PUBWEAK SPIM3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM3_IRQHandler + B . + + PUBWEAK PWM3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PWM3_IRQHandler + B . + + + END + + diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf51.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf51.c new file mode 100644 index 0000000000000000000000000000000000000000..54f499c410cf0f9cb572515a10c0d5af218add6f --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf51.c @@ -0,0 +1,143 @@ +/* + +Copyright (c) 2009-2017 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed 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 + + 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. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + +/* NOTE: Template files (including this one) are application specific and therefore expected to + be copied into the application project folder prior to its use! */ + +#include +#include +#include "nrf.h" +#include "system_nrf51.h" + +/*lint ++flb "Enter library region" */ + + +#define __SYSTEM_CLOCK (16000000UL) /*!< nRF51 devices use a fixed System Clock Frequency of 16MHz */ + +static bool is_manual_peripheral_setup_needed(void); +static bool is_disabled_in_debug_needed(void); +static bool is_peripheral_domain_setup_needed(void); + + +#if defined ( __CC_ARM ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; +#elif defined ( __ICCARM__ ) + __root uint32_t SystemCoreClock = __SYSTEM_CLOCK; +#elif defined ( __GNUC__ ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; +#endif + +void SystemCoreClockUpdate(void) +{ + SystemCoreClock = __SYSTEM_CLOCK; +} + +void SystemInit(void) +{ + /* If desired, switch off the unused RAM to lower consumption by the use of RAMON register. + It can also be done in the application main() function. */ + + /* Prepare the peripherals for use as indicated by the PAN 26 "System: Manual setup is required + to enable the use of peripherals" found at Product Anomaly document for your device found at + https://www.nordicsemi.com/. The side effect of executing these instructions in the devices + that do not need it is that the new peripherals in the second generation devices (LPCOMP for + example) will not be available. */ + if (is_manual_peripheral_setup_needed()) + { + *(uint32_t volatile *)0x40000504 = 0xC007FFDF; + *(uint32_t volatile *)0x40006C18 = 0x00008000; + } + + /* Disable PROTENSET registers under debug, as indicated by PAN 59 "MPU: Reset value of DISABLEINDEBUG + register is incorrect" found at Product Anomaly document for your device found at + https://www.nordicsemi.com/. There is no side effect of using these instruction if not needed. */ + if (is_disabled_in_debug_needed()) + { + NRF_MPU->DISABLEINDEBUG = MPU_DISABLEINDEBUG_DISABLEINDEBUG_Disabled << MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos; + } + + /* Execute the following code to eliminate excessive current in sleep mode with RAM retention in nRF51802 devices, + as indicated by PAN 76 "System: Excessive current in sleep mode with retention" found at Product Anomaly document + for your device found at https://www.nordicsemi.com/. */ + if (is_peripheral_domain_setup_needed()){ + if (*(uint32_t volatile *)0x4006EC00 != 1){ + *(uint32_t volatile *)0x4006EC00 = 0x9375; + while (*(uint32_t volatile *)0x4006EC00 != 1){ + } + } + *(uint32_t volatile *)0x4006EC14 = 0xC0; + } +} + + +static bool is_manual_peripheral_setup_needed(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) + { + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x00) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x10) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + } + + return false; +} + +static bool is_disabled_in_debug_needed(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) + { + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + } + + return false; +} + +static bool is_peripheral_domain_setup_needed(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) + { + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0xA0) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0xD0) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + } + + return false; +} + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf51.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf51.h new file mode 100644 index 0000000000000000000000000000000000000000..d999723323eb185f5e056265b0dfb7f87f6385db --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf51.h @@ -0,0 +1,61 @@ +/* + +Copyright (c) 2009-2017 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed 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 + + 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. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + +#ifndef SYSTEM_NRF51_H +#define SYSTEM_NRF51_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_NRF51_H */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf52.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf52.c new file mode 100644 index 0000000000000000000000000000000000000000..116edad1b9f4998acc722f511291b4d04baae198 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf52.c @@ -0,0 +1,327 @@ +/* + +Copyright (c) 2009-2017 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed 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 + + 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. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + +/* NOTE: Template files (including this one) are application specific and therefore expected to + be copied into the application project folder prior to its use! */ + +#include +#include +#include "nrf.h" +#include "system_nrf52.h" + +/*lint ++flb "Enter library region" */ + +#define __SYSTEM_CLOCK_64M (64000000UL) + +static bool errata_12(void); +static bool errata_16(void); +static bool errata_31(void); +static bool errata_32(void); +static bool errata_36(void); +static bool errata_37(void); +static bool errata_57(void); +static bool errata_66(void); +static bool errata_108(void); + + +#if defined ( __CC_ARM ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; +#elif defined ( __ICCARM__ ) + __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M; +#elif defined ( __GNUC__ ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; +#endif + +void SystemCoreClockUpdate(void) +{ + SystemCoreClock = __SYSTEM_CLOCK_64M; +} + +void SystemInit(void) +{ + /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product + Specification to see which one). */ + #if defined (ENABLE_SWO) + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos; + NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + #endif + + /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product + Specification to see which ones). */ + #if defined (ENABLE_TRACE) + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos; + NRF_P0->PIN_CNF[14] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P0->PIN_CNF[15] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P0->PIN_CNF[16] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P0->PIN_CNF[20] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + #endif + + /* Workaround for Errata 12 "COMP: Reference ladder not correctly callibrated" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_12()){ + *(volatile uint32_t *)0x40013540 = (*(uint32_t *)0x10000324 & 0x00001F00) >> 8; + } + + /* Workaround for Errata 16 "System: RAM may be corrupt on wakeup from CPU IDLE" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_16()){ + *(volatile uint32_t *)0x4007C074 = 3131961357ul; + } + + /* Workaround for Errata 31 "CLOCK: Calibration values are not correctly loaded from FICR at reset" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_31()){ + *(volatile uint32_t *)0x4000053C = ((*(volatile uint32_t *)0x10000244) & 0x0000E000) >> 13; + } + + /* Workaround for Errata 32 "DIF: Debug session automatically enables TracePort pins" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_32()){ + CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; + } + + /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_36()){ + NRF_CLOCK->EVENTS_DONE = 0; + NRF_CLOCK->EVENTS_CTTO = 0; + NRF_CLOCK->CTIV = 0; + } + + /* Workaround for Errata 37 "RADIO: Encryption engine is slow by default" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_37()){ + *(volatile uint32_t *)0x400005A0 = 0x3; + } + + /* Workaround for Errata 57 "NFCT: NFC Modulation amplitude" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_57()){ + *(volatile uint32_t *)0x40005610 = 0x00000005; + *(volatile uint32_t *)0x40005688 = 0x00000001; + *(volatile uint32_t *)0x40005618 = 0x00000000; + *(volatile uint32_t *)0x40005614 = 0x0000003F; + } + + /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_66()){ + NRF_TEMP->A0 = NRF_FICR->TEMP.A0; + NRF_TEMP->A1 = NRF_FICR->TEMP.A1; + NRF_TEMP->A2 = NRF_FICR->TEMP.A2; + NRF_TEMP->A3 = NRF_FICR->TEMP.A3; + NRF_TEMP->A4 = NRF_FICR->TEMP.A4; + NRF_TEMP->A5 = NRF_FICR->TEMP.A5; + NRF_TEMP->B0 = NRF_FICR->TEMP.B0; + NRF_TEMP->B1 = NRF_FICR->TEMP.B1; + NRF_TEMP->B2 = NRF_FICR->TEMP.B2; + NRF_TEMP->B3 = NRF_FICR->TEMP.B3; + NRF_TEMP->B4 = NRF_FICR->TEMP.B4; + NRF_TEMP->B5 = NRF_FICR->TEMP.B5; + NRF_TEMP->T0 = NRF_FICR->TEMP.T0; + NRF_TEMP->T1 = NRF_FICR->TEMP.T1; + NRF_TEMP->T2 = NRF_FICR->TEMP.T2; + NRF_TEMP->T3 = NRF_FICR->TEMP.T3; + NRF_TEMP->T4 = NRF_FICR->TEMP.T4; + } + + /* Workaround for Errata 108 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_108()){ + *(volatile uint32_t *)0x40000EE4 = *(volatile uint32_t *)0x10000258 & 0x0000004F; + } + + /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the + * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit + * operations are not used in your code. */ + #if (__FPU_USED == 1) + SCB->CPACR |= (3UL << 20) | (3UL << 22); + __DSB(); + __ISB(); + #endif + + /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined, + two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as + normal GPIOs. */ + #if defined (CONFIG_NFCT_PINS_AS_GPIOS) + if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){ + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NVIC_SystemReset(); + } + #endif + + /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not + defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be + reserved for PinReset and not available as normal GPIO. */ + #if defined (CONFIG_GPIO_AS_PINRESET) + if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) || + ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){ + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->PSELRESET[0] = 21; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->PSELRESET[1] = 21; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NVIC_SystemReset(); + } + #endif + + SystemCoreClockUpdate(); +} + + +static bool errata_12(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ + return true; + } + } + + return false; +} + +static bool errata_16(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + } + + return false; +} + +static bool errata_31(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ + return true; + } + } + + return false; +} + +static bool errata_32(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + } + + return false; +} + +static bool errata_36(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ + return true; + } + } + + return false; +} + +static bool errata_37(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + } + + return false; +} + +static bool errata_57(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + } + + return false; +} + +static bool errata_66(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ + return true; + } + } + + return false; +} + + +static bool errata_108(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ + return true; + } + } + + return false; +} + + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf52.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf52.h new file mode 100644 index 0000000000000000000000000000000000000000..ee9f40ef66c618f23b680d5448f4dfc431d524d5 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf52.h @@ -0,0 +1,61 @@ +/* + +Copyright (c) 2009-2017 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed 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 + + 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. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + +#ifndef SYSTEM_NRF52_H +#define SYSTEM_NRF52_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_NRF52_H */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf52840.c b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf52840.c new file mode 100644 index 0000000000000000000000000000000000000000..8958b1ddc5fadce4d8ba921b0a35ca39ac4c9813 --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf52840.c @@ -0,0 +1,237 @@ +/* + +Copyright (c) 2009-2017 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed 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 + + 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. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + +/* NOTE: Template files (including this one) are application specific and therefore expected to + be copied into the application project folder prior to its use! */ + +#include +#include +#include "nrf.h" +#include "system_nrf52840.h" + +/*lint ++flb "Enter library region" */ + +#define __SYSTEM_CLOCK_64M (64000000UL) + +static bool errata_36(void); +static bool errata_66(void); +static bool errata_98(void); +static bool errata_103(void); +static bool errata_115(void); +static bool errata_120(void); + + +#if defined ( __CC_ARM ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; +#elif defined ( __ICCARM__ ) + __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M; +#elif defined ( __GNUC__ ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; +#endif + +void SystemCoreClockUpdate(void) +{ + SystemCoreClock = __SYSTEM_CLOCK_64M; +} + +void SystemInit(void) +{ + /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product + Specification to see which one). */ + #if defined (ENABLE_SWO) + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos; + NRF_P1->PIN_CNF[0] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + #endif + + /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product + Specification to see which ones). */ + #if defined (ENABLE_TRACE) + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos; + NRF_P0->PIN_CNF[7] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P1->PIN_CNF[0] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P0->PIN_CNF[12] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P0->PIN_CNF[11] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P1->PIN_CNF[9] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + #endif + + /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_36()){ + NRF_CLOCK->EVENTS_DONE = 0; + NRF_CLOCK->EVENTS_CTTO = 0; + NRF_CLOCK->CTIV = 0; + } + + /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_66()){ + NRF_TEMP->A0 = NRF_FICR->TEMP.A0; + NRF_TEMP->A1 = NRF_FICR->TEMP.A1; + NRF_TEMP->A2 = NRF_FICR->TEMP.A2; + NRF_TEMP->A3 = NRF_FICR->TEMP.A3; + NRF_TEMP->A4 = NRF_FICR->TEMP.A4; + NRF_TEMP->A5 = NRF_FICR->TEMP.A5; + NRF_TEMP->B0 = NRF_FICR->TEMP.B0; + NRF_TEMP->B1 = NRF_FICR->TEMP.B1; + NRF_TEMP->B2 = NRF_FICR->TEMP.B2; + NRF_TEMP->B3 = NRF_FICR->TEMP.B3; + NRF_TEMP->B4 = NRF_FICR->TEMP.B4; + NRF_TEMP->B5 = NRF_FICR->TEMP.B5; + NRF_TEMP->T0 = NRF_FICR->TEMP.T0; + NRF_TEMP->T1 = NRF_FICR->TEMP.T1; + NRF_TEMP->T2 = NRF_FICR->TEMP.T2; + NRF_TEMP->T3 = NRF_FICR->TEMP.T3; + NRF_TEMP->T4 = NRF_FICR->TEMP.T4; + } + + /* Workaround for Errata 98 "NFCT: Not able to communicate with the peer" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_98()){ + *(volatile uint32_t *)0x4000568Cul = 0x00038148ul; + } + + /* Workaround for Errata 103 "CCM: Wrong reset value of CCM MAXPACKETSIZE" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_103()){ + NRF_CCM->MAXPACKETSIZE = 0xFBul; + } + + /* Workaround for Errata 115 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_115()){ + *(volatile uint32_t *)0x40000EE4 = (*(volatile uint32_t *)0x40000EE4 & 0xFFFFFFF0) | (*(uint32_t *)0x10000258 & 0x0000000F); + } + + /* Workaround for Errata 120 "QSPI: Data read or written is corrupted" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_120()){ + *(volatile uint32_t *)0x40029640ul = 0x200ul; + } + + /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the + * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit + * operations are not used in your code. */ + #if (__FPU_USED == 1) + SCB->CPACR |= (3UL << 20) | (3UL << 22); + __DSB(); + __ISB(); + #endif + + /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined, + two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as + normal GPIOs. */ + #if defined (CONFIG_NFCT_PINS_AS_GPIOS) + if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){ + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NVIC_SystemReset(); + } + #endif + + /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not + defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be + reserved for PinReset and not available as normal GPIO. */ + #if defined (CONFIG_GPIO_AS_PINRESET) + if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) || + ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){ + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->PSELRESET[0] = 18; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->PSELRESET[1] = 18; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NVIC_SystemReset(); + } + #endif + + SystemCoreClockUpdate(); +} + + +static bool errata_36(void) +{ + if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ + return true; + } + + return false; +} + + +static bool errata_66(void) +{ + if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ + return true; + } + + return false; +} + + +static bool errata_98(void) +{ + if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ + return true; + } + + return false; +} + + +static bool errata_103(void) +{ + if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ + return true; + } + + return false; +} + + +static bool errata_115(void) +{ + if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ + return true; + } + + return false; +} + + +static bool errata_120(void) +{ + if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ + return true; + } + + return false; +} + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf52840.h b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf52840.h new file mode 100644 index 0000000000000000000000000000000000000000..5a1e794962dedb4d8b01defbad26d3ac6d73abdf --- /dev/null +++ b/bsp/nrf52832/nRF5_SDK_13.0.0_04a0bfd/components/toolchain/system_nrf52840.h @@ -0,0 +1,61 @@ +/* + +Copyright (c) 2009-2017 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed 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 + + 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. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + +#ifndef SYSTEM_NRF52840_H +#define SYSTEM_NRF52840_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_NRF52840_H */ diff --git a/bsp/nrf52832/project.uvguix.lx b/bsp/nrf52832/project.uvguix.lx deleted file mode 100644 index 0b23e79810a618485dbc34e2b97593d11267a9a3..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/project.uvguix.lx +++ /dev/null @@ -1,2655 +0,0 @@ - - - - -5.1 - -
### uVision Project, (C) Keil Software
- - - - - - 38003 - Registers - 115 195 - - - 346 - Code Coverage - 1410 160 - - - 204 - Performance Analyzer - 1570 - - - - - - 1506 - Symbols - - 106 106 106 - - - 1936 - Watch 1 - - 106 106 106 - - - 1937 - Watch 2 - - 106 106 106 - - - 1935 - Call Stack + Locals - - 106 106 106 - - - 2506 - Trace Data - - 75 135 130 95 70 230 200 150 - - - - - - 0 - 0 - 0 - 50 - 16 - - - - - - - 44 - 0 - 1 - - -32000 - -32000 - - - -1 - -1 - - - 245 - 332 - 2125 - 1356 - - - - 0 - - 738 - 01000000040000000100000001000000010000000100000000000000020000000000000001000000010000000000000028000000280000000100000007000000060000000100000033463A5C776F726B73706163655C72742D7468726561645C6273705C6E726635323833325C647269766572735C626F6172642E630000000007626F6172642E6300000000F7B88600FFFFFFFF56463A5C776F726B73706163655C72742D7468726561645C6273705C6E726635323833325C4C69627261726965735C6E726635323833325C536F757263655C74656D706C617465735C73797374656D5F6E726635322E63000000000E73797374656D5F6E726635322E63000000009CC1B600FFFFFFFF3E463A5C776F726B73706163655C72742D7468726561645C6273705C6E726635323833325C6170706C69636174696F6E735C6170706C69636174696F6E2E63000000000D6170706C69636174696F6E2E6300000000BCA8E100FFFFFFFF32463A5C776F726B73706163655C72742D7468726561645C6273705C6E726635323833325C647269766572735C756172742E630000000006756172742E6300000000F0A0A100FFFFFFFF32463A5C776F726B73706163655C72742D7468726561645C6273705C6E726635323833325C647269766572735C756172742E680000000006756172742E6800000000BECEA100FFFFFFFF21463A5C776F726B73706163655C72742D7468726561645C7372635C69646C652E63000000000669646C652E6300000000FFDC7800FFFFFFFF2E463A5C776F726B73706163655C72742D7468726561645C6273705C6E726635323833325C7274636F6E6669672E68000000000A7274636F6E6669672E6800000000D9ADC200FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD50001000000000000000200000098020000630100004508000066040000 - - - - 0 - Build - - -1 - -1 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 440100004F0000007007000016010000 - - - 16 - 450200007A0100007108000041020000 - - - - 1005 - 1005 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000660000003D01000039030000 - - - 16 - 260100003D0100006602000052020000 - - - - 109 - 109 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000660000003D01000039030000 - - - 16 - 260100003D010000A20200005C040000 - - - - 1465 - 1465 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D010000DE04000004020000 - - - - 1466 - 1466 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D010000DE04000004020000 - - - - 1467 - 1467 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D010000DE04000004020000 - - - - 1468 - 1468 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D010000DE04000004020000 - - - - 1506 - 1506 - 0 - 0 - 0 - 0 - 32767 - 0 - 16384 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 1913 - 1913 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 47010000660000006D070000FD000000 - - - 16 - 260100003D010000DE04000004020000 - - - - 1935 - 1935 - 0 - 0 - 0 - 0 - 32767 - 0 - 32768 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D0100006602000052020000 - - - - 1936 - 1936 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D0100006602000052020000 - - - - 1937 - 1937 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D0100006602000052020000 - - - - 1939 - 1939 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D010000DE04000004020000 - - - - 1940 - 1940 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D010000DE04000004020000 - - - - 1941 - 1941 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D010000DE04000004020000 - - - - 1942 - 1942 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D010000DE04000004020000 - - - - 195 - 195 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000660000003D01000039030000 - - - 16 - 260100003D010000A20200005C040000 - - - - 196 - 196 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000660000003D01000039030000 - - - 16 - 260100003D010000A20200005C040000 - - - - 197 - 197 - 1 - 0 - 0 - 0 - 32767 - 0 - 32768 - 0 - - 16 - 000000006A030000F10600001D040000 - - - 16 - 260100003D010000DE04000004020000 - - - - 198 - 198 - 0 - 0 - 0 - 0 - 32767 - 0 - 32768 - 0 - - 16 - 00000000F802000070070000D3030000 - - - 16 - 260100003D010000DE04000004020000 - - - - 199 - 199 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000006D030000EE06000004040000 - - - 16 - 260100003D010000DE04000004020000 - - - - 203 - 203 - 0 - 0 - 0 - 0 - 32767 - 0 - 8192 - 0 - - 16 - 47010000660000006D070000FD000000 - - - 16 - 260100003D010000DE04000004020000 - - - - 204 - 204 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 47010000660000006D070000FD000000 - - - 16 - 260100003D010000DE04000004020000 - - - - 221 - 221 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 00000000000000000000000000000000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 2506 - 2506 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 2507 - 2507 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D010000DE04000004020000 - - - - 343 - 343 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 47010000660000006D070000FD000000 - - - 16 - 260100003D010000DE04000004020000 - - - - 346 - 346 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 47010000660000006D070000FD000000 - - - 16 - 260100003D010000DE04000004020000 - - - - 35824 - 35824 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 47010000660000006D070000FD000000 - - - 16 - 260100003D010000DE04000004020000 - - - - 35885 - 35885 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35886 - 35886 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35887 - 35887 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35888 - 35888 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35889 - 35889 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35890 - 35890 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35891 - 35891 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35892 - 35892 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35893 - 35893 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35894 - 35894 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35895 - 35895 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35896 - 35896 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35897 - 35897 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35898 - 35898 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35899 - 35899 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35900 - 35900 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35901 - 35901 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35902 - 35902 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35903 - 35903 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35904 - 35904 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 35905 - 35905 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 260100003D0100006602000052020000 - - - - 38003 - 38003 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000660000003D01000039030000 - - - 16 - 260100003D010000A20200005C040000 - - - - 38007 - 38007 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000006D030000EE06000004040000 - - - 16 - 260100003D010000DE04000004020000 - - - - 436 - 436 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000006D030000EE06000004040000 - - - 16 - 260100003D010000A20200005C040000 - - - - 437 - 437 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D0100006602000052020000 - - - - 440 - 440 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 030000000F0300006D070000BA030000 - - - 16 - 260100003D0100006602000052020000 - - - - 59392 - 59392 - 1 - 0 - 0 - 0 - 940 - 0 - 8192 - 0 - - 16 - 0000000000000000B70300001C000000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 59393 - 0 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 000000001D040000F106000030040000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 59399 - 59399 - 1 - 0 - 0 - 0 - 463 - 0 - 8192 - 1 - - 16 - 000000001C000000DA01000038000000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 59400 - 59400 - 0 - 0 - 0 - 0 - 612 - 0 - 8192 - 2 - - 16 - 00000000380000006F02000054000000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 2619 - 000000000B000000000000000020000000000000FFFFFFFFFFFFFFFF4401000016010000700700001A010000000000000100000004000000010000000000000000000000FFFFFFFF06000000CB00000057010000CC000000F08B00005A01000079070000FFFF02000B004354616262656450616E650020000000000000450200007A0100007108000041020000440100004F00000070070000160100000000000040280046060000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFF2C0600004F0000003006000008030000000000000200000004000000010000000000000000000000FFFFFFFF17000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000001800040000000000000310700007A0100007108000033040000300600004F00000070070000080300000000000040410046170000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFF400100004F0000004401000052030000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C40000007394000001800010000001000000010100007A010000410200007D040000000000004F00000040010000520300000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF00000000F402000070070000F802000000000000010000000400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0E0000008F070000930700009407000095070000960700009007000091070000B5010000B8010000B9050000BA050000BB050000BC050000CB09000001800080000000000000010100002304000071080000FE04000000000000F802000070070000D303000000000000404100460E0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFB8030000F8020000BC030000D303000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000001000000FFFFFFFFFFFFFFFF0000000052030000F106000056030000010000000100001004000000010000000000000000000000FFFFFFFF04000000C5000000C7000000B401000077940000018000800000010000000101000081040000F2070000480500000000000056030000F10600001D0400000000000040820056040000000C4275696C64204F757470757401000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000 - - - 59392 - File - - 2390 - 00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE803000000000000000000000000000000000000000000000001000000010000009600000002002050000000000D4750494F5F4F55545055545F31960000000000000013000D4750494F5F4F55545055545F31094253505F4C45445F3009705F69635F696E666F1273645F626C655F757569645F76735F6164641B626C655F6C62735F6C65645F77726974655F68616E646C65725F74254750494F54455F434F4E4649475F4E554D5F4F465F4C4F575F504F5745525F4556454E5453154150505F4952515F5052494F524954595F484947480A6D616E75665F646174610F626C655F616476646174615F7365740E75756964735F636F6D706C6574650D626C655F616476646174615F74146E72665F6472765F7477695F636F6E6669675F74066F6363757273106D5F6465766963655F61646472657373076D61696E5F49440C7469645F626C696E6B4C4544094552524F525F50494E044857464314454E41424C455F4C4F4F504241434B5F5445535400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000020000001500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000400160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000000180C8880000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E4C010000020001001A0000000F2650726F6A6563742057696E646F77000000000000000000000000010000000100000000000000000000000100000008002880DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002880DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002880E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002880E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000288018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000028800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002880D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002880E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65AC030000 - - - 1423 - 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000FFFFFFFF000100000000000000010000000000000001000000018001E1000000000000FFFFFFFF000100000000000000010000000000000001000000018003E1000000000000FFFFFFFF0001000000000000000100000000000000010000000180CD7F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF000000000000000000010000000000000001000000018023E1000000000000FFFFFFFF000100000000000000010000000000000001000000018022E1000000000000FFFFFFFF000100000000000000010000000000000001000000018025E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802BE1000000000000FFFFFFFF00010000000000000001000000000000000100000001802CE1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001807A8A000000000000FFFFFFFF00010000000000000001000000000000000100000001807B8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180D3B0000000000000FFFFFFFF000100000000000000010000000000000001000000018015B1000000000000FFFFFFFF0001000000000000000100000000000000010000000180F4B0000000000000FFFFFFFF000100000000000000010000000000000001000000018036B1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FF88000000000000FFFFFFFF0001000000000000000100000000000000010000000180FE88000000000000FFFFFFFF00010000000000000001000000000000000100000001800B81000000000000FFFFFFFF00010000000000000001000000000000000100000001800C81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180F088000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE7F000000000000FFFFFFFF000100000000000000010000000000000001000000018024E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800A81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802280000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C488000000000000FFFFFFFF0001000000000000000100000000000000010000000180C988000000000000FFFFFFFF0001000000000000000100000000000000010000000180C788000000000000FFFFFFFF0001000000000000000100000000000000010000000180C888000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180DD88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FB7F000000000000FFFFFFFF000100000000000000010000000000000001000000 - - - 1423 - 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000000000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000000000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000000000C0000000000000000000000000000000001000000010000000180F4B00000000000000D000000000000000000000000000000000100000001000000018036B10000000000000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF880000000000000F0000000000000000000000000000000001000000010000000180FE880000000000001000000000000000000000000000000000010000000100000001800B810000000000001100000000000000000000000000000000010000000100000001800C810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F088000000000000130000000000000000000000000000000001000000010000000180EE7F00000000000014000000000000000000000000000000000100000001000000018024E10000000000001500000000000000000000000000000000010000000100000001800A810000000000001600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000180000000000000000000000000000000001000000010000000180C988000000000000190000000000000000000000000000000001000000010000000180C7880000000000001A0000000000000000000000000000000001000000010000000180C8880000000000001B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180DD880000000000001C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001D000000000000000000000000000000000100000001000000 - - - - 59399 - Build - - 680 - 00200000010000001000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000004001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E00000000000000000000000000000000010000000100000001809E8A0000000000001F0000000000000000000000000000000001000000010000000180D17F0000000004002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA00000000000000000000000000000000000000000000000001000000010000009600000003002050000000000972742D746872656164960000000000000001000972742D746872656164000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000400240000000000000000000000000000000001000000010000000180A8010000000000004E00000000000000000000000000000000010000000100000001807202000000000000530000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C64CF010000 - - - 583 - 1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000FFFFFFFF0001000000000000000100000000000000010000000180D07F000000000000FFFFFFFF00010000000000000001000000000000000100000001803080000000000000FFFFFFFF00010000000000000001000000000000000100000001809E8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D17F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001804C8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001806680000000000000FFFFFFFF0001000000000000000100000000000000010000000180EB88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180B08A000000000000FFFFFFFF0001000000000000000100000000000000010000000180A801000000000000FFFFFFFF00010000000000000001000000000000000100000001807202000000000000FFFFFFFF0001000000000000000100000000000000010000000180BE01000000000000FFFFFFFF000100000000000000010000000000000001000000 - - - 583 - 1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000000000000000000000000000000000000001000000010000000180D07F00000000000001000000000000000000000000000000000100000001000000018030800000000000000200000000000000000000000000000000010000000100000001809E8A000000000000030000000000000000000000000000000001000000010000000180D17F0000000000000400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000000500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001806680000000000000060000000000000000000000000000000001000000010000000180EB880000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000080000000000000000000000000000000001000000010000000180B08A000000000000090000000000000000000000000000000001000000010000000180A8010000000000000A000000000000000000000000000000000100000001000000018072020000000000000B0000000000000000000000000000000001000000010000000180BE010000000000000C000000000000000000000000000000000100000001000000 - - - - 59400 - Debug - - 2247 - 00200000000000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000000002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000000000002D0000000000000000000000000000000001000000010000000180F07F0000000000002E0000000000000000000000000000000001000000010000000180E8880000000000003700000000000000000000000000000000010000000100000001803B010000000000002F0000000000000000000000000000000001000000010000000180BB8A00000000000030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000000000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000002001380D88B00000000000031000000085761746368202631000000000000000000000000010000000100000000000000000000000100000000001380D98B000000000000310000000857617463682026320000000000000000000000000100000001000000000000000000000001000000000013800F01000000000000320000000E4D656D6F72792057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000094D656D6F7279202631000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000094D656D6F7279202632000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000094D656D6F7279202633000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000094D656D6F72792026340000000000000000000000000100000001000000000000000000000001000000000013801001000000000000330000000E53657269616C2057696E646F777300000000000000000000000001000000010000000000000000000000010000000400138093070000000000003300000008554152542023263100000000000000000000000001000000010000000000000000000000010000000000138094070000000000003300000008554152542023263200000000000000000000000001000000010000000000000000000000010000000000138095070000000000003300000008554152542023263300000000000000000000000001000000010000000000000000000000010000000000138096070000000000003300000015446562756720287072696E746629205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000000000003400000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380658A000000000000340000000F264C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E0000001526506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000E26436F646520436F76657261676500000000000000000000000001000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720000000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720000000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000013800189000000000000360000000F26546F6F6C626F782057696E646F7700000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730000000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72000000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000 - - - 898 - 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801780000000000000FFFFFFFF00010000000000000001000000000000000100000001801D80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801A80000000000000FFFFFFFF00010000000000000001000000000000000100000001801B80000000000000FFFFFFFF0001000000000000000100000000000000010000000180E57F000000000000FFFFFFFF00010000000000000001000000000000000100000001801C80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800089000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180E48B000000000000FFFFFFFF0001000000000000000100000000000000010000000180F07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180E888000000000000FFFFFFFF00010000000000000001000000000000000100000001803B01000000000000FFFFFFFF0001000000000000000100000000000000010000000180BB8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D88B000000000000FFFFFFFF0001000000000000000100000000000000010000000180D28B000000000000FFFFFFFF00010000000000000001000000000000000100000001809307000000000000FFFFFFFF0001000000000000000100000000000000010000000180658A000000000000FFFFFFFF0001000000000000000100000000000000010000000180C18A000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE8B000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800189000000000000FFFFFFFF000100000000000000010000000000000001000000 - - - 898 - 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000000000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000000100000000000000000000000000000000010000000100000001801D800000000000000200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000000300000000000000000000000000000000010000000100000001801B80000000000000040000000000000000000000000000000001000000010000000180E57F0000000000000500000000000000000000000000000000010000000100000001801C800000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B000000000000080000000000000000000000000000000001000000010000000180F07F000000000000090000000000000000000000000000000001000000010000000180E8880000000000000A00000000000000000000000000000000010000000100000001803B010000000000000B0000000000000000000000000000000001000000010000000180BB8A0000000000000C0000000000000000000000000000000001000000010000000180D88B0000000000000D0000000000000000000000000000000001000000010000000180D28B0000000000000E000000000000000000000000000000000100000001000000018093070000000000000F0000000000000000000000000000000001000000010000000180658A000000000000100000000000000000000000000000000001000000010000000180C18A000000000000110000000000000000000000000000000001000000010000000180EE8B0000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180018900000000000013000000000000000000000000000000000100000001000000 - - - - 0 - 2560 - 1440 - - - - 1 - Debug - - -1 - -1 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 440100004F000000F106000016010000 - - - 16 - B403000065010000E00900002C020000 - - - - 1005 - 1005 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000660000003D01000025030000 - - - 16 - 560000006D0000009601000082010000 - - - - 109 - 109 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000660000003D010000DB020000 - - - 16 - 560000006D000000D20100008C030000 - - - - 1465 - 1465 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 8003000059030000EE06000004040000 - - - 16 - 560000006D0000000E04000034010000 - - - - 1466 - 1466 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 80030000590300002E07000004040000 - - - 16 - 560000006D0000000E04000034010000 - - - - 1467 - 1467 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 80030000590300002E07000004040000 - - - 16 - 560000006D0000000E04000034010000 - - - - 1468 - 1468 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 80030000590300002E07000004040000 - - - 16 - 560000006D0000000E04000034010000 - - - - 1506 - 1506 - 0 - 0 - 0 - 0 - 32767 - 0 - 16384 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 1913 - 1913 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 47010000660000006D070000FD000000 - - - 16 - 560000006D0000000E04000034010000 - - - - 1935 - 1935 - 1 - 0 - 0 - 0 - 32767 - 0 - 32768 - 0 - - 16 - 8003000059030000EE06000004040000 - - - 16 - 560000006D0000009601000082010000 - - - - 1936 - 1936 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 80030000590300002E07000004040000 - - - 16 - 560000006D0000009601000082010000 - - - - 1937 - 1937 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 80030000590300002E07000004040000 - - - 16 - 560000006D0000009601000082010000 - - - - 1939 - 1939 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 80030000590300002E07000004040000 - - - 16 - 560000006D0000000E04000034010000 - - - - 1940 - 1940 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 80030000590300002E07000004040000 - - - 16 - 560000006D0000000E04000034010000 - - - - 1941 - 1941 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 80030000590300002E07000004040000 - - - 16 - 560000006D0000000E04000034010000 - - - - 1942 - 1942 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 80030000590300002E07000004040000 - - - 16 - 560000006D0000000E04000034010000 - - - - 195 - 195 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000660000003D010000DB020000 - - - 16 - 560000006D000000D20100008C030000 - - - - 196 - 196 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000660000003D010000DB020000 - - - 16 - 560000006D000000D20100008C030000 - - - - 197 - 197 - 0 - 0 - 0 - 0 - 32767 - 0 - 32768 - 0 - - 16 - 03000000230300006D070000BA030000 - - - 16 - 560000006D0000000E04000034010000 - - - - 198 - 198 - 1 - 0 - 0 - 0 - 32767 - 0 - 32768 - 0 - - 16 - 0000000042030000790300001D040000 - - - 16 - 560000006D0000000E04000034010000 - - - - 199 - 199 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000230300006D070000BA030000 - - - 16 - 560000006D0000000E04000034010000 - - - - 203 - 203 - 1 - 0 - 0 - 0 - 32767 - 0 - 8192 - 0 - - 16 - 4401000063000000F106000016010000 - - - 16 - 560000006D0000000E04000034010000 - - - - 204 - 204 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 47010000660000006D070000FD000000 - - - 16 - 560000006D0000000E04000034010000 - - - - 221 - 221 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 00000000000000000000000000000000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 2506 - 2506 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 2507 - 2507 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 80030000590300002E07000004040000 - - - 16 - 560000006D0000000E04000034010000 - - - - 343 - 343 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 47010000660000006D070000FD000000 - - - 16 - 560000006D0000000E04000034010000 - - - - 346 - 346 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 47010000660000006D070000FD000000 - - - 16 - 560000006D0000000E04000034010000 - - - - 35824 - 35824 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 47010000660000006D070000FD000000 - - - 16 - 560000006D0000000E04000034010000 - - - - 35885 - 35885 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35886 - 35886 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35887 - 35887 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35888 - 35888 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35889 - 35889 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35890 - 35890 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35891 - 35891 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35892 - 35892 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35893 - 35893 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35894 - 35894 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35895 - 35895 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35896 - 35896 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35897 - 35897 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35898 - 35898 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35899 - 35899 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35900 - 35900 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35901 - 35901 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35902 - 35902 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35903 - 35903 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35904 - 35904 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 35905 - 35905 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 33060000660000006D070000EF020000 - - - 16 - 560000006D0000009601000082010000 - - - - 38003 - 38003 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000660000003D01000025030000 - - - 16 - 560000006D000000D20100008C030000 - - - - 38007 - 38007 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000230300006D070000BA030000 - - - 16 - 560000006D0000000E04000034010000 - - - - 436 - 436 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 03000000230300006D070000BA030000 - - - 16 - 560000006D000000D20100008C030000 - - - - 437 - 437 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 80030000590300002E07000004040000 - - - 16 - 560000006D0000009601000082010000 - - - - 440 - 440 - 0 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 80030000590300002E07000004040000 - - - 16 - 560000006D0000009601000082010000 - - - - 59392 - 59392 - 1 - 0 - 0 - 0 - 940 - 0 - 8192 - 0 - - 16 - 0000000000000000B70300001C000000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 59393 - 0 - 1 - 0 - 0 - 0 - 32767 - 0 - 4096 - 0 - - 16 - 000000001D040000F106000030040000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 59399 - 59399 - 0 - 0 - 0 - 0 - 463 - 0 - 8192 - 1 - - 16 - 000000001C000000DA01000038000000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 59400 - 59400 - 1 - 0 - 0 - 0 - 612 - 0 - 8192 - 2 - - 16 - 000000001C0000006F02000038000000 - - - 16 - 0A0000000A0000006E0000006E000000 - - - - 2618 - 000000000B000000000000000020000001000000FFFFFFFFFFFFFFFF4401000016010000F10600001A010000010000000100000004000000010000000000000000000000FFFFFFFF06000000CB00000057010000CC000000F08B00005A01000079070000FFFF02000B004354616262656450616E650020000001000000B403000065010000E00900002C020000440100004F000000F1060000160100000000000040280056060000000B446973617373656D626C7901000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFF2C0600004F0000003006000008030000000000000200000004000000010000000000000000000000FFFFFFFF17000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000001800040000000000000A008000065010000E00900001E040000300600004F00000070070000080300000000000040410046170000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFF400100004F000000440100003E030000010000000200000004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C400000073940000018000100000010000007002000065010000B00300000A040000000000004F000000400100003E0300000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73000000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7300000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657300000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273010000007394000001000000FFFFFFFFFFFFFFFF04000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000001000000FFFFFFFFFFFFFFFF000000003E030000F10600004203000001000000010000000400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0E0000008F070000930700009407000095070000960700009007000091070000B5010000B8010000B9050000BA050000BB050000BC050000CB090000018000800000010000002C0600000E040000E0090000E90400007D03000042030000F10600001D04000000000000404100560E0000001343616C6C20537461636B202B204C6F63616C73010000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF084D656D6F7279203101000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFF000000000000000001000000000000000100000001000000FFFFFFFF79030000420300007D0300001D04000001000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000000000000FFFFFFFFFFFFFFFF0000000008030000700700000C030000000000000100000004000000010000000000000000000000FFFFFFFF04000000C5000000C7000000B401000077940000018000800000000000007002000022040000E0090000E9040000000000000C03000070070000D30300000000000040820046040000000C4275696C64204F757470757400000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0642726F777365000000007794000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000 - - - 59392 - File - - 2390 - 00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000004000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE803000000000000000000000000000000000000000000000001000000010000009600000002002050000000000D4750494F5F4F55545055545F31960000000000000013000D4750494F5F4F55545055545F31094253505F4C45445F3009705F69635F696E666F1273645F626C655F757569645F76735F6164641B626C655F6C62735F6C65645F77726974655F68616E646C65725F74254750494F54455F434F4E4649475F4E554D5F4F465F4C4F575F504F5745525F4556454E5453154150505F4952515F5052494F524954595F484947480A6D616E75665F646174610F626C655F616476646174615F7365740E75756964735F636F6D706C6574650D626C655F616476646174615F74146E72665F6472765F7477695F636F6E6669675F74066F6363757273106D5F6465766963655F61646472657373076D61696E5F49440C7469645F626C696E6B4C4544094552524F525F50494E044857464314454E41424C455F4C4F4F504241434B5F5445535400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000020001001500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000000180C8880000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E4C010000020001001A0000000F2650726F6A6563742057696E646F77000000000000000000000000010000000100000000000000000000000100000008002880DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002880DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002880E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002880E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000288018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000028800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002880D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002880E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65AC030000 - - - 1423 - 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000FFFFFFFF000100000000000000010000000000000001000000018001E1000000000000FFFFFFFF000100000000000000010000000000000001000000018003E1000000000000FFFFFFFF0001000000000000000100000000000000010000000180CD7F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF000000000000000000010000000000000001000000018023E1000000000000FFFFFFFF000100000000000000010000000000000001000000018022E1000000000000FFFFFFFF000100000000000000010000000000000001000000018025E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802BE1000000000000FFFFFFFF00010000000000000001000000000000000100000001802CE1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001807A8A000000000000FFFFFFFF00010000000000000001000000000000000100000001807B8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180D3B0000000000000FFFFFFFF000100000000000000010000000000000001000000018015B1000000000000FFFFFFFF0001000000000000000100000000000000010000000180F4B0000000000000FFFFFFFF000100000000000000010000000000000001000000018036B1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FF88000000000000FFFFFFFF0001000000000000000100000000000000010000000180FE88000000000000FFFFFFFF00010000000000000001000000000000000100000001800B81000000000000FFFFFFFF00010000000000000001000000000000000100000001800C81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180F088000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE7F000000000000FFFFFFFF000100000000000000010000000000000001000000018024E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800A81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802280000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C488000000000000FFFFFFFF0001000000000000000100000000000000010000000180C988000000000000FFFFFFFF0001000000000000000100000000000000010000000180C788000000000000FFFFFFFF0001000000000000000100000000000000010000000180C888000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180DD88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FB7F000000000000FFFFFFFF000100000000000000010000000000000001000000 - - - 1423 - 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000000000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000000000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000000000C0000000000000000000000000000000001000000010000000180F4B00000000000000D000000000000000000000000000000000100000001000000018036B10000000000000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF880000000000000F0000000000000000000000000000000001000000010000000180FE880000000000001000000000000000000000000000000000010000000100000001800B810000000000001100000000000000000000000000000000010000000100000001800C810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F088000000000000130000000000000000000000000000000001000000010000000180EE7F00000000000014000000000000000000000000000000000100000001000000018024E10000000000001500000000000000000000000000000000010000000100000001800A810000000000001600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000180000000000000000000000000000000001000000010000000180C988000000000000190000000000000000000000000000000001000000010000000180C7880000000000001A0000000000000000000000000000000001000000010000000180C8880000000000001B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180DD880000000000001C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001D000000000000000000000000000000000100000001000000 - - - - 59399 - Build - - 657 - 00200000000000001000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000000001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E00000000000000000000000000000000010000000100000001809E8A0000000000001F0000000000000000000000000000000001000000010000000180D17F0000000000002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA00000000000000000000000000000000000000000000000001000000010000009600000003002050FFFFFFFF00960000000000000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000000240000000000000000000000000000000001000000010000000180A8010000000000004E00000000000000000000000000000000010000000100000001807202000000000000530000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C64CF010000 - - - 583 - 1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000FFFFFFFF0001000000000000000100000000000000010000000180D07F000000000000FFFFFFFF00010000000000000001000000000000000100000001803080000000000000FFFFFFFF00010000000000000001000000000000000100000001809E8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D17F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001804C8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001806680000000000000FFFFFFFF0001000000000000000100000000000000010000000180EB88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180B08A000000000000FFFFFFFF0001000000000000000100000000000000010000000180A801000000000000FFFFFFFF00010000000000000001000000000000000100000001807202000000000000FFFFFFFF0001000000000000000100000000000000010000000180BE01000000000000FFFFFFFF000100000000000000010000000000000001000000 - - - 583 - 1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000000000000000000000000000000000000001000000010000000180D07F00000000000001000000000000000000000000000000000100000001000000018030800000000000000200000000000000000000000000000000010000000100000001809E8A000000000000030000000000000000000000000000000001000000010000000180D17F0000000000000400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000000500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001806680000000000000060000000000000000000000000000000001000000010000000180EB880000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000080000000000000000000000000000000001000000010000000180B08A000000000000090000000000000000000000000000000001000000010000000180A8010000000000000A000000000000000000000000000000000100000001000000018072020000000000000B0000000000000000000000000000000001000000010000000180BE010000000000000C000000000000000000000000000000000100000001000000 - - - - 59400 - Debug - - 2236 - 00200000010000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000004002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000020001002D0000000000000000000000000000000001000000010000000180F07F0000020001002E0000000000000000000000000000000001000000010000000180E8880000020000003700000000000000000000000000000000010000000100000001803B010000020001002F0000000000000000000000000000000001000000010000000180BB8A00000200010030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000002000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000002001380D88B00000000000031000000085761746368202631000000000000000000000000010000000100000000000000000000000100000000001380D98B000000000000310000000857617463682026320000000000000000000000000100000001000000000000000000000001000000000013800F0100000200010032000000094D656D6F7279202631000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000094D656D6F7279202631000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000094D656D6F7279202632000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000094D656D6F7279202633000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000094D656D6F727920263400000000000000000000000001000000010000000000000000000000010000000000138010010000020000003300000008554152542023263100000000000000000000000001000000010000000000000000000000010000000400138093070000000000003300000008554152542023263100000000000000000000000001000000010000000000000000000000010000000000138094070000000000003300000008554152542023263200000000000000000000000001000000010000000000000000000000010000000000138095070000000000003300000008554152542023263300000000000000000000000001000000010000000000000000000000010000000000138096070000000000003300000015446562756720287072696E746629205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000020000003400000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380658A000000000000340000000F264C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E0000001526506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000E26436F646520436F76657261676500000000000000000000000001000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720000000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720000000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000013800189000002000000360000000F26546F6F6C626F782057696E646F7700000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730000000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72000000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000 - - - 898 - 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801780000000000000FFFFFFFF00010000000000000001000000000000000100000001801D80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801A80000000000000FFFFFFFF00010000000000000001000000000000000100000001801B80000000000000FFFFFFFF0001000000000000000100000000000000010000000180E57F000000000000FFFFFFFF00010000000000000001000000000000000100000001801C80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800089000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180E48B000000000000FFFFFFFF0001000000000000000100000000000000010000000180F07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180E888000000000000FFFFFFFF00010000000000000001000000000000000100000001803B01000000000000FFFFFFFF0001000000000000000100000000000000010000000180BB8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D88B000000000000FFFFFFFF0001000000000000000100000000000000010000000180D28B000000000000FFFFFFFF00010000000000000001000000000000000100000001809307000000000000FFFFFFFF0001000000000000000100000000000000010000000180658A000000000000FFFFFFFF0001000000000000000100000000000000010000000180C18A000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE8B000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800189000000000000FFFFFFFF000100000000000000010000000000000001000000 - - - 898 - 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000000000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000000100000000000000000000000000000000010000000100000001801D800000000000000200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000000300000000000000000000000000000000010000000100000001801B80000000000000040000000000000000000000000000000001000000010000000180E57F0000000000000500000000000000000000000000000000010000000100000001801C800000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B000000000000080000000000000000000000000000000001000000010000000180F07F000000000000090000000000000000000000000000000001000000010000000180E8880000000000000A00000000000000000000000000000000010000000100000001803B010000000000000B0000000000000000000000000000000001000000010000000180BB8A0000000000000C0000000000000000000000000000000001000000010000000180D88B0000000000000D0000000000000000000000000000000001000000010000000180D28B0000000000000E000000000000000000000000000000000100000001000000018093070000000000000F0000000000000000000000000000000001000000010000000180658A000000000000100000000000000000000000000000000001000000010000000180C18A000000000000110000000000000000000000000000000001000000010000000180EE8B0000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180018900000000000013000000000000000000000000000000000100000001000000 - - - - 0 - 2560 - 1440 - - - - - - 1 - 0 - - 100 - 6 - - .\drivers\board.c - 44 - 10 - 46 - 1 - - 0 - - - .\Libraries\nrf52832\Source\templates\system_nrf52.c - 0 - 32 - 47 - 1 - - 0 - - - .\applications\application.c - 0 - 1 - 1 - 1 - - 0 - - - .\drivers\uart.c - 18 - 140 - 182 - 1 - - 0 - - - drivers\uart.h - 32 - 1 - 20 - 1 - - 0 - - - ..\..\src\idle.c - 0 - 29 - 75 - 1 - - 0 - - - .\rtconfig.h - 31 - 1 - 15 - 1 - - 0 - - - - -
diff --git a/bsp/nrf52832/project.uvoptx b/bsp/nrf52832/project.uvoptx deleted file mode 100644 index 0fe361125511935918061fccd9fd8f1e5a366fde..0000000000000000000000000000000000000000 --- a/bsp/nrf52832/project.uvoptx +++ /dev/null @@ -1,638 +0,0 @@ - - - - 1.0 - -
### uVision Project, (C) Keil Software
- - - *.c - *.s*; *.src; *.a* - *.obj - *.lib - *.txt; *.h; *.inc - *.plm - *.cpp - 0 - - - - 0 - 0 - - - - rt-thread - 0x4 - ARM-ADS - - 64000000 - - 1 - 1 - 0 - 1 - 0 - - - 1 - 65535 - 0 - 0 - 0 - - - 79 - 66 - 8 - .\build\ - - - 1 - 1 - 1 - 0 - 1 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 0 - - - 1 - 0 - 1 - - 5 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 1 - 0 - 0 - 6 - - - - - - - - - - - Segger\JL2CM3.dll - - - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - 0 - JL2CM3 - -U682468122 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC2000 -FN2 -FF0nrf52xxx.flm -FS00 -FL0200000 -FP0($$Device:nRF52832_xxAA$Flash\nrf52xxx.flm) -FF1nrf52xxx_uicr.flm -FS110001000 -FL11000 -FP1($$Device:nRF52832_xxAA$Flash\nrf52xxx_uicr.flm) - - - 0 - UL2CM3 - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC4000 -FN2 -FF0nrf52xxx -FS00 -FL0200000 -FF1nrf52xxx_uicr -FS110001000 -FL11000 -FP0($$Device:nRF52832_xxAA$Flash\nrf52xxx.flm) -FP1($$Device:nRF52832_xxAA$Flash\nrf52xxx_uicr.flm)) - - - - - 0 - - - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - - - - - Startup Code - 1 - 0 - 0 - 0 - - 1 - 1 - 1 - 0 - 0 - 0 - 0 - .\Libraries\nrf52832\Source\templates\system_nrf52.c - system_nrf52.c - 0 - 0 - - - 1 - 2 - 2 - 0 - 0 - 0 - 0 - .\Libraries\nrf52832\Source\templates\arm\arm_startup_nrf52.s - arm_startup_nrf52.s - 0 - 0 - - - - - Applications - 1 - 0 - 0 - 0 - - 2 - 3 - 1 - 0 - 0 - 0 - 0 - .\applications\application.c - application.c - 0 - 0 - - - 2 - 4 - 1 - 0 - 0 - 0 - 0 - .\applications\startup.c - startup.c - 0 - 0 - - - - - Drivers - 1 - 0 - 0 - 0 - - 3 - 5 - 1 - 0 - 0 - 0 - 0 - .\drivers\board.c - board.c - 0 - 0 - - - 3 - 6 - 1 - 0 - 0 - 0 - 0 - .\drivers\uart.c - uart.c - 0 - 0 - - - - - Kernel - 0 - 0 - 0 - 0 - - 4 - 7 - 1 - 0 - 0 - 0 - 0 - ..\..\src\clock.c - clock.c - 0 - 0 - - - 4 - 8 - 1 - 0 - 0 - 0 - 0 - ..\..\src\components.c - components.c - 0 - 0 - - - 4 - 9 - 1 - 0 - 0 - 0 - 0 - ..\..\src\device.c - device.c - 0 - 0 - - - 4 - 10 - 1 - 0 - 0 - 0 - 0 - ..\..\src\idle.c - idle.c - 0 - 0 - - - 4 - 11 - 1 - 0 - 0 - 0 - 0 - ..\..\src\ipc.c - ipc.c - 0 - 0 - - - 4 - 12 - 1 - 0 - 0 - 0 - 0 - ..\..\src\irq.c - irq.c - 0 - 0 - - - 4 - 13 - 1 - 0 - 0 - 0 - 0 - ..\..\src\kservice.c - kservice.c - 0 - 0 - - - 4 - 14 - 1 - 0 - 0 - 0 - 0 - ..\..\src\object.c - object.c - 0 - 0 - - - 4 - 15 - 1 - 0 - 0 - 0 - 0 - ..\..\src\scheduler.c - scheduler.c - 0 - 0 - - - 4 - 16 - 1 - 0 - 0 - 0 - 0 - ..\..\src\thread.c - thread.c - 0 - 0 - - - 4 - 17 - 1 - 0 - 0 - 0 - 0 - ..\..\src\timer.c - timer.c - 0 - 0 - - - - - CORTEX-M4 - 1 - 0 - 0 - 0 - - 5 - 18 - 1 - 0 - 0 - 0 - 0 - ..\..\libcpu\arm\common\backtrace.c - backtrace.c - 0 - 0 - - - 5 - 19 - 1 - 0 - 0 - 0 - 0 - ..\..\libcpu\arm\common\div0.c - div0.c - 0 - 0 - - - 5 - 20 - 1 - 0 - 0 - 0 - 0 - ..\..\libcpu\arm\common\showmem.c - showmem.c - 0 - 0 - - - 5 - 21 - 2 - 0 - 0 - 0 - 0 - ..\..\libcpu\arm\cortex-m4\context_rvds.S - context_rvds.S - 0 - 0 - - - 5 - 22 - 1 - 0 - 0 - 0 - 0 - ..\..\libcpu\arm\cortex-m4\cpuport.c - cpuport.c - 0 - 0 - - - - - DeviceDrivers - 1 - 0 - 0 - 0 - - 6 - 23 - 1 - 0 - 0 - 0 - 0 - ..\..\components\drivers\src\completion.c - completion.c - 0 - 0 - - - 6 - 24 - 1 - 0 - 0 - 0 - 0 - ..\..\components\drivers\src\portal.c - portal.c - 0 - 0 - - - 6 - 25 - 1 - 0 - 0 - 0 - 0 - ..\..\components\drivers\src\ringbuffer.c - ringbuffer.c - 0 - 0 - - - 6 - 26 - 1 - 0 - 0 - 0 - 0 - ..\..\components\drivers\src\workqueue.c - workqueue.c - 0 - 0 - - - - - finsh - 1 - 0 - 0 - 0 - - 7 - 27 - 1 - 0 - 0 - 0 - 0 - ..\..\components\finsh\cmd.c - cmd.c - 0 - 0 - - - 7 - 28 - 1 - 0 - 0 - 0 - 0 - ..\..\components\finsh\shell.c - shell.c - 0 - 0 - - - 7 - 29 - 1 - 0 - 0 - 0 - 0 - ..\..\components\finsh\symbol.c - symbol.c - 0 - 0 - - - 7 - 30 - 1 - 0 - 0 - 0 - 0 - ..\..\components\finsh\msh_cmd.c - msh_cmd.c - 0 - 0 - - - 7 - 31 - 1 - 0 - 0 - 0 - 0 - ..\..\components\finsh\msh.c - msh.c - 0 - 0 - - - -
diff --git a/bsp/nrf52832/project.uvprojx b/bsp/nrf52832/project.uvprojx index f9b3c89433ab9e01efd88a97e2d0a21f9e19896a..e44a2d6b6f04e4dc2c72c0b231358fbdc5b255f3 100644 --- a/bsp/nrf52832/project.uvprojx +++ b/bsp/nrf52832/project.uvprojx @@ -7,17 +7,17 @@ - rt-thread + rtthread 0x4 ARM-ADS - 5060020::V5.06 (build 20)::ARMCC + 5060422::V5.06 update 4 (build 422)::ARMCC nRF52832_xxAA Nordic Semiconductor - NordicSemiconductor.nRF_DeviceFamilyPack.8.0.5 - http://developer.nordicsemi.com/nRF51_SDK/pieces/nRF_DeviceFamilyPack/ - IROM(0x00000000,0x80000) IRAM(0x20000000,0x10000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + NordicSemiconductor.nRF_DeviceFamilyPack.8.12.0 + http://developer.nordicsemi.com/nRF5_SDK/pieces/nRF_DeviceFamilyPack/ + IRAM(0x20000000,0x10000) IROM(0x00000000,0x80000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE UL2CM3(-S0 -C0 -P0 -FD20000000 -FC4000 -FN2 -FF0nrf52xxx -FS00 -FL0200000 -FF1nrf52xxx_uicr -FS110001000 -FL11000 -FP0($$Device:nRF52832_xxAA$Flash\nrf52xxx.flm) -FP1($$Device:nRF52832_xxAA$Flash\nrf52xxx_uicr.flm)) @@ -48,10 +48,10 @@ 1 .\build\ - rtthread-nrf52832 + rtthread 1 0 - 1 + 0 1 1 .\build\ @@ -79,9 +79,9 @@ 0 - 0 + 1 0 - + fromelf --bin !L --output rtthread.bin 0 0 @@ -125,47 +125,6 @@ 0 16 - - 0 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - - - 1 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - - 0 - 6 - - - - - - - - - - - - - - Segger\JL2CM3.dll - @@ -173,12 +132,12 @@ 0 0 1 - 0 - -1 + 1 + 4096 1 BIN\UL2CM3.DLL - + "" () @@ -313,8 +272,8 @@ 1 - 0x0 - 0x80000 + 0x1f000 + 0x61000 1 @@ -338,8 +297,8 @@ 0 - 0x20000000 - 0x10000 + 0x200025f8 + 0xda08 0 @@ -363,17 +322,20 @@ 2 0 0 - 0 + 1 0 - 0 - 0 - 0 - 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 - --c99 - NRF52, USE_STDPERIPH_DRIVER + --reduce_paths + NRF52_PAN_55, NRF52_PAN_12, NRF52_PAN_15, NRF52_PAN_58, SWI_DISABLE0, SOFTDEVICE_PRESENT, NRF52_PAN_54, NRF52, BLE_STACK_SUPPORT_REQD, NRF52_PAN_51, NRF52_PAN_36, RTTHREAD, CONFIG_GPIO_AS_PINRESET, NRF52_PAN_64, NRF52_PAN_20, NRF52_PAN_74, NRF52832_XXAA, S132, NRF_SD_BLE_API_VERSION=4, NRF52_PAN_31 - Libraries/CMSIS/Include;Libraries/nrf52832/Include;applications;.;drivers;../../include;../../libcpu/arm/cortex-m0;../../libcpu/arm/common;../../components/drivers/include;../../components/finsh + applications;.;board;nRF5_SDK_13.0.0_04a0bfd\components;nRF5_SDK_13.0.0_04a0bfd\components\softdevice\common\softdevice_handler;nRF5_SDK_13.0.0_04a0bfd\components\softdevice\s132\headers;nRF5_SDK_13.0.0_04a0bfd\components\softdevice\s132\headers\nrf52;nRF5_SDK_13.0.0_04a0bfd\components\ble\common;nRF5_SDK_13.0.0_04a0bfd\components\ble\nrf_ble_gatt;nRF5_SDK_13.0.0_04a0bfd\components\ble\ble_advertising;nRF5_SDK_13.0.0_04a0bfd\components\ble\ble_services\ble_nus;startups;nRF5_SDK_13.0.0_04a0bfd\components;nRF5_SDK_13.0.0_04a0bfd\components\device;nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\delay;nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\uart;nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\clock;nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\gpiote;nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\common;nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\hal;nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\pwm;nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\saadc;nRF5_SDK_13.0.0_04a0bfd\components\libraries\util;nRF5_SDK_13.0.0_04a0bfd\components\libraries\timer;nRF5_SDK_13.0.0_04a0bfd\components\libraries\fstorage;nRF5_SDK_13.0.0_04a0bfd\components\libraries\experimental_section_vars;nRF5_SDK_13.0.0_04a0bfd\components\libraries\log;nRF5_SDK_13.0.0_04a0bfd\components\libraries\log\src;nRF5_SDK_13.0.0_04a0bfd\components\libraries\strerror;nRF5_SDK_13.0.0_04a0bfd\components\toolchain\cmsis\include;..\..\include;..\..\libcpu\arm\cortex-m4;..\..\libcpu\arm\common;..\..\components\drivers\include;..\..\components\drivers\include @@ -386,9 +348,10 @@ 0 0 0 + 0 - - NRF52, USE_STDPERIPH_DRIVER + --cpreproc_opts=-DBLE_STACK_SUPPORT_REQD,-DNRF_SD_BLE_API_VERSION=4,-DS132,-DSOFTDEVICE_PRESENT,-DSWI_DISABLE0,-DCONFIG_GPIO_AS_PINRESET,-DNRF52,-DNRF52832_XXAA,-DNRF52_PAN_12,-DNRF52_PAN_15,-DNRF52_PAN_20,-DNRF52_PAN_31,-DNRF52_PAN_36,-DNRF52_PAN_51,-DNRF52_PAN_54,-DNRF52_PAN_55,-DNRF52_PAN_58,-DNRF52_PAN_64,-DNRF52_PAN_74 + BLE_STACK_SUPPORT_REQD NRF_SD_BLE_API_VERSION=4 S132 SOFTDEVICE_PRESENT SWI_DISABLE0 CONFIG_GPIO_AS_PINRESET NRF52 NRF52832_XXAA NRF52_PAN_12 NRF52_PAN_15 NRF52_PAN_20 NRF52_PAN_31 NRF52_PAN_36 NRF52_PAN_51 NRF52_PAN_54 NRF52_PAN_55 NRF52_PAN_58 NRF52_PAN_64 NRF52_PAN_74 @@ -414,62 +377,187 @@ - Startup Code + Applications - system_nrf52.c + application.c 1 - .\Libraries\nrf52832\Source\templates\system_nrf52.c + applications\application.c - arm_startup_nrf52.s - 2 - .\Libraries\nrf52832\Source\templates\arm\arm_startup_nrf52.s + ble_nus_app.c + 1 + applications\ble_nus_app.c + + + startup.c + 1 + applications\startup.c - Applications + Board - application.c + board.c 1 - .\applications\application.c + board\board.c - startup.c + uart.c 1 - .\applications\startup.c + board\uart.c - Drivers + BLE_STACK - board.c + ble_advdata.c 1 - .\drivers\board.c + nRF5_SDK_13.0.0_04a0bfd\components\ble\common\ble_advdata.c - uart.c + ble_conn_params.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\ble\common\ble_conn_params.c + + + ble_srv_common.c 1 - .\drivers\uart.c + nRF5_SDK_13.0.0_04a0bfd\components\ble\common\ble_srv_common.c + + + nrf_ble_gatt.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\ble\nrf_ble_gatt\nrf_ble_gatt.c + + + ble_nus.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\ble\ble_services\ble_nus\ble_nus.c + + + ble_advertising.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\ble\ble_advertising\ble_advertising.c + + + softdevice_handler.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\softdevice\common\softdevice_handler\softdevice_handler.c - Kernel + Startup - clock.c + system_nrf52.c 1 - ..\..\src\clock.c + startups\system_nrf52.c + + + arm_startup_nrf52.s + 2 + startups\arm\arm_startup_nrf52.s + + + + + NRF_DRIVERS + + + nrf_saadc.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\hal\nrf_saadc.c + + + nrf_drv_common.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\common\nrf_drv_common.c + + + nrf_drv_clock.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\clock\nrf_drv_clock.c - components.c + nrf_drv_gpiote.c 1 - ..\..\src\components.c + nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\gpiote\nrf_drv_gpiote.c + + + nrf_drv_pwm.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\pwm\nrf_drv_pwm.c + + + nrf_drv_saadc.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\drivers_nrf\saadc\nrf_drv_saadc.c + + + nrf_log_backend_serial.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\libraries\log\src\nrf_log_backend_serial.c + + + nrf_log_frontend.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\libraries\log\src\nrf_log_frontend.c + + + app_timer_rtthread.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\libraries\timer\app_timer_rtthread.c + + + app_error.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\libraries\util\app_error.c + + + app_error_weak.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\libraries\util\app_error_weak.c + + + app_util_platform.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\libraries\util\app_util_platform.c + + + nrf_assert.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\libraries\util\nrf_assert.c + + + sdk_mapped_flags.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\libraries\util\sdk_mapped_flags.c + + + fstorage.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\libraries\fstorage\fstorage.c + + + nrf_strerror.c + 1 + nRF5_SDK_13.0.0_04a0bfd\components\libraries\strerror\nrf_strerror.c + + + + + Kernel + + + clock.c + 1 + ..\..\src\clock.c device.c @@ -496,6 +584,11 @@ 1 ..\..\src\kservice.c + + mem.c + 1 + ..\..\src\mem.c + object.c 1 @@ -521,6 +614,16 @@ CORTEX-M4 + + cpuport.c + 1 + ..\..\libcpu\arm\cortex-m4\cpuport.c + + + context_rvds.S + 2 + ..\..\libcpu\arm\cortex-m4\context_rvds.S + backtrace.c 1 @@ -536,70 +639,45 @@ 1 ..\..\libcpu\arm\common\showmem.c - - context_rvds.S - 2 - ..\..\libcpu\arm\cortex-m4\context_rvds.S - - - cpuport.c - 1 - ..\..\libcpu\arm\cortex-m4\cpuport.c - DeviceDrivers - completion.c - 1 - ..\..\components\drivers\src\completion.c - - - portal.c - 1 - ..\..\components\drivers\src\portal.c - - - ringbuffer.c + serial.c 1 - ..\..\components\drivers\src\ringbuffer.c + ..\..\components\drivers\serial\serial.c - workqueue.c + completion.c 1 - ..\..\components\drivers\src\workqueue.c + ..\..\components\drivers\src\completion.c - - - - finsh - - cmd.c + dataqueue.c 1 - ..\..\components\finsh\cmd.c + ..\..\components\drivers\src\dataqueue.c - shell.c + pipe.c 1 - ..\..\components\finsh\shell.c + ..\..\components\drivers\src\pipe.c - symbol.c + portal.c 1 - ..\..\components\finsh\symbol.c + ..\..\components\drivers\src\portal.c - msh_cmd.c + ringbuffer.c 1 - ..\..\components\finsh\msh_cmd.c + ..\..\components\drivers\src\ringbuffer.c - msh.c + workqueue.c 1 - ..\..\components\finsh\msh.c + ..\..\components\drivers\src\workqueue.c @@ -607,4 +685,10 @@ + + + + + + diff --git a/bsp/nrf52832/rtconfig.h b/bsp/nrf52832/rtconfig.h index b4df9066cb7e9b460737e6337051765acc2aa515..b8710f31c8327ee78957a9940a2cc717e9a7b2e8 100644 --- a/bsp/nrf52832/rtconfig.h +++ b/bsp/nrf52832/rtconfig.h @@ -12,47 +12,49 @@ #define RT_THREAD_PRIORITY_MAX 8 /* Tick per Second */ -#define RT_TICK_PER_SECOND 100 +#define RT_TICK_PER_SECOND 200 /* SECTION: RT_DEBUG */ /* Thread Debug */ -#define RT_DEBUG +// #define RT_DEBUG //#define RT_DEBUG_INIT 1 -#define RT_USING_OVERFLOW_CHECK +// #define RT_USING_OVERFLOW_CHECK /* Using Hook */ #define RT_USING_HOOK -#define IDLE_THREAD_STACK_SIZE 512 +// #define RT_USING_IDLE_HOOK + +#define IDLE_THREAD_STACK_SIZE 384 /* Using Software Timer */ -/* #define RT_USING_TIMER_SOFT */ -#define RT_TIMER_THREAD_PRIO 4 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 1 #define RT_TIMER_THREAD_STACK_SIZE 512 -#define RT_TIMER_TICK_PER_SECOND 100 +#define RT_TIMER_TICK_PER_SECOND 200 /* SECTION: IPC */ /* Using Semaphore*/ #define RT_USING_SEMAPHORE /* Using Mutex */ -/* #define RT_USING_MUTEX */ +#define RT_USING_MUTEX /* Using Event */ -/* #define RT_USING_EVENT */ +#define RT_USING_EVENT /* Using MailBox */ -#define RT_USING_MAILBOX +/* #define RT_USING_MAILBOX */ /* Using Message Queue */ -/* #define RT_USING_MESSAGEQUEUE */ +#define RT_USING_MESSAGEQUEUE /* SECTION: Memory Management */ /* Using Memory Pool Management*/ /* #define RT_USING_MEMPOOL */ /* Using Dynamic Heap Management */ -//#define RT_USING_HEAP +#define RT_USING_HEAP /* Using Small MM */ #define RT_USING_SMALL_MEM @@ -67,7 +69,7 @@ // #define RT_USING_DEVICE_IPC // -//#define RT_USING_SERIAL +#define RT_USING_SERIAL /* SECTION: Console options */ #define RT_USING_CONSOLE @@ -76,19 +78,19 @@ // #define RT_CONSOLE_DEVICE_NAME "uart0" - +// #define RT_USING_SPI /* SECTION: finsh, a C-Express shell */ -#define RT_USING_FINSH +// #define RT_USING_FINSH /* configure finsh parameters */ #define FINSH_THREAD_PRIORITY 6 #define FINSH_THREAD_STACK_SIZE 512 #define FINSH_HISTORY_LINES 1 /* Using symbol table */ -#define FINSH_USING_SYMTAB -#define FINSH_USING_DESCRIPTION +// #define FINSH_USING_SYMTAB +// #define FINSH_USING_DESCRIPTION -#define FINSH_USING_MSH +// #define FINSH_USING_MSH #define FINSH_USING_MSH_ONLY #endif diff --git a/bsp/nrf52832/rtconfig.py b/bsp/nrf52832/rtconfig.py index f8aacec78b116545a5c04ef9bc4e02cd6d89b008..5e40e7201ed30a1423fb6937889a3e95a2768f93 100644 --- a/bsp/nrf52832/rtconfig.py +++ b/bsp/nrf52832/rtconfig.py @@ -10,9 +10,10 @@ if os.getenv('RTT_CC'): # cross_tool provides the cross compiler # EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR + if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' - EXEC_PATH = 'C:/Program Files/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin' + EXEC_PATH = 'D:/SourceryGCC/bin' elif CROSS_TOOL == 'keil': PLATFORM = 'armcc' EXEC_PATH = 'C:/Keil_v5' @@ -26,7 +27,6 @@ if os.getenv('RTT_EXEC_PATH'): EXEC_PATH = os.getenv('RTT_EXEC_PATH') BUILD = 'debug' -NRF_TYPE = 'NRF52832' if PLATFORM == 'gcc': # toolchains @@ -40,10 +40,10 @@ if PLATFORM == 'gcc': OBJDUMP = PREFIX + 'objdump' OBJCPY = PREFIX + 'objcopy' - DEVICE = ' -mcpu=cortex-m0 -mthumb -ffunction-sections -fdata-sections' - CFLAGS = DEVICE + DEVICE = ' -mcpu=cortex-m4 -mthumb -ffunction-sections -fdata-sections' + CFLAGS = DEVICE AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp' - LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-nrf52832.map,-cref,-u,Reset_Handler -T nrf52832_rom.ld' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-nrf52832.map,-cref,-u,Reset_Handler -T nrf52_xxaa.ld' CPATH = '' LPATH = '' @@ -67,8 +67,9 @@ elif PLATFORM == 'armcc': DEVICE = ' --device DARMSTM' CFLAGS = DEVICE + ' --apcs=interwork' AFLAGS = DEVICE - LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread-nrf52832.map --scatter nrf52832_rom.sct' + LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread-nrf52832.map --scatter rtthread-nrf52832.sct' + CFLAGS += ' --c99' CFLAGS += ' -I' + EXEC_PATH + '/ARM/RV31/INC' LFLAGS += ' --libpath ' + EXEC_PATH + '/ARM/RV31/LIB' diff --git a/bsp/nrf52832/rtthread-nrf52832.sct b/bsp/nrf52832/rtthread-nrf52832.sct new file mode 100644 index 0000000000000000000000000000000000000000..0200e96087ef805bed85a9a25f71ede3630d08d2 --- /dev/null +++ b/bsp/nrf52832/rtthread-nrf52832.sct @@ -0,0 +1,15 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LR_IROM1 0x0001F000 0x00061000 { ; load region size_region + ER_IROM1 0x0001F000 0x00061000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_IRAM1 0x200025F8 0x0000DA08 { ; RW data + .ANY (+RW +ZI) + } +} + diff --git a/bsp/nrf52832/startups/Sconscript b/bsp/nrf52832/startups/Sconscript new file mode 100644 index 0000000000000000000000000000000000000000..91c4983ebe1b2e30789fbff399f6563f57b15ac3 --- /dev/null +++ b/bsp/nrf52832/startups/Sconscript @@ -0,0 +1,16 @@ +Import('RTT_ROOT') +Import('rtconfig') +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +src += [cwd + '/arm/arm_startup_nrf52.s'] + +CPPPATH = [cwd] + +#remove other no use files +#SrcRemove(src, '*.c') + +group = DefineGroup('Startup', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') \ No newline at end of file diff --git a/bsp/nrf52832/startups/arm/arm_startup_nrf52.s b/bsp/nrf52832/startups/arm/arm_startup_nrf52.s new file mode 100644 index 0000000000000000000000000000000000000000..bd73f4342d2abf482fb5b2eff63e1d6612cc8dec --- /dev/null +++ b/bsp/nrf52832/startups/arm/arm_startup_nrf52.s @@ -0,0 +1,369 @@ +; Copyright (c) 2009-2017 ARM Limited. All rights reserved. +; +; SPDX-License-Identifier: Apache-2.0 +; +; Licensed 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 +; +; 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. +; +; NOTICE: This file has been modified by Nordic Semiconductor ASA. + + IF :DEF: __STARTUP_CONFIG +#include "startup_config.h" +#ifndef __STARTUP_CONFIG_STACK_ALIGNEMENT +#define __STARTUP_CONFIG_STACK_ALIGNEMENT 3 +#endif + ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Size EQU __STARTUP_CONFIG_STACK_SIZE + ELIF :DEF: __STACK_SIZE +Stack_Size EQU __STACK_SIZE + ELSE +Stack_Size EQU 8096 + ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Align EQU __STARTUP_CONFIG_STACK_ALIGNEMENT + ELSE +Stack_Align EQU 3 + ENDIF + + AREA STACK, NOINIT, READWRITE, ALIGN=Stack_Align +Stack_Mem SPACE Stack_Size +__initial_sp + + IF :DEF: __STARTUP_CONFIG +Heap_Size EQU __STARTUP_CONFIG_HEAP_SIZE + ELIF :DEF: __HEAP_SIZE +Heap_Size EQU __HEAP_SIZE + ELSE +Heap_Size EQU 0 + ENDIF + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler + DCD NMI_Handler + DCD HardFault_Handler + DCD MemoryManagement_Handler + DCD BusFault_Handler + DCD UsageFault_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler + DCD DebugMon_Handler + DCD 0 ; Reserved + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD POWER_CLOCK_IRQHandler + DCD RADIO_IRQHandler + DCD UARTE0_UART0_IRQHandler + DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + DCD NFCT_IRQHandler + DCD GPIOTE_IRQHandler + DCD SAADC_IRQHandler + DCD TIMER0_IRQHandler + DCD TIMER1_IRQHandler + DCD TIMER2_IRQHandler + DCD RTC0_IRQHandler + DCD TEMP_IRQHandler + DCD RNG_IRQHandler + DCD ECB_IRQHandler + DCD CCM_AAR_IRQHandler + DCD WDT_IRQHandler + DCD RTC1_IRQHandler + DCD QDEC_IRQHandler + DCD COMP_LPCOMP_IRQHandler + DCD SWI0_EGU0_IRQHandler + DCD SWI1_EGU1_IRQHandler + DCD SWI2_EGU2_IRQHandler + DCD SWI3_EGU3_IRQHandler + DCD SWI4_EGU4_IRQHandler + DCD SWI5_EGU5_IRQHandler + DCD TIMER3_IRQHandler + DCD TIMER4_IRQHandler + DCD PWM0_IRQHandler + DCD PDM_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD MWU_IRQHandler + DCD PWM1_IRQHandler + DCD PWM2_IRQHandler + DCD SPIM2_SPIS2_SPI2_IRQHandler + DCD RTC2_IRQHandler + DCD I2S_IRQHandler + DCD FPU_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset Handler + + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemoryManagement_Handler\ + PROC + EXPORT MemoryManagement_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT POWER_CLOCK_IRQHandler [WEAK] + EXPORT RADIO_IRQHandler [WEAK] + EXPORT UARTE0_UART0_IRQHandler [WEAK] + EXPORT SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler [WEAK] + EXPORT SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler [WEAK] + EXPORT NFCT_IRQHandler [WEAK] + EXPORT GPIOTE_IRQHandler [WEAK] + EXPORT SAADC_IRQHandler [WEAK] + EXPORT TIMER0_IRQHandler [WEAK] + EXPORT TIMER1_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT RTC0_IRQHandler [WEAK] + EXPORT TEMP_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT ECB_IRQHandler [WEAK] + EXPORT CCM_AAR_IRQHandler [WEAK] + EXPORT WDT_IRQHandler [WEAK] + EXPORT RTC1_IRQHandler [WEAK] + EXPORT QDEC_IRQHandler [WEAK] + EXPORT COMP_LPCOMP_IRQHandler [WEAK] + EXPORT SWI0_EGU0_IRQHandler [WEAK] + EXPORT SWI1_EGU1_IRQHandler [WEAK] + EXPORT SWI2_EGU2_IRQHandler [WEAK] + EXPORT SWI3_EGU3_IRQHandler [WEAK] + EXPORT SWI4_EGU4_IRQHandler [WEAK] + EXPORT SWI5_EGU5_IRQHandler [WEAK] + EXPORT TIMER3_IRQHandler [WEAK] + EXPORT TIMER4_IRQHandler [WEAK] + EXPORT PWM0_IRQHandler [WEAK] + EXPORT PDM_IRQHandler [WEAK] + EXPORT MWU_IRQHandler [WEAK] + EXPORT PWM1_IRQHandler [WEAK] + EXPORT PWM2_IRQHandler [WEAK] + EXPORT SPIM2_SPIS2_SPI2_IRQHandler [WEAK] + EXPORT RTC2_IRQHandler [WEAK] + EXPORT I2S_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] +POWER_CLOCK_IRQHandler +RADIO_IRQHandler +UARTE0_UART0_IRQHandler +SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler +SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler +NFCT_IRQHandler +GPIOTE_IRQHandler +SAADC_IRQHandler +TIMER0_IRQHandler +TIMER1_IRQHandler +TIMER2_IRQHandler +RTC0_IRQHandler +TEMP_IRQHandler +RNG_IRQHandler +ECB_IRQHandler +CCM_AAR_IRQHandler +WDT_IRQHandler +RTC1_IRQHandler +QDEC_IRQHandler +COMP_LPCOMP_IRQHandler +SWI0_EGU0_IRQHandler +SWI1_EGU1_IRQHandler +SWI2_EGU2_IRQHandler +SWI3_EGU3_IRQHandler +SWI4_EGU4_IRQHandler +SWI5_EGU5_IRQHandler +TIMER3_IRQHandler +TIMER4_IRQHandler +PWM0_IRQHandler +PDM_IRQHandler +MWU_IRQHandler +PWM1_IRQHandler +PWM2_IRQHandler +SPIM2_SPIS2_SPI2_IRQHandler +RTC2_IRQHandler +I2S_IRQHandler +FPU_IRQHandler + B . + ENDP + ALIGN + +; User Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + + LDR R0, = Heap_Mem + LDR R1, = (Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/bsp/nrf52832/startups/system_nrf52.c b/bsp/nrf52832/startups/system_nrf52.c new file mode 100644 index 0000000000000000000000000000000000000000..116edad1b9f4998acc722f511291b4d04baae198 --- /dev/null +++ b/bsp/nrf52832/startups/system_nrf52.c @@ -0,0 +1,327 @@ +/* + +Copyright (c) 2009-2017 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed 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 + + 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. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + +/* NOTE: Template files (including this one) are application specific and therefore expected to + be copied into the application project folder prior to its use! */ + +#include +#include +#include "nrf.h" +#include "system_nrf52.h" + +/*lint ++flb "Enter library region" */ + +#define __SYSTEM_CLOCK_64M (64000000UL) + +static bool errata_12(void); +static bool errata_16(void); +static bool errata_31(void); +static bool errata_32(void); +static bool errata_36(void); +static bool errata_37(void); +static bool errata_57(void); +static bool errata_66(void); +static bool errata_108(void); + + +#if defined ( __CC_ARM ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; +#elif defined ( __ICCARM__ ) + __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M; +#elif defined ( __GNUC__ ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; +#endif + +void SystemCoreClockUpdate(void) +{ + SystemCoreClock = __SYSTEM_CLOCK_64M; +} + +void SystemInit(void) +{ + /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product + Specification to see which one). */ + #if defined (ENABLE_SWO) + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos; + NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + #endif + + /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product + Specification to see which ones). */ + #if defined (ENABLE_TRACE) + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos; + NRF_P0->PIN_CNF[14] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P0->PIN_CNF[15] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P0->PIN_CNF[16] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P0->PIN_CNF[20] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + #endif + + /* Workaround for Errata 12 "COMP: Reference ladder not correctly callibrated" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_12()){ + *(volatile uint32_t *)0x40013540 = (*(uint32_t *)0x10000324 & 0x00001F00) >> 8; + } + + /* Workaround for Errata 16 "System: RAM may be corrupt on wakeup from CPU IDLE" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_16()){ + *(volatile uint32_t *)0x4007C074 = 3131961357ul; + } + + /* Workaround for Errata 31 "CLOCK: Calibration values are not correctly loaded from FICR at reset" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_31()){ + *(volatile uint32_t *)0x4000053C = ((*(volatile uint32_t *)0x10000244) & 0x0000E000) >> 13; + } + + /* Workaround for Errata 32 "DIF: Debug session automatically enables TracePort pins" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_32()){ + CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; + } + + /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_36()){ + NRF_CLOCK->EVENTS_DONE = 0; + NRF_CLOCK->EVENTS_CTTO = 0; + NRF_CLOCK->CTIV = 0; + } + + /* Workaround for Errata 37 "RADIO: Encryption engine is slow by default" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_37()){ + *(volatile uint32_t *)0x400005A0 = 0x3; + } + + /* Workaround for Errata 57 "NFCT: NFC Modulation amplitude" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_57()){ + *(volatile uint32_t *)0x40005610 = 0x00000005; + *(volatile uint32_t *)0x40005688 = 0x00000001; + *(volatile uint32_t *)0x40005618 = 0x00000000; + *(volatile uint32_t *)0x40005614 = 0x0000003F; + } + + /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_66()){ + NRF_TEMP->A0 = NRF_FICR->TEMP.A0; + NRF_TEMP->A1 = NRF_FICR->TEMP.A1; + NRF_TEMP->A2 = NRF_FICR->TEMP.A2; + NRF_TEMP->A3 = NRF_FICR->TEMP.A3; + NRF_TEMP->A4 = NRF_FICR->TEMP.A4; + NRF_TEMP->A5 = NRF_FICR->TEMP.A5; + NRF_TEMP->B0 = NRF_FICR->TEMP.B0; + NRF_TEMP->B1 = NRF_FICR->TEMP.B1; + NRF_TEMP->B2 = NRF_FICR->TEMP.B2; + NRF_TEMP->B3 = NRF_FICR->TEMP.B3; + NRF_TEMP->B4 = NRF_FICR->TEMP.B4; + NRF_TEMP->B5 = NRF_FICR->TEMP.B5; + NRF_TEMP->T0 = NRF_FICR->TEMP.T0; + NRF_TEMP->T1 = NRF_FICR->TEMP.T1; + NRF_TEMP->T2 = NRF_FICR->TEMP.T2; + NRF_TEMP->T3 = NRF_FICR->TEMP.T3; + NRF_TEMP->T4 = NRF_FICR->TEMP.T4; + } + + /* Workaround for Errata 108 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_108()){ + *(volatile uint32_t *)0x40000EE4 = *(volatile uint32_t *)0x10000258 & 0x0000004F; + } + + /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the + * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit + * operations are not used in your code. */ + #if (__FPU_USED == 1) + SCB->CPACR |= (3UL << 20) | (3UL << 22); + __DSB(); + __ISB(); + #endif + + /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined, + two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as + normal GPIOs. */ + #if defined (CONFIG_NFCT_PINS_AS_GPIOS) + if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){ + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NVIC_SystemReset(); + } + #endif + + /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not + defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be + reserved for PinReset and not available as normal GPIO. */ + #if defined (CONFIG_GPIO_AS_PINRESET) + if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) || + ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){ + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->PSELRESET[0] = 21; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->PSELRESET[1] = 21; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NVIC_SystemReset(); + } + #endif + + SystemCoreClockUpdate(); +} + + +static bool errata_12(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ + return true; + } + } + + return false; +} + +static bool errata_16(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + } + + return false; +} + +static bool errata_31(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ + return true; + } + } + + return false; +} + +static bool errata_32(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + } + + return false; +} + +static bool errata_36(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ + return true; + } + } + + return false; +} + +static bool errata_37(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + } + + return false; +} + +static bool errata_57(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + } + + return false; +} + +static bool errata_66(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ + return true; + } + } + + return false; +} + + +static bool errata_108(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ + return true; + } + } + + return false; +} + + +/*lint --flb "Leave library region" */ diff --git a/bsp/nrf52832/startups/system_nrf52.h b/bsp/nrf52832/startups/system_nrf52.h new file mode 100644 index 0000000000000000000000000000000000000000..ee9f40ef66c618f23b680d5448f4dfc431d524d5 --- /dev/null +++ b/bsp/nrf52832/startups/system_nrf52.h @@ -0,0 +1,61 @@ +/* + +Copyright (c) 2009-2017 ARM Limited. All rights reserved. + + SPDX-License-Identifier: Apache-2.0 + +Licensed 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 + + 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. + +NOTICE: This file has been modified by Nordic Semiconductor ASA. + +*/ + +#ifndef SYSTEM_NRF52_H +#define SYSTEM_NRF52_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_NRF52_H */ diff --git a/bsp/nrf52832/template.uvprojx b/bsp/nrf52832/template.uvprojx new file mode 100644 index 0000000000000000000000000000000000000000..db615bfa8bb946c0564f7f7d032d3f8e484cd886 --- /dev/null +++ b/bsp/nrf52832/template.uvprojx @@ -0,0 +1,386 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rtthread + 0x4 + ARM-ADS + + + nRF52832_xxAA + Nordic Semiconductor + NordicSemiconductor.nRF_DeviceFamilyPack.8.12.0 + http://developer.nordicsemi.com/nRF5_SDK/pieces/nRF_DeviceFamilyPack/ + IRAM(0x20000000,0x10000) IROM(0x00000000,0x80000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC4000 -FN2 -FF0nrf52xxx -FS00 -FL0200000 -FF1nrf52xxx_uicr -FS110001000 -FL11000 -FP0($$Device:nRF52832_xxAA$Flash\nrf52xxx.flm) -FP1($$Device:nRF52832_xxAA$Flash\nrf52xxx_uicr.flm)) + 0 + $$Device:nRF52832_xxAA$Device\Include\nrf.h + + + + + + + + + + $$Device:nRF52832_xxAA$SVD\nrf52.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread + 1 + 0 + 0 + 1 + 1 + .\build\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 1 + 0 + fromelf --bin !L --output rtthread.bin + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 2 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x0 + 0x80000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x1f000 + 0x61000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x200025f8 + 0xda08 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + --reduce_paths + BLE_STACK_SUPPORT_REQD NRF_SD_BLE_API_VERSION=4 S132 SOFTDEVICE_PRESENT SWI_DISABLE0 CONFIG_GPIO_AS_PINRESET NRF52 NRF52832_XXAA NRF52_PAN_12 NRF52_PAN_15 NRF52_PAN_20 NRF52_PAN_31 NRF52_PAN_36 NRF52_PAN_51 NRF52_PAN_54 NRF52_PAN_55 NRF52_PAN_58 NRF52_PAN_64 NRF52_PAN_74 + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + --cpreproc_opts=-DBLE_STACK_SUPPORT_REQD,-DNRF_SD_BLE_API_VERSION=4,-DS132,-DSOFTDEVICE_PRESENT,-DSWI_DISABLE0,-DCONFIG_GPIO_AS_PINRESET,-DNRF52,-DNRF52832_XXAA,-DNRF52_PAN_12,-DNRF52_PAN_15,-DNRF52_PAN_20,-DNRF52_PAN_31,-DNRF52_PAN_36,-DNRF52_PAN_51,-DNRF52_PAN_54,-DNRF52_PAN_55,-DNRF52_PAN_58,-DNRF52_PAN_64,-DNRF52_PAN_74 + BLE_STACK_SUPPORT_REQD NRF_SD_BLE_API_VERSION=4 S132 SOFTDEVICE_PRESENT SWI_DISABLE0 CONFIG_GPIO_AS_PINRESET NRF52 NRF52832_XXAA NRF52_PAN_12 NRF52_PAN_15 NRF52_PAN_20 NRF52_PAN_31 NRF52_PAN_36 NRF52_PAN_51 NRF52_PAN_54 NRF52_PAN_55 NRF52_PAN_58 NRF52_PAN_64 NRF52_PAN_74 + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + + + + --diag_suppress 6330 + + + + + + + + + + + + + + +